diff --git a/Demo/Common/ethernet/FreeTCPIP/uip.c b/Demo/Common/ethernet/FreeTCPIP/uip.c index c03dde4eb..0a3fbb5af 100644 --- a/Demo/Common/ethernet/FreeTCPIP/uip.c +++ b/Demo/Common/ethernet/FreeTCPIP/uip.c @@ -75,13 +75,12 @@ #include "net/uip_arp.h" #include "net/uip_arch.h" -#if !UIP_CONF_IPV6 /* If UIP_CONF_IPV6 is defined, we compile the - uip6.c file instead of this one. Therefore - this #ifndef removes the entire compilation - output of the uip.c file */ +/* If UIP_CONF_IPV6 is defined, we compile the uip6.c file instead of this one. +Therefore this #ifndef removes the entire compilation output of the uip.c file */ +#if !UIP_CONF_IPV6 #if UIP_CONF_IPV6 -#include "net/uip-neighbor.h" + #include "net/uip-neighbor.h" #endif /* UIP_CONF_IPV6 */ #include @@ -90,96 +89,89 @@ /* Variable definitions. */ -/* The IP address of this host. If it is defined to be fixed (by - setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set - here. Otherwise, the address */ +/* The IP address of this host. If it is defined to be fixed (by setting +UIP_FIXEDADDR to 1 in uipopt.h), the address is set here. Otherwise, the address */ #if UIP_FIXEDADDR > 0 -const uip_ipaddr_t uip_hostaddr = { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 }; -const uip_ipaddr_t uip_draddr = { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 }; -const uip_ipaddr_t uip_netmask = { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 }; + const uip_ipaddr_t uip_hostaddr = { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 }; + const uip_ipaddr_t uip_draddr = { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 }; + const uip_ipaddr_t uip_netmask = { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 }; #else -uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; + uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; #endif /* UIP_FIXEDADDR */ const uip_ipaddr_t uip_broadcast_addr = #if UIP_CONF_IPV6 -{ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; + { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; #else /* UIP_CONF_IPV6 */ -{ - { - 0xff, 0xff, 0xff, 0xff - } -}; + { { 0xff, 0xff, 0xff, 0xff } }; #endif /* UIP_CONF_IPV6 */ -const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } }; + +const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } }; #if UIP_FIXEDETHADDR -const struct uip_eth_addr uip_ethaddr = { { UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5 } }; + const struct uip_eth_addr uip_ethaddr = { { UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5 } }; #else -struct uip_eth_addr uip_ethaddr = { { 0, 0, 0, 0, 0, 0 } }; + struct uip_eth_addr uip_ethaddr = { { 0, 0, 0, 0, 0, 0 } }; #endif + #ifndef UIP_CONF_EXTERNAL_BUFFER -u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains - incoming packets. */ + /* The packet buffer that contains incoming packets. */ + u8_t uip_buf[ UIP_BUFSIZE + 2 ]; #endif /* UIP_CONF_EXTERNAL_BUFFER */ -void *uip_appdata; /* The uip_appdata pointer points to - application data. */ -void *uip_sappdata; /* The uip_appdata pointer points to - the application data which is to - be sent. */ +/* The uip_appdata pointer points to application data. */ +void *uip_appdata; + +/* The uip_appdata pointer points to the application data which is to be sent. */ +void *uip_sappdata; + #if UIP_URGDATA > 0 -void *uip_urgdata; /* The uip_urgdata pointer points to - urgent data (out-of-band data), if - present. */ -u16_t uip_urglen, uip_surglen; + /* The uip_urgdata pointer points to urgent data (out-of-band data), if + present. */ + void *uip_urgdata; + u16_t uip_urglen, uip_surglen; #endif /* UIP_URGDATA > 0 */ -u16_t uip_len, uip_slen; +/* The uip_len is either 8 or 16 bits, depending on the maximum packet size. */ +u16_t uip_len, uip_slen; -/* The uip_len is either 8 or 16 bits, - depending on the maximum packet - size. */ -u8_t uip_flags; /* The uip_flags variable is used for - communication between the TCP/IP stack - and the application program. */ -struct uip_conn *uip_conn; /* uip_conn always points to the current - connection. */ +/* The uip_flags variable is used for communication between the TCP/IP stack +and the application program. */ +u8_t uip_flags; -struct uip_conn uip_conns[UIP_CONNS]; +/* uip_conn always points to the current connection. */ +struct uip_conn *uip_conn; +struct uip_conn uip_conns[ UIP_CONNS ]; -/* The uip_conns array holds all TCP - connections. */ -u16_t uip_listenports[UIP_LISTENPORTS]; +/* The uip_conns array holds all TCP connections. */ +u16_t uip_listenports[UIP_LISTENPORTS]; -/* The uip_listenports list all currently - listning ports. */ +/* The uip_listenports list all currently listning ports. */ #if UIP_UDP -struct uip_udp_conn *uip_udp_conn; -struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; + struct uip_udp_conn *uip_udp_conn; + struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; #endif /* UIP_UDP */ -static u16_t ipid; /* Ths ipid variable is an increasing - number that is used for the IP ID - field. */ +/* Ths ipid variable is an increasing number that is used for the IP ID field. */ +static u16_t ipid; void uip_setipid( u16_t id ) { ipid = id; } -static u8_t iss[4]; /* The iss variable is used for the TCP - initial sequence number. */ +/* The iss variable is used for the TCP initial sequence number. */ +static u8_t iss[ 4 ]; #if UIP_ACTIVE_OPEN -static u16_t lastport; /* Keeps track of the last port used for - a new connection. */ + /* Keeps track of the last port used for a new connection. */ + static u16_t lastport; #endif /* UIP_ACTIVE_OPEN */ /* Temporary variables. */ -u8_t uip_acc32[4]; -static u8_t c, opt; -static u16_t tmp16; +u8_t uip_acc32[ 4 ]; +static u8_t c, opt; +static u16_t tmp16; /* Structures and definitions. */ #define TCP_FIN 0x01 @@ -216,42 +208,31 @@ static u16_t tmp16; #define FBUF ( ( struct uip_tcpip_hdr * ) &uip_reassbuf[0] ) #define ICMPBUF ( ( struct uip_icmpip_hdr * ) &uip_buf[UIP_LLH_LEN] ) #define UDPBUF ( ( struct uip_udpip_hdr * ) &uip_buf[UIP_LLH_LEN] ) + #if UIP_STATISTICS == 1 -struct uip_stats uip_stat; -#define UIP_STAT( s ) s + struct uip_stats uip_stat; + #define UIP_STAT( s ) s #else -#define UIP_STAT( s ) + #define UIP_STAT( s ) #endif /* UIP_STATISTICS == 1 */ #if UIP_LOGGING == 1 -#include -void uip_log( char *msg ); -#define UIP_LOG( m ) uip_log( m ) + #include + void uip_log( char *msg ); + #define UIP_LOG( m ) uip_log( m ) #else -#define UIP_LOG( m ) + #define UIP_LOG( m ) #endif /* UIP_LOGGING == 1 */ #if !UIP_ARCH_ADD32 -void uip_add32( u8_t *op32, u16_t op16 ) -{ - uip_acc32[3] = op32[3] + ( op16 & 0xff ); - uip_acc32[2] = op32[2] + ( op16 >> 8 ); - uip_acc32[1] = op32[1]; - uip_acc32[0] = op32[0]; - - if( uip_acc32[2] < (op16 >> 8) ) + void uip_add32( u8_t *op32, u16_t op16 ) { - ++uip_acc32[1]; - if( uip_acc32[1] == 0 ) - { - ++uip_acc32[0]; - } - } + uip_acc32[3] = op32[3] + ( op16 & 0xff ); + uip_acc32[2] = op32[2] + ( op16 >> 8 ); + uip_acc32[1] = op32[1]; + uip_acc32[0] = op32[0]; - if( uip_acc32[3] < (op16 & 0xff) ) - { - ++uip_acc32[2]; - if( uip_acc32[2] == 0 ) + if( uip_acc32[2] < (op16 >> 8) ) { ++uip_acc32[1]; if( uip_acc32[1] == 0 ) @@ -259,468 +240,474 @@ void uip_add32( u8_t *op32, u16_t op16 ) ++uip_acc32[0]; } } - } -} + if( uip_acc32[3] < (op16 & 0xff) ) + { + ++uip_acc32[2]; + if( uip_acc32[2] == 0 ) + { + ++uip_acc32[1]; + if( uip_acc32[1] == 0 ) + { + ++uip_acc32[0]; + } + } + } + } +/*---------------------------------------------------------------------------*/ #endif /* UIP_ARCH_ADD32 */ #if !UIP_ARCH_CHKSUM -/*---------------------------------------------------------------------------*/ -static u16_t chksum( u16_t sum, const u8_t *data, u16_t len ) -{ - u16_t t; - const u8_t *dataptr; - const u8_t *last_byte; - - dataptr = data; - last_byte = data + len - 1; - - while( dataptr < last_byte ) - { /* At least two more bytes */ - t = ( dataptr[0] << 8 ) + dataptr[1]; - sum += t; - if( sum < t ) - { - sum++; /* carry */ - } - - dataptr += 2; - } - - if( dataptr == last_byte ) + static u16_t chksum( u16_t sum, const u8_t *data, u16_t len ) { - t = ( dataptr[0] << 8 ) + 0; - sum += t; - if( sum < t ) + u16_t t; + const u8_t *dataptr; + const u8_t *last_byte; + + dataptr = data; + last_byte = data + len - 1; + + while( dataptr < last_byte ) { - sum++; /* carry */ + /* At least two more bytes */ + t = ( dataptr[ 0 ] << 8 ) + dataptr[ 1 ]; + sum += t; + if( sum < t ) + { + sum++; /* carry */ + } + + dataptr += 2; } + + if( dataptr == last_byte ) + { + t = ( dataptr[ 0 ] << 8 ) + 0; + sum += t; + if( sum < t ) + { + sum++; /* carry */ + } + } + + /* Return sum in host byte order. */ + return sum; } + /*---------------------------------------------------------------------------*/ - /* Return sum in host byte order. */ - return sum; -} + u16_t uip_chksum( u16_t *data, u16_t len ) + { + return htons( chksum( 0, ( u8_t * ) data, len ) ); + } + /*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -u16_t uip_chksum( u16_t *data, u16_t len ) -{ - return htons( chksum(0, ( u8_t * ) data, len) ); -} + #ifndef UIP_ARCH_IPCHKSUM + u16_t uip_ipchksum( void ) + { + u16_t sum; -/*---------------------------------------------------------------------------*/ -#ifndef UIP_ARCH_IPCHKSUM -u16_t uip_ipchksum( void ) -{ - u16_t sum; + sum = chksum( 0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN ); - sum = chksum( 0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN ); + //DEBUG_PRINTF( "uip_ipchksum: sum 0x%04x\n", sum ); + return( sum == 0 ) ? 0xffff : htons( sum ); + } + #endif + /*---------------------------------------------------------------------------*/ - //DEBUG_PRINTF( "uip_ipchksum: sum 0x%04x\n", sum ); - return( sum == 0 ) ? 0xffff : htons( sum ); -} + static u16_t upper_layer_chksum( u8_t proto ) + { + u16_t upper_layer_len; + u16_t sum; -#endif + #if UIP_CONF_IPV6 + upper_layer_len = ( ((u16_t) (BUF->len[ 0 ]) << 8) + BUF->len[ 1 ] ); + #else /* UIP_CONF_IPV6 */ + upper_layer_len = ( ((u16_t) (BUF->len[ 0 ]) << 8) + BUF->len[ 1 ] ) - UIP_IPH_LEN; + #endif /* UIP_CONF_IPV6 */ -/*---------------------------------------------------------------------------*/ -static u16_t upper_layer_chksum( u8_t proto ) -{ - u16_t upper_layer_len; - u16_t sum; + /* First sum pseudoheader. */ -#if UIP_CONF_IPV6 - upper_layer_len = ( ((u16_t) (BUF->len[0]) << 8) + BUF->len[1] ); -#else /* UIP_CONF_IPV6 */ - upper_layer_len = ( ((u16_t) (BUF->len[0]) << 8) + BUF->len[1] ) - UIP_IPH_LEN; -#endif /* UIP_CONF_IPV6 */ + /* IP protocol and length fields. This addition cannot carry. */ + sum = upper_layer_len + proto; - /* First sum pseudoheader. */ + /* Sum IP source and destination addresses. */ + sum = chksum( sum, ( u8_t * ) &BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t) ); - /* IP protocol and length fields. This addition cannot carry. */ - sum = upper_layer_len + proto; + /* Sum TCP header and data. */ + sum = chksum( sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_len ); - /* Sum IP source and destination addresses. */ - sum = chksum( sum, ( u8_t * ) &BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t) ); + return( sum == 0 ) ? 0xffff : htons( sum ); + } + /*---------------------------------------------------------------------------*/ - /* Sum TCP header and data. */ - sum = chksum( sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_len ); + #if UIP_CONF_IPV6 + u16_t uip_icmp6chksum( void ) + { + return upper_layer_chksum( UIP_PROTO_ICMP6 ); + } + #endif /* UIP_CONF_IPV6 */ + /*---------------------------------------------------------------------------*/ - return( sum == 0 ) ? 0xffff : htons( sum ); -} + u16_t uip_tcpchksum( void ) + { + return upper_layer_chksum( UIP_PROTO_TCP ); + } + /*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_IPV6 -u16_t uip_icmp6chksum( void ) -{ - return upper_layer_chksum( UIP_PROTO_ICMP6 ); -} + #if UIP_UDP_CHECKSUMS + u16_t uip_udpchksum( void ) + { + return upper_layer_chksum( UIP_PROTO_UDP ); + } + #endif /* UIP_UDP_CHECKSUMS */ -#endif /* UIP_CONF_IPV6 */ - -/*---------------------------------------------------------------------------*/ -u16_t uip_tcpchksum( void ) -{ - return upper_layer_chksum( UIP_PROTO_TCP ); -} - -/*---------------------------------------------------------------------------*/ -#if UIP_UDP_CHECKSUMS -u16_t uip_udpchksum( void ) -{ - return upper_layer_chksum( UIP_PROTO_UDP ); -} - -#endif /* UIP_UDP_CHECKSUMS */ #endif /* UIP_ARCH_CHKSUM */ - /*---------------------------------------------------------------------------*/ + void uip_init( void ) { for( c = 0; c < UIP_LISTENPORTS; ++c ) { - uip_listenports[c] = 0; + uip_listenports[ c ] = 0; } for( c = 0; c < UIP_CONNS; ++c ) { - uip_conns[c].tcpstateflags = UIP_CLOSED; + uip_conns[ c ].tcpstateflags = UIP_CLOSED; } -#if UIP_ACTIVE_OPEN - lastport = 1024; -#endif /* UIP_ACTIVE_OPEN */ + #if UIP_ACTIVE_OPEN + lastport = 1024; + #endif /* UIP_ACTIVE_OPEN */ -#if UIP_UDP - for( c = 0; c < UIP_UDP_CONNS; ++c ) - { - uip_udp_conns[c].lport = 0; - } - -#endif /* UIP_UDP */ + #if UIP_UDP + for( c = 0; c < UIP_UDP_CONNS; ++c ) + { + uip_udp_conns[ c ].lport = 0; + } + #endif /* UIP_UDP */ /* IPv4 initialization. */ -#if UIP_FIXEDADDR == 0 - /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/ -#endif /* UIP_FIXEDADDR */ + #if UIP_FIXEDADDR == 0 + /* uip_hostaddr[ 0 ] = uip_hostaddr[ 1 ] = 0;*/ + #endif /* UIP_FIXEDADDR */ } - /*---------------------------------------------------------------------------*/ + #if UIP_ACTIVE_OPEN -struct uip_conn *uip_connect( uip_ipaddr_t *ripaddr, u16_t rport ) -{ - register struct uip_conn *conn, *cconn; - - /* Find an unused local port. */ -again: - ++lastport; - - if( lastport >= 32000 ) + struct uip_conn *uip_connect( uip_ipaddr_t *ripaddr, u16_t rport ) { - lastport = 4096; - } + register struct uip_conn *conn, *cconn; - /* Check if this port is already in use, and if so try to find - another one. */ - for( c = 0; c < UIP_CONNS; ++c ) - { - conn = &uip_conns[c]; - if( conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(lastport) ) + /* Find an unused local port. */ + again: + ++lastport; + + if( lastport >= 32000 ) { - goto again; - } - } - - conn = 0; - for( c = 0; c < UIP_CONNS; ++c ) - { - cconn = &uip_conns[c]; - if( cconn->tcpstateflags == UIP_CLOSED ) - { - conn = cconn; - break; + lastport = 4096; } - if( cconn->tcpstateflags == UIP_TIME_WAIT ) + /* Check if this port is already in use, and if so try to find + another one. */ + for( c = 0; c < UIP_CONNS; ++c ) { - if( conn == 0 || cconn->timer > conn->timer ) + conn = &uip_conns[ c ]; + if( conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(lastport) ) { - conn = cconn; + goto again; } } + + conn = 0; + for( c = 0; c < UIP_CONNS; ++c ) + { + cconn = &uip_conns[ c ]; + if( cconn->tcpstateflags == UIP_CLOSED ) + { + conn = cconn; + break; + } + + if( cconn->tcpstateflags == UIP_TIME_WAIT ) + { + if( conn == 0 || cconn->timer > conn->timer ) + { + conn = cconn; + } + } + } + + if( conn == 0 ) + { + return 0; + } + + conn->tcpstateflags = UIP_SYN_SENT; + + conn->snd_nxt[ 0 ] = iss[ 0 ]; + conn->snd_nxt[ 1 ] = iss[ 1 ]; + conn->snd_nxt[ 2 ] = iss[ 2 ]; + conn->snd_nxt[ 3 ] = iss[ 3 ]; + + conn->initialmss = conn->mss = UIP_TCP_MSS; + + conn->len = 1; /* TCP length of the SYN is one. */ + conn->nrtx = 0; + conn->timer = 1; /* Send the SYN next time around. */ + conn->rto = UIP_RTO; + conn->sa = 0; + conn->sv = 16; /* Initial value of the RTT variance. */ + conn->lport = htons( lastport ); + conn->rport = rport; + uip_ipaddr_copy( &conn->ripaddr, ripaddr ); + + return conn; } - - if( conn == 0 ) - { - return 0; - } - - conn->tcpstateflags = UIP_SYN_SENT; - - conn->snd_nxt[0] = iss[0]; - conn->snd_nxt[1] = iss[1]; - conn->snd_nxt[2] = iss[2]; - conn->snd_nxt[3] = iss[3]; - - conn->initialmss = conn->mss = UIP_TCP_MSS; - - conn->len = 1; /* TCP length of the SYN is one. */ - conn->nrtx = 0; - conn->timer = 1; /* Send the SYN next time around. */ - conn->rto = UIP_RTO; - conn->sa = 0; - conn->sv = 16; /* Initial value of the RTT variance. */ - conn->lport = htons( lastport ); - conn->rport = rport; - uip_ipaddr_copy( &conn->ripaddr, ripaddr ); - - return conn; -} - +/*---------------------------------------------------------------------------*/ #endif /* UIP_ACTIVE_OPEN */ -/*---------------------------------------------------------------------------*/ #if UIP_UDP -struct uip_udp_conn *uip_udp_new( const uip_ipaddr_t *ripaddr, u16_t rport ) -{ - register struct uip_udp_conn *conn; - - /* Find an unused local port. */ -again: - ++lastport; - - if( lastport >= 32000 ) + struct uip_udp_conn *uip_udp_new( const uip_ipaddr_t *ripaddr, u16_t rport ) { - lastport = 4096; - } + register struct uip_udp_conn *conn; - for( c = 0; c < UIP_UDP_CONNS; ++c ) - { - if( uip_udp_conns[c].lport == htons(lastport) ) + /* Find an unused local port. */ + again: + ++lastport; + + if( lastport >= 32000 ) { - goto again; + lastport = 4096; } - } - conn = 0; - for( c = 0; c < UIP_UDP_CONNS; ++c ) - { - if( uip_udp_conns[c].lport == 0 ) + for( c = 0; c < UIP_UDP_CONNS; ++c ) { - conn = &uip_udp_conns[c]; - break; + if( uip_udp_conns[ c ].lport == htons(lastport) ) + { + goto again; + } } + + conn = 0; + for( c = 0; c < UIP_UDP_CONNS; ++c ) + { + if( uip_udp_conns[ c ].lport == 0 ) + { + conn = &uip_udp_conns[ c ]; + break; + } + } + + if( conn == 0 ) + { + return 0; + } + + conn->lport = HTONS( lastport ); + conn->rport = rport; + if( ripaddr == NULL ) + { + memset( &conn->ripaddr, 0, sizeof(uip_ipaddr_t) ); + } + else + { + uip_ipaddr_copy( &conn->ripaddr, ripaddr ); + } + + conn->ttl = UIP_TTL; + + return conn; } - - if( conn == 0 ) - { - return 0; - } - - conn->lport = HTONS( lastport ); - conn->rport = rport; - if( ripaddr == NULL ) - { - memset( &conn->ripaddr, 0, sizeof(uip_ipaddr_t) ); - } - else - { - uip_ipaddr_copy( &conn->ripaddr, ripaddr ); - } - - conn->ttl = UIP_TTL; - - return conn; -} - +/*---------------------------------------------------------------------------*/ #endif /* UIP_UDP */ -/*---------------------------------------------------------------------------*/ void uip_unlisten( u16_t port ) { for( c = 0; c < UIP_LISTENPORTS; ++c ) { - if( uip_listenports[c] == port ) + if( uip_listenports[ c ] == port ) { - uip_listenports[c] = 0; + uip_listenports[ c ] = 0; return; } } } - /*---------------------------------------------------------------------------*/ + void uip_listen( u16_t port ) { for( c = 0; c < UIP_LISTENPORTS; ++c ) { - if( uip_listenports[c] == 0 ) + if( uip_listenports[ c ] == 0 ) { - uip_listenports[c] = port; + uip_listenports[ c ] = port; return; } } } - /*---------------------------------------------------------------------------*/ /* XXX: IP fragment reassembly: not well-tested. */ #if UIP_REASSEMBLY && !UIP_CONF_IPV6 -#define UIP_REASS_BUFSIZE ( UIP_BUFSIZE - UIP_LLH_LEN ) -static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; -static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / ( 8 * 8 )]; -static const u8_t bitmap_bits[8] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; -static u16_t uip_reasslen; -static u8_t uip_reassflags; -#define UIP_REASS_FLAG_LASTFRAG 0x01 -static u8_t uip_reasstmr; + #define UIP_REASS_BUFSIZE ( UIP_BUFSIZE - UIP_LLH_LEN ) + static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; + static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / ( 8 * 8 )]; + static const u8_t bitmap_bits[8] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; + static u16_t uip_reasslen; + static u8_t uip_reassflags; + #define UIP_REASS_FLAG_LASTFRAG 0x01 + static u8_t uip_reasstmr; -#define IP_MF 0x20 + #define IP_MF 0x20 -static u8_t uip_reass( void ) -{ - u16_t offset, len; - u16_t i; - - /* If ip_reasstmr is zero, no packet is present in the buffer, so we - write the IP header of the fragment into the reassembly - buffer. The timer is updated with the maximum age. */ - if( uip_reasstmr == 0 ) + static u8_t uip_reass( void ) { - memcpy( uip_reassbuf, &BUF->vhl, UIP_IPH_LEN ); - uip_reasstmr = UIP_REASS_MAXAGE; - uip_reassflags = 0; + u16_t offset, len; + u16_t i; - /* Clear the bitmap. */ - memset( uip_reassbitmap, 0, sizeof(uip_reassbitmap) ); - } - - /* Check if the incoming fragment matches the one currently present - in the reasembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if - ( - BUF->srcipaddr[0] == FBUF->srcipaddr[0] && - BUF->srcipaddr[1] == FBUF->srcipaddr[1] && - BUF->destipaddr[0] == FBUF->destipaddr[0] && - BUF->destipaddr[1] == FBUF->destipaddr[1] && - BUF->ipid[0] == FBUF->ipid[0] && - BUF->ipid[1] == FBUF->ipid[1] - ) - { - len = ( BUF->len[0] << 8 ) + BUF->len[1] - ( BUF->vhl & 0x0f ) * 4; - offset = ( ((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1] ) * 8; - - /* If the offset or the offset + fragment length overflows the - reassembly buffer, we discard the entire packet. */ - if( offset > UIP_REASS_BUFSIZE || offset + len > UIP_REASS_BUFSIZE ) + /* If ip_reasstmr is zero, no packet is present in the buffer, so we + write the IP header of the fragment into the reassembly + buffer. The timer is updated with the maximum age. */ + if( uip_reasstmr == 0 ) { - uip_reasstmr = 0; - goto nullreturn; + memcpy( uip_reassbuf, &BUF->vhl, UIP_IPH_LEN ); + uip_reasstmr = UIP_REASS_MAXAGE; + uip_reassflags = 0; + + /* Clear the bitmap. */ + memset( uip_reassbitmap, 0, sizeof(uip_reassbitmap) ); } - /* Copy the fragment into the reassembly buffer, at the right - offset. */ - memcpy( &uip_reassbuf[UIP_IPH_LEN + offset], ( char * ) BUF + ( int ) ((BUF->vhl & 0x0f) * 4), len ); + /* Check if the incoming fragment matches the one currently present + in the reasembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if + ( + BUF->srcipaddr[ 0 ] == FBUF->srcipaddr[ 0 ] && + BUF->srcipaddr[ 1 ] == FBUF->srcipaddr[ 1 ] && + BUF->destipaddr[ 0 ] == FBUF->destipaddr[ 0 ] && + BUF->destipaddr[ 1 ] == FBUF->destipaddr[ 1 ] && + BUF->ipid[ 0 ] == FBUF->ipid[ 0 ] && + BUF->ipid[ 1 ] == FBUF->ipid[ 1 ] + ) + { + len = ( BUF->len[ 0 ] << 8 ) + BUF->len[ 1 ] - ( BUF->vhl & 0x0f ) * 4; + offset = ( ((BUF->ipoffset[ 0 ] & 0x3f) << 8) + BUF->ipoffset[ 1 ] ) * 8; - /* Update the bitmap. */ - if( offset / (8 * 8) == (offset + len) / (8 * 8) ) - { - /* If the two endpoints are in the same byte, we only update - that byte. */ - uip_reassbitmap[offset / ( 8 * 8 )] |= bitmap_bits[( offset / 8 ) & 7] &~bitmap_bits[( (offset + len) / 8 ) & 7]; - } - else - { - /* If the two endpoints are in different bytes, we update the - bytes in the endpoints and fill the stuff inbetween with - 0xff. */ - uip_reassbitmap[offset / ( 8 * 8 )] |= bitmap_bits[( offset / 8 ) & 7]; - for( i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i ) - { - uip_reassbitmap[i] = 0xff; - } - - uip_reassbitmap[( offset + len ) / ( 8 * 8 )] |= ~bitmap_bits[( (offset + len) / 8 ) & 7]; - } - - /* If this fragment has the More Fragments flag set to zero, we - know that this is the last fragment, so we can calculate the - size of the entire packet. We also set the - IP_REASS_FLAG_LASTFRAG flag to indicate that we have received - the final fragment. */ - if( (BUF->ipoffset[0] & IP_MF) == 0 ) - { - uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; - uip_reasslen = offset + len; - } - - /* Finally, we check if we have a full packet in the buffer. We do - this by checking if we have the last fragment and if all bits - in the bitmap are set. */ - if( uip_reassflags & UIP_REASS_FLAG_LASTFRAG ) - { - /* Check all bytes up to and including all but the last byte in - the bitmap. */ - for( i = 0; i < uip_reasslen / (8 * 8) - 1; ++i ) - { - if( uip_reassbitmap[i] != 0xff ) - { - goto nullreturn; - } - } - - /* Check the last byte in the bitmap. It should contain just the - right amount of bits. */ - if( uip_reassbitmap[uip_reasslen / (8 * 8)] != (u8_t)~bitmap_bits[uip_reasslen / 8 & 7] ) + /* If the offset or the offset + fragment length overflows the + reassembly buffer, we discard the entire packet. */ + if( offset > UIP_REASS_BUFSIZE || offset + len > UIP_REASS_BUFSIZE ) { + uip_reasstmr = 0; goto nullreturn; } - /* If we have come this far, we have a full packet in the - buffer, so we allocate a pbuf and copy the packet into it. We - also reset the timer. */ - uip_reasstmr = 0; - memcpy( BUF, FBUF, uip_reasslen ); + /* Copy the fragment into the reassembly buffer, at the right + offset. */ + memcpy( &uip_reassbuf[UIP_IPH_LEN + offset], ( char * ) BUF + ( int ) ((BUF->vhl & 0x0f) * 4), len ); - /* Pretend to be a "normal" (i.e., not fragmented) IP packet - from now on. */ - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - BUF->len[0] = uip_reasslen >> 8; - BUF->len[1] = uip_reasslen & 0xff; - BUF->ipchksum = 0; - BUF->ipchksum = ~( uip_ipchksum() ); + /* Update the bitmap. */ + if( offset / (8 * 8) == (offset + len) / (8 * 8) ) + { + /* If the two endpoints are in the same byte, we only update + that byte. */ + uip_reassbitmap[offset / ( 8 * 8 )] |= bitmap_bits[( offset / 8 ) & 7] &~bitmap_bits[( (offset + len) / 8 ) & 7]; + } + else + { + /* If the two endpoints are in different bytes, we update the + bytes in the endpoints and fill the stuff inbetween with + 0xff. */ + uip_reassbitmap[offset / ( 8 * 8 )] |= bitmap_bits[( offset / 8 ) & 7]; + for( i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i ) + { + uip_reassbitmap[i] = 0xff; + } - return uip_reasslen; + uip_reassbitmap[( offset + len ) / ( 8 * 8 )] |= ~bitmap_bits[( (offset + len) / 8 ) & 7]; + } + + /* If this fragment has the More Fragments flag set to zero, we + know that this is the last fragment, so we can calculate the + size of the entire packet. We also set the + IP_REASS_FLAG_LASTFRAG flag to indicate that we have received + the final fragment. */ + if( (BUF->ipoffset[ 0 ] & IP_MF) == 0 ) + { + uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; + uip_reasslen = offset + len; + } + + /* Finally, we check if we have a full packet in the buffer. We do + this by checking if we have the last fragment and if all bits + in the bitmap are set. */ + if( uip_reassflags & UIP_REASS_FLAG_LASTFRAG ) + { + /* Check all bytes up to and including all but the last byte in + the bitmap. */ + for( i = 0; i < uip_reasslen / (8 * 8) - 1; ++i ) + { + if( uip_reassbitmap[i] != 0xff ) + { + goto nullreturn; + } + } + + /* Check the last byte in the bitmap. It should contain just the + right amount of bits. */ + if( uip_reassbitmap[uip_reasslen / (8 * 8)] != (u8_t)~bitmap_bits[uip_reasslen / 8 & 7] ) + { + goto nullreturn; + } + + /* If we have come this far, we have a full packet in the + buffer, so we allocate a pbuf and copy the packet into it. We + also reset the timer. */ + uip_reasstmr = 0; + memcpy( BUF, FBUF, uip_reasslen ); + + /* Pretend to be a "normal" (i.e., not fragmented) IP packet + from now on. */ + BUF->ipoffset[ 0 ] = BUF->ipoffset[ 1 ] = 0; + BUF->len[ 0 ] = uip_reasslen >> 8; + BUF->len[ 1 ] = uip_reasslen & 0xff; + BUF->ipchksum = 0; + BUF->ipchksum = ~( uip_ipchksum() ); + + return uip_reasslen; + } } + + nullreturn: + + return 0; } - -nullreturn: - return 0; -} - +/*---------------------------------------------------------------------------*/ #endif /* UIP_REASSEMBLY */ -/*---------------------------------------------------------------------------*/ + static void uip_add_rcv_nxt( u16_t n ) { uip_add32( uip_conn->rcv_nxt, n ); - uip_conn->rcv_nxt[0] = uip_acc32[0]; - uip_conn->rcv_nxt[1] = uip_acc32[1]; - uip_conn->rcv_nxt[2] = uip_acc32[2]; - uip_conn->rcv_nxt[3] = uip_acc32[3]; + uip_conn->rcv_nxt[ 0 ] = uip_acc32[ 0 ]; + uip_conn->rcv_nxt[ 1 ] = uip_acc32[ 1 ]; + uip_conn->rcv_nxt[ 2 ] = uip_acc32[ 2 ]; + uip_conn->rcv_nxt[ 3 ] = uip_acc32[ 3 ]; } - /*---------------------------------------------------------------------------*/ + void uip_process( u8_t flag ) { register struct uip_conn *uip_connr = uip_conn; -#if UIP_UDP - if( flag == UIP_UDP_SEND_CONN ) - { - goto udp_send; - } - -#endif /* UIP_UDP */ + #if UIP_UDP + if( flag == UIP_UDP_SEND_CONN ) + { + goto udp_send; + } + #endif /* UIP_UDP */ uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; @@ -741,22 +728,21 @@ void uip_process( u8_t flag ) } else if( flag == UIP_TIMER ) { -#if UIP_REASSEMBLY - if( uip_reasstmr != 0 ) - { - --uip_reasstmr; - } - -#endif /* UIP_REASSEMBLY */ + #if UIP_REASSEMBLY + if( uip_reasstmr != 0 ) + { + --uip_reasstmr; + } + #endif /* UIP_REASSEMBLY */ /* Increase the initial sequence number. */ - if( ++iss[3] == 0 ) + if( ++iss[ 3 ] == 0 ) { - if( ++iss[2] == 0 ) + if( ++iss[ 2 ] == 0 ) { - if( ++iss[1] == 0 ) + if( ++iss[ 1 ] == 0 ) { - ++iss[0]; + ++iss[ 0 ]; } } } @@ -782,7 +768,7 @@ void uip_process( u8_t flag ) /* If the connection has outstanding data, we increase the connection's timer and see if it has reached the RTO value in which case we retransmit. */ - if( uip_outstanding(uip_connr) ) + if( uip_outstanding(uip_connr) ) { if( uip_connr->timer-- == 0 ) { @@ -800,7 +786,7 @@ void uip_process( u8_t flag ) /* We call UIP_APPCALL() with uip_flags set to UIP_TIMEDOUT to inform the application that the connection has timed out. */ - uip_flags = UIP_TIMEDOUT; + uip_flags = UIP_TIMEDOUT; UIP_APPCALL(); /* We also send a reset packet to the remote host. */ @@ -826,13 +812,12 @@ void uip_process( u8_t flag ) SYNACK. */ goto tcp_send_synack; - #if UIP_ACTIVE_OPEN - - case UIP_SYN_SENT: - /* In the SYN_SENT state, we retransmit out SYN. */ - BUF->flags = 0; - goto tcp_send_syn; - #endif /* UIP_ACTIVE_OPEN */ + #if UIP_ACTIVE_OPEN + case UIP_SYN_SENT: + /* In the SYN_SENT state, we retransmit out SYN. */ + BUF->flags = 0; + goto tcp_send_syn; + #endif /* UIP_ACTIVE_OPEN */ case UIP_ESTABLISHED: /* In the ESTABLISHED state, we call upon the application @@ -864,51 +849,50 @@ void uip_process( u8_t flag ) goto drop; } -#if UIP_UDP - if( flag == UIP_UDP_TIMER ) - { - if( uip_udp_conn->lport != 0 ) + #if UIP_UDP + if( flag == UIP_UDP_TIMER ) { - uip_conn = NULL; - uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - uip_len = uip_slen = 0; - uip_flags = UIP_POLL; - UIP_UDP_APPCALL(); - goto udp_send; + if( uip_udp_conn->lport != 0 ) + { + uip_conn = NULL; + uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; + uip_len = uip_slen = 0; + uip_flags = UIP_POLL; + UIP_UDP_APPCALL(); + goto udp_send; + } + else + { + goto drop; + } } - else - { - goto drop; - } - } - -#endif + #endif /* This is where the input processing starts. */ UIP_STAT( ++uip_stat.ip.recv ); /* Start of IP input header processing code. */ -#if UIP_CONF_IPV6 - /* Check validity of the IP header. */ - if( (BUF->vtc & 0xf0) != 0x60 ) - { /* IP version and header length. */ - UIP_STAT( ++uip_stat.ip.drop ); - UIP_STAT( ++uip_stat.ip.vhlerr ); - UIP_LOG( "ipv6: invalid version." ); - goto drop; - } + #if UIP_CONF_IPV6 + /* Check validity of the IP header. */ + if( (BUF->vtc & 0xf0) != 0x60 ) + { /* IP version and header length. */ + UIP_STAT( ++uip_stat.ip.drop ); + UIP_STAT( ++uip_stat.ip.vhlerr ); + UIP_LOG( "ipv6: invalid version." ); + goto drop; + } -#else /* UIP_CONF_IPV6 */ - /* Check validity of the IP header. */ - if( BUF->vhl != 0x45 ) - { /* IP version and header length. */ - UIP_STAT( ++uip_stat.ip.drop ); - UIP_STAT( ++uip_stat.ip.vhlerr ); - UIP_LOG( "ip: invalid version or header length." ); - goto drop; - } + #else /* UIP_CONF_IPV6 */ + /* Check validity of the IP header. */ + if( BUF->vhl != 0x45 ) + { /* IP version and header length. */ + UIP_STAT( ++uip_stat.ip.drop ); + UIP_STAT( ++uip_stat.ip.vhlerr ); + UIP_LOG( "ip: invalid version or header length." ); + goto drop; + } -#endif /* UIP_CONF_IPV6 */ + #endif /* UIP_CONF_IPV6 */ /* Check the size of the packet. If the size reported to us in uip_len is smaller the size reported in the IP header, we assume @@ -916,20 +900,21 @@ void uip_process( u8_t flag ) uip_len is larger than the size reported in the IP packet header, the packet has been padded and we set uip_len to the correct value.. */ - if( (BUF->len[0] << 8) + BUF->len[1] <= uip_len ) + if( (BUF->len[ 0 ] << 8) + BUF->len[ 1 ] <= uip_len ) { - uip_len = ( BUF->len[0] << 8 ) + BUF->len[1]; -#if UIP_CONF_IPV6 - uip_len += 40; /* The length reported in the IPv6 header is the - length of the payload that follows the - header. However, uIP uses the uip_len variable - for holding the size of the entire packet, - including the IP header. For IPv4 this is not a - problem as the length field in the IPv4 header - contains the length of the entire packet. But - for IPv6 we need to add the size of the IPv6 - header (40 bytes). */ -#endif /* UIP_CONF_IPV6 */ + uip_len = ( BUF->len[ 0 ] << 8 ) + BUF->len[ 1 ]; + #if UIP_CONF_IPV6 + /* The length reported in the IPv6 header is the + length of the payload that follows the + header. However, uIP uses the uip_len variable + for holding the size of the entire packet, + including the IP header. For IPv4 this is not a + problem as the length field in the IPv4 header + contains the length of the entire packet. But + for IPv6 we need to add the size of the IPv6 + header (40 bytes). */ + uip_len += 40; + #endif /* UIP_CONF_IPV6 */ } else { @@ -937,322 +922,316 @@ void uip_process( u8_t flag ) goto drop; } -#if !UIP_CONF_IPV6 - /* Check the fragment flag. */ - if( (BUF->ipoffset[0] & 0x3f) != 0 || BUF->ipoffset[1] != 0 ) - { -#if UIP_REASSEMBLY - uip_len = uip_reass(); - if( uip_len == 0 ) + #if !UIP_CONF_IPV6 + /* Check the fragment flag. */ + if( (BUF->ipoffset[ 0 ] & 0x3f) != 0 || BUF->ipoffset[ 1 ] != 0 ) { - goto drop; + #if UIP_REASSEMBLY + uip_len = uip_reass(); + if( uip_len == 0 ) + { + goto drop; + } + #else /* UIP_REASSEMBLY */ + UIP_STAT( ++uip_stat.ip.drop ); + UIP_STAT( ++uip_stat.ip.fragerr ); + UIP_LOG( "ip: fragment dropped." ); + goto drop; + #endif /* UIP_REASSEMBLY */ } - -#else /* UIP_REASSEMBLY */ - UIP_STAT( ++uip_stat.ip.drop ); - UIP_STAT( ++uip_stat.ip.fragerr ); - UIP_LOG( "ip: fragment dropped." ); - goto drop; -#endif /* UIP_REASSEMBLY */ - } - -#endif /* UIP_CONF_IPV6 */ + #endif /* UIP_CONF_IPV6 */ if( uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) ) { /* If we are configured to use ping IP address configuration and - hasn't been assigned an IP address yet, we accept all ICMP - packets. */ -#if UIP_PINGADDRCONF && !UIP_CONF_IPV6 - if( BUF->proto == UIP_PROTO_ICMP ) - { - UIP_LOG( "ip: possible ping config packet received." ); - goto icmp_input; - } - else - { - UIP_LOG( "ip: packet dropped since no address assigned." ); - goto drop; - } - -#endif /* UIP_PINGADDRCONF */ + hasn't been assigned an IP address yet, we accept all ICMP + packets. */ + #if UIP_PINGADDRCONF && !UIP_CONF_IPV6 + if( BUF->proto == UIP_PROTO_ICMP ) + { + UIP_LOG( "ip: possible ping config packet received." ); + goto icmp_input; + } + else + { + UIP_LOG( "ip: packet dropped since no address assigned." ); + goto drop; + } + #endif /* UIP_PINGADDRCONF */ } else { /* If IP broadcast support is configured, we check for a broadcast - UDP packet, which may be destined to us. */ -#if UIP_BROADCAST - //DEBUG_PRINTF( "UDP IP checksum 0x%04x\n", uip_ipchksum() ); - if( BUF->proto == UIP_PROTO_UDP && uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) /*&& - uip_ipchksum() == 0xffff*/ ) - { - goto udp_input; - } - -#endif /* UIP_BROADCAST */ + UDP packet, which may be destined to us. */ + #if UIP_BROADCAST + //DEBUG_PRINTF( "UDP IP checksum 0x%04x\n", uip_ipchksum() ); + if( BUF->proto == UIP_PROTO_UDP && uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) /*&& uip_ipchksum() == 0xffff*/ ) + { + goto udp_input; + } + #endif /* UIP_BROADCAST */ /* Check if the packet is destined for our IP address. */ -#if !UIP_CONF_IPV6 - if( !uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) ) - { - UIP_STAT( ++uip_stat.ip.drop ); - goto drop; - } - -#else /* UIP_CONF_IPV6 */ - /* For IPv6, packet reception is a little trickier as we need to - make sure that we listen to certain multicast addresses (all - hosts multicast address, and the solicited-node multicast - address) as well. However, we will cheat here and accept all - multicast packets that are sent to the ff02::/16 addresses. */ - if( !uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) && BUF->destipaddr.u16[0] != HTONS(0xff02) ) - { - UIP_STAT( ++uip_stat.ip.drop ); - goto drop; - } - -#endif /* UIP_CONF_IPV6 */ + #if !UIP_CONF_IPV6 + if( !uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) ) + { + UIP_STAT( ++uip_stat.ip.drop ); + goto drop; + } + #else /* UIP_CONF_IPV6 */ + /* For IPv6, packet reception is a little trickier as we need to + make sure that we listen to certain multicast addresses (all + hosts multicast address, and the solicited-node multicast + address) as well. However, we will cheat here and accept all + multicast packets that are sent to the ff02::/16 addresses. */ + if( !uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) && BUF->destipaddr.u16[ 0 ] != HTONS(0xff02) ) + { + UIP_STAT( ++uip_stat.ip.drop ); + goto drop; + } + #endif /* UIP_CONF_IPV6 */ } -#if !UIP_CONF_IPV6 - if( uip_ipchksum() != 0xffff ) - { /* Compute and check the IP header - checksum. */ - UIP_STAT( ++uip_stat.ip.drop ); - UIP_STAT( ++uip_stat.ip.chkerr ); - UIP_LOG( "ip: bad checksum." ); - goto drop; - } - -#endif /* UIP_CONF_IPV6 */ + #if !UIP_CONF_IPV6 + if( uip_ipchksum() != 0xffff ) + { + /* Compute and check the IP header checksum. */ + UIP_STAT( ++uip_stat.ip.drop ); + UIP_STAT( ++uip_stat.ip.chkerr ); + UIP_LOG( "ip: bad checksum." ); + goto drop; + } + #endif /* UIP_CONF_IPV6 */ if( BUF->proto == UIP_PROTO_TCP ) - { /* Check for TCP packet. If so, - proceed with TCP input - processing. */ + { + /* Check for TCP packet. If so, proceed with TCP input processing. */ goto tcp_input; } -#if UIP_UDP - if( BUF->proto == UIP_PROTO_UDP ) - { - goto udp_input; - } - -#endif /* UIP_UDP */ - -#if !UIP_CONF_IPV6 - /* ICMPv4 processing code follows. */ - if( BUF->proto != UIP_PROTO_ICMP ) - { /* We only allow ICMP packets from - here. */ - UIP_STAT( ++uip_stat.ip.drop ); - UIP_STAT( ++uip_stat.ip.protoerr ); - UIP_LOG( "ip: neither tcp nor icmp." ); - goto drop; - } - -#if UIP_PINGADDRCONF - icmp_input : -#endif /* UIP_PINGADDRCONF */ - UIP_STAT( ++uip_stat.icmp.recv ); - - /* ICMP echo (i.e., ping) processing. This is simple, we only change - the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP - checksum before we return the packet. */ - if( ICMPBUF->type != ICMP_ECHO ) - { - UIP_STAT( ++uip_stat.icmp.drop ); - UIP_STAT( ++uip_stat.icmp.typeerr ); - UIP_LOG( "icmp: not icmp echo." ); - goto drop; - } - - /* If we are configured to use ping IP address assignment, we use - the destination IP address of this ping packet and assign it to - ourself. */ -#if UIP_PINGADDRCONF - if( uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) ) - { - uip_hostaddr = BUF->destipaddr; - } - -#endif /* UIP_PINGADDRCONF */ - - ICMPBUF->type = ICMP_ECHO_REPLY; - - if( ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8)) ) - { - ICMPBUF->icmpchksum += HTONS( ICMP_ECHO << 8 ) + 1; - } - else - { - ICMPBUF->icmpchksum += HTONS( ICMP_ECHO << 8 ); - } - - /* Swap IP addresses. */ - uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr ); - uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr ); - - UIP_STAT( ++uip_stat.icmp.sent ); - BUF->ttl = UIP_TTL; - goto ip_send_nolen; - - /* End of IPv4 input header processing code. */ -#else /* !UIP_CONF_IPV6 */ - /* This is IPv6 ICMPv6 processing code. */ - - //DEBUG_PRINTF( "icmp6_input: length %d\n", uip_len ); - if( BUF->proto != UIP_PROTO_ICMP6 ) - { /* We only allow ICMPv6 packets from - here. */ - UIP_STAT( ++uip_stat.ip.drop ); - UIP_STAT( ++uip_stat.ip.protoerr ); - UIP_LOG( "ip: neither tcp nor icmp6." ); - goto drop; - } - - UIP_STAT( ++uip_stat.icmp.recv ); - - /* If we get a neighbor solicitation for our address we should send - a neighbor advertisement message back. */ - if( ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION ) - { - if( uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr) ) + #if UIP_UDP + if( BUF->proto == UIP_PROTO_UDP ) { - if( ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS ) + goto udp_input; + } + #endif /* UIP_UDP */ + + #if !UIP_CONF_IPV6 + /* ICMPv4 processing code follows. */ + if( BUF->proto != UIP_PROTO_ICMP ) + { + /* We only allow ICMP packets from here. */ + UIP_STAT( ++uip_stat.ip.drop ); + UIP_STAT( ++uip_stat.ip.protoerr ); + UIP_LOG( "ip: neither tcp nor icmp." ); + goto drop; + } + + #if UIP_PINGADDRCONF + icmp_input : + #endif /* UIP_PINGADDRCONF */ + + UIP_STAT( ++uip_stat.icmp.recv ); + + /* ICMP echo (i.e., ping) processing. This is simple, we only change + the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP + checksum before we return the packet. */ + if( ICMPBUF->type != ICMP_ECHO ) + { + UIP_STAT( ++uip_stat.icmp.drop ); + UIP_STAT( ++uip_stat.icmp.typeerr ); + UIP_LOG( "icmp: not icmp echo." ); + goto drop; + } + + /* If we are configured to use ping IP address assignment, we use + the destination IP address of this ping packet and assign it to + ourself. */ + #if UIP_PINGADDRCONF + if( uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) ) { - /* Save the sender's address in our neighbor list. */ - uip_neighbor_add( &ICMPBUF->srcipaddr, &(ICMPBUF->options[2]) ); + uip_hostaddr = BUF->destipaddr; + } + #endif /* UIP_PINGADDRCONF */ + + ICMPBUF->type = ICMP_ECHO_REPLY; + + if( ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8)) ) + { + ICMPBUF->icmpchksum += HTONS( ICMP_ECHO << 8 ) + 1; + } + else + { + ICMPBUF->icmpchksum += HTONS( ICMP_ECHO << 8 ); + } + + /* Swap IP addresses. */ + uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr ); + uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr ); + + UIP_STAT( ++uip_stat.icmp.sent ); + BUF->ttl = UIP_TTL; + goto ip_send_nolen; + + /* End of IPv4 input header processing code. */ + + #else /* !UIP_CONF_IPV6 */ + + /* This is IPv6 ICMPv6 processing code. */ + + //DEBUG_PRINTF( "icmp6_input: length %d\n", uip_len ); + if( BUF->proto != UIP_PROTO_ICMP6 ) + { + /* We only allow ICMPv6 packets from here. */ + UIP_STAT( ++uip_stat.ip.drop ); + UIP_STAT( ++uip_stat.ip.protoerr ); + UIP_LOG( "ip: neither tcp nor icmp6." ); + goto drop; + } + + UIP_STAT( ++uip_stat.icmp.recv ); + + /* If we get a neighbor solicitation for our address we should send + a neighbor advertisement message back. */ + if( ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION ) + { + if( uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr) ) + { + if( ICMPBUF->options[ 0 ] == ICMP6_OPTION_SOURCE_LINK_ADDRESS ) + { + /* Save the sender's address in our neighbor list. */ + uip_neighbor_add( &ICMPBUF->srcipaddr, &(ICMPBUF->options[ 2 ]) ); + } + + /* We should now send a neighbor advertisement back to where the + neighbor solicication came from. */ + ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; + ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ + + ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; + + uip_ipaddr_copy( &ICMPBUF->destipaddr, &ICMPBUF->srcipaddr ); + uip_ipaddr_copy( &ICMPBUF->srcipaddr, &uip_hostaddr ); + ICMPBUF->options[ 0 ] = ICMP6_OPTION_TARGET_LINK_ADDRESS; + ICMPBUF->options[ 1 ] = 1; /* Options length, 1 = 8 bytes. */ + memcpy( &(ICMPBUF->options[ 2 ]), &uip_ethaddr, sizeof(uip_ethaddr) ); + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + + goto send; } - /* We should now send a neighbor advertisement back to where the - neighbor solicication came from. */ - ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; - ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ + goto drop; + } + else if( ICMPBUF->type == ICMP6_ECHO ) + { + /* ICMP echo (i.e., ping) processing. This is simple, we only + change the ICMP type from ECHO to ECHO_REPLY and update the + ICMP checksum before we return the packet. */ + ICMPBUF->type = ICMP6_ECHO_REPLY; - ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; - - uip_ipaddr_copy( &ICMPBUF->destipaddr, &ICMPBUF->srcipaddr ); - uip_ipaddr_copy( &ICMPBUF->srcipaddr, &uip_hostaddr ); - ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; - ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ - memcpy( &(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr) ); + uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr ); + uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr ); ICMPBUF->icmpchksum = 0; ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + UIP_STAT( ++uip_stat.icmp.sent ); goto send; } - - goto drop; - } - else if( ICMPBUF->type == ICMP6_ECHO ) - { - /* ICMP echo (i.e., ping) processing. This is simple, we only - change the ICMP type from ECHO to ECHO_REPLY and update the - ICMP checksum before we return the packet. */ - ICMPBUF->type = ICMP6_ECHO_REPLY; - - uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr ); - uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr ); - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_icmp6chksum(); - - UIP_STAT( ++uip_stat.icmp.sent ); - goto send; - } - else - { - //DEBUG_PRINTF( "Unknown icmp6 message type %d\n", ICMPBUF->type ); - UIP_STAT( ++uip_stat.icmp.drop ); - UIP_STAT( ++uip_stat.icmp.typeerr ); - UIP_LOG( "icmp: unknown ICMP message." ); - goto drop; - } - - /* End of IPv6 ICMP processing. */ -#endif /* !UIP_CONF_IPV6 */ - -#if UIP_UDP - /* UDP input processing. */ - udp_input : - /* UDP processing is really just a hack. We don't do anything to the - UDP/IP headers, but let the UDP application do all the hard - work. If the application sets uip_slen, it has a packet to - send. */ -#if UIP_UDP_CHECKSUMS - uip_len = uip_len - UIP_IPUDPH_LEN; - uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; - if( UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff ) - { - UIP_STAT( ++uip_stat.udp.drop ); - UIP_STAT( ++uip_stat.udp.chkerr ); - UIP_LOG( "udp: bad checksum." ); - goto drop; - } - -#else /* UIP_UDP_CHECKSUMS */ - uip_len = uip_len - UIP_IPUDPH_LEN; -#endif /* UIP_UDP_CHECKSUMS */ - - /* Demultiplex this UDP packet between the UDP "connections". */ - for( uip_udp_conn = &uip_udp_conns[0]; uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; ++uip_udp_conn ) - { - /* If the local UDP port is non-zero, the connection is considered - to be used. If so, the local port number is checked against the - destination port number in the received packet. If the two port - numbers match, the remote port number is checked if the - connection is bound to a remote port. Finally, if the - connection is bound to a remote IP address, the source IP - address of the packet is checked. */ - if - ( - uip_udp_conn->lport != 0 && - UDPBUF->destport == uip_udp_conn->lport && - (uip_udp_conn->rport == 0 || UDPBUF->srcport == uip_udp_conn->rport) && - ( - uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) || - uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) || - uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr) - ) - ) + else { - goto udp_found; + //DEBUG_PRINTF( "Unknown icmp6 message type %d\n", ICMPBUF->type ); + UIP_STAT( ++uip_stat.icmp.drop ); + UIP_STAT( ++uip_stat.icmp.typeerr ); + UIP_LOG( "icmp: unknown ICMP message." ); + goto drop; } - } - UIP_LOG( "udp: no matching connection found" ); -#if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6 - /* Copy fields from packet header into payload of this ICMP packet. */ - memcpy( &(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8 ); + /* End of IPv6 ICMP processing. */ + #endif /* !UIP_CONF_IPV6 */ - /* Set the ICMP type and code. */ - ICMPBUF->type = ICMP_DEST_UNREACHABLE; - ICMPBUF->icode = ICMP_PORT_UNREACHABLE; + #if UIP_UDP + /* UDP input processing. */ + udp_input : + /* UDP processing is really just a hack. We don't do anything to the + UDP/IP headers, but let the UDP application do all the hard + work. If the application sets uip_slen, it has a packet to + send. */ + #if UIP_UDP_CHECKSUMS + uip_len = uip_len - UIP_IPUDPH_LEN; + uip_appdata = &uip_buf[ UIP_LLH_LEN + UIP_IPUDPH_LEN ]; + if( UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff ) + { + UIP_STAT( ++uip_stat.udp.drop ); + UIP_STAT( ++uip_stat.udp.chkerr ); + UIP_LOG( "udp: bad checksum." ); + goto drop; + } - /* Calculate the ICMP checksum. */ - ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_chksum( ( u16_t * ) &(ICMPBUF->type), 36 ); + #else /* UIP_UDP_CHECKSUMS */ + uip_len = uip_len - UIP_IPUDPH_LEN; + #endif /* UIP_UDP_CHECKSUMS */ - /* Set the IP destination address to be the source address of the - original packet. */ - uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr ); + /* Demultiplex this UDP packet between the UDP "connections". */ + for( uip_udp_conn = &uip_udp_conns[ 0 ]; uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; ++uip_udp_conn ) + { + /* If the local UDP port is non-zero, the connection is considered + to be used. If so, the local port number is checked against the + destination port number in the received packet. If the two port + numbers match, the remote port number is checked if the + connection is bound to a remote port. Finally, if the + connection is bound to a remote IP address, the source IP + address of the packet is checked. */ + if + ( + uip_udp_conn->lport != 0 && + UDPBUF->destport == uip_udp_conn->lport && + (uip_udp_conn->rport == 0 || UDPBUF->srcport == uip_udp_conn->rport) && + ( + uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) || + uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) || + uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr) + ) + ) + { + goto udp_found; + } + } - /* Set our IP address as the source address. */ - uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr ); + UIP_LOG( "udp: no matching connection found" ); - /* The size of the ICMP destination unreachable packet is 36 + the - size of the IP header (20) = 56. */ - uip_len = 36 + UIP_IPH_LEN; - ICMPBUF->len[0] = 0; - ICMPBUF->len[1] = ( u8_t ) uip_len; - ICMPBUF->ttl = UIP_TTL; - ICMPBUF->proto = UIP_PROTO_ICMP; + #if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6 - goto ip_send_nolen; -#else /* UIP_CONF_ICMP_DEST_UNREACH */ - goto drop; -#endif /* UIP_CONF_ICMP_DEST_UNREACH */ + /* Copy fields from packet header into payload of this ICMP packet. */ + memcpy( &(ICMPBUF->payload[ 0 ]), ICMPBUF, UIP_IPH_LEN + 8 ); + + /* Set the ICMP type and code. */ + ICMPBUF->type = ICMP_DEST_UNREACHABLE; + ICMPBUF->icode = ICMP_PORT_UNREACHABLE; + + /* Calculate the ICMP checksum. */ + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_chksum( ( u16_t * ) &(ICMPBUF->type), 36 ); + + /* Set the IP destination address to be the source address of the + original packet. */ + uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr ); + + /* Set our IP address as the source address. */ + uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr ); + + /* The size of the ICMP destination unreachable packet is 36 + the + size of the IP header (20) = 56. */ + uip_len = 36 + UIP_IPH_LEN; + ICMPBUF->len[ 0 ] = 0; + ICMPBUF->len[ 1 ] = ( u8_t ) uip_len; + ICMPBUF->ttl = UIP_TTL; + ICMPBUF->proto = UIP_PROTO_ICMP; + + goto ip_send_nolen; + #else /* UIP_CONF_ICMP_DEST_UNREACH */ + goto drop; + #endif /* UIP_CONF_ICMP_DEST_UNREACH */ udp_found : uip_conn = NULL; uip_flags = UIP_NEWDATA; @@ -1268,15 +1247,15 @@ udp_send: uip_len = uip_slen + UIP_IPUDPH_LEN; -#if UIP_CONF_IPV6 - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - BUF->len[0] = ( (uip_len - UIP_IPH_LEN) >> 8 ); - BUF->len[1] = ( (uip_len - UIP_IPH_LEN) & 0xff ); -#else /* UIP_CONF_IPV6 */ - BUF->len[0] = ( uip_len >> 8 ); - BUF->len[1] = ( uip_len & 0xff ); -#endif /* UIP_CONF_IPV6 */ + #if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[ 0 ] = ( (uip_len - UIP_IPH_LEN) >> 8 ); + BUF->len[ 1 ] = ( (uip_len - UIP_IPH_LEN) & 0xff ); + #else /* UIP_CONF_IPV6 */ + BUF->len[ 0 ] = ( uip_len >> 8 ); + BUF->len[ 1 ] = ( uip_len & 0xff ); + #endif /* UIP_CONF_IPV6 */ BUF->ttl = uip_udp_conn->ttl; BUF->proto = UIP_PROTO_UDP; @@ -1292,26 +1271,24 @@ udp_send: uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; -#if UIP_UDP_CHECKSUMS - /* Calculate UDP checksum. */ - UDPBUF->udpchksum = ~( uip_udpchksum() ); - if( UDPBUF->udpchksum == 0 ) - { - UDPBUF->udpchksum = 0xffff; - } - -#endif /* UIP_UDP_CHECKSUMS */ - - goto ip_send_nolen; -#endif /* UIP_UDP */ + #if UIP_UDP_CHECKSUMS + /* Calculate UDP checksum. */ + UDPBUF->udpchksum = ~( uip_udpchksum() ); + if( UDPBUF->udpchksum == 0 ) + { + UDPBUF->udpchksum = 0xffff; + } + #endif /* UIP_UDP_CHECKSUMS */ + goto ip_send_nolen; + #endif /* UIP_UDP */ /* TCP input processing. */ tcp_input : UIP_STAT( ++uip_stat.tcp.recv ); /* Start of TCP input header processing code. */ if( uip_tcpchksum() != 0xffff ) - { /* Compute and check the TCP - checksum. */ + { + /* Compute and check the TCP checksum. */ UIP_STAT( ++uip_stat.tcp.drop ); UIP_STAT( ++uip_stat.tcp.chkerr ); UIP_LOG( "tcp: bad checksum." ); @@ -1321,7 +1298,7 @@ udp_send: /* Demultiplex this segment. */ /* First check any active connections. */ - for( uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; ++uip_connr ) + for( uip_connr = &uip_conns[ 0 ]; uip_connr <= &uip_conns[UIP_CONNS - 1]; ++uip_connr ) { if ( @@ -1349,7 +1326,7 @@ udp_send: /* Next, check listening connections. */ for( c = 0; c < UIP_LISTENPORTS; ++c ) { - if( tmp16 == uip_listenports[c] ) + if( tmp16 == uip_listenports[ c ] ) { goto found_listen; } @@ -1372,32 +1349,32 @@ reset: BUF->tcpoffset = 5 << 4; /* Flip the seqno and ackno fields in the TCP header. */ - c = BUF->seqno[3]; - BUF->seqno[3] = BUF->ackno[3]; - BUF->ackno[3] = c; + c = BUF->seqno[ 3 ]; + BUF->seqno[ 3 ] = BUF->ackno[ 3 ]; + BUF->ackno[ 3 ] = c; - c = BUF->seqno[2]; - BUF->seqno[2] = BUF->ackno[2]; - BUF->ackno[2] = c; + c = BUF->seqno[ 2 ]; + BUF->seqno[ 2 ] = BUF->ackno[ 2 ]; + BUF->ackno[ 2 ] = c; - c = BUF->seqno[1]; - BUF->seqno[1] = BUF->ackno[1]; - BUF->ackno[1] = c; + c = BUF->seqno[ 1 ]; + BUF->seqno[ 1 ] = BUF->ackno[ 1 ]; + BUF->ackno[ 1 ] = c; - c = BUF->seqno[0]; - BUF->seqno[0] = BUF->ackno[0]; - BUF->ackno[0] = c; + c = BUF->seqno[ 0 ]; + BUF->seqno[ 0 ] = BUF->ackno[ 0 ]; + BUF->ackno[ 0 ] = c; /* We also have to increase the sequence number we are acknowledging. If the least significant byte overflowed, we need to propagate the carry to the other bytes as well. */ - if( ++BUF->ackno[3] == 0 ) + if( ++BUF->ackno[ 3 ] == 0 ) { - if( ++BUF->ackno[2] == 0 ) + if( ++BUF->ackno[ 2 ] == 0 ) { - if( ++BUF->ackno[1] == 0 ) + if( ++BUF->ackno[ 1 ] == 0 ) { - ++BUF->ackno[0]; + ++BUF->ackno[ 0 ]; } } } @@ -1427,17 +1404,17 @@ found_listen: uip_connr = 0; for( c = 0; c < UIP_CONNS; ++c ) { - if( uip_conns[c].tcpstateflags == UIP_CLOSED ) + if( uip_conns[ c ].tcpstateflags == UIP_CLOSED ) { - uip_connr = &uip_conns[c]; + uip_connr = &uip_conns[ c ]; break; } - if( uip_conns[c].tcpstateflags == UIP_TIME_WAIT ) + if( uip_conns[ c ].tcpstateflags == UIP_TIME_WAIT ) { - if( uip_connr == 0 || uip_conns[c].timer > uip_connr->timer ) + if( uip_connr == 0 || uip_conns[ c ].timer > uip_connr->timer ) { - uip_connr = &uip_conns[c]; + uip_connr = &uip_conns[ c ]; } } } @@ -1445,8 +1422,8 @@ found_listen: if( uip_connr == 0 ) { /* All connections are used already, we drop packet and hope that - the remote end will retransmit the packet at a time when we - have more spare connections. */ + the remote end will retransmit the packet at a time when we + have more spare connections. */ UIP_STAT( ++uip_stat.tcp.syndrop ); UIP_LOG( "tcp: found no unused connections." ); goto drop; @@ -1464,17 +1441,17 @@ found_listen: uip_ipaddr_copy( &uip_connr->ripaddr, &BUF->srcipaddr ); uip_connr->tcpstateflags = UIP_SYN_RCVD; - uip_connr->snd_nxt[0] = iss[0]; - uip_connr->snd_nxt[1] = iss[1]; - uip_connr->snd_nxt[2] = iss[2]; - uip_connr->snd_nxt[3] = iss[3]; + uip_connr->snd_nxt[ 0 ] = iss[ 0 ]; + uip_connr->snd_nxt[ 1 ] = iss[ 1 ]; + uip_connr->snd_nxt[ 2 ] = iss[ 2 ]; + uip_connr->snd_nxt[ 3 ] = iss[ 3 ]; uip_connr->len = 1; /* rcv_nxt should be the seqno from the incoming packet + 1. */ - uip_connr->rcv_nxt[3] = BUF->seqno[3]; - uip_connr->rcv_nxt[2] = BUF->seqno[2]; - uip_connr->rcv_nxt[1] = BUF->seqno[1]; - uip_connr->rcv_nxt[0] = BUF->seqno[0]; + uip_connr->rcv_nxt[ 3 ] = BUF->seqno[ 3 ]; + uip_connr->rcv_nxt[ 2 ] = BUF->seqno[ 2 ]; + uip_connr->rcv_nxt[ 1 ] = BUF->seqno[ 1 ]; + uip_connr->rcv_nxt[ 0 ] = BUF->seqno[ 0 ]; uip_add_rcv_nxt( 1 ); /* Parse the TCP MSS option, if present. */ @@ -1506,11 +1483,11 @@ found_listen: else { /* All other options have a length field, so that we easily - can skip past them. */ + can skip past them. */ if( uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0 ) { /* If the length field is zero, the options are malformed - and we don't process them further. */ + and we don't process them further. */ break; } @@ -1520,21 +1497,20 @@ found_listen: } /* Our response will be a SYNACK. */ -#if UIP_ACTIVE_OPEN - tcp_send_synack : BUF->flags = TCP_ACK; - + #if UIP_ACTIVE_OPEN + tcp_send_synack : BUF->flags = TCP_ACK; tcp_send_syn: - BUF->flags |= TCP_SYN; -#else /* UIP_ACTIVE_OPEN */ - tcp_send_synack : BUF->flags = TCP_SYN | TCP_ACK; -#endif /* UIP_ACTIVE_OPEN */ + BUF->flags |= TCP_SYN; + #else /* UIP_ACTIVE_OPEN */ + tcp_send_synack : BUF->flags = TCP_SYN | TCP_ACK; + #endif /* UIP_ACTIVE_OPEN */ /* We send out the TCP Maximum Segment Size option with our - SYNACK. */ - BUF->optdata[0] = TCP_OPT_MSS; - BUF->optdata[1] = TCP_OPT_MSS_LEN; - BUF->optdata[2] = ( UIP_TCP_MSS ) / 256; - BUF->optdata[3] = ( UIP_TCP_MSS ) & 255; + SYNACK. */ + BUF->optdata[ 0 ] = TCP_OPT_MSS; + BUF->optdata[ 1 ] = TCP_OPT_MSS_LEN; + BUF->optdata[ 2 ] = ( UIP_TCP_MSS ) / 256; + BUF->optdata[ 3 ] = ( UIP_TCP_MSS ) & 255; uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; BUF->tcpoffset = ( (UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4 ) << 4; goto tcp_send; @@ -1545,9 +1521,9 @@ found: uip_flags = 0; /* We do a very naive form of TCP reset processing; we just accept - any RST and kill our connection. We should in fact check if the - sequence number of this reset is wihtin our advertised window - before we accept the reset. */ + any RST and kill our connection. We should in fact check if the + sequence number of this reset is wihtin our advertised window + before we accept the reset. */ if( BUF->flags & TCP_RST ) { uip_connr->tcpstateflags = UIP_CLOSED; @@ -1558,27 +1534,27 @@ found: } /* Calculate the length of the data, if the application has sent - any data to us. */ + any data to us. */ c = ( BUF->tcpoffset >> 4 ) << 2; /* uip_len will contain the length of the actual TCP data. This is - calculated by subtracing the length of the TCP header (in - c) and the length of the IP header (20 bytes). */ + calculated by subtracing the length of the TCP header (in + c) and the length of the IP header (20 bytes). */ uip_len = uip_len - c - UIP_IPH_LEN; /* First, check if the sequence number of the incoming packet is - what we're expecting next. If not, we send out an ACK with the - correct numbers in. */ + what we're expecting next. If not, we send out an ACK with the + correct numbers in. */ if( !(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ) { if ( (uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && ( - BUF->seqno[0] != uip_connr->rcv_nxt[0] || - BUF->seqno[1] != uip_connr->rcv_nxt[1] || - BUF->seqno[2] != uip_connr->rcv_nxt[2] || - BUF->seqno[3] != uip_connr->rcv_nxt[3] + BUF->seqno[ 0 ] != uip_connr->rcv_nxt[ 0 ] || + BUF->seqno[ 1 ] != uip_connr->rcv_nxt[ 1 ] || + BUF->seqno[ 2 ] != uip_connr->rcv_nxt[ 2 ] || + BUF->seqno[ 3 ] != uip_connr->rcv_nxt[ 3 ] ) ) { @@ -1587,26 +1563,26 @@ found: } /* Next, check if the incoming segment acknowledges any outstanding - data. If so, we update the sequence number, reset the length of - the outstanding data, calculate RTT estimations, and reset the - retransmission timer. */ + data. If so, we update the sequence number, reset the length of + the outstanding data, calculate RTT estimations, and reset the + retransmission timer. */ if( (BUF->flags & TCP_ACK) && uip_outstanding(uip_connr) ) { uip_add32( uip_connr->snd_nxt, uip_connr->len ); if ( - BUF->ackno[0] == uip_acc32[0] && - BUF->ackno[1] == uip_acc32[1] && - BUF->ackno[2] == uip_acc32[2] && - BUF->ackno[3] == uip_acc32[3] + BUF->ackno[ 0 ] == uip_acc32[ 0 ] && + BUF->ackno[ 1 ] == uip_acc32[ 1 ] && + BUF->ackno[ 2 ] == uip_acc32[ 2 ] && + BUF->ackno[ 3 ] == uip_acc32[ 3 ] ) { /* Update sequence number. */ - uip_connr->snd_nxt[0] = uip_acc32[0]; - uip_connr->snd_nxt[1] = uip_acc32[1]; - uip_connr->snd_nxt[2] = uip_acc32[2]; - uip_connr->snd_nxt[3] = uip_acc32[3]; + uip_connr->snd_nxt[ 0 ] = uip_acc32[ 0 ]; + uip_connr->snd_nxt[ 1 ] = uip_acc32[ 1 ]; + uip_connr->snd_nxt[ 2 ] = uip_acc32[ 2 ]; + uip_connr->snd_nxt[ 3 ] = uip_acc32[ 3 ]; /* Do RTT estimation, unless we have done retransmissions. */ if( uip_connr->nrtx == 0 ) @@ -1667,79 +1643,79 @@ found: } goto drop; - #if UIP_ACTIVE_OPEN - case UIP_SYN_SENT: - /* In SYN_SENT, we wait for a SYNACK that is sent in response to - our SYN. The rcv_nxt is set to sequence number in the SYNACK - plus one, and we send an ACK. We move into the ESTABLISHED - state. */ - if( (uip_flags & UIP_ACKDATA) && (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK) ) - { - /* Parse the TCP MSS option, if present. */ - if( (BUF->tcpoffset & 0xf0) > 0x50 ) + #if UIP_ACTIVE_OPEN + case UIP_SYN_SENT: + /* In SYN_SENT, we wait for a SYNACK that is sent in response to + our SYN. The rcv_nxt is set to sequence number in the SYNACK + plus one, and we send an ACK. We move into the ESTABLISHED + state. */ + if( (uip_flags & UIP_ACKDATA) && (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK) ) { - for( c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2; ) + /* Parse the TCP MSS option, if present. */ + if( (BUF->tcpoffset & 0xf0) > 0x50 ) { - opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; - if( opt == TCP_OPT_END ) + for( c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2; ) { - /* End of options. */ - break; - } - else if( opt == TCP_OPT_NOOP ) - { - ++c; - - /* NOP option. */ - } - else if( opt == TCP_OPT_MSS && uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN ) - { - /* An MSS option with the right option length. */ - tmp16 = ( uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8 ) | uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; - uip_connr->initialmss = uip_connr->mss = tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16; - - /* And we are done processing options. */ - break; - } - else - { - /* All other options have a length field, so that we easily - can skip past them. */ - if( uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0 ) + opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; + if( opt == TCP_OPT_END ) { - /* If the length field is zero, the options are malformed - and we don't process them further. */ + /* End of options. */ break; } + else if( opt == TCP_OPT_NOOP ) + { + ++c; - c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; + /* NOP option. */ + } + else if( opt == TCP_OPT_MSS && uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN ) + { + /* An MSS option with the right option length. */ + tmp16 = ( uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8 ) | uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; + uip_connr->initialmss = uip_connr->mss = tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16; + + /* And we are done processing options. */ + break; + } + else + { + /* All other options have a length field, so that we easily + can skip past them. */ + if( uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0 ) + { + /* If the length field is zero, the options are malformed + and we don't process them further. */ + break; + } + + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; + } } } + + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_connr->rcv_nxt[ 0 ] = BUF->seqno[ 0 ]; + uip_connr->rcv_nxt[ 1 ] = BUF->seqno[ 1 ]; + uip_connr->rcv_nxt[ 2 ] = BUF->seqno[ 2 ]; + uip_connr->rcv_nxt[ 3 ] = BUF->seqno[ 3 ]; + uip_add_rcv_nxt( 1 ); + uip_flags = UIP_CONNECTED | UIP_NEWDATA; + uip_connr->len = 0; + uip_len = 0; + uip_slen = 0; + UIP_APPCALL(); + goto appsend; } - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_connr->rcv_nxt[0] = BUF->seqno[0]; - uip_connr->rcv_nxt[1] = BUF->seqno[1]; - uip_connr->rcv_nxt[2] = BUF->seqno[2]; - uip_connr->rcv_nxt[3] = BUF->seqno[3]; - uip_add_rcv_nxt( 1 ); - uip_flags = UIP_CONNECTED | UIP_NEWDATA; - uip_connr->len = 0; - uip_len = 0; - uip_slen = 0; + /* Inform the application that the connection failed */ + uip_flags = UIP_ABORT; UIP_APPCALL(); - goto appsend; - } - /* Inform the application that the connection failed */ - uip_flags = UIP_ABORT; - UIP_APPCALL(); - - /* The connection is closed after we send the RST */ - uip_conn->tcpstateflags = UIP_CLOSED; - goto reset; - #endif /* UIP_ACTIVE_OPEN */ + /* The connection is closed after we send the RST */ + uip_conn->tcpstateflags = UIP_CLOSED; + goto reset; + #endif /* UIP_ACTIVE_OPEN */ case UIP_ESTABLISHED: /* In the ESTABLISHED state, we call upon the application to feed @@ -1752,7 +1728,7 @@ found: this side as well, and we send out a FIN and enter the LAST_ACK state. We require that there is no outstanding data; otherwise the sequence numbers will be screwed up. */ - if( BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED) ) + if( BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED) ) { if( uip_outstanding(uip_connr) ) { @@ -1779,26 +1755,26 @@ found: data that we must pass to the application. */ if( (BUF->flags & TCP_URG) != 0 ) { - #if UIP_URGDATA > 0 - uip_urglen = ( BUF->urgp[0] << 8 ) | BUF->urgp[1]; - if( uip_urglen > uip_len ) - { - /* There is more urgent data in the next segment to come. */ - uip_urglen = uip_len; - } + #if UIP_URGDATA > 0 + uip_urglen = ( BUF->urgp[ 0 ] << 8 ) | BUF->urgp[ 1 ]; + if( uip_urglen > uip_len ) + { + /* There is more urgent data in the next segment to come. */ + uip_urglen = uip_len; + } - uip_add_rcv_nxt( uip_urglen ); - uip_len -= uip_urglen; - uip_urgdata = uip_appdata; - uip_appdata += uip_urglen; - } - else - { - uip_urglen = 0; - #else /* UIP_URGDATA > 0 */ - uip_appdata = ( ( char * ) uip_appdata ) + ( (BUF->urgp[0] << 8) | BUF->urgp[1] ); - uip_len -= ( BUF->urgp[0] << 8 ) | BUF->urgp[1]; - #endif /* UIP_URGDATA > 0 */ + uip_add_rcv_nxt( uip_urglen ); + uip_len -= uip_urglen; + uip_urgdata = uip_appdata; + uip_appdata += uip_urglen; + } + else + { + uip_urglen = 0; + #else /* UIP_URGDATA > 0 */ + uip_appdata = ( ( char * ) uip_appdata ) + ( (BUF->urgp[ 0 ] << 8) | BUF->urgp[ 1 ] ); + uip_len -= ( BUF->urgp[ 0 ] << 8 ) | BUF->urgp[ 1 ]; + #endif /* UIP_URGDATA > 0 */ } /* If uip_len > 0 we have TCP data in the packet, and we flag this @@ -1806,7 +1782,7 @@ found: we acknowledge. If the application has stopped the dataflow using uip_stop(), we must not accept any data packets from the remote host. */ - if( uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED) ) + if( uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED) ) { uip_flags |= UIP_NEWDATA; uip_add_rcv_nxt( uip_len ); @@ -1824,7 +1800,7 @@ found: and the application will retransmit it. This is called the "persistent timer" and uses the retransmission mechanim. */ - tmp16 = ( (u16_t) BUF->wnd[0] << 8 ) + ( u16_t ) BUF->wnd[1]; + tmp16 = ( (u16_t) BUF->wnd[ 0 ] << 8 ) + ( u16_t ) BUF->wnd[ 1 ]; if( tmp16 > uip_connr->initialmss || tmp16 == 0 ) { tmp16 = uip_connr->initialmss; @@ -1848,12 +1824,12 @@ found: put into the uip_appdata and the length of the data should be put into uip_len. If the application don't have any data to send, uip_len must be set to 0. */ - if( uip_flags & (UIP_NEWDATA | UIP_ACKDATA) ) + if( uip_flags & (UIP_NEWDATA | UIP_ACKDATA) ) { uip_slen = 0; UIP_APPCALL(); - appsend: +appsend: if( uip_flags & UIP_ABORT ) { uip_slen = 0; @@ -1909,7 +1885,7 @@ found: } uip_connr->nrtx = 0; - apprexmit: +apprexmit: uip_appdata = uip_sappdata; /* If the application has data to be sent, or if the incoming @@ -1927,7 +1903,7 @@ found: } /* If there is no data to send, just send out a pure ACK if - there is newdata. */ + there is newdata. */ if( uip_flags & UIP_NEWDATA ) { uip_len = UIP_TCPIP_HLEN; @@ -1940,7 +1916,7 @@ found: case UIP_LAST_ACK: /* We can close this connection if the peer has acknowledged our - FIN. This is indicated by the UIP_ACKDATA flag. */ + FIN. This is indicated by the UIP_ACKDATA flag. */ if( uip_flags & UIP_ACKDATA ) { uip_connr->tcpstateflags = UIP_CLOSED; @@ -1952,8 +1928,8 @@ found: case UIP_FIN_WAIT_1: /* The application has closed the connection, but the remote host - hasn't closed its end yet. Thus we do nothing but wait for a - FIN from the other side. */ + hasn't closed its end yet. Thus we do nothing but wait for a + FIN from the other side. */ if( uip_len > 0 ) { uip_add_rcv_nxt( uip_len ); @@ -2043,15 +2019,15 @@ tcp_send_noopts: headers before calculating the checksum and finally send the packet. */ tcp_send: - BUF->ackno[0] = uip_connr->rcv_nxt[0]; - BUF->ackno[1] = uip_connr->rcv_nxt[1]; - BUF->ackno[2] = uip_connr->rcv_nxt[2]; - BUF->ackno[3] = uip_connr->rcv_nxt[3]; + BUF->ackno[ 0 ] = uip_connr->rcv_nxt[ 0 ]; + BUF->ackno[ 1 ] = uip_connr->rcv_nxt[ 1 ]; + BUF->ackno[ 2 ] = uip_connr->rcv_nxt[ 2 ]; + BUF->ackno[ 3 ] = uip_connr->rcv_nxt[ 3 ]; - BUF->seqno[0] = uip_connr->snd_nxt[0]; - BUF->seqno[1] = uip_connr->snd_nxt[1]; - BUF->seqno[2] = uip_connr->snd_nxt[2]; - BUF->seqno[3] = uip_connr->snd_nxt[3]; + BUF->seqno[ 0 ] = uip_connr->snd_nxt[ 0 ]; + BUF->seqno[ 1 ] = uip_connr->snd_nxt[ 1 ]; + BUF->seqno[ 2 ] = uip_connr->snd_nxt[ 2 ]; + BUF->seqno[ 3 ] = uip_connr->snd_nxt[ 3 ]; BUF->proto = UIP_PROTO_TCP; @@ -2064,58 +2040,62 @@ tcp_send: if( uip_connr->tcpstateflags & UIP_STOPPED ) { /* If the connection has issued uip_stop(), we advertise a zero - window so that the remote host will stop sending data. */ - BUF->wnd[0] = BUF->wnd[1] = 0; + window so that the remote host will stop sending data. */ + BUF->wnd[ 0 ] = BUF->wnd[ 1 ] = 0; } else { - BUF->wnd[0] = ( (UIP_RECEIVE_WINDOW) >> 8 ); - BUF->wnd[1] = ( (UIP_RECEIVE_WINDOW) & 0xff ); + BUF->wnd[ 0 ] = ( (UIP_RECEIVE_WINDOW) >> 8 ); + BUF->wnd[ 1 ] = ( (UIP_RECEIVE_WINDOW) & 0xff ); } tcp_send_noconn: - BUF->ttl = UIP_TTL; -#if UIP_CONF_IPV6 - /* For IPv6, the IP length field does not include the IPv6 IP header - length. */ - BUF->len[0] = ( (uip_len - UIP_IPH_LEN) >> 8 ); - BUF->len[1] = ( (uip_len - UIP_IPH_LEN) & 0xff ); -#else /* UIP_CONF_IPV6 */ - BUF->len[0] = ( uip_len >> 8 ); - BUF->len[1] = ( uip_len & 0xff ); -#endif /* UIP_CONF_IPV6 */ - BUF->urgp[0] = BUF->urgp[1] = 0; + BUF->ttl = UIP_TTL; + + #if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[ 0 ] = ( (uip_len - UIP_IPH_LEN) >> 8 ); + BUF->len[ 1 ] = ( (uip_len - UIP_IPH_LEN) & 0xff ); + #else /* UIP_CONF_IPV6 */ + BUF->len[ 0 ] = ( uip_len >> 8 ); + BUF->len[ 1 ] = ( uip_len & 0xff ); + #endif /* UIP_CONF_IPV6 */ + + BUF->urgp[ 0 ] = BUF->urgp[ 1 ] = 0; /* Calculate TCP checksum. */ BUF->tcpchksum = 0; BUF->tcpchksum = ~( uip_tcpchksum() ); ip_send_nolen: -#if UIP_CONF_IPV6 - BUF->vtc = 0x60; - BUF->tcflow = 0x00; - BUF->flow = 0x00; -#else /* UIP_CONF_IPV6 */ - BUF->vhl = 0x45; - BUF->tos = 0; - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - ++ipid; - BUF->ipid[0] = ipid >> 8; - BUF->ipid[1] = ipid & 0xff; + #if UIP_CONF_IPV6 + BUF->vtc = 0x60; + BUF->tcflow = 0x00; + BUF->flow = 0x00; + #else /* UIP_CONF_IPV6 */ + BUF->vhl = 0x45; + BUF->tos = 0; + BUF->ipoffset[ 0 ] = BUF->ipoffset[ 1 ] = 0; + ++ipid; + BUF->ipid[ 0 ] = ipid >> 8; + BUF->ipid[ 1 ] = ipid & 0xff; - /* Calculate IP checksum. */ - BUF->ipchksum = 0; - BUF->ipchksum = ~( uip_ipchksum() ); + /* Calculate IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~( uip_ipchksum() ); + + //DEBUG_PRINTF( "uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum() ); + #endif /* UIP_CONF_IPV6 */ - //DEBUG_PRINTF( "uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum() ); -#endif /* UIP_CONF_IPV6 */ UIP_STAT( ++uip_stat.tcp.sent ); -#if UIP_CONF_IPV6 - send : -#endif /* UIP_CONF_IPV6 */ - //DEBUG_PRINTF( "Sending packet with length %d (%d)\n", uip_len, (BUF->len[0] << 8) | BUF->len[1] ); + #if UIP_CONF_IPV6 +send : + #endif /* UIP_CONF_IPV6 */ + + //DEBUG_PRINTF( "Sending packet with length %d (%d)\n", uip_len, (BUF->len[ 0 ] << 8) | BUF->len[ 1 ] ); UIP_STAT( ++uip_stat.ip.sent ); /* Return and let the caller do the actual transmission. */ @@ -2127,8 +2107,8 @@ drop: uip_flags = 0; return; } - /*---------------------------------------------------------------------------*/ + u16_t htons( u16_t val ) { return HTONS( val ); @@ -2138,12 +2118,14 @@ u32_t htonl( u32_t val ) { return HTONL( val ); } - /*---------------------------------------------------------------------------*/ + void uip_send( const void *data, int len ) { int copylen; -#define MIN( a, b ) ( (a) < (b) ? (a) : (b) ) + + #define MIN( a, b ) ( (a) < (b) ? (a) : (b) ) + copylen = MIN( len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - ( int ) (( char * ) uip_sappdata - ( char * ) &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]) ); if( copylen > 0 ) @@ -2155,7 +2137,6 @@ void uip_send( const void *data, int len ) } } } - /*---------------------------------------------------------------------------*/ /** @} */