[BACK]Return to mrinfo.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.sbin / mrinfo

Annotation of src/usr.sbin/mrinfo/mrinfo.c, Revision 1.12.2.2

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

CVSweb <webmaster@jp.NetBSD.org>