Annotation of embedaddon/igmpproxy/src/mroute-api.c, revision 1.1.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>