diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-06-07 16:48:04 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-06-07 16:48:04 +0200 |
commit | 8f087e019f551078b97da4dec4973fe9979c9551 (patch) | |
tree | f2d8b26d8cad25787a0c8872cef5a3922f5b06ac /sys/src | |
parent | 85ffa283f67b4bd139a4e28e82f0d1c7f6c53b3b (diff) |
snoopy: add ipmux pseudo protocol
the ipmux pseudo protocol handles the extra ipv6 interface address
prefixed to the ip header as used by /net/ipmux packet filter.
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/cmd/ip/snoopy/ipmux.c | 103 | ||||
-rw-r--r-- | sys/src/cmd/ip/snoopy/mkfile | 1 |
2 files changed, 104 insertions, 0 deletions
diff --git a/sys/src/cmd/ip/snoopy/ipmux.c b/sys/src/cmd/ip/snoopy/ipmux.c new file mode 100644 index 000000000..0e47e687d --- /dev/null +++ b/sys/src/cmd/ip/snoopy/ipmux.c @@ -0,0 +1,103 @@ +#include <u.h> +#include <libc.h> +#include <ip.h> +#include "dat.h" +#include "protos.h" + +typedef struct Hdr Hdr; +struct Hdr { + uchar ia[16]; + uchar data[1]; +}; + +static Mux p_mux[] = +{ + {"ip", 0x40, }, + {"ip6", 0x60, }, + {0} +}; + +enum +{ + Oia, /* interface address */ + Ot, /* ip type */ +}; + +static Field p_fields[] = +{ + {"ia", Fv6ip, Oia, "interface address", }, + {"t", Fnum, Ot, "ip type" }, + {0} +}; + +static void +p_compile(Filter *f) +{ + Mux *m; + + if(f->op == '='){ + compile_cmp(ipmux.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 ipmux field or protocol: %s", f->s); +} + +static int +p_filter(Filter *f, Msg *m) +{ + Hdr *h; + + if(m->pe - m->ps <= 16) + return 0; + + h = (Hdr*)m->ps; + m->ps += 16; + + switch(f->subop){ + case Oia: + return memcmp(h->ia, f->a, 16) == 0; + case Ot: + return (h->data[0]&0xF0) == f->ulv; + } + return 0; +} + +static int +p_seprint(Msg *m) +{ + int len; + uint t; + Hdr *h; + + len = m->pe - m->ps; + if(len <= 16) + return -1; + + h = (Hdr*)m->ps; + m->ps += 16; + + t = h->data[0]&0xF0; + demux(p_mux, t, t, m, &dump); + + m->p = seprint(m->p, m->e, "ia=%I t=%2.2ux ln=%d", h->ia, t, len); + return 0; +} + +Proto ipmux = +{ + "ipmux", + p_compile, + p_filter, + p_seprint, + p_mux, + "%#.2lux", + p_fields, + defaultframer +}; diff --git a/sys/src/cmd/ip/snoopy/mkfile b/sys/src/cmd/ip/snoopy/mkfile index 69a137937..ab4e1b286 100644 --- a/sys/src/cmd/ip/snoopy/mkfile +++ b/sys/src/cmd/ip/snoopy/mkfile @@ -19,6 +19,7 @@ PROTOS=\ eapol\ eapol_key\ ether\ + ipmux\ gre\ hdlc\ icmp6\ |