Rev 4726 | Rev 4730 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4726 | Rev 4728 | ||
|---|---|---|---|
| Line 269... | Line 269... | ||
| 269 | return udp_release_and_return( packet, NO_DATA ); |
269 | return udp_release_and_return( packet, NO_DATA ); |
| 270 | } |
270 | } |
| 271 | // get udp header |
271 | // get udp header |
| 272 | header = ( udp_header_ref )( data + offset ); |
272 | header = ( udp_header_ref )( data + offset ); |
| 273 | // find the destination socket |
273 | // find the destination socket |
| 274 | socket = socket_ports_find( & udp_globals.sockets, ntohs( header->dest )); |
274 | socket = socket_ports_find( & udp_globals.sockets, ntohs( header->destination_port )); |
| 275 | if( ! socket ){ |
275 | if( ! socket ){ |
| 276 | tl_send_icmp_port_unreachable( udp_globals.net_phone, udp_globals.icmp_phone, packet, error ); |
276 | tl_send_icmp_port_unreachable( udp_globals.net_phone, udp_globals.icmp_phone, packet, error ); |
| 277 | return EADDRNOTAVAIL; |
277 | return EADDRNOTAVAIL; |
| 278 | } |
278 | } |
| 279 | // trim after successful processing to be able to send an ICMP error message! |
279 | // trim after successful processing to be able to send an ICMP error message! |
| 280 | ERROR_PROPAGATE( packet_trim( packet, offset, 0 )); |
280 | ERROR_PROPAGATE( packet_trim( packet, offset, 0 )); |
| 281 | // count the received packet fragments |
281 | // count the received packet fragments |
| 282 | next_packet = packet; |
282 | next_packet = packet; |
| 283 | fragments = 0; |
283 | fragments = 0; |
| 284 | total_length = ntohs( header->len ); |
284 | total_length = ntohs( header->total_length ); |
| 285 | // compute header checksum if set |
285 | // compute header checksum if set |
| 286 | if( header->check && ( ! error )){ |
286 | if( header->checksum && ( ! error )){ |
| 287 | result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest ); |
287 | result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest ); |
| 288 | if( result <= 0 ){ |
288 | if( result <= 0 ){ |
| 289 | return udp_release_and_return( packet, result ); |
289 | return udp_release_and_return( packet, result ); |
| 290 | } |
290 | } |
| 291 | if( ERROR_OCCURRED( ip_client_get_pseudo_header( IPPROTO_UDP, src, result, dest, result, total_length, & ip_header, & length ))){ |
291 | if( ERROR_OCCURRED( ip_client_get_pseudo_header( IPPROTO_UDP, src, result, dest, result, total_length, & ip_header, & length ))){ |
| Line 294... | Line 294... | ||
| 294 | checksum = compute_checksum( 0, ip_header, length ); |
294 | checksum = compute_checksum( 0, ip_header, length ); |
| 295 | // the udp header checksum will be added with the first fragment later |
295 | // the udp header checksum will be added with the first fragment later |
| 296 | free( ip_header ); |
296 | free( ip_header ); |
| 297 | } |
297 | } |
| 298 | }else{ |
298 | }else{ |
| 299 | header->check = 0; |
299 | header->checksum = 0; |
| 300 | checksum = 0; |
300 | checksum = 0; |
| 301 | } |
301 | } |
| 302 | do{ |
302 | do{ |
| 303 | ++ fragments; |
303 | ++ fragments; |
| 304 | length = packet_get_data_length( next_packet ); |
304 | length = packet_get_data_length( next_packet ); |
| Line 308... | Line 308... | ||
| 308 | if( total_length < length ){ |
308 | if( total_length < length ){ |
| 309 | if( ERROR_OCCURRED( packet_trim( next_packet, 0, length - total_length ))){ |
309 | if( ERROR_OCCURRED( packet_trim( next_packet, 0, length - total_length ))){ |
| 310 | return udp_release_and_return( packet, ERROR_CODE ); |
310 | return udp_release_and_return( packet, ERROR_CODE ); |
| 311 | } |
311 | } |
| 312 | // add partial checksum if set |
312 | // add partial checksum if set |
| 313 | if( header->check ){ |
313 | if( header->checksum ){ |
| 314 | checksum = compute_checksum( checksum, packet_get_data( packet ), packet_get_data_length( packet )); |
314 | checksum = compute_checksum( checksum, packet_get_data( packet ), packet_get_data_length( packet )); |
| 315 | } |
315 | } |
| 316 | // relese the rest of the packet fragments |
316 | // relese the rest of the packet fragments |
| 317 | tmp_packet = pq_next( next_packet ); |
317 | tmp_packet = pq_next( next_packet ); |
| 318 | while( tmp_packet ){ |
318 | while( tmp_packet ){ |
| Line 323... | Line 323... | ||
| 323 | // exit the loop |
323 | // exit the loop |
| 324 | break; |
324 | break; |
| 325 | } |
325 | } |
| 326 | total_length -= length; |
326 | total_length -= length; |
| 327 | // add partial checksum if set |
327 | // add partial checksum if set |
| 328 | if( header->check ){ |
328 | if( header->checksum ){ |
| 329 | checksum = compute_checksum( checksum, packet_get_data( packet ), packet_get_data_length( packet )); |
329 | checksum = compute_checksum( checksum, packet_get_data( packet ), packet_get_data_length( packet )); |
| 330 | } |
330 | } |
| 331 | }while(( next_packet = pq_next( next_packet )) && ( total_length > 0 )); |
331 | }while(( next_packet = pq_next( next_packet )) && ( total_length > 0 )); |
| 332 | // check checksum |
332 | // check checksum |
| 333 | if( header->check ){ |
333 | if( header->checksum ){ |
| 334 | if( flip_checksum( compact_checksum( checksum ))){ |
334 | if( flip_checksum( compact_checksum( checksum ))){ |
| 335 | // TODO checksum error ICMP? |
335 | // TODO checksum error ICMP? |
| 336 | // TODO remove debug dump |
336 | // TODO remove debug dump |
| 337 | printf("udp check failed %x => %x\n", header->check, flip_checksum( compact_checksum( checksum ))); |
337 | printf("udp check failed %x => %x\n", header->checksum, flip_checksum( compact_checksum( checksum ))); |
| 338 | return udp_release_and_return( packet, EINVAL ); |
338 | return udp_release_and_return( packet, EINVAL ); |
| 339 | } |
339 | } |
| 340 | } |
340 | } |
| 341 | // queue the received packet |
341 | // queue the received packet |
| 342 | if( ERROR_OCCURRED( dyn_fifo_push( &( ** socket ).received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){ |
342 | if( ERROR_OCCURRED( dyn_fifo_push( &( ** socket ).received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){ |
| Line 534... | Line 534... | ||
| 534 | if( udp_globals.checksum_computing ){ |
534 | if( udp_globals.checksum_computing ){ |
| 535 | checksum = compute_checksum( checksum, packet_get_data( next_packet ), packet_get_data_length( next_packet )); |
535 | checksum = compute_checksum( checksum, packet_get_data( next_packet ), packet_get_data_length( next_packet )); |
| 536 | } |
536 | } |
| 537 | } |
537 | } |
| 538 | // set the udp header |
538 | // set the udp header |
| 539 | header->source = htons( socket->port ); |
539 | header->source_port = htons( socket->port ); |
| 540 | header->dest = htons( dest_port ); |
540 | header->destination_port = htons( dest_port ); |
| 541 | header->len = htons( total_length + sizeof( udp_header_t )); |
541 | header->total_length = htons( total_length + sizeof( udp_header_t )); |
| 542 | header->check = 0; |
542 | header->checksum = 0; |
| 543 | if( udp_globals.checksum_computing ){ |
543 | if( udp_globals.checksum_computing ){ |
| 544 | if( ERROR_OCCURRED( ip_get_route_req( udp_globals.ip_phone, IPPROTO_UDP, addr, addrlen, & device_id, & ip_header, & headerlen ))){ |
544 | if( ERROR_OCCURRED( ip_get_route_req( udp_globals.ip_phone, IPPROTO_UDP, addr, addrlen, & device_id, & ip_header, & headerlen ))){ |
| 545 | return udp_release_and_return( packet, ERROR_CODE ); |
545 | return udp_release_and_return( packet, ERROR_CODE ); |
| 546 | } |
546 | } |
| 547 | if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( ip_header, headerlen, total_length + sizeof( udp_header_t )))){ |
547 | if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( ip_header, headerlen, total_length + sizeof( udp_header_t )))){ |
| Line 552... | Line 552... | ||
| 552 | uint8_t * data; |
552 | uint8_t * data; |
| 553 | data = ip_header; |
553 | data = ip_header; |
| 554 | 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 ] ); |
554 | 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 ] ); |
| 555 | */ checksum = compute_checksum( checksum, ip_header, headerlen ); |
555 | */ checksum = compute_checksum( checksum, ip_header, headerlen ); |
| 556 | checksum = compute_checksum( checksum, ( uint8_t * ) header, sizeof( * header )); |
556 | checksum = compute_checksum( checksum, ( uint8_t * ) header, sizeof( * header )); |
| 557 | header->check = htons( flip_checksum( compact_checksum( checksum ))); |
557 | header->checksum = htons( flip_checksum( compact_checksum( checksum ))); |
| 558 | free( ip_header ); |
558 | free( ip_header ); |
| 559 | }else{ |
559 | }else{ |
| 560 | device_id = -1; |
560 | device_id = -1; |
| 561 | } |
561 | } |
| 562 | // prepare the first packet fragment |
562 | // prepare the first packet fragment |
| Line 598... | Line 598... | ||
| 598 | } |
598 | } |
| 599 | header = ( udp_header_ref ) data; |
599 | header = ( udp_header_ref ) data; |
| 600 | 600 | ||
| 601 | // set the source address port |
601 | // set the source address port |
| 602 | result = packet_get_addr( packet, ( uint8_t ** ) & addr, NULL ); |
602 | result = packet_get_addr( packet, ( uint8_t ** ) & addr, NULL ); |
| 603 | if( ERROR_OCCURRED( tl_set_address_port( addr, result, ntohs( header->source )))){ |
603 | if( ERROR_OCCURRED( tl_set_address_port( addr, result, ntohs( header->source_port )))){ |
| 604 | pq_release( udp_globals.net_phone, packet_id ); |
604 | pq_release( udp_globals.net_phone, packet_id ); |
| 605 | return ERROR_CODE; |
605 | return ERROR_CODE; |
| 606 | } |
606 | } |
| 607 | * addrlen = ( size_t ) result; |
607 | * addrlen = ( size_t ) result; |
| 608 | // send the source address |
608 | // send the source address |