source: mainline/uspace/srv/net/il/ip/ip.c@ 3bb5735

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3bb5735 was 3bb5735, checked in by Jakub Jermar <jakub@…>, 15 years ago

Cherry pick fixes from changeset lp:~helenos-nicf/helenos/nicf,705.

Original description:
Solved first ping timeout

Cleaned up a little and replaced EBUSY with EAGAIN.

  • Property mode set to 100644
File size: 55.5 KB
Line 
1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup ip
30 * @{
31 */
32
33/** @file
34 * IP module implementation.
35 * @see arp.h
36 */
37
38#include "ip.h"
39#include "ip_module.h"
40
41#include <async.h>
42#include <errno.h>
43#include <fibril_synch.h>
44#include <stdio.h>
45#include <str.h>
46#include <ipc/ipc.h>
47#include <ipc/services.h>
48#include <ipc/net.h>
49#include <ipc/nil.h>
50#include <ipc/il.h>
51#include <ipc/ip.h>
52#include <sys/types.h>
53#include <byteorder.h>
54
55#include <adt/measured_strings.h>
56#include <adt/module_map.h>
57
58#include <packet_client.h>
59#include <net/socket_codes.h>
60#include <net/in.h>
61#include <net/in6.h>
62#include <net/inet.h>
63#include <net/modules.h>
64#include <net/device.h>
65#include <net/packet.h>
66#include <net/icmp_codes.h>
67
68#include <arp_interface.h>
69#include <net_checksum.h>
70#include <icmp_client.h>
71#include <icmp_interface.h>
72#include <il_interface.h>
73#include <ip_client.h>
74#include <ip_interface.h>
75#include <ip_header.h>
76#include <net_interface.h>
77#include <nil_interface.h>
78#include <tl_interface.h>
79#include <packet_remote.h>
80#include <il_local.h>
81
82/** IP module name. */
83#define NAME "ip"
84
85/** IP version 4. */
86#define IPV4 4
87
88/** Default network interface IP version. */
89#define NET_DEFAULT_IPV IPV4
90
91/** Default network interface IP routing. */
92#define NET_DEFAULT_IP_ROUTING false
93
94/** Minimum IP packet content. */
95#define IP_MIN_CONTENT 576
96
97/** ARP module name. */
98#define ARP_NAME "arp"
99
100/** ARP module filename. */
101#define ARP_FILENAME "/srv/arp"
102
103/** IP packet address length. */
104#define IP_ADDR sizeof(struct sockaddr_in6)
105
106/** IP packet prefix length. */
107#define IP_PREFIX sizeof(ip_header_t)
108
109/** IP packet suffix length. */
110#define IP_SUFFIX 0
111
112/** IP packet maximum content length. */
113#define IP_MAX_CONTENT 65535
114
115/** The IP localhost address. */
116#define IPV4_LOCALHOST_ADDRESS htonl((127 << 24) + 1)
117
118/** How many times can arp_translate_req respond EAGAIN before IP gives up */
119#define ARP_EAGAIN_MAX_COUNT 10
120
121/** IP global data. */
122ip_globals_t ip_globals;
123
124DEVICE_MAP_IMPLEMENT(ip_netifs, ip_netif_t);
125INT_MAP_IMPLEMENT(ip_protos, ip_proto_t);
126GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t);
127
128/** Releases the packet and returns the result.
129 *
130 * @param[in] packet The packet queue to be released.
131 * @param[in] result The result to be returned.
132 * @return The result parameter.
133 */
134static int ip_release_and_return(packet_t *packet, int result)
135{
136 pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
137 return result;
138}
139
140/** Returns the ICMP phone.
141 *
142 * Searches the registered protocols.
143 *
144 * @return The found ICMP phone.
145 * @return ENOENT if the ICMP is not registered.
146 */
147static int ip_get_icmp_phone(void)
148{
149 ip_proto_t *proto;
150 int phone;
151
152 fibril_rwlock_read_lock(&ip_globals.protos_lock);
153 proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP);
154 phone = proto ? proto->phone : ENOENT;
155 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
156 return phone;
157}
158
159/** Prepares the ICMP notification packet.
160 *
161 * Releases additional packets and keeps only the first one.
162 *
163 * @param[in] packet The packet or the packet queue to be reported as faulty.
164 * @param[in] header The first packet IP header. May be NULL.
165 * @return EOK on success.
166 * @return EINVAL if there are no data in the packet.
167 * @return EINVAL if the packet is a fragment.
168 * @return ENOMEM if the packet is too short to contain the IP
169 * header.
170 * @return EAFNOSUPPORT if the address family is not supported.
171 * @return EPERM if the protocol is not allowed to send ICMP
172 * notifications. The ICMP protocol itself.
173 * @return Other error codes as defined for the packet_set_addr().
174 */
175static int ip_prepare_icmp(packet_t *packet, ip_header_t *header)
176{
177 packet_t *next;
178 struct sockaddr *dest;
179 struct sockaddr_in dest_in;
180 socklen_t addrlen;
181
182 // detach the first packet and release the others
183 next = pq_detach(packet);
184 if (next)
185 pq_release_remote(ip_globals.net_phone, packet_get_id(next));
186
187 if (!header) {
188 if (packet_get_data_length(packet) <= sizeof(ip_header_t))
189 return ENOMEM;
190
191 // get header
192 header = (ip_header_t *) packet_get_data(packet);
193 if (!header)
194 return EINVAL;
195
196 }
197
198 // only for the first fragment
199 if (IP_FRAGMENT_OFFSET(header))
200 return EINVAL;
201
202 // not for the ICMP protocol
203 if (header->protocol == IPPROTO_ICMP)
204 return EPERM;
205
206 // set the destination address
207 switch (header->version) {
208 case IPVERSION:
209 addrlen = sizeof(dest_in);
210 bzero(&dest_in, addrlen);
211 dest_in.sin_family = AF_INET;
212 memcpy(&dest_in.sin_addr.s_addr, &header->source_address,
213 sizeof(header->source_address));
214 dest = (struct sockaddr *) &dest_in;
215 break;
216
217 default:
218 return EAFNOSUPPORT;
219 }
220
221 return packet_set_addr(packet, NULL, (uint8_t *) dest, addrlen);
222}
223
224/** Prepares the ICMP notification packet.
225 *
226 * Releases additional packets and keeps only the first one.
227 * All packets are released on error.
228 *
229 * @param[in] error The packet error service.
230 * @param[in] packet The packet or the packet queue to be reported as faulty.
231 * @param[in] header The first packet IP header. May be NULL.
232 * @return The found ICMP phone.
233 * @return EINVAL if the error parameter is set.
234 * @return EINVAL if the ICMP phone is not found.
235 * @return EINVAL if the ip_prepare_icmp() fails.
236 */
237static int
238ip_prepare_icmp_and_get_phone(services_t error, packet_t *packet,
239 ip_header_t *header)
240{
241 int phone;
242
243 phone = ip_get_icmp_phone();
244 if (error || (phone < 0) || ip_prepare_icmp(packet, header))
245 return ip_release_and_return(packet, EINVAL);
246 return phone;
247}
248
249/** Initializes the IP module.
250 *
251 * @param[in] client_connection The client connection processing function. The
252 * module skeleton propagates its own one.
253 * @return EOK on success.
254 * @return ENOMEM if there is not enough memory left.
255 */
256int ip_initialize(async_client_conn_t client_connection)
257{
258 int rc;
259
260 fibril_rwlock_initialize(&ip_globals.lock);
261 fibril_rwlock_write_lock(&ip_globals.lock);
262 fibril_rwlock_initialize(&ip_globals.protos_lock);
263 fibril_rwlock_initialize(&ip_globals.netifs_lock);
264 ip_globals.packet_counter = 0;
265 ip_globals.gateway.address.s_addr = 0;
266 ip_globals.gateway.netmask.s_addr = 0;
267 ip_globals.gateway.gateway.s_addr = 0;
268 ip_globals.gateway.netif = NULL;
269 ip_globals.client_connection = client_connection;
270
271 rc = ip_netifs_initialize(&ip_globals.netifs);
272 if (rc != EOK)
273 goto out;
274 rc = ip_protos_initialize(&ip_globals.protos);
275 if (rc != EOK)
276 goto out;
277 rc = modules_initialize(&ip_globals.modules);
278 if (rc != EOK)
279 goto out;
280 rc = add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME,
281 SERVICE_ARP, 0, arp_connect_module);
282
283out:
284 fibril_rwlock_write_unlock(&ip_globals.lock);
285
286 return rc;
287}
288
289/** Initializes a new network interface specific data.
290 *
291 * Connects to the network interface layer module, reads the netif
292 * configuration, starts an ARP module if needed and sets the netif routing
293 * table.
294 *
295 * The device identifier and the nil service has to be set.
296 *
297 * @param[in,out] ip_netif Network interface specific data.
298 * @return EOK on success.
299 * @return ENOTSUP if DHCP is configured.
300 * @return ENOTSUP if IPv6 is configured.
301 * @return EINVAL if any of the addresses is invalid.
302 * @return EINVAL if the used ARP module is not known.
303 * @return ENOMEM if there is not enough memory left.
304 * @return Other error codes as defined for the
305 * net_get_device_conf_req() function.
306 * @return Other error codes as defined for the bind_service()
307 * function.
308 * @return Other error codes as defined for the specific
309 * arp_device_req() function.
310 * @return Other error codes as defined for the
311 * nil_packet_size_req() function.
312 */
313static int ip_netif_initialize(ip_netif_t *ip_netif)
314{
315 measured_string_t names[] = {
316 {
317 (char *) "IPV",
318 3
319 },
320 {
321 (char *) "IP_CONFIG",
322 9
323 },
324 {
325 (char *) "IP_ADDR",
326 7
327 },
328 {
329 (char *) "IP_NETMASK",
330 10
331 },
332 {
333 (char *) "IP_GATEWAY",
334 10
335 },
336 {
337 (char *) "IP_BROADCAST",
338 12
339 },
340 {
341 (char *) "ARP",
342 3
343 },
344 {
345 (char *) "IP_ROUTING",
346 10
347 }
348 };
349 measured_string_t *configuration;
350 size_t count = sizeof(names) / sizeof(measured_string_t);
351 char *data;
352 measured_string_t address;
353 ip_route_t *route;
354 in_addr_t gateway;
355 int index;
356 int rc;
357
358 ip_netif->arp = NULL;
359 route = NULL;
360 ip_netif->ipv = NET_DEFAULT_IPV;
361 ip_netif->dhcp = false;
362 ip_netif->routing = NET_DEFAULT_IP_ROUTING;
363 configuration = &names[0];
364
365 // get configuration
366 rc = net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id,
367 &configuration, count, &data);
368 if (rc != EOK)
369 return rc;
370
371 if (configuration) {
372 if (configuration[0].value)
373 ip_netif->ipv = strtol(configuration[0].value, NULL, 0);
374
375 ip_netif->dhcp = !str_lcmp(configuration[1].value, "dhcp",
376 configuration[1].length);
377
378 if (ip_netif->dhcp) {
379 // TODO dhcp
380 net_free_settings(configuration, data);
381 return ENOTSUP;
382 } else if (ip_netif->ipv == IPV4) {
383 route = (ip_route_t *) malloc(sizeof(ip_route_t));
384 if (!route) {
385 net_free_settings(configuration, data);
386 return ENOMEM;
387 }
388 route->address.s_addr = 0;
389 route->netmask.s_addr = 0;
390 route->gateway.s_addr = 0;
391 route->netif = ip_netif;
392 index = ip_routes_add(&ip_netif->routes, route);
393 if (index < 0) {
394 net_free_settings(configuration, data);
395 free(route);
396 return index;
397 }
398
399 if ((inet_pton(AF_INET, configuration[2].value,
400 (uint8_t *) &route->address.s_addr) != EOK) ||
401 (inet_pton(AF_INET, configuration[3].value,
402 (uint8_t *) &route->netmask.s_addr) != EOK) ||
403 (inet_pton(AF_INET, configuration[4].value,
404 (uint8_t *) &gateway.s_addr) == EINVAL) ||
405 (inet_pton(AF_INET, configuration[5].value,
406 (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL))
407 {
408 net_free_settings(configuration, data);
409 return EINVAL;
410 }
411 } else {
412 // TODO ipv6 in separate module
413 net_free_settings(configuration, data);
414 return ENOTSUP;
415 }
416
417 if (configuration[6].value) {
418 ip_netif->arp = get_running_module(&ip_globals.modules,
419 configuration[6].value);
420 if (!ip_netif->arp) {
421 printf("Failed to start the arp %s\n",
422 configuration[6].value);
423 net_free_settings(configuration, data);
424 return EINVAL;
425 }
426 }
427 if (configuration[7].value)
428 ip_netif->routing = (configuration[7].value[0] == 'y');
429
430 net_free_settings(configuration, data);
431 }
432
433 // binds the netif service which also initializes the device
434 ip_netif->phone = nil_bind_service(ip_netif->service,
435 (ipcarg_t) ip_netif->device_id, SERVICE_IP,
436 ip_globals.client_connection);
437 if (ip_netif->phone < 0) {
438 printf("Failed to contact the nil service %d\n",
439 ip_netif->service);
440 return ip_netif->phone;
441 }
442
443 // has to be after the device netif module initialization
444 if (ip_netif->arp) {
445 if (route) {
446 address.value = (char *) &route->address.s_addr;
447 address.length = CONVERT_SIZE(in_addr_t, char, 1);
448
449 rc = arp_device_req(ip_netif->arp->phone,
450 ip_netif->device_id, SERVICE_IP, ip_netif->service,
451 &address);
452 if (rc != EOK)
453 return rc;
454 } else {
455 ip_netif->arp = 0;
456 }
457 }
458
459 // get packet dimensions
460 rc = nil_packet_size_req(ip_netif->phone, ip_netif->device_id,
461 &ip_netif->packet_dimension);
462 if (rc != EOK)
463 return rc;
464
465 if (ip_netif->packet_dimension.content < IP_MIN_CONTENT) {
466 printf("Maximum transmission unit %d bytes is too small, at "
467 "least %d bytes are needed\n",
468 ip_netif->packet_dimension.content, IP_MIN_CONTENT);
469 ip_netif->packet_dimension.content = IP_MIN_CONTENT;
470 }
471
472 index = ip_netifs_add(&ip_globals.netifs, ip_netif->device_id, ip_netif);
473 if (index < 0)
474 return index;
475
476 if (gateway.s_addr) {
477 // the default gateway
478 ip_globals.gateway.address.s_addr = 0;
479 ip_globals.gateway.netmask.s_addr = 0;
480 ip_globals.gateway.gateway.s_addr = gateway.s_addr;
481 ip_globals.gateway.netif = ip_netif;
482 }
483
484 return EOK;
485}
486
487/** Updates the device content length according to the new MTU value.
488 *
489 * @param[in] device_id The device identifier.
490 * @param[in] mtu The new mtu value.
491 * @return EOK on success.
492 * @return ENOENT if device is not found.
493 */
494static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
495{
496 ip_netif_t *netif;
497
498 fibril_rwlock_write_lock(&ip_globals.netifs_lock);
499 netif = ip_netifs_find(&ip_globals.netifs, device_id);
500 if (!netif) {
501 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
502 return ENOENT;
503 }
504 netif->packet_dimension.content = mtu;
505 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
506
507 printf("%s: Device %d changed MTU to %d\n", NAME, device_id, mtu);
508
509 return EOK;
510}
511
512/** Updates the device state.
513 *
514 * @param[in] device_id The device identifier.
515 * @param[in] state The new state value.
516 * @return EOK on success.
517 * @return ENOENT if device is not found.
518 */
519static int ip_device_state_message(device_id_t device_id, device_state_t state)
520{
521 ip_netif_t *netif;
522
523 fibril_rwlock_write_lock(&ip_globals.netifs_lock);
524 // find the device
525 netif = ip_netifs_find(&ip_globals.netifs, device_id);
526 if (!netif) {
527 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
528 return ENOENT;
529 }
530 netif->state = state;
531 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
532
533 printf("%s: Device %d changed state to %d\n", NAME, device_id, state);
534
535 return EOK;
536}
537
538
539/** Prefixes a middle fragment header based on the last fragment header to the
540 * packet.
541 *
542 * @param[in] packet The packet to be prefixed.
543 * @param[in] last The last header to be copied.
544 * @return The prefixed middle header.
545 * @return NULL on error.
546 */
547static ip_header_t *
548ip_create_middle_header(packet_t *packet, ip_header_t *last)
549{
550 ip_header_t *middle;
551
552 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));
553 if (!middle)
554 return NULL;
555 memcpy(middle, last, IP_HEADER_LENGTH(last));
556 middle->flags |= IPFLAG_MORE_FRAGMENTS;
557 return middle;
558}
559
560/** Copies the fragment header.
561 *
562 * Copies only the header itself and relevant IP options.
563 *
564 * @param[out] last The created header.
565 * @param[in] first The original header to be copied.
566 */
567static void ip_create_last_header(ip_header_t *last, ip_header_t *first)
568{
569 ip_option_t *option;
570 size_t next;
571 size_t length;
572
573 // copy first itself
574 memcpy(last, first, sizeof(ip_header_t));
575 length = sizeof(ip_header_t);
576 next = sizeof(ip_header_t);
577
578 // process all ip options
579 while (next < first->header_length) {
580 option = (ip_option_t *) (((uint8_t *) first) + next);
581 // skip end or noop
582 if ((option->type == IPOPT_END) ||
583 (option->type == IPOPT_NOOP)) {
584 next++;
585 } else {
586 // copy if told so or skip
587 if (IPOPT_COPIED(option->type)) {
588 memcpy(((uint8_t *) last) + length,
589 ((uint8_t *) first) + next, option->length);
590 length += option->length;
591 }
592 // next option
593 next += option->length;
594 }
595 }
596
597 // align 4 byte boundary
598 if (length % 4) {
599 bzero(((uint8_t *) last) + length, 4 - (length % 4));
600 last->header_length = length / 4 + 1;
601 } else {
602 last->header_length = length / 4;
603 }
604
605 last->header_checksum = 0;
606}
607
608/** Prepares the outgoing packet or the packet queue.
609 *
610 * The packet queue is a fragmented packet
611 * Updates the first packet's IP header.
612 * Prefixes the additional packets with fragment headers.
613 *
614 * @param[in] source The source address.
615 * @param[in] dest The destination address.
616 * @param[in,out] packet The packet to be sent.
617 * @param[in] destination The destination hardware address.
618 * @return EOK on success.
619 * @return EINVAL if the packet is too small to contain the IP
620 * header.
621 * @return EINVAL if the packet is too long than the IP allows.
622 * @return ENOMEM if there is not enough memory left.
623 * @return Other error codes as defined for the packet_set_addr()
624 * function.
625 */
626static int
627ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet,
628 measured_string_t *destination)
629{
630 size_t length;
631 ip_header_t *header;
632 ip_header_t *last_header;
633 ip_header_t *middle_header;
634 packet_t *next;
635 int rc;
636
637 length = packet_get_data_length(packet);
638 if ((length < sizeof(ip_header_t)) || (length > IP_MAX_CONTENT))
639 return EINVAL;
640
641 header = (ip_header_t *) packet_get_data(packet);
642 if (destination) {
643 rc = packet_set_addr(packet, NULL, (uint8_t *) destination->value,
644 CONVERT_SIZE(char, uint8_t, destination->length));
645 } else {
646 rc = packet_set_addr(packet, NULL, NULL, 0);
647 }
648 if (rc != EOK)
649 return rc;
650
651 header->version = IPV4;
652 header->fragment_offset_high = 0;
653 header->fragment_offset_low = 0;
654 header->header_checksum = 0;
655 if (source)
656 header->source_address = source->s_addr;
657 header->destination_address = dest.s_addr;
658
659 fibril_rwlock_write_lock(&ip_globals.lock);
660 ip_globals.packet_counter++;
661 header->identification = htons(ip_globals.packet_counter);
662 fibril_rwlock_write_unlock(&ip_globals.lock);
663
664 if (pq_next(packet)) {
665 last_header = (ip_header_t *) malloc(IP_HEADER_LENGTH(header));
666 if (!last_header)
667 return ENOMEM;
668 ip_create_last_header(last_header, header);
669 next = pq_next(packet);
670 while (pq_next(next)) {
671 middle_header = (ip_header_t *) packet_prefix(next,
672 IP_HEADER_LENGTH(last_header));
673 if (!middle_header) {
674 free(last_header);
675 return ENOMEM;
676 }
677
678 memcpy(middle_header, last_header,
679 IP_HEADER_LENGTH(last_header));
680 header->flags |= IPFLAG_MORE_FRAGMENTS;
681 middle_header->total_length =
682 htons(packet_get_data_length(next));
683 middle_header->fragment_offset_high =
684 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length);
685 middle_header->fragment_offset_low =
686 IP_COMPUTE_FRAGMENT_OFFSET_LOW(length);
687 middle_header->header_checksum =
688 IP_HEADER_CHECKSUM(middle_header);
689 if (destination) {
690 rc = packet_set_addr(next, NULL,
691 (uint8_t *) destination->value,
692 CONVERT_SIZE(char, uint8_t,
693 destination->length));
694 if (rc != EOK) {
695 free(last_header);
696 return rc;
697 }
698 }
699 length += packet_get_data_length(next);
700 next = pq_next(next);
701 }
702
703 middle_header = (ip_header_t *) packet_prefix(next,
704 IP_HEADER_LENGTH(last_header));
705 if (!middle_header) {
706 free(last_header);
707 return ENOMEM;
708 }
709
710 memcpy(middle_header, last_header,
711 IP_HEADER_LENGTH(last_header));
712 middle_header->total_length =
713 htons(packet_get_data_length(next));
714 middle_header->fragment_offset_high =
715 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length);
716 middle_header->fragment_offset_low =
717 IP_COMPUTE_FRAGMENT_OFFSET_LOW(length);
718 middle_header->header_checksum =
719 IP_HEADER_CHECKSUM(middle_header);
720 if (destination) {
721 rc = packet_set_addr(next, NULL,
722 (uint8_t *) destination->value,
723 CONVERT_SIZE(char, uint8_t, destination->length));
724 if (rc != EOK) {
725 free(last_header);
726 return rc;
727 }
728 }
729 length += packet_get_data_length(next);
730 free(last_header);
731 header->flags |= IPFLAG_MORE_FRAGMENTS;
732 }
733
734 header->total_length = htons(length);
735 // unnecessary for all protocols
736 header->header_checksum = IP_HEADER_CHECKSUM(header);
737
738 return EOK;
739}
740
741/** Fragments the packet from the end.
742 *
743 * @param[in] packet The packet to be fragmented.
744 * @param[in,out] new_packet The new packet fragment.
745 * @param[in,out] header The original packet header.
746 * @param[in,out] new_header The new packet fragment header.
747 * @param[in] length The new fragment length.
748 * @param[in] src The source address.
749 * @param[in] dest The destiantion address.
750 * @param[in] addrlen The address length.
751 * @return EOK on success.
752 * @return ENOMEM if the target packet is too small.
753 * @return Other error codes as defined for the packet_set_addr()
754 * function.
755 * @return Other error codes as defined for the pq_insert_after()
756 * function.
757 */
758static int
759ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
760 ip_header_t *header, ip_header_t *new_header, size_t length,
761 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen)
762{
763 void *data;
764 size_t offset;
765 int rc;
766
767 data = packet_suffix(new_packet, length);
768 if (!data)
769 return ENOMEM;
770
771 memcpy(data, ((void *) header) + IP_TOTAL_LENGTH(header) - length,
772 length);
773
774 rc = packet_trim(packet, 0, length);
775 if (rc != EOK)
776 return rc;
777
778 header->total_length = htons(IP_TOTAL_LENGTH(header) - length);
779 new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length);
780 offset = IP_FRAGMENT_OFFSET(header) + IP_HEADER_DATA_LENGTH(header);
781 new_header->fragment_offset_high =
782 IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset);
783 new_header->fragment_offset_low =
784 IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset);
785 new_header->header_checksum = IP_HEADER_CHECKSUM(new_header);
786
787 rc = packet_set_addr(new_packet, (const uint8_t *) src,
788 (const uint8_t *) dest, addrlen);
789 if (rc != EOK)
790 return rc;
791
792 return pq_insert_after(packet, new_packet);
793}
794
795/** Checks the packet length and fragments it if needed.
796 *
797 * The new fragments are queued before the original packet.
798 *
799 * @param[in,out] packet The packet to be checked.
800 * @param[in] length The maximum packet length.
801 * @param[in] prefix The minimum prefix size.
802 * @param[in] suffix The minimum suffix size.
803 * @param[in] addr_len The minimum address length.
804 * @return EOK on success.
805 * @return EINVAL if the packet_get_addr() function fails.
806 * @return EINVAL if the packet does not contain the IP header.
807 * @return EPERM if the packet needs to be fragmented and the
808 * fragmentation is not allowed.
809 * @return ENOMEM if there is not enough memory left.
810 * @return ENOMEM if there is no packet available.
811 * @return ENOMEM if the packet is too small to contain the IP
812 * header.
813 * @return Other error codes as defined for the packet_trim()
814 * function.
815 * @return Other error codes as defined for the
816 * ip_create_middle_header() function.
817 * @return Other error codes as defined for the
818 * ip_fragment_packet_data() function.
819 */
820static int
821ip_fragment_packet(packet_t *packet, size_t length, size_t prefix, size_t suffix,
822 socklen_t addr_len)
823{
824 packet_t *new_packet;
825 ip_header_t *header;
826 ip_header_t *middle_header;
827 ip_header_t *last_header;
828 struct sockaddr *src;
829 struct sockaddr *dest;
830 socklen_t addrlen;
831 int result;
832 int rc;
833
834 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
835 if (result <= 0)
836 return EINVAL;
837
838 addrlen = (socklen_t) result;
839 if (packet_get_data_length(packet) <= sizeof(ip_header_t))
840 return ENOMEM;
841
842 // get header
843 header = (ip_header_t *) packet_get_data(packet);
844 if (!header)
845 return EINVAL;
846
847 // fragmentation forbidden?
848 if(header->flags & IPFLAG_DONT_FRAGMENT)
849 return EPERM;
850
851 // create the last fragment
852 new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length,
853 suffix, ((addrlen > addr_len) ? addrlen : addr_len));
854 if (!new_packet)
855 return ENOMEM;
856
857 // allocate as much as originally
858 last_header = (ip_header_t *) packet_suffix(new_packet,
859 IP_HEADER_LENGTH(header));
860 if (!last_header)
861 return ip_release_and_return(packet, ENOMEM);
862
863 ip_create_last_header(last_header, header);
864
865 // trim the unused space
866 rc = packet_trim(new_packet, 0,
867 IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header));
868 if (rc != EOK)
869 return ip_release_and_return(packet, rc);
870
871 // biggest multiple of 8 lower than content
872 // TODO even fragmentation?
873 length = length & ~0x7;
874
875 rc = ip_fragment_packet_data(packet, new_packet, header, last_header,
876 ((IP_HEADER_DATA_LENGTH(header) -
877 ((length - IP_HEADER_LENGTH(header)) & ~0x7)) %
878 ((length - IP_HEADER_LENGTH(last_header)) & ~0x7)),
879 src, dest, addrlen);
880 if (rc != EOK)
881 return ip_release_and_return(packet, rc);
882
883 // mark the first as fragmented
884 header->flags |= IPFLAG_MORE_FRAGMENTS;
885
886 // create middle framgents
887 while (IP_TOTAL_LENGTH(header) > length) {
888 new_packet = packet_get_4_remote(ip_globals.net_phone, prefix,
889 length, suffix,
890 ((addrlen >= addr_len) ? addrlen : addr_len));
891 if (!new_packet)
892 return ENOMEM;
893
894 middle_header = ip_create_middle_header(new_packet,
895 last_header);
896 if (!middle_header)
897 return ip_release_and_return(packet, ENOMEM);
898
899 rc = ip_fragment_packet_data(packet, new_packet, header,
900 middle_header,
901 (length - IP_HEADER_LENGTH(middle_header)) & ~0x7,
902 src, dest, addrlen);
903 if (rc != EOK)
904 return ip_release_and_return(packet, rc);
905 }
906
907 // finish the first fragment
908 header->header_checksum = IP_HEADER_CHECKSUM(header);
909
910 return EOK;
911}
912
913/** Checks the packet queue lengths and fragments the packets if needed.
914 *
915 * The ICMP_FRAG_NEEDED error notification may be sent if the packet needs to
916 * be fragmented and the fragmentation is not allowed.
917 *
918 * @param[in,out] packet The packet or the packet queue to be checked.
919 * @param[in] prefix The minimum prefix size.
920 * @param[in] content The maximum content size.
921 * @param[in] suffix The minimum suffix size.
922 * @param[in] addr_len The minimum address length.
923 * @param[in] error The error module service.
924 * @return The packet or the packet queue of the allowed length.
925 * @return NULL if there are no packets left.
926 */
927static packet_t *
928ip_split_packet(packet_t *packet, size_t prefix, size_t content, size_t suffix,
929 socklen_t addr_len, services_t error)
930{
931 size_t length;
932 packet_t *next;
933 packet_t *new_packet;
934 int result;
935 int phone;
936
937 next = packet;
938 // check all packets
939 while (next) {
940 length = packet_get_data_length(next);
941
942 if (length <= content) {
943 next = pq_next(next);
944 continue;
945 }
946
947 // too long
948 result = ip_fragment_packet(next, content, prefix,
949 suffix, addr_len);
950 if (result != EOK) {
951 new_packet = pq_detach(next);
952 if (next == packet) {
953 // the new first packet of the queue
954 packet = new_packet;
955 }
956 // fragmentation needed?
957 if (result == EPERM) {
958 phone = ip_prepare_icmp_and_get_phone(
959 error, next, NULL);
960 if (phone >= 0) {
961 // fragmentation necessary ICMP
962 icmp_destination_unreachable_msg(phone,
963 ICMP_FRAG_NEEDED, content, next);
964 }
965 } else {
966 pq_release_remote(ip_globals.net_phone,
967 packet_get_id(next));
968 }
969
970 next = new_packet;
971 continue;
972 }
973
974 next = pq_next(next);
975 }
976
977 return packet;
978}
979
980/** Sends the packet or the packet queue via the specified route.
981 *
982 * The ICMP_HOST_UNREACH error notification may be sent if route hardware
983 * destination address is found.
984 *
985 * @param[in,out] packet The packet to be sent.
986 * @param[in] netif The target network interface.
987 * @param[in] route The target route.
988 * @param[in] src The source address.
989 * @param[in] dest The destination address.
990 * @param[in] error The error module service.
991 * @return EOK on success.
992 * @return Other error codes as defined for the arp_translate_req()
993 * function.
994 * @return Other error codes as defined for the ip_prepare_packet()
995 * function.
996 */
997static int
998ip_send_route(packet_t *packet, ip_netif_t *netif, ip_route_t *route,
999 in_addr_t *src, in_addr_t dest, services_t error)
1000{
1001 measured_string_t destination;
1002 measured_string_t *translation;
1003 char *data;
1004 int phone;
1005 int rc;
1006
1007 // get destination hardware address
1008 if (netif->arp && (route->address.s_addr != dest.s_addr)) {
1009 destination.value = route->gateway.s_addr ?
1010 (char *) &route->gateway.s_addr : (char *) &dest.s_addr;
1011 destination.length = CONVERT_SIZE(dest.s_addr, char, 1);
1012
1013 /** Try calling translate several times, then give up */
1014 int count = 0;
1015 do {
1016 rc = arp_translate_req(netif->arp->phone,
1017 netif->device_id, SERVICE_IP, &destination,
1018 &translation, &data);
1019 count++;
1020 } while (rc == EAGAIN && count <= ARP_EAGAIN_MAX_COUNT);
1021 if (rc != EOK) {
1022 pq_release_remote(ip_globals.net_phone,
1023 packet_get_id(packet));
1024 return rc;
1025 }
1026
1027 if (!translation || !translation->value) {
1028 if (translation) {
1029 free(translation);
1030 free(data);
1031 }
1032 phone = ip_prepare_icmp_and_get_phone(error, packet,
1033 NULL);
1034 if (phone >= 0) {
1035 // unreachable ICMP if no routing
1036 icmp_destination_unreachable_msg(phone,
1037 ICMP_HOST_UNREACH, 0, packet);
1038 }
1039 return EINVAL;
1040 }
1041
1042 } else {
1043 translation = NULL;
1044 }
1045
1046 rc = ip_prepare_packet(src, dest, packet, translation);
1047 if (rc != EOK) {
1048 pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
1049 } else {
1050 packet = ip_split_packet(packet, netif->packet_dimension.prefix,
1051 netif->packet_dimension.content,
1052 netif->packet_dimension.suffix,
1053 netif->packet_dimension.addr_len, error);
1054 if (packet) {
1055 nil_send_msg(netif->phone, netif->device_id, packet,
1056 SERVICE_IP);
1057 }
1058 }
1059
1060 if (translation) {
1061 free(translation);
1062 free(data);
1063 }
1064
1065 return rc;
1066}
1067
1068/** Searches the network interfaces if there is a suitable route.
1069 *
1070 * @param[in] netif The network interface to be searched for routes. May be
1071 * NULL.
1072 * @param[in] destination The destination address.
1073 * @return The found route.
1074 * @return NULL if no route was found.
1075 */
1076static ip_route_t *
1077ip_netif_find_route(ip_netif_t *netif, in_addr_t destination)
1078{
1079 int index;
1080 ip_route_t *route;
1081
1082 if (!netif)
1083 return NULL;
1084
1085 // start with the first one - the direct route
1086 for (index = 0; index < ip_routes_count(&netif->routes); index++) {
1087 route = ip_routes_get_index(&netif->routes, index);
1088 if (route &&
1089 ((route->address.s_addr & route->netmask.s_addr) ==
1090 (destination.s_addr & route->netmask.s_addr))) {
1091 return route;
1092 }
1093 }
1094
1095 return NULL;
1096}
1097
1098/** Searches all network interfaces if there is a suitable route.
1099 *
1100 * @param[in] destination The destination address.
1101 * @return The found route.
1102 * @return NULL if no route was found.
1103 */
1104static ip_route_t *ip_find_route(in_addr_t destination) {
1105 int index;
1106 ip_route_t *route;
1107 ip_netif_t *netif;
1108
1109 // start with the last netif - the newest one
1110 index = ip_netifs_count(&ip_globals.netifs) - 1;
1111 while (index >= 0) {
1112 netif = ip_netifs_get_index(&ip_globals.netifs, index);
1113 if (netif && (netif->state == NETIF_ACTIVE)) {
1114 route = ip_netif_find_route(netif, destination);
1115 if (route)
1116 return route;
1117 }
1118 index--;
1119 }
1120
1121 return &ip_globals.gateway;
1122}
1123
1124/** Returns the network interface's IP address.
1125 *
1126 * @param[in] netif The network interface.
1127 * @return The IP address.
1128 * @return NULL if no IP address was found.
1129 */
1130static in_addr_t *ip_netif_address(ip_netif_t *netif)
1131{
1132 ip_route_t *route;
1133
1134 route = ip_routes_get_index(&netif->routes, 0);
1135 return route ? &route->address : NULL;
1136}
1137
1138/** Registers the transport layer protocol.
1139 *
1140 * The traffic of this protocol will be supplied using either the receive
1141 * function or IPC message.
1142 *
1143 * @param[in] protocol The transport layer module protocol.
1144 * @param[in] service The transport layer module service.
1145 * @param[in] phone The transport layer module phone.
1146 * @param[in] received_msg The receiving function.
1147 * @return EOK on success.
1148 * @return EINVAL if the protocol parameter and/or the service
1149 * parameter is zero.
1150 * @return EINVAL if the phone parameter is not a positive number
1151 * and the tl_receive_msg is NULL.
1152 * @return ENOMEM if there is not enough memory left.
1153 */
1154static int
1155ip_register(int protocol, services_t service, int phone,
1156 tl_received_msg_t received_msg)
1157{
1158 ip_proto_t *proto;
1159 int index;
1160
1161 if (!protocol || !service || ((phone < 0) && !received_msg))
1162 return EINVAL;
1163
1164 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
1165 if (!proto)
1166 return ENOMEM;
1167
1168 proto->protocol = protocol;
1169 proto->service = service;
1170 proto->phone = phone;
1171 proto->received_msg = received_msg;
1172
1173 fibril_rwlock_write_lock(&ip_globals.protos_lock);
1174 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
1175 if (index < 0) {
1176 fibril_rwlock_write_unlock(&ip_globals.protos_lock);
1177 free(proto);
1178 return index;
1179 }
1180 fibril_rwlock_write_unlock(&ip_globals.protos_lock);
1181
1182 printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
1183 NAME, proto->protocol, proto->phone);
1184
1185 return EOK;
1186}
1187
1188static int
1189ip_device_req_local(int il_phone, device_id_t device_id, services_t netif)
1190{
1191 ip_netif_t *ip_netif;
1192 ip_route_t *route;
1193 int index;
1194 int rc;
1195
1196 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t));
1197 if (!ip_netif)
1198 return ENOMEM;
1199
1200 rc = ip_routes_initialize(&ip_netif->routes);
1201 if (rc != EOK) {
1202 free(ip_netif);
1203 return rc;
1204 }
1205
1206 ip_netif->device_id = device_id;
1207 ip_netif->service = netif;
1208 ip_netif->state = NETIF_STOPPED;
1209
1210 fibril_rwlock_write_lock(&ip_globals.netifs_lock);
1211
1212 rc = ip_netif_initialize(ip_netif);
1213 if (rc != EOK) {
1214 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
1215 ip_routes_destroy(&ip_netif->routes);
1216 free(ip_netif);
1217 return rc;
1218 }
1219 if (ip_netif->arp)
1220 ip_netif->arp->usage++;
1221
1222 // print the settings
1223 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
1224 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
1225 ip_netif->dhcp ? "dhcp" : "static");
1226
1227 // TODO ipv6 addresses
1228
1229 char address[INET_ADDRSTRLEN];
1230 char netmask[INET_ADDRSTRLEN];
1231 char gateway[INET_ADDRSTRLEN];
1232
1233 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) {
1234 route = ip_routes_get_index(&ip_netif->routes, index);
1235 if (route) {
1236 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr,
1237 address, INET_ADDRSTRLEN);
1238 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr,
1239 netmask, INET_ADDRSTRLEN);
1240 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr,
1241 gateway, INET_ADDRSTRLEN);
1242 printf("%s: Route %d (address: %s, netmask: %s, "
1243 "gateway: %s)\n", NAME, index, address, netmask,
1244 gateway);
1245 }
1246 }
1247
1248 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address,
1249 INET_ADDRSTRLEN);
1250 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
1251
1252 printf("%s: Broadcast (%s)\n", NAME, address);
1253
1254 return EOK;
1255}
1256
1257static int
1258ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet,
1259 services_t sender, services_t error)
1260{
1261 int addrlen;
1262 ip_netif_t *netif;
1263 ip_route_t *route;
1264 struct sockaddr *addr;
1265 struct sockaddr_in *address_in;
1266 in_addr_t *dest;
1267 in_addr_t *src;
1268 int phone;
1269 int rc;
1270
1271 // addresses in the host byte order
1272 // should be the next hop address or the target destination address
1273 addrlen = packet_get_addr(packet, NULL, (uint8_t **) &addr);
1274 if (addrlen < 0)
1275 return ip_release_and_return(packet, addrlen);
1276 if ((size_t) addrlen < sizeof(struct sockaddr))
1277 return ip_release_and_return(packet, EINVAL);
1278
1279 switch (addr->sa_family) {
1280 case AF_INET:
1281 if (addrlen != sizeof(struct sockaddr_in))
1282 return ip_release_and_return(packet, EINVAL);
1283 address_in = (struct sockaddr_in *) addr;
1284 dest = &address_in->sin_addr;
1285 if (!dest->s_addr)
1286 dest->s_addr = IPV4_LOCALHOST_ADDRESS;
1287 break;
1288 case AF_INET6:
1289 default:
1290 return ip_release_and_return(packet, EAFNOSUPPORT);
1291 }
1292
1293 netif = NULL;
1294 route = NULL;
1295 fibril_rwlock_read_lock(&ip_globals.netifs_lock);
1296
1297 // device specified?
1298 if (device_id > 0) {
1299 netif = ip_netifs_find(&ip_globals.netifs, device_id);
1300 route = ip_netif_find_route(netif, * dest);
1301 if (netif && !route && (ip_globals.gateway.netif == netif))
1302 route = &ip_globals.gateway;
1303 }
1304
1305 if (!route) {
1306 route = ip_find_route(*dest);
1307 netif = route ? route->netif : NULL;
1308 }
1309 if (!netif || !route) {
1310 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
1311 phone = ip_prepare_icmp_and_get_phone(error, packet, NULL);
1312 if (phone >= 0) {
1313 // unreachable ICMP if no routing
1314 icmp_destination_unreachable_msg(phone,
1315 ICMP_NET_UNREACH, 0, packet);
1316 }
1317 return ENOENT;
1318 }
1319
1320 if (error) {
1321 // do not send for broadcast, anycast packets or network
1322 // broadcast
1323 if (!dest->s_addr || !(~dest->s_addr) ||
1324 !(~((dest->s_addr & ~route->netmask.s_addr) |
1325 route->netmask.s_addr)) ||
1326 (!(dest->s_addr & ~route->netmask.s_addr))) {
1327 return ip_release_and_return(packet, EINVAL);
1328 }
1329 }
1330
1331 // if the local host is the destination
1332 if ((route->address.s_addr == dest->s_addr) &&
1333 (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) {
1334 // find the loopback device to deliver
1335 dest->s_addr = IPV4_LOCALHOST_ADDRESS;
1336 route = ip_find_route(*dest);
1337 netif = route ? route->netif : NULL;
1338 if (!netif || !route) {
1339 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
1340 phone = ip_prepare_icmp_and_get_phone(error, packet,
1341 NULL);
1342 if (phone >= 0) {
1343 // unreachable ICMP if no routing
1344 icmp_destination_unreachable_msg(phone,
1345 ICMP_HOST_UNREACH, 0, packet);
1346 }
1347 return ENOENT;
1348 }
1349 }
1350
1351 src = ip_netif_address(netif);
1352 if (!src) {
1353 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
1354 return ip_release_and_return(packet, ENOENT);
1355 }
1356
1357 rc = ip_send_route(packet, netif, route, src, *dest, error);
1358 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
1359
1360 return rc;
1361}
1362
1363/** Returns the device packet dimensions for sending.
1364 *
1365 * @param[in] phone The service module phone.
1366 * @param[in] message The service specific message.
1367 * @param[in] device_id The device identifier.
1368 * @param[out] addr_len The minimum reserved address length.
1369 * @param[out] prefix The minimum reserved prefix size.
1370 * @param[out] content The maximum content size.
1371 * @param[out] suffix The minimum reserved suffix size.
1372 * @return EOK on success.
1373 */
1374static int
1375ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix,
1376 size_t *content, size_t *suffix)
1377{
1378 ip_netif_t *netif;
1379 int index;
1380
1381 if (!addr_len || !prefix || !content || !suffix)
1382 return EBADMEM;
1383
1384 *content = IP_MAX_CONTENT - IP_PREFIX;
1385 fibril_rwlock_read_lock(&ip_globals.netifs_lock);
1386 if (device_id < 0) {
1387 *addr_len = IP_ADDR;
1388 *prefix = 0;
1389 *suffix = 0;
1390
1391 for (index = ip_netifs_count(&ip_globals.netifs) - 1;
1392 index >= 0; index--) {
1393 netif = ip_netifs_get_index(&ip_globals.netifs, index);
1394 if (!netif)
1395 continue;
1396
1397 if (netif->packet_dimension.addr_len > *addr_len)
1398 *addr_len = netif->packet_dimension.addr_len;
1399
1400 if (netif->packet_dimension.prefix > *prefix)
1401 *prefix = netif->packet_dimension.prefix;
1402
1403 if (netif->packet_dimension.suffix > *suffix)
1404 *suffix = netif->packet_dimension.suffix;
1405 }
1406
1407 *prefix = *prefix + IP_PREFIX;
1408 *suffix = *suffix + IP_SUFFIX;
1409 } else {
1410 netif = ip_netifs_find(&ip_globals.netifs, device_id);
1411 if (!netif) {
1412 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
1413 return ENOENT;
1414 }
1415
1416 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?
1417 netif->packet_dimension.addr_len : IP_ADDR;
1418 *prefix = netif->packet_dimension.prefix + IP_PREFIX;
1419 *suffix = netif->packet_dimension.suffix + IP_SUFFIX;
1420 }
1421 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
1422
1423 return EOK;
1424}
1425
1426/** Returns the packet destination address from the IP header.
1427 *
1428 * @param[in] header The packet IP header to be read.
1429 * @return The packet destination address.
1430 */
1431static in_addr_t ip_get_destination(ip_header_t *header)
1432{
1433 in_addr_t destination;
1434
1435 // TODO search set ipopt route?
1436 destination.s_addr = header->destination_address;
1437 return destination;
1438}
1439
1440/** Delivers the packet to the local host.
1441 *
1442 * The packet is either passed to another module or released on error.
1443 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not
1444 * found.
1445 *
1446 * @param[in] device_id The source device identifier.
1447 * @param[in] packet The packet to be delivered.
1448 * @param[in] header The first packet IP header. May be NULL.
1449 * @param[in] error The packet error service.
1450 * @return EOK on success.
1451 * @return ENOTSUP if the packet is a fragment.
1452 * @return EAFNOSUPPORT if the address family is not supported.
1453 * @return ENOENT if the target protocol is not found.
1454 * @return Other error codes as defined for the packet_set_addr()
1455 * function.
1456 * @return Other error codes as defined for the packet_trim()
1457 * function.
1458 * @return Other error codes as defined for the protocol specific
1459 * tl_received_msg() function.
1460 */
1461static int
1462ip_deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header,
1463 services_t error)
1464{
1465 ip_proto_t *proto;
1466 int phone;
1467 services_t service;
1468 tl_received_msg_t received_msg;
1469 struct sockaddr *src;
1470 struct sockaddr *dest;
1471 struct sockaddr_in src_in;
1472 struct sockaddr_in dest_in;
1473 socklen_t addrlen;
1474 int rc;
1475
1476 if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
1477 IP_FRAGMENT_OFFSET(header)) {
1478 // TODO fragmented
1479 return ENOTSUP;
1480 }
1481
1482 switch (header->version) {
1483 case IPVERSION:
1484 addrlen = sizeof(src_in);
1485 bzero(&src_in, addrlen);
1486 src_in.sin_family = AF_INET;
1487 memcpy(&dest_in, &src_in, addrlen);
1488 memcpy(&src_in.sin_addr.s_addr, &header->source_address,
1489 sizeof(header->source_address));
1490 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address,
1491 sizeof(header->destination_address));
1492 src = (struct sockaddr *) &src_in;
1493 dest = (struct sockaddr *) &dest_in;
1494 break;
1495
1496 default:
1497 return ip_release_and_return(packet, EAFNOSUPPORT);
1498 }
1499
1500 rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest,
1501 addrlen);
1502 if (rc != EOK)
1503 return ip_release_and_return(packet, rc);
1504
1505 // trim padding if present
1506 if (!error &&
1507 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) {
1508 rc = packet_trim(packet, 0,
1509 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header));
1510 if (rc != EOK)
1511 return ip_release_and_return(packet, rc);
1512 }
1513
1514 fibril_rwlock_read_lock(&ip_globals.protos_lock);
1515
1516 proto = ip_protos_find(&ip_globals.protos, header->protocol);
1517 if (!proto) {
1518 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
1519 phone = ip_prepare_icmp_and_get_phone(error, packet, header);
1520 if (phone >= 0) {
1521 // unreachable ICMP
1522 icmp_destination_unreachable_msg(phone,
1523 ICMP_PROT_UNREACH, 0, packet);
1524 }
1525 return ENOENT;
1526 }
1527
1528 if (proto->received_msg) {
1529 service = proto->service;
1530 received_msg = proto->received_msg;
1531 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
1532 rc = received_msg(device_id, packet, service, error);
1533 } else {
1534 rc = tl_received_msg(proto->phone, device_id, packet,
1535 proto->service, error);
1536 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
1537 }
1538
1539 return rc;
1540}
1541
1542/** Processes the received packet.
1543 *
1544 * The packet is either passed to another module or released on error.
1545 *
1546 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is
1547 * invalid.
1548 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two.
1549 * The ICMP_HOST_UNREACH error notification may be sent if no route was found.
1550 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for
1551 * another host and the routing is disabled.
1552 *
1553 * @param[in] device_id The source device identifier.
1554 * @param[in] packet The received packet to be processed.
1555 * @return EOK on success.
1556 * @return EINVAL if the TTL is less than two.
1557 * @return EINVAL if the checksum is invalid.
1558 * @return EAFNOSUPPORT if the address family is not supported.
1559 * @return ENOENT if no route was found.
1560 * @return ENOENT if the packet is for another host and the routing
1561 * is disabled.
1562 */
1563static int
1564ip_process_packet(device_id_t device_id, packet_t *packet)
1565{
1566 ip_header_t *header;
1567 in_addr_t dest;
1568 ip_route_t *route;
1569 int phone;
1570 struct sockaddr *addr;
1571 struct sockaddr_in addr_in;
1572 socklen_t addrlen;
1573 int rc;
1574
1575 header = (ip_header_t *) packet_get_data(packet);
1576 if (!header)
1577 return ip_release_and_return(packet, ENOMEM);
1578
1579 // checksum
1580 if ((header->header_checksum) &&
1581 (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
1582 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
1583 if (phone >= 0) {
1584 // checksum error ICMP
1585 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
1586 ((size_t) ((void *) &header->header_checksum)) -
1587 ((size_t) ((void *) header)), packet);
1588 }
1589 return EINVAL;
1590 }
1591
1592 if (header->ttl <= 1) {
1593 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
1594 if (phone >= 0) {
1595 // ttl exceeded ICMP
1596 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
1597 }
1598 return EINVAL;
1599 }
1600
1601 // process ipopt and get destination
1602 dest = ip_get_destination(header);
1603
1604 // set the addrination address
1605 switch (header->version) {
1606 case IPVERSION:
1607 addrlen = sizeof(addr_in);
1608 bzero(&addr_in, addrlen);
1609 addr_in.sin_family = AF_INET;
1610 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest));
1611 addr = (struct sockaddr *) &addr_in;
1612 break;
1613
1614 default:
1615 return ip_release_and_return(packet, EAFNOSUPPORT);
1616 }
1617
1618 rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen);
1619 if (rc != EOK)
1620 return rc;
1621
1622 route = ip_find_route(dest);
1623 if (!route) {
1624 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
1625 if (phone >= 0) {
1626 // unreachable ICMP
1627 icmp_destination_unreachable_msg(phone,
1628 ICMP_HOST_UNREACH, 0, packet);
1629 }
1630 return ENOENT;
1631 }
1632
1633 if (route->address.s_addr == dest.s_addr) {
1634 // local delivery
1635 return ip_deliver_local(device_id, packet, header, 0);
1636 }
1637
1638 if (route->netif->routing) {
1639 header->ttl--;
1640 return ip_send_route(packet, route->netif, route, NULL, dest,
1641 0);
1642 }
1643
1644 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
1645 if (phone >= 0) {
1646 // unreachable ICMP if no routing
1647 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
1648 packet);
1649 }
1650
1651 return ENOENT;
1652}
1653
1654static int
1655ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address,
1656 in_addr_t netmask, in_addr_t gateway)
1657{
1658 ip_route_t *route;
1659 ip_netif_t *netif;
1660 int index;
1661
1662 fibril_rwlock_write_lock(&ip_globals.netifs_lock);
1663
1664 netif = ip_netifs_find(&ip_globals.netifs, device_id);
1665 if (!netif) {
1666 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
1667 return ENOENT;
1668 }
1669
1670 route = (ip_route_t *) malloc(sizeof(ip_route_t));
1671 if (!route) {
1672 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
1673 return ENOMEM;
1674 }
1675
1676 route->address.s_addr = address.s_addr;
1677 route->netmask.s_addr = netmask.s_addr;
1678 route->gateway.s_addr = gateway.s_addr;
1679 route->netif = netif;
1680 index = ip_routes_add(&netif->routes, route);
1681 if (index < 0)
1682 free(route);
1683
1684 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
1685
1686 return index;
1687}
1688
1689static int
1690ip_set_gateway_req_local(int ip_phone, device_id_t device_id, in_addr_t gateway)
1691{
1692 ip_netif_t *netif;
1693
1694 fibril_rwlock_write_lock(&ip_globals.netifs_lock);
1695
1696 netif = ip_netifs_find(&ip_globals.netifs, device_id);
1697 if (!netif) {
1698 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
1699 return ENOENT;
1700 }
1701
1702 ip_globals.gateway.address.s_addr = 0;
1703 ip_globals.gateway.netmask.s_addr = 0;
1704 ip_globals.gateway.gateway.s_addr = gateway.s_addr;
1705 ip_globals.gateway.netif = netif;
1706
1707 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
1708
1709 return EOK;
1710}
1711
1712/** Notify the IP module about the received error notification packet.
1713 *
1714 * @param[in] ip_phone The IP module phone used for (semi)remote calls.
1715 * @param[in] device_id The device identifier.
1716 * @param[in] packet The received packet or the received packet queue.
1717 * @param[in] target The target internetwork module service to be
1718 * delivered to.
1719 * @param[in] error The packet error reporting service. Prefixes the
1720 * received packet.
1721 * @return EOK on success.
1722 *
1723 */
1724static int
1725ip_received_error_msg_local(int ip_phone, device_id_t device_id,
1726 packet_t *packet, services_t target, services_t error)
1727{
1728 uint8_t *data;
1729 int offset;
1730 icmp_type_t type;
1731 icmp_code_t code;
1732 ip_netif_t *netif;
1733 measured_string_t address;
1734 ip_route_t *route;
1735 ip_header_t *header;
1736
1737 switch (error) {
1738 case SERVICE_ICMP:
1739 offset = icmp_client_process_packet(packet, &type, &code, NULL,
1740 NULL);
1741 if (offset < 0)
1742 return ip_release_and_return(packet, ENOMEM);
1743
1744 data = packet_get_data(packet);
1745 header = (ip_header_t *)(data + offset);
1746
1747 // destination host unreachable?
1748 if ((type != ICMP_DEST_UNREACH) ||
1749 (code != ICMP_HOST_UNREACH)) {
1750 // no, something else
1751 break;
1752 }
1753
1754 fibril_rwlock_read_lock(&ip_globals.netifs_lock);
1755
1756 netif = ip_netifs_find(&ip_globals.netifs, device_id);
1757 if (!netif || !netif->arp) {
1758 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
1759 break;
1760 }
1761
1762 route = ip_routes_get_index(&netif->routes, 0);
1763
1764 // from the same network?
1765 if (route && ((route->address.s_addr & route->netmask.s_addr) ==
1766 (header->destination_address & route->netmask.s_addr))) {
1767 // clear the ARP mapping if any
1768 address.value = (char *) &header->destination_address;
1769 address.length = CONVERT_SIZE(uint8_t, char,
1770 sizeof(header->destination_address));
1771 arp_clear_address_req(netif->arp->phone,
1772 netif->device_id, SERVICE_IP, &address);
1773 }
1774
1775 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
1776 break;
1777
1778 default:
1779 return ip_release_and_return(packet, ENOTSUP);
1780 }
1781
1782 return ip_deliver_local(device_id, packet, header, error);
1783}
1784
1785static int
1786ip_get_route_req_local(int ip_phone, ip_protocol_t protocol,
1787 const struct sockaddr *destination, socklen_t addrlen,
1788 device_id_t *device_id, void **header, size_t *headerlen)
1789{
1790 struct sockaddr_in *address_in;
1791 in_addr_t *dest;
1792 in_addr_t *src;
1793 ip_route_t *route;
1794 ipv4_pseudo_header_t *header_in;
1795
1796 if (!destination || (addrlen <= 0))
1797 return EINVAL;
1798
1799 if (!device_id || !header || !headerlen)
1800 return EBADMEM;
1801
1802 if ((size_t) addrlen < sizeof(struct sockaddr))
1803 return EINVAL;
1804
1805 switch (destination->sa_family) {
1806 case AF_INET:
1807 if (addrlen != sizeof(struct sockaddr_in))
1808 return EINVAL;
1809 address_in = (struct sockaddr_in *) destination;
1810 dest = &address_in->sin_addr;
1811 if (!dest->s_addr)
1812 dest->s_addr = IPV4_LOCALHOST_ADDRESS;
1813 break;
1814
1815 case AF_INET6:
1816 default:
1817 return EAFNOSUPPORT;
1818 }
1819
1820 fibril_rwlock_read_lock(&ip_globals.lock);
1821 route = ip_find_route(*dest);
1822 // if the local host is the destination
1823 if (route && (route->address.s_addr == dest->s_addr) &&
1824 (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) {
1825 // find the loopback device to deliver
1826 dest->s_addr = IPV4_LOCALHOST_ADDRESS;
1827 route = ip_find_route(*dest);
1828 }
1829
1830 if (!route || !route->netif) {
1831 fibril_rwlock_read_unlock(&ip_globals.lock);
1832 return ENOENT;
1833 }
1834
1835 *device_id = route->netif->device_id;
1836 src = ip_netif_address(route->netif);
1837 fibril_rwlock_read_unlock(&ip_globals.lock);
1838
1839 *headerlen = sizeof(*header_in);
1840 header_in = (ipv4_pseudo_header_t *) malloc(*headerlen);
1841 if (!header_in)
1842 return ENOMEM;
1843
1844 bzero(header_in, *headerlen);
1845 header_in->destination_address = dest->s_addr;
1846 header_in->source_address = src->s_addr;
1847 header_in->protocol = protocol;
1848 header_in->data_length = 0;
1849 *header = header_in;
1850
1851 return EOK;
1852}
1853
1854/** Processes the received IP packet or the packet queue one by one.
1855 *
1856 * The packet is either passed to another module or released on error.
1857 *
1858 * @param[in] device_id The source device identifier.
1859 * @param[in,out] packet The received packet.
1860 * @return EOK on success and the packet is no longer needed.
1861 * @return EINVAL if the packet is too small to carry the IP
1862 * packet.
1863 * @return EINVAL if the received address lengths differs from the
1864 * registered values.
1865 * @return ENOENT if the device is not found in the cache.
1866 * @return ENOENT if the protocol for the device is not found in
1867 * the cache.
1868 * @return ENOMEM if there is not enough memory left.
1869 */
1870static int ip_receive_message(device_id_t device_id, packet_t *packet)
1871{
1872 packet_t *next;
1873
1874 do {
1875 next = pq_detach(packet);
1876 ip_process_packet(device_id, packet);
1877 packet = next;
1878 } while (packet);
1879
1880 return EOK;
1881}
1882
1883/** Processes the IP message.
1884 *
1885 * @param[in] callid The message identifier.
1886 * @param[in] call The message parameters.
1887 * @param[out] answer The message answer parameters.
1888 * @param[out] answer_count The last parameter for the actual answer in the
1889 * answer parameter.
1890 * @return EOK on success.
1891 * @return ENOTSUP if the message is not known.
1892 *
1893 * @see ip_interface.h
1894 * @see il_interface.h
1895 * @see IS_NET_IP_MESSAGE()
1896 */
1897int
1898ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
1899 int *answer_count)
1900{
1901 packet_t *packet;
1902 struct sockaddr *addr;
1903 size_t addrlen;
1904 size_t prefix;
1905 size_t suffix;
1906 size_t content;
1907 void *header;
1908 size_t headerlen;
1909 device_id_t device_id;
1910 int rc;
1911
1912 *answer_count = 0;
1913 switch (IPC_GET_METHOD(*call)) {
1914 case IPC_M_PHONE_HUNGUP:
1915 return EOK;
1916
1917 case IPC_M_CONNECT_TO_ME:
1918 return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call),
1919 IPC_GET_PHONE(call), NULL);
1920
1921 case NET_IL_DEVICE:
1922 return ip_device_req_local(0, IPC_GET_DEVICE(call),
1923 IPC_GET_SERVICE(call));
1924
1925 case NET_IL_SEND:
1926 rc = packet_translate_remote(ip_globals.net_phone, &packet,
1927 IPC_GET_PACKET(call));
1928 if (rc != EOK)
1929 return rc;
1930 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0,
1931 IPC_GET_ERROR(call));
1932
1933 case NET_IL_DEVICE_STATE:
1934 return ip_device_state_message(IPC_GET_DEVICE(call),
1935 IPC_GET_STATE(call));
1936
1937 case NET_IL_RECEIVED:
1938 rc = packet_translate_remote(ip_globals.net_phone, &packet,
1939 IPC_GET_PACKET(call));
1940 if (rc != EOK)
1941 return rc;
1942 return ip_receive_message(IPC_GET_DEVICE(call), packet);
1943
1944 case NET_IP_RECEIVED_ERROR:
1945 rc = packet_translate_remote(ip_globals.net_phone, &packet,
1946 IPC_GET_PACKET(call));
1947 if (rc != EOK)
1948 return rc;
1949 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call),
1950 packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));
1951
1952 case NET_IP_ADD_ROUTE:
1953 return ip_add_route_req_local(0, IPC_GET_DEVICE(call),
1954 IP_GET_ADDRESS(call), IP_GET_NETMASK(call),
1955 IP_GET_GATEWAY(call));
1956
1957 case NET_IP_SET_GATEWAY:
1958 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(call),
1959 IP_GET_GATEWAY(call));
1960
1961 case NET_IP_GET_ROUTE:
1962 rc = data_receive((void **) &addr, &addrlen);
1963 if (rc != EOK)
1964 return rc;
1965
1966 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(call), addr,
1967 (socklen_t) addrlen, &device_id, &header, &headerlen);
1968 if (rc != EOK)
1969 return rc;
1970
1971 IPC_SET_DEVICE(answer, device_id);
1972 IP_SET_HEADERLEN(answer, headerlen);
1973
1974 *answer_count = 2;
1975
1976 rc = data_reply(&headerlen, sizeof(headerlen));
1977 if (rc == EOK)
1978 rc = data_reply(header, headerlen);
1979
1980 free(header);
1981 return rc;
1982
1983 case NET_IL_PACKET_SPACE:
1984 rc = ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen,
1985 &prefix, &content, &suffix);
1986 if (rc != EOK)
1987 return rc;
1988
1989 IPC_SET_ADDR(answer, addrlen);
1990 IPC_SET_PREFIX(answer, prefix);
1991 IPC_SET_CONTENT(answer, content);
1992 IPC_SET_SUFFIX(answer, suffix);
1993 *answer_count = 4;
1994 return EOK;
1995
1996 case NET_IL_MTU_CHANGED:
1997 return ip_mtu_changed_message(IPC_GET_DEVICE(call),
1998 IPC_GET_MTU(call));
1999 }
2000
2001 return ENOTSUP;
2002}
2003
2004/** Default thread for new connections.
2005 *
2006 * @param[in] iid The initial message identifier.
2007 * @param[in] icall The initial message call structure.
2008 */
2009static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
2010{
2011 /*
2012 * Accept the connection
2013 * - Answer the first IPC_M_CONNECT_ME_TO call.
2014 */
2015 ipc_answer_0(iid, EOK);
2016
2017 while (true) {
2018 ipc_call_t answer;
2019 int answer_count;
2020
2021 /* Clear the answer structure */
2022 refresh_answer(&answer, &answer_count);
2023
2024 /* Fetch the next message */
2025 ipc_call_t call;
2026 ipc_callid_t callid = async_get_call(&call);
2027
2028 /* Process the message */
2029 int res = il_module_message_standalone(callid, &call, &answer,
2030 &answer_count);
2031
2032 /*
2033 * End if told to either by the message or the processing
2034 * result.
2035 */
2036 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
2037 (res == EHANGUP)) {
2038 return;
2039 }
2040
2041 /* Answer the message */
2042 answer_call(callid, res, &answer, answer_count);
2043 }
2044}
2045
2046/** Starts the module.
2047 *
2048 * @return EOK on success.
2049 * @return Other error codes as defined for each specific module start function.
2050 */
2051int main(int argc, char *argv[])
2052{
2053 int rc;
2054
2055 /* Start the module */
2056 rc = il_module_start_standalone(il_client_connection);
2057 return rc;
2058}
2059
2060/** @}
2061 */
Note: See TracBrowser for help on using the repository browser.