Subversion Repositories HelenOS

Rev

Rev 4728 | Rev 4735 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4728 Rev 4731
1
/*
1
/*
2
 * Copyright (c) 2009 Lukas Mejdrech
2
 * Copyright (c) 2009 Lukas Mejdrech
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup ip
29
/** @addtogroup ip
30
 *  @{
30
 *  @{
31
 */
31
 */
32
 
32
 
33
/** @file
33
/** @file
34
 *  IP module implementation.
34
 *  IP module implementation.
35
 *  @see arp.h
35
 *  @see arp.h
36
 *  \todo
36
 *  \todo
37
 */
37
 */
38
 
38
 
39
#include <async.h>
39
#include <async.h>
40
#include <errno.h>
40
#include <errno.h>
41
#include <fibril_sync.h>
41
#include <fibril_sync.h>
42
#include <stdio.h>
42
#include <stdio.h>
43
#include <string.h>
43
#include <string.h>
44
 
44
 
45
#include <ipc/ipc.h>
45
#include <ipc/ipc.h>
46
#include <ipc/services.h>
46
#include <ipc/services.h>
47
 
47
 
48
#include <sys/types.h>
48
#include <sys/types.h>
49
 
49
 
50
#include "../../err.h"
50
#include "../../err.h"
51
#include "../../messages.h"
51
#include "../../messages.h"
52
#include "../../modules.h"
52
#include "../../modules.h"
53
 
53
 
54
#include "../../include/arp_interface.h"
54
#include "../../include/arp_interface.h"
55
#include "../../include/byteorder.h"
55
#include "../../include/byteorder.h"
56
#include "../../include/crc.h"
56
#include "../../include/crc.h"
57
#include "../../include/device.h"
57
#include "../../include/device.h"
58
#include "../../include/icmp_client.h"
58
#include "../../include/icmp_client.h"
59
#include "../../include/icmp_codes.h"
59
#include "../../include/icmp_codes.h"
60
#include "../../include/icmp_interface.h"
60
#include "../../include/icmp_interface.h"
61
#include "../../include/il_interface.h"
61
#include "../../include/il_interface.h"
62
#include "../../include/in.h"
62
#include "../../include/in.h"
63
#include "../../include/in6.h"
63
#include "../../include/in6.h"
64
#include "../../include/inet.h"
64
#include "../../include/inet.h"
65
#include "../../include/ip_client.h"
65
#include "../../include/ip_client.h"
66
#include "../../include/ip_interface.h"
66
#include "../../include/ip_interface.h"
67
#include "../../include/net_interface.h"
67
#include "../../include/net_interface.h"
68
#include "../../include/nil_interface.h"
68
#include "../../include/nil_interface.h"
69
#include "../../include/tl_interface.h"
69
#include "../../include/tl_interface.h"
70
#include "../../include/socket_codes.h"
70
#include "../../include/socket_codes.h"
71
#include "../../include/socket_errno.h"
71
#include "../../include/socket_errno.h"
72
#include "../../structures/measured_strings.h"
72
#include "../../structures/measured_strings.h"
73
#include "../../structures/module_map.h"
73
#include "../../structures/module_map.h"
74
#include "../../structures/packet/packet_client.h"
74
#include "../../structures/packet/packet_client.h"
75
 
75
 
76
#include "../../nil/nil_messages.h"
76
#include "../../nil/nil_messages.h"
77
 
77
 
78
#include "../il_messages.h"
78
#include "../il_messages.h"
79
 
79
 
80
#include "ip.h"
80
#include "ip.h"
81
#include "ip_header.h"
81
#include "ip_header.h"
82
#include "ip_messages.h"
82
#include "ip_messages.h"
83
#include "ip_module.h"
83
#include "ip_module.h"
84
 
84
 
85
/** IP version 4.
85
/** IP version 4.
86
 */
86
 */
87
#define IPV4                4
87
#define IPV4                4
88
 
88
 
89
/** Default network interface IP version.
89
/** Default network interface IP version.
90
 */
90
 */
91
#define NET_DEFAULT_IPV     IPV4
91
#define NET_DEFAULT_IPV     IPV4
92
 
92
 
93
/** Default network interface IP routing.
93
/** Default network interface IP routing.
94
 */
94
 */
95
#define NET_DEFAULT_IP_ROUTING  false
95
#define NET_DEFAULT_IP_ROUTING  false
96
 
96
 
97
/** Minimum IP packet content.
97
/** Minimum IP packet content.
98
 */
98
 */
99
#define IP_MIN_CONTENT  576
99
#define IP_MIN_CONTENT  576
100
 
100
 
101
/** ARP module name.
101
/** ARP module name.
102
 */
102
 */
103
#define ARP_NAME                "arp"
103
#define ARP_NAME                "arp"
104
 
104
 
105
/** ARP module filename.
105
/** ARP module filename.
106
 */
106
 */
107
#define ARP_FILENAME            "/srv/arp"
107
#define ARP_FILENAME            "/srv/arp"
108
 
108
 
109
/** IP packet address length.
109
/** IP packet address length.
110
 */
110
 */
111
#define IP_ADDR                         sizeof( struct sockaddr_in6 )
111
#define IP_ADDR                         sizeof( struct sockaddr_in6 )
112
 
112
 
113
/** IP packet prefix length.
113
/** IP packet prefix length.
114
 */
114
 */
115
#define IP_PREFIX                       sizeof( ip_header_t )
115
#define IP_PREFIX                       sizeof( ip_header_t )
116
 
116
 
117
/** IP packet suffix length.
117
/** IP packet suffix length.
118
 */
118
 */
119
#define IP_SUFFIX                       0
119
#define IP_SUFFIX                       0
120
 
120
 
121
/** IP packet maximum content length.
121
/** IP packet maximum content length.
122
 */
122
 */
123
#define IP_MAX_CONTENT                  65535
123
#define IP_MAX_CONTENT                  65535
124
 
124
 
125
/** The IP localhost address.
125
/** The IP localhost address.
126
 */
126
 */
127
#define IPV4_LOCALHOST_ADDRESS  htonl(( 127 << 24 ) + 1 )
127
#define IPV4_LOCALHOST_ADDRESS  htonl(( 127 << 24 ) + 1 )
128
 
128
 
129
/** IP global data.
129
/** IP global data.
130
 */
130
 */
131
ip_globals_t    ip_globals;
131
ip_globals_t    ip_globals;
132
 
132
 
133
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
133
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
134
 
134
 
135
INT_MAP_IMPLEMENT( ip_protos, ip_proto_t )
135
INT_MAP_IMPLEMENT( ip_protos, ip_proto_t )
136
 
136
 
137
GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t )
137
GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t )
138
 
138
 
139
/** Updates the device content length according to the new MTU value.
139
/** Updates the device content length according to the new MTU value.
140
 *  @param device_id The device identifier. Input parameter.
140
 *  @param device_id The device identifier. Input parameter.
141
 *  @param mtu The new mtu value. Input parameter.
141
 *  @param mtu The new mtu value. Input parameter.
142
 *  @returns EOK on success.
142
 *  @returns EOK on success.
143
 *  @returns ENOENT if device is not found.
143
 *  @returns ENOENT if device is not found.
144
 */
144
 */
145
int ip_mtu_changed_message( device_id_t device_id, size_t mtu );
145
int ip_mtu_changed_message( device_id_t device_id, size_t mtu );
146
 
146
 
147
/** Updates the device state.
147
/** Updates the device state.
148
 *  @param device_id The device identifier. Input parameter.
148
 *  @param device_id The device identifier. Input parameter.
149
 *  @param state The new state value. Input parameter.
149
 *  @param state The new state value. Input parameter.
150
 *  @returns EOK on success.
150
 *  @returns EOK on success.
151
 *  @returns ENOENT if device is not found.
151
 *  @returns ENOENT if device is not found.
152
 */
152
 */
153
int ip_device_state_message( device_id_t device_id, device_state_t state );
153
int ip_device_state_message( device_id_t device_id, device_state_t state );
154
 
154
 
155
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg );
155
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg );
156
 
156
 
157
/** Initializes a new network interface specific data.
157
/** Initializes a new network interface specific data.
158
 *  Connects to the network interface layer module, reads the netif configuration, starts an ARP module if needed and sets the netif routing table.
158
 *  Connects to the network interface layer module, reads the netif configuration, starts an ARP module if needed and sets the netif routing table.
159
 *  The device identifier and the nil service has to be set.
159
 *  The device identifier and the nil service has to be set.
160
 *  @param ip_netif Network interface specific data. Input/output parameter.
160
 *  @param ip_netif Network interface specific data. Input/output parameter.
161
 *  @returns EOK on success.
161
 *  @returns EOK on success.
162
 *  @returns ENOTSUP if DHCP is configured.
162
 *  @returns ENOTSUP if DHCP is configured.
163
 *  @returns ENOTSUP if IPv6 is configured.
163
 *  @returns ENOTSUP if IPv6 is configured.
164
 *  @returns EINVAL if any of the addresses is invalid.
164
 *  @returns EINVAL if any of the addresses is invalid.
165
 *  @returns EINVAL if the used ARP module is not known.
165
 *  @returns EINVAL if the used ARP module is not known.
166
 *  @returns ENOMEM if there is not enough memory left.
166
 *  @returns ENOMEM if there is not enough memory left.
167
 *  @returns Other error codes as defined for the net_get_device_conf_req() function.
167
 *  @returns Other error codes as defined for the net_get_device_conf_req() function.
168
 *  @returns Other error codes as defined for the bind_service() function.
168
 *  @returns Other error codes as defined for the bind_service() function.
169
 *  @returns Other error codes as defined for the specific arp_device_req() function.
169
 *  @returns Other error codes as defined for the specific arp_device_req() function.
170
 *  @returns Other error codes as defined for the nil_packet_size_req() function.
170
 *  @returns Other error codes as defined for the nil_packet_size_req() function.
171
 */
171
 */
172
int ip_netif_initialize( ip_netif_ref ip_netif );
172
int ip_netif_initialize( ip_netif_ref ip_netif );
173
 
173
 
174
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error );
174
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error );
175
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination );
175
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination );
176
 
176
 
177
packet_t    ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error );
177
packet_t    ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error );
178
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len );
178
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len );
179
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen );
179
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen );
180
ip_header_ref   ip_create_middle_header( packet_t packet, ip_header_ref last );
180
ip_header_ref   ip_create_middle_header( packet_t packet, ip_header_ref last );
181
void ip_create_last_header( ip_header_ref last, ip_header_ref first );
181
void ip_create_last_header( ip_header_ref last, ip_header_ref first );
182
 
182
 
183
in_addr_t * ip_netif_address( ip_netif_ref netif );
183
in_addr_t * ip_netif_address( ip_netif_ref netif );
184
ip_route_ref    ip_find_route( in_addr_t destination );
184
ip_route_ref    ip_find_route( in_addr_t destination );
185
ip_route_ref    ip_netif_find_route( ip_netif_ref netif, in_addr_t destination );
185
ip_route_ref    ip_netif_find_route( ip_netif_ref netif, in_addr_t destination );
186
 
186
 
187
/** Processes the received IP packet.
187
/** Processes the received IP packet.
188
 *  @param device_id The source device identifier. Input parameter.
188
 *  @param device_id The source device identifier. Input parameter.
189
 *  @param packet The received packet. Input/output parameter.
189
 *  @param packet The received packet. Input/output parameter.
190
 *  @returns EOK on success and the packet is no longer needed.
190
 *  @returns EOK on success and the packet is no longer needed.
191
 *  @returns EINVAL if the packet is too small to carry the IP packet.
191
 *  @returns EINVAL if the packet is too small to carry the IP packet.
192
 *  @returns EINVAL if the received address lengths differs from the registered values.
192
 *  @returns EINVAL if the received address lengths differs from the registered values.
193
 *  @returns ENOENT if the device is not found in the cache.
193
 *  @returns ENOENT if the device is not found in the cache.
194
 *  @returns ENOENT if the protocol for the device is not found in the cache.
194
 *  @returns ENOENT if the protocol for the device is not found in the cache.
195
 *  @returns ENOMEM if there is not enough memory left.
195
 *  @returns ENOMEM if there is not enough memory left.
196
 */
196
 */
197
int ip_receive_message( device_id_t device_id, packet_t packet );
197
int ip_receive_message( device_id_t device_id, packet_t packet );
198
 
198
 
199
int ip_process_packet( device_id_t device_id, packet_t packet );
199
int ip_process_packet( device_id_t device_id, packet_t packet );
200
in_addr_t   ip_get_destination( ip_header_ref header );
200
in_addr_t   ip_get_destination( ip_header_ref header );
201
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error );
201
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error );
202
 
