changeset 4454:1037d1e35cd8 draft

BPF: Set flag indicate whether the packet was broadcast or not
author Roy Marples <roy@marples.name>
date Thu, 18 Apr 2019 16:56:34 +0100
parents 00fb50fd1a45
children 767d7b8a78cb
files src/bpf.c src/bpf.h
diffstat 2 files changed, 25 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/bpf.c	Thu Apr 18 14:54:47 2019 +0100
+++ b/src/bpf.c	Thu Apr 18 16:56:34 2019 +0100
@@ -84,7 +84,7 @@
 bpf_frame_header_len(const struct interface *ifp)
 {
 
-	switch(ifp->family) {
+	switch (ifp->family) {
 	case ARPHRD_ETHER:
 		return sizeof(struct ether_header);
 	default:
@@ -92,6 +92,23 @@
 	}
 }
 
+static const uint8_t etherbroadcastaddr[] =
+    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+static int
+bpf_frame_bcast(const struct interface *ifp, const char *frame)
+{
+
+	switch (ifp->family) {
+	case ARPHRD_ETHER:
+		return memcmp(frame +
+		    offsetof(struct ether_header, ether_dhost),
+		    etherbroadcastaddr, sizeof(etherbroadcastaddr));
+	default:
+		return -1;
+	}
+}
+
 #ifndef __linux__
 /* Linux is a special snowflake for opening, attaching and reading BPF.
  * See if-linux.c for the Linux specific BPF functions. */
@@ -227,8 +244,12 @@
 		if (state->buffer_pos + packet.bh_caplen + packet.bh_hdrlen >
 		    state->buffer_len)
 			goto next; /* Packet beyond buffer, drop. */
-		payload = state->buffer + state->buffer_pos +
-		    packet.bh_hdrlen + fl;
+		payload = state->buffer + state->buffer_pos + packet.bh_hdrlen;
+		if (bpf_frame_bcast(ifp, payload) == 0)
+			*flags |= BPF_BCAST;
+		else
+			*flags &= ~BPF_BCAST;
+		payload += fl;
 		bytes = (ssize_t)packet.bh_caplen - fl;
 		if ((size_t)bytes > len)
 			bytes = (ssize_t)len;
--- a/src/bpf.h	Thu Apr 18 14:54:47 2019 +0100
+++ b/src/bpf.h	Thu Apr 18 16:56:34 2019 +0100
@@ -31,6 +31,7 @@
 #define	BPF_READING		(1U << 0)
 #define	BPF_EOF			(1U << 1)
 #define	BPF_PARTIALCSUM		(1U << 2)
+#define	BPF_BCAST		(1U << 3)
 
 #include "dhcpcd.h"