summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/user/app/ethdump/icmp.c16
-rw-r--r--src/user/app/ethdump/ipv4.c19
-rw-r--r--src/user/app/ethdump/proto.h6
-rw-r--r--src/user/app/ethdump/udp.c23
4 files changed, 29 insertions, 35 deletions
diff --git a/src/user/app/ethdump/icmp.c b/src/user/app/ethdump/icmp.c
index 94f718e..e23ab01 100644
--- a/src/user/app/ethdump/icmp.c
+++ b/src/user/app/ethdump/icmp.c
@@ -13,25 +13,21 @@ void icmp_parse(const uint8_t *buf, size_t len, struct ipv4 ip) {
uint8_t type = buf[Type];
if (type == 8 && ip.dst == state.ip) {
/* echo reply */
- uint8_t *pkt = icmp_start(len - Payload, (struct icmp){
+ icmp_send(buf + Payload, len - Payload, (struct icmp){
.type = 0,
.ip.dst = ip.src,
.ip.e.dst = ip.e.src,
});
- memcpy(pkt, buf + Payload, len - Payload);
- icmp_finish(pkt, len - Payload);
}
}
-uint8_t *icmp_start(size_t len, struct icmp i) {
+void icmp_send(const void *payload, size_t len, struct icmp i) {
i.ip.proto = 1;
- uint8_t *pkt = ipv4_start(Payload + len, i.ip);
+ uint8_t *pkt = malloc(Payload + len);
pkt[Type] = i.type;
pkt[Code] = i.code;
- return pkt + Payload;
-}
-void icmp_finish(uint8_t *pkt, size_t len) {
- pkt -= Payload;
+ memcpy(pkt + Payload, payload, len);
nput16(pkt + Checksum, ip_checksum(pkt, Payload + len));
- ipv4_finish(pkt);
+ ipv4_send(pkt, Payload + len, i.ip);
+ free(pkt);
}
diff --git a/src/user/app/ethdump/ipv4.c b/src/user/app/ethdump/ipv4.c
index 93dd98a..fda0c0c 100644
--- a/src/user/app/ethdump/ipv4.c
+++ b/src/user/app/ethdump/ipv4.c
@@ -183,15 +183,17 @@ void ipv4_parse(const uint8_t *buf, size_t len, struct ethernet ether) {
}
}
-// TODO just have a single *_send function, this is getting ridiculous
-uint8_t *ipv4_start(size_t len, struct ipv4 ip) {
+void ipv4_send(const void *payload, size_t len, struct ipv4 ip) {
+ size_t hdrlen = 20;
+
ip.e.type = ET_IPv4;
if (!ip.src) ip.src = state.ip;
if (!ip.e.dst && ip.dst == 0xFFFFFFFF)
ip.e.dst = &MAC_BROADCAST;
- size_t hdrlen = 20;
- uint8_t *pkt = ether_start(len + hdrlen, ip.e);
+ // TODO output fragmentation
+
+ uint8_t *pkt = ether_start(hdrlen + len, ip.e);
pkt[Version] = 0x40;
pkt[HdrLen] |= hdrlen / 4;
nput16(pkt + TotalLen, len + hdrlen);
@@ -199,12 +201,7 @@ uint8_t *ipv4_start(size_t len, struct ipv4 ip) {
pkt[Proto] = ip.proto;
nput32(pkt + SrcIP, ip.src);
nput32(pkt + DstIP, ip.dst);
-
nput16(pkt + Checksum, ip_checksum(pkt, hdrlen));
-
- return pkt + hdrlen;
-}
-void ipv4_finish(uint8_t *pkt) {
- // TODO output fragmentation
- ether_finish(pkt - 20);
+ memcpy(pkt + hdrlen, payload, len);
+ ether_finish(pkt);
}
diff --git a/src/user/app/ethdump/proto.h b/src/user/app/ethdump/proto.h
index af73470..106f286 100644
--- a/src/user/app/ethdump/proto.h
+++ b/src/user/app/ethdump/proto.h
@@ -48,12 +48,10 @@ extern struct ethq *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);
-uint8_t *icmp_start(size_t len, struct icmp i);
-void icmp_finish(uint8_t *pkt, size_t len);
+void icmp_send(const void *payload, size_t len, struct icmp i);
void ipv4_parse(const uint8_t *buf, size_t len, struct ethernet ether);
-uint8_t *ipv4_start(size_t len, struct ipv4 ip);
-void ipv4_finish(uint8_t *pkt);
+void ipv4_send(const void *payload, size_t len, struct ipv4 ip);
void ether_parse(const uint8_t *buf, size_t len);
uint8_t *ether_start(size_t len, struct ethernet ether);
diff --git a/src/user/app/ethdump/udp.c b/src/user/app/ethdump/udp.c
index 328f12b..8129a48 100644
--- a/src/user/app/ethdump/udp.c
+++ b/src/user/app/ethdump/udp.c
@@ -44,18 +44,19 @@ void udpc_close(struct udp_conn *c) {
free(c);
}
void udpc_send(struct udp_conn *c, const void *buf, size_t len) {
- uint8_t *pkt = ipv4_start(Payload + len, (struct ipv4){
- .proto = 0x11,
- .src = c->lip,
- .dst = c->rip,
- .e.dst = c->rmac,
- });
+ uint8_t *pkt = malloc(Payload + len);
nput16(pkt + SrcPort, c->lport);
nput16(pkt + DstPort, c->rport);
nput16(pkt + Length, Payload + len);
nput16(pkt + Checksum, 0);
memcpy(pkt + Payload, buf, len);
- ipv4_finish(pkt);
+ ipv4_send(pkt, Payload + len, (struct ipv4){
+ .proto = 0x11,
+ .src = c->lip,
+ .dst = c->rip,
+ .e.dst = c->rmac,
+ });
+ free(pkt);
}
@@ -83,13 +84,15 @@ void udp_parse(const uint8_t *buf, size_t len, struct ipv4 ip) {
}
if (!active) {
- uint8_t *pkt = icmp_start(4 + ip.hlen + 8, (struct icmp){
+ uint8_t *pkt = malloc(4 + ip.hlen + 8);
+ nput32(pkt, 0);
+ memcpy(pkt + 4, ip.header, ip.hlen + 8);
+ icmp_send(pkt, 4 + ip.hlen + 8, (struct icmp){
.type = 3, /* destination unreachable */
.code = 3, /* port unreachable */
.ip.dst = ip.src,
.ip.e.dst = ip.e.src,
});
- memcpy(pkt + 4, ip.header, ip.hlen + 8);
- icmp_finish(pkt, 4 + ip.hlen + 8);
+ free(pkt);
}
}