Merge branch 'master' of epagris.com:epagris/EtherLib
This commit is contained in:
		
						commit
						1127b3dd1d
					
				@ -5,6 +5,7 @@
 | 
				
			|||||||
#include "eth_interface.h"
 | 
					#include "eth_interface.h"
 | 
				
			||||||
#include "dynmem.h"
 | 
					#include "dynmem.h"
 | 
				
			||||||
#include "etherlib/prefab/conn_blocks/ethernet_connblock.h"
 | 
					#include "etherlib/prefab/conn_blocks/ethernet_connblock.h"
 | 
				
			||||||
 | 
					#include "etherlib/prefab/packet_parsers/ipv4_types.h"
 | 
				
			||||||
#include "etherlib_options.h"
 | 
					#include "etherlib_options.h"
 | 
				
			||||||
#include "utils.h"
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -74,6 +75,11 @@ EthInterface *ethintf_new(EthIODef *io) {
 | 
				
			|||||||
    ethIntf->interceptTxCb = NULL;
 | 
					    ethIntf->interceptTxCb = NULL;
 | 
				
			||||||
    ethIntf->interceptRxCb = NULL;
 | 
					    ethIntf->interceptRxCb = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ethIntf->ip = 0;
 | 
				
			||||||
 | 
					    ethIntf->router = 0;
 | 
				
			||||||
 | 
					    ethIntf->dns = 0;
 | 
				
			||||||
 | 
					    ethIntf->netmask = IPv4_ANY_ADDR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ethIntf->linkState = false;
 | 
					    ethIntf->linkState = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ethintf_register(ethIntf);
 | 
					    ethintf_register(ethIntf);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								packet.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								packet.h
									
									
									
									
									
								
							@ -3,6 +3,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \struct RawPckt
 | 
					 * \struct RawPckt
 | 
				
			||||||
 * \brief Raw packet received on wire
 | 
					 * \brief Raw packet received on wire
 | 
				
			||||||
@ -20,6 +22,9 @@
 | 
				
			|||||||
             uint32_t arg; ///> User-defined argument
 | 
					             uint32_t arg; ///> User-defined argument
 | 
				
			||||||
         } tx;
 | 
					         } tx;
 | 
				
			||||||
     } ext; ///> Extensions
 | 
					     } ext; ///> Extensions
 | 
				
			||||||
 | 
					     struct {
 | 
				
			||||||
 | 
					        bool calculate_ethernet_CRC : 1; ///> Instruct the packet assembler to always computer FCS regardless of device capabilities
 | 
				
			||||||
 | 
					     } opts;
 | 
				
			||||||
 } RawPckt;
 | 
					 } RawPckt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PcktHeaderElement_;
 | 
					struct PcktHeaderElement_;
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,7 @@ int pckt_assemble(RawPckt *raw, Pckt *cooked, EthInterface *intf) {
 | 
				
			|||||||
        hdrIter = hdrIter->next;
 | 
					        hdrIter = hdrIter->next;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    frameSize = headerSize + cooked->payloadSize;// + 4; // header + payload
 | 
					    frameSize = headerSize + cooked->payloadSize;// + 4; // header + payload
 | 
				
			||||||
    bool computeCRC = !(intf->capabilities & ETHINF_CAP_TX_CRC_OFFLOAD);
 | 
					    bool computeCRC = (!(intf->capabilities & ETHINF_CAP_TX_CRC_OFFLOAD)) || raw->opts.calculate_ethernet_CRC;
 | 
				
			||||||
    if (computeCRC) { // + CRC32 checksum area if needed
 | 
					    if (computeCRC) { // + CRC32 checksum area if needed
 | 
				
			||||||
        frameSize += 4;
 | 
					        frameSize += 4;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -73,10 +73,10 @@ int pckt_assemble(RawPckt *raw, Pckt *cooked, EthInterface *intf) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // insert CRC32 if interface is not capable of inserting CRC
 | 
					    // insert CRC32 if interface cannot handle CRC calculation or if explicitly requested
 | 
				
			||||||
    if (computeCRC) {
 | 
					    if (computeCRC) {
 | 
				
			||||||
        uint32_t crc = crc32(raw->payload, frameSize - 4);
 | 
					        uint32_t crc = crc32(raw->payload, frameSize - 4);
 | 
				
			||||||
        memcpy(raw->payload + frameSize - 4, (const uint8_t *)&crc, 4);
 | 
					        memcpy(raw->payload + frameSize - 4, &crc, 4);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // turn off TX timestamping by default
 | 
					    // turn off TX timestamping by default
 | 
				
			||||||
 | 
				
			|||||||
@ -80,6 +80,7 @@ void arp_send(const ConnBlock *connBlock, const ArpProps *props) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // send packet
 | 
					    // send packet
 | 
				
			||||||
    RawPckt rpckt;
 | 
					    RawPckt rpckt;
 | 
				
			||||||
 | 
					    memset(&rpckt, 0, sizeof(RawPckt));
 | 
				
			||||||
    rpckt.size = txBufSize;
 | 
					    rpckt.size = txBufSize;
 | 
				
			||||||
    rpckt.payload = txBuf;
 | 
					    rpckt.payload = txBuf;
 | 
				
			||||||
    rpckt.ext.tx.txTsCb = NULL;
 | 
					    rpckt.ext.tx.txTsCb = NULL;
 | 
				
			||||||
 | 
				
			|||||||
@ -73,6 +73,7 @@ int cet_send_arg(cbd d, const uint8_t *dest, const uint8_t *data, uint16_t size,
 | 
				
			|||||||
    cooked.time_ns = 0;
 | 
					    cooked.time_ns = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RawPckt raw;
 | 
					    RawPckt raw;
 | 
				
			||||||
 | 
					    memset(&raw, 0, sizeof(RawPckt));
 | 
				
			||||||
    pckt_assemble(&raw, &cooked, connBlock.sieve->intf);
 | 
					    pckt_assemble(&raw, &cooked, connBlock.sieve->intf);
 | 
				
			||||||
    raw.ext.tx.arg = arg; // assign argument
 | 
					    raw.ext.tx.arg = arg; // assign argument
 | 
				
			||||||
    raw.ext.tx.txTsCb = connBlock.sieveLayer->txTsCb; // assign with TX timestamp callback
 | 
					    raw.ext.tx.txTsCb = connBlock.sieveLayer->txTsCb; // assign with TX timestamp callback
 | 
				
			||||||
 | 
				
			|||||||
@ -81,6 +81,7 @@ static int icmp_recv_cb(const Pckt * pckt, PcktSieveLayerTag tag) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            // assemble packet
 | 
					            // assemble packet
 | 
				
			||||||
            RawPckt raw;
 | 
					            RawPckt raw;
 | 
				
			||||||
 | 
					            memset(&raw, 0, sizeof(RawPckt));
 | 
				
			||||||
            pckt_assemble(&raw, &reply, intf);
 | 
					            pckt_assemble(&raw, &reply, intf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // release headers
 | 
					            // release headers
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
#include "../../dynmem.h"
 | 
					#include "../../dynmem.h"
 | 
				
			||||||
#include "../../pckt_assembler.h"
 | 
					#include "../../pckt_assembler.h"
 | 
				
			||||||
#include "../../eth_interface.h"
 | 
					#include "../../eth_interface.h"
 | 
				
			||||||
 | 
					#include "etherlib/prefab/packet_parsers/ipv4_packet.h"
 | 
				
			||||||
#include "ipv4_connblock.h"
 | 
					#include "ipv4_connblock.h"
 | 
				
			||||||
#include "../packet_parsers/igmp_packet.h"
 | 
					#include "../packet_parsers/igmp_packet.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -37,6 +38,9 @@ ConnBlock igmp_new_connblock(struct EthInterface_ *intf) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void igmp_send(ConnBlock * connBlock, ip4_addr ga, int mt) {
 | 
					static void igmp_send(ConnBlock * connBlock, ip4_addr ga, int mt) {
 | 
				
			||||||
 | 
					    // fetch interface
 | 
				
			||||||
 | 
					    EthInterface * intf = connBlock->sieve->intf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // allocate headers
 | 
					    // allocate headers
 | 
				
			||||||
    PcktHeaderElement * igmpHeader = ALLOC_HEADER_ELEMENT(IgmpProps);
 | 
					    PcktHeaderElement * igmpHeader = ALLOC_HEADER_ELEMENT(IgmpProps);
 | 
				
			||||||
    PcktHeaderElement * ipHeader = ALLOC_HEADER_ELEMENT(IPv4Props);
 | 
					    PcktHeaderElement * ipHeader = ALLOC_HEADER_ELEMENT(IPv4Props);
 | 
				
			||||||
@ -67,34 +71,49 @@ static void igmp_send(ConnBlock * connBlock, ip4_addr ga, int mt) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // IP
 | 
					    // IP
 | 
				
			||||||
    layer = layer->parent;
 | 
					    layer = layer->parent;
 | 
				
			||||||
    ipv4_fill_props(ipProps, ETH_IGMP_HEADER_SIZE, ETH_IGMP_PACKET_CLASS, connBlock->sieve->intf->ip, ga);
 | 
					    ipv4_fill_props(ipProps, ETH_IGMP_HEADER_SIZE, ETH_IGMP_PACKET_CLASS, intf->ip, ga);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Ethernet
 | 
					    // Ethernet
 | 
				
			||||||
    ethmc_from_ipmc(ethProps->destAddr, ga);
 | 
					    ethmc_from_ipmc(ethProps->destAddr, ga);
 | 
				
			||||||
    memcpy(ethProps->sourceAddr, connBlock->sieve->intf->mac, ETH_HW_ADDR_LEN);
 | 
					    memcpy(ethProps->sourceAddr, intf->mac, ETH_HW_ADDR_LEN);
 | 
				
			||||||
    ethProps->length_type = ETH_IPv4_PACKET_CLASS;
 | 
					    ethProps->length_type = ETH_IPv4_PACKET_CLASS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // common fields for packet assembly
 | 
					    // common fields for packet assembly
 | 
				
			||||||
    ethProps->hdrInsFn = insert_ethernet_header;
 | 
					    ethProps->hdrInsFn = insert_ethernet_header;
 | 
				
			||||||
    ethProps->headerSize = ETH_ETHERNET_HEADER_SIZE;
 | 
					    ethProps->headerSize = ETH_ETHERNET_HEADER_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Pckt cooked;
 | 
					    // allocate transmit buffer
 | 
				
			||||||
    cooked.payload = NULL;
 | 
					    uint32_t txHeaderSize = ETH_ETHERNET_HEADER_SIZE + ETH_IPv4_HEADER_SIZE + ETH_IGMP_HEADER_SIZE;
 | 
				
			||||||
    cooked.payloadSize = 0;
 | 
					    uint32_t txBufSize = MAX(txHeaderSize + 4, ETH_FRAME_MIN_SIZE);
 | 
				
			||||||
    cooked.header = ethHeader;
 | 
					    uint8_t *txBuf = dynmem_alloc(txBufSize);
 | 
				
			||||||
 | 
					    memset(txBuf, 0, txBufSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // NOT FILLED FIELDS
 | 
					    // insert Ethernet header
 | 
				
			||||||
    cooked.headerSize = 0;
 | 
					    insert_ethernet_header(txBuf, ethHeader, NULL);
 | 
				
			||||||
    cooked.time_s = 0;
 | 
					 | 
				
			||||||
    cooked.time_ns = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RawPckt raw;
 | 
					    // insert IPv4 header
 | 
				
			||||||
    pckt_assemble(&raw, &cooked, connBlock->sieve->intf);
 | 
					    insert_ipv4_header(txBuf + ETH_ETHERNET_HEADER_SIZE, ipHeader, intf);
 | 
				
			||||||
 | 
					    ipv4_fill_in_chksum(txBuf + ETH_ETHERNET_HEADER_SIZE); // fill-in IPv4 checksum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ethinf_transmit(connBlock->sieve->intf, &raw);
 | 
					    // insert IGMP header
 | 
				
			||||||
 | 
					    insert_igmp_header(txBuf + ETH_ETHERNET_HEADER_SIZE + ETH_IPv4_HEADER_SIZE, igmpHeader, intf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // free headers
 | 
					    // release headers
 | 
				
			||||||
    pckthdr_chain_free(ethHeader);
 | 
					    dynmem_free(ethHeader);
 | 
				
			||||||
 | 
					    dynmem_free(ipHeader);
 | 
				
			||||||
 | 
					    dynmem_free(igmpHeader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // calculate CRC
 | 
				
			||||||
 | 
					    uint32_t crc = crc32(txBuf, txBufSize - 4);
 | 
				
			||||||
 | 
					    memcpy(txBuf + txBufSize - 4, &crc, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // send packet
 | 
				
			||||||
 | 
					    RawPckt rpckt;
 | 
				
			||||||
 | 
					    memset(&rpckt, 0, sizeof(RawPckt));
 | 
				
			||||||
 | 
					    rpckt.size = txBufSize;
 | 
				
			||||||
 | 
					    rpckt.payload = txBuf;
 | 
				
			||||||
 | 
					    rpckt.ext.tx.txTsCb = NULL;
 | 
				
			||||||
 | 
					    ethinf_transmit(intf, &rpckt);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void igmp_report_membership(ConnBlock * connBlock, ip4_addr ga) {
 | 
					void igmp_report_membership(ConnBlock * connBlock, ip4_addr ga) {
 | 
				
			||||||
 | 
				
			|||||||
@ -694,6 +694,7 @@ int tcp_send_segment(const struct ConnBlock_ *connBlock, TcpFlag flags, TcpOptio
 | 
				
			|||||||
    cooked.time_ns = 0;
 | 
					    cooked.time_ns = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RawPckt raw;
 | 
					    RawPckt raw;
 | 
				
			||||||
 | 
					    memset(&raw, 0, sizeof(RawPckt));
 | 
				
			||||||
    pckt_assemble(&raw, &cooked, connBlock->sieve->intf);
 | 
					    pckt_assemble(&raw, &cooked, connBlock->sieve->intf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ethinf_transmit(connBlock->sieve->intf, &raw);
 | 
					    ethinf_transmit(connBlock->sieve->intf, &raw);
 | 
				
			||||||
 | 
				
			|||||||
@ -120,6 +120,7 @@ int udp_sendto_arg(cbd d, const uint8_t *data, uint32_t size, ip4_addr addr, uin
 | 
				
			|||||||
    cooked.time_ns = 0;
 | 
					    cooked.time_ns = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RawPckt raw;
 | 
					    RawPckt raw;
 | 
				
			||||||
 | 
					    memset(&raw, 0, sizeof(RawPckt));
 | 
				
			||||||
    pckt_assemble(&raw, &cooked, connBlock.sieve->intf);
 | 
					    pckt_assemble(&raw, &cooked, connBlock.sieve->intf);
 | 
				
			||||||
    raw.ext.tx.arg = arg; // assign argument
 | 
					    raw.ext.tx.arg = arg; // assign argument
 | 
				
			||||||
    raw.ext.tx.txTsCb = connBlock.sieveLayer->txTsCb; // assign with TX timestamp callback
 | 
					    raw.ext.tx.txTsCb = connBlock.sieveLayer->txTsCb; // assign with TX timestamp callback
 | 
				
			||||||
 | 
				
			|||||||
@ -145,3 +145,9 @@ void ipv4_fill_props(IPv4Props *ipProps,
 | 
				
			|||||||
    ipProps->headerSize = ETH_IPv4_HEADER_SIZE;
 | 
					    ipProps->headerSize = ETH_IPv4_HEADER_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ipv4_fill_in_chksum(uint8_t * hdr) {
 | 
				
			||||||
 | 
					    uint8_t * ChkSumPtr = hdr + 10; // create a pointer to checksum position
 | 
				
			||||||
 | 
					    uint16_t checksum = chksum(hdr, ETH_IPv4_HEADER_SIZE, false); // compute checksum
 | 
				
			||||||
 | 
					    memcpy(ChkSumPtr, &checksum, 2); // copy checksum to the proper position
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -76,4 +76,10 @@ void ethmc_from_ipmc(uint8_t * hwa, ip4_addr ipa);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void ipv4_fill_props(IPv4Props *ipProps, uint32_t payloadSize, uint16_t protocol, ip4_addr srcIpA, ip4_addr dstIpA);
 | 
					void ipv4_fill_props(IPv4Props *ipProps, uint32_t payloadSize, uint16_t protocol, ip4_addr srcIpA, ip4_addr dstIpA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Fill in IPv4 checksum, based on header data.
 | 
				
			||||||
 | 
					 * @param hdr Pointer to the IPv4 header's beginning. Checksum field's position will be written.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					void ipv4_fill_in_chksum(uint8_t * hdr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //ETHERLIB_IPV4_PACKET_H
 | 
					#endif //ETHERLIB_IPV4_PACKET_H
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user