]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-dvmrp.c
This commit was generated by cvs2svn to compensate for changes in r51292,
[FreeBSD/FreeBSD.git] / contrib / tcpdump / print-dvmrp.c
1 /*
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
22 #ifndef lint
23 static const char rcsid[] =
24     "@(#) $Header: print-dvmrp.c,v 1.13 96/12/10 23:16:30 leres Exp $ (LBL)";
25 #endif
26
27 #include <sys/param.h>
28 #include <sys/time.h>
29 #include <sys/socket.h>
30
31 #include <netinet/in.h>
32 #include <netinet/in_systm.h>
33 #include <netinet/ip.h>
34 #include <netinet/ip_var.h>
35 #include <netinet/udp.h>
36 #include <netinet/udp_var.h>
37 #include <netinet/tcp.h>
38 #include <netinet/tcpip.h>
39
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44
45 #include "interface.h"
46 #include "addrtoname.h"
47
48 /*
49  * DVMRP message types and flag values shamelessly stolen from
50  * mrouted/dvmrp.h.
51  */
52 #define DVMRP_PROBE             1       /* for finding neighbors */
53 #define DVMRP_REPORT            2       /* for reporting some or all routes */
54 #define DVMRP_ASK_NEIGHBORS     3       /* sent by mapper, asking for a list */
55                                         /*
56                                          * of this router's neighbors
57                                          */
58 #define DVMRP_NEIGHBORS         4       /* response to such a request */
59 #define DVMRP_ASK_NEIGHBORS2    5       /* as above, want new format reply */
60 #define DVMRP_NEIGHBORS2        6
61 #define DVMRP_PRUNE             7       /* prune message */
62 #define DVMRP_GRAFT             8       /* graft message */
63 #define DVMRP_GRAFT_ACK         9       /* graft acknowledgement */
64
65 /*
66  * 'flags' byte values in DVMRP_NEIGHBORS2 reply.
67  */
68 #define DVMRP_NF_TUNNEL         0x01    /* neighbors reached via tunnel */
69 #define DVMRP_NF_SRCRT          0x02    /* tunnel uses IP source routing */
70 #define DVMRP_NF_DOWN           0x10    /* kernel state of interface */
71 #define DVMRP_NF_DISABLED       0x20    /* administratively disabled */
72 #define DVMRP_NF_QUERIER        0x40    /* I am the subnet's querier */
73
74 static void print_probe(const u_char *, const u_char *, u_int);
75 static void print_report(const u_char *, const u_char *, u_int);
76 static void print_neighbors(const u_char *, const u_char *, u_int);
77 static void print_neighbors2(const u_char *, const u_char *, u_int);
78 static void print_prune(const u_char *, const u_char *, u_int);
79 static void print_graft(const u_char *, const u_char *, u_int);
80 static void print_graft_ack(const u_char *, const u_char *, u_int);
81
82 static u_int32_t target_level;
83
84 void
85 dvmrp_print(register const u_char *bp, register u_int len)
86 {
87         register const u_char *ep;
88         register u_char type;
89
90         ep = (const u_char *)snapend;
91         if (bp >= ep)
92                 return;
93
94         type = bp[1];
95         bp += 8;
96         /*
97          * Skip IGMP header
98          */
99
100         len -= 8;
101
102         switch (type) {
103
104         case DVMRP_PROBE:
105                 printf(" Probe");
106                 if (vflag)
107                         print_probe(bp, ep, len);
108                 break;
109
110         case DVMRP_REPORT:
111                 printf(" Report");
112                 if (vflag)
113                         print_report(bp, ep, len);
114                 break;
115
116         case DVMRP_ASK_NEIGHBORS:
117                 printf(" Ask-neighbors(old)");
118                 break;
119
120         case DVMRP_NEIGHBORS:
121                 printf(" Neighbors(old)");
122                 print_neighbors(bp, ep, len);
123                 break;
124
125         case DVMRP_ASK_NEIGHBORS2:
126                 printf(" Ask-neighbors2");
127                 break;
128
129         case DVMRP_NEIGHBORS2:
130                 printf(" Neighbors2");
131                 /*
132                  * extract version and capabilities from IGMP group
133                  * address field
134                  */
135                 bp -= 4;
136                 target_level = (bp[0] << 24) | (bp[1] << 16) |
137                     (bp[2] << 8) | bp[3];
138                 bp += 4;
139                 print_neighbors2(bp, ep, len);
140                 break;
141
142         case DVMRP_PRUNE:
143                 printf(" Prune");
144                 print_prune(bp, ep, len);
145                 break;
146
147         case DVMRP_GRAFT:
148                 printf(" Graft");
149                 print_graft(bp, ep, len);
150                 break;
151
152         case DVMRP_GRAFT_ACK:
153                 printf(" Graft-ACK");
154                 print_graft_ack(bp, ep, len);
155                 break;
156
157         default:
158                 printf(" [type %d]", type);
159                 break;
160         }
161 }
162
163 static void
164 print_report(register const u_char *bp, register const u_char *ep,
165     register u_int len)
166 {
167         register u_int32_t mask, origin;
168         register int metric, i, width, done;
169
170         while (len > 0) {
171                 if (len < 3) {
172                         printf(" [|]");
173                         return;
174                 }
175                 mask = (u_int32_t)0xff << 24 | bp[0] << 16 | bp[1] << 8 | bp[2];
176                 width = 1;
177                 if (bp[0])
178                         width = 2;
179                 if (bp[1])
180                         width = 3;
181                 if (bp[2])
182                         width = 4;
183
184                 printf("\n\tMask %s", intoa(htonl(mask)));
185                 bp += 3;
186                 len -= 3;
187                 do {
188                         if (bp + width + 1 > ep) {
189                                 printf(" [|]");
190                                 return;
191                         }
192                         if (len < width + 1) {
193                                 printf("\n\t  [Truncated Report]");
194                                 return;
195                         }
196                         origin = 0;
197                         for (i = 0; i < width; ++i)
198                                 origin = origin << 8 | *bp++;
199                         for ( ; i < 4; ++i)
200                                 origin <<= 8;
201
202                         metric = *bp++;
203                         done = metric & 0x80;
204                         metric &= 0x7f;
205                         printf("\n\t  %s metric %d", intoa(htonl(origin)),
206                                 metric);
207                         len -= width + 1;
208                 } while (!done);
209         }
210 }
211
212 #define GET_ADDR(to) (memcpy((char *)to, (char *)bp, 4), bp += 4)
213
214 static void
215 print_probe(register const u_char *bp, register const u_char *ep,
216     register u_int len)
217 {
218         register u_int32_t genid;
219         u_char neighbor[4];
220
221         if ((len < 4) || ((bp + 4) > ep)) {
222                 /* { (ctags) */
223                 printf(" [|}");
224                 return;
225         }
226         genid = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3];
227         bp += 4;
228         len -= 4;
229         printf("\n\tgenid %u", genid);
230
231         while ((len > 0) && (bp < ep)) {
232                 if ((len < 4) || ((bp + 4) > ep)) {
233                         printf(" [|]");
234                         return;
235                 }
236                 GET_ADDR(neighbor);
237                 len -= 4;
238                 printf("\n\tneighbor %s", ipaddr_string(neighbor));
239         }
240 }
241
242 static void
243 print_neighbors(register const u_char *bp, register const u_char *ep,
244     register u_int len)
245 {
246         u_char laddr[4], neighbor[4];
247         register u_char metric;
248         register u_char thresh;
249         register int ncount;
250
251         while (len > 0 && bp < ep) {
252                 if (len < 7 || (bp + 7) >= ep) {
253                         printf(" [|]");
254                         return;
255                 }
256                 GET_ADDR(laddr);
257                 metric = *bp++;
258                 thresh = *bp++;
259                 ncount = *bp++;
260                 len -= 7;
261                 while (--ncount >= 0 && (len >= 4) && (bp + 4) < ep) {
262                         GET_ADDR(neighbor);
263                         printf(" [%s ->", ipaddr_string(laddr));
264                         printf(" %s, (%d/%d)]",
265                                    ipaddr_string(neighbor), metric, thresh);
266                         len -= 4;
267                 }
268         }
269 }
270
271 static void
272 print_neighbors2(register const u_char *bp, register const u_char *ep,
273     register u_int len)
274 {
275         u_char laddr[4], neighbor[4];
276         register u_char metric, thresh, flags;
277         register int ncount;
278
279         printf(" (v %d.%d):",
280                (int)target_level & 0xff,
281                (int)(target_level >> 8) & 0xff);
282
283         while (len > 0 && bp < ep) {
284                 if (len < 8 || (bp + 8) >= ep) {
285                         printf(" [|]");
286                         return;
287                 }
288                 GET_ADDR(laddr);
289                 metric = *bp++;
290                 thresh = *bp++;
291                 flags = *bp++;
292                 ncount = *bp++;
293                 len -= 8;
294                 while (--ncount >= 0 && (len >= 4) && (bp + 4) <= ep) {
295                         GET_ADDR(neighbor);
296                         printf(" [%s -> ", ipaddr_string(laddr));
297                         printf("%s (%d/%d", ipaddr_string(neighbor),
298                                      metric, thresh);
299                         if (flags & DVMRP_NF_TUNNEL)
300                                 printf("/tunnel");
301                         if (flags & DVMRP_NF_SRCRT)
302                                 printf("/srcrt");
303                         if (flags & DVMRP_NF_QUERIER)
304                                 printf("/querier");
305                         if (flags & DVMRP_NF_DISABLED)
306                                 printf("/disabled");
307                         if (flags & DVMRP_NF_DOWN)
308                                 printf("/down");
309                         printf(")]");
310                         len -= 4;
311                 }
312                 if (ncount != -1) {
313                         printf(" [|]");
314                         return;
315                 }
316         }
317 }
318
319 static void
320 print_prune(register const u_char *bp, register const u_char *ep,
321     register u_int len)
322 {
323         union a {
324                 u_char b[4];
325                 u_int32_t i;
326         } prune_timer;
327
328         if (len < 12 || (bp + 12) > ep) {
329                 printf(" [|]");
330                 return;
331         }
332         printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
333         bp += 8;
334         GET_ADDR(prune_timer.b);
335         printf(" timer %d", (int)ntohl(prune_timer.i));
336 }
337
338 static void
339 print_graft(register const u_char *bp, register const u_char *ep,
340     register u_int len)
341 {
342
343         if (len < 8 || (bp + 8) > ep) {
344                 printf(" [|]");
345                 return;
346         }
347         printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
348 }
349
350 static void
351 print_graft_ack(register const u_char *bp, register const u_char *ep,
352     register u_int len)
353 {
354
355         if (len < 8 || (bp + 8) > ep) {
356                 printf(" [|]");
357                 return;
358         }
359         printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
360 }