1 /* $NetBSD: sockmisc.c,v 1.19 2011/03/14 17:18:13 tteras Exp $ */
2
3 /* Id: sockmisc.c,v 1.24 2006/05/07 21:32:59 manubsd Exp */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 #include <sys/uio.h>
40
41 #include <netinet/in.h>
42 #include PATH_IPSEC_H
43
44 #if defined(INET6) && !defined(INET6_ADVAPI) && \
45 defined(IP_RECVDSTADDR) && !defined(IPV6_RECVDSTADDR)
46 #define IPV6_RECVDSTADDR IP_RECVDSTADDR
47 #endif
48
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <errno.h>
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56
57 #include "var.h"
58 #include "misc.h"
59 #include "vmbuf.h"
60 #include "plog.h"
61 #include "sockmisc.h"
62 #include "debug.h"
63 #include "gcmalloc.h"
64 #include "debugrm.h"
65 #include "libpfkey.h"
66 #include "isakmp_var.h"
67
68 #ifdef NOUSE_PRIVSEP
69 #define BIND bind
70 #define SOCKET socket
71 #define SETSOCKOPT setsockopt
72 #else
73 #include "admin.h"
74 #include "privsep.h"
75 #define BIND privsep_bind
76 #define SOCKET privsep_socket
77 #define SETSOCKOPT privsep_setsockopt
78 #endif
79
80 const int niflags = 0;
81
82 /*
83 * compare two sockaddr with port, taking care wildcard.
84 * addr1 is a subject address, addr2 is in a database entry.
85 * OUT: 0: equal.
86 * 1: not equal.
87 */
88 int
cmpsaddr(addr1,addr2)89 cmpsaddr(addr1, addr2)
90 const struct sockaddr *addr1;
91 const struct sockaddr *addr2;
92 {
93 caddr_t sa1, sa2;
94 u_short port1 = IPSEC_PORT_ANY;
95 u_short port2 = IPSEC_PORT_ANY;
96
97 if (addr1 == NULL && addr2 == NULL)
98 return CMPSADDR_MATCH;
99
100 if (addr1 == NULL || addr2 == NULL)
101 return CMPSADDR_MISMATCH;
102
103 if (addr1->sa_family != addr2->sa_family ||
104 sysdep_sa_len(addr1) != sysdep_sa_len(addr2))
105 return CMPSADDR_MISMATCH;
106
107 switch (addr1->sa_family) {
108 case AF_UNSPEC:
109 break;
110 case AF_INET:
111 sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr;
112 sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr;
113 port1 = ((struct sockaddr_in *)addr1)->sin_port;
114 port2 = ((struct sockaddr_in *)addr2)->sin_port;
115 if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0)
116 return CMPSADDR_MISMATCH;
117 break;
118 #ifdef INET6
119 case AF_INET6:
120 sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr;
121 sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr;
122 port1 = ((struct sockaddr_in6 *)addr1)->sin6_port;
123 port2 = ((struct sockaddr_in6 *)addr2)->sin6_port;
124 if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0)
125 return CMPSADDR_MISMATCH;
126 if (((struct sockaddr_in6 *)addr1)->sin6_scope_id !=
127 ((struct sockaddr_in6 *)addr2)->sin6_scope_id)
128 return CMPSADDR_MISMATCH;
129 break;
130 #endif
131 default:
132 return CMPSADDR_MISMATCH;
133 }
134
135 if (port1 == port2)
136 return CMPSADDR_MATCH;
137
138 if (port1 == IPSEC_PORT_ANY ||
139 port2 == IPSEC_PORT_ANY)
140 return CMPSADDR_WILDPORT_MATCH;
141
142 return CMPSADDR_WOP_MATCH;
143 }
144
145 #ifdef ANDROID_PATCHED
146
getlocaladdr(struct sockaddr * remote)147 struct sockaddr *getlocaladdr(struct sockaddr *remote)
148 {
149 struct sockaddr_storage local;
150 socklen_t len = sysdep_sa_len(remote);
151 int s = privsep_socket(remote->sa_family, SOCK_DGRAM, 0);
152 if (s == -1 || connect(s, remote, len) == -1 ||
153 getsockname(s, (struct sockaddr *)&local, &len) == -1) {
154 close(s);
155 return NULL;
156 }
157 close(s);
158 return dupsaddr((struct sockaddr *)&local);
159 }
160
recvfromto(int s,void * buf,size_t len,int flags,struct sockaddr * from,socklen_t * fromlen,struct sockaddr * to,unsigned int * tolen)161 int recvfromto(int s, void *buf, size_t len, int flags, struct sockaddr *from,
162 socklen_t *fromlen, struct sockaddr *to, unsigned int *tolen)
163 {
164 if (getsockname(s, to, (socklen_t *)tolen) == -1) {
165 return -1;
166 }
167 return recvfrom(s, buf, len, flags, from, fromlen);
168 }
169
sendfromto(int s,const void * buf,size_t len,struct sockaddr * from,struct sockaddr * to,int count)170 int sendfromto(int s, const void *buf, size_t len, struct sockaddr *from,
171 struct sockaddr *to, int count)
172 {
173 int i;
174 for (i = 0; i < count; ++i) {
175 if (sendto(s, buf, len, 0, to, sysdep_sa_len(to)) == -1) {
176 return -1;
177 }
178 }
179 return len;
180 }
181
setsockopt_bypass(int s,int family)182 int setsockopt_bypass(int s, int family)
183 {
184 struct sadb_x_policy p = {
185 .sadb_x_policy_len = PFKEY_UNIT64(sizeof(struct sadb_x_policy)),
186 .sadb_x_policy_exttype = SADB_X_EXT_POLICY,
187 .sadb_x_policy_type = IPSEC_POLICY_BYPASS,
188 .sadb_x_policy_dir = IPSEC_DIR_INBOUND,
189 #ifdef HAVE_PFKEY_POLICY_PRIORITY
190 .sadb_x_policy_priority = PRIORITY_DEFAULT,
191 #endif
192 };
193 int level = (family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6;
194 int option = (family == AF_INET) ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY;
195 int len = PFKEY_EXTLEN(&p);
196 if (setsockopt(s, level, option, &p, len) == -1) {
197 plog(LLV_WARNING, LOCATION, NULL, "setsockopt in bypass: %s\n",
198 strerror(errno));
199 }
200 p.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
201 if (setsockopt(s, level, option, &p, len) == -1) {
202 plog(LLV_WARNING, LOCATION, NULL, "setsockopt out bypass: %s\n",
203 strerror(errno));
204 }
205 return 0;
206 }
207
208 #else
209
210 /* get local address against the destination. */
211 struct sockaddr *
getlocaladdr(remote)212 getlocaladdr(remote)
213 struct sockaddr *remote;
214 {
215 struct sockaddr *local;
216 u_int local_len = sizeof(struct sockaddr_storage);
217 int s; /* for dummy connection */
218
219 /* allocate buffer */
220 if ((local = racoon_calloc(1, local_len)) == NULL) {
221 plog(LLV_ERROR, LOCATION, NULL,
222 "failed to get address buffer.\n");
223 goto err;
224 }
225
226 /* get real interface received packet */
227 if ((s = SOCKET(remote->sa_family, SOCK_DGRAM, 0)) < 0) {
228 plog(LLV_ERROR, LOCATION, NULL,
229 "socket (%s)\n", strerror(errno));
230 goto err;
231 }
232
233 setsockopt_bypass(s, remote->sa_family);
234
235 if (connect(s, remote, sysdep_sa_len(remote)) < 0) {
236 plog(LLV_ERROR, LOCATION, NULL,
237 "connect (%s)\n", strerror(errno));
238 close(s);
239 goto err;
240 }
241
242 if (getsockname(s, local, &local_len) < 0) {
243 plog(LLV_ERROR, LOCATION, NULL,
244 "getsockname (%s)\n", strerror(errno));
245 close(s);
246 return NULL;
247 }
248
249 close(s);
250 return local;
251
252 err:
253 if (local != NULL)
254 racoon_free(local);
255 return NULL;
256 }
257
258 /*
259 * Receive packet, with src/dst information. It is assumed that necessary
260 * setsockopt() have already performed on socket.
261 */
262 int
recvfromto(s,buf,buflen,flags,from,fromlen,to,tolen)263 recvfromto(s, buf, buflen, flags, from, fromlen, to, tolen)
264 int s;
265 void *buf;
266 size_t buflen;
267 int flags;
268 struct sockaddr *from;
269 socklen_t *fromlen;
270 struct sockaddr *to;
271 u_int *tolen;
272 {
273 int otolen;
274 socklen_t slen;
275 int len;
276 union sockaddr_any sa;
277 struct msghdr m;
278 struct cmsghdr *cm;
279 struct iovec iov[2];
280 u_char cmsgbuf[256];
281 #if defined(INET6) && defined(INET6_ADVAPI)
282 struct in6_pktinfo *pi;
283 #endif /*INET6_ADVAPI*/
284 struct sockaddr_in *sin;
285 #ifdef INET6
286 struct sockaddr_in6 *sin6;
287 #endif
288
289 slen = sizeof(sa);
290 if (getsockname(s, &sa.sa, &slen) < 0) {
291 plog(LLV_ERROR, LOCATION, NULL,
292 "getsockname (%s)\n", strerror(errno));
293 return -1;
294 }
295
296 m.msg_name = (caddr_t)from;
297 m.msg_namelen = *fromlen;
298 iov[0].iov_base = (caddr_t)buf;
299 iov[0].iov_len = buflen;
300 m.msg_iov = iov;
301 m.msg_iovlen = 1;
302 memset(cmsgbuf, 0, sizeof(cmsgbuf));
303 cm = (struct cmsghdr *)cmsgbuf;
304 m.msg_control = (caddr_t)cm;
305 m.msg_controllen = sizeof(cmsgbuf);
306 if ((len = recvmsg(s, &m, flags)) < 0) {
307 plog(LLV_ERROR, LOCATION, NULL,
308 "recvmsg (%s)\n", strerror(errno));
309 return -1;
310 }
311 *fromlen = m.msg_namelen;
312
313 otolen = *tolen;
314 *tolen = 0;
315 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&m);
316 m.msg_controllen != 0 && cm;
317 cm = (struct cmsghdr *)CMSG_NXTHDR(&m, cm)) {
318 #if 0
319 plog(LLV_ERROR, LOCATION, NULL,
320 "cmsg %d %d\n", cm->cmsg_level, cm->cmsg_type);)
321 #endif
322 #if defined(INET6) && defined(INET6_ADVAPI)
323 if (sa.sa.sa_family == AF_INET6
324 && cm->cmsg_level == IPPROTO_IPV6
325 && cm->cmsg_type == IPV6_PKTINFO
326 && otolen >= sizeof(*sin6)) {
327 pi = (struct in6_pktinfo *)(CMSG_DATA(cm));
328 *tolen = sizeof(*sin6);
329 sin6 = (struct sockaddr_in6 *)to;
330 memset(sin6, 0, sizeof(*sin6));
331 sin6->sin6_family = AF_INET6;
332 #ifndef __linux__
333 sin6->sin6_len = sizeof(*sin6);
334 #endif
335 memcpy(&sin6->sin6_addr, &pi->ipi6_addr,
336 sizeof(sin6->sin6_addr));
337 /* XXX other cases, such as site-local? */
338 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
339 sin6->sin6_scope_id = pi->ipi6_ifindex;
340 else
341 sin6->sin6_scope_id = 0;
342 sin6->sin6_port = sa.sin6.sin6_port;
343 otolen = -1; /* "to" already set */
344 continue;
345 }
346 #endif
347 #ifdef __linux__
348 if (sa.sa.sa_family == AF_INET
349 && cm->cmsg_level == IPPROTO_IP
350 && cm->cmsg_type == IP_PKTINFO
351 && otolen >= sizeof(sin)) {
352 struct in_pktinfo *pi = (struct in_pktinfo *)(CMSG_DATA(cm));
353 *tolen = sizeof(*sin);
354 sin = (struct sockaddr_in *)to;
355 memset(sin, 0, sizeof(*sin));
356 sin->sin_family = AF_INET;
357 memcpy(&sin->sin_addr, &pi->ipi_addr,
358 sizeof(sin->sin_addr));
359 sin->sin_port = sa.sin.sin_port;
360 otolen = -1; /* "to" already set */
361 continue;
362 }
363 #endif
364 #if defined(INET6) && defined(IPV6_RECVDSTADDR)
365 if (sa.sa.sa_family == AF_INET6
366 && cm->cmsg_level == IPPROTO_IPV6
367 && cm->cmsg_type == IPV6_RECVDSTADDR
368 && otolen >= sizeof(*sin6)) {
369 *tolen = sizeof(*sin6);
370 sin6 = (struct sockaddr_in6 *)to;
371 memset(sin6, 0, sizeof(*sin6));
372 sin6->sin6_family = AF_INET6;
373 sin6->sin6_len = sizeof(*sin6);
374 memcpy(&sin6->sin6_addr, CMSG_DATA(cm),
375 sizeof(sin6->sin6_addr));
376 sin6->sin6_port = sa.sin6.sin6_port;
377 otolen = -1; /* "to" already set */
378 continue;
379 }
380 #endif
381 #ifndef __linux__
382 if (sa.sa.sa_family == AF_INET
383 && cm->cmsg_level == IPPROTO_IP
384 && cm->cmsg_type == IP_RECVDSTADDR
385 && otolen >= sizeof(*sin)) {
386 *tolen = sizeof(*sin);
387 sin = (struct sockaddr_in *)to;
388 memset(sin, 0, sizeof(*sin));
389 sin->sin_family = AF_INET;
390 sin->sin_len = sizeof(*sin);
391 memcpy(&sin->sin_addr, CMSG_DATA(cm),
392 sizeof(sin->sin_addr));
393 sin->sin_port = sa.sin.sin_port;
394 otolen = -1; /* "to" already set */
395 continue;
396 }
397 #endif
398 }
399
400 return len;
401 }
402
403 /* send packet, with fixing src/dst address pair. */
404 int
sendfromto(s,buf,buflen,src,dst,cnt)405 sendfromto(s, buf, buflen, src, dst, cnt)
406 int s, cnt;
407 const void *buf;
408 size_t buflen;
409 struct sockaddr *src;
410 struct sockaddr *dst;
411 {
412 struct sockaddr_storage ss;
413 socklen_t slen;
414 int len = 0;
415 int i;
416
417 if (src->sa_family != dst->sa_family) {
418 plog(LLV_ERROR, LOCATION, NULL,
419 "address family mismatch\n");
420 return -1;
421 }
422
423 slen = sizeof(ss);
424 if (getsockname(s, (struct sockaddr *)&ss, &slen) < 0) {
425 plog(LLV_ERROR, LOCATION, NULL,
426 "getsockname (%s)\n", strerror(errno));
427 return -1;
428 }
429
430 plog(LLV_DEBUG, LOCATION, NULL,
431 "sockname %s\n", saddr2str((struct sockaddr *)&ss));
432 plog(LLV_DEBUG, LOCATION, NULL,
433 "send packet from %s\n", saddr2str(src));
434 plog(LLV_DEBUG, LOCATION, NULL,
435 "send packet to %s\n", saddr2str(dst));
436
437 if (src->sa_family != ss.ss_family) {
438 plog(LLV_ERROR, LOCATION, NULL,
439 "address family mismatch\n");
440 return -1;
441 }
442
443 switch (src->sa_family) {
444 #if defined(INET6) && defined(INET6_ADVAPI)
445 // XXX: This block wasn't compiled on Linux - does it work?
446 case AF_INET6:
447 {
448 struct msghdr m;
449 struct cmsghdr *cm;
450 struct iovec iov[2];
451 u_char cmsgbuf[256];
452 struct in6_pktinfo *pi;
453 int ifindex;
454 struct sockaddr_in6 src6, dst6;
455
456 memcpy(&src6, src, sizeof(src6));
457 memcpy(&dst6, dst, sizeof(dst6));
458
459 /* XXX take care of other cases, such as site-local */
460 ifindex = 0;
461 if (IN6_IS_ADDR_LINKLOCAL(&src6.sin6_addr)
462 || IN6_IS_ADDR_MULTICAST(&src6.sin6_addr)) {
463 ifindex = src6.sin6_scope_id; /*???*/
464 }
465
466 /* XXX some sanity check on dst6.sin6_scope_id */
467
468 /* flowinfo for IKE? mmm, maybe useful but for now make it 0 */
469 src6.sin6_flowinfo = dst6.sin6_flowinfo = 0;
470
471 memset(&m, 0, sizeof(m));
472 m.msg_name = (caddr_t)&dst6;
473 m.msg_namelen = sizeof(dst6);
474 iov[0].iov_base = (char *)buf;
475 iov[0].iov_len = buflen;
476 m.msg_iov = iov;
477 m.msg_iovlen = 1;
478
479 memset(cmsgbuf, 0, sizeof(cmsgbuf));
480 cm = (struct cmsghdr *)cmsgbuf;
481 m.msg_control = (caddr_t)cm;
482 m.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
483
484 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
485 cm->cmsg_level = IPPROTO_IPV6;
486 cm->cmsg_type = IPV6_PKTINFO;
487 pi = (struct in6_pktinfo *)CMSG_DATA(cm);
488 memcpy(&pi->ipi6_addr, &src6.sin6_addr, sizeof(src6.sin6_addr));
489 pi->ipi6_ifindex = ifindex;
490
491 plog(LLV_DEBUG, LOCATION, NULL,
492 "src6 %s %d\n",
493 saddr2str((struct sockaddr *)&src6),
494 src6.sin6_scope_id);
495 plog(LLV_DEBUG, LOCATION, NULL,
496 "dst6 %s %d\n",
497 saddr2str((struct sockaddr *)&dst6),
498 dst6.sin6_scope_id);
499
500 for (i = 0; i < cnt; i++) {
501 len = sendmsg(s, &m, 0 /*MSG_DONTROUTE*/);
502 if (len < 0) {
503 plog(LLV_ERROR, LOCATION, NULL,
504 "sendmsg (%s)\n", strerror(errno));
505 return -1;
506 }
507 plog(LLV_DEBUG, LOCATION, NULL,
508 "%d times of %d bytes message will be sent "
509 "to %s\n",
510 i + 1, len, saddr2str(dst));
511 }
512 plogdump(LLV_DEBUG, (char *)buf, buflen);
513
514 return len;
515 }
516 #endif
517 #ifdef __linux__
518 case AF_INET:
519 {
520 struct msghdr m;
521 struct cmsghdr *cm;
522 struct iovec iov[2];
523 u_char cmsgbuf[256];
524 struct in_pktinfo *pi;
525 int ifindex = 0;
526 struct sockaddr_in src6, dst6;
527
528 memcpy(&src6, src, sizeof(src6));
529 memcpy(&dst6, dst, sizeof(dst6));
530
531 memset(&m, 0, sizeof(m));
532 m.msg_name = (caddr_t)&dst6;
533 m.msg_namelen = sizeof(dst6);
534 iov[0].iov_base = (char *)buf;
535 iov[0].iov_len = buflen;
536 m.msg_iov = iov;
537 m.msg_iovlen = 1;
538
539 memset(cmsgbuf, 0, sizeof(cmsgbuf));
540 cm = (struct cmsghdr *)cmsgbuf;
541 m.msg_control = (caddr_t)cm;
542 m.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
543
544 cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
545 cm->cmsg_level = IPPROTO_IP;
546 cm->cmsg_type = IP_PKTINFO;
547 pi = (struct in_pktinfo *)CMSG_DATA(cm);
548 memcpy(&pi->ipi_spec_dst, &src6.sin_addr, sizeof(src6.sin_addr));
549 pi->ipi_ifindex = ifindex;
550
551 plog(LLV_DEBUG, LOCATION, NULL,
552 "src4 %s\n",
553 saddr2str((struct sockaddr *)&src6));
554 plog(LLV_DEBUG, LOCATION, NULL,
555 "dst4 %s\n",
556 saddr2str((struct sockaddr *)&dst6));
557
558 for (i = 0; i < cnt; i++) {
559 len = sendmsg(s, &m, 0 /*MSG_DONTROUTE*/);
560 if (len < 0) {
561 plog(LLV_ERROR, LOCATION, NULL,
562 "sendmsg (%s)\n", strerror(errno));
563 return -1;
564 }
565 plog(LLV_DEBUG, LOCATION, NULL,
566 "%d times of %d bytes message will be sent "
567 "to %s\n",
568 i + 1, len, saddr2str(dst));
569 }
570 plogdump(LLV_DEBUG, (char *)buf, buflen);
571
572 return len;
573 }
574 #endif /* __linux__ */
575 default:
576 {
577 int needclose = 0;
578 int sendsock;
579
580 if (ss.ss_family == src->sa_family && memcmp(&ss, src, sysdep_sa_len(src)) == 0) {
581 sendsock = s;
582 needclose = 0;
583 } else {
584 int yes = 1;
585 /*
586 * Use newly opened socket for sending packets.
587 * NOTE: this is unsafe, because if the peer is quick enough
588 * the packet from the peer may be queued into sendsock.
589 * Better approach is to prepare bind'ed udp sockets for
590 * each of the interface addresses.
591 */
592 sendsock = SOCKET(src->sa_family, SOCK_DGRAM, 0);
593 if (sendsock < 0) {
594 plog(LLV_ERROR, LOCATION, NULL,
595 "socket (%s)\n", strerror(errno));
596 return -1;
597 }
598 if (setsockopt(sendsock, SOL_SOCKET,
599 #ifdef __linux__
600 SO_REUSEADDR,
601 #else
602 SO_REUSEPORT,
603 #endif
604 (void *)&yes, sizeof(yes)) < 0) {
605 plog(LLV_ERROR, LOCATION, NULL,
606 "setsockopt SO_REUSEPORT (%s)\n",
607 strerror(errno));
608 close(sendsock);
609 return -1;
610 }
611 #ifdef IPV6_USE_MIN_MTU
612 if (src->sa_family == AF_INET6 &&
613 setsockopt(sendsock, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
614 (void *)&yes, sizeof(yes)) < 0) {
615 plog(LLV_ERROR, LOCATION, NULL,
616 "setsockopt IPV6_USE_MIN_MTU (%s)\n",
617 strerror(errno));
618 close(sendsock);
619 return -1;
620 }
621 #endif
622 if (setsockopt_bypass(sendsock, src->sa_family) < 0) {
623 close(sendsock);
624 return -1;
625 }
626
627 if (BIND(sendsock, (struct sockaddr *)src,
628 sysdep_sa_len(src)) < 0) {
629 plog(LLV_ERROR, LOCATION, NULL,
630 "bind 1 (%s)\n", strerror(errno));
631 close(sendsock);
632 return -1;
633 }
634 needclose = 1;
635 }
636
637 for (i = 0; i < cnt; i++) {
638 len = sendto(sendsock, buf, buflen, 0, dst, sysdep_sa_len(dst));
639 if (len < 0) {
640 plog(LLV_ERROR, LOCATION, NULL,
641 "sendto (%s)\n", strerror(errno));
642 if (needclose)
643 close(sendsock);
644 return len;
645 }
646 plog(LLV_DEBUG, LOCATION, NULL,
647 "%d times of %d bytes message will be sent "
648 "to %s\n",
649 i + 1, len, saddr2str(dst));
650 }
651 plogdump(LLV_DEBUG, (char *)buf, buflen);
652
653 if (needclose)
654 close(sendsock);
655
656 return len;
657 }
658 }
659 }
660
661 int
setsockopt_bypass(so,family)662 setsockopt_bypass(so, family)
663 int so, family;
664 {
665 int level;
666 char *buf;
667 char *policy;
668
669 switch (family) {
670 case AF_INET:
671 level = IPPROTO_IP;
672 break;
673 #ifdef INET6
674 case AF_INET6:
675 level = IPPROTO_IPV6;
676 break;
677 #endif
678 default:
679 plog(LLV_ERROR, LOCATION, NULL,
680 "unsupported address family %d\n", family);
681 return -1;
682 }
683
684 policy = "in bypass";
685 buf = ipsec_set_policy(policy, strlen(policy));
686 if (buf == NULL) {
687 plog(LLV_ERROR, LOCATION, NULL,
688 "ipsec_set_policy (%s)\n",
689 ipsec_strerror());
690 return -1;
691 }
692 if (SETSOCKOPT(so, level,
693 (level == IPPROTO_IP ?
694 IP_IPSEC_POLICY : IPV6_IPSEC_POLICY),
695 buf, ipsec_get_policylen(buf)) < 0) {
696 plog(LLV_ERROR, LOCATION, NULL,
697 "setsockopt IP_IPSEC_POLICY (%s)\n",
698 strerror(errno));
699 return -1;
700 }
701 racoon_free(buf);
702
703 policy = "out bypass";
704 buf = ipsec_set_policy(policy, strlen(policy));
705 if (buf == NULL) {
706 plog(LLV_ERROR, LOCATION, NULL,
707 "ipsec_set_policy (%s)\n",
708 ipsec_strerror());
709 return -1;
710 }
711 if (SETSOCKOPT(so, level,
712 (level == IPPROTO_IP ?
713 IP_IPSEC_POLICY : IPV6_IPSEC_POLICY),
714 buf, ipsec_get_policylen(buf)) < 0) {
715 plog(LLV_ERROR, LOCATION, NULL,
716 "setsockopt IP_IPSEC_POLICY (%s)\n",
717 strerror(errno));
718 return -1;
719 }
720 racoon_free(buf);
721
722 return 0;
723 }
724
725 #endif
726
727 struct sockaddr *
newsaddr(len)728 newsaddr(len)
729 int len;
730 {
731 struct sockaddr *new;
732
733 if ((new = racoon_calloc(1, len)) == NULL) {
734 plog(LLV_ERROR, LOCATION, NULL,
735 "%s\n", strerror(errno));
736 goto out;
737 }
738
739 #ifdef __linux__
740 if (len == sizeof (struct sockaddr_in6))
741 new->sa_family = AF_INET6;
742 else
743 new->sa_family = AF_INET;
744 #else
745 /* initial */
746 new->sa_len = len;
747 #endif
748 out:
749 return new;
750 }
751
752 struct sockaddr *
dupsaddr(src)753 dupsaddr(src)
754 struct sockaddr *src;
755 {
756 struct sockaddr *dst;
757
758 dst = racoon_calloc(1, sysdep_sa_len(src));
759 if (dst == NULL) {
760 plog(LLV_ERROR, LOCATION, NULL,
761 "%s\n", strerror(errno));
762 return NULL;
763 }
764
765 memcpy(dst, src, sysdep_sa_len(src));
766
767 return dst;
768 }
769
770 char *
saddr2str(saddr)771 saddr2str(saddr)
772 const struct sockaddr *saddr;
773 {
774 static char buf[NI_MAXHOST + NI_MAXSERV + 10];
775 char addr[NI_MAXHOST], port[NI_MAXSERV];
776
777 if (saddr == NULL)
778 return NULL;
779
780 if (saddr->sa_family == AF_UNSPEC)
781 snprintf (buf, sizeof(buf), "%s", "anonymous");
782 else {
783 GETNAMEINFO(saddr, addr, port);
784 snprintf(buf, sizeof(buf), "%s[%s]", addr, port);
785 }
786
787 return buf;
788 }
789
790 char *
saddrwop2str(saddr)791 saddrwop2str(saddr)
792 const struct sockaddr *saddr;
793 {
794 static char buf[NI_MAXHOST + NI_MAXSERV + 10];
795 char addr[NI_MAXHOST];
796
797 if (saddr == NULL)
798 return NULL;
799
800 GETNAMEINFO_NULL(saddr, addr);
801 snprintf(buf, sizeof(buf), "%s", addr);
802
803 return buf;
804 }
805
806 char *
naddrwop2str(const struct netaddr * naddr)807 naddrwop2str(const struct netaddr *naddr)
808 {
809 static char buf[NI_MAXHOST + 10];
810 static const struct sockaddr sa_any; /* this is initialized to all zeros */
811
812 if (naddr == NULL)
813 return NULL;
814
815 if (memcmp(&naddr->sa, &sa_any, sizeof(sa_any)) == 0)
816 snprintf(buf, sizeof(buf), "%s", "any");
817 else {
818 snprintf(buf, sizeof(buf), "%s", saddrwop2str(&naddr->sa.sa));
819 snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf), "/%ld", naddr->prefix);
820 }
821 return buf;
822 }
823
824 char *
naddrwop2str_fromto(const char * format,const struct netaddr * saddr,const struct netaddr * daddr)825 naddrwop2str_fromto(const char *format, const struct netaddr *saddr,
826 const struct netaddr *daddr)
827 {
828 static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100];
829 char *src, *dst;
830
831 src = racoon_strdup(naddrwop2str(saddr));
832 dst = racoon_strdup(naddrwop2str(daddr));
833 STRDUP_FATAL(src);
834 STRDUP_FATAL(dst);
835 /* WARNING: Be careful about the format string! Don't
836 ever pass in something that a user can modify!!! */
837 snprintf (buf, sizeof(buf), format, src, dst);
838 racoon_free (src);
839 racoon_free (dst);
840
841 return buf;
842 }
843
844 char *
saddr2str_fromto(format,saddr,daddr)845 saddr2str_fromto(format, saddr, daddr)
846 const char *format;
847 const struct sockaddr *saddr;
848 const struct sockaddr *daddr;
849 {
850 static char buf[2*(NI_MAXHOST + NI_MAXSERV + 10) + 100];
851 char *src, *dst;
852
853 src = racoon_strdup(saddr2str(saddr));
854 dst = racoon_strdup(saddr2str(daddr));
855 STRDUP_FATAL(src);
856 STRDUP_FATAL(dst);
857 /* WARNING: Be careful about the format string! Don't
858 ever pass in something that a user can modify!!! */
859 snprintf (buf, sizeof(buf), format, src, dst);
860 racoon_free (src);
861 racoon_free (dst);
862
863 return buf;
864 }
865
866 struct sockaddr *
str2saddr(host,port)867 str2saddr(host, port)
868 char *host;
869 char *port;
870 {
871 struct addrinfo hints, *res;
872 struct sockaddr *saddr;
873 int error;
874
875 memset(&hints, 0, sizeof(hints));
876 hints.ai_family = PF_UNSPEC;
877 hints.ai_socktype = SOCK_DGRAM;
878 hints.ai_flags = AI_NUMERICHOST;
879 error = getaddrinfo(host, port, &hints, &res);
880 if (error != 0) {
881 plog(LLV_ERROR, LOCATION, NULL,
882 "getaddrinfo(%s%s%s): %s\n",
883 host, port ? "," : "", port ? port : "",
884 gai_strerror(error));
885 return NULL;
886 }
887 if (res->ai_next != NULL) {
888 plog(LLV_WARNING, LOCATION, NULL,
889 "getaddrinfo(%s%s%s): "
890 "resolved to multiple address, "
891 "taking the first one\n",
892 host, port ? "," : "", port ? port : "");
893 }
894 saddr = racoon_malloc(res->ai_addrlen);
895 if (saddr == NULL) {
896 plog(LLV_ERROR, LOCATION, NULL,
897 "failed to allocate buffer.\n");
898 freeaddrinfo(res);
899 return NULL;
900 }
901 memcpy(saddr, res->ai_addr, res->ai_addrlen);
902 freeaddrinfo(res);
903
904 return saddr;
905 }
906
907 void
mask_sockaddr(a,b,l)908 mask_sockaddr(a, b, l)
909 struct sockaddr *a;
910 const struct sockaddr *b;
911 size_t l;
912 {
913 size_t i;
914 u_int8_t *p, alen;
915
916 switch (b->sa_family) {
917 case AF_INET:
918 alen = sizeof(struct in_addr);
919 p = (u_int8_t *)&((struct sockaddr_in *)a)->sin_addr;
920 break;
921 #ifdef INET6
922 case AF_INET6:
923 alen = sizeof(struct in6_addr);
924 p = (u_int8_t *)&((struct sockaddr_in6 *)a)->sin6_addr;
925 break;
926 #endif
927 default:
928 plog(LLV_ERROR, LOCATION, NULL,
929 "invalid family: %d\n", b->sa_family);
930 exit(1);
931 }
932
933 if ((alen << 3) < l) {
934 plog(LLV_ERROR, LOCATION, NULL,
935 "unexpected inconsistency: %d %zu\n", b->sa_family, l);
936 exit(1);
937 }
938
939 memcpy(a, b, sysdep_sa_len(b));
940 p[l / 8] &= (0xff00 >> (l % 8)) & 0xff;
941 for (i = l / 8 + 1; i < alen; i++)
942 p[i] = 0x00;
943 }
944
945 /* Compute a score describing how "accurate" a netaddr is for a given sockaddr.
946 * Examples:
947 * Return values for address 10.20.30.40 [port 500] and given netaddresses...
948 * 10.10.0.0/16 => -1 ... doesn't match
949 * 0.0.0.0/0 => 0 ... matches, but only 0 bits.
950 * 10.20.0.0/16 => 16 ... 16 bits match
951 * 10.20.30.0/24 => 24 ... guess what ;-)
952 * 10.20.30.40/32 => 32 ... whole address match
953 * 10.20.30.40:500 => 33 ... both address and port match
954 * 10.20.30.40:501 => -1 ... port doesn't match and isn't 0 (=any)
955 */
956 int
naddr_score(const struct netaddr * naddr,const struct sockaddr * saddr)957 naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr)
958 {
959 static const struct netaddr naddr_any; /* initialized to all-zeros */
960 struct sockaddr sa;
961 u_int16_t naddr_port, saddr_port;
962 int port_score;
963
964 if (!naddr || !saddr) {
965 plog(LLV_ERROR, LOCATION, NULL,
966 "Call with null args: naddr=%p, saddr=%p\n",
967 naddr, saddr);
968 return -1;
969 }
970
971 /* Wildcard address matches, but only 0 bits. */
972 if (memcmp(naddr, &naddr_any, sizeof(naddr_any)) == 0)
973 return 0;
974
975 /* If families don't match we really can't do much... */
976 if (naddr->sa.sa.sa_family != saddr->sa_family)
977 return -1;
978
979 /* If port check fail don't bother to check addresses. */
980 naddr_port = extract_port(&naddr->sa.sa);
981 saddr_port = extract_port(saddr);
982 if (naddr_port == 0 || saddr_port == 0) /* wildcard match */
983 port_score = 0;
984 else if (naddr_port == saddr_port) /* exact match */
985 port_score = 1;
986 else /* mismatch :-) */
987 return -1;
988
989 /* Here it comes - compare network addresses. */
990 mask_sockaddr(&sa, saddr, naddr->prefix);
991 if (loglevel >= LLV_DEBUG) { /* debug only */
992 char *a1, *a2, *a3;
993 a1 = racoon_strdup(naddrwop2str(naddr));
994 a2 = racoon_strdup(saddrwop2str(saddr));
995 a3 = racoon_strdup(saddrwop2str(&sa));
996 STRDUP_FATAL(a1);
997 STRDUP_FATAL(a2);
998 STRDUP_FATAL(a3);
999 plog(LLV_DEBUG, LOCATION, NULL,
1000 "naddr=%s, saddr=%s (masked=%s)\n",
1001 a1, a2, a3);
1002 free(a1);
1003 free(a2);
1004 free(a3);
1005 }
1006 if (cmpsaddr(&sa, &naddr->sa.sa) <= CMPSADDR_WOP_MATCH)
1007 return naddr->prefix + port_score;
1008
1009 return -1;
1010 }
1011
1012 /* Some useful functions for sockaddr port manipulations. */
1013 u_int16_t
extract_port(const struct sockaddr * addr)1014 extract_port (const struct sockaddr *addr)
1015 {
1016 u_int16_t port = 0;
1017
1018 if (!addr)
1019 return port;
1020
1021 switch (addr->sa_family) {
1022 case AF_UNSPEC:
1023 break;
1024 case AF_INET:
1025 port = ((struct sockaddr_in *)addr)->sin_port;
1026 break;
1027 case AF_INET6:
1028 port = ((struct sockaddr_in6 *)addr)->sin6_port;
1029 break;
1030 default:
1031 plog(LLV_ERROR, LOCATION, NULL, "unknown AF: %u\n", addr->sa_family);
1032 break;
1033 }
1034
1035 return ntohs(port);
1036 }
1037
1038 u_int16_t *
get_port_ptr(struct sockaddr * addr)1039 get_port_ptr (struct sockaddr *addr)
1040 {
1041 u_int16_t *port_ptr;
1042
1043 if (!addr)
1044 return NULL;
1045
1046 switch (addr->sa_family) {
1047 case AF_INET:
1048 port_ptr = &(((struct sockaddr_in *)addr)->sin_port);
1049 break;
1050 case AF_INET6:
1051 port_ptr = &(((struct sockaddr_in6 *)addr)->sin6_port);
1052 break;
1053 default:
1054 plog(LLV_ERROR, LOCATION, NULL, "unknown AF: %u\n", addr->sa_family);
1055 return NULL;
1056 break;
1057 }
1058
1059 return port_ptr;
1060 }
1061
1062 u_int16_t *
set_port(struct sockaddr * addr,u_int16_t new_port)1063 set_port (struct sockaddr *addr, u_int16_t new_port)
1064 {
1065 u_int16_t *port_ptr;
1066
1067 port_ptr = get_port_ptr (addr);
1068
1069 if (port_ptr)
1070 *port_ptr = htons(new_port);
1071
1072 return port_ptr;
1073 }
1074