]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/snoopy/ip.c
ip/cifsd: fix %.*s format xdirflush() path
[plan9front.git] / sys / src / cmd / ip / snoopy / ip.c
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         int f, len;
195         Hdr *h;
196
197         if(m->pe - m->ps < IPHDR)
198                 return -1;
199         h = (Hdr*)m->ps;
200
201         /* next protocol, just dump unless this is the first fragment */
202         m->pr = &dump;
203         f = NetS(h->frag);
204         if((f & ~(IP_DF|IP_MF)) == 0)
205                 demux(p_mux, h->proto, h->proto, m, &dump);
206
207         /* truncate the message if there's extra */
208         len = NetS(h->length);
209         if(len < m->pe - m->ps)
210                 m->pe = m->ps + len;
211
212         /* next header */
213         m->ps += (h->vihl  &0xf) << 2;
214
215         m->p = seprint(m->p, m->e, "s=%V d=%V id=%4.4ux frag=%4.4ux ttl=%3d pr=%d ln=%d",
216                 h->src, h->dst, NetS(h->id), NetS(h->frag), h->ttl, h->proto,
217                 NetS(h->length));
218         return 0;
219 }
220
221 Proto ip =
222 {
223         "ip",
224         p_compile,
225         p_filter,
226         p_seprint,
227         p_mux,
228         "%lud",
229         p_fields,
230         defaultframer,
231 };