ref: fdf8af5e94a2989d1b3c94aa5c9f43139d2f56c6
parent: fd3ac94c8ba7fdd7cf2243204905a23699613423
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jun 7 12:48:04 EDT 2020
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.
--- /dev/null
+++ b/sys/src/cmd/ip/snoopy/ipmux.c
@@ -1,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
+};
--- a/sys/src/cmd/ip/snoopy/mkfile
+++ b/sys/src/cmd/ip/snoopy/mkfile
@@ -19,6 +19,7 @@
eapol\
eapol_key\
ether\
+ ipmux\
gre\
hdlc\
icmp6\
--
⑨