202
 
203
int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header );
203
int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header );
204
int ip_get_icmp_phone( void );
204
int ip_get_icmp_phone( void );
205
int ip_prepare_icmp( packet_t packet, ip_header_ref header );
205
int ip_prepare_icmp( packet_t packet, ip_header_ref header );
206
 
206
 
207
int ip_release_and_return( packet_t packet, int result );
207
int ip_release_and_return( packet_t packet, int result );
208
 
208
 
209
int ip_initialize( async_client_conn_t client_connection ){
209
int ip_initialize( async_client_conn_t client_connection ){
210
    ERROR_DECLARE;
210
    ERROR_DECLARE;
211
 
211
 
212
    fibril_rwlock_initialize( & ip_globals.lock );
212
    fibril_rwlock_initialize( & ip_globals.lock );
213
    fibril_rwlock_write_lock( & ip_globals.lock );
213
    fibril_rwlock_write_lock( & ip_globals.lock );
214
    fibril_rwlock_initialize( & ip_globals.protos_lock );
214
    fibril_rwlock_initialize( & ip_globals.protos_lock );
215
    fibril_rwlock_initialize( & ip_globals.netifs_lock );
215
    fibril_rwlock_initialize( & ip_globals.netifs_lock );
216
    ip_globals.packet_counter = 0;
216
    ip_globals.packet_counter = 0;
217
    ip_globals.gateway.address.s_addr = 0;
217
    ip_globals.gateway.address.s_addr = 0;
218
    ip_globals.gateway.netmask.s_addr = 0;
218
    ip_globals.gateway.netmask.s_addr = 0;
219
    ip_globals.gateway.gateway.s_addr = 0;
219
    ip_globals.gateway.gateway.s_addr = 0;
220
    ip_globals.gateway.netif = NULL;
220
    ip_globals.gateway.netif = NULL;
221
    ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
221
    ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
222
    ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
222
    ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
223
    ip_globals.client_connection = client_connection;
223
    ip_globals.client_connection = client_connection;
224
    ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
224
    ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
225
    ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module ));
225
    ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module ));
226
    fibril_rwlock_write_unlock( & ip_globals.lock );
226
    fibril_rwlock_write_unlock( & ip_globals.lock );
227
    return EOK;
227
    return EOK;
228
}
228
}
229
 
229
 
230
int ip_device_req( int il_phone, device_id_t device_id, services_t netif ){
230
int ip_device_req( int il_phone, device_id_t device_id, services_t netif ){
231
    ERROR_DECLARE;
231
    ERROR_DECLARE;
232
 
232
 
233
    ip_netif_ref    ip_netif;
233
    ip_netif_ref    ip_netif;
234
    ip_route_ref    route;
234
    ip_route_ref    route;
235
    int             index;
235
    int             index;
236
    char *          data;
236
    char *          data;
237
 
237
 
238
    ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t ));
238
    ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t ));
239
    if( ! ip_netif ) return ENOMEM;
239
    if( ! ip_netif ) return ENOMEM;
240
    if( ERROR_OCCURRED( ip_routes_initialize( & ip_netif->routes ))){
240
    if( ERROR_OCCURRED( ip_routes_initialize( & ip_netif->routes ))){
241
        free( ip_netif );
241
        free( ip_netif );
242
        return ERROR_CODE;
242
        return ERROR_CODE;
243
    }
243
    }
244
    ip_netif->device_id = device_id;
244
    ip_netif->device_id = device_id;
245
    ip_netif->service = netif;
245
    ip_netif->service = netif;
246
    ip_netif->state = NETIF_STOPPED;
246
    ip_netif->state = NETIF_STOPPED;
247
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
247
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
248
    if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
248
    if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
249
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
249
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
250
        ip_routes_destroy( & ip_netif->routes );
250
        ip_routes_destroy( & ip_netif->routes );
251
        free( ip_netif );
251
        free( ip_netif );
252
        return ERROR_CODE;
252
        return ERROR_CODE;
253
    }
253
    }
254
    if( ip_netif->arp ) ++ ip_netif->arp->usage;
254
    if( ip_netif->arp ) ++ ip_netif->arp->usage;
255
    // print the settings
255
    // print the settings
256
    printf( "New device registered:\n\tid\t= %d\n\tphone\t= %d\n\tIPV\t= %d\n", ip_netif->device_id, ip_netif->phone, ip_netif->ipv );
256
    printf( "New device registered:\n\tid\t= %d\n\tphone\t= %d\n\tIPV\t= %d\n", ip_netif->device_id, ip_netif->phone, ip_netif->ipv );
257
    printf( "\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static" );
257
    printf( "\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static" );
258
    // TODO ipv6 addresses
258
    // TODO ipv6 addresses
259
    data = ( char * ) malloc( INET_ADDRSTRLEN );
259
    data = ( char * ) malloc( INET_ADDRSTRLEN );
260
    if( data ){
260
    if( data ){
261
        for( index = 0; index < ip_routes_count( & ip_netif->routes ); ++ index ){
261
        for( index = 0; index < ip_routes_count( & ip_netif->routes ); ++ index ){
262
            route = ip_routes_get_index( & ip_netif->routes, index );
262
            route = ip_routes_get_index( & ip_netif->routes, index );
263
            if( route ){
263
            if( route ){
264
                printf( "\tRouting %d:\n", index );
264
                printf( "\tRouting %d:\n", index );
265
                inet_ntop( AF_INET, ( uint8_t * ) & route->address.s_addr, data, INET_ADDRSTRLEN );
265
                inet_ntop( AF_INET, ( uint8_t * ) & route->address.s_addr, data, INET_ADDRSTRLEN );
266
                printf( "\t\taddress\t= %s\n", data );
266
                printf( "\t\taddress\t= %s\n", data );
267
                inet_ntop( AF_INET, ( uint8_t * ) & route->netmask.s_addr, data, INET_ADDRSTRLEN );
267
                inet_ntop( AF_INET, ( uint8_t * ) & route->netmask.s_addr, data, INET_ADDRSTRLEN );
268
                printf( "\t\tnetmask\t= %s\n", data );
268
                printf( "\t\tnetmask\t= %s\n", data );
269
                inet_ntop( AF_INET, ( uint8_t * ) & route->gateway.s_addr, data, INET_ADDRSTRLEN );
269
                inet_ntop( AF_INET, ( uint8_t * ) & route->gateway.s_addr, data, INET_ADDRSTRLEN );
270
                printf( "\t\tgateway\t= %s\n", data );
270
                printf( "\t\tgateway\t= %s\n", data );
271
            }
271
            }
272
        }
272
        }
273
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN );
273
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN );
274
        printf( "\tbroadcast\t= %s\n", data );
274
        printf( "\tbroadcast\t= %s\n", data );
275
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns1, data, INET_ADDRSTRLEN );
275
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns1, data, INET_ADDRSTRLEN );
276
        printf( "\tdns1\t= %s\n", data );
276
        printf( "\tdns1\t= %s\n", data );
277
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns2, data, INET_ADDRSTRLEN );
277
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns2, data, INET_ADDRSTRLEN );
278
        printf( "\tdns2\t= %s\n", data );
278
        printf( "\tdns2\t= %s\n", data );
279
        free( data );
279
        free( data );
280
    }
280
    }
281
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
281
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
282
    return EOK;
282
    return EOK;
283
}
283
}
284
 
284
 
285
int ip_netif_initialize( ip_netif_ref ip_netif ){
285
int ip_netif_initialize( ip_netif_ref ip_netif ){
286
    ERROR_DECLARE;
286
    ERROR_DECLARE;
287
 
287
 
288
    measured_string_t   names[] = {{ "IPV", 3 }, { "IP_CONFIG", 9 }, { "IP_ADDR", 7 }, { "NETMASK", 7 }, { "GATEWAY", 7 }, { "BROADCAST", 9 }, { "DNS1", 4 }, { "DNS2", 4 }, { "ARP", 3 }, { "IP_ROUTING", 10 }};
288
    measured_string_t   names[] = {{ "IPV", 3 }, { "IP_CONFIG", 9 }, { "IP_ADDR", 7 }, { "NETMASK", 7 }, { "GATEWAY", 7 }, { "BROADCAST", 9 }, { "DNS1", 4 }, { "DNS2", 4 }, { "ARP", 3 }, { "IP_ROUTING", 10 }};
289
    measured_string_ref configuration;
289
    measured_string_ref configuration;
290
    size_t              count = sizeof( names ) / sizeof( measured_string_t );
290
    size_t              count = sizeof( names ) / sizeof( measured_string_t );
291
    char *              data;
291
    char *              data;
292
    measured_string_t   address;
292
    measured_string_t   address;
293
    int                 index;
293
    int                 index;
294
    ip_route_ref        route;
294
    ip_route_ref        route;
295
    in_addr_t           gateway;
295
    in_addr_t           gateway;
296
 
296
 
297
    ip_netif->arp = NULL;
297
    ip_netif->arp = NULL;
298
    route = NULL;
298
    route = NULL;
299
    ip_netif->ipv = NET_DEFAULT_IPV;
299
    ip_netif->ipv = NET_DEFAULT_IPV;
300
    ip_netif->dhcp = false;
300
    ip_netif->dhcp = false;
301
    ip_netif->routing = NET_DEFAULT_IP_ROUTING;
301
    ip_netif->routing = NET_DEFAULT_IP_ROUTING;
302
    configuration = & names[ 0 ];
302
    configuration = & names[ 0 ];
303
    // get configuration
303
    // get configuration
304
    ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data ));
304
    ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data ));
305
    if( configuration ){
305
    if( configuration ){
306
        if( configuration[ 0 ].value ){
306
        if( configuration[ 0 ].value ){
307
            ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 );
307
            ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 );
308
        }
308
        }
309
        ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length );
309
        ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length );
310
        if( ip_netif->dhcp ){
310
        if( ip_netif->dhcp ){
311
            // TODO dhcp
311
            // TODO dhcp
312
            net_free_settings( configuration, data );
312
            net_free_settings( configuration, data );
313
            return ENOTSUP;
313
            return ENOTSUP;
314
        }else if( ip_netif->ipv == IPV4 ){
314
        }else if( ip_netif->ipv == IPV4 ){
315
            route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
315
            route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
316
            if( ! route ){
316
            if( ! route ){
317
                net_free_settings( configuration, data );
317
                net_free_settings( configuration, data );
318
                return ENOMEM;
318
                return ENOMEM;
319
            }
319
            }
320
            route->address.s_addr = 0;
320
            route->address.s_addr = 0;
321
            route->netmask.s_addr = 0;
321
            route->netmask.s_addr = 0;
322
            route->gateway.s_addr = 0;
322
            route->gateway.s_addr = 0;
323
            route->netif = ip_netif;
323
            route->netif = ip_netif;
324
            index = ip_routes_add( & ip_netif->routes, route );
324
            index = ip_routes_add( & ip_netif->routes, route );
325
            if( index < 0 ){
325
            if( index < 0 ){
326
                net_free_settings( configuration, data );
326
                net_free_settings( configuration, data );
327
                free( route );
327
                free( route );
328
                return index;
328
                return index;
329
            }
329
            }
330
            if( ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 2 ].value, ( uint8_t * ) & route->address.s_addr ))
330
            if( ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 2 ].value, ( uint8_t * ) & route->address.s_addr ))
331
            || ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 3 ].value, ( uint8_t * ) & route->netmask.s_addr ))
331
            || ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 3 ].value, ( uint8_t * ) & route->netmask.s_addr ))
332
            || ( inet_pton( AF_INET, configuration[ 4 ].value, ( uint8_t * ) & gateway.s_addr ) == EINVAL )
332
            || ( inet_pton( AF_INET, configuration[ 4 ].value, ( uint8_t * ) & gateway.s_addr ) == EINVAL )
333
            || ( inet_pton( AF_INET, configuration[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast.s_addr ) == EINVAL )
333
            || ( inet_pton( AF_INET, configuration[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast.s_addr ) == EINVAL )
334
            || ( inet_pton( AF_INET, configuration[ 6 ].value, ( uint8_t * ) & ip_netif->dns1 ) == EINVAL )
334
            || ( inet_pton( AF_INET, configuration[ 6 ].value, ( uint8_t * ) & ip_netif->dns1 ) == EINVAL )
335
            || ( inet_pton( AF_INET, configuration[ 7 ].value, ( uint8_t * ) & ip_netif->dns2 ) == EINVAL )){
335
            || ( inet_pton( AF_INET, configuration[ 7 ].value, ( uint8_t * ) & ip_netif->dns2 ) == EINVAL )){
336
                net_free_settings( configuration, data );
336
                net_free_settings( configuration, data );
337
                return EINVAL;
337
                return EINVAL;
338
            }
338
            }
