summaryrefslogtreecommitdiff
path: root/src/user/app/netstack
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/app/netstack')
-rw-r--r--src/user/app/netstack/arp.c10
-rw-r--r--src/user/app/netstack/fs.c35
-rw-r--r--src/user/app/netstack/proto.h14
-rw-r--r--src/user/app/netstack/udp.c45
4 files changed, 87 insertions, 17 deletions
diff --git a/src/user/app/netstack/arp.c b/src/user/app/netstack/arp.c
index b43b7e8..9e292b3 100644
--- a/src/user/app/netstack/arp.c
+++ b/src/user/app/netstack/arp.c
@@ -73,6 +73,16 @@ static void arpcache_put(uint32_t ip, mac_t mac) {
arpcache = e;
}
+int arpcache_get(uint32_t ip, mac_t *mac) {
+ for (struct arpc *iter = arpcache; iter; iter = iter->next) {
+ if (iter->ip == ip) {
+ if (mac) memcpy(mac, iter->mac, 6);
+ return 0;
+ }
+ }
+ return -1;
+}
+
void arp_fsread(handle_t h, long offset) {
const char *fmt = "%08x\t%02x:%02x:%02x:%02x:%02x:%02x\n";
long linelen = snprintf(NULL, 0, fmt, 0, 1, 2, 3, 4, 5, 6) + 1;
diff --git a/src/user/app/netstack/fs.c b/src/user/app/netstack/fs.c
index dc6db04..4d1e38c 100644
--- a/src/user/app/netstack/fs.c
+++ b/src/user/app/netstack/fs.c
@@ -42,8 +42,6 @@ struct handle {
static void udp_listen_callback(struct udp_conn *c, void *arg) {
struct handle *h = arg;
h->udp.c = c;
- h->udp.rx = NULL;
- h->udp.rxlast = NULL;
_syscall_fs_respond(h->reqh, h, 0, 0);
h->reqh = -1;
}
@@ -55,7 +53,6 @@ static void udp_recv_callback(const void *buf, size_t len, void *arg) {
h->reqh = -1;
return;
}
- // TODO don't malloc on the network thread, dumbass
struct strqueue *sq = malloc(sizeof(*sq) + len);
sq->next = NULL;
sq->len = len;
@@ -99,10 +96,10 @@ static void fs_open(handle_t reqh, char *path) {
}
char *save;
- const char *srcip, *verb, *proto, *port_s;
+ const char *srcip_s, *dstip_s, *verb, *proto, *port_s;
- srcip = strtok_r(path, "/", &save);
- if (strcmp(srcip, "0.0.0.0") != 0)
+ srcip_s = strtok_r(path, "/", &save);
+ if (strcmp(srcip_s, "0.0.0.0") != 0)
respond(NULL, -1);
verb = strtok_r(NULL, "/", &save);
@@ -113,6 +110,7 @@ static void fs_open(handle_t reqh, char *path) {
if (port_s) {
uint16_t port = strtol(port_s, NULL, 0);
h = malloc(sizeof *h);
+ memset(h, 0, sizeof *h);
h->type = H_UDP;
h->udp.c = NULL;
h->reqh = reqh;
@@ -120,6 +118,31 @@ static void fs_open(handle_t reqh, char *path) {
return;
}
}
+ } else if (strcmp(verb, "connect") == 0) {
+ dstip_s = strtok_r(NULL, "/", &save);
+ // TODO proper ip parsing
+ // 0xc0a80001 == 192.168.0.1
+ uint32_t dstip = strtol(dstip_s, NULL, 0);
+ proto = strtok_r(NULL, "/", &save);
+ if (strcmp(proto, "udp") == 0) {
+ port_s = strtok_r(NULL, "/", &save);
+ if (port_s) {
+ uint16_t port = strtol(port_s, NULL, 0);
+ h = malloc(sizeof *h);
+ memset(h, 0, sizeof *h);
+ h->type = H_UDP;
+ h->udp.c = udpc_new((struct udp){
+ .dst = port,
+ .ip.dst = dstip,
+ }, udp_recv_callback, h);
+ if (h->udp.c) {
+ respond(h, 0);
+ } else {
+ free(h);
+ respond(NULL, -1);
+ }
+ }
+ }
}
respond(NULL, -1);
#undef respond
diff --git a/src/user/app/netstack/proto.h b/src/user/app/netstack/proto.h
index 864f1c1..68dccad 100644
--- a/src/user/app/netstack/proto.h
+++ b/src/user/app/netstack/proto.h
@@ -31,6 +31,11 @@ struct ipv4 {
const uint8_t *header; size_t hlen;
};
+struct udp {
+ struct ipv4 ip;
+ uint16_t src, dst;
+};
+
struct icmp {
struct ipv4 ip;
uint8_t type, code;
@@ -46,6 +51,8 @@ struct ethq {
extern struct ethq *ether_queue;
void arp_parse(const uint8_t *buf, size_t len);
+/* 0 on success, -1 on failure */
+int arpcache_get(uint32_t ip, mac_t *mac);
void arp_fsread(handle_t h, long offset);
void icmp_parse(const uint8_t *buf, size_t len, struct ipv4 ip);
@@ -61,10 +68,15 @@ void ether_finish(uint8_t *pkt);
struct udp_conn;
void udp_parse(const uint8_t *buf, size_t len, struct ipv4 ip);
/* calls callback once, after a client connects. */
-void udp_listen(uint16_t port,
+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);
+struct udp_conn *udpc_new(
+ struct udp u,
+ void (*on_recv)(const void *, size_t, void *carg),
+ void *carg);
// TODO udp_onclosed
void udpc_send(struct udp_conn *, const void *buf, size_t len);
/* frees */
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) {