Annotation of embedaddon/igmpproxy/src/mroute-api.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: * mroute-api.c
35: *
36: * This module contains the interface routines to the Linux mrouted API
37: */
38:
39:
40: #include "igmpproxy.h"
41:
42: // MAX_MC_VIFS from mclab.h must have same value as MAXVIFS from mroute.h
43: #if MAX_MC_VIFS != MAXVIFS
44: # error "constants don't match, correct mclab.h"
45: #endif
46:
47: // need an IGMP socket as interface for the mrouted API
48: // - receives the IGMP messages
49: int MRouterFD; /* socket for all network I/O */
50: char *recv_buf; /* input packet buffer */
51: char *send_buf; /* output packet buffer */
52:
53:
54: // my internal virtual interfaces descriptor vector
55: static struct VifDesc {
56: struct IfDesc *IfDp;
57: } VifDescVc[ MAXVIFS ];
58:
59:
60:
61: /*
62: ** Initialises the mrouted API and locks it by this exclusively.
63: **
64: ** returns: - 0 if the functions succeeds
65: ** - the errno value for non-fatal failure condition
66: */
67: int enableMRouter()
68: {
69: int Va = 1;
70:
71: if ( (MRouterFD = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0 )
72: my_log( LOG_ERR, errno, "IGMP socket open" );
73:
74: if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_INIT,
75: (void *)&Va, sizeof( Va ) ) )
76: return errno;
77:
78: return 0;
79: }
80:
81: /*
82: ** Diables the mrouted API and relases by this the lock.
83: **
84: */
85: void disableMRouter()
86: {
87: if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_DONE, NULL, 0 )
88: || close( MRouterFD )
89: ) {
90: MRouterFD = 0;
91: my_log( LOG_ERR, errno, "MRT_DONE/close" );
92: }
93:
94: MRouterFD = 0;
95: }
96:
97: /*
98: ** Adds the interface '*IfDp' as virtual interface to the mrouted API
99: **
100: */
101: void addVIF( struct IfDesc *IfDp )
102: {
103: struct vifctl VifCtl;
104: struct VifDesc *VifDp;
105:
106: /* search free VifDesc
107: */
108: for ( VifDp = VifDescVc; VifDp < VCEP( VifDescVc ); VifDp++ ) {
109: if ( ! VifDp->IfDp )
110: break;
111: }
112:
113: /* no more space
114: */
115: if ( VifDp >= VCEP( VifDescVc ) )
116: my_log( LOG_ERR, ENOMEM, "addVIF, out of VIF space" );
117:
118: VifDp->IfDp = IfDp;
119:
120: VifCtl.vifc_vifi = VifDp - VifDescVc;
121: VifCtl.vifc_flags = 0; /* no tunnel, no source routing, register ? */
122: VifCtl.vifc_threshold = VifDp->IfDp->threshold; // Packet TTL must be at least 1 to pass them
123: VifCtl.vifc_rate_limit = VifDp->IfDp->ratelimit; // Ratelimit
124:
125: VifCtl.vifc_lcl_addr.s_addr = VifDp->IfDp->InAdr.s_addr;
126: VifCtl.vifc_rmt_addr.s_addr = INADDR_ANY;
127:
128: // Set the index...
129: VifDp->IfDp->index = VifCtl.vifc_vifi;
130:
131: my_log( LOG_NOTICE, 0, "adding VIF, Ix %d Fl 0x%x IP 0x%08x %s, Threshold: %d, Ratelimit: %d",
132: VifCtl.vifc_vifi, VifCtl.vifc_flags, VifCtl.vifc_lcl_addr.s_addr, VifDp->IfDp->Name,
133: VifCtl.vifc_threshold, VifCtl.vifc_rate_limit);
134:
135: struct SubnetList *currSubnet;
136: for(currSubnet = IfDp->allowednets; currSubnet; currSubnet = currSubnet->next) {
137: my_log(LOG_DEBUG, 0, " Network for [%s] : %s",
138: IfDp->Name,
139: inetFmts(currSubnet->subnet_addr, currSubnet->subnet_mask, s1));
140: }
141:
142: if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF,
143: (char *)&VifCtl, sizeof( VifCtl ) ) )
144: my_log( LOG_ERR, errno, "MRT_ADD_VIF" );
145:
146: }
147:
148: /*
149: ** Adds the multicast routed '*Dp' to the kernel routes
150: **
151: ** returns: - 0 if the function succeeds
152: ** - the errno value for non-fatal failure condition
153: */
154: int addMRoute( struct MRouteDesc *Dp )
155: {
156: struct mfcctl CtlReq;
157: int rc;
158:
159: CtlReq.mfcc_origin = Dp->OriginAdr;
160: CtlReq.mfcc_mcastgrp = Dp->McAdr;
161: CtlReq.mfcc_parent = Dp->InVif;
162:
163: /* copy the TTL vector
164: */
165:
166: memcpy( CtlReq.mfcc_ttls, Dp->TtlVc, sizeof( CtlReq.mfcc_ttls ) );
167:
168: {
169: char FmtBuO[ 32 ], FmtBuM[ 32 ];
170:
171: my_log( LOG_NOTICE, 0, "Adding MFC: %s -> %s, InpVIf: %d",
172: fmtInAdr( FmtBuO, CtlReq.mfcc_origin ),
173: fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ),
174: (int)CtlReq.mfcc_parent
175: );
176: }
177:
178: rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_MFC,
179: (void *)&CtlReq, sizeof( CtlReq ) );
180: if (rc)
181: my_log( LOG_WARNING, errno, "MRT_ADD_MFC" );
182:
183: return rc;
184: }
185:
186: /*
187: ** Removes the multicast routed '*Dp' from the kernel routes
188: **
189: ** returns: - 0 if the function succeeds
190: ** - the errno value for non-fatal failure condition
191: */
192: int delMRoute( struct MRouteDesc *Dp )
193: {
194: struct mfcctl CtlReq;
195: int rc;
196:
197: CtlReq.mfcc_origin = Dp->OriginAdr;
198: CtlReq.mfcc_mcastgrp = Dp->McAdr;
199: CtlReq.mfcc_parent = Dp->InVif;
200:
201: /* clear the TTL vector
202: */
203: memset( CtlReq.mfcc_ttls, 0, sizeof( CtlReq.mfcc_ttls ) );
204:
205: {
206: char FmtBuO[ 32 ], FmtBuM[ 32 ];
207:
208: my_log( LOG_NOTICE, 0, "Removing MFC: %s -> %s, InpVIf: %d",
209: fmtInAdr( FmtBuO, CtlReq.mfcc_origin ),
210: fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ),
211: (int)CtlReq.mfcc_parent
212: );
213: }
214:
215: rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_DEL_MFC,
216: (void *)&CtlReq, sizeof( CtlReq ) );
217: if (rc)
218: my_log( LOG_WARNING, errno, "MRT_DEL_MFC" );
219:
220: return rc;
221: }
222:
223: /*
224: ** Returns for the virtual interface index for '*IfDp'
225: **
226: ** returns: - the vitrual interface index if the interface is registered
227: ** - -1 if no virtual interface exists for the interface
228: **
229: */
230: int getVifIx( struct IfDesc *IfDp )
231: {
232: struct VifDesc *Dp;
233:
234: for ( Dp = VifDescVc; Dp < VCEP( VifDescVc ); Dp++ )
235: if ( Dp->IfDp == IfDp )
236: return Dp - VifDescVc;
237:
238: return -1;
239: }
240:
241:
242:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>