From 7af522335d94c751320f3a2a2fb8753fe770af37 Mon Sep 17 00:00:00 2001 From: Epagris Date: Tue, 30 Apr 2024 23:11:22 +0200 Subject: [PATCH] - interface packet interception capability added --- eth_interface.c | 18 ++++++++- eth_interface.h | 101 ++++++++++++++++++++++++++++-------------------- 2 files changed, 75 insertions(+), 44 deletions(-) diff --git a/eth_interface.c b/eth_interface.c index 3c9af03..2883aeb 100644 --- a/eth_interface.c +++ b/eth_interface.c @@ -68,6 +68,8 @@ EthInterface *ethintf_new(EthIODef *io) { memset(ðIntf->evtCbTable, 0, sizeof(EthIntfEventCbTable)); + ethIntf->interceptCb = NULL; + ethIntf->linkState = false; ethintf_register(ethIntf); @@ -88,8 +90,16 @@ static ThreadReturnType task_ethintf(ThreadParamType param) { case ETH_IIE_RECV_NOTIFY: { intf->ioDef->llRxRead(intf->ioDef); // read packets, will invoke RxStore while (mq_avail(intf->rxQ) > 0) { + // get the raw packet RawPckt rawPckt = mq_top(intf->rxQ); mq_pop(intf->rxQ); + + // packet interception, if defined + if (intf->interceptCb != NULL) { + intf->interceptCb(intf, &rawPckt); + } + + // packet processing packsieve_input(&intf->sieve, &rawPckt); } @@ -123,7 +133,7 @@ void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt) { bool pushOK = mq_push(intf->rxQ, rawPckt); if (!pushOK) { dynmem_free(rawPckt->payload); - ERROR("Input queue full, packet dropped!\n"); + ERROR("Interface RECEIVE queue full, packet dropped!\n"); } } @@ -131,7 +141,7 @@ void ethinf_transmit(EthInterface *intf, const RawPckt *rawPckt) { if (mq_push(intf->txQ, rawPckt)) { // push packet onto the message queue ethinf_push_notification(intf, ETH_IIE_TRANSMIT_NOTIFY, 0); // notify processing thread of the peding transmit } else { - ERROR("Interface transmit queue full!\n"); + ERROR("Interface TRANSMIT queue full, packet dropped!\n"); } } @@ -190,3 +200,7 @@ void ethinf_up(EthInterface *intf) { void ethinf_down(EthInterface *intf) { intf->up = false; } + +void ethinf_set_intercept_callback(EthInterface * intf, EthIntfInterceptCb cb) { + intf->interceptCb = cb; +} \ No newline at end of file diff --git a/eth_interface.h b/eth_interface.h index 84e3a1a..560f7c8 100644 --- a/eth_interface.h +++ b/eth_interface.h @@ -3,15 +3,15 @@ #include -#include "packet_sieve.h" -#include "prefab/packet_parsers/packet_parsers.h" -#include "prefab/packet_parsers/ipv4_types.h" #include "arp_cache.h" #include "connection_block.h" -#include "msg_queue.h" #include "gen_queue.h" +#include "msg_queue.h" +#include "packet_sieve.h" #include "prefab/conn_blocks/ipv4/ip_assembler.h" #include "prefab/packet_parsers/dhcp.h" +#include "prefab/packet_parsers/ipv4_types.h" +#include "prefab/packet_parsers/packet_parsers.h" #include @@ -19,14 +19,14 @@ * Ethernet interface low level definition. */ typedef struct EthIODef_ { - int (*llTxTrigger)(struct EthIODef_ * io, MsgQueue * mq); ///< Function pointer to low-level transmit function trigger - int (*llTxDone)(struct EthIODef_ * io, const RawPckt * rawPckt); ///< Transmission done (interrupt) callback - int (*llLinkChg)(struct EthIODef_ * io, int linkState); ///< Link change interrupt - int (*llRxStore)(struct EthIODef_ * io, const RawPckt * rawPckt); ///< Receive done callback - int (*llError)(struct EthIODef_ * io, int error); ///< Low-level error interrupt - int (*llRxRead)(struct EthIODef_ * io); ///< Read received packets - int (*llRxNotify)(struct EthIODef_ * io); ///< Notify of received packets - void * tag; ///< Some arbitrary tagging + int (*llTxTrigger)(struct EthIODef_ *io, MsgQueue *mq); ///< Function pointer to low-level transmit function trigger + int (*llTxDone)(struct EthIODef_ *io, const RawPckt *rawPckt); ///< Transmission done (interrupt) callback + int (*llLinkChg)(struct EthIODef_ *io, int linkState); ///< Link change interrupt + int (*llRxStore)(struct EthIODef_ *io, const RawPckt *rawPckt); ///< Receive done callback + int (*llError)(struct EthIODef_ *io, int error); ///< Low-level error interrupt + int (*llRxRead)(struct EthIODef_ *io); ///< Read received packets + int (*llRxNotify)(struct EthIODef_ *io); ///< Notify of received packets + void *tag; ///< Some arbitrary tagging } EthIODef; @@ -45,7 +45,14 @@ typedef enum { struct EthInterface_; -typedef void (*EthIntfEvtCb)(struct EthInterface_ * intf); +typedef void (*EthIntfEvtCb)(struct EthInterface_ *intf); + +/** + * Function prototype for intercepting packets on an interface. + * @param intf pointer to corresponding Ethernet interface + * @param rawPckt pointer to the IMMUTABLE raw packet + */ +typedef void (*EthIntfInterceptCb)(struct EthInterface_ *intf, const RawPckt *rawPckt); typedef enum { ETH_EVT_LINK_CHANGE = 0, @@ -56,33 +63,35 @@ typedef enum { * Ethernet interface event callback table */ typedef struct { - EthIntfEvtCb linkChange; ///< Link change event - EthIntfEvtCb ipChange; ///< IP-address changed - } EthIntfEventCbTable; + EthIntfEvtCb linkChange; ///< Link change event + EthIntfEvtCb ipChange; ///< IP-address changed +} EthIntfEventCbTable; /** * Ethernet interface representation. */ typedef struct EthInterface_ { - PcktSieve sieve; ///< Packet sieve - EthIODef * ioDef; ///< Low-level IO definitions - EthernetAddress mac; ///< Ethernet address - uint32_t capabilities; ///< Ethernet interface capabilities - DhcpState * dhcp; ///< DHCP control block (allocated only, if DHCP operation is initiated) - ip4_addr ip; ///< IP address - ip4_addr router; ///< Router IP address - ip4_addr netmask; ///< Subnet mask - ip4_addr dns; ///< Domain Name Server - ArpCache * arpc; ///< ARP cache - ConnBlock arpCb; ///< ARP connection block - MsgQueue * txQ; ///< Transmit queue - MsgQueue * rxQ; ///< Receive queue + PcktSieve sieve; ///< Packet sieve + EthIODef *ioDef; ///< Low-level IO definitions + EthernetAddress mac; ///< Ethernet address + uint32_t capabilities; ///< Ethernet interface capabilities + DhcpState *dhcp; ///< DHCP control block (allocated only, if DHCP operation is initiated) + ip4_addr ip; ///< IP address + ip4_addr router; ///< Router IP address + ip4_addr netmask; ///< Subnet mask + ip4_addr dns; ///< Domain Name Server + ArpCache *arpc; ///< ARP cache + ConnBlock arpCb; ///< ARP connection block + MsgQueue *txQ; ///< Transmit queue + MsgQueue *rxQ; ///< Receive queue ETHLIB_OS_QUEUE_TYPE eventQ; ///< Event queue - //ETHLIB_OS_SEM_TYPE eventSem; ///< Event queue semaphore - IPv4Assembler * ipra; ///< IPv4 reassembler + // ETHLIB_OS_SEM_TYPE eventSem; ///< Event queue semaphore + IPv4Assembler *ipra; ///< IPv4 reassembler EthIntfEventCbTable evtCbTable; ///< Event callback table - bool linkState; ///< Interface link state - bool up; ///< Is the interface up? + bool linkState; ///< Interface link state + bool up; ///< Is the interface up? + EthIntfInterceptCb interceptCb; ///< Intercept callback + } EthInterface; /** @@ -90,7 +99,7 @@ typedef struct EthInterface_ { * @param io Low-level IO definitions * @return new interface instance */ -EthInterface *ethintf_new(EthIODef * io); +EthInterface *ethintf_new(EthIODef *io); /** * Receive uncooked packet. @@ -113,7 +122,7 @@ void ethinf_push_notification(EthInterface *intf, uint16_t event_code, uint16_t * @param event_code pointer to event code * @param event_data pointer to event data */ -void ethinf_pull_notification(EthInterface *intf, uint16_t * event_code, uint16_t * event_data); +void ethinf_pull_notification(EthInterface *intf, uint16_t *event_code, uint16_t *event_data); /** * Transmit packet. @@ -133,38 +142,46 @@ void ethinf_set_capabilities(EthInterface *intf, uint32_t cap); * @param idx index of Ethernet event * @param cb callback function pointer */ -void ethinf_set_event_callback(EthInterface * intf, EthIntfEvIndex idx, EthIntfEvtCb cb); +void ethinf_set_event_callback(EthInterface *intf, EthIntfEvIndex idx, EthIntfEvtCb cb); /** * Trigger Ethernet event. * @param intf pointer to Ethernet interface * @param idx index of Ethernet interface event */ -void ethinf_trigger_event(EthInterface * intf, EthIntfEvIndex idx); +void ethinf_trigger_event(EthInterface *intf, EthIntfEvIndex idx); /** * Set link state. * @param intf pointer to Ethernet interface * @param ls link state */ -void ethinf_set_link_state(EthInterface * intf, bool ls); +void ethinf_set_link_state(EthInterface *intf, bool ls); /** * Get link state. * @param intf pointer to Ethernet interface + * @return link state */ -bool ethinf_get_link_state(EthInterface * intf); +bool ethinf_get_link_state(EthInterface *intf); /** * Enable interface. * @param intf pointer to Ethernet interface -*/ + */ void ethinf_up(EthInterface *intf); /** * Disable interface. * @param intf pointer to Ethernet interface -*/ + */ void ethinf_down(EthInterface *intf); -#endif //ETHERLIB_ETH_INTERFACE_H +/** + * Set callback for packet interception. + * @param intf pointer to Ethernet interface + * @param cb intercept callback pointer + */ +void ethinf_set_intercept_callback(EthInterface *intf, EthIntfInterceptCb cb); + +#endif // ETHERLIB_ETH_INTERFACE_H