⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rttable.c

📁 igmp proxy 实现源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***  igmpproxy - IGMP proxy based multicast router **  Copyright (C) 2005 Johnny Egeland <johnny@rlo.org>****  This program is free software; you can redistribute it and/or modify**  it under the terms of the GNU General Public License as published by**  the Free Software Foundation; either version 2 of the License, or**  (at your option) any later version.****  This program is distributed in the hope that it will be useful,**  but WITHOUT ANY WARRANTY; without even the implied warranty of**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the**  GNU General Public License for more details.****  You should have received a copy of the GNU General Public License**  along with this program; if not, write to the Free Software**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA****----------------------------------------------------------------------------****  This software is derived work from the following software. The original**  source code has been modified from it's original state by the author**  of igmpproxy.****  smcroute 0.92 - Copyright (C) 2001 Carsten Schill <carsten@cschill.de>**  - Licensed under the GNU General Public License, version 2**  **  mrouted 3.9-beta3 - COPYRIGHT 1989 by The Board of Trustees of **  Leland Stanford Junior University.**  - Original license can be found in the "doc/mrouted-LINCESE" file.***//***   rttable.c **   Updates the routingtable according to *     recieved request.*/#include "defs.h"    /***   Routing table structure definition. Double linked list...*/struct RouteTable {    struct RouteTable   *nextroute;     // Pointer to the next group in line.    struct RouteTable   *prevroute;     // Pointer to the previous group in line.    uint32              group;          // The group to route    uint32              originAddr;     // The origin adress (only set on activated routes)    uint32              vifBits;        // Bits representing recieving VIFs.    // Keeps the upstream membership state...    short               upstrState;     // Upstream membership state.    // These parameters contain aging details.    uint32              ageVifBits;     // Bits representing aging VIFs.    int                 ageValue;       // Downcounter for death.              int                 ageActivity;    // Records any acitivity that notes there are still listeners.};                 // Keeper for the routing table...static struct RouteTable   *routing_table;// Prototypesvoid logRouteTable(char *header);int  internAgeRoute(struct RouteTable*  croute);// Socket for sending join or leave requests.int mcGroupSock = 0;/***   Function for retrieving the Multicast Group socket.*/int getMcGroupSock() {    if( ! mcGroupSock ) {        mcGroupSock = openUdpSocket( INADDR_ANY, 0 );;    }    return mcGroupSock;} /***   Initializes the routing table.*/void initRouteTable() {    unsigned Ix;    struct IfDesc *Dp;    // Clear routing table...    routing_table = NULL;    // Join the all routers group on downstream vifs...    for ( Ix = 0; Dp = getIfByIx( Ix ); Ix++ ) {        // If this is a downstream vif, we should join the All routers group...        if( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) && Dp->state == IF_STATE_DOWNSTREAM) {            IF_DEBUG log(LOG_DEBUG, 0, "Joining all-routers group %s on vif %s",                         inetFmt(allrouters_group,s1),inetFmt(Dp->InAdr.s_addr,s2));                        //k_join(allrouters_group, Dp->InAdr.s_addr);            joinMcGroup( getMcGroupSock(), Dp, allrouters_group );        }    }}/***   Internal function to send join or leave requests for*   a specified route upstream...*/void sendJoinLeaveUpstream(struct RouteTable* route, int join) {    struct IfDesc*      upstrIf;        // Get the upstream VIF...    upstrIf = getIfByIx( upStreamVif );    if(upstrIf == NULL) {        log(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF.");    }    /*    IF_DEBUG {        log(LOG_DEBUG, 0, "Upstream IF addr  : %s", inetFmt(upstrIf->InAdr.s_addr,s1));        log(LOG_DEBUG, 0, "Upstream IF state : %d", upstrIf->state);        log(LOG_DEBUG, 0, "Upstream IF index : %d", upstrIf->index);    }*/    // Send join or leave request...    if(join) {        // Only join a group if there are listeners downstream...        if(route->vifBits > 0) {            IF_DEBUG log(LOG_DEBUG, 0, "Joining group %s upstream on IF address %s",                         inetFmt(route->group, s1),                          inetFmt(upstrIf->InAdr.s_addr, s2));            //k_join(route->group, upstrIf->InAdr.s_addr);            joinMcGroup( getMcGroupSock(), upstrIf, route->group );            route->upstrState = ROUTESTATE_JOINED;        } else IF_DEBUG {            log(LOG_DEBUG, 0, "No downstream listeners for group %s. No join sent.",                inetFmt(route->group, s1));        }    } else {        // Only leave if group is not left already...        if(route->upstrState != ROUTESTATE_NOTJOINED) {            IF_DEBUG log(LOG_DEBUG, 0, "Leaving group %s upstream on IF address %s",                         inetFmt(route->group, s1),                          inetFmt(upstrIf->InAdr.s_addr, s2));                        //k_leave(route->group, upstrIf->InAdr.s_addr);            leaveMcGroup( getMcGroupSock(), upstrIf, route->group );            route->upstrState = ROUTESTATE_NOTJOINED;        }    }}/***   Clear all routes from routing table, and alerts Leaves upstream.*/void clearAllRoutes() {    struct RouteTable   *croute, *remainroute;    // Loop through all routes...    for(croute = routing_table; croute; croute = remainroute) {        remainroute = croute->nextroute;        // Log the cleanup in debugmode...        IF_DEBUG log(LOG_DEBUG, 0, "Removing route entry for %s",                     inetFmt(croute->group, s1));        // Uninstall current route        if(!internUpdateKernelRoute(croute, 0)) {            log(LOG_WARNING, 0, "The removal from Kernel failed.");        }        // Send Leave message upstream.        sendJoinLeaveUpstream(croute, 0);        // Clear memory, and set pointer to next route...        free(croute);    }    routing_table = NULL;    // Send a notice that the routing table is empty...    log(LOG_NOTICE, 0, "All routes removed. Routing table is empty.");}                 /***   Private access function to find a route from a given *   Route Descriptor.*/struct RouteTable *findRoute(uint32 group) {    struct RouteTable*  croute;    for(croute = routing_table; croute; croute = croute->nextroute) {        if(croute->group == group) {            return croute;        }    }    return NULL;}/***   Adds a specified route to the routingtable.*   If the route already exists, the existing route *   is updated...*/int insertRoute(uint32 group, int ifx) {        struct Config *conf = getCommonConfig();    struct RouteTable*  croute;    int result = 1;    // Sanitycheck the group adress...    if( ! IN_MULTICAST( ntohl(group) )) {        log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group. Table insert failed.",            inetFmt(group, s1));        return 0;    }    // Santiycheck the VIF index...    //if(ifx < 0 || ifx >= MAX_MC_VIFS) {    if(ifx >= MAX_MC_VIFS) {        log(LOG_WARNING, 0, "The VIF Ix %d is out of range (0-%d). Table insert failed.",ifx,MAX_MC_VIFS);        return 0;    }    // Try to find an existing route for this group...    croute = findRoute(group);    if(croute==NULL) {        struct RouteTable*  newroute;        IF_DEBUG log(LOG_DEBUG, 0, "No existing route for %s. Create new.",                     inetFmt(group, s1));        // Create and initialize the new route table entry..        newroute = (struct RouteTable*)malloc(sizeof(struct RouteTable));        // Insert the route desc and clear all pointers...        newroute->group      = group;        newroute->originAddr = 0;        newroute->nextroute  = NULL;        newroute->prevroute  = NULL;        // The group is not joined initially.        newroute->upstrState = ROUTESTATE_NOTJOINED;        // The route is not active yet, so the age is unimportant.        newroute->ageValue    = conf->robustnessValue;        newroute->ageActivity = 0;                BIT_ZERO(newroute->ageVifBits);     // Initially we assume no listeners.        // Set the listener flag...        BIT_ZERO(newroute->vifBits);    // Initially no listeners...        if(ifx >= 0) {            BIT_SET(newroute->vifBits, ifx);        }        // Check if there is a table already....        if(routing_table == NULL) {            // No location set, so insert in on the table top.            routing_table = newroute;            IF_DEBUG log(LOG_DEBUG, 0, "No routes in table. Insert at beginning.");        } else {            IF_DEBUG log(LOG_DEBUG, 0, "Found existing routes. Find insert location.");            // Check if the route could be inserted at the beginning...            if(routing_table->group > group) {                IF_DEBUG log(LOG_DEBUG, 0, "Inserting at beginning, before route %s",inetFmt(routing_table->group,s1));                // Insert at beginning...                newroute->nextroute = routing_table;                newroute->prevroute = NULL;                routing_table = newroute;                // If the route has a next node, the previous pointer must be updated.                if(newroute->nextroute != NULL) {                    newroute->nextroute->prevroute = newroute;                }            } else {                // Find the location which is closest to the route.                for( croute = routing_table; croute->nextroute != NULL; croute = croute->nextroute ) {                    // Find insert position.                    if(croute->nextroute->group > group) {                        break;                    }                }                IF_DEBUG log(LOG_DEBUG, 0, "Inserting after route %s",inetFmt(croute->group,s1));                                // Insert after current...                newroute->nextroute = croute->nextroute;                newroute->prevroute = croute;                if(croute->nextroute != NULL) {                    croute->nextroute->prevroute = newroute;                 }                croute->nextroute = newroute;            }        }        // Set the new route as the current...        croute = newroute;        // Log the cleanup in debugmode...        log(LOG_INFO, 0, "Inserted route table entry for %s on VIF #%d",            inetFmt(croute->group, s1),ifx);    } else if(ifx >= 0) {        // The route exists already, so just update it.        BIT_SET(croute->vifBits, ifx);                // Register the VIF activity for the aging routine        BIT_SET(croute->ageVifBits, ifx);        // Log the cleanup in debugmode...        log(LOG_INFO, 0, "Updated route entry for %s on VIF #%d",            inetFmt(croute->group, s1), ifx);        // If the route is active, it must be reloaded into the Kernel..        if(croute->originAddr != 0) {            // Update route in kernel...            if(!internUpdateKernelRoute(croute, 1)) {                log(LOG_WARNING, 0, "The insertion into Kernel failed.");                return 0;            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -