Annotation of embedaddon/igmpproxy/src/mroute-api.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: *   mroute-api.c
        !            35: *
        !            36: *   This module contains the interface routines to the Linux mrouted API
        !            37: */
        !            38: 
        !            39: 
        !            40: #include "igmpproxy.h"
        !            41: 
        !            42: // MAX_MC_VIFS from mclab.h must have same value as MAXVIFS from mroute.h
        !            43: #if MAX_MC_VIFS != MAXVIFS
        !            44: # error "constants don't match, correct mclab.h"
        !            45: #endif
        !            46:      
        !            47: // need an IGMP socket as interface for the mrouted API
        !            48: // - receives the IGMP messages
        !            49: int         MRouterFD;        /* socket for all network I/O  */
        !            50: char        *recv_buf;           /* input packet buffer         */
        !            51: char        *send_buf;           /* output packet buffer        */
        !            52: 
        !            53: 
        !            54: // my internal virtual interfaces descriptor vector  
        !            55: static struct VifDesc {
        !            56:     struct IfDesc *IfDp;
        !            57: } VifDescVc[ MAXVIFS ];
        !            58: 
        !            59: 
        !            60: 
        !            61: /*
        !            62: ** Initialises the mrouted API and locks it by this exclusively.
        !            63: **     
        !            64: ** returns: - 0 if the functions succeeds     
        !            65: **          - the errno value for non-fatal failure condition
        !            66: */
        !            67: int enableMRouter()
        !            68: {
        !            69:     int Va = 1;
        !            70: 
        !            71:     if ( (MRouterFD  = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0 )
        !            72:         my_log( LOG_ERR, errno, "IGMP socket open" );
        !            73: 
        !            74:     if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_INIT, 
        !            75:                      (void *)&Va, sizeof( Va ) ) )
        !            76:         return errno;
        !            77: 
        !            78:     return 0;
        !            79: }
        !            80: 
        !            81: /*
        !            82: ** Diables the mrouted API and relases by this the lock.
        !            83: **          
        !            84: */
        !            85: void disableMRouter()
        !            86: {
        !            87:     if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_DONE, NULL, 0 ) 
        !            88:          || close( MRouterFD )
        !            89:        ) {
        !            90:         MRouterFD = 0;
        !            91:         my_log( LOG_ERR, errno, "MRT_DONE/close" );
        !            92:     }
        !            93: 
        !            94:     MRouterFD = 0;
        !            95: }
        !            96: 
        !            97: /*
        !            98: ** Adds the interface '*IfDp' as virtual interface to the mrouted API
        !            99: ** 
        !           100: */
        !           101: void addVIF( struct IfDesc *IfDp )
        !           102: {
        !           103:     struct vifctl VifCtl;
        !           104:     struct VifDesc *VifDp;
        !           105: 
        !           106:     /* search free VifDesc
        !           107:      */
        !           108:     for ( VifDp = VifDescVc; VifDp < VCEP( VifDescVc ); VifDp++ ) {
        !           109:         if ( ! VifDp->IfDp )
        !           110:             break;
        !           111:     }
        !           112: 
        !           113:     /* no more space
        !           114:      */
        !           115:     if ( VifDp >= VCEP( VifDescVc ) )
        !           116:         my_log( LOG_ERR, ENOMEM, "addVIF, out of VIF space" );
        !           117: 
        !           118:     VifDp->IfDp = IfDp;
        !           119: 
        !           120:     VifCtl.vifc_vifi  = VifDp - VifDescVc; 
        !           121:     VifCtl.vifc_flags = 0;        /* no tunnel, no source routing, register ? */
        !           122:     VifCtl.vifc_threshold  = VifDp->IfDp->threshold;    // Packet TTL must be at least 1 to pass them
        !           123:     VifCtl.vifc_rate_limit = VifDp->IfDp->ratelimit;    // Ratelimit
        !           124: 
        !           125:     VifCtl.vifc_lcl_addr.s_addr = VifDp->IfDp->InAdr.s_addr;
        !           126:     VifCtl.vifc_rmt_addr.s_addr = INADDR_ANY;
        !           127: 
        !           128:     // Set the index...
        !           129:     VifDp->IfDp->index = VifCtl.vifc_vifi;
        !           130: 
        !           131:     my_log( LOG_NOTICE, 0, "adding VIF, Ix %d Fl 0x%x IP 0x%08x %s, Threshold: %d, Ratelimit: %d", 
        !           132:          VifCtl.vifc_vifi, VifCtl.vifc_flags,  VifCtl.vifc_lcl_addr.s_addr, VifDp->IfDp->Name,
        !           133:          VifCtl.vifc_threshold, VifCtl.vifc_rate_limit);
        !           134: 
        !           135:     struct SubnetList *currSubnet;
        !           136:     for(currSubnet = IfDp->allowednets; currSubnet; currSubnet = currSubnet->next) {
        !           137:        my_log(LOG_DEBUG, 0, "        Network for [%s] : %s",
        !           138:            IfDp->Name,
        !           139:            inetFmts(currSubnet->subnet_addr, currSubnet->subnet_mask, s1));
        !           140:     }
        !           141: 
        !           142:     if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF, 
        !           143:                      (char *)&VifCtl, sizeof( VifCtl ) ) )
        !           144:         my_log( LOG_ERR, errno, "MRT_ADD_VIF" );
        !           145: 
        !           146: }
        !           147: 
        !           148: /*
        !           149: ** Adds the multicast routed '*Dp' to the kernel routes
        !           150: **
        !           151: ** returns: - 0 if the function succeeds
        !           152: **          - the errno value for non-fatal failure condition
        !           153: */
        !           154: int addMRoute( struct MRouteDesc *Dp )
        !           155: {
        !           156:     struct mfcctl CtlReq;
        !           157:     int rc;
        !           158: 
        !           159:     CtlReq.mfcc_origin    = Dp->OriginAdr;
        !           160:     CtlReq.mfcc_mcastgrp  = Dp->McAdr;
        !           161:     CtlReq.mfcc_parent    = Dp->InVif;
        !           162: 
        !           163:     /* copy the TTL vector
        !           164:      */
        !           165: 
        !           166:     memcpy( CtlReq.mfcc_ttls, Dp->TtlVc, sizeof( CtlReq.mfcc_ttls ) );
        !           167: 
        !           168:     {
        !           169:         char FmtBuO[ 32 ], FmtBuM[ 32 ];
        !           170: 
        !           171:         my_log( LOG_NOTICE, 0, "Adding MFC: %s -> %s, InpVIf: %d", 
        !           172:              fmtInAdr( FmtBuO, CtlReq.mfcc_origin ), 
        !           173:              fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ),
        !           174:              (int)CtlReq.mfcc_parent
        !           175:            );
        !           176:     }
        !           177: 
        !           178:     rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_MFC,
        !           179:                    (void *)&CtlReq, sizeof( CtlReq ) );
        !           180:     if (rc)
        !           181:         my_log( LOG_WARNING, errno, "MRT_ADD_MFC" );
        !           182: 
        !           183:     return rc;
        !           184: }
        !           185: 
        !           186: /*
        !           187: ** Removes the multicast routed '*Dp' from the kernel routes
        !           188: **
        !           189: ** returns: - 0 if the function succeeds
        !           190: **          - the errno value for non-fatal failure condition
        !           191: */
        !           192: int delMRoute( struct MRouteDesc *Dp )
        !           193: {
        !           194:     struct mfcctl CtlReq;
        !           195:     int rc;
        !           196: 
        !           197:     CtlReq.mfcc_origin    = Dp->OriginAdr;
        !           198:     CtlReq.mfcc_mcastgrp  = Dp->McAdr;
        !           199:     CtlReq.mfcc_parent    = Dp->InVif;
        !           200: 
        !           201:     /* clear the TTL vector
        !           202:      */
        !           203:     memset( CtlReq.mfcc_ttls, 0, sizeof( CtlReq.mfcc_ttls ) );
        !           204: 
        !           205:     {
        !           206:         char FmtBuO[ 32 ], FmtBuM[ 32 ];
        !           207: 
        !           208:         my_log( LOG_NOTICE, 0, "Removing MFC: %s -> %s, InpVIf: %d", 
        !           209:              fmtInAdr( FmtBuO, CtlReq.mfcc_origin ), 
        !           210:              fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ),
        !           211:              (int)CtlReq.mfcc_parent
        !           212:            );
        !           213:     }
        !           214: 
        !           215:     rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_DEL_MFC,
        !           216:                    (void *)&CtlReq, sizeof( CtlReq ) );
        !           217:     if (rc)
        !           218:         my_log( LOG_WARNING, errno, "MRT_DEL_MFC" );
        !           219: 
        !           220:     return rc;
        !           221: }
        !           222: 
        !           223: /*
        !           224: ** Returns for the virtual interface index for '*IfDp'
        !           225: **
        !           226: ** returns: - the vitrual interface index if the interface is registered
        !           227: **          - -1 if no virtual interface exists for the interface 
        !           228: **          
        !           229: */
        !           230: int getVifIx( struct IfDesc *IfDp )
        !           231: {
        !           232:     struct VifDesc *Dp;
        !           233: 
        !           234:     for ( Dp = VifDescVc; Dp < VCEP( VifDescVc ); Dp++ )
        !           235:         if ( Dp->IfDp == IfDp )
        !           236:             return Dp - VifDescVc;
        !           237: 
        !           238:     return -1;
        !           239: }
        !           240: 
        !           241: 
        !           242: 

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