From 8a229a16f63d06cb99a7b5c6e384533faf9bbfbb Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sat, 13 May 2006 11:24:25 +0000 Subject: (Redoing check-in lost by SourceForge's failure.) Moved to net/ --- src/proto/hello.c | 133 ---- src/proto/tcp.c | 164 ----- src/proto/uip/uip.c | 1501 ---------------------------------------------- src/proto/uip/uip.h | 1060 -------------------------------- src/proto/uip/uip_arch.c | 83 --- src/proto/uip/uip_arch.h | 130 ---- src/proto/uip/uipopt.h | 572 ------------------ 7 files changed, 3643 deletions(-) delete mode 100644 src/proto/hello.c delete mode 100644 src/proto/tcp.c delete mode 100644 src/proto/uip/uip.c delete mode 100644 src/proto/uip/uip.h delete mode 100644 src/proto/uip/uip_arch.c delete mode 100644 src/proto/uip/uip_arch.h delete mode 100644 src/proto/uip/uipopt.h (limited to 'src/proto') diff --git a/src/proto/hello.c b/src/proto/hello.c deleted file mode 100644 index eee9c77b..00000000 --- a/src/proto/hello.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include -#include -#include -#include - -/** @file - * - * "Hello world" TCP protocol - * - * This file implements a trivial TCP-based protocol. It connects to - * the server specified in hello_request::tcp and transmits a single - * message (hello_request::message). Any data received from the - * server will be passed to the callback function, - * hello_request::callback(), and once the connection has been closed, - * hello_request::complete will be set to 1. - * - * To use this code, do something like: - * - * @code - * - * static void my_callback ( char *data, size_t len ) { - * ... process data ... - * } - * - * struct hello_request hello = { - * .message = "hello world!", - * .callback = my_callback, - * }; - * - * hello.sin.sin_addr.s_addr = ... server IP address ... - * hello.sin.sin_port = ... server port ... - * - * hello_connect ( &hello ); - * while ( ! hello.completed ) { - * run_tcpip(); - * } - * - * @endcode - * - * It's worth noting that this trivial protocol would be entirely - * adequate to implement a TCP-based version of TFTP; just use "RRQ - * " as the message. Now, if only an appropriate server - * existed... - */ - -static inline struct hello_request * -tcp_to_hello ( struct tcp_connection *conn ) { - return container_of ( conn, struct hello_request, tcp ); -} - -static void hello_aborted ( struct tcp_connection *conn ) { - struct hello_request *hello = tcp_to_hello ( conn ); - - printf ( "Connection aborted\n" ); - hello->complete = 1; -} - -static void hello_timedout ( struct tcp_connection *conn ) { - struct hello_request *hello = tcp_to_hello ( conn ); - - printf ( "Connection timed out\n" ); - hello->complete = 1; -} - -static void hello_closed ( struct tcp_connection *conn ) { - struct hello_request *hello = tcp_to_hello ( conn ); - - hello->complete = 1; -} - -static void hello_connected ( struct tcp_connection *conn ) { - struct hello_request *hello = tcp_to_hello ( conn ); - - hello->remaining = strlen ( hello->message ); - hello->state = HELLO_SENDING_MESSAGE; -} - -static void hello_acked ( struct tcp_connection *conn, size_t len ) { - struct hello_request *hello = tcp_to_hello ( conn ); - - hello->message += len; - hello->remaining -= len; - if ( hello->remaining == 0 ) { - switch ( hello->state ) { - case HELLO_SENDING_MESSAGE: - hello->message = "\r\n"; - hello->remaining = 2; - hello->state = HELLO_SENDING_ENDL; - break; - case HELLO_SENDING_ENDL: - /* Nothing to do once we've finished sending - * the end-of-line indicator. - */ - break; - default: - assert ( 0 ); - } - } -} - -static void hello_newdata ( struct tcp_connection *conn, void *data, - size_t len ) { - struct hello_request *hello = tcp_to_hello ( conn ); - - hello->callback ( data, len ); -} - -static void hello_senddata ( struct tcp_connection *conn ) { - struct hello_request *hello = tcp_to_hello ( conn ); - - tcp_send ( conn, hello->message, hello->remaining ); -} - -static struct tcp_operations hello_tcp_operations = { - .aborted = hello_aborted, - .timedout = hello_timedout, - .closed = hello_closed, - .connected = hello_connected, - .acked = hello_acked, - .newdata = hello_newdata, - .senddata = hello_senddata, -}; - -/** - * Initiate a "hello world" connection - * - * @v hello "Hello world" request - */ -int hello_connect ( struct hello_request *hello ) { - hello->tcp.tcp_op = &hello_tcp_operations; - return tcp_connect ( &hello->tcp ); -} diff --git a/src/proto/tcp.c b/src/proto/tcp.c deleted file mode 100644 index 69fe95f5..00000000 --- a/src/proto/tcp.c +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include -#include -#include -#include "uip/uip.h" - -/** @file - * - * TCP protocol - * - * The gPXE TCP stack is currently implemented on top of the uIP - * protocol stack. This file provides wrappers around uIP so that - * higher-level protocol implementations do not need to talk directly - * to uIP (which has a somewhat baroque API). - * - * Basic operation is to create a #tcp_connection structure, call - * tcp_connect() and then call run_tcpip() in a loop until the - * operation has completed. The TCP stack will call the various - * methods defined in the #tcp_operations structure in order to send - * and receive data. - * - * See hello.c for a trivial example of a TCP protocol using this - * API. - * - */ - -/** - * TCP transmit buffer - * - * When a tcp_operations::senddata() method is called, it is - * guaranteed to be able to use this buffer as temporary space for - * constructing the data to be sent. For example, code such as - * - * @code - * - * static void my_senddata ( struct tcp_connection *conn ) { - * int len; - * - * len = snprintf ( tcp_buffer, tcp_buflen, "FETCH %s\r\n", filename ); - * tcp_send ( conn, tcp_buffer + already_sent, len - already_sent ); - * } - * - * @endcode - * - * is allowed, and is probably the best way to deal with - * variably-sized data. - * - * Note that you cannot use this simple mechanism if you want to be - * able to construct single data blocks of more than #tcp_buflen - * bytes. - */ -void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN ); - -/** Size of #tcp_buffer */ -size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN ); - -/** - * Open a TCP connection - * - * @v conn TCP connection - * @ret 0 Success - * @ret <0 Failure - * - * This sets up a new TCP connection to the remote host specified in - * tcp_connection::sin. The actual SYN packet will not be sent out - * until run_tcpip() is called for the first time. - * - * @todo Use linked lists instead of a static buffer, and thereby - * remove the only potential failure case, giving this function - * a void return type. - */ -int tcp_connect ( struct tcp_connection *conn ) { - struct uip_conn *uip_conn; - u16_t ipaddr[2]; - - assert ( conn->sin.sin_addr.s_addr != 0 ); - assert ( conn->sin.sin_port != 0 ); - assert ( conn->tcp_op != NULL ); - assert ( sizeof ( uip_conn->appstate ) == sizeof ( conn ) ); - - * ( ( uint32_t * ) ipaddr ) = conn->sin.sin_addr.s_addr; - uip_conn = uip_connect ( ipaddr, conn->sin.sin_port ); - if ( ! uip_conn ) - return -1; - - *( ( void ** ) uip_conn->appstate ) = conn; - return 0; -} - -/** - * Send data via a TCP connection - * - * @v conn TCP connection - * @v data Data to send - * @v len Length of data - * - * Data will be automatically limited to the current TCP window size. - * - * If retransmission is required, the connection's - * tcp_operations::senddata() method will be called again in order to - * regenerate the data. - */ -void tcp_send ( struct tcp_connection *conn __unused, - const void *data, size_t len ) { - - assert ( conn = *( ( void ** ) uip_conn->appstate ) ); - - if ( len > tcp_buflen ) - len = tcp_buflen; - memmove ( tcp_buffer, data, len ); - - uip_send ( tcp_buffer, len ); -} - -/** - * Close a TCP connection - * - * @v conn TCP connection - */ -void tcp_close ( struct tcp_connection *conn __unused ) { - assert ( conn = *( ( void ** ) uip_conn->appstate ) ); - uip_close(); -} - -/** - * uIP TCP application call interface - * - * This is the entry point of gPXE from the point of view of the uIP - * protocol stack. This function calls the appropriate methods from - * the connection's @tcp_operations table in order to process received - * data, transmit new data etc. - */ -void uip_tcp_appcall ( void ) { - struct tcp_connection *conn = *( ( void ** ) uip_conn->appstate ); - struct tcp_operations *op = conn->tcp_op; - - assert ( conn->tcp_op->closed != NULL ); - assert ( conn->tcp_op->connected != NULL ); - assert ( conn->tcp_op->acked != NULL ); - assert ( conn->tcp_op->newdata != NULL ); - assert ( conn->tcp_op->senddata != NULL ); - - if ( uip_aborted() && op->aborted ) /* optional method */ - op->aborted ( conn ); - if ( uip_timedout() && op->timedout ) /* optional method */ - op->timedout ( conn ); - if ( uip_closed() && op->closed ) /* optional method */ - op->closed ( conn ); - if ( uip_connected() ) - op->connected ( conn ); - if ( uip_acked() ) - op->acked ( conn, uip_conn->len ); - if ( uip_newdata() ) - op->newdata ( conn, ( void * ) uip_appdata, uip_len ); - if ( uip_rexmit() || uip_newdata() || uip_acked() || - uip_connected() || uip_poll() ) - op->senddata ( conn ); -} - -/* Present here to allow everything to link. Will go into separate - * udp.c file - */ -void uip_udp_appcall ( void ) { -} diff --git a/src/proto/uip/uip.c b/src/proto/uip/uip.c deleted file mode 100644 index cde69fef..00000000 --- a/src/proto/uip/uip.c +++ /dev/null @@ -1,1501 +0,0 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \file - * The uIP TCP/IP stack code. - * \author Adam Dunkels - */ - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. 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. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id$ - * - */ - -/* -This is a small implementation of the IP and TCP protocols (as well as -some basic ICMP stuff). The implementation couples the IP, TCP and the -application layers very tightly. To keep the size of the compiled code -down, this code also features heavy usage of the goto statement. - -The principle is that we have a small buffer, called the uip_buf, in -which the device driver puts an incoming packet. The TCP/IP stack -parses the headers in the packet, and calls upon the application. If -the remote host has sent data to the application, this data is present -in the uip_buf and the application read the data from there. It is up -to the application to put this data into a byte stream if needed. The -application will not be fed with data that is out of sequence. - -If the application whishes to send data to the peer, it should put its -data into the uip_buf, 40 bytes from the start of the buffer. The -TCP/IP stack will calculate the checksums, and fill in the necessary -header fields and finally send the packet back to the peer. -*/ - -#include -#include -#include "uip.h" -#include "uipopt.h" -#include "uip_arch.h" - -/*-----------------------------------------------------------------------------------*/ -/* 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 */ -#if UIP_FIXEDADDR > 0 -const u16_t uip_hostaddr[2] = - {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), - HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; -const u16_t uip_arp_draddr[2] = - {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), - HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; -const u16_t uip_arp_netmask[2] = - {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), - HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; -#else -u16_t uip_hostaddr[2]; -u16_t uip_arp_draddr[2], uip_arp_netmask[2]; -#endif /* UIP_FIXEDADDR */ - -u8_t uip_buf[UIP_BUFSIZE+2]; /* The packet buffer that contains - incoming packets. */ -volatile u8_t *uip_appdata; /* The uip_appdata pointer points to - application data. */ -volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to the - application data which is to be sent. */ -#if UIP_URGDATA > 0 -volatile u8_t *uip_urgdata; /* The uip_urgdata pointer points to - urgent data (out-of-band data), if - present. */ -volatile u8_t uip_urglen, uip_surglen; -#endif /* UIP_URGDATA > 0 */ - -volatile u16_t uip_len, uip_slen; - /* The uip_len is either 8 or 16 bits, - depending on the maximum packet - size. */ - -volatile 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. */ - -struct uip_conn uip_conns[UIP_CONNS]; - /* The uip_conns array holds all TCP - connections. */ -u16_t uip_listenports[UIP_LISTENPORTS]; - /* 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]; -#endif /* UIP_UDP */ - - -static u16_t ipid; /* Ths ipid variable is an increasing - number that is used for the IP ID - field. */ - -static u8_t iss[4]; /* The iss variable is used for the TCP - initial sequence number. */ - -#if UIP_ACTIVE_OPEN -static u16_t lastport = 1024; /* Keeps track of the last port used for - a new connection. */ -#endif /* UIP_ACTIVE_OPEN */ - -/* Temporary variables. */ -volatile u8_t uip_acc32[4]; -static u8_t c, opt; -static u16_t tmp16; - -/* Structures and definitions. */ -#define TCP_FIN 0x01 -#define TCP_SYN 0x02 -#define TCP_RST 0x04 -#define TCP_PSH 0x08 -#define TCP_ACK 0x10 -#define TCP_URG 0x20 -#define TCP_CTL 0x3f - -#define ICMP_ECHO_REPLY 0 -#define ICMP_ECHO 8 - -/* Macros. */ -#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0]) -#define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) - -#if UIP_STATISTICS == 1 -struct uip_stats uip_stat; -#define UIP_STAT(s) s -#else -#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) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -/*-----------------------------------------------------------------------------------*/ -#if 0 -void -uip_init(void) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - uip_listenports[c] = 0; - } - for(c = 0; c < UIP_CONNS; ++c) { - uip_conns[c].tcpstateflags = CLOSED; - } -#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 */ - - - /* IPv4 initialization. */ -#if UIP_FIXEDADDR == 0 - uip_hostaddr[0] = uip_hostaddr[1] = 0; -#endif /* UIP_FIXEDADDR */ - -} -#endif -/*-----------------------------------------------------------------------------------*/ -#if UIP_ACTIVE_OPEN -struct uip_conn * -uip_connect(u16_t *ripaddr, u16_t rport) -{ - register struct uip_conn *conn, *cconn; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - /* 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 != CLOSED && - conn->lport == htons(lastport)) { - goto again; - } - } - - - conn = 0; - for(c = 0; c < UIP_CONNS; ++c) { - cconn = &uip_conns[c]; - if(cconn->tcpstateflags == CLOSED) { - conn = cconn; - break; - } - if(cconn->tcpstateflags == TIME_WAIT) { - if(conn == 0 || - cconn->timer > uip_conn->timer) { - conn = cconn; - } - } - } - - if(conn == 0) { - return 0; - } - - conn->tcpstateflags = 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; - conn->lport = htons(lastport); - conn->rport = rport; - conn->ripaddr[0] = ripaddr[0]; - conn->ripaddr[1] = ripaddr[1]; - - return conn; -} -#endif /* UIP_ACTIVE_OPEN */ -/*-----------------------------------------------------------------------------------*/ -#if UIP_UDP -struct uip_udp_conn * -uip_udp_new(u16_t *ripaddr, u16_t rport) -{ - register struct uip_udp_conn *conn; - - /* Find an unused local port. */ - again: - ++lastport; - - if(lastport >= 32000) { - lastport = 4096; - } - - for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == 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 = HTONS(rport); - conn->ripaddr[0] = ripaddr[0]; - conn->ripaddr[1] = ripaddr[1]; - - return conn; -} -#endif /* UIP_UDP */ -/*-----------------------------------------------------------------------------------*/ -void -uip_unlisten(u16_t port) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == port) { - uip_listenports[c] = 0; - return; - } - } -} -/*-----------------------------------------------------------------------------------*/ -void -uip_listen(u16_t port) -{ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(uip_listenports[c] == 0) { - uip_listenports[c] = port; - return; - } - } -} -/*-----------------------------------------------------------------------------------*/ -/* XXX: IP fragment reassembly: not well-tested. */ - -#if UIP_REASSEMBLY -#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_HLEN 20 -#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) { - memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN); - uip_reasstmr = UIP_REASS_MAXAGE; - uip_reassflags = 0; - /* Clear the bitmap. */ - memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0); - } - - /* 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) { - uip_reasstmr = 0; - goto nullreturn; - } - - /* Copy the fragment into the reassembly buffer, at the right - offset. */ - memcpy(&uip_reassbuf[IP_HLEN + offset], - (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), - len); - - /* 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]) { - 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; -} -#endif /* UIP_REASSEMBL */ -/*-----------------------------------------------------------------------------------*/ -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]; -} -/*-----------------------------------------------------------------------------------*/ -void -uip_process(u8_t flag) -{ - register struct uip_conn *uip_connr = uip_conn; - - uip_appdata = &uip_buf[40 + UIP_LLH_LEN]; - - - /* Check if we were invoked because of the perodic timer fireing. */ - if(flag == UIP_TIMER) { -#if UIP_REASSEMBLY - if(uip_reasstmr != 0) { - --uip_reasstmr; - } -#endif /* UIP_REASSEMBLY */ - /* Increase the initial sequence number. */ - if(++iss[3] == 0) { - if(++iss[2] == 0) { - if(++iss[1] == 0) { - ++iss[0]; - } - } - } - uip_len = 0; - if(uip_connr->tcpstateflags == TIME_WAIT || - uip_connr->tcpstateflags == FIN_WAIT_2) { - ++(uip_connr->timer); - if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { - uip_connr->tcpstateflags = CLOSED; - } - } else if(uip_connr->tcpstateflags != CLOSED) { - /* 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_connr->timer-- == 0) { - if(uip_connr->nrtx == UIP_MAXRTX || - ((uip_connr->tcpstateflags == SYN_SENT || - uip_connr->tcpstateflags == SYN_RCVD) && - uip_connr->nrtx == UIP_MAXSYNRTX)) { - uip_connr->tcpstateflags = CLOSED; - - /* 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_APPCALL(); - - /* We also send a reset packet to the remote host. */ - BUF->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - /* Exponential backoff. */ - uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? - 4: - uip_connr->nrtx); - ++(uip_connr->nrtx); - - /* Ok, so we need to retransmit. We do this differently - depending on which state we are in. In ESTABLISHED, we - call upon the application so that it may prepare the - data for the retransmit. In SYN_RCVD, we resend the - SYNACK that we sent earlier and in LAST_ACK we have to - retransmit our FINACK. */ - UIP_STAT(++uip_stat.tcp.rexmit); - switch(uip_connr->tcpstateflags & TS_MASK) { - case SYN_RCVD: - /* In the SYN_RCVD state, we should retransmit our - SYNACK. */ - goto tcp_send_synack; - -#if UIP_ACTIVE_OPEN - case SYN_SENT: - /* In the SYN_SENT state, we retransmit out SYN. */ - BUF->flags = 0; - goto tcp_send_syn; -#endif /* UIP_ACTIVE_OPEN */ - - case ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application - to do the actual retransmit after which we jump into - the code for sending out the packet (the apprexmit - label). */ - uip_len = 0; - uip_slen = 0; - uip_flags = UIP_REXMIT; - UIP_APPCALL(); - goto apprexmit; - - case FIN_WAIT_1: - case CLOSING: - case LAST_ACK: - /* In all these states we should retransmit a FINACK. */ - goto tcp_send_finack; - - } - } - } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) { - /* If there was no need for a retransmission, we poll the - application for new data. */ - uip_len = 0; - uip_slen = 0; - uip_flags = UIP_POLL; - UIP_APPCALL(); - goto appsend; - } - } - goto drop; - } -#if UIP_UDP - if(flag == UIP_UDP_TIMER) { - if(uip_udp_conn->lport != 0) { - uip_appdata = &uip_buf[UIP_LLH_LEN + 28]; - uip_len = uip_slen = 0; - uip_flags = UIP_POLL; - UIP_UDP_APPCALL(); - goto udp_send; - } else { - goto drop; - } - } -#endif - - /* This is where the input processing starts. */ - UIP_STAT(++uip_stat.ip.recv); - - - /* Start of IPv4 input header processing code. */ - - /* 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; - } - - /* Check the size of the packet. If the size reported to us in - uip_len doesn't match the size reported in the IP header, there - has been a transmission error and we drop the packet. */ - - if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */ - uip_len = (uip_len & 0xff) | (BUF->len[0] << 8); - } - if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */ - uip_len = (uip_len & 0xff00) | BUF->len[1]; - } - - /* 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) { - goto drop; - } -#else - UIP_STAT(++uip_stat.ip.drop); - UIP_STAT(++uip_stat.ip.fragerr); - UIP_LOG("ip: fragment dropped."); - goto drop; -#endif /* UIP_REASSEMBLY */ - } - - /* 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 - if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) { - 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 */ - - /* Check if the packet is destined for our IP address. */ - if(BUF->destipaddr[0] != uip_hostaddr[0]) { - UIP_STAT(++uip_stat.ip.drop); - UIP_LOG("ip: packet not for us."); - goto drop; - } - if(BUF->destipaddr[1] != uip_hostaddr[1]) { - UIP_STAT(++uip_stat.ip.drop); - UIP_LOG("ip: packet not for us."); - goto drop; - } - - 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; - } - - if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump - to the tcp_input label. */ - goto tcp_input; - -#if UIP_UDP - if(BUF->proto == UIP_PROTO_UDP) - goto udp_input; -#endif /* UIP_UDP */ - - 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; - } - - icmp_input: - 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_hostaddr[0] | uip_hostaddr[1]) == 0) { - uip_hostaddr[0] = BUF->destipaddr[0]; - uip_hostaddr[1] = BUF->destipaddr[1]; - } -#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. */ - tmp16 = BUF->destipaddr[0]; - BUF->destipaddr[0] = BUF->srcipaddr[0]; - BUF->srcipaddr[0] = tmp16; - tmp16 = BUF->destipaddr[1]; - BUF->destipaddr[1] = BUF->srcipaddr[1]; - BUF->srcipaddr[1] = tmp16; - - UIP_STAT(++uip_stat.icmp.sent); - goto send; - - /* End of IPv4 input header processing code. */ - - -#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 - if(uip_udpchksum() != 0xffff) { - UIP_STAT(++uip_stat.udp.drop); - UIP_STAT(++uip_stat.udp.chkerr); - UIP_LOG("udp: bad checksum."); - goto drop; - } -#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(uip_udp_conn->lport != 0 && - UDPBUF->destport == uip_udp_conn->lport && - (uip_udp_conn->rport == 0 || - UDPBUF->srcport == uip_udp_conn->rport) && - BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] && - BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) { - goto udp_found; - } - } - goto drop; - - udp_found: - uip_len = uip_len - 28; - uip_appdata = &uip_buf[UIP_LLH_LEN + 28]; - uip_flags = UIP_NEWDATA; - uip_slen = 0; - UIP_UDP_APPCALL(); - udp_send: - if(uip_slen == 0) { - goto drop; - } - uip_len = uip_slen + 28; - - BUF->len[0] = (uip_len >> 8); - BUF->len[1] = (uip_len & 0xff); - - BUF->proto = UIP_PROTO_UDP; - - UDPBUF->udplen = HTONS(uip_slen + 8); - UDPBUF->udpchksum = 0; -#if UIP_UDP_CHECKSUMS - /* Calculate UDP checksum. */ - UDPBUF->udpchksum = ~(uip_udpchksum()); - if(UDPBUF->udpchksum == 0) { - UDPBUF->udpchksum = 0xffff; - } -#endif /* UIP_UDP_CHECKSUMS */ - - BUF->srcport = uip_udp_conn->lport; - BUF->destport = uip_udp_conn->rport; - - BUF->srcipaddr[0] = uip_hostaddr[0]; - BUF->srcipaddr[1] = uip_hostaddr[1]; - BUF->destipaddr[0] = uip_udp_conn->ripaddr[0]; - BUF->destipaddr[1] = uip_udp_conn->ripaddr[1]; - - uip_appdata = &uip_buf[UIP_LLH_LEN + 40]; - 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. */ - UIP_STAT(++uip_stat.tcp.drop); - UIP_STAT(++uip_stat.tcp.chkerr); - UIP_LOG("tcp: bad checksum."); - goto drop; - } - - /* Demultiplex this segment. */ - /* First check any active connections. */ - for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) { - if(uip_connr->tcpstateflags != CLOSED && - BUF->destport == uip_connr->lport && - BUF->srcport == uip_connr->rport && - BUF->srcipaddr[0] == uip_connr->ripaddr[0] && - BUF->srcipaddr[1] == uip_connr->ripaddr[1]) { - goto found; - } - } - - /* If we didn't find and active connection that expected the packet, - either this packet is an old duplicate, or this is a SYN packet - destined for a connection in LISTEN. If the SYN flag isn't set, - it is an old packet and we send a RST. */ - if((BUF->flags & TCP_CTL) != TCP_SYN) - goto reset; - - tmp16 = BUF->destport; - /* Next, check listening connections. */ - for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(tmp16 == uip_listenports[c]) - goto found_listen; - } - - /* No matching connection found, so we send a RST packet. */ - UIP_STAT(++uip_stat.tcp.synrst); - reset: - - /* We do not send resets in response to resets. */ - if(BUF->flags & TCP_RST) - goto drop; - - UIP_STAT(++uip_stat.tcp.rst); - - BUF->flags = TCP_RST | TCP_ACK; - uip_len = 40; - 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[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[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[2] == 0) { - if(++BUF->ackno[1] == 0) { - ++BUF->ackno[0]; - } - } - } - - /* Swap port numbers. */ - tmp16 = BUF->srcport; - BUF->srcport = BUF->destport; - BUF->destport = tmp16; - - /* Swap IP addresses. */ - tmp16 = BUF->destipaddr[0]; - BUF->destipaddr[0] = BUF->srcipaddr[0]; - BUF->srcipaddr[0] = tmp16; - tmp16 = BUF->destipaddr[1]; - BUF->destipaddr[1] = BUF->srcipaddr[1]; - BUF->srcipaddr[1] = tmp16; - - - /* And send out the RST packet! */ - goto tcp_send_noconn; - - /* This label will be jumped to if we matched the incoming packet - with a connection in LISTEN. In that case, we should create a new - connection and send a SYNACK in return. */ - found_listen: - /* First we check if there are any connections avaliable. Unused - connections are kept in the same table as used connections, but - unused ones have the tcpstate set to CLOSED. Also, connections in - TIME_WAIT are kept track of and we'll use the oldest one if no - CLOSED connections are found. Thanks to Eddie C. Dost for a very - nice algorithm for the TIME_WAIT search. */ - uip_connr = 0; - for(c = 0; c < UIP_CONNS; ++c) { - if(uip_conns[c].tcpstateflags == CLOSED) { - uip_connr = &uip_conns[c]; - break; - } - if(uip_conns[c].tcpstateflags == TIME_WAIT) { - if(uip_connr == 0 || - uip_conns[c].timer > uip_connr->timer) { - uip_connr = &uip_conns[c]; - } - } - } - - 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. */ - UIP_STAT(++uip_stat.tcp.syndrop); - UIP_LOG("tcp: found no unused connections."); - goto drop; - } - uip_conn = uip_connr; - - /* Fill in the necessary fields for the new connection. */ - uip_connr->rto = uip_connr->timer = UIP_RTO; - uip_connr->sa = 0; - uip_connr->sv = 4; - uip_connr->nrtx = 0; - uip_connr->lport = BUF->destport; - uip_connr->rport = BUF->srcport; - uip_connr->ripaddr[0] = BUF->srcipaddr[0]; - uip_connr->ripaddr[1] = BUF->srcipaddr[1]; - uip_connr->tcpstateflags = 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->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_add_rcv_nxt(1); - - /* Parse the TCP MSS option, if present. */ - if((BUF->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; - if(opt == 0x00) { - /* End of options. */ - break; - } else if(opt == 0x01) { - ++c; - /* NOP option. */ - } else if(opt == 0x02 && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) { - /* An MSS option with the right option length. */ - tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - (u16_t)uip_buf[40 + 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]; - } - } - } - - /* Our response will be a SYNACK. */ -#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 */ - - /* We send out the TCP Maximum Segment Size option with our - SYNACK. */ - BUF->optdata[0] = 2; - BUF->optdata[1] = 4; - BUF->optdata[2] = (UIP_TCP_MSS) / 256; - BUF->optdata[3] = (UIP_TCP_MSS) & 255; - uip_len = 44; - BUF->tcpoffset = 6 << 4; - goto tcp_send; - - /* This label will be jumped to if we found an active connection. */ - found: - uip_conn = uip_connr; - 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. */ - if(BUF->flags & TCP_RST) { - uip_connr->tcpstateflags = CLOSED; - UIP_LOG("tcp: got reset, aborting connection."); - uip_flags = UIP_ABORT; - UIP_APPCALL(); - goto drop; - } - /* Calculated the length of the data, if the application has sent - 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). */ - uip_len = uip_len - c - 20; - - /* 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. */ - if(uip_len > 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])) { - goto tcp_send_ack; - } - - /* 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. */ - 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]) { - /* 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]; - - - /* Do RTT estimation, unless we have done retransmissions. */ - if(uip_connr->nrtx == 0) { - signed char m; - m = uip_connr->rto - uip_connr->timer; - /* This is taken directly from VJs original code in his paper */ - m = m - (uip_connr->sa >> 3); - uip_connr->sa += m; - if(m < 0) { - m = -m; - } - m = m - (uip_connr->sv >> 2); - uip_connr->sv += m; - uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; - - } - /* Set the acknowledged flag. */ - uip_flags = UIP_ACKDATA; - /* Reset the retransmission timer. */ - uip_connr->timer = uip_connr->rto; - } - - } - - /* Do different things depending on in what state the connection is. */ - switch(uip_connr->tcpstateflags & TS_MASK) { - /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not - implemented, since we force the application to close when the - peer sends a FIN (hence the application goes directly from - ESTABLISHED to LAST_ACK). */ - case SYN_RCVD: - /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and - we are waiting for an ACK that acknowledges the data we sent - out the last time. Therefore, we want to have the UIP_ACKDATA - flag set. If so, we enter the ESTABLISHED state. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = ESTABLISHED; - uip_flags = UIP_CONNECTED; - uip_connr->len = 0; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } - uip_slen = 0; - UIP_APPCALL(); - goto appsend; - } - goto drop; -#if UIP_ACTIVE_OPEN - case 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_SYN | TCP_ACK)) { - - /* Parse the TCP MSS option, if present. */ - if((BUF->tcpoffset & 0xf0) > 0x50) { - for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { - opt = uip_buf[40 + UIP_LLH_LEN + c]; - if(opt == 0x00) { - /* End of options. */ - break; - } else if(opt == 0x01) { - ++c; - /* NOP option. */ - } else if(opt == 0x02 && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) { - /* 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 = 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; - } - goto reset; -#endif /* UIP_ACTIVE_OPEN */ - - case ESTABLISHED: - /* In the ESTABLISHED state, we call upon the application to feed - data into the uip_buf. If the UIP_ACKDATA flag is set, the - application should put new data into the buffer, otherwise we are - retransmitting an old segment, and the application should put that - data into the buffer. - - If the incoming packet is a FIN, we should close the connection on - 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) { - if(uip_outstanding(uip_connr)) { - goto drop; - } - uip_add_rcv_nxt(1 + uip_len); - uip_flags = UIP_CLOSE; - if(uip_len > 0) { - uip_flags |= UIP_NEWDATA; - } - UIP_APPCALL(); - uip_connr->len = 1; - uip_connr->tcpstateflags = LAST_ACK; - uip_connr->nrtx = 0; - tcp_send_finack: - BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* Check the URG flag. If this is set, the segment carries urgent - data that we must pass to the application. */ - if(BUF->flags & TCP_URG) { -#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; -#endif /* UIP_URGDATA > 0 */ - uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1]; - uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1]; - } - - - /* If uip_len > 0 we have TCP data in the packet, and we flag this - by setting the UIP_NEWDATA flag and update the sequence number - 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)) { - uip_flags |= UIP_NEWDATA; - uip_add_rcv_nxt(uip_len); - } - - /* Check if the available buffer space advertised by the other end - is smaller than the initial MSS for this connection. If so, we - set the current MSS to the window size to ensure that the - application does not send more data than the other end can - handle. - - If the remote host advertises a zero window, we set the MSS to - the initial MSS so that the application will send an entire MSS - of data. This data will not be acknowledged by the receiver, - 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]; - if(tmp16 > uip_connr->initialmss || - tmp16 == 0) { - tmp16 = uip_connr->initialmss; - } - uip_connr->mss = tmp16; - - /* If this packet constitutes an ACK for outstanding data (flagged - by the UIP_ACKDATA flag, we should call the application since it - might want to send more data. If the incoming packet had data - from the peer (as flagged by the UIP_NEWDATA flag), the - application must also be notified. - - When the application is called, the global variable uip_len - contains the length of the incoming data. The application can - access the incoming data through the global pointer - uip_appdata, which usually points 40 bytes into the uip_buf - array. - - If the application wishes to send any data, this data should be - 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)) { - uip_slen = 0; - UIP_APPCALL(); - - appsend: - - if(uip_flags & UIP_ABORT) { - uip_slen = 0; - uip_connr->tcpstateflags = CLOSED; - BUF->flags = TCP_RST | TCP_ACK; - goto tcp_send_nodata; - } - - if(uip_flags & UIP_CLOSE) { - uip_slen = 0; - uip_connr->len = 1; - uip_connr->tcpstateflags = FIN_WAIT_1; - uip_connr->nrtx = 0; - BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; - } - - /* If uip_slen > 0, the application has data to be sent. */ - if(uip_slen > 0) { - - /* If the connection has acknowledged data, the contents of - the ->len variable should be discarded. */ - if((uip_flags & UIP_ACKDATA) != 0) { - uip_connr->len = 0; - } - - /* If the ->len variable is non-zero the connection has - already data in transit and cannot send anymore right - now. */ - if(uip_connr->len == 0) { - - /* The application cannot send more than what is allowed by - the mss (the minumum of the MSS and the available - window). */ - if(uip_slen > uip_connr->mss) { - uip_slen = uip_connr->mss; - } - - /* Remember how much data we send out now so that we know - when everything has been acknowledged. */ - uip_connr->len = uip_slen; - } else { - - /* If the application already had unacknowledged data, we - make sure that the application does not send (i.e., - retransmit) out more than it previously sent out. */ - uip_slen = uip_connr->len; - } - } else { - uip_connr->len = 0; - } - uip_connr->nrtx = 0; - apprexmit: - uip_appdata = uip_sappdata; - - /* If the application has data to be sent, or if the incoming - packet had new data in it, we must send out a packet. */ - if(uip_slen > 0 && uip_connr->len > 0) { - /* Add the length of the IP and TCP headers. */ - uip_len = uip_connr->len + UIP_TCPIP_HLEN; - /* We always set the ACK flag in response packets. */ - BUF->flags = TCP_ACK | TCP_PSH; - /* Send the packet. */ - goto tcp_send_noopts; - } - /* If there is no data to send, just send out a pure ACK if - there is newdata. */ - if(uip_flags & UIP_NEWDATA) { - uip_len = UIP_TCPIP_HLEN; - BUF->flags = TCP_ACK; - goto tcp_send_noopts; - } - } - goto drop; - case LAST_ACK: - /* We can close this connection if the peer has acknowledged our - FIN. This is indicated by the UIP_ACKDATA flag. */ - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = CLOSED; - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - } - break; - - case 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. */ - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(BUF->flags & TCP_FIN) { - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = TIME_WAIT; - uip_connr->timer = 0; - uip_connr->len = 0; - } else { - uip_connr->tcpstateflags = CLOSING; - } - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } else if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = FIN_WAIT_2; - uip_connr->len = 0; - goto drop; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case FIN_WAIT_2: - if(uip_len > 0) { - uip_add_rcv_nxt(uip_len); - } - if(BUF->flags & TCP_FIN) { - uip_connr->tcpstateflags = TIME_WAIT; - uip_connr->timer = 0; - uip_add_rcv_nxt(1); - uip_flags = UIP_CLOSE; - UIP_APPCALL(); - goto tcp_send_ack; - } - if(uip_len > 0) { - goto tcp_send_ack; - } - goto drop; - - case TIME_WAIT: - goto tcp_send_ack; - - case CLOSING: - if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = TIME_WAIT; - uip_connr->timer = 0; - } - } - goto drop; - - - /* We jump here when we are ready to send the packet, and just want - to set the appropriate TCP sequence numbers in the TCP header. */ - tcp_send_ack: - BUF->flags = TCP_ACK; - tcp_send_nodata: - uip_len = 40; - tcp_send_noopts: - BUF->tcpoffset = 5 << 4; - tcp_send: - /* We're done with the input processing. We are now ready to send a - reply. Our job is to fill in all the fields of the TCP and IP - headers before calculating the checksum and finally send the - packet. */ - 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->proto = UIP_PROTO_TCP; - - BUF->srcport = uip_connr->lport; - BUF->destport = uip_connr->rport; - - BUF->srcipaddr[0] = uip_hostaddr[0]; - BUF->srcipaddr[1] = uip_hostaddr[1]; - BUF->destipaddr[0] = uip_connr->ripaddr[0]; - BUF->destipaddr[1] = uip_connr->ripaddr[1]; - - - 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; - } else { - BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); - BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); - } - - tcp_send_noconn: - - BUF->len[0] = (uip_len >> 8); - BUF->len[1] = (uip_len & 0xff); - - /* Calculate TCP checksum. */ - BUF->tcpchksum = 0; - BUF->tcpchksum = ~(uip_tcpchksum()); - - ip_send_nolen: - - BUF->vhl = 0x45; - BUF->tos = 0; - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - BUF->ttl = UIP_TTL; - ++ipid; - BUF->ipid[0] = ipid >> 8; - BUF->ipid[1] = ipid & 0xff; - - /* Calculate IP checksum. */ - BUF->ipchksum = 0; - BUF->ipchksum = ~(uip_ipchksum()); - - UIP_STAT(++uip_stat.tcp.sent); - send: - UIP_STAT(++uip_stat.ip.sent); - /* Return and let the caller do the actual transmission. */ - return; - drop: - uip_len = 0; - return; -} -/** @} */ diff --git a/src/proto/uip/uip.h b/src/proto/uip/uip.h deleted file mode 100644 index 60dd7351..00000000 --- a/src/proto/uip/uip.h +++ /dev/null @@ -1,1060 +0,0 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \file - * Header file for the uIP TCP/IP stack. - * \author Adam Dunkels - * - * The uIP TCP/IP stack header file contains definitions for a number - * of C macros that are used by uIP programs as well as internal uIP - * structures, TCP/IP header structures and function declarations. - * - */ - - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. 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. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id$ - * - */ - -#ifndef __UIP_H__ -#define __UIP_H__ - -#include "uipopt.h" - -/*-----------------------------------------------------------------------------------*/ -/* First, the functions that should be called from the - * system. Initialization, the periodic timer and incoming packets are - * handled by the following three functions. - */ - -/** - * \defgroup uipconffunc uIP configuration functions - * @{ - * - * The uIP configuration functions are used for setting run-time - * parameters in uIP such as IP addresses. - */ - -/** - * Set the IP address of this host. - * - * The IP address is represented as a 4-byte array where the first - * octet of the IP address is put in the first member of the 4-byte - * array. - * - * \param addr A pointer to a 4-byte representation of the IP address. - * - * \hideinitializer - */ -#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \ - uip_hostaddr[1] = addr[1]; } while(0) - -/** - * Get the IP address of this host. - * - * The IP address is represented as a 4-byte array where the first - * octet of the IP address is put in the first member of the 4-byte - * array. - * - * \param addr A pointer to a 4-byte array that will be filled in with - * the currently configured IP address. - * - * \hideinitializer - */ -#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \ - addr[1] = uip_hostaddr[1]; } while(0) - -/** @} */ - -/** - * \defgroup uipinit uIP initialization functions - * @{ - * - * The uIP initialization functions are used for booting uIP. - */ - -/** - * uIP initialization function. - * - * This function should be called at boot up to initilize the uIP - * TCP/IP stack. - */ -void uip_init(void); - -/** @} */ - -/** - * \defgroup uipdevfunc uIP device driver functions - * @{ - * - * These functions are used by a network device driver for interacting - * with uIP. - */ - -/** - * Process an incoming packet. - * - * This function should be called when the device driver has received - * a packet from the network. The packet from the device driver must - * be present in the uip_buf buffer, and the length of the packet - * should be placed in the uip_len variable. - * - * When the function returns, there may be an outbound packet placed - * in the uip_buf packet buffer. If so, the uip_len variable is set to - * the length of the packet. If no packet is to be sent out, the - * uip_len variable is set to 0. - * - * The usual way of calling the function is presented by the source - * code below. - \code - uip_len = devicedriver_poll(); - if(uip_len > 0) { - uip_input(); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note If you are writing a uIP device driver that needs ARP - * (Address Resolution Protocol), e.g., when running uIP over - * Ethernet, you will need to call the uIP ARP code before calling - * this function: - \code - #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) - uip_len = ethernet_devicedrver_poll(); - if(uip_len > 0) { - if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { - uip_arp_ipin(); - uip_input(); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { - uip_arp_arpin(); - if(uip_len > 0) { - ethernet_devicedriver_send(); - } - } - \endcode - * - * \hideinitializer - */ -#define uip_input() uip_process(UIP_DATA) - -/** - * Periodic processing for a connection identified by its number. - * - * This function does the necessary periodic processing (timers, - * polling) for a uIP TCP conneciton, and should be called when the - * periodic uIP timer goes off. It should be called for every - * connection, regardless of whether they are open of closed. - * - * When the function returns, it may have an outbound packet waiting - * for service in the uIP packet buffer, and if so the uip_len - * variable is set to a value larger than zero. The device driver - * should be called to send out the packet. - * - * The ususal way of calling the function is through a for() loop like - * this: - \code - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note If you are writing a uIP device driver that needs ARP - * (Address Resolution Protocol), e.g., when running uIP over - * Ethernet, you will need to call the uip_arp_out() function before - * calling the device driver: - \code - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } - \endcode - * - * \param conn The number of the connection which is to be periodically polled. - * - * \hideinitializer - */ -#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \ - uip_process(UIP_TIMER); } while (0) - -/** - * Periodic processing for a connection identified by a pointer to its structure. - * - * Same as uip_periodic() but takes a pointer to the actual uip_conn - * struct instead of an integer as its argument. This function can be - * used to force periodic processing of a specific connection. - * - * \param conn A pointer to the uip_conn struct for the connection to - * be processed. - * - * \hideinitializer - */ -#define uip_periodic_conn(conn) do { uip_conn = conn; \ - uip_process(UIP_TIMER); } while (0) - -#if UIP_UDP -/** - * Periodic processing for a UDP connection identified by its number. - * - * This function is essentially the same as uip_prerioic(), but for - * UDP connections. It is called in a similar fashion as the - * uip_periodic() function: - \code - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - devicedriver_send(); - } - } - \endcode - * - * \note As for the uip_periodic() function, special care has to be - * taken when using uIP together with ARP and Ethernet: - \code - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } - \endcode - * - * \param conn The number of the UDP connection to be processed. - * - * \hideinitializer - */ -#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \ - uip_process(UIP_UDP_TIMER); } while (0) - -/** - * Periodic processing for a UDP connection identified by a pointer to - * its structure. - * - * Same as uip_udp_periodic() but takes a pointer to the actual - * uip_conn struct instead of an integer as its argument. This - * function can be used to force periodic processing of a specific - * connection. - * - * \param conn A pointer to the uip_udp_conn struct for the connection - * to be processed. - * - * \hideinitializer - */ -#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \ - uip_process(UIP_UDP_TIMER); } while (0) - - -#endif /* UIP_UDP */ - -/** - * The uIP packet buffer. - * - * The uip_buf array is used to hold incoming and outgoing - * packets. The device driver should place incoming data into this - * buffer. When sending data, the device driver should read the link - * level headers and the TCP/IP headers from this buffer. The size of - * the link level headers is configured by the UIP_LLH_LEN define. - * - * \note The application data need not be placed in this buffer, so - * the device driver must read it from the place pointed to by the - * uip_appdata pointer as illustrated by the following example: - \code - void - devicedriver_send(void) - { - hwsend(&uip_buf[0], UIP_LLH_LEN); - hwsend(&uip_buf[UIP_LLH_LEN], 40); - hwsend(uip_appdata, uip_len - 40 - UIP_LLH_LEN); - } - \endcode - */ -extern u8_t uip_buf[UIP_BUFSIZE+2]; - -/** @} */ - -/*-----------------------------------------------------------------------------------*/ -/* Functions that are used by the uIP application program. Opening and - * closing connections, sending and receiving data, etc. is all - * handled by the functions below. -*/ -/** - * \defgroup uipappfunc uIP application functions - * @{ - * - * Functions used by an application running of top of uIP. - */ - -/** - * Start listening to the specified port. - * - * \note Since this function expects the port number in network byte - * order, a conversion using HTONS() or htons() is necessary. - * - \code - uip_listen(HTONS(80)); - \endcode - * - * \param port A 16-bit port number in network byte order. - */ -void uip_listen(u16_t port); - -/** - * Stop listening to the specified port. - * - * \note Since this function expects the port number in network byte - * order, a conversion using HTONS() or htons() is necessary. - * - \code - uip_unlisten(HTONS(80)); - \endcode - * - * \param port A 16-bit port number in network byte order. - */ -void uip_unlisten(u16_t port); - -/** - * Connect to a remote host using TCP. - * - * This function is used to start a new connection to the specified - * port on the specied host. It allocates a new connection identifier, - * sets the connection to the SYN_SENT state and sets the - * retransmission timer to 0. This will cause a TCP SYN segment to be - * sent out the next time this connection is periodically processed, - * which usually is done within 0.5 seconds after the call to - * uip_connect(). - * - * \note This function is avaliable only if support for active open - * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h. - * - * \note Since this function requires the port number to be in network - * byte order, a convertion using HTONS() or htons() is necessary. - * - \code - u16_t ipaddr[2]; - - uip_ipaddr(ipaddr, 192,168,1,2); - uip_connect(ipaddr, HTONS(80)); - \endcode - * - * \param ripaddr A pointer to a 4-byte array representing the IP - * address of the remote hot. - * - * \param port A 16-bit port number in network byte order. - * - * \return A pointer to the uIP connection identifier for the new connection, - * or NULL if no connection could be allocated. - * - */ -struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port); - - - -/** - * \internal - * - * Check if a connection has outstanding (i.e., unacknowledged) data. - * - * \param conn A pointer to the uip_conn structure for the connection. - * - * \hideinitializer - */ -#define uip_outstanding(conn) ((conn)->len) - -/** - * Send data on the current connection. - * - * This function is used to send out a single segment of TCP - * data. Only applications that have been invoked by uIP for event - * processing can send data. - * - * The amount of data that actually is sent out after a call to this - * funcion is determined by the maximum amount of data TCP allows. uIP - * will automatically crop the data so that only the appropriate - * amount of data is sent. The function uip_mss() can be used to query - * uIP for the amount of data that actually will be sent. - * - * \note This function does not guarantee that the sent data will - * arrive at the destination. If the data is lost in the network, the - * application will be invoked with the uip_rexmit() event being - * set. The application will then have to resend the data using this - * function. - * - * \param data A pointer to the data which is to be sent. - * - * \param len The maximum amount of data bytes to be sent. - * - * \hideinitializer - */ -#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0) - -/** - * The length of any incoming data that is currently avaliable (if avaliable) - * in the uip_appdata buffer. - * - * The test function uip_data() must first be used to check if there - * is any data available at all. - * - * \hideinitializer - */ -#define uip_datalen() uip_len - -/** - * The length of any out-of-band data (urgent data) that has arrived - * on the connection. - * - * \note The configuration parameter UIP_URGDATA must be set for this - * function to be enabled. - * - * \hideinitializer - */ -#define uip_urgdatalen() uip_urglen - -/** - * Close the current connection. - * - * This function will close the current connection in a nice way. - * - * \hideinitializer - */ -#define uip_close() (uip_flags = UIP_CLOSE) - -/** - * Abort the current connection. - * - * This function will abort (reset) the current connection, and is - * usually used when an error has occured that prevents using the - * uip_close() function. - * - * \hideinitializer - */ -#define uip_abort() (uip_flags = UIP_ABORT) - -/** - * Tell the sending host to stop sending data. - * - * This function will close our receiver's window so that we stop - * receiving data for the current connection. - * - * \hideinitializer - */ -#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED) - -/** - * Find out if the current connection has been previously stopped with - * uip_stop(). - * - * \hideinitializer - */ -#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED) - -/** - * Restart the current connection, if is has previously been stopped - * with uip_stop(). - * - * This function will open the receiver's window again so that we - * start receiving data for the current connection. - * - * \hideinitializer - */ -#define uip_restart() do { uip_flags |= UIP_NEWDATA; \ - uip_conn->tcpstateflags &= ~UIP_STOPPED; \ - } while(0) - - -/* uIP tests that can be made to determine in what state the current - connection is, and what the application function should do. */ - -/** - * Is new incoming data available? - * - * Will reduce to non-zero if there is new data for the application - * present at the uip_appdata pointer. The size of the data is - * avaliable through the uip_len variable. - * - * \hideinitializer - */ -#define uip_newdata() (uip_flags & UIP_NEWDATA) - -/** - * Has previously sent data been acknowledged? - * - * Will reduce to non-zero if the previously sent data has been - * acknowledged by the remote host. This means that the application - * can send new data. - * - * \hideinitializer - */ -#define uip_acked() (uip_flags & UIP_ACKDATA) - -/** - * Has the connection just been connected? - * - * Reduces to non-zero if the current connection has been connected to - * a remote host. This will happen both if the connection has been - * actively opened (with uip_connect()) or passively opened (with - * uip_listen()). - * - * \hideinitializer - */ -#define uip_connected() (uip_flags & UIP_CONNECTED) - -/** - * Has the connection been closed by the other end? - * - * Is non-zero if the connection has been closed by the remote - * host. The application may then do the necessary clean-ups. - * - * \hideinitializer - */ -#define uip_closed() (uip_flags & UIP_CLOSE) - -/** - * Has the connection been aborted by the other end? - * - * Non-zero if the current connection has been aborted (reset) by the - * remote host. - * - * \hideinitializer - */ -#define uip_aborted() (uip_flags & UIP_ABORT) - -/** - * Has the connection timed out? - * - * Non-zero if the current connection has been aborted due to too many - * retransmissions. - * - * \hideinitializer - */ -#define uip_timedout() (uip_flags & UIP_TIMEDOUT) - -/** - * Do we need to retransmit previously data? - * - * Reduces to non-zero if the previously sent data has been lost in - * the network, and the application should retransmit it. The - * application should send the exact same data as it did the last - * time, using the uip_send() function. - * - * \hideinitializer - */ -#define uip_rexmit() (uip_flags & UIP_REXMIT) - -/** - * Is the connection being polled by uIP? - * - * Is non-zero if the reason the application is invoked is that the - * current connection has been idle for a while and should be - * polled. - * - * The polling event can be used for sending data without having to - * wait for the remote host to send data. - * - * \hideinitializer - */ -#define uip_poll() (uip_flags & UIP_POLL) - -/** - * Get the initial maxium segment size (MSS) of the current - * connection. - * - * \hideinitializer - */ -#define uip_initialmss() (uip_conn->initialmss) - -/** - * Get the current maxium segment size that can be sent on the current - * connection. - * - * The current maxiumum segment size that can be sent on the - * connection is computed from the receiver's window and the MSS of - * the connection (which also is available by calling - * uip_initialmss()). - * - * \hideinitializer - */ -#define uip_mss() (uip_conn->mss) - -/** - * Set up a new UDP connection. - * - * \param ripaddr A pointer to a 4-byte structure representing the IP - * address of the remote host. - * - * \param rport The remote port number in network byte order. - * - * \return The uip_udp_conn structure for the new connection or NULL - * if no connection could be allocated. - */ -struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport); - -/** - * Removed a UDP connection. - * - * \param conn A pointer to the uip_udp_conn structure for the connection. - * - * \hideinitializer - */ -#define uip_udp_remove(conn) (conn)->lport = 0 - -/** - * Send a UDP datagram of length len on the current connection. - * - * This function can only be called in response to a UDP event (poll - * or newdata). The data must be present in the uip_buf buffer, at the - * place pointed to by the uip_appdata pointer. - * - * \param len The length of the data in the uip_buf buffer. - * - * \hideinitializer - */ -#define uip_udp_send(len) uip_slen = (len) - -/** @} */ - -/* uIP convenience and converting functions. */ - -/** - * \defgroup uipconvfunc uIP conversion functions - * @{ - * - * These functions can be used for converting between different data - * formats used by uIP. - */ - -/** - * Pack an IP address into a 4-byte array which is used by uIP to - * represent IP addresses. - * - * Example: - \code - u16_t ipaddr[2]; - - uip_ipaddr(&ipaddr, 192,168,1,2); - \endcode - * - * \param addr A pointer to a 4-byte array that will be filled in with - * the IP addres. - * \param addr0 The first octet of the IP address. - * \param addr1 The second octet of the IP address. - * \param addr2 The third octet of the IP address. - * \param addr3 The forth octet of the IP address. - * - * \hideinitializer - */ -#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ - (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \ - (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \ - } while(0) - -/** - * Convert 16-bit quantity from host byte order to network byte order. - * - * This macro is primarily used for converting constants from host - * byte order to network byte order. For converting variables to - * network byte order, use the htons() function instead. - * - * \hideinitializer - */ -#ifndef HTONS -# if BYTE_ORDER == BIG_ENDIAN -# define HTONS(n) (n) -# else /* BYTE_ORDER == BIG_ENDIAN */ -# define HTONS(n) ((((u16_t)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8)) -# endif /* BYTE_ORDER == BIG_ENDIAN */ -#endif /* HTONS */ - -/** - * Convert 16-bit quantity from host byte order to network byte order. - * - * This function is primarily used for converting variables from host - * byte order to network byte order. For converting constants to - * network byte order, use the HTONS() macro instead. - */ -#ifndef htons -u16_t htons(u16_t val); -#endif /* htons */ - -/** @} */ - -/** - * Pointer to the application data in the packet buffer. - * - * This pointer points to the application data when the application is - * called. If the application wishes to send data, the application may - * use this space to write the data into before calling uip_send(). - */ -extern volatile u8_t *uip_appdata; -extern volatile u8_t *uip_sappdata; - -#if UIP_URGDATA > 0 -/* u8_t *uip_urgdata: - * - * This pointer points to any urgent data that has been received. Only - * present if compiled with support for urgent data (UIP_URGDATA). - */ -extern volatile u8_t *uip_urgdata; -#endif /* UIP_URGDATA > 0 */ - - -/* u[8|16]_t uip_len: - * - * When the application is called, uip_len contains the length of any - * new data that has been received from the remote host. The - * application should set this variable to the size of any data that - * the application wishes to send. When the network device driver - * output function is called, uip_len should contain the length of the - * outgoing packet. - */ -extern volatile u16_t uip_len, uip_slen; - -#if UIP_URGDATA > 0 -extern volatile u8_t uip_urglen, uip_surglen; -#endif /* UIP_URGDATA > 0 */ - - -/** - * Representation of a uIP TCP connection. - * - * The uip_conn structure is used for identifying a connection. All - * but one field in the structure are to be considered read-only by an - * application. The only exception is the appstate field whos purpose - * is to let the application store application-specific state (e.g., - * file pointers) for the connection. The size of this field is - * configured in the "uipopt.h" header file. - */ -struct uip_conn { - u16_t ripaddr[2]; /**< The IP address of the remote host. */ - - u16_t lport; /**< The local TCP port, in network byte order. */ - u16_t rport; /**< The local remote TCP port, in network byte - order. */ - - u8_t rcv_nxt[4]; /**< The sequence number that we expect to - receive next. */ - u8_t snd_nxt[4]; /**< The sequence number that was last sent by - us. */ - u16_t len; /**< Length of the data that was previously sent. */ - u16_t mss; /**< Current maximum segment size for the - connection. */ - u16_t initialmss; /**< Initial maximum segment size for the - connection. */ - u8_t sa; /**< Retransmission time-out calculation state - variable. */ - u8_t sv; /**< Retransmission time-out calculation state - variable. */ - u8_t rto; /**< Retransmission time-out. */ - u8_t tcpstateflags; /**< TCP state and flags. */ - u8_t timer; /**< The retransmission timer. */ - u8_t nrtx; /**< The number of retransmissions for the last - segment sent. */ - - /** The application state. */ - u8_t appstate[UIP_APPSTATE_SIZE]; -}; - - -/* Pointer to the current connection. */ -extern struct uip_conn *uip_conn; -/* The array containing all uIP connections. */ -extern struct uip_conn uip_conns[UIP_CONNS]; -/** - * \addtogroup uiparch - * @{ - */ - -/** - * 4-byte array used for the 32-bit sequence number calculations. - */ -extern volatile u8_t uip_acc32[4]; - -/** @} */ - - -#if UIP_UDP -/** - * Representation of a uIP UDP connection. - */ -struct uip_udp_conn { - u16_t ripaddr[2]; /**< The IP address of the remote peer. */ - u16_t lport; /**< The local port number in network byte order. */ - u16_t rport; /**< The remote port number in network byte order. */ -}; - -extern struct uip_udp_conn *uip_udp_conn; -extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; -#endif /* UIP_UDP */ - -/** - * The structure holding the TCP/IP statistics that are gathered if - * UIP_STATISTICS is set to 1. - * - */ -struct uip_stats { - struct { - uip_stats_t drop; /**< Number of dropped packets at the IP - layer. */ - uip_stats_t recv; /**< Number of received packets at the IP - layer. */ - uip_stats_t sent; /**< Number of sent packets at the IP - layer. */ - uip_stats_t vhlerr; /**< Number of packets dropped due to wrong - IP version or header length. */ - uip_stats_t hblenerr; /**< Number of packets dropped due to wrong - IP length, high byte. */ - uip_stats_t lblenerr; /**< Number of packets dropped due to wrong - IP length, low byte. */ - uip_stats_t fragerr; /**< Number of packets dropped since they - were IP fragments. */ - uip_stats_t chkerr; /**< Number of packets dropped due to IP - checksum errors. */ - uip_stats_t protoerr; /**< Number of packets dropped since they - were neither ICMP, UDP nor TCP. */ - } ip; /**< IP statistics. */ - struct { - uip_stats_t drop; /**< Number of dropped ICMP packets. */ - uip_stats_t recv; /**< Number of received ICMP packets. */ - uip_stats_t sent; /**< Number of sent ICMP packets. */ - uip_stats_t typeerr; /**< Number of ICMP packets with a wrong - type. */ - } icmp; /**< ICMP statistics. */ - struct { - uip_stats_t drop; /**< Number of dropped TCP segments. */ - uip_stats_t recv; /**< Number of recived TCP segments. */ - uip_stats_t sent; /**< Number of sent TCP segments. */ - uip_stats_t chkerr; /**< Number of TCP segments with a bad - checksum. */ - uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK - number. */ - uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */ - uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */ - uip_stats_t syndrop; /**< Number of dropped SYNs due to too few - connections was avaliable. */ - uip_stats_t synrst; /**< Number of SYNs for closed ports, - triggering a RST. */ - } tcp; /**< TCP statistics. */ -}; - -/** - * The uIP TCP/IP statistics. - * - * This is the variable in which the uIP TCP/IP statistics are gathered. - */ -extern struct uip_stats uip_stat; - - -/*-----------------------------------------------------------------------------------*/ -/* All the stuff below this point is internal to uIP and should not be - * used directly by an application or by a device driver. - */ -/*-----------------------------------------------------------------------------------*/ -/* u8_t uip_flags: - * - * When the application is called, uip_flags will contain the flags - * that are defined in this file. Please read below for more - * infomation. - */ -extern volatile u8_t uip_flags; - -/* The following flags may be set in the global variable uip_flags - before calling the application callback. The UIP_ACKDATA and - UIP_NEWDATA flags may both be set at the same time, whereas the - others are mutualy exclusive. Note that these flags should *NOT* be - accessed directly, but through the uIP functions/macros. */ - -#define UIP_ACKDATA 1 /* Signifies that the outstanding data was - acked and the application should send - out new data instead of retransmitting - the last data. */ -#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent - us new data. */ -#define UIP_REXMIT 4 /* Tells the application to retransmit the - data that was last sent. */ -#define UIP_POLL 8 /* Used for polling the application, to - check if the application has data that - it wants to send. */ -#define UIP_CLOSE 16 /* The remote host has closed the - connection, thus the connection has - gone away. Or the application signals - that it wants to close the - connection. */ -#define UIP_ABORT 32 /* The remote host has aborted the - connection, thus the connection has - gone away. Or the application signals - that it wants to abort the - connection. */ -#define UIP_CONNECTED 64 /* We have got a connection from a remote - host and have set up a new connection - for it, or an active connection has - been successfully established. */ - -#define UIP_TIMEDOUT 128 /* The connection has been aborted due to - too many retransmissions. */ - - -/* uip_process(flag): - * - * The actual uIP function which does all the work. - */ -void uip_process(u8_t flag); - -/* The following flags are passed as an argument to the uip_process() - function. They are used to distinguish between the two cases where - uip_process() is called. It can be called either because we have - incoming data that should be processed, or because the periodic - timer has fired. */ - -#define UIP_DATA 1 /* Tells uIP that there is incoming data in - the uip_buf buffer. The length of the - data is stored in the global variable - uip_len. */ -#define UIP_TIMER 2 /* Tells uIP that the periodic timer has - fired. */ -#if UIP_UDP -#define UIP_UDP_TIMER 3 -#endif /* UIP_UDP */ - -/* The TCP states used in the uip_conn->tcpstateflags. */ -#define CLOSED 0 -#define SYN_RCVD 1 -#define SYN_SENT 2 -#define ESTABLISHED 3 -#define FIN_WAIT_1 4 -#define FIN_WAIT_2 5 -#define CLOSING 6 -#define TIME_WAIT 7 -#define LAST_ACK 8 -#define TS_MASK 15 - -#define UIP_STOPPED 16 - -#define UIP_TCPIP_HLEN 40 - -/* The TCP and IP headers. */ -typedef struct { - /* IP header. */ - u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; - - /* TCP header. */ - u16_t srcport, - destport; - u8_t seqno[4], - ackno[4], - tcpoffset, - flags, - wnd[2]; - u16_t tcpchksum; - u8_t urgp[2]; - u8_t optdata[4]; -} uip_tcpip_hdr; - -/* The ICMP and IP headers. */ -typedef struct { - /* IP header. */ - u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; - /* ICMP (echo) header. */ - u8_t type, icode; - u16_t icmpchksum; - u16_t id, seqno; -} uip_icmpip_hdr; - - -/* The UDP and IP headers. */ -typedef struct { - /* IP header. */ - u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; - - /* UDP header. */ - u16_t srcport, - destport; - u16_t udplen; - u16_t udpchksum; -} uip_udpip_hdr; - -#define UIP_PROTO_ICMP 1 -#define UIP_PROTO_TCP 6 -#define UIP_PROTO_UDP 17 - -#if UIP_FIXEDADDR -extern const u16_t uip_hostaddr[2]; -#else /* UIP_FIXEDADDR */ -extern u16_t uip_hostaddr[2]; -#endif /* UIP_FIXEDADDR */ - -#endif /* __UIP_H__ */ - - -/** @} */ - diff --git a/src/proto/uip/uip_arch.c b/src/proto/uip/uip_arch.c deleted file mode 100644 index 421d6506..00000000 --- a/src/proto/uip/uip_arch.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include "uip_arch.h" -#include "uip.h" - -volatile u8_t uip_acc32[4]; - -void uip_add32 ( u8_t *op32, u16_t op16 ) { - * ( ( uint32_t * ) uip_acc32 ) = - htonl ( ntohl ( *( ( uint32_t * ) op32 ) ) + op16 ); -} - -#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define IP_PROTO_TCP 6 - -u16_t uip_chksum(u16_t *sdata, u16_t len) { - u16_t acc; - - for(acc = 0; len > 1; len -= 2) { - acc += *sdata; - if(acc < *sdata) { - /* Overflow, so we add the carry to acc (i.e., increase by - one). */ - ++acc; - } - ++sdata; - } - - /* add up any odd byte */ - if(len == 1) { - acc += htons(((u16_t)(*(u8_t *)sdata)) << 8); - if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) { - ++acc; - } - } - - return acc; -} - -u16_t uip_ipchksum(void) { - return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20); -} - -u16_t uip_tcpchksum(void) { - u16_t hsum, sum; - - - /* Compute the checksum of the TCP header. */ - hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20); - - /* Compute the checksum of the data in the TCP packet and add it to - the TCP header checksum. */ - sum = uip_chksum((u16_t *)uip_appdata, - (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40))); - - if((sum += hsum) < hsum) { - ++sum; - } - - if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) { - ++sum; - } - if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) { - ++sum; - } - if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) { - ++sum; - } - if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) { - ++sum; - } - if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) { - ++sum; - } - - hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20); - - if((sum += hsum) < hsum) { - ++sum; - } - - return sum; -} diff --git a/src/proto/uip/uip_arch.h b/src/proto/uip/uip_arch.h deleted file mode 100644 index db71aeb2..00000000 --- a/src/proto/uip/uip_arch.h +++ /dev/null @@ -1,130 +0,0 @@ -/** - * \defgroup uiparch Architecture specific uIP functions - * @{ - * - * The functions in the architecture specific module implement the IP - * check sum and 32-bit additions. - * - * The IP checksum calculation is the most computationally expensive - * operation in the TCP/IP stack and it therefore pays off to - * implement this in efficient assembler. The purpose of the uip-arch - * module is to let the checksum functions to be implemented in - * architecture specific assembler. - * - */ - -/** - * \file - * Declarations of architecture specific functions. - * \author Adam Dunkels - */ - -/* - * Copyright (c) 2001, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. 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. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id$ - * - */ - -#ifndef __UIP_ARCH_H__ -#define __UIP_ARCH_H__ - -#include "uip.h" - -/** - * Carry out a 32-bit addition. - * - * Because not all architectures for which uIP is intended has native - * 32-bit arithmetic, uIP uses an external C function for doing the - * required 32-bit additions in the TCP protocol processing. This - * function should add the two arguments and place the result in the - * global variable uip_acc32. - * - * \note The 32-bit integer pointed to by the op32 parameter and the - * result in the uip_acc32 variable are in network byte order (big - * endian). - * - * \param op32 A pointer to a 4-byte array representing a 32-bit - * integer in network byte order (big endian). - * - * \param op16 A 16-bit integer in host byte order. - */ -void uip_add32(u8_t *op32, u16_t op16); - -/** - * Calculate the Internet checksum over a buffer. - * - * The Internet checksum is the one's complement of the one's - * complement sum of all 16-bit words in the buffer. - * - * See RFC1071. - * - * \note This function is not called in the current version of uIP, - * but future versions might make use of it. - * - * \param buf A pointer to the buffer over which the checksum is to be - * computed. - * - * \param len The length of the buffer over which the checksum is to - * be computed. - * - * \return The Internet checksum of the buffer. - */ -u16_t uip_chksum(u16_t *buf, u16_t len); - -/** - * Calculate the IP header checksum of the packet header in uip_buf. - * - * The IP header checksum is the Internet checksum of the 20 bytes of - * the IP header. - * - * \return The IP header checksum of the IP header in the uip_buf - * buffer. - */ -u16_t uip_ipchksum(void); - -/** - * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. - * - * The TCP checksum is the Internet checksum of data contents of the - * TCP segment, and a pseudo-header as defined in RFC793. - * - * \note The uip_appdata pointer that points to the packet data may - * point anywhere in memory, so it is not possible to simply calculate - * the Internet checksum of the contents of the uip_buf buffer. - * - * \return The TCP checksum of the TCP segment in uip_buf and pointed - * to by uip_appdata. - */ -u16_t uip_tcpchksum(void); - -/** @} */ - -#endif /* __UIP_ARCH_H__ */ diff --git a/src/proto/uip/uipopt.h b/src/proto/uip/uipopt.h deleted file mode 100644 index 70dd90ca..00000000 --- a/src/proto/uip/uipopt.h +++ /dev/null @@ -1,572 +0,0 @@ -/** - * \defgroup uipopt Configuration options for uIP - * @{ - * - * uIP is configured using the per-project configuration file - * "uipopt.h". This file contains all compile-time options for uIP and - * should be tweaked to match each specific project. The uIP - * distribution contains a documented example "uipopt.h" that can be - * copied and modified for each project. - */ - -/** - * \file - * Configuration options for uIP. - * \author Adam Dunkels - * - * This file is used for tweaking various configuration options for - * uIP. You should make a copy of this file into one of your project's - * directories instead of editing this example "uipopt.h" file that - * comes with the uIP distribution. - */ - -/* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. 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. - * - * This file is part of the uIP TCP/IP stack. - * - * $Id$ - * - */ - -#ifndef __UIPOPT_H__ -#define __UIPOPT_H__ - -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipopttypedef uIP type definitions - * @{ - */ - -/** - * The 8-bit unsigned data type. - * - * This may have to be tweaked for your particular compiler. "unsigned - * char" works for most compilers. - */ -typedef unsigned char u8_t; - -/** - * The 16-bit unsigned data type. - * - * This may have to be tweaked for your particular compiler. "unsigned - * short" works for most compilers. - */ -typedef unsigned short u16_t; - -/** - * The statistics data type. - * - * This datatype determines how high the statistics counters are able - * to count. - */ -typedef unsigned short uip_stats_t; - -/** @} */ - -/*------------------------------------------------------------------------------*/ - -/** - * \defgroup uipoptstaticconf Static configuration options - * @{ - * - * These configuration options can be used for setting the IP address - * settings statically, but only if UIP_FIXEDADDR is set to 1. The - * configuration options for a specific node includes IP address, - * netmask and default router as well as the Ethernet address. The - * netmask, default router and Ethernet address are appliciable only - * if uIP should be run over Ethernet. - * - * All of these should be changed to suit your project. -*/ - -/** - * Determines if uIP should use a fixed IP address or not. - * - * If uIP should use a fixed IP address, the settings are set in the - * uipopt.h file. If not, the macros uip_sethostaddr(), - * uip_setdraddr() and uip_setnetmask() should be used instead. - * - * \hideinitializer - */ -#define UIP_FIXEDADDR 0 - -/** - * Ping IP address asignment. - * - * uIP uses a "ping" packets for setting its own IP address if this - * option is set. If so, uIP will start with an empty IP address and - * the destination IP address of the first incoming "ping" (ICMP echo) - * packet will be used for setting the hosts IP address. - * - * \note This works only if UIP_FIXEDADDR is 0. - * - * \hideinitializer - */ -#define UIP_PINGADDRCONF 0 - -#define UIP_IPADDR0 0 /**< The first octet of the IP address of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_IPADDR1 0 /**< The second octet of the IP address of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_IPADDR2 0 /**< The third octet of the IP address of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_IPADDR3 0 /**< The fourth octet of the IP address of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ - -#define UIP_NETMASK0 0 /**< The first octet of the netmask of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_NETMASK1 0 /**< The second octet of the netmask of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_NETMASK2 0 /**< The third octet of the netmask of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_NETMASK3 0 /**< The fourth octet of the netmask of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ - -#define UIP_DRIPADDR0 0 /**< The first octet of the IP address of - the default router, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_DRIPADDR1 0 /**< The second octet of the IP address of - the default router, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_DRIPADDR2 0 /**< The third octet of the IP address of - the default router, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_DRIPADDR3 0 /**< The fourth octet of the IP address of - the default router, if UIP_FIXEDADDR is - 1. \hideinitializer */ - -/** - * Specifies if the uIP ARP module should be compiled with a fixed - * Ethernet MAC address or not. - * - * If this configuration option is 0, the macro uip_setethaddr() can - * be used to specify the Ethernet address at run-time. - * - * \hideinitializer - */ -#define UIP_FIXEDETHADDR 0 - -#define UIP_ETHADDR0 0x00 /**< The first octet of the Ethernet - address if UIP_FIXEDETHADDR is - 1. \hideinitializer */ -#define UIP_ETHADDR1 0xbd /**< The second octet of the Ethernet - address if UIP_FIXEDETHADDR is - 1. \hideinitializer */ -#define UIP_ETHADDR2 0x3b /**< The third octet of the Ethernet - address if UIP_FIXEDETHADDR is - 1. \hideinitializer */ -#define UIP_ETHADDR3 0x33 /**< The fourth octet of the Ethernet - address if UIP_FIXEDETHADDR is - 1. \hideinitializer */ -#define UIP_ETHADDR4 0x05 /**< The fifth octet of the Ethernet - address if UIP_FIXEDETHADDR is - 1. \hideinitializer */ -#define UIP_ETHADDR5 0x71 /**< The sixth octet of the Ethernet - address if UIP_FIXEDETHADDR is - 1. \hideinitializer */ - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptip IP configuration options - * @{ - * - */ -/** - * The IP TTL (time to live) of IP packets sent by uIP. - * - * This should normally not be changed. - */ -#define UIP_TTL 255 - -/** - * Turn on support for IP packet reassembly. - * - * uIP supports reassembly of fragmented IP packets. This features - * requires an additonal amount of RAM to hold the reassembly buffer - * and the reassembly code size is approximately 700 bytes. The - * reassembly buffer is of the same size as the uip_buf buffer - * (configured by UIP_BUFSIZE). - * - * \note IP packet reassembly is not heavily tested. - * - * \hideinitializer - */ -#define UIP_REASSEMBLY 0 - -/** - * The maximum time an IP fragment should wait in the reassembly - * buffer before it is dropped. - * - */ -#define UIP_REASS_MAXAGE 40 - -/** @} */ - -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptudp UDP configuration options - * @{ - * - * \note The UDP support in uIP is still not entirely complete; there - * is no support for sending or receiving broadcast or multicast - * packets, but it works well enough to support a number of vital - * applications such as DNS queries, though - */ - -/** - * Toggles wether UDP support should be compiled in or not. - * - * \hideinitializer - */ -#define UIP_UDP 1 - -/** - * Toggles if UDP checksums should be used or not. - * - * \note Support for UDP checksums is currently not included in uIP, - * so this option has no function. - * - * \hideinitializer - */ -#define UIP_UDP_CHECKSUMS 0 - -/** - * The maximum amount of concurrent UDP connections. - * - * \hideinitializer - */ -#define UIP_UDP_CONNS 10 - -/** - * The name of the function that should be called when UDP datagrams arrive. - * - * \hideinitializer - */ -extern void uip_udp_appcall ( void ); -#define UIP_UDP_APPCALL uip_udp_appcall - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipopttcp TCP configuration options - * @{ - */ - -/** - * Determines if support for opening connections from uIP should be - * compiled in. - * - * If the applications that are running on top of uIP for this project - * do not need to open outgoing TCP connections, this configration - * option can be turned off to reduce the code size of uIP. - * - * \hideinitializer - */ -#define UIP_ACTIVE_OPEN 1 - -/** - * The maximum number of simultaneously open TCP connections. - * - * Since the TCP connections are statically allocated, turning this - * configuration knob down results in less RAM used. Each TCP - * connection requires approximatly 30 bytes of memory. - * - * \hideinitializer - */ -#define UIP_CONNS 10 - -/** - * The maximum number of simultaneously listening TCP ports. - * - * Each listening TCP port requires 2 bytes of memory. - * - * \hideinitializer - */ -#define UIP_LISTENPORTS 10 - -/** - * The size of the advertised receiver's window. - * - * Should be set low (i.e., to the size of the uip_buf buffer) is the - * application is slow to process incoming data, or high (32768 bytes) - * if the application processes data quickly. - * - * \hideinitializer - */ -#define UIP_RECEIVE_WINDOW 32768 - -/** - * Determines if support for TCP urgent data notification should be - * compiled in. - * - * Urgent data (out-of-band data) is a rarely used TCP feature that - * very seldom would be required. - * - * \hideinitializer - */ -#define UIP_URGDATA 1 - -/** - * The initial retransmission timeout counted in timer pulses. - * - * This should not be changed. - */ -#define UIP_RTO 3 - -/** - * The maximum number of times a segment should be retransmitted - * before the connection should be aborted. - * - * This should not be changed. - */ -#define UIP_MAXRTX 8 - -/** - * The maximum number of times a SYN segment should be retransmitted - * before a connection request should be deemed to have been - * unsuccessful. - * - * This should not need to be changed. - */ -#define UIP_MAXSYNRTX 3 - -/** - * The TCP maximum segment size. - * - * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40. - */ -#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40) - -/** - * How long a connection should stay in the TIME_WAIT state. - * - * This configiration option has no real implication, and it should be - * left untouched. - */ -#define UIP_TIME_WAIT_TIMEOUT 120 - - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptarp ARP configuration options - * @{ - */ - -/** - * The size of the ARP table. - * - * This option should be set to a larger value if this uIP node will - * have many connections from the local network. - * - * \hideinitializer - */ -#define UIP_ARPTAB_SIZE 8 - -/** - * The maxium age of ARP table entries measured in 10ths of seconds. - * - * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD - * default). - */ -#define UIP_ARP_MAXAGE 120 - -/** @} */ - -/*------------------------------------------------------------------------------*/ - -/** - * \defgroup uipoptgeneral General configuration options - * @{ - */ - -/** - * The size of the uIP packet buffer. - * - * The uIP packet buffer should not be smaller than 60 bytes, and does - * not need to be larger than 1500 bytes. Lower size results in lower - * TCP throughput, larger size results in higher TCP throughput. - * - * \hideinitializer - */ -#define UIP_BUFSIZE 1500 - - -/** - * Determines if statistics support should be compiled in. - * - * The statistics is useful for debugging and to show the user. - * - * \hideinitializer - */ -#define UIP_STATISTICS 0 - -/** - * Determines if logging of certain events should be compiled in. - * - * This is useful mostly for debugging. The function uip_log() - * must be implemented to suit the architecture of the project, if - * logging is turned on. - * - * \hideinitializer - */ -#define UIP_LOGGING 0 - -/** - * Print out a uIP log message. - * - * This function must be implemented by the module that uses uIP, and - * is called by uIP whenever a log message is generated. - */ -void uip_log(char *msg); - -/** - * The link level header length. - * - * This is the offset into the uip_buf where the IP header can be - * found. For Ethernet, this should be set to 14. For SLIP, this - * should be set to 0. - * - * \hideinitializer - */ -#define UIP_LLH_LEN 0 - - -/** @} */ -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipoptcpu CPU architecture configuration - * @{ - * - * The CPU architecture configuration is where the endianess of the - * CPU on which uIP is to be run is specified. Most CPUs today are - * little endian, and the most notable exception are the Motorolas - * which are big endian. The BYTE_ORDER macro should be changed to - * reflect the CPU architecture on which uIP is to be run. - */ -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 3412 -#endif /* LITTLE_ENDIAN */ -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 1234 -#endif /* BIGE_ENDIAN */ - -/** - * The byte order of the CPU architecture on which uIP is to be run. - * - * This option can be either BIG_ENDIAN (Motorola byte order) or - * LITTLE_ENDIAN (Intel byte order). - * - * \hideinitializer - */ -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif /* BYTE_ORDER */ - -/** @} */ -/*------------------------------------------------------------------------------*/ - -/** - * \defgroup uipoptapp Appication specific configurations - * @{ - * - * An uIP application is implemented using a single application - * function that is called by uIP whenever a TCP/IP event occurs. The - * name of this function must be registered with uIP at compile time - * using the UIP_APPCALL definition. - * - * uIP applications can store the application state within the - * uip_conn structure by specifying the size of the application - * structure with the UIP_APPSTATE_SIZE macro. - * - * The file containing the definitions must be included in the - * uipopt.h file. - * - * The following example illustrates how this can look. - \code - -void httpd_appcall(void); -#define UIP_APPCALL httpd_appcall - -struct httpd_state { - u8_t state; - u16_t count; - char *dataptr; - char *script; -}; -#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state)) - \endcode - */ - -/** - * \var #define UIP_APPCALL - * - * The name of the application function that uIP should call in - * response to TCP/IP events. - * - */ -extern void uip_tcp_appcall ( void ); -#define UIP_APPCALL uip_tcp_appcall - -/** - * \var #define UIP_APPSTATE_SIZE - * - * The size of the application state that is to be stored in the - * uip_conn structure. - */ -#define UIP_APPSTATE_SIZE sizeof ( void * ) -/** @} */ - -/* Include the header file for the application program that should be - used. If you don't use the example web server, you should change - this. */ -//#include "httpd.h" - -#warning "Remove this static IP address hack" -#undef UIP_FIXEDADDR -#undef UIP_IPADDR0 -#undef UIP_IPADDR1 -#undef UIP_IPADDR2 -#undef UIP_IPADDR3 -#define UIP_FIXEDADDR 1 -#define UIP_IPADDR0 10 -#define UIP_IPADDR1 254 -#define UIP_IPADDR2 254 -#define UIP_IPADDR3 1 - -#endif /* __UIPOPT_H__ */ -- cgit v1.2.3-55-g7522