summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-09-25 14:23:36 -0400
committerIan Moffett <ian@osmora.org>2025-09-25 14:23:36 -0400
commitafcdcf6ae6d95eb828733994c7de30f8ab095dcc (patch)
treee45ee28dc7bff6da7ab0d5f6a3e2b27c6ac36aa8 /src
parent25872d593fc4f9d2845ef6f676ce4ec3d55e9aac (diff)
dgram: Add support for data reception
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src')
-rw-r--r--src/dgram/dgram_link.c69
-rw-r--r--src/include/dgram.h9
-rw-r--r--src/include/if_ether.h4
-rw-r--r--src/link/if_ether.c15
-rw-r--r--src/link/link_subr.c2
-rw-r--r--src/main.c38
6 files changed, 121 insertions, 16 deletions
diff --git a/src/dgram/dgram_link.c b/src/dgram/dgram_link.c
index eec8697..47646d6 100644
--- a/src/dgram/dgram_link.c
+++ b/src/dgram/dgram_link.c
@@ -79,3 +79,72 @@ dgram_send(struct onet_link *link, mac_addr_t dst, void *buf, uint16_t len)
free(p);
return len;
}
+
+rx_len_t
+dgram_recv(struct onet_link *link, void *buf, uint16_t len)
+{
+ socklen_t addr_len;
+ struct sockaddr_ll saddr;
+ struct ether_hdr *hdr;
+ size_t dgram_len, recv_len;
+ uint16_t proto;
+ mac_addr_t dest_mac;
+ char *p;
+
+ if (link == NULL || buf == NULL) {
+ return -1;
+ }
+
+ if (len == 0) {
+ return -1;
+ }
+
+ /* Allocate an RX buffer */
+ dgram_len = DGRAM_LEN(len);
+ p = malloc(dgram_len);
+ if (p == NULL) {
+ return -1;
+ }
+
+ addr_len = sizeof(struct sockaddr_ll);
+ saddr.sll_ifindex = link->iface_idx;
+ saddr.sll_halen = HW_ADDR_LEN;
+
+ /*
+ * Wait until we get a packet for us with the right
+ * protocol ID.
+ */
+ for (;;) {
+ recv_len = recvfrom(
+ link->sockfd, p, dgram_len,
+ 0, (struct sockaddr *)&saddr,
+ &addr_len
+ );
+
+ hdr = (void *)p;
+ proto = ntohs(hdr->proto);
+ dest_mac = mac_swap(hdr->dest);
+
+ if (recv_len != dgram_len) {
+ continue;
+ }
+
+ if (proto != PROTO_ID) {
+ continue;
+ }
+
+ /* If this is for everyone, take it */
+ if (dest_mac == MAC_BROADCAST) {
+ break;
+ }
+
+ /* If this is for us, take it */
+ if (dest_mac == link->hwaddr) {
+ break;
+ }
+ }
+
+ memcpy(buf, DGRAM_DATA(p), len);
+ free(p);
+ return dgram_len;
+}
diff --git a/src/include/dgram.h b/src/include/dgram.h
index 9c87b81..0f798ee 100644
--- a/src/include/dgram.h
+++ b/src/include/dgram.h
@@ -35,6 +35,7 @@
#include "link.h"
typedef int16_t tx_len_t;
+typedef tx_len_t rx_len_t;
/*
* Represents an ONET datagram
@@ -103,5 +104,13 @@ tx_len_t dgram_send(
void *buf, uint16_t len
);
+/*
+ * Get data from an ONET link
+ *
+ * @link: The ONET link to recv data from
+ * @buf: The buffer to recv data into
+ * @len: The length of expected data
+ */
+rx_len_t dgram_recv(struct onet_link *link, void *buf, uint16_t len);
#endif /* DGRAM_H */
diff --git a/src/include/if_ether.h b/src/include/if_ether.h
index 0cdf2fa..4da9b7a 100644
--- a/src/include/if_ether.h
+++ b/src/include/if_ether.h
@@ -33,8 +33,8 @@
#include <stdint.h>
#define HW_ADDR_LEN 6
-#define PROTO_IPV4 0x0800
-#define PROTO_ARP 0x0806
+#define PROTO_ID 0x88B5
+#define MAC_BROADCAST 0xFFFFFFFFFFFF
typedef uint64_t mac_addr_t;
diff --git a/src/link/if_ether.c b/src/link/if_ether.c
index 48b4f19..6043810 100644
--- a/src/link/if_ether.c
+++ b/src/link/if_ether.c
@@ -32,15 +32,6 @@
#include <string.h>
#include "if_ether.h"
-/*
- * Using the protocol ID 0xFD for testing,
- * see RFC 3692
- */
-#define PROTO_ID 0xFD
-
-/* 48-bit mask for MAC addresses */
-#define MAC_MASK 0xFFFFFFFFFFFF
-
int
ether_load_route(mac_addr_t src, mac_addr_t dest, struct ether_hdr *res)
{
@@ -65,6 +56,10 @@ ether_load_route(mac_addr_t src, mac_addr_t dest, struct ether_hdr *res)
res->dest[3] = (dest >> 16) & 0xFF;
res->dest[4] = (dest >> 8) & 0xFF;
res->dest[5] = dest & 0xFF;
- res->proto = PROTO_ID;
+
+ /* Setup the protocl ID */
+ res->proto = 0;
+ res->proto |= (PROTO_ID & 0xFF) << 8;
+ res->proto |= (PROTO_ID >> 8) & 0xFF;
return 0;
}
diff --git a/src/link/link_subr.c b/src/link/link_subr.c
index d1a977d..297e720 100644
--- a/src/link/link_subr.c
+++ b/src/link/link_subr.c
@@ -50,7 +50,7 @@ onet_open(const char *iface, struct onet_link *res)
}
/* Open a raw socket */
- res->sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
+ res->sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (res->sockfd < 0) {
return res->sockfd;
}
diff --git a/src/main.c b/src/main.c
index 5cdcc63..c2087e7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,6 +35,7 @@
#include <net/ethernet.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include "if_ether.h"
@@ -44,6 +45,7 @@
#define TEST_STR "Hello from o.1p!! Meow meow!"
static const char *iface = NULL;
+static bool do_recv = false;
static void
help(char **argv)
@@ -78,10 +80,36 @@ data_send(void)
return 0;
}
+static int
+data_recv(void)
+{
+ char buf[sizeof(TEST_STR) + 8];
+ struct onet_link link;
+ int error;
+
+ /* Open a link */
+ error = onet_open(iface, &link);
+ if (error < 0) {
+ return error;
+ }
+
+ memset(buf, 0, sizeof(buf));
+
+ /* Recv data */
+ dgram_recv(
+ &link, buf,
+ sizeof(TEST_STR)
+ );
+
+ printf("%s\n", buf);
+ onet_close(&link);
+ return 0;
+}
+
int
main(int argc, char **argv)
{
- int opt;
+ int opt, error;
if (argc < 2) {
printf("error: too few arguments!\n");
@@ -89,7 +117,7 @@ main(int argc, char **argv)
return -1;
}
- while ((opt = getopt(argc, argv, "i:h")) != -1) {
+ while ((opt = getopt(argc, argv, "i:hr")) != -1) {
switch (opt) {
case 'h':
help(argv);
@@ -97,6 +125,9 @@ main(int argc, char **argv)
case 'i':
iface = optarg;
break;
+ case 'r':
+ do_recv = true;
+ break;
}
}
@@ -106,5 +137,6 @@ main(int argc, char **argv)
return -1;
}
- return data_send();
+ error = do_recv ? data_recv() : data_send();
+ return error;
}