4 * @brief Implementation of socket_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 * Copyright (C) 1998-2002 D. Hugh Redelmeier.
12 * Copyright (C) 1997 Angelos D. Keromytis.
14 * Some parts of interface lookup code from pluto.
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 #include <sys/types.h>
29 #include <sys/socket.h>
36 #include <sys/ioctl.h>
37 #include <netinet/in.h>
38 #include <linux/filter.h>
43 #include <utils/logger_manager.h>
46 #define IP_HEADER_LENGTH 20
47 #define UDP_HEADER_LENGTH 8
51 * This filter code filters out all non-IKEv2 traffic on
52 * a SOCK_RAW IP_PROTP_UDP socket. Handling of other
53 * IKE versions is done in pluto.
55 struct sock_filter ikev2_filter_code
[] =
57 /* Protocol must be UDP */
58 BPF_STMT(BPF_LD
+BPF_B
+BPF_ABS
, 9),
59 BPF_JUMP(BPF_JMP
+BPF_JEQ
+BPF_K
, IPPROTO_UDP
, 0, 7),
60 /* Destination Port must be 500 */
61 BPF_STMT(BPF_LD
+BPF_H
+BPF_ABS
, 22),
62 BPF_JUMP(BPF_JMP
+BPF_JEQ
+BPF_K
, 500, 0, 5),
63 /* IKE version must be 2.0 */
64 BPF_STMT(BPF_LD
+BPF_B
+BPF_ABS
, 45),
65 BPF_JUMP(BPF_JMP
+BPF_JEQ
+BPF_K
, 0x20, 0, 3),
66 /* packet length is length in IKEv2 header + ip header + udp header */
67 BPF_STMT(BPF_LD
+BPF_W
+BPF_ABS
, 52),
68 BPF_STMT(BPF_ALU
+BPF_ADD
+BPF_K
, IP_HEADER_LENGTH
+ UDP_HEADER_LENGTH
),
69 BPF_STMT(BPF_RET
+BPF_A
, 0),
70 /* packet doesn't match IKEv2, ignore */
71 BPF_STMT(BPF_RET
+BPF_K
, 0),
75 * Filter struct to use with setsockopt
77 struct sock_fprog ikev2_filter
= {
78 sizeof(ikev2_filter_code
) / sizeof(struct sock_filter
),
83 typedef struct interface_t interface_t
;
86 * An interface on which we listen.
91 * Name of the interface
101 * Host with listening address
106 typedef struct private_socket_t private_socket_t
;
109 * Private data of an socket_t object
111 struct private_socket_t
{
123 * List of all socket to listen
125 linked_list_t
* interfaces
;
128 * logger for this socket
134 * implementation of socket_t.receive
136 static status_t
receiver(private_socket_t
*this, packet_t
**packet
)
138 char buffer
[MAX_PACKET
];
140 packet_t
*pkt
= packet_create();
141 host_t
*source
, *dest
;
145 while (bytes_read
>= 0)
149 iterator_t
*iterator
;
151 interface_t
*interface
;
155 iterator
= this->interfaces
->create_iterator(this->interfaces
, TRUE
);
156 while (iterator
->has_next(iterator
))
158 iterator
->current(iterator
, (void**)&interface
);
159 FD_SET(interface
->socket_fd
, &readfds
);
160 if (interface
->socket_fd
> max_fd
)
162 max_fd
= interface
->socket_fd
+ 1;
165 iterator
->destroy(iterator
);
167 /* add packet destroy handler for cancellation, enable cancellation */
168 pthread_cleanup_push((void(*)(void*))pkt
->destroy
, (void*)pkt
);
169 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, &oldstate
);
171 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "waiting on sockets");
172 bytes_read
= select(max_fd
, &readfds
, NULL
, NULL
, NULL
);
174 /* reset cancellation, remove packet destroy handler (without executing) */
175 pthread_setcancelstate(oldstate
, NULL
);
176 pthread_cleanup_pop(0);
178 /* read on the first nonblocking socket */
180 iterator
= this->interfaces
->create_iterator(this->interfaces
, TRUE
);
181 while (iterator
->has_next(iterator
))
183 iterator
->current(iterator
, (void**)&interface
);
184 if (FD_ISSET(interface
->socket_fd
, &readfds
))
187 bytes_read
= recv(interface
->socket_fd
, buffer
, MAX_PACKET
, 0);
191 iterator
->destroy(iterator
);
195 this->logger
->log(this->logger
, ERROR
, "error reading from socket: %s", strerror(errno
));
198 if (bytes_read
> IP_HEADER_LENGTH
+ UDP_HEADER_LENGTH
)
200 /* read source/dest from raw IP/UDP header */
201 chunk_t source_chunk
= {buffer
+ 12, 4};
202 chunk_t dest_chunk
= {buffer
+ 16, 4};
203 u_int16_t source_port
= ntohs(*(u_int16_t
*)(buffer
+ 20));
204 u_int16_t dest_port
= ntohs(*(u_int16_t
*)(buffer
+ 22));
205 source
= host_create_from_chunk(AF_INET
, source_chunk
, source_port
);
206 dest
= host_create_from_chunk(AF_INET
, dest_chunk
, dest_port
);
207 pkt
->set_source(pkt
, source
);
208 pkt
->set_destination(pkt
, dest
);
211 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "too short packet received");
214 this->logger
->log(this->logger
, CONTROL
, "received packet: from %s:%d to %s:%d",
215 source
->get_address(source
), source
->get_port(source
),
216 dest
->get_address(dest
), dest
->get_port(dest
));
219 data
.len
= bytes_read
- IP_HEADER_LENGTH
- UDP_HEADER_LENGTH
;
220 data
.ptr
= malloc(data
.len
);
221 memcpy(data
.ptr
, buffer
+ IP_HEADER_LENGTH
+ UDP_HEADER_LENGTH
, data
.len
);
222 pkt
->set_data(pkt
, data
);
231 * implementation of socket_t.send
233 status_t
sender(private_socket_t
*this, packet_t
*packet
)
239 src
= packet
->get_source(packet
);
240 dst
= packet
->get_destination(packet
);
241 data
= packet
->get_data(packet
);
243 this->logger
->log(this->logger
, CONTROL
, "sending packet: from %s:%d to %s:%d",
244 src
->get_address(src
), src
->get_port(src
),
245 dst
->get_address(dst
), dst
->get_port(dst
));
248 /* TODO: should we send via the interface we received the packet? */
249 bytes_sent
= sendto(this->master_fd
, data
.ptr
, data
.len
, 0,
250 dst
->get_sockaddr(dst
), *(dst
->get_sockaddr_len(dst
)));
252 if (bytes_sent
!= data
.len
)
254 this->logger
->log(this->logger
, ERROR
, "error writing to socket: %s", strerror(errno
));
261 * Find all suitable interfaces, bind them and add them to the list
263 static status_t
build_interface_list(private_socket_t
*this, u_int16_t port
)
267 struct sockaddr_in addr
;
268 struct ifconf ifconf
;
269 struct ifreq buf
[300];
271 /* master socket for querying socket for a specific interfaces */
272 this->master_fd
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
273 if (this->master_fd
== -1)
275 this->logger
->log(this->logger
, ERROR
, "could not open IPv4 master socket!");
279 /* allow binding of multiplo sockets */
280 if (setsockopt(this->master_fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&on
, sizeof(on
)) < 0)
282 this->logger
->log(this->logger
, ERROR
, "unable to set SO_REUSEADDR on master socket!");
286 /* bind the master socket */
287 addr
.sin_family
= AF_INET
;
288 addr
.sin_addr
.s_addr
= INADDR_ANY
;
289 addr
.sin_port
= htons(port
);
290 if (bind(this->master_fd
,(struct sockaddr
*)&addr
, sizeof(addr
)) < 0)
292 this->logger
->log(this->logger
, ERROR
, "unable to bind master socket: %s!", strerror(errno
));
296 /* get all interfaces */
297 ifconf
.ifc_len
= sizeof(buf
);
298 ifconf
.ifc_buf
= (void*) buf
;
299 memset(buf
, 0, sizeof(buf
));
300 if (ioctl(this->master_fd
, SIOCGIFCONF
, &ifconf
) == -1)
302 this->logger
->log(this->logger
, ERROR
, "unable to get interfaces!");
306 /* add every interesting interfaces to our interface list */
307 for (i
= 0; (i
+1) * sizeof(*buf
) <= (size_t)ifconf
.ifc_len
; i
++)
309 struct sockaddr_in
*current
= (struct sockaddr_in
*) &buf
[i
].ifr_addr
;
310 struct ifreq auxinfo
;
312 interface_t
*interface
;
314 if (current
->sin_family
!= AF_INET
)
316 /* ignore all but AF_INET interfaces */
320 /* get auxilary info about socket */
321 memset(&auxinfo
, 0, sizeof(auxinfo
));
322 memcpy(auxinfo
.ifr_name
, buf
[i
].ifr_name
, IFNAMSIZ
);
323 if (ioctl(this->master_fd
, SIOCGIFFLAGS
, &auxinfo
) == -1)
325 this->logger
->log(this->logger
, ERROR
, "unable to SIOCGIFFLAGS master socket!");
328 if (!(auxinfo
.ifr_flags
& IFF_UP
))
330 /* ignore an interface that isn't up */
333 if (current
->sin_addr
.s_addr
== 0)
335 /* ignore unconfigured interfaces */
339 /* set up interface socket */
340 skt
= socket(AF_INET
, SOCK_RAW
, IPPROTO_UDP
);
343 this->logger
->log(this->logger
, ERROR
, "unable to open interface socket!");
346 if (setsockopt(skt
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&on
, sizeof(on
)) < 0)
348 this->logger
->log(this->logger
, ERROR
, "unable to set SO_REUSEADDR on interface socket!");
352 current
->sin_port
= htons(port
);
353 current
->sin_family
= AF_INET
;
354 if (bind(skt
, (struct sockaddr
*)current
, sizeof(struct sockaddr_in
)) < 0)
356 this->logger
->log(this->logger
, ERROR
, "unable to bind interface socket!");
361 if (setsockopt(skt
, SOL_SOCKET
, SO_ATTACH_FILTER
, &ikev2_filter
, sizeof(ikev2_filter
)) < 0)
363 this->logger
->log(this->logger
, ERROR
, "unable to attack IKEv2 filter to interface socket!");
368 /* add socket with interface name to list */
369 interface
= malloc_thing(interface_t
);
370 strncpy(interface
->name
, buf
[i
].ifr_name
, IFNAMSIZ
);
371 interface
->socket_fd
= skt
;
372 interface
->address
= host_create_from_sockaddr((struct sockaddr
*)current
);
373 this->logger
->log(this->logger
, CONTROL
, "listening on %s (%s)",
374 interface
->name
, interface
->address
->get_address(interface
->address
));
375 this->interfaces
->insert_last(this->interfaces
, (void*)interface
);
378 if (this->interfaces
->get_count(this->interfaces
) == 0)
380 this->logger
->log(this->logger
, ERROR
, "unable to find any usable interface!");
387 * implementation of socket_t.is_listening_on
389 static bool is_listening_on(private_socket_t
*this, host_t
*host
)
391 iterator_t
*iterator
;
393 /* listening on 0.0.0.0 is always TRUE */
394 if (host
->is_default_route(host
))
399 /* compare host with all interfaces */
400 iterator
= this->interfaces
->create_iterator(this->interfaces
, TRUE
);
401 while (iterator
->has_next(iterator
))
403 interface_t
*interface
;
404 iterator
->current(iterator
, (void**)&interface
);
405 if (host
->equals(host
, interface
->address
))
407 iterator
->destroy(iterator
);
411 iterator
->destroy(iterator
);
416 * implementation of socket_t.destroy
418 static void destroy(private_socket_t
*this)
420 interface_t
*interface
;
421 while (this->interfaces
->remove_last(this->interfaces
, (void**)&interface
) == SUCCESS
)
423 interface
->address
->destroy(interface
->address
);
424 close(interface
->socket_fd
);
427 this->interfaces
->destroy(this->interfaces
);
428 close(this->master_fd
);
433 * See header for description
435 socket_t
*socket_create(u_int16_t port
)
437 private_socket_t
*this = malloc_thing(private_socket_t
);
439 /* public functions */
440 this->public.send
= (status_t(*)(socket_t
*, packet_t
*))sender
;
441 this->public.receive
= (status_t(*)(socket_t
*, packet_t
**))receiver
;
442 this->public.is_listening_on
= (bool (*)(socket_t
*,host_t
*))is_listening_on
;
443 this->public.destroy
= (void(*)(socket_t
*)) destroy
;
445 this->logger
= logger_manager
->get_logger(logger_manager
, SOCKET
);
446 this->interfaces
= linked_list_create();
448 if (build_interface_list(this, port
) != SUCCESS
)
450 this->interfaces
->destroy(this->interfaces
);
452 charon
->kill(charon
, "could not bind any interface!");
455 return (socket_t
*)this;