Subversion Repositories HelenOS

Rev

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

Rev 4695 Rev 4702
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.
-
 
35
 *  @see arp.h
-
 
36
 *  \todo
34
 */
37
 */
35
 
38
 
36
#include <async.h>
39
#include <async.h>
37
#include <errno.h>
40
#include <errno.h>
38
#include <fibril_sync.h>
41
#include <fibril_sync.h>
39
#include <stdio.h>
42
#include <stdio.h>
40
#include <string.h>
43
#include <string.h>
41
 
44
 
42
#include <ipc/ipc.h>
45
#include <ipc/ipc.h>
43
#include <ipc/services.h>
46
#include <ipc/services.h>
44
 
47
 
45
#include <sys/types.h>
48
#include <sys/types.h>
46
 
49
 
47
#include "../../err.h"
50
#include "../../err.h"
48
#include "../../messages.h"
51
#include "../../messages.h"
49
#include "../../modules.h"
52
#include "../../modules.h"
50
 
53
 
51
#include "../../include/net_interface.h"
54
#include "../../include/net_interface.h"
52
#include "../../include/inet.h"
55
#include "../../include/inet.h"
53
#include "../../include/socket.h"
56
#include "../../include/socket.h"
54
#include "../../include/byteorder.h"
57
#include "../../include/byteorder.h"
55
#include "../../include/crc.h"
58
#include "../../include/crc.h"
56
#include "../../include/device.h"
59
#include "../../include/device.h"
57
#include "../../include/arp_interface.h"
60
#include "../../include/arp_interface.h"
58
#include "../../include/nil_interface.h"
61
#include "../../include/nil_interface.h"
59
#include "../../include/il_interface.h"
62
#include "../../include/il_interface.h"
60
#include "../../include/ip_client.h"
63
#include "../../include/ip_client.h"
61
#include "../../include/ip_interface.h"
64
#include "../../include/ip_interface.h"
62
#include "../../include/tl_interface.h"
65
#include "../../include/tl_interface.h"
63
#include "../../structures/measured_strings.h"
66
#include "../../structures/measured_strings.h"
64
#include "../../structures/module_map.h"
67
#include "../../structures/module_map.h"
65
#include "../../structures/packet/packet_client.h"
68
#include "../../structures/packet/packet_client.h"
66
 
69
 
67
#include "../../nil/nil_messages.h"
70
#include "../../nil/nil_messages.h"
68
 
71
 
69
#include "../il_messages.h"
72
#include "../il_messages.h"
70
 
73
 
71
#include "ip.h"
74
#include "ip.h"
72
#include "ip_header.h"
75
#include "ip_header.h"
73
#include "ip_messages.h"
76
#include "ip_messages.h"
74
#include "ip_module.h"
77
#include "ip_module.h"
75
 
78
 
-
 
79
/** Default IP version.
-
 
80
 */
76
#define DEFAULT_IPV     4
81
#define DEFAULT_IPV     4
-
 
82
 
-
 
83
/** Minimum IP packet content.
-
 
84
 */
77
#define IP_MIN_CONTENT  576
85
#define IP_MIN_CONTENT  576
78
 
86
 
-
 
87
/** ARP module name.
-
 
88
 */
79
#define ARP_NAME                "arp"
89
#define ARP_NAME                "arp"
-
 
90
 
-
 
91
/** ARP module filename.
-
 
92
 */
80
#define ARP_FILENAME            "/srv/arp"
93
#define ARP_FILENAME            "/srv/arp"
81
 
94
 
-
 
95
/** IP packet address length.
-
 
96
 */
82
#define IP_ADDR                         sizeof( in_addr_t )
97
#define IP_ADDR                         sizeof( in_addr_t )
-
 
98
 
-
 
99
/** IP packet prefix length.
-
 
100
 */
83
#define IP_PREFIX                       sizeof( ip_header_t )
101
#define IP_PREFIX                       sizeof( ip_header_t )
-
 
102
 
-
 
103
/** IP packet suffix length.
-
 
104
 */
84
#define IP_SUFFIX                       0
105
#define IP_SUFFIX                       0
-
 
106
 
-
 
107
/** IP packet maximum content length.
-
 
108
 */
85
#define IP_MAX_CONTENT                  65535
109
#define IP_MAX_CONTENT                  65535
-
 
110
 
-
 
111
/** Returns the actual IP header length.
-
 
112
 *  @param header The IP packet header. Input parameter.
-
 
113
 */
86
#define IP_HEADER_LENGTH( header )      (( header )->ihl * 4u )
114
#define IP_HEADER_LENGTH( header )      (( header )->ihl * 4u )
-
 
115
 
-
 
116
/** Returns the actual IP packet total length.
-
 
117
 *  @param header The IP packet header. Input parameter.
-
 
118
 */
87
#define IP_TOTAL_LENGTH( header )       ntohs(( header )->total_length )
119
#define IP_TOTAL_LENGTH( header )       ntohs(( header )->total_length )
-
 
120
 
-
 
121
/** Returns the actual IP packet data length.
-
 
122
 *  @param header The IP packet header. Input parameter.
-
 
123
 */
88
#define IP_HEADER_DATA_LENGTH( header ) ( IP_TOTAL_LENGTH( header ) - IP_HEADER_LENGTH( header ))
124
#define IP_HEADER_DATA_LENGTH( header ) ( IP_TOTAL_LENGTH( header ) - IP_HEADER_LENGTH( header ))
-
 
125
 
-
 
126
/** Returns the IP packet header checksum.
-
 
127
 *  @param header The IP packet header. Input parameter.
-
 
128
 */
89
#define IP_HEADER_CHECKSUM( header )    ( htons( ip_checksum(( uint8_t * )( header ), IP_HEADER_LENGTH( header ))))
129
#define IP_HEADER_CHECKSUM( header )    ( htons( ip_checksum(( uint8_t * )( header ), IP_HEADER_LENGTH( header ))))
90
 
130
 
-
 
131
/** IP header checksum value for computed zero checksum.
91
//zero is returned as 0xFFFF (not flipped)
132
 *  Zero is returned as 0xFFFF (not flipped)
-
 
133
 */
92
#define IP_HEADER_CHECKSUM_ZERO         0xFFFFu
134
#define IP_HEADER_CHECKSUM_ZERO         0xFFFFu
93
 
135
 
-
 
136
/** IP global data.
-
 
137
 */
94
ip_globals_t    ip_globals;
138
ip_globals_t    ip_globals;
95
 
139
 
96
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
140
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
97
 
141
 
98
INT_MAP_IMPLEMENT( ip_protos, ip_proto_t )
142
INT_MAP_IMPLEMENT( ip_protos, ip_proto_t )
99
 
143
 
100
GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t )
144
GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t )
101
 
145
 
-
 
146
/** Updates the device content length according to the new MTU value.
-
 
147
 *  @param device_id The device identifier. Input parameter.
-
 
148
 *  @param mtu The new mtu value. Input parameter.
-
 
149
 *  @returns EOK on success.
-
 
150
 *  @returns ENOENT if device is not found.
-
 
151
 */
102
int ip_mtu_changed_msg( device_id_t device_id, size_t mtu );
152
int ip_mtu_changed_message( device_id_t device_id, size_t mtu );
-
 
153
 
-
 
154
/** Updates the device state.
-
 
155
 *  @param device_id The device identifier. Input parameter.
-
 
156
 *  @param state The new state value. Input parameter.
-
 
157
 *  @returns EOK on success.
-
 
158
 *  @returns ENOENT if device is not found.
-
 
159
 */
103
int ip_device_state_msg( int il_phone, device_id_t device_id, device_state_t state );
160
int ip_device_state_message( device_id_t device_id, device_state_t state );
-
 
161
 
104
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg );
162
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg );
-
 
163
 
-
 
164
/** Initializes a new network interface specific data.
-
 
165
 *  Connects to the network interface layer module, reads the netif configuration, starts an ARP module if needed and sets the netif routing table.
-
 
166
 *  The device identifier and the nil service has to be set.
-
 
167
 *  @param ip_netif Network interface specific data. Input/output parameter.
-
 
168
 *  @returns EOK on success.
-
 
169
 *  @returns ENOTSUP if DHCP is configured.
-
 
170
 *  @returns ENOTSUP if IPv6 is configured.
-
 
171
 *  @returns EINVAL if any of the addresses is invalid.
-
 
172
 *  @returns EINVAL if the used ARP module is not known.
-
 
173
 *  @returns ENOMEM if there is not enough memory left.
-
 
174
 *  @returns Other error codes as defined for the net_get_device_conf_req() function.
-
 
175
 *  @returns Other error codes as defined for the bind_service() function.
-
 
176
 *  @returns Other error codes as defined for the specific arp_device_req() function.
-
 
177
 *  @returns Other error codes as defined for the nil_packet_size_req() function.
-
 
178
 */
