luci-app-olsrd2: upgrade uci-defaults for ucitrack handling to use json
[feed/routing.git] / mcproxy / patches / 0003-add-sourcefilter.patch
1 --- a/mcproxy/src/utils/mc_socket.cpp
2 +++ b/mcproxy/src/utils/mc_socket.cpp
3 @@ -37,6 +37,10 @@
4 #include <numeric>
5 #include <unistd.h>
6
7 +#if !defined(__GLIBC__) || defined(__UCLIBC__)
8 +#include "sourcefilter.cpp"
9 +#endif /* __GLIBC__ */
10 +
11 std::string ipAddrResolver(std::string ipAddr)
12 {
13 std::string str[][2] = {
14 --- /dev/null
15 +++ b/mcproxy/src/utils/sourcefilter.cpp
16 @@ -0,0 +1,165 @@
17 +/* Get source filter. Linux version.
18 + Copyright (C) 2004-2014 Free Software Foundation, Inc.
19 + This file is part of the GNU C Library.
20 + Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
21 +
22 + The GNU C Library is free software; you can redistribute it and/or
23 + modify it under the terms of the GNU Lesser General Public
24 + License as published by the Free Software Foundation; either
25 + version 2.1 of the License, or (at your option) any later version.
26 +
27 + The GNU C Library is distributed in the hope that it will be useful,
28 + but WITHOUT ANY WARRANTY; without even the implied warranty of
29 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 + Lesser General Public License for more details.
31 +
32 + You should have received a copy of the GNU Lesser General Public
33 + License along with the GNU C Library; if not, see
34 + <http://www.gnu.org/licenses/>. */
35 +
36 +#include <assert.h>
37 +#include <errno.h>
38 +#include <stdlib.h>
39 +#include <string.h>
40 +#include <stdint.h>
41 +#include <netinet/in.h>
42 +#include <netpacket/packet.h>
43 +#include <sys/param.h>
44 +#include <sys/socket.h>
45 +
46 +static const struct
47 +{
48 + int sol;
49 + int af;
50 + socklen_t size;
51 +} sol_map[] =
52 + {
53 + /* Sort the array according to importance of the protocols. Add
54 + more protocols when they become available. */
55 + { SOL_IP, AF_INET, sizeof (struct sockaddr_in) },
56 + { SOL_IPV6, AF_INET6, sizeof (struct sockaddr_in6) },
57 + { SOL_PACKET, AF_PACKET, sizeof (struct sockaddr_ll) }
58 + };
59 +#define NSOL_MAP (sizeof (sol_map) / sizeof (sol_map[0]))
60 +
61 +
62 +/* Try to determine the socket level value. Ideally both side and
63 + family are set. But sometimes only the size is correct and the
64 + family value might be bogus. Loop over the array entries and look
65 + for a perfect match or the first match based on size. */
66 +static int
67 +__get_sol (int af, socklen_t len)
68 +{
69 + int first_size_sol = -1;
70 +
71 + for (size_t cnt = 0; cnt < NSOL_MAP; ++cnt)
72 + {
73 + /* Just a test so that we make sure the special value used to
74 + signal the "we have so far no socket level value" is OK. */
75 + assert (sol_map[cnt].sol != -1);
76 +
77 + if (len == sol_map[cnt].size)
78 + {
79 + /* The size matches, which is a requirement. If the family
80 + matches, too, we have a winner. Otherwise we remember the
81 + socket level value for this protocol if it is the first
82 + match. */
83 + if (af == sol_map[cnt].af)
84 + /* Bingo! */
85 + return sol_map[cnt].sol;
86 +
87 + if (first_size_sol == -1)
88 + first_size_sol = sol_map[cnt].sol;
89 + }
90 + }
91 +
92 + return first_size_sol;
93 +}
94 +
95 +
96 +int
97 +getsourcefilter (int s, uint32_t interface, const struct sockaddr *group,
98 + socklen_t grouplen, uint32_t *fmode, uint32_t *numsrc,
99 + struct sockaddr_storage *slist)
100 +{
101 + /* We have to create an struct ip_msfilter object which we can pass
102 + to the kernel. */
103 + socklen_t needed = GROUP_FILTER_SIZE (*numsrc);
104 + struct group_filter *gf;
105 + gf = (struct group_filter *) malloc (needed);
106 + if (gf == NULL)
107 + return -1;
108 +
109 + gf->gf_interface = interface;
110 + memcpy (&gf->gf_group, group, grouplen);
111 + gf->gf_numsrc = *numsrc;
112 +
113 + /* We need to provide the appropriate socket level value. */
114 + int result;
115 + int sol = __get_sol (group->sa_family, grouplen);
116 + if (sol == -1)
117 + {
118 + errno = EINVAL;
119 + result = -1;
120 + }
121 + else
122 + {
123 + result = getsockopt (s, sol, MCAST_MSFILTER, gf, &needed);
124 +
125 + /* If successful, copy the results to the places the caller wants
126 + them in. */
127 + if (result == 0)
128 + {
129 + *fmode = gf->gf_fmode;
130 + memcpy (slist, gf->gf_slist,
131 + MIN (*numsrc, gf->gf_numsrc)
132 + * sizeof (struct sockaddr_storage));
133 + *numsrc = gf->gf_numsrc;
134 + }
135 + }
136 +
137 + int save_errno = errno;
138 + free (gf);
139 + errno = save_errno;
140 +
141 + return result;
142 +}
143 +
144 +
145 +int
146 +setsourcefilter (int s, uint32_t interface, const struct sockaddr *group,
147 + socklen_t grouplen, uint32_t fmode, uint32_t numsrc,
148 + const struct sockaddr_storage *slist)
149 +{
150 + /* We have to create an struct ip_msfilter object which we can pass
151 + to the kernel. */
152 + size_t needed = GROUP_FILTER_SIZE (numsrc);
153 +
154 + struct group_filter *gf;
155 + gf = (struct group_filter *) malloc (needed);
156 + if (gf == NULL)
157 + return -1;
158 +
159 + gf->gf_interface = interface;
160 + memcpy (&gf->gf_group, group, grouplen);
161 + gf->gf_fmode = fmode;
162 + gf->gf_numsrc = numsrc;
163 + memcpy (gf->gf_slist, slist, numsrc * sizeof (struct sockaddr_storage));
164 +
165 + /* We need to provide the appropriate socket level value. */
166 + int result;
167 + int sol = __get_sol (group->sa_family, grouplen);
168 + if (sol == -1)
169 + {
170 + errno = EINVAL;
171 + result = -1;
172 + }
173 + else
174 + result = setsockopt (s, sol, MCAST_MSFILTER, gf, needed);
175 +
176 + int save_errno = errno;
177 + free (gf);
178 + errno = save_errno;
179 +
180 + return result;
181 +}