Subversion Repositories HelenOS

Rev

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

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