105
int ip_netif_initialize( ip_netif_ref ip_netif );
179
int ip_netif_initialize( ip_netif_ref ip_netif );
106
 
180
 
107
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest );
181
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest );
108
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination );
182
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination );
109
 
183
 
110
packet_t    ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len );
184
packet_t    ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len );
111
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, size_t addr_len );
185
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, size_t addr_len );
112
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, void * src, void * dest, size_t address_length );
186
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, void * src, void * dest, size_t address_length );
113
ip_header_ref   ip_create_middle_header( packet_t packet, ip_header_ref last );
187
ip_header_ref   ip_create_middle_header( packet_t packet, ip_header_ref last );
114
void ip_create_last_header( ip_header_ref last, ip_header_ref first );
188
void ip_create_last_header( ip_header_ref last, ip_header_ref first );
115
 
189
 
116
in_addr_t * ip_netif_addr( ip_netif_ref netif );
190
in_addr_t * ip_netif_addr( ip_netif_ref netif );
117
ip_route_ref    ip_find_route( in_addr_t destination );
191
ip_route_ref    ip_find_route( in_addr_t destination );
118
ip_route_ref    ip_netif_find_route( ip_netif_ref netif, in_addr_t destination );
192
ip_route_ref    ip_netif_find_route( ip_netif_ref netif, in_addr_t destination );
119
 
193
 
-
 
194
/** Processes the received IP packet.
-
 
195
 *  @param device_id The source device identifier. Input parameter.
-
 
196
 *  @param packet The received packet. Input/output parameter.
-
 
197
 *  @returns EOK on success and the packet is no longer needed.
-
 
198
 *  @returns EINVAL if the packet is too small to carry the IP packet.
-
 
199
 *  @returns EINVAL if the received address lengths differs from the registered values.
-
 
200
 *  @returns ENOENT if the device is not found in the cache.
-
 
201
 *  @returns ENOENT if the protocol for the device is not found in the cache.
-
 
202
 *  @returns ENOMEM if there is not enough memory left.
-
 
203
 */
120
int ip_received_msg( device_id_t device_id, packet_t packet );
204
int ip_receive_message( device_id_t device_id, packet_t packet );
-
 
205
 
121
int ip_process_packet( device_id_t device_id, packet_t packet );
206
int ip_process_packet( device_id_t device_id, packet_t packet );
122
in_addr_t   ip_get_destination( ip_header_ref header );
207
in_addr_t   ip_get_destination( ip_header_ref header );
123
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header );
208
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header );
124
 
209
 
125
/** Computes the ip header checksum.
210
/** Computes the ip header checksum.
126
 *  To compute the checksum of a new packet, the checksum header field must be zero.
211
 *  To compute the checksum of a new packet, the checksum header field must be zero.
127
 *  To check the checksum of a received packet, the checksum may be left set.
212
 *  To check the checksum of a received packet, the checksum may be left set.
128
 *  The zero (0) value will returned in this case if valid.
213
 *  The zero (0) value will returned in this case if valid.
129
 *  @param data The header data. Input parameter.
214
 *  @param data The header data. Input parameter.
130
 *  @param length The header length in bytes. Input parameter.
215
 *  @param length The header length in bytes. Input parameter.
131
 *  @returns The internet protocol header checksum.
216
 *  @returns The internet protocol header checksum.
132
 *  @returns 0xFFFF if the computed checksum is zero.
217
 *  @returns 0xFFFF if the computed checksum is zero.
133
 */
218
 */
134
uint16_t ip_checksum( uint8_t * data, size_t length );
219
uint16_t ip_checksum( uint8_t * data, size_t length );
135
 
220
 
136
uint16_t ip_checksum( uint8_t * data, size_t length ){
221
uint16_t ip_checksum( uint8_t * data, size_t length ){
137
    uint16_t    checksum;
222
    uint16_t    checksum;
138
 
223
 
139
    checksum = compact_checksum(compute_checksum( 0, data, length ));
224
    checksum = compact_checksum(compute_checksum( 0, data, length ));
140
 
225
 
141
    // flip, zero is returned as 0xFFFF (not flipped)
226
    // flip, zero is returned as 0xFFFF (not flipped)
142
    return ( ~ checksum ) ? ~ checksum : IP_HEADER_CHECKSUM_ZERO;
227
    return ( ~ checksum ) ? ~ checksum : IP_HEADER_CHECKSUM_ZERO;
143
}
228
}
144
 
229
 
145
/** Initializes the module.
-
 
146
 */
-
 
147
int ip_initialize( async_client_conn_t client_connection ){
230
int ip_initialize( async_client_conn_t client_connection ){
148
    ERROR_DECLARE;
231
    ERROR_DECLARE;
149
 
232
 
150
    fibril_rwlock_initialize( & ip_globals.lock );
233
    fibril_rwlock_initialize( & ip_globals.lock );
151
    fibril_rwlock_write_lock( & ip_globals.lock );
234
    fibril_rwlock_write_lock( & ip_globals.lock );
152
    fibril_rwlock_initialize( & ip_globals.protos_lock );
235
    fibril_rwlock_initialize( & ip_globals.protos_lock );
153
    fibril_rwlock_initialize( & ip_globals.netifs_lock );
236
    fibril_rwlock_initialize( & ip_globals.netifs_lock );
154
    ip_globals.packet_counter = 0;
237
    ip_globals.packet_counter = 0;
155
    ip_globals.gateway.address.s_addr = 0;
238
    ip_globals.gateway.address.s_addr = 0;
156
    ip_globals.gateway.netmask.s_addr = 0;
239
    ip_globals.gateway.netmask.s_addr = 0;
157
    ip_globals.gateway.gateway.s_addr = 0;
240
    ip_globals.gateway.gateway.s_addr = 0;
158
    ip_globals.gateway.netif = NULL;
241
    ip_globals.gateway.netif = NULL;
159
    ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
242
    ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
160
    ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
243
    ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
161
    ip_globals.client_connection = client_connection;
244
    ip_globals.client_connection = client_connection;
162
    ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
245
    ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
163
    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 ));
164
    fibril_rwlock_write_unlock( & ip_globals.lock );
247
    fibril_rwlock_write_unlock( & ip_globals.lock );
165
    return EOK;
248
    return EOK;
166
}
249
}
167
 
250
 
168
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 ){
169
    ERROR_DECLARE;
252
    ERROR_DECLARE;
170
 
253
 
171
    ip_netif_ref    ip_netif;
254
    ip_netif_ref    ip_netif;
172
    ip_route_ref    route;
255
    ip_route_ref    route;
173
    int             index;
256
    int             index;
174
    char *          data;
257
    char *          data;
175
 
258
 
176
    ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t ));
259
    ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t ));
177
    if( ! ip_netif ) return ENOMEM;
260
    if( ! ip_netif ) return ENOMEM;
178
    if( ERROR_OCCURRED( ip_routes_initialize( & ip_netif->routes ))){
261
    if( ERROR_OCCURRED( ip_routes_initialize( & ip_netif->routes ))){
179
        free( ip_netif );
262
        free( ip_netif );
180
        return ERROR_CODE;
263
        return ERROR_CODE;
181
    }
264
    }
182
    ip_netif->device_id = device_id;
265
    ip_netif->device_id = device_id;
183
    ip_netif->service = netif;
266
    ip_netif->service = netif;
184
    ip_netif->state = NETIF_STOPPED;
267
    ip_netif->state = NETIF_STOPPED;
185
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
268
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
186
    if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
269
    if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
187
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
270
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
188
        ip_routes_destroy( & ip_netif->routes );
271
        ip_routes_destroy( & ip_netif->routes );
189
        free( ip_netif );
272
        free( ip_netif );
190
        return ERROR_CODE;
273
        return ERROR_CODE;
191
    }
274
    }
192
    if( ip_netif->arp ) ++ ip_netif->arp->usage;
275
    if( ip_netif->arp ) ++ ip_netif->arp->usage;
193
    // print the settings
276
    // print the settings
194
    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 );
195
    printf( "\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static" );
278
    printf( "\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static" );
196
    // TODO ipv6 addresses
279
    // TODO ipv6 addresses
197
    data = ( char * ) malloc( INET_ADDRSTRLEN );
280
    data = ( char * ) malloc( INET_ADDRSTRLEN );
