summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fw/src/ether.c23
-rw-r--r--fw/src/fw.c3
2 files changed, 26 insertions, 0 deletions
diff --git a/fw/src/ether.c b/fw/src/ether.c
index d77143a..48f69b9 100644
--- a/fw/src/ether.c
+++ b/fw/src/ether.c
@@ -292,6 +292,29 @@ arpin(uchar *f, int n)
write(efd, r, sizeof r);
}
+/*
+ * Is this frame ours to look at?
+ *
+ * The card is promiscuous and has to be: the stack behind fw joins
+ * multicast groups on a pkt interface, which has no way to tell a card
+ * about them, so without it the groups would never be received. What
+ * promiscuous adds beyond that is other machines' unicast, and handing
+ * that to the protected stack means judging it, counting it and
+ * tracking flows for conversations that were never ours. ethermux
+ * would have given us frames addressed to this card plus broadcast and
+ * multicast for nothing; this puts back the filter that asking for
+ * promiscuous took away.
+ */
+int
+etherforme(uchar *f, int n)
+{
+ if(n < Ehdrlen)
+ return 0;
+ if((f[0] & 1) != 0) /* group: broadcast or multicast */
+ return 1;
+ return memcmp(f, ourmac, Eaddrlen) == 0;
+}
+
int
etherisarp(uchar *f, int n)
{
diff --git a/fw/src/fw.c b/fw/src/fw.c
index 8901c2a..6ae38df 100644
--- a/fw/src/fw.c
+++ b/fw/src/fw.c
@@ -378,6 +378,7 @@ flowadd(Pkt *p)
void servenet(char*, char*, char*);
int etheropen(char*, uchar*);
void ethersetaddr(uchar*, uchar*, int);
+int etherforme(uchar*, int);
int etherisarp(uchar*, int);
int etherisip(uchar*, int);
int etherwriteip(uchar*, int, uchar*, int, uchar*);
@@ -1093,6 +1094,8 @@ etherin(void *a)
}
if(debug > 1)
fprint(2, "wire: %d bytes type %.4ux\n", n, (buf[12]<<8)|buf[13]);
+ if(!etherforme(buf, n)) /* the wire's, not ours */
+ continue;
if(etherisarp(buf, n))
continue;
if(!etherisip(buf, n))