blob: d20e5befe9691da0b3e9bea17ddb20a36a1dffb7 [file] [log] [blame]
The Android Open Source Project2949f582009-03-03 19:30:46 -08001/*
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
Elliott Hughese2e3bd12017-05-15 10:59:29 -070021/* \summary: Exterior Gateway Protocol (EGP) printer */
22
Elliott Hughes820eced2021-08-20 18:00:50 -070023/* specification: RFC 827 */
24
The Android Open Source Project2949f582009-03-03 19:30:46 -080025#ifdef HAVE_CONFIG_H
Elliott Hughes820eced2021-08-20 18:00:50 -070026#include <config.h>
The Android Open Source Project2949f582009-03-03 19:30:46 -080027#endif
28
Elliott Hughes820eced2021-08-20 18:00:50 -070029#include "netdissect-stdinc.h"
The Android Open Source Project2949f582009-03-03 19:30:46 -080030
Elliott Hughese2e3bd12017-05-15 10:59:29 -070031#include "netdissect.h"
The Android Open Source Project2949f582009-03-03 19:30:46 -080032#include "addrtoname.h"
33#include "extract.h"
34
The Android Open Source Project2949f582009-03-03 19:30:46 -080035struct egp_packet {
Elliott Hughes820eced2021-08-20 18:00:50 -070036 nd_uint8_t egp_version;
The Android Open Source Project2949f582009-03-03 19:30:46 -080037#define EGP_VERSION 2
Elliott Hughes820eced2021-08-20 18:00:50 -070038 nd_uint8_t egp_type;
The Android Open Source Project2949f582009-03-03 19:30:46 -080039#define EGPT_ACQUIRE 3
40#define EGPT_REACH 5
41#define EGPT_POLL 2
42#define EGPT_UPDATE 1
43#define EGPT_ERROR 8
Elliott Hughes820eced2021-08-20 18:00:50 -070044 nd_uint8_t egp_code;
The Android Open Source Project2949f582009-03-03 19:30:46 -080045#define EGPC_REQUEST 0
46#define EGPC_CONFIRM 1
47#define EGPC_REFUSE 2
48#define EGPC_CEASE 3
49#define EGPC_CEASEACK 4
50#define EGPC_HELLO 0
51#define EGPC_HEARDU 1
Elliott Hughes820eced2021-08-20 18:00:50 -070052 nd_uint8_t egp_status;
The Android Open Source Project2949f582009-03-03 19:30:46 -080053#define EGPS_UNSPEC 0
54#define EGPS_ACTIVE 1
55#define EGPS_PASSIVE 2
56#define EGPS_NORES 3
57#define EGPS_ADMIN 4
58#define EGPS_GODOWN 5
59#define EGPS_PARAM 6
60#define EGPS_PROTO 7
61#define EGPS_INDET 0
62#define EGPS_UP 1
63#define EGPS_DOWN 2
64#define EGPS_UNSOL 0x80
Elliott Hughes820eced2021-08-20 18:00:50 -070065 nd_uint16_t egp_checksum;
66 nd_uint16_t egp_as;
67 nd_uint16_t egp_sequence;
The Android Open Source Project2949f582009-03-03 19:30:46 -080068 union {
Elliott Hughes820eced2021-08-20 18:00:50 -070069 nd_uint16_t egpu_hello;
70 nd_uint8_t egpu_gws[2];
71 nd_uint16_t egpu_reason;
The Android Open Source Project2949f582009-03-03 19:30:46 -080072#define EGPR_UNSPEC 0
73#define EGPR_BADHEAD 1
74#define EGPR_BADDATA 2
75#define EGPR_NOREACH 3
76#define EGPR_XSPOLL 4
77#define EGPR_NORESP 5
78#define EGPR_UVERSION 6
79 } egp_handg;
80#define egp_hello egp_handg.egpu_hello
81#define egp_intgw egp_handg.egpu_gws[0]
82#define egp_extgw egp_handg.egpu_gws[1]
83#define egp_reason egp_handg.egpu_reason
84 union {
Elliott Hughes820eced2021-08-20 18:00:50 -070085 nd_uint16_t egpu_poll;
86 nd_ipv4 egpu_sourcenet;
The Android Open Source Project2949f582009-03-03 19:30:46 -080087 } egp_pands;
88#define egp_poll egp_pands.egpu_poll
89#define egp_sourcenet egp_pands.egpu_sourcenet
90};
91
Elliott Hughes892a68b2015-10-19 14:43:53 -070092static const char *egp_acquire_codes[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -080093 "request",
94 "confirm",
95 "refuse",
96 "cease",
97 "cease_ack"
98};
99
Elliott Hughes892a68b2015-10-19 14:43:53 -0700100static const char *egp_acquire_status[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800101 "unspecified",
102 "active_mode",
103 "passive_mode",
104 "insufficient_resources",
105 "administratively_prohibited",
106 "going_down",
107 "parameter_violation",
108 "protocol_violation"
109};
110
Elliott Hughes892a68b2015-10-19 14:43:53 -0700111static const char *egp_reach_codes[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800112 "hello",
113 "i-h-u"
114};
115
Elliott Hughes892a68b2015-10-19 14:43:53 -0700116static const char *egp_status_updown[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800117 "indeterminate",
118 "up",
119 "down"
120};
121
Elliott Hughes892a68b2015-10-19 14:43:53 -0700122static const char *egp_reasons[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800123 "unspecified",
124 "bad_EGP_header_format",
125 "bad_EGP_data_field_format",
126 "reachability_info_unavailable",
127 "excessive_polling_rate",
128 "no_response",
129 "unsupported_version"
130};
131
132static void
Elliott Hughes820eced2021-08-20 18:00:50 -0700133egpnr_print(netdissect_options *ndo,
134 const struct egp_packet *egp, u_int length)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800135{
Elliott Hughes820eced2021-08-20 18:00:50 -0700136 const uint8_t *cp;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700137 uint32_t addr;
Elliott Hughes820eced2021-08-20 18:00:50 -0700138 uint32_t net;
139 u_int netlen;
140 u_int gateways, distances, networks;
141 u_int intgw, extgw, t_gateways;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800142 const char *comma;
143
Elliott Hughes820eced2021-08-20 18:00:50 -0700144 addr = GET_IPV4_TO_NETWORK_ORDER(egp->egp_sourcenet);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800145 if (IN_CLASSA(addr)) {
146 net = addr & IN_CLASSA_NET;
147 netlen = 1;
148 } else if (IN_CLASSB(addr)) {
149 net = addr & IN_CLASSB_NET;
150 netlen = 2;
151 } else if (IN_CLASSC(addr)) {
152 net = addr & IN_CLASSC_NET;
153 netlen = 3;
154 } else {
155 net = 0;
156 netlen = 0;
157 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700158 cp = (const uint8_t *)(egp + 1);
159 length -= sizeof(*egp);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800160
Elliott Hughes820eced2021-08-20 18:00:50 -0700161 intgw = GET_U_1(egp->egp_intgw);
162 extgw = GET_U_1(egp->egp_extgw);
163 t_gateways = intgw + extgw;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800164 for (gateways = 0; gateways < t_gateways; ++gateways) {
165 /* Pickup host part of gateway address */
166 addr = 0;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700167 if (length < 4 - netlen)
168 goto trunc;
Elliott Hughes820eced2021-08-20 18:00:50 -0700169 ND_TCHECK_LEN(cp, 4 - netlen);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800170 switch (netlen) {
171
172 case 1:
Elliott Hughes820eced2021-08-20 18:00:50 -0700173 addr = GET_U_1(cp);
174 cp++;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800175 /* fall through */
176 case 2:
Elliott Hughes820eced2021-08-20 18:00:50 -0700177 addr = (addr << 8) | GET_U_1(cp);
178 cp++;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800179 /* fall through */
180 case 3:
Elliott Hughes820eced2021-08-20 18:00:50 -0700181 addr = (addr << 8) | GET_U_1(cp);
182 cp++;
183 break;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800184 }
185 addr |= net;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700186 length -= 4 - netlen;
187 if (length < 1)
188 goto trunc;
Elliott Hughes820eced2021-08-20 18:00:50 -0700189 distances = GET_U_1(cp);
190 cp++;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700191 length--;
Elliott Hughes820eced2021-08-20 18:00:50 -0700192 ND_PRINT(" %s %s ",
193 gateways < intgw ? "int" : "ext",
194 ipaddr_string(ndo, (const u_char *)&addr));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800195
196 comma = "";
Elliott Hughes820eced2021-08-20 18:00:50 -0700197 ND_PRINT("(");
198 while (distances != 0) {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700199 if (length < 2)
200 goto trunc;
Elliott Hughes820eced2021-08-20 18:00:50 -0700201 ND_PRINT("%sd%u:", comma, GET_U_1(cp));
202 cp++;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800203 comma = ", ";
Elliott Hughes820eced2021-08-20 18:00:50 -0700204 networks = GET_U_1(cp);
205 cp++;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700206 length -= 2;
Elliott Hughes820eced2021-08-20 18:00:50 -0700207 while (networks != 0) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800208 /* Pickup network number */
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700209 if (length < 1)
210 goto trunc;
Elliott Hughes820eced2021-08-20 18:00:50 -0700211 addr = ((uint32_t) GET_U_1(cp)) << 24;
212 cp++;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700213 length--;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800214 if (IN_CLASSB(addr)) {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700215 if (length < 1)
216 goto trunc;
Elliott Hughes820eced2021-08-20 18:00:50 -0700217 addr |= ((uint32_t) GET_U_1(cp)) << 16;
218 cp++;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700219 length--;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800220 } else if (!IN_CLASSA(addr)) {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700221 if (length < 2)
222 goto trunc;
Elliott Hughes820eced2021-08-20 18:00:50 -0700223 addr |= ((uint32_t) GET_U_1(cp)) << 16;
224 cp++;
225 addr |= ((uint32_t) GET_U_1(cp)) << 8;
226 cp++;
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700227 length -= 2;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800228 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700229 ND_PRINT(" %s", ipaddr_string(ndo, (const u_char *)&addr));
230 networks--;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800231 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700232 distances--;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800233 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700234 ND_PRINT(")");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800235 }
236 return;
237trunc:
Elliott Hughes820eced2021-08-20 18:00:50 -0700238 nd_print_trunc(ndo);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800239}
240
241void
Elliott Hughes892a68b2015-10-19 14:43:53 -0700242egp_print(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -0700243 const uint8_t *bp, u_int length)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800244{
Elliott Hughes820eced2021-08-20 18:00:50 -0700245 const struct egp_packet *egp;
246 u_int version;
247 u_int type;
248 u_int code;
249 u_int status;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800250
Elliott Hughes820eced2021-08-20 18:00:50 -0700251 ndo->ndo_protocol = "egp";
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700252 egp = (const struct egp_packet *)bp;
Elliott Hughes820eced2021-08-20 18:00:50 -0700253 if (length < sizeof(*egp) || !ND_TTEST_SIZE(egp)) {
254 nd_print_trunc(ndo);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800255 return;
256 }
JP Abgrall53f17a92014-02-12 14:02:41 -0800257
Elliott Hughes820eced2021-08-20 18:00:50 -0700258 version = GET_U_1(egp->egp_version);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700259 if (!ndo->ndo_vflag) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700260 ND_PRINT("EGPv%u, AS %u, seq %u, length %u",
261 version,
262 GET_BE_U_2(egp->egp_as),
263 GET_BE_U_2(egp->egp_sequence),
264 length);
JP Abgrall53f17a92014-02-12 14:02:41 -0800265 return;
266 } else
Elliott Hughes820eced2021-08-20 18:00:50 -0700267 ND_PRINT("EGPv%u, length %u",
268 version,
269 length);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800270
Elliott Hughes820eced2021-08-20 18:00:50 -0700271 if (version != EGP_VERSION) {
272 ND_PRINT("[version %u]", version);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800273 return;
274 }
The Android Open Source Project2949f582009-03-03 19:30:46 -0800275
Elliott Hughes820eced2021-08-20 18:00:50 -0700276 type = GET_U_1(egp->egp_type);
277 code = GET_U_1(egp->egp_code);
278 status = GET_U_1(egp->egp_status);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800279
280 switch (type) {
281 case EGPT_ACQUIRE:
Elliott Hughes820eced2021-08-20 18:00:50 -0700282 ND_PRINT(" acquire");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800283 switch (code) {
284 case EGPC_REQUEST:
285 case EGPC_CONFIRM:
Elliott Hughes820eced2021-08-20 18:00:50 -0700286 ND_PRINT(" %s", egp_acquire_codes[code]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800287 switch (status) {
288 case EGPS_UNSPEC:
289 case EGPS_ACTIVE:
290 case EGPS_PASSIVE:
Elliott Hughes820eced2021-08-20 18:00:50 -0700291 ND_PRINT(" %s", egp_acquire_status[status]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800292 break;
293
294 default:
Elliott Hughes820eced2021-08-20 18:00:50 -0700295 ND_PRINT(" [status %u]", status);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800296 break;
297 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700298 ND_PRINT(" hello:%u poll:%u",
299 GET_BE_U_2(egp->egp_hello),
300 GET_BE_U_2(egp->egp_poll));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800301 break;
302
303 case EGPC_REFUSE:
304 case EGPC_CEASE:
305 case EGPC_CEASEACK:
Elliott Hughes820eced2021-08-20 18:00:50 -0700306 ND_PRINT(" %s", egp_acquire_codes[code]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800307 switch (status ) {
308 case EGPS_UNSPEC:
309 case EGPS_NORES:
310 case EGPS_ADMIN:
311 case EGPS_GODOWN:
312 case EGPS_PARAM:
313 case EGPS_PROTO:
Elliott Hughes820eced2021-08-20 18:00:50 -0700314 ND_PRINT(" %s", egp_acquire_status[status]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800315 break;
316
317 default:
Elliott Hughes820eced2021-08-20 18:00:50 -0700318 ND_PRINT("[status %u]", status);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800319 break;
320 }
321 break;
322
323 default:
Elliott Hughes820eced2021-08-20 18:00:50 -0700324 ND_PRINT("[code %u]", code);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800325 break;
326 }
327 break;
328
329 case EGPT_REACH:
330 switch (code) {
331
332 case EGPC_HELLO:
333 case EGPC_HEARDU:
Elliott Hughes820eced2021-08-20 18:00:50 -0700334 ND_PRINT(" %s", egp_reach_codes[code]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800335 if (status <= EGPS_DOWN)
Elliott Hughes820eced2021-08-20 18:00:50 -0700336 ND_PRINT(" state:%s", egp_status_updown[status]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800337 else
Elliott Hughes820eced2021-08-20 18:00:50 -0700338 ND_PRINT(" [status %u]", status);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800339 break;
340
341 default:
Elliott Hughes820eced2021-08-20 18:00:50 -0700342 ND_PRINT("[reach code %u]", code);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800343 break;
344 }
345 break;
346
347 case EGPT_POLL:
Elliott Hughes820eced2021-08-20 18:00:50 -0700348 ND_PRINT(" poll");
349 if (status <= EGPS_DOWN)
350 ND_PRINT(" state:%s", egp_status_updown[status]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800351 else
Elliott Hughes820eced2021-08-20 18:00:50 -0700352 ND_PRINT(" [status %u]", status);
353 ND_PRINT(" net:%s", GET_IPADDR_STRING(egp->egp_sourcenet));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800354 break;
355
356 case EGPT_UPDATE:
Elliott Hughes820eced2021-08-20 18:00:50 -0700357 ND_PRINT(" update");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800358 if (status & EGPS_UNSOL) {
359 status &= ~EGPS_UNSOL;
Elliott Hughes820eced2021-08-20 18:00:50 -0700360 ND_PRINT(" unsolicited");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800361 }
362 if (status <= EGPS_DOWN)
Elliott Hughes820eced2021-08-20 18:00:50 -0700363 ND_PRINT(" state:%s", egp_status_updown[status]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800364 else
Elliott Hughes820eced2021-08-20 18:00:50 -0700365 ND_PRINT(" [status %u]", status);
366 ND_PRINT(" %s int %u ext %u",
367 GET_IPADDR_STRING(egp->egp_sourcenet),
368 GET_U_1(egp->egp_intgw),
369 GET_U_1(egp->egp_extgw));
Elliott Hughes892a68b2015-10-19 14:43:53 -0700370 if (ndo->ndo_vflag)
Elliott Hughes820eced2021-08-20 18:00:50 -0700371 egpnr_print(ndo, egp, length);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800372 break;
373
374 case EGPT_ERROR:
Elliott Hughes820eced2021-08-20 18:00:50 -0700375 ND_PRINT(" error");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800376 if (status <= EGPS_DOWN)
Elliott Hughes820eced2021-08-20 18:00:50 -0700377 ND_PRINT(" state:%s", egp_status_updown[status]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800378 else
Elliott Hughes820eced2021-08-20 18:00:50 -0700379 ND_PRINT(" [status %u]", status);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800380
Elliott Hughes820eced2021-08-20 18:00:50 -0700381 if (GET_BE_U_2(egp->egp_reason) <= EGPR_UVERSION)
382 ND_PRINT(" %s",
383 egp_reasons[GET_BE_U_2(egp->egp_reason)]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800384 else
Elliott Hughes820eced2021-08-20 18:00:50 -0700385 ND_PRINT(" [reason %u]", GET_BE_U_2(egp->egp_reason));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800386 break;
387
388 default:
Elliott Hughes820eced2021-08-20 18:00:50 -0700389 ND_PRINT("[type %u]", type);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800390 break;
391 }
392}