plan9port

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

ip.c (4310B)


      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	vihl;		/* Version and header length */
     11 	uchar	tos;		/* Type of service */
     12 	uchar	length[2];	/* packet length */
     13 	uchar	id[2];		/* ip->identification */
     14 	uchar	frag[2];	/* Fragment information */
     15 	uchar	ttl;		/* Time to live */
     16 	uchar	proto;		/* Protocol */
     17 	uchar	cksum[2];	/* Header checksum */
     18 	uchar	src[4];		/* IP source */
     19 	uchar	dst[4];		/* IP destination */
     20 };
     21 
     22 enum
     23 {
     24 	IPHDR		= 20,		/* sizeof(Iphdr) */
     25 	IP_VER		= 0x40,		/* Using IP version 4 */
     26 	IP_DF		= 0x4000,	/* Don't fragment */
     27 	IP_MF		= 0x2000,	/* More fragments */
     28 };
     29 
     30 static Mux p_mux[] =
     31 {
     32 	{ "icmp", 1, },
     33 	{ "igmp", 2, },
     34 	{ "ggp", 3, },
     35 	{ "ip", 4, },
     36 	{ "st", 5, },
     37 	{ "tcp", 6, },
     38 	{ "ucl", 7, },
     39 	{ "egp", 8, },
     40 	{ "igp", 9, },
     41 	{ "bbn-rcc-mon", 10, },
     42 	{ "nvp-ii", 11, },
     43 	{ "pup", 12, },
     44 	{ "argus", 13, },
     45 	{ "emcon", 14, },
     46 	{ "xnet", 15, },
     47 	{ "chaos", 16, },
     48 	{ "udp", 17, },
     49 	{ "mux", 18, },
     50 	{ "dcn-meas", 19, },
     51 	{ "hmp", 20, },
     52 	{ "prm", 21, },
     53 	{ "xns-idp", 22, },
     54 	{ "trunk-1", 23, },
     55 	{ "trunk-2", 24, },
     56 	{ "leaf-1", 25, },
     57 	{ "leaf-2", 26, },
     58 	{ "rdp", 27, },
     59 	{ "irtp", 28, },
     60 	{ "iso-tp4", 29, },
     61 	{ "netblt", 30, },
     62 	{ "mfe-nsp", 31, },
     63 	{ "merit-inp", 32, },
     64 	{ "sep", 33, },
     65 	{ "3pc", 34, },
     66 	{ "idpr", 35, },
     67 	{ "xtp", 36, },
     68 	{ "ddp", 37, },
     69 	{ "idpr-cmtp", 38, },
     70 	{ "tp++", 39, },
     71 	{ "il", 40, },
     72 	{ "sip", 41, },
     73 	{ "sdrp", 42, },
     74 	{ "sip-sr", 43, },
     75 	{ "sip-frag", 44, },
     76 	{ "idrp", 45, },
     77 	{ "rsvp", 46, },
     78 	{ "gre", 47, },
     79 	{ "mhrp", 48, },
     80 	{ "bna", 49, },
     81 	{ "sipp-esp", 50, },
     82 	{ "sipp-ah", 51, },
     83 	{ "i-nlsp", 52, },
     84 	{ "swipe", 53, },
     85 	{ "nhrp", 54, },
     86 	{ "any", 61, },
     87 	{ "cftp", 62, },
     88 	{ "any", 63, },
     89 	{ "sat-expak", 64, },
     90 	{ "kryptolan", 65, },
     91 	{ "rvd", 66, },
     92 	{ "ippc", 67, },
     93 	{ "any", 68, },
     94 	{ "sat-mon", 69, },
     95 	{ "visa", 70, },
     96 	{ "ipcv", 71, },
     97 	{ "cpnx", 72, },
     98 	{ "cphb", 73, },
     99 	{ "wsn", 74, },
    100 	{ "pvp", 75, },
    101 	{ "br-sat-mon", 76, },
    102 	{ "sun-nd", 77, },
    103 	{ "wb-mon", 78, },
    104 	{ "wb-expak", 79, },
    105 	{ "iso-ip", 80, },
    106 	{ "vmtp", 81, },
    107 	{ "secure-vmtp", 82, },
    108 	{ "vines", 83, },
    109 	{ "ttp", 84, },
    110 	{ "nsfnet-igp", 85, },
    111 	{ "dgp", 86, },
    112 	{ "tcf", 87, },
    113 	{ "igrp", 88, },
    114 	{ "ospf", 89, },
    115 	{ "sprite-rpc", 90, },
    116 	{ "larp", 91, },
    117 	{ "mtp", 92, },
    118 	{ "ax.25", 93, },
    119 	{ "ipip", 94, },
    120 	{ "micp", 95, },
    121 	{ "scc-sp", 96, },
    122 	{ "etherip", 97, },
    123 	{ "encap", 98, },
    124 	{ "any", 99, },
    125 	{ "gmtp", 100, },
    126 	{ "rudp", 254, },
    127 	{ 0 }
    128 };
    129 
    130 enum
    131 {
    132 	Os,	/* source */
    133 	Od,	/* destination */
    134 	Osd,	/* source or destination */
    135 	Ot,	/* type */
    136 };
    137 
    138 static Field p_fields[] =
    139 {
    140 	{"s",	Fv4ip,	Os,	"source address",	} ,
    141 	{"d",	Fv4ip,	Od,	"destination address",	} ,
    142 	{"a",	Fv4ip,	Osd,	"source|destination address",} ,
    143 	{"sd",	Fv4ip,	Osd,	"source|destination address",} ,
    144 	{"t",	Fnum,	Ot,	"sub protocol number",	} ,
    145 	{0}
    146 };
    147 
    148 static void
    149 p_compile(Filter *f)
    150 {
    151 	Mux *m;
    152 
    153 	if(f->op == '='){
    154 		compile_cmp(ip.name, f, p_fields);
    155 		return;
    156 	}
    157 	for(m = p_mux; m->name != nil; m++)
    158 		if(strcmp(f->s, m->name) == 0){
    159 			f->pr = m->pr;
    160 			f->ulv = m->val;
    161 			f->subop = Ot;
    162 			return;
    163 		}
    164 	sysfatal("unknown ip field or protocol: %s", f->s);
    165 }
    166 
    167 static int
    168 p_filter(Filter *f, Msg *m)
    169 {
    170 	Hdr *h;
    171 
    172 	if(m->pe - m->ps < IPHDR)
    173 		return 0;
    174 
    175 	h = (Hdr*)m->ps;
    176 	m->ps += ((h->vihl&0xf)<<2);
    177 
    178 	switch(f->subop){
    179 	case Os:
    180 		return NetL(h->src) == f->ulv;
    181 	case Od:
    182 		return NetL(h->dst) == f->ulv;
    183 	case Osd:
    184 		return NetL(h->src) == f->ulv || NetL(h->dst) == f->ulv;
    185 	case Ot:
    186 		return h->proto == f->ulv;
    187 	}
    188 	return 0;
    189 }
    190 
    191 static int
    192 p_seprint(Msg *m)
    193 {
    194 	Hdr *h;
    195 	int f;
    196 	int len;
    197 
    198 	if(m->pe - m->ps < IPHDR)
    199 		return -1;
    200 	h = (Hdr*)m->ps;
    201 
    202 	/* next protocol, just dump unless this is the first fragment */
    203 	m->pr = &dump;
    204 	f = NetS(h->frag);
    205 	if((f & ~(IP_DF|IP_MF)) == 0)
    206 		demux(p_mux, h->proto, h->proto, m, &dump);
    207 
    208 	/* truncate the message if there's extra */
    209 	len = NetS(h->length);
    210 	if(len < m->pe - m->ps)
    211 		m->pe = m->ps + len;
    212 
    213 	/* next header */
    214 	m->ps += ((h->vihl&0xf)<<2);
    215 
    216 	m->p = seprint(m->p, m->e, "s=%V d=%V id=%4.4ux frag=%4.4ux ttl=%3d pr=%d ln=%d",
    217 			h->src, h->dst,
    218 			NetS(h->id),
    219 			NetS(h->frag),
    220 			h->ttl,
    221 			h->proto,
    222 			NetS(h->length)
    223 			);
    224 	return 0;
    225 }
    226 
    227 Proto ip =
    228 {
    229 	"ip",
    230 	p_compile,
    231 	p_filter,
    232 	p_seprint,
    233 	p_mux,
    234 	"%lud",
    235 	p_fields,
    236 	defaultframer
    237 };