e208624b52fcf0c59acb0e813a41350ee8dcf3d6
[strongswan.git] / src / charon / network / socket.c
1 /**
2 * @file socket.c
3 *
4 * @brief Implementation of socket_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
10 * Copyright (C) 2005-2006 Martin Willi
11 * Copyright (C) 2005 Jan Hutter
12 * Hochschule fuer Technik Rapperswil
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 */
24
25 #include <pthread.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <sys/ioctl.h>
34 #include <netinet/in.h>
35 #include <netinet/ip.h>
36 #include <netinet/ip6.h>
37 #include <netinet/udp.h>
38 #include <linux/ipsec.h>
39 #include <linux/filter.h>
40 #include <net/if.h>
41 #include <ifaddrs.h>
42
43 #include "socket.h"
44
45 #include <daemon.h>
46 #include <utils/logger_manager.h>
47
48 /* constants for packet handling */
49 #define IP_LEN sizeof(struct iphdr)
50 #define IP6_LEN sizeof(struct ip6_hdr)
51 #define UDP_LEN sizeof(struct udphdr)
52 #define MARKER_LEN sizeof(u_int32_t)
53
54 /* offsets for packet handling */
55 #define IP_PROTO_OFFSET 9
56 #define IP6_PROTO_OFFSET 6
57 #define IKE_VERSION_OFFSET 17
58 #define IKE_LENGTH_OFFSET 24
59
60 /* from linux/in.h */
61 #ifndef IP_IPSEC_POLICY
62 #define IP_IPSEC_POLICY 16
63 #endif /*IP_IPSEC_POLICY*/
64
65 /* from linux/udp.h */
66 #ifndef UDP_ENCAP
67 #define UDP_ENCAP 100
68 #endif /*UDP_ENCAP*/
69
70 #ifndef UDP_ENCAP_ESPINUDP
71 #define UDP_ENCAP_ESPINUDP 2
72 #endif /*UDP_ENCAP_ESPINUDP*/
73
74 typedef struct private_socket_t private_socket_t;
75
76 /**
77 * Private data of an socket_t object
78 */
79 struct private_socket_t{
80 /**
81 * public functions
82 */
83 socket_t public;
84
85 /**
86 * regular port
87 */
88 int port;
89
90 /**
91 * port used for nat-t
92 */
93 int natt_port;
94
95 /**
96 * raw receiver socket for IPv4
97 */
98 int recv4;
99
100 /**
101 * raw receiver socket for IPv6
102 */
103 int recv6;
104
105 /**
106 * send socket on regular port for IPv4
107 */
108 int send4;
109
110 /**
111 * send socket on regular port for IPv6
112 */
113 int send6;
114
115 /**
116 * send socket on nat-t port for IPv4
117 */
118 int send4_natt;
119
120 /**
121 * send socket on nat-t port for IPv6
122 */
123 int send6_natt;
124
125 /**
126 * logger for this socket
127 */
128 logger_t *logger;
129 };
130
131 /**
132 * implementation of socket_t.receive
133 */
134 static status_t receiver(private_socket_t *this, packet_t **packet)
135 {
136 char buffer[MAX_PACKET];
137 chunk_t data;
138 packet_t *pkt;
139 struct iphdr *ip;
140 struct udphdr *udp;
141 host_t *source = NULL, *dest = NULL;
142 int bytes_read = 0;
143 int data_offset, oldstate;
144 fd_set rfds;
145
146 FD_ZERO(&rfds);
147 FD_SET(this->recv4, &rfds);
148 FD_SET(this->recv6, &rfds);
149
150 this->logger->log(this->logger, CONTROL|LEVEL1,
151 "waiting for data on raw sockets");
152
153 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
154 if (select(max(this->recv4, this->recv6) + 1, &rfds, NULL, NULL, NULL) <= 0)
155 {
156 pthread_setcancelstate(oldstate, NULL);
157 return FAILED;
158 }
159 pthread_setcancelstate(oldstate, NULL);
160
161 if (FD_ISSET(this->recv4, &rfds))
162 {
163 /* IPv4 raw sockets return the IP header. We read src/dest
164 * information directly from the raw header */
165 struct sockaddr_in src, dst;
166 bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0);
167 if (bytes_read < 0)
168 {
169 this->logger->log(this->logger, ERROR,
170 "error reading from IPv4 socket: %s",
171 strerror(errno));
172 return FAILED;
173 }
174 this->logger->log_bytes(this->logger, RAW,
175 "received IPv4 packet", buffer, bytes_read);
176
177 /* read source/dest from raw IP/UDP header */
178 if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
179 {
180 this->logger->log(this->logger, ERROR,
181 "received IPv4 packet too short");
182 return FAILED;
183 }
184 ip = (struct iphdr*) buffer;
185 udp = (struct udphdr*) (buffer + IP_LEN);
186 src.sin_family = AF_INET;
187 src.sin_addr.s_addr = ip->saddr;
188 src.sin_port = udp->source;
189 dst.sin_family = AF_INET;
190 dst.sin_addr.s_addr = ip->daddr;
191 dst.sin_port = udp->dest;
192 source = host_create_from_sockaddr((sockaddr_t*)&src);
193 dest = host_create_from_sockaddr((sockaddr_t*)&dst);
194
195 pkt = packet_create();
196 pkt->set_source(pkt, source);
197 pkt->set_destination(pkt, dest);
198 this->logger->log(this->logger, CONTROL|LEVEL1,
199 "received packet: from %s[%d] to %s[%d]",
200 source->get_string(source), source->get_port(source),
201 dest->get_string(dest), dest->get_port(dest));
202 data_offset = IP_LEN + UDP_LEN;
203 /* remove non esp marker */
204 if (dest->get_port(dest) == this->natt_port)
205 {
206 data_offset += MARKER_LEN;
207 }
208 /* fill in packet */
209 data.len = bytes_read - data_offset;
210 data.ptr = malloc(data.len);
211 memcpy(data.ptr, buffer + data_offset, data.len);
212 pkt->set_data(pkt, data);
213 }
214 else if (FD_ISSET(this->recv6, &rfds))
215 {
216 /* IPv6 raw sockets return the no IP header. We must query
217 * src/dest via socket options/ancillary data */
218 struct msghdr msg;
219 struct cmsghdr *cmsgptr;
220 struct sockaddr_in6 src, dst;
221 struct iovec iov;
222 char ancillary[64];
223
224 msg.msg_name = &src;
225 msg.msg_namelen = sizeof(src);
226 iov.iov_base = buffer;
227 iov.iov_len = sizeof(buffer);
228 msg.msg_iov = &iov;
229 msg.msg_iovlen = 1;
230 msg.msg_control = ancillary;
231 msg.msg_controllen = sizeof(ancillary);
232 msg.msg_flags = 0;
233
234 bytes_read = recvmsg(this->recv6, &msg, 0);
235 if (bytes_read < 0)
236 {
237 this->logger->log(this->logger, ERROR,
238 "error reading from IPv6 socket: %s",
239 strerror(errno));
240 return FAILED;
241 }
242 this->logger->log_bytes(this->logger, RAW,
243 "received IPv6 packet", buffer, bytes_read);
244
245 if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
246 {
247 this->logger->log(this->logger, ERROR,
248 "received IPv6 packet too short");
249 return FAILED;
250 }
251
252 /* read ancillary data to get destination address */
253 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
254 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
255 {
256 if (cmsgptr->cmsg_len == 0)
257 {
258 this->logger->log(this->logger, ERROR,
259 "error reading IPv6 ancillary data: %s",
260 strerror(errno));
261 return FAILED;
262 }
263 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
264 cmsgptr->cmsg_type == IPV6_PKTINFO)
265 {
266 struct in6_pktinfo *pktinfo;
267 pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
268
269 memset(&dst, 0, sizeof(dst));
270 memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
271 dst.sin6_family = AF_INET6;
272 udp = (struct udphdr*) (buffer);
273 dst.sin6_port = udp->dest;
274 src.sin6_port = udp->source;
275 dest = host_create_from_sockaddr((sockaddr_t*)&dst);
276 }
277 }
278 /* ancillary data missing? */
279 if (dest == NULL)
280 {
281 this->logger->log(this->logger, ERROR,
282 "error reading IPv6 packet header");
283 return FAILED;
284 }
285
286 source = host_create_from_sockaddr((sockaddr_t*)&src);
287
288 pkt = packet_create();
289 pkt->set_source(pkt, source);
290 pkt->set_destination(pkt, dest);
291 this->logger->log(this->logger, CONTROL|LEVEL1,
292 "received packet: from %s[%d] to %s[%d]",
293 source->get_string(source), source->get_port(source),
294 dest->get_string(dest), dest->get_port(dest));
295 data_offset = UDP_LEN;
296 /* remove non esp marker */
297 if (dest->get_port(dest) == this->natt_port)
298 {
299 data_offset += MARKER_LEN;
300 }
301 /* fill in packet */
302 data.len = bytes_read - data_offset;
303 data.ptr = malloc(data.len);
304 memcpy(data.ptr, buffer + data_offset, data.len);
305 pkt->set_data(pkt, data);
306 }
307 else
308 {
309 /* oops, shouldn't happen */
310 return FAILED;
311 }
312
313 /* return packet */
314 *packet = pkt;
315 return SUCCESS;
316 }
317
318 /**
319 * implementation of socket_t.send
320 */
321 status_t sender(private_socket_t *this, packet_t *packet)
322 {
323 int sport, skt, family;
324 ssize_t bytes_sent;
325 chunk_t data, marked;
326 host_t *src, *dst;
327
328 src = packet->get_source(packet);
329 dst = packet->get_destination(packet);
330 data = packet->get_data(packet);
331
332 this->logger->log(this->logger, CONTROL|LEVEL1, "sending packet: from %s[%d] to %s[%d]",
333 src->get_string(src), src->get_port(src),
334 dst->get_string(dst), dst->get_port(dst));
335
336 /* send data */
337 sport = src->get_port(src);
338 family = dst->get_family(dst);
339 if (sport == this->port)
340 {
341 if (family == AF_INET)
342 {
343 skt = this->send4;
344 }
345 else
346 {
347 skt = this->send6;
348 }
349 }
350 else if (sport == this->natt_port)
351 {
352 if (family == AF_INET)
353 {
354 skt = this->send4_natt;
355 }
356 else
357 {
358 skt = this->send6_natt;
359 }
360 /* NAT keepalives without marker */
361 if (data.len != 1 || data.ptr[0] != 0xFF)
362 {
363 /* add non esp marker to packet */
364 if (data.len > MAX_PACKET - MARKER_LEN)
365 {
366 this->logger->log(this->logger, ERROR,
367 "unable to send packet: it's too big");
368 return FAILED;
369 }
370 marked = chunk_alloc(data.len + MARKER_LEN);
371 memset(marked.ptr, 0, MARKER_LEN);
372 memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
373 /* let the packet do the clean up for us */
374 packet->set_data(packet, marked);
375 data = marked;
376 }
377 }
378 else
379 {
380 this->logger->log(this->logger, ERROR,
381 "unable to locate a send socket for port %d", sport);
382 return FAILED;
383 }
384
385 bytes_sent = sendto(skt, data.ptr, data.len, 0,
386 dst->get_sockaddr(dst), *(dst->get_sockaddr_len(dst)));
387
388 if (bytes_sent != data.len)
389 {
390 this->logger->log(this->logger, ERROR,
391 "error writing to socket: %s", strerror(errno));
392 return FAILED;
393 }
394 return SUCCESS;
395 }
396
397 /**
398 * implements socket_t.is_local_address
399 */
400 static bool is_local_address(private_socket_t *this, host_t *host)
401 {
402 struct ifaddrs *list;
403 struct ifaddrs *cur;
404 bool found = FALSE;
405
406 if (getifaddrs(&list) < 0)
407 {
408 return FALSE;
409 }
410
411 for (cur = list; cur != NULL; cur = cur->ifa_next)
412 {
413 if (!(cur->ifa_flags & IFF_UP))
414 {
415 /* ignore interface which are down */
416 continue;
417 }
418
419 if (cur->ifa_addr == NULL ||
420 cur->ifa_addr->sa_family != host->get_family(host))
421 {
422 /* no match in family */
423 continue;
424 }
425
426 switch (cur->ifa_addr->sa_family)
427 {
428 case AF_INET:
429 {
430 struct sockaddr_in *listed, *requested;
431 listed = (struct sockaddr_in*)cur->ifa_addr;
432 requested = (struct sockaddr_in*)host->get_sockaddr(host);
433 if (listed->sin_addr.s_addr == requested->sin_addr.s_addr)
434 {
435 found = TRUE;
436 }
437 break;
438 }
439 case AF_INET6:
440 {
441 struct sockaddr_in6 *listed, *requested;
442 listed = (struct sockaddr_in6*)cur->ifa_addr;
443 requested = (struct sockaddr_in6*)host->get_sockaddr(host);
444 if (memcmp(&listed->sin6_addr, &requested->sin6_addr,
445 sizeof(listed->sin6_addr)) == 0)
446 {
447 found = TRUE;
448 }
449 break;
450 }
451 default:
452 break;
453 }
454
455 if (found)
456 {
457 break;
458 }
459 }
460 freeifaddrs(list);
461 return found;
462 }
463
464
465 /**
466 * implements socket_t.create_local_address_list
467 */
468 static linked_list_t* create_local_address_list(private_socket_t *this)
469 {
470 struct ifaddrs *list;
471 struct ifaddrs *cur;
472 host_t *host;
473 linked_list_t *result = linked_list_create();
474
475 if (getifaddrs(&list) < 0)
476 {
477 return result;
478 }
479
480 for (cur = list; cur != NULL; cur = cur->ifa_next)
481 {
482 if (!(cur->ifa_flags & IFF_UP))
483 {
484 /* ignore interface which are down */
485 continue;
486 }
487
488 host = host_create_from_sockaddr(cur->ifa_addr);
489 if (host)
490 {
491 /* we use always the IKEv2 port. This is relevant for
492 * natd payload hashing. */
493 host->set_port(host, this->port);
494 result->insert_last(result, host);
495 }
496 }
497 freeifaddrs(list);
498 return result;
499 }
500
501 /**
502 * open a socket to send packets
503 */
504 static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
505 {
506 int on = TRUE;
507 int type = UDP_ENCAP_ESPINUDP;
508 struct sockaddr_storage addr;
509 u_int ip_proto, ipsec_policy;
510 struct sadb_x_policy policy;
511 int skt;
512
513 memset(&addr, 0, sizeof(addr));
514 /* precalculate constants depending on address family */
515 switch (family)
516 {
517 case AF_INET:
518 {
519 struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
520 sin->sin_family = AF_INET;
521 sin->sin_addr.s_addr = INADDR_ANY;
522 sin->sin_port = htons(port);
523 ip_proto = IPPROTO_IP;
524 ipsec_policy = IP_IPSEC_POLICY;
525 break;
526 }
527 case AF_INET6:
528 {
529 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
530 sin6->sin6_family = AF_INET6;
531 memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
532 sin6->sin6_port = htons(port);
533 ip_proto = IPPROTO_IPV6;
534 ipsec_policy = IPV6_IPSEC_POLICY;
535 break;
536 }
537 default:
538 return 0;
539 }
540
541 skt = socket(family, SOCK_DGRAM, IPPROTO_UDP);
542 if (skt < 0)
543 {
544 this->logger->log(this->logger, ERROR, "could not open send socket: %s",
545 strerror(errno));
546 return 0;
547 }
548
549 if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
550 {
551 this->logger->log(this->logger, ERROR,
552 "unable to set SO_REUSEADDR on send socket: %s",
553 strerror(errno));
554 close(skt);
555 return 0;
556 }
557
558 /* bypass outgoung IKE traffic on send socket */
559 policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
560 policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
561 policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
562 policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
563 policy.sadb_x_policy_reserved = 0;
564 policy.sadb_x_policy_id = 0;
565
566 if (setsockopt(skt, ip_proto, ipsec_policy, &policy, sizeof(policy)) < 0)
567 {
568 this->logger->log(this->logger, ERROR,
569 "unable to set IPSEC_POLICY on send socket: %s",
570 strerror(errno));
571 close(skt);
572 return 0;
573 }
574
575 /* We don't receive packets on the send socket, but we need a INBOUND policy.
576 * Otherwise, UDP decapsulation does not work!!! */
577 policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
578 if (setsockopt(skt, ip_proto, ipsec_policy, &policy, sizeof(policy)) < 0)
579 {
580 this->logger->log(this->logger, ERROR,
581 "unable to set IPSEC_POLICY on send socket: %s",
582 strerror(errno));
583 close(skt);
584 return 0;
585 }
586
587 /* bind the send socket */
588 if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
589 {
590 this->logger->log(this->logger, ERROR, "unable to bind send socket: %s",
591 strerror(errno));
592 close(skt);
593 return 0;
594 }
595
596 /* enable UDP decapsulation globally */
597 if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
598 {
599 this->logger->log(this->logger, ERROR,
600 "unable to set UDP_ENCAP: %s; NAT-T may fail",
601 strerror(errno));
602 }
603
604 return skt;
605 }
606
607 /**
608 * open a socket to receive packets
609 */
610 static int open_recv_socket(private_socket_t *this, int family)
611 {
612 int skt;
613 int on = TRUE;
614 u_int proto_offset, ip_len, ip_proto, ipsec_policy, ip_pktinfo, udp_header, ike_header;
615 struct sadb_x_policy policy;
616
617 /* precalculate constants depending on address family */
618 switch (family)
619 {
620 case AF_INET:
621 proto_offset = IP_PROTO_OFFSET;
622 ip_len = IP_LEN;
623 ip_proto = IPPROTO_IP;
624 ip_pktinfo = IP_PKTINFO;
625 ipsec_policy = IP_IPSEC_POLICY;
626 break;
627 case AF_INET6:
628 proto_offset = IP6_PROTO_OFFSET;
629 ip_len = IP6_LEN;
630 ip_proto = IPPROTO_IPV6;
631 ip_pktinfo = IPV6_PKTINFO;
632 ipsec_policy = IPV6_IPSEC_POLICY;
633 break;
634 default:
635 return 0;
636 }
637 udp_header = ip_len;
638 ike_header = ip_len + UDP_LEN;
639
640 /* This filter code filters out all non-IKEv2 traffic on
641 * a SOCK_RAW IP_PROTP_UDP socket. Handling of other
642 * IKE versions is done in pluto.
643 */
644 struct sock_filter ikev2_filter_code[] =
645 {
646 /* Protocol must be UDP */
647 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, proto_offset),
648 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_UDP, 0, 15),
649 /* Destination Port must be either port or natt_port */
650 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, udp_header + 2),
651 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, this->port, 1, 0),
652 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, this->natt_port, 5, 12),
653 /* port */
654 /* IKE version must be 2.0 */
655 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + IKE_VERSION_OFFSET),
656 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 10),
657 /* packet length is length in IKEv2 header + ip header + udp header */
658 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header + IKE_LENGTH_OFFSET),
659 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, ip_len + UDP_LEN),
660 BPF_STMT(BPF_RET+BPF_A, 0),
661 /* natt_port */
662 /* nat-t: check for marker */
663 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header),
664 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 5),
665 /* nat-t: IKE version must be 2.0 */
666 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + MARKER_LEN + IKE_VERSION_OFFSET),
667 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 3),
668 /* nat-t: packet length is length in IKEv2 header + ip header + udp header + non esp marker */
669 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header + MARKER_LEN + IKE_LENGTH_OFFSET),
670 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, ip_len + UDP_LEN + MARKER_LEN),
671 BPF_STMT(BPF_RET+BPF_A, 0),
672 /* packet doesn't match, ignore */
673 BPF_STMT(BPF_RET+BPF_K, 0),
674 };
675
676 /* Filter struct to use with setsockopt */
677 struct sock_fprog ikev2_filter = {
678 sizeof(ikev2_filter_code) / sizeof(struct sock_filter),
679 ikev2_filter_code
680 };
681
682 /* set up a raw socket */
683 skt = socket(family, SOCK_RAW, IPPROTO_UDP);
684 if (skt < 0)
685 {
686 this->logger->log(this->logger, ERROR,
687 "unable to create raw socket: %s",
688 strerror(errno));
689 return 0;
690 }
691
692 if (family == AF_INET)
693 {
694 if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER,
695 &ikev2_filter, sizeof(ikev2_filter)) < 0)
696 {
697 this->logger->log(this->logger, ERROR,
698 "unable to attach IKEv2 filter to raw socket: %s",
699 strerror(errno));
700 close(skt);
701 return 0;
702 }
703 }
704
705 else if (setsockopt(skt, ip_proto, ip_pktinfo, &on, sizeof(on)) < 0)
706 {
707 this->logger->log(this->logger, ERROR,
708 "unable to set IPV6_PKTINFO on raw socket: %s",
709 strerror(errno));
710 close(skt);
711 return 0;
712 }
713
714 /* bypass incomining IKE traffic on this socket */
715 policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
716 policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
717 policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
718 policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
719 policy.sadb_x_policy_reserved = 0;
720 policy.sadb_x_policy_id = 0;
721
722 if (setsockopt(skt, ip_proto, ipsec_policy, &policy, sizeof(policy)) < 0)
723 {
724 this->logger->log(this->logger, ERROR,
725 "unable to set IPSEC_POLICY on raw socket: %s",
726 strerror(errno));
727 close(skt);
728 return 0;
729 }
730
731 return skt;
732 }
733
734 /**
735 * implementation of socket_t.destroy
736 */
737 static void destroy(private_socket_t *this)
738 {
739 if (this->recv4)
740 {
741 close(this->recv4);
742 }
743 if (this->recv6)
744 {
745 close(this->recv6);
746 }
747 if (this->send4)
748 {
749 close(this->send4);
750 }
751 if (this->send6)
752 {
753 close(this->send6);
754 }
755 if (this->send4_natt)
756 {
757 close(this->send4_natt);
758 }
759 if (this->send6_natt)
760 {
761 close(this->send6_natt);
762 }
763 free(this);
764 }
765
766 /*
767 * See header for description
768 */
769 socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
770 {
771 private_socket_t *this = malloc_thing(private_socket_t);
772
773 /* public functions */
774 this->public.send = (status_t(*)(socket_t*, packet_t*))sender;
775 this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
776 this->public.is_local_address = (bool(*)(socket_t*, host_t*))is_local_address;
777 this->public.create_local_address_list = (linked_list_t*(*)(socket_t*))create_local_address_list;
778 this->public.destroy = (void(*)(socket_t*)) destroy;
779
780 this->logger = logger_manager->get_logger(logger_manager, SOCKET);
781
782 this->port = port;
783 this->natt_port = natt_port;
784 this->recv4 = 0;
785 this->recv6 = 0;
786 this->send4 = 0;
787 this->send6 = 0;
788 this->send4_natt = 0;
789 this->send6_natt = 0;
790
791 this->recv4 = open_recv_socket(this, AF_INET);
792 if (this->recv4 == 0)
793 {
794 this->logger->log(this->logger, ERROR,
795 "could not open IPv4 receive socket, IPv4 disabled");
796 }
797 else
798 {
799 this->send4 = open_send_socket(this, AF_INET, this->port);
800 if (this->send4 == 0)
801 {
802 this->logger->log(this->logger, ERROR,
803 "could not open IPv4 send socket, IPv4 disabled");
804 close(this->recv4);
805 }
806 else
807 {
808 this->send4_natt = open_send_socket(this, AF_INET, this->natt_port);
809 if (this->send4_natt == 0)
810 {
811 this->logger->log(this->logger, ERROR,
812 "could not open IPv4 NAT-T send socket");
813 }
814 }
815 }
816
817 this->recv6 = open_recv_socket(this, AF_INET6);
818 if (this->recv6 == 0)
819 {
820 this->logger->log(this->logger, ERROR,
821 "could not open IPv6 receive socket, IPv6 disabled");
822 }
823 else
824 {
825 this->send6 = open_send_socket(this, AF_INET6, this->port);
826 if (this->send4 == 0)
827 {
828 this->logger->log(this->logger, ERROR,
829 "could not open IPv6 send socket, IPv6 disabled");
830 close(this->recv6);
831 }
832 else
833 {
834 this->send6_natt = open_send_socket(this, AF_INET, this->natt_port);
835 if (this->send6_natt == 0)
836 {
837 this->logger->log(this->logger, ERROR,
838 "could not open IPv6 NAT-T send socket");
839 }
840 }
841 }
842
843 if (!(this->send4 || this->send6))
844 {
845 this->logger->log(this->logger, ERROR,
846 "could not create any sockets");
847 destroy(this);
848 charon->kill(charon, "socket initialization failed");
849 }
850
851 return (socket_t*)this;
852 }