198
    if( data ){
281
    if( data ){
199
        for( index = 0; index < ip_routes_count( & ip_netif->routes ); ++ index ){
282
        for( index = 0; index < ip_routes_count( & ip_netif->routes ); ++ index ){
200
            route = ip_routes_get_index( & ip_netif->routes, index );
283
            route = ip_routes_get_index( & ip_netif->routes, index );
201
            if( route ){
284
            if( route ){
202
                printf( "\tRouting %d:\n", index );
285
                printf( "\tRouting %d:\n", index );
203
                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 );
204
                printf( "\t\taddress\t= %s\n", data );
287
                printf( "\t\taddress\t= %s\n", data );
205
                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 );
206
                printf( "\t\tnetmask\t= %s\n", data );
289
                printf( "\t\tnetmask\t= %s\n", data );
207
                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 );
208
                printf( "\t\tgateway\t= %s\n", data );
291
                printf( "\t\tgateway\t= %s\n", data );
209
            }
292
            }
210
        }
293
        }
211
        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 );
212
        printf( "\tbroadcast\t= %s\n", data );
295
        printf( "\tbroadcast\t= %s\n", data );
213
        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 );
214
        printf( "\tdns1\t= %s\n", data );
297
        printf( "\tdns1\t= %s\n", data );
215
        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 );
216
        printf( "\tdns2\t= %s\n", data );
299
        printf( "\tdns2\t= %s\n", data );
217
        free( data );
300
        free( data );
218
    }
301
    }
219
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
302
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
220
    return EOK;
303
    return EOK;
221
}
304
}
222
 
305
 
223
int ip_netif_initialize( ip_netif_ref ip_netif ){
306
int ip_netif_initialize( ip_netif_ref ip_netif ){
224
    ERROR_DECLARE;
307
    ERROR_DECLARE;
225
 
308
 
226
    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 }};
227
    measured_string_ref configuration;
310
    measured_string_ref configuration;
228
    size_t              count = sizeof( names ) / sizeof( measured_string_t );
311
    size_t              count = sizeof( names ) / sizeof( measured_string_t );
229
    char *              data;
312
    char *              data;
230
    int                 index;
313
    int                 index;
231
    ip_route_ref        route;
314
    ip_route_ref        route;
232
    in_addr_t           gateway;
315
    in_addr_t           gateway;
233
 
316
 
234
    ip_netif->arp = 0;
317
    ip_netif->arp = NULL;
235
    route = NULL;
318
    route = NULL;
236
    configuration = & names[ 0 ];
319
    configuration = & names[ 0 ];
237
    // get configuration
320
    // get configuration
238
    ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data ));
321
    ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data ));
239
    if( configuration ){
322
    if( configuration ){
240
        if( configuration[ 0 ].value ){
323
        if( configuration[ 0 ].value ){
241
            ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 );
324
            ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 );
242
        }else{
325
        }else{
243
            ip_netif->ipv = DEFAULT_IPV;
326
            ip_netif->ipv = DEFAULT_IPV;
244
        }
327
        }
245
        ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length );
328
        ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length );
246
        if( ip_netif->dhcp ){
329
        if( ip_netif->dhcp ){
247
            // TODO dhcp
330
            // TODO dhcp
248
            net_free_settings( configuration, data );
331
            net_free_settings( configuration, data );
249
            return ENOTSUP;
332
            return ENOTSUP;
250
        }else if( ip_netif->ipv == 4 ){
333
        }else if( ip_netif->ipv == 4 ){
251
            route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
334
            route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
252
            if( ! route ){
335
            if( ! route ){
253
                net_free_settings( configuration, data );
336
                net_free_settings( configuration, data );
254
                return ENOMEM;
337
                return ENOMEM;
255
            }
338
            }
256
            route->address.s_addr = 0;
339
            route->address.s_addr = 0;
257
            route->netmask.s_addr = 0;
340
            route->netmask.s_addr = 0;
258
            route->gateway.s_addr = 0;
341
            route->gateway.s_addr = 0;
259
            route->netif = ip_netif;
342
            route->netif = ip_netif;
260
            index = ip_routes_add( & ip_netif->routes, route );
343
            index = ip_routes_add( & ip_netif->routes, route );
261
            if( index < 0 ){
344
            if( index < 0 ){
262
                net_free_settings( configuration, data );
345
                net_free_settings( configuration, data );
263
                free( route );
346
                free( route );
264
                return index;
347
                return index;
265
            }
348
            }
266
            if( ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 2 ].value, ( uint8_t * ) & route->address.s_addr ))
349
            if( ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 2 ].value, ( uint8_t * ) & route->address.s_addr ))
267
            || ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 3 ].value, ( uint8_t * ) & route->netmask.s_addr ))
350
            || ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 3 ].value, ( uint8_t * ) & route->netmask.s_addr ))
268
            || ( inet_pton( AF_INET, configuration[ 4 ].value, ( uint8_t * ) & gateway.s_addr ) == EINVAL )
351
            || ( inet_pton( AF_INET, configuration[ 4 ].value, ( uint8_t * ) & gateway.s_addr ) == EINVAL )
269
            || ( inet_pton( AF_INET, configuration[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast.s_addr ) == EINVAL )
352
            || ( inet_pton( AF_INET, configuration[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast.s_addr ) == EINVAL )
270
            || ( inet_pton( AF_INET, configuration[ 6 ].value, ( uint8_t * ) & ip_netif->dns1 ) == EINVAL )
353
            || ( inet_pton( AF_INET, configuration[ 6 ].value, ( uint8_t * ) & ip_netif->dns1 ) == EINVAL )
271
            || ( inet_pton( AF_INET, configuration[ 7 ].value, ( uint8_t * ) & ip_netif->dns2 ) == EINVAL )){
354
            || ( inet_pton( AF_INET, configuration[ 7 ].value, ( uint8_t * ) & ip_netif->dns2 ) == EINVAL )){
272
                net_free_settings( configuration, data );
355
                net_free_settings( configuration, data );
273
                return EINVAL;
356
                return EINVAL;
274
            }
357
            }
275
        }else{
358
        }else{
276
            // TODO ipv6 in separate module
359
            // TODO ipv6 in separate module
277
            net_free_settings( configuration, data );
360
            net_free_settings( configuration, data );
278
            return ENOTSUP;
361
            return ENOTSUP;
279
        }
362
        }
280
        if( configuration[ 8 ].value ){
363
        if( configuration[ 8 ].value ){
281
            ip_netif->arp = get_running_module( & ip_globals.modules, configuration[ 8 ].value );
364
            ip_netif->arp = get_running_module( & ip_globals.modules, configuration[ 8 ].value );
282
            if( ! ip_netif->arp ){
365
            if( ! ip_netif->arp ){
283
                printf( "Failed to start the arp %s\n", configuration[ 8 ].value );
366
                printf( "Failed to start the arp %s\n", configuration[ 8 ].value );
284
                net_free_settings( configuration, data );
367
                net_free_settings( configuration, data );
285
                return EINVAL;
368
                return EINVAL;
286
            }
369
            }
287
        }else{
370
        }else{
288
            ip_netif->arp = NULL;
371
            ip_netif->arp = NULL;
289
        }
372
        }
290
        ip_netif->routing = configuration[ 9 ].value && ( configuration[ 9 ].value[ 0 ] == 'y' );
373
        ip_netif->routing = configuration[ 9 ].value && ( configuration[ 9 ].value[ 0 ] == 'y' );
291
        net_free_settings( configuration, data );
374
        net_free_settings( configuration, data );
292
    }
375
    }
293
    ip_netif->phone = bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection );
376
    ip_netif->phone = bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection );
294
    if( ip_netif->phone < 0 ){
377
    if( ip_netif->phone < 0 ){
295
        printf( "Failed to contact the nil service %d\n", ip_netif->service );
378
        printf( "Failed to contact the nil service %d\n", ip_netif->service );
296
        return ip_netif->phone;
379
        return ip_netif->phone;
297
    }
380
    }
298
    // MUST BE AFTER the bind_service up there!
381
    // MUST BE AFTER the bind_service up there!
299
    if( ip_netif->arp ){
382
    if( ip_netif->arp ){
300
        if( route ){
383
        if( route ){
301
            configuration[ 0 ].value = ( char * ) & route->address.s_addr;
384
            configuration[ 0 ].value = ( char * ) & route->address.s_addr;
302
            configuration[ 0 ].length = CONVERT_SIZE( in_addr_t, char, 1 );
385
            configuration[ 0 ].length = CONVERT_SIZE( in_addr_t, char, 1 );
303
            ERROR_PROPAGATE( arp_device_req( ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, & configuration[ 0 ] ));
386
            ERROR_PROPAGATE( arp_device_req( ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, & configuration[ 0 ] ));
304
        }else{
387
        }else{
305
            ip_netif->arp = 0;
388
            ip_netif->arp = 0;
306
        }
389
        }
307
    }
390
    }
308
    // get packet dimensions
391
    // get packet dimensions
309
    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 ));
392
    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 ));
