aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ip/snoopy/ether.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-12-26 04:48:52 +0000
committerrsc <devnull@localhost>2005-12-26 04:48:52 +0000
commit87a52e0485d3281ebea6bf4b725aa8023690e96f (patch)
tree0abc2d2ddb875196177231639d3cb4519e814b9d /src/cmd/ip/snoopy/ether.c
parent35d26aa32167e84326cdb745c0e906393b8de71d (diff)
downloadplan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.gz
plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.bz2
plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.zip
new goodies
Diffstat (limited to 'src/cmd/ip/snoopy/ether.c')
-rwxr-xr-xsrc/cmd/ip/snoopy/ether.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/cmd/ip/snoopy/ether.c b/src/cmd/ip/snoopy/ether.c
new file mode 100755
index 00000000..62ec485d
--- /dev/null
+++ b/src/cmd/ip/snoopy/ether.c
@@ -0,0 +1,121 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+
+typedef struct Hdr Hdr;
+struct Hdr {
+ uchar d[6];
+ uchar s[6];
+ uchar type[2];
+ char data[1500];
+};
+#define ETHERMINTU 60 /* minimum transmit size */
+#define ETHERMAXTU 1514 /* maximum transmit size */
+#define ETHERHDRSIZE 14 /* size of an ethernet header */
+
+static Mux p_mux[] =
+{
+ {"ip", 0x0800, } ,
+ {"arp", 0x0806, } ,
+ {"rarp", 0x0806, } ,
+ {"ip6", 0x86dd, } ,
+ {"pppoe_disc", 0x8863, },
+ {"pppoe_sess", 0x8864, },
+ {0}
+};
+
+enum
+{
+ Os, // source
+ Od, // destination
+ Oa, // source or destination
+ Ot, // type
+};
+
+static Field p_fields[] =
+{
+ {"s", Fether, Os, "source address", } ,
+ {"d", Fether, Od, "destination address", } ,
+ {"a", Fether, Oa, "source|destination address" } ,
+ {"sd", Fether, Oa, "source|destination address" } ,
+ {"t", Fnum, Ot, "type" } ,
+ {0}
+};
+
+static void
+p_compile(Filter *f)
+{
+ Mux *m;
+
+ if(f->op == '='){
+ compile_cmp(ether.name, f, p_fields);
+ return;
+ }
+ for(m = p_mux; m->name != nil; m++)
+ if(strcmp(f->s, m->name) == 0){
+ f->pr = m->pr;
+ f->ulv = m->val;
+ f->subop = Ot;
+ return;
+ }
+ sysfatal("unknown ethernet field or protocol: %s", f->s);
+}
+
+static int
+p_filter(Filter *f, Msg *m)
+{
+ Hdr *h;
+
+ if(m->pe - m->ps < ETHERHDRSIZE)
+ return 0;
+
+ h = (Hdr*)m->ps;
+ m->ps += ETHERHDRSIZE;
+
+ switch(f->subop){
+ case Os:
+ return !memcmp(h->s, f->a, 6);
+ case Od:
+ return !memcmp(h->d, f->a, 6);
+ case Oa:
+ return memcmp(h->s, f->a, 6) == 0 || memcmp(h->d, f->a, 6) == 0;
+ case Ot:
+ return NetS(h->type) == f->ulv;
+ }
+ return 0;
+}
+
+static int
+p_seprint(Msg *m)
+{
+ Hdr *h;
+ uint t;
+ int len;
+
+ len = m->pe - m->ps;
+ if(len < ETHERHDRSIZE)
+ return -1;
+
+ h = (Hdr*)m->ps;
+ m->ps += ETHERHDRSIZE;
+
+ t = NetS(h->type);
+ demux(p_mux, t, t, m, &dump);
+
+ m->p = seprint(m->p, m->e, "s=%E d=%E pr=%4.4ux ln=%d", h->s, h->d,
+ t, len);
+ return 0;
+}
+
+Proto ether =
+{
+ "ether",
+ p_compile,
+ p_filter,
+ p_seprint,
+ p_mux,
+ p_fields,
+ defaultframer
+};