git: 9front

Download patch

ref: 452df957d14f04ea100de1504d21db6c4695a5cc
parent: abd6a2225cd83ee64c7329e938bb8a0275b9591b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Sep 18 08:35:47 EDT 2022

snoopy: add "ippkt" protocol to demux ip packet interfaces without media header.

When using a packet interface, such as /net/ipifc/x as the
packet-soucre, there is no media header and the ip protocol
version has to be determined from the first byte.

The ippkt protocol solves this, allowing one to decode
both ipv4 and ipv6, such as:

snoopy -h ippkt /net/ipifc/2

--- a/sys/man/8/snoopy
+++ b/sys/man/8/snoopy
@@ -174,6 +174,11 @@
 protocol.
 The default is
 .LR ether .
+For packet interfaces without a media header, use
+.B ippkt
+as the
+.I first-header
+type to decode ipv4 and ipv6 packets.
 .SH EXAMPLES
 To display only
 .SM BOOTP
@@ -209,7 +214,3 @@
 Ethernet device
 .SH SOURCE
 .B /sys/src/cmd/ip/snoopy
-.SH BUGS
-.I Snoopy
-only dumps ethernet packets, because there's
-no device to get IP packets without a media header.
--- /dev/null
+++ b/sys/src/cmd/ip/snoopy/ippkt.c
@@ -1,0 +1,82 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+
+static Mux p_mux[] =
+{
+	{"ip",		0x40, },
+	{"ip6", 	0x60, },
+	{0}
+};
+
+enum
+{
+	Ot,	/* ip type */
+};
+
+static Field p_fields[] =
+{
+	{"t",	Fnum,	Ot,	"ip type" },
+	{0}
+};
+
+static void
+p_compile(Filter *f)
+{
+	Mux *m;
+
+	if(f->op == '='){
+		compile_cmp(ippkt.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 ippkt field or protocol: %s", f->s);
+}
+
+static int
+p_filter(Filter *f, Msg *m)
+{
+	if(m->ps >= m->pe)
+		return 0;
+
+	switch(f->subop){
+	case Ot:
+		return (m->ps[0]&0xF0) == f->ulv;
+	}
+	return 0;
+}
+
+static int
+p_seprint(Msg *m)
+{
+	uint t;
+
+	if(m->ps >= m->pe)
+		return -1;
+
+	t = m->ps[0]&0xF0;
+	demux(p_mux, t, t, m, &dump);
+
+	m->p = seprint(m->p, m->e, "t=%2.2ux", t);
+	return 0;
+}
+
+Proto ippkt =
+{
+	"ippkt",
+	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
@@ -20,6 +20,7 @@
 	eapol_key\
 	ether\
 	ipmux\
+	ippkt\
 	gre\
 	hdlc\
 	icmp6\
--