Subversion Repositories HelenOS

Rev

Rev 4722 | Rev 4728 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4722 Rev 4724
Line 145... Line 145...
145
/** Returns the fragment offest.
145
/** Returns the fragment offest.
146
 *  @param length The prefixed data total length. Input parameter.
146
 *  @param length The prefixed data total length. Input parameter.
147
 */
147
 */
148
#define IP_FRAGMENT_OFFSET( length ) (( length ) / 8 )
148
#define IP_FRAGMENT_OFFSET( length ) (( length ) / 8 )
149
 
149
 
-
 
150
/** The IP localhost address.
-
 
151
 */
-
 
152
#define IPV4_LOCALHOST_ADDRESS  htonl(( 127 << 24 ) + 1 )
-
 
153
 
150
/** IP global data.
154
/** IP global data.
151
 */
155
 */
152
ip_globals_t    ip_globals;
156
ip_globals_t    ip_globals;
153
 
157
 
154
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
158
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
Line 571... Line 575...
571
    if( !( netif && route )){
575
    if( !( netif && route )){
572
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
576
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
573
        phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
577
        phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
574
        if( phone >= 0 ){
578
        if( phone >= 0 ){
575
            // unreachable ICMP if no routing
579
            // unreachable ICMP if no routing
576
            icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
580
            icmp_destination_unreachable_msg( phone, ICMP_NET_UNREACH, 0, packet );
577
        }
581
        }
578
        return ENOENT;
582
        return ENOENT;
579
    }
583
    }
580
    if( error ){
584
    if( error ){
581
        // do not send for broadcast, anycast packets or network broadcast
585
        // do not send for broadcast, anycast packets or network broadcast
Line 584... Line 588...
584
        || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr )))
588
        || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr )))
585
        || ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){
589
        || ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){
586
            return ip_release_and_return( packet, EINVAL );
590
            return ip_release_and_return( packet, EINVAL );
587
        }
591
        }
588
    }
592
    }
-
 
593
    if( route->address.s_addr == dest->s_addr ){
-
 
594
        // find the loopback device to deliver
-
 
595
        dest->s_addr = IPV4_LOCALHOST_ADDRESS;
-
 
596
        route = ip_find_route( * dest );
-
 
597
        netif = route ? route->netif : NULL;
-
 
598
        if( !( netif && route )){
-
 
599
            fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
-
 
600
            phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
-
 
601
            if( phone >= 0 ){
-
 
602
                // unreachable ICMP if no routing
-
 
603
                icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
-
 
604
            }
-
 
605
            return ENOENT;
-
 
606
        }
-
 
607
    }
589
    src = ip_netif_address( netif );
608
    src = ip_netif_address( netif );
590
    if( ! src ){
609
    if( ! src ){
591
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
610
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
592
        return ip_release_and_return( packet, ENOENT );
611
        return ip_release_and_return( packet, ENOENT );
593
    }
612
    }