diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dgram/dgram_link.c | 69 | ||||
-rw-r--r-- | src/include/dgram.h | 9 | ||||
-rw-r--r-- | src/include/if_ether.h | 4 | ||||
-rw-r--r-- | src/link/if_ether.c | 15 | ||||
-rw-r--r-- | src/link/link_subr.c | 2 | ||||
-rw-r--r-- | src/main.c | 38 |
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; } @@ -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; } |