Subversion Repositories HelenOS

Rev

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;