]> The Tcpdump Group git mirrors - tcpdump/blob - print-egp.c
Add a few more GCC warnings on GCC >= 2 for ".devel" builds.
[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.31 2002-09-05 00:00:12 guy 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_char egp_version;
41 #define EGP_VERSION 2
42 u_char 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_char 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_char 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_short egp_checksum;
70 u_short egp_as;
71 u_short egp_sequence;
72 union {
73 u_short egpu_hello;
74 u_char egpu_gws[2];
75 u_short 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_short 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 };
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, register u_int length)
138 {
139 register const u_char *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_char *)(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_char *bp, register u_int length,
217 register const u_char *bp2)
218 {
219 register const struct egp_packet *egp;
220 register const struct ip *ip;
221 register int status;
222 register int code;
223 register int type;
224
225 egp = (struct egp_packet *)bp;
226 ip = (struct ip *)bp2;
227 (void)printf("egp: ");
228
229 if (egp->egp_version != EGP_VERSION) {
230 printf("[version %d]", egp->egp_version);
231 return;
232 }
233 printf("as:%d seq:%d", ntohs(egp->egp_as), ntohs(egp->egp_sequence));
234
235 type = egp->egp_type;
236 code = egp->egp_code;
237 status = egp->egp_status;
238
239 switch (type) {
240 case EGPT_ACQUIRE:
241 printf(" acquire");
242 switch (code) {
243 case EGPC_REQUEST:
244 case EGPC_CONFIRM:
245 printf(" %s", egp_acquire_codes[code]);
246 switch (status) {
247 case EGPS_UNSPEC:
248 case EGPS_ACTIVE:
249 case EGPS_PASSIVE:
250 printf(" %s", egp_acquire_status[status]);
251 break;
252
253 default:
254 printf(" [status %d]", status);
255 break;
256 }
257 printf(" hello:%d poll:%d",
258 ntohs(egp->egp_hello),
259 ntohs(egp->egp_poll));
260 break;
261
262 case EGPC_REFUSE:
263 case EGPC_CEASE:
264 case EGPC_CEASEACK:
265 printf(" %s", egp_acquire_codes[code]);
266 switch (status ) {
267 case EGPS_UNSPEC:
268 case EGPS_NORES:
269 case EGPS_ADMIN:
270 case EGPS_GODOWN:
271 case EGPS_PARAM:
272 case EGPS_PROTO:
273 printf(" %s", egp_acquire_status[status]);
274 break;
275
276 default:
277 printf("[status %d]", status);
278 break;
279 }
280 break;
281
282 default:
283 printf("[code %d]", code);
284 break;
285 }
286 break;
287
288 case EGPT_REACH:
289 switch (code) {
290
291 case EGPC_HELLO:
292 case EGPC_HEARDU:
293 printf(" %s", egp_reach_codes[code]);
294 if (status <= EGPS_DOWN)
295 printf(" state:%s", egp_status_updown[status]);
296 else
297 printf(" [status %d]", status);
298 break;
299
300 default:
301 printf("[reach code %d]", code);
302 break;
303 }
304 break;
305
306 case EGPT_POLL:
307 printf(" poll");
308 if (egp->egp_status <= EGPS_DOWN)
309 printf(" state:%s", egp_status_updown[status]);
310 else
311 printf(" [status %d]", status);
312 printf(" net:%s", ipaddr_string(&egp->egp_sourcenet));
313 break;
314
315 case EGPT_UPDATE:
316 printf(" update");
317 if (status & EGPS_UNSOL) {
318 status &= ~EGPS_UNSOL;
319 printf(" unsolicited");
320 }
321 if (status <= EGPS_DOWN)
322 printf(" state:%s", egp_status_updown[status]);
323 else
324 printf(" [status %d]", status);
325 printf(" %s int %d ext %d",
326 ipaddr_string(&egp->egp_sourcenet),
327 egp->egp_intgw,
328 egp->egp_extgw);
329 if (vflag)
330 egpnrprint(egp, length);
331 break;
332
333 case EGPT_ERROR:
334 printf(" error");
335 if (status <= EGPS_DOWN)
336 printf(" state:%s", egp_status_updown[status]);
337 else
338 printf(" [status %d]", status);
339
340 if (ntohs(egp->egp_reason) <= EGPR_UVERSION)
341 printf(" %s", egp_reasons[ntohs(egp->egp_reason)]);
342 else
343 printf(" [reason %d]", ntohs(egp->egp_reason));
344 break;
345
346 default:
347 printf("[type %d]", type);
348 break;
349 }
350 }