339
        }else{
339
        }else{
340
            // TODO ipv6 in separate module
340
            // TODO ipv6 in separate module
341
            net_free_settings( configuration, data );
341
            net_free_settings( configuration, data );
342
            return ENOTSUP;
342
            return ENOTSUP;
343
        }
343
        }
344
        if( configuration[ 8 ].value ){
344
        if( configuration[ 8 ].value ){
345
            ip_netif->arp = get_running_module( & ip_globals.modules, configuration[ 8 ].value );
345
            ip_netif->arp = get_running_module( & ip_globals.modules, configuration[ 8 ].value );
346
            if( ! ip_netif->arp ){
346
            if( ! ip_netif->arp ){
347
                printf( "Failed to start the arp %s\n", configuration[ 8 ].value );
347
                printf( "Failed to start the arp %s\n", configuration[ 8 ].value );
348
                net_free_settings( configuration, data );
348
                net_free_settings( configuration, data );
349
                return EINVAL;
349
                return EINVAL;
350
            }
350
            }
351
        }
351
        }
352
        if( configuration[ 9 ].value ){
352
        if( configuration[ 9 ].value ){
353
            ip_netif->routing = ( configuration[ 9 ].value[ 0 ] == 'y' );
353
            ip_netif->routing = ( configuration[ 9 ].value[ 0 ] == 'y' );
354
        }
354
        }
355
        net_free_settings( configuration, data );
355
        net_free_settings( configuration, data );
356
    }
356
    }
357
    // binds the netif service which also initializes the device
357
    // binds the netif service which also initializes the device
358
    ip_netif->phone = bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection );
358
    ip_netif->phone = bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection );
359
    if( ip_netif->phone < 0 ){
359
    if( ip_netif->phone < 0 ){
360
        printf( "Failed to contact the nil service %d\n", ip_netif->service );
360
        printf( "Failed to contact the nil service %d\n", ip_netif->service );
361
        return ip_netif->phone;
361
        return ip_netif->phone;
362
    }
362
    }
363
    // has to be after the device netif module initialization
363
    // has to be after the device netif module initialization
364
    if( ip_netif->arp ){
364
    if( ip_netif->arp ){
365
        if( route ){
365
        if( route ){
366
            address.value = ( char * ) & route->address.s_addr;
366
            address.value = ( char * ) & route->address.s_addr;
367
            address.length = CONVERT_SIZE( in_addr_t, char, 1 );
367
            address.length = CONVERT_SIZE( in_addr_t, char, 1 );
368
            ERROR_PROPAGATE( arp_device_req( ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, & address ));
368
            ERROR_PROPAGATE( arp_device_req( ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, & address ));
369
        }else{
369
        }else{
370
            ip_netif->arp = 0;
370
            ip_netif->arp = 0;
371
        }
371
        }
372
    }
372
    }
373
    // get packet dimensions
373
    // get packet dimensions
374
    ERROR_PROPAGATE( nil_packet_size_req( ip_netif->phone, ip_netif->device_id, & ip_netif->addr_len, & ip_netif->prefix, & ip_netif->content, & ip_netif->suffix ));
374
    ERROR_PROPAGATE( nil_packet_size_req( ip_netif->phone, ip_netif->device_id, & ip_netif->addr_len, & ip_netif->prefix, & ip_netif->content, & ip_netif->suffix ));
375
    if( ip_netif->content < IP_MIN_CONTENT ){
375
    if( ip_netif->content < IP_MIN_CONTENT ){
376
        printf( "Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->content, IP_MIN_CONTENT );
376
        printf( "Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->content, IP_MIN_CONTENT );
377
        ip_netif->content = IP_MIN_CONTENT;
377
        ip_netif->content = IP_MIN_CONTENT;
378
    }
378
    }
379
    index = ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif );
379
    index = ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif );
380
    if( index < 0 ) return index;
380
    if( index < 0 ) return index;
381
    if( gateway.s_addr ){
381
    if( gateway.s_addr ){
382
        // the default gateway
382
        // the default gateway
383
        ip_globals.gateway.address.s_addr = 0;
383
        ip_globals.gateway.address.s_addr = 0;
384
        ip_globals.gateway.netmask.s_addr = 0;
384
        ip_globals.gateway.netmask.s_addr = 0;
385
        ip_globals.gateway.gateway.s_addr = gateway.s_addr;
385
        ip_globals.gateway.gateway.s_addr = gateway.s_addr;
386
        ip_globals.gateway.netif = ip_netif;
386
        ip_globals.gateway.netif = ip_netif;
387
    }
387
    }
388
    return EOK;
388
    return EOK;
389
}
389
}
390
 
390
 
391
int ip_mtu_changed_message( device_id_t device_id, size_t mtu ){
391
int ip_mtu_changed_message( device_id_t device_id, size_t mtu ){
392
    ip_netif_ref    netif;
392
    ip_netif_ref    netif;
393
 
393
 
394
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
394
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
395
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
395
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
396
    if( ! netif ){
396
    if( ! netif ){
397
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
397
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
398
        return ENOENT;
398
        return ENOENT;
399
    }
399
    }
400
    netif->content = mtu;
400
    netif->content = mtu;
401
    printf( "ip - device %d changed mtu to %d\n\n", device_id, mtu );
401
    printf( "ip - device %d changed mtu to %d\n\n", device_id, mtu );
402
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
402
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
403
    return EOK;
403
    return EOK;
404
}
404
}
405
 
405
 
406
int ip_device_state_message( device_id_t device_id, device_state_t state ){
406
int ip_device_state_message( device_id_t device_id, device_state_t state ){
407
//  ERROR_DECLARE;
-
 
408
 
-
 
409
/*  measured_string_t   address;
-
 
410
    measured_string_ref translation;
-
 
411
    char *              data;
-
 
412
*/
-
 
413
/*  packet_t        packet;
-
 
414
    in_addr_t       destination;
-
 
415
*/
-
 
416
    ip_netif_ref    netif;
407
    ip_netif_ref    netif;
417
 
408
 
418
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
409
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
-
 
410
    // find the device
419
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
411
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
420
    if( ! netif ){
412
    if( ! netif ){
421
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
413
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
422
        return ENOENT;
414
        return ENOENT;
423
    }
415
    }
424
    netif->state = state;
416
    netif->state = state;
425
    // TODO state
-
 
426
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
417
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
427
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
418
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
428
//  if( netif->arp ){
-
 
429
/*      address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
-
 
430
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
-
 
431
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
-
 
432
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
-
 
433
        }
-
 
434
        printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
-
 
435
        free( translation );
-
 
436
        free( data );
-
 
437
        address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
-
 
438
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
-
 
439
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
-
 
440
            sleep( 2 );
-
 
441
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
-
 
442
        }
-
 
443
        printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
-
 
444
        free( translation );
-
 
445
        free( data );
-
 
446
*//*        printf( "IP - testing to send packet:\n" );
-
 
447
        ERROR_PROPAGATE( inet_pton( AF_INET, "90.182.101.18", ( uint8_t * ) & destination.s_addr ));
-
 
448
        packet = packet_get_4( ip_globals.net_phone, 30, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
-
 
449
        if( ! packet ) return ENOMEM;
-
 
450
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
451
        packet = packet_get_4( ip_globals.net_phone, 30, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
-
 
452
        if( ! packet ) return ENOMEM;
-
 
453
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
454
        packet = packet_get_4( ip_globals.net_phone, 30, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
-
 
455
        if( ! packet ) return ENOMEM;
-
 
456
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
457
        packet = packet_get_4( ip_globals.net_phone, 1500, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
-
 
458
        if( ! packet ) return ENOMEM;
-
 
459
        // try this long version
-
 
460
//      if( ERROR_OCCURRED( packet_copy_data( packet, "Hi, this is IP, wery long version 1, wery long version 2, wery long version 3, wery long version 4, wery long version 5, wery long version 6, wery long version 7, wery long version 8, wery long version 9, wery long version 10, wery long version 11, wery long version 12, wery long version 13, wery long version 14, wery long version 15, wery long version 16, wery long version 17, wery long version 18, wery long version 19, wery long version 20, wery long version 21, wery long version 22, wery long version 23, wery long version 24, wery long version 25, wery long version 26, wery long version 27, wery long version 28, wery long version 29, wery long version 30Hi, this is IP, wery long version 1, wery long version 2, wery long version 3, wery long version 4, wery long version 5, wery long version 6, wery long version 7, wery long version 8, wery long version 9, wery long version 10, wery long version 11, wery long version 12, wery long version 13, wery long version 14, wery long version 15, wery long version 16, wery long version 17, wery long version 18, wery long version 19, wery long version 20, wery long version 21, wery long version 22, wery long version 23, wery long version 24, wery long version 25, wery long version 26, wery long version 27, wery long version 28, wery long version 29, wery long version 30", 1330 ))
-
 
461
        if( ERROR_OCCURRED( packet_copy_data( packet, "Hi, this is IP", 14 ))
-
 
462
        || ERROR_OCCURRED( packet_set_addr( packet, NULL, ( uint8_t * ) & destination.s_addr, 4 ))
-
 
463
        || ERROR_OCCURRED( ip_client_prepare_packet( packet, 0, 0, 0, 0, 0 ))){
-
 
464
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
465
        }
-
 
466
        ERROR_CODE = ip_send_msg( 0, 0, packet, SERVICE_IP );
-
 
467
        printf( "send returned %d\n", ERROR_CODE );
-
 
468
    }
-
 
469
*/  return EOK;
419
    return EOK;
470
}
420
}
471
 
421
 
472
int ip_connect_module( services_t service ){
422
int ip_connect_module( services_t service ){
473
    return EOK;
423
    return EOK;
474
}
424
}
475
 
425
 
476
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){
426
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){
477
    return ip_register( protocol, me, 0, received_msg );
427
    return ip_register( protocol, me, 0, received_msg );
478
}
428
}
479
 
429
 
480
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){
430
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){
481
    ip_proto_ref    proto;
431
    ip_proto_ref    proto;
482
    int             index;
432
    int             index;
483
 
433
 
484
    if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL;
434
    if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL;
485
    proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
435
    proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
486
    if( ! proto ) return ENOMEM;
436
    if( ! proto ) return ENOMEM;
487
    proto->protocol = protocol;
437
    proto->protocol = protocol;
488
    proto->service = service;
438
    proto->service = service;
489
    proto->phone = phone;
439
    proto->phone = phone;
490
    proto->received_msg = received_msg;
440
    proto->received_msg = received_msg;
491
    fibril_rwlock_write_lock( & ip_globals.protos_lock );
441
    fibril_rwlock_write_lock( & ip_globals.protos_lock );
492
    index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
442
    index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
493
    if( index < 0 ){
443
    if( index < 0 ){
494
        fibril_rwlock_write_unlock( & ip_globals.protos_lock );
444
        fibril_rwlock_write_unlock( & ip_globals.protos_lock );
495
        free( proto );
445
        free( proto );
496
        return index;
446
        return index;
497
    }
447
    }
498
    printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
448
    printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
499
    fibril_rwlock_write_unlock( & ip_globals.protos_lock );
449
    fibril_rwlock_write_unlock( & ip_globals.protos_lock );
500
    return EOK;
450
    return EOK;
501
}
451
}
502
 
452
 
