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; |