Changes in uspace/srv/net/il/ip/ip.c [836dd794:a000878c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/ip/ip.c
r836dd794 ra000878c 108 108 /** IP packet address length. 109 109 */ 110 #define IP_ADDR sizeof( struct sockaddr_in6)110 #define IP_ADDR sizeof( struct sockaddr_in6 ) 111 111 112 112 /** IP packet prefix length. 113 113 */ 114 #define IP_PREFIX sizeof( ip_header_t)114 #define IP_PREFIX sizeof( ip_header_t ) 115 115 116 116 /** IP packet suffix length. … … 124 124 /** The IP localhost address. 125 125 */ 126 #define IPV4_LOCALHOST_ADDRESS htonl(( 127 << 24) + 1)126 #define IPV4_LOCALHOST_ADDRESS htonl(( 127 << 24 ) + 1 ) 127 127 128 128 /** IP global data. … … 130 130 ip_globals_t ip_globals; 131 131 132 DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t)133 134 INT_MAP_IMPLEMENT( ip_protos, ip_proto_t)135 136 GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t)132 DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t ) 133 134 INT_MAP_IMPLEMENT( ip_protos, ip_proto_t ) 135 136 GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t ) 137 137 138 138 /** Updates the device content length according to the new MTU value. … … 142 142 * @returns ENOENT if device is not found. 143 143 */ 144 int ip_mtu_changed_message(device_id_t device_id, size_t mtu);144 int ip_mtu_changed_message( device_id_t device_id, size_t mtu ); 145 145 146 146 /** Updates the device state. … … 150 150 * @returns ENOENT if device is not found. 151 151 */ 152 int ip_device_state_message(device_id_t device_id, device_state_t state);152 int ip_device_state_message( device_id_t device_id, device_state_t state ); 153 153 154 154 /** Returns the device packet dimensions for sending. … … 162 162 * @returns EOK on success. 163 163 */ 164 int ip_packet_size_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix);164 int ip_packet_size_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); 165 165 166 166 /** Registers the transport layer protocol. … … 175 175 * @returns ENOMEM if there is not enough memory left. 176 176 */ 177 int ip_register(int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg);177 int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg ); 178 178 179 179 /** Initializes a new network interface specific data. … … 192 192 * @returns Other error codes as defined for the nil_packet_size_req() function. 193 193 */ 194 int ip_netif_initialize(ip_netif_ref ip_netif);194 int ip_netif_initialize( ip_netif_ref ip_netif ); 195 195 196 196 /** Sends the packet or the packet queue via the specified route. … … 206 206 * @returns Other error codes as defined for the ip_prepare_packet() function. 207 207 */ 208 int ip_send_route(packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error);208 int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error ); 209 209 210 210 /** Prepares the outgoing packet or the packet queue. … … 222 222 * @returns Other error codes as defined for the packet_set_addr() function. 223 223 */ 224 int ip_prepare_packet(in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination);224 int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ); 225 225 226 226 /** Checks the packet queue lengths and fragments the packets if needed. … … 235 235 * @returns NULL if there are no packets left. 236 236 */ 237 packet_t ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error);237 packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error ); 238 238 239 239 /** Checks the packet length and fragments it if needed. … … 255 255 * @returns Other error codes as defined for the ip_fragment_packet_data() function. 256 256 */ 257 int ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len);257 int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len ); 258 258 259 259 /** Fragments the packet from the end. … … 271 271 * @returns Other error codes as defined for the pq_insert_after() function. 272 272 */ 273 int ip_fragment_packet_data(packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen);273 int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen ); 274 274 275 275 /** Prefixes a middle fragment header based on the last fragment header to the packet. … … 279 279 * @returns NULL on error. 280 280 */ 281 ip_header_ref ip_create_middle_header(packet_t packet, ip_header_ref last);281 ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ); 282 282 283 283 /** Copies the fragment header. … … 286 286 * @param[in] first The original header to be copied. 287 287 */ 288 void ip_create_last_header( ip_header_ref last, ip_header_ref first);288 void ip_create_last_header( ip_header_ref last, ip_header_ref first ); 289 289 290 290 /** Returns the network interface's IP address. … … 293 293 * @returns NULL if no IP address was found. 294 294 */ 295 in_addr_t * ip_netif_address(ip_netif_ref netif);295 in_addr_t * ip_netif_address( ip_netif_ref netif ); 296 296 297 297 /** Searches all network interfaces if there is a suitable route. … … 300 300 * @returns NULL if no route was found. 301 301 */ 302 ip_route_ref ip_find_route(in_addr_t destination);302 ip_route_ref ip_find_route( in_addr_t destination ); 303 303 304 304 /** Searches the network interfaces if there is a suitable route. … … 308 308 * @returns NULL if no route was found. 309 309 */ 310 ip_route_ref ip_netif_find_route(ip_netif_ref netif, in_addr_t destination);310 ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ); 311 311 312 312 /** Processes the received IP packet or the packet queue one by one. … … 321 321 * @returns ENOMEM if there is not enough memory left. 322 322 */ 323 int ip_receive_message(device_id_t device_id, packet_t packet);323 int ip_receive_message( device_id_t device_id, packet_t packet ); 324 324 325 325 /** Processes the received packet. … … 338 338 * @returns ENOENT if the packet is for another host and the routing is disabled. 339 339 */ 340 int ip_process_packet(device_id_t device_id, packet_t packet);340 int ip_process_packet( device_id_t device_id, packet_t packet ); 341 341 342 342 /** Returns the packet destination address from the IP header. … … 344 344 * @returns The packet destination address. 345 345 */ 346 in_addr_t ip_get_destination(ip_header_ref header);346 in_addr_t ip_get_destination( ip_header_ref header ); 347 347 348 348 /** Delivers the packet to the local host. … … 361 361 * @returns Other error codes as defined for the protocol specific tl_received_msg function. 362 362 */ 363 int ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header, services_t error);363 int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ); 364 364 365 365 /** Prepares the ICMP notification packet. … … 374 374 * @returns EINVAL if the ip_prepare_icmp() fails. 375 375 */ 376 int ip_prepare_icmp_and_get_phone(services_t error, packet_t packet, ip_header_ref header);376 int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ); 377 377 378 378 /** Returns the ICMP phone. … … 381 381 * @returns ENOENT if the ICMP is not registered. 382 382 */ 383 int ip_get_icmp_phone(void);383 int ip_get_icmp_phone( void ); 384 384 385 385 /** Prepares the ICMP notification packet. … … 395 395 * @returns Other error codes as defined for the packet_set_addr(). 396 396 */ 397 int ip_prepare_icmp(packet_t packet, ip_header_ref header);397 int ip_prepare_icmp( packet_t packet, ip_header_ref header ); 398 398 399 399 /** Releases the packet and returns the result. … … 402 402 * @return The result parameter. 403 403 */ 404 int ip_release_and_return(packet_t packet, int result);405 406 int ip_initialize( async_client_conn_t client_connection){404 int ip_release_and_return( packet_t packet, int result ); 405 406 int ip_initialize( async_client_conn_t client_connection ){ 407 407 ERROR_DECLARE; 408 408 409 fibril_rwlock_initialize( &ip_globals.lock);410 fibril_rwlock_write_lock( &ip_globals.lock);411 fibril_rwlock_initialize( &ip_globals.protos_lock);412 fibril_rwlock_initialize( &ip_globals.netifs_lock);409 fibril_rwlock_initialize( & ip_globals.lock ); 410 fibril_rwlock_write_lock( & ip_globals.lock ); 411 fibril_rwlock_initialize( & ip_globals.protos_lock ); 412 fibril_rwlock_initialize( & ip_globals.netifs_lock ); 413 413 ip_globals.packet_counter = 0; 414 414 ip_globals.gateway.address.s_addr = 0; … … 416 416 ip_globals.gateway.gateway.s_addr = 0; 417 417 ip_globals.gateway.netif = NULL; 418 ERROR_PROPAGATE( ip_netifs_initialize(&ip_globals.netifs));419 ERROR_PROPAGATE( ip_protos_initialize(&ip_globals.protos));418 ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs )); 419 ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos )); 420 420 ip_globals.client_connection = client_connection; 421 ERROR_PROPAGATE( modules_initialize(&ip_globals.modules));422 ERROR_PROPAGATE( add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module));423 fibril_rwlock_write_unlock( &ip_globals.lock);421 ERROR_PROPAGATE( modules_initialize( & ip_globals.modules )); 422 ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module )); 423 fibril_rwlock_write_unlock( & ip_globals.lock ); 424 424 return EOK; 425 425 } 426 426 427 int ip_device_req( int il_phone, device_id_t device_id, services_t netif){427 int ip_device_req( int il_phone, device_id_t device_id, services_t netif ){ 428 428 ERROR_DECLARE; 429 429 430 ip_netif_ref ip_netif; 431 ip_route_ref route; 432 int index; 433 char * data; 434 435 ip_netif = (ip_netif_ref) malloc(sizeof(ip_netif_t)); 436 if(! ip_netif){ 437 return ENOMEM; 438 } 439 if(ERROR_OCCURRED(ip_routes_initialize(&ip_netif->routes))){ 440 free(ip_netif); 430 ip_netif_ref ip_netif; 431 ip_route_ref route; 432 int index; 433 char * data; 434 435 ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t )); 436 if( ! ip_netif ) return ENOMEM; 437 if( ERROR_OCCURRED( ip_routes_initialize( & ip_netif->routes ))){ 438 free( ip_netif ); 441 439 return ERROR_CODE; 442 440 } … … 444 442 ip_netif->service = netif; 445 443 ip_netif->state = NETIF_STOPPED; 446 fibril_rwlock_write_lock( &ip_globals.netifs_lock);447 if( ERROR_OCCURRED(ip_netif_initialize(ip_netif))){448 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);449 ip_routes_destroy( &ip_netif->routes);450 free( ip_netif);444 fibril_rwlock_write_lock( & ip_globals.netifs_lock ); 445 if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){ 446 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 447 ip_routes_destroy( & ip_netif->routes ); 448 free( ip_netif ); 451 449 return ERROR_CODE; 452 450 } 453 if(ip_netif->arp){ 454 ++ ip_netif->arp->usage; 455 } 451 if( ip_netif->arp ) ++ ip_netif->arp->usage; 456 452 // print the settings 457 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);458 printf( "\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static");453 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 ); 454 printf( "\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static" ); 459 455 // TODO ipv6 addresses 460 data = ( char *) malloc(INET_ADDRSTRLEN);461 if( data){462 for( index = 0; index < ip_routes_count(&ip_netif->routes); ++ index){463 route = ip_routes_get_index( &ip_netif->routes, index);464 if( route){465 printf( "\tRouting %d:\n", index);466 inet_ntop( AF_INET, (uint8_t *) &route->address.s_addr, data, INET_ADDRSTRLEN);467 printf( "\t\taddress\t= %s\n", data);468 inet_ntop( AF_INET, (uint8_t *) &route->netmask.s_addr, data, INET_ADDRSTRLEN);469 printf( "\t\tnetmask\t= %s\n", data);470 inet_ntop( AF_INET, (uint8_t *) &route->gateway.s_addr, data, INET_ADDRSTRLEN);471 printf( "\t\tgateway\t= %s\n", data);472 } 473 } 474 inet_ntop( AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN);475 printf( "\t\tbroadcast\t= %s\n", data);476 free( data);477 } 478 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);456 data = ( char * ) malloc( INET_ADDRSTRLEN ); 457 if( data ){ 458 for( index = 0; index < ip_routes_count( & ip_netif->routes ); ++ index ){ 459 route = ip_routes_get_index( & ip_netif->routes, index ); 460 if( route ){ 461 printf( "\tRouting %d:\n", index ); 462 inet_ntop( AF_INET, ( uint8_t * ) & route->address.s_addr, data, INET_ADDRSTRLEN ); 463 printf( "\t\taddress\t= %s\n", data ); 464 inet_ntop( AF_INET, ( uint8_t * ) & route->netmask.s_addr, data, INET_ADDRSTRLEN ); 465 printf( "\t\tnetmask\t= %s\n", data ); 466 inet_ntop( AF_INET, ( uint8_t * ) & route->gateway.s_addr, data, INET_ADDRSTRLEN ); 467 printf( "\t\tgateway\t= %s\n", data ); 468 } 469 } 470 inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN ); 471 printf( "\t\tbroadcast\t= %s\n", data ); 472 free( data ); 473 } 474 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 479 475 return EOK; 480 476 } 481 477 482 int ip_netif_initialize( ip_netif_ref ip_netif){478 int ip_netif_initialize( ip_netif_ref ip_netif ){ 483 479 ERROR_DECLARE; 484 480 485 measured_string_t names[] = {{str_dup("IPV"), 3}, {str_dup("IP_CONFIG"), 9}, {str_dup("IP_ADDR"), 7}, {str_dup("IP_NETMASK"), 10}, {str_dup("IP_GATEWAY"), 10}, {str_dup("IP_BROADCAST"), 12}, {str_dup("ARP"), 3}, {str_dup("IP_ROUTING"), 10}};486 measured_string_ref 487 size_t count = sizeof(names) / sizeof(measured_string_t);488 char * 489 measured_string_t 490 int 491 ip_route_ref 492 in_addr_t 481 measured_string_t names[] = {{ str_dup("IPV"), 3 }, { str_dup("IP_CONFIG"), 9 }, { str_dup("IP_ADDR"), 7 }, { str_dup("IP_NETMASK"), 10 }, { str_dup("IP_GATEWAY"), 10 }, { str_dup("IP_BROADCAST"), 12 }, { str_dup("ARP"), 3 }, { str_dup("IP_ROUTING"), 10 }}; 482 measured_string_ref configuration; 483 size_t count = sizeof( names ) / sizeof( measured_string_t ); 484 char * data; 485 measured_string_t address; 486 int index; 487 ip_route_ref route; 488 in_addr_t gateway; 493 489 494 490 ip_netif->arp = NULL; … … 497 493 ip_netif->dhcp = false; 498 494 ip_netif->routing = NET_DEFAULT_IP_ROUTING; 499 configuration = & names[0];495 configuration = & names[ 0 ]; 500 496 // get configuration 501 ERROR_PROPAGATE( net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id, &configuration, count, &data));502 if( configuration){503 if( configuration[0].value){504 ip_netif->ipv = strtol( configuration[0].value, NULL, 0);505 } 506 ip_netif->dhcp = ! str_lcmp( configuration[1].value, "dhcp", configuration[1].length);507 if( ip_netif->dhcp){497 ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data )); 498 if( configuration ){ 499 if( configuration[ 0 ].value ){ 500 ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 ); 501 } 502 ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length ); 503 if( ip_netif->dhcp ){ 508 504 // TODO dhcp 509 net_free_settings( configuration, data);505 net_free_settings( configuration, data ); 510 506 return ENOTSUP; 511 }else if( ip_netif->ipv == IPV4){512 route = ( ip_route_ref) malloc(sizeof(ip_route_t));513 if( ! route){514 net_free_settings( configuration, data);507 }else if( ip_netif->ipv == IPV4 ){ 508 route = ( ip_route_ref ) malloc( sizeof( ip_route_t )); 509 if( ! route ){ 510 net_free_settings( configuration, data ); 515 511 return ENOMEM; 516 512 } … … 519 515 route->gateway.s_addr = 0; 520 516 route->netif = ip_netif; 521 index = ip_routes_add( &ip_netif->routes, route);522 if( index < 0){523 net_free_settings( configuration, data);524 free( route);517 index = ip_routes_add( & ip_netif->routes, route ); 518 if( index < 0 ){ 519 net_free_settings( configuration, data ); 520 free( route ); 525 521 return index; 526 522 } 527 if( ERROR_OCCURRED(inet_pton(AF_INET, configuration[2].value, (uint8_t *) &route->address.s_addr))528 || ERROR_OCCURRED(inet_pton(AF_INET, configuration[3].value, (uint8_t *) &route->netmask.s_addr))529 || (inet_pton(AF_INET, configuration[4].value, (uint8_t *) &gateway.s_addr) == EINVAL)530 || (inet_pton(AF_INET, configuration[5].value, (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL)){531 net_free_settings( configuration, data);523 if( ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 2 ].value, ( uint8_t * ) & route->address.s_addr )) 524 || ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 3 ].value, ( uint8_t * ) & route->netmask.s_addr )) 525 || ( inet_pton( AF_INET, configuration[ 4 ].value, ( uint8_t * ) & gateway.s_addr ) == EINVAL ) 526 || ( inet_pton( AF_INET, configuration[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast.s_addr ) == EINVAL )){ 527 net_free_settings( configuration, data ); 532 528 return EINVAL; 533 529 } 534 530 }else{ 535 531 // TODO ipv6 in separate module 536 net_free_settings( configuration, data);532 net_free_settings( configuration, data ); 537 533 return ENOTSUP; 538 534 } 539 if( configuration[6].value){540 ip_netif->arp = get_running_module( &ip_globals.modules, configuration[6].value);541 if( ! ip_netif->arp){542 printf( "Failed to start the arp %s\n", configuration[6].value);543 net_free_settings( configuration, data);535 if( configuration[ 6 ].value ){ 536 ip_netif->arp = get_running_module( & ip_globals.modules, configuration[ 6 ].value ); 537 if( ! ip_netif->arp ){ 538 printf( "Failed to start the arp %s\n", configuration[ 6 ].value ); 539 net_free_settings( configuration, data ); 544 540 return EINVAL; 545 541 } 546 542 } 547 if( configuration[7].value){548 ip_netif->routing = ( configuration[7].value[0] == 'y');549 } 550 net_free_settings( configuration, data);543 if( configuration[ 7 ].value ){ 544 ip_netif->routing = ( configuration[ 7 ].value[ 0 ] == 'y' ); 545 } 546 net_free_settings( configuration, data ); 551 547 } 552 548 // binds the netif service which also initializes the device 553 ip_netif->phone = nil_bind_service( ip_netif->service, (ipcarg_t) ip_netif->device_id, SERVICE_IP, ip_globals.client_connection);554 if( ip_netif->phone < 0){555 printf( "Failed to contact the nil service %d\n", ip_netif->service);549 ip_netif->phone = nil_bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, ip_globals.client_connection ); 550 if( ip_netif->phone < 0 ){ 551 printf( "Failed to contact the nil service %d\n", ip_netif->service ); 556 552 return ip_netif->phone; 557 553 } 558 554 // has to be after the device netif module initialization 559 if( ip_netif->arp){560 if( route){561 address.value = ( char *) &route->address.s_addr;562 address.length = CONVERT_SIZE( in_addr_t, char, 1);563 ERROR_PROPAGATE( arp_device_req(ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, &address));555 if( ip_netif->arp ){ 556 if( route ){ 557 address.value = ( char * ) & route->address.s_addr; 558 address.length = CONVERT_SIZE( in_addr_t, char, 1 ); 559 ERROR_PROPAGATE( arp_device_req( ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, & address )); 564 560 }else{ 565 561 ip_netif->arp = 0; … … 567 563 } 568 564 // get packet dimensions 569 ERROR_PROPAGATE( nil_packet_size_req(ip_netif->phone, ip_netif->device_id, &ip_netif->packet_dimension));570 if( ip_netif->packet_dimension.content < IP_MIN_CONTENT){571 printf( "Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->packet_dimension.content, IP_MIN_CONTENT);565 ERROR_PROPAGATE( nil_packet_size_req( ip_netif->phone, ip_netif->device_id, & ip_netif->packet_dimension )); 566 if( ip_netif->packet_dimension.content < IP_MIN_CONTENT ){ 567 printf( "Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->packet_dimension.content, IP_MIN_CONTENT ); 572 568 ip_netif->packet_dimension.content = IP_MIN_CONTENT; 573 569 } 574 index = ip_netifs_add(&ip_globals.netifs, ip_netif->device_id, ip_netif); 575 if(index < 0){ 576 return index; 577 } 578 if(gateway.s_addr){ 570 index = ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif ); 571 if( index < 0 ) return index; 572 if( gateway.s_addr ){ 579 573 // the default gateway 580 574 ip_globals.gateway.address.s_addr = 0; … … 586 580 } 587 581 588 int ip_mtu_changed_message( device_id_t device_id, size_t mtu){589 ip_netif_ref 590 591 fibril_rwlock_write_lock( &ip_globals.netifs_lock);592 netif = ip_netifs_find( &ip_globals.netifs, device_id);593 if( ! netif){594 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);582 int ip_mtu_changed_message( device_id_t device_id, size_t mtu ){ 583 ip_netif_ref netif; 584 585 fibril_rwlock_write_lock( & ip_globals.netifs_lock ); 586 netif = ip_netifs_find( & ip_globals.netifs, device_id ); 587 if( ! netif ){ 588 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 595 589 return ENOENT; 596 590 } 597 591 netif->packet_dimension.content = mtu; 598 printf( "ip - device %d changed mtu to %d\n\n", device_id, mtu);599 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);592 printf( "ip - device %d changed mtu to %d\n\n", device_id, mtu ); 593 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 600 594 return EOK; 601 595 } 602 596 603 int ip_device_state_message( device_id_t device_id, device_state_t state){604 ip_netif_ref 605 606 fibril_rwlock_write_lock( &ip_globals.netifs_lock);597 int ip_device_state_message( device_id_t device_id, device_state_t state ){ 598 ip_netif_ref netif; 599 600 fibril_rwlock_write_lock( & ip_globals.netifs_lock ); 607 601 // find the device 608 netif = ip_netifs_find( &ip_globals.netifs, device_id);609 if( ! netif){610 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);602 netif = ip_netifs_find( & ip_globals.netifs, device_id ); 603 if( ! netif ){ 604 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 611 605 return ENOENT; 612 606 } 613 607 netif->state = state; 614 printf( "ip - device %d changed state to %d\n\n", device_id, state);615 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);608 printf( "ip - device %d changed state to %d\n\n", device_id, state ); 609 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 616 610 return EOK; 617 611 } 618 612 619 int ip_connect_module( services_t service){613 int ip_connect_module( services_t service ){ 620 614 return EOK; 621 615 } 622 616 623 int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg){ 624 return ip_register(protocol, me, 0, received_msg); 625 } 626 627 int ip_register(int protocol, services_t service, int phone, tl_received_msg_t received_msg){ 628 ip_proto_ref proto; 629 int index; 630 631 if(!(protocol && service && ((phone > 0) || (received_msg)))){ 632 return EINVAL; 633 } 634 proto = (ip_proto_ref) malloc(sizeof(ip_protos_t)); 635 if(! proto){ 636 return ENOMEM; 637 } 617 int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){ 618 return ip_register( protocol, me, 0, received_msg ); 619 } 620 621 int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){ 622 ip_proto_ref proto; 623 int index; 624 625 if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL; 626 proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t )); 627 if( ! proto ) return ENOMEM; 638 628 proto->protocol = protocol; 639 629 proto->service = service; 640 630 proto->phone = phone; 641 631 proto->received_msg = received_msg; 642 fibril_rwlock_write_lock( &ip_globals.protos_lock);643 index = ip_protos_add( &ip_globals.protos, proto->protocol, proto);644 if( index < 0){645 fibril_rwlock_write_unlock( &ip_globals.protos_lock);646 free( proto);632 fibril_rwlock_write_lock( & ip_globals.protos_lock ); 633 index = ip_protos_add( & ip_globals.protos, proto->protocol, proto ); 634 if( index < 0 ){ 635 fibril_rwlock_write_unlock( & ip_globals.protos_lock ); 636 free( proto ); 647 637 return index; 648 638 } 649 printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone);650 fibril_rwlock_write_unlock( &ip_globals.protos_lock);639 printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone ); 640 fibril_rwlock_write_unlock( & ip_globals.protos_lock ); 651 641 return EOK; 652 642 } 653 643 654 int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){644 int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ){ 655 645 ERROR_DECLARE; 656 646 657 int 658 ip_netif_ref 659 ip_route_ref 660 struct sockaddr * 661 struct sockaddr_in * 647 int addrlen; 648 ip_netif_ref netif; 649 ip_route_ref route; 650 struct sockaddr * addr; 651 struct sockaddr_in * address_in; 662 652 // struct sockaddr_in6 * address_in6; 663 in_addr_t * 664 in_addr_t * 665 int 653 in_addr_t * dest; 654 in_addr_t * src; 655 int phone; 666 656 667 657 // addresses in the host byte order 668 658 // should be the next hop address or the target destination address 669 addrlen = packet_get_addr( packet, NULL, (uint8_t **) &addr);670 if( addrlen < 0){671 return ip_release_and_return( packet, addrlen);672 } 673 if(( size_t) addrlen < sizeof(struct sockaddr)){674 return ip_release_and_return( packet, EINVAL);675 } 676 switch( addr->sa_family){659 addrlen = packet_get_addr( packet, NULL, ( uint8_t ** ) & addr ); 660 if( addrlen < 0 ){ 661 return ip_release_and_return( packet, addrlen ); 662 } 663 if(( size_t ) addrlen < sizeof( struct sockaddr )){ 664 return ip_release_and_return( packet, EINVAL ); 665 } 666 switch( addr->sa_family ){ 677 667 case AF_INET: 678 if( addrlen != sizeof(struct sockaddr_in)){679 return ip_release_and_return( packet, EINVAL);680 } 681 address_in = ( struct sockaddr_in *) addr;682 dest = & address_in->sin_addr;683 if( ! dest->s_addr){668 if( addrlen != sizeof( struct sockaddr_in )){ 669 return ip_release_and_return( packet, EINVAL ); 670 } 671 address_in = ( struct sockaddr_in * ) addr; 672 dest = & address_in->sin_addr; 673 if( ! dest->s_addr ){ 684 674 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 685 675 } … … 687 677 // TODO IPv6 688 678 /* case AF_INET6: 689 if(addrlen != sizeof(struct sockaddr_in6)){ 690 return EINVAL; 691 } 692 address_in6 = (struct sockaddr_in6 *) dest; 679 if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; 680 address_in6 = ( struct sockaddr_in6 * ) dest; 693 681 address_in6.sin6_addr.s6_addr; 694 682 IPV6_LOCALHOST_ADDRESS; 695 683 */ default: 696 return ip_release_and_return(packet, EAFNOSUPPORT); 697 } 698 netif = NULL; 699 route = NULL; 700 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 684 return ip_release_and_return( packet, EAFNOSUPPORT ); 685 } 686 fibril_rwlock_read_lock( & ip_globals.netifs_lock ); 701 687 // device specified? 702 if(device_id > 0){ 703 netif = ip_netifs_find(&ip_globals.netifs, device_id); 704 route = ip_netif_find_route(netif, * dest); 705 if(netif && (! route) && (ip_globals.gateway.netif == netif)){ 706 route = &ip_globals.gateway; 707 } 708 } 709 if(! route){ 710 route = ip_find_route(*dest); 688 if( device_id > 0 ){ 689 netif = ip_netifs_find( & ip_globals.netifs, device_id ); 690 route = ip_netif_find_route( netif, * dest ); 691 if( netif && ( ! route ) && ( ip_globals.gateway.netif == netif )){ 692 route = & ip_globals.gateway; 693 } 694 }else{ 695 route = ip_find_route( * dest ); 711 696 netif = route ? route->netif : NULL; 712 697 } 713 if( !(netif && route)){714 fibril_rwlock_read_unlock( &ip_globals.netifs_lock);715 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL);716 if( phone >= 0){698 if( !( netif && route )){ 699 fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); 700 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL ); 701 if( phone >= 0 ){ 717 702 // unreachable ICMP if no routing 718 icmp_destination_unreachable_msg( phone, ICMP_NET_UNREACH, 0, packet);703 icmp_destination_unreachable_msg( phone, ICMP_NET_UNREACH, 0, packet ); 719 704 } 720 705 return ENOENT; 721 706 } 722 if( error){707 if( error ){ 723 708 // do not send for broadcast, anycast packets or network broadcast 724 if((! dest->s_addr) 725 || (!(~ dest->s_addr)) 726 || (!(~((dest->s_addr &(~ route->netmask.s_addr)) | route->netmask.s_addr))) 727 || (!(dest->s_addr &(~ route->netmask.s_addr)))){ 728 return ip_release_and_return(packet, EINVAL); 729 } 730 } 731 // if the local host is the destination 732 if((route->address.s_addr == dest->s_addr) 733 && (dest->s_addr != IPV4_LOCALHOST_ADDRESS)){ 709 if(( ! dest->s_addr ) 710 || ( !( ~ dest->s_addr )) 711 || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr ))) 712 || ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){ 713 return ip_release_and_return( packet, EINVAL ); 714 } 715 } 716 if( route->address.s_addr == dest->s_addr ){ 734 717 // find the loopback device to deliver 735 718 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 736 route = ip_find_route( *dest);719 route = ip_find_route( * dest ); 737 720 netif = route ? route->netif : NULL; 738 if( !(netif && route)){739 fibril_rwlock_read_unlock( &ip_globals.netifs_lock);740 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL);741 if( phone >= 0){721 if( !( netif && route )){ 722 fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); 723 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL ); 724 if( phone >= 0 ){ 742 725 // unreachable ICMP if no routing 743 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet);726 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet ); 744 727 } 745 728 return ENOENT; 746 729 } 747 730 } 748 src = ip_netif_address( netif);749 if( ! src){750 fibril_rwlock_read_unlock( &ip_globals.netifs_lock);751 return ip_release_and_return( packet, ENOENT);752 } 753 ERROR_CODE = ip_send_route( packet, netif, route, src, * dest, error);754 fibril_rwlock_read_unlock( &ip_globals.netifs_lock);731 src = ip_netif_address( netif ); 732 if( ! src ){ 733 fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); 734 return ip_release_and_return( packet, ENOENT ); 735 } 736 ERROR_CODE = ip_send_route( packet, netif, route, src, * dest, error ); 737 fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); 755 738 return ERROR_CODE; 756 739 } 757 740 758 in_addr_t * ip_netif_address( ip_netif_ref netif){759 ip_route_ref 760 761 route = ip_routes_get_index( &netif->routes, 0);762 return route ? & route->address : NULL;763 } 764 765 int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error){741 in_addr_t * ip_netif_address( ip_netif_ref netif ){ 742 ip_route_ref route; 743 744 route = ip_routes_get_index( & netif->routes, 0 ); 745 return route ? & route->address : NULL; 746 } 747 748 int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error ){ 766 749 ERROR_DECLARE; 767 750 768 measured_string_t 769 measured_string_ref 770 char * 771 int 751 measured_string_t destination; 752 measured_string_ref translation; 753 char * data; 754 int phone; 772 755 773 756 // get destination hardware address 774 if( netif->arp && (route->address.s_addr != dest.s_addr)){775 destination.value = route->gateway.s_addr ? ( char *) &route->gateway.s_addr : (char *) &dest.s_addr;776 destination.length = CONVERT_SIZE( dest.s_addr, char, 1);777 if( ERROR_OCCURRED(arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data))){778 // sleep( 1);779 // ERROR_PROPAGATE( arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data));780 pq_release( ip_globals.net_phone, packet_get_id(packet));757 if( netif->arp && ( route->address.s_addr != dest.s_addr )){ 758 destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr; 759 destination.length = CONVERT_SIZE( dest.s_addr, char, 1 ); 760 if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){ 761 // sleep( 1 ); 762 // ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data )); 763 pq_release( ip_globals.net_phone, packet_get_id( packet )); 781 764 return ERROR_CODE; 782 765 } 783 if( !(translation && translation->value)){784 if( translation){785 free( translation);786 free( data);787 } 788 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL);789 if( phone >= 0){766 if( !( translation && translation->value )){ 767 if( translation ){ 768 free( translation ); 769 free( data ); 770 } 771 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL ); 772 if( phone >= 0 ){ 790 773 // unreachable ICMP if no routing 791 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet);774 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet ); 792 775 } 793 776 return EINVAL; 794 777 } 795 778 }else translation = NULL; 796 if( ERROR_OCCURRED(ip_prepare_packet(src, dest, packet, translation))){797 pq_release( ip_globals.net_phone, packet_get_id(packet));779 if( ERROR_OCCURRED( ip_prepare_packet( src, dest, packet, translation ))){ 780 pq_release( ip_globals.net_phone, packet_get_id( packet )); 798 781 }else{ 799 packet = ip_split_packet( packet, netif->packet_dimension.prefix, netif->packet_dimension.content, netif->packet_dimension.suffix, netif->packet_dimension.addr_len, error);800 if( packet){801 nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP);802 } 803 } 804 if( translation){805 free( translation);806 free( data);782 packet = ip_split_packet( packet, netif->packet_dimension.prefix, netif->packet_dimension.content, netif->packet_dimension.suffix, netif->packet_dimension.addr_len, error ); 783 if( packet ){ 784 nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP ); 785 } 786 } 787 if( translation ){ 788 free( translation ); 789 free( data ); 807 790 } 808 791 return ERROR_CODE; 809 792 } 810 793 811 int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination){794 int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ){ 812 795 ERROR_DECLARE; 813 796 814 size_t length; 815 ip_header_ref header; 816 ip_header_ref last_header; 817 ip_header_ref middle_header; 818 packet_t next; 819 820 length = packet_get_data_length(packet); 821 if((length < sizeof(ip_header_t)) || (length > IP_MAX_CONTENT)){ 822 return EINVAL; 823 } 824 header = (ip_header_ref) packet_get_data(packet); 825 if(destination){ 826 ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 797 size_t length; 798 ip_header_ref header; 799 ip_header_ref last_header; 800 ip_header_ref middle_header; 801 packet_t next; 802 803 length = packet_get_data_length( packet ); 804 if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL; 805 header = ( ip_header_ref ) packet_get_data( packet ); 806 if( destination ){ 807 ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); 827 808 }else{ 828 ERROR_PROPAGATE( packet_set_addr(packet, NULL, NULL, 0));809 ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0 )); 829 810 } 830 811 header->version = IPV4; … … 832 813 header->fragment_offset_low = 0; 833 814 header->header_checksum = 0; 834 if(source){ 835 header->source_address = source->s_addr; 836 } 815 if( source ) header->source_address = source->s_addr; 837 816 header->destination_address = dest.s_addr; 838 fibril_rwlock_write_lock( &ip_globals.lock);817 fibril_rwlock_write_lock( & ip_globals.lock ); 839 818 ++ ip_globals.packet_counter; 840 header->identification = htons(ip_globals.packet_counter); 841 fibril_rwlock_write_unlock(&ip_globals.lock); 842 // length = packet_get_data_length(packet); 843 if(pq_next(packet)){ 844 last_header = (ip_header_ref) malloc(IP_HEADER_LENGTH(header)); 845 if(! last_header){ 846 return ENOMEM; 847 } 848 ip_create_last_header(last_header, header); 849 next = pq_next(packet); 850 while(pq_next(next)){ 851 middle_header = (ip_header_ref) packet_prefix(next, IP_HEADER_LENGTH(last_header)); 852 if(! middle_header){ 853 return ENOMEM; 854 } 855 memcpy(middle_header, last_header, IP_HEADER_LENGTH(last_header)); 819 header->identification = htons( ip_globals.packet_counter ); 820 fibril_rwlock_write_unlock( & ip_globals.lock ); 821 // length = packet_get_data_length( packet ); 822 if( pq_next( packet )){ 823 last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header )); 824 if( ! last_header ) return ENOMEM; 825 ip_create_last_header( last_header, header ); 826 next = pq_next( packet ); 827 while( pq_next( next )){ 828 middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header )); 829 if( ! middle_header ) return ENOMEM; 830 memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header )); 856 831 header->flags |= IPFLAG_MORE_FRAGMENTS; 857 middle_header->total_length = htons(packet_get_data_length(next)); 858 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length); 859 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); 860 middle_header->header_checksum = IP_HEADER_CHECKSUM(middle_header); 861 if(destination){ 862 ERROR_PROPAGATE(packet_set_addr(next, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 863 } 864 length += packet_get_data_length(next); 865 next = pq_next(next); 866 } 867 middle_header = (ip_header_ref) packet_prefix(next, IP_HEADER_LENGTH(last_header)); 868 if(! middle_header){ 869 return ENOMEM; 870 } 871 memcpy(middle_header, last_header, IP_HEADER_LENGTH(last_header)); 872 middle_header->total_length = htons(packet_get_data_length(next)); 873 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length); 874 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(length); 875 middle_header->header_checksum = IP_HEADER_CHECKSUM(middle_header); 876 if(destination){ 877 ERROR_PROPAGATE(packet_set_addr(next, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length))); 878 } 879 length += packet_get_data_length(next); 880 free(last_header); 832 middle_header->total_length = htons( packet_get_data_length( next )); 833 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length ); 834 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length ); 835 middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header ); 836 if( destination ){ 837 ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); 838 } 839 length += packet_get_data_length( next ); 840 next = pq_next( next ); 841 } 842 middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header )); 843 if( ! middle_header ) return ENOMEM; 844 memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header )); 845 middle_header->total_length = htons( packet_get_data_length( next )); 846 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length ); 847 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length ); 848 middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header ); 849 if( destination ){ 850 ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); 851 } 852 length += packet_get_data_length( next ); 853 free( last_header ); 881 854 header->flags |= IPFLAG_MORE_FRAGMENTS; 882 855 } 883 header->total_length = htons( length);856 header->total_length = htons( length ); 884 857 // unnecessary for all protocols 885 header->header_checksum = IP_HEADER_CHECKSUM( header);858 header->header_checksum = IP_HEADER_CHECKSUM( header ); 886 859 return EOK; 887 860 } 888 861 889 int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){862 int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ 890 863 ERROR_DECLARE; 891 864 892 packet_t 893 struct sockaddr * 894 size_t 895 ip_pseudo_header_ref 896 size_t 897 898 * answer_count = 0;899 switch( IPC_GET_METHOD(*call)){865 packet_t packet; 866 struct sockaddr * addr; 867 size_t addrlen; 868 ip_pseudo_header_ref header; 869 size_t headerlen; 870 871 * answer_count = 0; 872 switch( IPC_GET_METHOD( * call )){ 900 873 case IPC_M_PHONE_HUNGUP: 901 874 return EOK; 902 875 case NET_IL_DEVICE: 903 return ip_device_req( 0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call));876 return ip_device_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call )); 904 877 case IPC_M_CONNECT_TO_ME: 905 return ip_register( IL_GET_PROTO(call), IL_GET_SERVICE(call), IPC_GET_PHONE(call), NULL);878 return ip_register( IL_GET_PROTO( call ), IL_GET_SERVICE( call ), IPC_GET_PHONE( call ), NULL ); 906 879 case NET_IL_SEND: 907 ERROR_PROPAGATE( packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));908 return ip_send_msg( 0, IPC_GET_DEVICE(call), packet, 0, IPC_GET_ERROR(call));880 ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call ))); 881 return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0, IPC_GET_ERROR( call )); 909 882 case NET_IL_DEVICE_STATE: 910 return ip_device_state_message( IPC_GET_DEVICE(call), IPC_GET_STATE(call));883 return ip_device_state_message( IPC_GET_DEVICE( call ), IPC_GET_STATE( call )); 911 884 case NET_IL_RECEIVED: 912 ERROR_PROPAGATE( packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));913 return ip_receive_message( IPC_GET_DEVICE(call), packet);885 ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call ))); 886 return ip_receive_message( IPC_GET_DEVICE( call ), packet ); 914 887 case NET_IP_RECEIVED_ERROR: 915 ERROR_PROPAGATE( packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));916 return ip_received_error_msg( 0, IPC_GET_DEVICE(call), packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));888 ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call ))); 889 return ip_received_error_msg( 0, IPC_GET_DEVICE( call ), packet, IPC_GET_TARGET( call ), IPC_GET_ERROR( call )); 917 890 case NET_IP_ADD_ROUTE: 918 return ip_add_route_req( 0, IPC_GET_DEVICE(call), IP_GET_ADDRESS(call), IP_GET_NETMASK(call), IP_GET_GATEWAY(call));891 return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call )); 919 892 case NET_IP_SET_GATEWAY: 920 return ip_set_gateway_req( 0, IPC_GET_DEVICE(call), IP_GET_GATEWAY(call));893 return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call )); 921 894 case NET_IP_GET_ROUTE: 922 ERROR_PROPAGATE( data_receive((void **) &addr, &addrlen));923 ERROR_PROPAGATE( ip_get_route_req(0, IP_GET_PROTOCOL(call), addr, (socklen_t) addrlen, IPC_SET_DEVICE(answer), &header, &headerlen));924 * IP_SET_HEADERLEN(answer) = headerlen;925 * answer_count = 2;926 if( ! ERROR_OCCURRED(data_reply(&headerlen, sizeof(headerlen)))){927 ERROR_CODE = data_reply( header, headerlen);928 } 929 free( header);895 ERROR_PROPAGATE( data_receive(( void ** ) & addr, & addrlen )); 896 ERROR_PROPAGATE( ip_get_route_req( 0, IP_GET_PROTOCOL( call ), addr, ( socklen_t ) addrlen, IPC_SET_DEVICE( answer ), & header, & headerlen )); 897 * IP_SET_HEADERLEN( answer ) = headerlen; 898 * answer_count = 2; 899 if( ! ERROR_OCCURRED( data_reply( & headerlen, sizeof( headerlen )))){ 900 ERROR_CODE = data_reply( header, headerlen ); 901 } 902 free( header ); 930 903 return ERROR_CODE; 931 904 case NET_IL_PACKET_SPACE: 932 ERROR_PROPAGATE( ip_packet_size_message(IPC_GET_DEVICE(call), IPC_SET_ADDR(answer), IPC_SET_PREFIX(answer), IPC_SET_CONTENT(answer), IPC_SET_SUFFIX(answer)));933 * answer_count = 3;905 ERROR_PROPAGATE( ip_packet_size_message( IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer ))); 906 * answer_count = 3; 934 907 return EOK; 935 908 case NET_IL_MTU_CHANGED: 936 return ip_mtu_changed_message( IPC_GET_DEVICE(call), IPC_GET_MTU(call));909 return ip_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call )); 937 910 } 938 911 return ENOTSUP; 939 912 } 940 913 941 int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){ 942 if(! packet_dimension){ 943 return EBADMEM; 944 } 945 return ip_packet_size_message(device_id, &packet_dimension->addr_len, &packet_dimension->prefix, &packet_dimension->content, &packet_dimension->suffix); 946 } 947 948 int ip_packet_size_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){ 949 ip_netif_ref netif; 950 int index; 951 952 if(!(addr_len && prefix && content && suffix)){ 953 return EBADMEM; 954 } 955 *content = IP_MAX_CONTENT - IP_PREFIX; 956 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 957 if(device_id < 0){ 958 *addr_len = IP_ADDR; 959 *prefix = 0; 960 *suffix = 0; 961 for(index = ip_netifs_count(&ip_globals.netifs) - 1; index >= 0; -- index){ 962 netif = ip_netifs_get_index(&ip_globals.netifs, index); 963 if(netif){ 964 if(netif->packet_dimension.addr_len > * addr_len){ 965 *addr_len = netif->packet_dimension.addr_len; 966 } 967 if(netif->packet_dimension.prefix > * prefix){ 968 *prefix = netif->packet_dimension.prefix; 969 } 970 if(netif->packet_dimension.suffix > * suffix){ 971 *suffix = netif->packet_dimension.suffix; 972 } 973 } 974 } 975 *prefix = * prefix + IP_PREFIX; 976 *suffix = * suffix + IP_SUFFIX; 914 int ip_packet_size_req( int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension ){ 915 if( ! packet_dimension ) return EBADMEM; 916 return ip_packet_size_message( device_id, & packet_dimension->addr_len, & packet_dimension->prefix, & packet_dimension->content, & packet_dimension->suffix ); 917 } 918 919 int ip_packet_size_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ 920 ip_netif_ref netif; 921 int index; 922 923 if( !( addr_len && prefix && content && suffix )) return EBADMEM; 924 * content = IP_MAX_CONTENT - IP_PREFIX; 925 fibril_rwlock_read_lock( & ip_globals.netifs_lock ); 926 if( device_id < 0 ){ 927 * addr_len = IP_ADDR; 928 * prefix = 0; 929 * suffix = 0; 930 for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){ 931 netif = ip_netifs_get_index( & ip_globals.netifs, index ); 932 if( netif ){ 933 if( netif->packet_dimension.addr_len > * addr_len ) * addr_len = netif->packet_dimension.addr_len; 934 if( netif->packet_dimension.prefix > * prefix ) * prefix = netif->packet_dimension.prefix; 935 if( netif->packet_dimension.suffix > * suffix ) * suffix = netif->packet_dimension.suffix; 936 } 937 } 938 * prefix = * prefix + IP_PREFIX; 939 * suffix = * suffix + IP_SUFFIX; 977 940 }else{ 978 netif = ip_netifs_find( &ip_globals.netifs, device_id);979 if( ! netif){980 fibril_rwlock_read_unlock( &ip_globals.netifs_lock);941 netif = ip_netifs_find( & ip_globals.netifs, device_id ); 942 if( ! netif ){ 943 fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); 981 944 return ENOENT; 982 945 } 983 * addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ? netif->packet_dimension.addr_len : IP_ADDR;984 * prefix = netif->packet_dimension.prefix + IP_PREFIX;985 * suffix = netif->packet_dimension.suffix + IP_SUFFIX;986 } 987 fibril_rwlock_read_unlock( &ip_globals.netifs_lock);946 * addr_len = ( netif->packet_dimension.addr_len > IP_ADDR ) ? netif->packet_dimension.addr_len : IP_ADDR; 947 * prefix = netif->packet_dimension.prefix + IP_PREFIX; 948 * suffix = netif->packet_dimension.suffix + IP_SUFFIX; 949 } 950 fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); 988 951 return EOK; 989 952 } 990 953 991 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){992 ip_route_ref 993 ip_netif_ref 994 int 995 996 fibril_rwlock_write_lock( &ip_globals.netifs_lock);997 netif = ip_netifs_find( &ip_globals.netifs, device_id);998 if( ! netif){999 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);954 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 ){ 955 ip_route_ref route; 956 ip_netif_ref netif; 957 int index; 958 959 fibril_rwlock_write_lock( & ip_globals.netifs_lock ); 960 netif = ip_netifs_find( & ip_globals.netifs, device_id ); 961 if( ! netif ){ 962 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 1000 963 return ENOENT; 1001 964 } 1002 route = ( ip_route_ref) malloc(sizeof(ip_route_t));1003 if( ! route){1004 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);965 route = ( ip_route_ref ) malloc( sizeof( ip_route_t )); 966 if( ! route ){ 967 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 1005 968 return ENOMEM; 1006 969 } … … 1009 972 route->gateway.s_addr = gateway.s_addr; 1010 973 route->netif = netif; 1011 index = ip_routes_add(&netif->routes, route); 1012 if(index < 0){ 1013 free(route); 1014 } 1015 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 974 index = ip_routes_add( & netif->routes, route ); 975 if( index < 0 ) free( route ); 976 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 1016 977 return index; 1017 978 } 1018 979 1019 ip_route_ref ip_find_route( in_addr_t destination){1020 int 1021 ip_route_ref 1022 ip_netif_ref 980 ip_route_ref ip_find_route( in_addr_t destination ){ 981 int index; 982 ip_route_ref route; 983 ip_netif_ref netif; 1023 984 1024 985 // start with the last netif - the newest one 1025 index = ip_netifs_count(&ip_globals.netifs) - 1; 1026 while(index >= 0){ 1027 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1028 if(netif && (netif->state == NETIF_ACTIVE)){ 1029 route = ip_netif_find_route(netif, destination); 1030 if(route){ 986 index = ip_netifs_count( & ip_globals.netifs ) - 1; 987 while( index >= 0 ){ 988 netif = ip_netifs_get_index( & ip_globals.netifs, index ); 989 if( netif && ( netif->state == NETIF_ACTIVE )){ 990 route = ip_netif_find_route( netif, destination ); 991 if( route ) return route; 992 } 993 -- index; 994 } 995 return & ip_globals.gateway; 996 } 997 998 ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ){ 999 int index; 1000 ip_route_ref route; 1001 1002 if( netif ){ 1003 // start with the first one - the direct route 1004 for( index = 0; index < ip_routes_count( & netif->routes ); ++ index ){ 1005 route = ip_routes_get_index( & netif->routes, index ); 1006 if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( destination.s_addr & route->netmask.s_addr ))){ 1031 1007 return route; 1032 1008 } 1033 1009 } 1034 -- index;1035 }1036 return &ip_globals.gateway;1037 }1038 1039 ip_route_ref ip_netif_find_route(ip_netif_ref netif, in_addr_t destination){1040 int index;1041 ip_route_ref route;1042 1043 if(netif){1044 // start with the first one - the direct route1045 for(index = 0; index < ip_routes_count(&netif->routes); ++ index){1046 route = ip_routes_get_index(&netif->routes, index);1047 if(route && ((route->address.s_addr &route->netmask.s_addr) == (destination.s_addr &route->netmask.s_addr))){1048 return route;1049 }1050 }1051 1010 } 1052 1011 return NULL; 1053 1012 } 1054 1013 1055 int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway){1056 ip_netif_ref 1057 1058 fibril_rwlock_write_lock( &ip_globals.netifs_lock);1059 netif = ip_netifs_find( &ip_globals.netifs, device_id);1060 if( ! netif){1061 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);1014 int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){ 1015 ip_netif_ref netif; 1016 1017 fibril_rwlock_write_lock( & ip_globals.netifs_lock ); 1018 netif = ip_netifs_find( & ip_globals.netifs, device_id ); 1019 if( ! netif ){ 1020 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 1062 1021 return ENOENT; 1063 1022 } … … 1066 1025 ip_globals.gateway.gateway.s_addr = gateway.s_addr; 1067 1026 ip_globals.gateway.netif = netif; 1068 fibril_rwlock_write_unlock( &ip_globals.netifs_lock);1027 fibril_rwlock_write_unlock( & ip_globals.netifs_lock ); 1069 1028 return EOK; 1070 1029 } 1071 1030 1072 packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error){1073 size_t 1074 packet_t 1075 packet_t 1076 int 1077 int 1031 packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error ){ 1032 size_t length; 1033 packet_t next; 1034 packet_t new_packet; 1035 int result; 1036 int phone; 1078 1037 1079 1038 next = packet; 1080 1039 // check all packets 1081 while( next){1082 length = packet_get_data_length( next);1040 while( next ){ 1041 length = packet_get_data_length( next ); 1083 1042 // too long? 1084 if( length > content){1085 result = ip_fragment_packet( next, content, prefix, suffix, addr_len);1086 if( result != EOK){1087 new_packet = pq_detach( next);1088 if( next == packet){1043 if( length > content ){ 1044 result = ip_fragment_packet( next, content, prefix, suffix, addr_len ); 1045 if( result != EOK ){ 1046 new_packet = pq_detach( next ); 1047 if( next == packet ){ 1089 1048 // the new first packet of the queue 1090 1049 packet = new_packet; 1091 1050 } 1092 1051 // fragmentation needed? 1093 if( result == EPERM){1094 phone = ip_prepare_icmp_and_get_phone( error, next, NULL);1095 if( phone >= 0){1052 if( result == EPERM ){ 1053 phone = ip_prepare_icmp_and_get_phone( error, next, NULL ); 1054 if( phone >= 0 ){ 1096 1055 // fragmentation necessary ICMP 1097 icmp_destination_unreachable_msg( phone, ICMP_FRAG_NEEDED, content, next);1056 icmp_destination_unreachable_msg( phone, ICMP_FRAG_NEEDED, content, next ); 1098 1057 } 1099 1058 }else{ 1100 pq_release( ip_globals.net_phone, packet_get_id(next));1059 pq_release( ip_globals.net_phone, packet_get_id( next )); 1101 1060 } 1102 1061 next = new_packet; … … 1104 1063 } 1105 1064 } 1106 next = pq_next( next);1065 next = pq_next( next ); 1107 1066 } 1108 1067 return packet; 1109 1068 } 1110 1069 1111 int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len){1070 int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len ){ 1112 1071 ERROR_DECLARE; 1113 1072 1114 packet_t new_packet; 1115 ip_header_ref header; 1116 ip_header_ref middle_header; 1117 ip_header_ref last_header; 1118 struct sockaddr * src; 1119 struct sockaddr * dest; 1120 socklen_t addrlen; 1121 int result; 1122 1123 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest); 1124 if(result <= 0){ 1125 return EINVAL; 1126 } 1127 addrlen = (socklen_t) result; 1128 if(packet_get_data_length(packet) <= sizeof(ip_header_t)){ 1129 return ENOMEM; 1130 } 1073 packet_t new_packet; 1074 ip_header_ref header; 1075 ip_header_ref middle_header; 1076 ip_header_ref last_header; 1077 struct sockaddr * src; 1078 struct sockaddr * dest; 1079 socklen_t addrlen; 1080 int result; 1081 1082 result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest ); 1083 if( result <= 0 ) return EINVAL; 1084 addrlen = ( socklen_t ) result; 1085 if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM; 1131 1086 // get header 1132 header = (ip_header_ref) packet_get_data(packet); 1133 if(! header){ 1134 return EINVAL; 1135 } 1087 header = ( ip_header_ref ) packet_get_data( packet ); 1088 if( ! header ) return EINVAL; 1136 1089 // fragmentation forbidden? 1137 if( header->flags &IPFLAG_DONT_FRAGMENT){1090 if( header->flags & IPFLAG_DONT_FRAGMENT ){ 1138 1091 return EPERM; 1139 1092 } 1140 1093 // create the last fragment 1141 new_packet = packet_get_4(ip_globals.net_phone, prefix, length, suffix, ((addrlen > addr_len) ? addrlen : addr_len)); 1142 if(! new_packet){ 1143 return ENOMEM; 1144 } 1094 new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen > addr_len ) ? addrlen : addr_len )); 1095 if( ! new_packet ) return ENOMEM; 1145 1096 // allocate as much as originally 1146 last_header = ( ip_header_ref) packet_suffix(new_packet, IP_HEADER_LENGTH(header));1147 if( ! last_header){1148 return ip_release_and_return( packet, ENOMEM);1149 } 1150 ip_create_last_header( last_header, header);1097 last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header )); 1098 if( ! last_header ){ 1099 return ip_release_and_return( packet, ENOMEM ); 1100 } 1101 ip_create_last_header( last_header, header ); 1151 1102 // trim the unused space 1152 if( ERROR_OCCURRED(packet_trim(new_packet, 0, IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)))){1153 return ip_release_and_return( packet, ERROR_CODE);1103 if( ERROR_OCCURRED( packet_trim( new_packet, 0, IP_HEADER_LENGTH( header ) - IP_HEADER_LENGTH( last_header )))){ 1104 return ip_release_and_return( packet, ERROR_CODE ); 1154 1105 } 1155 1106 // biggest multiple of 8 lower than content 1156 1107 // TODO even fragmentation? 1157 length = length & (~ 0x7);// (content / 8) * 81158 if( ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header, last_header, ((IP_HEADER_DATA_LENGTH(header) - ((length - IP_HEADER_LENGTH(header)) &(~ 0x7))) % ((length - IP_HEADER_LENGTH(last_header)) &(~ 0x7))), src, dest, addrlen))){1159 return ip_release_and_return( packet, ERROR_CODE);1108 length = length & ( ~ 0x7 );// ( content / 8 ) * 8 1109 if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, last_header, (( IP_HEADER_DATA_LENGTH( header ) - (( length - IP_HEADER_LENGTH( header )) & ( ~ 0x7 ))) % (( length - IP_HEADER_LENGTH( last_header )) & ( ~ 0x7 ))), src, dest, addrlen ))){ 1110 return ip_release_and_return( packet, ERROR_CODE ); 1160 1111 } 1161 1112 // mark the first as fragmented 1162 1113 header->flags |= IPFLAG_MORE_FRAGMENTS; 1163 1114 // create middle framgents 1164 while(IP_TOTAL_LENGTH(header) > length){ 1165 new_packet = packet_get_4(ip_globals.net_phone, prefix, length, suffix, ((addrlen >= addr_len) ? addrlen : addr_len)); 1166 if(! new_packet){ 1167 return ENOMEM; 1168 } 1169 middle_header = ip_create_middle_header(new_packet, last_header); 1170 if(! middle_header){ 1171 return ip_release_and_return(packet, ENOMEM); 1172 } 1173 if(ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header, middle_header, (length - IP_HEADER_LENGTH(middle_header)) &(~ 0x7), src, dest, addrlen))){ 1174 return ip_release_and_return(packet, ERROR_CODE); 1115 while( IP_TOTAL_LENGTH( header ) > length ){ 1116 new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen >= addr_len ) ? addrlen : addr_len )); 1117 if( ! new_packet ) return ENOMEM; 1118 middle_header = ip_create_middle_header( new_packet, last_header ); 1119 if( ! middle_header ){ 1120 return ip_release_and_return( packet, ENOMEM ); 1121 } 1122 if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, ( length - IP_HEADER_LENGTH( middle_header )) & ( ~ 0x7 ), src, dest, addrlen ))){ 1123 return ip_release_and_return( packet, ERROR_CODE ); 1175 1124 } 1176 1125 } 1177 1126 // finish the first fragment 1178 header->header_checksum = IP_HEADER_CHECKSUM( header);1127 header->header_checksum = IP_HEADER_CHECKSUM( header ); 1179 1128 return EOK; 1180 1129 } 1181 1130 1182 int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen){1131 int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen ){ 1183 1132 ERROR_DECLARE; 1184 1133 1185 void * data; 1186 size_t offset; 1187 1188 data = packet_suffix(new_packet, length); 1189 if(! data){ 1190 return ENOMEM; 1191 } 1192 memcpy(data, ((void *) header) + IP_TOTAL_LENGTH(header) - length, length); 1193 ERROR_PROPAGATE(packet_trim(packet, 0, length)); 1194 header->total_length = htons(IP_TOTAL_LENGTH(header) - length); 1195 new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length); 1196 offset = IP_FRAGMENT_OFFSET(header) + IP_HEADER_DATA_LENGTH(header); 1197 new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset); 1198 new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset); 1199 new_header->header_checksum = IP_HEADER_CHECKSUM(new_header); 1200 ERROR_PROPAGATE(packet_set_addr(new_packet, (const uint8_t *) src, (const uint8_t *) dest, addrlen)); 1201 return pq_insert_after(packet, new_packet); 1202 } 1203 1204 ip_header_ref ip_create_middle_header(packet_t packet, ip_header_ref last){ 1205 ip_header_ref middle; 1206 1207 middle = (ip_header_ref) packet_suffix(packet, IP_HEADER_LENGTH(last)); 1208 if(! middle){ 1209 return NULL; 1210 } 1211 memcpy(middle, last, IP_HEADER_LENGTH(last)); 1134 void * data; 1135 size_t offset; 1136 1137 data = packet_suffix( new_packet, length ); 1138 if( ! data ) return ENOMEM; 1139 memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length ); 1140 ERROR_PROPAGATE( packet_trim( packet, 0, length )); 1141 header->total_length = htons( IP_TOTAL_LENGTH( header ) - length ); 1142 new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length ); 1143 offset = IP_FRAGMENT_OFFSET( header ) + IP_HEADER_DATA_LENGTH( header ); 1144 new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( offset ); 1145 new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( offset ); 1146 new_header->header_checksum = IP_HEADER_CHECKSUM( new_header ); 1147 ERROR_PROPAGATE( packet_set_addr( new_packet, ( const uint8_t * ) src, ( const uint8_t * ) dest, addrlen )); 1148 return pq_insert_after( packet, new_packet ); 1149 } 1150 1151 ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){ 1152 ip_header_ref middle; 1153 1154 middle = ( ip_header_ref ) packet_suffix( packet, IP_HEADER_LENGTH( last )); 1155 if( ! middle ) return NULL; 1156 memcpy( middle, last, IP_HEADER_LENGTH( last )); 1212 1157 middle->flags |= IPFLAG_MORE_FRAGMENTS; 1213 1158 return middle; 1214 1159 } 1215 1160 1216 void ip_create_last_header( ip_header_ref last, ip_header_ref first){1217 ip_option_ref 1218 size_t 1219 size_t 1161 void ip_create_last_header( ip_header_ref last, ip_header_ref first ){ 1162 ip_option_ref option; 1163 size_t next; 1164 size_t length; 1220 1165 1221 1166 // copy first itself 1222 memcpy( last, first, sizeof(ip_header_t));1223 length = sizeof( ip_header_t);1224 next = sizeof( ip_header_t);1167 memcpy( last, first, sizeof( ip_header_t )); 1168 length = sizeof( ip_header_t ); 1169 next = sizeof( ip_header_t ); 1225 1170 // process all ip options 1226 while( next < first->header_length){1227 option = ( ip_option_ref) (((uint8_t *) first) + next);1171 while( next < first->header_length ){ 1172 option = ( ip_option_ref ) ((( uint8_t * ) first ) + next ); 1228 1173 // skip end or noop 1229 if(( option->type == IPOPT_END) || (option->type == IPOPT_NOOP)){1174 if(( option->type == IPOPT_END ) || ( option->type == IPOPT_NOOP )){ 1230 1175 ++ next; 1231 1176 }else{ 1232 1177 // copy if said so or skip 1233 if( IPOPT_COPIED(option->type)){1234 memcpy((( uint8_t *) last) + length, ((uint8_t *) first) + next, option->length);1178 if( IPOPT_COPIED( option->type )){ 1179 memcpy((( uint8_t * ) last ) + length, (( uint8_t * ) first ) + next, option->length ); 1235 1180 length += option->length; 1236 1181 } … … 1240 1185 } 1241 1186 // align 4 byte boundary 1242 if( length % 4){1243 bzero((( uint8_t *) last) + length, 4 - (length % 4));1187 if( length % 4 ){ 1188 bzero((( uint8_t * ) last ) + length, 4 - ( length % 4 )); 1244 1189 last->header_length = length / 4 + 1; 1245 1190 }else{ … … 1249 1194 } 1250 1195 1251 int ip_receive_message( device_id_t device_id, packet_t packet){1252 packet_t 1196 int ip_receive_message( device_id_t device_id, packet_t packet ){ 1197 packet_t next; 1253 1198 1254 1199 do{ 1255 next = pq_detach( packet);1256 ip_process_packet( device_id, packet);1200 next = pq_detach( packet ); 1201 ip_process_packet( device_id, packet ); 1257 1202 packet = next; 1258 }while( packet);1203 }while( packet ); 1259 1204 return EOK; 1260 1205 } 1261 1206 1262 int ip_process_packet( device_id_t device_id, packet_t packet){1207 int ip_process_packet( device_id_t device_id, packet_t packet ){ 1263 1208 ERROR_DECLARE; 1264 1209 1265 ip_header_ref 1266 in_addr_t 1267 ip_route_ref 1268 int 1269 struct sockaddr * 1270 struct sockaddr_in 1210 ip_header_ref header; 1211 in_addr_t dest; 1212 ip_route_ref route; 1213 int phone; 1214 struct sockaddr * addr; 1215 struct sockaddr_in addr_in; 1271 1216 // struct sockaddr_in addr_in6; 1272 socklen_t 1273 1274 header = ( ip_header_ref) packet_get_data(packet);1275 if( ! header){1276 return ip_release_and_return( packet, ENOMEM);1217 socklen_t addrlen; 1218 1219 header = ( ip_header_ref ) packet_get_data( packet ); 1220 if( ! header ){ 1221 return ip_release_and_return( packet, ENOMEM ); 1277 1222 } 1278 1223 // checksum 1279 if(( header->header_checksum) && (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)){1280 phone = ip_prepare_icmp_and_get_phone( 0, packet, header);1281 if( phone >= 0){1224 if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ) != IP_CHECKSUM_ZERO )){ 1225 phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); 1226 if( phone >= 0 ){ 1282 1227 // checksum error ICMP 1283 icmp_parameter_problem_msg( phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->header_checksum)) - ((size_t) ((void *) header)), packet);1228 icmp_parameter_problem_msg( phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->header_checksum )) - (( size_t ) (( void * ) header )), packet ); 1284 1229 } 1285 1230 return EINVAL; 1286 1231 } 1287 if( header->ttl <= 1){1288 phone = ip_prepare_icmp_and_get_phone( 0, packet, header);1289 if( phone >= 0){1232 if( header->ttl <= 1 ){ 1233 phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); 1234 if( phone >= 0 ){ 1290 1235 // ttl oxceeded ICMP 1291 icmp_time_exceeded_msg( phone, ICMP_EXC_TTL, packet);1236 icmp_time_exceeded_msg( phone, ICMP_EXC_TTL, packet ); 1292 1237 } 1293 1238 return EINVAL; 1294 1239 } 1295 1240 // process ipopt and get destination 1296 dest = ip_get_destination( header);1241 dest = ip_get_destination( header ); 1297 1242 // set the addrination address 1298 switch( header->version){1243 switch( header->version ){ 1299 1244 case IPVERSION: 1300 addrlen = sizeof( addr_in);1301 bzero( &addr_in, addrlen);1245 addrlen = sizeof( addr_in ); 1246 bzero( & addr_in, addrlen ); 1302 1247 addr_in.sin_family = AF_INET; 1303 memcpy( &addr_in.sin_addr.s_addr, &dest, sizeof(dest));1304 addr = ( struct sockaddr *) &addr_in;1248 memcpy( & addr_in.sin_addr.s_addr, & dest, sizeof( dest )); 1249 addr = ( struct sockaddr * ) & addr_in; 1305 1250 break; 1306 1251 /* case IPv6VERSION: 1307 addrlen = sizeof( dest_in6);1308 bzero( &dest_in6, addrlen);1252 addrlen = sizeof( dest_in6 ); 1253 bzero( & dest_in6, addrlen ); 1309 1254 dest_in6.sin6_family = AF_INET6; 1310 memcpy( &dest_in6.sin6_addr.s6_addr,);1311 dest = ( struct sockaddr *) &dest_in;1255 memcpy( & dest_in6.sin6_addr.s6_addr, ); 1256 dest = ( struct sockaddr * ) & dest_in; 1312 1257 break; 1313 1258 */ default: 1314 return ip_release_and_return( packet, EAFNOSUPPORT);1315 } 1316 ERROR_PROPAGATE( packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen));1317 route = ip_find_route( dest);1318 if( ! route){1319 phone = ip_prepare_icmp_and_get_phone( 0, packet, header);1320 if( phone >= 0){1259 return ip_release_and_return( packet, EAFNOSUPPORT ); 1260 } 1261 ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & addr, addrlen )); 1262 route = ip_find_route( dest ); 1263 if( ! route ){ 1264 phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); 1265 if( phone >= 0 ){ 1321 1266 // unreachable ICMP 1322 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet);1267 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet ); 1323 1268 } 1324 1269 return ENOENT; 1325 1270 } 1326 if( route->address.s_addr == dest.s_addr){1271 if( route->address.s_addr == dest.s_addr ){ 1327 1272 // local delivery 1328 return ip_deliver_local( device_id, packet, header, 0);1273 return ip_deliver_local( device_id, packet, header, 0 ); 1329 1274 }else{ 1330 1275 // only if routing enabled 1331 if( route->netif->routing){1276 if( route->netif->routing ){ 1332 1277 -- header->ttl; 1333 return ip_send_route( packet, route->netif, route, NULL, dest, 0);1278 return ip_send_route( packet, route->netif, route, NULL, dest, 0 ); 1334 1279 }else{ 1335 phone = ip_prepare_icmp_and_get_phone( 0, packet, header);1336 if( phone >= 0){1280 phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); 1281 if( phone >= 0 ){ 1337 1282 // unreachable ICMP if no routing 1338 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet);1283 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet ); 1339 1284 } 1340 1285 return ENOENT; … … 1343 1288 } 1344 1289 1345 int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){1346 uint8_t * 1347 int 1348 icmp_type_t 1349 icmp_code_t 1350 ip_netif_ref 1351 measured_string_t 1352 ip_route_ref 1353 ip_header_ref 1354 1355 switch( error){1290 int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error ){ 1291 uint8_t * data; 1292 int offset; 1293 icmp_type_t type; 1294 icmp_code_t code; 1295 ip_netif_ref netif; 1296 measured_string_t address; 1297 ip_route_ref route; 1298 ip_header_ref header; 1299 1300 switch( error ){ 1356 1301 case SERVICE_ICMP: 1357 offset = icmp_client_process_packet( packet, &type, &code, NULL, NULL);1358 if( offset < 0){1359 return ip_release_and_return( packet, ENOMEM);1360 } 1361 data = packet_get_data( packet);1362 header = ( ip_header_ref)(data + offset);1302 offset = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); 1303 if( offset < 0 ){ 1304 return ip_release_and_return( packet, ENOMEM ); 1305 } 1306 data = packet_get_data( packet ); 1307 header = ( ip_header_ref )( data + offset ); 1363 1308 // destination host unreachable? 1364 if(( type == ICMP_DEST_UNREACH) && (code == ICMP_HOST_UNREACH)){1365 fibril_rwlock_read_lock( &ip_globals.netifs_lock);1366 netif = ip_netifs_find( &ip_globals.netifs, device_id);1367 if( netif && netif->arp){1368 route = ip_routes_get_index( &netif->routes, 0);1309 if(( type == ICMP_DEST_UNREACH ) && ( code == ICMP_HOST_UNREACH )){ 1310 fibril_rwlock_read_lock( & ip_globals.netifs_lock ); 1311 netif = ip_netifs_find( & ip_globals.netifs, device_id ); 1312 if( netif && netif->arp ){ 1313 route = ip_routes_get_index( & netif->routes, 0 ); 1369 1314 // from the same network? 1370 if( route && ((route->address.s_addr &route->netmask.s_addr) == (header->destination_address &route->netmask.s_addr))){1315 if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( header->destination_address & route->netmask.s_addr ))){ 1371 1316 // clear the ARP mapping if any 1372 address.value = ( char *) &header->destination_address;1373 address.length = CONVERT_SIZE( uint8_t, char, sizeof(header->destination_address));1374 arp_clear_address_req( netif->arp->phone, netif->device_id, SERVICE_IP, &address);1317 address.value = ( char * ) & header->destination_address; 1318 address.length = CONVERT_SIZE( uint8_t, char, sizeof( header->destination_address )); 1319 arp_clear_address_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address ); 1375 1320 } 1376 1321 } 1377 fibril_rwlock_read_unlock( &ip_globals.netifs_lock);1322 fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); 1378 1323 } 1379 1324 break; 1380 1325 default: 1381 return ip_release_and_return( packet, ENOTSUP);1382 } 1383 return ip_deliver_local( device_id, packet, header, error);1384 } 1385 1386 int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error){1326 return ip_release_and_return( packet, ENOTSUP ); 1327 } 1328 return ip_deliver_local( device_id, packet, header, error ); 1329 } 1330 1331 int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ){ 1387 1332 ERROR_DECLARE; 1388 1333 1389 ip_proto_ref 1390 int 1391 services_t 1392 tl_received_msg_t 1393 struct sockaddr * 1394 struct sockaddr * 1395 struct sockaddr_in 1396 struct sockaddr_in 1334 ip_proto_ref proto; 1335 int phone; 1336 services_t service; 1337 tl_received_msg_t received_msg; 1338 struct sockaddr * src; 1339 struct sockaddr * dest; 1340 struct sockaddr_in src_in; 1341 struct sockaddr_in dest_in; 1397 1342 // struct sockaddr_in src_in6; 1398 1343 // struct sockaddr_in dest_in6; 1399 socklen_t 1400 1401 if(( header->flags &IPFLAG_MORE_FRAGMENTS) || IP_FRAGMENT_OFFSET(header)){1344 socklen_t addrlen; 1345 1346 if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || IP_FRAGMENT_OFFSET( header )){ 1402 1347 // TODO fragmented 1403 1348 return ENOTSUP; 1404 1349 }else{ 1405 switch( header->version){1350 switch( header->version ){ 1406 1351 case IPVERSION: 1407 addrlen = sizeof( src_in);1408 bzero( &src_in, addrlen);1352 addrlen = sizeof( src_in ); 1353 bzero( & src_in, addrlen ); 1409 1354 src_in.sin_family = AF_INET; 1410 memcpy( &dest_in, &src_in, addrlen);1411 memcpy( &src_in.sin_addr.s_addr, &header->source_address, sizeof(header->source_address));1412 memcpy( &dest_in.sin_addr.s_addr, &header->destination_address, sizeof(header->destination_address));1413 src = ( struct sockaddr *) &src_in;1414 dest = ( struct sockaddr *) &dest_in;1355 memcpy( & dest_in, & src_in, addrlen ); 1356 memcpy( & src_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address )); 1357 memcpy( & dest_in.sin_addr.s_addr, & header->destination_address, sizeof( header->destination_address )); 1358 src = ( struct sockaddr * ) & src_in; 1359 dest = ( struct sockaddr * ) & dest_in; 1415 1360 break; 1416 1361 /* case IPv6VERSION: 1417 addrlen = sizeof( src_in6);1418 bzero( &src_in6, addrlen);1362 addrlen = sizeof( src_in6 ); 1363 bzero( & src_in6, addrlen ); 1419 1364 src_in6.sin6_family = AF_INET6; 1420 memcpy( &dest_in6, &src_in6, addrlen);1421 memcpy( &src_in6.sin6_addr.s6_addr,);1422 memcpy( &dest_in6.sin6_addr.s6_addr,);1423 src = ( struct sockaddr *) &src_in;1424 dest = ( struct sockaddr *) &dest_in;1365 memcpy( & dest_in6, & src_in6, addrlen ); 1366 memcpy( & src_in6.sin6_addr.s6_addr, ); 1367 memcpy( & dest_in6.sin6_addr.s6_addr, ); 1368 src = ( struct sockaddr * ) & src_in; 1369 dest = ( struct sockaddr * ) & dest_in; 1425 1370 break; 1426 1371 */ default: 1427 return ip_release_and_return( packet, EAFNOSUPPORT);1428 } 1429 if( ERROR_OCCURRED(packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, addrlen))){1430 return ip_release_and_return( packet, ERROR_CODE);1372 return ip_release_and_return( packet, EAFNOSUPPORT ); 1373 } 1374 if( ERROR_OCCURRED( packet_set_addr( packet, ( uint8_t * ) src, ( uint8_t * ) dest, addrlen ))){ 1375 return ip_release_and_return( packet, ERROR_CODE ); 1431 1376 } 1432 1377 // trim padding if present 1433 if(( ! error) && (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))){1434 if( ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)))){1435 return ip_release_and_return( packet, ERROR_CODE);1436 } 1437 } 1438 fibril_rwlock_read_lock( &ip_globals.protos_lock);1439 proto = ip_protos_find( &ip_globals.protos, header->protocol);1440 if( ! proto){1441 fibril_rwlock_read_unlock( &ip_globals.protos_lock);1442 phone = ip_prepare_icmp_and_get_phone( error, packet, header);1443 if( phone >= 0){1378 if(( ! error ) && ( IP_TOTAL_LENGTH( header ) < packet_get_data_length( packet ))){ 1379 if( ERROR_OCCURRED( packet_trim( packet, 0, packet_get_data_length( packet ) - IP_TOTAL_LENGTH( header )))){ 1380 return ip_release_and_return( packet, ERROR_CODE ); 1381 } 1382 } 1383 fibril_rwlock_read_lock( & ip_globals.protos_lock ); 1384 proto = ip_protos_find( & ip_globals.protos, header->protocol ); 1385 if( ! proto ){ 1386 fibril_rwlock_read_unlock( & ip_globals.protos_lock ); 1387 phone = ip_prepare_icmp_and_get_phone( error, packet, header ); 1388 if( phone >= 0 ){ 1444 1389 // unreachable ICMP 1445 icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet);1390 icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet ); 1446 1391 } 1447 1392 return ENOENT; 1448 1393 } 1449 if( proto->received_msg){1394 if( proto->received_msg ){ 1450 1395 service = proto->service; 1451 1396 received_msg = proto->received_msg; 1452 fibril_rwlock_read_unlock( &ip_globals.protos_lock);1453 ERROR_CODE = received_msg( device_id, packet, service, error);1397 fibril_rwlock_read_unlock( & ip_globals.protos_lock ); 1398 ERROR_CODE = received_msg( device_id, packet, service, error ); 1454 1399 }else{ 1455 ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error);1456 fibril_rwlock_read_unlock( &ip_globals.protos_lock);1400 ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error ); 1401 fibril_rwlock_read_unlock( & ip_globals.protos_lock ); 1457 1402 } 1458 1403 return ERROR_CODE; … … 1460 1405 } 1461 1406 1462 in_addr_t ip_get_destination( ip_header_ref header){1463 in_addr_t 1407 in_addr_t ip_get_destination( ip_header_ref header ){ 1408 in_addr_t destination; 1464 1409 1465 1410 // TODO search set ipopt route? … … 1468 1413 } 1469 1414 1470 int ip_prepare_icmp( packet_t packet, ip_header_ref header){1471 packet_t 1472 struct sockaddr * 1473 struct sockaddr_in 1415 int ip_prepare_icmp( packet_t packet, ip_header_ref header ){ 1416 packet_t next; 1417 struct sockaddr * dest; 1418 struct sockaddr_in dest_in; 1474 1419 // struct sockaddr_in dest_in6; 1475 socklen_t 1420 socklen_t addrlen; 1476 1421 1477 1422 // detach the first packet and release the others 1478 next = pq_detach(packet); 1479 if(next){ 1480 pq_release(ip_globals.net_phone, packet_get_id(next)); 1481 } 1482 if(! header){ 1483 if(packet_get_data_length(packet) <= sizeof(ip_header_t)){ 1484 return ENOMEM; 1485 } 1423 next = pq_detach( packet ); 1424 if( next ){ 1425 pq_release( ip_globals.net_phone, packet_get_id( next )); 1426 } 1427 if( ! header ){ 1428 if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM; 1486 1429 // get header 1487 header = (ip_header_ref) packet_get_data(packet); 1488 if(! header){ 1489 return EINVAL; 1490 } 1430 header = ( ip_header_ref ) packet_get_data( packet ); 1431 if( ! header ) return EINVAL; 1491 1432 } 1492 1433 // only for the first fragment 1493 if(IP_FRAGMENT_OFFSET(header)){ 1494 return EINVAL; 1495 } 1434 if( IP_FRAGMENT_OFFSET( header )) return EINVAL; 1496 1435 // not for the ICMP protocol 1497 if( header->protocol == IPPROTO_ICMP){1436 if( header->protocol == IPPROTO_ICMP ){ 1498 1437 return EPERM; 1499 1438 } 1500 1439 // set the destination address 1501 switch( header->version){1440 switch( header->version ){ 1502 1441 case IPVERSION: 1503 addrlen = sizeof( dest_in);1504 bzero( &dest_in, addrlen);1442 addrlen = sizeof( dest_in ); 1443 bzero( & dest_in, addrlen ); 1505 1444 dest_in.sin_family = AF_INET; 1506 memcpy( &dest_in.sin_addr.s_addr, &header->source_address, sizeof(header->source_address));1507 dest = ( struct sockaddr *) &dest_in;1445 memcpy( & dest_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address )); 1446 dest = ( struct sockaddr * ) & dest_in; 1508 1447 break; 1509 1448 /* case IPv6VERSION: 1510 addrlen = sizeof( dest_in6);1511 bzero( &dest_in6, addrlen);1449 addrlen = sizeof( dest_in6 ); 1450 bzero( & dest_in6, addrlen ); 1512 1451 dest_in6.sin6_family = AF_INET6; 1513 memcpy( &dest_in6.sin6_addr.s6_addr,);1514 dest = ( struct sockaddr *) &dest_in;1452 memcpy( & dest_in6.sin6_addr.s6_addr, ); 1453 dest = ( struct sockaddr * ) & dest_in; 1515 1454 break; 1516 1455 */ default: 1517 1456 return EAFNOSUPPORT; 1518 1457 } 1519 return packet_set_addr( packet, NULL, (uint8_t *) dest, addrlen);1520 } 1521 1522 int ip_get_icmp_phone( void){1523 ip_proto_ref 1524 int 1525 1526 fibril_rwlock_read_lock( &ip_globals.protos_lock);1527 proto = ip_protos_find( &ip_globals.protos, IPPROTO_ICMP);1458 return packet_set_addr( packet, NULL, ( uint8_t * ) dest, addrlen ); 1459 } 1460 1461 int ip_get_icmp_phone( void ){ 1462 ip_proto_ref proto; 1463 int phone; 1464 1465 fibril_rwlock_read_lock( & ip_globals.protos_lock ); 1466 proto = ip_protos_find( & ip_globals.protos, IPPROTO_ICMP ); 1528 1467 phone = proto ? proto->phone : ENOENT; 1529 fibril_rwlock_read_unlock( &ip_globals.protos_lock);1468 fibril_rwlock_read_unlock( & ip_globals.protos_lock ); 1530 1469 return phone; 1531 1470 } 1532 1471 1533 int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header){1534 int 1472 int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ){ 1473 int phone; 1535 1474 1536 1475 phone = ip_get_icmp_phone(); 1537 if( error || (phone < 0) || ip_prepare_icmp(packet, header)){1538 return ip_release_and_return( packet, EINVAL);1476 if( error || ( phone < 0 ) || ip_prepare_icmp( packet, header )){ 1477 return ip_release_and_return( packet, EINVAL ); 1539 1478 } 1540 1479 return phone; 1541 1480 } 1542 1481 1543 int ip_release_and_return(packet_t packet, int result){1544 pq_release( ip_globals.net_phone, packet_get_id(packet));1482 int ip_release_and_return( packet_t packet, int result ){ 1483 pq_release( ip_globals.net_phone, packet_get_id( packet )); 1545 1484 return result; 1546 1485 } 1547 1486 1548 int ip_get_route_req( int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen){1549 struct sockaddr_in * 1487 int ip_get_route_req( int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen ){ 1488 struct sockaddr_in * address_in; 1550 1489 // struct sockaddr_in6 * address_in6; 1551 in_addr_t * dest; 1552 in_addr_t * src; 1553 ip_route_ref route; 1554 ipv4_pseudo_header_ref header_in; 1555 1556 if(!(destination && (addrlen > 0))){ 1490 in_addr_t * dest; 1491 in_addr_t * src; 1492 ip_route_ref route; 1493 ipv4_pseudo_header_ref header_in; 1494 1495 if( !( destination && ( addrlen > 0 ))) return EINVAL; 1496 if( !( device_id && header && headerlen )) return EBADMEM; 1497 if(( size_t ) addrlen < sizeof( struct sockaddr )){ 1557 1498 return EINVAL; 1558 1499 } 1559 if(!(device_id && header && headerlen)){ 1560 return EBADMEM; 1561 } 1562 if((size_t) addrlen < sizeof(struct sockaddr)){ 1563 return EINVAL; 1564 } 1565 switch(destination->sa_family){ 1500 switch( destination->sa_family ){ 1566 1501 case AF_INET: 1567 if( addrlen != sizeof(struct sockaddr_in)){1502 if( addrlen != sizeof( struct sockaddr_in )){ 1568 1503 return EINVAL; 1569 1504 } 1570 address_in = ( struct sockaddr_in *) destination;1571 dest = & address_in->sin_addr;1572 if( ! dest->s_addr){1505 address_in = ( struct sockaddr_in * ) destination; 1506 dest = & address_in->sin_addr; 1507 if( ! dest->s_addr ){ 1573 1508 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1574 1509 } … … 1576 1511 // TODO IPv6 1577 1512 /* case AF_INET6: 1578 if(addrlen != sizeof(struct sockaddr_in6)){ 1579 return EINVAL; 1580 } 1581 address_in6 = (struct sockaddr_in6 *) dest; 1513 if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; 1514 address_in6 = ( struct sockaddr_in6 * ) dest; 1582 1515 address_in6.sin6_addr.s6_addr; 1583 1516 */ default: 1584 1517 return EAFNOSUPPORT; 1585 1518 } 1586 fibril_rwlock_read_lock(&ip_globals.lock); 1587 route = ip_find_route(*dest); 1588 // if the local host is the destination 1589 if(route && (route->address.s_addr == dest->s_addr) 1590 && (dest->s_addr != IPV4_LOCALHOST_ADDRESS)){ 1591 // find the loopback device to deliver 1592 dest->s_addr = IPV4_LOCALHOST_ADDRESS; 1593 route = ip_find_route(*dest); 1594 } 1595 if(!(route && route->netif)){ 1596 fibril_rwlock_read_unlock(&ip_globals.lock); 1519 fibril_rwlock_read_lock( & ip_globals.lock ); 1520 route = ip_find_route( * dest ); 1521 if( !( route && route->netif )){ 1522 fibril_rwlock_read_unlock( & ip_globals.lock ); 1597 1523 return ENOENT; 1598 1524 } 1599 *device_id = route->netif->device_id; 1600 src = ip_netif_address(route->netif); 1601 fibril_rwlock_read_unlock(&ip_globals.lock); 1602 *headerlen = sizeof(*header_in); 1603 header_in = (ipv4_pseudo_header_ref) malloc(*headerlen); 1604 if(! header_in){ 1605 return ENOMEM; 1606 } 1607 bzero(header_in, * headerlen); 1525 * device_id = route->netif->device_id; 1526 src = ip_netif_address( route->netif ); 1527 fibril_rwlock_read_unlock( & ip_globals.lock ); 1528 * headerlen = sizeof( * header_in ); 1529 header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen ); 1530 if( ! header_in ) return ENOMEM; 1531 bzero( header_in, * headerlen ); 1608 1532 header_in->destination_address = dest->s_addr; 1609 1533 header_in->source_address = src->s_addr; 1610 1534 header_in->protocol = protocol; 1611 1535 header_in->data_length = 0; 1612 * header = (ip_pseudo_header_ref) header_in;1536 * header = ( ip_pseudo_header_ref ) header_in; 1613 1537 return EOK; 1614 1538 }
Note:
See TracChangeset
for help on using the changeset viewer.