- Timestamping management added - Errors due to reading uninitialized data in ARP fixed - EthInterface reworked, incoming packet notification and payload readout separated (through which fixing concurrent access problems) - RX and TX offloads added - Capability to add a packet sieve layer without prior registration of specific packet class added (this makes it possible to register arbitrary EtherType connection blocks, for example)
99 lines
3.0 KiB
C
99 lines
3.0 KiB
C
#include <stddef.h>
|
|
#include "global_state.h"
|
|
#include "dynmem.h"
|
|
|
|
#include "prefab/prefab.h"
|
|
#include "packet_sieve.h"
|
|
#include "prefab/packet_parsers/arp_packet.h"
|
|
#include "prefab/packet_parsers/icmp_packet.h"
|
|
#include "etherlib/prefab/packet_parsers/igmp_packet.h"
|
|
#include "etherlib/prefab/packet_parsers/tcp_segment.h"
|
|
#include "utils.h"
|
|
|
|
EthState gEthState;
|
|
|
|
static void register_packet_parsers() {
|
|
PcktClassDesc cdesc;
|
|
// Ethernet frame parser
|
|
cdesc.class = 0;
|
|
cdesc.containerClass = 0;
|
|
cdesc.procFun = parse_ethernet;
|
|
cdesc.hdrInsFn = insert_ethernet_header;
|
|
cdesc.propertySize = sizeof(EthernetProps);
|
|
packreg_add_class(E.pcktReg, &cdesc);
|
|
|
|
// IPv4 packet parser
|
|
cdesc.class = ETH_IPv4_PACKET_CLASS;
|
|
cdesc.containerClass = 0;
|
|
cdesc.procFun = parse_ipv4;
|
|
cdesc.hdrInsFn = insert_ipv4_header;
|
|
cdesc.propertySize = sizeof(IPv4Props);
|
|
packreg_add_class(E.pcktReg, &cdesc);
|
|
|
|
// UDP packet parser
|
|
cdesc.class = ETH_UDP_PACKET_CLASS;
|
|
cdesc.containerClass = ETH_IPv4_PACKET_CLASS;
|
|
cdesc.procFun = parse_udp;
|
|
cdesc.hdrInsFn = insert_udp_header;
|
|
cdesc.propertySize = sizeof(UdpProps);
|
|
packreg_add_class(E.pcktReg, &cdesc);
|
|
|
|
// ARP packet parser
|
|
cdesc.class = ETH_ARP_PACKET_CLASS;
|
|
cdesc.containerClass = 0;
|
|
cdesc.procFun = parse_arp;
|
|
cdesc.hdrInsFn = insert_arp_header;
|
|
cdesc.propertySize = sizeof(ArpProps);
|
|
packreg_add_class(E.pcktReg, &cdesc);
|
|
|
|
// ICMP packet parser
|
|
cdesc.class = ETH_ICMP_PACKET_CLASS;
|
|
cdesc.containerClass = ETH_IPv4_PACKET_CLASS;
|
|
cdesc.procFun = parse_icmp;
|
|
cdesc.hdrInsFn = insert_icmp_header;
|
|
cdesc.propertySize = sizeof(IcmpProps);
|
|
packreg_add_class(E.pcktReg, &cdesc);
|
|
|
|
// IGMP packet parser
|
|
cdesc.class = ETH_IGMP_PACKET_CLASS;
|
|
cdesc.containerClass = ETH_IPv4_PACKET_CLASS;
|
|
cdesc.procFun = parse_igmp;
|
|
cdesc.hdrInsFn = insert_igmp_header;
|
|
cdesc.propertySize = sizeof(IgmpProps);
|
|
packreg_add_class(E.pcktReg, &cdesc);
|
|
|
|
// TCP packet parser
|
|
cdesc.class = ETH_TCP_PACKET_CLASS;
|
|
cdesc.containerClass = ETH_IPv4_PACKET_CLASS;
|
|
cdesc.procFun = parse_tcp;
|
|
cdesc.hdrInsFn = insert_tcp_header;
|
|
cdesc.propertySize = sizeof(TcpProps);
|
|
packreg_add_class(E.pcktReg, &cdesc);
|
|
}
|
|
|
|
void ethlib_init() {
|
|
dynmem_init(); // initialize dynamic memory subsystem
|
|
E.tmr = timer_new(ETHLIB_TMR_SCHED_TABLE_SIZE); // create timer
|
|
E.cbdt = cbdt_new(ETHLIB_CBD_TABLE_SIZE); // create a new connection block descriptor table
|
|
E.pcktReg = packreg_new(); // create new packet registry
|
|
register_packet_parsers(); // register packet parsers
|
|
|
|
//E.ethIntf = ethintf_new(); // create new Ethernet interface
|
|
}
|
|
|
|
void close_connection(cbd d) {
|
|
ConnBlock connBlock;
|
|
if (!cbdt_get_connection_block(E.cbdt, d, &connBlock)) {
|
|
ERROR("Invalid CBD descriptor: '%d'!\n", d);
|
|
return;
|
|
}
|
|
|
|
cbdt_release(E.cbdt, d); // release from CBD table
|
|
|
|
connb_remove(&connBlock); // remove connection block
|
|
}
|
|
|
|
EthInterface *get_default_interface() {
|
|
return E.ethIntf;
|
|
}
|