From 0add1094303d338ad86d471cf9500b7740108909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiesner=20Andr=C3=A1s?= Date: Wed, 25 Oct 2023 17:41:36 +0200 Subject: [PATCH] implicit type conversions fixed --- connection_block.h | 5 + dynmem.c | 4 +- dynmem.h | 8 +- eth_interface.c | 21 ++-- packet.h | 12 ++- packet_registry.c | 4 +- packet_registry.h | 2 +- packet_sieve.c | 16 +-- packet_sieve.h | 2 +- prefab/conn_blocks/arp_connblock.c | 6 +- .../conn_blocks/custom_ethertype_connblock.c | 2 +- .../conn_blocks/custom_ethertype_connblock.h | 2 +- prefab/conn_blocks/icmp_connblock.c | 1 + prefab/packet_parsers/dhcp.c | 101 ++++++++++++------ prefab/packet_parsers/dhcp.h | 13 ++- prefab/packet_parsers/icmp_packet.c | 4 +- timer.c | 59 +++++----- 17 files changed, 171 insertions(+), 91 deletions(-) diff --git a/connection_block.h b/connection_block.h index d38c05b..2b9bc4c 100644 --- a/connection_block.h +++ b/connection_block.h @@ -15,6 +15,11 @@ typedef struct ConnBlock_ { PcktSieveLayer * sieveLayer; ///< Sieve layer } ConnBlock; +typedef struct ConstConnBlock_ { + const PcktSieve * sieve; ///< Ethernet interface + const PcktSieveLayer * sieveLayer; ///< Sieve layer +} ConstConnBlock; + /** * Initialize non-mandatory fields to default values. * @param connb diff --git a/dynmem.c b/dynmem.c index ef30511..eb6ba5d 100644 --- a/dynmem.c +++ b/dynmem.c @@ -17,6 +17,6 @@ void * dynmem_alloc_(uint32_t size) { return mp_alloc(E.mp, size); } -void dynmem_free_(void * ptr) { - mp_free(E.mp, ptr); +void dynmem_free_(const void * ptr) { + mp_free(E.mp, (const uint8_t *)ptr); } diff --git a/dynmem.h b/dynmem.h index 0ca62d3..1d9a726 100644 --- a/dynmem.h +++ b/dynmem.h @@ -1,5 +1,5 @@ -#ifndef ETHERLIB_DYNMEM_H -#define ETHERLIB_DYNMEM_H +#ifndef CORE_ETHERLIB_DYNMEM +#define CORE_ETHERLIB_DYNMEM #include @@ -37,7 +37,7 @@ void * dynmem_alloc_(uint32_t size); * Release allocated block. * @param ptr pointer to allocated area */ -void dynmem_free_(void * ptr); +void dynmem_free_(const void * ptr); #ifdef DYNMEM_DEBUG #define dynmem_free(ptr) MSG("FREE: %s() in %s:%d\n", __FUNCTION__, __FILE__, __LINE__), dynmem_free_(ptr) @@ -45,6 +45,6 @@ void dynmem_free_(void * ptr); #define dynmem_free(p) free(p) #else #define dynmem_free(ptr) dynmem_free_(ptr) -#endif +#endif /* CORE_ETHERLIB_DYNMEM */ #endif //ETHERLIB_DYNMEM_H diff --git a/eth_interface.c b/eth_interface.c index 8f85e16..ea24b42 100644 --- a/eth_interface.c +++ b/eth_interface.c @@ -19,7 +19,17 @@ static int ethintf_llrxnotify(EthIODef * io) { } static int ethinf_lllinkchg(EthIODef * io, int ls) { - ethinf_set_link_state((EthInterface *) io->tag, ls); + EthInterface * intf = (EthInterface *) io->tag; + ethinf_set_link_state(intf, ls); + + if (intf->dhcp != NULL) { + if (ls) { // if link is on + dhcp_start(intf->dhcp); + } else { // if link is off + dhcp_stop(intf->dhcp); + } + } + MSG("Link state: %d\n", ls); return 0; } @@ -32,7 +42,7 @@ static void ethintf_register(EthInterface * intf) { } // interface processing thread -static void * ethinf_proc_thread(void * param); +static void task_ethinf(const void * param); EthInterface *ethintf_new(EthIODef * io) { EthInterface * ethIntf = (EthInterface *)dynmem_alloc(sizeof(EthInterface)); @@ -49,8 +59,8 @@ EthInterface *ethintf_new(EthIODef * io) { ethIntf->txQ = mq_create(ETHLIB_DEF_MQ_SIZE); ethIntf->rxQ = mq_create(ETHLIB_DEF_MQ_SIZE); ETHLIB_OS_SEM_CREATE(ðIntf->rxSem, ETHLIB_DEF_MQ_SIZE); - ETHLIB_OS_THREAD_DEFINE(ethinf_proc_thread, ethrx, osPriorityHigh, 4096, ethIntf); - ETHLIB_OS_THREAD_CREATE(ethrx, ethIntf); + ETHLIB_OS_THREAD_DEFINE(task_ethinf, osPriorityHigh, 512, ethIntf); + ETHLIB_OS_THREAD_CREATE(task_ethinf, ethIntf); ethIntf->ipra = ipra_new(); @@ -65,7 +75,7 @@ EthInterface *ethintf_new(EthIODef * io) { return ethIntf; } -static void * ethinf_proc_thread(void * param) { +static void task_ethinf(const void * param) { EthInterface * intf = (EthInterface *) param; while (true) { ETHLIB_OS_SEM_WAIT(&intf->rxSem); @@ -76,7 +86,6 @@ static void * ethinf_proc_thread(void * param) { packsieve_input(&intf->sieve, &rawPckt); } } - return NULL; } void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt) { diff --git a/packet.h b/packet.h index 3b82765..accb2c6 100644 --- a/packet.h +++ b/packet.h @@ -34,10 +34,20 @@ typedef struct { uint64_t time_s; ///< Timestamp seconds part uint32_t time_ns; ///< Timestamp nanoseconds part. struct PcktHeaderElement_ * header; ///< Pointer to packet header. Points to the innermost header - uint8_t * payload; ///< Pointer to (innermost) payload. + const uint8_t * payload; ///< Pointer to (innermost) payload. uint16_t headerSize; ///< Packet header size in bytes. uint16_t payloadSize; ///< Payload size in bytes. //uint16_t type; ///< Packet class indicator (e.g. UDP, TCP, IPv4 etc.) } Pckt; +// typedef struct { +// uint64_t time_s; ///< Timestamp seconds part +// uint32_t time_ns; ///< Timestamp nanoseconds part. +// struct PcktHeaderElement_ * header; ///< Pointer to packet header. Points to the innermost header +// const uint8_t * payload; ///< Pointer to (innermost) payload. +// uint16_t headerSize; ///< Packet header size in bytes. +// uint16_t payloadSize; ///< Payload size in bytes. +// //uint16_t type; ///< Packet class indicator (e.g. UDP, TCP, IPv4 etc.) +// } ConstPckt; + #endif //ETHERLIB_PACKET_H diff --git a/packet_registry.c b/packet_registry.c index 0be4e11..4948414 100644 --- a/packet_registry.c +++ b/packet_registry.c @@ -41,10 +41,10 @@ void packreg_add_class(PcktRegistry * packReg, const PcktClassDesc * classDesc) packReg->entCnt++; } -PcktClassDesc * packreg_get_by_class(const PcktRegistry * packReg, uint16_t ownClass, uint16_t containerClass) { +PcktClassDesc * packreg_get_by_class(PcktRegistry * packReg, uint16_t ownClass, uint16_t containerClass) { uint32_t i; for (i = 0; i < packReg->entCnt; i++) { - const PcktClassDesc * cdesc = packReg->ents + i; + PcktClassDesc * cdesc = packReg->ents + i; if ((cdesc->class == ownClass) && ((cdesc->containerClass == containerClass) || (containerClass == 0))) { return cdesc; } diff --git a/packet_registry.h b/packet_registry.h index e889cb4..02d7100 100644 --- a/packet_registry.h +++ b/packet_registry.h @@ -113,7 +113,7 @@ void packreg_add_class(PcktRegistry *packReg, const PcktClassDesc *classDesc); * @param containerClass container packet's class (if 0, then search by container class is not considered) * @return pointer to descriptor on success or NULL on failure */ -PcktClassDesc *packreg_get_by_class(const PcktRegistry *packReg, uint16_t ownClass, uint16_t containerClass); +PcktClassDesc *packreg_get_by_class(PcktRegistry *packReg, uint16_t ownClass, uint16_t containerClass); diff --git a/packet_sieve.c b/packet_sieve.c index 491987e..b8d2f18 100644 --- a/packet_sieve.c +++ b/packet_sieve.c @@ -119,11 +119,11 @@ void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) { packet.time_ns = rawPckt->ext.rx.time_ns; // lookup headers in the sieve - const PcktHeaderElement *headerIter = outermostHeader; + PcktHeaderElement *headerIter = outermostHeader; PcktSieveLayer *layer = &sieve->layer0; // innermost matched sieve layer bool found = true; // first structure is always an Ethernet-frame while (found && headerIter) { - const PcktSieveLayer *nodeIter = layer->nodes; + PcktSieveLayer *nodeIter = layer->nodes; found = false; while (nodeIter && !found) { found |= nodeIter->matchAny || nodeIter->filtFn(&nodeIter->filtCond, &headerIter->props, &headerIter->next->props, sieve->intf); // specific or general match @@ -139,7 +139,7 @@ void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) { packet.payload = data + offset; packet.headerSize = offset; packet.payloadSize = size - offset; - int action = layer->cbFn(&packet, layer->tag); + int action = layer->cbFn((Pckt *)&packet, layer->tag); // FIXME! // execute special return action switch (action) { @@ -233,7 +233,7 @@ PcktSieveLayer* packsieve_new_layer(PcktSieveLayer *parent, const PcktSieveFilte } } -bool packsieve_remove_layer(PcktSieveLayer *layer) { +bool packsieve_remove_layer(const PcktSieveLayer *layer) { // avoid NULL-operations if (layer == NULL) { return true; @@ -271,8 +271,8 @@ bool packsieve_remove_layer(PcktSieveLayer *layer) { void packsieve_report(const PcktSieve *sieve, const PcktSieveLayer *layer, uint32_t indent) { if (layer->connBReportFn != NULL) { INFO("%*c└─┤", indent, ' '); - ConnBlock connBlock = { sieve, layer }; // tag not required - layer->connBReportFn(&connBlock); + ConstConnBlock connBlock = { sieve, layer }; // tag not required + layer->connBReportFn((const ConnBlock *)&connBlock); INFO("├───\n"); } else { INFO("%*c└─┤%d├───\n", indent, ' ', layer->packetClass); @@ -288,8 +288,8 @@ void packsieve_layer_info(const PcktSieve *sieve, const PcktSieveLayer *layer) { const PcktSieveLayer *iter = layer; while (iter != NULL) { // climb up to the top in the sieve tree if (iter->connBReportFn != NULL) { - ConnBlock connBlock = { sieve, iter }; // tag not required - iter->connBReportFn(&connBlock); + ConstConnBlock connBlock = { sieve, iter }; // tag not required + iter->connBReportFn((const ConnBlock *)&connBlock); } else { INFO("[%d]", layer->packetClass); } diff --git a/packet_sieve.h b/packet_sieve.h index 87998f3..6077062 100644 --- a/packet_sieve.h +++ b/packet_sieve.h @@ -138,7 +138,7 @@ PcktSieveLayer *packsieve_new_layer(PcktSieveLayer *parent, const PcktSieveFilte * Remove sieve layer from packet sieve. * @param layer Layer to remove and deallocate */ -bool packsieve_remove_layer(PcktSieveLayer *layer); +bool packsieve_remove_layer(const PcktSieveLayer *layer); /** * Recursively report layer structure on terminal. diff --git a/prefab/conn_blocks/arp_connblock.c b/prefab/conn_blocks/arp_connblock.c index ac4ce45..7052417 100644 --- a/prefab/conn_blocks/arp_connblock.c +++ b/prefab/conn_blocks/arp_connblock.c @@ -47,7 +47,11 @@ void arp_send(const ConnBlock * connBlock, const ArpProps * props) { // Ethernet ethProps->length_type = ETH_ARP_PACKET_CLASS; - memset(ethProps->destAddr, 0xFF, ETH_HW_ADDR_LEN); // broadcast destination + if (arpProps->OPER == ARPOP_REP) { // respond in unicast + memcpy(ethProps->destAddr, arpProps->THA, ETH_HW_ADDR_LEN); // unicast destination + } else if(arpProps->OPER == ARPOP_REQ) { // request in broadcast + memset(ethProps->destAddr, 0xFF, ETH_HW_ADDR_LEN); // broadcast destination + } memcpy(ethProps->sourceAddr, connBlock->sieve->intf->mac, ETH_HW_ADDR_LEN); // source // allocate transmit buffer diff --git a/prefab/conn_blocks/custom_ethertype_connblock.c b/prefab/conn_blocks/custom_ethertype_connblock.c index f2e6cd5..23c806d 100644 --- a/prefab/conn_blocks/custom_ethertype_connblock.c +++ b/prefab/conn_blocks/custom_ethertype_connblock.c @@ -43,7 +43,7 @@ int cet_send(cbd d, uint8_t *dest, const uint8_t *data, uint16_t size) { return cet_send_arg(d, dest, data, size, 0); } -int cet_send_arg(cbd d, uint8_t *dest, const uint8_t *data, uint16_t size, uint32_t arg) { +int cet_send_arg(cbd d, const uint8_t *dest, const uint8_t *data, uint16_t size, uint32_t arg) { ConnBlock connBlock; if (!cbdt_get_connection_block(E.cbdt, d, &connBlock)) { ERROR("Invalid CBD descriptor: '%d'!\n", d); diff --git a/prefab/conn_blocks/custom_ethertype_connblock.h b/prefab/conn_blocks/custom_ethertype_connblock.h index dd413cf..b04fe64 100644 --- a/prefab/conn_blocks/custom_ethertype_connblock.h +++ b/prefab/conn_blocks/custom_ethertype_connblock.h @@ -12,7 +12,7 @@ struct EthInterface_; cbd cet_new_connblock(struct EthInterface_ * intf, uint16_t etherType, SieveCallBackFn cbFn); -int cet_send_arg(cbd d, uint8_t *dest, const uint8_t *data, uint16_t size, uint32_t arg); +int cet_send_arg(cbd d, const uint8_t *dest, const uint8_t *data, uint16_t size, uint32_t arg); int cet_send(cbd d, EthernetAddress dest, const uint8_t * data, uint16_t size); diff --git a/prefab/conn_blocks/icmp_connblock.c b/prefab/conn_blocks/icmp_connblock.c index 92608d3..09596f4 100644 --- a/prefab/conn_blocks/icmp_connblock.c +++ b/prefab/conn_blocks/icmp_connblock.c @@ -53,6 +53,7 @@ static int icmp_recv_cb(const Pckt * pckt, PcktSieveLayerTag tag) { *txIcmpProps = *icmpProps; txIcmpProps->type = ICMP_MT_ECHO_REPLY; // replace request with reply txIcmpProps->hdrInsFn = insert_icmp_header; + txIcmpProps->checksum = 0; // swap source an destination IP addresses IPv4Props * iPv4Props = HEADER_FETCH_PROPS(IPv4Props, pckt->header->prev); diff --git a/prefab/packet_parsers/dhcp.c b/prefab/packet_parsers/dhcp.c index 9eb4475..9a089b0 100644 --- a/prefab/packet_parsers/dhcp.c +++ b/prefab/packet_parsers/dhcp.c @@ -2,13 +2,13 @@ // Created by epagris on 2022.12.09.. // -#include #include "dhcp.h" -#include "../../dynmem.h" -#include "../../utils.h" #include "../../connection_block.h" -#include "../conn_blocks/udp_connblock.h" +#include "../../dynmem.h" #include "../../global_state.h" +#include "../../utils.h" +#include "../conn_blocks/udp_connblock.h" +#include static const uint8_t DHCP_MAGIC_COOKIE[] = {99, 130, 83, 99}; @@ -47,9 +47,9 @@ typedef enum { // DHCP options typedef struct DhcpOption_ { - uint8_t id; ///< Options - uint8_t length; ///< Option data length - struct DhcpOption_ *next; /// next DHCP option + uint8_t id; ///< Options + uint8_t length; ///< Option data length + struct DhcpOption_ *next; /// next DHCP option uint8_t value[MAX_DHCP_OPTION_LENGTH]; ///< Option value } DhcpOption; @@ -115,9 +115,9 @@ static const DhcpOption *dhcp_get_option(const DhcpOption *opts, DhcpOptionId id return NULL; } -static void dhcp_send(DhcpState * s, 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)); @@ -141,9 +141,9 @@ static void dhcp_send(DhcpState * s, const DhcpProps *props, const DhcpOption *o iter = iter->next; } -// dhcp_option_insert_msg_type(&buf, DHCPDISCOVER); -// dhcp_option_insert_max_msg_size(&buf, 1500); -// dhcp_option_insert_end(&buf); + // dhcp_option_insert_msg_type(&buf, DHCPDISCOVER); + // dhcp_option_insert_max_msg_size(&buf, 1500); + // dhcp_option_insert_end(&buf); // send packet udp_sendto(s->desc, s->buf, DHCP_MIN_PACKET_SIZE, IPv4_ANY_ADDR, DHCP_SERVER_PORT); @@ -179,15 +179,14 @@ static void dhcp_parse(const uint8_t *buf, DhcpProps *props, DhcpOption **opts) dhcp_read_next_option(&buf, iter); iter->next = NULL; } - } -#define UINT16_TO_BE_BYTES(u) ((u) >> 8) & 0xFF, ((u) & 0xFF), -#define UINT32_TO_BE_BYTES(u) ((u) >> 24) & 0xFF, ((u) >> 16) & 0xFF, ((u) >> 8) & 0xFF, ((u) & 0xFF), -#define IPv4_ADDR_TO_BE_BYTES(addr) ((addr) & 0xFF), (((addr) >> 8) & 0xFF), (((addr) >> 16) & 0xFF), (((addr) >> 24) & 0xFF), +#define UINT16_TO_BE_BYTES(u) (uint8_t)((u) >> 8) & 0xFF, (uint8_t)((u) & 0xFF), +#define UINT32_TO_BE_BYTES(u) (uint8_t)((u) >> 24) & 0xFF, (uint8_t)((u) >> 16) & 0xFF, (uint8_t)((u) >> 8) & 0xFF, (uint8_t)((u) & 0xFF), +#define IPv4_ADDR_TO_BE_BYTES(addr) (uint8_t)((addr) & 0xFF), (uint8_t)(((addr) >> 8) & 0xFF), (uint8_t)(((addr) >> 16) & 0xFF), (uint8_t)(((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(DhcpState * s) { +static void dhcp_discover(DhcpState *s) { s->tranId = rand(); DhcpProps props = {0}; @@ -213,7 +212,7 @@ static void dhcp_discover(DhcpState * s) { dhcp_send(s, &props, &msgType); } -void dhcp_request(DhcpState * s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) { +void dhcp_request(DhcpState *s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) { DhcpProps props = {0}; props.op = DHCP_BOOTREQUEST; @@ -243,18 +242,31 @@ void dhcp_request(DhcpState * s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) { dhcp_send(s, &props, &msgType); } -static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) { +static void dhcp_retry_discover(struct Timer_ *timer, AlarmUserData user) { + DhcpState *s = (DhcpState *)user.ptr; + if (s->state != DHCP_BOUND) { // only retransmit DISCOVER if not BOUND + dhcp_start(s); + } + s->retryAlarmId = 0; // clear schedule ID +} + +static void dhcp_process(DhcpState *s, DhcpProps *props, DhcpOption *opts) { ETHLIB_OS_MTX_LOCK(&s->procMtx); // LOCK! switch (s->state) { - case DHCP_INIT: + case DHCP_INIT: { dhcp_discover(s); // send discover message s->state = DHCP_SELECTING; - break; + + // schedule the DHCP discovery retry + AlarmUserData params; + params.ptr = (void *)s; + s->retryAlarmId = timer_sched_rel(E.tmr, ((int64_t)DHCP_RETRY_TIMEOUT_S) * 1000000, dhcp_retry_discover, params); + } break; case DHCP_SELECTING: { const DhcpOption *msgType = dhcp_get_option(opts, DHCP_OPT_MsgType); if (msgType->value[0] == DHCPOFFER) { - const DhcpOption * serverIdentifier = dhcp_get_option(opts, DHCP_OPT_ServerId); + const DhcpOption *serverIdentifier = dhcp_get_option(opts, DHCP_OPT_ServerId); if (serverIdentifier != NULL) { ip4_addr serverAddr; FETCH_DWORD(&serverAddr, serverIdentifier->value); @@ -264,14 +276,13 @@ static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) { s->state = DHCP_REQUESTING; } - } - break; + } break; case DHCP_REQUESTING: { const DhcpOption *opt = dhcp_get_option(opts, DHCP_OPT_MsgType); uint8_t msgType = opt->value[0]; if (msgType == DHCPNAK) { - //dhcp_discover(); - //s.state = DHCP_SELECTING; + // dhcp_discover(); + // s.state = DHCP_SELECTING; } else if (msgType == DHCPACK) { s->intf->ip = props->yiaddr; // fetch ip address @@ -289,7 +300,7 @@ static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) { FETCH_DWORD_H2N(&dhcpLeaseTime_s, opt->value); AlarmUserData params = {0}; - timer_sched_rel(E.tmr, ((int64_t) dhcpLeaseTime_s) * 1000000, NULL, params); + s->renewAlarmId = timer_sched_rel(E.tmr, ((int64_t)dhcpLeaseTime_s) * 1000000, NULL, params); MSG("DHCP done!\n"); MSG("IP: "); @@ -308,8 +319,7 @@ static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) { // call event callback ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE); } - } - break; + } break; default: break; } @@ -322,7 +332,7 @@ static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) { DhcpOption *opts = NULL; dhcp_parse(pckt->payload, &props, &opts); - DhcpState * s = (DhcpState *) tag.p; + DhcpState *s = (DhcpState *)tag.p; dhcp_process(s, &props, opts); dhcp_free_opt_chain(opts); @@ -330,22 +340,47 @@ static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) { return 0; } -void dhcp_start(DhcpState * s) { +void dhcp_start(DhcpState *s) { s->state = DHCP_INIT; dhcp_process(s, NULL, NULL); } +void dhcp_stop(DhcpState *s) { + s->state = DHCP_STOPPED; + if (s->renewAlarmId != 0) { // unschedule renew alarm + timer_unsched(E.tmr, s->renewAlarmId); + s->renewAlarmId = 0; + } + + if (s->retryAlarmId != 0) { // unschedule discovery retry alarm + timer_unsched(E.tmr, s->retryAlarmId); + s->retryAlarmId = 0; + } + + // if it was an IP assigned to the interface, then clear that too + if (s->intf->ip != 0) { + s->intf->ip = 0; + s->intf->dns = 0; + s->intf->netmask = 0; + s->intf->router = 0; + ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE); + } + + ETHLIB_OS_MTX_UNLOCK(&s->procMtx); +} + void dhcp_initiate(EthInterface *intf) { - DhcpState * s = (DhcpState *) dynmem_alloc(sizeof(DhcpState)); + DhcpState *s = (DhcpState *)dynmem_alloc(sizeof(DhcpState)); ETHLIB_OS_MTX_CREATE(&s->procMtx); - s->state = DHCP_INIT; + s->state = DHCP_STOPPED; 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; + s->renewAlarmId = 0; intf->dhcp = s; } diff --git a/prefab/packet_parsers/dhcp.h b/prefab/packet_parsers/dhcp.h index 3ad965c..b2f8c87 100644 --- a/prefab/packet_parsers/dhcp.h +++ b/prefab/packet_parsers/dhcp.h @@ -34,7 +34,8 @@ typedef enum { DHCP_SELECTING, DHCP_REBINDING, DHCP_BOUND, - DHCP_RENEWING + DHCP_RENEWING, + DHCP_STOPPED, } DhcpFSMState; /** @@ -58,8 +59,12 @@ typedef struct { uint32_t tranId; ///< Transaction ID struct EthInterface_ *intf; ///< Pointer to corresponding Ethernet interface ETHLIB_OS_MTX_TYPE procMtx; ///< Mutex protecting the state machine + uint32_t renewAlarmId; ///< IP renew alarm ID (valid if nonzero) + uint32_t retryAlarmId; ///< DISCOVER retry alarm ID (valid if nonzero) } DhcpState; +#define DHCP_RETRY_TIMEOUT_S (3) + /** * Initiate DHCP on interface * @param intf interface @@ -72,4 +77,10 @@ void dhcp_initiate(struct EthInterface_ * intf); */ void dhcp_start(DhcpState * s); +/** + * Stop DHCP operation. + * @param s pointer to DhcpState structure + */ +void dhcp_stop(DhcpState * s); + #endif //ETHERLIB_DHCP_H diff --git a/prefab/packet_parsers/icmp_packet.c b/prefab/packet_parsers/icmp_packet.c index 0c3b789..728e6c7 100644 --- a/prefab/packet_parsers/icmp_packet.c +++ b/prefab/packet_parsers/icmp_packet.c @@ -37,9 +37,9 @@ void insert_icmp_header(uint8_t *hdr, const PcktHeaderElement *headers, struct E FILL_ADVANCE(hdr, &icmpProps->identifier, 2); FILL_ADVANCE(hdr, &icmpProps->sequenceNumber, 2); - IPv4Props * ipProps = HEADER_FETCH_PROPS(IPv4Props, headers->prev); + /*IPv4Props * ipProps = HEADER_FETCH_PROPS(IPv4Props, headers->prev); icmpProps->checksum = chksum(hdrStart, ipProps->TotalLength - ETH_IPv4_HEADER_SIZE, false); - FILL_WORD_ADVANCE(ChkSumPtr, icmpProps->checksum); + FILL_WORD_ADVANCE(ChkSumPtr, icmpProps->checksum);*/ } diff --git a/timer.c b/timer.c index 25c1170..5caef61 100644 --- a/timer.c +++ b/timer.c @@ -2,28 +2,30 @@ // Created by epagris on 2022.12.21.. // -#include #include "timer.h" #include "dynmem.h" #include "utils.h" +#include -int64_t time_to_us(const TimePoint * t) { +// FIXME nagyon bugos vagyok! Help me! :) + +int64_t time_to_us(const TimePoint *t) { return (int64_t)t->s * 1000000 + (int64_t)t->us; } -void time_from_us(TimePoint * t, int64_t us) { +void time_from_us(TimePoint *t, int64_t us) { t->s = us / 1000000; t->us = us - ((int64_t)t->s * 1000000); } -void time_add_us(TimePoint * t, int64_t us) { +void time_add_us(TimePoint *t, int64_t us) { time_from_us(t, time_to_us(t) + us); } // ------------------------------ Timer *timer_new(uint32_t maxSched) { - Timer * tmr = (Timer *) dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment)); + Timer *tmr = (Timer *)dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment)); ASSERT_NULL(tmr); ETHLIB_OS_MTX_CREATE(&tmr->tabMtx); @@ -37,26 +39,27 @@ Timer *timer_new(uint32_t maxSched) { return tmr; } -static AlarmAssignment * timer_get_alarm_by_id(Timer * tmr, uint32_t id) { - AlarmAssignment * slot = NULL; - for (uint32_t i = 0; (i < tmr->maxSched) && (slot == NULL); i++) { +static AlarmAssignment *timer_get_alarm_by_id(Timer *tmr, uint32_t id) { + AlarmAssignment *slot = NULL; + for (uint32_t i = 0; i < tmr->maxSched; i++) { if (tmr->alarms[i].id == id) { slot = (tmr->alarms) + i; + break; } } return slot; } -static uint32_t timer_generate_id(Timer * tmr) { +static uint32_t timer_generate_id(Timer *tmr) { uint32_t newId = 0; do { - newId = ((uint32_t) rand()) | 0x01; // ID cannot be 0 + newId = ((uint32_t)rand()) | 0x01; // ID cannot be 0 } while (timer_get_alarm_by_id(tmr, newId) != NULL); return newId; } -static void timer_update_nearest_alarm(Timer * tmr) { +static void timer_update_nearest_alarm(Timer *tmr) { if (tmr->nSched == 0) { tmr->nextAlarm = NULL; return; @@ -65,7 +68,7 @@ static void timer_update_nearest_alarm(Timer * tmr) { int64_t t_c_us = time_to_us(&tmr->time); int64_t min_delta_t_us = 0; - AlarmAssignment * nearest = NULL; + AlarmAssignment *nearest = NULL; for (uint32_t i = 0; i < tmr->maxSched; i++) { int64_t t_i_us = time_to_us(&(tmr->alarms[i].time)); if ((nearest == NULL) && (tmr->alarms[i].id != 0)) { @@ -83,7 +86,7 @@ static void timer_update_nearest_alarm(Timer * tmr) { tmr->nextAlarm = nearest; } -uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUserData params) { +uint32_t timer_sched(Timer *tmr, const TimePoint *t, TimerAlarmCb cb, AlarmUserData params) { if (tmr->nSched == tmr->maxSched) { // if cannot schedule more alarm return TIMER_SCHED_FAILED; } @@ -91,7 +94,7 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx)); // if we can schedule get the first unused block - AlarmAssignment * slot = timer_get_alarm_by_id(tmr, 0); + AlarmAssignment *slot = timer_get_alarm_by_id(tmr, 0); // allocate on the first free slot slot->id = timer_generate_id(tmr); @@ -109,26 +112,29 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse tmr->nextAlarm = slot; } - timer_report(tmr); + //timer_report(tmr); ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx)); return slot->id; } -uint32_t timer_sched_rel(Timer * tmr, int64_t us, TimerAlarmCb cb, AlarmUserData params) { +uint32_t timer_sched_rel(Timer *tmr, int64_t us, TimerAlarmCb cb, AlarmUserData params) { TimePoint t = tmr->time; time_add_us(&t, us); return timer_sched(tmr, &t, cb, params); } -void timer_unsched(Timer * tmr, uint32_t id) { +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--; + if (tmr->nSched > 0) { + AlarmAssignment *alarm = timer_get_alarm_by_id(tmr, id); + if (alarm != NULL) { + memset(alarm, 0, sizeof(AlarmAssignment)); + tmr->nSched--; + timer_update_nearest_alarm(tmr); + } } ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx)); @@ -138,15 +144,15 @@ void timer_set_time(Timer *tmr, const TimePoint *t) { tmr->time = *t; } -int64_t timer_get_time_us(const Timer * tmr) { +int64_t timer_get_time_us(const Timer *tmr) { return time_to_us(&tmr->time); } -TimePoint timer_get_time(const Timer * tmr) { +TimePoint timer_get_time(const Timer *tmr) { return tmr->time; } -void timer_tick(Timer * tmr, int64_t us) { +void timer_tick(Timer *tmr, int64_t us) { // advance time time_add_us(&tmr->time, us); /*t_us += us; @@ -161,7 +167,7 @@ void timer_tick(Timer * tmr, int64_t us) { return; // break from the loop, since we cannot lock the mutex } - timer_report(tmr); + //timer_report(tmr); // fetch alarm (obtain a COPY) AlarmAssignment alarm = *(tmr->nextAlarm); @@ -187,10 +193,9 @@ void timer_tick(Timer * tmr, int64_t us) { } } } - } -void timer_report(const Timer * tmr) { +void timer_report(const Timer *tmr) { MSG("Time: %u.%06u\n\n", tmr->time.s, tmr->time.us); int64_t t_c_us = timer_get_time_us(tmr);