Rev 4730 | Rev 4738 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4730 | Rev 4731 | ||
---|---|---|---|
Line 241... | Line 241... | ||
241 | ERROR_DECLARE; |
241 | ERROR_DECLARE; |
242 | 242 | ||
243 | size_t length; |
243 | size_t length; |
244 | size_t offset; |
244 | size_t offset; |
245 | int result; |
245 | int result; |
246 | uint8_t * data; |
- | |
247 | udp_header_ref header; |
246 | udp_header_ref header; |
248 | socket_core_ref * socket; |
247 | socket_core_ref * socket; |
249 | packet_t next_packet; |
248 | packet_t next_packet; |
250 | size_t total_length; |
249 | size_t total_length; |
251 | uint32_t checksum; |
250 | uint32_t checksum; |
Line 258... | Line 257... | ||
258 | struct sockaddr * dest; |
257 | struct sockaddr * dest; |
259 | 258 | ||
260 | if( error ){ |
259 | if( error ){ |
261 | switch( error ){ |
260 | switch( error ){ |
262 | case SERVICE_ICMP: |
261 | case SERVICE_ICMP: |
263 | // process error |
262 | // ignore error |
264 | // TODO remove debug dump |
- | |
265 | // length = icmp_client_header_length( packet ); |
263 | // length = icmp_client_header_length( packet ); |
- | 264 | // process error |
|
266 | result = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); |
265 | result = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); |
267 | if( result < 0 ){ |
266 | if( result < 0 ){ |
268 | return udp_release_and_return( packet, result ); |
267 | return udp_release_and_return( packet, result ); |
269 | } |
268 | } |
270 | printf( "ICMP error %d (%d) in packet %d\n", type, code, packet_get_id( packet ) ); |
- | |
271 | length = ( size_t ) result; |
269 | length = ( size_t ) result; |
272 | if( ERROR_OCCURRED( packet_trim( packet, length, 0 ))){ |
270 | if( ERROR_OCCURRED( packet_trim( packet, length, 0 ))){ |
273 | return udp_release_and_return( packet, ERROR_CODE ); |
271 | return udp_release_and_return( packet, ERROR_CODE ); |
274 | } |
272 | } |
275 | break; |
273 | break; |
Line 289... | Line 287... | ||
289 | return udp_release_and_return( packet, EINVAL ); |
287 | return udp_release_and_return( packet, EINVAL ); |
290 | } |
288 | } |
291 | if( length < sizeof( udp_header_t ) + offset ){ |
289 | if( length < sizeof( udp_header_t ) + offset ){ |
292 | return udp_release_and_return( packet, NO_DATA ); |
290 | return udp_release_and_return( packet, NO_DATA ); |
293 | } |
291 | } |
- | 292 | ||
294 | data = packet_get_data( packet ); |
293 | // trim all but UDP header |
295 | if( ! data ){ |
294 | if( ERROR_OCCURRED( packet_trim( packet, offset, 0 ))){ |
296 | return udp_release_and_return( packet, NO_DATA ); |
295 | return udp_release_and_return( packet, ERROR_CODE ); |
297 | } |
296 | } |
- | 297 | ||
298 | // get udp header |
298 | // get udp header |
299 | header = ( udp_header_ref )( data + offset ); |
299 | header = ( udp_header_ref ) packet_get_data( packet ); |
- | 300 | if( ! header ){ |
|
- | 301 | return udp_release_and_return( packet, NO_DATA ); |
|
- | 302 | } |
|
300 | // find the destination socket |
303 | // find the destination socket |
301 | socket = socket_ports_find( & udp_globals.sockets, ntohs( header->destination_port )); |
304 | socket = socket_ports_find( & udp_globals.sockets, ntohs( header->destination_port )); |
302 | if( ! socket ){ |
305 | if( ! socket ){ |
303 | tl_send_icmp_port_unreachable( udp_globals.net_phone, udp_globals.icmp_phone, packet, error ); |
306 | if( tl_prepare_icmp_packet( udp_globals.net_phone, udp_globals.icmp_phone, packet, error ) == EOK ){ |
- | 307 | icmp_destination_unreachable_msg( udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet ); |
|
- | 308 | } |
|
304 | return EADDRNOTAVAIL; |
309 | return EADDRNOTAVAIL; |
305 | } |
310 | } |
306 | 311 | ||
307 | // trim after successful processing to be able to send an ICMP error message! |
- | |
308 | ERROR_PROPAGATE( packet_trim( packet, offset, 0 )); |
- | |
309 | - | ||
310 | // count the received packet fragments |
312 | // count the received packet fragments |
311 | next_packet = packet; |
313 | next_packet = packet; |
312 | fragments = 0; |
314 | fragments = 0; |
313 | total_length = ntohs( header->total_length ); |
315 | total_length = ntohs( header->total_length ); |
314 | // compute header checksum if set |
316 | // compute header checksum if set |
Line 361... | Line 363... | ||
361 | }while(( next_packet = pq_next( next_packet )) && ( total_length > 0 )); |
363 | }while(( next_packet = pq_next( next_packet )) && ( total_length > 0 )); |
362 | 364 | ||
363 | // check checksum |
365 | // check checksum |
364 | if( header->checksum ){ |
366 | if( header->checksum ){ |
365 | if( flip_checksum( compact_checksum( checksum ))){ |
367 | if( flip_checksum( compact_checksum( checksum ))){ |
- | 368 | if( tl_prepare_icmp_packet( udp_globals.net_phone, udp_globals.icmp_phone, packet, error ) == EOK ){ |
|
366 | // TODO checksum error ICMP? |
369 | // checksum error ICMP |
367 | // TODO remove debug dump |
- | |
368 | printf("udp check failed %x => %x\n", header->checksum, flip_checksum( compact_checksum( checksum ))); |
370 | icmp_parameter_problem_msg( udp_globals.icmp_phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->checksum )) - (( size_t ) (( void * ) header )), packet ); |
- | 371 | } |
|
369 | return udp_release_and_return( packet, EINVAL ); |
372 | return EINVAL; |
370 | } |
373 | } |
371 | } |
374 | } |
372 | 375 | ||
373 | // queue the received packet |
376 | // queue the received packet |
374 | if( ERROR_OCCURRED( dyn_fifo_push( &( ** socket ).received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){ |
377 | if( ERROR_OCCURRED( dyn_fifo_push( &( ** socket ).received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){ |
Line 434... | Line 437... | ||
434 | break; |
437 | break; |
435 | case NET_SOCKET: |
438 | case NET_SOCKET: |
436 | // fibril_rwlock_write_lock( & lock ); |
439 | // fibril_rwlock_write_lock( & lock ); |
437 | res = socket_create( & local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID( answer )); |
440 | res = socket_create( & local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID( answer )); |
438 | // fibril_rwlock_write_unlock( & lock ); |
441 | // fibril_rwlock_write_unlock( & lock ); |
- | 442 | // TODO max fragment size |
|
439 | * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE; |
443 | * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE; |
440 | * SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t ); |
444 | * SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t ); |
441 | answer_count = 3; |
445 | answer_count = 3; |
442 | break; |
446 | break; |
443 | case NET_SOCKET_BIND: |
447 | case NET_SOCKET_BIND: |
Line 580... | Line 584... | ||
580 | } |
584 | } |
581 | if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( ip_header, headerlen, total_length + sizeof( udp_header_t )))){ |
585 | if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( ip_header, headerlen, total_length + sizeof( udp_header_t )))){ |
582 | free( ip_header ); |
586 | free( ip_header ); |
583 | return udp_release_and_return( packet, ERROR_CODE ); |
587 | return udp_release_and_return( packet, ERROR_CODE ); |
584 | } |
588 | } |
585 | /*// TODO remove debug dump: |
- | |
586 | uint8_t * data; |
- | |
587 | data = ip_header; |
- | |
588 | printf( "ip_header:\tlength\t= %d\n\tdata\t= %.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX\n", headerlen, data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ], data[ 8 ], data[ 9 ], data[ 10 ], data[ 11 ] ); |
- | |
589 | */ checksum = compute_checksum( checksum, ip_header, headerlen ); |
589 | checksum = compute_checksum( checksum, ip_header, headerlen ); |
590 | checksum = compute_checksum( checksum, ( uint8_t * ) header, sizeof( * header )); |
590 | checksum = compute_checksum( checksum, ( uint8_t * ) header, sizeof( * header )); |
591 | header->checksum = htons( flip_checksum( compact_checksum( checksum ))); |
591 | header->checksum = htons( flip_checksum( compact_checksum( checksum ))); |
592 | free( ip_header ); |
592 | free( ip_header ); |
593 | }else{ |
593 | }else{ |
594 | device_id = -1; |
594 | device_id = -1; |