Subversion Repositories HelenOS

Rev

Rev 4351 | Rev 4506 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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