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