Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "dat.h"
5 #include "protos.h"
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 };
16 enum
17 {
18 UDPLEN= 8
19 };
21 enum
22 {
23 Os,
24 Od,
25 Osd,
26 Osetport
27 };
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 };
38 #define ANYPORT ~0UL
40 static Mux p_mux[] =
41 {
42 {"bootp", 67, },
43 {"ninep", 6346, }, /* tvs */
44 {"dns", 53 },
45 {"rtp", ANYPORT, },
46 {"rtcp", ANYPORT, },
47 {0}
48 };
50 /* default next protocol, can be changed by p_filter, reset by p_compile */
51 static Proto *defproto = &dump;
53 static void
54 p_compile(Filter *f)
55 {
56 Mux *m;
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 }
70 sysfatal("unknown udp field or protocol: %s", f->s);
71 }
73 static int
74 p_filter(Filter *f, Msg *m)
75 {
76 Hdr *h;
78 if(m->pe - m->ps < UDPLEN)
79 return 0;
81 h = (Hdr*)m->ps;
82 m->ps += UDPLEN;
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 }
99 static int
100 p_seprint(Msg *m)
102 Hdr *h;
103 int dport, sport;
106 if(m->pe - m->ps < UDPLEN)
107 return -1;
108 h = (Hdr*)m->ps;
109 m->ps += UDPLEN;
111 /* next protocol */
112 sport = NetS(h->sport);
113 dport = NetS(h->dport);
114 demux(p_mux, sport, dport, m, defproto);
115 defproto = &dump;
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;
123 Proto udp =
125 "udp",
126 p_compile,
127 p_filter,
128 p_seprint,
129 p_mux,
130 "%lud",
131 p_fields,
132 defaultframer
133 };