310
    if( ip_netif->content < IP_MIN_CONTENT ){
393
    if( ip_netif->content < IP_MIN_CONTENT ){
311
        printf( "Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->content, IP_MIN_CONTENT );
394
        printf( "Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->content, IP_MIN_CONTENT );
312
        ip_netif->content = IP_MIN_CONTENT;
395
        ip_netif->content = IP_MIN_CONTENT;
313
    }
396
    }
314
    index = ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif );
397
    index = ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif );
315
    if( index < 0 ) return index;
398
    if( index < 0 ) return index;
316
    if( gateway.s_addr ){
399
    if( gateway.s_addr ){
317
        // the default gateway
400
        // the default gateway
318
        ip_globals.gateway.address.s_addr = 0;
401
        ip_globals.gateway.address.s_addr = 0;
319
        ip_globals.gateway.netmask.s_addr = 0;
402
        ip_globals.gateway.netmask.s_addr = 0;
320
        ip_globals.gateway.gateway.s_addr = gateway.s_addr;
403
        ip_globals.gateway.gateway.s_addr = gateway.s_addr;
321
        ip_globals.gateway.netif = ip_netif;
404
        ip_globals.gateway.netif = ip_netif;
322
    }
405
    }
323
    return EOK;
406
    return EOK;
324
}
407
}
325
 
408
 
326
int ip_mtu_changed_msg( device_id_t device_id, size_t mtu ){
409
int ip_mtu_changed_message( device_id_t device_id, size_t mtu ){
327
    ip_netif_ref    netif;
410
    ip_netif_ref    netif;
328
 
411
 
329
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
412
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
330
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
413
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
331
    if( ! netif ){
414
    if( ! netif ){
332
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
415
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
333
        return ENOENT;
416
        return ENOENT;
334
    }
417
    }
335
    netif->content = mtu;
418
    netif->content = mtu;
336
    printf( "ip - device %d changed mtu to %d\n\n", device_id, mtu );
419
    printf( "ip - device %d changed mtu to %d\n\n", device_id, mtu );
337
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
420
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
338
    return EOK;
421
    return EOK;
339
}
422
}
340
 
423
 
341
int ip_device_state_msg( int il_phone, device_id_t device_id, device_state_t state ){
424
int ip_device_state_message( device_id_t device_id, device_state_t state ){
342
//  ERROR_DECLARE;
425
//  ERROR_DECLARE;
343
 
426
 
344
/*  measured_string_t   address;
427
/*  measured_string_t   address;
345
    measured_string_ref translation;
428
    measured_string_ref translation;
346
    char *              data;
429
    char *              data;
347
*/
430
*/
348
/*  packet_t        packet;
431
/*  packet_t        packet;
349
    in_addr_t       destination;
432
    in_addr_t       destination;
350
*/
433
*/
351
    ip_netif_ref    netif;
434
    ip_netif_ref    netif;
352
 
435
 
353
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
436
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
354
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
437
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
355
    if( ! netif ){
438
    if( ! netif ){
356
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
439
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
357
        return ENOENT;
440
        return ENOENT;
358
    }
441
    }
359
    netif->state = state;
442
    netif->state = state;
360
    // TODO state
443
    // TODO state
361
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
444
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
362
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
445
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
363
//  if( netif->arp ){
446
//  if( netif->arp ){
364
/*      address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
447
/*      address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
365
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
448
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
366
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
449
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
367
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
450
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
368
        }
451
        }
369
        printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
452
        printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
370
        free( translation );
453
        free( translation );
371
        free( data );
454
        free( data );
372
        address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
455
        address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
373
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
456
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
374
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
457
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
375
            sleep( 2 );
458
            sleep( 2 );
376
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
459
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
377
        }
460
        }
378
        printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
461
        printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
379
        free( translation );
462
        free( translation );
380
        free( data );
463
        free( data );
381
*//*        printf( "IP - testing to send packet:\n" );
464
*//*        printf( "IP - testing to send packet:\n" );
382
        ERROR_PROPAGATE( inet_pton( AF_INET, "90.182.101.18", ( uint8_t * ) & destination.s_addr ));
465
        ERROR_PROPAGATE( inet_pton( AF_INET, "90.182.101.18", ( uint8_t * ) & destination.s_addr ));
383
        packet = packet_get_4( ip_globals.net_phone, 30, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
466
        packet = packet_get_4( ip_globals.net_phone, 30, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
384
        if( ! packet ) return ENOMEM;
467
        if( ! packet ) return ENOMEM;
385
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
468
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
386
        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 );
387
        if( ! packet ) return ENOMEM;
470
        if( ! packet ) return ENOMEM;
388
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
471
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
389
        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 );
390
        if( ! packet ) return ENOMEM;
473
        if( ! packet ) return ENOMEM;
391
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
474
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
392
        packet = packet_get_4( ip_globals.net_phone, 1500, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
475
        packet = packet_get_4( ip_globals.net_phone, 1500, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
393
        if( ! packet ) return ENOMEM;
476
        if( ! packet ) return ENOMEM;
394
        // try this long version
477
        // try this long version
395
//      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 ))
478
//      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 ))
396
        if( ERROR_OCCURRED( packet_copy_data( packet, "Hi, this is IP", 14 ))
479
        if( ERROR_OCCURRED( packet_copy_data( packet, "Hi, this is IP", 14 ))
397
        || ERROR_OCCURRED( packet_set_addr( packet, NULL, ( uint8_t * ) & destination.s_addr, 4 ))
480
        || ERROR_OCCURRED( packet_set_addr( packet, NULL, ( uint8_t * ) & destination.s_addr, 4 ))
398
        || ERROR_OCCURRED( ip_client_prepare_packet( packet, 0, 0, 0, 0, 0 ))){
481
        || ERROR_OCCURRED( ip_client_prepare_packet( packet, 0, 0, 0, 0, 0 ))){
399
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
482
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
400
        }
483
        }
401
        ERROR_CODE = ip_send_msg( 0, 0, packet, SERVICE_IP );
484
        ERROR_CODE = ip_send_msg( 0, 0, packet, SERVICE_IP );
402
        printf( "send returned %d\n", ERROR_CODE );
485
        printf( "send returned %d\n", ERROR_CODE );
403
    }
486
    }
404
*/  return EOK;
487
*/  return EOK;
405
}
488
}
406
 
489
 
407
int ip_connect_module( services_t service ){
490
int ip_connect_module( services_t service ){
408
    return EOK;
491
    return EOK;
409
}
492
}
410
 
493
 
411
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){
494
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){
412
    return ip_register( protocol, me, 0, received_msg );
495
    return ip_register( protocol, me, 0, received_msg );
413
}
496
}
414
 
497
 
415
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){
498
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){
416
    ip_proto_ref    proto;
499
    ip_proto_ref    proto;
417
    int             index;
500
    int             index;
418
 
501
 
419
    if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL;
502
    if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL;
420
    proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
503
    proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
421
    if( ! proto ) return ENOMEM;
504
    if( ! proto ) return ENOMEM;
422
    proto->protocol = protocol;
505
    proto->protocol = protocol;
423
    proto->service = service;
506
    proto->service = service;
424
    proto->phone = phone;
507
    proto->phone = phone;
425
    proto->received_msg = received_msg;
508
    proto->received_msg = received_msg;
426
    fibril_rwlock_write_lock( & ip_globals.protos_lock );
509
    fibril_rwlock_write_lock( & ip_globals.protos_lock );
427
    index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
510
    index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
428
    if( index < 0 ){
511
    if( index < 0 ){
429
        fibril_rwlock_write_unlock( & ip_globals.protos_lock );
512
        fibril_rwlock_write_unlock( & ip_globals.protos_lock );
430
        free( proto );
513
        free( proto );
431
        return index;
514
        return index;
432
    }
515
    }
433
    printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
516
    printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
434
    fibril_rwlock_write_unlock( & ip_globals.protos_lock );
517
    fibril_rwlock_write_unlock( & ip_globals.protos_lock );
435
    return EOK;
518
    return EOK;
436
}
519
}
437
 
520
 
