summaryrefslogtreecommitdiff
path: root/src/user/app/netstack/arp.c
diff options
context:
space:
mode:
authordzwdz2022-08-27 10:58:13 +0200
committerdzwdz2022-08-27 10:58:13 +0200
commit0f51f64e9bdaeed74981150a7b29726610d00504 (patch)
treeaec373ecef3db1f9ab061d31d488f929411a658e /src/user/app/netstack/arp.c
parent48e612a8c19ae1fd6aa1ab8fb48b03a0291110b4 (diff)
user/netstack: ARP requests
Diffstat (limited to 'src/user/app/netstack/arp.c')
-rw-r--r--src/user/app/netstack/arp.c41
1 files changed, 40 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;
+ }
+}