summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/user/app/ethdump/arp.c8
-rw-r--r--src/user/app/ethdump/ethdump.c27
-rw-r--r--src/user/app/ethdump/ether.c37
-rw-r--r--src/user/app/ethdump/fs.c65
-rw-r--r--src/user/app/ethdump/icmp.c2
-rw-r--r--src/user/app/ethdump/ipv4.c32
-rw-r--r--src/user/app/ethdump/proto.h9
-rw-r--r--src/user/app/ethdump/util.c14
-rw-r--r--src/user/app/ethdump/util.h5
-rw-r--r--src/user/app/init/init.c4
-rw-r--r--src/user/app/shell/builtins.c2
11 files changed, 119 insertions, 86 deletions
diff --git a/src/user/app/ethdump/arp.c b/src/user/app/ethdump/arp.c
index a022b12..cfb1e04 100644
--- a/src/user/app/ethdump/arp.c
+++ b/src/user/app/ethdump/arp.c
@@ -1,6 +1,5 @@
#include "proto.h"
#include "util.h"
-#include <stdlib.h>
#include <string.h>
enum {
@@ -20,12 +19,6 @@ void arp_parse(const uint8_t *buf, size_t len) {
uint16_t ptype = nget16(buf + ProtoType);
uint16_t op = nget16(buf + Operation);
- const char *ops = "bad operation";
- if (op == 1) ops = "request";
- if (op == 2) ops = "reply";
-
- printf("ARP htype 0x%x, ptype 0x%x, %s\n", htype, ptype, ops);
-
if (!(htype == HdrTypeEther && ptype == ET_IPv4)) return;
enum { /* only valid for this combination of header + proto */
SrcMAC = 8,
@@ -36,7 +29,6 @@ void arp_parse(const uint8_t *buf, size_t len) {
if (op == OpReq) {
uint32_t daddr = nget32(buf + DstIP);
- printf("IPv4 request for %08x\n", daddr);
if (daddr == state.ip) {
uint8_t *pkt = ether_start(30, (struct ethernet){
.dst = buf + SrcMAC,
diff --git a/src/user/app/ethdump/ethdump.c b/src/user/app/ethdump/ethdump.c
index 4047962..17592a1 100644
--- a/src/user/app/ethdump/ethdump.c
+++ b/src/user/app/ethdump/ethdump.c
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
+#include <user/lib/thread.h>
struct net_state state = {
// TODO dynamically get mac
@@ -12,23 +13,29 @@ struct net_state state = {
.ip = (192 << 24) + (168 << 16) + 11,
};
-int main(void) {
- const char *path = "/kdev/eth";
- state.raw_h = _syscall_open(path, strlen(path), 0);
- if (state.raw_h < 0) {
- eprintf("couldn't open %s", path);
- return 1;
- }
-
+void network_thread(void *arg) { (void)arg;
const size_t buflen = 4096;
char *buf = malloc(buflen);
for (;;) {
long ret = _syscall_read(state.raw_h, buf, buflen, -1);
if (ret < 0) break;
- printf("\npacket of length %u\n", ret);
- hexdump(buf, ret);
ether_parse((void*)buf, ret);
}
free(buf);
+}
+
+void fs_thread(void *arg);
+
+int main(void) {
+ const char *path = "/kdev/eth";
+ state.raw_h = _syscall_open(path, strlen(path), 0);
+ if (state.raw_h < 0) {
+ eprintf("couldn't open %s", path);
+ return 1;
+ }
+
+ thread_create(0, network_thread, NULL);
+ thread_create(0, fs_thread, NULL);
+ _syscall_await();
return 0;
}
diff --git a/src/user/app/ethdump/ether.c b/src/user/app/ethdump/ether.c
index 32646e2..3f6a40d 100644
--- a/src/user/app/ethdump/ether.c
+++ b/src/user/app/ethdump/ether.c
@@ -10,37 +10,32 @@ enum {
EtherType = 12,
Payload = 14,
};
+struct queue_entry *ether_queue;
void ether_parse(const uint8_t *buf, size_t len) {
- uint8_t dmac[6], smac[6];
-
- if (len < 60) return;
- for (int i = 0; i < 6; i++) dmac[i] = buf[i + DstMAC];
- for (int i = 0; i < 6; i++) smac[i] = buf[i + SrcMAC];
- printf("from %02x:%02x:%02x:%02x:%02x:%02x\n",
- smac[0], smac[1], smac[2], smac[3], smac[4], smac[5]);
- printf("to %02x:%02x:%02x:%02x:%02x:%02x\n",
- dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]);
-
- uint16_t ethertype = nget16(buf + EtherType);
- printf("ethertype %u\n", ethertype);
-
struct ethernet ether = (struct ethernet){
- .src = &smac,
- .dst = &dmac,
- .type = ethertype,
+ .src = buf + SrcMAC,
+ .dst = buf + DstMAC,
+ .type = nget16(buf + EtherType),
};
- switch (ethertype) {
+ struct queue_entry **iter = &ether_queue;
+ while (iter && *iter) {
+ struct queue_entry *qe = *iter;
+ _syscall_fs_respond(qe->h, buf, len, 0);
+ /* remove entry */
+ /* yes, doing it this way here doesn't make sense. i'm preparing for filtering */
+ *iter = qe->next;
+ free(qe);
+ }
+
+ switch (ether.type) {
case ET_IPv4:
ipv4_parse(buf + Payload, len - Payload, ether);
break;
case ET_ARP:
arp_parse(buf + Payload, len - Payload);
break;
- default:
- printf("(unknown)\n");
- break;
}
}
@@ -62,8 +57,6 @@ uint8_t *ether_start(size_t len, struct ethernet ether) {
void ether_finish(uint8_t *pkt) {
uint8_t *buf = pkt - Payload - fhoff;
size_t len = *(size_t*)buf;
- printf("sending:\n");
- hexdump(buf + fhoff, len);
_syscall_write(state.raw_h, buf + fhoff, len, 0, 0);
free(buf);
}
diff --git a/src/user/app/ethdump/fs.c b/src/user/app/ethdump/fs.c
new file mode 100644
index 0000000..5078a13
--- /dev/null
+++ b/src/user/app/ethdump/fs.c
@@ -0,0 +1,65 @@
+#include "proto.h"
+#include <camellia/syscalls.h>
+#include <stdlib.h>
+#include <string.h>
+#include <user/lib/fs/dir.h>
+
+enum {
+ H_ROOT,
+ H_ETHER,
+};
+
+void fs_thread(void *arg) { (void)arg;
+ const size_t buflen = 4096;
+ char *buf = malloc(buflen);
+ for (;;) {
+ struct fs_wait_response res;
+ handle_t h = _syscall_fs_wait(buf, buflen, &res);
+ if (h < 0) break;
+ switch (res.op) {
+ long ret;
+ case VFSOP_OPEN:
+ ret = -1;
+ if (res.len < buflen) {
+ buf[res.len] = '\0';
+ if (!strcmp("/", buf)) ret = H_ROOT;
+ else if (!strcmp("/raw", buf)) ret = H_ETHER;
+ }
+ _syscall_fs_respond(h, (void*)ret, ret, 0);
+ break;
+ case VFSOP_READ:
+ switch ((long)res.id) {
+ struct dirbuild db;
+ struct queue_entry *qe;
+ case H_ROOT:
+ dir_start(&db, res.offset, buf, sizeof buf);
+ dir_append(&db, "raw");
+ _syscall_fs_respond(h, buf, dir_finish(&db), 0);
+ break;
+ case H_ETHER:
+ qe = malloc(sizeof *qe);
+ qe->h = h;
+ qe->next = ether_queue;
+ ether_queue = qe;
+ break;
+ default:
+ _syscall_fs_respond(h, NULL, -1, 0);
+ }
+ break;
+ case VFSOP_WRITE:
+ switch ((long)res.id) {
+ case H_ETHER:
+ ret = _syscall_write(state.raw_h, buf, res.len, 0, 0);
+ _syscall_fs_respond(h, NULL, ret, 0);
+ break;
+ default:
+ _syscall_fs_respond(h, NULL, -1, 0);
+ }
+ break;
+ default:
+ _syscall_fs_respond(h, NULL, -1, 0);
+ break;
+ }
+ }
+ free(buf);
+}
diff --git a/src/user/app/ethdump/icmp.c b/src/user/app/ethdump/icmp.c
index 3f10ae8..b3eff93 100644
--- a/src/user/app/ethdump/icmp.c
+++ b/src/user/app/ethdump/icmp.c
@@ -12,8 +12,8 @@ enum {
void icmp_parse(const uint8_t *buf, size_t len, struct ipv4 ip) {
if (len < Payload) return;
uint8_t type = buf[Type];
- printf("ICMP type %u\n", type);
if (type == 8 && ip.dst == state.ip) {
+ /* echo reply */
uint8_t *pkt = icmp_start(len - Payload, (struct icmp){
.type = 0,
.ip.dst = ip.src,
diff --git a/src/user/app/ethdump/ipv4.c b/src/user/app/ethdump/ipv4.c
index c9b2df4..e8ab7ea 100644
--- a/src/user/app/ethdump/ipv4.c
+++ b/src/user/app/ethdump/ipv4.c
@@ -15,48 +15,30 @@ enum {
};
void ipv4_parse(const uint8_t *buf, size_t len, struct ethernet ether) {
- uint8_t version, headerlen, proto;
+ uint8_t version, headerlen;
uint16_t packetlen, id;
- uint32_t dst, src;
version = buf[Version] >> 4;
- if (version != 4) {
- printf("bad IPv4 version %u\n", version);
- return;
- }
+ if (version != 4) return;
headerlen = (buf[HdrLen] & 0xf) * 4;
packetlen = nget16(buf + PktLen);
+ if (packetlen < headerlen) return;
id = nget16(buf + Id);
- proto = buf[Proto];
- src = nget32(buf + SrcIP);
- dst = nget32(buf + DstIP);
// TODO checksum
// TODO fragmentation
- printf("headerlen %u, packetlen %u (real %u), id %u\n", headerlen, packetlen, len, id);
- printf("from %x to %x\n", src, dst);
- printf("id %u\n", id);
- if (packetlen < headerlen) {
- printf("headerlen too big\n");
- return;
- }
-
struct ipv4 ip = (struct ipv4){
.e = ether,
- .src = src,
- .dst = dst,
- .proto = proto,
+ .src = nget32(buf + SrcIP),
+ .dst = nget32(buf + DstIP),
+ .proto = buf[Proto],
};
- switch (proto) {
+ switch (ip.proto) {
case 1:
- printf("proto %u - icmp\n", proto);
icmp_parse(buf + headerlen, packetlen - headerlen, ip);
break;
- default:
- printf("proto %u - unknown\n", proto);
- break;
}
}
diff --git a/src/user/app/ethdump/proto.h b/src/user/app/ethdump/proto.h
index df2000e..21057a2 100644
--- a/src/user/app/ethdump/proto.h
+++ b/src/user/app/ethdump/proto.h
@@ -34,6 +34,15 @@ struct icmp {
};
+/* NOT THREADSAFE, YET USED FROM THREADS
+ * will break if i implement a scheduler*/
+struct queue_entry {
+ handle_t h;
+ struct queue_entry *next;
+};
+extern struct queue_entry *ether_queue;
+
+
void arp_parse(const uint8_t *buf, size_t len);
void icmp_parse(const uint8_t *buf, size_t len, struct ipv4 ip);
diff --git a/src/user/app/ethdump/util.c b/src/user/app/ethdump/util.c
index 8c29340..7c484f3 100644
--- a/src/user/app/ethdump/util.c
+++ b/src/user/app/ethdump/util.c
@@ -1,19 +1,5 @@
#include "util.h"
-void hexdump(const void *vbuf, size_t len) {
- const uint8_t *buf = vbuf;
- for (size_t i = 0; i < len; i += 16) {
- printf("%08x ", i);
-
- for (size_t j = i; j < i + 8 && j < len; j++)
- printf("%02x ", buf[j]);
- printf(" ");
- for (size_t j = i + 8; j < i + 16 && j < len; j++)
- printf("%02x ", buf[j]);
- printf("\n");
- }
-}
-
/* https://www.w3.org/TR/PNG/#D-CRCAppendix */
static uint32_t crc_table[256];
uint32_t crc32(const uint8_t *buf, size_t len) {
diff --git a/src/user/app/ethdump/util.h b/src/user/app/ethdump/util.h
index ca7e99b..6f58b82 100644
--- a/src/user/app/ethdump/util.h
+++ b/src/user/app/ethdump/util.h
@@ -4,14 +4,9 @@
#define eprintf(fmt, ...) fprintf(stderr, "ethdump: "fmt"\n" __VA_OPT__(,) __VA_ARGS__)
-// #define printf(...)
-
-void hexdump(const void *vbuf, size_t len);
-
uint32_t crc32(const uint8_t *buf, size_t len);
uint16_t ip_checksum(const uint8_t *buf, size_t len);
-
static inline void nput16(void *vbuf, uint16_t n) {
uint8_t *b = vbuf;
b[0] = n >> 8;
diff --git a/src/user/app/init/init.c b/src/user/app/init/init.c
index 49cc085..acf9b03 100644
--- a/src/user/app/init/init.c
+++ b/src/user/app/init/init.c
@@ -67,6 +67,10 @@ int main(void) {
const char *argv[] = {"/bin/vterm", NULL};
execv(argv[0], (void*)argv);
}
+ MOUNT_AT("/net/") {
+ const char *argv[] = {"/bin/ethdump", NULL};
+ execv(argv[0], (void*)argv);
+ }
if (_syscall_pipe(killswitch_pipe, 0) < 0) {
printf("couldn't create the killswitch pipe, quitting...\n");
diff --git a/src/user/app/shell/builtins.c b/src/user/app/shell/builtins.c
index 23a8221..1be9b5b 100644
--- a/src/user/app/shell/builtins.c
+++ b/src/user/app/shell/builtins.c
@@ -28,7 +28,7 @@ static void cmd_cat(int argc, char **argv) {
}
if (!strcmp(argv[i], "!stdin")) fextflags(file, FEXT_NOFILL);
for (;;) {
- int len = fread(buf, 1, sizeof buf, file);
+ int len = fread(buf, 1, buflen, file);
if (len <= 0) break;
fwrite(buf, 1, len, stdout);
}