Annotation of embedaddon/igmpproxy/src/ifvc.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: #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>