File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / igmpproxy / src / mroute-api.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 (12 years, 4 months 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: *   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>