Subversion Repositories HelenOS

Rev

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

Rev 4506 Rev 4558
Line 33... Line 33...
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 <rwlock.h>
38
#include <stdio.h>
39
#include <stdio.h>
39
#include <string.h>
40
#include <string.h>
40
 
41
 
41
#include <ipc/ipc.h>
42
#include <ipc/ipc.h>
42
#include <ipc/services.h>
43
#include <ipc/services.h>
Line 46... Line 47...
46
#include "../../err.h"
47
#include "../../err.h"
47
#include "../../messages.h"
48
#include "../../messages.h"
48
#include "../../modules.h"
49
#include "../../modules.h"
49
 
50
 
50
#include "../../include/net_interface.h"
51
#include "../../include/net_interface.h"
51
#include "../../include/sockaddr.h"
52
#include "../../include/inet.h"
52
#include "../../include/socket.h"
53
#include "../../include/socket.h"
53
#include "../../include/byteorder.h"
54
#include "../../include/byteorder.h"
54
#include "../../include/crc.h"
55
#include "../../include/crc.h"
55
#include "../../include/device.h"
56
#include "../../include/device.h"
56
#include "../../include/arp_interface.h"
57
#include "../../include/arp_interface.h"
Line 80... Line 81...
80
 
81
 
81
#define IP_ADDR                         sizeof( in_addr_t )
82
#define IP_ADDR                         sizeof( in_addr_t )
82
#define IP_PREFIX                       sizeof( ip_header_t )
83
#define IP_PREFIX                       sizeof( ip_header_t )
83
#define IP_SUFFIX                       0
84
#define IP_SUFFIX                       0
84
#define IP_MAX_CONTENT                  65535
85
#define IP_MAX_CONTENT                  65535
85
#define IP_HEADER_LENGTH( header )      (( header )->ihl * 4 )
86
#define IP_HEADER_LENGTH( header )      (( header )->ihl * 4u )
86
#define IP_TOTAL_LENGTH( header )       ntohs(( header )->total_length )
87
#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_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
#define IP_HEADER_CHECKSUM( header )    ( htons( ip_checksum(( uint8_t * )( header ), IP_HEADER_LENGTH( header ))))
89
 
90
 
90
//zero is returned as 0xFFFF (not flipped)
91
//zero is returned as 0xFFFF (not flipped)
91
#define IP_HEADER_CHECKSUM_ZERO         0xFFFF
92
#define IP_HEADER_CHECKSUM_ZERO         0xFFFFu
92
 
93
 
93
ip_globals_t    ip_globals;
94
ip_globals_t    ip_globals;
94
 
95
 
95
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
96
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
96
 
97
 
Line 125... Line 126...
125
 *  To check the checksum of a received packet, the checksum may be left set.
126
 *  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
 *  The zero (0) value will returned in this case if valid.
127
 *  @param data The header data. Input parameter.
128
 *  @param data The header data. Input parameter.
128
 *  @param length The header length in bytes. Input parameter.
129
 *  @param length The header length in bytes. Input parameter.
129
 *  @returns The internet protocol header checksum.
130
 *  @returns The internet protocol header checksum.
130
 *  @returns IP_HEADER_CHECKSUM_ZERO if the computed checksum is zero.
131
 *  @returns 0xFFFF if the computed checksum is zero.
131
 */
132
 */
132
uint16_t ip_checksum( uint8_t * data, int length );
133
uint16_t ip_checksum( uint8_t * data, size_t length );
133
 
134
 
