File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / igmpproxy / src / rttable.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:00:29 2012 UTC (13 years, 1 month ago) by misho
Branches: igmpproxy, MAIN
CVS tags: v0_1p0, v0_1, HEAD
igmpproxy

    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>