438
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender ){
521
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender ){
439
    ERROR_DECLARE;
522
    ERROR_DECLARE;
440
 
523
 
441
    int                 length;
524
    int                 length;
442
    ip_netif_ref        netif;
525
    ip_netif_ref        netif;
443
    ip_route_ref        route;
526
    ip_route_ref        route;
444
    in_addr_t *         dest;
527
    in_addr_t *         dest;
445
    in_addr_t *         src;
528
    in_addr_t *         src;
446
 
529
 
447
    // addresses in the host byte order
530
    // addresses in the host byte order
448
    // should be the next hop address or the target destination address
531
    // should be the next hop address or the target destination address
449
    length = packet_get_addr( packet, NULL, ( uint8_t ** ) & dest );
532
    length = packet_get_addr( packet, NULL, ( uint8_t ** ) & dest );
450
    if( length < 0 ){
533
    if( length < 0 ){
451
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
534
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
452
        return length;
535
        return length;
453
    }
536
    }
454
    // TODO IPv6
537
    // TODO IPv6
455
    if( length != IP_ADDR ){
538
    if( length != IP_ADDR ){
456
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
539
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
457
        return EINVAL;
540
        return EINVAL;
458
    }
541
    }
459
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
542
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
460
    // device specified?
543
    // device specified?
461
//  dest.s_addr = ntohl( dest.s_addr );
544
//  dest.s_addr = ntohl( dest.s_addr );
462
    if( device_id > 0 ){
545
    if( device_id > 0 ){
463
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
546
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
464
        route = ip_netif_find_route( netif, * dest );
547
        route = ip_netif_find_route( netif, * dest );
465
    }else{
548
    }else{
466
        // TODO IPv6
549
        // TODO IPv6
467
        route = ip_find_route( * dest );
550
        route = ip_find_route( * dest );
468
        netif = route ? route->netif : NULL;
551
        netif = route ? route->netif : NULL;
469
    }
552
    }
470
    if( !( netif && route )){
553
    if( !( netif && route )){
471
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
554
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
472
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
555
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
473
        return ENOENT;
556
        return ENOENT;
474
    }
557
    }
475
    // to me?
558
    // to me?
476
    if( route->address.s_addr == dest->s_addr ){
559
    if( route->address.s_addr == dest->s_addr ){
477
        // TODO loopback deliver
560
        // TODO loopback deliver
478
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
561
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
479
        return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet ));
562
        return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet ));
480
    }
563
    }
481
 
564
 
482
    src = ip_netif_addr( netif );
565
    src = ip_netif_addr( netif );
483
    if( ! src ){
566
    if( ! src ){
484
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
567
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
485
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
568
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
486
        return ENOENT;
569
        return ENOENT;
487
    }
570
    }
488
    if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, * dest ))){
571
    if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, * dest ))){
489
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
572
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
490
    }
573
    }
491
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
574
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
492
    return ERROR_CODE;
575
    return ERROR_CODE;
493
}
576
}
494
 
577
 
495
in_addr_t * ip_netif_addr( ip_netif_ref netif ){
578
in_addr_t * ip_netif_addr( ip_netif_ref netif ){
496
    ip_route_ref    route;
579
    ip_route_ref    route;
497
 
580
 
498
    route = ip_routes_get_index( & netif->routes, 0 );
581
    route = ip_routes_get_index( & netif->routes, 0 );
499
    return route ? & route->address : NULL;
582
    return route ? & route->address : NULL;
500
}
583
}
501
 
584
 
502
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest ){
585
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest ){
503
    ERROR_DECLARE;
586
    ERROR_DECLARE;
504
 
587
 
505
    measured_string_t   destination;
588
    measured_string_t   destination;
506
    measured_string_ref translation;
589
    measured_string_ref translation;
507
    char *              data;
590
    char *              data;
508
 
591
 
509
    // get destination hardware address
592
    // get destination hardware address
510
    if( netif->arp ){
593
    if( netif->arp ){
511
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
594
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
512
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
595
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
513
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
596
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
514
            sleep( 1 );
597
            sleep( 1 );
515
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
598
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
516
        }
599
        }
517
        // TODO unreachable
600
        // TODO unreachable
518
        if( ! translation ) return EINVAL;
601
        if( ! translation ) return EINVAL;
519
        if( ! translation->value ){
602
        if( ! translation->value ){
520
            // TODO unreachable
603
            // TODO unreachable
521
            free( translation );
604
            free( translation );
522
            free( data );
605
            free( data );
523
            return EINVAL;
606
            return EINVAL;
524
        }
607
        }
525
    }else translation = NULL;
608
    }else translation = NULL;
526
    if( ERROR_OCCURRED( ip_prepare_packet( src, dest, packet, translation ))){
609
    if( ERROR_OCCURRED( ip_prepare_packet( src, dest, packet, translation ))){
527
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
610
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
528
    }else{
611
    }else{
529
        packet = ip_split_packet( packet, netif->prefix, netif->content, netif->suffix, netif->addr_len );
612
        packet = ip_split_packet( packet, netif->prefix, netif->content, netif->suffix, netif->addr_len );
530
        if( packet ){
613
        if( packet ){
531
            nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP );
614
            nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP );
532
        }
615
        }
533
    }
616
    }
534
    if( translation ){
617
    if( translation ){
535
        free( translation );
618
        free( translation );
536
        free( data );
619
        free( data );
537
    }
620
    }
538
    return ERROR_CODE;
621
    return ERROR_CODE;
539
}
622
}
540
 
623
 
541
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ){
624
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ){
542
    ERROR_DECLARE;
625
    ERROR_DECLARE;
543
 
626
 
544
    size_t              length;
627
    size_t              length;
545
    ip_header_ref       header;
628
    ip_header_ref       header;
546
    ip_header_ref       last_header;
629
    ip_header_ref       last_header;
547
    ip_header_ref       middle_header;
630
    ip_header_ref       middle_header;
548
    packet_t            next;
631
    packet_t            next;
549
 
632
 
550
    length = packet_get_data_length( packet );
633
    length = packet_get_data_length( packet );
551
    if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
634
    if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
552
    header = ( ip_header_ref ) packet_get_data( packet );
635
    header = ( ip_header_ref ) packet_get_data( packet );
553
    if( destination ){
636
    if( destination ){
554
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
637
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
555
    }
638
    }
556
    header->version = 4;
639
    header->version = 4;
557
    header->fragment_offset = 0;
640
    header->fragment_offset = 0;
558
    header->header_checksum = 0;
641
    header->header_checksum = 0;
559
    if( source ) header->source_address = source->s_addr;
642
    if( source ) header->source_address = source->s_addr;
560
    header->destination_address = dest.s_addr;
643
    header->destination_address = dest.s_addr;
561
    fibril_rwlock_write_lock( & ip_globals.lock );
644
    fibril_rwlock_write_lock( & ip_globals.lock );
562
    ++ ip_globals.packet_counter;
645
    ++ ip_globals.packet_counter;
563
    header->identification = htons( ip_globals.packet_counter );
646
    header->identification = htons( ip_globals.packet_counter );
564
    fibril_rwlock_write_unlock( & ip_globals.lock );
647
    fibril_rwlock_write_unlock( & ip_globals.lock );
565
    length = packet_get_data_length( packet );
648
    length = packet_get_data_length( packet );
566
    if( pq_next( packet )){
649
    if( pq_next( packet )){
567
        last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header ));
650
        last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header ));
568
        if( ! last_header ) return ENOMEM;
651
        if( ! last_header ) return ENOMEM;
569
        ip_create_last_header( last_header, header );
652
        ip_create_last_header( last_header, header );
570
        next = pq_next( packet );
653
        next = pq_next( packet );
571
        while( pq_next( next )){
654
        while( pq_next( next )){
572
            middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
655
            middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
573
            if( ! middle_header ) return ENOMEM;
656
            if( ! middle_header ) return ENOMEM;
574
            memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
657
            memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
575
            header->flags |= IPFLAG_MORE_FRAGMENTS;
658
            header->flags |= IPFLAG_MORE_FRAGMENTS;
576
            middle_header->total_length = htons( packet_get_data_length( next ));
659
            middle_header->total_length = htons( packet_get_data_length( next ));
577
            middle_header->fragment_offset = length / 8;
660
            middle_header->fragment_offset = length / 8;
578
            middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
661
            middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
579
            if( destination ){
662
            if( destination ){
580
                ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
663
                ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
581
            }
664
            }
582
            length += packet_get_data_length( next );
665
            length += packet_get_data_length( next );
583
            next = pq_next( next );
666
            next = pq_next( next );
584
        }
667
        }
585
        middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
668
        middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
586
        if( ! middle_header ) return ENOMEM;
669
        if( ! middle_header ) return ENOMEM;
587
        memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
670
        memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
588
        middle_header->total_length = htons( packet_get_data_length( next ));
671
        middle_header->total_length = htons( packet_get_data_length( next ));
589
        middle_header->fragment_offset = length / 8;
672
        middle_header->fragment_offset = length / 8;
590
        middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
673
        middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
591
        if( destination ){
674
        if( destination ){
592
            ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
675
            ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
593
        }
676
        }
594
        length += packet_get_data_length( next );
677
        length += packet_get_data_length( next );
595
        free( last_header );
678
        free( last_header );
596
        header->flags |= IPFLAG_MORE_FRAGMENTS;
679
        header->flags |= IPFLAG_MORE_FRAGMENTS;
597
    }
680
    }
598
    header->total_length = htons( length );
681
    header->total_length = htons( length );
599
    // unnecessary for all protocols
682
    // unnecessary for all protocols
600
    header->header_checksum = IP_HEADER_CHECKSUM( header );
