diff options
author | dzwdz | 2022-08-27 10:58:13 +0200 |
---|---|---|
committer | dzwdz | 2022-08-27 10:58:13 +0200 |
commit | 0f51f64e9bdaeed74981150a7b29726610d00504 (patch) | |
tree | aec373ecef3db1f9ab061d31d488f929411a658e /src/user | |
parent | 48e612a8c19ae1fd6aa1ab8fb48b03a0291110b4 (diff) |
user/netstack: ARP requests
Diffstat (limited to 'src/user')
-rw-r--r-- | src/user/app/netstack/arp.c | 41 | ||||
-rw-r--r-- | src/user/app/netstack/fs.c | 3 | ||||
-rw-r--r-- | src/user/app/netstack/proto.h | 2 |
3 files changed, 45 insertions, 1 deletions
diff --git a/src/user/app/netstack/arp.c b/src/user/app/netstack/arp.c index 9e292b3..6c230b3 100644 --- a/src/user/app/netstack/arp.c +++ b/src/user/app/netstack/arp.c @@ -46,7 +46,7 @@ void arp_parse(const uint8_t *buf, size_t len) { .dst = (void*)(buf + SrcMAC), .type = ET_ARP, }); - nput16(pkt + HdrType, 1); + nput16(pkt + HdrType, HdrTypeEther); nput16(pkt + ProtoType, ET_IPv4); pkt[HdrALen] = 6; pkt[ProtoALen] = 4; @@ -59,6 +59,30 @@ void arp_parse(const uint8_t *buf, size_t len) { } } +void arp_request(uint32_t ip) { + enum { + SrcMAC = 8, + SrcIP = 14, + DstMAC = 18, + DstIP = 24, + }; + uint8_t *pkt = ether_start(28, (struct ethernet){ + .src = &state.mac, + .dst = &MAC_BROADCAST, + .type = ET_ARP, + }); + nput16(pkt + HdrType, HdrTypeEther); + nput16(pkt + ProtoType, ET_IPv4); + pkt[HdrALen] = 6; + pkt[ProtoALen] = 4; + nput16(pkt + Operation, OpReq); + memcpy(pkt + SrcMAC, state.mac, 6); + nput32(pkt + SrcIP, state.ip); + memcpy(pkt + DstMAC, &MAC_BROADCAST, 6); + nput32(pkt + DstIP, ip); + ether_finish(pkt); +} + static void arpcache_put(uint32_t ip, mac_t mac) { for (struct arpc *iter = arpcache; iter; iter = iter->next) { if (memcmp(iter->mac, mac, 6) == 0) { @@ -110,3 +134,18 @@ void arp_fsread(handle_t h, long offset) { err: _syscall_fs_respond(h, NULL, -1, 0); } + +long arp_fswrite(const char *buf, long len, long offset) { + if (offset != -1) return -1; + uint32_t ip; + char tmp[16]; + size_t iplen = len < 15 ? len : 15; + memcpy(tmp, buf, iplen); + tmp[iplen] = '\0'; + if (ip_parse(tmp, &ip) < 0) { + return -1; + } else { + arp_request(ip); + return len; + } +} diff --git a/src/user/app/netstack/fs.c b/src/user/app/netstack/fs.c index 9f40ef8..cbead8f 100644 --- a/src/user/app/netstack/fs.c +++ b/src/user/app/netstack/fs.c @@ -294,6 +294,9 @@ void fs_thread(void *arg) { (void)arg; udpc_send(h->udp.c, buf, res.len); _syscall_fs_respond(reqh, NULL, res.len, 0); break; + case H_ARP: + _syscall_fs_respond(reqh, NULL, arp_fswrite(buf, res.len, res.offset), 0); + break; default: _syscall_fs_respond(reqh, NULL, -1, 0); } diff --git a/src/user/app/netstack/proto.h b/src/user/app/netstack/proto.h index 30ff864..72a4fca 100644 --- a/src/user/app/netstack/proto.h +++ b/src/user/app/netstack/proto.h @@ -56,9 +56,11 @@ struct ethq { extern struct ethq *ether_queue; void arp_parse(const uint8_t *buf, size_t len); +void arp_request(uint32_t ip); /* 0 on success, -1 on failure */ int arpcache_get(uint32_t ip, mac_t *mac); void arp_fsread(handle_t h, long offset); +long arp_fswrite(const char *buf, long len, long offset); void icmp_parse(const uint8_t *buf, size_t len, struct ipv4 ip); void icmp_send(const void *payload, size_t len, struct icmp i); |