503
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ){
453
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ){
504
    ERROR_DECLARE;
454
    ERROR_DECLARE;
505
 
455
 
506
    int                 addrlen;
456
    int                 addrlen;
507
    ip_netif_ref        netif;
457
    ip_netif_ref        netif;
508
    ip_route_ref        route;
458
    ip_route_ref        route;
509
    struct sockaddr *       addr;
459
    struct sockaddr *       addr;
510
    struct sockaddr_in *    address_in;
460
    struct sockaddr_in *    address_in;
511
//  struct sockaddr_in6 *   address_in6;
461
//  struct sockaddr_in6 *   address_in6;
512
    in_addr_t *         dest;
462
    in_addr_t *         dest;
513
    in_addr_t *         src;
463
    in_addr_t *         src;
514
    int                 phone;
464
    int                 phone;
515
 
465
 
516
    // addresses in the host byte order
466
    // addresses in the host byte order
517
    // should be the next hop address or the target destination address
467
    // should be the next hop address or the target destination address
518
    addrlen = packet_get_addr( packet, NULL, ( uint8_t ** ) & addr );
468
    addrlen = packet_get_addr( packet, NULL, ( uint8_t ** ) & addr );
519
    if( addrlen < 0 ){
469
    if( addrlen < 0 ){
520
        return ip_release_and_return( packet, addrlen );
470
        return ip_release_and_return( packet, addrlen );
521
    }
471
    }
522
    if( addrlen < sizeof( struct sockaddr )){
472
    if( addrlen < sizeof( struct sockaddr )){
523
        return ip_release_and_return( packet, EINVAL );
473
        return ip_release_and_return( packet, EINVAL );
524
    }
474
    }
525
    switch( addr->sa_family ){
475
    switch( addr->sa_family ){
526
        case AF_INET:
476
        case AF_INET:
527
            if( addrlen != sizeof( struct sockaddr_in )){
477
            if( addrlen != sizeof( struct sockaddr_in )){
528
                return ip_release_and_return( packet, EINVAL );
478
                return ip_release_and_return( packet, EINVAL );
529
            }
479
            }
530
            address_in = ( struct sockaddr_in * ) addr;
480
            address_in = ( struct sockaddr_in * ) addr;
531
            dest = & address_in->sin_addr;
481
            dest = & address_in->sin_addr;
532
            break;
482
            break;
533
        // TODO IPv6
483
        // TODO IPv6
534
/*      case AF_INET6:
484
/*      case AF_INET6:
535
            if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
485
            if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
536
            address_in6 = ( struct sockaddr_in6 * ) dest;
486
            address_in6 = ( struct sockaddr_in6 * ) dest;
537
            address_in6.sin6_addr.s6_addr;
487
            address_in6.sin6_addr.s6_addr;
538
*/      default:
488
*/      default:
539
            return ip_release_and_return( packet, EAFNOSUPPORT );
489
            return ip_release_and_return( packet, EAFNOSUPPORT );
540
    }
490
    }
541
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
491
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
542
    // device specified?
492
    // device specified?
543
    if( device_id > 0 ){
493
    if( device_id > 0 ){
544
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
494
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
545
        route = ip_netif_find_route( netif, * dest );
495
        route = ip_netif_find_route( netif, * dest );
546
    }else{
496
    }else{
547
        route = ip_find_route( * dest );
497
        route = ip_find_route( * dest );
548
        netif = route ? route->netif : NULL;
498
        netif = route ? route->netif : NULL;
549
    }
499
    }
550
    if( !( netif && route )){
500
    if( !( netif && route )){
551
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
501
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
552
        phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
502
        phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
553
        if( phone >= 0 ){
503
        if( phone >= 0 ){
554
            // unreachable ICMP if no routing
504
            // unreachable ICMP if no routing
555
            icmp_destination_unreachable_msg( phone, ICMP_NET_UNREACH, 0, packet );
505
            icmp_destination_unreachable_msg( phone, ICMP_NET_UNREACH, 0, packet );
556
        }
506
        }
557
        return ENOENT;
507
        return ENOENT;
558
    }
508
    }
559
    if( error ){
509
    if( error ){
560
        // do not send for broadcast, anycast packets or network broadcast
510
        // do not send for broadcast, anycast packets or network broadcast
561
        if(( ! dest->s_addr )
511
        if(( ! dest->s_addr )
562
        || ( !( ~ dest->s_addr ))
512
        || ( !( ~ dest->s_addr ))
563
        || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr )))
513
        || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr )))
564
        || ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){
514
        || ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){
565
            return ip_release_and_return( packet, EINVAL );
515
            return ip_release_and_return( packet, EINVAL );
566
        }
516
        }
567
    }
517
    }
568
    if( route->address.s_addr == dest->s_addr ){
518
    if( route->address.s_addr == dest->s_addr ){
569
        // find the loopback device to deliver
519
        // find the loopback device to deliver
570
        dest->s_addr = IPV4_LOCALHOST_ADDRESS;
520
        dest->s_addr = IPV4_LOCALHOST_ADDRESS;
571
        route = ip_find_route( * dest );
521
        route = ip_find_route( * dest );
572
        netif = route ? route->netif : NULL;
522
        netif = route ? route->netif : NULL;
573
        if( !( netif && route )){
523
        if( !( netif && route )){
574
            fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
524
            fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
575
            phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
525
            phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
576
            if( phone >= 0 ){
526
            if( phone >= 0 ){
577
                // unreachable ICMP if no routing
527
                // unreachable ICMP if no routing
578
                icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
528
                icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
579
            }
529
            }
580
            return ENOENT;
530
            return ENOENT;
581
        }
531
        }
582
    }
532
    }
583
    src = ip_netif_address( netif );
533
    src = ip_netif_address( netif );
584
    if( ! src ){
534
    if( ! src ){
585
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
535
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
586
        return ip_release_and_return( packet, ENOENT );
536
        return ip_release_and_return( packet, ENOENT );
587
    }
537
    }
588
    ERROR_CODE = ip_send_route( packet, netif, route, src, * dest, error );
538
    ERROR_CODE = ip_send_route( packet, netif, route, src, * dest, error );
589
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
539
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
590
    return ERROR_CODE;
540
    return ERROR_CODE;
591
}
541
}
592
 
542
 
593
in_addr_t * ip_netif_address( ip_netif_ref netif ){
543
in_addr_t * ip_netif_address( ip_netif_ref netif ){
594
    ip_route_ref    route;
544
    ip_route_ref    route;
595
 
545
 
596
    route = ip_routes_get_index( & netif->routes, 0 );
546
    route = ip_routes_get_index( & netif->routes, 0 );
597
    return route ? & route->address : NULL;
547
    return route ? & route->address : NULL;
598
}
548
}
599
 
549
 
600
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error ){
550
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error ){
601
    ERROR_DECLARE;
551
    ERROR_DECLARE;
602
 
552
 
603
    measured_string_t   destination;
553
    measured_string_t   destination;
604
    measured_string_ref translation;
554
    measured_string_ref translation;
605
    char *              data;
555
    char *              data;
606
    int                 phone;
556
    int                 phone;
607
 
557
 
608
    // get destination hardware address
558
    // get destination hardware address
609
    if( netif->arp && ( route->address.s_addr != dest.s_addr )){
559
    if( netif->arp && ( route->address.s_addr != dest.s_addr )){
610
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
560
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
611
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
561
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
612
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
562
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
613
//          sleep( 1 );
563
//          sleep( 1 );
614
//          ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
564
//          ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
615
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
565
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
616
            return ERROR_CODE;
566
            return ERROR_CODE;
617
        }
567
        }
618
        if( !( translation && translation->value )){
568
        if( !( translation && translation->value )){
619
            if( translation ){
569
            if( translation ){
620
                free( translation );
570
                free( translation );
621
                free( data );
571
                free( data );
622
            }
572
            }
623
            phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
573
            phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
624
            if( phone >= 0 ){
574
            if( phone >= 0 ){
625
                // unreachable ICMP if no routing
575
                // unreachable ICMP if no routing
626
                icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
576
                icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
627
            }
577
            }
628
            return EINVAL;
578
            return EINVAL;
629
        }
579
        }
630
    }else translation = NULL;
580
    }else translation = NULL;
631
    if( ERROR_OCCURRED( ip_prepare_packet( src, dest, packet, translation ))){
581
    if( ERROR_OCCURRED( ip_prepare_packet( src, dest, packet, translation ))){
632
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
582
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
633
    }else{
583
    }else{
634
        packet = ip_split_packet( packet, netif->prefix, netif->content, netif->suffix, netif->addr_len, error );
584
        packet = ip_split_packet( packet, netif->prefix, netif->content, netif->suffix, netif->addr_len, error );
635
        if( packet ){
585
        if( packet ){
636
            nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP );
586
            nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP );
637
        }
587
        }
638
    }
588
    }
639
    if( translation ){
589
    if( translation ){
640
        free( translation );
590
        free( translation );
641
        free( data );
591
        free( data );
642
    }
592
    }
643
    return ERROR_CODE;
593
    return ERROR_CODE;
644
}
594
}
645
 
595
 
646
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ){
596
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ){
647
    ERROR_DECLARE;
597
    ERROR_DECLARE;
648
 
598
 
649
    size_t              length;
599
    size_t              length;
650
    ip_header_ref       header;
600
    ip_header_ref       header;
651
    ip_header_ref       last_header;
601
    ip_header_ref       last_header;
652
    ip_header_ref       middle_header;
602
    ip_header_ref       middle_header;
653
    packet_t            next;
603
    packet_t            next;
654
 
604
 
655
    length = packet_get_data_length( packet );
605
    length = packet_get_data_length( packet );
656
    if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
606
    if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
657
    header = ( ip_header_ref ) packet_get_data( packet );
607
    header = ( ip_header_ref ) packet_get_data( packet );
658
    if( destination ){
608
    if( destination ){
659
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
609
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
660
    }else{
610
    }else{
661
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0 ));
611
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0 ));
662
    }
612
    }
663
    header->version = IPV4;
613
    header->version = IPV4;
-
 
614
    header->fragment_offset_high = 0;
664
    header->fragment_offset = 0;
615
    header->fragment_offset_low = 0;
665
    header->header_checksum = 0;
616
    header->header_checksum = 0;
666
    if( source ) header->source_address = source->s_addr;
617
    if( source ) header->source_address = source->s_addr;
667
    header->destination_address = dest.s_addr;
618
    header->destination_address = dest.s_addr;
668
    fibril_rwlock_write_lock( & ip_globals.lock );
619
    fibril_rwlock_write_lock( & ip_globals.lock );
669
    ++ ip_globals.packet_counter;
620
    ++ ip_globals.packet_counter;
670
    header->identification = htons( ip_globals.packet_counter );
621
    header->identification = htons( ip_globals.packet_counter );
671
    fibril_rwlock_write_unlock( & ip_globals.lock );
622
    fibril_rwlock_write_unlock( & ip_globals.lock );
672
    length = packet_get_data_length( packet );
623
//  length = packet_get_data_length( packet );
673
    if( pq_next( packet )){
624
    if( pq_next( packet )){
674
        last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header ));
625
        last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header ));
675
        if( ! last_header ) return ENOMEM;
626
        if( ! last_header ) return ENOMEM;
676
        ip_create_last_header( last_header, header );
627
        ip_create_last_header( last_header, header );
677
        next = pq_next( packet );
628
        next = pq_next( packet );
678
        while( pq_next( next )){
629
        while( pq_next( next )){
679
            middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
630
            middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
680
            if( ! middle_header ) return ENOMEM;
631
            if( ! middle_header ) return ENOMEM;
681
            memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
632
            memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
682
            header->flags |= IPFLAG_MORE_FRAGMENTS;
633
            header->flags |= IPFLAG_MORE_FRAGMENTS;
683
            middle_header->total_length = htons( packet_get_data_length( next ));
634
            middle_header->total_length = htons( packet_get_data_length( next ));
-
 
635
            middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length );
684
            middle_header->fragment_offset = IP_COMPUTE_FRAGMENT_OFFSET( length );
636
            middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length );
685
            middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
637
            middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
686
            if( destination ){
638
            if( destination ){
687
                ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
639
                ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
688
            }
640
            }
689
            length += packet_get_data_length( next );
641
            length += packet_get_data_length( next );
690
            next = pq_next( next );
642
            next = pq_next( next );
691
        }
643
        }
692
        middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
644
        middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
693
        if( ! middle_header ) return ENOMEM;
645
        if( ! middle_header ) return ENOMEM;
694
        memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
646
        memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
695
        middle_header->total_length = htons( packet_get_data_length( next ));
647
        middle_header->total_length = htons( packet_get_data_length( next ));
-
 
648
        middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length );
696
        middle_header->fragment_offset = IP_COMPUTE_FRAGMENT_OFFSET( length );
649
        middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length );
697
        middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
650
        middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
698
        if( destination ){
651
        if( destination ){
699
            ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
652
            ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
700
        }
653
        }
701
        length += packet_get_data_length( next );
654
        length += packet_get_data_length( next );
702
        free( last_header );
655
        free( last_header );
703
        header->flags |= IPFLAG_MORE_FRAGMENTS;
656
        header->flags |= IPFLAG_MORE_FRAGMENTS;
704
    }
657
    }
705
    header->total_length = htons( length );
658
    header->total_length = htons( length );
706
    // unnecessary for all protocols
659
    // unnecessary for all protocols
707
    header->header_checksum = IP_HEADER_CHECKSUM( header );
660
    header->header_checksum = IP_HEADER_CHECKSUM( header );
708
    return EOK;
661
    return EOK;
709
}
662
}
710
 
663
 