683
    header->header_checksum = IP_HEADER_CHECKSUM( header );
601
    return EOK;
684
    return EOK;
602
}
685
}
603
 
686
 
604
int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
687
int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
605
    ERROR_DECLARE;
688
    ERROR_DECLARE;
606
 
689
 
607
    packet_t    packet;
690
    packet_t    packet;
608
 
691
 
609
    * answer_count = 0;
692
    * answer_count = 0;
610
    switch( IPC_GET_METHOD( * call )){
693
    switch( IPC_GET_METHOD( * call )){
611
        case IPC_M_PHONE_HUNGUP:
694
        case IPC_M_PHONE_HUNGUP:
612
            return EOK;
695
            return EOK;
613
        case NET_IL_DEVICE:
696
        case NET_IL_DEVICE:
614
            return ip_device_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ));
697
            return ip_device_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ));
615
        case IPC_M_CONNECT_TO_ME:
698
        case IPC_M_CONNECT_TO_ME:
616
            return ip_register( IL_GET_PROTO( call ), IL_GET_SERVICE( call ), IPC_GET_PHONE( call ), NULL );
699
            return ip_register( IL_GET_PROTO( call ), IL_GET_SERVICE( call ), IPC_GET_PHONE( call ), NULL );
617
        case NET_IL_SEND:
700
        case NET_IL_SEND:
618
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
701
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
619
            return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0 );
702
            return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0 );
620
        case NET_IL_DEVICE_STATE:
703
        case NET_IL_DEVICE_STATE:
621
            return ip_device_state_msg( 0, IPC_GET_DEVICE( call ), IPC_GET_STATE( call ));
704
            return ip_device_state_message( IPC_GET_DEVICE( call ), IPC_GET_STATE( call ));
622
        case NET_IL_RECEIVED:
705
        case NET_IL_RECEIVED:
623
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
706
            ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
624
            return ip_received_msg( IPC_GET_DEVICE( call ), packet );
707
            return ip_receive_message( IPC_GET_DEVICE( call ), packet );
625
        case NET_IP_ADD_ROUTE:
708
        case NET_IP_ADD_ROUTE:
626
            return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call ));
709
            return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call ));
627
        case NET_IP_SET_GATEWAY:
710
        case NET_IP_SET_GATEWAY:
628
            return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call ));
711
            return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call ));
629
        case NET_IL_PACKET_SPACE:
712
        case NET_IL_PACKET_SPACE:
630
            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 )));
713
            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 )));
631
            * answer_count = 3;
714
            * answer_count = 3;
632
            return EOK;
715
            return EOK;
633
        case NET_IL_MTU_CHANGED:
716
        case NET_IL_MTU_CHANGED:
634
            return ip_mtu_changed_msg( IPC_GET_DEVICE( call ), IPC_GET_MTU( call ));
717
            return ip_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call ));
635
    }
718
    }
636
    return ENOTSUP;
719
    return ENOTSUP;
637
}
720
}
638
 
721
 
639
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 ){
722
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 ){
640
    ip_netif_ref    netif;
723
    ip_netif_ref    netif;
641
    int             index;
724
    int             index;
642
 
725
 
643
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
726
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
644
    * content = IP_MAX_CONTENT - IP_PREFIX;
727
    * content = IP_MAX_CONTENT - IP_PREFIX;
645
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
728
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
646
    if( device_id < 0 ){
729
    if( device_id < 0 ){
647
        * addr_len = IP_ADDR;
730
        * addr_len = IP_ADDR;
648
        * prefix = 0;
731
        * prefix = 0;
649
        * suffix = 0;
732
        * suffix = 0;
650
        for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){
733
        for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){
651
            netif = ip_netifs_get_index( & ip_globals.netifs, index );
734
            netif = ip_netifs_get_index( & ip_globals.netifs, index );
652
            if( netif ){
735
            if( netif ){
653
                if( netif->addr_len > * addr_len ) * addr_len = netif->addr_len;
736
                if( netif->addr_len > * addr_len ) * addr_len = netif->addr_len;
654
                if( netif->prefix > * prefix ) * prefix = netif->prefix;
737
                if( netif->prefix > * prefix ) * prefix = netif->prefix;
655
                if( netif->suffix > * suffix ) * suffix = netif->suffix;
738
                if( netif->suffix > * suffix ) * suffix = netif->suffix;
656
            }
739
            }
657
        }
740
        }
658
        * prefix = * prefix + IP_PREFIX;
741
        * prefix = * prefix + IP_PREFIX;
659
        * suffix = * suffix + IP_SUFFIX;
742
        * suffix = * suffix + IP_SUFFIX;
660
    }else{
743
    }else{
661
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
744
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
662
        if( ! netif ){
745
        if( ! netif ){
663
            fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
746
            fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
664
            return ENOENT;
747
            return ENOENT;
665
        }
748
        }
666
        * addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR;
749
        * addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR;
667
        * prefix = netif->prefix + IP_PREFIX;
750
        * prefix = netif->prefix + IP_PREFIX;
668
        * suffix = netif->suffix + IP_SUFFIX;
751
        * suffix = netif->suffix + IP_SUFFIX;
669
    }
752
    }
670
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
753
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
671
    return EOK;
754
    return EOK;
672
}
755
}
673
 
756
 
674
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 ){
757
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 ){
675
    ip_route_ref    route;
758
    ip_route_ref    route;
676
    ip_netif_ref    netif;
759
    ip_netif_ref    netif;
677
    int             index;
760
    int             index;
678
 
761
 
679
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
762
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
680
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
763
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
681
    if( ! netif ){
764
    if( ! netif ){
682
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
765
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
683
        return ENOENT;
766
        return ENOENT;
684
    }
767
    }
685
    route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
768
    route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
686
    if( ! route ){
769
    if( ! route ){
687
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
770
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
688
        return ENOMEM;
771
        return ENOMEM;
689
    }
772
    }
690
    route->address.s_addr = address.s_addr;
773
    route->address.s_addr = address.s_addr;
691
    route->netmask.s_addr = netmask.s_addr;
774
    route->netmask.s_addr = netmask.s_addr;
692
    route->gateway.s_addr = gateway.s_addr;
775
    route->gateway.s_addr = gateway.s_addr;
693
    route->netif = netif;
776
    route->netif = netif;
694
    index = ip_routes_add( & netif->routes, route );
777
    index = ip_routes_add( & netif->routes, route );
695
    if( index < 0 ) free( route );
778
    if( index < 0 ) free( route );
696
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
779
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
697
    return index;
780
    return index;
698
}
781
}
699
 
782
 
700
ip_route_ref ip_find_route( in_addr_t destination ){
783
ip_route_ref ip_find_route( in_addr_t destination ){
701
    int             index;
784
    int             index;
702
    ip_route_ref    route;
785
    ip_route_ref    route;
703
    ip_netif_ref    netif;
786
    ip_netif_ref    netif;
704
 
787
 
705
    // start with the last netif - the newest one
788
    // start with the last netif - the newest one
706
    index = ip_netifs_count( & ip_globals.netifs ) - 1;
789
    index = ip_netifs_count( & ip_globals.netifs ) - 1;
707
    while( index >= 0 ){
790
    while( index >= 0 ){
708
        netif = ip_netifs_get_index( & ip_globals.netifs, index );
791
        netif = ip_netifs_get_index( & ip_globals.netifs, index );
709
        if( netif && ( netif->state == NETIF_ACTIVE )){
792
        if( netif && ( netif->state == NETIF_ACTIVE )){
710
            route = ip_netif_find_route( netif, destination );
793
            route = ip_netif_find_route( netif, destination );
711
            if( route ) return route;
794
            if( route ) return route;
712
        }
795
        }
713
        -- index;
796
        -- index;
714
    }
797
    }
715
    return & ip_globals.gateway;
798
    return & ip_globals.gateway;
716
}
799
}
717
 
800
 
718
ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ){
801
ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ){
719
    int             index;
802
    int             index;
720
    ip_route_ref    route;
803
    ip_route_ref    route;
721
 
804
 
722
    if( netif ){
805
    if( netif ){
723
        // start with the first one - the direct route
806
        // start with the first one - the direct route
724
        for( index = 0; index < ip_routes_count( & netif->routes ); ++ index ){
807
        for( index = 0; index < ip_routes_count( & netif->routes ); ++ index ){
725
            route = ip_routes_get_index( & netif->routes, index );
808
            route = ip_routes_get_index( & netif->routes, index );
726
            if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( destination.s_addr & route->netmask.s_addr ))){
809
            if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( destination.s_addr & route->netmask.s_addr ))){
727
                return route;
810
                return route;
728
            }
811
            }
729
        }
812
        }
730
    }
813
    }
731
    return NULL;
814
    return NULL;
732
}
815
}
733
 
