udp.c (2009B)
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 {"bootp", 67, }, 43 {"ninep", 6346, }, /* tvs */ 44 {"dns", 53 }, 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 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 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 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 };