2 * Copyright (C) 2006-2010 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>
44 #include <sys/sysctl.h>
49 #include <threading/thread.h>
51 /* Maximum size of a packet */
52 #define MAX_PACKET 10000
54 /* length of non-esp marker */
55 #define MARKER_LEN sizeof(u_int32_t)
57 /* from linux/udp.h */
62 #ifndef UDP_ENCAP_ESPINUDP
63 #define UDP_ENCAP_ESPINUDP 2
64 #endif /*UDP_ENCAP_ESPINUDP*/
66 /* these are not defined on some platforms */
68 #define SOL_IP IPPROTO_IP
71 #define SOL_IPV6 IPPROTO_IPV6
74 #define SOL_UDP IPPROTO_UDP
77 /* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
78 * previously defined IPV6_PKTINFO */
79 #ifndef IPV6_RECVPKTINFO
80 #define IPV6_RECVPKTINFO IPV6_PKTINFO
83 #ifndef IN6ADDR_ANY_INIT
84 #define IN6ADDR_ANY_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}
87 #ifndef HAVE_IN6ADDR_ANY
88 static const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
91 typedef struct private_socket_default_socket_t private_socket_default_socket_t
;
94 * Private data of an socket_t object
96 struct private_socket_default_socket_t
{
101 socket_default_socket_t
public;
109 * IPv4 socket for NATT (4500)
119 * IPv6 socket for NATT (4500)
124 * Maximum packet size to receive
129 METHOD(socket_t
, receiver
, status_t
,
130 private_socket_default_socket_t
*this, packet_t
**packet
)
132 char buffer
[this->max_packet
];
135 host_t
*source
= NULL
, *dest
= NULL
;
136 int bytes_read
= 0, data_offset
;
140 int max_fd
= 0, selected
= 0;
147 FD_SET(this->ipv4
, &rfds
);
151 FD_SET(this->ipv4_natt
, &rfds
);
155 FD_SET(this->ipv6
, &rfds
);
159 FD_SET(this->ipv6_natt
, &rfds
);
161 max_fd
= max(max(this->ipv4
, this->ipv4_natt
), max(this->ipv6
, this->ipv6_natt
));
163 DBG2(DBG_NET
, "waiting for data on sockets");
164 oldstate
= thread_cancelability(TRUE
);
165 if (select(max_fd
+ 1, &rfds
, NULL
, NULL
, NULL
) <= 0)
167 thread_cancelability(oldstate
);
170 thread_cancelability(oldstate
);
172 if (FD_ISSET(this->ipv4
, &rfds
))
174 port
= CHARON_UDP_PORT
;
175 selected
= this->ipv4
;
177 if (FD_ISSET(this->ipv4_natt
, &rfds
))
179 port
= CHARON_NATT_PORT
;
180 selected
= this->ipv4_natt
;
182 if (FD_ISSET(this->ipv6
, &rfds
))
184 port
= CHARON_UDP_PORT
;
185 selected
= this->ipv6
;
187 if (FD_ISSET(this->ipv6_natt
, &rfds
))
189 port
= CHARON_NATT_PORT
;
190 selected
= this->ipv6_natt
;
195 struct cmsghdr
*cmsgptr
;
199 struct sockaddr_in in4
;
200 struct sockaddr_in6 in6
;
204 msg
.msg_namelen
= sizeof(src
);
205 iov
.iov_base
= buffer
;
206 iov
.iov_len
= this->max_packet
;
209 msg
.msg_control
= ancillary
;
210 msg
.msg_controllen
= sizeof(ancillary
);
212 bytes_read
= recvmsg(selected
, &msg
, 0);
215 DBG1(DBG_NET
, "error reading socket: %s", strerror(errno
));
218 if (msg
.msg_flags
& MSG_TRUNC
)
220 DBG1(DBG_NET
, "receive buffer too small, packet discarded");
223 DBG3(DBG_NET
, "received packet %b", buffer
, bytes_read
);
225 if (bytes_read
< MARKER_LEN
)
227 DBG3(DBG_NET
, "received packet too short (%d bytes)",
232 /* read ancillary data to get destination address */
233 for (cmsgptr
= CMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
234 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
236 if (cmsgptr
->cmsg_len
== 0)
238 DBG1(DBG_NET
, "error reading ancillary data");
242 #ifdef HAVE_IN6_PKTINFO
243 if (cmsgptr
->cmsg_level
== SOL_IPV6
&&
244 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
246 struct in6_pktinfo
*pktinfo
;
247 pktinfo
= (struct in6_pktinfo
*)CMSG_DATA(cmsgptr
);
248 struct sockaddr_in6 dst
;
250 memset(&dst
, 0, sizeof(dst
));
251 memcpy(&dst
.sin6_addr
, &pktinfo
->ipi6_addr
, sizeof(dst
.sin6_addr
));
252 dst
.sin6_family
= AF_INET6
;
253 dst
.sin6_port
= htons(port
);
254 dest
= host_create_from_sockaddr((sockaddr_t
*)&dst
);
256 #endif /* HAVE_IN6_PKTINFO */
257 if (cmsgptr
->cmsg_level
== SOL_IP
&&
259 cmsgptr
->cmsg_type
== IP_PKTINFO
260 #elif defined(IP_RECVDSTADDR)
261 cmsgptr
->cmsg_type
== IP_RECVDSTADDR
267 struct in_addr
*addr
;
268 struct sockaddr_in dst
;
271 struct in_pktinfo
*pktinfo
;
272 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(cmsgptr
);
273 addr
= &pktinfo
->ipi_addr
;
274 #elif defined(IP_RECVDSTADDR)
275 addr
= (struct in_addr
*)CMSG_DATA(cmsgptr
);
277 memset(&dst
, 0, sizeof(dst
));
278 memcpy(&dst
.sin_addr
, addr
, sizeof(dst
.sin_addr
));
280 dst
.sin_family
= AF_INET
;
281 dst
.sin_port
= htons(port
);
282 dest
= host_create_from_sockaddr((sockaddr_t
*)&dst
);
291 DBG1(DBG_NET
, "error reading IP header");
294 source
= host_create_from_sockaddr((sockaddr_t
*)&src
);
296 pkt
= packet_create();
297 pkt
->set_source(pkt
, source
);
298 pkt
->set_destination(pkt
, dest
);
299 DBG2(DBG_NET
, "received packet: from %#H to %#H", source
, dest
);
301 /* remove non esp marker */
302 if (dest
->get_port(dest
) == CHARON_NATT_PORT
)
304 data_offset
+= MARKER_LEN
;
307 data
.len
= bytes_read
- data_offset
;
308 data
.ptr
= malloc(data
.len
);
309 memcpy(data
.ptr
, buffer
+ data_offset
, data
.len
);
310 pkt
->set_data(pkt
, data
);
314 /* oops, shouldn't happen */
322 METHOD(socket_t
, sender
, status_t
,
323 private_socket_default_socket_t
*this, packet_t
*packet
)
325 int sport
, skt
, family
;
327 chunk_t data
, marked
;
330 struct cmsghdr
*cmsg
;
333 src
= packet
->get_source(packet
);
334 dst
= packet
->get_destination(packet
);
335 data
= packet
->get_data(packet
);
337 DBG2(DBG_NET
, "sending packet: from %#H to %#H", src
, dst
);
340 sport
= src
->get_port(src
);
341 family
= dst
->get_family(dst
);
342 if (sport
== CHARON_UDP_PORT
)
344 if (family
== AF_INET
)
353 else if (sport
== CHARON_NATT_PORT
)
355 if (family
== AF_INET
)
357 skt
= this->ipv4_natt
;
361 skt
= this->ipv6_natt
;
363 /* NAT keepalives without marker */
364 if (data
.len
!= 1 || data
.ptr
[0] != 0xFF)
366 /* add non esp marker to packet */
367 marked
= chunk_alloc(data
.len
+ MARKER_LEN
);
368 memset(marked
.ptr
, 0, MARKER_LEN
);
369 memcpy(marked
.ptr
+ MARKER_LEN
, data
.ptr
, data
.len
);
370 /* let the packet do the clean up for us */
371 packet
->set_data(packet
, marked
);
377 DBG1(DBG_NET
, "unable to locate a send socket for port %d", sport
);
381 memset(&msg
, 0, sizeof(struct msghdr
));
382 msg
.msg_name
= dst
->get_sockaddr(dst
);;
383 msg
.msg_namelen
= *dst
->get_sockaddr_len(dst
);
384 iov
.iov_base
= data
.ptr
;
385 iov
.iov_len
= data
.len
;
390 if (!src
->is_anyaddr(src
))
392 if (family
== AF_INET
)
394 #if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR)
395 struct in_addr
*addr
;
396 struct sockaddr_in
*sin
;
398 char buf
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
399 struct in_pktinfo
*pktinfo
;
400 #elif defined(IP_SENDSRCADDR)
401 char buf
[CMSG_SPACE(sizeof(struct in_addr
))];
403 msg
.msg_control
= buf
;
404 msg
.msg_controllen
= sizeof(buf
);
405 cmsg
= CMSG_FIRSTHDR(&msg
);
406 cmsg
->cmsg_level
= SOL_IP
;
408 cmsg
->cmsg_type
= IP_PKTINFO
;
409 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
410 pktinfo
= (struct in_pktinfo
*)CMSG_DATA(cmsg
);
411 memset(pktinfo
, 0, sizeof(struct in_pktinfo
));
412 addr
= &pktinfo
->ipi_spec_dst
;
413 #elif defined(IP_SENDSRCADDR)
414 cmsg
->cmsg_type
= IP_SENDSRCADDR
;
415 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in_addr
));
416 addr
= (struct in_addr
*)CMSG_DATA(cmsg
);
418 sin
= (struct sockaddr_in
*)src
->get_sockaddr(src
);
419 memcpy(addr
, &sin
->sin_addr
, sizeof(struct in_addr
));
420 #endif /* IP_PKTINFO || IP_SENDSRCADDR */
422 #ifdef HAVE_IN6_PKTINFO
425 char buf
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
426 struct in6_pktinfo
*pktinfo
;
427 struct sockaddr_in6
*sin
;
429 msg
.msg_control
= buf
;
430 msg
.msg_controllen
= sizeof(buf
);
431 cmsg
= CMSG_FIRSTHDR(&msg
);
432 cmsg
->cmsg_level
= SOL_IPV6
;
433 cmsg
->cmsg_type
= IPV6_PKTINFO
;
434 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
435 pktinfo
= (struct in6_pktinfo
*)CMSG_DATA(cmsg
);
436 memset(pktinfo
, 0, sizeof(struct in6_pktinfo
));
437 sin
= (struct sockaddr_in6
*)src
->get_sockaddr(src
);
438 memcpy(&pktinfo
->ipi6_addr
, &sin
->sin6_addr
, sizeof(struct in6_addr
));
440 #endif /* HAVE_IN6_PKTINFO */
443 bytes_sent
= sendmsg(skt
, &msg
, 0);
445 if (bytes_sent
!= data
.len
)
447 DBG1(DBG_NET
, "error writing to socket: %s", strerror(errno
));
454 * open a socket to send and receive packets
456 static int open_socket(private_socket_default_socket_t
*this,
457 int family
, u_int16_t port
)
460 struct sockaddr_storage addr
;
462 u_int sol
, pktinfo
= 0;
465 memset(&addr
, 0, sizeof(addr
));
466 addr
.ss_family
= family
;
467 /* precalculate constants depending on address family */
472 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&addr
;
473 htoun32(&sin
->sin_addr
.s_addr
, INADDR_ANY
);
474 htoun16(&sin
->sin_port
, port
);
475 addrlen
= sizeof(struct sockaddr_in
);
478 pktinfo
= IP_PKTINFO
;
479 #elif defined(IP_RECVDSTADDR)
480 pktinfo
= IP_RECVDSTADDR
;
486 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)&addr
;
487 memcpy(&sin6
->sin6_addr
, &in6addr_any
, sizeof(in6addr_any
));
488 htoun16(&sin6
->sin6_port
, port
);
489 addrlen
= sizeof(struct sockaddr_in6
);
491 pktinfo
= IPV6_RECVPKTINFO
;
498 skt
= socket(family
, SOCK_DGRAM
, IPPROTO_UDP
);
501 DBG1(DBG_NET
, "could not open socket: %s", strerror(errno
));
504 if (setsockopt(skt
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&on
, sizeof(on
)) < 0)
506 DBG1(DBG_NET
, "unable to set SO_REUSEADDR on socket: %s", strerror(errno
));
511 /* bind the socket */
512 if (bind(skt
, (struct sockaddr
*)&addr
, addrlen
) < 0)
514 DBG1(DBG_NET
, "unable to bind socket: %s", strerror(errno
));
519 /* get additional packet info on receive */
522 if (setsockopt(skt
, sol
, pktinfo
, &on
, sizeof(on
)) < 0)
524 DBG1(DBG_NET
, "unable to set IP_PKTINFO on socket: %s", strerror(errno
));
530 if (!hydra
->kernel_interface
->bypass_socket(hydra
->kernel_interface
,
533 DBG1(DBG_NET
, "installing IKE bypass policy failed");
538 /* enable UDP decapsulation globally, only for one socket needed */
539 int type
= UDP_ENCAP_ESPINUDP
;
540 if (family
== AF_INET
&& port
== CHARON_NATT_PORT
&&
541 setsockopt(skt
, SOL_UDP
, UDP_ENCAP
, &type
, sizeof(type
)) < 0)
543 DBG1(DBG_NET
, "unable to set UDP_ENCAP: %s", strerror(errno
));
550 METHOD(socket_t
, destroy
, void,
551 private_socket_default_socket_t
*this)
559 close(this->ipv4_natt
);
567 close(this->ipv6_natt
);
573 * See header for description
575 socket_default_socket_t
*socket_default_socket_create()
577 private_socket_default_socket_t
*this;
583 .receive
= _receiver
,
587 .max_packet
= lib
->settings
->get_int(lib
->settings
,
588 "%s.max_packet", MAX_PACKET
, charon
->name
),
593 int natt_port
= CHARON_NATT_PORT
;
594 if (sysctlbyname("net.inet.ipsec.esp_port", NULL
, NULL
, &natt_port
,
595 sizeof(natt_port
)) != 0)
597 DBG1(DBG_NET
, "could not set net.inet.ipsec.esp_port to %d: %s",
598 natt_port
, strerror(errno
));
603 this->ipv4
= open_socket(this, AF_INET
, CHARON_UDP_PORT
);
606 DBG1(DBG_NET
, "could not open IPv4 socket, IPv4 disabled");
610 this->ipv4_natt
= open_socket(this, AF_INET
, CHARON_NATT_PORT
);
611 if (this->ipv4_natt
== 0)
613 DBG1(DBG_NET
, "could not open IPv4 NAT-T socket");
617 this->ipv6
= open_socket(this, AF_INET6
, CHARON_UDP_PORT
);
620 DBG1(DBG_NET
, "could not open IPv6 socket, IPv6 disabled");
624 this->ipv6_natt
= open_socket(this, AF_INET6
, CHARON_NATT_PORT
);
625 if (this->ipv6_natt
== 0)
627 DBG1(DBG_NET
, "could not open IPv6 NAT-T socket");
631 if (!this->ipv4
&& !this->ipv6
)
633 DBG1(DBG_NET
, "could not create any sockets");
637 return &this->public;