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>