diff options
Diffstat (limited to 'fw')
| -rw-r--r-- | fw/src/ether.c | 23 | ||||
| -rw-r--r-- | fw/src/fw.c | 3 |
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)) |
