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

1.1     ! misho       1: /*
        !             2:  * Copyright (c) 1998-2001
        !             3:  * University of Southern California/Information Sciences Institute.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  * 3. Neither the name of the project nor the names of its contributors
        !            15:  *    may be used to endorse or promote products derived from this software
        !            16:  *    without specific prior written permission.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
        !            19:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            20:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            21:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
        !            22:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            23:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            24:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            25:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            26:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            28:  * SUCH DAMAGE.
        !            29:  */
        !            30: /*
        !            31:  *  $Id: debug.c,v 1.22 2001/11/28 00:13:50 pavlin Exp $
        !            32:  */
        !            33: /*
        !            34:  * Part of this program has been derived from mrouted.
        !            35:  * The mrouted program is covered by the license in the accompanying file
        !            36:  * named "LICENSE.mrouted".
        !            37:  *
        !            38:  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
        !            39:  * Leland Stanford Junior University.
        !            40:  *
        !            41:  */
        !            42: 
        !            43: #define SYSLOG_NAMES
        !            44: #include "defs.h"
        !            45: 
        !            46: #include <stdarg.h>
        !            47: #include <stdio.h>
        !            48: 
        !            49: #define MAX_MSG_SIZE 64                  /* Max for dump_frame() */
        !            50: 
        !            51: int log_nmsgs = 0;
        !            52: int loglevel = LOG_NOTICE;
        !            53: unsigned long debug = 0x00000000;        /* If (long) is smaller than
        !            54:                                          * 4 bytes, then we are in
        !            55:                                          * trouble.
        !            56:                                          */
        !            57: static char dumpfilename[] = _PATH_PIMD_DUMP;
        !            58: static char cachefilename[] = _PATH_PIMD_CACHE; /* TODO: notused */
        !            59: 
        !            60: 
        !            61: char *packet_kind(int proto, int type, int code)
        !            62: {
        !            63:     static char unknown[60];
        !            64: 
        !            65:     switch (proto) {
        !            66:        case IPPROTO_IGMP:
        !            67:            switch (type) {
        !            68:                case IGMP_MEMBERSHIP_QUERY:     return "IGMP Membership Query    ";
        !            69:                case IGMP_V1_MEMBERSHIP_REPORT: return "IGMP v1 Membership Report";
        !            70:                case IGMP_V2_MEMBERSHIP_REPORT: return "IGMP v2 Membership Report";
        !            71:                case IGMP_V3_MEMBERSHIP_REPORT: return "IGMP v3 Membership Report";
        !            72:                case IGMP_V2_LEAVE_GROUP:       return "IGMP Leave message       ";
        !            73:                case IGMP_DVMRP:
        !            74:                    switch (code) {
        !            75:                        case DVMRP_PROBE:          return "DVMRP Neighbor Probe     ";
        !            76:                        case DVMRP_REPORT:         return "DVMRP Route Report       ";
        !            77:                        case DVMRP_ASK_NEIGHBORS:  return "DVMRP Neighbor Request   ";
        !            78:                        case DVMRP_NEIGHBORS:      return "DVMRP Neighbor List      ";
        !            79:                        case DVMRP_ASK_NEIGHBORS2: return "DVMRP Neighbor request 2 ";
        !            80:                        case DVMRP_NEIGHBORS2:     return "DVMRP Neighbor list 2    ";
        !            81:                        case DVMRP_PRUNE:          return "DVMRP Prune message      ";
        !            82:                        case DVMRP_GRAFT:          return "DVMRP Graft message      ";
        !            83:                        case DVMRP_GRAFT_ACK:      return "DVMRP Graft message ack  ";
        !            84:                        case DVMRP_INFO_REQUEST:   return "DVMRP Info Request       ";
        !            85:                        case DVMRP_INFO_REPLY:     return "DVMRP Info Reply         ";
        !            86:                        default:
        !            87:                            snprintf(unknown, sizeof(unknown), "UNKNOWN DVMRP message code = %3d ", code);
        !            88:                            return unknown;
        !            89:                    }
        !            90: 
        !            91:                case IGMP_PIM:
        !            92:                    /* The old style (PIM v1) encapsulation of PIM messages
        !            93:                     * inside IGMP messages.
        !            94:                     */
        !            95:                    /* PIM v1 is not implemented but we just inform that a message
        !            96:                     *  has arrived.
        !            97:                     */
        !            98:                    switch (code) {
        !            99:                        case PIM_V1_QUERY:         return "PIM v1 Router-Query      ";
        !           100:                        case PIM_V1_REGISTER:      return "PIM v1 Register          ";
        !           101:                        case PIM_V1_REGISTER_STOP: return "PIM v1 Register-Stop     ";
        !           102:                        case PIM_V1_JOIN_PRUNE:    return "PIM v1 Join/Prune        ";
        !           103:                        case PIM_V1_RP_REACHABILITY:
        !           104:                            return "PIM v1 RP-Reachability   ";
        !           105: 
        !           106:                        case PIM_V1_ASSERT:        return "PIM v1 Assert            ";
        !           107:                        case PIM_V1_GRAFT:         return "PIM v1 Graft             ";
        !           108:                        case PIM_V1_GRAFT_ACK:     return "PIM v1 Graft_Ack         ";
        !           109:                        default:
        !           110:                            snprintf(unknown, sizeof(unknown), "UNKNOWN PIM v1 message type =%3d ", code);
        !           111:                            return unknown;
        !           112:                    }
        !           113: 
        !           114:                case IGMP_MTRACE:              return "IGMP trace query         ";
        !           115:                case IGMP_MTRACE_RESP:         return "IGMP trace reply         ";
        !           116:                default:
        !           117:                    snprintf(unknown, sizeof (unknown), "UNKNOWN IGMP message: type = 0x%02x, code = 0x%02x ", type, code);
        !           118:                    return unknown;
        !           119:            }
        !           120: 
        !           121:        case IPPROTO_PIM:    /* PIM v2 */
        !           122:            switch (type) {
        !           123:                case PIM_V2_HELLO:             return "PIM v2 Hello             ";
        !           124:                case PIM_V2_REGISTER:          return "PIM v2 Register          ";
        !           125:                case PIM_V2_REGISTER_STOP:     return "PIM v2 Register_Stop     ";
        !           126:                case PIM_V2_JOIN_PRUNE:        return "PIM v2 Join/Prune        ";
        !           127:                case PIM_V2_BOOTSTRAP:         return "PIM v2 Bootstrap         ";
        !           128:                case PIM_V2_ASSERT:            return "PIM v2 Assert            ";
        !           129:                case PIM_V2_GRAFT:             return "PIM-DM v2 Graft          ";
        !           130:                case PIM_V2_GRAFT_ACK:         return "PIM-DM v2 Graft_Ack      ";
        !           131:                case PIM_V2_CAND_RP_ADV:       return "PIM v2 Cand. RP Adv.     ";
        !           132:                default:
        !           133:                    snprintf(unknown, sizeof(unknown), "UNKNOWN PIM v2 message type =%3d ", type);
        !           134:                    return unknown;
        !           135:            }
        !           136: 
        !           137:        default:
        !           138:            snprintf(unknown, sizeof(unknown), "UNKNOWN proto =%3d               ", proto);
        !           139:            return unknown;
        !           140:     }
        !           141: }
        !           142: 
        !           143: 
        !           144: /*
        !           145:  * Used for debugging particular type of messages.
        !           146:  */
        !           147: int debug_kind(int proto, int type, int code)
        !           148: {
        !           149:     switch (proto) {
        !           150:        case IPPROTO_IGMP:
        !           151:            switch (type) {
        !           152:                case IGMP_MEMBERSHIP_QUERY:        return DEBUG_IGMP;
        !           153:                case IGMP_V1_MEMBERSHIP_REPORT:    return DEBUG_IGMP;
        !           154:                case IGMP_V2_MEMBERSHIP_REPORT:    return DEBUG_IGMP;
        !           155:                case IGMP_V3_MEMBERSHIP_REPORT:    return DEBUG_IGMP;
        !           156:                case IGMP_V2_LEAVE_GROUP:          return DEBUG_IGMP;
        !           157:                case IGMP_DVMRP:
        !           158:                    switch (code) {
        !           159:                        case DVMRP_PROBE:              return DEBUG_DVMRP_PEER;
        !           160:                        case DVMRP_REPORT:             return DEBUG_DVMRP_ROUTE;
        !           161:                        case DVMRP_ASK_NEIGHBORS:      return 0;
        !           162:                        case DVMRP_NEIGHBORS:          return 0;
        !           163:                        case DVMRP_ASK_NEIGHBORS2:     return 0;
        !           164:                        case DVMRP_NEIGHBORS2:         return 0;
        !           165:                        case DVMRP_PRUNE:              return DEBUG_DVMRP_PRUNE;
        !           166:                        case DVMRP_GRAFT:              return DEBUG_DVMRP_PRUNE;
        !           167:                        case DVMRP_GRAFT_ACK:          return DEBUG_DVMRP_PRUNE;
        !           168:                        case DVMRP_INFO_REQUEST:       return 0;
        !           169:                        case DVMRP_INFO_REPLY:         return 0;
        !           170:                        default:                       return 0;
        !           171:                    }
        !           172: 
        !           173:                case IGMP_PIM:
        !           174:                    /* PIM v1 is not implemented */
        !           175:                    switch (code) {
        !           176:                        case PIM_V1_QUERY:             return DEBUG_PIM;
        !           177:                        case PIM_V1_REGISTER:          return DEBUG_PIM;
        !           178:                        case PIM_V1_REGISTER_STOP:     return DEBUG_PIM;
        !           179:                        case PIM_V1_JOIN_PRUNE:        return DEBUG_PIM;
        !           180:                        case PIM_V1_RP_REACHABILITY:   return DEBUG_PIM;
        !           181:                        case PIM_V1_ASSERT:            return DEBUG_PIM;
        !           182:                        case PIM_V1_GRAFT:             return DEBUG_PIM;
        !           183:                        case PIM_V1_GRAFT_ACK:         return DEBUG_PIM;
        !           184:                        default:                       return DEBUG_PIM;
        !           185:                    }
        !           186: 
        !           187:                case IGMP_MTRACE:                  return DEBUG_TRACE;
        !           188:                case IGMP_MTRACE_RESP:             return DEBUG_TRACE;
        !           189:                default:                           return DEBUG_IGMP;
        !           190:            }
        !           191: 
        !           192:        case IPPROTO_PIM:       /* PIM v2 */
        !           193:            /* TODO: modify? */
        !           194:            switch (type) {
        !           195:                case PIM_V2_HELLO:             return DEBUG_PIM;
        !           196:                case PIM_V2_REGISTER:          return DEBUG_PIM_REGISTER;
        !           197:                case PIM_V2_REGISTER_STOP:     return DEBUG_PIM_REGISTER;
        !           198:                case PIM_V2_JOIN_PRUNE:        return DEBUG_PIM;
        !           199:                case PIM_V2_BOOTSTRAP:         return DEBUG_PIM_BOOTSTRAP;
        !           200:                case PIM_V2_ASSERT:            return DEBUG_PIM;
        !           201:                case PIM_V2_GRAFT:             return DEBUG_PIM;
        !           202:                case PIM_V2_GRAFT_ACK:         return DEBUG_PIM;
        !           203:                case PIM_V2_CAND_RP_ADV:       return DEBUG_PIM_CAND_RP;
        !           204:                default:                       return DEBUG_PIM;
        !           205:            }
        !           206: 
        !           207:        default:                               return 0;
        !           208:     }
        !           209: 
        !           210:     return 0;
        !           211: }
        !           212: 
        !           213: 
        !           214: /*
        !           215:  * Some messages are more important than others.  This routine
        !           216:  * determines the logging level at which to log a send error (often
        !           217:  * "No route to host").  This is important when there is asymmetric
        !           218:  * reachability and someone is trying to, i.e., mrinfo me periodically.
        !           219:  */
        !           220: int
        !           221: log_level(int proto, int type, int code)
        !           222: {
        !           223:     switch (proto) {
        !           224:        case IPPROTO_IGMP:
        !           225:            switch (type) {
        !           226:                case IGMP_MTRACE_RESP:
        !           227:                    return LOG_INFO;
        !           228: 
        !           229:                case IGMP_DVMRP:
        !           230:                    switch (code) {
        !           231:                        case DVMRP_NEIGHBORS:
        !           232:                        case DVMRP_NEIGHBORS2:
        !           233:                            return LOG_INFO;
        !           234:                    }
        !           235:                    return LOG_WARNING;
        !           236: 
        !           237:                case IGMP_PIM:
        !           238:                    /* PIM v1 */
        !           239:                    switch (code) {
        !           240:                        default:
        !           241:                            return LOG_INFO;
        !           242:                    }
        !           243:                    return LOG_WARNING;
        !           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:            return LOG_WARNING;
        !           256: 
        !           257:        default:
        !           258:            return LOG_WARNING;
        !           259:     }
        !           260:     return LOG_WARNING;
        !           261: }
        !           262: 
        !           263: 
        !           264: /*
        !           265:  * Dump internal data structures to a file.
        !           266:  */
        !           267: void fdump(int i __attribute__((unused)))
        !           268: {
        !           269:     FILE *fp;
        !           270: 
        !           271:     fp = fopen(dumpfilename, "w");
        !           272:     if (fp) {
        !           273:        dump_vifs(fp);
        !           274:        dump_pim_mrt(fp);
        !           275:        fclose(fp);
        !           276:     }
        !           277: }
        !           278: 
        !           279: /* TODO: dummy, to be used in the future. */
        !           280: /*
        !           281:  * Dump local cache contents to a file.
        !           282:  */
        !           283: void cdump(int i __attribute__((unused)))
        !           284: {
        !           285:     FILE *fp;
        !           286: 
        !           287:     fp = fopen(cachefilename, "w");
        !           288:     if (fp) {
        !           289:        /* XXX: TODO: implement it:
        !           290:           dump_cache(fp);
        !           291:        */
        !           292:        fclose(fp);
        !           293:     }
        !           294: }
        !           295: 
        !           296: /*
        !           297:   1         2         3         4         5         6         7         8
        !           298:   012345678901234567890123456789012345678901234567890123456789012345678901234567890
        !           299:   Virtual Interface Table
        !           300:   Vif  Local-Address    Subnet                Thresh  Flags          Neighbors
        !           301:   0  10.0.3.1         10.0.3/24             1       DR NO-NBR
        !           302:   1  172.16.12.254    172.16.12/24          1       DR PIM         172.16.12.2
        !           303:   172.16.12.3
        !           304:   2  192.168.122.147  register_vif0         1
        !           305: */
        !           306: void dump_vifs(FILE *fp)
        !           307: {
        !           308:     vifi_t vifi;
        !           309:     struct uvif *v;
        !           310:     pim_nbr_entry_t *n;
        !           311:     int width;
        !           312:     int i;
        !           313:     struct listaddr *group, *source;
        !           314: 
        !           315:     fprintf(fp, "Virtual Interface Table ======================================================\n");
        !           316:     fprintf(fp, "Vif  Local Address    Subnet              Thresh  Flags      Neighbors\n");
        !           317:     fprintf(fp, "---  ---------------  ------------------  ------  ---------  -----------------\n");
        !           318: 
        !           319:     for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
        !           320:        int down = 0;
        !           321: 
        !           322:        fprintf(fp, "%3u  %-15s  ", vifi, inet_fmt(v->uv_lcl_addr, s1, sizeof(s1)));
        !           323: 
        !           324:        if (v->uv_flags & VIFF_REGISTER)
        !           325:            fprintf(fp, "%-18s  ", v->uv_name);
        !           326:        else
        !           327:            fprintf(fp,"%-18.18s  ", netname(v->uv_subnet, v->uv_subnetmask));
        !           328: 
        !           329:        fprintf(fp, "%6u ", v->uv_threshold);
        !           330: 
        !           331:        /* TODO: XXX: Print VIFF_TUNNEL? */
        !           332:        width = 0;
        !           333:        if (v->uv_flags & VIFF_DISABLED) {
        !           334:            fprintf(fp, " DISABLED");
        !           335:            down = 1;
        !           336:        }
        !           337:        if (v->uv_flags & VIFF_DOWN) {
        !           338:            fprintf(fp, " DOWN");
        !           339:            down = 1;
        !           340:        }
        !           341: 
        !           342:        if (v->uv_flags & VIFF_DR) {
        !           343:            fprintf(fp, " DR");
        !           344:            width += 3;
        !           345:        }
        !           346:        if (v->uv_flags & VIFF_PIM_NBR) {
        !           347:            fprintf(fp, " PIM");
        !           348:            width += 4;
        !           349:        }
        !           350:        if (v->uv_flags & VIFF_DVMRP_NBR) {
        !           351:            fprintf(fp, " DVMRP");
        !           352:            width += 6;
        !           353:        }
        !           354:        if (v->uv_flags & VIFF_NONBRS) {
        !           355:            fprintf(fp, " NO-NBR");
        !           356:            width += 6;
        !           357:        }
        !           358: 
        !           359:        n = v->uv_pim_neighbors;
        !           360:        if (!down && n) {
        !           361:            for (i = width; i <= 11; i++)
        !           362:                fprintf(fp, " ");
        !           363:            fprintf(fp, "%-15s\n", inet_fmt(n->address, s1, sizeof(s1)));
        !           364:            for (n = n->next; n; n = n->next)
        !           365:                fprintf(fp, "%61s%-15s\n", "", inet_fmt(n->address, s1, sizeof(s1)));
        !           366:        } else {
        !           367:            fprintf(fp, "\n");
        !           368:        }
        !           369:     }
        !           370: 
        !           371:     fprintf(fp, "\n");
        !           372: 
        !           373:     /* Dump groups and sources */
        !           374:     fprintf(fp, " %-3s  %-15s  %-20s", "Vif", "SSM Group", "Sources");
        !           375:     for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
        !           376:        for (group = v->uv_groups; group != NULL; group = group->al_next) {
        !           377:            if (IN_PIM_SSM_RANGE(group->al_addr)) {
        !           378:                fprintf(fp, "\n %3u  %-15s ", vifi, inet_fmt(group->al_addr, s1, sizeof(s1)));
        !           379:                for (source = group->al_sources; source != NULL; source = source->al_next) {
        !           380:                    fprintf(fp, "%s ", inet_fmt(source->al_addr, s1, sizeof(s1)));
        !           381:                }
        !           382:            }
        !           383:        }
        !           384:     }
        !           385: 
        !           386:     fprintf(fp, "\n\n");
        !           387: }
        !           388: 
        !           389: int loglvl(char *level)
        !           390: {
        !           391:     int i;
        !           392: 
        !           393:     for (i = 0; prioritynames[i].c_name; i++) {
        !           394:        if (string_match(prioritynames[i].c_name, level))
        !           395:            return prioritynames[i].c_val;
        !           396:     }
        !           397: 
        !           398:     return atoi(level);
        !           399: }
        !           400: 
        !           401: /*
        !           402:  * Log errors and other messages to the system log daemon and to stderr,
        !           403:  * according to the severity of the message and the current debug level.
        !           404:  * For errors of severity LOG_ERR or worse, terminate the program.
        !           405:  */
        !           406: void logit(int severity, int syserr, const char *format, ...)
        !           407: {
        !           408:     va_list ap;
        !           409:     char msg[211];
        !           410:     struct timeval now;
        !           411:     struct tm *thyme;
        !           412:     time_t lt;
        !           413: 
        !           414:     va_start(ap, format);
        !           415:     vsnprintf(msg, sizeof(msg), format, ap);
        !           416:     va_end(ap);
        !           417: 
        !           418:     /*
        !           419:      * Log to stderr if we haven't forked yet and it's a warning or
        !           420:      * worse, or if we're debugging.
        !           421:      */
        !           422:     if (haveterminal && (debug || severity <= LOG_WARNING)) {
        !           423:        gettimeofday(&now, NULL);
        !           424:        lt = now.tv_sec;
        !           425:        thyme = localtime(&lt);
        !           426: 
        !           427:        if (!debug)
        !           428:            fprintf(stderr, "%s: ", __progname);
        !           429: 
        !           430:        fprintf(stderr, "%02d:%02d:%02d.%03ld %s", thyme->tm_hour, thyme->tm_min,
        !           431:                thyme->tm_sec, (long int)(now.tv_usec / 1000), msg);
        !           432: 
        !           433:        if (syserr) {
        !           434:            errno = syserr;
        !           435:            fprintf(stderr, ": %m");
        !           436:        }
        !           437:        fprintf(stderr, "\n");
        !           438:     }
        !           439: 
        !           440:     /*
        !           441:      * Always log things that are worse than warnings, no matter what
        !           442:      * the log_nmsgs rate limiter says.
        !           443:      *
        !           444:      * Only count things at the defined loglevel or worse in the rate limiter
        !           445:      * and exclude debugging (since if you put daemon.debug in syslog.conf
        !           446:      * you probably actually want to log the debugging messages so they
        !           447:      * shouldn't be rate-limited)
        !           448:      */
        !           449:     if ((severity < LOG_WARNING) || (log_nmsgs < LOG_MAX_MSGS)) {
        !           450:        if ((severity <= loglevel) && (severity != LOG_DEBUG))
        !           451:            log_nmsgs++;
        !           452: 
        !           453:        if (syserr) {
        !           454:            errno = syserr;
        !           455:            syslog(severity, "%s: %m", msg);
        !           456:        } else {
        !           457:            syslog(severity, "%s", msg);
        !           458:        }
        !           459:     }
        !           460: 
        !           461: #ifndef CONTINUE_ON_ERROR
        !           462:     if (severity <= LOG_ERR)
        !           463:        exit(-1);               /* Exit status: 255 */
        !           464: #endif /* CONTINUE_ON_ERROR */
        !           465: }
        !           466: 
        !           467: 
        !           468: /*
        !           469:  * Hex dump a control frame to the log, MAX 64 bytes length
        !           470:  */
        !           471: void dump_frame(char *desc, void *dump, size_t len)
        !           472: {
        !           473:     unsigned int length, i = 0;
        !           474:     unsigned char *data = (unsigned char *)dump;
        !           475:     char buf[80] = "";
        !           476:     char tmp[10];
        !           477: 
        !           478:     length = len;
        !           479:     if (length > MAX_MSG_SIZE)
        !           480:        length = MAX_MSG_SIZE;
        !           481: 
        !           482:     if (desc)
        !           483:        logit(LOG_DEBUG, 0, "%s", desc);
        !           484: 
        !           485:     while (i < length) {
        !           486:        if (!(i % 16))
        !           487:            snprintf(buf, sizeof(buf), "%03X: ", i);
        !           488: 
        !           489:        snprintf(tmp, sizeof(tmp), "%02X ", data[i++]);
        !           490:        strlcat(buf, tmp, sizeof(buf));
        !           491: 
        !           492:        if (i > 0 && !(i % 16))
        !           493:            logit(LOG_DEBUG, 0, "%s", buf);
        !           494:        else if (i > 0 && !(i % 8))
        !           495:            strlcat(buf, ":: ", sizeof(buf));
        !           496:     }
        !           497:     logit(LOG_DEBUG, 0, "%s", buf);
        !           498: }
        !           499: 
        !           500: 
        !           501: static void dump_route(FILE *fp, mrtentry_t *r)
        !           502: {
        !           503:     vifi_t vifi;
        !           504:     char oifs[(sizeof(vifbitmap_t)<<3)+1];
        !           505:     char joined_oifs[(sizeof(vifbitmap_t)<<3)+1];
        !           506:     char pruned_oifs[(sizeof(vifbitmap_t)<<3)+1];
        !           507:     char leaves_oifs[(sizeof(vifbitmap_t)<<3)+1];
        !           508:     char asserted_oifs[(sizeof(vifbitmap_t)<<3)+1];
        !           509:     char incoming_iif[(sizeof(vifbitmap_t)<<3)+1];
        !           510: 
        !           511:     for (vifi = 0; vifi < numvifs; vifi++) {
        !           512:        oifs[vifi] =
        !           513:            VIFM_ISSET(vifi, r->oifs)          ? 'o' : '.';
        !           514:        joined_oifs[vifi] =
        !           515:            VIFM_ISSET(vifi, r->joined_oifs)   ? 'j' : '.';
        !           516:        pruned_oifs[vifi] =
        !           517:            VIFM_ISSET(vifi, r->pruned_oifs)   ? 'p' : '.';
        !           518:        leaves_oifs[vifi] =
        !           519:            VIFM_ISSET(vifi, r->leaves)        ? 'l' : '.';
        !           520:        asserted_oifs[vifi] =
        !           521:            VIFM_ISSET(vifi, r->asserted_oifs) ? 'a' : '.';
        !           522:        incoming_iif[vifi] = '.';
        !           523:     }
        !           524:     oifs[vifi]         = 0x0;  /* End of string */
        !           525:     joined_oifs[vifi]  = 0x0;
        !           526:     pruned_oifs[vifi]  = 0x0;
        !           527:     leaves_oifs[vifi]  = 0x0;
        !           528:     asserted_oifs[vifi] = 0x0;
        !           529:     incoming_iif[vifi] = 0x0;
        !           530:     incoming_iif[r->incoming] = 'I';
        !           531: 
        !           532:     /* TODO: don't need some of the flags */
        !           533:     if (r->flags & MRTF_SPT)          fprintf(fp, " SPT");
        !           534:     if (r->flags & MRTF_WC)           fprintf(fp, " WC");
        !           535:     if (r->flags & MRTF_RP)           fprintf(fp, " RP");
        !           536:     if (r->flags & MRTF_REGISTER)      fprintf(fp, " REG");
        !           537:     if (r->flags & MRTF_IIF_REGISTER)  fprintf(fp, " IIF_REG");
        !           538:     if (r->flags & MRTF_NULL_OIF)      fprintf(fp, " NULL_OIF");
        !           539:     if (r->flags & MRTF_KERNEL_CACHE)  fprintf(fp, " CACHE");
        !           540:     if (r->flags & MRTF_ASSERTED)      fprintf(fp, " ASSERTED");
        !           541:     if (r->flags & MRTF_REG_SUPP)      fprintf(fp, " REG_SUPP");
        !           542:     if (r->flags & MRTF_SG)           fprintf(fp, " SG");
        !           543:     if (r->flags & MRTF_PMBR)         fprintf(fp, " PMBR");
        !           544:     fprintf(fp, "\n");
        !           545: 
        !           546:     fprintf(fp, "Joined   oifs: %-20s\n", joined_oifs);
        !           547:     fprintf(fp, "Pruned   oifs: %-20s\n", pruned_oifs);
        !           548:     fprintf(fp, "Leaves   oifs: %-20s\n", leaves_oifs);
        !           549:     fprintf(fp, "Asserted oifs: %-20s\n", asserted_oifs);
        !           550:     fprintf(fp, "Outgoing oifs: %-20s\n", oifs);
        !           551:     fprintf(fp, "Incoming     : %-20s\n", incoming_iif);
        !           552: 
        !           553:     fprintf(fp, "\nTIMERS:  Entry    JP    RS  Assert VIFS:");
        !           554:     for (vifi = 0; vifi < numvifs; vifi++)
        !           555:        fprintf(fp, "  %d", vifi);
        !           556:     fprintf(fp, "\n         %5d  %4d  %4d  %6d      ",
        !           557:            r->timer, r->jp_timer, r->rs_timer, r->assert_timer);
        !           558:     for (vifi = 0; vifi < numvifs; vifi++)
        !           559:        fprintf(fp, " %2d", r->vif_timers[vifi]);
        !           560:     fprintf(fp, "\n");
        !           561: }
        !           562: 
        !           563: void dump_pim_mrt(FILE *fp)
        !           564: {
        !           565:     grpentry_t *g;
        !           566:     mrtentry_t *r;
        !           567:     u_int number_of_cache_mirrors = 0;
        !           568:     u_int number_of_groups = 0;
        !           569:     cand_rp_t *rp;
        !           570:     kernel_cache_t *kc;
        !           571: 
        !           572:     fprintf(fp, "Multicast Routing Table ======================================================\n");
        !           573: 
        !           574:     /* TODO: remove the dummy 0.0.0.0 group (first in the chain) */
        !           575:     for (g = grplist->next; g; g = g->next) {
        !           576:        number_of_groups++;
        !           577: 
        !           578:        r = g->grp_route;
        !           579:        if (r) {
        !           580:            if (r->flags & MRTF_KERNEL_CACHE) {
        !           581:                for (kc = r->kernel_cache; kc; kc = kc->next)
        !           582:                    number_of_cache_mirrors++;
        !           583:            }
        !           584: 
        !           585:            /* Print the (*,G) routing info */
        !           586:            fprintf(fp, "----------------------------------- (*,G) ------------------------------------\n");
        !           587:            fprintf(fp, "Source           Group            RP Address       Flags\n");
        !           588:            fprintf(fp, "---------------  ---------------  ---------------  ---------------------------\n");
        !           589:            fprintf(fp, "%-15s  ", "INADDR_ANY");
        !           590:            fprintf(fp, "%-15s  ", inet_fmt(g->group, s1, sizeof(s1)));
        !           591:            fprintf(fp, "%-15s ", IN_PIM_SSM_RANGE(g->group) ? "SSM" :
        !           592:                    (g->active_rp_grp ? inet_fmt(g->rpaddr, s2, sizeof(s2)) : "NULL"));
        !           593: 
        !           594:            dump_route(fp, r);
        !           595:        }
        !           596: 
        !           597:        /* Print all (S,G) routing info */
        !           598:        fprintf(fp, "----------------------------------- (S,G) ------------------------------------\n");
        !           599:        for (r = g->mrtlink; r; r = r->grpnext) {
        !           600:            if (r->flags & MRTF_KERNEL_CACHE)
        !           601:                number_of_cache_mirrors++;
        !           602: 
        !           603:            /* Print the routing info */
        !           604:            fprintf(fp, "Source           Group            RP Address       Flags\n");
        !           605:            fprintf(fp, "---------------  ---------------  ---------------  ---------------------------\n");
        !           606:            fprintf(fp, "%-15s  ", inet_fmt(r->source->address, s1, sizeof(s1)));
        !           607:            fprintf(fp, "%-15s  ", inet_fmt(g->group, s2, sizeof(s2)));
        !           608:            fprintf(fp, "%-15s ", IN_PIM_SSM_RANGE(g->group) ? "SSM" :
        !           609:                    (g->active_rp_grp ? inet_fmt(g->rpaddr, s2, sizeof(s2)) : "NULL"));
        !           610: 
        !           611:            dump_route(fp, r);
        !           612:        }
        !           613:     }/* for all groups */
        !           614: 
        !           615:     /* Print the (*,*,R) routing entries */
        !           616:     fprintf(fp, "--------------------------------- (*,*,G) ------------------------------------\n");
        !           617:     for (rp = cand_rp_list; rp; rp = rp->next) {
        !           618:        r = rp->rpentry->mrtlink;
        !           619:        if (r) {
        !           620:            if (r->flags & MRTF_KERNEL_CACHE) {
        !           621:                for (kc = r->kernel_cache; kc; kc = kc->next)
        !           622:                    number_of_cache_mirrors++;
        !           623:            }
        !           624: 
        !           625:            /* Print the (*,*,RP) routing info */
        !           626:            fprintf(fp, "Source           Group            RP Address       Flags\n");
        !           627:            fprintf(fp, "---------------  ---------------  ---------------  ---------------------------\n");
        !           628:            fprintf(fp, "%-15s  ", inet_fmt(r->source->address, s1, sizeof(s1)));
        !           629:            fprintf(fp, "%-15s  ", "INADDR_ANY");
        !           630:            fprintf(fp, "%-15s ", "");
        !           631: 
        !           632:            dump_route(fp, r);
        !           633:        }
        !           634:     } /* For all (*,*,RP) */
        !           635: 
        !           636:     fprintf(fp, "Number of Groups: %u\n", number_of_groups);
        !           637:     fprintf(fp, "Number of Cache MIRRORs: %u\n", number_of_cache_mirrors);
        !           638:     fprintf(fp, "------------------------------------------------------------------------------\n\n");
        !           639: }
        !           640: 
        !           641: static void dump_rpgrp(FILE *fp, rp_grp_entry_t *rpgrp, int indent)
        !           642: {
        !           643:     grp_mask_t *grp = rpgrp->group;
        !           644: 
        !           645:     if (indent)
        !           646:        fprintf(fp, "                           ");
        !           647: 
        !           648:     fprintf(fp, "%-18.18s  %-8u  %-8u\n",
        !           649:            netname(grp->group_addr, grp->group_mask),
        !           650:            rpgrp->priority, rpgrp->holdtime);
        !           651: }
        !           652: 
        !           653: /*
        !           654:  * Dumps the local Cand-RP-set
        !           655:  */
        !           656: int dump_rp_set(FILE *fp)
        !           657: {
        !           658:     cand_rp_t      *rp;
        !           659:     rp_grp_entry_t *rpgrp;
        !           660: 
        !           661:     fprintf(fp, "Candidate Rendezvous-Point Set ===============================================\n");
        !           662:     fprintf(fp, "RP address       Incoming  Group Prefix        Priority  Holdtime\n");
        !           663:     fprintf(fp, "---------------  --------  ------------------  --------  ---------------------\n");
        !           664:     for (rp = cand_rp_list; rp; rp = rp->next) {
        !           665:        fprintf(fp, "%-15s  %-8d  ",
        !           666:                inet_fmt(rp->rpentry->address, s1, sizeof(s1)),
        !           667:                rp->rpentry->incoming);
        !           668: 
        !           669:        rpgrp = rp->rp_grp_next;
        !           670:        if (rpgrp) {
        !           671:            dump_rpgrp(fp, rpgrp, 0);
        !           672: 
        !           673:            for (rpgrp = rpgrp->rp_grp_next; rpgrp; rpgrp = rpgrp->rp_grp_next)
        !           674:                dump_rpgrp(fp, rpgrp, 1);
        !           675:        }
        !           676:     }
        !           677: 
        !           678:     fprintf(fp, "------------------------------------------------------------------------------\n");
        !           679:     fprintf(fp, "Current BSR address: %s\n\n", inet_fmt(curr_bsr_address, s1, sizeof(s1)));
        !           680: 
        !           681:     return TRUE;
        !           682: }
        !           683: 
        !           684: /**
        !           685:  * Local Variables:
        !           686:  *  version-control: t
        !           687:  *  indent-tabs-mode: t
        !           688:  *  c-file-style: "ellemtel"
        !           689:  *  c-basic-offset: 4
        !           690:  * End:
        !           691:  */

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