From 9895b548037cb63de561594d517520c738b31943 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 25 Sep 2025 22:47:48 -0400 Subject: link: Introduce squeaking (peer discovery) A machine may decide to squeak at another machine, those who are listening shall squeak back to announce their presence on the wire. Signed-off-by: Ian Moffett --- src/dgram/dgram_link.c | 62 +++++++++++++++++++++++++++++++++++++++++++++----- src/dgram/dgram_subr.c | 3 ++- src/include/dgram.h | 39 +++++++++++++++++++++++++++++-- 3 files changed, 95 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/dgram/dgram_link.c b/src/dgram/dgram_link.c index 1ebe353..145e716 100644 --- a/src/dgram/dgram_link.c +++ b/src/dgram/dgram_link.c @@ -45,11 +45,13 @@ * @dst: Destination MAC address * @buf: Buffer to use * @len: Length to transmit + * @type: Packet type to use */ struct dgram_params { mac_addr_t dst; void *buf; uint16_t len; + uint8_t type; }; /* @@ -91,7 +93,7 @@ dgram_do_send(struct onet_link *link, struct dgram_params *params) saddr.sll_ifindex = link->iface_idx; saddr.sll_halen = HW_ADDR_LEN; ether_load_route(link->hwaddr, params->dst, eth); - dgram_load(params->len, 50, dgram); + dgram_load(params->len, 50, params->type, dgram); sendto( link->sockfd, p, dgram_len, 0, (struct sockaddr *)&saddr, sizeof(struct sockaddr_ll) @@ -101,6 +103,37 @@ dgram_do_send(struct onet_link *link, struct dgram_params *params) return params->len; } +/* + * Squeak back at a machine that squeaks at + * us. + * + * @link: Link to squeak through + * @src: Who squeaked first? + * @dst: Who was intended to be squeaked at? + */ +static int +squeak_back(struct onet_link *link, mac_addr_t src, mac_addr_t dst) +{ + /* + * If one were to spoof their address as the broadcast + * address, that could end up VERY badly as it would + * result in a feedback loop. + */ + if (src == MAC_BROADCAST) { + return -1; + } + + /* + * If we were not intended and this was a not broadcast + * squeak, it must have been directed to another node. + */ + if (dst != link->hwaddr && dst != MAC_BROADCAST) { + return -1; + } + + return dgram_squeak(link, src); +} + tx_len_t dgram_send(struct onet_link *link, mac_addr_t dst, void *buf, uint16_t len) { @@ -109,6 +142,20 @@ dgram_send(struct onet_link *link, mac_addr_t dst, void *buf, uint16_t len) params.dst = dst; params.buf = buf; params.len = len; + params.type = OTYPE_DATA; + return dgram_do_send(link, ¶ms); +} + +tx_len_t +dgram_squeak(struct onet_link *link, mac_addr_t dst) +{ + struct dgram_params params; + uint8_t pad[8]; + + params.dst = dst; + params.buf = pad; + params.len = sizeof(pad); + params.type = OTYPE_SQUEAK; return dgram_do_send(link, ¶ms); } @@ -122,7 +169,7 @@ dgram_recv(struct onet_link *link, void *buf, uint16_t len) size_t dgram_len, recv_len; uint32_t crc; uint16_t proto; - mac_addr_t dest_mac; + mac_addr_t dest_mac, src_mac; char *p; if (link == NULL || buf == NULL) { @@ -158,10 +205,7 @@ dgram_recv(struct onet_link *link, void *buf, uint16_t len) hdr = (void *)p; proto = ntohs(hdr->proto); dest_mac = mac_swap(hdr->dest); - - if (recv_len != dgram_len) { - continue; - } + src_mac = mac_swap(hdr->source); if (proto != PROTO_ID) { continue; @@ -173,6 +217,12 @@ dgram_recv(struct onet_link *link, void *buf, uint16_t len) continue; } + /* Is this a squeak? */ + if (o1p_hdr->type == OTYPE_SQUEAK) { + squeak_back(link, src_mac, dest_mac); + continue; + } + /* If this is for everyone, take it */ if (dest_mac == MAC_BROADCAST) { break; diff --git a/src/dgram/dgram_subr.c b/src/dgram/dgram_subr.c index fda8178..a4712d5 100644 --- a/src/dgram/dgram_subr.c +++ b/src/dgram/dgram_subr.c @@ -34,7 +34,7 @@ #include "crc.h" int -dgram_load(uint16_t length, uint8_t port, struct onet_dgram *res) +dgram_load(uint16_t length, uint8_t port, uint8_t type, struct onet_dgram *res) { if (res == NULL) { return -EINVAL; @@ -43,6 +43,7 @@ dgram_load(uint16_t length, uint8_t port, struct onet_dgram *res) memset(res, 0, sizeof(*res)); res->length = (length >> 8) & 0xFF; res->length |= (length & 0xFF) << 8; + res->type = type; res->port = port; res->crc32 = crc32(res, sizeof(*res) - sizeof(res->crc32)); return 0; diff --git a/src/include/dgram.h b/src/include/dgram.h index 31f7c03..779c7ef 100644 --- a/src/include/dgram.h +++ b/src/include/dgram.h @@ -42,6 +42,7 @@ typedef tx_len_t rx_len_t; * * @length: Packet length in bytes * @reserved: Reserved for future use + * @type: Describes the type of packet (see OTYPE_*) * @reserved1: Reserved for future use * @port: Datagram port number to send on * @crc32: CRC32 checksum of data + header @@ -49,11 +50,30 @@ typedef tx_len_t rx_len_t; struct onet_dgram { uint16_t length; uint16_t reserved; - uint16_t reserved1; + uint8_t type : 3; + uint16_t reserved1 : 13; uint8_t port; uint32_t crc32; } __attribute__((packed)); +/* + * ONET packet types + * + * @OTYPE_DATA: Regular data to be sent + * @OTYPE_SQUEAK: For peer discovery + * + * [ALL OTHER VALUES ARE RESERVED] + * + * -- Squeaks -- + * + * A machine may squeak at the wire and those whom the squeak is + * intended for shall squeak back. One thing to be aware of is that + * this may allow squeak storms / attacks where a machine continuously + * squeaks at a wire. + */ +#define OTYPE_DATA 0x0 +#define OTYPE_SQUEAK 0x1 + /* * Get the total length of a datagram including * the length of the ethernet header and the header @@ -81,12 +101,16 @@ struct onet_dgram { * * @length: Length of a packet to send * @port: Port number to send on + * @type: Packet type (OTYPE_*) * @res: Result is written here * * Returns zero on success, otherwise a less than zero * value on failure. */ -int dgram_load(uint16_t length, uint8_t port, struct onet_dgram *res); +int dgram_load( + uint16_t length, uint8_t port, + uint8_t type, struct onet_dgram *res +); /* * Send a datagram through ONET @@ -104,6 +128,17 @@ tx_len_t dgram_send( void *buf, uint16_t len ); +/* + * Send a squeak through a wire + * + * @link: Link to squeak through + * @dst: Destination address to squeak at + * + * Returns the length of the squeak on success, otherwise + * a less than zero value on failure. + */ +tx_len_t dgram_squeak(struct onet_link *link, mac_addr_t dst); + /* * Get data from an ONET link * -- cgit v1.2.3