/branches/network/uspace/srv/net/nil/eth/eth.c |
---|
80,7 → 80,7 |
/** Minimum packet content length. |
*/ |
#define ETH_MIN_CONTENT 46 |
#define ETH_MIN_CONTENT 46u |
/** Maximum tagged packet content length. |
*/ |
381,10 → 381,11 |
eth_header_ex_ref header; |
size_t length; |
int type; |
eth_type_t type; |
size_t prefix; |
size_t suffix; |
eth_fcs_ref fcs; |
uint8_t * data; |
length = packet_get_data_length( packet ); |
if( IS_DUMMY( flags )){ |
391,13 → 392,15 |
packet_trim( packet, sizeof( eth_preamble_t ), 0 ); |
} |
if( length < sizeof( eth_header_t ) + ETH_MIN_CONTENT + ( IS_DUMMY( flags ) ? ETH_SUFFIX : 0 )) return NULL; |
header = ( eth_header_ex_ref ) packet_get_data( packet ); |
data = packet_get_data( packet ); |
header = ( eth_header_ex_ref ) data; |
type = ntohs( header->header.ethertype ); |
if( type >= ETH_MIN_PROTO ){ |
// DIX Ethernet |
prefix = sizeof( eth_header_t ); |
suffix = 0; |
fcs = (( void * ) header ) + length - sizeof( eth_fcs_t ); |
fcs = ( eth_fcs_ref ) data + length - sizeof( eth_fcs_t ); |
length -= sizeof( eth_fcs_t ); |
}else if( type <= ETH_MAX_CONTENT ){ |
// translate "LSAP" values |
if(( header->lsap.dsap == ETH_LSAP_GLSAP ) && ( header->lsap.ssap == ETH_LSAP_GLSAP )){ |
414,15 → 417,16 |
type = lsap_map( header->lsap.dsap ); |
prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t); |
} |
suffix = ( type < ETH_MIN_CONTENT ) ? ETH_MIN_CONTENT - type : 0; |
fcs = (( void * ) header ) + prefix + type + suffix; |
suffix = ( type < ETH_MIN_CONTENT ) ? ETH_MIN_CONTENT - type : 0u; |
fcs = ( eth_fcs_ref ) data + prefix + type + suffix; |
suffix += length - prefix - type; |
length = prefix + type + suffix; |
}else{ |
// invalid length/type, should not occurr |
return NULL; |
} |
if( IS_DUMMY( flags )){ |
if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ntohl( * fcs )){ |
if(( ~ compute_crc32( ~ 0u, data, length * 8 )) != ntohl( * fcs )){ |
return NULL; |
} |
suffix += sizeof( eth_fcs_t ); |
541,14 → 545,14 |
eth_fcs_ref fcs; |
uint8_t * src; |
uint8_t * dest; |
int length; |
size_t length; |
int i; |
void * padding; |
eth_preamble_ref preamble; |
length = packet_get_addr( packet, & src, & dest ); |
if( length < 0 ) return length; |
if( length != ETH_ADDR ) return EINVAL; |
i = packet_get_addr( packet, & src, & dest ); |
if( i < 0 ) return i; |
if( i != ETH_ADDR ) return EINVAL; |
length = packet_get_data_length( packet ); |
if( length > mtu ) return EINVAL; |
if( length < ETH_MIN_TAGGED_CONTENT( flags )){ |
586,7 → 590,7 |
if( IS_DUMMY( flags )){ |
fcs = PACKET_SUFFIX( packet, eth_fcs_t ); |
if( ! fcs ) return ENOMEM; |
* fcs = htonl( ~ compute_crc32( ~ 0, src, ((( void * ) fcs ) - (( void * ) src )) * 8 )); |
* fcs = htonl( ~ compute_crc32( ~ 0u, src, length * 8 )); |
} |
return EOK; |
} |
679,10 → 683,10 |
if( ! ERROR_OCCURRED( packet_translate( eth_globals.net_phone, & packet, IPC_GET_PACKET( icall )))){ |
ERROR_CODE = nil_received_msg( 0, IPC_GET_DEVICE( icall ), packet, 0 ); |
} |
ipc_answer_0( iid, ERROR_CODE ); |
ipc_answer_0( iid, ( ipcarg_t ) ERROR_CODE ); |
break; |
default: |
ipc_answer_0( iid, ENOTSUP ); |
ipc_answer_0( iid, ( ipcarg_t ) ENOTSUP ); |
} |
iid = async_get_call( icall ); |
} |
/branches/network/uspace/srv/net/include/ethernet_lsap.h |
---|
37,6 → 37,10 |
#ifndef __NET_ETHERNET_LSAP_H__ |
#define __NET_ETHERNET_LSAP_H__ |
#include <sys/types.h> |
typedef uint8_t eth_lsap_t; |
/** Null LSAP LSAP identifier. |
*/ |
#define ETH_LSAP_NULL 0x00 |
/branches/network/uspace/srv/net/include/hardware.h |
---|
38,6 → 38,10 |
#ifndef __NET_HW_TYPES_H__ |
#define __NET_HW_TYPES_H__ |
#include <sys/types.h> |
typedef uint8_t hw_type_t; |
/** Ethernet (10Mb) hardware type. |
*/ |
#define HW_ETHER 1 |
/branches/network/uspace/srv/net/include/protocol_map.h |
---|
49,7 → 49,7 |
* @returns Network interface layer type of the internetworking layer service. |
* @returns 0 if mapping is not found. |
*/ |
static inline int protocol_map( services_t nil, services_t il ){ |
static inline eth_type_t protocol_map( services_t nil, services_t il ){ |
switch( nil ){ |
case SERVICE_ETHERNET: |
case SERVICE_DP8390: |
94,7 → 94,7 |
* @returns Ethernet protocol identifier of the link service access point identifier. |
* @returns ETH_LSAP_NULL if mapping is not found. |
*/ |
static inline int lsap_map( int lsap ){ |
static inline int lsap_map( eth_lsap_t lsap ){ |
switch( lsap ){ |
case ETH_LSAP_IP: |
return ETH_P_IP; |
110,7 → 110,7 |
* @returns The hardware type of the network interface service. |
* @returns 0 if mapping is not found. |
*/ |
static inline int hardware_map( services_t nil ){ |
static inline hw_type_t hardware_map( services_t nil ){ |
switch( nil ){ |
case SERVICE_ETHERNET: |
case SERVICE_DP8390: |
/branches/network/uspace/srv/net/include/ip_client.h |
---|
37,6 → 37,12 |
#ifndef __NET_IP_CLIENT_H__ |
#define __NET_IP_CLIENT_H__ |
#include <sys/types.h> |
typedef uint8_t ip_ttl_t; |
typedef uint8_t ip_tos_t; |
typedef uint8_t ip_protocol_t; |
#include "../structures/packet/packet.h" |
#define IPVERSION 4 |
127,7 → 133,7 |
#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ |
#define IPOPT_TS_PRESPEC 3 /* specified modules only */ |
int ip_client_prepare_packet( packet_t packet, int protocol, int ttl, int tos, int dont_fragment, int ipopt_length ); |
int ip_client_prepare_packet( packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length ); |
// TODO ipopt manipulation |
/branches/network/uspace/srv/net/include/crc.h |
---|
59,7 → 59,7 |
* @param length Length of the data in bits. Input parameter. |
* @returns The computed CRC32 of the length bits of the data. |
*/ |
uint32_t compute_crc32_le( uint32_t seed, uint8_t * data, int length ); |
uint32_t compute_crc32_le( uint32_t seed, uint8_t * data, size_t length ); |
/** Computes CRC32 value in the big-endian environment. |
* @param seed Initial value. Often used as 0 or ~0. Input parameter. |
67,7 → 67,7 |
* @param length Length of the data in bits. Input parameter. |
* @returns The computed CRC32 of the length bits of the data. |
*/ |
uint32_t compute_crc32_be( uint32_t seed, uint8_t * data, int length ); |
uint32_t compute_crc32_be( uint32_t seed, uint8_t * data, size_t length ); |
/** Computes sum of the 2 byte fields. |
* Padds one zero (0) byte if odd. |
76,7 → 76,7 |
* @param length Length of the data in bytes. Input parameter. |
* @returns The computed checksum of the length bytes of the data. |
*/ |
uint32_t compute_checksum( uint32_t seed, uint8_t * data, int length ); |
uint32_t compute_checksum( uint32_t seed, uint8_t * data, size_t length ); |
/** Compacts the computed checksum to the 16 bit number adding the carries. |
* @param Computed checksum. Input parameter. |
/branches/network/uspace/srv/net/include/ethernet_protocols.h |
---|
38,6 → 38,10 |
#ifndef __NET_ETHERNET_PROTOCOLS_H__ |
#define __NET_ETHERNET_PROTOCOLS_H__ |
#include <sys/types.h> |
typedef uint16_t eth_type_t; |
/** Ethernet minimal protocol number. |
* According to the IEEE 802.3 specification. |
*/ |
/branches/network/uspace/srv/net/crc.c |
---|
42,7 → 42,7 |
#define CRC_DIVIDER_LE 0xEDB88320 |
uint32_t compute_crc32_le( uint32_t seed, uint8_t * data, int length ){ |
uint32_t compute_crc32_le( uint32_t seed, uint8_t * data, size_t length ){ |
int index; |
while( length >= 8 ){ |
71,7 → 71,7 |
return seed; |
} |
uint32_t compute_crc32_be( uint32_t seed, uint8_t * data, int length ){ |
uint32_t compute_crc32_be( uint32_t seed, uint8_t * data, size_t length ){ |
int index; |
while( length >= 8 ){ |
100,16 → 100,16 |
return seed; |
} |
uint32_t compute_checksum( uint32_t seed, uint8_t * data, int length ){ |
int index; |
uint32_t compute_checksum( uint32_t seed, uint8_t * data, size_t length ){ |
size_t index; |
// sum all the 16 bit fields |
for( index = 0; index < length - 1; index += 2 ){ |
for( index = 0; index + 1 < length; index += 2 ){ |
seed += ( data[ index ] << 8 ) + data[ index + 1 ]; |
} |
// last odd byte with zero padding |
if( index == length - 1 ){ |
if( index + 1 == length ){ |
seed += data[ index ] << 8; |
} |
/branches/network/uspace/srv/net/il/arp/arp.c |
---|
236,6 → 236,7 |
arp_device_ref device; |
arp_proto_ref proto; |
int index; |
hw_type_t hardware; |
rwlock_write_lock( & arp_globals.lock ); |
// an existing device? |
266,8 → 267,8 |
printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol ); |
} |
}else{ |
index = hardware_map( service ); |
if( ! index ) return ENOENT; |
hardware = hardware_map( service ); |
if( ! hardware ) return ENOENT; |
// create a new device |
device = ( arp_device_ref ) malloc( sizeof( arp_device_t )); |
if( ! device ){ |
274,7 → 275,7 |
rwlock_write_unlock( & arp_globals.lock ); |
return ENOMEM; |
} |
device->hardware = index; |
device->hardware = hardware; |
device->device_id = device_id; |
if( ERROR_OCCURRED( arp_protos_initialize( & device->protos )) |
|| ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){ |
291,7 → 292,7 |
} |
device->service = service; |
// bind the new one |
device->phone = bind_service( device->service, device->device_id, SERVICE_ARP, 0, arp_globals.client_connection ); |
device->phone = bind_service( device->service, ( ipcarg_t ) device->device_id, SERVICE_ARP, 0, arp_globals.client_connection ); |
if( device->phone < 0 ){ |
rwlock_write_unlock( & arp_globals.lock ); |
arp_protos_destroy( & device->protos ); |
363,9 → 364,9 |
return NULL; |
} |
header->hardware = htons( device->hardware ); |
header->hardware_length = device->addr->length; |
header->hardware_length = ( uint8_t ) device->addr->length; |
header->protocol = htons( protocol_map( device->service, protocol )); |
header->protocol_length = proto->addr->length; |
header->protocol_length = ( uint8_t ) proto->addr->length; |
header->operation = htons( ARPOP_REQUEST ); |
length = sizeof( arp_header_t ); |
memcpy((( uint8_t * ) header ) + length, device->addr->value, device->addr->length ); |
402,7 → 403,8 |
if( ! device ) return ENOENT; |
header = ( arp_header_ref ) packet_get_data( packet ); |
if(( ntohs( header->hardware ) != device->hardware ) |
|| ( length < sizeof( arp_header_t ) + ( header->hardware_length + header->protocol_length ) * 2 )){ |
// TODO how remove conversion from int '2' to uint? |
|| ( length < sizeof( arp_header_t ) + ( header->hardware_length + header->protocol_length ) * 2u )){ |
return EINVAL; |
} |
proto = arp_protos_find( & device->protos, protocol_unmap( device->service, ntohs( header->protocol ))); |
/branches/network/uspace/srv/net/il/arp/arp.h |
---|
43,6 → 43,7 |
#include <ipc/services.h> |
#include "../../include/device.h" |
#include "../../include/hardware.h" |
#include "../../structures/generic_char_map.h" |
#include "../../structures/int_map.h" |
100,7 → 101,7 |
device_id_t device_id; |
/** Hardware type. |
*/ |
ipcarg_t hardware; |
hw_type_t hardware; |
/** Reserved packet prefix length. |
*/ |
size_t prefix; |
/branches/network/uspace/srv/net/il/arp/arp_remote.c |
---|
55,10 → 55,10 |
aid_t message_id; |
ipcarg_t result; |
message_id = async_send_3( arp_phone, NET_ARP_DEVICE, device_id, protocol, netif, NULL ); |
message_id = async_send_3( arp_phone, NET_ARP_DEVICE, ( ipcarg_t ) device_id, protocol, netif, NULL ); |
measured_strings_send( arp_phone, address, 1 ); |
async_wait_for( message_id, & result ); |
return result; |
return ( int ) result; |
} |
int arp_translate_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data ){ |
66,11 → 66,11 |
} |
int arp_clear_device_req( int arp_phone, device_id_t device_id ){ |
return async_req_1_0( arp_phone, NET_ARP_CLEAR_DEVICE, device_id ); |
return ( int ) async_req_1_0( arp_phone, NET_ARP_CLEAR_DEVICE, ( ipcarg_t ) device_id ); |
} |
int arp_clean_cache_req( int arp_phone ){ |
return async_req_0_0( arp_phone, NET_ARP_CLEAN_CACHE ); |
return ( int ) async_req_0_0( arp_phone, NET_ARP_CLEAN_CACHE ); |
} |
int arp_connect_module( services_t service ){ |
/branches/network/uspace/srv/net/il/ip/ip_remote.c |
---|
39,8 → 39,8 |
#include "../../modules.h" |
#include "../../include/device.h" |
#include "../../include/inet.h" |
#include "../../include/ip_interface.h" |
#include "../../include/sockaddr.h" |
#include "../../structures/packet/packet_client.h" |
61,11 → 61,11 |
} |
int ip_add_route_req( int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway ){ |
return async_req_4_0( ip_phone, NET_IP_ADD_ROUTE, device_id, ( ipcarg_t ) gateway.s_addr, ( ipcarg_t ) address.s_addr, ( ipcarg_t ) netmask.s_addr ); |
return ( int ) async_req_4_0( ip_phone, NET_IP_ADD_ROUTE, ( ipcarg_t ) device_id, ( ipcarg_t ) gateway.s_addr, ( ipcarg_t ) address.s_addr, ( ipcarg_t ) netmask.s_addr ); |
} |
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){ |
return async_req_2_0( ip_phone, NET_IP_SET_GATEWAY, device_id, ( ipcarg_t ) gateway.s_addr ); |
return ( int ) async_req_2_0( ip_phone, NET_IP_SET_GATEWAY, ( ipcarg_t ) device_id, ( ipcarg_t ) gateway.s_addr ); |
} |
int ip_packet_size_req( int ip_phone, device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ |
73,7 → 73,7 |
} |
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg ){ |
return bind_service( service, protocol, me, service, receiver ); |
return ( int ) bind_service( service, ( ipcarg_t ) protocol, me, service, receiver ); |
} |
/** @} |
/branches/network/uspace/srv/net/il/ip/ip_client.c |
---|
45,10 → 45,10 |
#include "ip_header.h" |
int ip_client_prepare_packet( packet_t packet, int protocol, int ttl, int tos, int dont_fragment, int ipopt_length ){ |
int ip_client_prepare_packet( packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length ){ |
ip_header_ref header; |
uint8_t * data; |
int padding; |
size_t padding; |
padding = ipopt_length % 4; |
if( padding ){ |
59,8 → 59,8 |
if( ! data ) return ENOMEM; |
while( padding -- ) data[ sizeof( ip_header_t ) + padding ] = IPOPT_NOOP; |
header = ( ip_header_ref ) data; |
header->ihl = ( sizeof( ip_header_t ) + ipopt_length ) / 4; |
header->ttl = ( ttl > 0 ) ? (( ttl <= MAXTTL ) ? ttl : MAXTTL ) : IPDEFTTL; |
header->ihl = ( uint8_t ) ( sizeof( ip_header_t ) + ipopt_length ) / 4; |
header->ttl = ttl ? (( ttl <= MAXTTL ) ? ttl : MAXTTL ) : IPDEFTTL; |
header->tos = tos; |
header->protocol = protocol; |
if( dont_fragment ) header->flags = IPFLAG_DONT_FRAGMENT; |
/branches/network/uspace/srv/net/il/ip/ip.c |
---|
35,6 → 35,7 |
#include <async.h> |
#include <errno.h> |
#include <rwlock.h> |
#include <stdio.h> |
#include <string.h> |
48,7 → 49,7 |
#include "../../modules.h" |
#include "../../include/net_interface.h" |
#include "../../include/sockaddr.h" |
#include "../../include/inet.h" |
#include "../../include/socket.h" |
#include "../../include/byteorder.h" |
#include "../../include/crc.h" |
82,13 → 83,13 |
#define IP_PREFIX sizeof( ip_header_t ) |
#define IP_SUFFIX 0 |
#define IP_MAX_CONTENT 65535 |
#define IP_HEADER_LENGTH( header ) (( header )->ihl * 4 ) |
#define IP_HEADER_LENGTH( header ) (( header )->ihl * 4u ) |
#define IP_TOTAL_LENGTH( header ) ntohs(( header )->total_length ) |
#define IP_HEADER_DATA_LENGTH( header ) ( IP_TOTAL_LENGTH( header ) - IP_HEADER_LENGTH( header )) |
#define IP_HEADER_CHECKSUM( header ) ( htons( ip_checksum(( uint8_t * )( header ), IP_HEADER_LENGTH( header )))) |
//zero is returned as 0xFFFF (not flipped) |
#define IP_HEADER_CHECKSUM_ZERO 0xFFFF |
#define IP_HEADER_CHECKSUM_ZERO 0xFFFFu |
ip_globals_t ip_globals; |
127,11 → 128,11 |
* @param data The header data. Input parameter. |
* @param length The header length in bytes. Input parameter. |
* @returns The internet protocol header checksum. |
* @returns IP_HEADER_CHECKSUM_ZERO if the computed checksum is zero. |
* @returns 0xFFFF if the computed checksum is zero. |
*/ |
uint16_t ip_checksum( uint8_t * data, int length ); |
uint16_t ip_checksum( uint8_t * data, size_t length ); |
uint16_t ip_checksum( uint8_t * data, int length ){ |
uint16_t ip_checksum( uint8_t * data, size_t length ){ |
uint16_t checksum; |
checksum = compact_checksum(compute_checksum( 0, data, length )); |
145,6 → 146,10 |
int ip_initialize( async_client_conn_t client_connection ){ |
ERROR_DECLARE; |
rwlock_initialize( & ip_globals.lock ); |
rwlock_write_lock( & ip_globals.lock ); |
rwlock_initialize( & ip_globals.protos_lock ); |
rwlock_initialize( & ip_globals.netifs_lock ); |
ip_globals.packet_counter = 0; |
ip_globals.gateway.address.s_addr = 0; |
ip_globals.gateway.netmask.s_addr = 0; |
155,6 → 160,7 |
ip_globals.client_connection = client_connection; |
ERROR_PROPAGATE( modules_initialize( & ip_globals.modules )); |
ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module )); |
rwlock_write_unlock( & ip_globals.lock ); |
return EOK; |
} |
175,7 → 181,9 |
ip_netif->device_id = device_id; |
ip_netif->service = netif; |
ip_netif->state = NETIF_STOPPED; |
rwlock_write_lock( & ip_globals.netifs_lock ); |
if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){ |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
ip_routes_destroy( & ip_netif->routes ); |
free( ip_netif ); |
return ERROR_CODE; |
207,6 → 215,7 |
printf( "\tdns2\t= %s\n", data ); |
free( data ); |
} |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
return EOK; |
} |
279,7 → 288,7 |
} |
net_free_settings( configuration, data ); |
} |
ip_netif->phone = bind_service( ip_netif->service, ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection ); |
ip_netif->phone = bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection ); |
if( ip_netif->phone < 0 ){ |
printf( "Failed to contact the nil service %d\n", ip_netif->service ); |
return ip_netif->phone; |
324,11 → 333,16 |
*/ |
ip_netif_ref netif; |
rwlock_write_lock( & ip_globals.netifs_lock ); |
netif = ip_netifs_find( & ip_globals.netifs, device_id ); |
if( ! netif ) return ENOENT; |
if( ! netif ){ |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
return ENOENT; |
} |
netif->state = state; |
// TODO state |
printf( "ip - device %d changed state to %d\n\n", device_id, state ); |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
// if( netif->arp ){ |
/* address.value = ( char * ) & ip_globals.gateway.gateway.s_addr; |
address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 ); |
377,27 → 391,30 |
return EOK; |
} |
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg ){ |
return ip_register( protocol, me, 0, tl_received_msg ); |
int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){ |
return ip_register( protocol, me, 0, received_msg ); |
} |
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg ){ |
int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){ |
ip_proto_ref proto; |
int index; |
if( !( protocol && service && (( phone > 0 ) || ( tl_received_msg )))) return EINVAL; |
if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL; |
proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t )); |
if( ! proto ) return ENOMEM; |
proto->protocol = protocol; |
proto->service = service; |
proto->phone = phone; |
proto->tl_received_msg = tl_received_msg; |
proto->received_msg = received_msg; |
rwlock_write_lock( & ip_globals.protos_lock ); |
index = ip_protos_add( & ip_globals.protos, proto->protocol, proto ); |
if( index < 0 ){ |
rwlock_write_unlock( & ip_globals.protos_lock ); |
free( proto ); |
return index; |
} |
printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone ); |
rwlock_write_unlock( & ip_globals.protos_lock ); |
return EOK; |
} |
422,7 → 439,7 |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
return EINVAL; |
} |
// rwlock_read_lock( & ip_globals.devices_lock ); |
rwlock_read_lock( & ip_globals.netifs_lock ); |
// device specified? |
// dest.s_addr = ntohl( dest.s_addr ); |
if( device_id ){ |
434,7 → 451,7 |
netif = route ? route->netif : NULL; |
} |
if( !( netif && route )){ |
// rwlock_read_unlock( & ip_globals.devices_lock ); |
rwlock_read_unlock( & ip_globals.netifs_lock ); |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
return ENOENT; |
} |
441,10 → 458,13 |
// to me? |
if( route->address.s_addr == dest.s_addr ){ |
// TODO loopback deliver |
rwlock_read_unlock( & ip_globals.netifs_lock ); |
return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet )); |
} |
src = ip_netif_addr( netif ); |
if( ! src ){ |
rwlock_read_unlock( & ip_globals.netifs_lock ); |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
return ENOENT; |
} |
451,6 → 471,7 |
if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, dest ))){ |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
} |
rwlock_read_unlock( & ip_globals.netifs_lock ); |
return ERROR_CODE; |
} |
514,7 → 535,6 |
nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP ); |
} |
} |
// rwlock_read_unlock( & ip_globals.netifs_lock ); |
return EOK; |
} |
521,7 → 541,7 |
int ip_prepare_packet( in_addr_t * source, packet_t packet, measured_string_ref destination ){ |
ERROR_DECLARE; |
int length; |
size_t length; |
ip_header_ref header; |
length = packet_get_data_length( packet ); |
534,8 → 554,10 |
header->total_length = htons( length ); |
header->fragment_offset = 0; |
if( source ) header->source_address = source->s_addr;//htonl( source.s_addr ); |
rwlock_write_lock( & ip_globals.lock ); |
++ ip_globals.packet_counter; |
header->identification = htons( ip_globals.packet_counter ); |
rwlock_write_unlock( & ip_globals.lock ); |
header->header_checksum = 0; |
// unnecessary for all protocols |
header->header_checksum = IP_HEADER_CHECKSUM( header ); |
581,10 → 603,10 |
ip_netif_ref netif; |
if( !( addr_len && prefix && content && suffix )) return EBADMEM; |
// rwlock_read_lock( & ip_globals.netifs_lock ); |
rwlock_read_lock( & ip_globals.netifs_lock ); |
netif = ip_netifs_find( & ip_globals.netifs, device_id ); |
if( ! netif ){ |
// rwlock_read_unlock( & ip_globals.netifs_lock ); |
rwlock_read_unlock( & ip_globals.netifs_lock ); |
return ENOENT; |
} |
* content = IP_MAX_CONTENT - IP_PREFIX; |
591,7 → 613,7 |
* addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR; |
* prefix = netif->prefix + IP_PREFIX; |
* suffix = netif->suffix + IP_SUFFIX; |
// rwlock_read_unlock( & ip_globals.netifs_lock ); |
rwlock_read_unlock( & ip_globals.netifs_lock ); |
return EOK; |
} |
600,10 → 622,17 |
ip_netif_ref netif; |
int index; |
rwlock_write_lock( & ip_globals.netifs_lock ); |
netif = ip_netifs_find( & ip_globals.netifs, device_id ); |
if( ! netif ) return ENOENT; |
if( ! netif ){ |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
return ENOENT; |
} |
route = ( ip_route_ref ) malloc( sizeof( ip_route_t )); |
if( ! route ) return ENOMEM; |
if( ! route ){ |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
return ENOMEM; |
} |
route->address.s_addr = address.s_addr; |
route->netmask.s_addr = netmask.s_addr; |
route->gateway.s_addr = gateway.s_addr; |
610,6 → 639,7 |
route->netif = netif; |
index = ip_routes_add( & netif->routes, route ); |
if( index < 0 ) free( route ); |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
return index; |
} |
650,12 → 680,17 |
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){ |
ip_netif_ref netif; |
rwlock_write_lock( & ip_globals.netifs_lock ); |
netif = ip_netifs_find( & ip_globals.netifs, device_id ); |
if( ! netif ) return ENOENT; |
if( ! netif ){ |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
return ENOENT; |
} |
ip_globals.gateway.address.s_addr = 0; |
ip_globals.gateway.netmask.s_addr = 0; |
ip_globals.gateway.gateway.s_addr = gateway.s_addr; |
ip_globals.gateway.netif = netif; |
rwlock_write_unlock( & ip_globals.netifs_lock ); |
return EOK; |
} |
708,7 → 743,7 |
return EPERM; |
} |
// create the last fragment |
new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( address_length > addr_len ) ? address_length : addr_len )); |
new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, ((( size_t ) address_length > addr_len ) ? ( size_t ) address_length : addr_len )); |
if( ! new_packet ) return ENOMEM; |
last_header = ip_create_last_header( new_packet, header ); |
if( ! last_header ){ |
864,14 → 899,20 |
// TODO fragmented |
return ENOTSUP; |
}else{ |
ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR )); |
rwlock_read_lock( & ip_globals.protos_lock ); |
proto = ip_protos_find( & ip_globals.protos, header->protocol ); |
if( ! proto ) return ENOENT; |
ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR )); |
if( proto->tl_received_msg ){ |
return proto->tl_received_msg( device_id, packet, SERVICE_IP ); |
if( ! proto ){ |
rwlock_read_unlock( & ip_globals.protos_lock ); |
return ENOENT; |
} |
if( proto->received_msg ){ |
ERROR_CODE = proto->received_msg( device_id, packet, SERVICE_IP ); |
}else{ |
return tl_received_msg( proto->phone, device_id, packet, proto->service ); |
ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service ); |
} |
rwlock_read_unlock( & ip_globals.protos_lock ); |
return ERROR_CODE; |
} |
} |
/branches/network/uspace/srv/net/il/ip/ip.h |
---|
37,11 → 37,13 |
#ifndef __NET_IP_H__ |
#define __NET_IP_H__ |
#include <rwlock.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include "../../include/sockaddr.h" |
#include "../../include/device.h" |
#include "../../include/inet.h" |
#include "../../include/ip_interface.h" |
#include "../../structures/int_map.h" |
96,7 → 98,7 |
int protocol; |
services_t service; |
int phone; |
tl_received_msg_t tl_received_msg; |
tl_received_msg_t received_msg; |
}; |
struct ip_route{ |
109,11 → 111,14 |
struct ip_globals{ |
int net_phone; |
ip_netifs_t netifs; |
rwlock_t netifs_lock; |
ip_protos_t protos; |
rwlock_t protos_lock; |
ip_route_t gateway; |
modules_t modules; |
async_client_conn_t client_connection; |
uint16_t packet_counter; |
rwlock_t lock; |
}; |
#endif |