711
int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
664
int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
712
    ERROR_DECLARE;
665
    ERROR_DECLARE;
713
 
666
 
714
    packet_t                packet;
667
    packet_t                packet;
715
    struct sockaddr *       addr;
668
    struct sockaddr *       addr;
716
    size_t                  addrlen;
669
    size_t                  addrlen;
717
    ip_pseudo_header_ref    header;
670
    ip_pseudo_header_ref    header;
718
    size_t                  headerlen;
671
    size_t                  headerlen;
719
 
672
 
720
    * answer_count = 0;
673
    * answer_count = 0;
721
    switch( IPC_GET_METHOD( * call )){
674
    switch( IPC_GET_METHOD( * call )){
722
        case IPC_M_PHONE_HUNGUP:
675
        case IPC_M_PHONE_HUNGUP:
723
            return EOK;
676
            return EOK;
724
        case NET_IL_DEVICE:
677
        case NET_IL_DEVICE:
725
            return ip_device_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ));
678
            return ip_device_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ));
726
        case IPC_M_CONNECT_TO_ME:
679
        case IPC_M_CONNECT_TO_ME:
727
            return ip_register( IL_GET_PROTO( call ), IL_GET_SERVICE( call ), IPC_GET_PHONE( call ), NULL );
680
            return ip_register( IL_GET_PROTO( call ), IL_GET_SERVICE( call ), IPC_GET_PHONE( call ), NULL );
728
        case NET_IL_SEND:
681
        case NET_IL_SEND:
729
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
682
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
730
            return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0, IPC_GET_ERROR( call ));
683
            return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0, IPC_GET_ERROR( call ));
731
        case NET_IL_DEVICE_STATE:
684
        case NET_IL_DEVICE_STATE:
732
            return ip_device_state_message( IPC_GET_DEVICE( call ), IPC_GET_STATE( call ));
685
            return ip_device_state_message( IPC_GET_DEVICE( call ), IPC_GET_STATE( call ));
733
        case NET_IL_RECEIVED:
686
        case NET_IL_RECEIVED:
734
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
687
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
735
            return ip_receive_message( IPC_GET_DEVICE( call ), packet );
688
            return ip_receive_message( IPC_GET_DEVICE( call ), packet );
736
        case NET_IP_RECEIVED_ERROR:
689
        case NET_IP_RECEIVED_ERROR:
737
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
690
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
738
            return ip_received_error_msg( 0, IPC_GET_DEVICE( call ), packet, IPC_GET_TARGET( call ), IPC_GET_ERROR( call ));
691
            return ip_received_error_msg( 0, IPC_GET_DEVICE( call ), packet, IPC_GET_TARGET( call ), IPC_GET_ERROR( call ));
739
        case NET_IP_ADD_ROUTE:
692
        case NET_IP_ADD_ROUTE:
740
            return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call ));
693
            return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call ));
741
        case NET_IP_SET_GATEWAY:
694
        case NET_IP_SET_GATEWAY:
742
            return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call ));
695
            return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call ));
743
        case NET_IP_GET_ROUTE:
696
        case NET_IP_GET_ROUTE:
744
            ERROR_PROPAGATE( data_receive(( void ** ) & addr, & addrlen ));
697
            ERROR_PROPAGATE( data_receive(( void ** ) & addr, & addrlen ));
745
            ERROR_PROPAGATE( ip_get_route_req( 0, IP_GET_PROTOCOL( call ), addr, ( socklen_t ) addrlen, IPC_SET_DEVICE( answer ), & header, & headerlen ));
698
            ERROR_PROPAGATE( ip_get_route_req( 0, IP_GET_PROTOCOL( call ), addr, ( socklen_t ) addrlen, IPC_SET_DEVICE( answer ), & header, & headerlen ));
746
            * IP_SET_HEADERLEN( answer ) = headerlen;
699
            * IP_SET_HEADERLEN( answer ) = headerlen;
747
            if( ! ERROR_OCCURRED( data_reply( & headerlen, sizeof( headerlen )))){
700
            if( ! ERROR_OCCURRED( data_reply( & headerlen, sizeof( headerlen )))){
748
                ERROR_CODE = data_reply( header, headerlen );
701
                ERROR_CODE = data_reply( header, headerlen );
749
            }
702
            }
750
            free( header );
703
            free( header );
751
            return ERROR_CODE;
704
            return ERROR_CODE;
752
        case NET_IL_PACKET_SPACE:
705
        case NET_IL_PACKET_SPACE:
753
            ERROR_PROPAGATE( ip_packet_size_req( 0, IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer )));
706
            ERROR_PROPAGATE( ip_packet_size_req( 0, IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer )));
754
            * answer_count = 3;
707
            * answer_count = 3;
755
            return EOK;
708
            return EOK;
756
        case NET_IL_MTU_CHANGED:
709
        case NET_IL_MTU_CHANGED:
757
            return ip_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call ));
710
            return ip_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call ));
758
    }
711
    }
759
    return ENOTSUP;
712
    return ENOTSUP;
760
}
713
}
761
 
714
 
762
int ip_packet_size_req( int ip_phone, device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){
715
int ip_packet_size_req( int ip_phone, device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){
763
    ip_netif_ref    netif;
716
    ip_netif_ref    netif;
764
    int             index;
717
    int             index;
765
 
718
 
766
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
719
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
767
    * content = IP_MAX_CONTENT - IP_PREFIX;
720
    * content = IP_MAX_CONTENT - IP_PREFIX;
768
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
721
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
769
    if( device_id < 0 ){
722
    if( device_id < 0 ){
770
        * addr_len = IP_ADDR;
723
        * addr_len = IP_ADDR;
771
        * prefix = 0;
724
        * prefix = 0;
772
        * suffix = 0;
725
        * suffix = 0;
773
        for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){
726
        for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){
774
            netif = ip_netifs_get_index( & ip_globals.netifs, index );
727
            netif = ip_netifs_get_index( & ip_globals.netifs, index );
775
            if( netif ){
728
            if( netif ){
776
                if( netif->addr_len > * addr_len ) * addr_len = netif->addr_len;
729
                if( netif->addr_len > * addr_len ) * addr_len = netif->addr_len;
777
                if( netif->prefix > * prefix ) * prefix = netif->prefix;
730
                if( netif->prefix > * prefix ) * prefix = netif->prefix;
778
                if( netif->suffix > * suffix ) * suffix = netif->suffix;
731
                if( netif->suffix > * suffix ) * suffix = netif->suffix;
779
            }
732
            }
780
        }
733
        }
781
        * prefix = * prefix + IP_PREFIX;
734
        * prefix = * prefix + IP_PREFIX;
782
        * suffix = * suffix + IP_SUFFIX;
735
        * suffix = * suffix + IP_SUFFIX;
783
    }else{
736
    }else{
784
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
737
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
785
        if( ! netif ){
738
        if( ! netif ){
786
            fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
739
            fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
787
            return ENOENT;
740
            return ENOENT;
788
        }
741
        }
789
        * addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR;
742
        * addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR;
790
        * prefix = netif->prefix + IP_PREFIX;
743
        * prefix = netif->prefix + IP_PREFIX;
791
        * suffix = netif->suffix + IP_SUFFIX;
744
        * suffix = netif->suffix + IP_SUFFIX;
792
    }
745
    }
793
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
746
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
794
    return EOK;
747
    return EOK;
795
}
748
}
796
 
749
 
797
int ip_add_route_req( int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway ){
750
int ip_add_route_req( int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway ){
798
    ip_route_ref    route;
751
    ip_route_ref    route;
799
    ip_netif_ref    netif;
752
    ip_netif_ref    netif;
800
    int             index;
753
    int             index;
801
 
754
 
802
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
755
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
803
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
756
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
804
    if( ! netif ){
757
    if( ! netif ){
805
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
758
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
806
        return ENOENT;
759
        return ENOENT;
807
    }
760
    }
808
    route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
761
    route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
809
    if( ! route ){
762
    if( ! route ){
810
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
763
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
811
        return ENOMEM;
764
        return ENOMEM;
812
    }
765
    }
813
    route->address.s_addr = address.s_addr;
766
    route->address.s_addr = address.s_addr;
814
    route->netmask.s_addr = netmask.s_addr;
767
    route->netmask.s_addr = netmask.s_addr;
815
    route->gateway.s_addr = gateway.s_addr;
768
    route->gateway.s_addr = gateway.s_addr;
816
    route->netif = netif;
769
    route->netif = netif;
817
    index = ip_routes_add( & netif->routes, route );
770
    index = ip_routes_add( & netif->routes, route );
818
    if( index < 0 ) free( route );
771
    if( index < 0 ) free( route );
819
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
772
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
820
    return index;
773
    return index;
821
}
774
}
822
 
775
 
823
ip_route_ref ip_find_route( in_addr_t destination ){
776
ip_route_ref ip_find_route( in_addr_t destination ){
824
    int             index;
777
    int             index;
825
    ip_route_ref    route;
778
    ip_route_ref    route;
826
    ip_netif_ref    netif;
779
    ip_netif_ref    netif;
827
 
780
 
828
    // start with the last netif - the newest one
781
    // start with the last netif - the newest one
829
    index = ip_netifs_count( & ip_globals.netifs ) - 1;
782
    index = ip_netifs_count( & ip_globals.netifs ) - 1;
830
    while( index >= 0 ){
783
    while( index >= 0 ){
831
        netif = ip_netifs_get_index( & ip_globals.netifs, index );
784
        netif = ip_netifs_get_index( & ip_globals.netifs, index );
832
        if( netif && ( netif->state == NETIF_ACTIVE )){
785
        if( netif && ( netif->state == NETIF_ACTIVE )){
833
            route = ip_netif_find_route( netif, destination );
786
            route = ip_netif_find_route( netif, destination );
834
            if( route ) return route;
787
            if( route ) return route;
835
        }
788
        }
836
        -- index;
789
        -- index;
837
    }
790
    }
838
    return & ip_globals.gateway;
791
    return & ip_globals.gateway;
839
}
792
}
840
 
793
 
841
ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ){
794
ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ){
842
    int             index;
795
    int             index;
843
    ip_route_ref    route;
796
    ip_route_ref    route;
844
 
797
 
845
    if( netif ){
798
    if( netif ){
846
        // start with the first one - the direct route
799
        // start with the first one - the direct route
847
        for( index = 0; index < ip_routes_count( & netif->routes ); ++ index ){
800
        for( index = 0; index < ip_routes_count( & netif->routes ); ++ index ){
848
            route = ip_routes_get_index( & netif->routes, index );
801
            route = ip_routes_get_index( & netif->routes, index );
849
            if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( destination.s_addr & route->netmask.s_addr ))){
802
            if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( destination.s_addr & route->netmask.s_addr ))){
850
                return route;
803
                return route;
851
            }
804
            }
852
        }
805
        }
853
    }
806
    }
854
    return NULL;
807
    return NULL;
855
}
808
}
856
 
809
 
857
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
810
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
858
    ip_netif_ref    netif;
811
    ip_netif_ref    netif;
859
 
812
 
860
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
813
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
861
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
814
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
862
    if( ! netif ){
815
    if( ! netif ){
863
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
816
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
864
        return ENOENT;
817
        return ENOENT;
865
    }
818
    }
866
    ip_globals.gateway.address.s_addr = 0;
819
    ip_globals.gateway.address.s_addr = 0;
867
    ip_globals.gateway.netmask.s_addr = 0;
820
    ip_globals.gateway.netmask.s_addr = 0;
868
    ip_globals.gateway.gateway.s_addr = gateway.s_addr;
821
    ip_globals.gateway.gateway.s_addr = gateway.s_addr;
869
    ip_globals.gateway.netif = netif;
822
    ip_globals.gateway.netif = netif;
870
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
823
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
871
    return EOK;
824
    return EOK;
872
}
825
}
873
 
826
 
