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