- configuration_manager replaced by configuration_t interface
[strongswan.git] / Source / charon / network / socket.c
1 /**
2 * @file socket.c
3 *
4 * @brief Implementation of socket_t.
5 *
6 */
7
8 /*
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.
13 *
14 * Some parts of interface lookup code from pluto.
15 *
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>.
20 *
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
24 * for more details.
25 */
26
27 #include <pthread.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <fcntl.h>
35 #include <net/if.h>
36 #include <sys/ioctl.h>
37 #include <netinet/in.h>
38 #include <linux/filter.h>
39
40 #include "socket.h"
41
42 #include <daemon.h>
43 #include <utils/allocator.h>
44 #include <utils/logger_manager.h>
45
46
47 #define IP_HEADER_LENGTH 20
48 #define UDP_HEADER_LENGTH 8
49
50
51 /**
52 * This filter code filters out all non-IKEv2 traffic on
53 * a SOCK_RAW IP_PROTP_UDP socket. Handling of other
54 * IKE versions is done in pluto.
55 */
56 struct sock_filter ikev2_filter_code[] =
57 {
58 /* Protocol must be UDP */
59 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9),
60 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_UDP, 0, 7),
61 /* Destination Port must be 500 */
62 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 22),
63 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 500, 0, 5),
64 /* IKE version must be 2.0 */
65 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 45),
66 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 3),
67 /* packet length is length in IKEv2 header + ip header + udp header */
68 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 52),
69 BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, IP_HEADER_LENGTH + UDP_HEADER_LENGTH),
70 BPF_STMT(BPF_RET+BPF_A, 0),
71 /* packet doesn't match IKEv2, ignore */
72 BPF_STMT(BPF_RET+BPF_K, 0),
73 };
74
75 /**
76 * Filter struct to use with setsockopt
77 */
78 struct sock_fprog ikev2_filter = {
79 sizeof(ikev2_filter_code) / sizeof(struct sock_filter),
80 ikev2_filter_code
81 };
82
83
84 typedef struct interface_t interface_t;
85
86 /**
87 * An interface on which we listen.
88 */
89 struct interface_t {
90
91 /**
92 * Name of the interface
93 */
94 char name[IFNAMSIZ];
95
96 /**
97 * Associated socket
98 */
99 int socket_fd;
100 };
101
102 typedef struct private_socket_t private_socket_t;
103
104 /**
105 * Private data of an socket_t object
106 */
107 struct private_socket_t{
108 /**
109 * public functions
110 */
111 socket_t public;
112
113 /**
114 * Master socket
115 */
116 int master_fd;
117
118 /**
119 * List of all socket to listen
120 */
121 linked_list_t* interfaces;
122
123 /**
124 * logger for this socket
125 */
126 logger_t *logger;
127 };
128
129 /**
130 * implementation of socket_t.receive
131 */
132 status_t receiver(private_socket_t *this, packet_t **packet)
133 {
134 char buffer[MAX_PACKET];
135 chunk_t data;
136 packet_t *pkt = packet_create();
137 host_t *source, *dest;
138 int bytes_read = 0;
139
140
141 while (bytes_read >= 0)
142 {
143 int max_fd = 1;
144 fd_set readfds;
145 iterator_t *iterator;
146 int oldstate;
147 interface_t *interface;
148
149 /* build fd_set */
150 FD_ZERO(&readfds);
151 iterator = this->interfaces->create_iterator(this->interfaces, TRUE);
152 while (iterator->has_next(iterator))
153 {
154 iterator->current(iterator, (void**)&interface);
155 FD_SET(interface->socket_fd, &readfds);
156 if (interface->socket_fd > max_fd)
157 {
158 max_fd = interface->socket_fd + 1;
159 }
160 }
161 iterator->destroy(iterator);
162
163 /* add packet destroy handler for cancellation, enable cancellation */
164 pthread_cleanup_push((void(*)(void*))pkt->destroy, (void*)pkt);
165 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
166
167 this->logger->log(this->logger, CONTROL|LEVEL1, "waiting on sockets");
168 bytes_read = select(max_fd, &readfds, NULL, NULL, NULL);
169
170 /* reset cancellation, remove packet destroy handler (without executing) */
171 pthread_setcancelstate(oldstate, NULL);
172 pthread_cleanup_pop(0);
173
174 /* read on the first nonblocking socket */
175 bytes_read = 0;
176 iterator = this->interfaces->create_iterator(this->interfaces, TRUE);
177 while (iterator->has_next(iterator))
178 {
179 iterator->current(iterator, (void**)&interface);
180 if (FD_ISSET(interface->socket_fd, &readfds))
181 {
182 /* do the read */
183 bytes_read = recv(interface->socket_fd, buffer, MAX_PACKET, 0);
184 break;
185 }
186 }
187 iterator->destroy(iterator);
188
189 if (bytes_read < 0)
190 {
191 this->logger->log(this->logger, ERROR, "error reading from socket: %s", strerror(errno));
192 continue;
193 }
194 if (bytes_read > IP_HEADER_LENGTH + UDP_HEADER_LENGTH)
195 {
196 /* read source/dest from raw IP/UDP header */
197 chunk_t source_chunk = {buffer + 12, 4};
198 chunk_t dest_chunk = {buffer + 16, 4};
199 u_int16_t source_port = ntohs(*(u_int16_t*)(buffer + 20));
200 u_int16_t dest_port = ntohs(*(u_int16_t*)(buffer + 22));
201 source = host_create_from_chunk(AF_INET, source_chunk, source_port);
202 dest = host_create_from_chunk(AF_INET, dest_chunk, dest_port);
203 pkt->set_source(pkt, source);
204 pkt->set_destination(pkt, dest);
205 break;
206 }
207 this->logger->log(this->logger, ERROR|LEVEL1, "too short packet received");
208 }
209
210 this->logger->log(this->logger, CONTROL, "received packet: from %s:%d to %s:%d",
211 source->get_address(source), source->get_port(source),
212 dest->get_address(dest), dest->get_port(dest));
213
214 /* fill in packet */
215 data.len = bytes_read - IP_HEADER_LENGTH - UDP_HEADER_LENGTH;
216 data.ptr = allocator_alloc(data.len);
217 memcpy(data.ptr, buffer + IP_HEADER_LENGTH + UDP_HEADER_LENGTH, data.len);
218 pkt->set_data(pkt, data);
219
220 /* return packet */
221 *packet = pkt;
222
223 return SUCCESS;
224 }
225
226 /**
227 * implementation of socket_t.send
228 */
229 status_t sender(private_socket_t *this, packet_t *packet)
230 {
231 ssize_t bytes_sent;
232 chunk_t data;
233 host_t *source, *dest;
234
235 source = packet->get_source(packet);
236 dest = packet->get_destination(packet);
237 data = packet->get_data(packet);
238
239 this->logger->log(this->logger, CONTROL, "sending packet to %s:%d",
240 dest->get_address(dest),
241 dest->get_port(dest));
242
243 /* send data */
244 /* TODO: should we send via the interface we received the packet? */
245 bytes_sent = sendto(this->master_fd, data.ptr, data.len, 0,
246 dest->get_sockaddr(dest), *(dest->get_sockaddr_len(dest)));
247
248 if (bytes_sent != data.len)
249 {
250 this->logger->log(this->logger, ERROR, "error writing to socket: %s", strerror(errno));
251 return FAILED;
252 }
253 return SUCCESS;
254 }
255
256 /**
257 * Find all suitable interfaces, bind them and add them to the list
258 */
259 static status_t build_interface_list(private_socket_t *this, u_int16_t port)
260 {
261 int on = TRUE;
262 int i;
263 struct sockaddr_in addr;
264 struct ifconf ifconf;
265 struct ifreq buf[300];
266
267 /* master socket for querying socket for a specific interfaces */
268 this->master_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
269 if (this->master_fd == -1)
270 {
271 this->logger->log(this->logger, ERROR, "could not open IPv4 master socket!");
272 return FAILED;
273 }
274
275 /* allow binding of multiplo sockets */
276 if (setsockopt(this->master_fd, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
277 {
278 this->logger->log(this->logger, ERROR, "unable to set SO_REUSEADDR on master socket!");
279 return FAILED;
280 }
281
282 /* bind the master socket */
283 addr.sin_family = AF_INET;
284 addr.sin_addr.s_addr = INADDR_ANY;
285 addr.sin_port = htons(port);
286 if (bind(this->master_fd,(struct sockaddr*)&addr, sizeof(addr)) < 0)
287 {
288 this->logger->log(this->logger, ERROR, "unable to bind master socket!");
289 return FAILED;
290 }
291
292 /* get all interfaces */
293 ifconf.ifc_len = sizeof(buf);
294 ifconf.ifc_buf = (void*) buf;
295 memset(buf, 0, sizeof(buf));
296 if (ioctl(this->master_fd, SIOCGIFCONF, &ifconf) == -1)
297 {
298 this->logger->log(this->logger, ERROR, "unable to get interfaces!");
299 return FAILED;
300 }
301
302 /* add every interesting interfaces to our interface list */
303 for (i = 0; (i+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; i++)
304 {
305 struct sockaddr_in *current = (struct sockaddr_in*) &buf[i].ifr_addr;
306 struct ifreq auxinfo;
307 int skt;
308 interface_t *interface;
309
310 if (current->sin_family != AF_INET)
311 {
312 /* ignore all but AF_INET interfaces */
313 continue;
314 }
315
316 /* get auxilary info about socket */
317 memset(&auxinfo, 0, sizeof(auxinfo));
318 memcpy(auxinfo.ifr_name, buf[i].ifr_name, IFNAMSIZ);
319 if (ioctl(this->master_fd, SIOCGIFFLAGS, &auxinfo) == -1)
320 {
321 this->logger->log(this->logger, ERROR, "unable to SIOCGIFFLAGS master socket!");
322 continue;
323 }
324 if (!(auxinfo.ifr_flags & IFF_UP))
325 {
326 /* ignore an interface that isn't up */
327 continue;
328 }
329 if (current->sin_addr.s_addr == 0)
330 {
331 /* ignore unconfigured interfaces */
332 continue;
333 }
334
335 /* set up interface socket */
336 skt = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
337 if (socket < 0)
338 {
339 this->logger->log(this->logger, ERROR, "unable to open interface socket!");
340 continue;
341 }
342 if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
343 {
344 this->logger->log(this->logger, ERROR, "unable to set SO_REUSEADDR on interface socket!");
345 close(skt);
346 continue;
347 }
348 current->sin_port = htons(port);
349 current->sin_family = AF_INET;
350 if (bind(skt, (struct sockaddr*)current, sizeof(struct sockaddr_in)) < 0)
351 {
352 this->logger->log(this->logger, ERROR, "unable to bind interface socket!");
353 close(skt);
354 continue;
355 }
356
357 if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER, &ikev2_filter, sizeof(ikev2_filter)) < 0)
358 {
359 this->logger->log(this->logger, ERROR, "unable to attack IKEv2 filter to interface socket!");
360 close(skt);
361 continue;
362 }
363
364 /* add socket with interface name to list */
365 interface = allocator_alloc_thing(interface_t);
366 memcpy(interface->name, buf[i].ifr_name, IFNAMSIZ);
367 interface->name[IFNAMSIZ-1] = '\0';
368 interface->socket_fd = skt;
369 this->logger->log(this->logger, CONTROL, "listening on %s (%s)",
370 interface->name, inet_ntoa(current->sin_addr));
371 this->interfaces->insert_last(this->interfaces, (void*)interface);
372 }
373
374 if (this->interfaces->get_count(this->interfaces) == 0)
375 {
376 this->logger->log(this->logger, ERROR, "unable to find any usable interface!");
377 return FAILED;
378 }
379 return SUCCESS;
380 }
381
382 /**
383 * implementation of socket_t.destroy
384 */
385 void destroy(private_socket_t *this)
386 {
387 interface_t *interface;
388 while (this->interfaces->remove_last(this->interfaces, (void**)&interface) == SUCCESS)
389 {
390 close(interface->socket_fd);
391 allocator_free(interface);
392 }
393 this->interfaces->destroy(this->interfaces);
394 charon->logger_manager->destroy_logger(charon->logger_manager, this->logger);
395 close(this->master_fd);
396 allocator_free(this);
397 }
398
399 /*
400 * See header for description
401 */
402 socket_t *socket_create(u_int16_t port)
403 {
404 private_socket_t *this = allocator_alloc_thing(private_socket_t);
405
406 /* public functions */
407 this->public.send = (status_t(*)(socket_t*, packet_t*))sender;
408 this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
409 this->public.destroy = (void(*)(socket_t*)) destroy;
410
411 this->logger = charon->logger_manager->create_logger(charon->logger_manager, SOCKET, NULL);
412 this->interfaces = linked_list_create();
413
414 if (build_interface_list(this, port) != SUCCESS)
415 {
416 charon->kill(charon, "could not bind any interface!");
417 }
418
419 return (socket_t*)this;
420 }