Commit | Line | Data |
---|---|---|
984263bc MD |
1 | /* |
2 | * This tool requests configuration info from a multicast router | |
3 | * and prints the reply (if any). Invoke it as: | |
4 | * | |
5 | * mrinfo router-name-or-address | |
6 | * | |
7 | * Written Wed Mar 24 1993 by Van Jacobson (adapted from the | |
8 | * multicast mapper written by Pavel Curtis). | |
9 | * | |
10 | * The lawyers insist we include the following UC copyright notice. | |
11 | * The mapper from which this is derived contained a Xerox copyright | |
12 | * notice which follows the UC one. Try not to get depressed noting | |
13 | * that the legal gibberish is larger than the program. | |
14 | * | |
15 | * Copyright (c) 1993 Regents of the University of California. | |
16 | * All rights reserved. | |
17 | * | |
18 | * Redistribution and use in source and binary forms, with or without | |
19 | * modification, are permitted provided that the following conditions | |
20 | * are met: | |
21 | * 1. Redistributions of source code must retain the above copyright | |
22 | * notice, this list of conditions and the following disclaimer. | |
23 | * 2. Redistributions in binary form must reproduce the above copyright | |
24 | * notice, this list of conditions and the following disclaimer in the | |
25 | * documentation and/or other materials provided with the distribution. | |
26 | * 3. All advertising materials mentioning features or use of this software | |
27 | * must display the following acknowledgement: | |
28 | * This product includes software developed by the Computer Systems | |
29 | * Engineering Group at Lawrence Berkeley Laboratory. | |
30 | * 4. Neither the name of the University nor of the Laboratory may be used | |
31 | * to endorse or promote products derived from this software without | |
32 | * specific prior written permission. | |
33 | * | |
34 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
35 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
36 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
37 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
38 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
39 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
40 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
41 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
42 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
43 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
44 | * SUCH DAMAGE. | |
45 | * --------------------------------- | |
46 | * Copyright (c) Xerox Corporation 1992. All rights reserved. | |
47 | * | |
48 | * License is granted to copy, to use, and to make and to use derivative works | |
49 | * for research and evaluation purposes, provided that Xerox is acknowledged | |
50 | * in all documentation pertaining to any such copy or derivative work. Xerox | |
51 | * grants no other licenses expressed or implied. The Xerox trade name should | |
52 | * not be used in any advertising without its written permission. | |
53 | * | |
54 | * XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE | |
55 | * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE FOR | |
56 | * ANY PARTICULAR PURPOSE. The software is provided "as is" without express | |
57 | * or implied warranty of any kind. | |
58 | * | |
59 | * These notices must be retained in any copies of any part of this software. | |
1de703da MD |
60 | * |
61 | * @(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp | |
62 | * $FreeBSD: src/usr.sbin/mrouted/mrinfo.c,v 1.17.2.1 2002/09/12 16:27:49 nectar Exp $ | |
2d8a3be7 | 63 | * $DragonFly: src/usr.sbin/mrouted/mrinfo.c,v 1.3 2003/11/03 19:31:38 eirikn Exp $ |
984263bc MD |
64 | */ |
65 | ||
984263bc MD |
66 | #include <err.h> |
67 | #include <netdb.h> | |
68 | #include <sys/time.h> | |
69 | #include "defs.h" | |
70 | #include <arpa/inet.h> | |
71 | #ifdef __STDC__ | |
72 | #include <stdarg.h> | |
73 | #else | |
74 | #include <varargs.h> | |
75 | #endif | |
76 | ||
77 | #define DEFAULT_TIMEOUT 4 /* How long to wait before retrying requests */ | |
78 | #define DEFAULT_RETRIES 3 /* How many times to ask each router */ | |
79 | ||
80 | u_int32 our_addr, target_addr = 0; /* in NET order */ | |
81 | int debug = 0; | |
82 | int nflag = 0; | |
83 | int retries = DEFAULT_RETRIES; | |
84 | int timeout = DEFAULT_TIMEOUT; | |
85 | int target_level = 0; | |
86 | vifi_t numvifs; /* to keep loader happy */ | |
87 | /* (see COPY_TABLES macro called in kern.c) */ | |
88 | ||
2d8a3be7 EN |
89 | char * inet_name(u_int32 addr); |
90 | void ask(u_int32 dst); | |
91 | void ask2(u_int32 dst); | |
92 | int get_number(int *var, int deflt, char ***pargv, | |
93 | int *pargc); | |
94 | u_int32 host_addr(char *name); | |
95 | static void usage(void); | |
984263bc MD |
96 | |
97 | /* to shut up -Wstrict-prototypes */ | |
2d8a3be7 | 98 | int main(int argc, char *argv[]); |
984263bc MD |
99 | |
100 | ||
101 | char * | |
102 | inet_name(addr) | |
103 | u_int32 addr; | |
104 | { | |
105 | struct hostent *e; | |
106 | struct in_addr in; | |
107 | ||
108 | if (addr == 0) | |
109 | return "local"; | |
110 | ||
111 | if (nflag || | |
112 | (e = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)) == NULL) { | |
113 | in.s_addr = addr; | |
114 | return (inet_ntoa(in)); | |
115 | } | |
116 | return (e->h_name); | |
117 | } | |
118 | ||
119 | /* | |
120 | * Log errors and other messages to stderr, according to the severity of the | |
121 | * message and the current debug level. For errors of severity LOG_ERR or | |
122 | * worse, terminate the program. | |
123 | */ | |
124 | #ifdef __STDC__ | |
125 | void | |
126 | log(int severity, int syserr, char *format, ...) | |
127 | { | |
128 | va_list ap; | |
129 | char fmt[100]; | |
130 | ||
131 | va_start(ap, format); | |
132 | #else | |
133 | void | |
134 | log(severity, syserr, format, va_alist) | |
135 | int severity, syserr; | |
136 | char *format; | |
137 | va_dcl | |
138 | { | |
139 | va_list ap; | |
140 | char fmt[100]; | |
141 | ||
142 | va_start(ap); | |
143 | #endif | |
144 | switch (debug) { | |
145 | case 0: | |
146 | if (severity > LOG_WARNING) | |
147 | return; | |
148 | case 1: | |
149 | if (severity > LOG_NOTICE) | |
150 | return; | |
151 | case 2: | |
152 | if (severity > LOG_INFO) | |
153 | return; | |
154 | default: | |
155 | fmt[0] = '\0'; | |
156 | if (severity == LOG_WARNING) | |
157 | strcpy(fmt, "warning - "); | |
158 | strncat(fmt, format, sizeof(fmt)-strlen(fmt)); | |
159 | fmt[sizeof(fmt)-1]='\0'; | |
160 | vfprintf(stderr, fmt, ap); | |
161 | if (syserr == 0) | |
162 | fprintf(stderr, "\n"); | |
163 | else if (syserr < sys_nerr) | |
164 | fprintf(stderr, ": %s\n", sys_errlist[syserr]); | |
165 | else | |
166 | fprintf(stderr, ": errno %d\n", syserr); | |
167 | } | |
168 | ||
169 | if (severity <= LOG_ERR) | |
170 | exit(1); | |
171 | } | |
172 | ||
173 | /* | |
174 | * Send a neighbors-list request. | |
175 | */ | |
176 | void | |
177 | ask(dst) | |
178 | u_int32 dst; | |
179 | { | |
180 | send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS, | |
181 | htonl(MROUTED_LEVEL), 0); | |
182 | } | |
183 | ||
184 | void | |
185 | ask2(dst) | |
186 | u_int32 dst; | |
187 | { | |
188 | send_igmp(our_addr, dst, IGMP_DVMRP, DVMRP_ASK_NEIGHBORS2, | |
189 | htonl(MROUTED_LEVEL), 0); | |
190 | } | |
191 | ||
192 | /* | |
193 | * Process an incoming neighbor-list message. | |
194 | */ | |
195 | void | |
196 | accept_neighbors(src, dst, p, datalen, level) | |
197 | u_int32 src, dst, level; | |
198 | u_char *p; | |
199 | int datalen; | |
200 | { | |
201 | u_char *ep = p + datalen; | |
202 | #define GET_ADDR(a) (a = ((u_int32)*p++ << 24), a += ((u_int32)*p++ << 16),\ | |
203 | a += ((u_int32)*p++ << 8), a += *p++) | |
204 | ||
205 | printf("%s (%s):\n", inet_fmt(src, s1), inet_name(src)); | |
206 | while (p < ep) { | |
207 | register u_int32 laddr; | |
208 | register u_char metric; | |
209 | register u_char thresh; | |
210 | register int ncount; | |
211 | ||
212 | GET_ADDR(laddr); | |
213 | laddr = htonl(laddr); | |
214 | metric = *p++; | |
215 | thresh = *p++; | |
216 | ncount = *p++; | |
217 | while (--ncount >= 0) { | |
218 | register u_int32 neighbor; | |
219 | GET_ADDR(neighbor); | |
220 | neighbor = htonl(neighbor); | |
221 | printf(" %s -> ", inet_fmt(laddr, s1)); | |
222 | printf("%s (%s) [%d/%d]\n", inet_fmt(neighbor, s1), | |
223 | inet_name(neighbor), metric, thresh); | |
224 | } | |
225 | } | |
226 | } | |
227 | ||
228 | void | |
229 | accept_neighbors2(src, dst, p, datalen, level) | |
230 | u_int32 src, dst, level; | |
231 | u_char *p; | |
232 | int datalen; | |
233 | { | |
234 | u_char *ep = p + datalen; | |
235 | u_int broken_cisco = ((level & 0xffff) == 0x020a); /* 10.2 */ | |
236 | /* well, only possibly_broken_cisco, but that's too long to type. */ | |
237 | u_int majvers = level & 0xff; | |
238 | u_int minvers = (level >> 8) & 0xff; | |
239 | ||
240 | printf("%s (%s) [", inet_fmt(src, s1), inet_name(src)); | |
241 | if (majvers == 3 && minvers == 0xff) | |
242 | printf("DVMRPv3 compliant"); | |
243 | else | |
244 | printf("version %d.%d", majvers, minvers); | |
245 | printf ("]:\n"); | |
246 | ||
247 | while (p < ep) { | |
248 | register u_char metric; | |
249 | register u_char thresh; | |
250 | register u_char flags; | |
251 | register int ncount; | |
252 | register u_int32 laddr = *(u_int32*)p; | |
253 | ||
254 | p += 4; | |
255 | metric = *p++; | |
256 | thresh = *p++; | |
257 | flags = *p++; | |
258 | ncount = *p++; | |
259 | if (broken_cisco && ncount == 0) /* dumb Ciscos */ | |
260 | ncount = 1; | |
261 | if (broken_cisco && ncount > 15) /* dumb Ciscos */ | |
262 | ncount = ncount & 0xf; | |
263 | while (--ncount >= 0 && p < ep) { | |
264 | register u_int32 neighbor = *(u_int32*)p; | |
265 | p += 4; | |
266 | printf(" %s -> ", inet_fmt(laddr, s1)); | |
267 | printf("%s (%s) [%d/%d", inet_fmt(neighbor, s1), | |
268 | inet_name(neighbor), metric, thresh); | |
269 | if (flags & DVMRP_NF_TUNNEL) | |
270 | printf("/tunnel"); | |
271 | if (flags & DVMRP_NF_SRCRT) | |
272 | printf("/srcrt"); | |
273 | if (flags & DVMRP_NF_PIM) | |
274 | printf("/pim"); | |
275 | if (flags & DVMRP_NF_QUERIER) | |
276 | printf("/querier"); | |
277 | if (flags & DVMRP_NF_DISABLED) | |
278 | printf("/disabled"); | |
279 | if (flags & DVMRP_NF_DOWN) | |
280 | printf("/down"); | |
281 | if (flags & DVMRP_NF_LEAF) | |
282 | printf("/leaf"); | |
283 | printf("]\n"); | |
284 | } | |
285 | } | |
286 | } | |
287 | ||
288 | int | |
289 | get_number(var, deflt, pargv, pargc) | |
290 | int *var, *pargc, deflt; | |
291 | char ***pargv; | |
292 | { | |
293 | if ((*pargv)[0][2] == '\0') { /* Get the value from the next | |
294 | * argument */ | |
295 | if (*pargc > 1 && isdigit((*pargv)[1][0])) { | |
296 | (*pargv)++, (*pargc)--; | |
297 | *var = atoi((*pargv)[0]); | |
298 | return 1; | |
299 | } else if (deflt >= 0) { | |
300 | *var = deflt; | |
301 | return 1; | |
302 | } else | |
303 | return 0; | |
304 | } else { /* Get value from the rest of this argument */ | |
305 | if (isdigit((*pargv)[0][2])) { | |
306 | *var = atoi((*pargv)[0] + 2); | |
307 | return 1; | |
308 | } else { | |
309 | return 0; | |
310 | } | |
311 | } | |
312 | } | |
313 | ||
314 | static void | |
315 | usage() | |
316 | { | |
317 | fprintf(stderr, | |
318 | "usage: mrinfo [-n] [-t timeout] [-r retries] [router]\n"); | |
319 | exit(1); | |
320 | } | |
321 | ||
322 | int | |
323 | main(argc, argv) | |
324 | int argc; | |
325 | char *argv[]; | |
326 | { | |
327 | int tries; | |
328 | int trynew; | |
329 | struct timeval et; | |
330 | struct hostent *hp; | |
331 | struct hostent bogus; | |
332 | char *host; | |
333 | int curaddr; | |
334 | ||
335 | if (geteuid() != 0) | |
336 | errx(1, "must be root"); | |
337 | ||
338 | init_igmp(); | |
339 | setuid(getuid()); | |
340 | ||
341 | setlinebuf(stderr); | |
342 | ||
343 | argv++, argc--; | |
344 | while (argc > 0 && argv[0][0] == '-') { | |
345 | switch (argv[0][1]) { | |
346 | case 'd': | |
347 | if (!get_number(&debug, DEFAULT_DEBUG, &argv, &argc)) | |
348 | usage(); | |
349 | break; | |
350 | case 'n': | |
351 | ++nflag; | |
352 | break; | |
353 | case 'r': | |
354 | if (!get_number(&retries, -1, &argv, &argc)) | |
355 | usage(); | |
356 | break; | |
357 | case 't': | |
358 | if (!get_number(&timeout, -1, &argv, &argc)) | |
359 | usage(); | |
360 | break; | |
361 | default: | |
362 | usage(); | |
363 | } | |
364 | argv++, argc--; | |
365 | } | |
366 | if (argc > 1) | |
367 | usage(); | |
368 | if (argc == 1) | |
369 | host = argv[0]; | |
370 | else | |
371 | host = "127.0.0.1"; | |
372 | ||
373 | if ((target_addr = inet_addr(host)) != -1) { | |
374 | hp = &bogus; | |
375 | hp->h_length = sizeof(target_addr); | |
376 | hp->h_addr_list = (char **)malloc(2 * sizeof(char *)); | |
377 | hp->h_addr_list[0] = malloc(hp->h_length); | |
378 | memcpy(hp->h_addr_list[0], &target_addr, hp->h_length); | |
379 | hp->h_addr_list[1] = 0; | |
380 | } else | |
381 | hp = gethostbyname(host); | |
382 | ||
383 | if (hp == NULL || hp->h_length != sizeof(target_addr)) | |
384 | errx(1, "%s: no such host", argv[0]); | |
385 | if (debug) | |
386 | fprintf(stderr, "Debug level %u\n", debug); | |
387 | ||
388 | /* Check all addresses; mrouters often have unreachable interfaces */ | |
389 | for (curaddr = 0; hp->h_addr_list[curaddr] != NULL; curaddr++) { | |
390 | memcpy(&target_addr, hp->h_addr_list[curaddr], hp->h_length); | |
391 | { /* Find a good local address for us. */ | |
392 | int udp; | |
393 | struct sockaddr_in addr; | |
394 | int addrlen = sizeof(addr); | |
395 | ||
396 | addr.sin_family = AF_INET; | |
397 | #ifdef HAVE_SA_LEN | |
398 | addr.sin_len = sizeof addr; | |
399 | #endif | |
400 | addr.sin_addr.s_addr = target_addr; | |
401 | addr.sin_port = htons(2000); /* any port over 1024 will | |
402 | * do... */ | |
403 | if ((udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0 | |
404 | || connect(udp, (struct sockaddr *) & addr, sizeof(addr)) < 0 | |
405 | || getsockname(udp, (struct sockaddr *) & addr, &addrlen) < 0) | |
406 | err(-1, "determining local address"); | |
407 | close(udp); | |
408 | our_addr = addr.sin_addr.s_addr; | |
409 | } | |
410 | ||
411 | tries = 0; | |
412 | trynew = 1; | |
413 | /* | |
414 | * New strategy: send 'ask2' for two timeouts, then fall back | |
415 | * to 'ask', since it's not very likely that we are going to | |
416 | * find someone who only responds to 'ask' these days | |
417 | */ | |
418 | ask2(target_addr); | |
419 | ||
420 | gettimeofday(&et, 0); | |
421 | et.tv_sec += timeout; | |
422 | ||
423 | /* Main receive loop */ | |
424 | for (;;) { | |
425 | fd_set fds; | |
426 | struct timeval tv, now; | |
427 | int count, recvlen, dummy = 0; | |
428 | register u_int32 src, dst, group; | |
429 | struct ip *ip; | |
430 | struct igmp *igmp; | |
431 | int ipdatalen, iphdrlen, igmpdatalen; | |
432 | ||
433 | if (igmp_socket >= FD_SETSIZE) | |
434 | log(LOG_ERR, 0, "descriptor too big"); | |
435 | FD_ZERO(&fds); | |
436 | FD_SET(igmp_socket, &fds); | |
437 | ||
438 | gettimeofday(&now, 0); | |
439 | tv.tv_sec = et.tv_sec - now.tv_sec; | |
440 | tv.tv_usec = et.tv_usec - now.tv_usec; | |
441 | ||
442 | if (tv.tv_usec < 0) { | |
443 | tv.tv_usec += 1000000L; | |
444 | --tv.tv_sec; | |
445 | } | |
446 | if (tv.tv_sec < 0) | |
447 | tv.tv_sec = tv.tv_usec = 0; | |
448 | ||
449 | count = select(igmp_socket + 1, &fds, 0, 0, &tv); | |
450 | ||
451 | if (count < 0) { | |
452 | if (errno != EINTR) | |
453 | warn("select"); | |
454 | continue; | |
455 | } else if (count == 0) { | |
456 | log(LOG_DEBUG, 0, "Timed out receiving neighbor lists"); | |
457 | if (++tries > retries) | |
458 | break; | |
459 | /* If we've tried ASK_NEIGHBORS2 twice with | |
460 | * no response, fall back to ASK_NEIGHBORS | |
461 | */ | |
462 | if (tries == 2 && target_level == 0) | |
463 | trynew = 0; | |
464 | if (target_level == 0 && trynew == 0) | |
465 | ask(target_addr); | |
466 | else | |
467 | ask2(target_addr); | |
468 | gettimeofday(&et, 0); | |
469 | et.tv_sec += timeout; | |
470 | continue; | |
471 | } | |
472 | recvlen = recvfrom(igmp_socket, recv_buf, RECV_BUF_SIZE, | |
473 | 0, NULL, &dummy); | |
474 | if (recvlen <= 0) { | |
475 | if (recvlen && errno != EINTR) | |
476 | warn("recvfrom"); | |
477 | continue; | |
478 | } | |
479 | ||
480 | if (recvlen < sizeof(struct ip)) { | |
481 | log(LOG_WARNING, 0, | |
482 | "packet too short (%u bytes) for IP header", | |
483 | recvlen); | |
484 | continue; | |
485 | } | |
486 | ip = (struct ip *) recv_buf; | |
487 | if (ip->ip_p == 0) | |
488 | continue; /* Request to install cache entry */ | |
489 | src = ip->ip_src.s_addr; | |
490 | dst = ip->ip_dst.s_addr; | |
491 | iphdrlen = ip->ip_hl << 2; | |
492 | #ifdef RAW_INPUT_IS_RAW | |
493 | ipdatalen = ntohs(ip->ip_len) - iphdrlen; | |
494 | #else | |
495 | ipdatalen = ip->ip_len; | |
496 | #endif | |
497 | if (iphdrlen + ipdatalen != recvlen) { | |
498 | log(LOG_WARNING, 0, | |
499 | "packet shorter (%u bytes) than hdr+data length (%u+%u)", | |
500 | recvlen, iphdrlen, ipdatalen); | |
501 | continue; | |
502 | } | |
503 | igmp = (struct igmp *) (recv_buf + iphdrlen); | |
504 | group = igmp->igmp_group.s_addr; | |
505 | igmpdatalen = ipdatalen - IGMP_MINLEN; | |
506 | if (igmpdatalen < 0) { | |
507 | log(LOG_WARNING, 0, | |
508 | "IP data field too short (%u bytes) for IGMP, from %s", | |
509 | ipdatalen, inet_fmt(src, s1)); | |
510 | continue; | |
511 | } | |
512 | if (igmp->igmp_type != IGMP_DVMRP) | |
513 | continue; | |
514 | ||
515 | switch (igmp->igmp_code) { | |
516 | case DVMRP_NEIGHBORS: | |
517 | case DVMRP_NEIGHBORS2: | |
518 | if (src != target_addr) { | |
519 | warnx("got reply from %s instead of %s", | |
520 | inet_fmt(src, s1), inet_fmt(target_addr, s1)); | |
521 | /*continue;*/ | |
522 | } | |
523 | break; | |
524 | default: | |
525 | continue; /* ignore all other DVMRP messages */ | |
526 | } | |
527 | ||
528 | switch (igmp->igmp_code) { | |
529 | ||
530 | case DVMRP_NEIGHBORS: | |
531 | if (group) { | |
532 | /* knows about DVMRP_NEIGHBORS2 msg */ | |
533 | if (target_level == 0) { | |
534 | target_level = ntohl(group); | |
535 | ask2(target_addr); | |
536 | } | |
537 | } else { | |
538 | accept_neighbors(src, dst, (u_char *)(igmp + 1), | |
539 | igmpdatalen, ntohl(group)); | |
540 | exit(0); | |
541 | } | |
542 | break; | |
543 | ||
544 | case DVMRP_NEIGHBORS2: | |
545 | accept_neighbors2(src, dst, (u_char *)(igmp + 1), | |
546 | igmpdatalen, ntohl(group)); | |
547 | exit(0); | |
548 | } | |
549 | } | |
550 | } | |
551 | exit(1); | |
552 | } | |
553 | ||
554 | /* dummies */ | |
555 | void accept_probe(src, dst, p, datalen, level) | |
556 | u_int32 src, dst, level; | |
557 | char *p; | |
558 | int datalen; | |
559 | { | |
560 | } | |
561 | void accept_group_report(src, dst, group, r_type) | |
562 | u_int32 src, dst, group; | |
563 | int r_type; | |
564 | { | |
565 | } | |
566 | void accept_neighbor_request2(src, dst) | |
567 | u_int32 src, dst; | |
568 | { | |
569 | } | |
570 | void accept_report(src, dst, p, datalen, level) | |
571 | u_int32 src, dst, level; | |
572 | char *p; | |
573 | int datalen; | |
574 | { | |
575 | } | |
576 | void accept_neighbor_request(src, dst) | |
577 | u_int32 src, dst; | |
578 | { | |
579 | } | |
580 | void accept_prune(src, dst, p, datalen) | |
581 | u_int32 src, dst; | |
582 | char *p; | |
583 | int datalen; | |
584 | { | |
585 | } | |
586 | void accept_graft(src, dst, p, datalen) | |
587 | u_int32 src, dst; | |
588 | char *p; | |
589 | int datalen; | |
590 | { | |
591 | } | |
592 | void accept_g_ack(src, dst, p, datalen) | |
593 | u_int32 src, dst; | |
594 | char *p; | |
595 | int datalen; | |
596 | { | |
597 | } | |
598 | void add_table_entry(origin, mcastgrp) | |
599 | u_int32 origin, mcastgrp; | |
600 | { | |
601 | } | |
602 | void check_vif_state() | |
603 | { | |
604 | } | |
605 | void accept_leave_message(src, dst, group) | |
606 | u_int32 src, dst, group; | |
607 | { | |
608 | } | |
609 | void accept_mtrace(src, dst, group, data, no, datalen) | |
610 | u_int32 src, dst, group; | |
611 | char *data; | |
612 | u_int no; | |
613 | int datalen; | |
614 | { | |
615 | } | |
616 | void accept_membership_query(src, dst, group, tmo) | |
617 | u_int32 src, dst, group; | |
618 | int tmo; | |
619 | { | |
620 | } | |
621 | void accept_info_request(src, dst, p, datalen) | |
622 | u_int32 src, dst; | |
623 | u_char *p; | |
624 | int datalen; | |
625 | { | |
626 | } | |
627 | void accept_info_reply(src, dst, p, datalen) | |
628 | u_int32 src, dst; | |
629 | u_char *p; | |
630 | int datalen; | |
631 | { | |
632 | } |