874
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error ){
827
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error ){
875
    size_t          length;
828
    size_t          length;
876
    packet_t        next;
829
    packet_t        next;
877
    packet_t        new_packet;
830
    packet_t        new_packet;
878
    int             result;
831
    int             result;
879
    int             phone;
832
    int             phone;
880
 
833
 
881
    next = packet;
834
    next = packet;
882
    // check all packets
835
    // check all packets
883
    while( next ){
836
    while( next ){
884
        length = packet_get_data_length( next );
837
        length = packet_get_data_length( next );
885
        // too long?
838
        // too long?
886
        if( length > content ){
839
        if( length > content ){
887
            result = ip_fragment_packet( next, content, prefix, suffix, addr_len );
840
            result = ip_fragment_packet( next, content, prefix, suffix, addr_len );
888
            if( result != EOK ){
841
            if( result != EOK ){
889
                new_packet = pq_detach( next );
842
                new_packet = pq_detach( next );
890
                if( next == packet ){
843
                if( next == packet ){
891
                    // the new first packet of the queue
844
                    // the new first packet of the queue
892
                    packet = new_packet;
845
                    packet = new_packet;
893
                }
846
                }
894
                // fragmentation needed?
847
                // fragmentation needed?
895
                if( result == EPERM ){
848
                if( result == EPERM ){
896
                    phone = ip_prepare_icmp_and_get_phone( error, next, NULL );
849
                    phone = ip_prepare_icmp_and_get_phone( error, next, NULL );
897
                    if( phone >= 0 ){
850
                    if( phone >= 0 ){
898
                        // fragmentation necessary ICMP
851
                        // fragmentation necessary ICMP
899
                        icmp_destination_unreachable_msg( phone, ICMP_FRAG_NEEDED, content, next );
852
                        icmp_destination_unreachable_msg( phone, ICMP_FRAG_NEEDED, content, next );
900
                    }
853
                    }
901
                }else{
854
                }else{
902
                    pq_release( ip_globals.net_phone, packet_get_id( next ));
855
                    pq_release( ip_globals.net_phone, packet_get_id( next ));
903
                }
856
                }
904
                next = new_packet;
857
                next = new_packet;
905
                continue;
858
                continue;
906
            }
859
            }
907
        }
860
        }
908
        next = pq_next( next );
861
        next = pq_next( next );
909
    }
862
    }
910
    return packet;
863
    return packet;
911
}
864
}
912
 
865
 
913
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len ){
866
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len ){
914
    ERROR_DECLARE;
867
    ERROR_DECLARE;
915
 
868
 
916
    packet_t        new_packet;
869
    packet_t        new_packet;
917
    ip_header_ref   header;
870
    ip_header_ref   header;
918
    ip_header_ref   middle_header;
871
    ip_header_ref   middle_header;
919
    ip_header_ref   last_header;
872
    ip_header_ref   last_header;
920
    struct sockaddr *       src;
873
    struct sockaddr *       src;
921
    struct sockaddr *       dest;
874
    struct sockaddr *       dest;
922
    socklen_t       addrlen;
875
    socklen_t       addrlen;
923
    int             result;
876
    int             result;
924
 
877
 
925
    result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest );
878
    result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest );
926
    if( result <= 0 ) return EINVAL;
879
    if( result <= 0 ) return EINVAL;
927
    addrlen = ( socklen_t ) result;
880
    addrlen = ( socklen_t ) result;
928
    if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
881
    if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
929
    // get header
882
    // get header
930
    header = ( ip_header_ref ) packet_get_data( packet );
883
    header = ( ip_header_ref ) packet_get_data( packet );
931
    if( ! header ) return EINVAL;
884
    if( ! header ) return EINVAL;
932
    // fragmentation forbidden?
885
    // fragmentation forbidden?
933
    if( header->flags & IPFLAG_DONT_FRAGMENT ){
886
    if( header->flags & IPFLAG_DONT_FRAGMENT ){
934
        return EPERM;
887
        return EPERM;
935
    }
888
    }
936
    // create the last fragment
889
    // create the last fragment
937
    new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen > addr_len ) ? addrlen : addr_len ));
890
    new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen > addr_len ) ? addrlen : addr_len ));
938
    if( ! new_packet ) return ENOMEM;
891
    if( ! new_packet ) return ENOMEM;
939
    // allocate as much as originally
892
    // allocate as much as originally
940
    last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header ));
893
    last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header ));
941
    if( ! last_header ){
894
    if( ! last_header ){
942
        return ip_release_and_return( packet, ENOMEM );
895
        return ip_release_and_return( packet, ENOMEM );
943
    }
896
    }
944
    ip_create_last_header( last_header, header );
897
    ip_create_last_header( last_header, header );
945
    // trim the unused space
898
    // trim the unused space
946
    if( ERROR_OCCURRED( packet_trim( new_packet, 0, IP_HEADER_LENGTH( header ) - IP_HEADER_LENGTH( last_header )))){
899
    if( ERROR_OCCURRED( packet_trim( new_packet, 0, IP_HEADER_LENGTH( header ) - IP_HEADER_LENGTH( last_header )))){
947
        return ip_release_and_return( packet, ERROR_CODE );
900
        return ip_release_and_return( packet, ERROR_CODE );
948
    }
901
    }
949
    // biggest multiple of 8 lower than content
902
    // biggest multiple of 8 lower than content
950
    // TODO even fragmentation?
903
    // TODO even fragmentation?
951
    length = length & ( ~ 0x7 );// ( content / 8 ) * 8
904
    length = length & ( ~ 0x7 );// ( content / 8 ) * 8
952
    if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, last_header, (( IP_TOTAL_LENGTH( header ) - length ) % ( length - IP_HEADER_LENGTH( last_header ))), src, dest, addrlen ))){
905
    if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, last_header, (( IP_HEADER_DATA_LENGTH( header ) - (( length - IP_HEADER_LENGTH( header )) & ( ~ 0x7 ))) % (( length - IP_HEADER_LENGTH( last_header )) & ( ~ 0x7 ))), src, dest, addrlen ))){
953
        return ip_release_and_return( packet, ERROR_CODE );
906
        return ip_release_and_return( packet, ERROR_CODE );
954
    }
907
    }
955
    // mark the first as fragmented
908
    // mark the first as fragmented
956
    header->flags |= IPFLAG_MORE_FRAGMENTS;
909
    header->flags |= IPFLAG_MORE_FRAGMENTS;
957
    // create middle framgents
910
    // create middle framgents
958
    while( IP_TOTAL_LENGTH( header ) > length ){
911
    while( IP_TOTAL_LENGTH( header ) > length ){
959
        new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen >= addr_len ) ? addrlen : addr_len ));
912
        new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen >= addr_len ) ? addrlen : addr_len ));
960
        if( ! new_packet ) return ENOMEM;
913
        if( ! new_packet ) return ENOMEM;
961
        middle_header = ip_create_middle_header( new_packet, last_header );
914
        middle_header = ip_create_middle_header( new_packet, last_header );
962
        if( ! middle_header ){
915
        if( ! middle_header ){
963
            return ip_release_and_return( packet, ENOMEM );
916
            return ip_release_and_return( packet, ENOMEM );
964
        }
917
        }
965
        if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, length - IP_HEADER_LENGTH( middle_header ), src, dest, addrlen ))){
918
        if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, ( length - IP_HEADER_LENGTH( middle_header )) & ( ~ 0x7 ), src, dest, addrlen ))){
966
            return ip_release_and_return( packet, ERROR_CODE );
919
            return ip_release_and_return( packet, ERROR_CODE );
967
        }
920
        }
968
    }
921
    }
969
    // finish the first fragment
922
    // finish the first fragment
970
    header->header_checksum = IP_HEADER_CHECKSUM( header );
923
    header->header_checksum = IP_HEADER_CHECKSUM( header );
971
    return EOK;
924
    return EOK;
972
}
925
}
973
 
926
 
974
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen ){
927
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen ){
975
    ERROR_DECLARE;
928
    ERROR_DECLARE;
976
 
929
 
977
    void *          data;
930
    void *          data;
-
 
931
    size_t          offset;
978
 
932
 
979
    data = packet_suffix( new_packet, length );
933
    data = packet_suffix( new_packet, length );
980
    if( ! data ) return ENOMEM;
934
    if( ! data ) return ENOMEM;
981
    memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length );
935
    memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length );
982
    ERROR_PROPAGATE( packet_trim( packet, 0, length ));
936
    ERROR_PROPAGATE( packet_trim( packet, 0, length ));
983
    header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
937
    header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
984
    new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
938
    new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
985
    new_header->fragment_offset = header->fragment_offset + IP_HEADER_DATA_LENGTH( header ) / 8;
939
    offset = IP_FRAGMENT_OFFSET( header ) + IP_HEADER_DATA_LENGTH( header );
-
 
940
    printf( "offset %d = %d + %d\n", offset, IP_FRAGMENT_OFFSET( header ), IP_HEADER_DATA_LENGTH( header ));
-
 
941
    new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( offset );
-
 
942
    new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( offset );
986
    new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
943
    new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
987
    ERROR_PROPAGATE( packet_set_addr( new_packet, ( const uint8_t * ) src, ( const uint8_t * ) dest, addrlen ));
944
    ERROR_PROPAGATE( packet_set_addr( new_packet, ( const uint8_t * ) src, ( const uint8_t * ) dest, addrlen ));
988
    return pq_insert_after( packet, new_packet );
945
    return pq_insert_after( packet, new_packet );
989
}
946
}
990
 
947
 
991
ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){
948
ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){
992
    ip_header_ref   middle;
949
    ip_header_ref   middle;
993
 
950
 
994
    middle = ( ip_header_ref ) packet_suffix( packet, IP_HEADER_LENGTH( last ));
951
    middle = ( ip_header_ref ) packet_suffix( packet, IP_HEADER_LENGTH( last ));
995
    if( ! middle ) return NULL;
952
    if( ! middle ) return NULL;
996
    memcpy( middle, last, IP_HEADER_LENGTH( last ));
953
    memcpy( middle, last, IP_HEADER_LENGTH( last ));
997
    middle->flags |= IPFLAG_MORE_FRAGMENTS;
954
    middle->flags |= IPFLAG_MORE_FRAGMENTS;
998
    return middle;
955
    return middle;
999
}
956
}
1000
 
957
 
1001
void ip_create_last_header( ip_header_ref last, ip_header_ref first ){
958
void ip_create_last_header( ip_header_ref last, ip_header_ref first ){
1002
    ip_option_ref   option;
959
    ip_option_ref   option;
1003
    size_t          next;
960
    size_t          next;
1004
    size_t          length;
961
    size_t          length;
1005
 
962
 
1006
    // copy first itself
963
    // copy first itself
1007
    memcpy( last, first, sizeof( ip_header_t ));
964
    memcpy( last, first, sizeof( ip_header_t ));
1008
    length = sizeof( ip_header_t );
965
    length = sizeof( ip_header_t );
1009
    next = sizeof( ip_header_t );
966
    next = sizeof( ip_header_t );
1010
    // process all ip options
967
    // process all ip options
1011
    while( next < first->header_length ){
968
    while( next < first->header_length ){
1012
        option = ( ip_option_ref ) ((( uint8_t * ) first ) + next );
969
        option = ( ip_option_ref ) ((( uint8_t * ) first ) + next );
1013
        // skip end or noop
970
        // skip end or noop
1014
        if(( option->type == IPOPT_END ) || ( option->type == IPOPT_NOOP )){
971
        if(( option->type == IPOPT_END ) || ( option->type == IPOPT_NOOP )){
1015
            ++ next;
972
            ++ next;
1016
        }else{
973
        }else{
1017
            // copy if said so or skip
974
            // copy if said so or skip
1018
            if( IPOPT_COPIED( option->type )){
975
            if( IPOPT_COPIED( option->type )){
1019
                memcpy((( uint8_t * ) last ) + length, (( uint8_t * ) first ) + next, option->length );
976
                memcpy((( uint8_t * ) last ) + length, (( uint8_t * ) first ) + next, option->length );
1020
                length += option->length;
977
                length += option->length;
1021
            }
978
            }
1022
            // next option
979
            // next option
1023
            next += option->length;
980
            next += option->length;
1024
        }
981
        }
1025
    }
982
    }
1026
    // align 4 byte boundary
983
    // align 4 byte boundary
1027
    if( length % 4 ){
984
    if( length % 4 ){
1028
        bzero((( uint8_t * ) last ) + length, 4 - ( length % 4 ));
985
        bzero((( uint8_t * ) last ) + length, 4 - ( length % 4 ));
1029
        last->header_length = length / 4 + 1;
986
        last->header_length = length / 4 + 1;
1030
    }else{
987
    }else{
1031
        last->header_length = length / 4;
988
        last->header_length = length / 4;
1032
    }
989
    }
1033
    last->header_checksum = 0;
990
    last->header_checksum = 0;
1034
}
991
}
1035
 
992
 
1036
int ip_receive_message( device_id_t device_id, packet_t packet ){
993
int ip_receive_message( device_id_t device_id, packet_t packet ){
1037
    packet_t        next;
994
    packet_t        next;
1038
 
995
 
1039
    do{
996
    do{
1040
        next = pq_detach( packet );
997
        next = pq_detach( packet );
1041
        ip_process_packet( device_id, packet );
998
        ip_process_packet( device_id, packet );
1042
        packet = next;
999
        packet = next;
1043
    }while( packet );
1000
    }while( packet );
1044
    return EOK;
1001
    return EOK;
1045
}
1002
}
1046
 