816
 
734
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
817
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
735
    ip_netif_ref    netif;
818
    ip_netif_ref    netif;
736
 
819
 
737
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
820
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
738
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
821
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
739
    if( ! netif ){
822
    if( ! netif ){
740
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
823
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
741
        return ENOENT;
824
        return ENOENT;
742
    }
825
    }
743
    ip_globals.gateway.address.s_addr = 0;
826
    ip_globals.gateway.address.s_addr = 0;
744
    ip_globals.gateway.netmask.s_addr = 0;
827
    ip_globals.gateway.netmask.s_addr = 0;
745
    ip_globals.gateway.gateway.s_addr = gateway.s_addr;
828
    ip_globals.gateway.gateway.s_addr = gateway.s_addr;
746
    ip_globals.gateway.netif = netif;
829
    ip_globals.gateway.netif = netif;
747
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
830
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
748
    return EOK;
831
    return EOK;
749
}
832
}
750
 
833
 
751
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len ){
834
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len ){
752
    size_t          length;
835
    size_t          length;
753
    packet_t        next;
836
    packet_t        next;
754
    packet_t        new_packet;
837
    packet_t        new_packet;
755
 
838
 
756
    next = packet;
839
    next = packet;
757
    // check all packets
840
    // check all packets
758
    while( next ){
841
    while( next ){
759
        length = packet_get_data_length( next );
842
        length = packet_get_data_length( next );
760
        // too long?
843
        // too long?
761
        if( length > content ){
844
        if( length > content ){
762
            if( ip_fragment_packet( next, content, prefix, suffix, addr_len ) != EOK ){
845
            if( ip_fragment_packet( next, content, prefix, suffix, addr_len ) != EOK ){
763
                new_packet = pq_detach( next );
846
                new_packet = pq_detach( next );
764
                if( next == packet ){
847
                if( next == packet ){
765
                    packet = new_packet;
848
                    packet = new_packet;
766
                }
849
                }
767
                pq_release( ip_globals.net_phone, packet_get_id( next ));
850
                pq_release( ip_globals.net_phone, packet_get_id( next ));
768
                next = new_packet;
851
                next = new_packet;
769
                continue;
852
                continue;
770
            }
853
            }
771
        }
854
        }
772
        next = pq_next( next );
855
        next = pq_next( next );
773
    }
856
    }
774
    return packet;
857
    return packet;
775
}
858
}
776
 
859
 
777
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, size_t addr_len ){
860
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, size_t addr_len ){
778
    ERROR_DECLARE;
861
    ERROR_DECLARE;
779
 
862
 
780
    packet_t        new_packet;
863
    packet_t        new_packet;
781
    ip_header_ref   header;
864
    ip_header_ref   header;
782
    ip_header_ref   middle_header;
865
    ip_header_ref   middle_header;
783
    ip_header_ref   last_header;
866
    ip_header_ref   last_header;
784
    uint8_t *       src;
867
    uint8_t *       src;
785
    uint8_t *       dest;
868
    uint8_t *       dest;
786
    int             address_length;
869
    int             address_length;
787
 
870
 
788
    address_length = packet_get_addr( packet, & src, & dest );
871
    address_length = packet_get_addr( packet, & src, & dest );
789
    if( address_length <= 0 ) return EINVAL;
872
    if( address_length <= 0 ) return EINVAL;
790
    if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
873
    if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
791
    // get header
874
    // get header
792
    header = ( ip_header_ref ) packet_get_data( packet );
875
    header = ( ip_header_ref ) packet_get_data( packet );
793
    if( ! header ) return EINVAL;
876
    if( ! header ) return EINVAL;
794
    // fragmentation forbidden?
877
    // fragmentation forbidden?
795
    if( header->flags & IPFLAG_DONT_FRAGMENT ){
878
    if( header->flags & IPFLAG_DONT_FRAGMENT ){
796
        // TODO fragmentation necessary ICMP
879
        // TODO fragmentation necessary ICMP
797
        return EPERM;
880
        return EPERM;
798
    }
881
    }
799
    // create the last fragment
882
    // create the last fragment
800
    new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, ((( size_t ) address_length > addr_len ) ? ( size_t ) address_length : addr_len ));
883
    new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, ((( size_t ) address_length > addr_len ) ? ( size_t ) address_length : addr_len ));
801
    if( ! new_packet ) return ENOMEM;
884
    if( ! new_packet ) return ENOMEM;
802
    // allocate as much as originally
885
    // allocate as much as originally
803
    last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header ));
886
    last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header ));
804
    if( ! last_header ){
887
    if( ! last_header ){
805
        pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
888
        pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
806
        return ENOMEM;
889
        return ENOMEM;
807
    }
890
    }
808
    ip_create_last_header( last_header, header );
891
    ip_create_last_header( last_header, header );
809
    // trim the unused space
892
    // trim the unused space
810
    if( ERROR_OCCURRED( packet_trim( new_packet, 0, IP_HEADER_LENGTH( header ) - IP_HEADER_LENGTH( last_header )))){
893
    if( ERROR_OCCURRED( packet_trim( new_packet, 0, IP_HEADER_LENGTH( header ) - IP_HEADER_LENGTH( last_header )))){
811
        pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
894
        pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
812
        return ERROR_CODE;
895
        return ERROR_CODE;
813
    }
896
    }
814
    // biggest multiple of 8 lower than content
897
    // biggest multiple of 8 lower than content
815
    // TODO even fragmentation?
898
    // TODO even fragmentation?
816
    length = length & ( ~ 0x7 );// ( content / 8 ) * 8
899
    length = length & ( ~ 0x7 );// ( content / 8 ) * 8
817
    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, address_length ))){
900
    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, address_length ))){
818
        pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
901
        pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
819
        return ERROR_CODE;
902
        return ERROR_CODE;
820
    }
903
    }
821
    // mark the first as fragmented
904
    // mark the first as fragmented
822
    header->flags |= IPFLAG_MORE_FRAGMENTS;
905
    header->flags |= IPFLAG_MORE_FRAGMENTS;
823
    // create middle framgents
906
    // create middle framgents
824
    while( IP_TOTAL_LENGTH( header ) > length ){
907
    while( IP_TOTAL_LENGTH( header ) > length ){
825
        new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( address_length >= addr_len ) ? address_length : addr_len ));
908
        new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( address_length >= addr_len ) ? address_length : addr_len ));
826
        if( ! new_packet ) return ENOMEM;
909
        if( ! new_packet ) return ENOMEM;
827
        middle_header = ip_create_middle_header( new_packet, last_header );
910
        middle_header = ip_create_middle_header( new_packet, last_header );
828
        if( ! middle_header ){
911
        if( ! middle_header ){
829
            pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
912
            pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
830
            return ENOMEM;
913
            return ENOMEM;
831
        }
914
        }
832
        if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, length - IP_HEADER_LENGTH( middle_header ), src, dest, address_length ))){
915
        if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, length - IP_HEADER_LENGTH( middle_header ), src, dest, address_length ))){
833
            pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
916
            pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
834
            return ERROR_CODE;
917
            return ERROR_CODE;
835
        }
918
        }
836
    }
919
    }
837
    // finish the first fragment
920
    // finish the first fragment
838
    header->header_checksum = IP_HEADER_CHECKSUM( header );
921
    header->header_checksum = IP_HEADER_CHECKSUM( header );
839
    printf( "ok\n" );
922
    printf( "ok\n" );
840
    return EOK;
923
    return EOK;
841
}
924
}
842
 
925
 
843
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, void * src, void * dest, size_t address_length ){
926
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, void * src, void * dest, size_t address_length ){
844
    ERROR_DECLARE;
927
    ERROR_DECLARE;
845
 
928
 
846
    void *          data;
929
    void *          data;
847
 
930
 
848
    data = packet_suffix( new_packet, length );
931
    data = packet_suffix( new_packet, length );
849
    if( ! data ) return ENOMEM;
932
    if( ! data ) return ENOMEM;
850
    memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length );
933
    memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length );
851
    ERROR_PROPAGATE( packet_trim( packet, 0, length ));
934
    ERROR_PROPAGATE( packet_trim( packet, 0, length ));
852
    header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
935
    header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
853
    new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
936
    new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
854
    new_header->fragment_offset = header->fragment_offset + IP_HEADER_DATA_LENGTH( header ) / 8;
937
    new_header->fragment_offset = header->fragment_offset + IP_HEADER_DATA_LENGTH( header ) / 8;
855
    new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
938
    new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
856
    ERROR_PROPAGATE( packet_set_addr( new_packet, src, dest, address_length ));
939
    ERROR_PROPAGATE( packet_set_addr( new_packet, src, dest, address_length ));
857
    return pq_insert_after( packet, new_packet );
940
    return pq_insert_after( packet, new_packet );