134
uint16_t ip_checksum( uint8_t * data, int length ){
135
uint16_t ip_checksum( uint8_t * data, size_t length ){
135
    uint16_t    checksum;
136
    uint16_t    checksum;
136
 
137
 
137
    checksum = compact_checksum(compute_checksum( 0, data, length ));
138
    checksum = compact_checksum(compute_checksum( 0, data, length ));
138
 
139
 
139
    // flip, zero is returned as 0xFFFF (not flipped)
140
    // flip, zero is returned as 0xFFFF (not flipped)
Line 143... Line 144...
143
/** Initializes the module.
144
/** Initializes the module.
144
 */
145
 */
145
int ip_initialize( async_client_conn_t client_connection ){
146
int ip_initialize( async_client_conn_t client_connection ){
146
    ERROR_DECLARE;
147
    ERROR_DECLARE;
147
 
148
 
-
 
149
    rwlock_initialize( & ip_globals.lock );
-
 
150
    rwlock_write_lock( & ip_globals.lock );
-
 
151
    rwlock_initialize( & ip_globals.protos_lock );
-
 
152
    rwlock_initialize( & ip_globals.netifs_lock );
148
    ip_globals.packet_counter = 0;
153
    ip_globals.packet_counter = 0;
149
    ip_globals.gateway.address.s_addr = 0;
154
    ip_globals.gateway.address.s_addr = 0;
150
    ip_globals.gateway.netmask.s_addr = 0;
155
    ip_globals.gateway.netmask.s_addr = 0;
151
    ip_globals.gateway.gateway.s_addr = 0;
156
    ip_globals.gateway.gateway.s_addr = 0;
152
    ip_globals.gateway.netif = NULL;
157
    ip_globals.gateway.netif = NULL;
153
    ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
158
    ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
154
    ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
159
    ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
155
    ip_globals.client_connection = client_connection;
160
    ip_globals.client_connection = client_connection;
156
    ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
161
    ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
157
    ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module ));
162
    ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module ));
-
 
163
    rwlock_write_unlock( & ip_globals.lock );
158
    return EOK;
164
    return EOK;
159
}
165
}
160
 
166
 
161
int ip_device_req( int il_phone, device_id_t device_id, services_t netif ){
167
int ip_device_req( int il_phone, device_id_t device_id, services_t netif ){
162
    ERROR_DECLARE;
168
    ERROR_DECLARE;
Line 173... Line 179...
173
        return ERROR_CODE;
179
        return ERROR_CODE;
174
    }
180
    }
175
    ip_netif->device_id = device_id;
181
    ip_netif->device_id = device_id;
176
    ip_netif->service = netif;
182
    ip_netif->service = netif;
177
    ip_netif->state = NETIF_STOPPED;
183
    ip_netif->state = NETIF_STOPPED;
-
 
184
    rwlock_write_lock( & ip_globals.netifs_lock );
178
    if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
185
    if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
-
 
186
        rwlock_write_unlock( & ip_globals.netifs_lock );
179
        ip_routes_destroy( & ip_netif->routes );
187
        ip_routes_destroy( & ip_netif->routes );
180
        free( ip_netif );
188
        free( ip_netif );
181
        return ERROR_CODE;
189
        return ERROR_CODE;
182
    }
190
    }
183
    if( ip_netif->arp ) ++ ip_netif->arp->usage;
191
    if( ip_netif->arp ) ++ ip_netif->arp->usage;
Line 205... Line 213...
205
        printf( "\tdns1\t= %s\n", data );
213
        printf( "\tdns1\t= %s\n", data );
206
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns2, data, INET_ADDRSTRLEN );
214
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns2, data, INET_ADDRSTRLEN );
207
        printf( "\tdns2\t= %s\n", data );
215
        printf( "\tdns2\t= %s\n", data );
208
        free( data );
216
        free( data );
209
    }
217
    }
-
 
218
    rwlock_write_unlock( & ip_globals.netifs_lock );
210
    return EOK;
219
    return EOK;
211
}
220
}
212
 
221
 
213
int ip_netif_initialize( ip_netif_ref ip_netif ){
222
int ip_netif_initialize( ip_netif_ref ip_netif ){
214
    ERROR_DECLARE;
223
    ERROR_DECLARE;
Line 277... Line 286...
277
        }else{
286
        }else{
278
            ip_netif->arp = NULL;
287
            ip_netif->arp = NULL;
279
        }
288
        }
