Annotation of embedaddon/igmpproxy/src/ifvc.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: #include "igmpproxy.h"
! 35:
! 36: struct IfDesc IfDescVc[ MAX_IF ], *IfDescEp = IfDescVc;
! 37:
! 38: /*
! 39: ** Builds up a vector with the interface of the machine. Calls to the other functions of
! 40: ** the module will fail if they are called before the vector is build.
! 41: **
! 42: */
! 43: void buildIfVc() {
! 44: struct ifreq IfVc[ sizeof( IfDescVc ) / sizeof( IfDescVc[ 0 ] ) ];
! 45: struct ifreq *IfEp;
! 46:
! 47: int Sock;
! 48:
! 49: if ( (Sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
! 50: my_log( LOG_ERR, errno, "RAW socket open" );
! 51:
! 52: /* get If vector
! 53: */
! 54: {
! 55: struct ifconf IoCtlReq;
! 56:
! 57: IoCtlReq.ifc_buf = (void *)IfVc;
! 58: IoCtlReq.ifc_len = sizeof( IfVc );
! 59:
! 60: if ( ioctl( Sock, SIOCGIFCONF, &IoCtlReq ) < 0 )
! 61: my_log( LOG_ERR, errno, "ioctl SIOCGIFCONF" );
! 62:
! 63: IfEp = (void *)((char *)IfVc + IoCtlReq.ifc_len);
! 64: }
! 65:
! 66: /* loop over interfaces and copy interface info to IfDescVc
! 67: */
! 68: {
! 69: struct ifreq *IfPt, *IfNext;
! 70:
! 71: // Temp keepers of interface params...
! 72: uint32_t addr, subnet, mask;
! 73:
! 74: for ( IfPt = IfVc; IfPt < IfEp; IfPt = IfNext ) {
! 75: struct ifreq IfReq;
! 76: char FmtBu[ 32 ];
! 77:
! 78: IfNext = (struct ifreq *)((char *)&IfPt->ifr_addr +
! 79: #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
! 80: IfPt->ifr_addr.sa_len
! 81: #else
! 82: sizeof(struct sockaddr_in)
! 83: #endif
! 84: );
! 85: if (IfNext < IfPt + 1)
! 86: IfNext = IfPt + 1;
! 87:
! 88: strncpy( IfDescEp->Name, IfPt->ifr_name, sizeof( IfDescEp->Name ) );
! 89:
! 90: // Currently don't set any allowed nets...
! 91: //IfDescEp->allowednets = NULL;
! 92:
! 93: // Set the index to -1 by default.
! 94: IfDescEp->index = -1;
! 95:
! 96: /* don't retrieve more info for non-IP interfaces
! 97: */
! 98: if ( IfPt->ifr_addr.sa_family != AF_INET ) {
! 99: IfDescEp->InAdr.s_addr = 0; /* mark as non-IP interface */
! 100: IfDescEp++;
! 101: continue;
! 102: }
! 103:
! 104: // Get the interface adress...
! 105: IfDescEp->InAdr = ((struct sockaddr_in *)&IfPt->ifr_addr)->sin_addr;
! 106: addr = IfDescEp->InAdr.s_addr;
! 107:
! 108: memcpy( IfReq.ifr_name, IfDescEp->Name, sizeof( IfReq.ifr_name ) );
! 109: IfReq.ifr_addr.sa_family = AF_INET;
! 110: ((struct sockaddr_in *)&IfReq.ifr_addr)->sin_addr.s_addr = addr;
! 111:
! 112: // Get the subnet mask...
! 113: if (ioctl(Sock, SIOCGIFNETMASK, &IfReq ) < 0)
! 114: my_log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", IfReq.ifr_name);
! 115: mask = ((struct sockaddr_in *)&IfReq.ifr_addr)->sin_addr.s_addr;
! 116: subnet = addr & mask;
! 117:
! 118: /* get if flags
! 119: **
! 120: ** typical flags:
! 121: ** lo 0x0049 -> Running, Loopback, Up
! 122: ** ethx 0x1043 -> Multicast, Running, Broadcast, Up
! 123: ** ipppx 0x0091 -> NoArp, PointToPoint, Up
! 124: ** grex 0x00C1 -> NoArp, Running, Up
! 125: ** ipipx 0x00C1 -> NoArp, Running, Up
! 126: */
! 127: if ( ioctl( Sock, SIOCGIFFLAGS, &IfReq ) < 0 )
! 128: my_log( LOG_ERR, errno, "ioctl SIOCGIFFLAGS" );
! 129:
! 130: IfDescEp->Flags = IfReq.ifr_flags;
! 131:
! 132: // Insert the verified subnet as an allowed net...
! 133: IfDescEp->allowednets = (struct SubnetList *)malloc(sizeof(struct SubnetList));
! 134: if(IfDescEp->allowednets == NULL) my_log(LOG_ERR, 0, "Out of memory !");
! 135:
! 136: // Create the network address for the IF..
! 137: IfDescEp->allowednets->next = NULL;
! 138: IfDescEp->allowednets->subnet_mask = mask;
! 139: IfDescEp->allowednets->subnet_addr = subnet;
! 140:
! 141: // Set the default params for the IF...
! 142: IfDescEp->state = IF_STATE_DOWNSTREAM;
! 143: IfDescEp->robustness = DEFAULT_ROBUSTNESS;
! 144: IfDescEp->threshold = DEFAULT_THRESHOLD; /* ttl limit */
! 145: IfDescEp->ratelimit = DEFAULT_RATELIMIT;
! 146:
! 147:
! 148: // Debug log the result...
! 149: my_log( LOG_DEBUG, 0, "buildIfVc: Interface %s Addr: %s, Flags: 0x%04x, Network: %s",
! 150: IfDescEp->Name,
! 151: fmtInAdr( FmtBu, IfDescEp->InAdr ),
! 152: IfDescEp->Flags,
! 153: inetFmts(subnet,mask, s1));
! 154:
! 155: IfDescEp++;
! 156: }
! 157: }
! 158:
! 159: close( Sock );
! 160: }
! 161:
! 162: /*
! 163: ** Returns a pointer to the IfDesc of the interface 'IfName'
! 164: **
! 165: ** returns: - pointer to the IfDesc of the requested interface
! 166: ** - NULL if no interface 'IfName' exists
! 167: **
! 168: */
! 169: struct IfDesc *getIfByName( const char *IfName ) {
! 170: struct IfDesc *Dp;
! 171:
! 172: for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ )
! 173: if ( ! strcmp( IfName, Dp->Name ) )
! 174: return Dp;
! 175:
! 176: return NULL;
! 177: }
! 178:
! 179: /*
! 180: ** Returns a pointer to the IfDesc of the interface 'Ix'
! 181: **
! 182: ** returns: - pointer to the IfDesc of the requested interface
! 183: ** - NULL if no interface 'Ix' exists
! 184: **
! 185: */
! 186: struct IfDesc *getIfByIx( unsigned Ix ) {
! 187: struct IfDesc *Dp = &IfDescVc[ Ix ];
! 188: return Dp < IfDescEp ? Dp : NULL;
! 189: }
! 190:
! 191: /**
! 192: * Returns a pointer to the IfDesc whose subnet matches
! 193: * the supplied IP adress. The IP must match a interfaces
! 194: * subnet, or any configured allowed subnet on a interface.
! 195: */
! 196: struct IfDesc *getIfByAddress( uint32_t ipaddr ) {
! 197:
! 198: struct IfDesc *Dp;
! 199: struct SubnetList *currsubnet;
! 200: struct IfDesc *res = NULL;
! 201: uint32_t last_subnet_mask = 0;
! 202:
! 203: for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ ) {
! 204: // Loop through all registered allowed nets of the VIF...
! 205: for(currsubnet = Dp->allowednets; currsubnet != NULL; currsubnet = currsubnet->next) {
! 206: // Check if the ip falls in under the subnet....
! 207: if(currsubnet->subnet_mask > last_subnet_mask && (ipaddr & currsubnet->subnet_mask) == currsubnet->subnet_addr) {
! 208: res = Dp;
! 209: last_subnet_mask = currsubnet->subnet_mask;
! 210: }
! 211: }
! 212: }
! 213: return res;
! 214: }
! 215:
! 216:
! 217: /**
! 218: * Returns a pointer to the IfDesc whose subnet matches
! 219: * the supplied IP adress. The IP must match a interfaces
! 220: * subnet, or any configured allowed subnet on a interface.
! 221: */
! 222: struct IfDesc *getIfByVifIndex( unsigned vifindex ) {
! 223: struct IfDesc *Dp;
! 224: if(vifindex>0) {
! 225: for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ ) {
! 226: if(Dp->index == vifindex) {
! 227: return Dp;
! 228: }
! 229: }
! 230: }
! 231: return NULL;
! 232: }
! 233:
! 234:
! 235: /**
! 236: * Function that checks if a given ipaddress is a valid
! 237: * address for the supplied VIF.
! 238: */
! 239: int isAdressValidForIf( struct IfDesc* intrface, uint32_t ipaddr ) {
! 240: struct SubnetList *currsubnet;
! 241:
! 242: if(intrface == NULL) {
! 243: return 0;
! 244: }
! 245: // Loop through all registered allowed nets of the VIF...
! 246: for(currsubnet = intrface->allowednets; currsubnet != NULL; currsubnet = currsubnet->next) {
! 247: // Check if the ip falls in under the subnet....
! 248: if((ipaddr & currsubnet->subnet_mask) == currsubnet->subnet_addr) {
! 249: return 1;
! 250: }
! 251: }
! 252: return 0;
! 253: }
! 254:
! 255:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>