2 * Copyright (C) 2006-2013 Tobias Brunner
3 * Copyright (C) 2006 Daniel Roethlisberger
4 * Copyright (C) 2005-2010 Martin Willi
5 * Copyright (C) 2005 Jan Hutter
6 * Hochschule fuer Technik Rapperswil
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 /* for struct in6_pktinfo */
23 #define __EXTENSIONS__
25 /* make sure to use the proper defs on Mac OS X */
26 #define __APPLE_USE_RFC_3542
28 #include "socket_default_socket.h"
30 #include <sys/types.h>
31 #include <sys/socket.h>
37 #include <sys/ioctl.h>
38 #include <netinet/in_systm.h>
39 #include <netinet/in.h>
40 #include <netinet/ip.h>
41 #include <netinet/udp.h>
45 #include <threading/thread.h>
47 /* these are not defined on some platforms */
49 #define SOL_IP IPPROTO_IP
52 #define SOL_IPV6 IPPROTO_IPV6
55 #define IPV6_TCLASS 67
58 /* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
59 * previously defined IPV6_PKTINFO */
60 #ifndef IPV6_RECVPKTINFO
61 #define IPV6_RECVPKTINFO IPV6_PKTINFO
64 #ifndef IN6ADDR_ANY_INIT
65 #define IN6ADDR_ANY_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}
68 #ifndef HAVE_IN6ADDR_ANY
69 static const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
72 typedef struct private_socket_default_socket_t private_socket_default_socket_t
;
75 * Private data of an socket_t object
77 struct private_socket_default_socket_t
{
82 socket_default_socket_t
public;
85 * Configured port (or random, if initially 0)
90 * Configured port for NAT-T (or random, if initially 0)
95 * IPv4 socket (500 or port)
100 * IPv4 socket for NAT-T (4500 or natt)
105 * IPv6 socket (500 or port)
110 * IPv6 socket for NAT-T (4500 or natt)
115 * DSCP value set on IPv4 socket
120 * DSCP value set on IPv4 socket for NAT-T (4500 or natt)
125 * DSCP value set on IPv6 socket (500 or port)
130 * DSCP value set on IPv6 socket for NAT-T (4500 or natt)
135 * Maximum packet size to receive
140 * TRUE if the source address should be set on outbound packets
145 * TRUE to force sending source interface on outbound packetrs
150 * A counter to implement round-robin selection of read sockets
156 * Get the destination IPv4 address of a received packet, depending on the
157 * available mechanism.
161 static host_t
*get_dst_v4(struct cmsghdr
*cmsgptr
, uint16_t port
)
163 struct sockaddr_in dst
= {
164 .sin_family
= AF_INET
,
165 .sin_port
= htons(port
),
167 struct in_pktinfo
*pktinfo
;
168 struct in_addr
*addr
;
170 if (cmsgptr
->cmsg_type
== IP_PKTINFO
)
172 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(cmsgptr
);
173 addr
= &pktinfo
->ipi_addr
;
174 memcpy(&dst
.sin_addr
, addr
, sizeof(dst
.sin_addr
));
175 return host_create_from_sockaddr((sockaddr_t
*)&dst
);
180 #elif defined(IP_RECVDSTADDR)
182 static host_t
*get_dst_v4(struct cmsghdr
*cmsgptr
, uint16_t port
)
184 struct sockaddr_in dst
= {
185 .sin_family
= AF_INET
,
186 .sin_port
= htons(port
),
188 struct in_addr
*addr
;
190 if (cmsgptr
->cmsg_type
== IP_RECVDSTADDR
)
192 addr
= (struct in_addr
*)CMSG_DATA(cmsgptr
);
193 memcpy(&dst
.sin_addr
, addr
, sizeof(dst
.sin_addr
));
194 return host_create_from_sockaddr((sockaddr_t
*)&dst
);
199 #else /* IP_PKTINFO || IP_RECVDSTADDR */
201 static host_t
*get_dst_v4(struct cmsghdr
*cmsgptr
, uint16_t port
)
206 #endif /* IP_PKTINFO || IP_RECVDSTADDR */
209 * Get the destination IPv6 address of a received packet, depending on the
210 * available mechanism.
212 #ifdef HAVE_IN6_PKTINFO
214 static host_t
*get_dst_v6(struct cmsghdr
*cmsgptr
, uint16_t port
)
216 struct in6_pktinfo
*pktinfo
;
217 struct sockaddr_in6 dst
= {
218 .sin6_family
= AF_INET6
,
219 .sin6_port
= htons(port
),
222 if (cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
224 pktinfo
= (struct in6_pktinfo
*)CMSG_DATA(cmsgptr
);
225 memcpy(&dst
.sin6_addr
, &pktinfo
->ipi6_addr
, sizeof(dst
.sin6_addr
));
226 return host_create_from_sockaddr((sockaddr_t
*)&dst
);
231 #else /* HAVE_IN6_PKTINFO */
233 static host_t
*get_dst_v6(struct cmsghdr
*cmsgptr
, uint16_t port
)
238 #endif /* HAVE_IN6_PKTINFO */
240 METHOD(socket_t
, receiver
, status_t
,
241 private_socket_default_socket_t
*this, packet_t
**packet
)
243 char buffer
[this->max_packet
];
246 host_t
*source
= NULL
, *dest
= NULL
;
247 int i
, rr
, index
, bytes_read
= 0, selected
= -1;
250 struct pollfd pfd
[] = {
251 { .fd
= this->ipv4
, .events
= POLLIN
},
252 { .fd
= this->ipv4_natt
, .events
= POLLIN
},
253 { .fd
= this->ipv6
, .events
= POLLIN
},
254 { .fd
= this->ipv6_natt
, .events
= POLLIN
},
257 /* port numbers associated to pollfds */
258 this->port
, this->natt
, this->port
, this->natt
,
261 DBG2(DBG_NET
, "waiting for data on sockets");
262 oldstate
= thread_cancelability(TRUE
);
263 if (poll(pfd
, countof(pfd
), -1) <= 0)
265 thread_cancelability(oldstate
);
268 thread_cancelability(oldstate
);
270 rr
= this->rr_counter
++;
271 for (i
= 0; i
< countof(pfd
); i
++)
273 /* To serve all ports with equal priority, we use a round-robin
274 * scheme to choose the one to process in this invocation */
275 index
= (rr
+ i
) % countof(pfd
);
276 if (pfd
[index
].revents
& POLLIN
)
278 selected
= pfd
[index
].fd
;
286 struct cmsghdr
*cmsgptr
;
290 struct sockaddr_in in4
;
291 struct sockaddr_in6 in6
;
295 msg
.msg_namelen
= sizeof(src
);
296 iov
.iov_base
= buffer
;
297 iov
.iov_len
= this->max_packet
;
300 msg
.msg_control
= ancillary
;
301 msg
.msg_controllen
= sizeof(ancillary
);
303 bytes_read
= recvmsg(selected
, &msg
, 0);
306 DBG1(DBG_NET
, "error reading socket: %s", strerror(errno
));
309 if (msg
.msg_flags
& MSG_TRUNC
)
311 DBG1(DBG_NET
, "receive buffer too small, packet discarded");
314 DBG3(DBG_NET
, "received packet %b", buffer
, bytes_read
);
316 /* read ancillary data to get destination address */
317 for (cmsgptr
= CMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
318 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
320 if (cmsgptr
->cmsg_len
== 0)
322 DBG1(DBG_NET
, "error reading ancillary data");
325 if (cmsgptr
->cmsg_level
== SOL_IP
)
327 dest
= get_dst_v4(cmsgptr
, port
);
329 else if (cmsgptr
->cmsg_level
== SOL_IPV6
)
331 dest
= get_dst_v6(cmsgptr
, port
);
340 DBG1(DBG_NET
, "error reading IP header");
343 source
= host_create_from_sockaddr((sockaddr_t
*)&src
);
345 pkt
= packet_create();
346 pkt
->set_source(pkt
, source
);
347 pkt
->set_destination(pkt
, dest
);
348 DBG2(DBG_NET
, "received packet: from %#H to %#H", source
, dest
);
349 data
= chunk_create(buffer
, bytes_read
);
350 pkt
->set_data(pkt
, chunk_clone(data
));
354 /* oops, shouldn't happen */
363 * Generic function to send a message.
365 static ssize_t
send_msg_generic(int skt
, struct msghdr
*msg
)
367 return sendmsg(skt
, msg
, 0);
370 #if defined(IP_PKTINFO) || defined(HAVE_IN6_PKTINFO)
373 * Find the interface index a source address is installed on
375 static int find_srcif(host_t
*src
)
380 if (charon
->kernel
->get_interface(charon
->kernel
, src
, &ifname
))
382 idx
= if_nametoindex(ifname
);
388 #endif /* IP_PKTINFO || HAVE_IN6_PKTINFO */
391 * Send a message with the IPv4 source address set, if possible.
395 static ssize_t
send_msg_v4(private_socket_default_socket_t
*this, int skt
,
396 struct msghdr
*msg
, host_t
*src
)
398 char buf
[CMSG_SPACE(sizeof(struct in_pktinfo
))] = {};
399 struct cmsghdr
*cmsg
;
400 struct in_addr
*addr
;
401 struct in_pktinfo
*pktinfo
;
402 struct sockaddr_in
*sin
;
404 msg
->msg_control
= buf
;
405 msg
->msg_controllen
= sizeof(buf
);
406 cmsg
= CMSG_FIRSTHDR(msg
);
407 cmsg
->cmsg_level
= SOL_IP
;
408 cmsg
->cmsg_type
= IP_PKTINFO
;
409 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
411 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(cmsg
);
412 if (this->set_sourceif
)
414 pktinfo
->ipi_ifindex
= find_srcif(src
);
416 addr
= &pktinfo
->ipi_spec_dst
;
418 sin
= (struct sockaddr_in
*)src
->get_sockaddr(src
);
419 memcpy(addr
, &sin
->sin_addr
, sizeof(struct in_addr
));
420 return send_msg_generic(skt
, msg
);
423 #elif defined(IP_SENDSRCADDR)
425 static ssize_t
send_msg_v4(private_socket_default_socket_t
*this, int skt
,
426 struct msghdr
*msg
, host_t
*src
)
428 char buf
[CMSG_SPACE(sizeof(struct in_addr
))] = {};
429 struct cmsghdr
*cmsg
;
430 struct in_addr
*addr
;
431 struct sockaddr_in
*sin
;
433 msg
->msg_control
= buf
;
434 msg
->msg_controllen
= sizeof(buf
);
435 cmsg
= CMSG_FIRSTHDR(msg
);
436 cmsg
->cmsg_level
= SOL_IP
;
437 cmsg
->cmsg_type
= IP_SENDSRCADDR
;
438 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in_addr
));
440 addr
= (struct in_addr
*)CMSG_DATA(cmsg
);
442 sin
= (struct sockaddr_in
*)src
->get_sockaddr(src
);
443 memcpy(addr
, &sin
->sin_addr
, sizeof(struct in_addr
));
444 return send_msg_generic(skt
, msg
);
447 #else /* IP_PKTINFO || IP_RECVDSTADDR */
449 static ssize_t
send_msg_v4(private_socket_default_socket_t
*this,
450 int skt
, struct msghdr
*msg
, host_t
*src
)
452 return send_msg_generic(skt
, msg
);
455 #endif /* IP_PKTINFO || IP_RECVDSTADDR */
458 * Send a message with the IPv6 source address set, if possible.
460 #ifdef HAVE_IN6_PKTINFO
462 static ssize_t
send_msg_v6(private_socket_default_socket_t
*this, int skt
,
463 struct msghdr
*msg
, host_t
*src
)
465 char buf
[CMSG_SPACE(sizeof(struct in6_pktinfo
))] = {};
466 struct cmsghdr
*cmsg
;
467 struct in6_pktinfo
*pktinfo
;
468 struct sockaddr_in6
*sin
;
470 msg
->msg_control
= buf
;
471 msg
->msg_controllen
= sizeof(buf
);
472 cmsg
= CMSG_FIRSTHDR(msg
);
473 cmsg
->cmsg_level
= SOL_IPV6
;
474 cmsg
->cmsg_type
= IPV6_PKTINFO
;
475 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
476 pktinfo
= (struct in6_pktinfo
*)CMSG_DATA(cmsg
);
477 if (this->set_sourceif
)
479 pktinfo
->ipi6_ifindex
= find_srcif(src
);
481 sin
= (struct sockaddr_in6
*)src
->get_sockaddr(src
);
482 memcpy(&pktinfo
->ipi6_addr
, &sin
->sin6_addr
, sizeof(struct in6_addr
));
483 return send_msg_generic(skt
, msg
);
486 #else /* HAVE_IN6_PKTINFO */
488 static ssize_t
send_msg_v6(private_socket_default_socket_t
*this,
489 int skt
, struct msghdr
*msg
, host_t
*src
)
491 return send_msg_generic(skt
, msg
);
494 #endif /* HAVE_IN6_PKTINFO */
496 METHOD(socket_t
, sender
, status_t
,
497 private_socket_default_socket_t
*this, packet_t
*packet
)
499 int sport
, skt
= -1, family
;
507 src
= packet
->get_source(packet
);
508 dst
= packet
->get_destination(packet
);
509 data
= packet
->get_data(packet
);
511 DBG2(DBG_NET
, "sending packet: from %#H to %#H", src
, dst
);
514 sport
= src
->get_port(src
);
515 family
= dst
->get_family(dst
);
516 if (sport
== 0 || sport
== this->port
)
532 else if (sport
== this->natt
)
537 skt
= this->ipv4_natt
;
538 dscp
= &this->dscp4_natt
;
541 skt
= this->ipv6_natt
;
542 dscp
= &this->dscp6_natt
;
550 DBG1(DBG_NET
, "no socket found to send IPv%d packet from port %d",
551 family
== AF_INET ?
4 : 6, sport
);
555 /* setting DSCP values per-packet in a cmsg seems not to be supported
556 * on Linux. We instead setsockopt() before sending it, this should be
557 * safe as only a single thread calls send(). */
558 if (*dscp
!= packet
->get_dscp(packet
))
560 if (family
== AF_INET
)
564 ds4
= packet
->get_dscp(packet
) << 2;
565 if (setsockopt(skt
, SOL_IP
, IP_TOS
, &ds4
, sizeof(ds4
)) == 0)
567 *dscp
= packet
->get_dscp(packet
);
571 DBG1(DBG_NET
, "unable to set IP_TOS on socket: %s",
579 ds6
= packet
->get_dscp(packet
) << 2;
580 if (setsockopt(skt
, SOL_IPV6
, IPV6_TCLASS
, &ds6
, sizeof(ds6
)) == 0)
582 *dscp
= packet
->get_dscp(packet
);
586 DBG1(DBG_NET
, "unable to set IPV6_TCLASS on socket: %s",
592 memset(&msg
, 0, sizeof(struct msghdr
));
593 msg
.msg_name
= dst
->get_sockaddr(dst
);;
594 msg
.msg_namelen
= *dst
->get_sockaddr_len(dst
);
595 iov
.iov_base
= data
.ptr
;
596 iov
.iov_len
= data
.len
;
601 if (this->set_source
&& !src
->is_anyaddr(src
))
603 if (family
== AF_INET
)
605 bytes_sent
= send_msg_v4(this, skt
, &msg
, src
);
609 bytes_sent
= send_msg_v6(this, skt
, &msg
, src
);
614 bytes_sent
= send_msg_generic(skt
, &msg
);
617 if (bytes_sent
!= data
.len
)
619 DBG1(DBG_NET
, "error writing to socket: %s", strerror(errno
));
625 METHOD(socket_t
, get_port
, uint16_t,
626 private_socket_default_socket_t
*this, bool nat_t
)
628 return nat_t ?
this->natt
: this->port
;
631 METHOD(socket_t
, supported_families
, socket_family_t
,
632 private_socket_default_socket_t
*this)
634 socket_family_t families
= SOCKET_FAMILY_NONE
;
636 if (this->ipv4
!= -1 || this->ipv4_natt
!= -1)
638 families
|= SOCKET_FAMILY_IPV4
;
640 if (this->ipv6
!= -1 || this->ipv6_natt
!= -1)
642 families
|= SOCKET_FAMILY_IPV6
;
648 * open a socket to send and receive packets
650 static int open_socket(private_socket_default_socket_t
*this,
651 int family
, uint16_t *port
)
655 struct sockaddr sockaddr
;
656 struct sockaddr_in sin
;
657 struct sockaddr_in6 sin6
;
660 u_int sol
, pktinfo
= 0;
663 memset(&addr
, 0, sizeof(addr
));
664 addr
.sockaddr
.sa_family
= family
;
665 /* precalculate constants depending on address family */
669 addr
.sin
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
670 addr
.sin
.sin_port
= htons(*port
);
671 addrlen
= sizeof(addr
.sin
);
674 pktinfo
= IP_PKTINFO
;
675 #elif defined(IP_RECVDSTADDR)
676 pktinfo
= IP_RECVDSTADDR
;
680 memcpy(&addr
.sin6
.sin6_addr
, &in6addr_any
, sizeof(in6addr_any
));
681 addr
.sin6
.sin6_port
= htons(*port
);
682 addrlen
= sizeof(addr
.sin6
);
684 pktinfo
= IPV6_RECVPKTINFO
;
690 skt
= socket(family
, SOCK_DGRAM
, IPPROTO_UDP
);
693 DBG1(DBG_NET
, "could not open socket: %s", strerror(errno
));
696 if (setsockopt(skt
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&on
, sizeof(on
)) < 0)
698 DBG1(DBG_NET
, "unable to set SO_REUSEADDR on socket: %s", strerror(errno
));
703 /* bind the socket */
704 if (bind(skt
, &addr
.sockaddr
, addrlen
) < 0)
706 DBG1(DBG_NET
, "unable to bind socket: %s", strerror(errno
));
711 /* retrieve randomly allocated port if needed */
714 if (getsockname(skt
, &addr
.sockaddr
, &addrlen
) < 0)
716 DBG1(DBG_NET
, "unable to determine port: %s", strerror(errno
));
723 *port
= ntohs(addr
.sin
.sin_port
);
726 *port
= ntohs(addr
.sin6
.sin6_port
);
731 /* get additional packet info on receive */
734 if (setsockopt(skt
, sol
, pktinfo
, &on
, sizeof(on
)) < 0)
736 DBG1(DBG_NET
, "unable to set IP_PKTINFO on socket: %s", strerror(errno
));
742 { /* set optional MARK on socket (requires CAP_NET_ADMIN) */
746 fwmark
= lib
->settings
->get_str(lib
->settings
,
747 "%s.plugins.socket-default.fwmark", NULL
, lib
->ns
);
748 if (fwmark
&& mark_from_string(fwmark
, &mark
))
750 if (setsockopt(skt
, SOL_SOCKET
, SO_MARK
, &mark
.value
,
751 sizeof(mark
.value
)) < 0)
753 DBG1(DBG_NET
, "unable to set SO_MARK on socket: %s",
760 if (!charon
->kernel
->bypass_socket(charon
->kernel
, skt
, family
))
762 DBG1(DBG_NET
, "installing IKE bypass policy failed");
765 /* enable UDP decapsulation for NAT-T sockets */
766 if (port
== &this->natt
&&
767 !charon
->kernel
->enable_udp_decap(charon
->kernel
, skt
, family
,
770 DBG1(DBG_NET
, "enabling UDP decapsulation for %s on port %d failed",
771 family
== AF_INET ?
"IPv4" : "IPv6", this->natt
);
778 * Check if we should use the given family
780 static bool use_family(int family
)
785 return lib
->settings
->get_bool(lib
->settings
,
786 "%s.plugins.socket-default.use_ipv4", TRUE
, lib
->ns
);
788 return lib
->settings
->get_bool(lib
->settings
,
789 "%s.plugins.socket-default.use_ipv6", TRUE
, lib
->ns
);
796 * Open a socket pair (normal and NAT traversal) for a given address family
798 static void open_socketpair(private_socket_default_socket_t
*this, int family
,
799 int *skt
, int *skt_natt
, char *label
)
801 if (!use_family(family
))
808 *skt
= open_socket(this, family
, &this->port
);
812 DBG1(DBG_NET
, "could not open %s socket, %s disabled", label
, label
);
816 *skt_natt
= open_socket(this, family
, &this->natt
);
819 DBG1(DBG_NET
, "could not open %s NAT-T socket", label
);
824 METHOD(socket_t
, destroy
, void,
825 private_socket_default_socket_t
*this)
827 if (this->ipv4
!= -1)
831 if (this->ipv4_natt
!= -1)
833 close(this->ipv4_natt
);
835 if (this->ipv6
!= -1)
839 if (this->ipv6_natt
!= -1)
841 close(this->ipv6_natt
);
847 * See header for description
849 socket_default_socket_t
*socket_default_socket_create()
851 private_socket_default_socket_t
*this;
857 .receive
= _receiver
,
858 .get_port
= _get_port
,
859 .supported_families
= _supported_families
,
863 .port
= lib
->settings
->get_int(lib
->settings
,
864 "%s.port", CHARON_UDP_PORT
, lib
->ns
),
865 .natt
= lib
->settings
->get_int(lib
->settings
,
866 "%s.port_nat_t", CHARON_NATT_PORT
, lib
->ns
),
867 .max_packet
= lib
->settings
->get_int(lib
->settings
,
868 "%s.max_packet", PACKET_MAX_DEFAULT
, lib
->ns
),
869 .set_source
= lib
->settings
->get_bool(lib
->settings
,
870 "%s.plugins.socket-default.set_source", TRUE
,
872 .set_sourceif
= lib
->settings
->get_bool(lib
->settings
,
873 "%s.plugins.socket-default.set_sourceif", FALSE
,
877 if (this->port
&& this->port
== this->natt
)
879 DBG1(DBG_NET
, "IKE ports can't be equal, will allocate NAT-T "
884 if ((this->port
&& this->port
< 1024) || (this->natt
&& this->natt
< 1024))
886 if (!lib
->caps
->check(lib
->caps
, CAP_NET_BIND_SERVICE
))
888 /* required to bind ports < 1024 */
889 DBG1(DBG_NET
, "socket-default plugin requires CAP_NET_BIND_SERVICE "
896 /* we allocate IPv6 sockets first as that will reserve randomly allocated
897 * ports also for IPv4. On OS X, we have to do it the other way round
898 * for the same effect. */
900 open_socketpair(this, AF_INET
, &this->ipv4
, &this->ipv4_natt
, "IPv4");
901 open_socketpair(this, AF_INET6
, &this->ipv6
, &this->ipv6_natt
, "IPv6");
902 #else /* !__APPLE__ */
903 open_socketpair(this, AF_INET6
, &this->ipv6
, &this->ipv6_natt
, "IPv6");
904 open_socketpair(this, AF_INET
, &this->ipv4
, &this->ipv4_natt
, "IPv4");
905 #endif /* __APPLE__ */
907 if (this->ipv4
== -1 && this->ipv6
== -1)
909 DBG1(DBG_NET
, "could not create any sockets");
914 return &this->public;