diff options
Diffstat (limited to 'src/user/app/netstack/udp.c')
-rw-r--r-- | src/user/app/netstack/udp.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/src/user/app/netstack/udp.c b/src/user/app/netstack/udp.c index d53137d..46d09de 100644 --- a/src/user/app/netstack/udp.c +++ b/src/user/app/netstack/udp.c @@ -20,7 +20,14 @@ struct udp_conn { struct udp_conn *next, **prev; }; struct udp_conn *conns; -void udp_listen(uint16_t port, +static void conns_append(struct udp_conn *c) { + c->next = conns; + if (c->next) *(c->next->prev) = c; + c->prev = &conns; + *c->prev = c; +} +void udp_listen( + uint16_t port, void (*on_conn)(struct udp_conn *, void *carg), void (*on_recv)(const void *, size_t, void *carg), void *carg) @@ -32,16 +39,29 @@ void udp_listen(uint16_t port, c->on_conn = on_conn; c->on_recv = on_recv; c->carg = carg; - - c->next = conns; - if (c->next) *(c->next->prev) = c; - c->prev = &conns; - *c->prev = c; + conns_append(c); } -void udpc_close(struct udp_conn *c) { - if (c->next) c->next->prev = c->prev; - *(c->prev) = c->next; - free(c); +struct udp_conn *udpc_new( + struct udp u, + void (*on_recv)(const void *, size_t, void *carg), + void *carg) +{ + struct udp_conn *c = malloc(sizeof *c); + memset(c, 0, sizeof *c); + c->lip = u.ip.src; + c->rip = u.ip.dst; + c->lport = u.src ? u.src : 50000; // TODO randomize source ports + c->rport = u.dst; + if (arpcache_get(c->rip, &c->rmac) < 0) { + // TODO make arp request, wait for reply + eprintf("not in ARP cache, unimplemented"); + free(c); + return NULL; + } + c->on_recv = on_recv; + c->carg = carg; + conns_append(c); + return c; } void udpc_send(struct udp_conn *c, const void *buf, size_t len) { uint8_t *pkt = malloc(Payload + len); @@ -58,6 +78,11 @@ void udpc_send(struct udp_conn *c, const void *buf, size_t len) { }); free(pkt); } +void udpc_close(struct udp_conn *c) { + if (c->next) c->next->prev = c->prev; + *(c->prev) = c->next; + free(c); +} void udp_parse(const uint8_t *buf, size_t len, struct ipv4 ip) { |