etc/services - sync with NetBSD-8
[minix.git] / external / bsd / tcpdump / dist / print-egp.c
blob23c38d5c8fa6e2c76b9bb4c7949c75fa125b35cd
1 /*
2 * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
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.
18 * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU).
21 #include <sys/cdefs.h>
22 #ifndef lint
23 __RCSID("$NetBSD: print-egp.c,v 1.4 2014/11/20 03:05:03 christos Exp $");
24 #endif
26 #define NETDISSECT_REWORKED
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
31 #include <tcpdump-stdinc.h>
33 #include "interface.h"
34 #include "addrtoname.h"
35 #include "extract.h"
37 struct egp_packet {
38 uint8_t egp_version;
39 #define EGP_VERSION 2
40 uint8_t egp_type;
41 #define EGPT_ACQUIRE 3
42 #define EGPT_REACH 5
43 #define EGPT_POLL 2
44 #define EGPT_UPDATE 1
45 #define EGPT_ERROR 8
46 uint8_t egp_code;
47 #define EGPC_REQUEST 0
48 #define EGPC_CONFIRM 1
49 #define EGPC_REFUSE 2
50 #define EGPC_CEASE 3
51 #define EGPC_CEASEACK 4
52 #define EGPC_HELLO 0
53 #define EGPC_HEARDU 1
54 uint8_t egp_status;
55 #define EGPS_UNSPEC 0
56 #define EGPS_ACTIVE 1
57 #define EGPS_PASSIVE 2
58 #define EGPS_NORES 3
59 #define EGPS_ADMIN 4
60 #define EGPS_GODOWN 5
61 #define EGPS_PARAM 6
62 #define EGPS_PROTO 7
63 #define EGPS_INDET 0
64 #define EGPS_UP 1
65 #define EGPS_DOWN 2
66 #define EGPS_UNSOL 0x80
67 uint16_t egp_checksum;
68 uint16_t egp_as;
69 uint16_t egp_sequence;
70 union {
71 uint16_t egpu_hello;
72 uint8_t egpu_gws[2];
73 uint16_t egpu_reason;
74 #define EGPR_UNSPEC 0
75 #define EGPR_BADHEAD 1
76 #define EGPR_BADDATA 2
77 #define EGPR_NOREACH 3
78 #define EGPR_XSPOLL 4
79 #define EGPR_NORESP 5
80 #define EGPR_UVERSION 6
81 } egp_handg;
82 #define egp_hello egp_handg.egpu_hello
83 #define egp_intgw egp_handg.egpu_gws[0]
84 #define egp_extgw egp_handg.egpu_gws[1]
85 #define egp_reason egp_handg.egpu_reason
86 union {
87 uint16_t egpu_poll;
88 uint32_t egpu_sourcenet;
89 } egp_pands;
90 #define egp_poll egp_pands.egpu_poll
91 #define egp_sourcenet egp_pands.egpu_sourcenet
94 static const char *egp_acquire_codes[] = {
95 "request",
96 "confirm",
97 "refuse",
98 "cease",
99 "cease_ack"
102 static const char *egp_acquire_status[] = {
103 "unspecified",
104 "active_mode",
105 "passive_mode",
106 "insufficient_resources",
107 "administratively_prohibited",
108 "going_down",
109 "parameter_violation",
110 "protocol_violation"
113 static const char *egp_reach_codes[] = {
114 "hello",
115 "i-h-u"
118 static const char *egp_status_updown[] = {
119 "indeterminate",
120 "up",
121 "down"
124 static const char *egp_reasons[] = {
125 "unspecified",
126 "bad_EGP_header_format",
127 "bad_EGP_data_field_format",
128 "reachability_info_unavailable",
129 "excessive_polling_rate",
130 "no_response",
131 "unsupported_version"
134 static void
135 egpnrprint(netdissect_options *ndo,
136 register const struct egp_packet *egp)
138 register const uint8_t *cp;
139 uint32_t addr;
140 register uint32_t net;
141 register u_int netlen;
142 int gateways, distances, networks;
143 int t_gateways;
144 const char *comma;
146 addr = egp->egp_sourcenet;
147 if (IN_CLASSA(addr)) {
148 net = addr & IN_CLASSA_NET;
149 netlen = 1;
150 } else if (IN_CLASSB(addr)) {
151 net = addr & IN_CLASSB_NET;
152 netlen = 2;
153 } else if (IN_CLASSC(addr)) {
154 net = addr & IN_CLASSC_NET;
155 netlen = 3;
156 } else {
157 net = 0;
158 netlen = 0;
160 cp = (uint8_t *)(egp + 1);
162 t_gateways = egp->egp_intgw + egp->egp_extgw;
163 for (gateways = 0; gateways < t_gateways; ++gateways) {
164 /* Pickup host part of gateway address */
165 addr = 0;
166 ND_TCHECK2(cp[0], 4 - netlen);
167 switch (netlen) {
169 case 1:
170 addr = *cp++;
171 /* fall through */
172 case 2:
173 addr = (addr << 8) | *cp++;
174 /* fall through */
175 case 3:
176 addr = (addr << 8) | *cp++;
178 addr |= net;
179 ND_TCHECK2(cp[0], 1);
180 distances = *cp++;
181 ND_PRINT((ndo, " %s %s ",
182 gateways < (int)egp->egp_intgw ? "int" : "ext",
183 ipaddr_string(ndo, &addr)));
185 comma = "";
186 ND_PRINT((ndo, "("));
187 while (--distances >= 0) {
188 ND_TCHECK2(cp[0], 2);
189 ND_PRINT((ndo, "%sd%d:", comma, (int)*cp++));
190 comma = ", ";
191 networks = *cp++;
192 while (--networks >= 0) {
193 /* Pickup network number */
194 ND_TCHECK2(cp[0], 1);
195 addr = (uint32_t)*cp++ << 24;
196 if (IN_CLASSB(addr)) {
197 ND_TCHECK2(cp[0], 1);
198 addr |= (uint32_t)*cp++ << 16;
199 } else if (!IN_CLASSA(addr)) {
200 ND_TCHECK2(cp[0], 2);
201 addr |= (uint32_t)*cp++ << 16;
202 addr |= (uint32_t)*cp++ << 8;
204 ND_PRINT((ndo, " %s", ipaddr_string(ndo, &addr)));
207 ND_PRINT((ndo, ")"));
209 return;
210 trunc:
211 ND_PRINT((ndo, "[|]"));
214 void
215 egp_print(netdissect_options *ndo,
216 register const uint8_t *bp, register u_int length)
218 register const struct egp_packet *egp;
219 register int status;
220 register int code;
221 register int type;
223 egp = (struct egp_packet *)bp;
224 if (!ND_TTEST2(*egp, length)) {
225 ND_PRINT((ndo, "[|egp]"));
226 return;
229 if (!ndo->ndo_vflag) {
230 ND_PRINT((ndo, "EGPv%u, AS %u, seq %u, length %u",
231 egp->egp_version,
232 EXTRACT_16BITS(&egp->egp_as),
233 EXTRACT_16BITS(&egp->egp_sequence),
234 length));
235 return;
236 } else
237 ND_PRINT((ndo, "EGPv%u, length %u",
238 egp->egp_version,
239 length));
241 if (egp->egp_version != EGP_VERSION) {
242 ND_PRINT((ndo, "[version %d]", egp->egp_version));
243 return;
246 type = egp->egp_type;
247 code = egp->egp_code;
248 status = egp->egp_status;
250 switch (type) {
251 case EGPT_ACQUIRE:
252 ND_PRINT((ndo, " acquire"));
253 switch (code) {
254 case EGPC_REQUEST:
255 case EGPC_CONFIRM:
256 ND_PRINT((ndo, " %s", egp_acquire_codes[code]));
257 switch (status) {
258 case EGPS_UNSPEC:
259 case EGPS_ACTIVE:
260 case EGPS_PASSIVE:
261 ND_PRINT((ndo, " %s", egp_acquire_status[status]));
262 break;
264 default:
265 ND_PRINT((ndo, " [status %d]", status));
266 break;
268 ND_PRINT((ndo, " hello:%d poll:%d",
269 EXTRACT_16BITS(&egp->egp_hello),
270 EXTRACT_16BITS(&egp->egp_poll)));
271 break;
273 case EGPC_REFUSE:
274 case EGPC_CEASE:
275 case EGPC_CEASEACK:
276 ND_PRINT((ndo, " %s", egp_acquire_codes[code]));
277 switch (status ) {
278 case EGPS_UNSPEC:
279 case EGPS_NORES:
280 case EGPS_ADMIN:
281 case EGPS_GODOWN:
282 case EGPS_PARAM:
283 case EGPS_PROTO:
284 ND_PRINT((ndo, " %s", egp_acquire_status[status]));
285 break;
287 default:
288 ND_PRINT((ndo, "[status %d]", status));
289 break;
291 break;
293 default:
294 ND_PRINT((ndo, "[code %d]", code));
295 break;
297 break;
299 case EGPT_REACH:
300 switch (code) {
302 case EGPC_HELLO:
303 case EGPC_HEARDU:
304 ND_PRINT((ndo, " %s", egp_reach_codes[code]));
305 if (status <= EGPS_DOWN)
306 ND_PRINT((ndo, " state:%s", egp_status_updown[status]));
307 else
308 ND_PRINT((ndo, " [status %d]", status));
309 break;
311 default:
312 ND_PRINT((ndo, "[reach code %d]", code));
313 break;
315 break;
317 case EGPT_POLL:
318 ND_PRINT((ndo, " poll"));
319 if (egp->egp_status <= EGPS_DOWN)
320 ND_PRINT((ndo, " state:%s", egp_status_updown[status]));
321 else
322 ND_PRINT((ndo, " [status %d]", status));
323 ND_PRINT((ndo, " net:%s", ipaddr_string(ndo, &egp->egp_sourcenet)));
324 break;
326 case EGPT_UPDATE:
327 ND_PRINT((ndo, " update"));
328 if (status & EGPS_UNSOL) {
329 status &= ~EGPS_UNSOL;
330 ND_PRINT((ndo, " unsolicited"));
332 if (status <= EGPS_DOWN)
333 ND_PRINT((ndo, " state:%s", egp_status_updown[status]));
334 else
335 ND_PRINT((ndo, " [status %d]", status));
336 ND_PRINT((ndo, " %s int %d ext %d",
337 ipaddr_string(ndo, &egp->egp_sourcenet),
338 egp->egp_intgw,
339 egp->egp_extgw));
340 if (ndo->ndo_vflag)
341 egpnrprint(ndo, egp);
342 break;
344 case EGPT_ERROR:
345 ND_PRINT((ndo, " error"));
346 if (status <= EGPS_DOWN)
347 ND_PRINT((ndo, " state:%s", egp_status_updown[status]));
348 else
349 ND_PRINT((ndo, " [status %d]", status));
351 if (EXTRACT_16BITS(&egp->egp_reason) <= EGPR_UVERSION)
352 ND_PRINT((ndo, " %s", egp_reasons[EXTRACT_16BITS(&egp->egp_reason)]));
353 else
354 ND_PRINT((ndo, " [reason %d]", EXTRACT_16BITS(&egp->egp_reason)));
355 break;
357 default:
358 ND_PRINT((ndo, "[type %d]", type));
359 break;