xref: /plan9/sys/src/cmd/ip/snoopy/udp.c (revision b4b9fc2f779153b9820efab8812e6c2c09d0221c)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <ip.h>
49a747e4fSDavid du Colombier #include "dat.h"
59a747e4fSDavid du Colombier #include "protos.h"
69a747e4fSDavid du Colombier 
79a747e4fSDavid du Colombier typedef struct Hdr	Hdr;
89a747e4fSDavid du Colombier struct Hdr
99a747e4fSDavid du Colombier {
109a747e4fSDavid du Colombier 	uchar	sport[2];	/* Source port */
119a747e4fSDavid du Colombier 	uchar	dport[2];	/* Destination port */
129a747e4fSDavid du Colombier 	uchar	len[2];		/* data length */
139a747e4fSDavid du Colombier 	uchar	cksum[2];	/* Checksum */
149a747e4fSDavid du Colombier };
159a747e4fSDavid du Colombier 
169a747e4fSDavid du Colombier enum
179a747e4fSDavid du Colombier {
189a747e4fSDavid du Colombier 	UDPLEN=	8,
199a747e4fSDavid du Colombier };
209a747e4fSDavid du Colombier 
219a747e4fSDavid du Colombier enum
229a747e4fSDavid du Colombier {
239a747e4fSDavid du Colombier 	Os,
249a747e4fSDavid du Colombier 	Od,
259a747e4fSDavid du Colombier 	Osd,
26375daca8SDavid du Colombier 	Osetport,
279a747e4fSDavid du Colombier };
289a747e4fSDavid du Colombier 
299a747e4fSDavid du Colombier static Field p_fields[] =
309a747e4fSDavid du Colombier {
319a747e4fSDavid du Colombier 	{"s",		Fnum,	Os,	"source port",	} ,
329a747e4fSDavid du Colombier 	{"d",		Fnum,	Od,	"dest port",	} ,
33dc5a79c1SDavid du Colombier 	{"a",		Fnum,	Osd,	"source/dest port",	} ,
349a747e4fSDavid du Colombier 	{"sd",		Fnum,	Osd,	"source/dest port",	} ,
359a747e4fSDavid du Colombier 	{0}
369a747e4fSDavid du Colombier };
379a747e4fSDavid du Colombier 
38375daca8SDavid du Colombier #define ANYPORT ~0UL
39375daca8SDavid du Colombier 
409a747e4fSDavid du Colombier static Mux p_mux[] =
419a747e4fSDavid du Colombier {
42*b4b9fc2fSDavid du Colombier 	{"dns",	53, },
439a747e4fSDavid du Colombier 	{"bootp",	67, },
443ff48bf5SDavid du Colombier 	{"ninep",	6346, },	/* tvs */
45375daca8SDavid du Colombier 	{"rtp",		ANYPORT, },
46375daca8SDavid du Colombier 	{"rtcp",	ANYPORT, },
479a747e4fSDavid du Colombier 	{0},
489a747e4fSDavid du Colombier };
499a747e4fSDavid du Colombier 
50375daca8SDavid du Colombier /* default next protocol, can be changed by p_filter, reset by p_compile */
51375daca8SDavid du Colombier static Proto	*defproto = &dump;
52375daca8SDavid du Colombier 
539a747e4fSDavid du Colombier static void
p_compile(Filter * f)549a747e4fSDavid du Colombier p_compile(Filter *f)
559a747e4fSDavid du Colombier {
569a747e4fSDavid du Colombier 	Mux *m;
579a747e4fSDavid du Colombier 
589a747e4fSDavid du Colombier 	if(f->op == '='){
599a747e4fSDavid du Colombier 		compile_cmp(udp.name, f, p_fields);
609a747e4fSDavid du Colombier 		return;
619a747e4fSDavid du Colombier 	}
629a747e4fSDavid du Colombier 	for(m = p_mux; m->name != nil; m++)
639a747e4fSDavid du Colombier 		if(strcmp(f->s, m->name) == 0){
649a747e4fSDavid du Colombier 			f->pr = m->pr;
659a747e4fSDavid du Colombier 			f->ulv = m->val;
663ff48bf5SDavid du Colombier 			f->subop = Osd;
679a747e4fSDavid du Colombier 			return;
689a747e4fSDavid du Colombier 		}
69375daca8SDavid du Colombier 
709a747e4fSDavid du Colombier 	sysfatal("unknown udp field or protocol: %s", f->s);
719a747e4fSDavid du Colombier }
729a747e4fSDavid du Colombier 
739a747e4fSDavid du Colombier static int
p_filter(Filter * f,Msg * m)749a747e4fSDavid du Colombier p_filter(Filter *f, Msg *m)
759a747e4fSDavid du Colombier {
769a747e4fSDavid du Colombier 	Hdr *h;
779a747e4fSDavid du Colombier 
789a747e4fSDavid du Colombier 	if(m->pe - m->ps < UDPLEN)
799a747e4fSDavid du Colombier 		return 0;
809a747e4fSDavid du Colombier 
819a747e4fSDavid du Colombier 	h = (Hdr*)m->ps;
829a747e4fSDavid du Colombier 	m->ps += UDPLEN;
839a747e4fSDavid du Colombier 
849a747e4fSDavid du Colombier 	switch(f->subop){
859a747e4fSDavid du Colombier 	case Os:
869a747e4fSDavid du Colombier 		return NetS(h->sport) == f->ulv;
879a747e4fSDavid du Colombier 	case Od:
889a747e4fSDavid du Colombier 		return NetS(h->dport) == f->ulv;
899a747e4fSDavid du Colombier 	case Osd:
90375daca8SDavid du Colombier 		if(f->ulv == ANYPORT){
91375daca8SDavid du Colombier 			defproto = f->pr;
92375daca8SDavid du Colombier 			return 1;
93375daca8SDavid du Colombier 		}
949a747e4fSDavid du Colombier 		return NetS(h->sport) == f->ulv || NetS(h->dport) == f->ulv;
959a747e4fSDavid du Colombier 	}
969a747e4fSDavid du Colombier 	return 0;
979a747e4fSDavid du Colombier }
989a747e4fSDavid du Colombier 
999a747e4fSDavid du Colombier static int
p_seprint(Msg * m)1009a747e4fSDavid du Colombier p_seprint(Msg *m)
1019a747e4fSDavid du Colombier {
1029a747e4fSDavid du Colombier 	Hdr *h;
1039a747e4fSDavid du Colombier 	int dport, sport;
1049a747e4fSDavid du Colombier 
1059a747e4fSDavid du Colombier 
1069a747e4fSDavid du Colombier 	if(m->pe - m->ps < UDPLEN)
1079a747e4fSDavid du Colombier 		return -1;
1089a747e4fSDavid du Colombier 	h = (Hdr*)m->ps;
1099a747e4fSDavid du Colombier 	m->ps += UDPLEN;
1109a747e4fSDavid du Colombier 
1119a747e4fSDavid du Colombier 	/* next protocol */
1129a747e4fSDavid du Colombier 	sport = NetS(h->sport);
1139a747e4fSDavid du Colombier 	dport = NetS(h->dport);
114375daca8SDavid du Colombier 	demux(p_mux, sport, dport, m, defproto);
115375daca8SDavid du Colombier 	defproto = &dump;
1169a747e4fSDavid du Colombier 
1179a747e4fSDavid du Colombier 	m->p = seprint(m->p, m->e, "s=%d d=%d ck=%4.4ux ln=%4d",
1189a747e4fSDavid du Colombier 			NetS(h->sport), dport,
1199a747e4fSDavid du Colombier 			NetS(h->cksum), NetS(h->len));
1209a747e4fSDavid du Colombier 	return 0;
1219a747e4fSDavid du Colombier }
1229a747e4fSDavid du Colombier 
1239a747e4fSDavid du Colombier Proto udp =
1249a747e4fSDavid du Colombier {
1259a747e4fSDavid du Colombier 	"udp",
1269a747e4fSDavid du Colombier 	p_compile,
1279a747e4fSDavid du Colombier 	p_filter,
1289a747e4fSDavid du Colombier 	p_seprint,
1299a747e4fSDavid du Colombier 	p_mux,
130ed397113SDavid du Colombier 	"%lud",
1319a747e4fSDavid du Colombier 	p_fields,
1323ff48bf5SDavid du Colombier 	defaultframer,
1339a747e4fSDavid du Colombier };
134