]> The Tcpdump Group git mirrors - tcpdump/blob - print-egp.c
put __attribute__((packed)) to packet headers. s/u_short/u_int16_t/ and so
[tcpdump] / print-egp.c
1 /*
2 * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Lawrence Berkeley Laboratory,
11 * Berkeley, CA. The name of the University may not be used to
12 * endorse or promote products derived from this software without
13 * specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 *
18 * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU).
19 */
20
21 #ifndef lint
22 static const char rcsid[] =
23 "@(#) $Header: /tcpdump/master/tcpdump/print-egp.c,v 1.33 2002-11-09 17:19:25 itojun Exp $ (LBL)";
24 #endif
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <tcpdump-stdinc.h>
31
32 #include <stdio.h>
33
34 #include "interface.h"
35 #include "addrtoname.h"
36
37 #include "ip.h"
38
39 struct egp_packet {
40 u_int8_t egp_version;
41 #define EGP_VERSION 2
42 u_int8_t egp_type;
43 #define EGPT_ACQUIRE 3
44 #define EGPT_REACH 5
45 #define EGPT_POLL 2
46 #define EGPT_UPDATE 1
47 #define EGPT_ERROR 8
48 u_int8_t egp_code;
49 #define EGPC_REQUEST 0
50 #define EGPC_CONFIRM 1
51 #define EGPC_REFUSE 2
52 #define EGPC_CEASE 3
53 #define EGPC_CEASEACK 4
54 #define EGPC_HELLO 0
55 #define EGPC_HEARDU 1
56 u_int8_t egp_status;
57 #define EGPS_UNSPEC 0
58 #define EGPS_ACTIVE 1
59 #define EGPS_PASSIVE 2
60 #define EGPS_NORES 3
61 #define EGPS_ADMIN 4
62 #define EGPS_GODOWN 5
63 #define EGPS_PARAM 6
64 #define EGPS_PROTO 7
65 #define EGPS_INDET 0
66 #define EGPS_UP 1
67 #define EGPS_DOWN 2
68 #define EGPS_UNSOL 0x80
69 u_int16_t egp_checksum;
70 u_int16_t egp_as;
71 u_int16_t egp_sequence;
72 union {
73 u_int16_t egpu_hello;
74 u_int8_t egpu_gws[2];
75 u_int16_t egpu_reason;
76 #define EGPR_UNSPEC 0
77 #define EGPR_BADHEAD 1
78 #define EGPR_BADDATA 2
79 #define EGPR_NOREACH 3
80 #define EGPR_XSPOLL 4
81 #define EGPR_NORESP 5
82 #define EGPR_UVERSION 6
83 } egp_handg;
84 #define egp_hello egp_handg.egpu_hello
85 #define egp_intgw egp_handg.egpu_gws[0]
86 #define egp_extgw egp_handg.egpu_gws[1]
87 #define egp_reason egp_handg.egpu_reason
88 union {
89 u_int16_t egpu_poll;
90 u_int32_t egpu_sourcenet;
91 } egp_pands;
92 #define egp_poll egp_pands.egpu_poll
93 #define egp_sourcenet egp_pands.egpu_sourcenet
94 } __attribute__((packed));
95
96 const char *egp_acquire_codes[] = {
97 "request",
98 "confirm",
99 "refuse",
100 "cease",
101 "cease_ack"
102 };
103
104 const char *egp_acquire_status[] = {
105 "unspecified",
106 "active_mode",
107 "passive_mode",
108 "insufficient_resources",
109 "administratively_prohibited",
110 "going_down",
111 "parameter_violation",
112 "protocol_violation"
113 };
114
115 const char *egp_reach_codes[] = {
116 "hello",
117 "i-h-u"
118 };
119
120 const char *egp_status_updown[] = {
121 "indeterminate",
122 "up",
123 "down"
124 };
125
126 const char *egp_reasons[] = {
127 "unspecified",
128 "bad_EGP_header_format",
129 "bad_EGP_data_field_format",
130 "reachability_info_unavailable",
131 "excessive_polling_rate",
132 "no_response",
133 "unsupported_version"
134 };
135
136 static void
137 egpnrprint(register const struct egp_packet *egp)
138 {
139 register const u_int8_t *cp;
140 u_int32_t addr;
141 register u_int32_t net;
142 register u_int netlen;
143 int gateways, distances, networks;
144 int t_gateways;
145 const char *comma;
146
147 addr = egp->egp_sourcenet;
148 if (IN_CLASSA(addr)) {
149 net = addr & IN_CLASSA_NET;
150 netlen = 1;
151 } else if (IN_CLASSB(addr)) {
152 net = addr & IN_CLASSB_NET;
153 netlen = 2;
154 } else if (IN_CLASSC(addr)) {
155 net = addr & IN_CLASSC_NET;
156 netlen = 3;
157 } else {
158 net = 0;
159 netlen = 0;
160 }
161 cp = (u_int8_t *)(egp + 1);
162
163 t_gateways = egp->egp_intgw + egp->egp_extgw;
164 for (gateways = 0; gateways < t_gateways; ++gateways) {
165 /* Pickup host part of gateway address */
166 addr = 0;
167 TCHECK2(cp[0], 4 - netlen);
168 switch (netlen) {
169
170 case 1:
171 addr = *cp++;
172 /* fall through */
173 case 2:
174 addr = (addr << 8) | *cp++;
175 /* fall through */
176 case 3:
177 addr = (addr << 8) | *cp++;
178 }
179 addr |= net;
180 TCHECK2(cp[0], 1);
181 distances = *cp++;
182 printf(" %s %s ",
183 gateways < (int)egp->egp_intgw ? "int" : "ext",
184 ipaddr_string(&addr));
185
186 comma = "";
187 putchar('(');
188 while (--distances >= 0) {
189 TCHECK2(cp[0], 2);
190 printf("%sd%d:", comma, (int)*cp++);
191 comma = ", ";
192 networks = *cp++;
193 while (--networks >= 0) {
194 /* Pickup network number */
195 TCHECK2(cp[0], 1);
196 addr = (u_int32_t)*cp++ << 24;
197 if (IN_CLASSB(addr)) {
198 TCHECK2(cp[0], 1);
199 addr |= (u_int32_t)*cp++ << 16;
200 } else if (!IN_CLASSA(addr)) {
201 TCHECK2(cp[0], 2);
202 addr |= (u_int32_t)*cp++ << 16;
203 addr |= (u_int32_t)*cp++ << 8;
204 }
205 printf(" %s", ipaddr_string(&addr));
206 }
207 }
208 putchar(')');
209 }
210 return;
211 trunc:
212 fputs("[|]", stdout);
213 }
214
215 void
216 egp_print(register const u_int8_t *bp)
217 {
218 register const struct egp_packet *egp;
219 register int status;
220 register int code;
221 register int type;
222
223 egp = (struct egp_packet *)bp;
224 if (!TTEST(*egp)) {
225 printf("[|egp]");
226 return;
227 }
228 (void)printf("egp: ");
229
230 if (egp->egp_version != EGP_VERSION) {
231 printf("[version %d]", egp->egp_version);
232 return;
233 }
234 printf("as:%d seq:%d", ntohs(egp->egp_as), ntohs(egp->egp_sequence));
235
236 type = egp->egp_type;
237 code = egp->egp_code;
238 status = egp->egp_status;
239
240 switch (type) {
241 case EGPT_ACQUIRE:
242 printf(" acquire");
243 switch (code) {
244 case EGPC_REQUEST:
245 case EGPC_CONFIRM:
246 printf(" %s", egp_acquire_codes[code]);
247 switch (status) {
248 case EGPS_UNSPEC:
249 case EGPS_ACTIVE:
250 case EGPS_PASSIVE:
251 printf(" %s", egp_acquire_status[status]);
252 break;
253
254 default:
255 printf(" [status %d]", status);
256 break;
257 }
258 printf(" hello:%d poll:%d",
259 ntohs(egp->egp_hello),
260 ntohs(egp->egp_poll));
261 break;
262
263 case EGPC_REFUSE:
264 case EGPC_CEASE:
265 case EGPC_CEASEACK:
266 printf(" %s", egp_acquire_codes[code]);
267 switch (status ) {
268 case EGPS_UNSPEC:
269 case EGPS_NORES:
270 case EGPS_ADMIN:
271 case EGPS_GODOWN:
272 case EGPS_PARAM:
273 case EGPS_PROTO:
274 printf(" %s", egp_acquire_status[status]);
275 break;
276
277 default:
278 printf("[status %d]", status);
279 break;
280 }
281 break;
282
283 default:
284 printf("[code %d]", code);
285 break;
286 }
287 break;
288
289 case EGPT_REACH:
290 switch (code) {
291
292 case EGPC_HELLO:
293 case EGPC_HEARDU:
294 printf(" %s", egp_reach_codes[code]);
295 if (status <= EGPS_DOWN)
296 printf(" state:%s", egp_status_updown[status]);
297 else
298 printf(" [status %d]", status);
299 break;
300
301 default:
302 printf("[reach code %d]", code);
303 break;
304 }
305 break;
306
307 case EGPT_POLL:
308 printf(" poll");
309 if (egp->egp_status <= EGPS_DOWN)
310 printf(" state:%s", egp_status_updown[status]);
311 else
312 printf(" [status %d]", status);
313 printf(" net:%s", ipaddr_string(&egp->egp_sourcenet));
314 break;
315
316 case EGPT_UPDATE:
317 printf(" update");
318 if (status & EGPS_UNSOL) {
319 status &= ~EGPS_UNSOL;
320 printf(" unsolicited");
321 }
322 if (status <= EGPS_DOWN)
323 printf(" state:%s", egp_status_updown[status]);
324 else
325 printf(" [status %d]", status);
326 printf(" %s int %d ext %d",
327 ipaddr_string(&egp->egp_sourcenet),
328 egp->egp_intgw,
329 egp->egp_extgw);
330 if (vflag)
331 egpnrprint(egp);
332 break;
333
334 case EGPT_ERROR:
335 printf(" error");
336 if (status <= EGPS_DOWN)
337 printf(" state:%s", egp_status_updown[status]);
338 else
339 printf(" [status %d]", status);
340
341 if (ntohs(egp->egp_reason) <= EGPR_UVERSION)
342 printf(" %s", egp_reasons[ntohs(egp->egp_reason)]);
343 else
344 printf(" [reason %d]", ntohs(egp->egp_reason));
345 break;
346
347 default:
348 printf("[type %d]", type);
349 break;
350 }
351 }