xref: /plan9/sys/src/cmd/ip/snoopy/il.c (revision 0b9a5132554aff81f12a30adb0ffd48684252652)
1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "dat.h"
5 #include "protos.h"
6 
7 typedef struct Hdr	Hdr;
8 struct Hdr
9 {
10 	uchar	sum[2];		/* Checksum including header */
11 	uchar	len[2];		/* Packet length */
12 	uchar	type;		/* Packet type */
13 	uchar	spec;		/* Special */
14 	uchar	sport[2];	/* Src port */
15 	uchar	dport[2];	/* Dst port */
16 	uchar	id[4];		/* Sequence id */
17 	uchar	ack[4];		/* Acked sequence */
18 };
19 
20 enum
21 {
22 	ILLEN= 18,
23 };
24 
25 enum
26 {
27 	Os,
28 	Od,
29 	Osd,
30 };
31 
32 static Field p_fields[] =
33 {
34 	{"s",		Fnum,	Os,	"source port",	} ,
35 	{"d",		Fnum,	Od,	"dest port",	} ,
36 	{"a",		Fnum,	Osd,	"source/dest port",	} ,
37 	{"sd",		Fnum,	Osd,	"source/dest port",	} ,
38 	{0}
39 };
40 
41 static Mux p_mux[] =
42 {
43 	{"ninep",	17007, },	/* exportfs */
44 	{"ninep",	17008, },	/* 9fs */
45 	{"ninep",	17005, },	/* ocpu */
46 	{"ninep",	17010, },	/* ncpu */
47 	{"ninep",	17013, },	/* cpu */
48 	{0},
49 };
50 
51 static void
p_compile(Filter * f)52 p_compile(Filter *f)
53 {
54 	Mux *m;
55 
56 	if(f->op == '='){
57 		compile_cmp(il.name, f, p_fields);
58 		return;
59 	}
60 	for(m = p_mux; m->name != nil; m++)
61 		if(strcmp(f->s, m->name) == 0){
62 			f->pr = m->pr;
63 			f->ulv = m->val;
64 			f->subop = Osd;
65 			return;
66 		}
67 	sysfatal("unknown il field or protocol: %s", f->s);
68 }
69 
70 static int
p_filter(Filter * f,Msg * m)71 p_filter(Filter *f, Msg *m)
72 {
73 	Hdr *h;
74 
75 	if(m->pe - m->ps < ILLEN)
76 		return 0;
77 	h = (Hdr*)m->ps;
78 	m->ps += ILLEN;
79 
80 	switch(f->subop){
81 	case Os:
82 		return NetS(h->sport) == f->ulv;
83 	case Od:
84 		return NetS(h->dport) == f->ulv;
85 	case Osd:
86 		return NetS(h->sport) == f->ulv || NetS(h->dport) == f->ulv;
87 	}
88 	return 0;
89 }
90 
91 char *pktnames[] =
92 {
93 	"Sync",
94 	"Data",
95 	"Dataquery",
96 	"Ack",
97 	"Query",
98 	"State",
99 	"Close"
100 };
101 
102 static char*
pkttype(int t)103 pkttype(int t)
104 {
105 	static char b[10];
106 
107 	if(t > 6){
108 		sprint(b, "%d", t);
109 		return b;
110 	}
111 	return pktnames[t];
112 }
113 
114 static int
p_seprint(Msg * m)115 p_seprint(Msg *m)
116 {
117 	Hdr *h;
118 	int dport, sport;
119 
120 	if(m->pe - m->ps < ILLEN)
121 		return -1;
122 	h = (Hdr*)m->ps;
123 	m->ps += ILLEN;
124 
125 	dport = NetS(h->dport);
126 	sport = NetS(h->sport);
127 	demux(p_mux, sport, dport, m, &dump);
128 
129 	m->p = seprint(m->p, m->e, "s=%d d=%d t=%s id=%lud ack=%lud spec=%d ck=%4.4ux ln=%d",
130 			sport, dport, pkttype(h->type),
131 			(ulong)NetL(h->id), (ulong)NetL(h->ack),
132 			h->spec,
133 			NetS(h->sum), NetS(h->len));
134 	return 0;
135 }
136 
137 Proto il =
138 {
139 	"il",
140 	p_compile,
141 	p_filter,
142 	p_seprint,
143 	p_mux,
144 	"%lud",
145 	p_fields,
146 	defaultframer,
147 };
148