Subversion Repositories HelenOS

Rev

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