1003
 
1047
int ip_process_packet( device_id_t device_id, packet_t packet ){
1004
int ip_process_packet( device_id_t device_id, packet_t packet ){
1048
    ERROR_DECLARE;
1005
    ERROR_DECLARE;
1049
 
1006
 
1050
    ip_header_ref   header;
1007
    ip_header_ref   header;
1051
    in_addr_t       dest;
1008
    in_addr_t       dest;
1052
    ip_route_ref    route;
1009
    ip_route_ref    route;
1053
    int             phone;
1010
    int             phone;
1054
    struct sockaddr *   addr;
1011
    struct sockaddr *   addr;
1055
    struct sockaddr_in  addr_in;
1012
    struct sockaddr_in  addr_in;
1056
//  struct sockaddr_in  addr_in6;
1013
//  struct sockaddr_in  addr_in6;
1057
    socklen_t       addrlen;
1014
    socklen_t       addrlen;
1058
 
1015
 
1059
    header = ( ip_header_ref ) packet_get_data( packet );
1016
    header = ( ip_header_ref ) packet_get_data( packet );
1060
    if( ! header ){
1017
    if( ! header ){
1061
        return ip_release_and_return( packet, ENOMEM );
1018
        return ip_release_and_return( packet, ENOMEM );
1062
    }
1019
    }
1063
    // checksum
1020
    // checksum
1064
    if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ))){
1021
    if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ))){
-
 
1022
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
-
 
1023
        if( phone >= 0 ){
1065
        // TODO checksum error ICMP?
1024
            // checksum error ICMP
-
 
1025
            icmp_parameter_problem_msg( phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->header_checksum )) - (( size_t ) (( void * ) header )), packet );
-
 
1026
        }
1066
        return ip_release_and_return( packet, EINVAL );
1027
        return EINVAL;
1067
    }
1028
    }
1068
    if( header->ttl <= 1 ){
1029
    if( header->ttl <= 1 ){
1069
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1030
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1070
        if( phone >= 0 ){
1031
        if( phone >= 0 ){
1071
            // ttl oxceeded ICMP
1032
            // ttl oxceeded ICMP
1072
            icmp_time_exceeded_msg( phone, ICMP_EXC_TTL, packet );
1033
            icmp_time_exceeded_msg( phone, ICMP_EXC_TTL, packet );
1073
        }
1034
        }
1074
        return EINVAL;
1035
        return EINVAL;
1075
    }
1036
    }
1076
    // process ipopt and get destination
1037
    // process ipopt and get destination
1077
    dest = ip_get_destination( header );
1038
    dest = ip_get_destination( header );
1078
    // set the addrination address
1039
    // set the addrination address
1079
    switch( header->version ){
1040
    switch( header->version ){
1080
        case IPVERSION:
1041
        case IPVERSION:
1081
            addrlen = sizeof( addr_in );
1042
            addrlen = sizeof( addr_in );
1082
            bzero( & addr_in, addrlen );
1043
            bzero( & addr_in, addrlen );
1083
            addr_in.sin_family = AF_INET;
1044
            addr_in.sin_family = AF_INET;
1084
            memcpy( & addr_in.sin_addr.s_addr, & dest, sizeof( dest ));
1045
            memcpy( & addr_in.sin_addr.s_addr, & dest, sizeof( dest ));
1085
            addr = ( struct sockaddr * ) & addr_in;
1046
            addr = ( struct sockaddr * ) & addr_in;
1086
            break;
1047
            break;
1087
/*      case IPv6VERSION:
1048
/*      case IPv6VERSION:
1088
            addrlen = sizeof( dest_in6 );
1049
            addrlen = sizeof( dest_in6 );
1089
            bzero( & dest_in6, addrlen );
1050
            bzero( & dest_in6, addrlen );
1090
            dest_in6.sin6_family = AF_INET6;
1051
            dest_in6.sin6_family = AF_INET6;
1091
            memcpy( & dest_in6.sin6_addr.s6_addr, );
1052
            memcpy( & dest_in6.sin6_addr.s6_addr, );
1092
            dest = ( struct sockaddr * ) & dest_in;
1053
            dest = ( struct sockaddr * ) & dest_in;
1093
            break;
1054
            break;
1094
*/      default:
1055
*/      default:
1095
            return EAFNOSUPPORT;
1056
            return EAFNOSUPPORT;
1096
    }
1057
    }
1097
    ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & addr, addrlen ));
1058
    ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & addr, addrlen ));
1098
    route = ip_find_route( dest );
1059
    route = ip_find_route( dest );
1099
    if( ! route ){
1060
    if( ! route ){
1100
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1061
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1101
        if( phone >= 0 ){
1062
        if( phone >= 0 ){
1102
            // unreachable ICMP
1063
            // unreachable ICMP
1103
            icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
1064
            icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
1104
        }
1065
        }
1105
        return ENOENT;
1066
        return ENOENT;
1106
    }
1067
    }
1107
    if( route->address.s_addr == dest.s_addr ){
1068
    if( route->address.s_addr == dest.s_addr ){
1108
        // local delivery
1069
        // local delivery
1109
        return ip_deliver_local( device_id, packet, header, 0 );
1070
        return ip_deliver_local( device_id, packet, header, 0 );
1110
    }else{
1071
    }else{
1111
        // only if routing enabled
1072
        // only if routing enabled
1112
        if( route->netif->routing ){
1073
        if( route->netif->routing ){
1113
            -- header->ttl;
1074
            -- header->ttl;
1114
            return ip_send_route( packet, route->netif, route, NULL, dest, 0 );
1075
            return ip_send_route( packet, route->netif, route, NULL, dest, 0 );
1115
        }else{
1076
        }else{
1116
            phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1077
            phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1117
            if( phone >= 0 ){
1078
            if( phone >= 0 ){
1118
                // unreachable ICMP if no routing
1079
                // unreachable ICMP if no routing
1119
                icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
1080
                icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
1120
            }
1081
            }
1121
            return ENOENT;
1082
            return ENOENT;
1122
        }
1083
        }
1123
    }
1084
    }
1124
}
1085
}
1125
 
1086
 
1126
int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error ){
1087
int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error ){
1127
    uint8_t *           data;
1088
    uint8_t *           data;
1128
    int                 offset;
1089
    int                 offset;
1129
    icmp_type_t         type;
1090
    icmp_type_t         type;
1130
    icmp_code_t         code;
1091
    icmp_code_t         code;
1131
    ip_netif_ref        netif;
1092
    ip_netif_ref        netif;
1132
    measured_string_t   address;
1093
    measured_string_t   address;
1133
    ip_route_ref        route;
1094
    ip_route_ref        route;
1134
    ip_header_ref       header;
1095
    ip_header_ref       header;
1135
 
1096
 
1136
    switch( error ){
1097
    switch( error ){
1137
        case SERVICE_ICMP:
1098
        case SERVICE_ICMP:
1138
            offset = icmp_client_process_packet( packet, & type, & code, NULL, NULL );
1099
            offset = icmp_client_process_packet( packet, & type, & code, NULL, NULL );
1139
            if( offset < 0 ){
1100
            if( offset < 0 ){
1140
                return ip_release_and_return( packet, ENOMEM );
1101
                return ip_release_and_return( packet, ENOMEM );
1141
            }
1102
            }
1142
            data = packet_get_data( packet );
1103
            data = packet_get_data( packet );
1143
            header = ( ip_header_ref )( data + offset );
1104
            header = ( ip_header_ref )( data + offset );
1144
            // destination host unreachable?
1105
            // destination host unreachable?
1145
            if(( type == ICMP_DEST_UNREACH ) && ( code == ICMP_HOST_UNREACH )){
1106
            if(( type == ICMP_DEST_UNREACH ) && ( code == ICMP_HOST_UNREACH )){
1146
                fibril_rwlock_read_lock( & ip_globals.netifs_lock );
1107
                fibril_rwlock_read_lock( & ip_globals.netifs_lock );
1147
                netif = ip_netifs_find( & ip_globals.netifs, device_id );
1108
                netif = ip_netifs_find( & ip_globals.netifs, device_id );
1148
                if( netif && netif->arp ){
1109
                if( netif && netif->arp ){
1149
                    route = ip_routes_get_index( & netif->routes, 0 );
1110
                    route = ip_routes_get_index( & netif->routes, 0 );
1150
                    // from the same network?
1111
                    // from the same network?
1151
                    if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( header->destination_address & route->netmask.s_addr ))){
1112
                    if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( header->destination_address & route->netmask.s_addr ))){
1152
                        // clear the ARP mapping if any
1113
                        // clear the ARP mapping if any
1153
                        address.value = ( char * ) & header->destination_address;
1114
                        address.value = ( char * ) & header->destination_address;
1154
                        address.length = CONVERT_SIZE( uint8_t, char, sizeof( header->destination_address ));
1115
                        address.length = CONVERT_SIZE( uint8_t, char, sizeof( header->destination_address ));
1155
                        arp_clear_address_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address );
1116
                        arp_clear_address_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address );
1156
                    }
1117
                    }
1157
                }
1118
                }
1158
                fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
1119
                fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
1159
            }
1120
            }
1160
            break;
1121
            break;
1161
        default:
1122
        default:
1162
            return ip_release_and_return( packet, ENOTSUP );
1123
            return ip_release_and_return( packet, ENOTSUP );
1163
    }
1124
    }
1164
    return ip_deliver_local( device_id, packet, header, error );
1125
    return ip_deliver_local( device_id, packet, header, error );
1165
}
1126
}
1166
 
1127
 
1167
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ){
1128
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ){
1168
    ERROR_DECLARE;
1129
    ERROR_DECLARE;
1169
 
1130
 
1170
    ip_proto_ref    proto;
1131
    ip_proto_ref    proto;
1171
    int             phone;
1132
    int             phone;
1172
    services_t      service;
1133
    services_t      service;
1173
    tl_received_msg_t   received_msg;
1134
    tl_received_msg_t   received_msg;
1174
    struct sockaddr *   src;
1135
    struct sockaddr *   src;
1175
    struct sockaddr *   dest;
1136
    struct sockaddr *   dest;
1176
    struct sockaddr_in  src_in;
1137
    struct sockaddr_in  src_in;
1177
    struct sockaddr_in  dest_in;
1138
    struct sockaddr_in  dest_in;
1178
//  struct sockaddr_in  src_in6;
1139
//  struct sockaddr_in  src_in6;
1179
//  struct sockaddr_in  dest_in6;
1140
//  struct sockaddr_in  dest_in6;
1180
    socklen_t       addrlen;
1141
    socklen_t       addrlen;
1181
 
1142
 
1182
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
1143
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || IP_FRAGMENT_OFFSET( header )){
1183
        // TODO fragmented
1144
        // TODO fragmented
1184
        return ENOTSUP;
1145
        return ENOTSUP;
1185
    }else{
1146
    }else{
1186
        switch( header->version ){
1147
        switch( header->version ){
1187
            case IPVERSION:
1148
            case IPVERSION:
1188
                addrlen = sizeof( src_in );
1149
                addrlen = sizeof( src_in );
1189
                bzero( & src_in, addrlen );
1150
                bzero( & src_in, addrlen );
1190
                src_in.sin_family = AF_INET;
1151
                src_in.sin_family = AF_INET;
1191
                memcpy( & dest_in, & src_in, addrlen );
1152
                memcpy( & dest_in, & src_in, addrlen );
1192
                memcpy( & src_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address ));
1153
                memcpy( & src_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address ));
1193
                memcpy( & dest_in.sin_addr.s_addr, & header->destination_address, sizeof( header->destination_address ));
1154
                memcpy( & dest_in.sin_addr.s_addr, & header->destination_address, sizeof( header->destination_address ));
1194
                src = ( struct sockaddr * ) & src_in;
1155
                src = ( struct sockaddr * ) & src_in;
1195
                dest = ( struct sockaddr * ) & dest_in;
1156
                dest = ( struct sockaddr * ) & dest_in;
1196
                break;
1157
                break;
1197
/*          case IPv6VERSION:
1158
/*          case IPv6VERSION:
1198
                addrlen = sizeof( src_in6 );
1159
                addrlen = sizeof( src_in6 );
1199
                bzero( & src_in6, addrlen );
1160
                bzero( & src_in6, addrlen );
1200
                src_in6.sin6_family = AF_INET6;
1161
                src_in6.sin6_family = AF_INET6;
1201
                memcpy( & dest_in6, & src_in6, addrlen );
1162
                memcpy( & dest_in6, & src_in6, addrlen );
1202
                memcpy( & src_in6.sin6_addr.s6_addr, );
1163
                memcpy( & src_in6.sin6_addr.s6_addr, );
1203
                memcpy( & dest_in6.sin6_addr.s6_addr, );
1164
                memcpy( & dest_in6.sin6_addr.s6_addr, );
1204
                src = ( struct sockaddr * ) & src_in;
1165
                src = ( struct sockaddr * ) & src_in;
1205
                dest = ( struct sockaddr * ) & dest_in;
1166
                dest = ( struct sockaddr * ) & dest_in;
1206
                break;
1167
                break;
1207
*/          default:
1168
*/          default:
1208
                return EAFNOSUPPORT;
1169
                return EAFNOSUPPORT;
1209
        }
