File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / igmpproxy / src / ifvc.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: #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>