implicit type conversions fixed

This commit is contained in:
Wiesner András 2023-10-25 17:41:36 +02:00
parent e4d27454cd
commit 0add109430
17 changed files with 171 additions and 91 deletions

View File

@ -15,6 +15,11 @@ typedef struct ConnBlock_ {
PcktSieveLayer * sieveLayer; ///< Sieve layer PcktSieveLayer * sieveLayer; ///< Sieve layer
} ConnBlock; } ConnBlock;
typedef struct ConstConnBlock_ {
const PcktSieve * sieve; ///< Ethernet interface
const PcktSieveLayer * sieveLayer; ///< Sieve layer
} ConstConnBlock;
/** /**
* Initialize non-mandatory fields to default values. * Initialize non-mandatory fields to default values.
* @param connb * @param connb

View File

@ -17,6 +17,6 @@ void * dynmem_alloc_(uint32_t size) {
return mp_alloc(E.mp, size); return mp_alloc(E.mp, size);
} }
void dynmem_free_(void * ptr) { void dynmem_free_(const void * ptr) {
mp_free(E.mp, ptr); mp_free(E.mp, (const uint8_t *)ptr);
} }

View File

@ -1,5 +1,5 @@
#ifndef ETHERLIB_DYNMEM_H #ifndef CORE_ETHERLIB_DYNMEM
#define ETHERLIB_DYNMEM_H #define CORE_ETHERLIB_DYNMEM
#include <stdint.h> #include <stdint.h>
@ -37,7 +37,7 @@ void * dynmem_alloc_(uint32_t size);
* Release allocated block. * Release allocated block.
* @param ptr pointer to allocated area * @param ptr pointer to allocated area
*/ */
void dynmem_free_(void * ptr); void dynmem_free_(const void * ptr);
#ifdef DYNMEM_DEBUG #ifdef DYNMEM_DEBUG
#define dynmem_free(ptr) MSG("FREE: %s() in %s:%d\n", __FUNCTION__, __FILE__, __LINE__), dynmem_free_(ptr) #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) #define dynmem_free(p) free(p)
#else #else
#define dynmem_free(ptr) dynmem_free_(ptr) #define dynmem_free(ptr) dynmem_free_(ptr)
#endif #endif /* CORE_ETHERLIB_DYNMEM */
#endif //ETHERLIB_DYNMEM_H #endif //ETHERLIB_DYNMEM_H

View File

@ -19,7 +19,17 @@ static int ethintf_llrxnotify(EthIODef * io) {
} }
static int ethinf_lllinkchg(EthIODef * io, int ls) { 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); MSG("Link state: %d\n", ls);
return 0; return 0;
} }
@ -32,7 +42,7 @@ static void ethintf_register(EthInterface * intf) {
} }
// interface processing thread // interface processing thread
static void * ethinf_proc_thread(void * param); static void task_ethinf(const void * param);
EthInterface *ethintf_new(EthIODef * io) { EthInterface *ethintf_new(EthIODef * io) {
EthInterface * ethIntf = (EthInterface *)dynmem_alloc(sizeof(EthInterface)); 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->txQ = mq_create(ETHLIB_DEF_MQ_SIZE);
ethIntf->rxQ = mq_create(ETHLIB_DEF_MQ_SIZE); ethIntf->rxQ = mq_create(ETHLIB_DEF_MQ_SIZE);
ETHLIB_OS_SEM_CREATE(&ethIntf->rxSem, ETHLIB_DEF_MQ_SIZE); ETHLIB_OS_SEM_CREATE(&ethIntf->rxSem, ETHLIB_DEF_MQ_SIZE);
ETHLIB_OS_THREAD_DEFINE(ethinf_proc_thread, ethrx, osPriorityHigh, 4096, ethIntf); ETHLIB_OS_THREAD_DEFINE(task_ethinf, osPriorityHigh, 512, ethIntf);
ETHLIB_OS_THREAD_CREATE(ethrx, ethIntf); ETHLIB_OS_THREAD_CREATE(task_ethinf, ethIntf);
ethIntf->ipra = ipra_new(); ethIntf->ipra = ipra_new();
@ -65,7 +75,7 @@ EthInterface *ethintf_new(EthIODef * io) {
return ethIntf; return ethIntf;
} }
static void * ethinf_proc_thread(void * param) { static void task_ethinf(const void * param) {
EthInterface * intf = (EthInterface *) param; EthInterface * intf = (EthInterface *) param;
while (true) { while (true) {
ETHLIB_OS_SEM_WAIT(&intf->rxSem); ETHLIB_OS_SEM_WAIT(&intf->rxSem);
@ -76,7 +86,6 @@ static void * ethinf_proc_thread(void * param) {
packsieve_input(&intf->sieve, &rawPckt); packsieve_input(&intf->sieve, &rawPckt);
} }
} }
return NULL;
} }
void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt) { void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt) {

View File

@ -34,10 +34,20 @@ typedef struct {
uint64_t time_s; ///< Timestamp seconds part uint64_t time_s; ///< Timestamp seconds part
uint32_t time_ns; ///< Timestamp nanoseconds part. uint32_t time_ns; ///< Timestamp nanoseconds part.
struct PcktHeaderElement_ * header; ///< Pointer to packet header. Points to the innermost header 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 headerSize; ///< Packet header size in bytes.
uint16_t payloadSize; ///< Payload size in bytes. uint16_t payloadSize; ///< Payload size in bytes.
//uint16_t type; ///< Packet class indicator (e.g. UDP, TCP, IPv4 etc.) //uint16_t type; ///< Packet class indicator (e.g. UDP, TCP, IPv4 etc.)
} Pckt; } 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 #endif //ETHERLIB_PACKET_H

