summaryrefslogtreecommitdiff
path: root/src/user/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/app')
-rw-r--r--src/user/app/netstack/arp.c41
-rw-r--r--src/user/app/netstack/fs.c3
-rw-r--r--src/user/app/netstack/proto.h2
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);