blob: 7d7ca07555acf323e53d319be8b1ddf2965e05c5 [file] [log] [blame]
The Android Open Source Project2949f582009-03-03 19:30:46 -08001/*
2 * Copyright (c) 1995, 1996
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
Elliott Hughese2e3bd12017-05-15 10:59:29 -070022/* \summary: Distance Vector Multicast Routing Protocol printer */
23
The Android Open Source Project2949f582009-03-03 19:30:46 -080024#ifdef HAVE_CONFIG_H
Elliott Hughes820eced2021-08-20 18:00:50 -070025#include <config.h>
The Android Open Source Project2949f582009-03-03 19:30:46 -080026#endif
27
Elliott Hughes820eced2021-08-20 18:00:50 -070028#include "netdissect-stdinc.h"
The Android Open Source Project2949f582009-03-03 19:30:46 -080029
Elliott Hughese2e3bd12017-05-15 10:59:29 -070030#include "netdissect.h"
The Android Open Source Project2949f582009-03-03 19:30:46 -080031#include "extract.h"
32#include "addrtoname.h"
33
34/*
Elliott Hughes820eced2021-08-20 18:00:50 -070035 * See: RFC 1075 and draft-ietf-idmr-dvmrp-v3
36 *
The Android Open Source Project2949f582009-03-03 19:30:46 -080037 * DVMRP message types and flag values shamelessly stolen from
38 * mrouted/dvmrp.h.
39 */
40#define DVMRP_PROBE 1 /* for finding neighbors */
41#define DVMRP_REPORT 2 /* for reporting some or all routes */
42#define DVMRP_ASK_NEIGHBORS 3 /* sent by mapper, asking for a list */
43 /* of this router's neighbors */
44#define DVMRP_NEIGHBORS 4 /* response to such a request */
45#define DVMRP_ASK_NEIGHBORS2 5 /* as above, want new format reply */
46#define DVMRP_NEIGHBORS2 6
47#define DVMRP_PRUNE 7 /* prune message */
48#define DVMRP_GRAFT 8 /* graft message */
49#define DVMRP_GRAFT_ACK 9 /* graft acknowledgement */
Elliott Hughes820eced2021-08-20 18:00:50 -070050static const struct tok dvmrp_msgtype_str[] = {
51 { DVMRP_PROBE, "Probe" },
52 { DVMRP_REPORT, "Report" },
53 { DVMRP_ASK_NEIGHBORS, "Ask-neighbors(old)" },
54 { DVMRP_NEIGHBORS, "Neighbors(old)" },
55 { DVMRP_ASK_NEIGHBORS2, "Ask-neighbors2" },
56 { DVMRP_NEIGHBORS2, "Neighbors2" },
57 { DVMRP_PRUNE, "Prune" },
58 { DVMRP_GRAFT, "Graft" },
59 { DVMRP_GRAFT_ACK, "Graft-ACK" },
60 { 0, NULL }
61};
The Android Open Source Project2949f582009-03-03 19:30:46 -080062
63/*
64 * 'flags' byte values in DVMRP_NEIGHBORS2 reply.
65 */
66#define DVMRP_NF_TUNNEL 0x01 /* neighbors reached via tunnel */
67#define DVMRP_NF_SRCRT 0x02 /* tunnel uses IP source routing */
68#define DVMRP_NF_DOWN 0x10 /* kernel state of interface */
69#define DVMRP_NF_DISABLED 0x20 /* administratively disabled */
70#define DVMRP_NF_QUERIER 0x40 /* I am the subnet's querier */
71
Elliott Hughes820eced2021-08-20 18:00:50 -070072static void print_probe(netdissect_options *, const u_char *, u_int);
73static void print_report(netdissect_options *, const u_char *, u_int);
74static void print_neighbors(netdissect_options *, const u_char *, u_int);
75static void print_neighbors2(netdissect_options *, const u_char *, u_int, uint8_t, uint8_t);
The Android Open Source Project2949f582009-03-03 19:30:46 -080076
77void
Elliott Hughes892a68b2015-10-19 14:43:53 -070078dvmrp_print(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -070079 const u_char *bp, u_int len)
The Android Open Source Project2949f582009-03-03 19:30:46 -080080{
Elliott Hughes820eced2021-08-20 18:00:50 -070081 u_char type;
82 uint8_t major_version, minor_version;
The Android Open Source Project2949f582009-03-03 19:30:46 -080083
Elliott Hughes820eced2021-08-20 18:00:50 -070084 ndo->ndo_protocol = "dvmrp";
85 if (len < 8) {
86 ND_PRINT(" [length %u < 8]", len);
87 goto invalid;
88 }
The Android Open Source Project2949f582009-03-03 19:30:46 -080089
Elliott Hughes820eced2021-08-20 18:00:50 -070090 type = GET_U_1(bp + 1);
The Android Open Source Project2949f582009-03-03 19:30:46 -080091
92 /* Skip IGMP header */
93 bp += 8;
94 len -= 8;
95
Elliott Hughes820eced2021-08-20 18:00:50 -070096 ND_PRINT(" %s", tok2str(dvmrp_msgtype_str, "[type %u]", type));
The Android Open Source Project2949f582009-03-03 19:30:46 -080097 switch (type) {
98
99 case DVMRP_PROBE:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700100 if (ndo->ndo_vflag) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700101 print_probe(ndo, bp, len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800102 }
103 break;
104
105 case DVMRP_REPORT:
Elliott Hughes892a68b2015-10-19 14:43:53 -0700106 if (ndo->ndo_vflag > 1) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700107 print_report(ndo, bp, len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800108 }
109 break;
110
The Android Open Source Project2949f582009-03-03 19:30:46 -0800111 case DVMRP_NEIGHBORS:
Elliott Hughes820eced2021-08-20 18:00:50 -0700112 print_neighbors(ndo, bp, len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800113 break;
114
115 case DVMRP_NEIGHBORS2:
The Android Open Source Project2949f582009-03-03 19:30:46 -0800116 /*
Elliott Hughes820eced2021-08-20 18:00:50 -0700117 * extract version from IGMP group address field
The Android Open Source Project2949f582009-03-03 19:30:46 -0800118 */
119 bp -= 4;
Elliott Hughes820eced2021-08-20 18:00:50 -0700120 major_version = GET_U_1(bp + 3);
121 minor_version = GET_U_1(bp + 2);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800122 bp += 4;
Elliott Hughes820eced2021-08-20 18:00:50 -0700123 print_neighbors2(ndo, bp, len, major_version, minor_version);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800124 break;
125
126 case DVMRP_PRUNE:
Elliott Hughes820eced2021-08-20 18:00:50 -0700127 ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4));
128 ND_PRINT(" timer ");
129 unsigned_relts_print(ndo, GET_BE_U_4(bp + 8));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800130 break;
131
132 case DVMRP_GRAFT:
Elliott Hughes820eced2021-08-20 18:00:50 -0700133 ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800134 break;
135
136 case DVMRP_GRAFT_ACK:
Elliott Hughes820eced2021-08-20 18:00:50 -0700137 ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800138 break;
139 }
140 return;
141
Elliott Hughes820eced2021-08-20 18:00:50 -0700142invalid:
143 nd_print_invalid(ndo);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800144}
145
Elliott Hughes820eced2021-08-20 18:00:50 -0700146static void
Elliott Hughes892a68b2015-10-19 14:43:53 -0700147print_report(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -0700148 const u_char *bp,
149 u_int len)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800150{
Elliott Hughes820eced2021-08-20 18:00:50 -0700151 uint32_t mask, origin;
152 u_int metric, done;
153 u_int i, width;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800154
155 while (len > 0) {
156 if (len < 3) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700157 ND_PRINT(" [length %u < 3]", len);
158 goto invalid;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800159 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700160 mask = (uint32_t)0xff << 24 | GET_U_1(bp) << 16 |
161 GET_U_1(bp + 1) << 8 | GET_U_1(bp + 2);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800162 width = 1;
Elliott Hughes820eced2021-08-20 18:00:50 -0700163 if (GET_U_1(bp))
The Android Open Source Project2949f582009-03-03 19:30:46 -0800164 width = 2;
Elliott Hughes820eced2021-08-20 18:00:50 -0700165 if (GET_U_1(bp + 1))
The Android Open Source Project2949f582009-03-03 19:30:46 -0800166 width = 3;
Elliott Hughes820eced2021-08-20 18:00:50 -0700167 if (GET_U_1(bp + 2))
The Android Open Source Project2949f582009-03-03 19:30:46 -0800168 width = 4;
169
Elliott Hughes820eced2021-08-20 18:00:50 -0700170 ND_PRINT("\n\tMask %s", intoa(htonl(mask)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800171 bp += 3;
172 len -= 3;
173 do {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800174 if (len < width + 1) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700175 ND_PRINT("\n\t [Truncated Report]");
176 goto invalid;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800177 }
178 origin = 0;
179 for (i = 0; i < width; ++i) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700180 origin = origin << 8 | GET_U_1(bp);
181 bp++;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800182 }
183 for ( ; i < 4; ++i)
184 origin <<= 8;
185
Elliott Hughes820eced2021-08-20 18:00:50 -0700186 metric = GET_U_1(bp);
187 bp++;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800188 done = metric & 0x80;
189 metric &= 0x7f;
Elliott Hughes820eced2021-08-20 18:00:50 -0700190 ND_PRINT("\n\t %s metric %u", intoa(htonl(origin)),
191 metric);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800192 len -= width + 1;
193 } while (!done);
194 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700195 return;
196
197invalid:
198 nd_print_invalid(ndo);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800199}
200
Elliott Hughes820eced2021-08-20 18:00:50 -0700201static void
Elliott Hughes892a68b2015-10-19 14:43:53 -0700202print_probe(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -0700203 const u_char *bp,
204 u_int len)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800205{
Elliott Hughes820eced2021-08-20 18:00:50 -0700206 if (len < 4) {
207 ND_PRINT(" [full length %u < 4]", len);
208 goto invalid;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800209 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700210 ND_PRINT(ndo->ndo_vflag > 1 ? "\n\t" : " ");
211 ND_PRINT("genid %u", GET_BE_U_4(bp));
212 if (ndo->ndo_vflag < 2)
213 return;
214
The Android Open Source Project2949f582009-03-03 19:30:46 -0800215 bp += 4;
216 len -= 4;
Elliott Hughes820eced2021-08-20 18:00:50 -0700217 while (len > 0) {
218 if (len < 4) {
219 ND_PRINT("[remaining length %u < 4]", len);
220 goto invalid;
221 }
222 ND_PRINT("\n\tneighbor %s", GET_IPADDR_STRING(bp));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800223 bp += 4; len -= 4;
224 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700225 return;
226
227invalid:
228 nd_print_invalid(ndo);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800229}
230
Elliott Hughes820eced2021-08-20 18:00:50 -0700231static void
Elliott Hughes892a68b2015-10-19 14:43:53 -0700232print_neighbors(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -0700233 const u_char *bp,
234 u_int len)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800235{
236 const u_char *laddr;
Elliott Hughes820eced2021-08-20 18:00:50 -0700237 u_char metric;
238 u_char thresh;
239 int ncount;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800240
Elliott Hughes820eced2021-08-20 18:00:50 -0700241 while (len > 0) {
242 if (len < 7) {
243 ND_PRINT(" [length %u < 7]", len);
244 goto invalid;
245 }
The Android Open Source Project2949f582009-03-03 19:30:46 -0800246 laddr = bp;
247 bp += 4;
Elliott Hughes820eced2021-08-20 18:00:50 -0700248 metric = GET_U_1(bp);
249 bp++;
250 thresh = GET_U_1(bp);
251 bp++;
252 ncount = GET_U_1(bp);
253 bp++;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800254 len -= 7;
255 while (--ncount >= 0) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700256 if (len < 4) {
257 ND_PRINT(" [length %u < 4]", len);
258 goto invalid;
259 }
260 ND_PRINT(" [%s ->", GET_IPADDR_STRING(laddr));
261 ND_PRINT(" %s, (%u/%u)]",
262 GET_IPADDR_STRING(bp), metric, thresh);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800263 bp += 4;
264 len -= 4;
265 }
266 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700267 return;
268
269invalid:
270 nd_print_invalid(ndo);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800271}
272
Elliott Hughes820eced2021-08-20 18:00:50 -0700273static void
Elliott Hughes892a68b2015-10-19 14:43:53 -0700274print_neighbors2(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -0700275 const u_char *bp,
276 u_int len, uint8_t major_version,
277 uint8_t minor_version)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800278{
279 const u_char *laddr;
Elliott Hughes820eced2021-08-20 18:00:50 -0700280 u_char metric, thresh, flags;
281 int ncount;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800282
Elliott Hughes820eced2021-08-20 18:00:50 -0700283 ND_PRINT(" (v %u.%u):", major_version, minor_version);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800284
Elliott Hughes820eced2021-08-20 18:00:50 -0700285 while (len > 0) {
286 if (len < 8) {
287 ND_PRINT(" [length %u < 8]", len);
288 goto invalid;
289 }
The Android Open Source Project2949f582009-03-03 19:30:46 -0800290 laddr = bp;
291 bp += 4;
Elliott Hughes820eced2021-08-20 18:00:50 -0700292 metric = GET_U_1(bp);
293 bp++;
294 thresh = GET_U_1(bp);
295 bp++;
296 flags = GET_U_1(bp);
297 bp++;
298 ncount = GET_U_1(bp);
299 bp++;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800300 len -= 8;
Elliott Hughes820eced2021-08-20 18:00:50 -0700301 while (--ncount >= 0 && len > 0) {
302 if (len < 4) {
303 ND_PRINT(" [length %u < 4]", len);
304 goto invalid;
305 }
306 ND_PRINT(" [%s -> ", GET_IPADDR_STRING(laddr));
307 ND_PRINT("%s (%u/%u", GET_IPADDR_STRING(bp),
308 metric, thresh);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800309 if (flags & DVMRP_NF_TUNNEL)
Elliott Hughes820eced2021-08-20 18:00:50 -0700310 ND_PRINT("/tunnel");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800311 if (flags & DVMRP_NF_SRCRT)
Elliott Hughes820eced2021-08-20 18:00:50 -0700312 ND_PRINT("/srcrt");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800313 if (flags & DVMRP_NF_QUERIER)
Elliott Hughes820eced2021-08-20 18:00:50 -0700314 ND_PRINT("/querier");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800315 if (flags & DVMRP_NF_DISABLED)
Elliott Hughes820eced2021-08-20 18:00:50 -0700316 ND_PRINT("/disabled");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800317 if (flags & DVMRP_NF_DOWN)
Elliott Hughes820eced2021-08-20 18:00:50 -0700318 ND_PRINT("/down");
319 ND_PRINT(")]");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800320 bp += 4;
321 len -= 4;
322 }
323 if (ncount != -1) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700324 ND_PRINT(" [invalid ncount]");
325 goto invalid;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800326 }
327 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700328 return;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800329
Elliott Hughes820eced2021-08-20 18:00:50 -0700330invalid:
331 nd_print_invalid(ndo);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800332}