Subversion Repositories HelenOS

Rev

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

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