xref: /plan9/sys/src/cmd/ip/snoopy/udp.c (revision b4b9fc2f779153b9820efab8812e6c2c09d0221c)
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	sport[2];	/* Source port */
11 	uchar	dport[2];	/* Destination port */
12 	uchar	len[2];		/* data length */
13 	uchar	cksum[2];	/* Checksum */
14 };
15 
16 enum
17 {
18 	UDPLEN=	8,
19 };
20 
21 enum
22 {
23 	Os,
24 	Od,
25 	Osd,
26 	Osetport,
27 };
28 
29 static Field p_fields[] =
30 {
31 	{"s",		Fnum,	Os,	"source port",	} ,
32 	{"d",		Fnum,	Od,	"dest port",	} ,
33 	{"a",		Fnum,	Osd,	"source/dest port",	} ,
34 	{"sd",		Fnum,	Osd,	"source/dest port",	} ,
35 	{0}
36 };
37 
38 #define ANYPORT ~0UL
39 
40 static Mux p_mux[] =
41 {
42 	{"dns",	53, },
43 	{"bootp",	67, },
44 	{"ninep",	6346, },	/* tvs */
45 	{"rtp",		ANYPORT, },
46 	{"rtcp",	ANYPORT, },
47 	{0},
48 };
49 
50 /* default next protocol, can be changed by p_filter, reset by p_compile */
51 static Proto	*defproto = &dump;
52 
53 static void
p_compile(Filter * f)54 p_compile(Filter *f)
55 {
56 	Mux *m;
57 
58 	if(f->op == '='){
59 		compile_cmp(udp.name, f, p_fields);
60 		return;
61 	}
62 	for(m = p_mux; m->name != nil; m++)
63 		if(strcmp(f->s, m->name) == 0){
64 			f->pr = m->pr;
65 			f->ulv = m->val;
66 			f->subop = Osd;
67 			return;
68 		}
69 
70 	sysfatal("unknown udp field or protocol: %s", f->s);
71 }
72 
73 static int
p_filter(Filter * f,Msg * m)74 p_filter(Filter *f, Msg *m)
75 {
76 	Hdr *h;
77 
78 	if(m->pe - m->ps < UDPLEN)
79 		return 0;
80 
81 	h = (Hdr*)m->ps;
82 	m->ps += UDPLEN;
83 
84 	switch(f->subop){
85 	case Os:
86 		return NetS(h->sport) == f->ulv;
87 	case Od:
88 		return NetS(h->dport) == f->ulv;
89 	case Osd:
90 		if(f->ulv == ANYPORT){
91 			defproto = f->pr;
92 			return 1;
93 		}
94 		return NetS(h->sport) == f->ulv || NetS(h->dport) == f->ulv;
95 	}
96 	return 0;
97 }
98 
99 static int
p_seprint(Msg * m)100 p_seprint(Msg *m)
101 {
102 	Hdr *h;
103 	int dport, sport;
104 
105 
106 	if(m->pe - m->ps < UDPLEN)
107 		return -1;
108 	h = (Hdr*)m->ps;
109 	m->ps += UDPLEN;
110 
111 	/* next protocol */
112 	sport = NetS(h->sport);
113 	dport = NetS(h->dport);
114 	demux(p_mux, sport, dport, m, defproto);
115 	defproto = &dump;
116 
117 	m->p = seprint(m->p, m->e, "s=%d d=%d ck=%4.4ux ln=%4d",
118 			NetS(h->sport), dport,
119 			NetS(h->cksum), NetS(h->len));
120 	return 0;
121 }
122 
123 Proto udp =
124 {
125 	"udp",
126 	p_compile,
127 	p_filter,
128 	p_seprint,
129 	p_mux,
130 	"%lud",
131 	p_fields,
132 	defaultframer,
133 };
134