858
}
941
}
859
 
942
 
860
ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){
943
ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){
861
    ip_header_ref   middle;
944
    ip_header_ref   middle;
862
 
945
 
863
    middle = ( ip_header_ref ) packet_suffix( packet, IP_HEADER_LENGTH( last ));
946
    middle = ( ip_header_ref ) packet_suffix( packet, IP_HEADER_LENGTH( last ));
864
    if( ! middle ) return NULL;
947
    if( ! middle ) return NULL;
865
    memcpy( middle, last, IP_HEADER_LENGTH( last ));
948
    memcpy( middle, last, IP_HEADER_LENGTH( last ));
866
    middle->flags |= IPFLAG_MORE_FRAGMENTS;
949
    middle->flags |= IPFLAG_MORE_FRAGMENTS;
867
    return middle;
950
    return middle;
868
}
951
}
869
 
952
 
870
void ip_create_last_header( ip_header_ref last, ip_header_ref first ){
953
void ip_create_last_header( ip_header_ref last, ip_header_ref first ){
871
    ip_option_ref   option;
954
    ip_option_ref   option;
872
    size_t          next;
955
    size_t          next;
873
    size_t          length;
956
    size_t          length;
874
 
957
 
875
    // copy first itself
958
    // copy first itself
876
    memcpy( last, first, sizeof( ip_header_t ));
959
    memcpy( last, first, sizeof( ip_header_t ));
877
    length = sizeof( ip_header_t );
960
    length = sizeof( ip_header_t );
878
    next = sizeof( ip_header_t );
961
    next = sizeof( ip_header_t );
879
    // process all ip options
962
    // process all ip options
880
    while( next < first->ihl ){
963
    while( next < first->ihl ){
881
        option = ( ip_option_ref ) ((( void * ) first ) + next );
964
        option = ( ip_option_ref ) ((( void * ) first ) + next );
882
        // skip end or noop
965
        // skip end or noop
883
        if(( option->type == IPOPT_END ) || ( option->type == IPOPT_NOOP )){
966
        if(( option->type == IPOPT_END ) || ( option->type == IPOPT_NOOP )){
884
            ++ next;
967
            ++ next;
885
        }else{
968
        }else{
886
            // copy if said so or skip
969
            // copy if said so or skip
887
            if( IPOPT_COPIED( option->type )){
970
            if( IPOPT_COPIED( option->type )){
888
                memcpy((( void * ) last ) + length, (( void * ) first ) + next, option->length );
971
                memcpy((( void * ) last ) + length, (( void * ) first ) + next, option->length );
889
                length += option->length;
972
                length += option->length;
890
            }
973
            }
891
            // next option
974
            // next option
892
            next += option->length;
975
            next += option->length;
893
        }
976
        }
894
    }
977
    }
895
    // align 4 byte boundary
978
    // align 4 byte boundary
896
    if( length % 4 ){
979
    if( length % 4 ){
897
        bzero((( void * ) last ) + length, 4 - ( length % 4 ));
980
        bzero((( void * ) last ) + length, 4 - ( length % 4 ));
898
        last->ihl = length / 4 + 1;
981
        last->ihl = length / 4 + 1;
899
    }else{
982
    }else{
900
        last->ihl = length / 4;
983
        last->ihl = length / 4;
901
    }
984
    }
902
    last->header_checksum = 0;
985
    last->header_checksum = 0;
903
}
986
}
904
 
987
 
905
int ip_received_msg( device_id_t device_id, packet_t packet ){
988
int ip_receive_message( device_id_t device_id, packet_t packet ){
906
    packet_t        next;
989
    packet_t        next;
907
 
990
 
908
    do{
991
    do{
909
        next = pq_detach( packet );
992
        next = pq_detach( packet );
910
        if( ip_process_packet( device_id, packet ) != EOK ){
993
        if( ip_process_packet( device_id, packet ) != EOK ){
911
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
994
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
912
        }
995
        }
913
        packet = next;
996
        packet = next;
914
    }while( packet );
997
    }while( packet );
915
    return EOK;
998
    return EOK;
916
}
999
}
917
 
1000
 
918
int ip_process_packet( device_id_t device_id, packet_t packet ){
1001
int ip_process_packet( device_id_t device_id, packet_t packet ){
919
    ERROR_DECLARE;
1002
    ERROR_DECLARE;
920
 
1003
 
921
    ip_header_ref   header;
1004
    ip_header_ref   header;
922
    in_addr_t       dest;
1005
    in_addr_t       dest;
923
    ip_route_ref    route;
1006
    ip_route_ref    route;
924
 
1007
 
925
    header = ( ip_header_ref ) packet_get_data( packet );
1008
    header = ( ip_header_ref ) packet_get_data( packet );
926
    if( ! header ) return ENOMEM;
1009
    if( ! header ) return ENOMEM;
927
    // checksum
1010
    // checksum
928
    if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ))){
1011
    if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ))){
929
        // TODO checksum error ICMP?
1012
        // TODO checksum error ICMP?
930
        return EINVAL;
1013
        return EINVAL;
931
    }
1014
    }
932
    // TODO ttl oxceeded ICMP?
1015
    // TODO ttl oxceeded ICMP?
933
    if( !( -- header->ttl )) return EINVAL;
1016
    if( !( -- header->ttl )) return EINVAL;
934
    // process ipopt and get destination
1017
    // process ipopt and get destination
935
    dest = ip_get_destination( header );
1018
    dest = ip_get_destination( header );
936
    ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & dest.s_addr, IP_ADDR ));
1019
    ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & dest.s_addr, IP_ADDR ));
937
    route = ip_find_route( dest );
1020
    route = ip_find_route( dest );
938
    // TODO unreachable ICMP?
1021
    // TODO unreachable ICMP?
939
    if( ! route ) return ENOENT;
1022
    if( ! route ) return ENOENT;
940
    if( route->address.s_addr == dest.s_addr ){
1023
    if( route->address.s_addr == dest.s_addr ){
941
        // local delivery
1024
        // local delivery
942
        return ip_deliver_local( device_id, packet, header );
1025
        return ip_deliver_local( device_id, packet, header );
943
    }else{
1026
    }else{
944
        // only if routing enabled
1027
        // only if routing enabled
945
        if( route->netif->routing ){
1028
        if( route->netif->routing ){
946
            return ip_send_route( packet, route->netif, route, NULL, dest );
1029
            return ip_send_route( packet, route->netif, route, NULL, dest );
947
        }
1030
        }
948
        else
1031
        else
949
        {
1032
        {
950
            // TODO icmp unreachable?
1033
            // TODO icmp unreachable?
951
            return ENOENT;
1034
            return ENOENT;
952
        }
1035
        }
953
    }
1036
    }
954
}
1037
}
955
 
1038
 
956
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header ){
1039
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header ){
957
    ERROR_DECLARE;
1040
    ERROR_DECLARE;
958
 
1041
 
959
    ip_proto_ref    proto;
1042
    ip_proto_ref    proto;
960
 
1043
 
961
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
1044
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
962
        // TODO fragmented
1045
        // TODO fragmented
963
        return ENOTSUP;
1046
        return ENOTSUP;
964
    }else{
1047
    }else{
965
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR ));
1048
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR ));
966
        fibril_rwlock_read_lock( & ip_globals.protos_lock );
1049
        fibril_rwlock_read_lock( & ip_globals.protos_lock );
967
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
1050
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
968
        if( ! proto ){
1051
        if( ! proto ){
969
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1052
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
970
            return ENOENT;
1053
            return ENOENT;
971
        }
1054
        }
972
        if( proto->received_msg ){
1055
        if( proto->received_msg ){
973
            ERROR_CODE = proto->received_msg( device_id, packet, SERVICE_IP );
1056
            ERROR_CODE = proto->received_msg( device_id, packet, SERVICE_IP );
974
        }else{
1057
        }else{
975
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service );
1058
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service );
976
        }
1059
        }
977
        fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1060
        fibril_rwlock_read_unlock( & ip_globals.protos_lock );
978
        return ERROR_CODE;
1061
        return ERROR_CODE;
979
    }
1062
    }
980
}
1063
}
981
 
1064
 
982
in_addr_t ip_get_destination( ip_header_ref header ){
1065
in_addr_t ip_get_destination( ip_header_ref header ){
983
    in_addr_t   destination;
1066
    in_addr_t   destination;
984
 
1067
 
985
    // TODO search set ipopt route?
1068
    // TODO search set ipopt route?
986
    destination.s_addr = header->destination_address; //ntohl( header->destination_address );
1069
    destination.s_addr = header->destination_address; //ntohl( header->destination_address );
987
    return destination;
1070
    return destination;
988
}
1071
}
989
 
1072
 
990
/** @}
1073
/** @}
991
 */
1074
 */
992
 
1075