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
35#include "igmpproxy.h"
36
37int curttl = 0;
38
39void k_set_rcvbuf(int bufsize, int minsize) {
40    int delta = bufsize / 2;
41    int iter = 0;
42
43    /*
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.
48     */
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;
56
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;
64            }
65        }
66        if (bufsize < minsize) {
67            my_log(LOG_ERR, 0, "OS-allowed buffer size %u < app min %u",
68                bufsize, minsize);
69            /*NOTREACHED*/
70        }
71    }
72    my_log(LOG_DEBUG, 0, "Got %d byte buffer size in %d iterations", bufsize, iter);
73}
74
75
76void 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);
80}
81
82
83void k_set_ttl(int t) {
84#ifndef RAW_OUTPUT_IS_RAW
85    u_char ttl;
86
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;
93}
94
95
96void k_set_loop(int l) {
97    u_char loop;
98
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);
103}
104
105void k_set_if(uint32_t ifa) {
106    struct in_addr adr;
107
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));
113}
114
115/*
116void k_join(uint32_t grp, uint32_t ifa) {
117    struct ip_mreq mreq;
118
119    mreq.imr_multiaddr.s_addr = grp;
120    mreq.imr_interface.s_addr = ifa;
121
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));
126}
127
128
129void k_leave(uint32_t grp, uint32_t ifa) {
130    struct ip_mreq mreq;
131
132    mreq.imr_multiaddr.s_addr = grp;
133    mreq.imr_interface.s_addr = ifa;
134
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));
139}
140*/
141