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