BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file address_utils.h
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29  
30 #ifndef NCD_ADDRESS_UTILS_H
31 #define NCD_ADDRESS_UTILS_H
32  
33 #include <string.h>
34 #include <limits.h>
35  
36 #include <misc/debug.h>
37 #include <misc/ipaddr.h>
38 #include <misc/ipaddr6.h>
39 #include <misc/byteorder.h>
40 #include <system/BAddr.h>
41 #include <system/BConnectionGeneric.h>
42 #include <ncd/NCDVal.h>
43 #include <ncd/extra/value_utils.h>
44  
45 typedef int (*ncd_read_bconnection_addr_CustomHandler) (void *user, NCDValRef protocol, NCDValRef data);
46  
47 static int ncd_read_baddr (NCDValRef val, BAddr *out) WARN_UNUSED;
48 static NCDValRef ncd_make_baddr (BAddr addr, NCDValMem *mem);
49 static int ncd_read_bconnection_addr (NCDValRef val, struct BConnection_addr *out_addr) WARN_UNUSED;
50 static int ncd_read_bconnection_addr_ext (NCDValRef val, ncd_read_bconnection_addr_CustomHandler custom_handler, void *user, struct BConnection_addr *out_addr) WARN_UNUSED;
51  
52 static int ncd_read_baddr (NCDValRef val, BAddr *out)
53 {
54 ASSERT(!NCDVal_IsInvalid(val))
55 ASSERT(out)
56  
57 if (!NCDVal_IsList(val)) {
58 goto fail;
59 }
60  
61 NCDValRef type_val;
62 if (!NCDVal_ListReadHead(val, 1, &type_val)) {
63 goto fail;
64 }
65 if (!NCDVal_IsString(type_val)) {
66 goto fail;
67 }
68  
69 BAddr addr;
70  
71 if (NCDVal_StringEquals(type_val, "none")) {
72 if (!NCDVal_ListRead(val, 1, &type_val)) {
73 goto fail;
74 }
75  
76 addr.type = BADDR_TYPE_NONE;
77 }
78 else if (NCDVal_StringEquals(type_val, "ipv4")) {
79 NCDValRef ipaddr_val;
80 NCDValRef port_val;
81 if (!NCDVal_ListRead(val, 3, &type_val, &ipaddr_val, &port_val)) {
82 goto fail;
83 }
84 if (!NCDVal_IsString(ipaddr_val)) {
85 goto fail;
86 }
87  
88 addr.type = BADDR_TYPE_IPV4;
89  
90 if (!ipaddr_parse_ipv4_addr(NCDVal_StringMemRef(ipaddr_val), &addr.ipv4.ip)) {
91 goto fail;
92 }
93  
94 uintmax_t port;
95 if (!ncd_read_uintmax(port_val, &port) || port > UINT16_MAX) {
96 goto fail;
97 }
98 addr.ipv4.port = hton16(port);
99 }
100 else if (NCDVal_StringEquals(type_val, "ipv6")) {
101 NCDValRef ipaddr_val;
102 NCDValRef port_val;
103 if (!NCDVal_ListRead(val, 3, &type_val, &ipaddr_val, &port_val)) {
104 goto fail;
105 }
106 if (!NCDVal_IsString(ipaddr_val)) {
107 goto fail;
108 }
109  
110 addr.type = BADDR_TYPE_IPV6;
111  
112 struct ipv6_addr i6addr;
113 if (!ipaddr6_parse_ipv6_addr(NCDVal_StringMemRef(ipaddr_val), &i6addr)) {
114 goto fail;
115 }
116 memcpy(addr.ipv6.ip, i6addr.bytes, 16);
117  
118 uintmax_t port;
119 if (!ncd_read_uintmax(port_val, &port) || port > UINT16_MAX) {
120 goto fail;
121 }
122 addr.ipv6.port = hton16(port);
123 }
124 else {
125 goto fail;
126 }
127  
128 *out = addr;
129 return 1;
130  
131 fail:
132 return 0;
133 }
134  
135 static NCDValRef ncd_make_baddr (BAddr addr, NCDValMem *mem)
136 {
137 BAddr_Assert(&addr);
138 ASSERT(mem)
139  
140 NCDValRef val;
141  
142 switch (addr.type) {
143 default:
144 case BADDR_TYPE_NONE: {
145 val = NCDVal_NewList(mem, 1);
146 if (NCDVal_IsInvalid(val)) {
147 goto fail;
148 }
149  
150 const char *str = (addr.type == BADDR_TYPE_NONE ? "none" : "unknown");
151 NCDValRef type_val = NCDVal_NewString(mem, str);
152 if (NCDVal_IsInvalid(type_val)) {
153 goto fail;
154 }
155  
156 if (!NCDVal_ListAppend(val, type_val)) {
157 goto fail;
158 }
159 } break;
160  
161 case BADDR_TYPE_IPV4: {
162 val = NCDVal_NewList(mem, 3);
163 if (NCDVal_IsInvalid(val)) {
164 goto fail;
165 }
166  
167 NCDValRef type_val = NCDVal_NewString(mem, "ipv4");
168 if (NCDVal_IsInvalid(type_val)) {
169 goto fail;
170 }
171  
172 char ipaddr_buf[IPADDR_PRINT_MAX];
173 ipaddr_print_addr(addr.ipv4.ip, ipaddr_buf);
174 NCDValRef ipaddr_val = NCDVal_NewString(mem, ipaddr_buf);
175 if (NCDVal_IsInvalid(ipaddr_val)) {
176 goto fail;
177 }
178  
179 NCDValRef port_val = ncd_make_uintmax(mem, ntoh16(addr.ipv4.port));
180 if (NCDVal_IsInvalid(port_val)) {
181 goto fail;
182 }
183  
184 if (!NCDVal_ListAppend(val, type_val)) {
185 goto fail;
186 }
187 if (!NCDVal_ListAppend(val, ipaddr_val)) {
188 goto fail;
189 }
190 if (!NCDVal_ListAppend(val, port_val)) {
191 goto fail;
192 }
193 } break;
194  
195 case BADDR_TYPE_IPV6: {
196 val = NCDVal_NewList(mem, 3);
197 if (NCDVal_IsInvalid(val)) {
198 goto fail;
199 }
200  
201 NCDValRef type_val = NCDVal_NewString(mem, "ipv6");
202 if (NCDVal_IsInvalid(type_val)) {
203 goto fail;
204 }
205  
206 char ipaddr_buf[IPADDR6_PRINT_MAX];
207 struct ipv6_addr i6addr;
208 memcpy(i6addr.bytes, addr.ipv6.ip, 16);
209 ipaddr6_print_addr(i6addr, ipaddr_buf);
210 NCDValRef ipaddr_val = NCDVal_NewString(mem, ipaddr_buf);
211 if (NCDVal_IsInvalid(ipaddr_val)) {
212 goto fail;
213 }
214  
215 NCDValRef port_val = ncd_make_uintmax(mem, ntoh16(addr.ipv6.port));
216 if (NCDVal_IsInvalid(port_val)) {
217 goto fail;
218 }
219  
220 if (!NCDVal_ListAppend(val, type_val)) {
221 goto fail;
222 }
223 if (!NCDVal_ListAppend(val, ipaddr_val)) {
224 goto fail;
225 }
226 if (!NCDVal_ListAppend(val, port_val)) {
227 goto fail;
228 }
229 } break;
230 }
231  
232 return val;
233  
234 fail:
235 return NCDVal_NewInvalid();
236 }
237  
238 static int ncd_read_bconnection_addr (NCDValRef val, struct BConnection_addr *out_addr)
239 {
240 return ncd_read_bconnection_addr_ext(val, NULL, NULL, out_addr);
241 }
242  
243 static int ncd_read_bconnection_addr_ext (NCDValRef val, ncd_read_bconnection_addr_CustomHandler custom_handler, void *user, struct BConnection_addr *out_addr)
244 {
245 ASSERT(!NCDVal_IsInvalid(val))
246  
247 if (!NCDVal_IsList(val)) {
248 goto fail;
249 }
250  
251 NCDValRef protocol_arg;
252 NCDValRef data_arg;
253 if (!NCDVal_ListRead(val, 2, &protocol_arg, &data_arg)) {
254 goto fail;
255 }
256  
257 if (!NCDVal_IsString(protocol_arg)) {
258 goto fail;
259 }
260  
261 if (NCDVal_StringEquals(protocol_arg, "unix")) {
262 if (!NCDVal_IsStringNoNulls(data_arg)) {
263 goto fail;
264 }
265  
266 *out_addr = BConnection_addr_unix(NCDVal_StringMemRef(data_arg));
267 }
268 else if (NCDVal_StringEquals(protocol_arg, "tcp")) {
269 BAddr baddr;
270 if (!ncd_read_baddr(data_arg, &baddr)) {
271 goto fail;
272 }
273  
274 *out_addr = BConnection_addr_baddr(baddr);
275 }
276 else {
277 if (!custom_handler || !custom_handler(user, protocol_arg, data_arg)) {
278 goto fail;
279 }
280  
281 out_addr->type = -1;
282 }
283  
284 return 1;
285  
286 fail:
287 return 0;
288 }
289  
290 #endif