tip.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tip.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… | |
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 addre… | |
143 {"sd", Fv4ip, Osd, "source|destination addr… | |
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=… | |
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 }; |