plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 };