280
        net_free_settings( configuration, data );
289
        net_free_settings( configuration, data );
281
    }
290
    }
282
    ip_netif->phone = bind_service( ip_netif->service, ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection );
291
    ip_netif->phone = bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection );
283
    if( ip_netif->phone < 0 ){
292
    if( ip_netif->phone < 0 ){
284
        printf( "Failed to contact the nil service %d\n", ip_netif->service );
293
        printf( "Failed to contact the nil service %d\n", ip_netif->service );
285
        return ip_netif->phone;
294
        return ip_netif->phone;
286
    }
295
    }
287
    // MUST BE AFTER the bind_service up there!
296
    // MUST BE AFTER the bind_service up there!
Line 322... Line 331...
322
/*  packet_t        packet;
331
/*  packet_t        packet;
323
    in_addr_t       destination;
332
    in_addr_t       destination;
324
*/
333
*/
325
    ip_netif_ref    netif;
334
    ip_netif_ref    netif;
326
 
335
 
-
 
336
    rwlock_write_lock( & ip_globals.netifs_lock );
327
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
337
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
-
 
338
    if( ! netif ){
-
 
339
        rwlock_write_unlock( & ip_globals.netifs_lock );
328
    if( ! netif ) return ENOENT;
340
        return ENOENT;
-
 
341
    }
329
    netif->state = state;
342
    netif->state = state;
330
    // TODO state
343
    // TODO state
331
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
344
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
-
 
345
    rwlock_write_unlock( & ip_globals.netifs_lock );
