Annotation of embedaddon/igmpproxy/src/rttable.c, revision 1.1
1.1 ! misho 1: /*
! 2: ** igmpproxy - IGMP proxy based multicast router
! 3: ** Copyright (C) 2005 Johnny Egeland <johnny@rlo.org>
! 4: **
! 5: ** This program is free software; you can redistribute it and/or modify
! 6: ** it under the terms of the GNU General Public License as published by
! 7: ** the Free Software Foundation; either version 2 of the License, or
! 8: ** (at your option) any later version.
! 9: **
! 10: ** This program is distributed in the hope that it will be useful,
! 11: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
! 12: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 13: ** GNU General Public License for more details.
! 14: **
! 15: ** You should have received a copy of the GNU General Public License
! 16: ** along with this program; if not, write to the Free Software
! 17: ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
! 18: **
! 19: **----------------------------------------------------------------------------
! 20: **
! 21: ** This software is derived work from the following software. The original
! 22: ** source code has been modified from it's original state by the author
! 23: ** of igmpproxy.
! 24: **
! 25: ** smcroute 0.92 - Copyright (C) 2001 Carsten Schill <carsten@cschill.de>
! 26: ** - Licensed under the GNU General Public License, version 2
! 27: **
! 28: ** mrouted 3.9-beta3 - COPYRIGHT 1989 by The Board of Trustees of
! 29: ** Leland Stanford Junior University.
! 30: ** - Original license can be found in the Stanford.txt file.
! 31: **
! 32: */
! 33: /**
! 34: * rttable.c
! 35: *
! 36: * Updates the routingtable according to
! 37: * recieved request.
! 38: */
! 39:
! 40: #include "igmpproxy.h"
! 41:
! 42: /**
! 43: * Routing table structure definition. Double linked list...
! 44: */
! 45: struct RouteTable {
! 46: struct RouteTable *nextroute; // Pointer to the next group in line.
! 47: struct RouteTable *prevroute; // Pointer to the previous group in line.
! 48: uint32_t group; // The group to route
! 49: uint32_t originAddr; // The origin adress (only set on activated routes)
! 50: uint32_t vifBits; // Bits representing recieving VIFs.
! 51:
! 52: // Keeps the upstream membership state...
! 53: short upstrState; // Upstream membership state.
! 54:
! 55: // These parameters contain aging details.
! 56: uint32_t ageVifBits; // Bits representing aging VIFs.
! 57: int ageValue; // Downcounter for death.
! 58: int ageActivity; // Records any acitivity that notes there are still listeners.
! 59: };
! 60:
! 61:
! 62: // Keeper for the routing table...
! 63: static struct RouteTable *routing_table;
! 64:
! 65: // Prototypes
! 66: void logRouteTable(char *header);
! 67: int internAgeRoute(struct RouteTable* croute);
! 68: int internUpdateKernelRoute(struct RouteTable *route, int activate);
! 69:
! 70: // Socket for sending join or leave requests.
! 71: int mcGroupSock = 0;
! 72:
! 73:
! 74: /**
! 75: * Function for retrieving the Multicast Group socket.
! 76: */
! 77: int getMcGroupSock() {
! 78: if( ! mcGroupSock ) {
! 79: mcGroupSock = openUdpSocket( INADDR_ANY, 0 );;
! 80: }
! 81: return mcGroupSock;
! 82: }
! 83:
! 84: /**
! 85: * Initializes the routing table.
! 86: */
! 87: void initRouteTable() {
! 88: unsigned Ix;
! 89: struct IfDesc *Dp;
! 90:
! 91: // Clear routing table...
! 92: routing_table = NULL;
! 93:
! 94: // Join the all routers group on downstream vifs...
! 95: for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) {
! 96: // If this is a downstream vif, we should join the All routers group...
! 97: if( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) && Dp->state == IF_STATE_DOWNSTREAM) {
! 98: my_log(LOG_DEBUG, 0, "Joining all-routers group %s on vif %s",
! 99: inetFmt(allrouters_group,s1),inetFmt(Dp->InAdr.s_addr,s2));
! 100:
! 101: //k_join(allrouters_group, Dp->InAdr.s_addr);
! 102: joinMcGroup( getMcGroupSock(), Dp, allrouters_group );
! 103: }
! 104: }
! 105: }
! 106:
! 107: /**
! 108: * Internal function to send join or leave requests for
! 109: * a specified route upstream...
! 110: */
! 111: void sendJoinLeaveUpstream(struct RouteTable* route, int join) {
! 112: struct IfDesc* upstrIf;
! 113:
! 114: // Get the upstream VIF...
! 115: upstrIf = getIfByIx( upStreamVif );
! 116: if(upstrIf == NULL) {
! 117: my_log(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF.");
! 118: }
! 119:
! 120: // Send join or leave request...
! 121: if(join) {
! 122:
! 123: // Only join a group if there are listeners downstream...
! 124: if(route->vifBits > 0) {
! 125: my_log(LOG_DEBUG, 0, "Joining group %s upstream on IF address %s",
! 126: inetFmt(route->group, s1),
! 127: inetFmt(upstrIf->InAdr.s_addr, s2));
! 128:
! 129: //k_join(route->group, upstrIf->InAdr.s_addr);
! 130: joinMcGroup( getMcGroupSock(), upstrIf, route->group );
! 131:
! 132: route->upstrState = ROUTESTATE_JOINED;
! 133: } else {
! 134: my_log(LOG_DEBUG, 0, "No downstream listeners for group %s. No join sent.",
! 135: inetFmt(route->group, s1));
! 136: }
! 137:
! 138: } else {
! 139: // Only leave if group is not left already...
! 140: if(route->upstrState != ROUTESTATE_NOTJOINED) {
! 141: my_log(LOG_DEBUG, 0, "Leaving group %s upstream on IF address %s",
! 142: inetFmt(route->group, s1),
! 143: inetFmt(upstrIf->InAdr.s_addr, s2));
! 144:
! 145: //k_leave(route->group, upstrIf->InAdr.s_addr);
! 146: leaveMcGroup( getMcGroupSock(), upstrIf, route->group );
! 147:
! 148: route->upstrState = ROUTESTATE_NOTJOINED;
! 149: }
! 150: }
! 151: }
! 152:
! 153: /**
! 154: * Clear all routes from routing table, and alerts Leaves upstream.
! 155: */
! 156: void clearAllRoutes() {
! 157: struct RouteTable *croute, *remainroute;
! 158:
! 159: // Loop through all routes...
! 160: for(croute = routing_table; croute; croute = remainroute) {
! 161:
! 162: remainroute = croute->nextroute;
! 163:
! 164: // Log the cleanup in debugmode...
! 165: my_log(LOG_DEBUG, 0, "Removing route entry for %s",
! 166: inetFmt(croute->group, s1));
! 167:
! 168: // Uninstall current route
! 169: if(!internUpdateKernelRoute(croute, 0)) {
! 170: my_log(LOG_WARNING, 0, "The removal from Kernel failed.");
! 171: }
! 172:
! 173: // Send Leave message upstream.
! 174: sendJoinLeaveUpstream(croute, 0);
! 175:
! 176: // Clear memory, and set pointer to next route...
! 177: free(croute);
! 178: }
! 179: routing_table = NULL;
! 180:
! 181: // Send a notice that the routing table is empty...
! 182: my_log(LOG_NOTICE, 0, "All routes removed. Routing table is empty.");
! 183: }
! 184:
! 185: /**
! 186: * Private access function to find a route from a given
! 187: * Route Descriptor.
! 188: */
! 189: struct RouteTable *findRoute(uint32_t group) {
! 190: struct RouteTable* croute;
! 191:
! 192: for(croute = routing_table; croute; croute = croute->nextroute) {
! 193: if(croute->group == group) {
! 194: return croute;
! 195: }
! 196: }
! 197:
! 198: return NULL;
! 199: }
! 200:
! 201: /**
! 202: * Adds a specified route to the routingtable.
! 203: * If the route already exists, the existing route
! 204: * is updated...
! 205: */
! 206: int insertRoute(uint32_t group, int ifx) {
! 207:
! 208: struct Config *conf = getCommonConfig();
! 209: struct RouteTable* croute;
! 210:
! 211: // Sanitycheck the group adress...
! 212: if( ! IN_MULTICAST( ntohl(group) )) {
! 213: my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group. Table insert failed.",
! 214: inetFmt(group, s1));
! 215: return 0;
! 216: }
! 217:
! 218: // Santiycheck the VIF index...
! 219: //if(ifx < 0 || ifx >= MAX_MC_VIFS) {
! 220: if(ifx >= MAX_MC_VIFS) {
! 221: my_log(LOG_WARNING, 0, "The VIF Ix %d is out of range (0-%d). Table insert failed.",ifx,MAX_MC_VIFS);
! 222: return 0;
! 223: }
! 224:
! 225: // Try to find an existing route for this group...
! 226: croute = findRoute(group);
! 227: if(croute==NULL) {
! 228: struct RouteTable* newroute;
! 229:
! 230: my_log(LOG_DEBUG, 0, "No existing route for %s. Create new.",
! 231: inetFmt(group, s1));
! 232:
! 233:
! 234: // Create and initialize the new route table entry..
! 235: newroute = (struct RouteTable*)malloc(sizeof(struct RouteTable));
! 236: // Insert the route desc and clear all pointers...
! 237: newroute->group = group;
! 238: newroute->originAddr = 0;
! 239: newroute->nextroute = NULL;
! 240: newroute->prevroute = NULL;
! 241:
! 242: // The group is not joined initially.
! 243: newroute->upstrState = ROUTESTATE_NOTJOINED;
! 244:
! 245: // The route is not active yet, so the age is unimportant.
! 246: newroute->ageValue = conf->robustnessValue;
! 247: newroute->ageActivity = 0;
! 248:
! 249: BIT_ZERO(newroute->ageVifBits); // Initially we assume no listeners.
! 250:
! 251: // Set the listener flag...
! 252: BIT_ZERO(newroute->vifBits); // Initially no listeners...
! 253: if(ifx >= 0) {
! 254: BIT_SET(newroute->vifBits, ifx);
! 255: }
! 256:
! 257: // Check if there is a table already....
! 258: if(routing_table == NULL) {
! 259: // No location set, so insert in on the table top.
! 260: routing_table = newroute;
! 261: my_log(LOG_DEBUG, 0, "No routes in table. Insert at beginning.");
! 262: } else {
! 263:
! 264: my_log(LOG_DEBUG, 0, "Found existing routes. Find insert location.");
! 265:
! 266: // Check if the route could be inserted at the beginning...
! 267: if(routing_table->group > group) {
! 268: my_log(LOG_DEBUG, 0, "Inserting at beginning, before route %s",inetFmt(routing_table->group,s1));
! 269:
! 270: // Insert at beginning...
! 271: newroute->nextroute = routing_table;
! 272: newroute->prevroute = NULL;
! 273: routing_table = newroute;
! 274:
! 275: // If the route has a next node, the previous pointer must be updated.
! 276: if(newroute->nextroute != NULL) {
! 277: newroute->nextroute->prevroute = newroute;
! 278: }
! 279:
! 280: } else {
! 281:
! 282: // Find the location which is closest to the route.
! 283: for( croute = routing_table; croute->nextroute != NULL; croute = croute->nextroute ) {
! 284: // Find insert position.
! 285: if(croute->nextroute->group > group) {
! 286: break;
! 287: }
! 288: }
! 289:
! 290: my_log(LOG_DEBUG, 0, "Inserting after route %s",inetFmt(croute->group,s1));
! 291:
! 292: // Insert after current...
! 293: newroute->nextroute = croute->nextroute;
! 294: newroute->prevroute = croute;
! 295: if(croute->nextroute != NULL) {
! 296: croute->nextroute->prevroute = newroute;
! 297: }
! 298: croute->nextroute = newroute;
! 299: }
! 300: }
! 301:
! 302: // Set the new route as the current...
! 303: croute = newroute;
! 304:
! 305: // Log the cleanup in debugmode...
! 306: my_log(LOG_INFO, 0, "Inserted route table entry for %s on VIF #%d",
! 307: inetFmt(croute->group, s1),ifx);
! 308:
! 309: } else if(ifx >= 0) {
! 310:
! 311: // The route exists already, so just update it.
! 312: BIT_SET(croute->vifBits, ifx);
! 313:
! 314: // Register the VIF activity for the aging routine
! 315: BIT_SET(croute->ageVifBits, ifx);
! 316:
! 317: // Log the cleanup in debugmode...
! 318: my_log(LOG_INFO, 0, "Updated route entry for %s on VIF #%d",
! 319: inetFmt(croute->group, s1), ifx);
! 320:
! 321: // If the route is active, it must be reloaded into the Kernel..
! 322: if(croute->originAddr != 0) {
! 323:
! 324: // Update route in kernel...
! 325: if(!internUpdateKernelRoute(croute, 1)) {
! 326: my_log(LOG_WARNING, 0, "The insertion into Kernel failed.");
! 327: return 0;
! 328: }
! 329: }
! 330: }
! 331:
! 332: // Send join message upstream, if the route has no joined flag...
! 333: if(croute->upstrState != ROUTESTATE_JOINED) {
! 334: // Send Join request upstream
! 335: sendJoinLeaveUpstream(croute, 1);
! 336: }
! 337:
! 338: logRouteTable("Insert Route");
! 339:
! 340: return 1;
! 341: }
! 342:
! 343: /**
! 344: * Activates a passive group. If the group is already
! 345: * activated, it's reinstalled in the kernel. If
! 346: * the route is activated, no originAddr is needed.
! 347: */
! 348: int activateRoute(uint32_t group, uint32_t originAddr) {
! 349: struct RouteTable* croute;
! 350: int result = 0;
! 351:
! 352: // Find the requested route.
! 353: croute = findRoute(group);
! 354: if(croute == NULL) {
! 355: my_log(LOG_DEBUG, 0,
! 356: "No table entry for %s [From: %s]. Inserting route.",
! 357: inetFmt(group, s1),inetFmt(originAddr, s2));
! 358:
! 359: // Insert route, but no interfaces have yet requested it downstream.
! 360: insertRoute(group, -1);
! 361:
! 362: // Retrieve the route from table...
! 363: croute = findRoute(group);
! 364: }
! 365:
! 366: if(croute != NULL) {
! 367: // If the origin address is set, update the route data.
! 368: if(originAddr > 0) {
! 369: if(croute->originAddr > 0 && croute->originAddr!=originAddr) {
! 370: my_log(LOG_WARNING, 0, "The origin for route %s changed from %s to %s",
! 371: inetFmt(croute->group, s1),
! 372: inetFmt(croute->originAddr, s2),
! 373: inetFmt(originAddr, s3));
! 374: }
! 375: croute->originAddr = originAddr;
! 376: }
! 377:
! 378: // Only update kernel table if there are listeners !
! 379: if(croute->vifBits > 0) {
! 380: result = internUpdateKernelRoute(croute, 1);
! 381: }
! 382: }
! 383: logRouteTable("Activate Route");
! 384:
! 385: return result;
! 386: }
! 387:
! 388:
! 389: /**
! 390: * This function loops through all routes, and updates the age
! 391: * of any active routes.
! 392: */
! 393: void ageActiveRoutes() {
! 394: struct RouteTable *croute, *nroute;
! 395:
! 396: my_log(LOG_DEBUG, 0, "Aging routes in table.");
! 397:
! 398: // Scan all routes...
! 399: for( croute = routing_table; croute != NULL; croute = nroute ) {
! 400:
! 401: // Keep the next route (since current route may be removed)...
! 402: nroute = croute->nextroute;
! 403:
! 404: // Run the aging round algorithm.
! 405: if(croute->upstrState != ROUTESTATE_CHECK_LAST_MEMBER) {
! 406: // Only age routes if Last member probe is not active...
! 407: internAgeRoute(croute);
! 408: }
! 409: }
! 410: logRouteTable("Age active routes");
! 411: }
! 412:
! 413: /**
! 414: * Should be called when a leave message is recieved, to
! 415: * mark a route for the last member probe state.
! 416: */
! 417: void setRouteLastMemberMode(uint32_t group) {
! 418: struct Config *conf = getCommonConfig();
! 419: struct RouteTable *croute;
! 420:
! 421: croute = findRoute(group);
! 422: if(croute!=NULL) {
! 423: // Check for fast leave mode...
! 424: if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) {
! 425: // Send a leave message right away..
! 426: sendJoinLeaveUpstream(croute, 0);
! 427: }
! 428: // Set the routingstate to Last member check...
! 429: croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER;
! 430: // Set the count value for expiring... (-1 since first aging)
! 431: croute->ageValue = conf->lastMemberQueryCount;
! 432: }
! 433: }
! 434:
! 435:
! 436: /**
! 437: * Ages groups in the last member check state. If the
! 438: * route is not found, or not in this state, 0 is returned.
! 439: */
! 440: int lastMemberGroupAge(uint32_t group) {
! 441: struct RouteTable *croute;
! 442:
! 443: croute = findRoute(group);
! 444: if(croute!=NULL) {
! 445: if(croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER) {
! 446: return !internAgeRoute(croute);
! 447: } else {
! 448: return 0;
! 449: }
! 450: }
! 451: return 0;
! 452: }
! 453:
! 454: /**
! 455: * Remove a specified route. Returns 1 on success,
! 456: * and 0 if route was not found.
! 457: */
! 458: int removeRoute(struct RouteTable* croute) {
! 459: struct Config *conf = getCommonConfig();
! 460: int result = 1;
! 461:
! 462: // If croute is null, no routes was found.
! 463: if(croute==NULL) {
! 464: return 0;
! 465: }
! 466:
! 467: // Log the cleanup in debugmode...
! 468: my_log(LOG_DEBUG, 0, "Removed route entry for %s from table.",
! 469: inetFmt(croute->group, s1));
! 470:
! 471: //BIT_ZERO(croute->vifBits);
! 472:
! 473: // Uninstall current route from kernel
! 474: if(!internUpdateKernelRoute(croute, 0)) {
! 475: my_log(LOG_WARNING, 0, "The removal from Kernel failed.");
! 476: result = 0;
! 477: }
! 478:
! 479: // Send Leave request upstream if group is joined
! 480: if(croute->upstrState == ROUTESTATE_JOINED ||
! 481: (croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER && !conf->fastUpstreamLeave))
! 482: {
! 483: sendJoinLeaveUpstream(croute, 0);
! 484: }
! 485:
! 486: // Update pointers...
! 487: if(croute->prevroute == NULL) {
! 488: // Topmost node...
! 489: if(croute->nextroute != NULL) {
! 490: croute->nextroute->prevroute = NULL;
! 491: }
! 492: routing_table = croute->nextroute;
! 493:
! 494: } else {
! 495: croute->prevroute->nextroute = croute->nextroute;
! 496: if(croute->nextroute != NULL) {
! 497: croute->nextroute->prevroute = croute->prevroute;
! 498: }
! 499: }
! 500: // Free the memory, and set the route to NULL...
! 501: free(croute);
! 502: croute = NULL;
! 503:
! 504: logRouteTable("Remove route");
! 505:
! 506: return result;
! 507: }
! 508:
! 509:
! 510: /**
! 511: * Ages a specific route
! 512: */
! 513: int internAgeRoute(struct RouteTable* croute) {
! 514: struct Config *conf = getCommonConfig();
! 515: int result = 0;
! 516:
! 517: // Drop age by 1.
! 518: croute->ageValue--;
! 519:
! 520: // Check if there has been any activity...
! 521: if( croute->ageVifBits > 0 && croute->ageActivity == 0 ) {
! 522: // There was some activity, check if all registered vifs responded.
! 523: if(croute->vifBits == croute->ageVifBits) {
! 524: // Everything is in perfect order, so we just update the route age.
! 525: croute->ageValue = conf->robustnessValue;
! 526: //croute->ageActivity = 0;
! 527: } else {
! 528: // One or more VIF has not gotten any response.
! 529: croute->ageActivity++;
! 530:
! 531: // Update the actual bits for the route...
! 532: croute->vifBits = croute->ageVifBits;
! 533: }
! 534: }
! 535: // Check if there have been activity in aging process...
! 536: else if( croute->ageActivity > 0 ) {
! 537:
! 538: // If the bits are different in this round, we must
! 539: if(croute->vifBits != croute->ageVifBits) {
! 540: // Or the bits together to insure we don't lose any listeners.
! 541: croute->vifBits |= croute->ageVifBits;
! 542:
! 543: // Register changes in this round as well..
! 544: croute->ageActivity++;
! 545: }
! 546: }
! 547:
! 548: // If the aging counter has reached zero, its time for updating...
! 549: if(croute->ageValue == 0) {
! 550: // Check for activity in the aging process,
! 551: if(croute->ageActivity>0) {
! 552:
! 553: my_log(LOG_DEBUG, 0, "Updating route after aging : %s",
! 554: inetFmt(croute->group,s1));
! 555:
! 556: // Just update the routing settings in kernel...
! 557: internUpdateKernelRoute(croute, 1);
! 558:
! 559: // We append the activity counter to the age, and continue...
! 560: croute->ageValue = croute->ageActivity;
! 561: croute->ageActivity = 0;
! 562: } else {
! 563:
! 564: my_log(LOG_DEBUG, 0, "Removing group %s. Died of old age.",
! 565: inetFmt(croute->group,s1));
! 566:
! 567: // No activity was registered within the timelimit, so remove the route.
! 568: removeRoute(croute);
! 569: }
! 570: // Tell that the route was updated...
! 571: result = 1;
! 572: }
! 573:
! 574: // The aging vif bits must be reset for each round...
! 575: BIT_ZERO(croute->ageVifBits);
! 576:
! 577: return result;
! 578: }
! 579:
! 580: /**
! 581: * Updates the Kernel routing table. If activate is 1, the route
! 582: * is (re-)activated. If activate is false, the route is removed.
! 583: */
! 584: int internUpdateKernelRoute(struct RouteTable *route, int activate) {
! 585: struct MRouteDesc mrDesc;
! 586: struct IfDesc *Dp;
! 587: unsigned Ix;
! 588:
! 589: if(route->originAddr>0) {
! 590:
! 591: // Build route descriptor from table entry...
! 592: // Set the source address and group address...
! 593: mrDesc.McAdr.s_addr = route->group;
! 594: mrDesc.OriginAdr.s_addr = route->originAddr;
! 595:
! 596: // clear output interfaces
! 597: memset( mrDesc.TtlVc, 0, sizeof( mrDesc.TtlVc ) );
! 598:
! 599: my_log(LOG_DEBUG, 0, "Vif bits : 0x%08x", route->vifBits);
! 600:
! 601: // Set the TTL's for the route descriptor...
! 602: for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) {
! 603: if(Dp->state == IF_STATE_UPSTREAM) {
! 604: mrDesc.InVif = Dp->index;
! 605: }
! 606: else if(BIT_TST(route->vifBits, Dp->index)) {
! 607: my_log(LOG_DEBUG, 0, "Setting TTL for Vif %d to %d", Dp->index, Dp->threshold);
! 608: mrDesc.TtlVc[ Dp->index ] = Dp->threshold;
! 609: }
! 610: }
! 611:
! 612: // Do the actual Kernel route update...
! 613: if(activate) {
! 614: // Add route in kernel...
! 615: addMRoute( &mrDesc );
! 616:
! 617: } else {
! 618: // Delete the route from Kernel...
! 619: delMRoute( &mrDesc );
! 620: }
! 621:
! 622: } else {
! 623: my_log(LOG_NOTICE, 0, "Route is not active. No kernel updates done.");
! 624: }
! 625:
! 626: return 1;
! 627: }
! 628:
! 629: /**
! 630: * Debug function that writes the routing table entries
! 631: * to the log.
! 632: */
! 633: void logRouteTable(char *header) {
! 634: struct RouteTable* croute = routing_table;
! 635: unsigned rcount = 0;
! 636:
! 637: my_log(LOG_DEBUG, 0, "");
! 638: my_log(LOG_DEBUG, 0, "Current routing table (%s):", header);
! 639: my_log(LOG_DEBUG, 0, "-----------------------------------------------------");
! 640: if(croute==NULL) {
! 641: my_log(LOG_DEBUG, 0, "No routes in table...");
! 642: } else {
! 643: do {
! 644: /*
! 645: my_log(LOG_DEBUG, 0, "#%d: Src: %s, Dst: %s, Age:%d, St: %s, Prev: 0x%08x, T: 0x%08x, Next: 0x%08x",
! 646: rcount, inetFmt(croute->originAddr, s1), inetFmt(croute->group, s2),
! 647: croute->ageValue,(croute->originAddr>0?"A":"I"),
! 648: croute->prevroute, croute, croute->nextroute);
! 649: */
! 650: my_log(LOG_DEBUG, 0, "#%d: Src: %s, Dst: %s, Age:%d, St: %s, OutVifs: 0x%08x",
! 651: rcount, inetFmt(croute->originAddr, s1), inetFmt(croute->group, s2),
! 652: croute->ageValue,(croute->originAddr>0?"A":"I"),
! 653: croute->vifBits);
! 654:
! 655: croute = croute->nextroute;
! 656:
! 657: rcount++;
! 658: } while ( croute != NULL );
! 659: }
! 660:
! 661: my_log(LOG_DEBUG, 0, "-----------------------------------------------------");
! 662: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>