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>