Annotation of embedaddon/pimdd/debug.c, revision 1.1.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>