From 418cb68ffe64e9359e2e991538ece442fafc0c94 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Sat, 27 Aug 2022 11:36:42 +0200
Subject: user/netstack: IP gateway, make networking work without a second vm

---
 src/user/app/netstack/netstack.c | 17 +++++++++++------
 src/user/app/netstack/proto.h    |  2 +-
 src/user/app/netstack/tcp.c      | 11 +++++++----
 3 files changed, 19 insertions(+), 11 deletions(-)

(limited to 'src/user/app/netstack')

diff --git a/src/user/app/netstack/netstack.c b/src/user/app/netstack/netstack.c
index 137d9d9..75a5162 100644
--- a/src/user/app/netstack/netstack.c
+++ b/src/user/app/netstack/netstack.c
@@ -26,19 +26,24 @@ void network_thread(void *arg) { (void)arg;
 void fs_thread(void *arg);
 
 int main(int argc, char **argv) {
-	if (argc < 3) {
-		eprintf("usage: netstack iface ip");
+	if (argc < 4) {
+		eprintf("usage: netstack iface ip gateway");
 		return 1;
 	}
-	if (ip_parse(argv[2], &state.ip) < 0) {
-		eprintf("invalid ip");
-		return -1;
-	}
 	state.raw_h = _syscall_open(argv[1], strlen(argv[1]), 0);
 	if (state.raw_h < 0) {
 		eprintf("couldn't open %s", argv[1]);
 		return 1;
 	}
+	if (ip_parse(argv[2], &state.ip) < 0) {
+		eprintf("invalid ip");
+		return -1;
+	}
+	if (ip_parse(argv[3], &state.gateway) < 0) {
+		eprintf("invalid gateway");
+		return -1;
+	}
+	arp_request(state.gateway);
 	thread_create(0, network_thread, NULL);
 	thread_create(0, fs_thread, NULL);
 	_syscall_await();
diff --git a/src/user/app/netstack/proto.h b/src/user/app/netstack/proto.h
index 72a4fca..4d881ca 100644
--- a/src/user/app/netstack/proto.h
+++ b/src/user/app/netstack/proto.h
@@ -8,7 +8,7 @@ static const mac_t MAC_BROADCAST = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 
 extern struct net_state {
 	mac_t mac;
-	uint32_t ip;
+	uint32_t ip, gateway;
 
 	handle_t raw_h;
 } state;
diff --git a/src/user/app/netstack/tcp.c b/src/user/app/netstack/tcp.c
index 2f13a31..dd6d121 100644
--- a/src/user/app/netstack/tcp.c
+++ b/src/user/app/netstack/tcp.c
@@ -120,10 +120,13 @@ struct tcp_conn *tcpc_new(
 	c->lport = t.src ? t.src : 50002; // TODO randomize source ports
 	c->rport = t.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;
+		// TODO wait for ARP reply
+		arp_request(c->rip);
+		if (arpcache_get(state.gateway, &c->rmac) < 0) {
+			eprintf("neither target nor gateway not in ARP cache, dropping");
+			free(c);
+			return NULL;
+		}
 	}
 
 	c->state = SYN_SENT;
-- 
cgit v1.2.3