shithub: riscv

Download patch

ref: fd1cfc824aa780c784fbb001932b7c51842cc919
parent: 9944e16b16ab7eaa517a2c1eacffb2b936f51e45
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Feb 26 22:33:01 EST 2022

snoopy: add vlan protocol (802.1q)

--- a/sys/src/cmd/ip/snoopy/ether.c
+++ b/sys/src/cmd/ip/snoopy/ether.c
@@ -16,7 +16,7 @@
 #define	ETHERMAXTU	1514	/* maximum transmit size */
 #define ETHERHDRSIZE	14	/* size of an ethernet header */
 
-static Mux p_mux[] =
+Mux ethertypes[] =
 {
 	{"ip",		0x0800,	} ,
 	{"arp",		0x0806,	} ,
@@ -27,6 +27,7 @@
 	{"eapol",	0x888e, },
 	{"aoe",		0x88a2, } ,
 	{"cec",		0xbcbc, } ,
+	{"vlan",	0x8100, } ,
 	{0}
 };
 
@@ -57,7 +58,7 @@
 		compile_cmp(ether.name, f, p_fields);
 		return;
 	}
-	for(m = p_mux; m->name != nil; m++)
+	for(m = ethertypes; m->name != nil; m++)
 		if(strcmp(f->s, m->name) == 0){
 			f->pr = m->pr;
 			f->ulv = m->val;
@@ -106,7 +107,7 @@
 	m->ps += ETHERHDRSIZE;
 
 	t = NetS(h->type);
-	demux(p_mux, t, t, m, &dump);
+	demux(ethertypes, 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);
@@ -119,7 +120,7 @@
 	p_compile,
 	p_filter,
 	p_seprint,
-	p_mux,
+	ethertypes,
 	"%#.4lux",
 	p_fields,
 	defaultframer
--- a/sys/src/cmd/ip/snoopy/mkfile
+++ b/sys/src/cmd/ip/snoopy/mkfile
@@ -43,6 +43,7 @@
 	tcp\
 	ttls\
 	udp\
+	vlan\
 
 POBJS=${PROTOS:%=%.$O}
 
--- /dev/null
+++ b/sys/src/cmd/ip/snoopy/vlan.c
@@ -1,0 +1,104 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+
+extern Mux ethertypes[];
+
+typedef struct Hdr	Hdr;
+struct Hdr {
+	uchar	tag[2];
+	uchar	type[2];
+};
+
+enum
+{
+	Ov,	/* vlan */
+	Oq,	/* qprio */
+	Ot,	/* type */
+};
+
+static Field p_fields[] =
+{
+	{"v",	Fnum,	Ov,	"vlan id" } ,
+	{"q",	Fnum,	Oq,	"queue prio" } ,
+	{"t",	Fnum,	Ot,	"type" } ,
+	{0}
+};
+
+static void
+p_compile(Filter *f)
+{
+	Mux *m;
+
+	if(f->op == '='){
+		compile_cmp(vlan.name, f, p_fields);
+		return;
+	}
+	for(m = ethertypes; 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 vlan field or protocol: %s", f->s);
+}
+
+static int
+p_filter(Filter *f, Msg *m)
+{
+	Hdr *h;
+
+	if(m->pe - m->ps < 4)
+		return 0;
+
+	h = (Hdr*)m->ps;
+	m->ps += 4;
+
+	switch(f->subop){
+	case Ov:
+		return (NetS(h->tag) & 0xFFF) == f->ulv;
+	case Oq:
+		return (NetS(h->tag) >> 12) == f->ulv;
+	case Ot:
+		return NetS(h->type) == f->ulv;
+	}
+	return 0;
+}
+
+static int
+p_seprint(Msg *m)
+{
+	uint v, q, t;
+	int len;
+	Hdr *h;
+
+	len = m->pe - m->ps;
+	if(len < 4)
+		return -1;
+
+	h = (Hdr*)m->ps;
+	m->ps += 4;
+
+	q = NetS(h->tag) >> 12;
+	v = NetS(h->tag) & 0xFFF;
+	t = NetS(h->type);
+	demux(ethertypes, t, t, m, &dump);
+
+	m->p = seprint(m->p, m->e, "v=%ud q=%ux pr=%4.4ux ln=%d", v, q, t, len);
+	return 0;
+}
+
+Proto vlan =
+{
+	"vlan",
+	p_compile,
+	p_filter,
+	p_seprint,
+	ethertypes,
+	"%#.4lux",
+	p_fields,
+	defaultframer
+};