141c99275SPeter Avalos /*
241c99275SPeter Avalos * Copyright (c) 1995, 1996
341c99275SPeter Avalos * The Regents of the University of California. All rights reserved.
441c99275SPeter Avalos *
541c99275SPeter Avalos * Redistribution and use in source and binary forms, with or without
641c99275SPeter Avalos * modification, are permitted provided that: (1) source code distributions
741c99275SPeter Avalos * retain the above copyright notice and this paragraph in its entirety, (2)
841c99275SPeter Avalos * distributions including binary code include the above copyright notice and
941c99275SPeter Avalos * this paragraph in its entirety in the documentation or other materials
1041c99275SPeter Avalos * provided with the distribution, and (3) all advertising materials mentioning
1141c99275SPeter Avalos * features or use of this software display the following acknowledgement:
1241c99275SPeter Avalos * ``This product includes software developed by the University of California,
1341c99275SPeter Avalos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1441c99275SPeter Avalos * the University nor the names of its contributors may be used to endorse
1541c99275SPeter Avalos * or promote products derived from this software without specific prior
1641c99275SPeter Avalos * written permission.
1741c99275SPeter Avalos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1841c99275SPeter Avalos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1941c99275SPeter Avalos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2041c99275SPeter Avalos */
2141c99275SPeter Avalos
22411677aeSAaron LI /* \summary: Distance Vector Multicast Routing Protocol printer */
2341c99275SPeter Avalos
2441c99275SPeter Avalos #ifdef HAVE_CONFIG_H
25*ed775ee7SAntonio Huete Jimenez #include <config.h>
2641c99275SPeter Avalos #endif
2741c99275SPeter Avalos
28*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
2941c99275SPeter Avalos
30411677aeSAaron LI #include "netdissect.h"
3141c99275SPeter Avalos #include "extract.h"
3241c99275SPeter Avalos #include "addrtoname.h"
3341c99275SPeter Avalos
3441c99275SPeter Avalos /*
35411677aeSAaron LI * See: RFC 1075 and draft-ietf-idmr-dvmrp-v3
36411677aeSAaron LI *
3741c99275SPeter Avalos * DVMRP message types and flag values shamelessly stolen from
3841c99275SPeter Avalos * mrouted/dvmrp.h.
3941c99275SPeter Avalos */
4041c99275SPeter Avalos #define DVMRP_PROBE 1 /* for finding neighbors */
4141c99275SPeter Avalos #define DVMRP_REPORT 2 /* for reporting some or all routes */
4241c99275SPeter Avalos #define DVMRP_ASK_NEIGHBORS 3 /* sent by mapper, asking for a list */
4341c99275SPeter Avalos /* of this router's neighbors */
4441c99275SPeter Avalos #define DVMRP_NEIGHBORS 4 /* response to such a request */
4541c99275SPeter Avalos #define DVMRP_ASK_NEIGHBORS2 5 /* as above, want new format reply */
4641c99275SPeter Avalos #define DVMRP_NEIGHBORS2 6
4741c99275SPeter Avalos #define DVMRP_PRUNE 7 /* prune message */
4841c99275SPeter Avalos #define DVMRP_GRAFT 8 /* graft message */
4941c99275SPeter Avalos #define DVMRP_GRAFT_ACK 9 /* graft acknowledgement */
50*ed775ee7SAntonio Huete Jimenez static const struct tok dvmrp_msgtype_str[] = {
51*ed775ee7SAntonio Huete Jimenez { DVMRP_PROBE, "Probe" },
52*ed775ee7SAntonio Huete Jimenez { DVMRP_REPORT, "Report" },
53*ed775ee7SAntonio Huete Jimenez { DVMRP_ASK_NEIGHBORS, "Ask-neighbors(old)" },
54*ed775ee7SAntonio Huete Jimenez { DVMRP_NEIGHBORS, "Neighbors(old)" },
55*ed775ee7SAntonio Huete Jimenez { DVMRP_ASK_NEIGHBORS2, "Ask-neighbors2" },
56*ed775ee7SAntonio Huete Jimenez { DVMRP_NEIGHBORS2, "Neighbors2" },
57*ed775ee7SAntonio Huete Jimenez { DVMRP_PRUNE, "Prune" },
58*ed775ee7SAntonio Huete Jimenez { DVMRP_GRAFT, "Graft" },
59*ed775ee7SAntonio Huete Jimenez { DVMRP_GRAFT_ACK, "Graft-ACK" },
60*ed775ee7SAntonio Huete Jimenez { 0, NULL }
61*ed775ee7SAntonio Huete Jimenez };
6241c99275SPeter Avalos
6341c99275SPeter Avalos /*
6441c99275SPeter Avalos * 'flags' byte values in DVMRP_NEIGHBORS2 reply.
6541c99275SPeter Avalos */
6641c99275SPeter Avalos #define DVMRP_NF_TUNNEL 0x01 /* neighbors reached via tunnel */
6741c99275SPeter Avalos #define DVMRP_NF_SRCRT 0x02 /* tunnel uses IP source routing */
6841c99275SPeter Avalos #define DVMRP_NF_DOWN 0x10 /* kernel state of interface */
6941c99275SPeter Avalos #define DVMRP_NF_DISABLED 0x20 /* administratively disabled */
7041c99275SPeter Avalos #define DVMRP_NF_QUERIER 0x40 /* I am the subnet's querier */
7141c99275SPeter Avalos
72*ed775ee7SAntonio Huete Jimenez static void print_probe(netdissect_options *, const u_char *, u_int);
73*ed775ee7SAntonio Huete Jimenez static void print_report(netdissect_options *, const u_char *, u_int);
74*ed775ee7SAntonio Huete Jimenez static void print_neighbors(netdissect_options *, const u_char *, u_int);
75*ed775ee7SAntonio Huete Jimenez static void print_neighbors2(netdissect_options *, const u_char *, u_int, uint8_t, uint8_t);
7641c99275SPeter Avalos
7741c99275SPeter Avalos void
dvmrp_print(netdissect_options * ndo,const u_char * bp,u_int len)78411677aeSAaron LI dvmrp_print(netdissect_options *ndo,
79*ed775ee7SAntonio Huete Jimenez const u_char *bp, u_int len)
8041c99275SPeter Avalos {
81*ed775ee7SAntonio Huete Jimenez u_char type;
82411677aeSAaron LI uint8_t major_version, minor_version;
8341c99275SPeter Avalos
84*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "dvmrp";
85*ed775ee7SAntonio Huete Jimenez if (len < 8) {
86*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [length %u < 8]", len);
87*ed775ee7SAntonio Huete Jimenez goto invalid;
88*ed775ee7SAntonio Huete Jimenez }
8941c99275SPeter Avalos
90*ed775ee7SAntonio Huete Jimenez type = GET_U_1(bp + 1);
9141c99275SPeter Avalos
9241c99275SPeter Avalos /* Skip IGMP header */
9341c99275SPeter Avalos bp += 8;
9441c99275SPeter Avalos len -= 8;
9541c99275SPeter Avalos
96*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %s", tok2str(dvmrp_msgtype_str, "[type %u]", type));
9741c99275SPeter Avalos switch (type) {
9841c99275SPeter Avalos
9941c99275SPeter Avalos case DVMRP_PROBE:
100411677aeSAaron LI if (ndo->ndo_vflag) {
101*ed775ee7SAntonio Huete Jimenez print_probe(ndo, bp, len);
10241c99275SPeter Avalos }
10341c99275SPeter Avalos break;
10441c99275SPeter Avalos
10541c99275SPeter Avalos case DVMRP_REPORT:
106411677aeSAaron LI if (ndo->ndo_vflag > 1) {
107*ed775ee7SAntonio Huete Jimenez print_report(ndo, bp, len);
10841c99275SPeter Avalos }
10941c99275SPeter Avalos break;
11041c99275SPeter Avalos
11141c99275SPeter Avalos case DVMRP_NEIGHBORS:
112*ed775ee7SAntonio Huete Jimenez print_neighbors(ndo, bp, len);
11341c99275SPeter Avalos break;
11441c99275SPeter Avalos
11541c99275SPeter Avalos case DVMRP_NEIGHBORS2:
11641c99275SPeter Avalos /*
117411677aeSAaron LI * extract version from IGMP group address field
11841c99275SPeter Avalos */
11941c99275SPeter Avalos bp -= 4;
120*ed775ee7SAntonio Huete Jimenez major_version = GET_U_1(bp + 3);
121*ed775ee7SAntonio Huete Jimenez minor_version = GET_U_1(bp + 2);
12241c99275SPeter Avalos bp += 4;
123*ed775ee7SAntonio Huete Jimenez print_neighbors2(ndo, bp, len, major_version, minor_version);
12441c99275SPeter Avalos break;
12541c99275SPeter Avalos
12641c99275SPeter Avalos case DVMRP_PRUNE:
127*ed775ee7SAntonio Huete Jimenez ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4));
128*ed775ee7SAntonio Huete Jimenez ND_PRINT(" timer ");
129*ed775ee7SAntonio Huete Jimenez unsigned_relts_print(ndo, GET_BE_U_4(bp + 8));
13041c99275SPeter Avalos break;
13141c99275SPeter Avalos
13241c99275SPeter Avalos case DVMRP_GRAFT:
133*ed775ee7SAntonio Huete Jimenez ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4));
13441c99275SPeter Avalos break;
13541c99275SPeter Avalos
13641c99275SPeter Avalos case DVMRP_GRAFT_ACK:
137*ed775ee7SAntonio Huete Jimenez ND_PRINT(" src %s grp %s", GET_IPADDR_STRING(bp), GET_IPADDR_STRING(bp + 4));
13841c99275SPeter Avalos break;
13941c99275SPeter Avalos }
14041c99275SPeter Avalos return;
14141c99275SPeter Avalos
142*ed775ee7SAntonio Huete Jimenez invalid:
143*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
14441c99275SPeter Avalos }
14541c99275SPeter Avalos
146*ed775ee7SAntonio Huete Jimenez static void
print_report(netdissect_options * ndo,const u_char * bp,u_int len)147411677aeSAaron LI print_report(netdissect_options *ndo,
148*ed775ee7SAntonio Huete Jimenez const u_char *bp,
149*ed775ee7SAntonio Huete Jimenez u_int len)
15041c99275SPeter Avalos {
151*ed775ee7SAntonio Huete Jimenez uint32_t mask, origin;
152*ed775ee7SAntonio Huete Jimenez u_int metric, done;
153*ed775ee7SAntonio Huete Jimenez u_int i, width;
15441c99275SPeter Avalos
15541c99275SPeter Avalos while (len > 0) {
15641c99275SPeter Avalos if (len < 3) {
157*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [length %u < 3]", len);
158*ed775ee7SAntonio Huete Jimenez goto invalid;
15941c99275SPeter Avalos }
160*ed775ee7SAntonio Huete Jimenez mask = (uint32_t)0xff << 24 | GET_U_1(bp) << 16 |
161*ed775ee7SAntonio Huete Jimenez GET_U_1(bp + 1) << 8 | GET_U_1(bp + 2);
16241c99275SPeter Avalos width = 1;
163*ed775ee7SAntonio Huete Jimenez if (GET_U_1(bp))
16441c99275SPeter Avalos width = 2;
165*ed775ee7SAntonio Huete Jimenez if (GET_U_1(bp + 1))
16641c99275SPeter Avalos width = 3;
167*ed775ee7SAntonio Huete Jimenez if (GET_U_1(bp + 2))
16841c99275SPeter Avalos width = 4;
16941c99275SPeter Avalos
170*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\tMask %s", intoa(htonl(mask)));
17141c99275SPeter Avalos bp += 3;
17241c99275SPeter Avalos len -= 3;
17341c99275SPeter Avalos do {
17441c99275SPeter Avalos if (len < width + 1) {
175*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t [Truncated Report]");
176*ed775ee7SAntonio Huete Jimenez goto invalid;
17741c99275SPeter Avalos }
17841c99275SPeter Avalos origin = 0;
17941c99275SPeter Avalos for (i = 0; i < width; ++i) {
180*ed775ee7SAntonio Huete Jimenez origin = origin << 8 | GET_U_1(bp);
181*ed775ee7SAntonio Huete Jimenez bp++;
18241c99275SPeter Avalos }
18341c99275SPeter Avalos for ( ; i < 4; ++i)
18441c99275SPeter Avalos origin <<= 8;
18541c99275SPeter Avalos
186*ed775ee7SAntonio Huete Jimenez metric = GET_U_1(bp);
187*ed775ee7SAntonio Huete Jimenez bp++;
18841c99275SPeter Avalos done = metric & 0x80;
18941c99275SPeter Avalos metric &= 0x7f;
190*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s metric %u", intoa(htonl(origin)),
191*ed775ee7SAntonio Huete Jimenez metric);
19241c99275SPeter Avalos len -= width + 1;
19341c99275SPeter Avalos } while (!done);
19441c99275SPeter Avalos }
195*ed775ee7SAntonio Huete Jimenez return;
196*ed775ee7SAntonio Huete Jimenez
197*ed775ee7SAntonio Huete Jimenez invalid:
198*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
19941c99275SPeter Avalos }
20041c99275SPeter Avalos
201*ed775ee7SAntonio Huete Jimenez static void
print_probe(netdissect_options * ndo,const u_char * bp,u_int len)202411677aeSAaron LI print_probe(netdissect_options *ndo,
203*ed775ee7SAntonio Huete Jimenez const u_char *bp,
204*ed775ee7SAntonio Huete Jimenez u_int len)
20541c99275SPeter Avalos {
206*ed775ee7SAntonio Huete Jimenez if (len < 4) {
207*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [full length %u < 4]", len);
208*ed775ee7SAntonio Huete Jimenez goto invalid;
20941c99275SPeter Avalos }
210*ed775ee7SAntonio Huete Jimenez ND_PRINT(ndo->ndo_vflag > 1 ? "\n\t" : " ");
211*ed775ee7SAntonio Huete Jimenez ND_PRINT("genid %u", GET_BE_U_4(bp));
212*ed775ee7SAntonio Huete Jimenez if (ndo->ndo_vflag < 2)
213*ed775ee7SAntonio Huete Jimenez return;
214*ed775ee7SAntonio Huete Jimenez
21541c99275SPeter Avalos bp += 4;
21641c99275SPeter Avalos len -= 4;
217*ed775ee7SAntonio Huete Jimenez while (len > 0) {
218*ed775ee7SAntonio Huete Jimenez if (len < 4) {
219*ed775ee7SAntonio Huete Jimenez ND_PRINT("[remaining length %u < 4]", len);
220*ed775ee7SAntonio Huete Jimenez goto invalid;
221*ed775ee7SAntonio Huete Jimenez }
222*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\tneighbor %s", GET_IPADDR_STRING(bp));
22341c99275SPeter Avalos bp += 4; len -= 4;
22441c99275SPeter Avalos }
225*ed775ee7SAntonio Huete Jimenez return;
226*ed775ee7SAntonio Huete Jimenez
227*ed775ee7SAntonio Huete Jimenez invalid:
228*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
22941c99275SPeter Avalos }
23041c99275SPeter Avalos
231*ed775ee7SAntonio Huete Jimenez static void
print_neighbors(netdissect_options * ndo,const u_char * bp,u_int len)232411677aeSAaron LI print_neighbors(netdissect_options *ndo,
233*ed775ee7SAntonio Huete Jimenez const u_char *bp,
234*ed775ee7SAntonio Huete Jimenez u_int len)
23541c99275SPeter Avalos {
23641c99275SPeter Avalos const u_char *laddr;
237*ed775ee7SAntonio Huete Jimenez u_char metric;
238*ed775ee7SAntonio Huete Jimenez u_char thresh;
239*ed775ee7SAntonio Huete Jimenez int ncount;
24041c99275SPeter Avalos
241*ed775ee7SAntonio Huete Jimenez while (len > 0) {
242*ed775ee7SAntonio Huete Jimenez if (len < 7) {
243*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [length %u < 7]", len);
244*ed775ee7SAntonio Huete Jimenez goto invalid;
245*ed775ee7SAntonio Huete Jimenez }
24641c99275SPeter Avalos laddr = bp;
24741c99275SPeter Avalos bp += 4;
248*ed775ee7SAntonio Huete Jimenez metric = GET_U_1(bp);
249*ed775ee7SAntonio Huete Jimenez bp++;
250*ed775ee7SAntonio Huete Jimenez thresh = GET_U_1(bp);
251*ed775ee7SAntonio Huete Jimenez bp++;
252*ed775ee7SAntonio Huete Jimenez ncount = GET_U_1(bp);
253*ed775ee7SAntonio Huete Jimenez bp++;
25441c99275SPeter Avalos len -= 7;
25541c99275SPeter Avalos while (--ncount >= 0) {
256*ed775ee7SAntonio Huete Jimenez if (len < 4) {
257*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [length %u < 4]", len);
258*ed775ee7SAntonio Huete Jimenez goto invalid;
259*ed775ee7SAntonio Huete Jimenez }
260*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [%s ->", GET_IPADDR_STRING(laddr));
261*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %s, (%u/%u)]",
262*ed775ee7SAntonio Huete Jimenez GET_IPADDR_STRING(bp), metric, thresh);
26341c99275SPeter Avalos bp += 4;
26441c99275SPeter Avalos len -= 4;
26541c99275SPeter Avalos }
26641c99275SPeter Avalos }
267*ed775ee7SAntonio Huete Jimenez return;
268*ed775ee7SAntonio Huete Jimenez
269*ed775ee7SAntonio Huete Jimenez invalid:
270*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
27141c99275SPeter Avalos }
27241c99275SPeter Avalos
273*ed775ee7SAntonio Huete Jimenez static void
print_neighbors2(netdissect_options * ndo,const u_char * bp,u_int len,uint8_t major_version,uint8_t minor_version)274411677aeSAaron LI print_neighbors2(netdissect_options *ndo,
275*ed775ee7SAntonio Huete Jimenez const u_char *bp,
276*ed775ee7SAntonio Huete Jimenez u_int len, uint8_t major_version,
277411677aeSAaron LI uint8_t minor_version)
27841c99275SPeter Avalos {
27941c99275SPeter Avalos const u_char *laddr;
280*ed775ee7SAntonio Huete Jimenez u_char metric, thresh, flags;
281*ed775ee7SAntonio Huete Jimenez int ncount;
28241c99275SPeter Avalos
283*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (v %u.%u):", major_version, minor_version);
28441c99275SPeter Avalos
285*ed775ee7SAntonio Huete Jimenez while (len > 0) {
286*ed775ee7SAntonio Huete Jimenez if (len < 8) {
287*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [length %u < 8]", len);
288*ed775ee7SAntonio Huete Jimenez goto invalid;
289*ed775ee7SAntonio Huete Jimenez }
29041c99275SPeter Avalos laddr = bp;
29141c99275SPeter Avalos bp += 4;
292*ed775ee7SAntonio Huete Jimenez metric = GET_U_1(bp);
293*ed775ee7SAntonio Huete Jimenez bp++;
294*ed775ee7SAntonio Huete Jimenez thresh = GET_U_1(bp);
295*ed775ee7SAntonio Huete Jimenez bp++;
296*ed775ee7SAntonio Huete Jimenez flags = GET_U_1(bp);
297*ed775ee7SAntonio Huete Jimenez bp++;
298*ed775ee7SAntonio Huete Jimenez ncount = GET_U_1(bp);
299*ed775ee7SAntonio Huete Jimenez bp++;
30041c99275SPeter Avalos len -= 8;
301*ed775ee7SAntonio Huete Jimenez while (--ncount >= 0 && len > 0) {
302*ed775ee7SAntonio Huete Jimenez if (len < 4) {
303*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [length %u < 4]", len);
304*ed775ee7SAntonio Huete Jimenez goto invalid;
305*ed775ee7SAntonio Huete Jimenez }
306*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [%s -> ", GET_IPADDR_STRING(laddr));
307*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s (%u/%u", GET_IPADDR_STRING(bp),
308*ed775ee7SAntonio Huete Jimenez metric, thresh);
30941c99275SPeter Avalos if (flags & DVMRP_NF_TUNNEL)
310*ed775ee7SAntonio Huete Jimenez ND_PRINT("/tunnel");
31141c99275SPeter Avalos if (flags & DVMRP_NF_SRCRT)
312*ed775ee7SAntonio Huete Jimenez ND_PRINT("/srcrt");
31341c99275SPeter Avalos if (flags & DVMRP_NF_QUERIER)
314*ed775ee7SAntonio Huete Jimenez ND_PRINT("/querier");
31541c99275SPeter Avalos if (flags & DVMRP_NF_DISABLED)
316*ed775ee7SAntonio Huete Jimenez ND_PRINT("/disabled");
31741c99275SPeter Avalos if (flags & DVMRP_NF_DOWN)
318*ed775ee7SAntonio Huete Jimenez ND_PRINT("/down");
319*ed775ee7SAntonio Huete Jimenez ND_PRINT(")]");
32041c99275SPeter Avalos bp += 4;
32141c99275SPeter Avalos len -= 4;
32241c99275SPeter Avalos }
32341c99275SPeter Avalos if (ncount != -1) {
324*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [invalid ncount]");
325*ed775ee7SAntonio Huete Jimenez goto invalid;
32641c99275SPeter Avalos }
32741c99275SPeter Avalos }
328*ed775ee7SAntonio Huete Jimenez return;
32941c99275SPeter Avalos
330*ed775ee7SAntonio Huete Jimenez invalid:
331*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
33241c99275SPeter Avalos }
333