From e4d27454cd7c9b58c5323e6c9d1ed3706d201ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiesner=20Andr=C3=A1s?= Date: Sun, 15 Oct 2023 12:17:37 +0200 Subject: [PATCH] - add tag to CBD - DHCP state separated - link change handler added - timer mutex added --- cbd_table.c | 20 ++++++++ cbd_table.h | 18 +++++++ eth_interface.c | 35 +++++++++++++ eth_interface.h | 51 +++++++++++++++++++ prefab/packet_parsers/dhcp.c | 98 ++++++++++++++++++------------------ prefab/packet_parsers/dhcp.h | 24 +++++++-- timer.c | 30 +++++++++-- timer.h | 3 ++ utils.h | 2 +- 9 files changed, 224 insertions(+), 57 deletions(-) diff --git a/cbd_table.c b/cbd_table.c index 6db3977..f525f27 100644 --- a/cbd_table.c +++ b/cbd_table.c @@ -50,6 +50,26 @@ bool cbdt_get_connection_block(CbdTable *cbdt, cbd d, ConnBlock *connBlock) { return true; } +bool cbdt_set_tag(CbdTable *cbdt, cbd d, PcktSieveLayerTag tag) { + ConnBlock connBlock; + if (cbdt_get_connection_block(cbdt, d, &connBlock)) { + connBlock.sieveLayer->tag = tag; + return true; + } else { + return false; + } +} + +bool cbdt_get_tag(CbdTable * cbdt, cbd d, PcktSieveLayerTag * tag) { + ConnBlock connBlock; + if (cbdt_get_connection_block(cbdt, d, &connBlock)) { + *tag = connBlock.sieveLayer->tag; + return true; + } else { + return false; + } +} + void cbdt_report(const CbdTable *cbdt) { INFO("CBDT listing (%d/%d):\n---------------\n\n", cbdt->level, cbdt->maxEntries); diff --git a/cbd_table.h b/cbd_table.h index 919fb05..d354426 100644 --- a/cbd_table.h +++ b/cbd_table.h @@ -52,6 +52,24 @@ void cbdt_release(CbdTable * cbdt, cbd d); */ bool cbdt_get_connection_block(CbdTable * cbdt, cbd d, ConnBlock * connBlock); +/** + * Set connection block sieve tag. + * @param cbdt pointer to CBDT + * @param d CBD value + * @param tag tag getting stored + * @return operation successful (d was valid) + */ +bool cbdt_set_tag(CbdTable * cbdt, cbd d, PcktSieveLayerTag tag); + +/** + * Retrieve connection block sieve tag. + * @param cbdt pointer to CBDT + * @param d CBD value + * @param tag pointer to area where tag is written + * @return operation successful (d was valid) + */ +bool cbdt_get_tag(CbdTable * cbdt, cbd d, PcktSieveLayerTag * tag); + /** * Print report on connection block descriptors. * @param cbdt pointer to CBD table diff --git a/eth_interface.c b/eth_interface.c index 365d97f..8f85e16 100644 --- a/eth_interface.c +++ b/eth_interface.c @@ -18,10 +18,17 @@ static int ethintf_llrxnotify(EthIODef * io) { return 0; } +static int ethinf_lllinkchg(EthIODef * io, int ls) { + ethinf_set_link_state((EthInterface *) io->tag, ls); + MSG("Link state: %d\n", ls); + return 0; +} + static void ethintf_register(EthInterface * intf) { intf->ioDef->tag = intf; intf->ioDef->llRxStore = ethintf_llrecv; intf->ioDef->llRxNotify = ethintf_llrxnotify; + intf->ioDef->llLinkChg = ethinf_lllinkchg; } // interface processing thread @@ -49,6 +56,12 @@ EthInterface *ethintf_new(EthIODef * io) { ethIntf->capabilities = 0; + ethIntf->dhcp = NULL; + + memset(ðIntf->evtCbTable, 0, sizeof(EthIntfEventCbTable)); + + ethIntf->linkState = false; + return ethIntf; } @@ -87,3 +100,25 @@ void ethinf_notify(EthInterface *intf) { void ethinf_set_capabilities(EthInterface *intf, uint32_t cap) { intf->capabilities = cap; } + +void ethinf_set_event_callback(EthInterface *intf, EthIntfEvIndex idx, EthIntfEvtCb cb) { + ((EthIntfEvtCb *)((&(intf->evtCbTable))))[idx] = cb; +} + +void ethinf_trigger_event(EthInterface *intf, EthIntfEvIndex idx) { + EthIntfEvtCb cb = ((EthIntfEvtCb *)((&(intf->evtCbTable))))[idx]; + if (cb != NULL) { + cb(intf); + } +} + +void ethinf_set_link_state(EthInterface *intf, bool ls) { + if (intf->linkState != ls) { // trigger event only if state has actually changed + intf->linkState = ls; + ethinf_trigger_event(intf, ETH_EVT_LINK_CHANGE); + } +} + +bool ethinf_get_link_state(EthInterface *intf) { + return intf->linkState; +} diff --git a/eth_interface.h b/eth_interface.h index 1620dfb..14ade9e 100644 --- a/eth_interface.h +++ b/eth_interface.h @@ -1,6 +1,8 @@ #ifndef ETHERLIB_ETH_INTERFACE_H #define ETHERLIB_ETH_INTERFACE_H +#include + #include "packet_sieve.h" #include "prefab/packet_parsers/packet_parsers.h" #include "prefab/packet_parsers/ipv4_types.h" @@ -9,6 +11,7 @@ #include "msg_queue.h" #include "prefab/conn_blocks/ipv4/ip_assembler.h" #include "etherlib_options.h" +#include "etherlib/prefab/packet_parsers/dhcp.h" /** * Ethernet interface low level definition. @@ -38,6 +41,23 @@ typedef enum { ETHINF_CAP_ALL_RX_TX_CHECKSUM_OFFLOADS = 0b11111, } EthIntfCap; +struct EthInterface_; + +typedef void (*EthIntfEvtCb)(struct EthInterface_ * intf); + +typedef enum { + ETH_EVT_LINK_CHANGE = 0, + ETH_EVT_IP_CHANGE = 1 +} EthIntfEvIndex; + +/** + * Ethernet interface event callback table + */ +typedef struct { + EthIntfEvtCb linkChange; ///< Link change event + EthIntfEvtCb ipChange; ///< IP-address changed + } EthIntfEventCbTable; + /** * Ethernet interface representation. */ @@ -46,6 +66,7 @@ typedef struct EthInterface_ { 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 @@ -56,6 +77,8 @@ typedef struct EthInterface_ { MsgQueue * rxQ; ///< Receive queue ETHLIB_OS_SEM_TYPE rxSem; ///< Receive queue semaphore IPv4Assembler * ipra; ///< IPv4 reassembler + EthIntfEventCbTable evtCbTable; ///< Event callback table + bool linkState; ///< Interface link state } EthInterface; /** @@ -90,4 +113,32 @@ void ethinf_transmit(EthInterface *intf, const RawPckt *rawPckt); */ void ethinf_set_capabilities(EthInterface *intf, uint32_t cap); +/** + * Set Ethernet event callback. + * @param intf pointer to Ethernet interface + * @param idx index of Ethernet event + * @param cb callback function pointer + */ +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); + +/** + * Set link state. + * @param intf pointer to Ethernet interface + * @param ls link state + */ +void ethinf_set_link_state(EthInterface * intf, bool ls); + +/** + * Get link state. + * @param intf pointer to Ethernet interface + */ +bool ethinf_get_link_state(EthInterface * intf); + #endif //ETHERLIB_ETH_INTERFACE_H diff --git a/prefab/packet_parsers/dhcp.c b/prefab/packet_parsers/dhcp.c index 00e3cee..9eb4475 100644 --- a/prefab/packet_parsers/dhcp.c +++ b/prefab/packet_parsers/dhcp.c @@ -10,15 +10,6 @@ #include "../conn_blocks/udp_connblock.h" #include "../../global_state.h" -static struct { - DhcpState state; - void *buf; - cbd desc; - uint32_t tranId; - EthInterface *intf; - ETHLIB_OS_MTX_TYPE procMtx; -} s; - static const uint8_t DHCP_MAGIC_COOKIE[] = {99, 130, 83, 99}; #define SNAME_LEN (64) @@ -124,9 +115,9 @@ static const DhcpOption *dhcp_get_option(const DhcpOption *opts, DhcpOptionId id return NULL; } -static void dhcp_send(const DhcpProps *props, const DhcpOption *opts) { +static void dhcp_send(DhcpState * s, const DhcpProps *props, const DhcpOption *opts) { // construct body - uint8_t *buf = (uint8_t *) s.buf; + uint8_t *buf = (uint8_t *) s->buf; memset(buf, 0, DHCP_MIN_PACKET_SIZE); FILL_BYTE_ADVANCE(buf, &(props->op)); FILL_BYTE_ADVANCE(buf, &(props->htype)); @@ -155,7 +146,7 @@ static void dhcp_send(const DhcpProps *props, const DhcpOption *opts) { // dhcp_option_insert_end(&buf); // send packet - udp_sendto(s.desc, s.buf, DHCP_MIN_PACKET_SIZE, IPv4_ANY_ADDR, DHCP_SERVER_PORT); + udp_sendto(s->desc, s->buf, DHCP_MIN_PACKET_SIZE, IPv4_ANY_ADDR, DHCP_SERVER_PORT); } static void dhcp_parse(const uint8_t *buf, DhcpProps *props, DhcpOption **opts) { @@ -196,15 +187,15 @@ static void dhcp_parse(const uint8_t *buf, DhcpProps *props, DhcpOption **opts) #define IPv4_ADDR_TO_BE_BYTES(addr) ((addr) & 0xFF), (((addr) >> 8) & 0xFF), (((addr) >> 16) & 0xFF), (((addr) >> 24) & 0xFF), #define HWADDR_TO_BE_BYTES(hwa) (hwa)[0], (hwa)[1], (hwa)[2], (hwa)[3], (hwa)[4], (hwa)[5], -static void dhcp_discover() { - s.tranId = rand(); +static void dhcp_discover(DhcpState * s) { + s->tranId = rand(); DhcpProps props = {0}; props.op = DHCP_BOOTREQUEST; props.htype = DHCP_HW_TYPE_ETHERNET; props.hlen = 6; props.hops = 0; - props.xid = s.tranId; + props.xid = s->tranId; props.secs = 0; props.flags = 0; props.ciaddr = 0; @@ -212,24 +203,24 @@ static void dhcp_discover() { props.siaddr = 0; props.giaddr = 0; - memcpy(props.chaddr, s.intf->mac, ETH_HW_ADDR_LEN); + memcpy(props.chaddr, s->intf->mac, ETH_HW_ADDR_LEN); DhcpOption optEnd = {DHCP_OPT_End, 0, NULL}; uint16_t maxSize = 1500; // TODO... DhcpOption maxMsgSize = {DHCP_OPT_MaxMsgSize, 2, &optEnd, {UINT16_TO_BE_BYTES(maxSize)}}; DhcpOption msgType = {DHCP_OPT_MsgType, 1, &maxMsgSize, {DHCPDISCOVER}}; - dhcp_send(&props, &msgType); + dhcp_send(s, &props, &msgType); } -void dhcp_request(ip4_addr reqAddr, ip4_addr dhcpServerAddr) { +void dhcp_request(DhcpState * s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) { DhcpProps props = {0}; props.op = DHCP_BOOTREQUEST; props.htype = DHCP_HW_TYPE_ETHERNET; props.hlen = 6; props.hops = 0; - props.xid = s.tranId; + props.xid = s->tranId; props.secs = 0; props.flags = 0; props.ciaddr = 0; @@ -237,7 +228,7 @@ void dhcp_request(ip4_addr reqAddr, ip4_addr dhcpServerAddr) { props.siaddr = 0; props.giaddr = 0; - memcpy(props.chaddr, s.intf->mac, ETH_HW_ADDR_LEN); + memcpy(props.chaddr, s->intf->mac, ETH_HW_ADDR_LEN); uint16_t maxSize = 1500; // TODO... @@ -245,20 +236,20 @@ void dhcp_request(ip4_addr reqAddr, ip4_addr dhcpServerAddr) { DhcpOption paramReq = {DHCP_OPT_ParamReqList, 4, &optEnd, {1, 3, 6, 51}}; // TODO... DhcpOption reqIp = {DHCP_OPT_RequestedIpAddress, 4, ¶mReq, {IPv4_ADDR_TO_BE_BYTES(reqAddr)}}; DhcpOption serverIp = {DHCP_OPT_ServerId, 4, &reqIp, {IPv4_ADDR_TO_BE_BYTES(dhcpServerAddr)}}; - DhcpOption clId = {DHCP_OPT_ClientIdentifier, 7, &serverIp, {DHCP_HW_TYPE_ETHERNET, HWADDR_TO_BE_BYTES(s.intf->mac)}}; + DhcpOption clId = {DHCP_OPT_ClientIdentifier, 7, &serverIp, {DHCP_HW_TYPE_ETHERNET, HWADDR_TO_BE_BYTES(s->intf->mac)}}; DhcpOption maxMsgSize = {DHCP_OPT_MaxMsgSize, 2, &clId, {UINT16_TO_BE_BYTES(maxSize)}}; DhcpOption msgType = {DHCP_OPT_MsgType, 1, &maxMsgSize, {DHCPREQUEST}}; - dhcp_send(&props, &msgType); + dhcp_send(s, &props, &msgType); } -static void dhcp_process(DhcpProps *props, DhcpOption *opts) { - ETHLIB_OS_MTX_LOCK(&s.procMtx); // LOCK! +static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) { + ETHLIB_OS_MTX_LOCK(&s->procMtx); // LOCK! - switch (s.state) { + switch (s->state) { case DHCP_INIT: - dhcp_discover(); // send discover message - s.state = DHCP_SELECTING; + dhcp_discover(s); // send discover message + s->state = DHCP_SELECTING; break; case DHCP_SELECTING: { const DhcpOption *msgType = dhcp_get_option(opts, DHCP_OPT_MsgType); @@ -268,10 +259,10 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) { ip4_addr serverAddr; FETCH_DWORD(&serverAddr, serverIdentifier->value); ip4_addr addrOffer = props->yiaddr; - dhcp_request(addrOffer, serverAddr); + dhcp_request(s, addrOffer, serverAddr); } - s.state = DHCP_REQUESTING; + s->state = DHCP_REQUESTING; } } break; @@ -282,16 +273,16 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) { //dhcp_discover(); //s.state = DHCP_SELECTING; } else if (msgType == DHCPACK) { - s.intf->ip = props->yiaddr; // fetch ip address + s->intf->ip = props->yiaddr; // fetch ip address opt = dhcp_get_option(opts, DHCP_OPT_Router); // get gateway/router address - FETCH_DWORD(&(s.intf->router), opt->value); + FETCH_DWORD(&(s->intf->router), opt->value); opt = dhcp_get_option(opts, DHCP_OPT_SubnetMask); // get subnet mask - FETCH_DWORD(&(s.intf->netmask), opt->value); + FETCH_DWORD(&(s->intf->netmask), opt->value); opt = dhcp_get_option(opts, DHCP_OPT_DomainNameServer); // get DNS - FETCH_DWORD(&(s.intf->dns), opt->value); + FETCH_DWORD(&(s->intf->dns), opt->value); opt = dhcp_get_option(opts, DHCP_OPT_IPAddrLeaseTime); // fetch Lease Time uint32_t dhcpLeaseTime_s; @@ -302,17 +293,20 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) { MSG("DHCP done!\n"); MSG("IP: "); - PRINT_IPv4(s.intf->ip); + PRINT_IPv4(s->intf->ip); MSG("\nRouter: "); - PRINT_IPv4(s.intf->router); + PRINT_IPv4(s->intf->router); MSG("\nNetmask: "); - PRINT_IPv4(s.intf->netmask); + PRINT_IPv4(s->intf->netmask); MSG("\nDNS: "); - PRINT_IPv4(s.intf->dns); + PRINT_IPv4(s->intf->dns); MSG("\nLease time: %u s\n", dhcpLeaseTime_s); MSG("\n"); - s.state = DHCP_BOUND; + s->state = DHCP_BOUND; + + // call event callback + ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE); } } break; @@ -320,7 +314,7 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) { break; } - ETHLIB_OS_MTX_UNLOCK(&s.procMtx); // RELEASE! + ETHLIB_OS_MTX_UNLOCK(&s->procMtx); // RELEASE! } static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) { @@ -328,22 +322,30 @@ static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) { DhcpOption *opts = NULL; dhcp_parse(pckt->payload, &props, &opts); - dhcp_process(&props, opts); + DhcpState * s = (DhcpState *) tag.p; + dhcp_process(s, &props, opts); dhcp_free_opt_chain(opts); return 0; } -void dhcp_start() { - s.state = DHCP_INIT; - dhcp_process(NULL, NULL); +void dhcp_start(DhcpState * s) { + s->state = DHCP_INIT; + dhcp_process(s, NULL, NULL); } void dhcp_initiate(EthInterface *intf) { - ETHLIB_OS_MTX_CREATE(&s.procMtx); - s.state = DHCP_INIT; - s.buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE); - s.desc = udp_new_connblock(intf, IPv4_ANY_ADDR, DHCP_CLIENT_PORT, dhcp_resp_cb); - s.intf = intf; + DhcpState * s = (DhcpState *) dynmem_alloc(sizeof(DhcpState)); + + ETHLIB_OS_MTX_CREATE(&s->procMtx); + s->state = DHCP_INIT; + s->buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE); + s->desc = udp_new_connblock(intf, IPv4_ANY_ADDR, DHCP_CLIENT_PORT, dhcp_resp_cb); + PcktSieveLayerTag tag; // store pointer to DHCP state into UDP connection block tag + tag.p = (void *)s; + cbdt_set_tag(E.cbdt, s->desc, tag); + s->intf = intf; + + intf->dhcp = s; } diff --git a/prefab/packet_parsers/dhcp.h b/prefab/packet_parsers/dhcp.h index 388957a..3ad965c 100644 --- a/prefab/packet_parsers/dhcp.h +++ b/prefab/packet_parsers/dhcp.h @@ -2,7 +2,9 @@ #define ETHERLIB_DHCP_H #include -#include "../../eth_interface.h" +//#include "../../eth_interface.h" +#include "etherlib/cbd_table.h" +#include "etherlib_options.h" typedef struct { uint8_t op; ///< Operations @@ -33,7 +35,7 @@ typedef enum { DHCP_REBINDING, DHCP_BOUND, DHCP_RENEWING -} DhcpState; +} DhcpFSMState; /** * DHCP id codes. @@ -47,15 +49,27 @@ typedef enum { #define DHCP_CLIENT_PORT (68) #define DHCP_SERVER_PORT (67) +struct EthInterface_; + +typedef struct { + DhcpFSMState state; ///< DHCP state machine state + void *buf; ///< Pointer to packet an allocated packet buffer + cbd desc; ///< UDP connection block descriptor + uint32_t tranId; ///< Transaction ID + struct EthInterface_ *intf; ///< Pointer to corresponding Ethernet interface + ETHLIB_OS_MTX_TYPE procMtx; ///< Mutex protecting the state machine +} DhcpState; + /** * Initiate DHCP on interface * @param intf interface */ -void dhcp_initiate(EthInterface * intf); +void dhcp_initiate(struct EthInterface_ * intf); /** - * + * Start DHCP operation. + * @param s pointer to DhcpState structure */ -void dhcp_start(); +void dhcp_start(DhcpState * s); #endif //ETHERLIB_DHCP_H diff --git a/timer.c b/timer.c index 52cc114..25c1170 100644 --- a/timer.c +++ b/timer.c @@ -26,6 +26,7 @@ Timer *timer_new(uint32_t maxSched) { Timer * tmr = (Timer *) dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment)); ASSERT_NULL(tmr); + ETHLIB_OS_MTX_CREATE(&tmr->tabMtx); tmr->maxSched = maxSched; tmr->nSched = 0; tmr->nextAlarm = NULL; @@ -87,6 +88,8 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse return TIMER_SCHED_FAILED; } + ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx)); + // if we can schedule get the first unused block AlarmAssignment * slot = timer_get_alarm_by_id(tmr, 0); @@ -106,6 +109,10 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse tmr->nextAlarm = slot; } + timer_report(tmr); + + ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx)); + return slot->id; } @@ -116,11 +123,15 @@ uint32_t timer_sched_rel(Timer * tmr, int64_t us, TimerAlarmCb cb, AlarmUserData } void timer_unsched(Timer * tmr, uint32_t id) { + ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx)); + AlarmAssignment * alarm = timer_get_alarm_by_id(tmr, id); if (alarm != NULL) { memset(alarm, 0, sizeof(AlarmAssignment)); tmr->nSched--; } + + ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx)); } void timer_set_time(Timer *tmr, const TimePoint *t) { @@ -146,11 +157,15 @@ void timer_tick(Timer * tmr, int64_t us) { if ((tmr->nSched > 0) && (tmr->nextAlarm != NULL)) { int64_t t_alarm = time_to_us(&(tmr->nextAlarm->time)); while (((t_alarm - t_us) <= 0) && (tmr->nSched > 0)) { - // invoke callback - if (tmr->nextAlarm->cb != NULL) { - tmr->nextAlarm->cb(tmr, tmr->nextAlarm->params); + if (ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx)) != 0) { + return; // break from the loop, since we cannot lock the mutex } + timer_report(tmr); + + // fetch alarm (obtain a COPY) + AlarmAssignment alarm = *(tmr->nextAlarm); + // clear alarm descriptor memset(tmr->nextAlarm, 0, sizeof(AlarmAssignment)); @@ -159,11 +174,20 @@ void timer_tick(Timer * tmr, int64_t us) { // update nearest alarm timer_update_nearest_alarm(tmr); + + ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx)); + + // invoke callback + if (alarm.cb != NULL) { + alarm.cb(tmr, alarm.params); + } + if (tmr->nextAlarm != NULL) { t_alarm = time_to_us(&(tmr->nextAlarm->time)); } } } + } void timer_report(const Timer * tmr) { diff --git a/timer.h b/timer.h index 7e25c93..4878dfc 100644 --- a/timer.h +++ b/timer.h @@ -4,6 +4,8 @@ #include #include +#include + /** * A single point in time */ @@ -61,6 +63,7 @@ typedef struct { * Timer class */ typedef struct Timer_ { + ETHLIB_OS_MTX_TYPE tabMtx; ///< Mutex protecting the scheduling table TimePoint time; ///< Absolute time AlarmAssignment * nextAlarm; ///< Nearest alarm uint32_t maxSched; ///< Maximum number of scheduled alarms diff --git a/utils.h b/utils.h index a13e77a..a83d15b 100644 --- a/utils.h +++ b/utils.h @@ -39,7 +39,7 @@ #define IPv4(a,b,c,d) ((a) | (b << 8) | (c << 16) | (d << 24)) #define PRINT_IPv4(ip) MSG("%u.%u.%u.%u", (ip & 0xFF), ((ip >> 8) & 0xFF), ((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)) -#define PRINT_HWADDR(hwaddr) MSG("%02x:%02x:%02x:%02x:%02x:%02x", (hwaddr)[0], (hwaddr)[1], (hwaddr)[2], (hwaddr)[3], (hwaddr)[4], (hwaddr)[5]); +#define PRINT_HWADDR(hwaddr) MSG("%02x:%02x:%02x:%02x:%02x:%02x", (hwaddr)[0], (hwaddr)[1], (hwaddr)[2], (hwaddr)[3], (hwaddr)[4], (hwaddr)[5]) #define ASSERT_BAD_ALIGN(p) if ((size_t)(p) & 0b11) ERROR("Bad memory alignment in function '%s' in file '%s' on line %d!\n", __func__, __FILE__, __LINE__) #define ASSERT_NULL(p) if ((p) == NULL) ERROR("NULL in function '%s' in file '%s' on line %d!\n", __func__, __FILE__, __LINE__)