1170
        }
1210
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) src, ( uint8_t * ) dest, addrlen ));
1171
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) src, ( uint8_t * ) dest, addrlen ));
1211
        fibril_rwlock_read_lock( & ip_globals.protos_lock );
1172
        fibril_rwlock_read_lock( & ip_globals.protos_lock );
1212
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
1173
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
1213
        if( ! proto ){
1174
        if( ! proto ){
1214
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1175
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1215
            phone = ip_prepare_icmp_and_get_phone( error, packet, header );
1176
            phone = ip_prepare_icmp_and_get_phone( error, packet, header );
1216
            if( phone >= 0 ){
1177
            if( phone >= 0 ){
1217
                // unreachable ICMP
1178
                // unreachable ICMP
1218
                icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet );
1179
                icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet );
1219
            }
1180
            }
1220
            return ENOENT;
1181
            return ENOENT;
1221
        }
1182
        }
1222
        if( proto->received_msg ){
1183
        if( proto->received_msg ){
1223
            service = proto->service;
1184
            service = proto->service;
1224
            received_msg = proto->received_msg;
1185
            received_msg = proto->received_msg;
1225
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1186
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1226
            ERROR_CODE = received_msg( device_id, packet, service, error );
1187
            ERROR_CODE = received_msg( device_id, packet, service, error );
1227
        }else{
1188
        }else{
1228
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error );
1189
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error );
1229
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1190
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1230
        }
1191
        }
1231
        return ERROR_CODE;
1192
        return ERROR_CODE;
1232
    }
1193
    }
1233
}
1194
}
1234
 
1195
 
1235
in_addr_t ip_get_destination( ip_header_ref header ){
1196
in_addr_t ip_get_destination( ip_header_ref header ){
1236
    in_addr_t   destination;
1197
    in_addr_t   destination;
1237
 
1198
 
1238
    // TODO search set ipopt route?
1199
    // TODO search set ipopt route?
1239
    destination.s_addr = header->destination_address;
1200
    destination.s_addr = header->destination_address;
1240
    return destination;
1201
    return destination;
1241
}
1202
}
1242
 
1203
 
1243
int ip_prepare_icmp( packet_t packet, ip_header_ref header ){
1204
int ip_prepare_icmp( packet_t packet, ip_header_ref header ){
1244
    packet_t    next;
1205
    packet_t    next;
1245
    struct sockaddr *   dest;
1206
    struct sockaddr *   dest;
1246
    struct sockaddr_in  dest_in;
1207
    struct sockaddr_in  dest_in;
1247
//  struct sockaddr_in  dest_in6;
1208
//  struct sockaddr_in  dest_in6;
1248
    socklen_t       addrlen;
1209
    socklen_t       addrlen;
1249
 
1210
 
1250
    // detach the first packet and release the others
1211
    // detach the first packet and release the others
1251
    next = pq_detach( packet );
1212
    next = pq_detach( packet );
1252
    if( next ){
1213
    if( next ){
1253
        pq_release( ip_globals.net_phone, packet_get_id( next ));
1214
        pq_release( ip_globals.net_phone, packet_get_id( next ));
1254
    }
1215
    }
1255
    if( ! header ){
1216
    if( ! header ){
1256
        if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
1217
        if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
1257
        // get header
1218
        // get header
1258
        header = ( ip_header_ref ) packet_get_data( packet );
1219
        header = ( ip_header_ref ) packet_get_data( packet );
1259
        if( ! header ) return EINVAL;
1220
        if( ! header ) return EINVAL;
1260
    }
1221
    }
1261
    // only for the first fragment
1222
    // only for the first fragment
1262
    if( header->fragment_offset ) return EINVAL;
1223
    if( IP_FRAGMENT_OFFSET( header )) return EINVAL;
1263
    // set the destination address
1224
    // set the destination address
1264
    switch( header->version ){
1225
    switch( header->version ){
1265
        case IPVERSION:
1226
        case IPVERSION:
1266
            addrlen = sizeof( dest_in );
1227
            addrlen = sizeof( dest_in );
1267
            bzero( & dest_in, addrlen );
1228
            bzero( & dest_in, addrlen );
1268
            dest_in.sin_family = AF_INET;
1229
            dest_in.sin_family = AF_INET;
1269
            memcpy( & dest_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address ));
1230
            memcpy( & dest_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address ));
1270
            dest = ( struct sockaddr * ) & dest_in;
1231
            dest = ( struct sockaddr * ) & dest_in;
1271
            break;
1232
            break;
1272
/*      case IPv6VERSION:
1233
/*      case IPv6VERSION:
1273
            addrlen = sizeof( dest_in6 );
1234
            addrlen = sizeof( dest_in6 );
1274
            bzero( & dest_in6, addrlen );
1235
            bzero( & dest_in6, addrlen );
1275
            dest_in6.sin6_family = AF_INET6;
1236
            dest_in6.sin6_family = AF_INET6;
1276
            memcpy( & dest_in6.sin6_addr.s6_addr, );
1237
            memcpy( & dest_in6.sin6_addr.s6_addr, );
1277
            dest = ( struct sockaddr * ) & dest_in;
1238
            dest = ( struct sockaddr * ) & dest_in;
1278
            break;
1239
            break;
1279
*/      default:
1240
*/      default:
1280
            return EAFNOSUPPORT;
1241
            return EAFNOSUPPORT;
1281
    }
1242
    }
1282
    return packet_set_addr( packet, NULL, ( uint8_t * ) dest, addrlen );
1243
    return packet_set_addr( packet, NULL, ( uint8_t * ) dest, addrlen );
1283
}
1244
}
1284
 
1245
 
1285
int ip_get_icmp_phone( void ){
1246
int ip_get_icmp_phone( void ){
1286
    ip_proto_ref    proto;
1247
    ip_proto_ref    proto;
1287
    int             phone;
1248
    int             phone;
1288
 
1249
 
1289
    fibril_rwlock_read_lock( & ip_globals.protos_lock );
1250
    fibril_rwlock_read_lock( & ip_globals.protos_lock );
1290
    proto = ip_protos_find( & ip_globals.protos, IPPROTO_ICMP );
1251
    proto = ip_protos_find( & ip_globals.protos, IPPROTO_ICMP );
1291
    phone = proto ? proto->phone : ENOENT;
1252
    phone = proto ? proto->phone : ENOENT;
1292
    fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1253
    fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1293
    return phone;
1254
    return phone;
1294
}
1255
}
1295
 
1256
 
1296
int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ){
1257
int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ){
1297
    int phone;
1258
    int phone;
1298
 
1259
 
1299
    phone = ip_get_icmp_phone();
1260
    phone = ip_get_icmp_phone();
1300
    if( error || ( phone < 0 ) || ip_prepare_icmp( packet, header )){
1261
    if( error || ( phone < 0 ) || ip_prepare_icmp( packet, header )){
1301
        return ip_release_and_return( packet, EINVAL );
1262
        return ip_release_and_return( packet, EINVAL );
1302
    }
1263
    }
1303
    return phone;
1264
    return phone;
1304
}
1265
}
1305
 
1266
 
1306
int ip_release_and_return( packet_t packet, int result ){
1267
int ip_release_and_return( packet_t packet, int result ){
1307
    pq_release( ip_globals.net_phone, packet_get_id( packet ));
1268
    pq_release( ip_globals.net_phone, packet_get_id( packet ));
1308
    return result;
1269
    return result;
1309
}
1270
}
1310
 
1271
 
1311
int ip_get_route_req( int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen ){
1272
int ip_get_route_req( int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen ){
1312
    struct sockaddr_in *    address_in;
1273
    struct sockaddr_in *    address_in;
1313
//  struct sockaddr_in6 *   address_in6;
1274
//  struct sockaddr_in6 *   address_in6;
1314
    in_addr_t *             dest;
1275
    in_addr_t *             dest;
1315
    in_addr_t *             src;
1276
    in_addr_t *             src;
1316
    ip_route_ref            route;
1277
    ip_route_ref            route;
1317
    ipv4_pseudo_header_ref  header_in;
1278
    ipv4_pseudo_header_ref  header_in;
1318
 
1279
 
1319
    if( !( destination && ( addrlen > 0 ))) return EINVAL;
1280
    if( !( destination && ( addrlen > 0 ))) return EINVAL;
1320
    if( !( device_id && header && headerlen )) return EBADMEM;
1281
    if( !( device_id && header && headerlen )) return EBADMEM;
1321
    if( addrlen < sizeof( struct sockaddr )){
1282
    if( addrlen < sizeof( struct sockaddr )){
1322
        return EINVAL;
1283
        return EINVAL;
1323
    }
1284
    }
1324
    switch( destination->sa_family ){
1285
    switch( destination->sa_family ){
1325
        case AF_INET:
1286
        case AF_INET:
1326
            if( addrlen != sizeof( struct sockaddr_in )){
1287
            if( addrlen != sizeof( struct sockaddr_in )){
1327
                return EINVAL;
1288
                return EINVAL;
1328
            }
1289
            }
1329
            address_in = ( struct sockaddr_in * ) destination;
1290
            address_in = ( struct sockaddr_in * ) destination;
1330
            dest = & address_in->sin_addr;
1291
            dest = & address_in->sin_addr;
1331
            break;
1292
            break;
1332
        // TODO IPv6
1293
        // TODO IPv6
1333
/*      case AF_INET6:
1294
/*      case AF_INET6:
1334
            if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
1295
            if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
1335
            address_in6 = ( struct sockaddr_in6 * ) dest;
1296
            address_in6 = ( struct sockaddr_in6 * ) dest;
1336
            address_in6.sin6_addr.s6_addr;
1297
            address_in6.sin6_addr.s6_addr;
1337
*/      default:
1298
*/      default:
1338
            return EAFNOSUPPORT;
1299
            return EAFNOSUPPORT;
1339
    }
1300
    }
1340
    fibril_rwlock_read_lock( & ip_globals.lock );
1301
    fibril_rwlock_read_lock( & ip_globals.lock );
1341
    route = ip_find_route( * dest );
1302
    route = ip_find_route( * dest );
1342
    if( !( route && route->netif )){
1303
    if( !( route && route->netif )){
1343
        fibril_rwlock_read_unlock( & ip_globals.lock );
1304
        fibril_rwlock_read_unlock( & ip_globals.lock );
1344
        return ENOENT;
1305
        return ENOENT;
1345
    }
1306
    }
1346
    * device_id = route->netif->device_id;
1307
    * device_id = route->netif->device_id;
1347
    src = ip_netif_address( route->netif );
1308
    src = ip_netif_address( route->netif );
1348
    fibril_rwlock_read_unlock( & ip_globals.lock );
1309
    fibril_rwlock_read_unlock( & ip_globals.lock );
1349
    * headerlen = sizeof( * header_in );
1310
    * headerlen = sizeof( * header_in );
1350
    header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen );
1311
    header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen );
1351
    if( ! header_in ) return ENOMEM;
1312
    if( ! header_in ) return ENOMEM;
1352
    bzero( header_in, * headerlen );
1313
    bzero( header_in, * headerlen );
1353
    header_in->destination_address = dest->s_addr;
1314
    header_in->destination_address = dest->s_addr;
1354
    header_in->source_address = src->s_addr;
1315
    header_in->source_address = src->s_addr;
1355
    header_in->protocol = protocol;
1316
    header_in->protocol = protocol;
1356
    header_in->data_length = 0;
1317
    header_in->data_length = 0;
1357
    * header = ( ip_pseudo_header_ref ) header_in;
1318
    * header = ( ip_pseudo_header_ref ) header_in;
1358
    return EOK;
1319
    return EOK;
1359
}
1320
}
1360
 
1321
 
1361
/** @}
1322
/** @}
1362
 */
1323
 */
1363
 
1324