EtherLib/global_state.c

67 lines
1.9 KiB
C

#include <stddef.h>
#include "global_state.h"
#include "dynmem.h"
#include "prefab/prefab.h"
EthState gEthState;
static void register_packet_parsers() {
PcktClassDesc cdesc;
// Ethernet frame parser
cdesc.class = 0;
cdesc.containerClass = 0;
cdesc.procFun = parse_ethernet;
cdesc.propertySize = sizeof(EthernetProps);
packreg_add(E.pcktReg, &cdesc);
// IPv4 packet parser
cdesc.class = ETH_IPv4_PACKET_CLASS;
cdesc.containerClass = 0;
cdesc.procFun = parse_ipv4;
cdesc.propertySize = sizeof(IPv4Props);
packreg_add(E.pcktReg, &cdesc);
// UDP packet parser
cdesc.class = ETH_UDP_PACKET_CLASS;
cdesc.containerClass = ETH_IPv4_PACKET_CLASS;
cdesc.procFun = parse_udp;
cdesc.propertySize = sizeof(UDPProps);
packreg_add(E.pcktReg, &cdesc);
}
void ethlib_init() {
dynmem_init(); // initialize dynamic memory subsystem
E.pcktReg = packreg_new(); // create new packet registry
register_packet_parsers(); // register packet parsers
}
void process_raw_packet(const uint8_t * data, uint32_t size) {
uint16_t ownClass = 0, containerClass = 0; // Ethernet...
uint16_t offset = 0;
PcktProps * props = NULL;
do {
// get packet descriptor
const PcktClassDesc * cdesc = packreg_get_by_class(E.pcktReg, ownClass, containerClass);
if (cdesc == NULL) {
break;
}
// allocate property object
props = (PcktProps *) dynmem_alloc(cdesc->propertySize);
// call parsing function
cdesc->procFun(data + offset, size - offset, props);
uint16_t containedClass = props->containedPacketClass;
if (containedClass != 0) {
containerClass = ownClass;
offset += props->headerSize;
dynmem_free(props);
}
ownClass = containedClass;
} while (ownClass != 0);
// TODO process innermost packet
return;
}