Annotation of embedaddon/pimdd/debug.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *  Copyright (c) 1998 by the University of Southern California.
        !             3:  *  All rights reserved.
        !             4:  *
        !             5:  *  Permission to use, copy, modify, and distribute this software and
        !             6:  *  its documentation in source and binary forms for lawful
        !             7:  *  purposes and without fee is hereby granted, provided
        !             8:  *  that the above copyright notice appear in all copies and that both
        !             9:  *  the copyright notice and this permission notice appear in supporting
        !            10:  *  documentation, and that any documentation, advertising materials,
        !            11:  *  and other materials related to such distribution and use acknowledge
        !            12:  *  that the software was developed by the University of Southern
        !            13:  *  California and/or Information Sciences Institute.
        !            14:  *  The name of the University of Southern California may not
        !            15:  *  be used to endorse or promote products derived from this software
        !            16:  *  without specific prior written permission.
        !            17:  *
        !            18:  *  THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
        !            19:  *  ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  THIS SOFTWARE IS
        !            20:  *  PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
        !            21:  *  INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            22:  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND 
        !            23:  *  NON-INFRINGEMENT.
        !            24:  *
        !            25:  *  IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
        !            26:  *  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
        !            27:  *  TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
        !            28:  *  THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            29:  *
        !            30:  *  Other copyrights might apply to parts of this software and are so
        !            31:  *  noted when applicable.
        !            32:  */
        !            33: /*
        !            34:  *  Questions concerning this software should be directed to 
        !            35:  *  Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu)
        !            36:  *
        !            37:  *  $Id: debug.c,v 1.9 1998/06/02 19:46:54 kurtw Exp $
        !            38:  */
        !            39: /*
        !            40:  * Part of this program has been derived from mrouted.
        !            41:  * The mrouted program is covered by the license in the accompanying file
        !            42:  * named "LICENSE.mrouted".
        !            43:  *
        !            44:  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
        !            45:  * Leland Stanford Junior University.
        !            46:  *
        !            47:  */
        !            48: 
        !            49: #include "defs.h"
        !            50: 
        !            51: 
        !            52: #ifdef __STDC__
        !            53: #include <stdarg.h>
        !            54: #else
        !            55: #include <varargs.h>
        !            56: #endif
        !            57: 
        !            58: extern int haveterminal;
        !            59: extern char *progname;
        !            60: 
        !            61: int log_nmsgs = 0;
        !            62: unsigned long debug = 0x00000000;        /* If (long) is smaller than
        !            63:                                          * 4 bytes, then we are in
        !            64:                                          * trouble.
        !            65:                                          */
        !            66: static char dumpfilename[] = _PATH_PIMD_DUMP;
        !            67: static char cachefilename[] = _PATH_PIMD_CACHE; /* TODO: notused */
        !            68: 
        !            69: 
        !            70: char *
        !            71: packet_kind(proto, type, code)
        !            72:     u_int proto, type, code;
        !            73: {
        !            74:     static char unknown[60];
        !            75: 
        !            76:     switch (proto) {
        !            77:     case IPPROTO_IGMP:
        !            78:        switch (type) {
        !            79:        case IGMP_MEMBERSHIP_QUERY:    return "IGMP Membership Query    ";
        !            80:        case IGMP_V1_MEMBERSHIP_REPORT:return "IGMP v1 Member Report    ";
        !            81:        case IGMP_V2_MEMBERSHIP_REPORT:return "IGMP v2 Member Report    ";
        !            82:        case IGMP_V2_LEAVE_GROUP:      return "IGMP Leave message       ";
        !            83:        case IGMP_DVMRP:
        !            84:            switch (code) {
        !            85:            case DVMRP_PROBE:          return "DVMRP Neighbor Probe     ";
        !            86:            case DVMRP_REPORT:         return "DVMRP Route Report       ";
        !            87:            case DVMRP_ASK_NEIGHBORS:  return "DVMRP Neighbor Request   ";
        !            88:            case DVMRP_NEIGHBORS:      return "DVMRP Neighbor List      ";
        !            89:            case DVMRP_ASK_NEIGHBORS2: return "DVMRP Neighbor request 2 ";
        !            90:            case DVMRP_NEIGHBORS2:     return "DVMRP Neighbor list 2    ";
        !            91:            case DVMRP_PRUNE:          return "DVMRP Prune message      ";
        !            92:            case DVMRP_GRAFT:          return "DVMRP Graft message      ";
        !            93:            case DVMRP_GRAFT_ACK:      return "DVMRP Graft message ack  ";
        !            94:            case DVMRP_INFO_REQUEST:   return "DVMRP Info Request       ";
        !            95:            case DVMRP_INFO_REPLY:     return "DVMRP Info Reply         ";
        !            96:            default:
        !            97:                sprintf(unknown,   "UNKNOWN DVMRP message code = %3d ", code);
        !            98:                return unknown;
        !            99:            }
        !           100:        case IGMP_PIM:
        !           101:            /* The old style (PIM v1) encapsulation of PIM messages
        !           102:             * inside IGMP messages.
        !           103:             */
        !           104:            /* PIM v1 is not implemented but we just inform that a message
        !           105:             *  has arrived.
        !           106:             */
        !           107:            switch (code) {
        !           108:            case PIM_V1_QUERY:         return "PIM v1 Router-Query      ";
        !           109:            case PIM_V1_REGISTER:      return "PIM v1 Register          ";
        !           110:            case PIM_V1_REGISTER_STOP: return "PIM v1 Register-Stop     ";
        !           111:            case PIM_V1_JOIN_PRUNE:    return "PIM v1 Join/Prune        ";
        !           112:            case PIM_V1_RP_REACHABILITY:
        !           113:                                       return "PIM v1 RP-Reachability   ";
        !           114:            case PIM_V1_ASSERT:        return "PIM v1 Assert            ";
        !           115:            case PIM_V1_GRAFT:         return "PIM v1 Graft             ";
        !           116:            case PIM_V1_GRAFT_ACK:     return "PIM v1 Graft_Ack         ";
        !           117:            default:
        !           118:                sprintf(unknown,   "UNKNOWN PIM v1 message type =%3d ", code);
        !           119:                return unknown;
        !           120:            }
        !           121:        case IGMP_MTRACE:              return "IGMP trace query         ";
        !           122:        case IGMP_MTRACE_RESP:         return "IGMP trace reply         ";
        !           123:        default:
        !           124:            sprintf(unknown,
        !           125:                    "UNKNOWN IGMP message: type = 0x%02x, code = 0x%02x ",
        !           126:                    type, code);
        !           127:            return unknown;
        !           128:        }
        !           129:     case IPPROTO_PIM:    /* PIM v2 */
        !           130:        switch (type) {
        !           131:        case PIM_V2_HELLO:             return "PIM v2 Hello             ";
        !           132:        case PIM_V2_REGISTER:          return "PIM v2 Register          ";
        !           133:        case PIM_V2_REGISTER_STOP:     return "PIM v2 Register_Stop     ";
        !           134:        case PIM_V2_JOIN_PRUNE:        return "PIM v2 Join/Prune        ";
        !           135:        case PIM_V2_BOOTSTRAP:         return "PIM v2 Bootstrap         ";
        !           136:        case PIM_V2_ASSERT:            return "PIM v2 Assert            ";
        !           137:        case PIM_V2_GRAFT:             return "PIM-DM v2 Graft          ";
        !           138:        case PIM_V2_GRAFT_ACK:         return "PIM-DM v2 Graft_Ack      ";
        !           139:        case PIM_V2_CAND_RP_ADV:       return "PIM v2 Cand. RP Adv.     ";
        !           140:        default:
        !           141:            sprintf(unknown,      "UNKNOWN PIM v2 message type =%3d ", type);
        !           142:            return unknown;
        !           143:        }
        !           144:     default:
        !           145:        sprintf(unknown,          "UNKNOWN proto =%3d               ", proto);
        !           146:        return unknown;
        !           147:     }
        !           148: }
        !           149: 
        !           150: 
        !           151: /*
        !           152:  * Used for debugging particular type of messages.
        !           153:  */
        !           154: int
        !           155: debug_kind(proto, type, code)
        !           156:     u_int proto, type, code;
        !           157: {
        !           158:     switch (proto) {
        !           159:     case IPPROTO_IGMP:
        !           160:        switch (type) {
        !           161:        case IGMP_MEMBERSHIP_QUERY:        return DEBUG_IGMP;
        !           162:        case IGMP_V1_MEMBERSHIP_REPORT:    return DEBUG_IGMP;
        !           163:        case IGMP_V2_MEMBERSHIP_REPORT:    return DEBUG_IGMP;
        !           164:        case IGMP_V2_LEAVE_GROUP:          return DEBUG_IGMP;
        !           165:        case IGMP_DVMRP:
        !           166:            switch (code) {
        !           167:            case DVMRP_PROBE:              return DEBUG_DVMRP_PEER;
        !           168:            case DVMRP_REPORT:             return DEBUG_DVMRP_ROUTE;
        !           169:            case DVMRP_ASK_NEIGHBORS:      return 0;
        !           170:            case DVMRP_NEIGHBORS:          return 0;
        !           171:            case DVMRP_ASK_NEIGHBORS2:     return 0;
        !           172:            case DVMRP_NEIGHBORS2:         return 0;
        !           173:            case DVMRP_PRUNE:              return DEBUG_DVMRP_PRUNE;
        !           174:            case DVMRP_GRAFT:              return DEBUG_DVMRP_PRUNE;
        !           175:            case DVMRP_GRAFT_ACK:          return DEBUG_DVMRP_PRUNE;
        !           176:            case DVMRP_INFO_REQUEST:       return 0;
        !           177:            case DVMRP_INFO_REPLY:         return 0;
        !           178:            default:                       return 0;
        !           179:            }
        !           180:        case IGMP_PIM:
        !           181:            /* PIM v1 is not implemented */
        !           182:            switch (code) {
        !           183:            case PIM_V1_QUERY:             return DEBUG_PIM;
        !           184:            case PIM_V1_REGISTER:          return DEBUG_PIM;
        !           185:            case PIM_V1_REGISTER_STOP:     return DEBUG_PIM;
        !           186:            case PIM_V1_JOIN_PRUNE:        return DEBUG_PIM;
        !           187:            case PIM_V1_RP_REACHABILITY:   return DEBUG_PIM;
        !           188:            case PIM_V1_ASSERT:            return DEBUG_PIM;
        !           189:            case PIM_V1_GRAFT:             return DEBUG_PIM;
        !           190:            case PIM_V1_GRAFT_ACK:         return DEBUG_PIM;
        !           191:            default:                       return DEBUG_PIM;
        !           192:            }
        !           193:        case IGMP_MTRACE:                  return DEBUG_TRACE;
        !           194:        case IGMP_MTRACE_RESP:             return DEBUG_TRACE;
        !           195:        default:                           return DEBUG_IGMP;
        !           196:        }
        !           197:     case IPPROTO_PIM:  /* PIM v2 */
        !           198:        /* TODO: modify? */
        !           199:        switch (type) {
        !           200:        case PIM_V2_HELLO:             return DEBUG_PIM;
        !           201:        case PIM_V2_REGISTER:          return DEBUG_PIM_REGISTER;
        !           202:        case PIM_V2_REGISTER_STOP:     return DEBUG_PIM_REGISTER;
        !           203:        case PIM_V2_JOIN_PRUNE:        return DEBUG_PIM;
        !           204:        case PIM_V2_BOOTSTRAP:         return DEBUG_PIM_BOOTSTRAP;
        !           205:        case PIM_V2_ASSERT:            return DEBUG_PIM;
        !           206:        case PIM_V2_GRAFT:             return DEBUG_PIM;
        !           207:        case PIM_V2_GRAFT_ACK:         return DEBUG_PIM;
        !           208:        case PIM_V2_CAND_RP_ADV:       return DEBUG_PIM_CAND_RP;
        !           209:        default:                       return DEBUG_PIM;
        !           210:        }
        !           211:     default:                               return 0;
        !           212:     }
        !           213:     return 0;
        !           214: }
        !           215: 
        !           216: 
        !           217: /*
        !           218:  * Some messages are more important than others.  This routine
        !           219:  * determines the logging level at which to log a send error (often
        !           220:  * "No route to host").  This is important when there is asymmetric
        !           221:  * reachability and someone is trying to, i.e., mrinfo me periodically.
        !           222:  */
        !           223: int
        !           224: log_level(proto, type, code)
        !           225:     u_int proto, type, code;
        !           226: {
        !           227:     switch (proto) {
        !           228:     case IPPROTO_IGMP:
        !           229:        switch (type) {
        !           230:        case IGMP_MTRACE_RESP:
        !           231:            return LOG_INFO;
        !           232:            
        !           233:        case IGMP_DVMRP:
        !           234:            switch (code) {
        !           235:            case DVMRP_NEIGHBORS:
        !           236:            case DVMRP_NEIGHBORS2:
        !           237:                return LOG_INFO;
        !           238:            }
        !           239:        case IGMP_PIM:
        !           240:            /* PIM v1 */
        !           241:            switch (code) {
        !           242:            default:
        !           243:                return LOG_INFO;
        !           244:            }
        !           245:        default:
        !           246:            return LOG_WARNING;
        !           247:        }
        !           248:        
        !           249:     case IPPROTO_PIM:
        !           250:        /* PIM v2 */
        !           251:        switch (type) {
        !           252:        default:
        !           253:            return LOG_INFO;
        !           254:        }
        !           255:     default:
        !           256:        return LOG_WARNING;
        !           257:     }
        !           258:     return LOG_WARNING;
        !           259: }
        !           260: 
        !           261: 
        !           262: /*
        !           263:  * Dump internal data structures to stderr.
        !           264:  */
        !           265: /* TODO: currently not used
        !           266: void 
        !           267: dump(int i)
        !           268: {
        !           269:     dump_vifs(stderr);
        !           270:     dump_pim_mrt(stderr);
        !           271: }      
        !           272: */
        !           273: 
        !           274: /*
        !           275:  * Dump internal data structures to a file.
        !           276:  */
        !           277: void 
        !           278: fdump(i)
        !           279:     int i;
        !           280: {
        !           281:     FILE *fp;
        !           282:     fp = fopen(dumpfilename, "w");
        !           283:     if (fp != NULL) {
        !           284:        dump_vifs(fp);
        !           285:        dump_pim_mrt(fp);
        !           286:        (void) fclose(fp);
        !           287:     }
        !           288: }
        !           289: 
        !           290: /* TODO: dummy, to be used in the future. */
        !           291: /*
        !           292:  * Dump local cache contents to a file.
        !           293:  */
        !           294: void
        !           295: cdump(i)
        !           296:     int i;
        !           297: {
        !           298:     FILE *fp;
        !           299:     
        !           300:     fp = fopen(cachefilename, "w");
        !           301:     if (fp != NULL) {
        !           302:       /* TODO: implement it:
        !           303:         dump_cache(fp); 
        !           304:         */
        !           305:        (void) fclose(fp);
        !           306:     }
        !           307: }
        !           308: 
        !           309: void
        !           310: dump_vifs(fp)
        !           311:     FILE *fp;
        !           312: {      
        !           313:     vifi_t vifi;
        !           314:     register struct uvif *v;
        !           315:     pim_nbr_entry_t *n;
        !           316:     int width;
        !           317:     int i;
        !           318:     
        !           319:     fprintf(fp, "\nVirtual Interface Table\n %-4s %-17s %-16s %-8s %-14s %s",
        !           320:            "Vif", "Local-Address", "Subnet", "Thresh", "Flags",
        !           321:            "Neighbors\n");
        !           322:     
        !           323:     for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
        !           324:        fprintf(fp, "  %-3u %-17s ", vifi, inet_fmt(v->uv_lcl_addr, s1));
        !           325:        if (v->uv_flags & VIFF_REGISTER)
        !           326:            fprintf(fp, "%-16s ", v->uv_name);
        !           327:        else
        !           328:            fprintf(fp,"%-16.16s ", netname(v->uv_subnet, v->uv_subnetmask));
        !           329:        fprintf(fp, "%-5u   ", v->uv_threshold);
        !           330:        width = 0;
        !           331:        if (v->uv_flags & VIFF_DISABLED)
        !           332:            fprintf(fp, " DISABLED");
        !           333:        if (v->uv_flags & VIFF_DOWN)
        !           334:            fprintf(fp, " DOWN");
        !           335:        if (v->uv_flags & VIFF_DR) {
        !           336:            fprintf(fp, " DR");
        !           337:            width += 3;
        !           338:        }
        !           339:        if (v->uv_flags & VIFF_PIM_NBR) {
        !           340:            fprintf(fp, " PIM");
        !           341:            width += 4;
        !           342:        }
        !           343:        if (v->uv_flags & VIFF_DVMRP_NBR) {
        !           344:            fprintf(fp, " DVMRP");
        !           345:            width += 6;
        !           346:        }
        !           347:        if (v->uv_flags & VIFF_NONBRS) {
        !           348:            fprintf(fp, " %-12s", "NO-NBR");
        !           349:            width += 6;
        !           350:        }
        !           351: 
        !           352:        if ((n = v->uv_pim_neighbors) != NULL) {
        !           353:            /* Print the first neighbor on the same line */
        !           354:            for (i = width; i <= 15; i++)
        !           355:                fprintf(fp, " ");
        !           356:            fprintf(fp, "%-12s\n", inet_fmt(n->address, s1));
        !           357:            for (n = n->next; n != NULL; n = n->next)
        !           358:                fprintf(fp, "%64s %-15s\n", "", inet_fmt(n->address, s1));
        !           359:            
        !           360:        }
        !           361:        else
        !           362:            fprintf(fp, "\n");
        !           363:     }  
        !           364:     fprintf(fp, "\n");
        !           365: }
        !           366: 
        !           367: 
        !           368: /*
        !           369:  * Log errors and other messages to the system log daemon and to stderr,
        !           370:  * according to the severity of the message and the current debug level.
        !           371:  * For errors of severity LOG_ERR or worse, terminate the program.
        !           372:  */
        !           373: #ifdef __STDC__
        !           374: void
        !           375: log(int severity, int syserr, char *format, ...)
        !           376: {
        !           377:     va_list ap;
        !           378:     static char fmt[211] = "warning - ";
        !           379:     char *msg;
        !           380:     struct timeval now;
        !           381:     struct tm *thyme;
        !           382:     
        !           383:     va_start(ap, format);
        !           384: #else
        !           385: /*VARARGS3*/
        !           386: void
        !           387: log(severity, syserr, format, va_alist)
        !           388:     int severity, syserr;
        !           389:     char *format;
        !           390:     va_dcl
        !           391: {
        !           392:     va_list ap;
        !           393:     static char fmt[311] = "warning - ";
        !           394:     char *msg;
        !           395:     char tbuf[20];
        !           396:     struct timeval now;
        !           397:     struct tm *thyme;
        !           398:     
        !           399:     va_start(ap);
        !           400: #endif
        !           401:     vsprintf(&fmt[10], format, ap);
        !           402:     va_end(ap);
        !           403:     msg = (severity == LOG_WARNING) ? fmt : &fmt[10];
        !           404:     
        !           405:     /*
        !           406:      * Log to stderr if we haven't forked yet and it's a warning or worse,
        !           407:      * or if we're debugging.
        !           408:      */
        !           409:     if (haveterminal && (debug || severity <= LOG_WARNING)) {
        !           410:        gettimeofday(&now,NULL);
        !           411:        thyme = localtime(&now.tv_sec);
        !           412:        if (!debug)
        !           413:            fprintf(stderr, "%s: ", progname);
        !           414:        fprintf(stderr, "%02d:%02d:%02d.%03ld %s", thyme->tm_hour,
        !           415:                thyme->tm_min, thyme->tm_sec, now.tv_usec / 1000, msg);
        !           416:        if (syserr == 0)
        !           417:            fprintf(stderr, "\n");
        !           418:        else if (syserr < sys_nerr)
        !           419:            fprintf(stderr, ": %s\n", sys_errlist[syserr]);
        !           420:        else
        !           421:            fprintf(stderr, ": errno %d\n", syserr);
        !           422:     }
        !           423:     
        !           424:     /*
        !           425:      * Always log things that are worse than warnings, no matter what
        !           426:      * the log_nmsgs rate limiter says.
        !           427:      * Only count things worse than debugging in the rate limiter
        !           428:      * (since if you put daemon.debug in syslog.conf you probably
        !           429:      * actually want to log the debugging messages so they shouldn't
        !           430:      * be rate-limited)
        !           431:      */
        !           432:     if ((severity < LOG_WARNING) || (log_nmsgs < LOG_MAX_MSGS)) {
        !           433:        if (severity < LOG_DEBUG)
        !           434:            log_nmsgs++;
        !           435:        if (syserr != 0) {
        !           436:            errno = syserr;
        !           437:            syslog(severity, "%s: %m", msg);
        !           438:        } else
        !           439:            syslog(severity, "%s", msg);
        !           440:     }
        !           441:     
        !           442:     if (severity <= LOG_ERR) exit(-1);
        !           443: }
        !           444: 
        !           445: /* TODO: format the output for better readability */
        !           446: void 
        !           447: dump_pim_mrt(fp)
        !           448:     FILE *fp;
        !           449: {
        !           450:     grpentry_t *g;
        !           451:     register mrtentry_t *r;
        !           452:     register vifi_t vifi;
        !           453:     u_int number_of_groups = 0;
        !           454:     char oifs[(sizeof(vifbitmap_t)<<3)+1];
        !           455:     char pruned_oifs[(sizeof(vifbitmap_t)<<3)+1];
        !           456:     char leaves_oifs[(sizeof(vifbitmap_t)<<3)+1];
        !           457:     char incoming_iif[(sizeof(vifbitmap_t)<<3)+1];
        !           458:     
        !           459:     fprintf(fp, "Multicast Routing Table\n%s", 
        !           460:            " Source          Group           Flags\n");
        !           461: 
        !           462:     /* TODO: remove the dummy 0.0.0.0 group (first in the chain) */
        !           463:     for (g = grplist->next; g != (grpentry_t *)NULL; g = g->next) {
        !           464:        number_of_groups++;
        !           465:        /* Print all (S,G) routing info */
        !           466:        for (r = g->mrtlink; r != (mrtentry_t *)NULL; r = r->grpnext) {
        !           467:            fprintf(fp, "---------------------------(S,G)----------------------------\n");
        !           468:            /* Print the routing info */
        !           469:            fprintf(fp, " %-15s", inet_fmt(r->source->address, s1));
        !           470:            fprintf(fp, " %-15s", inet_fmt(g->group, s2));
        !           471: 
        !           472:            for (vifi = 0; vifi < numvifs; vifi++) {
        !           473:                oifs[vifi] =
        !           474:                    VIFM_ISSET(vifi, r->oifs)          ? 'o' : '.';
        !           475:                pruned_oifs[vifi] =
        !           476:                    VIFM_ISSET(vifi, r->pruned_oifs)   ? 'p' : '.';
        !           477:                leaves_oifs[vifi] =
        !           478:                    VIFM_ISSET(vifi, r->leaves)        ? 'l' : '.';
        !           479:                incoming_iif[vifi] = '.';
        !           480:            }
        !           481:            oifs[vifi]          = 0x0;  /* End of string */
        !           482:            pruned_oifs[vifi]   = 0x0;
        !           483:            leaves_oifs[vifi]   = 0x0;
        !           484:            incoming_iif[vifi]  = 0x0;
        !           485:            incoming_iif[r->incoming] = 'I';
        !           486: 
        !           487:            /* TODO: don't need some of the flags */
        !           488:            if (r->flags & MRTF_SPT)           fprintf(fp, " SPT");
        !           489:            if (r->flags & MRTF_WC)            fprintf(fp, " WC");
        !           490:            if (r->flags & MRTF_RP)            fprintf(fp, " RP");
        !           491:            if (r->flags & MRTF_REGISTER)      fprintf(fp, " REG");
        !           492:            if (r->flags & MRTF_IIF_REGISTER)  fprintf(fp, " IIF_REG");
        !           493:            if (r->flags & MRTF_NULL_OIF)      fprintf(fp, " NULL_OIF");
        !           494:            if (r->flags & MRTF_KERNEL_CACHE)  fprintf(fp, " CACHE");
        !           495:            if (r->flags & MRTF_ASSERTED)      fprintf(fp, " ASSERTED");
        !           496:            if (r->flags & MRTF_REG_SUPP)      fprintf(fp, " REG_SUPP");
        !           497:            if (r->flags & MRTF_SG)            fprintf(fp, " SG");
        !           498:            if (r->flags & MRTF_PMBR)          fprintf(fp, " PMBR");
        !           499:            fprintf(fp, "\n");
        !           500:            
        !           501:            fprintf(fp, "Pruned   oifs: %-20s\n", pruned_oifs);
        !           502:            fprintf(fp, "Leaves   oifs: %-20s\n", leaves_oifs);
        !           503:            fprintf(fp, "Outgoing oifs: %-20s\n", oifs);
        !           504:            fprintf(fp, "Incoming     : %-20s\n", incoming_iif);
        !           505: 
        !           506:            fprintf(fp, "Upstream nbr: %s\n", 
        !           507:                    r->upstream ? inet_fmt(r->upstream->address, s1) : "NONE");
        !           508:            fprintf(fp, "\nTIMERS:  Entry   Prune VIFS:");
        !           509:            for (vifi = 0; vifi < numvifs; vifi++)
        !           510:                fprintf(fp, "  %2d", vifi);
        !           511:            fprintf(fp, "\n           %3d              ",
        !           512:                    r->timer);
        !           513:            for (vifi = 0; vifi < numvifs; vifi++)
        !           514:                fprintf(fp, " %3d", r->prune_timers[vifi]);
        !           515:            fprintf(fp, "\n");
        !           516:        }
        !           517:     }/* for all groups */
        !           518: 
        !           519:     fprintf(fp, "Number of Groups: %u\n", number_of_groups);
        !           520: }
        !           521: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>