Changes to update Tomato RAF.
[tomato.git] / release / src / router / igmpproxy / src / ifvc.c
blob9d7ee974f416f0e74e2b753322e5e1ec0ba5edb3
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.
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
19 **----------------------------------------------------------------------------
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.
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.
34 #include "igmpproxy.h"
36 struct IfDesc IfDescVc[ MAX_IF ], *IfDescEp = IfDescVc;
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 **
43 void buildIfVc() {
44 struct ifreq IfVc[ sizeof( IfDescVc ) / sizeof( IfDescVc[ 0 ] ) ];
45 struct ifreq *IfEp;
47 int Sock;
49 if ( (Sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
50 my_log( LOG_ERR, errno, "RAW socket open" );
52 /* get If vector
55 struct ifconf IoCtlReq;
57 IoCtlReq.ifc_buf = (void *)IfVc;
58 IoCtlReq.ifc_len = sizeof( IfVc );
60 if ( ioctl( Sock, SIOCGIFCONF, &IoCtlReq ) < 0 )
61 my_log( LOG_ERR, errno, "ioctl SIOCGIFCONF" );
63 IfEp = (void *)((char *)IfVc + IoCtlReq.ifc_len);
66 /* loop over interfaces and copy interface info to IfDescVc
69 struct ifreq *IfPt, *IfNext;
71 // Temp keepers of interface params...
72 uint32_t addr, subnet, mask;
74 for ( IfPt = IfVc; IfPt < IfEp; IfPt = IfNext ) {
75 struct ifreq IfReq;
76 char FmtBu[ 32 ];
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
85 if (IfNext < IfPt + 1)
86 IfNext = IfPt + 1;
88 strncpy( IfDescEp->Name, IfPt->ifr_name, sizeof( IfDescEp->Name ) );
90 // Currently don't set any allowed nets...
91 //IfDescEp->allowednets = NULL;
93 // Set the index to -1 by default.
94 IfDescEp->index = -1;
96 /* don't retrieve more info for non-IP interfaces
98 if ( IfPt->ifr_addr.sa_family != AF_INET ) {
99 IfDescEp->InAdr.s_addr = 0; /* mark as non-IP interface */
100 IfDescEp++;
101 continue;
104 // Get the interface adress...
105 IfDescEp->InAdr = ((struct sockaddr_in *)&IfPt->ifr_addr)->sin_addr;
106 addr = IfDescEp->InAdr.s_addr;
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;
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;
118 /* get if flags
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
127 if ( ioctl( Sock, SIOCGIFFLAGS, &IfReq ) < 0 )
128 my_log( LOG_ERR, errno, "ioctl SIOCGIFFLAGS" );
130 IfDescEp->Flags = IfReq.ifr_flags;
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 !");
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;
141 // Set the default params for the IF...
142 IfDescEp->state = IF_STATE_DISABLED;
143 IfDescEp->robustness = DEFAULT_ROBUSTNESS;
144 IfDescEp->threshold = DEFAULT_THRESHOLD; /* ttl limit */
145 IfDescEp->ratelimit = DEFAULT_RATELIMIT;
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));
155 IfDescEp++;
159 close( Sock );
163 ** Returns a pointer to the IfDesc of the interface 'IfName'
165 ** returns: - pointer to the IfDesc of the requested interface
166 ** - NULL if no interface 'IfName' exists
169 struct IfDesc *getIfByName( const char *IfName ) {
170 struct IfDesc *Dp;
172 for ( Dp = IfDescVc; Dp < IfDescEp; Dp++ )
173 if ( ! strcmp( IfName, Dp->Name ) )
174 return Dp;
176 return NULL;
180 ** Returns a pointer to the IfDesc of the interface 'Ix'
182 ** returns: - pointer to the IfDesc of the requested interface
183 ** - NULL if no interface 'Ix' exists
186 struct IfDesc *getIfByIx( unsigned Ix ) {
187 struct IfDesc *Dp = &IfDescVc[ Ix ];
188 return Dp < IfDescEp ? Dp : NULL;
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.
196 struct IfDesc *getIfByAddress( uint32_t ipaddr ) {
198 struct IfDesc *Dp;
199 struct SubnetList *currsubnet;
200 struct IfDesc *res = NULL;
201 uint32_t last_subnet_mask = 0;
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;
213 return res;
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.
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;
231 return NULL;
236 * Function that checks if a given ipaddress is a valid
237 * address for the supplied VIF.
239 int isAdressValidForIf( struct IfDesc* intrface, uint32_t ipaddr ) {
240 struct SubnetList *currsubnet;
242 if(intrface == NULL) {
243 return 0;
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;
252 return 0;