Changes to update Tomato RAF.
[tomato.git] / release / src / router / igmpproxy / src / kern.c
blob20556363678884ea99b238096aef39048ce7fb0e
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.
35 #include "igmpproxy.h"
37 int curttl = 0;
39 void k_set_rcvbuf(int bufsize, int minsize) {
40 int delta = bufsize / 2;
41 int iter = 0;
44 * Set the socket buffer. If we can't set it as large as we
45 * want, search around to try to find the highest acceptable
46 * value. The highest acceptable value being smaller than
47 * minsize is a fatal error.
49 if (setsockopt(MRouterFD, SOL_SOCKET, SO_RCVBUF,
50 (char *)&bufsize, sizeof(bufsize)) < 0) {
51 bufsize -= delta;
52 while (1) {
53 iter++;
54 if (delta > 1)
55 delta /= 2;
57 if (setsockopt(MRouterFD, SOL_SOCKET, SO_RCVBUF,
58 (char *)&bufsize, sizeof(bufsize)) < 0) {
59 bufsize -= delta;
60 } else {
61 if (delta < 1024)
62 break;
63 bufsize += delta;
66 if (bufsize < minsize) {
67 my_log(LOG_ERR, 0, "OS-allowed buffer size %u < app min %u",
68 bufsize, minsize);
69 /*NOTREACHED*/
72 my_log(LOG_DEBUG, 0, "Got %d byte buffer size in %d iterations", bufsize, iter);
76 void k_hdr_include(int hdrincl) {
77 if (setsockopt(MRouterFD, IPPROTO_IP, IP_HDRINCL,
78 (char *)&hdrincl, sizeof(hdrincl)) < 0)
79 my_log(LOG_ERR, errno, "setsockopt IP_HDRINCL %u", hdrincl);
83 void k_set_ttl(int t) {
84 #ifndef RAW_OUTPUT_IS_RAW
85 u_char ttl;
87 ttl = t;
88 if (setsockopt(MRouterFD, IPPROTO_IP, IP_MULTICAST_TTL,
89 (char *)&ttl, sizeof(ttl)) < 0)
90 my_log(LOG_ERR, errno, "setsockopt IP_MULTICAST_TTL %u", ttl);
91 #endif
92 curttl = t;
96 void k_set_loop(int l) {
97 u_char loop;
99 loop = l;
100 if (setsockopt(MRouterFD, IPPROTO_IP, IP_MULTICAST_LOOP,
101 (char *)&loop, sizeof(loop)) < 0)
102 my_log(LOG_ERR, errno, "setsockopt IP_MULTICAST_LOOP %u", loop);
105 void k_set_if(uint32_t ifa) {
106 struct in_addr adr;
108 adr.s_addr = ifa;
109 if (setsockopt(MRouterFD, IPPROTO_IP, IP_MULTICAST_IF,
110 (char *)&adr, sizeof(adr)) < 0)
111 my_log(LOG_ERR, errno, "setsockopt IP_MULTICAST_IF %s",
112 inetFmt(ifa, s1));
116 void k_join(uint32_t grp, uint32_t ifa) {
117 struct ip_mreq mreq;
119 mreq.imr_multiaddr.s_addr = grp;
120 mreq.imr_interface.s_addr = ifa;
122 if (setsockopt(MRouterFD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
123 (char *)&mreq, sizeof(mreq)) < 0)
124 my_log(LOG_WARNING, errno, "can't join group %s on interface %s",
125 inetFmt(grp, s1), inetFmt(ifa, s2));
129 void k_leave(uint32_t grp, uint32_t ifa) {
130 struct ip_mreq mreq;
132 mreq.imr_multiaddr.s_addr = grp;
133 mreq.imr_interface.s_addr = ifa;
135 if (setsockopt(MRouterFD, IPPROTO_IP, IP_DROP_MEMBERSHIP,
136 (char *)&mreq, sizeof(mreq)) < 0)
137 my_log(LOG_WARNING, errno, "can't leave group %s on interface %s",
138 inetFmt(grp, s1), inetFmt(ifa, s2));