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>