Changeset aadf01e in mainline for uspace/srv/net/tl/icmp
- Timestamp:
- 2010-03-07T15:13:28Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 936835e
- Parents:
- aa85487
- Location:
- uspace/srv/net/tl/icmp
- Files:
-
- 10 edited
-
icmp.c (modified) (28 diffs)
-
icmp.h (modified) (4 diffs)
-
icmp_api.c (modified) (1 diff)
-
icmp_client.c (modified) (1 diff)
-
icmp_common.c (modified) (1 diff)
-
icmp_header.h (modified) (6 diffs)
-
icmp_messages.h (modified) (1 diff)
-
icmp_module.c (modified) (5 diffs)
-
icmp_module.h (modified) (2 diffs)
-
icmp_remote.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/icmp/icmp.c
raa85487 raadf01e 102 102 * @returns The computed checksum. 103 103 */ 104 #define ICMP_CHECKSUM( header, length ) htons( ip_checksum(( uint8_t * ) ( header ), ( length)))104 #define ICMP_CHECKSUM(header, length) htons(ip_checksum((uint8_t *) (header), (length))) 105 105 106 106 /** An echo request datagrams pattern. … … 113 113 * @returns The computed ICMP reply data key. 114 114 */ 115 #define ICMP_GET_REPLY_KEY( id, sequence ) ((( id ) << 16 ) | ( sequence & 0xFFFF))115 #define ICMP_GET_REPLY_KEY(id, sequence) (((id) << 16) | (sequence &0xFFFF)) 116 116 117 117 /** Processes the received ICMP packet. … … 125 125 * @returns Other error codes as defined for the icmp_process_packet() function. 126 126 */ 127 int icmp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error);127 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error); 128 128 129 129 /** Processes the received ICMP packet. … … 140 140 * @returns Other error codes as defined for the ip_client_process_packet() function. 141 141 */ 142 int icmp_process_packet( packet_t packet, services_t error);142 int icmp_process_packet(packet_t packet, services_t error); 143 143 144 144 /** Processes the client messages. … … 151 151 * @see icmp_api.h 152 152 */ 153 int icmp_process_client_messages( ipc_callid_t callid, ipc_call_t call);153 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 154 154 155 155 /** Processes the generic client messages. … … 164 164 * @see icmp_interface.h 165 165 */ 166 int icmp_process_message( ipc_call_t * call);166 int icmp_process_message(ipc_call_t * call); 167 167 168 168 /** Releases the packet and returns the result. … … 171 171 * @returns The result parameter. 172 172 */ 173 int icmp_release_and_return( packet_t packet, int result);173 int icmp_release_and_return(packet_t packet, int result); 174 174 175 175 /** Requests an echo message. … … 192 192 * @returns EPARTY if there was an internal error. 193 193 */ 194 int icmp_echo( icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen);194 int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen); 195 195 196 196 /** Prepares the ICMP error packet. … … 201 201 * @returns NULL on errors. 202 202 */ 203 icmp_header_ref icmp_prepare_packet( packet_t packet);203 icmp_header_ref icmp_prepare_packet(packet_t packet); 204 204 205 205 /** Sends the ICMP message. … … 218 218 * @returns EPERM if the error message is not allowed. 219 219 */ 220 int icmp_send_packet( icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment);220 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment); 221 221 222 222 /** Tries to set the pending reply result as the received message type. … … 230 230 * @returns EOK. 231 231 */ 232 int icmp_process_echo_reply( packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code);232 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code); 233 233 234 234 /** Assigns a new identifier for the connection. … … 239 239 * @returns ENOTCONN if no free identifier have been found. 240 240 */ 241 int icmp_bind_free_id( icmp_echo_ref echo_data);241 int icmp_bind_free_id(icmp_echo_ref echo_data); 242 242 243 243 /** ICMP global data. … … 245 245 icmp_globals_t icmp_globals; 246 246 247 INT_MAP_IMPLEMENT( icmp_replies, icmp_reply_t);248 249 INT_MAP_IMPLEMENT( icmp_echo_data, icmp_echo_t);250 251 int icmp_echo_msg( int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){252 icmp_echo_ref echo_data;253 int res;254 255 fibril_rwlock_write_lock( & icmp_globals.lock);247 INT_MAP_IMPLEMENT(icmp_replies, icmp_reply_t); 248 249 INT_MAP_IMPLEMENT(icmp_echo_data, icmp_echo_t); 250 251 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){ 252 icmp_echo_ref echo_data; 253 int res; 254 255 fibril_rwlock_write_lock(&icmp_globals.lock); 256 256 // use the phone as the echo data index 257 echo_data = icmp_echo_data_find( & icmp_globals.echo_data, icmp_phone);258 if( ! echo_data){257 echo_data = icmp_echo_data_find(&icmp_globals.echo_data, icmp_phone); 258 if(! echo_data){ 259 259 res = ENOENT; 260 260 }else{ 261 res = icmp_echo( echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen);262 if( echo_data->sequence_number < MAX_UINT16){261 res = icmp_echo(echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen); 262 if(echo_data->sequence_number < MAX_UINT16){ 263 263 ++ echo_data->sequence_number; 264 264 }else{ … … 266 266 } 267 267 } 268 fibril_rwlock_write_unlock( & icmp_globals.lock);268 fibril_rwlock_write_unlock(&icmp_globals.lock); 269 269 return res; 270 270 } 271 271 272 int icmp_echo( icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){272 int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){ 273 273 ERROR_DECLARE; 274 274 275 icmp_header_ref header;276 packet_t packet;277 size_t length;278 uint8_t * data;279 icmp_reply_ref reply;280 int reply_key;281 int result;282 int index;283 284 if( addrlen <= 0){275 icmp_header_ref header; 276 packet_t packet; 277 size_t length; 278 uint8_t * data; 279 icmp_reply_ref reply; 280 int reply_key; 281 int result; 282 int index; 283 284 if(addrlen <= 0){ 285 285 return EINVAL; 286 286 } 287 length = ( size_t) addrlen;287 length = (size_t) addrlen; 288 288 // TODO do not ask all the time 289 ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.packet_dimension )); 290 packet = packet_get_4( icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix ); 291 if( ! packet ) return ENOMEM; 289 ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension)); 290 packet = packet_get_4(icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix); 291 if(! packet){ 292 return ENOMEM; 293 } 292 294 293 295 // prepare the requesting packet 294 296 // set the destination address 295 if( ERROR_OCCURRED( packet_set_addr( packet, NULL, ( const uint8_t * ) addr, length))){296 return icmp_release_and_return( packet, ERROR_CODE);297 if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (const uint8_t *) addr, length))){ 298 return icmp_release_and_return(packet, ERROR_CODE); 297 299 } 298 300 // allocate space in the packet 299 data = ( uint8_t * ) packet_suffix( packet, size);300 if( ! data){301 return icmp_release_and_return( packet, ENOMEM);301 data = (uint8_t *) packet_suffix(packet, size); 302 if(! data){ 303 return icmp_release_and_return(packet, ENOMEM); 302 304 } 303 305 // fill the data 304 306 length = 0; 305 while( size > length + sizeof( ICMP_ECHO_TEXT)){306 memcpy( data + length, ICMP_ECHO_TEXT, sizeof( ICMP_ECHO_TEXT));307 length += sizeof( ICMP_ECHO_TEXT);308 } 309 memcpy( data + length, ICMP_ECHO_TEXT, size - length);307 while(size > length + sizeof(ICMP_ECHO_TEXT)){ 308 memcpy(data + length, ICMP_ECHO_TEXT, sizeof(ICMP_ECHO_TEXT)); 309 length += sizeof(ICMP_ECHO_TEXT); 310 } 311 memcpy(data + length, ICMP_ECHO_TEXT, size - length); 310 312 // prefix the header 311 header = PACKET_PREFIX( packet, icmp_header_t);312 if( ! header){313 return icmp_release_and_return( packet, ENOMEM);314 } 315 bzero( header, sizeof( * header));313 header = PACKET_PREFIX(packet, icmp_header_t); 314 if(! header){ 315 return icmp_release_and_return(packet, ENOMEM); 316 } 317 bzero(header, sizeof(*header)); 316 318 header->un.echo.identifier = id; 317 319 header->un.echo.sequence_number = sequence; 318 320 319 321 // prepare the reply structure 320 reply = malloc( sizeof( * reply));321 if( ! reply){322 return icmp_release_and_return( packet, ENOMEM);323 } 324 fibril_mutex_initialize( & reply->mutex);325 fibril_mutex_lock( & reply->mutex);326 fibril_condvar_initialize( & reply->condvar);327 reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number);328 index = icmp_replies_add( & icmp_globals.replies, reply_key, reply);329 if( index < 0){330 free( reply);331 return icmp_release_and_return( packet, index);322 reply = malloc(sizeof(*reply)); 323 if(! reply){ 324 return icmp_release_and_return(packet, ENOMEM); 325 } 326 fibril_mutex_initialize(&reply->mutex); 327 fibril_mutex_lock(&reply->mutex); 328 fibril_condvar_initialize(&reply->condvar); 329 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number); 330 index = icmp_replies_add(&icmp_globals.replies, reply_key, reply); 331 if(index < 0){ 332 free(reply); 333 return icmp_release_and_return(packet, index); 332 334 } 333 335 334 336 // unlock the globals and wait for a reply 335 fibril_rwlock_write_unlock( & icmp_globals.lock);337 fibril_rwlock_write_unlock(&icmp_globals.lock); 336 338 337 339 // send the request 338 icmp_send_packet( ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment);340 icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment); 339 341 340 342 // wait for a reply 341 343 // timeout in microseconds 342 if( ERROR_OCCURRED( fibril_condvar_wait_timeout( & reply->condvar, & reply->mutex, timeout * 1000))){344 if(ERROR_OCCURRED(fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, timeout * 1000))){ 343 345 result = ERROR_CODE; 344 346 345 347 // lock the globals again and clean up 346 fibril_rwlock_write_lock( & icmp_globals.lock);348 fibril_rwlock_write_lock(&icmp_globals.lock); 347 349 }else{ 348 350 // read the result … … 350 352 351 353 // release the reply structure 352 fibril_mutex_unlock( & reply->mutex);354 fibril_mutex_unlock(&reply->mutex); 353 355 } 354 356 355 357 // destroy the reply structure 356 icmp_replies_exclude_index( & icmp_globals.replies, index);358 icmp_replies_exclude_index(&icmp_globals.replies, index); 357 359 return result; 358 360 } 359 361 360 int icmp_destination_unreachable_msg( int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){361 icmp_header_ref header;362 363 header = icmp_prepare_packet( packet);364 if( ! header){365 return icmp_release_and_return( packet, ENOMEM);366 } 367 if( mtu){362 int icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){ 363 icmp_header_ref header; 364 365 header = icmp_prepare_packet(packet); 366 if(! header){ 367 return icmp_release_and_return(packet, ENOMEM); 368 } 369 if(mtu){ 368 370 header->un.frag.mtu = mtu; 369 371 } 370 return icmp_send_packet( ICMP_DEST_UNREACH, code, packet, header, SERVICE_ICMP, 0, 0, 0);371 } 372 373 int icmp_source_quench_msg( int icmp_phone, packet_t packet){374 icmp_header_ref header;375 376 header = icmp_prepare_packet( packet);377 if( ! header){378 return icmp_release_and_return( packet, ENOMEM);379 } 380 return icmp_send_packet( ICMP_SOURCE_QUENCH, 0, packet, header, SERVICE_ICMP, 0, 0, 0);381 } 382 383 int icmp_time_exceeded_msg( int icmp_phone, icmp_code_t code, packet_t packet){384 icmp_header_ref header;385 386 header = icmp_prepare_packet( packet);387 if( ! header){388 return icmp_release_and_return( packet, ENOMEM);389 } 390 return icmp_send_packet( ICMP_TIME_EXCEEDED, code, packet, header, SERVICE_ICMP, 0, 0, 0);391 } 392 393 int icmp_parameter_problem_msg( int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){394 icmp_header_ref header;395 396 header = icmp_prepare_packet( packet);397 if( ! header){398 return icmp_release_and_return( packet, ENOMEM);372 return icmp_send_packet(ICMP_DEST_UNREACH, code, packet, header, SERVICE_ICMP, 0, 0, 0); 373 } 374 375 int icmp_source_quench_msg(int icmp_phone, packet_t packet){ 376 icmp_header_ref header; 377 378 header = icmp_prepare_packet(packet); 379 if(! header){ 380 return icmp_release_and_return(packet, ENOMEM); 381 } 382 return icmp_send_packet(ICMP_SOURCE_QUENCH, 0, packet, header, SERVICE_ICMP, 0, 0, 0); 383 } 384 385 int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t packet){ 386 icmp_header_ref header; 387 388 header = icmp_prepare_packet(packet); 389 if(! header){ 390 return icmp_release_and_return(packet, ENOMEM); 391 } 392 return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header, SERVICE_ICMP, 0, 0, 0); 393 } 394 395 int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){ 396 icmp_header_ref header; 397 398 header = icmp_prepare_packet(packet); 399 if(! header){ 400 return icmp_release_and_return(packet, ENOMEM); 399 401 } 400 402 header->un.param.pointer = pointer; 401 return icmp_send_packet( ICMP_PARAMETERPROB, code, packet, header, SERVICE_ICMP, 0, 0, 0 ); 402 } 403 404 icmp_header_ref icmp_prepare_packet( packet_t packet ){ 405 icmp_header_ref header; 406 size_t header_length; 407 size_t total_length; 408 409 total_length = packet_get_data_length( packet ); 410 if( total_length <= 0 ) return NULL; 411 header_length = ip_client_header_length( packet ); 412 if( header_length <= 0 ) return NULL; 403 return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header, SERVICE_ICMP, 0, 0, 0); 404 } 405 406 icmp_header_ref icmp_prepare_packet(packet_t packet){ 407 icmp_header_ref header; 408 size_t header_length; 409 size_t total_length; 410 411 total_length = packet_get_data_length(packet); 412 if(total_length <= 0){ 413 return NULL; 414 } 415 header_length = ip_client_header_length(packet); 416 if(header_length <= 0){ 417 return NULL; 418 } 413 419 // truncate if longer than 64 bits (without the IP header) 414 if(( total_length > header_length + ICMP_KEEP_LENGTH)415 && ( packet_trim( packet, 0, total_length - header_length - ICMP_KEEP_LENGTH ) != EOK)){420 if((total_length > header_length + ICMP_KEEP_LENGTH) 421 && (packet_trim(packet, 0, total_length - header_length - ICMP_KEEP_LENGTH) != EOK)){ 416 422 return NULL; 417 423 } 418 header = PACKET_PREFIX( packet, icmp_header_t ); 419 if( ! header ) return NULL; 420 bzero( header, sizeof( * header )); 424 header = PACKET_PREFIX(packet, icmp_header_t); 425 if(! header){ 426 return NULL; 427 } 428 bzero(header, sizeof(*header)); 421 429 return header; 422 430 } 423 431 424 int icmp_send_packet( icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment){432 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment){ 425 433 ERROR_DECLARE; 426 434 427 435 // do not send an error if disabled 428 if( error && ( ! icmp_globals.error_reporting)){429 return icmp_release_and_return( packet, EPERM);436 if(error && (! icmp_globals.error_reporting)){ 437 return icmp_release_and_return(packet, EPERM); 430 438 } 431 439 header->type = type; 432 440 header->code = code; 433 441 header->checksum = 0; 434 header->checksum = ICMP_CHECKSUM( header, packet_get_data_length( packet )); 435 if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_ICMP, ttl, tos, dont_fragment, 0 ))){ 436 return icmp_release_and_return( packet, ERROR_CODE ); 437 } 438 return ip_send_msg( icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, error ); 439 } 440 441 int icmp_connect_module( services_t service, suseconds_t timeout ){ 442 icmp_echo_ref echo_data; 443 icmp_param_t id; 444 int index; 445 446 echo_data = ( icmp_echo_ref ) malloc( sizeof( * echo_data )); 447 if( ! echo_data ) return ENOMEM; 442 header->checksum = ICMP_CHECKSUM(header, packet_get_data_length(packet)); 443 if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos, dont_fragment, 0))){ 444 return icmp_release_and_return(packet, ERROR_CODE); 445 } 446 return ip_send_msg(icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, error); 447 } 448 449 int icmp_connect_module(services_t service, suseconds_t timeout){ 450 icmp_echo_ref echo_data; 451 icmp_param_t id; 452 int index; 453 454 echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data)); 455 if(! echo_data){ 456 return ENOMEM; 457 } 448 458 // assign a new identifier 449 fibril_rwlock_write_lock( & icmp_globals.lock);450 index = icmp_bind_free_id( echo_data);451 if( index < 0){452 free( echo_data);453 fibril_rwlock_write_unlock( & icmp_globals.lock);459 fibril_rwlock_write_lock(&icmp_globals.lock); 460 index = icmp_bind_free_id(echo_data); 461 if(index < 0){ 462 free(echo_data); 463 fibril_rwlock_write_unlock(&icmp_globals.lock); 454 464 return index; 455 465 }else{ 456 466 id = echo_data->identifier; 457 fibril_rwlock_write_unlock( & icmp_globals.lock);467 fibril_rwlock_write_unlock(&icmp_globals.lock); 458 468 // return the echo data identifier as the ICMP phone 459 469 return id; … … 461 471 } 462 472 463 int icmp_initialize( async_client_conn_t client_connection){473 int icmp_initialize(async_client_conn_t client_connection){ 464 474 ERROR_DECLARE; 465 475 466 measured_string_t names[] = {{ str_dup("ICMP_ERROR_REPORTING"), 20 }, { str_dup("ICMP_ECHO_REPLYING"), 18}};467 measured_string_ref configuration;468 size_t count = sizeof( names ) / sizeof( measured_string_t);469 char * data;470 471 fibril_rwlock_initialize( & icmp_globals.lock);472 fibril_rwlock_write_lock( & icmp_globals.lock);473 icmp_replies_initialize( & icmp_globals.replies);474 icmp_echo_data_initialize( & icmp_globals.echo_data);475 icmp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection, icmp_received_msg);476 if( icmp_globals.ip_phone < 0){476 measured_string_t names[] = {{str_dup("ICMP_ERROR_REPORTING"), 20}, {str_dup("ICMP_ECHO_REPLYING"), 18}}; 477 measured_string_ref configuration; 478 size_t count = sizeof(names) / sizeof(measured_string_t); 479 char * data; 480 481 fibril_rwlock_initialize(&icmp_globals.lock); 482 fibril_rwlock_write_lock(&icmp_globals.lock); 483 icmp_replies_initialize(&icmp_globals.replies); 484 icmp_echo_data_initialize(&icmp_globals.echo_data); 485 icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection, icmp_received_msg); 486 if(icmp_globals.ip_phone < 0){ 477 487 return icmp_globals.ip_phone; 478 488 } 479 ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.packet_dimension));489 ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension)); 480 490 icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE; 481 491 icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE; … … 483 493 icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING; 484 494 icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING; 485 configuration = & names[ 0];486 ERROR_PROPAGATE( net_get_conf_req( icmp_globals.net_phone, & configuration, count, & data));487 if( configuration){488 if( configuration[ 0 ].value){489 icmp_globals.error_reporting = ( configuration[ 0 ].value[ 0 ] == 'y');495 configuration = &names[0]; 496 ERROR_PROPAGATE(net_get_conf_req(icmp_globals.net_phone, &configuration, count, &data)); 497 if(configuration){ 498 if(configuration[0].value){ 499 icmp_globals.error_reporting = (configuration[0].value[0] == 'y'); 490 500 } 491 if( configuration[ 1 ].value){492 icmp_globals.echo_replying = ( configuration[ 1 ].value[ 0 ] == 'y');501 if(configuration[1].value){ 502 icmp_globals.echo_replying = (configuration[1].value[0] == 'y'); 493 503 } 494 net_free_settings( configuration, data);495 } 496 fibril_rwlock_write_unlock( & icmp_globals.lock);504 net_free_settings(configuration, data); 505 } 506 fibril_rwlock_write_unlock(&icmp_globals.lock); 497 507 return EOK; 498 508 } 499 509 500 int icmp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error){510 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){ 501 511 ERROR_DECLARE; 502 512 503 if( ERROR_OCCURRED( icmp_process_packet( packet, error))){504 return icmp_release_and_return( packet, ERROR_CODE);513 if(ERROR_OCCURRED(icmp_process_packet(packet, error))){ 514 return icmp_release_and_return(packet, ERROR_CODE); 505 515 } 506 516 … … 508 518 } 509 519 510 int icmp_process_packet( packet_t packet, services_t error){520 int icmp_process_packet(packet_t packet, services_t error){ 511 521 ERROR_DECLARE; 512 522 513 size_t length;514 uint8_t * src;515 int addrlen;516 int result;517 void * data;518 icmp_header_ref header;519 icmp_type_t type;520 icmp_code_t code;521 522 if( error){523 switch( error){523 size_t length; 524 uint8_t * src; 525 int addrlen; 526 int result; 527 void * data; 528 icmp_header_ref header; 529 icmp_type_t type; 530 icmp_code_t code; 531 532 if(error){ 533 switch(error){ 524 534 case SERVICE_ICMP: 525 535 // process error 526 result = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); 527 if( result < 0 ) return result; 528 length = ( size_t ) result; 536 result = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 537 if(result < 0){ 538 return result; 539 } 540 length = (size_t) result; 529 541 // remove the error header 530 ERROR_PROPAGATE( packet_trim( packet, length, 0));542 ERROR_PROPAGATE(packet_trim(packet, length, 0)); 531 543 break; 532 544 default: … … 535 547 } 536 548 // get rid of the ip header 537 length = ip_client_header_length( packet ); 538 ERROR_PROPAGATE( packet_trim( packet, length, 0 )); 539 540 length = packet_get_data_length( packet ); 541 if( length <= 0 ) return EINVAL; 542 if( length < ICMP_HEADER_SIZE) return EINVAL; 543 data = packet_get_data( packet ); 544 if( ! data ) return EINVAL; 549 length = ip_client_header_length(packet); 550 ERROR_PROPAGATE(packet_trim(packet, length, 0)); 551 552 length = packet_get_data_length(packet); 553 if(length <= 0){ 554 return EINVAL; 555 } 556 if(length < ICMP_HEADER_SIZE){ 557 return EINVAL; 558 } 559 data = packet_get_data(packet); 560 if(! data){ 561 return EINVAL; 562 } 545 563 // get icmp header 546 header = ( icmp_header_ref) data;564 header = (icmp_header_ref) data; 547 565 // checksum 548 if( header->checksum){549 while( ICMP_CHECKSUM( header, length ) != IP_CHECKSUM_ZERO){566 if(header->checksum){ 567 while(ICMP_CHECKSUM(header, length) != IP_CHECKSUM_ZERO){ 550 568 // set the original message type on error notification 551 569 // type swap observed in Qemu 552 if( error){553 switch( header->type){570 if(error){ 571 switch(header->type){ 554 572 case ICMP_ECHOREPLY: 555 573 header->type = ICMP_ECHO; … … 560 578 } 561 579 } 562 switch( header->type){580 switch(header->type){ 563 581 case ICMP_ECHOREPLY: 564 if( error){565 return icmp_process_echo_reply( packet, header, type, code);582 if(error){ 583 return icmp_process_echo_reply(packet, header, type, code); 566 584 }else{ 567 return icmp_process_echo_reply( packet, header, ICMP_ECHO, 0);585 return icmp_process_echo_reply(packet, header, ICMP_ECHO, 0); 568 586 } 569 587 case ICMP_ECHO: 570 if( error){571 return icmp_process_echo_reply( packet, header, type, code);588 if(error){ 589 return icmp_process_echo_reply(packet, header, type, code); 572 590 // do not send a reply if disabled 573 }else if( icmp_globals.echo_replying){574 addrlen = packet_get_addr( packet, & src, NULL);575 if(( addrlen > 0)591 }else if(icmp_globals.echo_replying){ 592 addrlen = packet_get_addr(packet, &src, NULL); 593 if((addrlen > 0) 576 594 // set both addresses to the source one (avoids the source address deletion before setting the destination one) 577 && ( packet_set_addr( packet, src, src, ( size_t ) addrlen ) == EOK)){595 && (packet_set_addr(packet, src, src, (size_t) addrlen) == EOK)){ 578 596 // send the reply 579 icmp_send_packet( ICMP_ECHOREPLY, 0, packet, header, 0, 0, 0, 0);597 icmp_send_packet(ICMP_ECHOREPLY, 0, packet, header, 0, 0, 0, 0); 580 598 return EOK; 581 599 }else{ … … 597 615 case ICMP_SKIP: 598 616 case ICMP_PHOTURIS: 599 ip_received_error_msg( icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP);617 ip_received_error_msg(icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP); 600 618 return EOK; 601 619 default: … … 604 622 } 605 623 606 int icmp_process_echo_reply( packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code){607 int reply_key;608 icmp_reply_ref reply;624 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code){ 625 int reply_key; 626 icmp_reply_ref reply; 609 627 610 628 // compute the reply key 611 reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number);612 pq_release( icmp_globals.net_phone, packet_get_id( packet));629 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number); 630 pq_release(icmp_globals.net_phone, packet_get_id(packet)); 613 631 // lock the globals 614 fibril_rwlock_write_lock( & icmp_globals.lock);632 fibril_rwlock_write_lock(&icmp_globals.lock); 615 633 // find the pending reply 616 reply = icmp_replies_find( & icmp_globals.replies, reply_key);617 if( reply){634 reply = icmp_replies_find(&icmp_globals.replies, reply_key); 635 if(reply){ 618 636 // set the result 619 637 reply->result = type; 620 638 // notify the main fibril 621 fibril_condvar_signal( & reply->condvar);639 fibril_condvar_signal(&reply->condvar); 622 640 }else{ 623 641 // unlock only if no reply 624 fibril_rwlock_write_unlock( & icmp_globals.lock);642 fibril_rwlock_write_unlock(&icmp_globals.lock); 625 643 } 626 644 return EOK; 627 645 } 628 646 629 int icmp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){647 int icmp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 630 648 ERROR_DECLARE; 631 649 632 packet_t packet;633 634 * answer_count = 0;635 switch( IPC_GET_METHOD( * call)){650 packet_t packet; 651 652 *answer_count = 0; 653 switch(IPC_GET_METHOD(*call)){ 636 654 case NET_TL_RECEIVED: 637 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){638 ERROR_CODE = icmp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_ICMP, IPC_GET_ERROR( call));655 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 656 ERROR_CODE = icmp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_ICMP, IPC_GET_ERROR(call)); 639 657 } 640 658 return ERROR_CODE; 641 659 case NET_ICMP_INIT: 642 return icmp_process_client_messages( callid, * call);660 return icmp_process_client_messages(callid, * call); 643 661 default: 644 return icmp_process_message( call);662 return icmp_process_message(call); 645 663 } 646 664 return ENOTSUP; 647 665 } 648 666 649 int icmp_process_client_messages( ipc_callid_t callid, ipc_call_t call){667 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call){ 650 668 ERROR_DECLARE; 651 669 652 bool keep_on_going = true;670 bool keep_on_going = true; 653 671 // fibril_rwlock_t lock; 654 ipc_call_t answer;655 int answer_count;656 size_t length;657 struct sockaddr * addr;658 ipc_callid_t data_callid;659 icmp_echo_ref echo_data;660 int res;672 ipc_call_t answer; 673 int answer_count; 674 size_t length; 675 struct sockaddr * addr; 676 ipc_callid_t data_callid; 677 icmp_echo_ref echo_data; 678 int res; 661 679 662 680 /* … … 667 685 answer_count = 0; 668 686 669 // fibril_rwlock_initialize( & lock ); 670 671 echo_data = ( icmp_echo_ref ) malloc( sizeof( * echo_data )); 672 if( ! echo_data ) return ENOMEM; 687 // fibril_rwlock_initialize(&lock); 688 689 echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data)); 690 if(! echo_data){ 691 return ENOMEM; 692 } 673 693 674 694 // assign a new identifier 675 fibril_rwlock_write_lock( & icmp_globals.lock);676 res = icmp_bind_free_id( echo_data);677 fibril_rwlock_write_unlock( & icmp_globals.lock);678 if( res < 0){679 free( echo_data);695 fibril_rwlock_write_lock(&icmp_globals.lock); 696 res = icmp_bind_free_id(echo_data); 697 fibril_rwlock_write_unlock(&icmp_globals.lock); 698 if(res < 0){ 699 free(echo_data); 680 700 return res; 681 701 } 682 702 683 while( keep_on_going){703 while(keep_on_going){ 684 704 685 705 // answer the call 686 answer_call( callid, res, & answer, answer_count);706 answer_call(callid, res, &answer, answer_count); 687 707 688 708 // refresh data 689 refresh_answer( & answer, & answer_count);709 refresh_answer(&answer, &answer_count); 690 710 691 711 // get the next call 692 callid = async_get_call( & call);712 callid = async_get_call(&call); 693 713 694 714 // process the call 695 switch( IPC_GET_METHOD( call)){715 switch(IPC_GET_METHOD(call)){ 696 716 case IPC_M_PHONE_HUNGUP: 697 717 keep_on_going = false; … … 699 719 break; 700 720 case NET_ICMP_ECHO: 701 // fibril_rwlock_write_lock( & lock);702 if( ! async_data_write_receive( & data_callid, & length)){721 // fibril_rwlock_write_lock(&lock); 722 if(! async_data_write_receive(&data_callid, &length)){ 703 723 res = EINVAL; 704 724 }else{ 705 addr = malloc( length);706 if( ! addr){725 addr = malloc(length); 726 if(! addr){ 707 727 res = ENOMEM; 708 728 }else{ 709 if( ! ERROR_OCCURRED( async_data_write_finalize( data_callid, addr, length))){710 fibril_rwlock_write_lock( & icmp_globals.lock);711 res = icmp_echo( echo_data->identifier, echo_data->sequence_number, ICMP_GET_SIZE( call ), ICMP_GET_TIMEOUT( call ), ICMP_GET_TTL( call ), ICMP_GET_TOS( call ), ICMP_GET_DONT_FRAGMENT( call ), addr, ( socklen_t ) length);712 fibril_rwlock_write_unlock( & icmp_globals.lock);713 free( addr);714 if( echo_data->sequence_number < MAX_UINT16){729 if(! ERROR_OCCURRED(async_data_write_finalize(data_callid, addr, length))){ 730 fibril_rwlock_write_lock(&icmp_globals.lock); 731 res = icmp_echo(echo_data->identifier, echo_data->sequence_number, ICMP_GET_SIZE(call), ICMP_GET_TIMEOUT(call), ICMP_GET_TTL(call), ICMP_GET_TOS(call), ICMP_GET_DONT_FRAGMENT(call), addr, (socklen_t) length); 732 fibril_rwlock_write_unlock(&icmp_globals.lock); 733 free(addr); 734 if(echo_data->sequence_number < MAX_UINT16){ 715 735 ++ echo_data->sequence_number; 716 736 }else{ … … 722 742 } 723 743 } 724 // fibril_rwlock_write_unlock( & lock);744 // fibril_rwlock_write_unlock(&lock); 725 745 break; 726 746 default: 727 res = icmp_process_message( & call);747 res = icmp_process_message(&call); 728 748 } 729 749 } 730 750 731 751 // release the identifier 732 fibril_rwlock_write_lock( & icmp_globals.lock);733 icmp_echo_data_exclude( & icmp_globals.echo_data, echo_data->identifier);734 fibril_rwlock_write_unlock( & icmp_globals.lock);752 fibril_rwlock_write_lock(&icmp_globals.lock); 753 icmp_echo_data_exclude(&icmp_globals.echo_data, echo_data->identifier); 754 fibril_rwlock_write_unlock(&icmp_globals.lock); 735 755 return res; 736 756 } 737 757 738 int icmp_process_message( ipc_call_t * call){758 int icmp_process_message(ipc_call_t * call){ 739 759 ERROR_DECLARE; 740 760 741 packet_t packet;742 743 switch( IPC_GET_METHOD( * call)){761 packet_t packet; 762 763 switch(IPC_GET_METHOD(*call)){ 744 764 case NET_ICMP_DEST_UNREACH: 745 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){746 ERROR_CODE = icmp_destination_unreachable_msg( 0, ICMP_GET_CODE( call ), ICMP_GET_MTU( call ), packet);765 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 766 ERROR_CODE = icmp_destination_unreachable_msg(0, ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet); 747 767 } 748 768 return ERROR_CODE; 749 769 case NET_ICMP_SOURCE_QUENCH: 750 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){751 ERROR_CODE = icmp_source_quench_msg( 0, packet);770 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 771 ERROR_CODE = icmp_source_quench_msg(0, packet); 752 772 } 753 773 return ERROR_CODE; 754 774 case NET_ICMP_TIME_EXCEEDED: 755 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){756 ERROR_CODE = icmp_time_exceeded_msg( 0, ICMP_GET_CODE( call ), packet);775 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 776 ERROR_CODE = icmp_time_exceeded_msg(0, ICMP_GET_CODE(call), packet); 757 777 } 758 778 return ERROR_CODE; 759 779 case NET_ICMP_PARAMETERPROB: 760 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){761 ERROR_CODE = icmp_parameter_problem_msg( 0, ICMP_GET_CODE( call ), ICMP_GET_POINTER( call ), packet);780 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 781 ERROR_CODE = icmp_parameter_problem_msg(0, ICMP_GET_CODE(call), ICMP_GET_POINTER(call), packet); 762 782 } 763 783 return ERROR_CODE; … … 767 787 } 768 788 769 int icmp_release_and_return( packet_t packet, int result){770 pq_release( icmp_globals.net_phone, packet_get_id( packet));789 int icmp_release_and_return(packet_t packet, int result){ 790 pq_release(icmp_globals.net_phone, packet_get_id(packet)); 771 791 return result; 772 792 } 773 793 774 int icmp_bind_free_id( icmp_echo_ref echo_data ){ 775 icmp_param_t index; 776 777 if( ! echo_data ) return EBADMEM; 794 int icmp_bind_free_id(icmp_echo_ref echo_data){ 795 icmp_param_t index; 796 797 if(! echo_data){ 798 return EBADMEM; 799 } 778 800 // from the last used one 779 801 index = icmp_globals.last_used_id; … … 781 803 ++ index; 782 804 // til the range end 783 if( index >= ICMP_FREE_IDS_END){805 if(index >= ICMP_FREE_IDS_END){ 784 806 // start from the range beginning 785 807 index = ICMP_FREE_IDS_START - 1; … … 787 809 ++ index; 788 810 // til the last used one 789 if( index >= icmp_globals.last_used_id){811 if(index >= icmp_globals.last_used_id){ 790 812 // none found 791 813 return ENOTCONN; 792 814 } 793 }while( icmp_echo_data_find( & icmp_globals.echo_data, index ) != NULL);815 }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL); 794 816 // found, break immediately 795 817 break; 796 818 } 797 }while( icmp_echo_data_find( & icmp_globals.echo_data, index ) != NULL);819 }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL); 798 820 echo_data->identifier = index; 799 821 echo_data->sequence_number = 0; 800 return icmp_echo_data_add( & icmp_globals.echo_data, index, echo_data);822 return icmp_echo_data_add(&icmp_globals.echo_data, index, echo_data); 801 823 } 802 824 -
uspace/srv/net/tl/icmp/icmp.h
raa85487 raadf01e 66 66 * Receiving fibril sets the associated reply with the return value and signals the event. 67 67 */ 68 INT_MAP_DECLARE( icmp_replies, icmp_reply_t);68 INT_MAP_DECLARE(icmp_replies, icmp_reply_t); 69 69 70 70 /** Echo specific data map. … … 72 72 * The identifier is used in the future semi-remote calls instead of the ICMP phone. 73 73 */ 74 INT_MAP_DECLARE( icmp_echo_data, icmp_echo_t);74 INT_MAP_DECLARE(icmp_echo_data, icmp_echo_t); 75 75 76 76 /** ICMP reply data. … … 79 79 /** Reply result. 80 80 */ 81 int result;81 int result; 82 82 /** Safety lock. 83 83 */ 84 fibril_mutex_t mutex;84 fibril_mutex_t mutex; 85 85 /** Received or timeouted reply signaling. 86 86 */ 87 fibril_condvar_t condvar;87 fibril_condvar_t condvar; 88 88 }; 89 89 … … 93 93 /** IP module phone. 94 94 */ 95 int ip_phone;95 int ip_phone; 96 96 /** Packet dimension. 97 97 */ 98 packet_dimension_t packet_dimension;98 packet_dimension_t packet_dimension; 99 99 /** Networking module phone. 100 100 */ 101 int net_phone;101 int net_phone; 102 102 /** Indicates whether ICMP error reporting is enabled. 103 103 */ 104 int error_reporting;104 int error_reporting; 105 105 /** Indicates whether ICMP echo replying (ping) is enabled. 106 106 */ 107 int echo_replying;107 int echo_replying; 108 108 /** The last used identifier number. 109 109 */ 110 icmp_param_t last_used_id;110 icmp_param_t last_used_id; 111 111 /** The budled modules assigned echo specific data. 112 112 */ 113 icmp_echo_data_t echo_data;113 icmp_echo_data_t echo_data; 114 114 /** Echo timeout locks. 115 115 */ 116 icmp_replies_t replies;116 icmp_replies_t replies; 117 117 /** Safety lock. 118 118 */ 119 fibril_rwlock_t lock;119 fibril_rwlock_t lock; 120 120 }; 121 121 -
uspace/srv/net/tl/icmp/icmp_api.c
raa85487 raadf01e 52 52 #include "icmp_messages.h" 53 53 54 int icmp_echo_msg( int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){55 aid_t message_id;56 ipcarg_t result;54 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){ 55 aid_t message_id; 56 ipcarg_t result; 57 57 58 if( addrlen <= 0){58 if(addrlen <= 0){ 59 59 return EINVAL; 60 60 } 61 message_id = async_send_5( icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, tos, ( ipcarg_t ) dont_fragment, NULL);61 message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, tos, (ipcarg_t) dont_fragment, NULL); 62 62 // send the address 63 async_data_write_start( icmp_phone, addr, ( size_t ) addrlen);63 async_data_write_start(icmp_phone, addr, (size_t) addrlen); 64 64 // timeout version may cause inconsistency - there is also an inner timer 65 // return async_wait_timeout( message_id, & result, timeout);66 async_wait_for( message_id, & result);67 return ( int) result;65 // return async_wait_timeout(message_id, &result, timeout); 66 async_wait_for(message_id, &result); 67 return (int) result; 68 68 } 69 69 -
uspace/srv/net/tl/icmp/icmp_client.c
raa85487 raadf01e 49 49 #include "icmp_header.h" 50 50 51 int icmp_client_process_packet( packet_t packet, icmp_type_t * type, icmp_code_t * code, icmp_param_t * pointer, icmp_param_t * mtu){52 icmp_header_ref header;51 int icmp_client_process_packet(packet_t packet, icmp_type_t * type, icmp_code_t * code, icmp_param_t * pointer, icmp_param_t * mtu){ 52 icmp_header_ref header; 53 53 54 header = ( icmp_header_ref ) packet_get_data( packet);55 if(( ! header)56 || ( packet_get_data_length( packet ) < sizeof( icmp_header_t))){54 header = (icmp_header_ref) packet_get_data(packet); 55 if((! header) 56 || (packet_get_data_length(packet) < sizeof(icmp_header_t))){ 57 57 return 0; 58 58 } 59 if( type ) * type = header->type; 60 if( code ) * code = header->code; 61 if( pointer ) * pointer = header->un.param.pointer; 62 if( mtu ) * mtu = header->un.frag.mtu; 59 if(type){ 60 *type = header->type; 61 } 62 if(code){ 63 *code = header->code; 64 } 65 if(pointer){ 66 *pointer = header->un.param.pointer; 67 } 68 if(mtu){ 69 *mtu = header->un.frag.mtu; 70 } 63 71 // remove debug dump 64 // printf( "ICMP error %d (%d) in packet %d\n", header->type, header->code, packet_get_id( packet));65 return sizeof( icmp_header_t);72 // printf("ICMP error %d (%d) in packet %d\n", header->type, header->code, packet_get_id(packet)); 73 return sizeof(icmp_header_t); 66 74 } 67 75 68 size_t icmp_client_header_length( packet_t packet){69 if( packet_get_data_length( packet ) < sizeof( icmp_header_t)){76 size_t icmp_client_header_length(packet_t packet){ 77 if(packet_get_data_length(packet) < sizeof(icmp_header_t)){ 70 78 return 0; 71 79 } 72 return sizeof( icmp_header_t);80 return sizeof(icmp_header_t); 73 81 } 74 82 -
uspace/srv/net/tl/icmp/icmp_common.c
raa85487 raadf01e 45 45 #include "icmp_messages.h" 46 46 47 int icmp_connect_module( services_t service, suseconds_t timeout){48 int phone;47 int icmp_connect_module(services_t service, suseconds_t timeout){ 48 int phone; 49 49 50 phone = connect_to_service_timeout( SERVICE_ICMP, timeout);51 if( phone >= 0){52 async_req_0_0( phone, NET_ICMP_INIT);50 phone = connect_to_service_timeout(SERVICE_ICMP, timeout); 51 if(phone >= 0){ 52 async_req_0_0(phone, NET_ICMP_INIT); 53 53 } 54 54 return phone; -
uspace/srv/net/tl/icmp/icmp_header.h
raa85487 raadf01e 46 46 /** ICMP header size in bytes. 47 47 */ 48 #define ICMP_HEADER_SIZE sizeof( icmp_header_t)48 #define ICMP_HEADER_SIZE sizeof(icmp_header_t) 49 49 50 50 /** Type definition of the echo specific data. … … 63 63 /** Message idintifier. 64 64 */ 65 icmp_param_t identifier;65 icmp_param_t identifier; 66 66 /** Message sequence number. 67 67 */ 68 icmp_param_t sequence_number;68 icmp_param_t sequence_number; 69 69 } __attribute__ ((packed)); 70 70 … … 84 84 /** The type of the message. 85 85 */ 86 uint8_t type;86 uint8_t type; 87 87 /** The error code for the datagram reported by the ICMP message. 88 88 * The interpretation is dependent on the message type. 89 89 */ 90 uint8_t code;90 uint8_t code; 91 91 /** The checksum is the 16-bit ones's complement of the one's complement sum of the ICMP message starting with the ICMP Type. 92 92 * For computing the checksum, the checksum field should be zero. 93 93 * If the checksum does not match the contents, the datagram is discarded. 94 94 */ 95 uint16_t checksum;95 uint16_t checksum; 96 96 /** Message specific data. 97 97 */ … … 99 99 /** Echo specific data. 100 100 */ 101 icmp_echo_t echo;101 icmp_echo_t echo; 102 102 /** Proposed gateway value. 103 103 */ 104 in_addr_t gateway;104 in_addr_t gateway; 105 105 /** Fragmentation needed specific data. 106 106 */ … … 109 109 * Must be zero. 110 110 */ 111 icmp_param_t reserved;111 icmp_param_t reserved; 112 112 /** Proposed MTU. 113 113 */ 114 icmp_param_t mtu;114 icmp_param_t mtu; 115 115 } frag; 116 116 /** Parameter problem specific data. … … 119 119 /** Problem pointer. 120 120 */ 121 icmp_param_t pointer;121 icmp_param_t pointer; 122 122 /** Reserved field. 123 123 * Must be zero. 124 124 */ 125 icmp_param_t reserved;125 icmp_param_t reserved; 126 126 } param; 127 127 } un; -
uspace/srv/net/tl/icmp/icmp_messages.h
raa85487 raadf01e 82 82 * @param[in] call The message call structure. 83 83 */ 84 #define ICMP_GET_CODE( call ) ( icmp_code_t ) IPC_GET_ARG1( * call)84 #define ICMP_GET_CODE(call) (icmp_code_t) IPC_GET_ARG1(*call) 85 85 86 86 /** Returns the ICMP link MTU message parameter. 87 87 * @param[in] call The message call structure. 88 88 */ 89 #define ICMP_GET_MTU( call ) ( icmp_param_t ) IPC_GET_ARG3( * call)89 #define ICMP_GET_MTU(call) (icmp_param_t) IPC_GET_ARG3(*call) 90 90 91 91 /** Returns the pointer message parameter. 92 92 * @param[in] call The message call structure. 93 93 */ 94 #define ICMP_GET_POINTER( call ) ( icmp_param_t ) IPC_GET_ARG3( * call)94 #define ICMP_GET_POINTER(call) (icmp_param_t) IPC_GET_ARG3(*call) 95 95 96 96 /** Returns the size message parameter. 97 97 * @param[in] call The message call structure. 98 98 */ 99 #define ICMP_GET_SIZE( call ) ( size_t ) IPC_GET_ARG1( call)99 #define ICMP_GET_SIZE(call) (size_t) IPC_GET_ARG1(call) 100 100 101 101 /** Returns the timeout message parameter. 102 102 * @param[in] call The message call structure. 103 103 */ 104 #define ICMP_GET_TIMEOUT( call ) (( suseconds_t ) IPC_GET_ARG2( call))104 #define ICMP_GET_TIMEOUT(call) ((suseconds_t) IPC_GET_ARG2(call)) 105 105 106 106 /** Returns the time to live message parameter. 107 107 * @param[in] call The message call structure. 108 108 */ 109 #define ICMP_GET_TTL( call ) ( ip_ttl_t ) IPC_GET_ARG3( call)109 #define ICMP_GET_TTL(call) (ip_ttl_t) IPC_GET_ARG3(call) 110 110 111 111 /** Returns the type of service message parameter. 112 112 * @param[in] call The message call structure. 113 113 */ 114 #define ICMP_GET_TOS( call ) ( ip_tos_t ) IPC_GET_ARG4( call)114 #define ICMP_GET_TOS(call) (ip_tos_t) IPC_GET_ARG4(call) 115 115 116 116 /** Returns the dont fragment message parameter. 117 117 * @param[in] call The message call structure. 118 118 */ 119 #define ICMP_GET_DONT_FRAGMENT( call ) ( int ) IPC_GET_ARG5( call)119 #define ICMP_GET_DONT_FRAGMENT(call) (int) IPC_GET_ARG5(call) 120 120 121 121 /*@}*/ -
uspace/srv/net/tl/icmp/icmp_module.c
raa85487 raadf01e 61 61 * @see NAME 62 62 */ 63 void module_print_name( void);63 void module_print_name(void); 64 64 65 65 /** Starts the ICMP module. … … 70 70 * @returns Other error codes as defined for the REGISTER_ME() macro function. 71 71 */ 72 int module_start( async_client_conn_t client_connection);72 int module_start(async_client_conn_t client_connection); 73 73 74 74 /** Processes the ICMP message. … … 80 80 * @returns Other error codes as defined for the icmp_message() function. 81 81 */ 82 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);82 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 83 83 84 84 /** ICMP module global data. … … 86 86 extern icmp_globals_t icmp_globals; 87 87 88 void module_print_name( void){89 printf( "%s", NAME);88 void module_print_name(void){ 89 printf("%s", NAME); 90 90 } 91 91 92 int module_start( async_client_conn_t client_connection){92 int module_start(async_client_conn_t client_connection){ 93 93 ERROR_DECLARE; 94 94 95 ipcarg_t phonehash;95 ipcarg_t phonehash; 96 96 97 async_set_client_connection( client_connection);98 icmp_globals.net_phone = net_connect_module( SERVICE_NETWORKING);99 if( icmp_globals.net_phone < 0){97 async_set_client_connection(client_connection); 98 icmp_globals.net_phone = net_connect_module(SERVICE_NETWORKING); 99 if(icmp_globals.net_phone < 0){ 100 100 return icmp_globals.net_phone; 101 101 } 102 ERROR_PROPAGATE( pm_init());103 if( ERROR_OCCURRED( icmp_initialize( client_connection))104 || ERROR_OCCURRED( REGISTER_ME( SERVICE_ICMP, & phonehash))){102 ERROR_PROPAGATE(pm_init()); 103 if(ERROR_OCCURRED(icmp_initialize(client_connection)) 104 || ERROR_OCCURRED(REGISTER_ME(SERVICE_ICMP, &phonehash))){ 105 105 pm_destroy(); 106 106 return ERROR_CODE; … … 113 113 } 114 114 115 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){116 return icmp_message( callid, call, answer, answer_count);115 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 116 return icmp_message(callid, call, answer, answer_count); 117 117 } 118 118 -
uspace/srv/net/tl/icmp/icmp_module.h
raa85487 raadf01e 47 47 * @returns ENOMEM if there is not enough memory left. 48 48 */ 49 int icmp_initialize( async_client_conn_t client_connection);49 int icmp_initialize(async_client_conn_t client_connection); 50 50 51 51 /** Processes the ICMP message. … … 59 59 * @see IS_NET_ICMP_MESSAGE() 60 60 */ 61 int icmp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);61 int icmp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 62 62 63 63 #endif -
uspace/srv/net/tl/icmp/icmp_remote.c
raa85487 raadf01e 53 53 #include "icmp_messages.h" 54 54 55 int icmp_destination_unreachable_msg( int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){56 async_msg_3( icmp_phone, NET_ICMP_DEST_UNREACH, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet ), ( ipcarg_t ) mtu);55 int icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){ 56 async_msg_3(icmp_phone, NET_ICMP_DEST_UNREACH, (ipcarg_t) code, (ipcarg_t) packet_get_id(packet), (ipcarg_t) mtu); 57 57 return EOK; 58 58 } 59 59 60 int icmp_source_quench_msg( int icmp_phone, packet_t packet){61 async_msg_2( icmp_phone, NET_ICMP_SOURCE_QUENCH, 0, ( ipcarg_t ) packet_get_id( packet));60 int icmp_source_quench_msg(int icmp_phone, packet_t packet){ 61 async_msg_2(icmp_phone, NET_ICMP_SOURCE_QUENCH, 0, (ipcarg_t) packet_get_id(packet)); 62 62 return EOK; 63 63 } 64 64 65 int icmp_time_exceeded_msg( int icmp_phone, icmp_code_t code, packet_t packet){66 async_msg_2( icmp_phone, NET_ICMP_TIME_EXCEEDED, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet));65 int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t packet){ 66 async_msg_2(icmp_phone, NET_ICMP_TIME_EXCEEDED, (ipcarg_t) code, (ipcarg_t) packet_get_id(packet)); 67 67 return EOK; 68 68 } 69 69 70 int icmp_parameter_problem_msg( int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){71 async_msg_3( icmp_phone, NET_ICMP_PARAMETERPROB, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet ), ( ipcarg_t ) pointer);70 int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){ 71 async_msg_3(icmp_phone, NET_ICMP_PARAMETERPROB, (ipcarg_t) code, (ipcarg_t) packet_get_id(packet), (ipcarg_t) pointer); 72 72 return EOK; 73 73 }
Note:
See TracChangeset
for help on using the changeset viewer.