332
//  if( netif->arp ){
346
//  if( netif->arp ){
333
/*      address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
347
/*      address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
334
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
348
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
335
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
349
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
336
            ERROR_PROPAGATE( 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 ));
Line 375... Line 389...
375
 
389
 
376
int ip_connect_module( services_t service ){
390
int ip_connect_module( services_t service ){
377
    return EOK;
391
    return EOK;
378
}
392
}
379
 
393
 
380
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg ){
394
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){
381
    return ip_register( protocol, me, 0, tl_received_msg );
395
    return ip_register( protocol, me, 0, received_msg );
382
}
396
}
383
 
397
 
384
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg ){
398
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){
385
    ip_proto_ref    proto;
399
    ip_proto_ref    proto;
386
    int             index;
400
    int             index;
387
 
401
 
388
    if( !( protocol && service && (( phone > 0 ) || ( tl_received_msg )))) return EINVAL;
402
    if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL;
389
    proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
403
    proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
390
    if( ! proto ) return ENOMEM;
404
    if( ! proto ) return ENOMEM;
391
    proto->protocol = protocol;
405
    proto->protocol = protocol;
392
    proto->service = service;
406
    proto->service = service;
393
    proto->phone = phone;
407
    proto->phone = phone;
394
    proto->tl_received_msg = tl_received_msg;
408
    proto->received_msg = received_msg;
-
 
409
    rwlock_write_lock( & ip_globals.protos_lock );
395
    index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
410
    index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
396
    if( index < 0 ){
411
    if( index < 0 ){
-
 
412
        rwlock_write_unlock( & ip_globals.protos_lock );
397
        free( proto );
413
        free( proto );
398
        return index;
414
        return index;
399
    }
415
    }
400
    printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
416
    printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
-
 
417
    rwlock_write_unlock( & ip_globals.protos_lock );
401
    return EOK;
418
    return EOK;
402
}
419
}
403
 
420
 
404
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender ){
421
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender ){
405
    ERROR_DECLARE;
422
    ERROR_DECLARE;
Line 420... Line 437...
420
    // TODO IPv6
437
    // TODO IPv6
421
    if( length != IP_ADDR ){
438
    if( length != IP_ADDR ){
422
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
439
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
423
        return EINVAL;
440
        return EINVAL;
424
    }
441
    }
425
//  rwlock_read_lock( & ip_globals.devices_lock );
442
    rwlock_read_lock( & ip_globals.netifs_lock );
426
    // device specified?
443
    // device specified?
427
//  dest.s_addr = ntohl( dest.s_addr );
444
//  dest.s_addr = ntohl( dest.s_addr );
428
    if( device_id ){
445
    if( device_id ){
429
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
446
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
430
        route = ip_netif_find_route( netif, dest );
447
        route = ip_netif_find_route( netif, dest );
Line 432... Line 449...
432
        // TODO IPv6
449
        // TODO IPv6
433
        route = ip_find_route( dest );
450
        route = ip_find_route( dest );
434
        netif = route ? route->netif : NULL;
451
        netif = route ? route->netif : NULL;
435
    }
452
    }
436
    if( !( netif && route )){
453
    if( !( netif && route )){
437
//      rwlock_read_unlock( & ip_globals.devices_lock );
454
        rwlock_read_unlock( & ip_globals.netifs_lock );
438
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
455
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
439
        return ENOENT;
456
        return ENOENT;
440
    }
457
    }
441
    // to me?
458
    // to me?
442
    if( route->address.s_addr == dest.s_addr ){
459
    if( route->address.s_addr == dest.s_addr ){
443
        // TODO loopback deliver
460
        // TODO loopback deliver
-
 
461
        rwlock_read_unlock( & ip_globals.netifs_lock );
-
 
462
        return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet ));
444
    }
463
    }
445
 
464
 
446
    src = ip_netif_addr( netif );
465
    src = ip_netif_addr( netif );
447
    if( ! src ){
466
    if( ! src ){
-
 
467
        rwlock_read_unlock( & ip_globals.netifs_lock );
448
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
468
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
449
        return ENOENT;
469
        return ENOENT;
450
    }
470
    }
451
    if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, dest ))){
471
    if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, dest ))){
452
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
472
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
453
    }
473
    }
-
 
474
    rwlock_read_unlock( & ip_globals.netifs_lock );
454
    return ERROR_CODE;
475
    return ERROR_CODE;
455
}
476
}
456
 
477
 
457
in_addr_t * ip_netif_addr( ip_netif_ref netif ){
478
in_addr_t * ip_netif_addr( ip_netif_ref netif ){
458
    ip_route_ref    route;
479
    ip_route_ref    route;
Line 512... Line 533...
512
        packet = ip_split_packet( packet, netif->prefix, netif->content, netif->suffix, netif->addr_len );
533
        packet = ip_split_packet( packet, netif->prefix, netif->content, netif->suffix, netif->addr_len );
513
        if( packet ){
534
        if( packet ){
514
            nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP );
535
            nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP );
515
        }
536
        }
516
    }
537
    }
517
//  rwlock_read_unlock( & ip_globals.netifs_lock );
-
 
518
    return EOK;
538
    return EOK;
519
}
539
}
520
 
540
 
521
int ip_prepare_packet( in_addr_t * source, packet_t packet, measured_string_ref destination ){
541
int ip_prepare_packet( in_addr_t * source, packet_t packet, measured_string_ref destination ){
522
    ERROR_DECLARE;
542
    ERROR_DECLARE;
523
 
543
 
524
    int                 length;
544
    size_t              length;
525
    ip_header_ref       header;
545
    ip_header_ref       header;
526
 
546
 
527
    length = packet_get_data_length( packet );
547
    length = packet_get_data_length( packet );
528
    if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
548
    if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
529
    header = ( ip_header_ref ) packet_get_data( packet );
549
    header = ( ip_header_ref ) packet_get_data( packet );
Line 532... Line 552...
532
    }
552
    }
533
    header->version = 4;
553
    header->version = 4;
534
    header->total_length = htons( length );
554
    header->total_length = htons( length );
535
    header->fragment_offset = 0;
555
    header->fragment_offset = 0;
536
    if( source ) header->source_address = source->s_addr;//htonl( source.s_addr );
556
    if( source ) header->source_address = source->s_addr;//htonl( source.s_addr );
-
 
557
    rwlock_write_lock( & ip_globals.lock );
537
    ++ ip_globals.packet_counter;
558
    ++ ip_globals.packet_counter;
538
    header->identification = htons( ip_globals.packet_counter );
559
    header->identification = htons( ip_globals.packet_counter );
-
 
560
    rwlock_write_unlock( & ip_globals.lock );
539
    header->header_checksum = 0;
561
    header->header_checksum = 0;
540
    // unnecessary for all protocols
562
    // unnecessary for all protocols
541
    header->header_checksum = IP_HEADER_CHECKSUM( header );
563
    header->header_checksum = IP_HEADER_CHECKSUM( header );
542
    return EOK;
564
    return EOK;
543
}
565
}
Line 579... Line 601...
579
 
601
 
580
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 ){
602
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 ){
581
    ip_netif_ref    netif;
603
    ip_netif_ref    netif;
582
 
604
 
583
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
605
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
584
//  rwlock_read_lock( & ip_globals.netifs_lock );
606
    rwlock_read_lock( & ip_globals.netifs_lock );
585
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
607
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
586
    if( ! netif ){
608
    if( ! netif ){
587
//      rwlock_read_unlock( & ip_globals.netifs_lock );
609
        rwlock_read_unlock( & ip_globals.netifs_lock );
588
        return ENOENT;
610
        return ENOENT;
589
    }
611
    }
590
    * content = IP_MAX_CONTENT - IP_PREFIX;
612
    * content = IP_MAX_CONTENT - IP_PREFIX;
591
    * addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR;
613
    * addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR;
592
    * prefix = netif->prefix + IP_PREFIX;
614
    * prefix = netif->prefix + IP_PREFIX;
593
    * suffix = netif->suffix + IP_SUFFIX;
615
    * suffix = netif->suffix + IP_SUFFIX;
594
//  rwlock_read_unlock( & ip_globals.netifs_lock );
616
    rwlock_read_unlock( & ip_globals.netifs_lock );
595
    return EOK;
617
    return EOK;
596
}
618
}
597
 
619
 
598
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 ){
620
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 ){
599
    ip_route_ref    route;
621
    ip_route_ref    route;
600
    ip_netif_ref    netif;
622
    ip_netif_ref    netif;
601
    int             index;
623
    int             index;
602
 
624
 
-
 
625
    rwlock_write_lock( & ip_globals.netifs_lock );
603
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
626
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
-
 
627
    if( ! netif ){
-
 
628
        rwlock_write_unlock( & ip_globals.netifs_lock );
604
    if( ! netif ) return ENOENT;
629
        return ENOENT;
-
 
630
    }
605
    route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
631
    route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
-
 
632
    if( ! route ){
-
 
633
        rwlock_write_unlock( & ip_globals.netifs_lock );
606
    if( ! route ) return ENOMEM;
634
        return ENOMEM;
-
 
635
    }
607
    route->address.s_addr = address.s_addr;
636
    route->address.s_addr = address.s_addr;
608
    route->netmask.s_addr = netmask.s_addr;
637
    route->netmask.s_addr = netmask.s_addr;
609
    route->gateway.s_addr = gateway.s_addr;
638
    route->gateway.s_addr = gateway.s_addr;
610
    route->netif = netif;
639
    route->netif = netif;
611
    index = ip_routes_add( & netif->routes, route );
640
    index = ip_routes_add( & netif->routes, route );
612
    if( index < 0 ) free( route );
641
    if( index < 0 ) free( route );
-
 
642
    rwlock_write_unlock( & ip_globals.netifs_lock );
613
    return index;
643
    return index;
614
}
644
}
615
 
645
 
616
ip_route_ref ip_find_route( in_addr_t destination ){
646
ip_route_ref ip_find_route( in_addr_t destination ){
617
    int             index;
647
    int             index;
Line 648... Line 678...
648
}
678
}
649
 
679
 
650
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
680
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
651
    ip_netif_ref    netif;
681
    ip_netif_ref    netif;
652
 
682
 
-
 
683
    rwlock_write_lock( & ip_globals.netifs_lock );
653
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
684
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
-
 
685
    if( ! netif ){
-
 
686
        rwlock_write_unlock( & ip_globals.netifs_lock );
654
    if( ! netif ) return ENOENT;
687
        return ENOENT;
-
 
688
    }
655
    ip_globals.gateway.address.s_addr = 0;
689
    ip_globals.gateway.address.s_addr = 0;
656
    ip_globals.gateway.netmask.s_addr = 0;
690
    ip_globals.gateway.netmask.s_addr = 0;
657
    ip_globals.gateway.gateway.s_addr = gateway.s_addr;
691
    ip_globals.gateway.gateway.s_addr = gateway.s_addr;
658
    ip_globals.gateway.netif = netif;
692
    ip_globals.gateway.netif = netif;
-
 
693
    rwlock_write_unlock( & ip_globals.netifs_lock );
659
    return EOK;
694
    return EOK;
660
}
695
}
661
 
696
 
662
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len ){
697
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len ){
663
    size_t          length;
698
    size_t          length;
Line 706... Line 741...
706
    if( header->flags & IPFLAG_DONT_FRAGMENT ){
741
    if( header->flags & IPFLAG_DONT_FRAGMENT ){
707
        // TODO fragmentation necessary ICMP
742
        // TODO fragmentation necessary ICMP
708
        return EPERM;
743
        return EPERM;
709
    }
744
    }
710
    // create the last fragment
745
    // create the last fragment
711
    new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( address_length > addr_len ) ? address_length : addr_len ));
746
    new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, ((( size_t ) address_length > addr_len ) ? ( size_t ) address_length : addr_len ));
712
    if( ! new_packet ) return ENOMEM;
747
    if( ! new_packet ) return ENOMEM;
713
    last_header = ip_create_last_header( new_packet, header );
748
    last_header = ip_create_last_header( new_packet, header );
714
    if( ! last_header ){
749
    if( ! last_header ){
715
        pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
750
        pq_release( ip_globals.net_phone, packet_get_id( new_packet ));
716
        return ENOMEM;
751
        return ENOMEM;
Line 862... Line 897...
862
 
897
 
863
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
898
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
864
        // TODO fragmented
899
        // TODO fragmented
865
        return ENOTSUP;
900
        return ENOTSUP;
866
    }else{
901
    }else{
867
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
-
 
868
        if( ! proto ) return ENOENT;
-
 
869
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR ));
902
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR ));
-
 
903
        rwlock_read_lock( & ip_globals.protos_lock );
-
 
904
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
-
 
905
        if( ! proto ){
-
 
906
            rwlock_read_unlock( & ip_globals.protos_lock );
-
 
907
            return ENOENT;
-
 
908
        }
870
        if( proto->tl_received_msg ){
909
        if( proto->received_msg ){
871
            return proto->tl_received_msg( device_id, packet, SERVICE_IP );
910
            ERROR_CODE = proto->received_msg( device_id, packet, SERVICE_IP );
872
        }else{
911
        }else{
873
            return tl_received_msg( proto->phone, device_id, packet, proto->service );
912
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service );
874
        }
913
        }
-
 
914
        rwlock_read_unlock( & ip_globals.protos_lock );
-
 
915
        return ERROR_CODE;
875
    }
916
    }
876
}
917
}
877
 
918
 
878
in_addr_t ip_get_destination( ip_header_ref header ){
919
in_addr_t ip_get_destination( ip_header_ref header ){
879
    in_addr_t   destination;
920
    in_addr_t   destination;