View File

@ -41,10 +41,10 @@ void packreg_add_class(PcktRegistry * packReg, const PcktClassDesc * classDesc)
packReg->entCnt++; 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; uint32_t i;
for (i = 0; i < packReg->entCnt; 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))) { if ((cdesc->class == ownClass) && ((cdesc->containerClass == containerClass) || (containerClass == 0))) {
return cdesc; return cdesc;
} }

View File

@ -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) * @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 * @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);

View File

@ -119,11 +119,11 @@ void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) {
packet.time_ns = rawPckt->ext.rx.time_ns; packet.time_ns = rawPckt->ext.rx.time_ns;
// lookup headers in the sieve // lookup headers in the sieve
const PcktHeaderElement *headerIter = outermostHeader; PcktHeaderElement *headerIter = outermostHeader;
PcktSieveLayer *layer = &sieve->layer0; // innermost matched sieve layer PcktSieveLayer *layer = &sieve->layer0; // innermost matched sieve layer
bool found = true; // first structure is always an Ethernet-frame bool found = true; // first structure is always an Ethernet-frame
while (found && headerIter) { while (found && headerIter) {
const PcktSieveLayer *nodeIter = layer->nodes; PcktSieveLayer *nodeIter = layer->nodes;
found = false; found = false;
while (nodeIter && !found) { while (nodeIter && !found) {
found |= nodeIter->matchAny || nodeIter->filtFn(&nodeIter->filtCond, &headerIter->props, &headerIter->next->props, sieve->intf); // specific or general match 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.payload = data + offset;
packet.headerSize = offset; packet.headerSize = offset;
packet.payloadSize = size - 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 // execute special return action
switch (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 // avoid NULL-operations
if (layer == NULL) { if (layer == NULL) {
return true; return true;
@ -271,8 +271,8 @@ bool packsieve_remove_layer(PcktSieveLayer *layer) {
void packsieve_report(const PcktSieve *sieve, const PcktSieveLayer *layer, uint32_t indent) { void packsieve_report(const PcktSieve *sieve, const PcktSieveLayer *layer, uint32_t indent) {
if (layer->connBReportFn != NULL) { if (layer->connBReportFn != NULL) {
INFO("%*c└─┤", indent, ' '); INFO("%*c└─┤", indent, ' ');
ConnBlock connBlock = { sieve, layer }; // tag not required ConstConnBlock connBlock = { sieve, layer }; // tag not required
layer->connBReportFn(&connBlock); layer->connBReportFn((const ConnBlock *)&connBlock);
INFO("├───\n"); INFO("├───\n");
} else { } else {
INFO("%*c└─┤%d├───\n", indent, ' ', layer->packetClass); 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; const PcktSieveLayer *iter = layer;
while (iter != NULL) { // climb up to the top in the sieve tree while (iter != NULL) { // climb up to the top in the sieve tree
if (iter->connBReportFn != NULL) { if (iter->connBReportFn != NULL) {
ConnBlock connBlock = { sieve, iter }; // tag not required ConstConnBlock connBlock = { sieve, iter }; // tag not required
iter->connBReportFn(&connBlock); iter->connBReportFn((const ConnBlock *)&connBlock);
} else { } else {
INFO("[%d]", layer->packetClass); INFO("[%d]", layer->packetClass);
} }

View File

@ -138,7 +138,7 @@ PcktSieveLayer *packsieve_new_layer(PcktSieveLayer *parent, const PcktSieveFilte
* Remove sieve layer from packet sieve. * Remove sieve layer from packet sieve.
* @param layer Layer to remove and deallocate * @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. * Recursively report layer structure on terminal.

View File

@ -47,7 +47,11 @@ void arp_send(const ConnBlock * connBlock, const ArpProps * props) {
// Ethernet // Ethernet
ethProps->length_type = ETH_ARP_PACKET_CLASS; 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 memcpy(ethProps->sourceAddr, connBlock->sieve->intf->mac, ETH_HW_ADDR_LEN); // source
// allocate transmit buffer // allocate transmit buffer

View File

@ -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); 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; ConnBlock connBlock;
if (!cbdt_get_connection_block(E.cbdt, d, &connBlock)) { if (!cbdt_get_connection_block(E.cbdt, d, &connBlock)) {
ERROR("Invalid CBD descriptor: '%d'!\n", d); ERROR("Invalid CBD descriptor: '%d'!\n", d);

View File

@ -12,7 +12,7 @@ struct EthInterface_;
cbd cet_new_connblock(struct EthInterface_ * intf, uint16_t etherType, SieveCallBackFn cbFn); 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); int cet_send(cbd d, EthernetAddress dest, const uint8_t * data, uint16_t size);

View File

@ -53,6 +53,7 @@ static int icmp_recv_cb(const Pckt * pckt, PcktSieveLayerTag tag) {
*txIcmpProps = *icmpProps; *txIcmpProps = *icmpProps;
txIcmpProps->type = ICMP_MT_ECHO_REPLY; // replace request with reply txIcmpProps->type = ICMP_MT_ECHO_REPLY; // replace request with reply
txIcmpProps->hdrInsFn = insert_icmp_header; txIcmpProps->hdrInsFn = insert_icmp_header;
txIcmpProps->checksum = 0;
// swap source an destination IP addresses // swap source an destination IP addresses
IPv4Props * iPv4Props = HEADER_FETCH_PROPS(IPv4Props, pckt->header->prev); IPv4Props * iPv4Props = HEADER_FETCH_PROPS(IPv4Props, pckt->header->prev);

View File

@ -2,13 +2,13 @@
// Created by epagris on 2022.12.09.. // Created by epagris on 2022.12.09..
// //
#include <stdlib.h>
#include "dhcp.h" #include "dhcp.h"
#include "../../dynmem.h"
#include "../../utils.h"
#include "../../connection_block.h" #include "../../connection_block.h"
#include "../conn_blocks/udp_connblock.h" #include "../../dynmem.h"
#include "../../global_state.h" #include "../../global_state.h"
#include "../../utils.h"
#include "../conn_blocks/udp_connblock.h"
#include <stdlib.h>
static const uint8_t DHCP_MAGIC_COOKIE[] = {99, 130, 83, 99}; static const uint8_t DHCP_MAGIC_COOKIE[] = {99, 130, 83, 99};
@ -47,9 +47,9 @@ typedef enum {
// DHCP options // DHCP options
typedef struct DhcpOption_ { typedef struct DhcpOption_ {
uint8_t id; ///< Options uint8_t id; ///< Options
uint8_t length; ///< Option data length uint8_t length; ///< Option data length
struct DhcpOption_ *next; /// next DHCP option struct DhcpOption_ *next; /// next DHCP option
uint8_t value[MAX_DHCP_OPTION_LENGTH]; ///< Option value uint8_t value[MAX_DHCP_OPTION_LENGTH]; ///< Option value
} DhcpOption; } DhcpOption;
@ -115,9 +115,9 @@ static const DhcpOption *dhcp_get_option(const DhcpOption *opts, DhcpOptionId id
return NULL; 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 // construct body
uint8_t *buf = (uint8_t *) s->buf; uint8_t *buf = (uint8_t *)s->buf;
memset(buf, 0, DHCP_MIN_PACKET_SIZE); memset(buf, 0, DHCP_MIN_PACKET_SIZE);
FILL_BYTE_ADVANCE(buf, &(props->op)); FILL_BYTE_ADVANCE(buf, &(props->op));
FILL_BYTE_ADVANCE(buf, &(props->htype)); 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; iter = iter->next;
} }
// dhcp_option_insert_msg_type(&buf, DHCPDISCOVER); // dhcp_option_insert_msg_type(&buf, DHCPDISCOVER);
// dhcp_option_insert_max_msg_size(&buf, 1500); // dhcp_option_insert_max_msg_size(&buf, 1500);
// dhcp_option_insert_end(&buf); // dhcp_option_insert_end(&buf);
// send packet // 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);
@ -179,15 +179,14 @@ static void dhcp_parse(const uint8_t *buf, DhcpProps *props, DhcpOption **opts)
dhcp_read_next_option(&buf, iter); dhcp_read_next_option(&buf, iter);
iter->next = NULL; iter->next = NULL;
} }
} }
#define UINT16_TO_BE_BYTES(u) ((u) >> 8) & 0xFF, ((u) & 0xFF), #define UINT16_TO_BE_BYTES(u) (uint8_t)((u) >> 8) & 0xFF, (uint8_t)((u) & 0xFF),
#define UINT32_TO_BE_BYTES(u) ((u) >> 24) & 0xFF, ((u) >> 16) & 0xFF, ((u) >> 8) & 0xFF, ((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) ((addr) & 0xFF), (((addr) >> 8) & 0xFF), (((addr) >> 16) & 0xFF), (((addr) >> 24) & 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], #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(); s->tranId = rand();
DhcpProps props = {0}; DhcpProps props = {0};
@ -213,7 +212,7 @@ static void dhcp_discover(DhcpState * s) {
dhcp_send(s, &props, &msgType); 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}; DhcpProps props = {0};
props.op = DHCP_BOOTREQUEST; props.op = DHCP_BOOTREQUEST;
@ -243,18 +242,31 @@ void dhcp_request(DhcpState * s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
dhcp_send(s, &props, &msgType); 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! ETHLIB_OS_MTX_LOCK(&s->procMtx); // LOCK!
switch (s->state) { switch (s->state) {
case DHCP_INIT: case DHCP_INIT: {
dhcp_discover(s); // send discover message dhcp_discover(s); // send discover message
s->state = DHCP_SELECTING; 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: { case DHCP_SELECTING: {
const DhcpOption *msgType = dhcp_get_option(opts, DHCP_OPT_MsgType); const DhcpOption *msgType = dhcp_get_option(opts, DHCP_OPT_MsgType);
if (msgType->value[0] == DHCPOFFER) { 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) { if (serverIdentifier != NULL) {
ip4_addr serverAddr; ip4_addr serverAddr;
FETCH_DWORD(&serverAddr, serverIdentifier->value); FETCH_DWORD(&serverAddr, serverIdentifier->value);
@ -264,14 +276,13 @@ static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) {
s->state = DHCP_REQUESTING; s->state = DHCP_REQUESTING;
} }
} } break;
break;
case DHCP_REQUESTING: { case DHCP_REQUESTING: {
const DhcpOption *opt = dhcp_get_option(opts, DHCP_OPT_MsgType); const DhcpOption *opt = dhcp_get_option(opts, DHCP_OPT_MsgType);
uint8_t msgType = opt->value[0]; uint8_t msgType = opt->value[0];
if (msgType == DHCPNAK) { if (msgType == DHCPNAK) {
//dhcp_discover(); // dhcp_discover();
//s.state = DHCP_SELECTING; // s.state = DHCP_SELECTING;
} else if (msgType == DHCPACK) { } else if (msgType == DHCPACK) {
s->intf->ip = props->yiaddr; // fetch ip address 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); FETCH_DWORD_H2N(&dhcpLeaseTime_s, opt->value);
AlarmUserData params = {0}; 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("DHCP done!\n");
MSG("IP: "); MSG("IP: ");
@ -308,8 +319,7 @@ static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) {
// call event callback // call event callback
ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE); ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE);
} }
} } break;
break;
default: default:
break; break;
} }
@ -322,7 +332,7 @@ static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
DhcpOption *opts = NULL; DhcpOption *opts = NULL;
dhcp_parse(pckt->payload, &props, &opts); dhcp_parse(pckt->payload, &props, &opts);
DhcpState * s = (DhcpState *) tag.p; DhcpState *s = (DhcpState *)tag.p;
dhcp_process(s, &props, opts); dhcp_process(s, &props, opts);
dhcp_free_opt_chain(opts); dhcp_free_opt_chain(opts);
@ -330,22 +340,47 @@ static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
return 0; return 0;
} }
void dhcp_start(DhcpState * s) { void dhcp_start(DhcpState *s) {
s->state = DHCP_INIT; s->state = DHCP_INIT;
dhcp_process(s, NULL, NULL); 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) { 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); ETHLIB_OS_MTX_CREATE(&s->procMtx);
s->state = DHCP_INIT; s->state = DHCP_STOPPED;
s->buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE); s->buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE);
s->desc = udp_new_connblock(intf, IPv4_ANY_ADDR, DHCP_CLIENT_PORT, dhcp_resp_cb); 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 PcktSieveLayerTag tag; // store pointer to DHCP state into UDP connection block tag
tag.p = (void *)s; tag.p = (void *)s;
cbdt_set_tag(E.cbdt, s->desc, tag); cbdt_set_tag(E.cbdt, s->desc, tag);
s->intf = intf; s->intf = intf;
s->renewAlarmId = 0;
intf->dhcp = s; intf->dhcp = s;
} }

View File

@ -34,7 +34,8 @@ typedef enum {
DHCP_SELECTING, DHCP_SELECTING,
DHCP_REBINDING, DHCP_REBINDING,
DHCP_BOUND, DHCP_BOUND,
DHCP_RENEWING DHCP_RENEWING,
DHCP_STOPPED,
} DhcpFSMState; } DhcpFSMState;
/** /**
@ -58,8 +59,12 @@ typedef struct {
uint32_t tranId; ///< Transaction ID uint32_t tranId; ///< Transaction ID
struct EthInterface_ *intf; ///< Pointer to corresponding Ethernet interface struct EthInterface_ *intf; ///< Pointer to corresponding Ethernet interface
ETHLIB_OS_MTX_TYPE procMtx; ///< Mutex protecting the state machine 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; } DhcpState;
#define DHCP_RETRY_TIMEOUT_S (3)
/** /**
* Initiate DHCP on interface * Initiate DHCP on interface
* @param intf interface * @param intf interface
@ -72,4 +77,10 @@ void dhcp_initiate(struct EthInterface_ * intf);
*/ */
void dhcp_start(DhcpState * s); void dhcp_start(DhcpState * s);
/**
* Stop DHCP operation.
* @param s pointer to DhcpState structure
*/
void dhcp_stop(DhcpState * s);
#endif //ETHERLIB_DHCP_H #endif //ETHERLIB_DHCP_H

View File

@ -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->identifier, 2);
FILL_ADVANCE(hdr, &icmpProps->sequenceNumber, 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); icmpProps->checksum = chksum(hdrStart, ipProps->TotalLength - ETH_IPv4_HEADER_SIZE, false);
FILL_WORD_ADVANCE(ChkSumPtr, icmpProps->checksum); FILL_WORD_ADVANCE(ChkSumPtr, icmpProps->checksum);*/
} }

59
timer.c
View File

@ -2,28 +2,30 @@
// Created by epagris on 2022.12.21.. // Created by epagris on 2022.12.21..
// //
#include <stdlib.h>
#include "timer.h" #include "timer.h"
#include "dynmem.h" #include "dynmem.h"
#include "utils.h" #include "utils.h"
#include <stdlib.h>
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; 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->s = us / 1000000;
t->us = us - ((int64_t)t->s * 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); time_from_us(t, time_to_us(t) + us);
} }
// ------------------------------ // ------------------------------
Timer *timer_new(uint32_t maxSched) { 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); ASSERT_NULL(tmr);
ETHLIB_OS_MTX_CREATE(&tmr->tabMtx); ETHLIB_OS_MTX_CREATE(&tmr->tabMtx);
@ -37,26 +39,27 @@ Timer *timer_new(uint32_t maxSched) {
return tmr; return tmr;
} }
static AlarmAssignment * timer_get_alarm_by_id(Timer * tmr, uint32_t id) { static AlarmAssignment *timer_get_alarm_by_id(Timer *tmr, uint32_t id) {
AlarmAssignment * slot = NULL; AlarmAssignment *slot = NULL;
for (uint32_t i = 0; (i < tmr->maxSched) && (slot == NULL); i++) { for (uint32_t i = 0; i < tmr->maxSched; i++) {
if (tmr->alarms[i].id == id) { if (tmr->alarms[i].id == id) {
slot = (tmr->alarms) + i; slot = (tmr->alarms) + i;
break;
} }
} }
return slot; return slot;
} }
static uint32_t timer_generate_id(Timer * tmr) { static uint32_t timer_generate_id(Timer *tmr) {
uint32_t newId = 0; uint32_t newId = 0;
do { 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); } while (timer_get_alarm_by_id(tmr, newId) != NULL);
return newId; return newId;
} }
static void timer_update_nearest_alarm(Timer * tmr) { static void timer_update_nearest_alarm(Timer *tmr) {
if (tmr->nSched == 0) { if (tmr->nSched == 0) {
tmr->nextAlarm = NULL; tmr->nextAlarm = NULL;
return; 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 t_c_us = time_to_us(&tmr->time);
int64_t min_delta_t_us = 0; int64_t min_delta_t_us = 0;
AlarmAssignment * nearest = NULL; AlarmAssignment *nearest = NULL;
for (uint32_t i = 0; i < tmr->maxSched; i++) { for (uint32_t i = 0; i < tmr->maxSched; i++) {
int64_t t_i_us = time_to_us(&(tmr->alarms[i].time)); int64_t t_i_us = time_to_us(&(tmr->alarms[i].time));
if ((nearest == NULL) && (tmr->alarms[i].id != 0)) { if ((nearest == NULL) && (tmr->alarms[i].id != 0)) {
@ -83,7 +86,7 @@ static void timer_update_nearest_alarm(Timer * tmr) {
tmr->nextAlarm = nearest; 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 if (tmr->nSched == tmr->maxSched) { // if cannot schedule more alarm
return TIMER_SCHED_FAILED; 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)); ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx));
// if we can schedule get the first unused block // 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 // allocate on the first free slot
slot->id = timer_generate_id(tmr); 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; tmr->nextAlarm = slot;
} }
timer_report(tmr); //timer_report(tmr);
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx)); ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
return slot->id; 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; TimePoint t = tmr->time;
time_add_us(&t, us); time_add_us(&t, us);
return timer_sched(tmr, &t, cb, params); 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)); ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx));
AlarmAssignment * alarm = timer_get_alarm_by_id(tmr, id); if (tmr->nSched > 0) {
if (alarm != NULL) { AlarmAssignment *alarm = timer_get_alarm_by_id(tmr, id);
memset(alarm, 0, sizeof(AlarmAssignment)); if (alarm != NULL) {
tmr->nSched--; memset(alarm, 0, sizeof(AlarmAssignment));
tmr->nSched--;
timer_update_nearest_alarm(tmr);
}
} }
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx)); ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
@ -138,15 +144,15 @@ void timer_set_time(Timer *tmr, const TimePoint *t) {
tmr->time = *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); return time_to_us(&tmr->time);
} }
TimePoint timer_get_time(const Timer * tmr) { TimePoint timer_get_time(const Timer *tmr) {
return tmr->time; return tmr->time;
} }
void timer_tick(Timer * tmr, int64_t us) { void timer_tick(Timer *tmr, int64_t us) {
// advance time // advance time
time_add_us(&tmr->time, us); time_add_us(&tmr->time, us);
/*t_us += 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 return; // break from the loop, since we cannot lock the mutex
} }
timer_report(tmr); //timer_report(tmr);
// fetch alarm (obtain a COPY) // fetch alarm (obtain a COPY)
AlarmAssignment alarm = *(tmr->nextAlarm); 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); MSG("Time: %u.%06u\n\n", tmr->time.s, tmr->time.us);
int64_t t_c_us = timer_get_time_us(tmr); int64_t t_c_us = timer_get_time_us(tmr);