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 |