/branches/network/uspace/srv/net/tl/tcp/tcp.c |
---|
54,35 → 54,42 |
#include "tcp.h" |
#include "tcp_module.h" |
/** Free ports pool start. |
*/ |
#define TCP_FREE_PORTS_START 1025 |
/** Free ports pool end. |
*/ |
#define TCP_FREE_PORTS_END 65535 |
/** TCP global data. |
*/ |
tcp_globals_t tcp_globals; |
int tcp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ); |
int tcp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ); |
/** Initializes the module. |
*/ |
int tcp_initialize( async_client_conn_t client_connection ){ |
// ERROR_DECLARE; |
ERROR_DECLARE; |
// ipcarg_t arg1, arg2; |
// packet_t packet; |
/* printf( "TCP - testing to send to IP:\n" ); |
ERROR_PROPAGATE( ip_echo( tcp_globals.ip_phone, 12, 34, 0, 0, 0, & arg1, & arg2, NULL, NULL, NULL )); |
if(( arg1 != 12 ) || ( arg2 != 34 )) return EINVAL; |
printf( "OK\n" ); |
*/ |
fibril_rwlock_initialize( & tcp_globals.lock ); |
fibril_rwlock_write_lock( & tcp_globals.lock ); |
tcp_globals.icmp_phone = icmp_connect_module( SERVICE_ICMP ); |
if( tcp_globals.icmp_phone < 0 ){ |
return tcp_globals.icmp_phone; |
} |
tcp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_TCP, SERVICE_TCP, client_connection, tcp_received_msg ); |
/* printf( "TCP - testing to send packet to IP:\n" ); |
packet = packet_get_4( tcp_globals.net_phone, 6, 20, 30, 20 ); |
if( ! packet ) return ENOMEM; |
packet_copy_data( packet, "Hi, this is TCP", 16 ); |
ip_send_msg( tcp_globals.ip_phone, -1, packet, SERVICE_TCP ); |
printf( "OK\n" ); |
*/ return EOK; |
if( tcp_globals.ip_phone < 0 ){ |
return tcp_globals.ip_phone; |
} |
ERROR_PROPAGATE( socket_ports_initialize( & tcp_globals.sockets )); |
tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1; |
fibril_rwlock_write_unlock( & tcp_globals.lock ); |
return EOK; |
} |
int tcp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ){ |
int tcp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ){ |
// TODO received |
// TODO remove debug dump: |
uint8_t * data; |
104,7 → 111,7 |
return EOK; |
case NET_TL_RECEIVED: |
ERROR_PROPAGATE( packet_translate( tcp_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
return tcp_received_msg( IPC_GET_DEVICE( call ), packet, 0 ); |
return tcp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_TCP, IPC_GET_ERROR( call )); |
} |
return ENOTSUP; |
} |
/branches/network/uspace/srv/net/tl/tcp/tcp.h |
---|
31,17 → 31,42 |
*/ |
/** @file |
* \todo |
* TCP module. |
*/ |
#ifndef __NET_TCP_H__ |
#define __NET_TCP_H__ |
#include <fibril_sync.h> |
#include "../../socket/socket_core.h" |
/** Type definition of the TCP global data. |
* @see tcp_globals |
*/ |
typedef struct tcp_globals tcp_globals_t; |
/** TCP global data. |
*/ |
struct tcp_globals{ |
/** Networking module phone. |
*/ |
int net_phone; |
/** IP module phone. |
*/ |
int ip_phone; |
int net_phone; |
/** ICMP module phone. |
*/ |
int icmp_phone; |
/** Last used free port. |
*/ |
int last_used_port; |
/** Active sockets. |
*/ |
socket_ports_t sockets; |
/** Safety lock. |
*/ |
fibril_rwlock_t lock; |
}; |
#endif |
/branches/network/uspace/srv/net/tl/tcp/Makefile |
---|
44,7 → 44,10 |
$(STRUCTURES)packet/packet_client.c \ |
$(STRUCTURES)packet/packet_remote.c \ |
$(STRUCTURES)measured_strings.c \ |
$(NET_BASE)il/ip/ip_client.c \ |
$(NET_BASE)il/ip/ip_remote.c \ |
$(NET_BASE)il/icmp/icmp_remote.c \ |
$(NET_BASE)il/icmp/icmp_client.c \ |
$(NET_BASE)net/net_remote.c |
include $(NET_BASE)Makefile.module |
/branches/network/uspace/srv/net/tl/udp/udp.c |
---|
38,7 → 38,6 |
#include <async.h> |
#include <fibril_sync.h> |
#include <malloc.h> |
#include <stdio.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
55,6 → 54,8 |
#include "../../include/ip_client.h" |
#include "../../include/ip_interface.h" |
#include "../../include/ip_protocols.h" |
#include "../../include/icmp_client.h" |
#include "../../include/icmp_interface.h" |
#include "../../include/socket.h" |
#include "../../include/socket_errno.h" |
79,21 → 80,15 |
*/ |
#define UDP_FREE_PORTS_END 65535 |
/** Processes the received UDP packet. |
/** Processes the received UDP packet queue. |
* Is used as an entry point from the underlying IP module. |
* Releases the packet on error. |
* Notifies the destination socket application. |
* Releases the packet on error or send an ICMP error notification.. |
* @param device_id The device identifier. Ignored parameter. |
* @param packet The received packet. Input/output parameter. |
* @param packet The received packet queue. Input/output parameter. |
* @param receiver The target service. Ignored parameter. |
* @param error The packet error reporting service. Prefixes the received packet. Input parameter. |
* @returns EOK on success. |
* @returns Other error codes as defined for the udp_process_packet() function. |
*/ |
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ); |
/** Processes the received UDP packet. |
* Notifies the destination socket application. |
* @param packet The received packet. Input/output parameter. |
* @returns EOK on success. |
* @returns EINVAL if the packet is not valid. |
* @returns EINVAL if the stored packet address is not the an_addr_t. |
* @returns EINVAL if the packet does not contain any data. |
102,8 → 97,23 |
* @returns EADDRNOTAVAIL if the destination socket does not exist. |
* @returns Other error codes as defined for the ip_client_process_packet() function. |
*/ |
int udp_process_packet( packet_t packet ); |
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ); |
/** Releases the packet and returns the result. |
* @param packet The packet queue to be released. Input parameter. |
* @param result The result to be returned. Input parameter. |
* @return The result parameter. |
*/ |
static int release_and_return( packet_t packet, int result ); |
/** Sends the port unreachable ICMP notification. |
* Sends the first packet and releases all the others. |
* Releases the packet queu on error. |
* @param packet The packet to be send. Input parameter. |
* @param error The packet error reporting service. Prefixes the received packet. Input parameter. |
*/ |
void udp_send_icmp_port_unreachable( packet_t packet, services_t error ); |
/** @name Socket messages processing functions |
*/ |
/*@{*/ |
196,6 → 206,10 |
fibril_rwlock_initialize( & udp_globals.lock ); |
fibril_rwlock_write_lock( & udp_globals.lock ); |
udp_globals.icmp_phone = icmp_connect_module( SERVICE_ICMP ); |
if( udp_globals.icmp_phone < 0 ){ |
return udp_globals.icmp_phone; |
} |
udp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg ); |
if( udp_globals.ip_phone < 0 ){ |
return udp_globals.ip_phone; |
209,24 → 223,12 |
return EOK; |
} |
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver ){ |
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ){ |
ERROR_DECLARE; |
if( ERROR_OCCURRED( udp_process_packet( packet ))){ |
pq_release( udp_globals.net_phone, packet_get_id( packet )); |
return ERROR_CODE; |
} |
return EOK; |
} |
int udp_process_packet( packet_t packet ){ |
ERROR_DECLARE; |
uint8_t * src; |
uint8_t * dest; |
int length; |
void * data; |
int offset; |
uint8_t * data; |
udp_header_ref header; |
socket_core_ref * socket; |
packet_t next_packet; |
234,23 → 236,55 |
// uint16_t checksum; |
int fragments; |
packet_t tmp_packet; |
icmp_type_t type; |
icmp_code_t code; |
// get packet data |
length = packet_get_addr( packet, & src, & dest ); |
if( length != sizeof( in_addr_t )) return EINVAL; |
if( error ){ |
switch( error ){ |
case SERVICE_ICMP: |
// process error |
// TODO remove debug dump |
// length = icmp_client_header_length( packet ); |
length = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); |
if( length < 0 ){ |
return release_and_return( packet, length ); |
} |
printf( "ICMP error %d (%d) in packet %d\n", type, code, packet_get_id( packet ) ); |
if( ERROR_OCCURRED( packet_trim( packet, length, 0 ))){ |
return release_and_return( packet, ERROR_CODE ); |
} |
break; |
default: |
return release_and_return( packet, ENOTSUP ); |
} |
} |
// TODO process received ipopts? |
ERROR_PROPAGATE( ip_client_process_packet( packet, NULL, NULL, NULL, NULL, NULL )); |
offset = ip_client_process_packet( packet, NULL, NULL, NULL, NULL, NULL ); |
if( offset < 0 ){ |
return release_and_return( packet, offset ); |
} |
length = packet_get_data_length( packet ); |
if( length <= 0 ) return EINVAL; |
if( length < sizeof( udp_header_t )) return NO_DATA; |
if( length <= 0 ){ |
return release_and_return( packet, EINVAL ); |
} |
if( length < sizeof( udp_header_t ) + offset ){ |
return release_and_return( packet, NO_DATA ); |
} |
data = packet_get_data( packet ); |
if( ! data ) return NO_DATA; |
if( ! data ){ |
return release_and_return( packet, NO_DATA ); |
} |
// get udp header |
header = ( udp_header_ref ) data; |
header = ( udp_header_ref )( data + offset ); |
// find the destination socket |
socket = socket_ports_find( & udp_globals.sockets, ntohs( header->dest )); |
if( ! socket ) return EADDRNOTAVAIL; |
if( ! socket ){ |
udp_send_icmp_port_unreachable( packet, error ); |
return EADDRNOTAVAIL; |
} |
// trim after successful processing to be able to send an ICMP error message! |
ERROR_PROPAGATE( packet_trim( packet, offset, 0 )); |
// count the received packet fragments |
next_packet = packet; |
fragments = 0; |
258,10 → 292,14 |
do{ |
++ fragments; |
length = packet_get_data_length( packet ); |
if( ! length ) return NO_DATA; |
if( ! length ){ |
return release_and_return( packet, NO_DATA ); |
} |
if( total_length < length ){ |
// cut of the suffix if too long |
ERROR_PROPAGATE( packet_trim( next_packet, 0, length - total_length )); |
if( ERROR_OCCURRED( packet_trim( next_packet, 0, length - total_length ))){ |
return release_and_return( packet, ERROR_CODE ); |
} |
// relese the rest of the packet fragments |
tmp_packet = pq_next( next_packet ); |
while( tmp_packet ){ |
277,7 → 315,9 |
*/ |
}while(( next_packet = pq_next( next_packet )) && ( total_length > 0 )); |
// queue the received packet |
ERROR_PROPAGATE( dyn_fifo_push( &( ** socket ).received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE )); |
if( ERROR_OCCURRED( dyn_fifo_push( &( ** socket ).received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){ |
return release_and_return( packet, ERROR_CODE ); |
} |
// notify the destination socket |
async_msg_2(( ** socket ).phone, NET_SOCKET_RECEIVED, ( ** socket ).socket_id, fragments ); |
294,7 → 334,7 |
case NET_TL_RECEIVED: |
fibril_rwlock_read_lock( & udp_globals.lock ); |
if( ! ERROR_OCCURRED( packet_translate( udp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){ |
ERROR_CODE = udp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_UDP ); |
ERROR_CODE = udp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_UDP, IPC_GET_ERROR( call )); |
} |
fibril_rwlock_read_unlock( & udp_globals.lock ); |
return ERROR_CODE; |
495,7 → 535,7 |
return ERROR_CODE; |
} |
// send the packet |
return ip_send_msg( udp_globals.ip_phone, socket->device_id, packet, SERVICE_UDP ); |
return ip_send_msg( udp_globals.ip_phone, socket->device_id, packet, SERVICE_UDP, 0 ); |
// TODO IPv6 |
default: |
return EAFNOSUPPORT; |
645,5 → 685,32 |
return length; |
} |
static int release_and_return( packet_t packet, int result ){ |
pq_release( udp_globals.net_phone, packet_get_id( packet )); |
return result; |
} |
void udp_send_icmp_port_unreachable( packet_t packet, services_t error ){ |
packet_t next; |
uint8_t * src; |
int length; |
// detach the first packet and release the others |
next = pq_detach( packet ); |
if( next ){ |
pq_release( udp_globals.net_phone, packet_get_id( next )); |
} |
length = packet_get_addr( packet, & src, NULL ); |
if(( length > 0 ) |
&& ( ! error ) |
&& ( udp_globals.icmp_phone >= 0 ) |
// set both addresses to the source one (avoids the source address deletion before setting the destination one) |
&& ( packet_set_addr( packet, src, src, length ) == EOK )){ |
icmp_destination_unreachable_msg( udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet ); |
}else{ |
return release_and_return( packet, EINVAL ); |
} |
} |
/** @} |
*/ |
/branches/network/uspace/srv/net/tl/udp/Makefile |
---|
47,6 → 47,8 |
$(STRUCTURES)measured_strings.c \ |
$(NET_BASE)il/ip/ip_client.c \ |
$(NET_BASE)il/ip/ip_remote.c \ |
$(NET_BASE)il/icmp/icmp_remote.c \ |
$(NET_BASE)il/icmp/icmp_client.c \ |
$(NET_BASE)net/net_remote.c \ |
$(NET_BASE)socket/socket_core.c |
/branches/network/uspace/srv/net/tl/udp/udp.h |
---|
49,9 → 49,15 |
/** UDP global data. |
*/ |
struct udp_globals{ |
/** Networking module phone. |
*/ |
int net_phone; |
/** IP module phone. |
*/ |
int ip_phone; |
/** ICMP module phone. |
*/ |
int icmp_phone; |
/** Reserved packet prefix length. |
*/ |
size_t prefix; |
64,9 → 70,6 |
/** Packet address length. |
*/ |
size_t addr_len; |
/** Networking module phone. |
*/ |
int net_phone; |
/** Last used free port. |
*/ |
int last_used_port; |
/branches/network/uspace/srv/net/nil/nil_remote.c |
---|
50,7 → 50,7 |
} |
int nil_received_msg( int nil_phone, device_id_t device_id, packet_t packet, services_t target ){ |
return generic_received_msg( nil_phone, NET_NIL_RECEIVED, device_id, packet_get_id( packet ), target ); |
return generic_received_msg( nil_phone, NET_NIL_RECEIVED, device_id, packet_get_id( packet ), target, 0 ); |
} |
/** @} |
/branches/network/uspace/srv/net/include/tl_interface.h |
---|
60,10 → 60,11 |
* @param device_id The device identifier. Input parameter. |
* @param packet The received packet or the received packet queue. Input parameter. |
* @param target The target transport layer module service to be delivered to. Input parameter. |
* @param error The packet error reporting service. Prefixes the received packet. Input parameter. |
* @returns EOK on success. |
*/ |
inline static int tl_received_msg( int tl_phone, device_id_t device_id, packet_t packet, services_t target ){ |
return generic_received_msg( tl_phone, NET_TL_RECEIVED, device_id, packet_get_id( packet ), target ); |
inline static int tl_received_msg( int tl_phone, device_id_t device_id, packet_t packet, services_t target, services_t error ){ |
return generic_received_msg( tl_phone, NET_TL_RECEIVED, device_id, packet_get_id( packet ), target, error ); |
} |
/*@}*/ |
/branches/network/uspace/srv/net/include/nil_interface.h |
---|
95,7 → 95,7 |
* @returns Other error codes as defined for the generic_send_msg() function. |
*/ |
#define nil_send_msg( nil_phone, device_id, packet, sender ) \ |
generic_send_msg( nil_phone, NET_NIL_SEND, device_id, packet_get_id( packet ), sender ) |
generic_send_msg( nil_phone, NET_NIL_SEND, device_id, packet_get_id( packet ), sender, 0 ) |
/** Returns the device packet dimensions for sending. |
* @param nil_phone The network interface layer phone. Input parameter. |
/branches/network/uspace/srv/net/include/icmp_codes.h |
---|
0,0 → 1,362 |
/* |
* Copyright (c) 2009 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP types and codes according to the on-line IANA - ICMP Type Numbers - <http://http://www.iana.org/assignments/icmp-parameters>, cited September 14 2009. |
* Names according to the linux src/include/linux/icmp.h header file. |
*/ |
#ifndef __NET_ICMP_CODES_H__ |
#define __NET_ICMP_CODES_H__ |
/** ICMP type type definition. |
*/ |
typedef uint8_t icmp_type_t; |
/** ICMP code type definition. |
*/ |
typedef uint8_t icmp_code_t; |
/** ICMP parameter type definition. |
*/ |
typedef uint16_t icmp_param_t; |
/** @name ICMP types definitions |
*/ |
/*@{*/ |
/** Echo Reply. |
*/ |
#define ICMP_ECHOREPLY 0 |
/** Destination Unreachable. |
*/ |
#define ICMP_DEST_UNREACH 3 |
/** Source Quench. |
*/ |
#define ICMP_SOURCE_QUENCH 4 |
/** Redirect. |
*/ |
#define ICMP_REDIRECT 5 |
/** Alternate Host Address. |
*/ |
#define ICMP_ALTERNATE_ADDR 6 |
/** Echo Request. |
*/ |
#define ICMP_ECHO 8 |
/** Router advertisement. |
*/ |
#define ICMP_ROUTER_ADV 9 |
/** Router solicitation. |
*/ |
#define ICMP_ROUTER_SOL 10 |
/** Time Exceeded. |
*/ |
#define ICMP_TIME_EXCEEDED 11 |
/** Parameter Problem. |
*/ |
#define ICMP_PARAMETERPROB 12 |
/** Timestamp Request. |
*/ |
#define ICMP_TIMESTAMP 13 |
/** Timestamp Reply. |
*/ |
#define ICMP_TIMESTAMPREPLY 14 |
/** Information Request. |
*/ |
#define ICMP_INFO_REQUEST 15 |
/** Information Reply. |
*/ |
#define ICMP_INFO_REPLY 16 |
/** Address Mask Request. |
*/ |
#define ICMP_ADDRESS 17 |
/** Address Mask Reply. |
*/ |
#define ICMP_ADDRESSREPLY 18 |
/** Traceroute. |
*/ |
#define ICMP_TRACEROUTE 30 |
/** Datagram Conversion Error. |
*/ |
#define ICMP_CONVERSION_ERROR 31 |
/** Mobile Host Redirect. |
*/ |
#define ICMP_REDIRECT_MOBILE 32 |
/** IPv6 Where-Are-You. |
*/ |
#define ICMP_IPV6_WHERE_ARE_YOU 33 |
/** IPv6 I-Am-Here. |
*/ |
#define ICMP_IPV6_I_AM_HERE 34 |
/** Mobile Registration Request. |
*/ |
#define ICMP_MOBILE_REQUEST 35 |
/** Mobile Registration Reply. |
*/ |
#define ICMP_MOBILE_REPLY 36 |
/** Domain name request. |
*/ |
#define ICMP_DN_REQUEST 37 |
/** Domain name reply. |
*/ |
#define ICMP_DN_REPLY 38 |
/** SKIP. |
*/ |
#define ICMP_SKIP 39 |
/** Photuris. |
*/ |
#define ICMP_PHOTURIS 40 |
/*@}*/ |
/** @name ICMP_DEST_UNREACH codes definitions |
*/ |
/*@{*/ |
/** Network Unreachable. |
*/ |
#define ICMP_NET_UNREACH 0 |
/** Host Unreachable. |
*/ |
#define ICMP_HOST_UNREACH 1 |
/** Protocol Unreachable. |
*/ |
#define ICMP_PROT_UNREACH 2 |
/** Port Unreachable. |
*/ |
#define ICMP_PORT_UNREACH 3 |
/** Fragmentation needed but the Do Not Fragment bit was set. |
*/ |
#define ICMP_FRAG_NEEDED 4 |
/** Source Route failed. |
*/ |
#define ICMP_SR_FAILED 5 |
/** Destination network unknown. |
*/ |
#define ICMP_NET_UNKNOWN 6 |
/** Destination host unknown. |
*/ |
#define ICMP_HOST_UNKNOWN 7 |
/** Source host isolated (obsolete). |
*/ |
#define ICMP_HOST_ISOLATED 8 |
/** Destination network administratively prohibited. |
*/ |
#define ICMP_NET_ANO 9 |
/** Destination host administratively prohibited. |
*/ |
#define ICMP_HOST_ANO 10 |
/** Network unreachable for this type of service. |
*/ |
#define ICMP_NET_UNR_TOS 11 |
/** Host unreachable for this type of service. |
*/ |
#define ICMP_HOST_UNR_TOS 12 |
/** Communication administratively prohibited by filtering. |
*/ |
#define ICMP_PKT_FILTERED 13 |
/** Host precedence violation. |
*/ |
#define ICMP_PREC_VIOLATION 14 |
/** Precedence cutoff in effect. |
*/ |
#define ICMP_PREC_CUTOFF 15 |
/*@}*/ |
/** @name ICMP_REDIRECT codes definitions |
*/ |
/*@{*/ |
/** Network redirect (or subnet). |
*/ |
#define ICMP_REDIR_NET 0 |
/** Host redirect. |
*/ |
#define ICMP_REDIR_HOST 1 |
/** Network redirect for this type of service. |
*/ |
#define ICMP_REDIR_NETTOS 2 |
/** Host redirect for this type of service. |
*/ |
#define ICMP_REDIR_HOSTTOS 3 |
/*@}*/ |
/** @name ICMP_ALTERNATE_ADDRESS codes definitions |
*/ |
/*@{*/ |
/** Alternate address for host. |
*/ |
#define ICMP_ALTERNATE_HOST 0 |
/*@}*/ |
/** @name ICMP_TIME_EXCEEDED codes definitions |
*/ |
/*@{*/ |
/** Transit TTL exceeded. |
*/ |
#define ICMP_EXC_TTL 0 |
/** Reassembly TTL exceeded. |
*/ |
#define ICMP_EXC_FRAGTIME 1 |
/*@}*/ |
/** @name ICMP_ROUTER_ADV codes definitions |
*/ |
/*@{*/ |
/** Normal router advertisement. |
*/ |
#define ICMP_ROUTER_NORMAL 0 |
/** Does not route common traffic. |
*/ |
#define ICMP_ROUTER_NO_NORMAL_TRAFFIC 16 |
/*@}*/ |
/** @name ICMP_TIME_EXCEEDED codes definitions |
*/ |
/*@{*/ |
/** Transit TTL exceeded. |
*/ |
#define ICMP_EXC_TTL 0 |
/** Reassembly TTL exceeded. |
*/ |
#define ICMP_EXC_FRAGTIME 1 |
/*@}*/ |
/** @name ICMP_PARAMETERPROB codes definitions |
*/ |
/*@{*/ |
/** Pointer indicates the error. |
*/ |
#define ICMP_PARAM_POINTER 0 |
/** Missing required option. |
*/ |
#define ICMP_PARAM_MISSING 1 |
/** Bad length. |
*/ |
#define ICMP_PARAM_LENGTH 2 |
/*@}*/ |
/** @name ICMP_PHOTURIS codes definitions |
*/ |
/*@{*/ |
/** Bad SPI. |
*/ |
#define ICMP_PHOTURIS_BAD_SPI 0 |
/** Authentication failed. |
*/ |
#define ICMP_PHOTURIS_AUTHENTICATION 1 |
/** Decompression failed. |
*/ |
#define ICMP_PHOTURIS_DECOMPRESSION 2 |
/** Decryption failed. |
*/ |
#define ICMP_PHOTURIS_DECRYPTION 3 |
/** Need authentication. |
*/ |
#define ICMP_PHOTURIS_NEED_AUTHENTICATION 4 |
/** Need authorization. |
*/ |
#define ICMP_PHOTURIS_NEED_AUTHORIZATION 5 |
/*@}*/ |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/include/ip_client.h |
---|
137,6 → 137,13 |
int ip_client_process_packet( packet_t packet, ip_protocol_t * protocol, ip_ttl_t * ttl, ip_tos_t * tos, int * dont_fragment, size_t * ipopt_length ); |
/** Returns the IP header length. |
* @param packet The packet. Input parameter. |
* @returns The IP header length in bytes. |
* @returns ENOMEM if there is no IP header. |
*/ |
int ip_client_header_length( packet_t packet ); |
// TODO ipopt manipulation |
#endif |
/branches/network/uspace/srv/net/include/icmp_interface.h |
---|
0,0 → 1,86 |
/* |
* Copyright (c) 2009 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP module interface. |
* The same interface is used for standalone remote modules as well as for bundle modules. |
* The standalone remote modules have to be compiled with the icmp_remote.c source file. |
* The bundle modules with the icmp.c source file. |
*/ |
#ifndef __NET_ICMP_INTERFACE_H__ |
#define __NET_ICMP_INTERFACE_H__ |
#include "device.h" |
#include "../structures/measured_strings.h" |
#include "icmp_codes.h" |
/** @name ICMP module interface |
* This interface is used by other modules. |
*/ |
/*@{*/ |
/** \todo |
*/ |
int icmp_echo_msg( int icmp_phone, icmp_param_t identifier, icmp_param_t sequence_number, const void * data, size_t length ); |
/** \todo |
*/ |
int icmp_destination_unreachable_msg( int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet ); |
/** \todo |
*/ |
int icmp_source_quench_msg( int icmp_phone, packet_t packet ); |
/** \todo |
*/ |
int icmp_time_exceeded_msg( int icmp_phone, icmp_code_t code, packet_t packet ); |
/** \todo |
*/ |
int icmp_parameter_problem_msg( int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet ); |
/** Connects to the ICMP module. |
* @param service The ICMP module service. Ignored parameter. |
* @returns The ICMP module phone on success. |
* @returns 0 if called by the bundle module. |
*/ |
int icmp_connect_module( services_t service ); |
/*@}*/ |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/include/il_interface.h |
---|
75,7 → 75,7 |
* @returns EOK on success. |
*/ |
inline static int il_received_msg( int il_phone, device_id_t device_id, packet_t packet, services_t target ){ |
return generic_received_msg( il_phone, NET_IL_RECEIVED, device_id, packet_get_id( packet ), target ); |
return generic_received_msg( il_phone, NET_IL_RECEIVED, device_id, packet_get_id( packet ), target, 0 ); |
} |
/** Notifies the internetwork layer modules about the mtu change. |
/branches/network/uspace/srv/net/include/icmp_client.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2009 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP client interface. |
*/ |
#ifndef __NET_ICMP_CLIENT_H__ |
#define __NET_ICMP_CLIENT_H__ |
#include "icmp_codes.h" |
#include "../structures/packet/packet.h" |
/** \todo |
*/ |
int icmp_client_process_packet( packet_t packet, icmp_type_t * type, icmp_code_t * code, icmp_param_t * pointer, icmp_param_t * mtu ); |
/** Returns the ICMP header length. |
* @param packet The packet. Input parameter. |
* @returns The ICMP header length in bytes. |
* @returns ENOMEM if there is no ICMP header. |
*/ |
int icmp_client_header_length( packet_t packet ); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/include/ip_interface.h |
---|
60,9 → 60,10 |
* @param device_id The device identifier. Input parameter. |
* @param packet The received packet or the received packet queue. Input parameter. |
* @param receiver The receiving module service. Input parameter. |
* @param error The packet error reporting service. Prefixes the received packet. Input parameter. |
* @returns EOK on success. |
*/ |
typedef int ( * tl_received_msg_t )( device_id_t device_id, packet_t packet, services_t receiver ); |
typedef int ( * tl_received_msg_t )( device_id_t device_id, packet_t packet, services_t receiver, services_t error ); |
/** Creates bidirectional connection with the ip module service and registers the message receiver. |
* @param service The IP module service. Input parameter. |
97,10 → 98,11 |
* @param device_id The device identifier. Input parameter. |
* @param packet The packet queue. Input parameter. |
* @param sender The sending module service. Input parameter. |
* @param target The target transport layer module service to be delivered to. Input parameter. |
* @returns EOK on success. |
* @returns Other error codes as defined for the generic_send_msg() function. |
*/ |
int ip_send_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t sender ); |
int ip_send_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ); |
/** Connects to the IP module. |
* @param service The IP module service. Ignored parameter. |
141,6 → 143,16 |
*/ |
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 ); |
/** Notifies the IP module about the received error notification packet. |
* @param ip_phone The IP module phone used for (semi)remote calls. Input parameter. |
* @param device_id The device identifier. Input parameter. |
* @param packet The received packet or the received packet queue. Input parameter. |
* @param target The target internetwork module service to be delivered to. Input parameter. |
* @param error The packet error reporting service. Prefixes the received packet. Input parameter. |
* @returns EOK on success. |
*/ |
int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error ); |
/*@}*/ |
#endif |
/branches/network/uspace/srv/net/net/net_standalone.c |
---|
81,10 → 81,10 |
task_id = spawn( "/srv/ip" ); |
if( ! task_id ) return EINVAL; |
ERROR_PROPAGATE( add_module( NULL, & net_globals.modules, IP_NAME, IP_FILENAME, SERVICE_IP, task_id, ip_connect_module )); |
if( ! spawn( "/srv/icmp" )) return EINVAL; |
if( ! spawn( "/srv/udp" )) return EINVAL; |
if( ! spawn( "/srv/tcp" )) return EINVAL; |
// if( ! spawn( "/srv/rarp" )) return EINVAL; |
// if( ! spawn( "/srv/icmp" )) return EINVAL; |
return EOK; |
} |
/branches/network/uspace/srv/net/net/net_bundle.c |
---|
49,6 → 49,7 |
#include "../il/arp/arp_module.h" |
#include "../il/ip/ip_module.h" |
#include "../il/icmp/icmp_module.h" |
#include "../tl/udp/udp_module.h" |
#include "../tl/tcp/tcp_module.h" |
81,9 → 82,9 |
return arp_message( callid, call, answer, answer_count ); |
/* }else if( IS_NET_RARP_MESSAGE( call )){ |
return rarp_message( callid, call, answer, answer_count ); |
}else if( IS_NET_ICMP_MESSAGE( call )){ |
*/ }else if( IS_NET_ICMP_MESSAGE( call )){ |
return icmp_message( callid, call, answer, answer_count ); |
*/ }else if( IS_NET_UDP_MESSAGE( call )){ |
}else if( IS_NET_UDP_MESSAGE( call )){ |
return udp_message( callid, call, answer, answer_count ); |
}else if( IS_NET_TCP_MESSAGE( call )){ |
return tcp_message( callid, call, answer, answer_count ); |
121,8 → 122,8 |
ERROR_PROPAGATE( arp_initialize( client_connection )); |
// ERROR_PROPAGATE( REGISTER_ME( SERVICE_RARP, & phonehash )); |
// ERROR_PROPAGATE( rarp_initialize( client_connection )); |
// ERROR_PROPAGATE( REGISTER_ME( SERVICE_ICMP, & phonehash )); |
// ERROR_PROPAGATE( icmp_initialize( client_connection )); |
ERROR_PROPAGATE( REGISTER_ME( SERVICE_ICMP, & phonehash )); |
ERROR_PROPAGATE( icmp_initialize( client_connection )); |
ERROR_PROPAGATE( REGISTER_ME( SERVICE_UDP, & phonehash )); |
ERROR_PROPAGATE( udp_initialize( client_connection )); |
ERROR_PROPAGATE( REGISTER_ME( SERVICE_TCP, & phonehash )); |
/branches/network/uspace/srv/net/net/Makefile |
---|
57,6 → 57,8 |
$(NET_BASE)il/arp/arp.c \ |
$(NET_BASE)il/ip/ip.c \ |
$(NET_BASE)il/ip/ip_client.c \ |
$(NET_BASE)il/icmp/icmp.c \ |
$(NET_BASE)il/icmp/icmp_client.c \ |
$(NET_BASE)inet.c \ |
$(NET_BASE)tl/tcp/tcp.c \ |
$(NET_BASE)tl/udp/udp.c \ |
/branches/network/uspace/srv/net/messages.h |
---|
52,10 → 52,10 |
#define NET_NIL_COUNT 7 |
#define NET_ETH_COUNT 0 |
#define NET_IL_COUNT 6 |
#define NET_IP_COUNT 2 |
#define NET_IP_COUNT 3 |
#define NET_ARP_COUNT 5 |
#define NET_RARP_COUNT 0 |
#define NET_ICMP_COUNT 0 |
#define NET_ICMP_COUNT 6 |
#define NET_TL_COUNT 1 |
#define NET_UDP_COUNT 0 |
#define NET_TCP_COUNT 0 |
114,6 → 114,7 |
#define IS_NET_IP_MESSAGE( call ) IS_IN_INTERVAL( IPC_GET_METHOD( * call ), NET_IP_FIRST, NET_IP_LAST ) |
#define IS_NET_ARP_MESSAGE( call ) IS_IN_INTERVAL( IPC_GET_METHOD( * call ), NET_ARP_FIRST, NET_ARP_LAST ) |
#define IS_NET_RARP_MESSAGE( call ) IS_IN_INTERVAL( IPC_GET_METHOD( * call ), NET_RARP_FIRST, NET_RARP_LAST ) |
#define IS_NET_ICMP_MESSAGE( call ) IS_IN_INTERVAL( IPC_GET_METHOD( * call ), NET_ICMP_FIRST, NET_ICMP_LAST ) |
#define IS_NET_TL_MESSAGE( call ) IS_IN_INTERVAL( IPC_GET_METHOD( * call ), NET_TL_FIRST, NET_TL_LAST ) |
#define IS_NET_UDP_MESSAGE( call ) IS_IN_INTERVAL( IPC_GET_METHOD( * call ), NET_UDP_FIRST, NET_UDP_LAST ) |
#define IS_NET_TCP_MESSAGE( call ) IS_IN_INTERVAL( IPC_GET_METHOD( * call ), NET_TCP_FIRST, NET_TCP_LAST ) |
140,6 → 141,8 |
#define IPC_GET_TARGET( call ) ( services_t ) IPC_GET_ARG3( * call ) |
#define IPC_GET_SENDER( call ) ( services_t ) IPC_GET_ARG3( * call ) |
#define IPC_GET_ERROR( call ) ( services_t ) IPC_GET_ARG4( * call ) |
#define IPC_GET_PHONE( call ) ( int ) IPC_GET_ARG5( * call ) |
#define IPC_SET_ADDR( answer ) (( size_t * ) & IPC_GET_ARG1( * answer )) |
202,8 → 205,12 |
return ( int ) result; |
} |
static inline int generic_send_msg( int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t sender ){ |
static inline int generic_send_msg( int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t sender, services_t error ){ |
if( error ){ |
async_msg_4( phone, ( ipcarg_t ) message, ( ipcarg_t ) device_id, ( ipcarg_t ) packet_id, ( ipcarg_t ) sender, ( ipcarg_t ) error ); |
}else{ |
async_msg_3( phone, ( ipcarg_t ) message, ( ipcarg_t ) device_id, ( ipcarg_t ) packet_id, ( ipcarg_t ) sender ); |
} |
return EOK; |
} |
216,8 → 223,12 |
return EOK; |
} |
static inline int generic_received_msg( int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t target ){ |
static inline int generic_received_msg( int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t target, services_t error ){ |
if( error ){ |
async_msg_4( phone, ( ipcarg_t ) message, ( ipcarg_t ) device_id, ( ipcarg_t ) packet_id, ( ipcarg_t ) target, ( ipcarg_t ) error ); |
}else{ |
async_msg_3( phone, ( ipcarg_t ) message, ( ipcarg_t ) device_id, ( ipcarg_t ) packet_id, ( ipcarg_t ) target ); |
} |
return EOK; |
} |
/branches/network/uspace/srv/net/il/icmp/icmp_module.h |
---|
0,0 → 1,66 |
/* |
* Copyright (c) 2008 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP module functions. |
* The functions are used as ICMP module entry points. |
*/ |
#ifndef __NET_ICMP_MODULE_H__ |
#define __NET_ICMP_MODULE_H__ |
#include <async.h> |
#include <ipc/ipc.h> |
/** Initializes the ICMP module. |
* @param client_connection The client connection processing function. The module skeleton propagates its own one. Input parameter. |
* @returns EOK on success. |
* @returns ENOMEM if there is not enough memory left. |
*/ |
int icmp_initialize( async_client_conn_t client_connection ); |
/** Processes the ICMP message. |
* @param callid The message identifier. Input parameter. |
* @param call The message parameters. Input parameter. |
* @param answer The message answer parameters. Output parameter. |
* @param answer_count The last parameter for the actual answer in the answer parameter. Output parameter. |
* @returns EOK on success. |
* @returns ENOTSUP if the message is not known. |
* @see icmp_interface.h |
* @see IS_NET_ICMP_MESSAGE() |
*/ |
int icmp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/icmp/icmp_remote.c |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2009 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP interface implementation for standalone remote modules. |
* @see icmp_interface.h |
*/ |
#include <async.h> |
#include <errno.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include "../../messages.h" |
#include "../../modules.h" |
#include "../../include/icmp_interface.h" |
#include "../../structures/packet/packet_client.h" |
#include "icmp_messages.h" |
int icmp_echo_msg( int icmp_phone, icmp_param_t identifier, icmp_param_t sequence_number, const void * data, size_t length ){ |
// TODO ICMP echo |
return ENOTSUP; |
} |
int icmp_destination_unreachable_msg( int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet ){ |
async_msg_3( icmp_phone, NET_ICMP_DEST_UNREACH, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet ), ( ipcarg_t ) mtu ); |
return EOK; |
} |
int icmp_source_quench_msg( int icmp_phone, packet_t packet ){ |
async_msg_2( icmp_phone, NET_ICMP_SOURCE_QUENCH, 0, ( ipcarg_t ) packet_get_id( packet )); |
return EOK; |
} |
int icmp_time_exceeded_msg( int icmp_phone, icmp_code_t code, packet_t packet ){ |
async_msg_2( icmp_phone, NET_ICMP_TIME_EXCEEDED, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet )); |
return EOK; |
} |
int icmp_parameter_problem_msg( int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet ){ |
async_msg_3( icmp_phone, NET_ICMP_PARAMETERPROB, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet ), ( ipcarg_t ) pointer ); |
return EOK; |
} |
int icmp_connect_module( services_t service ){ |
return connect_to_service( SERVICE_ICMP ); |
} |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/icmp/icmp_messages.h |
---|
0,0 → 1,108 |
/* |
* Copyright (c) 2009 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP module messages. |
* @see icmp_interface.h |
*/ |
#ifndef __NET_ICMP_MESSAGES__ |
#define __NET_ICMP_MESSAGES__ |
#include <ipc/ipc.h> |
#include "../../messages.h" |
/** ICMP module messages. |
*/ |
typedef enum{ |
/** Sends echo request. |
* @see icmp_echo() |
*/ |
NET_ICMP_ECHO = NET_ICMP_FIRST, |
/** Sends destination unreachable error message. |
* @see icmp_destination_unreachable_msg() |
*/ |
NET_ICMP_DEST_UNREACH, |
/** Sends source quench error message. |
* @see icmp_source_quench_msg() |
*/ |
NET_ICMP_SOURCE_QUENCH, |
/** Sends redirect error message. |
* @see icmp_redirect_msg() |
*/ |
NET_ICMP_REDIRECT, |
/** Sends time exceeded error message. |
* @see icmp_time_exceeded_msg() |
*/ |
NET_ICMP_TIME_EXCEEDED, |
/** Sends parameter problem error message. |
* @see icmp_parameter_problem_msg() |
*/ |
NET_ICMP_PARAMETERPROB, |
} icmp_messages; |
/** @name ICMP specific message parameters definitions |
*/ |
/*@{*/ |
/** Returns the ICMP code message parameter. |
* @param call The message call structure. Input parameter. |
*/ |
#define ICMP_GET_CODE( call ) ( uint8_t ) IPC_GET_ARG1( * call ) |
/** Returns the echo identifier message parameter. |
* @param call The message call structure. Input parameter. |
*/ |
#define ICMP_GET_IDENTIFIER( call ) ( uint8_t ) IPC_GET_ARG1( * call ) |
/** Returns the echo sequence number message parameter. |
* @param call The message call structure. Input parameter. |
*/ |
#define ICMP_GET_SEQUENCE( call ) ( uint8_t ) IPC_GET_ARG2( * call ) |
/** Returns the ICMP link MTU message parameter. |
* @param call The message call structure. Input parameter. |
*/ |
#define ICMP_GET_MTU( call ) ( uint16_t ) IPC_GET_ARG3( * call ) |
/** Returns the pointer message parameter. |
* @param call The message call structure. Input parameter. |
*/ |
#define ICMP_GET_POINTER( call ) ( uint16_t ) IPC_GET_ARG3( * call ) |
/*@}*/ |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/icmp/icmp_header.h |
---|
0,0 → 1,92 |
/* |
* Copyright (c) 2009 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP header definition. |
* Names according to the linux src/include/linux/icmp.h header file. |
*/ |
#ifndef __NET_ICMP_HEADER_H__ |
#define __NET_ICMP_HEADER_H__ |
#include <sys/types.h> |
#include "../../include/in.h" |
#include "../../include/icmp_codes.h" |
/** Type definition of the user datagram header. |
* @see icmp_header |
*/ |
typedef struct icmp_header icmp_header_t; |
/** Type definition of the user datagram header pointer. |
* @see icmp_header |
*/ |
typedef icmp_header_t * icmp_header_ref; |
/** User datagram header. |
*/ |
struct icmp_header{ |
/** Specifies the type of the message. |
*/ |
uint8_t type; |
/** Contains the error code for the datagram reported by this ICMP message. |
* The interpretation is dependent on the message type. |
*/ |
uint8_t code; |
/** Contains the checksum for the ICMP message starting with the ICMP Type field. |
* If the checksum does not match the contents, the datagram is discarded. |
*/ |
uint16_t checksum; |
/** \todo |
*/ |
union{ |
struct{ |
icmp_param_t id; |
icmp_param_t sequence; |
} echo; |
in_addr_t gateway; |
struct{ |
icmp_param_t unused; |
icmp_param_t mtu; |
} frag; |
struct{ |
icmp_param_t pointer; |
icmp_param_t unused; |
} param; |
} un; |
} __attribute__ ((packed)); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/icmp/icmp_client.c |
---|
0,0 → 1,67 |
/* |
* Copyright (c) 2009 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP client interface implementation. |
* @see icmp_client.h |
*/ |
#include <errno.h> |
#include <sys/types.h> |
#include "../../include/icmp_codes.h" |
#include "../../include/icmp_client.h" |
#include "../../structures/packet/packet.h" |
#include "../../structures/packet/packet_client.h" |
#include "icmp_header.h" |
int icmp_client_process_packet( packet_t packet, icmp_type_t * type, icmp_code_t * code, icmp_param_t * pointer, icmp_param_t * mtu ){ |
icmp_header_ref header; |
header = ( icmp_header_ref ) packet_get_data( packet ); |
if( ! header ) return ENOMEM; |
if( type ) * type = header->type; |
if( code ) * code = header->code; |
if( pointer ) * pointer = header->un.param.pointer; |
if( mtu ) * mtu = header->un.frag.mtu; |
return sizeof( icmp_header_t ); |
} |
int icmp_client_header_length( packet_t packet ){ |
return sizeof( icmp_header_t ); |
} |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/icmp/icmp.c |
---|
0,0 → 1,273 |
/* |
* Copyright (c) 2008 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP module implementation. |
* @see icmp.h |
*/ |
#include <async.h> |
#include <fibril_sync.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include "../../err.h" |
#include "../../messages.h" |
#include "../../modules.h" |
#include "../../structures/packet/packet_client.h" |
#include "../../include/crc.h" |
#include "../../include/icmp_codes.h" |
#include "../../include/icmp_client.h" |
#include "../../include/icmp_interface.h" |
#include "../../include/ip_client.h" |
#include "../../include/ip_interface.h" |
#include "../../include/il_interface.h" |
#include "../../include/ip_protocols.h" |
#include "../../tl/tl_messages.h" |
#include "icmp.h" |
#include "icmp_header.h" |
#include "icmp_messages.h" |
#include "icmp_module.h" |
#define ICMP_KEEP_LENGTH 8 |
#define ICMP_HEADER_CHECKSUM( header ) compact_checksum(compute_checksum( 0, ( uint8_t * ) header, sizeof( icmp_header_t ))) |
/** Processes the received ICMP packet. |
* Is used as an entry point from the underlying IP module. |
* Releases the packet on error. |
* @param device_id The device identifier. Ignored parameter. |
* @param packet The received packet. Input/output parameter. |
* @param receiver The target service. Ignored parameter. |
* @param error The packet error reporting service. Prefixes the received packet. Input parameter. |
* @returns EOK on success. |
* @returns Other error codes as defined for the icmp_process_packet() function. |
*/ |
int icmp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ); |
/** Processes the received ICMP packet. |
* Notifies the destination socket application. |
* @param packet The received packet. Input/output parameter. |
* @returns EOK on success. |
* @returns EINVAL if the packet is not valid. |
* @returns EINVAL if the stored packet address is not the an_addr_t. |
* @returns EINVAL if the packet does not contain any data. |
* @returns NO_DATA if the packet content is shorter than the user datagram header. |
* @returns ENOMEM if there is not enough memory left. |
* @returns EADDRNOTAVAIL if the destination socket does not exist. |
* @returns Other error codes as defined for the ip_client_process_packet() function. |
*/ |
int icmp_process_packet( packet_t packet ); |
icmp_header_ref icmp_prepare_packet( packet_t packet ); |
int icmp_send_packet( icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header ); |
/** ICMP global data. |
*/ |
icmp_globals_t icmp_globals; |
int icmp_echo_msg( int icmp_phone, icmp_param_t identifier, icmp_param_t sequence_number, const void * data, size_t length ){ |
// TODO echo - with timeout |
// waits for the reply up to the timeout |
return ENOTSUP; |
} |
int icmp_destination_unreachable_msg( int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet ){ |
icmp_header_ref header; |
header = icmp_prepare_packet( packet ); |
if( ! header ) return ENOMEM; |
if( mtu ){ |
header->un.frag.mtu = mtu; |
} |
return icmp_send_packet( ICMP_DEST_UNREACH, code, packet, header ); |
} |
int icmp_source_quench_msg( int icmp_phone, packet_t packet ){ |
icmp_header_ref header; |
header = icmp_prepare_packet( packet ); |
if( ! header ) return ENOMEM; |
return icmp_send_packet( ICMP_SOURCE_QUENCH, ICMP_SOURCE_QUENCH, packet, header ); |
} |
int icmp_time_exceeded_msg( int icmp_phone, icmp_code_t code, packet_t packet ){ |
icmp_header_ref header; |
header = icmp_prepare_packet( packet ); |
if( ! header ) return ENOMEM; |
return icmp_send_packet( ICMP_TIME_EXCEEDED, code, packet, header ); |
} |
int icmp_parameter_problem_msg( int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet ){ |
icmp_header_ref header; |
header = icmp_prepare_packet( packet ); |
if( ! header ) return ENOMEM; |
header->un.param.pointer = pointer; |
return icmp_send_packet( ICMP_PARAMETERPROB, code, packet, header ); |
} |
icmp_header_ref icmp_prepare_packet( packet_t packet ){ |
icmp_header_ref header; |
int header_length; |
size_t total_length; |
total_length = packet_get_data_length( packet ); |
if( total_length <= 0 ) return NULL; |
header_length = ip_client_header_length( packet ); |
if( header_length <= 0 ) return NULL; |
// truncate if longer than 64 bits (without the IP header) |
if( total_length - header_length > ICMP_KEEP_LENGTH ){ |
if( packet_trim( packet, 0, total_length - header_length - ICMP_KEEP_LENGTH ) != EOK ) return NULL; |
} |
header = PACKET_PREFIX( packet, icmp_header_t ); |
if( ! header ){ |
pq_release( icmp_globals.net_phone, packet_get_id( packet )); |
return NULL; |
} |
bzero( header, sizeof( * header )); |
return header; |
} |
int icmp_send_packet( icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header ){ |
ERROR_DECLARE; |
header->type = type; |
header->code = code; |
header->checksum = 0; |
header->checksum = ICMP_HEADER_CHECKSUM( header ); |
if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_ICMP, 0, 0, 0, 0 ))){ |
pq_release( icmp_globals.net_phone, packet_get_id( packet )); |
return ERROR_CODE; |
} |
return ip_send_msg( icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, SERVICE_ICMP ); |
} |
int icmp_connect_module( services_t service ){ |
return EOK; |
} |
int icmp_initialize( async_client_conn_t client_connection ){ |
ERROR_DECLARE; |
fibril_rwlock_initialize( & icmp_globals.lock ); |
fibril_rwlock_write_lock( & icmp_globals.lock ); |
icmp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection, icmp_received_msg ); |
if( icmp_globals.ip_phone < 0 ){ |
return icmp_globals.ip_phone; |
} |
ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.addr_len, & icmp_globals.prefix, & icmp_globals.content, & icmp_globals.suffix )); |
icmp_globals.prefix += sizeof( icmp_header_t ); |
icmp_globals.content -= sizeof( icmp_header_t ); |
fibril_rwlock_write_unlock( & icmp_globals.lock ); |
return EOK; |
} |
int icmp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ){ |
ERROR_DECLARE; |
if( error ){ |
pq_release( icmp_globals.net_phone, packet_get_id( packet )); |
return EINVAL; |
} |
if( ERROR_OCCURRED( icmp_process_packet( packet ))){ |
pq_release( icmp_globals.net_phone, packet_get_id( packet )); |
return ERROR_CODE; |
} |
return EOK; |
} |
int icmp_process_packet( packet_t packet ){ |
int length; |
void * data; |
icmp_header_ref header; |
// get rid of the ip header |
length = ip_client_process_packet( packet, NULL, NULL, NULL, NULL, NULL ); |
if( length < 0 ) return length; |
packet_trim( packet, length, 0 ); |
length = packet_get_data_length( packet ); |
if( length <= 0 ) return EINVAL; |
if( length < sizeof( icmp_header_t )) return EINVAL; |
data = packet_get_data( packet ); |
if( ! data ) return EINVAL; |
// get icmp header |
header = ( icmp_header_ref ) data; |
// checksum |
if(( header->checksum ) && ( ICMP_HEADER_CHECKSUM( header ))){ |
return EINVAL; |
} |
// TODO process requests and replies |
ip_received_error_msg( icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP ); |
return EOK; |
} |
int icmp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ |
ERROR_DECLARE; |
packet_t packet; |
* answer_count = 0; |
switch( IPC_GET_METHOD( * call )){ |
case NET_TL_RECEIVED: |
fibril_rwlock_read_lock( & icmp_globals.lock ); |
if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){ |
ERROR_CODE = icmp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_ICMP, IPC_GET_ERROR( call )); |
} |
fibril_rwlock_read_unlock( & icmp_globals.lock ); |
return ERROR_CODE; |
case NET_ICMP_DEST_UNREACH: |
ERROR_PROPAGATE( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
return icmp_destination_unreachable_msg( 0, ICMP_GET_CODE( call ), ICMP_GET_MTU( call ), packet ); |
case NET_ICMP_SOURCE_QUENCH: |
ERROR_PROPAGATE( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
return icmp_source_quench_msg( 0, packet ); |
case NET_ICMP_TIME_EXCEEDED: |
ERROR_PROPAGATE( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
return icmp_time_exceeded_msg( 0, ICMP_GET_CODE( call ), packet ); |
case NET_ICMP_PARAMETERPROB: |
ERROR_PROPAGATE( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
return icmp_parameter_problem_msg( 0, ICMP_GET_CODE( call ), ICMP_GET_POINTER( call ), packet ); |
} |
return ENOTSUP; |
} |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/icmp/Makefile |
---|
0,0 → 1,52 |
# |
# Copyright (c) 2009 Lukas Mejdrech |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
NAME = icmp |
NET_BASE = ../../ |
STRUCTURES = $(NET_BASE)structures/ |
## Sources |
# |
OUTPUT = $(NAME) |
SOURCES = \ |
$(NAME)_module.c \ |
$(NAME).c \ |
$(NET_BASE)module.c \ |
$(NET_BASE)modules.c \ |
$(NET_BASE)crc.c \ |
$(STRUCTURES)packet/packet.c \ |
$(STRUCTURES)packet/packet_client.c \ |
$(STRUCTURES)packet/packet_remote.c \ |
$(STRUCTURES)measured_strings.c \ |
$(NET_BASE)il/ip/ip_client.c \ |
$(NET_BASE)il/ip/ip_remote.c \ |
$(NET_BASE)net/net_remote.c |
include $(NET_BASE)Makefile.module |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/icmp/icmp.h |
---|
0,0 → 1,79 |
/* |
* Copyright (c) 2008 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP module. |
*/ |
#ifndef __NET_ICMP_H__ |
#define __NET_ICMP_H__ |
#include <fibril_sync.h> |
#include "../../socket/socket_core.h" |
/** Type definition of the ICMP global data. |
* @see icmp_globals |
*/ |
typedef struct icmp_globals icmp_globals_t; |
/** ICMP global data. |
*/ |
struct icmp_globals{ |
/** IP module phone. |
*/ |
int ip_phone; |
/** Reserved packet prefix length. |
*/ |
size_t prefix; |
/** Maximal packet content length. |
*/ |
size_t content; |
/** Reserved packet suffix length. |
*/ |
size_t suffix; |
/** Packet address length. |
*/ |
size_t addr_len; |
/** Networking module phone. |
*/ |
int net_phone; |
/** Safety lock. |
*/ |
fibril_rwlock_t lock; |
}; |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/icmp/icmp_module.c |
---|
0,0 → 1,120 |
/* |
* Copyright (c) 2008 Lukas Mejdrech |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup icmp |
* @{ |
*/ |
/** @file |
* ICMP standalone module implementation. |
* Contains skeleton module functions mapping. |
* The functions are used by the module skeleton as module specific entry points. |
* @see module.c |
*/ |
#include <async.h> |
#include <stdio.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include "../../err.h" |
#include "../../modules.h" |
#include "../../structures/packet/packet.h" |
#include "../../include/net_interface.h" |
#include "icmp.h" |
#include "icmp_module.h" |
/** ICMP module name. |
*/ |
#define NAME "ICMP protocol" |
/** Prints the module name. |
* @see NAME |
*/ |
void module_print_name( void ); |
/** Starts the ICMP module. |
* Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop. |
* @param client_connection The client connection processing function. The module skeleton propagates its own one. Input parameter. |
* @returns EOK on successful module termination. |
* @returns Other error codes as defined for the arp_initialize() function. |
* @returns Other error codes as defined for the REGISTER_ME() macro function. |
*/ |
int module_start( async_client_conn_t client_connection ); |
/** Processes the ICMP message. |
* @param callid The message identifier. Input parameter. |
* @param call The message parameters. Input parameter. |
* @param answer The message answer parameters. Output parameter. |
* @param answer_count The last parameter for the actual answer in the answer parameter. Output parameter. |
* @returns EOK on success. |
* @returns Other error codes as defined for the icmp_message() function. |
*/ |
int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ); |
/** ICMP module global data. |
*/ |
extern icmp_globals_t icmp_globals; |
void module_print_name( void ){ |
printf( "%s", NAME ); |
} |
int module_start( async_client_conn_t client_connection ){ |
ERROR_DECLARE; |
ipcarg_t phonehash; |
async_set_client_connection( client_connection ); |
icmp_globals.net_phone = net_connect_module( SERVICE_NETWORKING ); |
if( icmp_globals.net_phone < 0 ){ |
return icmp_globals.net_phone; |
} |
ERROR_PROPAGATE( pm_init()); |
if( ERROR_OCCURRED( icmp_initialize( client_connection )) |
|| ERROR_OCCURRED( REGISTER_ME( SERVICE_ICMP, & phonehash ))){ |
pm_destroy(); |
return ERROR_CODE; |
} |
async_manager(); |
pm_destroy(); |
return EOK; |
} |
int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ |
return icmp_message( callid, call, answer, answer_count ); |
} |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/il/ip/ip_remote.c |
---|
55,8 → 55,8 |
return generic_device_req( ip_phone, NET_IL_DEVICE, device_id, 0, service ); |
} |
int ip_send_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t sender ){ |
return generic_send_msg( ip_phone, NET_IL_SEND, device_id, packet_get_id( packet ), sender ); |
int ip_send_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ){ |
return generic_send_msg( ip_phone, NET_IL_SEND, device_id, packet_get_id( packet ), sender, error ); |
} |
int ip_connect_module( services_t service ){ |
79,5 → 79,9 |
return ( int ) bind_service( service, ( ipcarg_t ) protocol, me, service, receiver ); |
} |
int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error ){ |
return generic_received_msg( ip_phone, NET_IP_RECEIVED_ERROR, device_id, packet_get_id( packet ), target, error ); |
} |
/** @} |
*/ |
/branches/network/uspace/srv/net/il/ip/ip_messages.h |
---|
50,7 → 50,11 |
/** Sets the default gateway. |
* @see ip_set_default_gateway() |
*/ |
NET_IP_SET_GATEWAY |
NET_IP_SET_GATEWAY, |
/** Processes the received error notification. |
* @see ip_received_error_msg() |
*/ |
NET_IP_RECEIVED_ERROR |
} ip_messages; |
/** @name IP specific message parameters definitions |
/branches/network/uspace/srv/net/il/ip/ip_client.c |
---|
79,11 → 79,19 |
if( dont_fragment ) * dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT; |
if( ipopt_length ){ |
* ipopt_length = header->ihl * 4 - sizeof( ip_header_t ); |
return packet_trim( packet, sizeof( ip_header_t ), 0 ); |
return sizeof( ip_header_t ); |
}else{ |
return packet_trim( packet, header->ihl * 4, 0 ); |
return header->ihl * 4; |
} |
} |
int ip_client_header_length( packet_t packet ){ |
ip_header_ref header; |
header = ( ip_header_ref ) packet_get_data( packet ); |
if( ! header ) return ENOMEM; |
return header->ihl * 4; |
} |
/** @} |
*/ |
/branches/network/uspace/srv/net/il/ip/ip.c |
---|
63,6 → 63,9 |
#include "../../include/ip_client.h" |
#include "../../include/ip_interface.h" |
#include "../../include/tl_interface.h" |
#include "../../include/icmp_codes.h" |
#include "../../include/icmp_interface.h" |
#include "../../include/icmp_client.h" |
#include "../../structures/measured_strings.h" |
#include "../../structures/module_map.h" |
#include "../../structures/packet/packet_client.h" |
178,16 → 181,16 |
*/ |
int ip_netif_initialize( ip_netif_ref ip_netif ); |
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest ); |
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error ); |
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ); |
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len ); |
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len, services_t error ); |
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, size_t addr_len ); |
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, void * src, void * dest, size_t address_length ); |
ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ); |
void ip_create_last_header( ip_header_ref last, ip_header_ref first ); |
in_addr_t * ip_netif_addr( ip_netif_ref netif ); |
in_addr_t * ip_netif_address( ip_netif_ref netif ); |
ip_route_ref ip_find_route( in_addr_t destination ); |
ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ); |
205,7 → 208,7 |
int ip_process_packet( device_id_t device_id, packet_t packet ); |
in_addr_t ip_get_destination( ip_header_ref header ); |
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header ); |
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ); |
/** Computes the ip header checksum. |
* To compute the checksum of a new packet, the checksum header field must be zero. |
218,6 → 221,12 |
*/ |
uint16_t ip_checksum( uint8_t * data, size_t length ); |
int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ); |
int ip_get_icmp_phone( void ); |
int ip_prepare_icmp( packet_t packet, ip_header_ref header ); |
static int release_and_return( packet_t packet, int result ); |
uint16_t ip_checksum( uint8_t * data, size_t length ){ |
uint16_t checksum; |
518,7 → 527,7 |
return EOK; |
} |
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender ){ |
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ){ |
ERROR_DECLARE; |
int length; |
526,22 → 535,20 |
ip_route_ref route; |
in_addr_t * dest; |
in_addr_t * src; |
int phone; |
// addresses in the host byte order |
// should be the next hop address or the target destination address |
length = packet_get_addr( packet, NULL, ( uint8_t ** ) & dest ); |
if( length < 0 ){ |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
return length; |
return release_and_return( packet, length ); |
} |
// TODO IPv6 |
if( length != IP_ADDR ){ |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
return EINVAL; |
return release_and_return( packet, EINVAL ); |
} |
fibril_rwlock_read_lock( & ip_globals.netifs_lock ); |
// device specified? |
// dest.s_addr = ntohl( dest.s_addr ); |
if( device_id > 0 ){ |
netif = ip_netifs_find( & ip_globals.netifs, device_id ); |
route = ip_netif_find_route( netif, * dest ); |
552,23 → 559,35 |
} |
if( !( netif && route )){ |
fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
phone = ip_prepare_icmp_and_get_phone( error, packet, NULL ); |
if( phone >= 0 ){ |
// unreachable ICMP if no routing |
icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet ); |
} |
return ENOENT; |
} |
if( error ){ |
// do not send for broadcast, anycast packets or network broadcast |
if(( ! dest->s_addr ) |
|| ( !( ~ dest->s_addr )) |
|| ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr ))) |
|| ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){ |
return release_and_return( packet, EINVAL ); |
} |
} |
// to me? |
if( route->address.s_addr == dest->s_addr ){ |
// TODO loopback deliver |
fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); |
return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet )); |
return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet ), error ); |
} |
src = ip_netif_addr( netif ); |
src = ip_netif_address( netif ); |
if( ! src ){ |
fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
return ENOENT; |
return release_and_return( packet, ENOENT ); |
} |
if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, * dest ))){ |
if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, * dest, error ))){ |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
} |
fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); |
575,7 → 594,7 |
return ERROR_CODE; |
} |
in_addr_t * ip_netif_addr( ip_netif_ref netif ){ |
in_addr_t * ip_netif_address( ip_netif_ref netif ){ |
ip_route_ref route; |
route = ip_routes_get_index( & netif->routes, 0 ); |
582,12 → 601,13 |
return route ? & route->address : NULL; |
} |
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest ){ |
int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error ){ |
ERROR_DECLARE; |
measured_string_t destination; |
measured_string_ref translation; |
char * data; |
int phone; |
// get destination hardware address |
if( netif->arp ){ |
597,12 → 617,16 |
sleep( 1 ); |
ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data )); |
} |
// TODO unreachable |
if( ! translation ) return EINVAL; |
if( ! translation->value ){ |
// TODO unreachable |
if( !( translation && translation->value )){ |
if( translation ){ |
free( translation ); |
free( data ); |
} |
phone = ip_prepare_icmp_and_get_phone( error, packet, NULL ); |
if( phone >= 0 ){ |
// unreachable ICMP if no routing |
icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet ); |
} |
return EINVAL; |
} |
}else translation = NULL; |
609,7 → 633,7 |
if( ERROR_OCCURRED( ip_prepare_packet( src, dest, packet, translation ))){ |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
}else{ |
packet = ip_split_packet( packet, netif->prefix, netif->content, netif->suffix, netif->addr_len ); |
packet = ip_split_packet( packet, netif->prefix, netif->content, netif->suffix, netif->addr_len, error ); |
if( packet ){ |
nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP ); |
} |
699,12 → 723,15 |
return ip_register( IL_GET_PROTO( call ), IL_GET_SERVICE( call ), IPC_GET_PHONE( call ), NULL ); |
case NET_IL_SEND: |
ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0 ); |
return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0, IPC_GET_ERROR( call )); |
case NET_IL_DEVICE_STATE: |
return ip_device_state_message( IPC_GET_DEVICE( call ), IPC_GET_STATE( call )); |
case NET_IL_RECEIVED: |
ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
return ip_receive_message( IPC_GET_DEVICE( call ), packet ); |
case NET_IP_RECEIVED_ERROR: |
ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
return ip_received_error_msg( 0, IPC_GET_DEVICE( call ), packet, IPC_GET_TARGET( call ), IPC_GET_ERROR( call )); |
case NET_IP_ADD_ROUTE: |
return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call )); |
case NET_IP_SET_GATEWAY: |
831,10 → 858,12 |
return EOK; |
} |
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len ){ |
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len, services_t error ){ |
size_t length; |
packet_t next; |
packet_t new_packet; |
int result; |
int phone; |
next = packet; |
// check all packets |
842,12 → 871,23 |
length = packet_get_data_length( next ); |
// too long? |
if( length > content ){ |
if( ip_fragment_packet( next, content, prefix, suffix, addr_len ) != EOK ){ |
result = ip_fragment_packet( next, content, prefix, suffix, addr_len ); |
if( result != EOK ){ |
new_packet = pq_detach( next ); |
if( next == packet ){ |
// the new first packet of the queue |
packet = new_packet; |
} |
// fragmentation needed? |
if( result == EPERM ){ |
phone = ip_prepare_icmp_and_get_phone( error, next, NULL ); |
if( phone >= 0 ){ |
// fragmentation necessary ICMP |
icmp_destination_unreachable_msg( phone, ICMP_FRAG_NEEDED, content, next ); |
} |
}else{ |
pq_release( ip_globals.net_phone, packet_get_id( next )); |
} |
next = new_packet; |
continue; |
} |
876,7 → 916,6 |
if( ! header ) return EINVAL; |
// fragmentation forbidden? |
if( header->flags & IPFLAG_DONT_FRAGMENT ){ |
// TODO fragmentation necessary ICMP |
return EPERM; |
} |
// create the last fragment |
885,21 → 924,18 |
// allocate as much as originally |
last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header )); |
if( ! last_header ){ |
pq_release( ip_globals.net_phone, packet_get_id( new_packet )); |
return ENOMEM; |
return release_and_return( packet, ENOMEM ); |
} |
ip_create_last_header( last_header, header ); |
// trim the unused space |
if( ERROR_OCCURRED( packet_trim( new_packet, 0, IP_HEADER_LENGTH( header ) - IP_HEADER_LENGTH( last_header )))){ |
pq_release( ip_globals.net_phone, packet_get_id( new_packet )); |
return ERROR_CODE; |
return release_and_return( packet, ERROR_CODE ); |
} |
// biggest multiple of 8 lower than content |
// TODO even fragmentation? |
length = length & ( ~ 0x7 );// ( content / 8 ) * 8 |
if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, last_header, (( IP_TOTAL_LENGTH( header ) - length ) % ( length - IP_HEADER_LENGTH( last_header ))), src, dest, address_length ))){ |
pq_release( ip_globals.net_phone, packet_get_id( new_packet )); |
return ERROR_CODE; |
return release_and_return( packet, ERROR_CODE ); |
} |
// mark the first as fragmented |
header->flags |= IPFLAG_MORE_FRAGMENTS; |
909,17 → 945,14 |
if( ! new_packet ) return ENOMEM; |
middle_header = ip_create_middle_header( new_packet, last_header ); |
if( ! middle_header ){ |
pq_release( ip_globals.net_phone, packet_get_id( new_packet )); |
return ENOMEM; |
return release_and_return( packet, ENOMEM ); |
} |
if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, length - IP_HEADER_LENGTH( middle_header ), src, dest, address_length ))){ |
pq_release( ip_globals.net_phone, packet_get_id( new_packet )); |
return ERROR_CODE; |
return release_and_return( packet, ERROR_CODE ); |
} |
} |
// finish the first fragment |
header->header_checksum = IP_HEADER_CHECKSUM( header ); |
printf( "ok\n" ); |
return EOK; |
} |
990,9 → 1023,7 |
do{ |
next = pq_detach( packet ); |
if( ip_process_packet( device_id, packet ) != EOK ){ |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
} |
ip_process_packet( device_id, packet ); |
packet = next; |
}while( packet ); |
return EOK; |
1004,42 → 1035,102 |
ip_header_ref header; |
in_addr_t dest; |
ip_route_ref route; |
int phone; |
header = ( ip_header_ref ) packet_get_data( packet ); |
if( ! header ) return ENOMEM; |
if( ! header ){ |
return release_and_return( packet, ENOMEM ); |
} |
// checksum |
if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ))){ |
// TODO checksum error ICMP? |
return release_and_return( packet, EINVAL ); |
} |
if( header->ttl <= 1 ){ |
phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); |
if( phone >= 0 ){ |
// ttl oxceeded ICMP |
icmp_time_exceeded_msg( phone, ICMP_EXC_TTL, packet ); |
} |
return EINVAL; |
} |
// TODO ttl oxceeded ICMP? |
if( !( -- header->ttl )) return EINVAL; |
// process ipopt and get destination |
dest = ip_get_destination( header ); |
ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & dest.s_addr, IP_ADDR )); |
route = ip_find_route( dest ); |
// TODO unreachable ICMP? |
if( ! route ) return ENOENT; |
if( ! route ){ |
phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); |
if( phone >= 0 ){ |
// unreachable ICMP |
icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet ); |
} |
return ENOENT; |
} |
if( route->address.s_addr == dest.s_addr ){ |
// local delivery |
return ip_deliver_local( device_id, packet, header ); |
return ip_deliver_local( device_id, packet, header, 0 ); |
}else{ |
// only if routing enabled |
if( route->netif->routing ){ |
return ip_send_route( packet, route->netif, route, NULL, dest ); |
-- header->ttl; |
return ip_send_route( packet, route->netif, route, NULL, dest, 0 ); |
}else{ |
phone = ip_prepare_icmp_and_get_phone( 0, packet, header ); |
if( phone >= 0 ){ |
// unreachable ICMP if no routing |
icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet ); |
} |
else |
{ |
// TODO icmp unreachable? |
return ENOENT; |
} |
} |
} |
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header ){ |
int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error ){ |
uint8_t * data; |
int offset; |
icmp_type_t type; |
icmp_code_t code; |
ip_netif_ref netif; |
measured_string_t address; |
ip_route_ref route; |
ip_header_ref header; |
switch( error ){ |
case SERVICE_ICMP: |
offset = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); |
if( offset < 0 ){ |
return release_and_return( packet, ENOMEM ); |
} |
data = packet_get_data( packet ); |
header = ( ip_header_ref ) data + offset; |
// destination host unreachable? |
if(( type == ICMP_DEST_UNREACH ) && ( code == ICMP_HOST_UNREACH )){ |
fibril_rwlock_read_lock( & ip_globals.netifs_lock ); |
netif = ip_netifs_find( & ip_globals.netifs, device_id ); |
if( netif && netif->arp ){ |
route = ip_routes_get_index( & netif->routes, 0 ); |
// from the same network? |
if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( header->destination_address & route->netmask.s_addr ))){ |
// clear the ARP mapping if any |
address.value = ( char * ) & header->destination_address; |
address.length = CONVERT_SIZE( uint8_t, char, sizeof( header->destination_address )); |
arp_clear_address_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address ); |
} |
} |
fibril_rwlock_read_unlock( & ip_globals.netifs_lock ); |
} |
break; |
default: |
return release_and_return( packet, ENOTSUP ); |
} |
return ip_deliver_local( device_id, packet, header, error ); |
} |
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ){ |
ERROR_DECLARE; |
ip_proto_ref proto; |
int phone; |
if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){ |
// TODO fragmented |
1050,12 → 1141,17 |
proto = ip_protos_find( & ip_globals.protos, header->protocol ); |
if( ! proto ){ |
fibril_rwlock_read_unlock( & ip_globals.protos_lock ); |
phone = ip_prepare_icmp_and_get_phone( error, packet, header ); |
if( phone >= 0 ){ |
// unreachable ICMP |
icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet ); |
} |
return ENOENT; |
} |
if( proto->received_msg ){ |
ERROR_CODE = proto->received_msg( device_id, packet, SERVICE_IP ); |
ERROR_CODE = proto->received_msg( device_id, packet, proto->service, error ); |
}else{ |
ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service ); |
ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error ); |
} |
fibril_rwlock_read_unlock( & ip_globals.protos_lock ); |
return ERROR_CODE; |
1066,9 → 1162,55 |
in_addr_t destination; |
// TODO search set ipopt route? |
destination.s_addr = header->destination_address; //ntohl( header->destination_address ); |
destination.s_addr = header->destination_address; |
return destination; |
} |
int ip_prepare_icmp( packet_t packet, ip_header_ref header ){ |
packet_t next; |
// detach the first packet and release the others |
next = pq_detach( packet ); |
if( next ){ |
pq_release( ip_globals.net_phone, packet_get_id( next )); |
} |
if( ! header ){ |
if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM; |
// get header |
header = ( ip_header_ref ) packet_get_data( packet ); |
if( ! header ) return EINVAL; |
} |
// only for the first fragment |
if( header->fragment_offset ) return EINVAL; |
// set the destination address |
return packet_set_addr( packet, NULL, ( uint8_t * ) & header->source_address, sizeof( header->source_address )); |
} |
int ip_get_icmp_phone( void ){ |
ip_proto_ref proto; |
int phone; |
fibril_rwlock_read_lock( & ip_globals.protos_lock ); |
proto = ip_protos_find( & ip_globals.protos, IPPROTO_ICMP ); |
phone = proto ? proto->phone : ENOENT; |
fibril_rwlock_read_unlock( & ip_globals.protos_lock ); |
return phone; |
} |
int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ){ |
int phone; |
phone = ip_get_icmp_phone(); |
if( error || ( phone < 0 ) || ip_prepare_icmp( packet, header )){ |
return release_and_return( packet, EINVAL ); |
} |
return phone; |
} |
static int release_and_return( packet_t packet, int result ){ |
pq_release( ip_globals.net_phone, packet_get_id( packet )); |
return result; |
} |
/** @} |
*/ |
/branches/network/uspace/srv/net/il/ip/Makefile |
---|
50,6 → 50,8 |
$(NET_BASE)inet.c \ |
$(STRUCTURES)/packet/packet_remote.c \ |
$(NET_BASE)il/arp/arp_remote.c \ |
$(NET_BASE)il/icmp/icmp_remote.c \ |
$(NET_BASE)il/icmp/icmp_client.c \ |
$(NET_BASE)nil/nil_remote.c \ |
$(NET_BASE)net/net_remote.c |
/branches/network/uspace/srv/net/netif/netif_remote.c |
---|
57,7 → 57,7 |
} |
int netif_send_msg( int netif_phone, device_id_t device_id, packet_t packet, services_t sender ){ |
return generic_send_msg( netif_phone, NET_NETIF_SEND, device_id, packet_get_id( packet ), sender ); |
return generic_send_msg( netif_phone, NET_NETIF_SEND, device_id, packet_get_id( packet ), sender, 0 ); |
} |
int netif_start_req( int netif_phone, device_id_t device_id ){ |
/branches/network/uspace/srv/net/Makefile |
---|
38,12 → 38,12 |
socket \ |
app/echo |
DIRS_MODULAR = il/ip \ |
DIRS_MODULAR = \ |
il/arp \ |
il/ip \ |
il/icmp \ |
tl/udp \ |
tl/tcp \ |
# il/rarp \ |
# il/icmp \ |
DIRS_ALL = $(DIRS) $(DIRS_MODULAR) |