Subversion Repositories HelenOS

Rev

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

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