Subversion Repositories HelenOS

Rev

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

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