diff --git a/README b/README index 0cbcb2f..b501538 100644 --- a/README +++ b/README @@ -1,11 +1,13 @@ uIP is a very small implementation of the TCP/IP stack that is written -by Adam Dunkels . More information can be obtained -at the uIP homepage at - http://dunkels.com/adam/uip/ +by Adam Dunkels . More information can be obtained +at the uIP homepage at http://www.sics.se/~adam/uip/. + +This is version $Name: uip-1-0 $. The directory structure look as follows: -apps/ - example applications -doc/ - documentation -uip/ - actual uIP TCP/IP, SLIP and ARP code -unix/ - Example of how to run uIP as a user space process under FreeBSD or Linux +apps/ - Example applications +doc/ - Documentation +lib/ - Library code used by some applications +uip/ - uIP TCP/IP stack code +unix/ - uIP as a user space process under FreeBSD or Linux diff --git a/apps/README b/apps/README new file mode 100644 index 0000000..0096c4e --- /dev/null +++ b/apps/README @@ -0,0 +1,2 @@ +This directory contains a few example applications. They are not all +heavily tested, however. diff --git a/apps/dhcpc/Makefile.dhcpc b/apps/dhcpc/Makefile.dhcpc new file mode 100644 index 0000000..f84c84f --- /dev/null +++ b/apps/dhcpc/Makefile.dhcpc @@ -0,0 +1 @@ +APP_SOURCES += dhcpc.c timer.c diff --git a/apps/dhcpc/dhcpc.c b/apps/dhcpc/dhcpc.c new file mode 100644 index 0000000..ac738e7 --- /dev/null +++ b/apps/dhcpc/dhcpc.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $ + */ + +#include +#include + +#include "uip.h" +#include "dhcpc.h" +#include "timer.h" +#include "pt.h" + +#define STATE_INITIAL 0 +#define STATE_SENDING 1 +#define STATE_OFFER_RECEIVED 2 +#define STATE_CONFIG_RECEIVED 3 + +static struct dhcpc_state s; + +struct dhcp_msg { + u8_t op, htype, hlen, hops; + u8_t xid[4]; + u16_t secs, flags; + u8_t ciaddr[4]; + u8_t yiaddr[4]; + u8_t siaddr[4]; + u8_t giaddr[4]; + u8_t chaddr[16]; +#ifndef UIP_CONF_DHCP_LIGHT + u8_t sname[64]; + u8_t file[128]; +#endif + u8_t options[312]; +}; + +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPC_SERVER_PORT 67 +#define DHCPC_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +static const u8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; +static const u8_t magic_cookie[4] = {99, 130, 83, 99}; +/*---------------------------------------------------------------------------*/ +static u8_t * +add_msg_type(u8_t *optptr, u8_t type) +{ + *optptr++ = DHCP_OPTION_MSG_TYPE; + *optptr++ = 1; + *optptr++ = type; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_server_id(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_SERVER_ID; + *optptr++ = 4; + memcpy(optptr, s.serverid, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_ipaddr(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_IPADDR; + *optptr++ = 4; + memcpy(optptr, s.ipaddr, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_options(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_LIST; + *optptr++ = 3; + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = DHCP_OPTION_DNS_SERVER; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_end(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_END; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static void +create_msg(register struct dhcp_msg *m) +{ + m->op = DHCP_REQUEST; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = s.mac_len; + m->hops = 0; + memcpy(m->xid, xid, sizeof(m->xid)); + m->secs = 0; + m->flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ + /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/ + memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr)); + memset(m->yiaddr, 0, sizeof(m->yiaddr)); + memset(m->siaddr, 0, sizeof(m->siaddr)); + memset(m->giaddr, 0, sizeof(m->giaddr)); + memcpy(m->chaddr, s.mac_addr, s.mac_len); + memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len); +#ifndef UIP_CONF_DHCP_LIGHT + memset(m->sname, 0, sizeof(m->sname)); + memset(m->file, 0, sizeof(m->file)); +#endif + + memcpy(m->options, magic_cookie, sizeof(magic_cookie)); +} +/*---------------------------------------------------------------------------*/ +static void +send_discover(void) +{ + u8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPDISCOVER); + end = add_req_options(end); + end = add_end(end); + + uip_send(uip_appdata, end - (u8_t *)uip_appdata); +} +/*---------------------------------------------------------------------------*/ +static void +send_request(void) +{ + u8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPREQUEST); + end = add_server_id(end); + end = add_req_ipaddr(end); + end = add_end(end); + + uip_send(uip_appdata, end - (u8_t *)uip_appdata); +} +/*---------------------------------------------------------------------------*/ +static u8_t +parse_options(u8_t *optptr, int len) +{ + u8_t *end = optptr + len; + u8_t type = 0; + + while(optptr < end) { + switch(*optptr) { + case DHCP_OPTION_SUBNET_MASK: + memcpy(s.netmask, optptr + 2, 4); + break; + case DHCP_OPTION_ROUTER: + memcpy(s.default_router, optptr + 2, 4); + break; + case DHCP_OPTION_DNS_SERVER: + memcpy(s.dnsaddr, optptr + 2, 4); + break; + case DHCP_OPTION_MSG_TYPE: + type = *(optptr + 2); + break; + case DHCP_OPTION_SERVER_ID: + memcpy(s.serverid, optptr + 2, 4); + break; + case DHCP_OPTION_LEASE_TIME: + memcpy(s.lease_time, optptr + 2, 4); + break; + case DHCP_OPTION_END: + return type; + } + + optptr += optptr[1] + 2; + } + return type; +} +/*---------------------------------------------------------------------------*/ +static u8_t +parse_msg(void) +{ + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + if(m->op == DHCP_REPLY && + memcmp(m->xid, xid, sizeof(xid)) == 0 && + memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { + memcpy(s.ipaddr, m->yiaddr, 4); + return parse_options(&m->options[4], uip_datalen()); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_dhcp(void)) +{ + PT_BEGIN(&s.pt); + + /* try_again:*/ + s.state = STATE_SENDING; + s.ticks = CLOCK_SECOND; + + do { + send_discover(); + timer_set(&s.timer, s.ticks); + PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); + + if(uip_newdata() && parse_msg() == DHCPOFFER) { + s.state = STATE_OFFER_RECEIVED; + break; + } + + if(s.ticks < CLOCK_SECOND * 60) { + s.ticks *= 2; + } + } while(s.state != STATE_OFFER_RECEIVED); + + s.ticks = CLOCK_SECOND; + + do { + send_request(); + timer_set(&s.timer, s.ticks); + PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); + + if(uip_newdata() && parse_msg() == DHCPACK) { + s.state = STATE_CONFIG_RECEIVED; + break; + } + + if(s.ticks <= CLOCK_SECOND * 10) { + s.ticks += CLOCK_SECOND; + } else { + PT_RESTART(&s.pt); + } + } while(s.state != STATE_CONFIG_RECEIVED); + +#if 0 + printf("Got IP address %d.%d.%d.%d\n", + uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr), + uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr)); + printf("Got netmask %d.%d.%d.%d\n", + uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask), + uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask)); + printf("Got DNS server %d.%d.%d.%d\n", + uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr), + uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr)); + printf("Got default router %d.%d.%d.%d\n", + uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router), + uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router)); + printf("Lease expires in %ld seconds\n", + ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1])); +#endif + + dhcpc_configured(&s); + + /* timer_stop(&s.timer);*/ + + /* + * PT_END restarts the thread so we do this instead. Eventually we + * should reacquire expired leases here. + */ + while(1) { + PT_YIELD(&s.pt); + } + + PT_END(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_init(const void *mac_addr, int mac_len) +{ + uip_ipaddr_t addr; + + s.mac_addr = mac_addr; + s.mac_len = mac_len; + + s.state = STATE_INITIAL; + uip_ipaddr(addr, 255,255,255,255); + s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT)); + if(s.conn != NULL) { + uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT)); + } + PT_INIT(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_appcall(void) +{ + handle_dhcp(); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_request(void) +{ + u16_t ipaddr[2]; + + if(s.state == STATE_INITIAL) { + uip_ipaddr(ipaddr, 0,0,0,0); + uip_sethostaddr(ipaddr); + /* handle_dhcp(PROCESS_EVENT_NONE, NULL);*/ + } +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/dhcpc/dhcpc.h b/apps/dhcpc/dhcpc.h new file mode 100644 index 0000000..c6550ec --- /dev/null +++ b/apps/dhcpc/dhcpc.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $ + */ +#ifndef __DHCPC_H__ +#define __DHCPC_H__ + +#include "timer.h" +#include "pt.h" + +struct dhcpc_state { + struct pt pt; + char state; + struct uip_udp_conn *conn; + struct timer timer; + u16_t ticks; + const void *mac_addr; + int mac_len; + + u8_t serverid[4]; + + u16_t lease_time[2]; + u16_t ipaddr[2]; + u16_t netmask[2]; + u16_t dnsaddr[2]; + u16_t default_router[2]; +}; + +void dhcpc_init(const void *mac_addr, int mac_len); +void dhcpc_request(void); + +void dhcpc_appcall(void); + +void dhcpc_configured(const struct dhcpc_state *s); + +typedef struct dhcpc_state uip_udp_appstate_t; +#define UIP_UDP_APPCALL dhcpc_appcall + + +#endif /* __DHCPC_H__ */ diff --git a/apps/hello-world/Makefile.hello-world b/apps/hello-world/Makefile.hello-world new file mode 100644 index 0000000..e34aaf5 --- /dev/null +++ b/apps/hello-world/Makefile.hello-world @@ -0,0 +1 @@ +APP_SOURCES += hello-world.c diff --git a/apps/hello-world/hello-world.c b/apps/hello-world/hello-world.c new file mode 100644 index 0000000..7d0697c --- /dev/null +++ b/apps/hello-world/hello-world.c @@ -0,0 +1,100 @@ +/** + * \addtogroup helloworld + * @{ + */ + +/** + * \file + * An example of how to write uIP applications + * with protosockets. + * \author + * Adam Dunkels + */ + +/* + * This is a short example of how to write uIP applications using + * protosockets. + */ + +/* + * We define the application state (struct hello_world_state) in the + * hello-world.h file, so we need to include it here. We also include + * uip.h (since this cannot be included in hello-world.h) and + * , since we use the memcpy() function in the code. + */ +#include "hello-world.h" +#include "uip.h" +#include + +/* + * Declaration of the protosocket function that handles the connection + * (defined at the end of the code). + */ +static int handle_connection(struct hello_world_state *s); +/*---------------------------------------------------------------------------*/ +/* + * The initialization function. We must explicitly call this function + * from the system initialization code, some time after uip_init() is + * called. + */ +void +hello_world_init(void) +{ + /* We start to listen for connections on TCP port 1000. */ + uip_listen(HTONS(1000)); +} +/*---------------------------------------------------------------------------*/ +/* + * In hello-world.h we have defined the UIP_APPCALL macro to + * hello_world_appcall so that this funcion is uIP's application + * function. This function is called whenever an uIP event occurs + * (e.g. when a new connection is established, new data arrives, sent + * data is acknowledged, data needs to be retransmitted, etc.). + */ +void +hello_world_appcall(void) +{ + /* + * The uip_conn structure has a field called "appstate" that holds + * the application state of the connection. We make a pointer to + * this to access it easier. + */ + struct hello_world_state *s = &(uip_conn->appstate); + + /* + * If a new connection was just established, we should initialize + * the protosocket in our applications' state structure. + */ + if(uip_connected()) { + PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer)); + } + + /* + * Finally, we run the protosocket function that actually handles + * the communication. We pass it a pointer to the application state + * of the current connection. + */ + handle_connection(s); +} +/*---------------------------------------------------------------------------*/ +/* + * This is the protosocket function that handles the communication. A + * protosocket function must always return an int, but must never + * explicitly return - all return statements are hidden in the PSOCK + * macros. + */ +static int +handle_connection(struct hello_world_state *s) +{ + PSOCK_BEGIN(&s->p); + + PSOCK_SEND_STR(&s->p, "Hello. What is your name?\n"); + PSOCK_READTO(&s->p, '\n'); + strncpy(s->name, s->inputbuffer, sizeof(s->name)); + PSOCK_SEND_STR(&s->p, "Hello "); + PSOCK_SEND_STR(&s->p, s->name); + PSOCK_CLOSE(&s->p); + + PSOCK_END(&s->p); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/hello-world/hello-world.h b/apps/hello-world/hello-world.h new file mode 100644 index 0000000..5ef333b --- /dev/null +++ b/apps/hello-world/hello-world.h @@ -0,0 +1,52 @@ +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup helloworld Hello, world + * @{ + * + * A small example showing how to write applications with + * \ref psock "protosockets". + */ + +/** + * \file + * Header file for an example of how to write uIP applications + * with protosockets. + * \author + * Adam Dunkels + */ + +#ifndef __HELLO_WORLD_H__ +#define __HELLO_WORLD_H__ + +/* Since this file will be included by uip.h, we cannot include uip.h + here. But we might need to include uipopt.h if we need the u8_t and + u16_t datatypes. */ +#include "uipopt.h" + +#include "psock.h" + +/* Next, we define the uip_tcp_appstate_t datatype. This is the state + of our application, and the memory required for this state is + allocated together with each TCP connection. One application state + for each TCP connection. */ +typedef struct hello_world_state { + struct psock p; + char inputbuffer[10]; + char name[40]; +} uip_tcp_appstate_t; + +/* Finally we define the application function to be called by uIP. */ +void hello_world_appcall(void); +#ifndef UIP_APPCALL +#define UIP_APPCALL hello_world_appcall +#endif /* UIP_APPCALL */ + +void hello_world_init(void); + +#endif /* __HELLO_WORLD_H__ */ +/** @} */ +/** @} */ diff --git a/apps/httpd/cgi.c b/apps/httpd/cgi.c deleted file mode 100644 index adb53e9..0000000 --- a/apps/httpd/cgi.c +++ /dev/null @@ -1,211 +0,0 @@ -/** - * \addtogroup httpd - * @{ - */ - -/** - * \file - * HTTP server script language C functions file. - * \author Adam Dunkels - * - * This file contains functions that are called by the web server - * scripts. The functions takes one argument, and the return value is - * interpreted as follows. A zero means that the function did not - * complete and should be invoked for the next packet as well. A - * non-zero value indicates that the function has completed and that - * the web server should move along to the next script line. - * - */ - -/* - * 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: cgi.c,v 1.23.2.4 2003/10/07 13:22:27 adam Exp $ - * - */ - -#include "uip.h" -#include "cgi.h" -#include "httpd.h" -#include "fs.h" - -#include -#include - -static u8_t print_stats(u8_t next); -static u8_t file_stats(u8_t next); -static u8_t tcp_stats(u8_t next); - -cgifunction cgitab[] = { - print_stats, /* CGI function "a" */ - file_stats, /* CGI function "b" */ - tcp_stats /* CGI function "c" */ -}; - -static const char closed[] = /* "CLOSED",*/ -{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0}; -static const char syn_rcvd[] = /* "SYN-RCVD",*/ -{0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, - 0x44, 0}; -static const char syn_sent[] = /* "SYN-SENT",*/ -{0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, - 0x54, 0}; -static const char established[] = /* "ESTABLISHED",*/ -{0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, - 0x45, 0x44, 0}; -static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ -{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, - 0x54, 0x2d, 0x31, 0}; -static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ -{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, - 0x54, 0x2d, 0x32, 0}; -static const char closing[] = /* "CLOSING",*/ -{0x43, 0x4c, 0x4f, 0x53, 0x49, - 0x4e, 0x47, 0}; -static const char time_wait[] = /* "TIME-WAIT,"*/ -{0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, - 0x49, 0x54, 0}; -static const char last_ack[] = /* "LAST-ACK"*/ -{0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, - 0x4b, 0}; - -static const char *states[] = { - closed, - syn_rcvd, - syn_sent, - established, - fin_wait_1, - fin_wait_2, - closing, - time_wait, - last_ack}; - - -/*-----------------------------------------------------------------------------------*/ -/* print_stats: - * - * Prints out a part of the uIP statistics. The statistics data is - * written into the uip_appdata buffer. It overwrites any incoming - * packet. - */ -static u8_t -print_stats(u8_t next) -{ -#if UIP_STATISTICS - u16_t i, j; - u8_t *buf; - u16_t *databytes; - - if(next) { - /* If our last data has been acknowledged, we move on the next - chunk of statistics. */ - hs->count = hs->count + 4; - if(hs->count >= sizeof(struct uip_stats)/sizeof(u16_t)) { - /* We have printed out all statistics, so we return 1 to - indicate that we are done. */ - return 1; - } - } - - /* Write part of the statistics into the uip_appdata buffer. */ - databytes = (u16_t *)&uip_stat + hs->count; - buf = (u8_t *)uip_appdata; - - j = 4 + 1; - i = hs->count; - while (i < sizeof(struct uip_stats)/sizeof(u16_t) && --j > 0) { - sprintf((char *)buf, "%5u\r\n", *databytes); - ++databytes; - buf += 6; - ++i; - } - - /* Send the data. */ - uip_send(uip_appdata, buf - uip_appdata); - - return 0; -#else - return 1; -#endif /* UIP_STATISTICS */ -} -/*-----------------------------------------------------------------------------------*/ -static u8_t -file_stats(u8_t next) -{ - /* We use sprintf() to print the number of file accesses to a - particular file (given as an argument to the function in the - script). We then use uip_send() to actually send the data. */ - if(next) { - return 1; - } - uip_send(uip_appdata, sprintf((char *)uip_appdata, "%5u", fs_count(&hs->script[4]))); - return 0; -} -/*-----------------------------------------------------------------------------------*/ -static u8_t -tcp_stats(u8_t next) -{ - struct uip_conn *conn; - - if(next) { - /* If the previously sent data has been acknowledged, we move - forward one connection. */ - if(++hs->count == UIP_CONNS) { - /* If all connections has been printed out, we are done and - return 1. */ - return 1; - } - } - - conn = &uip_conns[hs->count]; - if((conn->tcpstateflags & TS_MASK) == CLOSED) { - uip_send(uip_appdata, sprintf((char *)uip_appdata, - "--%u%u%c %c\r\n", - conn->nrtx, - conn->timer, - (uip_outstanding(conn))? '*':' ', - (uip_stopped(conn))? '!':' ')); - } else { - uip_send(uip_appdata, sprintf((char *)uip_appdata, - "%u.%u.%u.%u:%u%s%u%u%c %c\r\n", - htons(conn->ripaddr[0]) >> 8, - htons(conn->ripaddr[0]) & 0xff, - htons(conn->ripaddr[1]) >> 8, - htons(conn->ripaddr[1]) & 0xff, - htons(conn->rport), - states[conn->tcpstateflags & TS_MASK], - conn->nrtx, - conn->timer, - (uip_outstanding(conn))? '*':' ', - (uip_stopped(conn))? '!':' ')); - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ diff --git a/apps/httpd/fs/404.html b/apps/httpd/fs/404.html deleted file mode 100644 index 8d6beec..0000000 --- a/apps/httpd/fs/404.html +++ /dev/null @@ -1 +0,0 @@ -

404 - file not found

\ No newline at end of file diff --git a/apps/httpd/fs/about.html b/apps/httpd/fs/about.html deleted file mode 100644 index 0d0dd6f..0000000 --- a/apps/httpd/fs/about.html +++ /dev/null @@ -1,18 +0,0 @@ - - -
-
-

Welcome

-

-These web pages are served by the small web server running on top of -the uIP TCP/IP -stack. -

-

-Click on the links above to see some status information about the web -server and the TCP/IP stack. -

-
-
- - \ No newline at end of file diff --git a/apps/httpd/fs/cgi/files b/apps/httpd/fs/cgi/files deleted file mode 100644 index b9d929b..0000000 --- a/apps/httpd/fs/cgi/files +++ /dev/null @@ -1,28 +0,0 @@ -# This script shows the access statistics for different files on the -# web server. -# -# First, we include the HTML header. -i /files_header.html -# Print out the name of the file, and call the function that prints -# the access statistics of that file. -t /index.html -c b /index.html -t /about.html -c b /about.html -t /control.html -c b /control.html -t /img/bg.png -c b /img/bg.png -t /404.html -c b /404.html -t /cgi/files -c b /cgi/files -t /cgi/stats -c b /cgi/stats -t /cgi/tcp -c b /cgi/tcp -t -# Include the HTML footer. -i /files_footer.plain -# End of script. -. \ No newline at end of file diff --git a/apps/httpd/fs/cgi/stats b/apps/httpd/fs/cgi/stats deleted file mode 100644 index 88a1785..0000000 --- a/apps/httpd/fs/cgi/stats +++ /dev/null @@ -1,4 +0,0 @@ -i /stats_header.html -c a -i /stats_footer.plain -. diff --git a/apps/httpd/fs/cgi/tcp b/apps/httpd/fs/cgi/tcp deleted file mode 100644 index b873743..0000000 --- a/apps/httpd/fs/cgi/tcp +++ /dev/null @@ -1,4 +0,0 @@ -i /tcp_header.html -c c -i /tcp_footer.plain -. \ No newline at end of file diff --git a/apps/httpd/fs/control.html b/apps/httpd/fs/control.html deleted file mode 100644 index 2327497..0000000 --- a/apps/httpd/fs/control.html +++ /dev/null @@ -1,14 +0,0 @@ - - -
-
-

uIP web server test pages

-[ About | -Connections | -Files | -Statistics ] -
-
- - \ No newline at end of file diff --git a/apps/httpd/fs/files_footer.plain b/apps/httpd/fs/files_footer.plain deleted file mode 100644 index 8e7b84f..0000000 --- a/apps/httpd/fs/files_footer.plain +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/httpd/fs/files_header.html b/apps/httpd/fs/files_header.html deleted file mode 100644 index 9e3ef68..0000000 --- a/apps/httpd/fs/files_header.html +++ /dev/null @@ -1,4 +0,0 @@ - - -
- diff --git a/apps/httpd/fs/img/bg.png b/apps/httpd/fs/img/bg.png deleted file mode 100644 index 18533b3..0000000 Binary files a/apps/httpd/fs/img/bg.png and /dev/null differ diff --git a/apps/httpd/fs/index.html b/apps/httpd/fs/index.html deleted file mode 100644 index a8aa4d8..0000000 --- a/apps/httpd/fs/index.html +++ /dev/null @@ -1,14 +0,0 @@ - -uIP web server test page - - - - - - - -<body> -Your browser must support frames -</body> - - \ No newline at end of file diff --git a/apps/httpd/fs/stats_footer.plain b/apps/httpd/fs/stats_footer.plain deleted file mode 100644 index 8e7b84f..0000000 --- a/apps/httpd/fs/stats_footer.plain +++ /dev/null @@ -1,3 +0,0 @@ -
- - diff --git a/apps/httpd/fs/tcp_footer.plain b/apps/httpd/fs/tcp_footer.plain deleted file mode 100644 index 9be88c0..0000000 --- a/apps/httpd/fs/tcp_footer.plain +++ /dev/null @@ -1,5 +0,0 @@ - - -
- - \ No newline at end of file diff --git a/apps/httpd/fs/tcp_header.html b/apps/httpd/fs/tcp_header.html deleted file mode 100644 index 595e99c..0000000 --- a/apps/httpd/fs/tcp_header.html +++ /dev/null @@ -1,6 +0,0 @@ - - -
- - - diff --git a/apps/httpd/fsdata.c b/apps/httpd/fsdata.c deleted file mode 100644 index 3c41ef3..0000000 --- a/apps/httpd/fsdata.c +++ /dev/null @@ -1,619 +0,0 @@ -static const char data_cgi_files[] = { - /* /cgi/files */ - 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0, - 0x23, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x73, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, - 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0xa, 0x23, - 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0xa, 0x23, 0xa, 0x23, 0x20, 0x46, 0x69, 0x72, - 0x73, 0x74, 0x2c, 0x20, 0x77, 0x65, 0x20, 0x69, 0x6e, 0x63, - 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x48, - 0x54, 0x4d, 0x4c, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x2e, 0xa, 0x69, 0x20, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, - 0x6d, 0x6c, 0xa, 0x23, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, - 0x20, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, - 0x68, 0x61, 0x74, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, - 0xa, 0x23, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, - 0x74, 0x69, 0x63, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, - 0x61, 0x74, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0xa, 0x74, - 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, - 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, - 0x3e, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, - 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, - 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xa, 0x63, 0x20, 0x62, 0x20, - 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, - 0x6c, 0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, - 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, - 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, - 0x3d, 0x22, 0x2f, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x2e, 0x68, - 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x61, 0x62, 0x6f, 0x75, - 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, - 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xa, - 0x63, 0x20, 0x62, 0x20, 0x2f, 0x61, 0x62, 0x6f, 0x75, 0x74, - 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x74, 0x20, 0x3c, 0x2f, - 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, - 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, - 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, - 0x3e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, - 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, - 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xa, 0x63, 0x20, - 0x62, 0x20, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x74, 0x20, 0x3c, 0x2f, - 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x20, 0x3c, - 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, - 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6d, 0x67, - 0x2f, 0x62, 0x67, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x3e, 0x2f, - 0x69, 0x6d, 0x67, 0x2f, 0x62, 0x67, 0x2e, 0x70, 0x6e, 0x67, - 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, - 0x74, 0x64, 0x3e, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x69, - 0x6d, 0x67, 0x2f, 0x62, 0x67, 0x2e, 0x70, 0x6e, 0x67, 0xa, - 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, - 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, - 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, - 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, - 0x3e, 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, - 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, - 0x74, 0x64, 0x3e, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x34, - 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x74, 0x20, - 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, - 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, - 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x63, - 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x3e, - 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, - 0x74, 0x64, 0x3e, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x63, - 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0xa, 0x74, - 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, - 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, - 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, - 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, - 0x3e, 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, - 0x3c, 0x74, 0x64, 0x3e, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, - 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0xa, - 0x74, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, - 0x72, 0x3e, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, - 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, - 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x22, 0x3e, - 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x3c, 0x2f, - 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, - 0x3e, 0xa, 0x63, 0x20, 0x62, 0x20, 0x2f, 0x63, 0x67, 0x69, - 0x2f, 0x74, 0x63, 0x70, 0xa, 0x74, 0x20, 0x3c, 0x2f, 0x74, - 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x23, 0x20, - 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x66, 0x6f, 0x6f, - 0x74, 0x65, 0x72, 0x2e, 0xa, 0x69, 0x20, 0x2f, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, - 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xa, 0x23, 0x20, 0x45, - 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x2e, 0xa, 0x2e, }; - -static const char data_cgi_stats[] = { - /* /cgi/stats */ - 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0, - 0x69, 0x20, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x68, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, - 0xa, 0x63, 0x20, 0x61, 0xa, 0x69, 0x20, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, - 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xa, 0x2e, 0xa, }; - -static const char data_cgi_tcp[] = { - /* /cgi/tcp */ - 0x2f, 0x63, 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0, - 0x69, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x5f, 0x68, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x63, - 0x20, 0x63, 0xa, 0x69, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x5f, - 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0xa, 0x2e, }; - -static const char data_img_bg_png[] = { - /* /img/bg.png */ - 0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x62, 0x67, 0x2e, 0x70, 0x6e, 0x67, 0, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, - 0xd, 0xa, 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, - 00, 00, 00, 0xd, 0x49, 0x48, 0x44, 0x52, 00, 00, - 0x3, 0x1d, 00, 00, 00, 0x5e, 0x8, 0x6, 00, 00, - 00, 0x46, 0xbd, 0x79, 0xcc, 00, 00, 00, 0x6, 0x62, - 0x4b, 0x47, 0x44, 00, 0xff, 00, 0xff, 00, 0xff, 0xa0, - 0xbd, 0xa7, 0x93, 00, 00, 00, 0x9, 0x70, 0x48, 0x59, - 0x73, 00, 00, 0xb, 0x12, 00, 00, 0xb, 0x12, 0x1, - 0xd2, 0xdd, 0x7e, 0xfc, 00, 00, 00, 0x7, 0x74, 0x49, - 0x4d, 0x45, 0x7, 0xd3, 0xa, 0x5, 0x12, 0x22, 0x33, 0x22, - 0xd0, 0x7c, 0x9a, 00, 00, 00, 0x1d, 0x74, 0x45, 0x58, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 00, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, - 0xef, 0x64, 0x25, 0x6e, 00, 00, 0x3, 0xa0, 0x49, 0x44, - 0x41, 0x54, 0x78, 0xda, 0xed, 0xdd, 0xc1, 0x76, 0x9a, 0x40, - 0x18, 0x80, 0x51, 0x27, 0xc7, 0x5, 0x6c, 0xd1, 0x65, 0x1a, - 0xec, 0xe9, 0xfb, 0xbf, 0x45, 0x9e, 0x23, 0xd5, 0xb4, 0x4b, - 0x71, 0x19, 0xdd, 0x4d, 0x97, 0x36, 0x8a, 0x6, 0x1c, 0x82, - 0x20, 0xf7, 0xee, 0x92, 0xa8, 0x3f, 0xc, 0x68, 0xfa, 0xa1, - 0x3d, 0x9, 0x6f, 0xaf, 0x1f, 0x71, 0x76, 0x26, 0xcc, 0x6e, - 0x15, 0x9e, 0xce, 0xbf, 0x17, 0xe3, 0x71, 0x44, 0xb8, 0xfd, - 0xa1, 0x93, 0xd5, 0x6d, 0x5b, 0x7f, 0xc3, 0x13, 0xef, 0x1e, - 0x86, 0xb3, 0x2d, 0x5d, 0x6d, 0xdb, 0xf2, 0x57, 0x96, 0x34, - 0x77, 0xfb, 0xfb, 0x90, 0x74, 0xff, 0xe5, 0xcf, 0xb4, 0xf9, - 0xbb, 0x4d, 0xda, 0xfc, 0xa2, 0xcc, 0x92, 0xd6, 0xb4, 0x5a, - 0x5f, 0x99, 0xdf, 0xe0, 0x5c, 0x5f, 0xae, 0xb2, 0xd9, 0x20, - 0x85, 0x6f, 0x5c, 0xff, 0x70, 0x7c, 0x2d, 0x5a, 0x94, 0xf9, - 0xf0, 0x76, 0xfd, 0x69, 0x36, 0x39, 0x53, 0xdc, 0xe7, 0x41, - 0xfc, 0x1e, 0x18, 0xe1, 0xef, 0x41, 0xc6, 0xf1, 0x7c, 0xa9, - 0x3d, 0x4f, 0xe3, 0x83, 0x1f, 0xfc, 0xb1, 0x1e, 0x17, 0xcb, - 0x4, 00, 00, 0x68, 0x33, 00, 00, 00, 0xd1, 0x1, - 00, 00, 0x88, 0xe, 00, 00, 0x40, 0x74, 00, 00, - 00, 0x88, 0xe, 00, 00, 0x40, 0x74, 00, 00, 00, - 0xa2, 0x3, 00, 00, 0x40, 0x74, 00, 00, 00, 0xa2, - 0x3, 00, 00, 0x40, 0x74, 00, 00, 00, 0xa2, 0x3, - 00, 00, 0x10, 0x1d, 00, 0x1d, 0xa, 0x96, 00, 00, - 0x44, 0x7, 00, 00, 0x40, 0x4b, 0xe1, 0xed, 0xf5, 0x23, - 0xd6, 0x7c, 0xfb, 0xf6, 0x7, 0xac, 0xc9, 0x98, 0x18, 0x8f, - 0x23, 0xc2, 0x1d, 0xaf, 0x64, 0x86, 0x7b, 0x26, 0x56, 0xe2, - 0x7e, 0x77, 0xba, 0x6e, 0x1d, 0x1f, 0x83, 0xa4, 0x6d, 0xb, - 0xfd, 0x6e, 0x6b, 0x97, 0x6b, 0x1a, 0xee, 0x7c, 0x55, 0x7e, - 0xb1, 0xca, 0x92, 0x9e, 0xb, 0xdb, 0xf5, 0x21, 0x69, 0xfe, - 0x32, 0x61, 0xfe, 0x18, 0x8f, 0xf7, 0xc3, 0xbf, 0x46, 0xd9, - 0xe7, 0xe1, 0xaf, 0xd5, 0xd8, 0xdf, 0x9, 0xf4, 0x4e, 0xe6, - 0x24, 0x9e, 0x2f, 0xb5, 0xe7, 0x69, 0x7c, 0xf0, 0x83, 0x3f, - 0xd6, 0xe3, 0x62, 0x99, 00, 00, 00, 0x6d, 0x6, 00, - 00, 0x20, 0x3a, 00, 00, 00, 0xd1, 0x1, 00, 00, - 0x88, 0xe, 00, 00, 00, 0xd1, 0x1, 00, 00, 0x88, - 0xe, 00, 00, 0x40, 0x74, 00, 00, 00, 0x88, 0xe, - 00, 00, 0x40, 0x74, 00, 00, 00, 0x88, 0xe, 0x98, - 0xaa, 0xe0, 0x59, 0xf, 00, 0x88, 0xe, 00, 0x86, 0x53, - 0xa9, 0x96, 00, 00, 0xd1, 0x1, 00, 00, 0x88, 0xe, - 00, 00, 0x40, 0x74, 00, 00, 00, 0x7c, 0x93, 0xb9, - 0x25, 0x80, 0xfb, 0x28, 0xca, 0xec, 0xe2, 0xcf, 0x42, 0x83, - 0xcf, 0xd1, 0x57, 0xeb, 0xc3, 0xe5, 0x1f, 0x36, 0xb8, 0x9c, - 0xb0, 0x5c, 0x65, 0x49, 0xdb, 0xbf, 0xbd, 0x30, 0x3f, 0x34, - 0xfc, 0x3f, 00, 0x8b, 0x32, 0x6d, 0xfe, 0x6e, 0x73, 0x68, - 0x7f, 0xa7, 0x10, 0xff, 0x9b, 0x9f, 0x27, 0xcd, 0xaf, 0xde, - 0xf7, 0xed, 0x46, 0x9f, 0x1c, 0x93, 0xe2, 0x39, 0xf7, 0x24, - 00, 0x60, 0x32, 0xbc, 0xd3, 0x1, 00, 00, 0x88, 0xe, - 00, 00, 0x40, 0x74, 00, 00, 00, 0x88, 0xe, 00, - 00, 0x40, 0x74, 00, 00, 00, 0x8f, 0x1f, 0x1d, 0xdd, - 0xfe, 0xf9, 0xd9, 0x18, 0xa3, 0x55, 0x6, 00, 00, 0xd1, - 0xc1, 0x64, 0x84, 0x8e, 0x1f, 0x2e, 0x58, 0x52, 00, 00, - 0x44, 0x7, 00, 00, 0x20, 0x3a, 00, 00, 00, 0xd1, - 0x1, 00, 00, 0x20, 0x3a, 00, 00, 00, 0xd1, 0x1, - 00, 00, 0x88, 0xe, 00, 00, 00, 0xd1, 0x1, 00, - 00, 0x88, 0xe, 00, 00, 0x80, 0xb9, 0x25, 0x80, 0xfb, - 0xd8, 0x6d, 0xe, 0x77, 0x9d, 0xbf, 0x5d, 0xa7, 0xcd, 0x5f, - 0xae, 0xb2, 0xa4, 0xfb, 0x57, 0x35, 0xfb, 0xdf, 0xe6, 0x8f, - 0x4d, 0x16, 0x65, 0xbb, 0xf9, 0xa7, 0x8f, 0x5d, 0x6d, 0xf6, - 0xe7, 0x37, 0x88, 0xf1, 0xca, 0x3, 0x7c, 0xfe, 0x72, 0xf1, - 0x92, 0x3b, 0x89, 0x1, 0xa0, 0x21, 0xef, 0x74, 00, 00, - 00, 0xa2, 0x3, 00, 00, 0x10, 0x1d, 00, 00, 00, - 0xa2, 0x63, 0xac, 0xda, 0x7c, 0xce, 0x1d, 00, 00, 0x44, - 0x7, 0xe0, 0x59, 0xd, 00, 0xf8, 0xe7, 0x9, 00, 00, - 0x80, 0xe8, 00, 00, 00, 0x44, 0x7, 00, 00, 0x80, - 0xe8, 00, 00, 00, 0x44, 0x7, 00, 00, 0x20, 0x3a, - 00, 00, 00, 0x44, 0x7, 00, 00, 0x20, 0x3a, 00, - 00, 00, 0xd1, 0x1, 00, 00, 0x20, 0x3a, 00, 00, - 0x80, 0x81, 0x98, 0x5b, 0x2, 0xe0, 0x16, 0xdb, 0xf5, 0xa1, - 0xf6, 0xfb, 0x21, 0xf4, 0x33, 0x7f, 0xb7, 0x39, 0xb4, 0xbb, - 0x43, 0x88, 0x9f, 0xbe, 0x5c, 0x94, 0x79, 0xd2, 0xfc, 0xea, - 0x7d, 0xdf, 0x6e, 0xfc, 0xc9, 0x25, 0x9e, 0xe2, 0xb9, 0xbf, - 0xf9, 0x75, 0xc7, 0xa4, 0xf8, 0x91, 0x3b, 0x89, 0x1, 0xe8, - 0x8d, 0x77, 0x3a, 00, 00, 00, 0xd1, 0x1, 0x43, 0xd3, - 0xd7, 0xd5, 0x7c, 0xeb, 0x2, 00, 0x88, 0xe, 00, 0xbe, - 0x8e, 0x31, 0xaf, 0xb4, 00, 0x88, 0xe, 00, 00, 00, - 0xd1, 0x1, 00, 00, 0x88, 0xe, 00, 00, 00, 0xd1, - 0x1, 00, 00, 0x88, 0xe, 00, 00, 0x40, 0x74, 00, - 00, 00, 0x88, 0xe, 00, 00, 0x40, 0x74, 00, 00, - 00, 0xa2, 0x3, 00, 00, 0x60, 0x34, 0xd1, 0x11, 0x82, - 0x5, 0x7, 00, 00, 0xd1, 0x1, 0x43, 0x21, 0x52, 0x1, - 00, 0x44, 0x7, 00, 00, 0xc0, 0x57, 0xe6, 0x96, 00, - 0x18, 0xa3, 0xa2, 0xcc, 0x5a, 0xdd, 0xfe, 0xf4, 0xe3, 0x9d, - 0xd5, 0x66, 0x7f, 0x7e, 0x83, 0x18, 0xaf, 0x3c, 0x40, 0xb7, - 0xdb, 0xbf, 0xfb, 0xbb, 0x4f, 0xba, 0xff, 0xe2, 0x25, 0x4f, - 0x9b, 0xff, 0xa7, 0xe1, 0xfc, 0xb, 0xfb, 0x5d, 0x3c, 0xe7, - 0xdf, 0xbe, 0xff, 0xe1, 0xca, 0x65, 0xb1, 0x3e, 0xe6, 0x5f, - 0x3d, 0xff, 0x12, 0xe7, 0x3, 0x4c, 0x8d, 0x77, 0x3a, 00, - 00, 00, 0xd1, 0x1, 00, 00, 0x88, 0xe, 00, 00, - 00, 0xd1, 0x1, 00, 00, 0x88, 0xe, 00, 00, 0x40, - 0x74, 00, 00, 00, 0x88, 0xe, 00, 00, 0x40, 0x74, - 00, 00, 00, 0xa2, 0x3, 00, 00, 0x40, 0x74, 0x34, - 0x13, 0xe4, 0x15, 00, 00, 0x88, 0xe, 00, 00, 0x40, - 0x74, 00, 00, 00, 0x88, 0xe, 00, 00, 0x40, 0x74, - 00, 00, 00, 0x13, 0xf1, 0xf, 0x24, 0xa1, 0x5c, 0xab, - 0x41, 0xd8, 0x92, 0xa4, 00, 00, 00, 00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, }; - -static const char data_about_html[] = { - /* /about.html */ - 0x2f, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x3c, - 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, - 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, - 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x3d, 0x22, 0x36, 0x30, 0x30, 0x22, 0x20, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, - 0x3e, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xa, - 0x3c, 0x68, 0x32, 0x3e, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, - 0x65, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0xa, 0x3c, 0x70, 0x20, - 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6a, 0x75, 0x73, - 0x74, 0x69, 0x66, 0x79, 0x22, 0x3e, 0xa, 0x54, 0x68, 0x65, - 0x73, 0x65, 0x20, 0x77, 0x65, 0x62, 0x20, 0x70, 0x61, 0x67, - 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x77, 0x65, 0x62, - 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x72, 0x75, - 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x74, - 0x6f, 0x70, 0x20, 0x6f, 0x66, 0xa, 0x74, 0x68, 0x65, 0x20, - 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, - 0x65, 0x6c, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, - 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0x22, 0x20, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x5f, 0x74, 0x6f, - 0x70, 0x22, 0x3e, 0x75, 0x49, 0x50, 0x20, 0x54, 0x43, 0x50, - 0x2f, 0x49, 0x50, 0xa, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x3c, - 0x2f, 0x61, 0x3e, 0x2e, 0xa, 0x3c, 0x2f, 0x70, 0x3e, 0xa, - 0x3c, 0x70, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, - 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, 0x22, 0x3e, 0xa, - 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x20, 0x61, - 0x62, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, - 0x65, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, - 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x65, 0x62, 0xa, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x54, 0x43, 0x50, 0x2f, 0x49, - 0x50, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0xa, 0x3c, - 0x2f, 0x70, 0x3e, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, - 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x3e, 0xa, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, - 0x72, 0x3e, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, }; - -static const char data_control_html[] = { - /* /control.html */ - 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x3c, - 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, - 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, - 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x3d, 0x22, 0x37, 0x39, 0x37, 0x22, 0x20, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x39, 0x34, - 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, - 0x30, 0x22, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x70, 0x61, 0x64, - 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x30, 0x22, 0xa, 0x9, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, - 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x62, 0x61, 0x63, 0x6b, - 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3d, 0x22, 0x2f, 0x69, - 0x6d, 0x67, 0x2f, 0x62, 0x67, 0x2e, 0x70, 0x6e, 0x67, 0x22, - 0x3e, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x20, 0x61, - 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x63, 0x65, 0x6e, 0x74, - 0x65, 0x72, 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x31, 0x3e, 0x75, - 0x49, 0x50, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x70, - 0x61, 0x67, 0x65, 0x73, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, - 0x5b, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, - 0x22, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x2e, 0x68, 0x74, 0x6d, - 0x6c, 0x22, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, - 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x41, 0x62, 0x6f, - 0x75, 0x74, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x7c, 0xa, 0x3c, - 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x63, - 0x67, 0x69, 0x2f, 0x74, 0x63, 0x70, 0x22, 0x20, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, - 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x7c, 0xa, - 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, - 0x63, 0x67, 0x69, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, - 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x6d, - 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x7c, 0xa, 0x3c, 0x61, 0x20, - 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x63, 0x67, 0x69, - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x20, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, - 0x22, 0x3e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, - 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x5d, 0xa, 0x3c, - 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, - 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xa, 0x3c, 0x2f, - 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0xa, 0x3c, 0x2f, - 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, - 0x6d, 0x6c, 0x3e, }; - -static const char data_404_html[] = { - /* /404.html */ - 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, - 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, - 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, - 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, - 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, - 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, - 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, - 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, - 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20, - 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, - 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, - 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f, - 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, - 0x6c, 0x3e, }; - -static const char data_files_footer_plain[] = { - /* /files_footer.plain */ - 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0, - 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, - 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xa, 0x3c, - 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, - 0x74, 0x6d, 0x6c, 0x3e, 0xa, }; - -static const char data_files_header_html[] = { - /* /files_header.html */ - 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x3c, - 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, - 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, - 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x3d, 0x22, 0x36, 0x30, 0x30, 0x22, 0x20, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, - 0x3e, 0xa, }; - -static const char data_index_html[] = { - /* /index.html */ - 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x3c, - 0x68, 0x65, 0x61, 0x64, 0x3e, 0x3c, 0x74, 0x69, 0x74, 0x6c, - 0x65, 0x3e, 0x75, 0x49, 0x50, 0x20, 0x77, 0x65, 0x62, 0x20, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x74, 0x65, 0x73, - 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x74, 0x69, - 0x74, 0x6c, 0x65, 0x3e, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, - 0x3e, 0xa, 0xa, 0x3c, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, - 0x65, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x73, 0x3d, 0x22, 0x2a, - 0x22, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x3d, 0x22, 0x31, 0x32, - 0x30, 0x2c, 0x2a, 0x22, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x6e, 0x6f, - 0x22, 0x3e, 0x20, 0xa, 0x20, 0x20, 0x3c, 0x66, 0x72, 0x61, - 0x6d, 0x65, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, - 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x66, 0x72, 0x61, 0x6d, - 0x65, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x61, 0x62, 0x6f, - 0x75, 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, - 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, - 0x65, 0x74, 0x3e, 0xa, 0xa, 0x3c, 0x6e, 0x6f, 0x66, 0x72, - 0x61, 0x6d, 0x65, 0x73, 0x3e, 0xa, 0x3c, 0x62, 0x6f, 0x64, - 0x79, 0x3e, 0xa, 0x59, 0x6f, 0x75, 0x72, 0x20, 0x62, 0x72, - 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x6d, 0x75, 0x73, 0x74, - 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, - 0x72, 0x61, 0x6d, 0x65, 0x73, 0xa, 0x3c, 0x2f, 0x62, 0x6f, - 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x6e, 0x6f, 0x66, 0x72, - 0x61, 0x6d, 0x65, 0x73, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, - 0x6d, 0x6c, 0x3e, }; - -static const char data_stats_footer_plain[] = { - /* /stats_footer.plain */ - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0, - 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, - 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xa, 0x3c, - 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, - 0x74, 0x6d, 0x6c, 0x3e, 0xa, }; - -static const char data_stats_header_html[] = { - /* /stats_header.html */ - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x3c, - 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, - 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, - 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x3d, 0x22, 0x36, 0x30, 0x30, 0x22, 0x20, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, - 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, - 0xa, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0xa, 0x49, 0x50, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, - 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, - 0x74, 0xa, 0x49, 0x50, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0xa, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x2c, 0x20, 0x68, 0x69, 0x67, 0x68, 0x20, 0x62, - 0x79, 0x74, 0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, - 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x6c, 0x6f, - 0x77, 0x20, 0x62, 0x79, 0x74, 0x65, 0xa, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x49, 0x50, 0x20, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, - 0x6d, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x72, 0x6f, 0x6e, 0x67, - 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xa, - 0x49, 0x43, 0x4d, 0x50, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, - 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, - 0x74, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xa, 0x54, 0x43, 0x50, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, - 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, - 0x74, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x73, 0x75, 0x6d, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x44, 0x61, 0x74, 0x61, 0x20, 0x70, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x6f, 0x75, 0x74, 0x20, 0x41, 0x43, 0x4b, 0x73, 0xa, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x52, 0x65, 0x73, 0x65, 0x74, 0x73, 0xa, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0xa, 0x9, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x6f, 0x20, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, - 0x76, 0x61, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0xa, 0x9, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x74, 0x74, 0x65, - 0x6d, 0x70, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6c, - 0x6f, 0x73, 0x65, 0x64, 0x20, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0xa, 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x9, 0x20, 0x20, - 0x20, 0x20, 0x20, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, - 0x74, 0x64, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, }; - -static const char data_tcp_footer_plain[] = { - /* /tcp_footer.plain */ - 0x2f, 0x74, 0x63, 0x70, 0x5f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0, - 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, - 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xa, - 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0xa, - 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, - 0x68, 0x74, 0x6d, 0x6c, 0x3e, }; - -static const char data_tcp_header_html[] = { - /* /tcp_header.html */ - 0x2f, 0x74, 0x63, 0x70, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x3c, - 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, - 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, - 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x3d, 0x22, 0x36, 0x30, 0x30, 0x22, 0x20, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, - 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, 0x3e, - 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, - 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, - 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, - 0x74, 0x68, 0x3e, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x3c, 0x2f, - 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x46, 0x6c, 0x61, - 0x67, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, - 0x72, 0x3e, 0xa, 0xa, }; - -const struct fsdata_file file_cgi_files[] = {{NULL, data_cgi_files, data_cgi_files + 11, sizeof(data_cgi_files) - 11}}; - -const struct fsdata_file file_cgi_stats[] = {{file_cgi_files, data_cgi_stats, data_cgi_stats + 11, sizeof(data_cgi_stats) - 11}}; - -const struct fsdata_file file_cgi_tcp[] = {{file_cgi_stats, data_cgi_tcp, data_cgi_tcp + 9, sizeof(data_cgi_tcp) - 9}}; - -const struct fsdata_file file_img_bg_png[] = {{file_cgi_tcp, data_img_bg_png, data_img_bg_png + 12, sizeof(data_img_bg_png) - 12}}; - -const struct fsdata_file file_about_html[] = {{file_img_bg_png, data_about_html, data_about_html + 12, sizeof(data_about_html) - 12}}; - -const struct fsdata_file file_control_html[] = {{file_about_html, data_control_html, data_control_html + 14, sizeof(data_control_html) - 14}}; - -const struct fsdata_file file_404_html[] = {{file_control_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}}; - -const struct fsdata_file file_files_footer_plain[] = {{file_404_html, data_files_footer_plain, data_files_footer_plain + 20, sizeof(data_files_footer_plain) - 20}}; - -const struct fsdata_file file_files_header_html[] = {{file_files_footer_plain, data_files_header_html, data_files_header_html + 19, sizeof(data_files_header_html) - 19}}; - -const struct fsdata_file file_index_html[] = {{file_files_header_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}}; - -const struct fsdata_file file_stats_footer_plain[] = {{file_index_html, data_stats_footer_plain, data_stats_footer_plain + 20, sizeof(data_stats_footer_plain) - 20}}; - -const struct fsdata_file file_stats_header_html[] = {{file_stats_footer_plain, data_stats_header_html, data_stats_header_html + 19, sizeof(data_stats_header_html) - 19}}; - -const struct fsdata_file file_tcp_footer_plain[] = {{file_stats_header_html, data_tcp_footer_plain, data_tcp_footer_plain + 18, sizeof(data_tcp_footer_plain) - 18}}; - -const struct fsdata_file file_tcp_header_html[] = {{file_tcp_footer_plain, data_tcp_header_html, data_tcp_header_html + 17, sizeof(data_tcp_header_html) - 17}}; - -#define FS_ROOT file_tcp_header_html - -#define FS_NUMFILES 14 \ No newline at end of file diff --git a/apps/httpd/httpd.c b/apps/httpd/httpd.c deleted file mode 100644 index ad927d0..0000000 --- a/apps/httpd/httpd.c +++ /dev/null @@ -1,371 +0,0 @@ -/** - * \addtogroup exampleapps - * @{ - */ - -/** - * \defgroup httpd Web server - * @{ - * - * The uIP web server is a very simplistic implementation of an HTTP - * server. It can serve web pages and files from a read-only ROM - * filesystem, and provides a very small scripting language. - * - * The script language is very simple and works as follows. Each - * script line starts with a command character, either "i", "t", "c", - * "#" or ".". The "i" command tells the script interpreter to - * "include" a file from the virtual file system and output it to the - * web browser. The "t" command should be followed by a line of text - * that is to be output to the browser. The "c" command is used to - * call one of the C functions from the httpd-cgi.c file. A line that - * starts with a "#" is ignored (i.e., the "#" denotes a comment), and - * the "." denotes the last script line. - * - * The script that produces the file statistics page looks somewhat - * like this: - * - \code -i /header.html -t

File statistics


RemoteStateRetransmissionsTimerFlags
-t
/index.html -c a /index.html -t
/cgi/files -c a /cgi/files -t
/cgi/tcp -c a /cgi/tcp -t
/404.html -c a /404.html -t
-i /footer.plain -. - \endcode - * - */ - - -/** - * \file - * HTTP server. - * \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: httpd.c,v 1.28.2.6 2003/10/07 13:22:27 adam Exp $ - * - */ - - -#include "uip.h" -#include "httpd.h" -#include "fs.h" -#include "fsdata.h" -#include "cgi.h" - -#define NULL (void *)0 - -/* The HTTP server states: */ -#define HTTP_NOGET 0 -#define HTTP_FILE 1 -#define HTTP_TEXT 2 -#define HTTP_FUNC 3 -#define HTTP_END 4 - -#ifdef DEBUG -#include -#define PRINT(x) printf("%s", x) -#define PRINTLN(x) printf("%s\n", x) -#else /* DEBUG */ -#define PRINT(x) -#define PRINTLN(x) -#endif /* DEBUG */ - -struct httpd_state *hs; - -extern const struct fsdata_file file_index_html; -extern const struct fsdata_file file_404_html; - -static void next_scriptline(void); -static void next_scriptstate(void); - -#define ISO_G 0x47 -#define ISO_E 0x45 -#define ISO_T 0x54 -#define ISO_slash 0x2f -#define ISO_c 0x63 -#define ISO_g 0x67 -#define ISO_i 0x69 -#define ISO_space 0x20 -#define ISO_nl 0x0a -#define ISO_cr 0x0d -#define ISO_a 0x61 -#define ISO_t 0x74 -#define ISO_hash 0x23 -#define ISO_period 0x2e - - -/*-----------------------------------------------------------------------------------*/ -/** - * Initialize the web server. - * - * Starts to listen for incoming connection requests on TCP port 80. - */ -/*-----------------------------------------------------------------------------------*/ -void -httpd_init(void) -{ - fs_init(); - - /* Listen to port 80. */ - uip_listen(HTONS(80)); -} -/*-----------------------------------------------------------------------------------*/ -void -httpd_appcall(void) -{ - struct fs_file fsfile; - - u8_t i; - - switch(uip_conn->lport) { - /* This is the web server: */ - case HTONS(80): - /* Pick out the application state from the uip_conn structure. */ - hs = (struct httpd_state *)(uip_conn->appstate); - - /* We use the uip_ test functions to deduce why we were - called. If uip_connected() is non-zero, we were called - because a remote host has connected to us. If - uip_newdata() is non-zero, we were called because the - remote host has sent us new data, and if uip_acked() is - non-zero, the remote host has acknowledged the data we - previously sent to it. */ - if(uip_connected()) { - /* Since we have just been connected with the remote host, we - reset the state for this connection. The ->count variable - contains the amount of data that is yet to be sent to the - remote host, and the ->state is set to HTTP_NOGET to signal - that we haven't received any HTTP GET request for this - connection yet. */ - hs->state = HTTP_NOGET; - hs->count = 0; - return; - - } else if(uip_poll()) { - /* If we are polled ten times, we abort the connection. This is - because we don't want connections lingering indefinately in - the system. */ - if(hs->count++ >= 10) { - uip_abort(); - } - return; - } else if(uip_newdata() && hs->state == HTTP_NOGET) { - /* This is the first data we receive, and it should contain a - GET. */ - - /* Check for GET. */ - if(uip_appdata[0] != ISO_G || - uip_appdata[1] != ISO_E || - uip_appdata[2] != ISO_T || - uip_appdata[3] != ISO_space) { - /* If it isn't a GET, we abort the connection. */ - uip_abort(); - return; - } - - /* Find the file we are looking for. */ - for(i = 4; i < 40; ++i) { - if(uip_appdata[i] == ISO_space || - uip_appdata[i] == ISO_cr || - uip_appdata[i] == ISO_nl) { - uip_appdata[i] = 0; - break; - } - } - - PRINT("request for file "); - PRINTLN(&uip_appdata[4]); - - /* Check for a request for "/". */ - if(uip_appdata[4] == ISO_slash && - uip_appdata[5] == 0) { - fs_open(file_index_html.name, &fsfile); - } else { - if(!fs_open((const char *)&uip_appdata[4], &fsfile)) { - PRINTLN("couldn't open file"); - fs_open(file_404_html.name, &fsfile); - } - } - - - if(uip_appdata[4] == ISO_slash && - uip_appdata[5] == ISO_c && - uip_appdata[6] == ISO_g && - uip_appdata[7] == ISO_i && - uip_appdata[8] == ISO_slash) { - /* If the request is for a file that starts with "/cgi/", we - prepare for invoking a script. */ - hs->script = fsfile.data; - next_scriptstate(); - } else { - hs->script = NULL; - /* The web server is now no longer in the HTTP_NOGET state, but - in the HTTP_FILE state since is has now got the GET from - the client and will start transmitting the file. */ - hs->state = HTTP_FILE; - - /* Point the file pointers in the connection state to point to - the first byte of the file. */ - hs->dataptr = fsfile.data; - hs->count = fsfile.len; - } - } - - - if(hs->state != HTTP_FUNC) { - /* Check if the client (remote end) has acknowledged any data that - we've previously sent. If so, we move the file pointer further - into the file and send back more data. If we are out of data to - send, we close the connection. */ - if(uip_acked()) { - if(hs->count >= uip_conn->len) { - hs->count -= uip_conn->len; - hs->dataptr += uip_conn->len; - } else { - hs->count = 0; - } - - if(hs->count == 0) { - if(hs->script != NULL) { - next_scriptline(); - next_scriptstate(); - } else { - uip_close(); - } - } - } - } else { - /* Call the CGI function. */ - if(cgitab[hs->script[2] - ISO_a](uip_acked())) { - /* If the function returns non-zero, we jump to the next line - in the script. */ - next_scriptline(); - next_scriptstate(); - } - } - - if(hs->state != HTTP_FUNC && !uip_poll()) { - /* Send a piece of data, but not more than the MSS of the - connection. */ - uip_send(hs->dataptr, hs->count); - } - - /* Finally, return to uIP. Our outgoing packet will soon be on its - way... */ - return; - - default: - /* Should never happen. */ - uip_abort(); - break; - } -} -/*-----------------------------------------------------------------------------------*/ -/* next_scriptline(): - * - * Reads the script until it finds a newline. */ -static void -next_scriptline(void) -{ - /* Loop until we find a newline character. */ - do { - ++(hs->script); - } while(hs->script[0] != ISO_nl); - - /* Eat up the newline as well. */ - ++(hs->script); -} -/*-----------------------------------------------------------------------------------*/ -/* next_sciptstate: - * - * Reads one line of script and decides what to do next. - */ -static void -next_scriptstate(void) -{ - struct fs_file fsfile; - u8_t i; - - again: - switch(hs->script[0]) { - case ISO_t: - /* Send a text string. */ - hs->state = HTTP_TEXT; - hs->dataptr = &hs->script[2]; - - /* Calculate length of string. */ - for(i = 0; hs->dataptr[i] != ISO_nl; ++i); - hs->count = i; - break; - case ISO_c: - /* Call a function. */ - hs->state = HTTP_FUNC; - hs->dataptr = NULL; - hs->count = 0; - cgitab[hs->script[2] - ISO_a](0); - break; - case ISO_i: - /* Include a file. */ - hs->state = HTTP_FILE; - if(!fs_open(&hs->script[2], &fsfile)) { - uip_abort(); - } - hs->dataptr = fsfile.data; - hs->count = fsfile.len; - break; - case ISO_hash: - /* Comment line. */ - next_scriptline(); - goto again; - break; - case ISO_period: - /* End of script. */ - hs->state = HTTP_END; - uip_close(); - break; - default: - uip_abort(); - break; - } -} -/*-----------------------------------------------------------------------------------*/ -/** @} */ -/** @} */ diff --git a/apps/httpd/makefsdata b/apps/httpd/makefsdata deleted file mode 100755 index cc655f3..0000000 --- a/apps/httpd/makefsdata +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/perl - -open(OUTPUT, "> fsdata.c"); - -chdir("fs"); -open(FILES, "find . -type f |"); - -while($file = ) { - - # Do not include files in CVS directories nor backup files. - if($file =~ /(CVS|~)/) { - next; - } - - chop($file); - - open(HEADER, "> /tmp/header") || die $!; - if($file =~ /404.html/) { - print(HEADER "HTTP/1.0 404 File not found\r\n"); - } else { - print(HEADER "HTTP/1.0 200 OK\r\n"); - } - print(HEADER "Server: uIP/0.9 (http://dunkels.com/adam/uip/)\r\n"); - if($file =~ /\.html$/) { - print(HEADER "Content-type: text/html\r\n"); - } elsif($file =~ /\.gif$/) { - print(HEADER "Content-type: image/gif\r\n"); - } elsif($file =~ /\.png$/) { - print(HEADER "Content-type: image/png\r\n"); - } elsif($file =~ /\.jpg$/) { - print(HEADER "Content-type: image/jpeg\r\n"); - } else { - print(HEADER "Content-type: text/plain\r\n"); - } - print(HEADER "\r\n"); - close(HEADER); - - unless($file =~ /\.plain$/ || $file =~ /cgi/) { - system("cat /tmp/header $file > /tmp/file"); - } else { - system("cp $file /tmp/file"); - } - - open(FILE, "/tmp/file"); - unlink("/tmp/file"); - unlink("/tmp/header"); - - $file =~ s/\.//; - $fvar = $file; - $fvar =~ s-/-_-g; - $fvar =~ s-\.-_-g; - print(OUTPUT "static const char data".$fvar."[] = {\n"); - print(OUTPUT "\t/* $file */\n\t"); - for($j = 0; $j < length($file); $j++) { - printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); - } - printf(OUTPUT "0,\n"); - - - $i = 0; - while(read(FILE, $data, 1)) { - if($i == 0) { - print(OUTPUT "\t"); - } - printf(OUTPUT "%#02x, ", unpack("C", $data)); - $i++; - if($i == 10) { - print(OUTPUT "\n"); - $i = 0; - } - } - print(OUTPUT "};\n\n"); - close(FILE); - push(@fvars, $fvar); - push(@files, $file); -} - -for($i = 0; $i < @fvars; $i++) { - $file = $files[$i]; - $fvar = $fvars[$i]; - - if($i == 0) { - $prevfile = "NULL"; - } else { - $prevfile = "file" . $fvars[$i - 1]; - } - print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); - print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); - print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); -} - -print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n"); -print(OUTPUT "#define FS_NUMFILES $i"); diff --git a/apps/resolv/Makefile.resolv b/apps/resolv/Makefile.resolv new file mode 100644 index 0000000..94c37d8 --- /dev/null +++ b/apps/resolv/Makefile.resolv @@ -0,0 +1 @@ +APP_SOURCES += resolv.c diff --git a/apps/resolv/resolv.c b/apps/resolv/resolv.c index f068e5c..8afbca6 100644 --- a/apps/resolv/resolv.c +++ b/apps/resolv/resolv.c @@ -1,10 +1,10 @@ /** - * \addtogroup uip + * \addtogroup apps * @{ */ /** - * \defgroup uipdns uIP hostname resolver functions + * \defgroup resolv DNS resolver * @{ * * The uIP DNS resolver functions are used to lookup a hostname and @@ -22,25 +22,25 @@ * \file * DNS host name to IP address resolver. * \author Adam Dunkels - * + * * This file implements a DNS host name to IP address resolver. */ /* * Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -52,15 +52,16 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: resolv.c,v 1.1.2.5 2003/10/06 22:56:44 adam Exp $ + * $Id: resolv.c,v 1.5 2006/06/11 21:46:37 adam Exp $ * */ #include "resolv.h" +#include "uip.h" #include @@ -100,7 +101,7 @@ struct dns_answer { u16_t class; u16_t ttl[2]; u16_t len; - u16_t ipaddr[2]; + uip_ipaddr_t ipaddr; }; struct namemap { @@ -115,7 +116,7 @@ struct namemap { u8_t seqno; u8_t err; char name[32]; - u16_t ipaddr[2]; + uip_ipaddr_t ipaddr; }; #ifndef UIP_CONF_RESOLV_ENTRIES @@ -132,13 +133,13 @@ static u8_t seqno; static struct uip_udp_conn *resolv_conn = NULL; -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** \internal * Walk through a compact encoded DNS name and return the end of it. * * \return The end of the name. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static unsigned char * parse_name(unsigned char *query) { @@ -157,12 +158,12 @@ parse_name(unsigned char *query) /* printf("\n");*/ return query + 1; } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** \internal * Runs through the list of names to see if there are any that have * not yet been queried and, if so, sends out a query. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static void check_entries(void) { @@ -183,7 +184,7 @@ check_entries(void) resolv_found(namemapptr->name, NULL); continue; } - namemapptr->tmr = namemapptr->retries; + namemapptr->tmr = namemapptr->retries; } else { /* printf("Timer %d\n", namemapptr->tmr);*/ /* Its timer has not run out, so we move on to next @@ -225,11 +226,11 @@ check_entries(void) } } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** \internal * Called when new UDP data arrives. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static void newdata(void) { @@ -282,7 +283,7 @@ newdata(void) while(nanswers > 0) { /* The first byte in the answer resource record determines if it is a compressed record or a normal one. */ - if(*nameptr & 0xc0) { + if(*nameptr & 0xc0) { /* Compressed name. */ nameptr +=2; /* printf("Compressed anwser\n");*/ @@ -321,13 +322,13 @@ newdata(void) } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** \internal * The main UDP function. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void -udp_appcall(void) +resolv_appcall(void) { if(uip_udp_conn->rport == HTONS(53)) { if(uip_poll()) { @@ -335,16 +336,16 @@ udp_appcall(void) } if(uip_newdata()) { newdata(); - } + } } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** * Queues a name so that a question for the name will be sent out. * * \param name The hostname that is to be queried. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void resolv_query(char *name) { @@ -376,12 +377,8 @@ resolv_query(char *name) nameptr->state = STATE_NEW; nameptr->seqno = seqno; ++seqno; - - /* if(resolv_conn != NULL) { - dispatcher_emit(uip_signal_poll_udp, resolv_conn, DISPATCHER_BROADCAST); - } */ } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** * Look up a hostname in the array of known hostnames. * @@ -394,7 +391,7 @@ resolv_query(char *name) * address, or NULL if the hostname was not found in the array of * hostnames. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ u16_t * resolv_lookup(char *name) { @@ -406,13 +403,13 @@ resolv_lookup(char *name) for(i = 0; i < RESOLV_ENTRIES; ++i) { nameptr = &names[i]; if(nameptr->state == STATE_DONE && - strcmp(name, nameptr->name) == 0) { + strcmp(name, nameptr->name) == 0) { return nameptr->ipaddr; } } return NULL; -} -/*-----------------------------------------------------------------------------------*/ +} +/*---------------------------------------------------------------------------*/ /** * Obtain the currently configured DNS server. * @@ -420,7 +417,7 @@ resolv_lookup(char *name) * the currently configured DNS server or NULL if no DNS server has * been configured. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ u16_t * resolv_getserver(void) { @@ -429,14 +426,14 @@ resolv_getserver(void) } return resolv_conn->ripaddr; } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** * Configure which DNS server to use for queries. * * \param dnsserver A pointer to a 4-byte representation of the IP * address of the DNS server to be configured. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void resolv_conf(u16_t *dnsserver) { @@ -444,13 +441,13 @@ resolv_conf(u16_t *dnsserver) uip_udp_remove(resolv_conn); } - resolv_conn = uip_udp_new(dnsserver, 53); + resolv_conn = uip_udp_new(dnsserver, HTONS(53)); } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** * Initalize the resolver. */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void resolv_init(void) { @@ -461,7 +458,7 @@ resolv_init(void) } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** @} */ /** @} */ diff --git a/apps/resolv/resolv.h b/apps/resolv/resolv.h index 06b723d..abab34e 100644 --- a/apps/resolv/resolv.h +++ b/apps/resolv/resolv.h @@ -1,5 +1,5 @@ /** - * \addtogroup uipdns + * \addtogroup resolv * @{ */ /** @@ -10,19 +10,19 @@ /* * Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -34,17 +34,21 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: resolv.h,v 1.1.2.3 2003/10/04 21:18:59 adam Exp $ + * $Id: resolv.h,v 1.4 2006/06/11 21:46:37 adam Exp $ * */ #ifndef __RESOLV_H__ #define __RESOLV_H__ -#include "uip.h" +typedef int uip_udp_appstate_t; +void resolv_appcall(void); +#define UIP_UDP_APPCALL resolv_appcall + +#include "uipopt.h" /** * Callback function which is called when a hostname is found. diff --git a/apps/smtp/Makefile.smtp b/apps/smtp/Makefile.smtp new file mode 100644 index 0000000..8b3a5aa --- /dev/null +++ b/apps/smtp/Makefile.smtp @@ -0,0 +1 @@ +APP_SOURCES += smtp.c smtp-strings.c memb.c diff --git a/apps/smtp/makesmtpstrings b/apps/smtp/makesmtpstrings deleted file mode 100755 index 720b358..0000000 --- a/apps/smtp/makesmtpstrings +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/perl - -open(OUTPUTC, "> smtp-strings.c"); -open(OUTPUTH, "> smtp-strings.h"); - -open(FILE, "smtp-strings"); - -while() { - if(/(.+) "(.+)"/) { - $var = $1; - $data = $2; - - printf(OUTPUTC "char $var\[%d] = \n", length($data) + 1); - printf(OUTPUTC "/* $data */\n"); - printf(OUTPUTC "{"); - for($j = 0; $j < length($data); $j++) { - printf(OUTPUTC "%#02x, ", unpack("C", substr($data, $j, 1))); - } - printf(OUTPUTC "};\n"); - - printf(OUTPUTH "extern char $var\[%d];\n", length($data) + 1); - - } -} -exit 0; - -printf(OUTPUT "%#02x, ", unpack("C", $data)); diff --git a/apps/smtp/makestrings b/apps/smtp/makestrings new file mode 100755 index 0000000..bea18a6 --- /dev/null +++ b/apps/smtp/makestrings @@ -0,0 +1,40 @@ +#!/usr/bin/perl + + +sub stringify { + my $name = shift(@_); + open(OUTPUTC, "> $name.c"); + open(OUTPUTH, "> $name.h"); + + open(FILE, "$name"); + + while() { + if(/(.+) "(.+)"/) { + $var = $1; + $data = $2; + + $datan = $data; + $datan =~ s/\\r/\r/g; + $datan =~ s/\\n/\n/g; + $datan =~ s/\\01/\01/g; + $datan =~ s/\\0/\0/g; + + printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1); + printf(OUTPUTC "/* \"$data\" */\n"); + printf(OUTPUTC "{"); + for($j = 0; $j < length($datan); $j++) { + printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1))); + } + printf(OUTPUTC "};\n"); + + printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1); + + } + } + close(OUTPUTC); + close(OUTPUTH); +} +stringify("smtp-strings"); + +exit 0; + diff --git a/apps/smtp/smtp-strings b/apps/smtp/smtp-strings index a9e937c..27f639c 100644 --- a/apps/smtp/smtp-strings +++ b/apps/smtp/smtp-strings @@ -2,8 +2,10 @@ smtp_220 "220" smtp_helo "HELO " smtp_mail_from "MAIL FROM: " smtp_rcpt_to "RCPT TO: " -smtp_data "DATA" +smtp_data "DATA\r\n" smtp_to "To: " smtp_from "From: " smtp_subject "Subject: " -smtp_quit "QUIT" \ No newline at end of file +smtp_quit "QUIT\r\n" +smtp_crnl "\r\n" +smtp_crnlperiodcrnl "\r\n.\r\n" \ No newline at end of file diff --git a/apps/smtp/smtp-strings.c b/apps/smtp/smtp-strings.c index dde1efe..f3981a1 100644 --- a/apps/smtp/smtp-strings.c +++ b/apps/smtp/smtp-strings.c @@ -1,27 +1,70 @@ -char smtp_220[4] = -/* 220 */ +/* + * Copyright (c) 2004, 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: smtp-strings.c,v 1.3 2006/06/11 21:46:37 adam Exp $ + */ +const char smtp_220[4] = +/* "220" */ {0x32, 0x32, 0x30, }; -char smtp_helo[6] = -/* HELO */ +const char smtp_helo[6] = +/* "HELO " */ {0x48, 0x45, 0x4c, 0x4f, 0x20, }; -char smtp_mail_from[12] = -/* MAIL FROM: */ +const char smtp_mail_from[12] = +/* "MAIL FROM: " */ {0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, 0x4d, 0x3a, 0x20, }; -char smtp_rcpt_to[10] = -/* RCPT TO: */ +const char smtp_rcpt_to[10] = +/* "RCPT TO: " */ {0x52, 0x43, 0x50, 0x54, 0x20, 0x54, 0x4f, 0x3a, 0x20, }; -char smtp_data[5] = -/* DATA */ -{0x44, 0x41, 0x54, 0x41, }; -char smtp_to[5] = -/* To: */ +const char smtp_data[7] = +/* "DATA\r\n" */ +{0x44, 0x41, 0x54, 0x41, 0xd, 0xa, }; +const char smtp_to[5] = +/* "To: " */ {0x54, 0x6f, 0x3a, 0x20, }; -char smtp_from[7] = -/* From: */ +const char smtp_cc[5] = +/* "Cc: " */ +{0x43, 0x63, 0x3a, 0x20, }; +const char smtp_from[7] = +/* "From: " */ {0x46, 0x72, 0x6f, 0x6d, 0x3a, 0x20, }; -char smtp_subject[10] = -/* Subject: */ +const char smtp_subject[10] = +/* "Subject: " */ {0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, }; -char smtp_quit[5] = -/* QUIT */ -{0x51, 0x55, 0x49, 0x54, }; +const char smtp_quit[7] = +/* "QUIT\r\n" */ +{0x51, 0x55, 0x49, 0x54, 0xd, 0xa, }; +const char smtp_crnl[3] = +/* "\r\n" */ +{0xd, 0xa, }; +const char smtp_crnlperiodcrnl[6] = +/* "\r\n.\r\n" */ +{0xd, 0xa, 0x2e, 0xd, 0xa, }; diff --git a/apps/smtp/smtp-strings.h b/apps/smtp/smtp-strings.h index 15bed46..f5ae68c 100644 --- a/apps/smtp/smtp-strings.h +++ b/apps/smtp/smtp-strings.h @@ -1,9 +1,46 @@ -extern char smtp_220[4]; -extern char smtp_helo[6]; -extern char smtp_mail_from[12]; -extern char smtp_rcpt_to[10]; -extern char smtp_data[5]; -extern char smtp_to[5]; -extern char smtp_from[7]; -extern char smtp_subject[10]; -extern char smtp_quit[5]; +/* + * Copyright (c) 2004, 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: smtp-strings.h,v 1.3 2006/06/11 21:46:37 adam Exp $ + */ +extern const char smtp_220[4]; +extern const char smtp_helo[6]; +extern const char smtp_mail_from[12]; +extern const char smtp_rcpt_to[10]; +extern const char smtp_data[7]; +extern const char smtp_to[5]; +extern const char smtp_cc[5]; +extern const char smtp_from[7]; +extern const char smtp_subject[10]; +extern const char smtp_quit[7]; +extern const char smtp_crnl[3]; +extern const char smtp_crnlperiodcrnl[6]; diff --git a/apps/smtp/smtp.c b/apps/smtp/smtp.c index fadfe2b..a860006 100644 --- a/apps/smtp/smtp.c +++ b/apps/smtp/smtp.c @@ -1,10 +1,10 @@ /** - * \addtogroup exampleapps + * \addtogroup apps * @{ */ /** - * \defgroup smtp SMTP E-mail sender + * \defgroup smtp SMTP E-mail sender * @{ * * The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is @@ -12,7 +12,7 @@ * Internet. This simple example implementation is intended as an * example of how to implement protocols in uIP, and is able to send * out e-mail but has not been extensively tested. - */ + */ /** * \file @@ -21,61 +21,51 @@ */ /* - * Copyright (c) 2002, Adam Dunkels. - * All rights reserved. + * Copyright (c) 2004, 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. + * 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. Neither the name of the Institute nor the names of its contributors + * may 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 SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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: smtp.c,v 1.1.2.7 2003/10/07 13:47:50 adam Exp $ + * Author: Adam Dunkels * + * $Id: smtp.c,v 1.4 2006/06/11 21:46:37 adam Exp $ */ - -#include "uip.h" #include "smtp.h" #include "smtp-strings.h" +#include "psock.h" +#include "uip.h" #include -#define STATE_SEND_NONE 0 -#define STATE_SEND_HELO 1 -#define STATE_SEND_MAIL_FROM 2 -#define STATE_SEND_RCPT_TO 3 -#define STATE_SEND_DATA 4 -#define STATE_SEND_DATA_HEADERS 5 -#define STATE_SEND_DATA_MESSAGE 6 -#define STATE_SEND_DATA_END 7 -#define STATE_SEND_QUIT 8 -#define STATE_SEND_DONE 9 +static struct smtp_state s; static char *localhostname; -static u16_t smtpserver[2]; - - +static uip_ipaddr_t smtpserver; #define ISO_nl 0x0a #define ISO_cr 0x0d @@ -88,317 +78,129 @@ static u16_t smtpserver[2]; #define ISO_5 0x35 - -/*-----------------------------------------------------------------------------------*/ -static void -senddata(struct smtp_state *s) +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(smtp_thread(void)) { - char *textptr; + PSOCK_BEGIN(&s.psock); - if(s->textlen != 0 && - s->textlen == s->sendptr) { - return; + PSOCK_READTO(&s.psock, ISO_nl); + + if(strncmp(s.inputbuffer, smtp_220, 3) != 0) { + PSOCK_CLOSE(&s.psock); + smtp_done(2); + PSOCK_EXIT(&s.psock); } - - textptr = (char *)uip_appdata; - switch(s->state) { - case STATE_SEND_HELO: - /* Create HELO message. */ - strcpy(textptr, smtp_helo); - textptr += sizeof(smtp_helo) - 1; - strcpy(textptr, localhostname); - textptr += strlen(localhostname); - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - /* printf("s->sendptr %d\n", s->sendptr);*/ - if(s->sendptr == 0) { - s->textlen = textptr - (char *)uip_appdata; - /* printf("s->textlen %d\n", s->textlen);*/ - } - textptr = (char *)uip_appdata; - break; - case STATE_SEND_MAIL_FROM: - /* Create MAIL FROM message. */ - strcpy(textptr, smtp_mail_from); - textptr += sizeof(smtp_mail_from) - 1; - strcpy(textptr, s->from); - textptr += strlen(s->from); - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - if(s->sendptr == 0) { - s->textlen = textptr - (char *)uip_appdata; - } - textptr = (char *)uip_appdata; - break; - case STATE_SEND_RCPT_TO: - /* Create RCPT_TO message. */ - strcpy(textptr, smtp_rcpt_to); - textptr += sizeof(smtp_rcpt_to) - 1; - strcpy(textptr, s->to); - textptr += strlen(s->to); - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - if(s->sendptr == 0) { - s->textlen = textptr - (char *)uip_appdata; - } - textptr = (char *)uip_appdata; - break; - case STATE_SEND_DATA: - strcpy(textptr, smtp_data); - textptr += sizeof(smtp_data) - 1; - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - if(s->sendptr == 0) { - s->textlen = textptr - (char *)uip_appdata; - } - textptr = (char *)uip_appdata; - break; - case STATE_SEND_DATA_HEADERS: - /* Create mail headers-> */ - strcpy(textptr, smtp_to); - textptr += sizeof(smtp_to) - 1; - strcpy(textptr, s->to); - textptr += strlen(s->to); - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - - strcpy(textptr, smtp_from); - textptr += sizeof(smtp_from) - 1; - strcpy(textptr, s->from); - textptr += strlen(s->from); - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - - strcpy(textptr, smtp_subject); - textptr += sizeof(smtp_subject) - 1; - strcpy(textptr, s->subject); - textptr += strlen(s->subject); - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - - if(s->sendptr == 0) { - s->textlen = textptr - (char *)uip_appdata; - } - textptr = (char *)uip_appdata; - break; - case STATE_SEND_DATA_MESSAGE: - textptr = s->msg; - if(s->sendptr == 0) { - s->textlen = s->msglen; - } - break; - case STATE_SEND_DATA_END: - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - *textptr = ISO_period; - ++textptr; - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - if(s->sendptr == 0) { - s->textlen = 5; - } - textptr = (char *)uip_appdata; - break; - case STATE_SEND_QUIT: - strcpy(textptr, smtp_quit); - textptr += sizeof(smtp_quit) - 1; - *textptr = ISO_cr; - ++textptr; - *textptr = ISO_nl; - ++textptr; - if(s->sendptr == 0) { - s->textlen = textptr - (char *)uip_appdata; - } - textptr = (char *)uip_appdata; - break; - default: - return; - } - - textptr += s->sendptr; - if(s->textlen - s->sendptr > uip_mss()) { - s->sentlen = uip_mss(); - } else { - s->sentlen = s->textlen - s->sendptr; - } + PSOCK_SEND_STR(&s.psock, (char *)smtp_helo); + PSOCK_SEND_STR(&s.psock, localhostname); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); - /* textptr[s->sentlen] = 0; - printf("Senidng '%s'\n", textptr);*/ + PSOCK_READTO(&s.psock, ISO_nl); - uip_send(textptr, s->sentlen); -} -/*-----------------------------------------------------------------------------------*/ -static void -acked(struct smtp_state *s) -{ - s->sendptr += s->sentlen; - s->sentlen = 0; + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(3); + PSOCK_EXIT(&s.psock); + } - if(s->sendptr == s->textlen) { - switch(s->state) { - case STATE_SEND_DATA_HEADERS: - s->state = STATE_SEND_DATA_MESSAGE; - s->sendptr = s->textlen = 0; - break; - case STATE_SEND_DATA_MESSAGE: - s->state = STATE_SEND_DATA_END; - s->sendptr = s->textlen = 0; - break; - case STATE_SEND_DATA_END: - s->state = STATE_SEND_QUIT; - s->sendptr = s->textlen = 0; - break; - case STATE_SEND_QUIT: - s->state = STATE_SEND_DONE; - smtp_done(SMTP_ERR_OK); - uip_close(); - break; + PSOCK_SEND_STR(&s.psock, (char *)smtp_mail_from); + PSOCK_SEND_STR(&s.psock, s.from); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(4); + PSOCK_EXIT(&s.psock); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to); + PSOCK_SEND_STR(&s.psock, s.to); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(5); + PSOCK_EXIT(&s.psock); + } + + if(s.cc != 0) { + PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to); + PSOCK_SEND_STR(&s.psock, s.cc); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(6); + PSOCK_EXIT(&s.psock); } } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_data); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_3) { + PSOCK_CLOSE(&s.psock); + smtp_done(7); + PSOCK_EXIT(&s.psock); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_to); + PSOCK_SEND_STR(&s.psock, s.to); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + if(s.cc != 0) { + PSOCK_SEND_STR(&s.psock, (char *)smtp_cc); + PSOCK_SEND_STR(&s.psock, s.cc); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_from); + PSOCK_SEND_STR(&s.psock, s.from); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_SEND_STR(&s.psock, (char *)smtp_subject); + PSOCK_SEND_STR(&s.psock, s.subject); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_SEND(&s.psock, s.msg, s.msglen); + + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnlperiodcrnl); + + PSOCK_READTO(&s.psock, ISO_nl); + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(8); + PSOCK_EXIT(&s.psock); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_quit); + smtp_done(SMTP_ERR_OK); + PSOCK_END(&s.psock); } -/*-----------------------------------------------------------------------------------*/ -static void -newdata(struct smtp_state *s) -{ - if(*(char *)uip_appdata == ISO_5) { - smtp_done(1); - uip_abort(); - return; - } - /* printf("Got %d bytes: '%s'\n", uip_datalen(), - uip_appdata);*/ - switch(s->state) { - case STATE_SEND_NONE: - if(strncmp((char *)uip_appdata, smtp_220, 3) == 0) { - /* printf("Newdata(): SEND_NONE, got 220, towards SEND_HELO\n");*/ - s->state = STATE_SEND_HELO; - s->sendptr = 0; - } - break; - case STATE_SEND_HELO: - if(*(char *)uip_appdata == ISO_2) { - /* printf("Newdata(): SEND_HELO, got 2*, towards SEND_MAIL_FROM\n");*/ - s->state = STATE_SEND_MAIL_FROM; - s->sendptr = 0; - } - break; - case STATE_SEND_MAIL_FROM: - if(*(char *)uip_appdata == ISO_2) { - /* printf("Newdata(): SEND_MAIL_FROM, got 2*, towards SEND_RCPT_TO\n"); */ - /* printf("2\n");*/ - s->state = STATE_SEND_RCPT_TO; - s->textlen = s->sendptr = 0; - } - break; - case STATE_SEND_RCPT_TO: - if(*(char *)uip_appdata == ISO_2) { - /* printf("2\n");*/ - s->state = STATE_SEND_DATA; - s->textlen = s->sendptr = 0; - } - break; - case STATE_SEND_DATA: - if(*(char *)uip_appdata == ISO_3) { - /* printf("3\n");*/ - s->state = STATE_SEND_DATA_HEADERS; - s->textlen = s->sendptr = 0; - } - break; - case STATE_SEND_DATA_HEADERS: - if(*(char *)uip_appdata == ISO_3) { - /* printf("3\n");*/ - s->state = STATE_SEND_DATA_MESSAGE; - s->textlen = s->sendptr = 0; - } - break; - } - -} -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void smtp_appcall(void) { - struct smtp_state *s; - - s = (struct smtp_state *)uip_conn->appstate; - - if(uip_connected()) { - /* senddata();*/ + if(uip_closed()) { + s.connected = 0; return; } - if(uip_acked()) { - acked(s); + if(uip_aborted() || uip_timedout()) { + s.connected = 0; + smtp_done(1); + return; } - if(uip_newdata()) { - newdata(s); - } - if(uip_rexmit() || - uip_newdata() || - uip_acked()) { - senddata(s); - } else if(uip_poll()) { - senddata(s); - } - /* if(uip_closed()) { - printf("Dnoe\n"); - }*/ - - + smtp_thread(); } -/*-----------------------------------------------------------------------------------*/ -/** - * Send an e-mail. - * - * \param to The e-mail address of the receiver of the e-mail. - * \param from The e-mail address of the sender of the e-mail. - * \param subject The subject of the e-mail. - * \param msg The actual e-mail message. - * \param msglen The length of the e-mail message. - */ -/*-----------------------------------------------------------------------------------*/ -unsigned char -smtp_send(char *to, char *from, char *subject, - char *msg, u16_t msglen) -{ - struct uip_conn *conn; - struct smtp_state *s; - - conn = uip_connect(smtpserver, HTONS(25)); - if(conn == NULL) { - return 0; - } - s = conn->appstate; - - s->state = STATE_SEND_NONE; - s->sentlen = s->sendptr = s->textlen = 0; - s->to = to; - s->from = from; - s->subject = subject; - s->msg = msg; - s->msglen = msglen; - - return 1; -} -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /** * Specificy an SMTP server and hostname. * @@ -410,13 +212,51 @@ smtp_send(char *to, char *from, char *subject, * \param server A pointer to a 4-byte array representing the IP * address of the SMTP server to be configured. */ -/*-----------------------------------------------------------------------------------*/ void -smtp_configure(char *lhostname, u16_t *server) +smtp_configure(char *lhostname, void *server) { localhostname = lhostname; - smtpserver[0] = server[0]; - smtpserver[1] = server[1]; + uip_ipaddr_copy(smtpserver, server); } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/** + * Send an e-mail. + * + * \param to The e-mail address of the receiver of the e-mail. + * \param cc The e-mail address of the CC: receivers of the e-mail. + * \param from The e-mail address of the sender of the e-mail. + * \param subject The subject of the e-mail. + * \param msg The actual e-mail message. + * \param msglen The length of the e-mail message. + */ +unsigned char +smtp_send(char *to, char *cc, char *from, + char *subject, char *msg, u16_t msglen) +{ + struct uip_conn *conn; + + conn = uip_connect(smtpserver, HTONS(25)); + if(conn == NULL) { + return 0; + } + s.connected = 1; + s.to = to; + s.cc = cc; + s.from = from; + s.subject = subject; + s.msg = msg; + s.msglen = msglen; + + PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer)); + + return 1; +} +/*---------------------------------------------------------------------------*/ +void +smtp_init(void) +{ + s.connected = 0; +} +/*---------------------------------------------------------------------------*/ +/** @} */ /** @} */ diff --git a/apps/smtp/smtp.h b/apps/smtp/smtp.h index 8eae70b..44d0766 100644 --- a/apps/smtp/smtp.h +++ b/apps/smtp/smtp.h @@ -13,19 +13,19 @@ /* * Copyright (c) 2002, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -37,11 +37,11 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: smtp.h,v 1.1.2.4 2003/10/06 22:56:45 adam Exp $ + * $Id: smtp.h,v 1.4 2006/06/11 21:46:37 adam Exp $ * */ #ifndef __SMTP_H__ @@ -66,11 +66,15 @@ */ void smtp_done(unsigned char error); +void smtp_init(void); + /* Functions. */ void smtp_configure(char *localhostname, u16_t *smtpserver); unsigned char smtp_send(char *to, char *from, char *subject, char *msg, u16_t msglen); +#define SMTP_SEND(to, cc, from, subject, msg) \ + smtp_send(to, cc, from, subject, msg, strlen(msg)) void smtp_appcall(void); @@ -91,10 +95,9 @@ struct smtp_state { #ifndef UIP_APPCALL #define UIP_APPCALL smtp_appcall #endif - -#ifndef UIP_APPSTATE_SIZE -#define UIP_APPSTATE_SIZE (sizeof(struct smtp_state)) -#endif +typedef struct smtp_state uip_tcp_appstate_t; #endif /* __SMTP_H__ */ + +/** @} */ diff --git a/apps/telnet/telnet.c b/apps/telnet/telnet.c deleted file mode 100644 index f72b6fc..0000000 --- a/apps/telnet/telnet.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2002, 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: telnet.c,v 1.1.2.3 2003/10/06 11:20:45 adam Exp $ - * - */ - -#include "uip.h" - -#include "telnet.h" - -#ifndef NULL -#define NULL (void *)0 -#endif /* NULL */ - -#define FLAG_CLOSE 1 -#define FLAG_ABORT 2 -/*-----------------------------------------------------------------------------------*/ -unsigned char -telnet_send(struct telnet_state *s, char *text, u16_t len) -{ - if(s->text != NULL) { - return 1; - } - s->text = text; - s->textlen = len; - s->sentlen = 0; - return 0; -} -/*-----------------------------------------------------------------------------------*/ -unsigned char -telnet_close(struct telnet_state *s) -{ - s->flags = FLAG_CLOSE; - if(s->text != NULL) { - return 1; - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ -unsigned char -telnet_abort(struct telnet_state *s) -{ - s->flags = FLAG_ABORT; - if(s->text != NULL) { - return 1; - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ -static void -acked(struct telnet_state *s) -{ - s->textlen -= s->sentlen; - if(s->textlen == 0) { - s->text = NULL; - telnet_sent(s); - } else { - s->text += s->sentlen; - } - s->sentlen = 0; -} -/*-----------------------------------------------------------------------------------*/ -static void -senddata(struct telnet_state *s) -{ - if(s->text == NULL) { - uip_send(s->text, 0); - return; - } - if(s->textlen > uip_mss()) { - s->sentlen = uip_mss(); - } else { - s->sentlen = s->textlen; - } - uip_send(s->text, s->sentlen); -} -/*-----------------------------------------------------------------------------------*/ -void telnet_app(void) -{ - struct telnet_state *s = (struct telnet_state *)uip_conn->appstate; - - if(uip_connected()) { - s->flags = 0; - telnet_connected(s); - senddata(s); - return; - } - - if(uip_closed()) { - telnet_closed(s); - } - - if(uip_aborted()) { - telnet_aborted(s); - } - if(uip_timedout()) { - telnet_timedout(s); - } - - - if(s->flags & FLAG_CLOSE) { - uip_close(); - return; - } - if(s->flags & FLAG_ABORT) { - uip_abort(); - return; - } - if(uip_acked()) { - acked(s); - } - if(uip_newdata()) { - telnet_newdata(s, (char *)uip_appdata, uip_datalen()); - } - if(uip_rexmit() || - uip_newdata() || - uip_acked()) { - senddata(s); - } else if(uip_poll()) { - senddata(s); - } -} -/*-----------------------------------------------------------------------------------*/ diff --git a/apps/telnetd/Makefile.telnetd b/apps/telnetd/Makefile.telnetd new file mode 100644 index 0000000..afb1b59 --- /dev/null +++ b/apps/telnetd/Makefile.telnetd @@ -0,0 +1 @@ +APP_SOURCES += telnetd.c shell.c memb.c diff --git a/apps/telnetd/memb.c b/apps/telnetd/memb.c deleted file mode 100644 index a2079a2..0000000 --- a/apps/telnetd/memb.c +++ /dev/null @@ -1,152 +0,0 @@ -/** - * \addtogroup exampleapps - * @{ - */ - -/** - * \file - * Memory block allocation routines. - * \author Adam Dunkels - * - * The memory block allocation routines provide a simple yet powerful - * set of functions for managing a set of memory blocks of fixed - * size. A set of memory blocks is statically declared with the - * MEMB() macro. Memory blocks are allocated from the declared - * memory by the memb_alloc() function, and are deallocated with the - * memb_free() function. - * - * \note Because of namespace clashes only one MEMB() can be - * declared per C module, and the name scope of a MEMB() memory - * block is local to each C module. - * - * The following example shows how to declare and use a memory block - * called "cmem" which has 8 chunks of memory with each memory chunk - * being 20 bytes large. - * - \code - MEMB(cmem, 20, 8); - - int main(int argc, char *argv[]) { - char *ptr; - - memb_init(&cmem); - - ptr = memb_alloc(&cmem); - - if(ptr != NULL) { - do_something(ptr); - } else { - printf("Could not allocate memory.\n"); - } - - if(memb_free(ptr) == 0) { - printf("Deallocation succeeded.\n"); - } - } - \endcode - * - */ - -#include - -#include "memb.h" - -/*------------------------------------------------------------------------------*/ -/** - * Initialize a memory block that was declared with MEMB(). - * - * \param m A memory block previosly declared with MEMB(). - */ -/*------------------------------------------------------------------------------*/ -void -memb_init(struct memb_blocks *m) -{ - memset(m->mem, (m->size + 1) * m->num, 0); -} -/*------------------------------------------------------------------------------*/ -/** - * Allocate a memory block from a block of memory declared with MEMB(). - * - * \param m A memory block previosly declared with MEMB(). - */ -/*------------------------------------------------------------------------------*/ -char * -memb_alloc(struct memb_blocks *m) -{ - int i; - char *ptr; - - ptr = m->mem; - for(i = 0; i < m->num; ++i) { - if(*ptr == 0) { - /* If this block was unused, we increase the reference count to - indicate that it now is used and return a pointer to the - first byte following the reference counter. */ - ++*ptr; - return ptr + 1; - } - ptr += m->size + 1; - } - - /* No free block was found, so we return NULL to indicate failure to - allocate block. */ - return NULL; -} -/*------------------------------------------------------------------------------*/ -/** - * Deallocate a memory block from a memory block previously declared - * with MEMB(). - * - * \param m m A memory block previosly declared with MEMB(). - * - * \param ptr A pointer to the memory block that is to be deallocated. - * - * \return The new reference count for the memory block (should be 0 - * if successfully deallocated) or -1 if the pointer "ptr" did not - * point to a legal memory block. - */ -/*------------------------------------------------------------------------------*/ -char -memb_free(struct memb_blocks *m, char *ptr) -{ - int i; - char *ptr2; - - /* Walk through the list of blocks and try to find the block to - which the pointer "ptr" points to. */ - ptr2 = m->mem; - for(i = 0; i < m->num; ++i) { - - if(ptr2 == ptr - 1) { - /* We've found to block to which "ptr" points so we decrease the - reference count and return the new value of it. */ - return --*ptr2; - } - ptr2 += m->size + 1; - } - return -1; -} -/*------------------------------------------------------------------------------*/ -/** - * Increase the reference count for a memory chunk. - * - * \note No sanity checks are currently made. - * - * \param m m A memory block previosly declared with MEMB(). - * - * \param ptr A pointer to the memory chunk for which the reference - * count should be increased. - * - * \return The new reference count. - */ -/*------------------------------------------------------------------------------*/ -char -memb_ref(struct memb_blocks *m, char *ptr) -{ - return ++*(ptr - 1); -} -/*------------------------------------------------------------------------------*/ - - - - diff --git a/apps/telnetd/memb.h b/apps/telnetd/memb.h deleted file mode 100644 index d073b30..0000000 --- a/apps/telnetd/memb.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * \addtogroup exampleapps - * @{ - */ - -/** - * \file - * Memory block allocation routines. - * \author Adam Dunkels - * - */ - -#ifndef __MEMB_H__ -#define __MEMB_H__ - -/** - * Declare a memory block. - * - * \param name The name of the memory block (later used with - * memb_init(), memb_alloc() and memb_free()). - * - * \param size The size of each memory chunk, in bytes. - * - * \param num The total number of memory chunks in the block. - * - */ -#define MEMB(name, size, num) \ - static char memb_mem[(size + 1) * num]; \ - static struct memb_blocks name = {size, num, memb_mem} - -struct memb_blocks { - unsigned short size; - unsigned short num; - char *mem; -}; - -void memb_init(struct memb_blocks *m); -char *memb_alloc(struct memb_blocks *m); -char memb_ref(struct memb_blocks *m, char *ptr); -char memb_free(struct memb_blocks *m, char *ptr); - - -#endif /* __MEMB_H__ */ diff --git a/apps/telnetd/shell.c b/apps/telnetd/shell.c new file mode 100644 index 0000000..9345cae --- /dev/null +++ b/apps/telnetd/shell.c @@ -0,0 +1,123 @@ + /* + * Copyright (c) 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: shell.c,v 1.1 2006/06/07 09:43:54 adam Exp $ + * + */ + +#include "shell.h" + +#include + +struct ptentry { + char *commandstr; + void (* pfunc)(char *str); +}; + +#define SHELL_PROMPT "uIP 1.0> " + +/*---------------------------------------------------------------------------*/ +static void +parse(register char *str, struct ptentry *t) +{ + struct ptentry *p; + for(p = t; p->commandstr != NULL; ++p) { + if(strncmp(p->commandstr, str, strlen(p->commandstr)) == 0) { + break; + } + } + + p->pfunc(str); +} +/*---------------------------------------------------------------------------*/ +static void +inttostr(register char *str, unsigned int i) +{ + str[0] = '0' + i / 100; + if(str[0] == '0') { + str[0] = ' '; + } + str[1] = '0' + (i / 10) % 10; + if(str[0] == ' ' && str[1] == '0') { + str[1] = ' '; + } + str[2] = '0' + i % 10; + str[3] = ' '; + str[4] = 0; +} +/*---------------------------------------------------------------------------*/ +static void +help(char *str) +{ + shell_output("Available commands:", ""); + shell_output("stats - show network statistics", ""); + shell_output("conn - show TCP connections", ""); + shell_output("help, ? - show help", ""); + shell_output("exit - exit shell", ""); +} +/*---------------------------------------------------------------------------*/ +static void +unknown(char *str) +{ + if(strlen(str) > 0) { + shell_output("Unknown command: ", str); + } +} +/*---------------------------------------------------------------------------*/ +static struct ptentry parsetab[] = + {{"stats", help}, + {"conn", help}, + {"help", help}, + {"exit", shell_quit}, + {"?", help}, + + /* Default action */ + {NULL, unknown}}; +/*---------------------------------------------------------------------------*/ +void +shell_init(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +shell_start(void) +{ + shell_output("uIP command shell", ""); + shell_output("Type '?' and return for help", ""); + shell_prompt(SHELL_PROMPT); +} +/*---------------------------------------------------------------------------*/ +void +shell_input(char *cmd) +{ + parse(cmd, parsetab); + shell_prompt(SHELL_PROMPT); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/telnetd/shell.h b/apps/telnetd/shell.h new file mode 100644 index 0000000..b57d7be --- /dev/null +++ b/apps/telnetd/shell.h @@ -0,0 +1,104 @@ +/** + * \file + * Interface for the Contiki shell. + * \author Adam Dunkels + * + * Some of the functions declared in this file must be implemented as + * a shell back-end in the architecture specific files of a Contiki + * port. + */ + + +/* + * Copyright (c) 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 Contiki desktop OS. + * + * $Id: shell.h,v 1.1 2006/06/07 09:43:54 adam Exp $ + * + */ +#ifndef __SHELL_H__ +#define __SHELL_H__ + +/** + * Initialize the shell. + * + * Called when the shell front-end process starts. This function may + * be used to start listening for signals. + */ +void shell_init(void); + +/** + * Start the shell back-end. + * + * Called by the front-end when a new shell is started. + */ +void shell_start(void); + +/** + * Process a shell command. + * + * This function will be called by the shell GUI / telnet server whan + * a command has been entered that should be processed by the shell + * back-end. + * + * \param command The command to be processed. + */ +void shell_input(char *command); + +/** + * Quit the shell. + * + */ +void shell_quit(char *); + + +/** + * Print a string to the shell window. + * + * This function is implemented by the shell GUI / telnet server and + * can be called by the shell back-end to output a string in the + * shell window. The string is automatically appended with a linebreak. + * + * \param str1 The first half of the string to be output. + * \param str2 The second half of the string to be output. + */ +void shell_output(char *str1, char *str2); + +/** + * Print a prompt to the shell window. + * + * This function can be used by the shell back-end to print out a + * prompt to the shell window. + * + * \param prompt The prompt to be printed. + * + */ +void shell_prompt(char *prompt); + +#endif /* __SHELL_H__ */ diff --git a/apps/telnetd/telnetd-shell.c b/apps/telnetd/telnetd-shell.c deleted file mode 100644 index d5abfb8..0000000 --- a/apps/telnetd/telnetd-shell.c +++ /dev/null @@ -1,181 +0,0 @@ -/** - * \addtogroup telnetd - * @{ - */ - -/** - * \file - * An example telnet server shell - * \author Adam Dunkels - */ - -/* - * Copyright (c) 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 Contiki desktop OS. - * - * $Id: telnetd-shell.c,v 1.1.2.1 2003/10/06 22:56:22 adam Exp $ - * - */ - -#include "uip.h" -#include "telnetd.h" -#include - -struct ptentry { - char c; - void (* pfunc)(struct telnetd_state *s, char *str); -}; - -/*-----------------------------------------------------------------------------------*/ -static void -parse(struct telnetd_state *s, register char *str, struct ptentry *t) -{ - register struct ptentry *p; - char *sstr; - - sstr = str; - - /* Loop over the parse table entries in t in order to find one that - matches the first character in str. */ - for(p = t; p->c != 0; ++p) { - if(*str == p->c) { - /* Skip rest of the characters up to the first space. */ - while(*str != ' ') { - ++str; - } - - /* Skip all spaces.*/ - while(*str == ' ') { - ++str; - } - - /* Call parse table entry function and return. */ - p->pfunc(s, str); - return; - } - } - - /* Did not find matching entry in parse table. We just call the - default handler supplied by the caller and return. */ - p->pfunc(s, str); -} -/*-----------------------------------------------------------------------------------*/ -static void -exitt(struct telnetd_state *s, char *str) -{ - telnetd_close(s); -} -/*-----------------------------------------------------------------------------------*/ -static void -inttostr(register char *str, unsigned int i) -{ - str[0] = '0' + i / 100; - if(str[0] == '0') { - str[0] = ' '; - } - str[1] = '0' + (i / 10) % 10; - if(str[1] == '0') { - str[1] = ' '; - } - str[2] = '0' + i % 10; - str[3] = ' '; - str[4] = 0; -} -/*-----------------------------------------------------------------------------------*/ -static void -stats(struct telnetd_state *s, char *strr) -{ - char str[10]; - - inttostr(str, uip_stat.ip.recv); - telnetd_output(s, "IP packets received ", str); - inttostr(str, uip_stat.ip.sent); - telnetd_output(s, "IP packets sent ", str); - inttostr(str, uip_stat.ip.drop); - telnetd_output(s, "IP packets dropped ", str); - - inttostr(str, uip_stat.icmp.recv); - telnetd_output(s, "ICMP packets received ", str); - inttostr(str, uip_stat.icmp.sent); - telnetd_output(s, "ICMP packets sent ", str); - inttostr(str, uip_stat.icmp.drop); - telnetd_output(s, "ICMP packets dropped ", str); - - inttostr(str, uip_stat.tcp.recv); - telnetd_output(s, "TCP packets received ", str); - inttostr(str, uip_stat.tcp.sent); - telnetd_output(s, "TCP packets sent ", str); - inttostr(str, uip_stat.tcp.drop); - telnetd_output(s, "TCP packets dropped ", str); - inttostr(str, uip_stat.tcp.rexmit); - telnetd_output(s, "TCP packets retransmitted ", str); - inttostr(str, uip_stat.tcp.synrst); - telnetd_output(s, "TCP connection attempts ", str); -} -/*-----------------------------------------------------------------------------------*/ -static void -help(struct telnetd_state *s, char *str) -{ - telnetd_output(s, "Available commands:", ""); - telnetd_output(s, "stats - show uIP statistics", ""); - telnetd_output(s, "exit - exit shell", ""); - telnetd_output(s, "? - show this help", ""); -} -/*-----------------------------------------------------------------------------------*/ -static void -none(struct telnetd_state *s, char *str) -{ - if(strlen(str) > 0) { - telnetd_output(s, "Unknown command", ""); - } -} -/*-----------------------------------------------------------------------------------*/ -static struct ptentry configparsetab[] = - {{'s', stats}, - {'e', exitt}, - {'?', help}, - - /* Default action */ - {0, none}}; -/*-----------------------------------------------------------------------------------*/ -void -telnetd_connected(struct telnetd_state *s) -{ - telnetd_output(s, "uIP command shell", ""); - telnetd_output(s, "Type '?' for help", ""); - telnetd_prompt(s, "uIP-0.9> "); -} -/*-----------------------------------------------------------------------------------*/ -void -telnetd_input(struct telnetd_state *s, char *cmd) -{ - parse(s, cmd, configparsetab); - telnetd_prompt(s, "uIP-0.9> "); -} -/*-----------------------------------------------------------------------------------*/ diff --git a/apps/telnetd/telnetd.c b/apps/telnetd/telnetd.c index 9c7e49e..7a5ae85 100644 --- a/apps/telnetd/telnetd.c +++ b/apps/telnetd/telnetd.c @@ -1,50 +1,18 @@ -/** - * \addtogroup exampleapps - * @{ - */ - -/** - * \defgroup telnetd Telnet server - * @{ - * - * The uIP telnet server provides a command based interface to uIP. It - * allows using the "telnet" application to access uIP, and implements - * the required telnet option negotiation. - * - * The code is structured in a way which makes it possible to add - * commands without having to rewrite the main telnet code. The main - * telnet code calls two callback functions, telnetd_connected() and - * telnetd_input(), when a telnet connection has been established and - * when a line of text arrives on a telnet connection. These two - * functions can be implemented in a way which suits the particular - * application or environment in which the uIP system is intended to - * be run. - * - * The uIP distribution contains an example telnet shell - * implementation that provides a basic set of commands. - */ - -/** - * \file - * Implementation of the Telnet server. - * \author Adam Dunkels - */ - /* * Copyright (c) 2003, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -56,199 +24,199 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * This file is part of the uIP TCP/IP stack. + * This file is part of the uIP TCP/IP stack * - * $Id: telnetd.c,v 1.1.2.2 2003/10/07 13:47:50 adam Exp $ + * $Id: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $ * */ #include "uip.h" -#include "memb.h" #include "telnetd.h" +#include "memb.h" +#include "shell.h" + #include #define ISO_nl 0x0a #define ISO_cr 0x0d -MEMB(linemem, TELNETD_LINELEN, TELNETD_NUMLINES); - -static u8_t i; +struct telnetd_line { + char line[TELNETD_CONF_LINELEN]; +}; +MEMB(linemem, struct telnetd_line, TELNETD_CONF_NUMLINES); #define STATE_NORMAL 0 #define STATE_IAC 1 #define STATE_WILL 2 #define STATE_WONT 3 -#define STATE_DO 4 +#define STATE_DO 4 #define STATE_DONT 5 #define STATE_CLOSE 6 +static struct telnetd_state s; + #define TELNET_IAC 255 #define TELNET_WILL 251 #define TELNET_WONT 252 #define TELNET_DO 253 #define TELNET_DONT 254 -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static char * alloc_line(void) -{ +{ return memb_alloc(&linemem); } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static void dealloc_line(char *line) { memb_free(&linemem, line); } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +void +shell_quit(char *str) +{ + s.state = STATE_CLOSE; +} +/*---------------------------------------------------------------------------*/ static void -sendline(struct telnetd_state *s, char *line) +sendline(char *line) { static unsigned int i; - for(i = 0; i < TELNETD_NUMLINES; ++i) { - if(s->lines[i] == NULL) { - s->lines[i] = line; + + for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) { + if(s.lines[i] == NULL) { + s.lines[i] = line; break; } } - if(i == TELNETD_NUMLINES) { + if(i == TELNETD_CONF_NUMLINES) { dealloc_line(line); } } -/*-----------------------------------------------------------------------------------*/ -/** - * Close a telnet session. - * - * This function can be called from a telnet command in order to close - * the connection. - * - * \param s The connection which is to be closed. - * - */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void -telnetd_close(struct telnetd_state *s) -{ - s->state = STATE_CLOSE; -} -/*-----------------------------------------------------------------------------------*/ -/** - * Print a prompt on a telnet connection. - * - * This function can be called by the telnet command shell in order to - * print out a command prompt. - * - * \param s A telnet connection. - * - * \param str The command prompt. - * - */ -/*-----------------------------------------------------------------------------------*/ -void -telnetd_prompt(struct telnetd_state *s, char *str) +shell_prompt(char *str) { char *line; line = alloc_line(); if(line != NULL) { - strncpy(line, str, TELNETD_LINELEN); - sendline(s, line); - } + strncpy(line, str, TELNETD_CONF_LINELEN); + /* petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/ + sendline(line); + } } -/*-----------------------------------------------------------------------------------*/ -/** - * Print out a string on a telnet connection. - * - * This function can be called from a telnet command parser in order - * to print out a string of text on the connection. The two strings - * given as arguments to the function will be concatenated, a carrige - * return and a new line character will be added, and the line is - * sent. - * - * \param s The telnet connection. - * - * \param str1 The first string. - * - * \param str2 The second string. - * - */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void -telnetd_output(struct telnetd_state *s, char *str1, char *str2) +shell_output(char *str1, char *str2) { static unsigned len; char *line; - + line = alloc_line(); if(line != NULL) { len = strlen(str1); - strncpy(line, str1, TELNETD_LINELEN); - if(len < TELNETD_LINELEN) { - strncpy(line + len, str2, TELNETD_LINELEN - len); + strncpy(line, str1, TELNETD_CONF_LINELEN); + if(len < TELNETD_CONF_LINELEN) { + strncpy(line + len, str2, TELNETD_CONF_LINELEN - len); } len = strlen(line); - if(len < TELNETD_LINELEN - 2) { + if(len < TELNETD_CONF_LINELEN - 2) { line[len] = ISO_cr; line[len+1] = ISO_nl; line[len+2] = 0; } - sendline(s, line); + /* petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/ + sendline(line); } } -/*-----------------------------------------------------------------------------------*/ -/** - * Initialize the telnet server. - * - * This function will perform the necessary initializations and start - * listening on TCP port 23. - */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void telnetd_init(void) { - memb_init(&linemem); uip_listen(HTONS(23)); + memb_init(&linemem); + shell_init(); } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static void -acked(struct telnetd_state *s) +acked(void) { - dealloc_line(s->lines[0]); - for(i = 1; i < TELNETD_NUMLINES; ++i) { - s->lines[i - 1] = s->lines[i]; + static unsigned int i; + + while(s.numsent > 0) { + dealloc_line(s.lines[0]); + for(i = 1; i < TELNETD_CONF_NUMLINES; ++i) { + s.lines[i - 1] = s.lines[i]; + } + s.lines[TELNETD_CONF_NUMLINES - 1] = NULL; + --s.numsent; } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static void -senddata(struct telnetd_state *s) +senddata(void) { - if(s->lines[0] != NULL) { - uip_send(s->lines[0], strlen(s->lines[0])); + static char *bufptr, *lineptr; + static int buflen, linelen; + + bufptr = uip_appdata; + buflen = 0; + for(s.numsent = 0; s.numsent < TELNETD_CONF_NUMLINES && + s.lines[s.numsent] != NULL ; ++s.numsent) { + lineptr = s.lines[s.numsent]; + linelen = strlen(lineptr); + if(linelen > TELNETD_CONF_LINELEN) { + linelen = TELNETD_CONF_LINELEN; + } + if(buflen + linelen < uip_mss()) { + memcpy(bufptr, lineptr, linelen); + bufptr += linelen; + buflen += linelen; + } else { + break; + } + } + uip_send(uip_appdata, buflen); +} +/*---------------------------------------------------------------------------*/ +static void +closed(void) +{ + static unsigned int i; + + for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) { + if(s.lines[i] != NULL) { + dealloc_line(s.lines[i]); + } } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static void -getchar(struct telnetd_state *s, u8_t c) +get_char(u8_t c) { if(c == ISO_cr) { return; } - s->buf[(int)s->bufptr] = c; - if(s->buf[(int)s->bufptr] == ISO_nl || - s->bufptr == sizeof(s->buf) - 1) { - if(s->bufptr > 0) { - s->buf[(int)s->bufptr] = 0; + s.buf[(int)s.bufptr] = c; + if(s.buf[(int)s.bufptr] == ISO_nl || + s.bufptr == sizeof(s.buf) - 1) { + if(s.bufptr > 0) { + s.buf[(int)s.bufptr] = 0; + /* petsciiconv_topetscii(s.buf, TELNETD_CONF_LINELEN);*/ } - telnetd_input(s, s->buf); - s->bufptr = 0; + shell_input(s.buf); + s.bufptr = 0; } else { - ++s->bufptr; + ++s.bufptr; } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static void -sendopt(struct telnetd_state *s, u8_t option, u8_t value) +sendopt(u8_t option, u8_t value) { char *line; line = alloc_line(); @@ -257,136 +225,126 @@ sendopt(struct telnetd_state *s, u8_t option, u8_t value) line[1] = option; line[2] = value; line[3] = 0; - sendline(s, line); - } + sendline(line); + } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ static void -newdata(struct telnetd_state *s) +newdata(void) { u16_t len; u8_t c; + char *dataptr; len = uip_datalen(); + dataptr = (char *)uip_appdata; - while(len > 0 && s->bufptr < sizeof(s->buf)) { - c = *uip_appdata; - ++uip_appdata; + while(len > 0 && s.bufptr < sizeof(s.buf)) { + c = *dataptr; + ++dataptr; --len; - switch(s->state) { + switch(s.state) { case STATE_IAC: if(c == TELNET_IAC) { - getchar(s, c); - s->state = STATE_NORMAL; + get_char(c); + s.state = STATE_NORMAL; } else { switch(c) { case TELNET_WILL: - s->state = STATE_WILL; + s.state = STATE_WILL; break; case TELNET_WONT: - s->state = STATE_WONT; + s.state = STATE_WONT; break; case TELNET_DO: - s->state = STATE_DO; + s.state = STATE_DO; break; case TELNET_DONT: - s->state = STATE_DONT; + s.state = STATE_DONT; break; default: - s->state = STATE_NORMAL; + s.state = STATE_NORMAL; break; } } break; case STATE_WILL: /* Reply with a DONT */ - sendopt(s, TELNET_DONT, c); - s->state = STATE_NORMAL; + sendopt(TELNET_DONT, c); + s.state = STATE_NORMAL; break; case STATE_WONT: /* Reply with a DONT */ - sendopt(s, TELNET_DONT, c); - s->state = STATE_NORMAL; + sendopt(TELNET_DONT, c); + s.state = STATE_NORMAL; break; case STATE_DO: /* Reply with a WONT */ - sendopt(s, TELNET_WONT, c); - s->state = STATE_NORMAL; + sendopt(TELNET_WONT, c); + s.state = STATE_NORMAL; break; case STATE_DONT: /* Reply with a WONT */ - sendopt(s, TELNET_WONT, c); - s->state = STATE_NORMAL; + sendopt(TELNET_WONT, c); + s.state = STATE_NORMAL; break; case STATE_NORMAL: if(c == TELNET_IAC) { - s->state = STATE_IAC; + s.state = STATE_IAC; } else { - getchar(s, c); - } + get_char(c); + } break; - } + } - } + } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void -telnetd_app(void) +telnetd_appcall(void) { - struct telnetd_state *s; - - s = (struct telnetd_state *)uip_conn->appstate; - + static unsigned int i; if(uip_connected()) { - - for(i = 0; i < TELNETD_NUMLINES; ++i) { - s->lines[i] = NULL; + /* tcp_markconn(uip_conn, &s);*/ + for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) { + s.lines[i] = NULL; } - s->bufptr = 0; - s->state = STATE_NORMAL; + s.bufptr = 0; + s.state = STATE_NORMAL; - telnetd_connected(s); - senddata(s); - return; + shell_start(); } - if(s->state == STATE_CLOSE) { - s->state = STATE_NORMAL; + if(s.state == STATE_CLOSE) { + s.state = STATE_NORMAL; uip_close(); return; } - if(uip_closed()) { - telnetd_output(s, "Connection closed", ""); - } - - - if(uip_aborted()) { - telnetd_output(s, "Connection reset", ""); - } - - if(uip_timedout()) { - telnetd_output(s, "Connection timed out", ""); + if(uip_closed() || + uip_aborted() || + uip_timedout()) { + closed(); } if(uip_acked()) { - acked(s); + acked(); } if(uip_newdata()) { - newdata(s); + newdata(); } if(uip_rexmit() || uip_newdata() || - uip_acked()) { - senddata(s); - } else if(uip_poll()) { - senddata(s); + uip_acked() || + uip_connected() || + uip_poll()) { + senddata(); } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/apps/telnetd/telnetd.h b/apps/telnetd/telnetd.h index 9f292cf..2ee8acd 100644 --- a/apps/telnetd/telnetd.h +++ b/apps/telnetd/telnetd.h @@ -1,29 +1,19 @@ -/** - * \addtogroup telnetd - * @{ - */ - -/** - * \file - * Header file for the telnet server. - * \author Adam Dunkels - */ - /* - * Copyright (c) 2002, Adam Dunkels. - * All rights reserved. + * Copyright (c) 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -35,80 +25,39 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * This file is part of the uIP TCP/IP stack. + * This file is part of the uIP TCP/IP stack * - * $Id: telnetd.h,v 1.1.2.2 2003/10/07 13:22:27 adam Exp $ + * $Id: telnetd.h,v 1.2 2006/06/07 09:43:54 adam Exp $ * */ #ifndef __TELNETD_H__ #define __TELNETD_H__ -#include "uip.h" +#include "uipopt.h" -/** - * The maximum length of a telnet line. - * - * \hideinitializer - */ -#define TELNETD_LINELEN 36 +void telnetd_appcall(void); -/** - * The number of output lines being buffered for all telnet - * connections. - * - * \hideinitializer - */ -#define TELNETD_NUMLINES 24 +#ifndef TELNETD_CONF_LINELEN +#define TELNETD_CONF_LINELEN 40 +#endif +#ifndef TELNETD_CONF_NUMLINES +#define TELNETD_CONF_NUMLINES 16 +#endif -/** - * A telnet connection structure. - */ struct telnetd_state { - char *lines[TELNETD_NUMLINES]; - char buf[TELNETD_LINELEN]; + char *lines[TELNETD_CONF_NUMLINES]; + char buf[TELNETD_CONF_LINELEN]; char bufptr; + u8_t numsent; u8_t state; }; - -/** - * Callback function that is called when a telnet connection has been - * established. - * - * \param s The telnet connection. - */ -void telnetd_connected(struct telnetd_state *s); - -/** - * Callback function that is called when a line of text has arrived on - * a telnet connection. - * - * \param s The telnet connection. - * - * \param cmd The line of text. - */ -void telnetd_input(struct telnetd_state *s, char *cmd); - - -void telnetd_close(struct telnetd_state *s); -void telnetd_output(struct telnetd_state *s, char *s1, char *s2); -void telnetd_prompt(struct telnetd_state *s, char *str); - -void telnetd_app(void); +typedef struct telnetd_state uip_tcp_appstate_t; #ifndef UIP_APPCALL -#define UIP_APPCALL telnetd_app +#define UIP_APPCALL telnetd_appcall #endif -#ifndef UIP_APPSTATE_SIZE -#define UIP_APPSTATE_SIZE (sizeof(struct telnetd_state)) -#endif - -void telnetd_init(void); - - -#endif /* __TELNET_H__ */ - -/** @} */ +#endif /* __TELNETD_H__ */ diff --git a/apps/webclient/Makefile.webclient b/apps/webclient/Makefile.webclient new file mode 100644 index 0000000..e6e7f08 --- /dev/null +++ b/apps/webclient/Makefile.webclient @@ -0,0 +1 @@ +APP_SOURCES += webclient-strings.c webclient.c diff --git a/apps/webclient/http-strings b/apps/webclient/http-strings deleted file mode 100644 index 8710354..0000000 --- a/apps/webclient/http-strings +++ /dev/null @@ -1,12 +0,0 @@ -http_200 "200 " -http_301 "301 " -http_302 "302 " -http_get "GET " -http_10 "HTTP/1.0" -http_11 "HTTP/1.1" -http_content_type "Content-Type: " -http_texthtml "text/html" -http_location "Location: " -http_host "Host: " -http_connection_close "Connection: close" -http_user_agent "User-Agent: Contiki/1.0 (Commodore 64; http://dunkels.com/adam/contiki/)" diff --git a/apps/webclient/http-strings.c b/apps/webclient/http-strings.c deleted file mode 100644 index b5afbbc..0000000 --- a/apps/webclient/http-strings.c +++ /dev/null @@ -1,39 +0,0 @@ -char http_200[5] = -/* 200 */ -{0x32, 0x30, 0x30, 0x20, }; -char http_301[5] = -/* 301 */ -{0x33, 0x30, 0x31, 0x20, }; -char http_302[5] = -/* 302 */ -{0x33, 0x30, 0x32, 0x20, }; -char http_get[5] = -/* GET */ -{0x47, 0x45, 0x54, 0x20, }; -char http_10[9] = -/* HTTP/1.0 */ -{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, }; -char http_11[9] = -/* HTTP/1.1 */ -{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, }; -char http_content_type[15] = -/* Content-Type: */ -{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, }; -char http_texthtml[10] = -/* text/html */ -{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, }; -char http_location[11] = -/* Location: */ -{0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, }; -char http_host[7] = -/* Host: */ -{0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, }; -char http_connection_close[18] = -/* Connection: close */ -{0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, }; -char http_user_agent[73] = -/* User-Agent: Contiki/1.0 (Commodore 64; http://dunkels.com/adam/contiki/) */ -{0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x28, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x64, 0x6f, 0x72, 0x65, 0x20, 0x36, 0x34, 0x3b, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x29, }; -char test_httpstring[16] = -/* HTTP/1.0 200 OK */ -{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, }; diff --git a/apps/webclient/http-strings.h b/apps/webclient/http-strings.h deleted file mode 100644 index 8a49c32..0000000 --- a/apps/webclient/http-strings.h +++ /dev/null @@ -1,13 +0,0 @@ -extern char http_200[5]; -extern char http_301[5]; -extern char http_302[5]; -extern char http_get[5]; -extern char http_10[9]; -extern char http_11[9]; -extern char http_content_type[15]; -extern char http_texthtml[10]; -extern char http_location[11]; -extern char http_host[7]; -extern char http_connection_close[18]; -extern char http_user_agent[73]; -extern char test_httpstring[16]; diff --git a/apps/webclient/makehttpstrings b/apps/webclient/makehttpstrings deleted file mode 100755 index b39d6ac..0000000 --- a/apps/webclient/makehttpstrings +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/perl - -open(OUTPUTC, "> http-strings.c"); -open(OUTPUTH, "> http-strings.h"); - -open(FILE, "http-strings"); - -while() { - if(/(.+) "(.+)"/) { - $var = $1; - $data = $2; - - printf(OUTPUTC "char $var\[%d] = \n", length($data) + 1); - printf(OUTPUTC "/* $data */\n"); - printf(OUTPUTC "{"); - for($j = 0; $j < length($data); $j++) { - printf(OUTPUTC "%#02x, ", unpack("C", substr($data, $j, 1))); - } - printf(OUTPUTC "};\n"); - - printf(OUTPUTH "extern char $var\[%d];\n", length($data) + 1); - - } -} -exit 0; - -printf(OUTPUT "%#02x, ", unpack("C", $data)); diff --git a/apps/webclient/makestrings b/apps/webclient/makestrings new file mode 100755 index 0000000..6dec075 --- /dev/null +++ b/apps/webclient/makestrings @@ -0,0 +1,40 @@ +#!/usr/bin/perl + + +sub stringify { + my $name = shift(@_); + open(OUTPUTC, "> $name.c"); + open(OUTPUTH, "> $name.h"); + + open(FILE, "$name"); + + while() { + if(/(.+) "(.+)"/) { + $var = $1; + $data = $2; + + $datan = $data; + $datan =~ s/\\r/\r/g; + $datan =~ s/\\n/\n/g; + $datan =~ s/\\01/\01/g; + $datan =~ s/\\0/\0/g; + + printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1); + printf(OUTPUTC "/* \"$data\" */\n"); + printf(OUTPUTC "{"); + for($j = 0; $j < length($datan); $j++) { + printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1))); + } + printf(OUTPUTC "0 };\n"); + + printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1); + + } + } + close(OUTPUTC); + close(OUTPUTH); +} +stringify("webclient-strings"); + +exit 0; + diff --git a/apps/webclient/webclient-strings b/apps/webclient/webclient-strings new file mode 100644 index 0000000..a331397 --- /dev/null +++ b/apps/webclient/webclient-strings @@ -0,0 +1,31 @@ +http_http "http://" +http_200 "200 " +http_301 "301 " +http_302 "302 " +http_get "GET " +http_10 "HTTP/1.0" +http_11 "HTTP/1.1" +http_content_type "content-type: " +http_texthtml "text/html" +http_location "location: " +http_host "host: " +http_crnl "\r\n" +http_index_html "/index.html" +http_404_html "/404.html" +http_content_type_html "Content-type: text/html\r\n\r\n" +http_content_type_css "Content-type: text/css\r\n\r\n" +http_content_type_text "Content-type: text/text\r\n\r\n" +http_content_type_png "Content-type: image/png\r\n\r\n" +http_content_type_gif "Content-type: image/gif\r\n\r\n" +http_content_type_jpg "Content-type: image/jpeg\r\n\r\n" +http_content_type_binary "Content-type: application/octet-stream\r\n\r\n" +http_html ".html" +http_shtml ".shtml" +http_htm ".htm" +http_css ".css" +http_png ".png" +http_gif ".gif" +http_jpg ".jpg" +http_text ".text" +http_txt ".txt" +http_user_agent_fields "Connection: close\r\nUser-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n" diff --git a/apps/webclient/webclient-strings.c b/apps/webclient/webclient-strings.c new file mode 100644 index 0000000..9472330 --- /dev/null +++ b/apps/webclient/webclient-strings.c @@ -0,0 +1,93 @@ +const char http_http[8] = +/* "http://" */ +{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0 }; +const char http_200[5] = +/* "200 " */ +{0x32, 0x30, 0x30, 0x20, 0 }; +const char http_301[5] = +/* "301 " */ +{0x33, 0x30, 0x31, 0x20, 0 }; +const char http_302[5] = +/* "302 " */ +{0x33, 0x30, 0x32, 0x20, 0 }; +const char http_get[5] = +/* "GET " */ +{0x47, 0x45, 0x54, 0x20, 0 }; +const char http_10[9] = +/* "HTTP/1.0" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0 }; +const char http_11[9] = +/* "HTTP/1.1" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0 }; +const char http_content_type[15] = +/* "content-type: " */ +{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0 }; +const char http_texthtml[10] = +/* "text/html" */ +{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_location[11] = +/* "location: " */ +{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0 }; +const char http_host[7] = +/* "host: " */ +{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0 }; +const char http_crnl[3] = +/* "\r\n" */ +{0xd, 0xa, 0 }; +const char http_index_html[12] = +/* "/index.html" */ +{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_404_html[10] = +/* "/404.html" */ +{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_content_type_html[28] = +/* "Content-type: text/html\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_css [27] = +/* "Content-type: text/css\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_text[28] = +/* "Content-type: text/text\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_png [28] = +/* "Content-type: image/png\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_gif [28] = +/* "Content-type: image/gif\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_jpg [29] = +/* "Content-type: image/jpeg\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_binary[43] = +/* "Content-type: application/octet-stream\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_html[6] = +/* ".html" */ +{0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_shtml[7] = +/* ".shtml" */ +{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_htm[5] = +/* ".htm" */ +{0x2e, 0x68, 0x74, 0x6d, 0 }; +const char http_css[5] = +/* ".css" */ +{0x2e, 0x63, 0x73, 0x73, 0 }; +const char http_png[5] = +/* ".png" */ +{0x2e, 0x70, 0x6e, 0x67, 0 }; +const char http_gif[5] = +/* ".gif" */ +{0x2e, 0x67, 0x69, 0x66, 0 }; +const char http_jpg[5] = +/* ".jpg" */ +{0x2e, 0x6a, 0x70, 0x67, 0 }; +const char http_text[6] = +/* ".text" */ +{0x2e, 0x74, 0x65, 0x78, 0x74, 0 }; +const char http_txt[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, 0 }; +const char http_user_agent_fields[77] = +/* "Connection: close\r\nUser-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x28, 0x3b, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0xd, 0xa, 0 }; diff --git a/apps/webclient/webclient-strings.h b/apps/webclient/webclient-strings.h new file mode 100644 index 0000000..9e3ec93 --- /dev/null +++ b/apps/webclient/webclient-strings.h @@ -0,0 +1,31 @@ +extern const char http_http[8]; +extern const char http_200[5]; +extern const char http_301[5]; +extern const char http_302[5]; +extern const char http_get[5]; +extern const char http_10[9]; +extern const char http_11[9]; +extern const char http_content_type[15]; +extern const char http_texthtml[10]; +extern const char http_location[11]; +extern const char http_host[7]; +extern const char http_crnl[3]; +extern const char http_index_html[12]; +extern const char http_404_html[10]; +extern const char http_content_type_html[28]; +extern const char http_content_type_css [27]; +extern const char http_content_type_text[28]; +extern const char http_content_type_png [28]; +extern const char http_content_type_gif [28]; +extern const char http_content_type_jpg [29]; +extern const char http_content_type_binary[43]; +extern const char http_html[6]; +extern const char http_shtml[7]; +extern const char http_htm[5]; +extern const char http_css[5]; +extern const char http_png[5]; +extern const char http_gif[5]; +extern const char http_jpg[5]; +extern const char http_text[6]; +extern const char http_txt[5]; +extern const char http_user_agent_fields[77]; diff --git a/apps/webclient/webclient.c b/apps/webclient/webclient.c index ae04a9e..746c008 100644 --- a/apps/webclient/webclient.c +++ b/apps/webclient/webclient.c @@ -1,5 +1,5 @@ /** - * \addtogroup exampleapps + * \addtogroup apps * @{ */ @@ -22,20 +22,20 @@ /* * Copyright (c) 2002, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -47,15 +47,16 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * This file is part of the "contiki" web browser. + * This file is part of the uIP TCP/IP stack. * - * $Id: webclient.c,v 1.1.2.5 2003/10/06 22:56:45 adam Exp $ + * $Id: webclient.c,v 1.2 2006/06/11 21:46:37 adam Exp $ * */ #include "uip.h" +#include "uiplib.h" #include "webclient.h" #include "resolv.h" @@ -78,22 +79,6 @@ #define ISO_cr 0x0d #define ISO_space 0x20 -struct webclient_state { - u8_t timer; - u8_t state; - u8_t httpflag; - - u16_t port; - char host[40]; - char file[WWW_CONF_MAX_URLLEN]; - u16_t getrequestptr; - u16_t getrequestleft; - - char httpheaderline[200]; - u16_t httpheaderlineptr; - - char mimetype[32]; -}; static struct webclient_state s; @@ -155,13 +140,13 @@ unsigned char webclient_get(char *host, u16_t port, char *file) { struct uip_conn *conn; - u16_t *ipaddr; - static u16_t addr[2]; + uip_ipaddr_t *ipaddr; + static uip_ipaddr_t addr; /* First check if the host is an IP address. */ - ipaddr = &addr[0]; - if(uip_main_ipaddrconv(host, (unsigned char *)addr) == 0) { - ipaddr = resolv_lookup(host); + ipaddr = &addr; + if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) { + ipaddr = (uip_ipaddr_t *)resolv_lookup(host); if(ipaddr == NULL) { return 0; @@ -182,11 +167,12 @@ webclient_get(char *host, u16_t port, char *file) return 1; } /*-----------------------------------------------------------------------------------*/ -static unsigned char * CC_FASTCALL +static unsigned char * copy_string(unsigned char *dest, const unsigned char *src, unsigned char len) { - return strcpy(dest, src) + len; + strncpy(dest, src, len); + return dest + len; } /*-----------------------------------------------------------------------------------*/ static void @@ -218,7 +204,7 @@ senddata(void) s.getrequestleft; uip_send(&(getrequest[s.getrequestptr]), len); } -} +} /*-----------------------------------------------------------------------------------*/ static void acked(void) @@ -240,8 +226,8 @@ parse_statusline(u16_t len) char *cptr; while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { - s.httpheaderline[s.httpheaderlineptr] = *uip_appdata; - ++uip_appdata; + s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; + ++((char *)uip_appdata); --len; if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { @@ -308,8 +294,8 @@ parse_headers(u16_t len) static unsigned char i; while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { - s.httpheaderline[s.httpheaderlineptr] = *uip_appdata; - ++uip_appdata; + s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; + ++((char *)uip_appdata); --len; if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { /* We have an entire HTTP header line in s.httpheaderline, so @@ -323,7 +309,7 @@ parse_headers(u16_t len) } s.httpheaderline[s.httpheaderlineptr - 1] = 0; - /* Check for specific HTTP header fields. */ + /* Check for specific HTTP header fields. */ if(casecmp(s.httpheaderline, http_content_type, sizeof(http_content_type) - 1) == 0) { /* Found Content-type field. */ @@ -339,7 +325,7 @@ parse_headers(u16_t len) sizeof(http_location) - 1; if(strncmp(cptr, http_http, 7) == 0) { - cptr += 7; + cptr += 7; for(i = 0; i < s.httpheaderlineptr - 7; ++i) { if(*cptr == 0 || *cptr == '/' || @@ -359,7 +345,7 @@ parse_headers(u16_t len) /* We're done parsing, so we reset the pointer and start the next line. */ - s.httpheaderlineptr = 0; + s.httpheaderlineptr = 0; } else { ++s.httpheaderlineptr; } @@ -388,7 +374,8 @@ newdata(void) } } /*-----------------------------------------------------------------------------------*/ -void webclient_appcall(void) +void +webclient_appcall(void) { if(uip_connected()) { s.timer = 0; @@ -398,19 +385,11 @@ void webclient_appcall(void) return; } - - if(state == NULL) { - uip_abort(); - return; - } - if(s.state == WEBCLIENT_STATE_CLOSE) { webclient_closed(); uip_abort(); return; - } - - + } if(uip_aborted()) { webclient_aborted(); diff --git a/apps/webclient/webclient.h b/apps/webclient/webclient.h index 9ec2686..44cb95c 100644 --- a/apps/webclient/webclient.h +++ b/apps/webclient/webclient.h @@ -7,24 +7,24 @@ * \file * Header file for the HTTP client. * \author Adam Dunkels - */ + */ /* * Copyright (c) 2002, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -36,22 +36,41 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * This file is part of the "contiki" web browser. + * This file is part of the uIP TCP/IP stack. * - * $Id: webclient.h,v 1.1.2.5 2003/10/06 22:56:45 adam Exp $ + * $Id: webclient.h,v 1.2 2006/06/11 21:46:37 adam Exp $ * */ #ifndef __WEBCLIENT_H__ #define __WEBCLIENT_H__ -#include "http-strings.h" -#include "http-user-agent-string.h" +#include "webclient-strings.h" +#include "uipopt.h" +#define WEBCLIENT_CONF_MAX_URLLEN 100 -struct webclient_state; +struct webclient_state { + u8_t timer; + u8_t state; + u8_t httpflag; + + u16_t port; + char host[40]; + char file[WEBCLIENT_CONF_MAX_URLLEN]; + u16_t getrequestptr; + u16_t getrequestleft; + + char httpheaderline[200]; + u16_t httpheaderlineptr; + + char mimetype[32]; +}; + +typedef struct webclient_state uip_tcp_appstate_t; +#define UIP_APPCALL webclient_appcall /** * Callback function that is called from the webclient code when HTTP @@ -201,7 +220,9 @@ char *webclient_hostname(void); * \return The port number of the current HTTP data stream, in host byte order. */ unsigned short webclient_port(void); - + + + #endif /* __WEBCLIENT_H__ */ /** @} */ diff --git a/apps/webserver/Makefile.webserver b/apps/webserver/Makefile.webserver new file mode 100644 index 0000000..7d3e086 --- /dev/null +++ b/apps/webserver/Makefile.webserver @@ -0,0 +1 @@ +APP_SOURCES += httpd.c http-strings.c httpd-fs.c httpd-cgi.c diff --git a/apps/webserver/http-strings b/apps/webserver/http-strings new file mode 100644 index 0000000..d0b9121 --- /dev/null +++ b/apps/webserver/http-strings @@ -0,0 +1,35 @@ +http_http "http://" +http_200 "200 " +http_301 "301 " +http_302 "302 " +http_get "GET " +http_10 "HTTP/1.0" +http_11 "HTTP/1.1" +http_content_type "content-type: " +http_texthtml "text/html" +http_location "location: " +http_host "host: " +http_crnl "\r\n" +http_index_html "/index.html" +http_404_html "/404.html" +http_referer "Referer:" +http_header_200 "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" +http_header_404 "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" +http_content_type_plain "Content-type: text/plain\r\n\r\n" +http_content_type_html "Content-type: text/html\r\n\r\n" +http_content_type_css "Content-type: text/css\r\n\r\n" +http_content_type_text "Content-type: text/text\r\n\r\n" +http_content_type_png "Content-type: image/png\r\n\r\n" +http_content_type_gif "Content-type: image/gif\r\n\r\n" +http_content_type_jpg "Content-type: image/jpeg\r\n\r\n" +http_content_type_binary "Content-type: application/octet-stream\r\n\r\n" +http_html ".html" +http_shtml ".shtml" +http_htm ".htm" +http_css ".css" +http_png ".png" +http_gif ".gif" +http_jpg ".jpg" +http_text ".txt" +http_txt ".txt" + diff --git a/apps/webserver/http-strings.c b/apps/webserver/http-strings.c new file mode 100644 index 0000000..0d822ba --- /dev/null +++ b/apps/webserver/http-strings.c @@ -0,0 +1,102 @@ +const char http_http[8] = +/* "http://" */ +{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; +const char http_200[5] = +/* "200 " */ +{0x32, 0x30, 0x30, 0x20, }; +const char http_301[5] = +/* "301 " */ +{0x33, 0x30, 0x31, 0x20, }; +const char http_302[5] = +/* "302 " */ +{0x33, 0x30, 0x32, 0x20, }; +const char http_get[5] = +/* "GET " */ +{0x47, 0x45, 0x54, 0x20, }; +const char http_10[9] = +/* "HTTP/1.0" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, }; +const char http_11[9] = +/* "HTTP/1.1" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, }; +const char http_content_type[15] = +/* "content-type: " */ +{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, }; +const char http_texthtml[10] = +/* "text/html" */ +{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_location[11] = +/* "location: " */ +{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, }; +const char http_host[7] = +/* "host: " */ +{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, }; +const char http_crnl[3] = +/* "\r\n" */ +{0xd, 0xa, }; +const char http_index_html[12] = +/* "/index.html" */ +{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_404_html[10] = +/* "/404.html" */ +{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_referer[9] = +/* "Referer:" */ +{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, }; +const char http_header_200[84] = +/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, }; +const char http_header_404[91] = +/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, }; +const char http_content_type_plain[29] = +/* "Content-type: text/plain\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_html[28] = +/* "Content-type: text/html\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_css [27] = +/* "Content-type: text/css\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_text[28] = +/* "Content-type: text/text\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_png [28] = +/* "Content-type: image/png\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_gif [28] = +/* "Content-type: image/gif\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_jpg [29] = +/* "Content-type: image/jpeg\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_binary[43] = +/* "Content-type: application/octet-stream\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, }; +const char http_html[6] = +/* ".html" */ +{0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_shtml[7] = +/* ".shtml" */ +{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_htm[5] = +/* ".htm" */ +{0x2e, 0x68, 0x74, 0x6d, }; +const char http_css[5] = +/* ".css" */ +{0x2e, 0x63, 0x73, 0x73, }; +const char http_png[5] = +/* ".png" */ +{0x2e, 0x70, 0x6e, 0x67, }; +const char http_gif[5] = +/* ".gif" */ +{0x2e, 0x67, 0x69, 0x66, }; +const char http_jpg[5] = +/* ".jpg" */ +{0x2e, 0x6a, 0x70, 0x67, }; +const char http_text[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, }; +const char http_txt[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, }; diff --git a/apps/webserver/http-strings.h b/apps/webserver/http-strings.h new file mode 100644 index 0000000..f121dd7 --- /dev/null +++ b/apps/webserver/http-strings.h @@ -0,0 +1,34 @@ +extern const char http_http[8]; +extern const char http_200[5]; +extern const char http_301[5]; +extern const char http_302[5]; +extern const char http_get[5]; +extern const char http_10[9]; +extern const char http_11[9]; +extern const char http_content_type[15]; +extern const char http_texthtml[10]; +extern const char http_location[11]; +extern const char http_host[7]; +extern const char http_crnl[3]; +extern const char http_index_html[12]; +extern const char http_404_html[10]; +extern const char http_referer[9]; +extern const char http_header_200[84]; +extern const char http_header_404[91]; +extern const char http_content_type_plain[29]; +extern const char http_content_type_html[28]; +extern const char http_content_type_css [27]; +extern const char http_content_type_text[28]; +extern const char http_content_type_png [28]; +extern const char http_content_type_gif [28]; +extern const char http_content_type_jpg [29]; +extern const char http_content_type_binary[43]; +extern const char http_html[6]; +extern const char http_shtml[7]; +extern const char http_htm[5]; +extern const char http_css[5]; +extern const char http_png[5]; +extern const char http_gif[5]; +extern const char http_jpg[5]; +extern const char http_text[5]; +extern const char http_txt[5]; diff --git a/apps/webserver/httpd-cgi.c b/apps/webserver/httpd-cgi.c new file mode 100644 index 0000000..6257035 --- /dev/null +++ b/apps/webserver/httpd-cgi.c @@ -0,0 +1,203 @@ +/** + * \addtogroup httpd + * @{ + */ + +/** + * \file + * Web server script interface + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2001-2006, 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: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $ + * + */ + +#include "uip.h" +#include "psock.h" +#include "httpd.h" +#include "httpd-cgi.h" +#include "httpd-fs.h" + +#include +#include + +HTTPD_CGI_CALL(file, "file-stats", file_stats); +HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats); +HTTPD_CGI_CALL(net, "net-stats", net_stats); + +static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, NULL }; + +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_cgifunction +httpd_cgi(char *name) +{ + const struct httpd_cgi_call **f; + + /* Find the matching name in the table, return the function. */ + for(f = calls; *f != NULL; ++f) { + if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) { + return (*f)->function; + } + } + return nullfunction; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_file_stats(void *arg) +{ + char *f = (char *)arg; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f)); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + + PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static const char closed[] = /* "CLOSED",*/ +{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0}; +static const char syn_rcvd[] = /* "SYN-RCVD",*/ +{0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, + 0x44, 0}; +static const char syn_sent[] = /* "SYN-SENT",*/ +{0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, + 0x54, 0}; +static const char established[] = /* "ESTABLISHED",*/ +{0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, + 0x45, 0x44, 0}; +static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ +{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, + 0x54, 0x2d, 0x31, 0}; +static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ +{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, + 0x54, 0x2d, 0x32, 0}; +static const char closing[] = /* "CLOSING",*/ +{0x43, 0x4c, 0x4f, 0x53, 0x49, + 0x4e, 0x47, 0}; +static const char time_wait[] = /* "TIME-WAIT,"*/ +{0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, + 0x49, 0x54, 0}; +static const char last_ack[] = /* "LAST-ACK"*/ +{0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, + 0x4b, 0}; + +static const char *states[] = { + closed, + syn_rcvd, + syn_sent, + established, + fin_wait_1, + fin_wait_2, + closing, + time_wait, + last_ack}; + + +static unsigned short +generate_tcp_stats(void *arg) +{ + struct uip_conn *conn; + struct httpd_state *s = (struct httpd_state *)arg; + + conn = &uip_conns[s->count]; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, + "%d%u.%u.%u.%u:%u%s%u%u%c %c\r\n", + htons(conn->lport), + htons(conn->ripaddr[0]) >> 8, + htons(conn->ripaddr[0]) & 0xff, + htons(conn->ripaddr[1]) >> 8, + htons(conn->ripaddr[1]) & 0xff, + htons(conn->rport), + states[conn->tcpstateflags & UIP_TS_MASK], + conn->nrtx, + conn->timer, + (uip_outstanding(conn))? '*':' ', + (uip_stopped(conn))? '!':' '); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) +{ + + PSOCK_BEGIN(&s->sout); + + for(s->count = 0; s->count < UIP_CONNS; ++s->count) { + if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { + PSOCK_GENERATOR_SEND(&s->sout, generate_tcp_stats, s); + } + } + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_net_stats(void *arg) +{ + struct httpd_state *s = (struct httpd_state *)arg; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, + "%5u\n", ((uip_stats_t *)&uip_stat)[s->count]); +} + +static +PT_THREAD(net_stats(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + +#if UIP_STATISTICS + + for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t); + ++s->count) { + PSOCK_GENERATOR_SEND(&s->sout, generate_net_stats, s); + } + +#endif /* UIP_STATISTICS */ + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/webserver/httpd-cgi.h b/apps/webserver/httpd-cgi.h new file mode 100644 index 0000000..e6ba51e --- /dev/null +++ b/apps/webserver/httpd-cgi.h @@ -0,0 +1,84 @@ +/** + * \addtogroup httpd + * @{ + */ + +/** + * \file + * Web server script interface header file + * \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: httpd-cgi.h,v 1.2 2006/06/11 21:46:38 adam Exp $ + * + */ + +#ifndef __HTTPD_CGI_H__ +#define __HTTPD_CGI_H__ + +#include "psock.h" +#include "httpd.h" + +typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *)); + +httpd_cgifunction httpd_cgi(char *name); + +struct httpd_cgi_call { + const char *name; + const httpd_cgifunction function; +}; + +/** + * \brief HTTPD CGI function declaration + * \param name The C variable name of the function + * \param str The string name of the function, used in the script file + * \param function A pointer to the function that implements it + * + * This macro is used for declaring a HTTPD CGI + * function. This function is then added to the list of + * HTTPD CGI functions with the httpd_cgi_add() function. + * + * \hideinitializer + */ +#define HTTPD_CGI_CALL(name, str, function) \ +static PT_THREAD(function(struct httpd_state *, char *)); \ +static const struct httpd_cgi_call name = {str, function} + +void httpd_cgi_init(void); +#endif /* __HTTPD_CGI_H__ */ + +/** @} */ diff --git a/apps/httpd/fs.c b/apps/webserver/httpd-fs.c similarity index 56% rename from apps/httpd/fs.c rename to apps/webserver/httpd-fs.c index 6b18545..21185e8 100644 --- a/apps/httpd/fs.c +++ b/apps/webserver/httpd-fs.c @@ -1,75 +1,62 @@ -/** - * \addtogroup httpd - * @{ - */ - -/** - * \file - * HTTP server read-only file system code. - * \author Adam Dunkels - * - * A simple read-only filesystem. - */ - /* * Copyright (c) 2001, Swedish Institute of Computer Science. - * All rights reserved. + * 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. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 lwIP TCP/IP stack. - * + * * Author: Adam Dunkels * - * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $ + * $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $ */ -#include "uip.h" #include "httpd.h" -#include "fs.h" -#include "fsdata.h" +#include "httpd-fs.h" +#include "httpd-fsdata.h" -#define NULL (void *)0 -#include "fsdata.c" +#ifndef NULL +#define NULL 0 +#endif /* NULL */ -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 -static u16_t count[FS_NUMFILES]; -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ +#include "httpd-fsdata.c" + +#if HTTPD_FS_STATISTICS +static u16_t count[HTTPD_FS_NUMFILES]; +#endif /* HTTPD_FS_STATISTICS */ /*-----------------------------------------------------------------------------------*/ static u8_t -fs_strcmp(const char *str1, const char *str2) +httpd_fs_strcmp(const char *str1, const char *str2) { u8_t i; i = 0; loop: if(str2[i] == 0 || - str1[i] == '\r' || + str1[i] == '\r' || str1[i] == '\n') { return 0; } @@ -84,72 +71,62 @@ fs_strcmp(const char *str1, const char *str2) } /*-----------------------------------------------------------------------------------*/ int -fs_open(const char *name, struct fs_file *file) +httpd_fs_open(const char *name, struct httpd_fs_file *file) { -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 +#if HTTPD_FS_STATISTICS u16_t i = 0; -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ - struct fsdata_file_noconst *f; +#endif /* HTTPD_FS_STATISTICS */ + struct httpd_fsdata_file_noconst *f; - for(f = (struct fsdata_file_noconst *)FS_ROOT; + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; f != NULL; - f = (struct fsdata_file_noconst *)f->next) { + f = (struct httpd_fsdata_file_noconst *)f->next) { - if(fs_strcmp(name, f->name) == 0) { + if(httpd_fs_strcmp(name, f->name) == 0) { file->data = f->data; file->len = f->len; -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 +#if HTTPD_FS_STATISTICS ++count[i]; -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ return 1; } -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 +#if HTTPD_FS_STATISTICS ++i; -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ } return 0; } /*-----------------------------------------------------------------------------------*/ void -fs_init(void) +httpd_fs_init(void) { -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 +#if HTTPD_FS_STATISTICS u16_t i; - for(i = 0; i < FS_NUMFILES; i++) { + for(i = 0; i < HTTPD_FS_NUMFILES; i++) { count[i] = 0; } -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ } /*-----------------------------------------------------------------------------------*/ -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 -u16_t fs_count +#if HTTPD_FS_STATISTICS +u16_t httpd_fs_count (char *name) { - struct fsdata_file_noconst *f; + struct httpd_fsdata_file_noconst *f; u16_t i; i = 0; - for(f = (struct fsdata_file_noconst *)FS_ROOT; + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; f != NULL; - f = (struct fsdata_file_noconst *)f->next) { + f = (struct httpd_fsdata_file_noconst *)f->next) { - if(fs_strcmp(name, f->name) == 0) { + if(httpd_fs_strcmp(name, f->name) == 0) { return count[i]; } ++i; } return 0; } -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ /*-----------------------------------------------------------------------------------*/ diff --git a/apps/httpd/fs.h b/apps/webserver/httpd-fs.h similarity index 53% rename from apps/httpd/fs.h rename to apps/webserver/httpd-fs.h index 2d9693b..d80ed3d 100644 --- a/apps/httpd/fs.h +++ b/apps/webserver/httpd-fs.h @@ -1,80 +1,57 @@ -/** - * \addtogroup httpd - * @{ - */ - -/** - * \file - * HTTP server read-only file system header file. - * \author Adam Dunkels - */ - /* * Copyright (c) 2001, Swedish Institute of Computer Science. - * All rights reserved. + * 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. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 lwIP TCP/IP stack. - * + * * Author: Adam Dunkels * - * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $ + * $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $ */ -#ifndef __FS_H__ -#define __FS_H__ +#ifndef __HTTPD_FS_H__ +#define __HTTPD_FS_H__ -#include "uip.h" +#define HTTPD_FS_STATISTICS 1 -/** - * An open file in the read-only file system. - */ -struct fs_file { - char *data; /**< The actual file data. */ - int len; /**< The length of the file data. */ +struct httpd_fs_file { + char *data; + int len; }; -/** - * Open a file in the read-only file system. - * - * \param name The name of the file. - * - * \param file The file pointer, which must be allocated by caller and - * will be filled in by the function. - */ -int fs_open(const char *name, struct fs_file *file); +/* file must be allocated by caller and will be filled in + by the function. */ +int httpd_fs_open(const char *name, struct httpd_fs_file *file); -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 -u16_t fs_count(char *name); -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 +u16_t httpd_fs_count(char *name); +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ -/** - * Initialize the read-only file system. - */ -void fs_init(void); +void httpd_fs_init(void); -#endif /* __FS_H__ */ +#endif /* __HTTPD_FS_H__ */ diff --git a/apps/webserver/httpd-fs/404.html b/apps/webserver/httpd-fs/404.html new file mode 100644 index 0000000..a17711d --- /dev/null +++ b/apps/webserver/httpd-fs/404.html @@ -0,0 +1,8 @@ + + +
+

404 - file not found

+

Go here instead.

+
+ + \ No newline at end of file diff --git a/apps/webserver/httpd-fs/fade.png b/apps/webserver/httpd-fs/fade.png new file mode 100644 index 0000000..a9e69f7 Binary files /dev/null and b/apps/webserver/httpd-fs/fade.png differ diff --git a/apps/webserver/httpd-fs/files.shtml b/apps/webserver/httpd-fs/files.shtml new file mode 100644 index 0000000..811e230 --- /dev/null +++ b/apps/webserver/httpd-fs/files.shtml @@ -0,0 +1,35 @@ +%!: /header.html +

File statistics

+
+ + + + + + + + + + + + + + + +
/index.html%! file-stats /index.html +
/files.shtml%! file-stats /files.shtml +
/tcp.shtml%! file-stats /tcp.shtml +
/stats.shtml%! file-stats /stats.shtml +
/style.css%! file-stats /style.css +
/404.html%! file-stats /404.html +
/fade.png%! file-stats /fade.png +
+
+%!: /footer.html diff --git a/apps/webserver/httpd-fs/footer.html b/apps/webserver/httpd-fs/footer.html new file mode 100644 index 0000000..1fd5f4f --- /dev/null +++ b/apps/webserver/httpd-fs/footer.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/apps/webserver/httpd-fs/header.html b/apps/webserver/httpd-fs/header.html new file mode 100644 index 0000000..7b1a1fe --- /dev/null +++ b/apps/webserver/httpd-fs/header.html @@ -0,0 +1,18 @@ + + + + Welcome to the uIP web server! + + + + + + +
diff --git a/apps/webserver/httpd-fs/index.html b/apps/webserver/httpd-fs/index.html new file mode 100644 index 0000000..27cbc93 --- /dev/null +++ b/apps/webserver/httpd-fs/index.html @@ -0,0 +1,29 @@ + + + + Welcome to the uIP web server! + + + + + + +
+

+ These web pages are served by a small web server running on top of + the uIP embedded TCP/IP + stack. +

+

+ Click on the links above for web server statistics. +

+ + + diff --git a/apps/webserver/httpd-fs/processes.shtml b/apps/webserver/httpd-fs/processes.shtml new file mode 100644 index 0000000..2f93e35 --- /dev/null +++ b/apps/webserver/httpd-fs/processes.shtml @@ -0,0 +1,5 @@ +%!: /header.html +

System processes


+ +%! processes +%!: /footer.html \ No newline at end of file diff --git a/apps/httpd/fs/stats_header.html b/apps/webserver/httpd-fs/stats.shtml similarity index 59% rename from apps/httpd/fs/stats_header.html rename to apps/webserver/httpd-fs/stats.shtml index e2e07ba..c63ed4a 100644 --- a/apps/httpd/fs/stats_header.html +++ b/apps/webserver/httpd-fs/stats.shtml @@ -1,30 +1,31 @@ - - +%!: /header.html +

Network statistics

-
IDNamePriorityPoll handlerEvent handlerProcstate
- - -
-
-IP           Packets dropped
-             Packets received
+
+
+IP           Packets received
              Packets sent
+	     Packets dropped
 IP errors    IP version/header length
              IP length, high byte
              IP length, low byte
              IP fragments
              Header checksum
              Wrong protocol
-ICMP	     Packets dropped
-             Packets received
+ICMP	     Packets received
              Packets sent
+             Packets dropped
              Type errors
-TCP          Packets dropped
-             Packets received
+TCP          Packets received
              Packets sent
+             Packets dropped
              Checksum errors
              Data packets without ACKs
              Resets
              Retransmissions
 	     No connection avaliable
 	     Connection attempts to closed ports
-
-
\ No newline at end of file
+
%! net-stats
+
+ +%!: /footer.html diff --git a/apps/webserver/httpd-fs/style.css b/apps/webserver/httpd-fs/style.css new file mode 100644 index 0000000..ba6df7f --- /dev/null +++ b/apps/webserver/httpd-fs/style.css @@ -0,0 +1,92 @@ +h1 +{ + text-align: center; + font-size:14pt; + font-family:arial,helvetica; + font-weight:bold; + padding:10px; +} + +body +{ + + background-color: #fffeec; + color:black; + + font-size:8pt; + font-family:arial,helvetica; +} + +.menu +{ + margin: 4px; + width:60%; + + padding:2px; + + border: solid 1px; + background-color: #fffcd2; + text-align:left; + + font-size:9pt; + font-family:arial,helvetica; +} + +div.menubox +{ + width: 25%; + border: 0; + float: left; +text-align: center; +} + +.contentblock +{ + margin: 4px; + width:60%; + + padding:2px; + + border: 1px dotted; + background-color: white; + + font-size:8pt; + font-family:arial,helvetica; + +} + +p.intro +{ + margin-left:20px; + margin-right:20px; + + font-size:10pt; +/* font-weight:bold; */ + font-family:arial,helvetica; +} + +p.clink +{ + font-size:12pt; + font-family:courier,monospace; + text-align:center; +} + +p.clink9 +{ + font-size:9pt; + font-family:courier,monospace; + text-align:center; +} + + +p +{ + padding-left:10px; +} + +p.right +{ + text-align:right; +} + diff --git a/apps/webserver/httpd-fs/tcp.shtml b/apps/webserver/httpd-fs/tcp.shtml new file mode 100644 index 0000000..4c4bffe --- /dev/null +++ b/apps/webserver/httpd-fs/tcp.shtml @@ -0,0 +1,5 @@ +%!: /header.html +

Current connections


+ +%! tcp-connections +%!: /footer.html \ No newline at end of file diff --git a/apps/webserver/httpd-fsdata.c b/apps/webserver/httpd-fsdata.c new file mode 100644 index 0000000..491095e --- /dev/null +++ b/apps/webserver/httpd-fsdata.c @@ -0,0 +1,607 @@ +static const unsigned char data_processes_shtml[] = { + /* /processes.shtml */ + 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x3c, 0x2f, 0x68, + 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, + 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x49, 0x44, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4e, 0x61, 0x6d, 0x65, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50, 0x6f, 0x6c, 0x6c, + 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50, + 0x72, 0x6f, 0x63, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, + 0x21, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, + 0x73, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, 0x6f, 0x6f, + 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0}; + +static const unsigned char data_404_html[] = { + /* /404.html */ + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, + 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, + 0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, + 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, + 0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, +0}; + +static const unsigned char data_files_shtml[] = { + /* /files.shtml */ + 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x31, + 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, + 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, 0x30, 0x22, 0x3e, + 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, + 0x3e, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, + 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, + 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, + 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, + 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, + 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x31, + 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25, 0x21, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, + 0x73, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, + 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, + 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, + 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, + 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, + 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x31, 0x30, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25, 0x21, 0x20, + 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x20, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x74, 0x63, 0x70, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, + 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, + 0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, + 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, + 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, + 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, + 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, + 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, + 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, + 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25, + 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x20, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, + 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x2f, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, + 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0xa, 0x3c, 0x2f, 0x74, + 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, + 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0xa, 0x3e, 0x20, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, + 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x34, + 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, + 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, + 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x34, 0x30, 0x34, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, + 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x34, 0x30, 0x34, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, + 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, + 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x3e, 0x2f, 0x66, 0x61, + 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, + 0x70, 0x6e, 0x67, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, + 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, + 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, + 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, + 0x70, 0x6e, 0x67, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x2f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xa, 0x3c, 0x2f, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x3a, 0x20, + 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, + 0x6d, 0x6c, 0xa, 0}; + +static const unsigned char data_footer_html[] = { + /* /footer.html */ + 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, + 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0}; + +static const unsigned char data_header_html[] = { + /* /header.html */ + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x49, 0x50, 0x20, 0x77, + 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x21, + 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, + 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, + 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, + 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x20, + 0x20, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, + 0x66, 0x66, 0x66, 0x65, 0x65, 0x63, 0x22, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x3d, 0x22, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x22, + 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, + 0x75, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, + 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x46, + 0x72, 0x6f, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f, + 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, + 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, + 0x65, 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0xa, 0x20, 0x20, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0xa, 0x20, + 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0}; + +static const unsigned char data_index_html[] = { + /* /index.html */ + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x49, 0x50, 0x20, 0x77, + 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x21, + 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, + 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, + 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, + 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x20, + 0x20, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, + 0x66, 0x66, 0x66, 0x65, 0x65, 0x63, 0x22, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x3d, 0x22, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x22, + 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, + 0x75, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, + 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x46, + 0x72, 0x6f, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f, + 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, + 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, + 0x65, 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0xa, 0x20, 0x20, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x70, + 0x3e, 0xa, 0x20, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, + 0x77, 0x65, 0x62, 0x20, 0x70, 0x61, 0x67, 0x65, 0x73, 0x20, + 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x73, 0x6d, 0x61, 0x6c, + 0x6c, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, + 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x66, + 0xa, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, + 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, + 0x2f, 0x75, 0x69, 0x70, 0x2f, 0x22, 0x3e, 0x75, 0x49, 0x50, + 0x20, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, + 0x54, 0x43, 0x50, 0x2f, 0x49, 0x50, 0xa, 0x20, 0x20, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x3c, 0x2f, 0x61, 0x3e, 0x2e, 0xa, + 0x20, 0x20, 0x3c, 0x2f, 0x70, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x70, 0x3e, 0xa, 0x20, 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b, + 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, + 0x6e, 0x6b, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x2e, 0xa, 0x20, 0x20, 0x3c, + 0x2f, 0x70, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0xa, 0}; + +static const unsigned char data_style_css[] = { + /* /style.css */ + 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0, + 0x68, 0x31, 0x20, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x20, 0x20, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x34, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, + 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, + 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0xa, 0x20, 0x20, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70, + 0x78, 0x3b, 0x20, 0xa, 0x7d, 0xa, 0xa, 0x62, 0x6f, 0x64, + 0x79, 0xa, 0x7b, 0xa, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x65, + 0x65, 0x63, 0x3b, 0xa, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x3b, 0xa, 0xa, + 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, + 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, + 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0xa, 0x7d, 0xa, + 0xa, 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0xa, 0x7b, 0xa, 0x20, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x34, + 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x36, 0x30, 0x25, 0x3b, 0xa, 0xa, 0x20, 0x20, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x32, 0x70, + 0x78, 0x3b, 0xa, 0x9, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x31, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, + 0x63, 0x64, 0x32, 0x3b, 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6c, 0x65, + 0x66, 0x74, 0x3b, 0xa, 0x20, 0x20, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x39, + 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, + 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, + 0x69, 0x63, 0x61, 0x3b, 0x20, 0x20, 0xa, 0x7d, 0xa, 0xa, + 0x64, 0x69, 0x76, 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f, + 0x78, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x20, 0x32, 0x35, 0x25, 0x3b, 0xa, 0x20, 0x20, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x30, 0x3b, + 0xa, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x20, + 0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0xa, 0x7b, 0x20, 0x20, 0xa, 0x20, 0x20, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x34, 0x70, 0x78, + 0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x36, 0x30, 0x25, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x32, 0x70, 0x78, 0x3b, + 0xa, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x64, 0x6f, 0x74, 0x74, + 0x65, 0x64, 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3b, + 0xa, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, 0x20, + 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, + 0x6c, 0x79, 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, + 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0x20, + 0x20, 0xa, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x69, 0x6e, + 0x74, 0x72, 0x6f, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x32, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, 0xa, 0xa, 0x20, 0x20, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x30, 0x70, 0x74, 0x3b, 0xa, 0x2f, 0x2a, 0x20, 0x20, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x20, 0x2a, 0x2f, + 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, + 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, + 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, + 0x3b, 0x20, 0x20, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x63, + 0x6c, 0x69, 0x6e, 0x6b, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, + 0x32, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x63, + 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x2c, 0x6d, 0x6f, 0x6e, + 0x6f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x20, 0xa, + 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, + 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x63, 0x6c, 0x69, 0x6e, + 0x6b, 0x39, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x39, 0x70, 0x74, + 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, + 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x63, 0x6f, 0x75, 0x72, + 0x69, 0x65, 0x72, 0x2c, 0x6d, 0x6f, 0x6e, 0x6f, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x3b, 0x20, 0x20, 0xa, 0x20, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x7d, 0xa, + 0xa, 0xa, 0x70, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x7d, 0xa, 0xa, + 0x70, 0x2e, 0x72, 0x69, 0x67, 0x68, 0x74, 0xa, 0x7b, 0xa, + 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x20, + 0xa, 0x7d, 0xa, 0xa, 0}; + +static const unsigned char data_tcp_shtml[] = { + /* /tcp.shtml */ + 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa, + 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, + 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, + 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x74, 0x68, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x46, + 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, + 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x20, 0x74, 0x63, + 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, + 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, +0}; + +static const unsigned char data_fade_png[] = { + /* /fade.png */ + 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0, + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 00, 00, + 00, 0xd, 0x49, 0x48, 0x44, 0x52, 00, 00, 00, 0x4, + 00, 00, 00, 0xa, 0x8, 0x2, 00, 00, 00, 0x1c, + 0x99, 0x68, 0x59, 00, 00, 00, 0x9, 0x70, 0x48, 0x59, + 0x73, 00, 00, 0xb, 0x13, 00, 00, 0xb, 0x13, 0x1, + 00, 0x9a, 0x9c, 0x18, 00, 00, 00, 0x7, 0x74, 0x49, + 0x4d, 0x45, 0x7, 0xd6, 0x6, 0x8, 0x14, 0x1b, 0x39, 0xaf, + 0x5b, 0xc0, 0xe3, 00, 00, 00, 0x1d, 0x74, 0x45, 0x58, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 00, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, + 0xef, 0x64, 0x25, 0x6e, 00, 00, 00, 0x3a, 0x49, 0x44, + 0x41, 0x54, 0x8, 0xd7, 0x75, 0x8c, 0x31, 0x12, 00, 0x10, + 0x10, 0xc4, 0x2e, 0x37, 0x9e, 0x40, 0x65, 0xfd, 0xff, 0x83, + 0xf4, 0xa, 0x1c, 0x8d, 0x54, 0x9b, 0xc9, 0xcc, 0x9a, 0x3d, + 0x90, 0x73, 0x71, 0x67, 0x91, 0xd4, 0x74, 0x36, 0xa9, 0x55, + 0x1, 0xf8, 0x29, 0x58, 0xc8, 0xbf, 0x48, 0xc4, 0x81, 0x74, + 0xb, 0xa3, 0xf, 0x7c, 0xdb, 0x4, 0xe8, 0x40, 0x5, 0xdf, + 0xa1, 0xf3, 0xfc, 0x73, 00, 00, 00, 00, 0x49, 0x45, + 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0}; + +static const unsigned char data_stats_shtml[] = { + /* /stats.shtml */ + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, + 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, + 0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, + 0x22, 0x30, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, + 0x74, 0x64, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0xa, 0x49, + 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, + 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, + 0x73, 0x65, 0x6e, 0x74, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x49, 0x50, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x20, 0x20, 0x20, 0x20, + 0x49, 0x50, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, + 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68, + 0x69, 0x67, 0x68, 0x20, 0x62, 0x79, 0x74, 0x65, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74, + 0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, 0x72, + 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0xa, 0x49, 0x43, 0x4d, 0x50, 0x9, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x54, 0x79, 0x70, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0xa, 0x54, 0x43, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, + 0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, + 0x41, 0x43, 0x4b, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, + 0x73, 0x65, 0x74, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x76, 0x61, 0x6c, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x20, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72, + 0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, + 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0x25, 0x21, 0x20, 0x6e, + 0x65, 0x74, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c, + 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0xa, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, + 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, + 0xa, 0}; + +const struct httpd_fsdata_file file_processes_shtml[] = {{NULL, data_processes_shtml, data_processes_shtml + 17, sizeof(data_processes_shtml) - 17}}; + +const struct httpd_fsdata_file file_404_html[] = {{file_processes_shtml, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}}; + +const struct httpd_fsdata_file file_files_shtml[] = {{file_404_html, data_files_shtml, data_files_shtml + 13, sizeof(data_files_shtml) - 13}}; + +const struct httpd_fsdata_file file_footer_html[] = {{file_files_shtml, data_footer_html, data_footer_html + 13, sizeof(data_footer_html) - 13}}; + +const struct httpd_fsdata_file file_header_html[] = {{file_footer_html, data_header_html, data_header_html + 13, sizeof(data_header_html) - 13}}; + +const struct httpd_fsdata_file file_index_html[] = {{file_header_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}}; + +const struct httpd_fsdata_file file_style_css[] = {{file_index_html, data_style_css, data_style_css + 11, sizeof(data_style_css) - 11}}; + +const struct httpd_fsdata_file file_tcp_shtml[] = {{file_style_css, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11}}; + +const struct httpd_fsdata_file file_fade_png[] = {{file_tcp_shtml, data_fade_png, data_fade_png + 10, sizeof(data_fade_png) - 10}}; + +const struct httpd_fsdata_file file_stats_shtml[] = {{file_fade_png, data_stats_shtml, data_stats_shtml + 13, sizeof(data_stats_shtml) - 13}}; + +#define HTTPD_FS_ROOT file_stats_shtml + +#define HTTPD_FS_NUMFILES 10 diff --git a/apps/httpd/fsdata.h b/apps/webserver/httpd-fsdata.h similarity index 64% rename from apps/httpd/fsdata.h rename to apps/webserver/httpd-fsdata.h index e525f4e..0ad2d6e 100644 --- a/apps/httpd/fsdata.h +++ b/apps/webserver/httpd-fsdata.h @@ -1,64 +1,64 @@ /* * Copyright (c) 2001, Swedish Institute of Computer Science. - * All rights reserved. + * 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. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 lwIP TCP/IP stack. - * + * * Author: Adam Dunkels * - * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $ + * $Id: httpd-fsdata.h,v 1.1 2006/06/07 09:13:08 adam Exp $ */ -#ifndef __FSDATA_H__ -#define __FSDATA_H__ +#ifndef __HTTPD_FSDATA_H__ +#define __HTTPD_FSDATA_H__ -#include "uipopt.h" +#include "uip.h" -struct fsdata_file { - const struct fsdata_file *next; +struct httpd_fsdata_file { + const struct httpd_fsdata_file *next; const char *name; const char *data; const int len; -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 u16_t count; -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ }; -struct fsdata_file_noconst { - struct fsdata_file *next; +struct httpd_fsdata_file_noconst { + struct httpd_fsdata_file *next; char *name; char *data; int len; -#ifdef FS_STATISTICS -#if FS_STATISTICS == 1 +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 u16_t count; -#endif /* FS_STATISTICS */ -#endif /* FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ }; -#endif /* __FSDATA_H__ */ +#endif /* __HTTPD_FSDATA_H__ */ diff --git a/apps/webserver/httpd.c b/apps/webserver/httpd.c new file mode 100644 index 0000000..937e138 --- /dev/null +++ b/apps/webserver/httpd.c @@ -0,0 +1,338 @@ +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup httpd Web server + * @{ + * The uIP web server is a very simplistic implementation of an HTTP + * server. It can serve web pages and files from a read-only ROM + * filesystem, and provides a very small scripting language. + + */ + +/** + * \file + * Web server + * \author + * Adam Dunkels + */ + + +/* + * Copyright (c) 2004, 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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. + * + * Author: Adam Dunkels + * + * $Id: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $ + */ + +#include "uip.h" +#include "httpd.h" +#include "httpd-fs.h" +#include "httpd-cgi.h" +#include "http-strings.h" + +#include + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_bang 0x21 +#define ISO_percent 0x25 +#define ISO_period 0x2e +#define ISO_slash 0x2f +#define ISO_colon 0x3a + + +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_part_of_file(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + memcpy(uip_appdata, s->file.data, s->len); + + return s->len; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + do { + PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s); + s->file.len -= s->len; + s->file.data += s->len; + } while(s->file.len > 0); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_part_of_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + PSOCK_SEND(&s->sout, s->file.data, s->len); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static void +next_scriptstate(struct httpd_state *s) +{ + char *p; + p = strchr(s->scriptptr, ISO_nl) + 1; + s->scriptlen -= (unsigned short)(p - s->scriptptr); + s->scriptptr = p; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_script(struct httpd_state *s)) +{ + char *ptr; + + PT_BEGIN(&s->scriptpt); + + + while(s->file.len > 0) { + + /* Check if we should start executing a script. */ + if(*s->file.data == ISO_percent && + *(s->file.data + 1) == ISO_bang) { + s->scriptptr = s->file.data + 3; + s->scriptlen = s->file.len - 3; + if(*(s->scriptptr - 1) == ISO_colon) { + httpd_fs_open(s->scriptptr + 1, &s->file); + PT_WAIT_THREAD(&s->scriptpt, send_file(s)); + } else { + PT_WAIT_THREAD(&s->scriptpt, + httpd_cgi(s->scriptptr)(s, s->scriptptr)); + } + next_scriptstate(s); + + /* The script is over, so we reset the pointers and continue + sending the rest of the file. */ + s->file.data = s->scriptptr; + s->file.len = s->scriptlen; + } else { + /* See if we find the start of script marker in the block of HTML + to be sent. */ + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + + if(*s->file.data == ISO_percent) { + ptr = strchr(s->file.data + 1, ISO_percent); + } else { + ptr = strchr(s->file.data, ISO_percent); + } + if(ptr != NULL && + ptr != s->file.data) { + s->len = (int)(ptr - s->file.data); + if(s->len >= uip_mss()) { + s->len = uip_mss(); + } + } + PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s)); + s->file.data += s->len; + s->file.len -= s->len; + + } + } + + PT_END(&s->scriptpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + char *ptr; + + PSOCK_BEGIN(&s->sout); + + PSOCK_SEND_STR(&s->sout, statushdr); + + ptr = strrchr(s->filename, ISO_period); + if(ptr == NULL) { + PSOCK_SEND_STR(&s->sout, http_content_type_binary); + } else if(strncmp(http_html, ptr, 5) == 0 || + strncmp(http_shtml, ptr, 6) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_html); + } else if(strncmp(http_css, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_css); + } else if(strncmp(http_png, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_png); + } else if(strncmp(http_gif, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_gif); + } else if(strncmp(http_jpg, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_jpg); + } else { + PSOCK_SEND_STR(&s->sout, http_content_type_plain); + } + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + char *ptr; + + PT_BEGIN(&s->outputpt); + + if(!httpd_fs_open(s->filename, &s->file)) { + httpd_fs_open(http_404_html, &s->file); + strcpy(s->filename, http_404_html); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, + http_header_404)); + PT_WAIT_THREAD(&s->outputpt, + send_file(s)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, + http_header_200)); + ptr = strchr(s->filename, ISO_period); + if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) { + PT_INIT(&s->scriptpt); + PT_WAIT_THREAD(&s->outputpt, handle_script(s)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_file(s)); + } + } + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); + } + + /* httpd_log_file(uip_conn->ripaddr, s->filename);*/ + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); + + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + /* httpd_log(&s->inputbuf[9]);*/ + } + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void) +{ + struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate); + + if(uip_closed() || uip_aborted() || uip_timedout()) { + } else if(uip_connected()) { + PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->state = STATE_WAITING; + /* timer_set(&s->timer, CLOCK_SECOND * 100);*/ + s->timer = 0; + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + ++s->timer; + if(s->timer >= 20) { + uip_abort(); + } + } else { + s->timer = 0; + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the web server + * + * This function initializes the web server and should be + * called at system boot-up. + */ +void +httpd_init(void) +{ + uip_listen(HTONS(80)); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/httpd/cgi.h b/apps/webserver/httpd.h similarity index 63% rename from apps/httpd/cgi.h rename to apps/webserver/httpd.h index dbc98f7..270d49d 100644 --- a/apps/httpd/cgi.h +++ b/apps/webserver/httpd.h @@ -1,29 +1,18 @@ -/** - * \addtogroup httpd - * @{ - */ - -/** - * \file - * HTTP script language header file. - * \author Adam Dunkels - */ - /* - * Copyright (c) 2001, Adam Dunkels. - * All rights reserved. + * Copyright (c) 2001-2005, 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -35,23 +24,39 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: cgi.h,v 1.3.2.4 2003/10/07 13:22:27 adam Exp $ + * $Id: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $ * */ -#ifndef __CGI_H__ -#define __CGI_H__ +#ifndef __HTTPD_H__ +#define __HTTPD_H__ -typedef u8_t (* cgifunction)(u8_t next); +#include "psock.h" +#include "httpd-fs.h" -/** - * A table containing pointers to C functions that can be called from - * a web server script. - */ -extern cgifunction cgitab[]; +struct httpd_state { + unsigned char timer; + struct psock sin, sout; + struct pt outputpt, scriptpt; + char inputbuf[50]; + char filename[20]; + char state; + struct httpd_fs_file file; + int len; + char *scriptptr; + int scriptlen; + + unsigned short count; +}; -#endif /* __CGI_H__ */ +void httpd_init(void); +void httpd_appcall(void); + +void httpd_log(char *msg); +void httpd_log_file(u16_t *requester, char *file); + +#endif /* __HTTPD_H__ */ diff --git a/apps/webserver/makefsdata b/apps/webserver/makefsdata new file mode 100755 index 0000000..b2109ab --- /dev/null +++ b/apps/webserver/makefsdata @@ -0,0 +1,78 @@ +#!/usr/bin/perl + +open(OUTPUT, "> httpd-fsdata.c"); + +chdir("httpd-fs"); + +opendir(DIR, "."); +@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); +closedir(DIR); + +foreach $file (@files) { + + if(-d $file && $file !~ /^\./) { + print "Processing directory $file\n"; + opendir(DIR, $file); + @newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); + closedir(DIR); + printf "Adding files @newfiles\n"; + @files = (@files, map { $_ = "$file/$_" } @newfiles); + next; + } +} + +foreach $file (@files) { + if(-f $file) { + + print "Adding file $file\n"; + + open(FILE, $file) || die "Could not open file $file\n"; + + $file =~ s-^-/-; + $fvar = $file; + $fvar =~ s-/-_-g; + $fvar =~ s-\.-_-g; + # for AVR, add PROGMEM here + print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); + print(OUTPUT "\t/* $file */\n\t"); + for($j = 0; $j < length($file); $j++) { + printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); + } + printf(OUTPUT "0,\n"); + + + $i = 0; + while(read(FILE, $data, 1)) { + if($i == 0) { + print(OUTPUT "\t"); + } + printf(OUTPUT "%#02x, ", unpack("C", $data)); + $i++; + if($i == 10) { + print(OUTPUT "\n"); + $i = 0; + } + } + print(OUTPUT "0};\n\n"); + close(FILE); + push(@fvars, $fvar); + push(@pfiles, $file); + } +} + +for($i = 0; $i < @fvars; $i++) { + $file = $pfiles[$i]; + $fvar = $fvars[$i]; + + if($i == 0) { + $prevfile = "NULL"; + } else { + $prevfile = "file" . $fvars[$i - 1]; + } + print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); + print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); + print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); +} + +print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n"); +print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n"); diff --git a/apps/webserver/makestrings b/apps/webserver/makestrings new file mode 100755 index 0000000..20f0e24 --- /dev/null +++ b/apps/webserver/makestrings @@ -0,0 +1,40 @@ +#!/usr/bin/perl + + +sub stringify { + my $name = shift(@_); + open(OUTPUTC, "> $name.c"); + open(OUTPUTH, "> $name.h"); + + open(FILE, "$name"); + + while() { + if(/(.+) "(.+)"/) { + $var = $1; + $data = $2; + + $datan = $data; + $datan =~ s/\\r/\r/g; + $datan =~ s/\\n/\n/g; + $datan =~ s/\\01/\01/g; + $datan =~ s/\\0/\0/g; + + printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1); + printf(OUTPUTC "/* \"$data\" */\n"); + printf(OUTPUTC "{"); + for($j = 0; $j < length($datan); $j++) { + printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1))); + } + printf(OUTPUTC "};\n"); + + printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1); + + } + } + close(OUTPUTC); + close(OUTPUTH); +} +stringify("http-strings"); + +exit 0; + diff --git a/apps/httpd/httpd.h b/apps/webserver/webserver.h similarity index 54% rename from apps/httpd/httpd.h rename to apps/webserver/webserver.h index a56221c..48753e6 100644 --- a/apps/httpd/httpd.h +++ b/apps/webserver/webserver.h @@ -1,29 +1,19 @@ -/** - * \addtogroup httpd - * @{ - */ - -/** - * \file - * HTTP server header file. - * \author Adam Dunkels - */ - /* - * Copyright (c) 2001, Adam Dunkels. - * All rights reserved. + * Copyright (c) 2002, 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -35,20 +25,19 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * This file is part of the uIP TCP/IP stack. + * This file is part of the uIP TCP/IP stack * - * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $ + * $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $ * */ +#ifndef __WEBSERVER_H__ +#define __WEBSERVER_H__ -#ifndef __HTTPD_H__ -#define __HTTPD_H__ - -void httpd_init(void); -void httpd_appcall(void); +#include "httpd.h" +typedef struct httpd_state uip_tcp_appstate_t; /* UIP_APPCALL: the name of the application function. This function must return void and take no arguments (i.e., C type "void appfunc(void)"). */ @@ -56,22 +45,5 @@ void httpd_appcall(void); #define UIP_APPCALL httpd_appcall #endif -struct httpd_state { - u8_t state; - u16_t count; - char *dataptr; - char *script; -}; - -/* UIP_APPSTATE_SIZE: The size of the application-specific state - stored in the uip_conn structure. */ -#ifndef UIP_APPSTATE_SIZE -#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state)) -#endif - -#define FS_STATISTICS 1 - -extern struct httpd_state *hs; - -#endif /* __HTTPD_H__ */ +#endif /* __WEBSERVER_H__ */ diff --git a/doc/Doxyfile b/doc/Doxyfile index d1c00fb..8c6223d 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1,52 +1,75 @@ -# Doxyfile 1.3.3 +# Doxyfile 1.4.6 #--------------------------------------------------------------------------- -# General configuration options +# Project related configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = "uIP 0.9" +PROJECT_NAME = "uIP 1.0" PROJECT_NUMBER = OUTPUT_DIRECTORY = . +CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO -EXTRACT_ALL = NO -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = NO -HIDE_UNDOC_MEMBERS = YES -HIDE_UNDOC_CLASSES = YES -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = ../ \ ../../ -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES +STRIP_FROM_INC_PATH = SHORT_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES JAVADOC_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = YES INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 8 +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = NO GENERATE_DEPRECATEDLIST= NO -ALIASES = ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO SHOW_USED_FILES = NO -SUBGROUPING = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -54,56 +77,79 @@ QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = uip-doc.txt \ + pt-doc.txt \ + examples.txt \ + uip-code-style.txt \ ../uip/uip.h \ ../uip/uip.c \ ../uip/uip_arch.h \ ../uip/uip_arp.h \ ../uip/uip_arp.c \ - ../uip/slipdev.h \ - ../uip/slipdev.c \ - ../unix/uipopt.h \ - ../apps/webclient/webclient.h \ - ../apps/webclient/webclient.c \ + ../unix/uip-conf.h \ + ../uip/uipopt.h \ + ../uip/uip-split.h \ + ../uip/uip-split.c \ + ../uip/uip-neighbor.h \ + ../uip/uip-neighbor.c \ + ../uip/pt.h \ + ../uip/lc.h \ + ../uip/lc-switch.h \ + ../uip/lc-addrlabels.h \ + ../uip/timer.h \ + ../uip/timer.c \ + ../uip/clock.h \ + ../uip/psock.h \ + ../uip/psock.c \ + ../lib/memb.c \ + ../lib/memb.h \ + ../apps/resolv/resolv.h \ + ../apps/resolv/resolv.c \ + ../apps/dhcpc/dhcpc.h \ + ../apps/dhcpc/dhcpc.c \ ../apps/smtp/smtp.h \ ../apps/smtp/smtp.c \ ../apps/telnetd/telnetd.h \ ../apps/telnetd/telnetd.c \ - ../apps/telnetd/telnetd-shell.c \ - ../apps/telnetd/memb.h \ - ../apps/telnetd/memb.c \ - ../apps/httpd/httpd.h \ - ../apps/httpd/httpd.c \ - ../apps/httpd/cgi.h \ - ../apps/httpd/cgi.c \ - ../apps/httpd/fs.h \ - ../apps/httpd/fs.c \ - ../apps/resolv/resolv.h \ - ../apps/resolv/resolv.c + ../apps/telnetd/shell.h \ + ../apps/telnetd/shell.c \ + ../apps/hello-world/hello-world.h \ + ../apps/hello-world/hello-world.c \ + ../apps/webclient/webclient.h \ + ../apps/webclient/webclient.c \ + ../apps/webserver/httpd.h \ + ../apps/webserver/httpd-cgi.h \ + ../apps/webserver/httpd-cgi.c \ + ../apps/webserver/httpd.c FILE_PATTERNS = RECURSIVE = NO EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = -EXAMPLE_PATH = +EXAMPLE_PATH = . ../apps/hello-world ../apps/smtp \ + ../apps/telnetd ../apps/resolv ../apps/webclient \ + ../apps/webserver ../unix ../apps/dhcpc EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = +FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- -SOURCE_BROWSER = NO +SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = NO REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES +USE_HTAGS = NO VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index @@ -141,7 +187,7 @@ MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = -LATEX_HEADER = +LATEX_HEADER = header.tex PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO @@ -169,6 +215,7 @@ GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = +XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -193,7 +240,7 @@ PREDEFINED = UIP_UDP EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::addtions related to external references +# Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = @@ -203,32 +250,30 @@ PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = NO CLASS_GRAPH = NO -COLLABORATION_GRAPH = YES +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO UML_LOOK = NO TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = YES -GRAPHICAL_HIERARCHY = YES +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 MAX_DOT_GRAPH_HEIGHT = 1024 MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine +# Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO -CGI_NAME = search.cgi -CGI_URL = -DOC_URL = -DOC_ABSPATH = -BIN_ABSPATH = /usr/local/bin/ -EXT_DOC_PATHS = diff --git a/doc/Makefile b/doc/Makefile index fadaea6..249018a 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,5 +1,7 @@ +all: htmldoc pdfdoc + htmldoc: doxygen Doxyfile pdfdoc: htmldoc - cd latex; make refman.pdf && mv refman.pdf ../uip-refman.pdf \ No newline at end of file + cd latex; make refman.pdf && mv refman.pdf ../uip-refman.pdf diff --git a/doc/doxygen.sty b/doc/doxygen.sty new file mode 100644 index 0000000..15e4f66 --- /dev/null +++ b/doc/doxygen.sty @@ -0,0 +1,62 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{doxygen} +\RequirePackage{calc} +\RequirePackage{array} +\pagestyle{fancyplain} +\newcommand{\clearemptydoublepage}{\newpage{\pagestyle{empty}\cleardoublepage}} +\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} +\lhead[\fancyplain{}{\bfseries\thepage}] + {\fancyplain{}{\bfseries\rightmark}} +\rhead[\fancyplain{}{\bfseries\leftmark}] + {\fancyplain{}{\bfseries\thepage}} +\rfoot[\fancyplain{}{\bfseries\scriptsize Generated on Wed Jun 7 11:37:14 2006 for uIP 1.0-rc0 by doxygen\lfoot[]{\fancyplain{}{\bfseries\scriptsize Generated on Wed Jun 7 11:37:14 2006 for uIP 1.0-rc0 by doxygen}} +\cfoot{} +\newenvironment{CompactList} +{\begin{list}{}{ + \setlength{\leftmargin}{0.5cm} + \setlength{\itemsep}{0pt} + \setlength{\parsep}{0pt} + \setlength{\topsep}{0pt} + \renewcommand{\makelabel}{}}} +{\end{list}} +\newenvironment{CompactItemize} +{ + \begin{itemize} + \setlength{\itemsep}{-3pt} + \setlength{\parsep}{0pt} + \setlength{\topsep}{0pt} + \setlength{\partopsep}{0pt} +} +{\end{itemize}} +\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp} +\newlength{\tmplength} +\newenvironment{TabularC}[1] +{ +\setlength{\tmplength} + {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)} + \par\begin{tabular*}{\linewidth} + {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|} +} +{\end{tabular*}\par} +\newcommand{\entrylabel}[1]{ + {\parbox[b]{\labelwidth-4pt}{\makebox[0pt][l]{\textbf{#1}}\\}}} +\newenvironment{Desc} +{\begin{list}{} + { + \settowidth{\labelwidth}{40pt} + \setlength{\leftmargin}{\labelwidth} + \setlength{\parsep}{0pt} + \setlength{\itemsep}{-4pt} + \renewcommand{\makelabel}{\entrylabel} + } +} +{\end{list}} +\newenvironment{Indent} + {\begin{list}{}{\setlength{\leftmargin}{0.5cm}} + \item[]\ignorespaces} + {\unskip\end{list}} +\setlength{\parindent}{0cm} +\setlength{\parskip}{0.2cm} +\addtocounter{secnumdepth}{1} +\sloppy +\usepackage[T1]{fontenc} diff --git a/doc/example-mainloop-with-arp.c b/doc/example-mainloop-with-arp.c new file mode 100644 index 0000000..7ed72c5 --- /dev/null +++ b/doc/example-mainloop-with-arp.c @@ -0,0 +1,86 @@ +#include "uip.h" +#include "uip_arp.h" +#include "network-device.h" +#include "httpd.h" +#include "timer.h" + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +/*---------------------------------------------------------------------------*/ +int +main(void) +{ + int i; + uip_ipaddr_t ipaddr; + struct timer periodic_timer, arp_timer; + + timer_set(&periodic_timer, CLOCK_SECOND / 2); + timer_set(&arp_timer, CLOCK_SECOND * 10); + + network_device_init(); + uip_init(); + + uip_ipaddr(ipaddr, 192,168,0,2); + uip_sethostaddr(ipaddr); + + httpd_init(); + + while(1) { + uip_len = network_device_read(); + if(uip_len > 0) { + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + network_device_send(); + } + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + network_device_send(); + } + } + + } else if(timer_expired(&periodic_timer)) { + timer_reset(&periodic_timer); + for(i = 0; i < UIP_CONNS; i++) { + uip_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + network_device_send(); + } + } + +#if UIP_UDP + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + network_device_send(); + } + } +#endif /* UIP_UDP */ + + /* Call the ARP timer function every 10 seconds. */ + if(timer_expired(&arp_timer)) { + timer_reset(&arp_timer); + uip_arp_timer(); + } + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/example-mainloop-without-arp.c b/doc/example-mainloop-without-arp.c new file mode 100644 index 0000000..85800e3 --- /dev/null +++ b/doc/example-mainloop-without-arp.c @@ -0,0 +1,62 @@ +#include "uip.h" +#include "uip_arp.h" +#include "network-device.h" +#include "httpd.h" +#include "timer.h" + +/*---------------------------------------------------------------------------*/ +int +main(void) +{ + int i; + uip_ipaddr_t ipaddr; + struct timer periodic_timer; + + timer_set(&periodic_timer, CLOCK_SECOND / 2); + + network_device_init(); + uip_init(); + + uip_ipaddr(ipaddr, 192,168,0,2); + uip_sethostaddr(ipaddr); + + httpd_init(); + + while(1) { + uip_len = network_device_read(); + if(uip_len > 0) { + uip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + network_device_send(); + } + } else if(timer_expired(&periodic_timer)) { + timer_reset(&periodic_timer); + for(i = 0; i < UIP_CONNS; i++) { + uip_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + network_device_send(); + } + } + +#if UIP_UDP + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + network_device_send(); + } + } +#endif /* UIP_UDP */ + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/examples.txt b/doc/examples.txt new file mode 100644 index 0000000..31edddc --- /dev/null +++ b/doc/examples.txt @@ -0,0 +1,34 @@ +/** +\defgroup apps Applications +@{ + +The uIP distribution contains a number of example applications that +can be either used directory or studied when learning to develop +applications for uIP. + +*/ + +/** \example hello-world.c */ +/** \example hello-world.h */ + +/** \example smtp.c */ +/** \example smtp.h */ + +/** \example webclient.c */ +/** \example webclient.h */ + +/** \example example-mainloop-with-arp.c */ +/** \example example-mainloop-without-arp.c */ + +/** \example telnetd.c */ +/** \example telnetd.h */ + +/** \example resolv.c */ +/** \example resolv.h */ + +/** \example dhcpc.c */ +/** \example dhcpc.h */ + +/** \example uip-conf.h */ + +/** @} */ diff --git a/doc/header.tex b/doc/header.tex new file mode 100644 index 0000000..ce91c30 --- /dev/null +++ b/doc/header.tex @@ -0,0 +1,53 @@ +\documentclass[a4paper]{book} +\usepackage{a4wide} +\usepackage{makeidx} +\usepackage{fancyhdr} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{times} +\ifx\pdfoutput\undefined +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue + ]{hyperref} +\usepackage{pspicture} +\else +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue + ]{hyperref} +\fi +\usepackage{doxygen} +\makeindex +\setcounter{tocdepth}{1} +\renewcommand{\footrulewidth}{0.4pt} +\begin{document} +\begin{titlepage} +\vspace*{5cm} +\begin{center} +{\Huge The uIP Embedded TCP/IP Stack}\\ +\vspace*{1cm} +{\LARGE The uIP 1.0 Reference Manual}\\ +\vspace*{3cm} +{\Large June 2006}\\ +\vspace*{2cm} +\includegraphics[width=6cm]{../sicslogo.pdf}\\ +\vspace*{1cm} +{\Large Adam Dunkels}\\ +{\Large \texttt{adam@sics.se}}\\ +\vspace*{1cm} +{\LARGE Swedish Institute of Computer Science}\\ +\vspace*{0.5cm} + +\end{center} +\end{titlepage} +\clearemptydoublepage +\pagenumbering{roman} +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} diff --git a/doc/html/a00030.html b/doc/html/a00030.html deleted file mode 100644 index 725cf12..0000000 --- a/doc/html/a00030.html +++ /dev/null @@ -1,33 +0,0 @@ - - -uIP 0.9: fs_file struct Reference - - - - -

fs_file Struct Reference
- -[Web server] -

#include <fs.h> -

-


Detailed Description

-An open file in the read-only file system. -

-

LocalRemoteStateRetransmissionsTimerFlags
- - - - - - - - -

Data Fields

-char * data
 The actual file data.

-int len
 The length of the file data.

-
Generated on Tue Oct 7 15:51:41 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00036.html b/doc/html/a00036.html index ea1329f..9ee3cf2 100644 --- a/doc/html/a00036.html +++ b/doc/html/a00036.html @@ -1,24 +1,120 @@ - + -uIP 0.9: telnetd_state struct Reference +uIP 1.0: hello-world.c + - - -

telnetd_state Struct Reference
- -[Telnet server] -

#include <telnetd.h> -

-


Detailed Description

-A telnet connection structure. -

- - -
-


Generated on Tue Oct 7 15:51:41 2003 for uIP 0.9 by + + +

hello-world.c

00001 /**
+00002  * \addtogroup helloworld
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \file
+00008  *         An example of how to write uIP applications
+00009  *         with protosockets.
+00010  * \author
+00011  *         Adam Dunkels <adam@sics.se>
+00012  */
+00013 
+00014 /*
+00015  * This is a short example of how to write uIP applications using
+00016  * protosockets.
+00017  */
+00018 
+00019 /*
+00020  * We define the application state (struct hello_world_state) in the
+00021  * hello-world.h file, so we need to include it here. We also include
+00022  * uip.h (since this cannot be included in hello-world.h) and
+00023  * <string.h>, since we use the memcpy() function in the code.
+00024  */
+00025 #include "hello-world.h"
+00026 #include "uip.h"
+00027 #include <string.h>
+00028 
+00029 /*
+00030  * Declaration of the protosocket function that handles the connection
+00031  * (defined at the end of the code).
+00032  */
+00033 static int handle_connection(struct hello_world_state *s);
+00034 /*---------------------------------------------------------------------------*/
+00035 /*
+00036  * The initialization function. We must explicitly call this function
+00037  * from the system initialization code, some time after uip_init() is
+00038  * called.
+00039  */
+00040 void
+00041 hello_world_init(void)
+00042 {
+00043   /* We start to listen for connections on TCP port 1000. */
+00044   uip_listen(HTONS(1000));
+00045 }
+00046 /*---------------------------------------------------------------------------*/
+00047 /*
+00048  * In hello-world.h we have defined the UIP_APPCALL macro to
+00049  * hello_world_appcall so that this funcion is uIP's application
+00050  * function. This function is called whenever an uIP event occurs
+00051  * (e.g. when a new connection is established, new data arrives, sent
+00052  * data is acknowledged, data needs to be retransmitted, etc.).
+00053  */
+00054 void
+00055 hello_world_appcall(void)
+00056 {
+00057   /*
+00058    * The uip_conn structure has a field called "appstate" that holds
+00059    * the application state of the connection. We make a pointer to
+00060    * this to access it easier.
+00061    */
+00062   struct hello_world_state *s = &(uip_conn->appstate);
+00063 
+00064   /*
+00065    * If a new connection was just established, we should initialize
+00066    * the protosocket in our applications' state structure.
+00067    */
+00068   if(uip_connected()) {
+00069     PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer));
+00070   }
+00071 
+00072   /*
+00073    * Finally, we run the protosocket function that actually handles
+00074    * the communication. We pass it a pointer to the application state
+00075    * of the current connection.
+00076    */
+00077   handle_connection(s);
+00078 }
+00079 /*---------------------------------------------------------------------------*/
+00080 /*
+00081  * This is the protosocket function that handles the communication. A
+00082  * protosocket function must always return an int, but must never
+00083  * explicitly return - all return statements are hidden in the PSOCK
+00084  * macros.
+00085  */
+00086 static int
+00087 handle_connection(struct hello_world_state *s)
+00088 {
+00089   PSOCK_BEGIN(&s->p);
+00090 
+00091   PSOCK_SEND_STR(&s->p, "Hello. What is your name?\n");
+00092   PSOCK_READTO(&s->p, '\n');
+00093   strncpy(s->name, s->inputbuffer, sizeof(s->name));
+00094   PSOCK_SEND_STR(&s->p, "Hello ");
+00095   PSOCK_SEND_STR(&s->p, s->name);
+00096   PSOCK_CLOSE(&s->p);
+00097   
+00098   PSOCK_END(&s->p);
+00099 }
+00100 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00037.html b/doc/html/a00037.html index ede2947..13d709b 100644 --- a/doc/html/a00037.html +++ b/doc/html/a00037.html @@ -1,87 +1,72 @@ - + -uIP 0.9: uip_conn struct Reference +uIP 1.0: hello-world.h + - - -

uip_conn Struct Reference
- -[The uIP TCP/IP stack] -

#include <uip.h> -

-


Detailed Description

-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. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Fields

-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.

-u8_t appstate [UIP_APPSTATE_SIZE]
 The application state.

-


Generated on Tue Oct 7 15:51:41 2003 for uIP 0.9 by + + +

hello-world.h

00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup helloworld Hello, world
+00008  * @{
+00009  *
+00010  * A small example showing how to write applications with
+00011  * \ref psock "protosockets".
+00012  */
+00013 
+00014 /**
+00015  * \file
+00016  *         Header file for an example of how to write uIP applications
+00017  *         with protosockets.
+00018  * \author
+00019  *         Adam Dunkels <adam@sics.se>
+00020  */
+00021 
+00022 #ifndef __HELLO_WORLD_H__
+00023 #define __HELLO_WORLD_H__
+00024 
+00025 /* Since this file will be included by uip.h, we cannot include uip.h
+00026    here. But we might need to include uipopt.h if we need the u8_t and
+00027    u16_t datatypes. */
+00028 #include "uipopt.h"
+00029 
+00030 #include "psock.h"
+00031 
+00032 /* Next, we define the uip_tcp_appstate_t datatype. This is the state
+00033    of our application, and the memory required for this state is
+00034    allocated together with each TCP connection. One application state
+00035    for each TCP connection. */
+00036 typedef struct hello_world_state {
+00037   struct psock p;
+00038   char inputbuffer[10];
+00039   char name[40];
+00040 } uip_tcp_appstate_t;
+00041 
+00042 /* Finally we define the application function to be called by uIP. */
+00043 void hello_world_appcall(void);
+00044 #ifndef UIP_APPCALL
+00045 #define UIP_APPCALL hello_world_appcall
+00046 #endif /* UIP_APPCALL */
+00047 
+00048 void hello_world_init(void);
+00049 
+00050 #endif /* __HELLO_WORLD_H__ */
+00051 /** @} */
+00052 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00038.html b/doc/html/a00038.html index a8dba05..f62a273 100644 --- a/doc/html/a00038.html +++ b/doc/html/a00038.html @@ -1,24 +1,282 @@ - + -uIP 0.9: uip_eth_addr struct Reference +uIP 1.0: smtp.c + - - -

uip_eth_addr Struct Reference
- -[uIP Address Resolution Protocol] -

#include <uip_arp.h> -

-


Detailed Description

-Representation of a 48-bit Ethernet address. -

- - -
-


Generated on Tue Oct 7 15:51:41 2003 for uIP 0.9 by + + +

smtp.c

00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup smtp SMTP E-mail sender
+00008  * @{
+00009  *
+00010  * The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is
+00011  * the standard way of sending and transfering e-mail on the
+00012  * Internet. This simple example implementation is intended as an
+00013  * example of how to implement protocols in uIP, and is able to send
+00014  * out e-mail but has not been extensively tested.
+00015  */
+00016 
+00017 /**
+00018  * \file
+00019  * SMTP example implementation
+00020  * \author Adam Dunkels <adam@dunkels.com>
+00021  */
+00022 
+00023 /*
+00024  * Copyright (c) 2004, Adam Dunkels.
+00025  * All rights reserved.
+00026  *
+00027  * Redistribution and use in source and binary forms, with or without
+00028  * modification, are permitted provided that the following conditions
+00029  * are met:
+00030  * 1. Redistributions of source code must retain the above copyright
+00031  *    notice, this list of conditions and the following disclaimer.
+00032  * 2. Redistributions in binary form must reproduce the above copyright
+00033  *    notice, this list of conditions and the following disclaimer in the
+00034  *    documentation and/or other materials provided with the distribution.
+00035  * 3. Neither the name of the Institute nor the names of its contributors
+00036  *    may be used to endorse or promote products derived from this software
+00037  *    without specific prior written permission.
+00038  *
+00039  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00040  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00041  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00042  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00043  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00044  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00045  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00046  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00047  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00048  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00049  * SUCH DAMAGE.
+00050  *
+00051  * This file is part of the uIP TCP/IP stack.
+00052  *
+00053  * Author: Adam Dunkels <adam@sics.se>
+00054  *
+00055  * $Id: smtp.c,v 1.4 2006/06/11 21:46:37 adam Exp $
+00056  */
+00057 #include "smtp.h"
+00058 
+00059 #include "smtp-strings.h"
+00060 #include "psock.h"
+00061 #include "uip.h"
+00062 
+00063 #include <string.h>
+00064 
+00065 static struct smtp_state s;
+00066 
+00067 static char *localhostname;
+00068 static uip_ipaddr_t smtpserver;
+00069 
+00070 #define ISO_nl 0x0a
+00071 #define ISO_cr 0x0d
+00072 
+00073 #define ISO_period 0x2e
+00074 
+00075 #define ISO_2  0x32
+00076 #define ISO_3  0x33
+00077 #define ISO_4  0x34
+00078 #define ISO_5  0x35
+00079 
+00080 
+00081 /*---------------------------------------------------------------------------*/
+00082 static
+00083 PT_THREAD(smtp_thread(void))
+00084 {
+00085   PSOCK_BEGIN(&s.psock);
+00086 
+00087   PSOCK_READTO(&s.psock, ISO_nl);
+00088    
+00089   if(strncmp(s.inputbuffer, smtp_220, 3) != 0) {
+00090     PSOCK_CLOSE(&s.psock);
+00091     smtp_done(2);
+00092     PSOCK_EXIT(&s.psock);
+00093   }
+00094   
+00095   PSOCK_SEND_STR(&s.psock, (char *)smtp_helo);
+00096   PSOCK_SEND_STR(&s.psock, localhostname);
+00097   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00098 
+00099   PSOCK_READTO(&s.psock, ISO_nl);
+00100   
+00101   if(s.inputbuffer[0] != ISO_2) {
+00102     PSOCK_CLOSE(&s.psock);
+00103     smtp_done(3);
+00104     PSOCK_EXIT(&s.psock);
+00105   }
+00106 
+00107   PSOCK_SEND_STR(&s.psock, (char *)smtp_mail_from);
+00108   PSOCK_SEND_STR(&s.psock, s.from);
+00109   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00110 
+00111   PSOCK_READTO(&s.psock, ISO_nl);
+00112   
+00113   if(s.inputbuffer[0] != ISO_2) {
+00114     PSOCK_CLOSE(&s.psock);
+00115     smtp_done(4);
+00116     PSOCK_EXIT(&s.psock);
+00117   }
+00118 
+00119   PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
+00120   PSOCK_SEND_STR(&s.psock, s.to);
+00121   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00122 
+00123   PSOCK_READTO(&s.psock, ISO_nl);
+00124   
+00125   if(s.inputbuffer[0] != ISO_2) {
+00126     PSOCK_CLOSE(&s.psock);
+00127     smtp_done(5);
+00128     PSOCK_EXIT(&s.psock);
+00129   }
+00130   
+00131   if(s.cc != 0) {
+00132     PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
+00133     PSOCK_SEND_STR(&s.psock, s.cc);
+00134     PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00135 
+00136     PSOCK_READTO(&s.psock, ISO_nl);
+00137   
+00138     if(s.inputbuffer[0] != ISO_2) {
+00139       PSOCK_CLOSE(&s.psock);
+00140       smtp_done(6);
+00141       PSOCK_EXIT(&s.psock);
+00142     }
+00143   }
+00144   
+00145   PSOCK_SEND_STR(&s.psock, (char *)smtp_data);
+00146   
+00147   PSOCK_READTO(&s.psock, ISO_nl);
+00148   
+00149   if(s.inputbuffer[0] != ISO_3) {
+00150     PSOCK_CLOSE(&s.psock);
+00151     smtp_done(7);
+00152     PSOCK_EXIT(&s.psock);
+00153   }
+00154 
+00155   PSOCK_SEND_STR(&s.psock, (char *)smtp_to);
+00156   PSOCK_SEND_STR(&s.psock, s.to);
+00157   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00158   
+00159   if(s.cc != 0) {
+00160     PSOCK_SEND_STR(&s.psock, (char *)smtp_cc);
+00161     PSOCK_SEND_STR(&s.psock, s.cc);
+00162     PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00163   }
+00164   
+00165   PSOCK_SEND_STR(&s.psock, (char *)smtp_from);
+00166   PSOCK_SEND_STR(&s.psock, s.from);
+00167   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00168   
+00169   PSOCK_SEND_STR(&s.psock, (char *)smtp_subject);
+00170   PSOCK_SEND_STR(&s.psock, s.subject);
+00171   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00172 
+00173   PSOCK_SEND(&s.psock, s.msg, s.msglen);
+00174   
+00175   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnlperiodcrnl);
+00176 
+00177   PSOCK_READTO(&s.psock, ISO_nl);
+00178   if(s.inputbuffer[0] != ISO_2) {
+00179     PSOCK_CLOSE(&s.psock);
+00180     smtp_done(8);
+00181     PSOCK_EXIT(&s.psock);
+00182   }
+00183 
+00184   PSOCK_SEND_STR(&s.psock, (char *)smtp_quit);
+00185   smtp_done(SMTP_ERR_OK);
+00186   PSOCK_END(&s.psock);
+00187 }
+00188 /*---------------------------------------------------------------------------*/
+00189 void
+00190 smtp_appcall(void)
+00191 {
+00192   if(uip_closed()) {
+00193     s.connected = 0;
+00194     return;
+00195   }
+00196   if(uip_aborted() || uip_timedout()) {
+00197     s.connected = 0;
+00198     smtp_done(1);
+00199     return;
+00200   }
+00201   smtp_thread();
+00202 }
+00203 /*---------------------------------------------------------------------------*/
+00204 /**
+00205  * Specificy an SMTP server and hostname.
+00206  *
+00207  * This function is used to configure the SMTP module with an SMTP
+00208  * server and the hostname of the host.
+00209  *
+00210  * \param lhostname The hostname of the uIP host.
+00211  *
+00212  * \param server A pointer to a 4-byte array representing the IP
+00213  * address of the SMTP server to be configured.
+00214  */
+00215 void
+00216 smtp_configure(char *lhostname, void *server)
+00217 {
+00218   localhostname = lhostname;
+00219   uip_ipaddr_copy(smtpserver, server);
+00220 }
+00221 /*---------------------------------------------------------------------------*/
+00222 /**
+00223  * Send an e-mail.
+00224  *
+00225  * \param to The e-mail address of the receiver of the e-mail.
+00226  * \param cc The e-mail address of the CC: receivers of the e-mail.
+00227  * \param from The e-mail address of the sender of the e-mail.
+00228  * \param subject The subject of the e-mail.
+00229  * \param msg The actual e-mail message.
+00230  * \param msglen The length of the e-mail message.
+00231  */
+00232 unsigned char
+00233 smtp_send(char *to, char *cc, char *from,
+00234           char *subject, char *msg, u16_t msglen)
+00235 {
+00236   struct uip_conn *conn;
+00237 
+00238   conn = uip_connect(smtpserver, HTONS(25));
+00239   if(conn == NULL) {
+00240     return 0;
+00241   }
+00242   s.connected = 1;
+00243   s.to = to;
+00244   s.cc = cc;
+00245   s.from = from;
+00246   s.subject = subject;
+00247   s.msg = msg;
+00248   s.msglen = msglen;
+00249 
+00250   PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer));
+00251   
+00252   return 1;
+00253 }
+00254 /*---------------------------------------------------------------------------*/
+00255 void
+00256 smtp_init(void)
+00257 {
+00258   s.connected = 0;
+00259 }
+00260 /*---------------------------------------------------------------------------*/
+00261 /** @} */
+00262 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00039.html b/doc/html/a00039.html index f8d5c0f..fb02d5a 100644 --- a/doc/html/a00039.html +++ b/doc/html/a00039.html @@ -1,28 +1,123 @@ - + -uIP 0.9: uip_eth_hdr struct Reference +uIP 1.0: smtp.h + - - -

uip_eth_hdr Struct Reference
- -[uIP Address Resolution Protocol] -

#include <uip_arp.h> -

-Collaboration diagram for uip_eth_hdr:

Collaboration graph
- - - -
[legend]

Detailed Description

-The Ethernet header. -

- - -
-


Generated on Tue Oct 7 15:51:42 2003 for uIP 0.9 by + + +

smtp.h

00001 
+00002 /**
+00003  * \addtogroup smtp
+00004  * @{
+00005  */
+00006 
+00007 
+00008 /**
+00009  * \file
+00010  * SMTP header file
+00011  * \author Adam Dunkels <adam@dunkels.com>
+00012  */
+00013 
+00014 /*
+00015  * Copyright (c) 2002, Adam Dunkels.
+00016  * All rights reserved.
+00017  *
+00018  * Redistribution and use in source and binary forms, with or without
+00019  * modification, are permitted provided that the following conditions
+00020  * are met:
+00021  * 1. Redistributions of source code must retain the above copyright
+00022  *    notice, this list of conditions and the following disclaimer.
+00023  * 2. Redistributions in binary form must reproduce the above copyright
+00024  *    notice, this list of conditions and the following disclaimer in the
+00025  *    documentation and/or other materials provided with the distribution.
+00026  * 3. The name of the author may not be used to endorse or promote
+00027  *    products derived from this software without specific prior
+00028  *    written permission.
+00029  *
+00030  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00031  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00032  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00033  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00034  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00035  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00036  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00037  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00038  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00039  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00040  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00041  *
+00042  * This file is part of the uIP TCP/IP stack.
+00043  *
+00044  * $Id: smtp.h,v 1.4 2006/06/11 21:46:37 adam Exp $
+00045  *
+00046  */
+00047 #ifndef __SMTP_H__
+00048 #define __SMTP_H__
+00049 
+00050 #include "uipopt.h"
+00051 
+00052 /**
+00053  * Error number that signifies a non-error condition.
+00054  */
+00055 #define SMTP_ERR_OK 0
+00056 
+00057 /**
+00058  * Callback function that is called when an e-mail transmission is
+00059  * done.
+00060  *
+00061  * This function must be implemented by the module that uses the SMTP
+00062  * module.
+00063  *
+00064  * \param error The number of the error if an error occured, or
+00065  * SMTP_ERR_OK.
+00066  */
+00067 void smtp_done(unsigned char error);
+00068 
+00069 void smtp_init(void);
+00070 
+00071 /* Functions. */
+00072 void smtp_configure(char *localhostname, u16_t *smtpserver);
+00073 unsigned char smtp_send(char *to, char *from,
+00074                         char *subject, char *msg,
+00075                         u16_t msglen);
+00076 #define SMTP_SEND(to, cc, from, subject, msg) \
+00077         smtp_send(to, cc, from, subject, msg, strlen(msg))
+00078 
+00079 void smtp_appcall(void);
+00080 
+00081 struct smtp_state {
+00082   u8_t state;
+00083   char *to;
+00084   char *from;
+00085   char *subject;
+00086   char *msg;
+00087   u16_t msglen;
+00088   
+00089   u16_t sentlen, textlen;
+00090   u16_t sendptr;
+00091 
+00092 };
+00093 
+00094 
+00095 #ifndef UIP_APPCALL
+00096 #define UIP_APPCALL     smtp_appcall
+00097 #endif
+00098 typedef struct smtp_state uip_tcp_appstate_t;
+00099 
+00100 
+00101 #endif /* __SMTP_H__ */
+00102 
+00103 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00040.html b/doc/html/a00040.html new file mode 100644 index 0000000..1b1f554 --- /dev/null +++ b/doc/html/a00040.html @@ -0,0 +1,459 @@ + + +uIP 1.0: webclient.c + + + + + +

webclient.c

00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup webclient Web client
+00008  * @{
+00009  *
+00010  * This example shows a HTTP client that is able to download web pages
+00011  * and files from web servers. It requires a number of callback
+00012  * functions to be implemented by the module that utilizes the code:
+00013  * webclient_datahandler(), webclient_connected(),
+00014  * webclient_timedout(), webclient_aborted(), webclient_closed().
+00015  */
+00016 
+00017 /**
+00018  * \file
+00019  * Implementation of the HTTP client.
+00020  * \author Adam Dunkels <adam@dunkels.com>
+00021  */
+00022 
+00023 /*
+00024  * Copyright (c) 2002, Adam Dunkels.
+00025  * All rights reserved.
+00026  *
+00027  * Redistribution and use in source and binary forms, with or without
+00028  * modification, are permitted provided that the following conditions
+00029  * are met:
+00030  * 1. Redistributions of source code must retain the above copyright
+00031  *    notice, this list of conditions and the following disclaimer.
+00032  * 2. Redistributions in binary form must reproduce the above
+00033  *    copyright notice, this list of conditions and the following
+00034  *    disclaimer in the documentation and/or other materials provided
+00035  *    with the distribution.
+00036  * 3. The name of the author may not be used to endorse or promote
+00037  *    products derived from this software without specific prior
+00038  *    written permission.
+00039  *
+00040  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00041  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00042  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00043  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00044  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00045  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00046  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00047  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00048  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00049  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00050  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00051  *
+00052  * This file is part of the uIP TCP/IP stack.
+00053  *
+00054  * $Id: webclient.c,v 1.2 2006/06/11 21:46:37 adam Exp $
+00055  *
+00056  */
+00057 
+00058 #include "uip.h"
+00059 #include "uiplib.h"
+00060 #include "webclient.h"
+00061 #include "resolv.h"
+00062 
+00063 #include <string.h>
+00064 
+00065 #define WEBCLIENT_TIMEOUT 100
+00066 
+00067 #define WEBCLIENT_STATE_STATUSLINE 0
+00068 #define WEBCLIENT_STATE_HEADERS    1
+00069 #define WEBCLIENT_STATE_DATA       2
+00070 #define WEBCLIENT_STATE_CLOSE      3
+00071 
+00072 #define HTTPFLAG_NONE   0
+00073 #define HTTPFLAG_OK     1
+00074 #define HTTPFLAG_MOVED  2
+00075 #define HTTPFLAG_ERROR  3
+00076 
+00077 
+00078 #define ISO_nl       0x0a
+00079 #define ISO_cr       0x0d
+00080 #define ISO_space    0x20
+00081 
+00082 
+00083 static struct webclient_state s;
+00084 
+00085 /*-----------------------------------------------------------------------------------*/
+00086 char *
+00087 webclient_mimetype(void)
+00088 {
+00089   return s.mimetype;
+00090 }
+00091 /*-----------------------------------------------------------------------------------*/
+00092 char *
+00093 webclient_filename(void)
+00094 {
+00095   return s.file;
+00096 }
+00097 /*-----------------------------------------------------------------------------------*/
+00098 char *
+00099 webclient_hostname(void)
+00100 {
+00101   return s.host;
+00102 }
+00103 /*-----------------------------------------------------------------------------------*/
+00104 unsigned short
+00105 webclient_port(void)
+00106 {
+00107   return s.port;
+00108 }
+00109 /*-----------------------------------------------------------------------------------*/
+00110 void
+00111 webclient_init(void)
+00112 {
+00113 
+00114 }
+00115 /*-----------------------------------------------------------------------------------*/
+00116 static void
+00117 init_connection(void)
+00118 {
+00119   s.state = WEBCLIENT_STATE_STATUSLINE;
+00120 
+00121   s.getrequestleft = sizeof(http_get) - 1 + 1 +
+00122     sizeof(http_10) - 1 +
+00123     sizeof(http_crnl) - 1 +
+00124     sizeof(http_host) - 1 +
+00125     sizeof(http_crnl) - 1 +
+00126     strlen(http_user_agent_fields) +
+00127     strlen(s.file) + strlen(s.host);
+00128   s.getrequestptr = 0;
+00129 
+00130   s.httpheaderlineptr = 0;
+00131 }
+00132 /*-----------------------------------------------------------------------------------*/
+00133 void
+00134 webclient_close(void)
+00135 {
+00136   s.state = WEBCLIENT_STATE_CLOSE;
+00137 }
+00138 /*-----------------------------------------------------------------------------------*/
+00139 unsigned char
+00140 webclient_get(char *host, u16_t port, char *file)
+00141 {
+00142   struct uip_conn *conn;
+00143   uip_ipaddr_t *ipaddr;
+00144   static uip_ipaddr_t addr;
+00145   
+00146   /* First check if the host is an IP address. */
+00147   ipaddr = &addr;
+00148   if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) {
+00149     ipaddr = (uip_ipaddr_t *)resolv_lookup(host);
+00150     
+00151     if(ipaddr == NULL) {
+00152       return 0;
+00153     }
+00154   }
+00155   
+00156   conn = uip_connect(ipaddr, htons(port));
+00157   
+00158   if(conn == NULL) {
+00159     return 0;
+00160   }
+00161   
+00162   s.port = port;
+00163   strncpy(s.file, file, sizeof(s.file));
+00164   strncpy(s.host, host, sizeof(s.host));
+00165   
+00166   init_connection();
+00167   return 1;
+00168 }
+00169 /*-----------------------------------------------------------------------------------*/
+00170 static unsigned char *
+00171 copy_string(unsigned char *dest,
+00172             const unsigned char *src, unsigned char len)
+00173 {
+00174   strncpy(dest, src, len);
+00175   return dest + len;
+00176 }
+00177 /*-----------------------------------------------------------------------------------*/
+00178 static void
+00179 senddata(void)
+00180 {
+00181   u16_t len;
+00182   char *getrequest;
+00183   char *cptr;
+00184   
+00185   if(s.getrequestleft > 0) {
+00186     cptr = getrequest = (char *)uip_appdata;
+00187 
+00188     cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
+00189     cptr = copy_string(cptr, s.file, strlen(s.file));
+00190     *cptr++ = ISO_space;
+00191     cptr = copy_string(cptr, http_10, sizeof(http_10) - 1);
+00192 
+00193     cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
+00194     
+00195     cptr = copy_string(cptr, http_host, sizeof(http_host) - 1);
+00196     cptr = copy_string(cptr, s.host, strlen(s.host));
+00197     cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
+00198 
+00199     cptr = copy_string(cptr, http_user_agent_fields,
+00200                        strlen(http_user_agent_fields));
+00201     
+00202     len = s.getrequestleft > uip_mss()?
+00203       uip_mss():
+00204       s.getrequestleft;
+00205     uip_send(&(getrequest[s.getrequestptr]), len);
+00206   }
+00207 }
+00208 /*-----------------------------------------------------------------------------------*/
+00209 static void
+00210 acked(void)
+00211 {
+00212   u16_t len;
+00213   
+00214   if(s.getrequestleft > 0) {
+00215     len = s.getrequestleft > uip_mss()?
+00216       uip_mss():
+00217       s.getrequestleft;
+00218     s.getrequestleft -= len;
+00219     s.getrequestptr += len;
+00220   }
+00221 }
+00222 /*-----------------------------------------------------------------------------------*/
+00223 static u16_t
+00224 parse_statusline(u16_t len)
+00225 {
+00226   char *cptr;
+00227   
+00228   while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
+00229     s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
+00230     ++((char *)uip_appdata);
+00231     --len;
+00232     if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
+00233 
+00234       if((strncmp(s.httpheaderline, http_10,
+00235                   sizeof(http_10) - 1) == 0) ||
+00236          (strncmp(s.httpheaderline, http_11,
+00237                   sizeof(http_11) - 1) == 0)) {
+00238         cptr = &(s.httpheaderline[9]);
+00239         s.httpflag = HTTPFLAG_NONE;
+00240         if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) {
+00241           /* 200 OK */
+00242           s.httpflag = HTTPFLAG_OK;
+00243         } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 ||
+00244                   strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) {
+00245           /* 301 Moved permanently or 302 Found. Location: header line
+00246              will contain thw new location. */
+00247           s.httpflag = HTTPFLAG_MOVED;
+00248         } else {
+00249           s.httpheaderline[s.httpheaderlineptr - 1] = 0;
+00250         }
+00251       } else {
+00252         uip_abort();
+00253         webclient_aborted();
+00254         return 0;
+00255       }
+00256       
+00257       /* We're done parsing the status line, so we reset the pointer
+00258          and start parsing the HTTP headers.*/
+00259       s.httpheaderlineptr = 0;
+00260       s.state = WEBCLIENT_STATE_HEADERS;
+00261       break;
+00262     } else {
+00263       ++s.httpheaderlineptr;
+00264     }
+00265   }
+00266   return len;
+00267 }
+00268 /*-----------------------------------------------------------------------------------*/
+00269 static char
+00270 casecmp(char *str1, const char *str2, char len)
+00271 {
+00272   static char c;
+00273   
+00274   while(len > 0) {
+00275     c = *str1;
+00276     /* Force lower-case characters. */
+00277     if(c & 0x40) {
+00278       c |= 0x20;
+00279     }
+00280     if(*str2 != c) {
+00281       return 1;
+00282     }
+00283     ++str1;
+00284     ++str2;
+00285     --len;
+00286   }
+00287   return 0;
+00288 }
+00289 /*-----------------------------------------------------------------------------------*/
+00290 static u16_t
+00291 parse_headers(u16_t len)
+00292 {
+00293   char *cptr;
+00294   static unsigned char i;
+00295   
+00296   while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
+00297     s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
+00298     ++((char *)uip_appdata);
+00299     --len;
+00300     if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
+00301       /* We have an entire HTTP header line in s.httpheaderline, so
+00302          we parse it. */
+00303       if(s.httpheaderline[0] == ISO_cr) {
+00304         /* This was the last header line (i.e., and empty "\r\n"), so
+00305            we are done with the headers and proceed with the actual
+00306            data. */
+00307         s.state = WEBCLIENT_STATE_DATA;
+00308         return len;
+00309       }
+00310 
+00311       s.httpheaderline[s.httpheaderlineptr - 1] = 0;
+00312       /* Check for specific HTTP header fields. */
+00313       if(casecmp(s.httpheaderline, http_content_type,
+00314                      sizeof(http_content_type) - 1) == 0) {
+00315         /* Found Content-type field. */
+00316         cptr = strchr(s.httpheaderline, ';');
+00317         if(cptr != NULL) {
+00318           *cptr = 0;
+00319         }
+00320         strncpy(s.mimetype, s.httpheaderline +
+00321                 sizeof(http_content_type) - 1, sizeof(s.mimetype));
+00322       } else if(casecmp(s.httpheaderline, http_location,
+00323                             sizeof(http_location) - 1) == 0) {
+00324         cptr = s.httpheaderline +
+00325           sizeof(http_location) - 1;
+00326         
+00327         if(strncmp(cptr, http_http, 7) == 0) {
+00328           cptr += 7;
+00329           for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
+00330             if(*cptr == 0 ||
+00331                *cptr == '/' ||
+00332                *cptr == ' ' ||
+00333                *cptr == ':') {
+00334               s.host[i] = 0;
+00335               break;
+00336             }
+00337             s.host[i] = *cptr;
+00338             ++cptr;
+00339           }
+00340         }
+00341         strncpy(s.file, cptr, sizeof(s.file));
+00342         /*      s.file[s.httpheaderlineptr - i] = 0;*/
+00343       }
+00344 
+00345 
+00346       /* We're done parsing, so we reset the pointer and start the
+00347          next line. */
+00348       s.httpheaderlineptr = 0;
+00349     } else {
+00350       ++s.httpheaderlineptr;
+00351     }
+00352   }
+00353   return len;
+00354 }
+00355 /*-----------------------------------------------------------------------------------*/
+00356 static void
+00357 newdata(void)
+00358 {
+00359   u16_t len;
+00360 
+00361   len = uip_datalen();
+00362 
+00363   if(s.state == WEBCLIENT_STATE_STATUSLINE) {
+00364     len = parse_statusline(len);
+00365   }
+00366   
+00367   if(s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
+00368     len = parse_headers(len);
+00369   }
+00370 
+00371   if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
+00372      s.httpflag != HTTPFLAG_MOVED) {
+00373     webclient_datahandler((char *)uip_appdata, len);
+00374   }
+00375 }
+00376 /*-----------------------------------------------------------------------------------*/
+00377 void
+00378 webclient_appcall(void)
+00379 {
+00380   if(uip_connected()) {
+00381     s.timer = 0;
+00382     s.state = WEBCLIENT_STATE_STATUSLINE;
+00383     senddata();
+00384     webclient_connected();
+00385     return;
+00386   }
+00387 
+00388   if(s.state == WEBCLIENT_STATE_CLOSE) {
+00389     webclient_closed();
+00390     uip_abort();
+00391     return;
+00392   }
+00393 
+00394   if(uip_aborted()) {
+00395     webclient_aborted();
+00396   }
+00397   if(uip_timedout()) {
+00398     webclient_timedout();
+00399   }
+00400 
+00401   
+00402   if(uip_acked()) {
+00403     s.timer = 0;
+00404     acked();
+00405   }
+00406   if(uip_newdata()) {
+00407     s.timer = 0;
+00408     newdata();
+00409   }
+00410   if(uip_rexmit() ||
+00411      uip_newdata() ||
+00412      uip_acked()) {
+00413     senddata();
+00414   } else if(uip_poll()) {
+00415     ++s.timer;
+00416     if(s.timer == WEBCLIENT_TIMEOUT) {
+00417       webclient_timedout();
+00418       uip_abort();
+00419       return;
+00420     }
+00421         /*    senddata();*/
+00422   }
+00423 
+00424   if(uip_closed()) {
+00425     if(s.httpflag != HTTPFLAG_MOVED) {
+00426       /* Send NULL data to signal EOF. */
+00427       webclient_datahandler(NULL, 0);
+00428     } else {
+00429       if(resolv_lookup(s.host) == NULL) {
+00430         resolv_query(s.host);
+00431       }
+00432       webclient_get(s.host, s.port, s.file);
+00433     }
+00434   }
+00435 }
+00436 /*-----------------------------------------------------------------------------------*/
+00437 
+00438 /** @} */
+00439 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00041.html b/doc/html/a00041.html index 3afba21..f1f93ea 100644 --- a/doc/html/a00041.html +++ b/doc/html/a00041.html @@ -1,448 +1,248 @@ - + -uIP 0.9: uip_stats struct Reference +uIP 1.0: webclient.h + - - -

uip_stats Struct Reference
- -[The uIP TCP/IP stack] -

#include <uip.h> -

-


Detailed Description

-The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Fields

-struct {
   uip_stats_t   drop
   uip_stats_t   recv
   uip_stats_t   sent
   uip_stats_t   vhlerr
   uip_stats_t   hblenerr
   uip_stats_t   lblenerr
   uip_stats_t   fragerr
   uip_stats_t   chkerr
   uip_stats_t   protoerr
ip
 IP statistics.

-struct {
   uip_stats_t   drop
   uip_stats_t   recv
   uip_stats_t   sent
   uip_stats_t   typeerr
icmp
 ICMP statistics.

-struct {
   uip_stats_t   drop
   uip_stats_t   recv
   uip_stats_t   sent
   uip_stats_t   chkerr
   uip_stats_t   ackerr
   uip_stats_t   rst
   uip_stats_t   rexmit
   uip_stats_t   syndrop
   uip_stats_t   synrst
tcp
 TCP statistics.

-


Field Documentation

-

- - - - -
- - -
uip_stats_t uip_stats::ackerr -
-
- - - - - -
-   - - -

-Number of TCP segments with a bad ACK number. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::chkerr -
-
- - - - - -
-   - - -

-Number of TCP segments with a bad checksum. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::drop -
-
- - - - - -
-   - - -

-Number of dropped TCP segments. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::fragerr -
-
- - - - - -
-   - - -

-Number of packets dropped since they were IP fragments. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::hblenerr -
-
- - - - - -
-   - - -

-Number of packets dropped due to wrong IP length, high byte. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::lblenerr -
-
- - - - - -
-   - - -

-Number of packets dropped due to wrong IP length, low byte. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::protoerr -
-
- - - - - -
-   - - -

-Number of packets dropped since they were neither ICMP, UDP nor TCP. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::recv -
-
- - - - - -
-   - - -

-Number of recived TCP segments. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::rexmit -
-
- - - - - -
-   - - -

-Number of retransmitted TCP segments. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::rst -
-
- - - - - -
-   - - -

-Number of recevied TCP RST (reset) segments. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::sent -
-
- - - - - -
-   - - -

-Number of sent TCP segments. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::syndrop -
-
- - - - - -
-   - - -

-Number of dropped SYNs due to too few connections was avaliable. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::synrst -
-
- - - - - -
-   - - -

-Number of SYNs for closed ports, triggering a RST. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::typeerr -
-
- - - - - -
-   - - -

-Number of ICMP packets with a wrong type. -

-

-

- - - - -
- - -
uip_stats_t uip_stats::vhlerr -
-
- - - - - -
-   - - -

-Number of packets dropped due to wrong IP version or header length. -

-

-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by + + +

webclient.h

00001 /**
+00002  * \addtogroup webclient
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \file
+00008  * Header file for the HTTP client.
+00009  * \author Adam Dunkels <adam@dunkels.com>
+00010  */
+00011 
+00012 /*
+00013  * Copyright (c) 2002, Adam Dunkels.
+00014  * All rights reserved.
+00015  *
+00016  * Redistribution and use in source and binary forms, with or without
+00017  * modification, are permitted provided that the following conditions
+00018  * are met:
+00019  * 1. Redistributions of source code must retain the above copyright
+00020  *    notice, this list of conditions and the following disclaimer.
+00021  * 2. Redistributions in binary form must reproduce the above
+00022  *    copyright notice, this list of conditions and the following
+00023  *    disclaimer in the documentation and/or other materials provided
+00024  *    with the distribution.
+00025  * 3. The name of the author may not be used to endorse or promote
+00026  *    products derived from this software without specific prior
+00027  *    written permission.
+00028  *
+00029  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00030  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00031  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00033  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00035  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00036  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00037  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00038  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00039  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00040  *
+00041  * This file is part of the uIP TCP/IP stack.
+00042  *
+00043  * $Id: webclient.h,v 1.2 2006/06/11 21:46:37 adam Exp $
+00044  *
+00045  */
+00046 #ifndef __WEBCLIENT_H__
+00047 #define __WEBCLIENT_H__
+00048 
+00049 
+00050 #include "webclient-strings.h"
+00051 #include "uipopt.h"
+00052 
+00053 #define WEBCLIENT_CONF_MAX_URLLEN 100
+00054 
+00055 struct webclient_state {
+00056   u8_t timer;
+00057   u8_t state;
+00058   u8_t httpflag;
+00059 
+00060   u16_t port;
+00061   char host[40];
+00062   char file[WEBCLIENT_CONF_MAX_URLLEN];
+00063   u16_t getrequestptr;
+00064   u16_t getrequestleft;
+00065   
+00066   char httpheaderline[200];
+00067   u16_t httpheaderlineptr;
+00068 
+00069   char mimetype[32];
+00070 };
+00071 
+00072 typedef struct webclient_state uip_tcp_appstate_t;
+00073 #define UIP_APPCALL webclient_appcall
+00074 
+00075 /**
+00076  * Callback function that is called from the webclient code when HTTP
+00077  * data has been received.
+00078  *
+00079  * This function must be implemented by the module that uses the
+00080  * webclient code. The function is called from the webclient module
+00081  * when HTTP data has been received. The function is not called when
+00082  * HTTP headers are received, only for the actual data.
+00083  *
+00084  * \note This function is called many times, repetedly, when data is
+00085  * being received, and not once when all data has been received.
+00086  *
+00087  * \param data A pointer to the data that has been received.
+00088  * \param len The length of the data that has been received.
+00089  */
+00090 void webclient_datahandler(char *data, u16_t len);
+00091 
+00092 /**
+00093  * Callback function that is called from the webclient code when the
+00094  * HTTP connection has been connected to the web server.
+00095  *
+00096  * This function must be implemented by the module that uses the
+00097  * webclient code.
+00098  */
+00099 void webclient_connected(void);
+00100 
+00101 /**
+00102  * Callback function that is called from the webclient code if the
+00103  * HTTP connection to the web server has timed out.
+00104  *
+00105  * This function must be implemented by the module that uses the
+00106  * webclient code.
+00107  */
+00108 void webclient_timedout(void);
+00109 
+00110 /**
+00111  * Callback function that is called from the webclient code if the
+00112  * HTTP connection to the web server has been aborted by the web
+00113  * server.
+00114  *
+00115  * This function must be implemented by the module that uses the
+00116  * webclient code.
+00117  */
+00118 void webclient_aborted(void);
+00119 
+00120 /**
+00121  * Callback function that is called from the webclient code when the
+00122  * HTTP connection to the web server has been closed.
+00123  *
+00124  * This function must be implemented by the module that uses the
+00125  * webclient code.
+00126  */
+00127 void webclient_closed(void);
+00128 
+00129 
+00130 
+00131 /**
+00132  * Initialize the webclient module.
+00133  */
+00134 void webclient_init(void);
+00135 
+00136 /**
+00137  * Open an HTTP connection to a web server and ask for a file using
+00138  * the GET method.
+00139  *
+00140  * This function opens an HTTP connection to the specified web server
+00141  * and requests the specified file using the GET method. When the HTTP
+00142  * connection has been connected, the webclient_connected() callback
+00143  * function is called and when the HTTP data arrives the
+00144  * webclient_datahandler() callback function is called.
+00145  *
+00146  * The callback function webclient_timedout() is called if the web
+00147  * server could not be contacted, and the webclient_aborted() callback
+00148  * function is called if the HTTP connection is aborted by the web
+00149  * server.
+00150  *
+00151  * When the HTTP request has been completed and the HTTP connection is
+00152  * closed, the webclient_closed() callback function will be called.
+00153  *
+00154  * \note If the function is passed a host name, it must already be in
+00155  * the resolver cache in order for the function to connect to the web
+00156  * server. It is therefore up to the calling module to implement the
+00157  * resolver calls and the signal handler used for reporting a resolv
+00158  * query answer.
+00159  *
+00160  * \param host A pointer to a string containing either a host name or
+00161  * a numerical IP address in dotted decimal notation (e.g., 192.168.23.1).
+00162  *
+00163  * \param port The port number to which to connect, in host byte order.
+00164  *
+00165  * \param file A pointer to the name of the file to get.
+00166  *
+00167  * \retval 0 if the host name could not be found in the cache, or
+00168  * if a TCP connection could not be created.
+00169  *
+00170  * \retval 1 if the connection was initiated.
+00171  */
+00172 unsigned char webclient_get(char *host, u16_t port, char *file);
+00173 
+00174 /**
+00175  * Close the currently open HTTP connection.
+00176  */
+00177 void webclient_close(void);
+00178 void webclient_appcall(void);
+00179 
+00180 /**
+00181  * Obtain the MIME type of the current HTTP data stream.
+00182  *
+00183  * \return A pointer to a string contaning the MIME type. The string
+00184  * may be empty if no MIME type was reported by the web server.
+00185  */
+00186 char *webclient_mimetype(void);
+00187 
+00188 /**
+00189  * Obtain the filename of the current HTTP data stream.
+00190  *
+00191  * The filename of an HTTP request may be changed by the web server,
+00192  * and may therefore not be the same as when the original GET request
+00193  * was made with webclient_get(). This function is used for obtaining
+00194  * the current filename.
+00195  *
+00196  * \return A pointer to the current filename.
+00197  */
+00198 char *webclient_filename(void);
+00199 
+00200 /**
+00201  * Obtain the hostname of the current HTTP data stream.
+00202  *
+00203  * The hostname of the web server of an HTTP request may be changed
+00204  * by the web server, and may therefore not be the same as when the
+00205  * original GET request was made with webclient_get(). This function
+00206  * is used for obtaining the current hostname.
+00207  *
+00208  * \return A pointer to the current hostname.
+00209  */
+00210 char *webclient_hostname(void);
+00211 
+00212 /**
+00213  * Obtain the port number of the current HTTP data stream.
+00214  *
+00215  * The port number of an HTTP request may be changed by the web
+00216  * server, and may therefore not be the same as when the original GET
+00217  * request was made with webclient_get(). This function is used for
+00218  * obtaining the current port number.
+00219  *
+00220  * \return The port number of the current HTTP data stream, in host byte order.
+00221  */
+00222 unsigned short webclient_port(void);
+00223 
+00224 
+00225 
+00226 #endif /* __WEBCLIENT_H__ */
+00227 
+00228 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00042.html b/doc/html/a00042.html new file mode 100644 index 0000000..ecff751 --- /dev/null +++ b/doc/html/a00042.html @@ -0,0 +1,106 @@ + + +uIP 1.0: example-mainloop-with-arp.c + + + + + +

example-mainloop-with-arp.c

00001 #include "uip.h"
+00002 #include "uip_arp.h"
+00003 #include "network-device.h"
+00004 #include "httpd.h"
+00005 #include "timer.h"
+00006 
+00007 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+00008 
+00009 /*---------------------------------------------------------------------------*/
+00010 int
+00011 main(void)
+00012 {
+00013   int i;
+00014   uip_ipaddr_t ipaddr;
+00015   struct timer periodic_timer, arp_timer;
+00016   
+00017   timer_set(&periodic_timer, CLOCK_SECOND / 2);
+00018   timer_set(&arp_timer, CLOCK_SECOND * 10);
+00019   
+00020   network_device_init();
+00021   uip_init();
+00022 
+00023   uip_ipaddr(ipaddr, 192,168,0,2);
+00024   uip_sethostaddr(ipaddr);
+00025 
+00026   httpd_init();
+00027   
+00028   while(1) {
+00029     uip_len = network_device_read();
+00030     if(uip_len > 0) {
+00031       if(BUF->type == htons(UIP_ETHTYPE_IP)) {
+00032         uip_arp_ipin();
+00033         uip_input();
+00034         /* If the above function invocation resulted in data that
+00035            should be sent out on the network, the global variable
+00036            uip_len is set to a value > 0. */
+00037         if(uip_len > 0) {
+00038           uip_arp_out();
+00039           network_device_send();
+00040         }
+00041       } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
+00042         uip_arp_arpin();
+00043         /* If the above function invocation resulted in data that
+00044            should be sent out on the network, the global variable
+00045            uip_len is set to a value > 0. */
+00046         if(uip_len > 0) {
+00047           network_device_send();
+00048         }
+00049       }
+00050 
+00051     } else if(timer_expired(&periodic_timer)) {
+00052       timer_reset(&periodic_timer);
+00053       for(i = 0; i < UIP_CONNS; i++) {
+00054         uip_periodic(i);
+00055         /* If the above function invocation resulted in data that
+00056            should be sent out on the network, the global variable
+00057            uip_len is set to a value > 0. */
+00058         if(uip_len > 0) {
+00059           uip_arp_out();
+00060           network_device_send();
+00061         }
+00062       }
+00063 
+00064 #if UIP_UDP
+00065       for(i = 0; i < UIP_UDP_CONNS; i++) {
+00066         uip_udp_periodic(i);
+00067         /* If the above function invocation resulted in data that
+00068            should be sent out on the network, the global variable
+00069            uip_len is set to a value > 0. */
+00070         if(uip_len > 0) {
+00071           uip_arp_out();
+00072           network_device_send();
+00073         }
+00074       }
+00075 #endif /* UIP_UDP */
+00076       
+00077       /* Call the ARP timer function every 10 seconds. */
+00078       if(timer_expired(&arp_timer)) {
+00079         timer_reset(&arp_timer);
+00080         uip_arp_timer();
+00081       }
+00082     }
+00083   }
+00084   return 0;
+00085 }
+00086 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00043.html b/doc/html/a00043.html new file mode 100644 index 0000000..be8d85c --- /dev/null +++ b/doc/html/a00043.html @@ -0,0 +1,82 @@ + + +uIP 1.0: example-mainloop-without-arp.c + + + + + +

example-mainloop-without-arp.c

00001 #include "uip.h"
+00002 #include "uip_arp.h"
+00003 #include "network-device.h"
+00004 #include "httpd.h"
+00005 #include "timer.h"
+00006 
+00007 /*---------------------------------------------------------------------------*/
+00008 int
+00009 main(void)
+00010 {
+00011   int i;
+00012   uip_ipaddr_t ipaddr;
+00013   struct timer periodic_timer;
+00014   
+00015   timer_set(&periodic_timer, CLOCK_SECOND / 2);
+00016   
+00017   network_device_init();
+00018   uip_init();
+00019 
+00020   uip_ipaddr(ipaddr, 192,168,0,2);
+00021   uip_sethostaddr(ipaddr);
+00022 
+00023   httpd_init();
+00024   
+00025   while(1) {
+00026     uip_len = network_device_read();
+00027     if(uip_len > 0) {
+00028       uip_input();
+00029       /* If the above function invocation resulted in data that
+00030          should be sent out on the network, the global variable
+00031          uip_len is set to a value > 0. */
+00032       if(uip_len > 0) {
+00033         network_device_send();
+00034       }
+00035     } else if(timer_expired(&periodic_timer)) {
+00036       timer_reset(&periodic_timer);
+00037       for(i = 0; i < UIP_CONNS; i++) {
+00038         uip_periodic(i);
+00039         /* If the above function invocation resulted in data that
+00040            should be sent out on the network, the global variable
+00041            uip_len is set to a value > 0. */
+00042         if(uip_len > 0) {
+00043           network_device_send();
+00044         }
+00045       }
+00046 
+00047 #if UIP_UDP
+00048       for(i = 0; i < UIP_UDP_CONNS; i++) {
+00049         uip_udp_periodic(i);
+00050         /* If the above function invocation resulted in data that
+00051            should be sent out on the network, the global variable
+00052            uip_len is set to a value > 0. */
+00053         if(uip_len > 0) {
+00054           network_device_send();
+00055         }
+00056       }
+00057 #endif /* UIP_UDP */
+00058     }
+00059   }
+00060   return 0;
+00061 }
+00062 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00044.html b/doc/html/a00044.html new file mode 100644 index 0000000..63af613 --- /dev/null +++ b/doc/html/a00044.html @@ -0,0 +1,370 @@ + + +uIP 1.0: telnetd.c + + + + + +

telnetd.c

00001 /*
+00002  * Copyright (c) 2003, Adam Dunkels.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. The name of the author may not be used to endorse or promote
+00014  *    products derived from this software without specific prior
+00015  *    written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00018  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00019  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00021  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00023  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00026  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00027  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * $Id: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $
+00032  *
+00033  */
+00034 
+00035 #include "uip.h"
+00036 #include "telnetd.h"
+00037 #include "memb.h"
+00038 #include "shell.h"
+00039 
+00040 #include <string.h>
+00041 
+00042 #define ISO_nl       0x0a
+00043 #define ISO_cr       0x0d
+00044 
+00045 struct telnetd_line {
+00046   char line[TELNETD_CONF_LINELEN];
+00047 };
+00048 MEMB(linemem, struct telnetd_line, TELNETD_CONF_NUMLINES);
+00049 
+00050 #define STATE_NORMAL 0
+00051 #define STATE_IAC    1
+00052 #define STATE_WILL   2
+00053 #define STATE_WONT   3
+00054 #define STATE_DO     4
+00055 #define STATE_DONT   5
+00056 #define STATE_CLOSE  6
+00057 
+00058 static struct telnetd_state s;
+00059 
+00060 #define TELNET_IAC   255
+00061 #define TELNET_WILL  251
+00062 #define TELNET_WONT  252
+00063 #define TELNET_DO    253
+00064 #define TELNET_DONT  254
+00065 /*---------------------------------------------------------------------------*/
+00066 static char *
+00067 alloc_line(void)
+00068 {
+00069   return memb_alloc(&linemem);
+00070 }
+00071 /*---------------------------------------------------------------------------*/
+00072 static void
+00073 dealloc_line(char *line)
+00074 {
+00075   memb_free(&linemem, line);
+00076 }
+00077 /*---------------------------------------------------------------------------*/
+00078 void
+00079 shell_quit(char *str)
+00080 {
+00081   s.state = STATE_CLOSE;
+00082 }
+00083 /*---------------------------------------------------------------------------*/
+00084 static void
+00085 sendline(char *line)
+00086 {
+00087   static unsigned int i;
+00088   
+00089   for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+00090     if(s.lines[i] == NULL) {
+00091       s.lines[i] = line;
+00092       break;
+00093     }
+00094   }
+00095   if(i == TELNETD_CONF_NUMLINES) {
+00096     dealloc_line(line);
+00097   }
+00098 }
+00099 /*---------------------------------------------------------------------------*/
+00100 void
+00101 shell_prompt(char *str)
+00102 {
+00103   char *line;
+00104   line = alloc_line();
+00105   if(line != NULL) {
+00106     strncpy(line, str, TELNETD_CONF_LINELEN);
+00107     /*    petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
+00108     sendline(line);
+00109   }
+00110 }
+00111 /*---------------------------------------------------------------------------*/
+00112 void
+00113 shell_output(char *str1, char *str2)
+00114 {
+00115   static unsigned len;
+00116   char *line;
+00117 
+00118   line = alloc_line();
+00119   if(line != NULL) {
+00120     len = strlen(str1);
+00121     strncpy(line, str1, TELNETD_CONF_LINELEN);
+00122     if(len < TELNETD_CONF_LINELEN) {
+00123       strncpy(line + len, str2, TELNETD_CONF_LINELEN - len);
+00124     }
+00125     len = strlen(line);
+00126     if(len < TELNETD_CONF_LINELEN - 2) {
+00127       line[len] = ISO_cr;
+00128       line[len+1] = ISO_nl;
+00129       line[len+2] = 0;
+00130     }
+00131     /*    petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
+00132     sendline(line);
+00133   }
+00134 }
+00135 /*---------------------------------------------------------------------------*/
+00136 void
+00137 telnetd_init(void)
+00138 {
+00139   uip_listen(HTONS(23));
+00140   memb_init(&linemem);
+00141   shell_init();
+00142 }
+00143 /*---------------------------------------------------------------------------*/
+00144 static void
+00145 acked(void)
+00146 {
+00147   static unsigned int i;
+00148   
+00149   while(s.numsent > 0) {
+00150     dealloc_line(s.lines[0]);
+00151     for(i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
+00152       s.lines[i - 1] = s.lines[i];
+00153     }
+00154     s.lines[TELNETD_CONF_NUMLINES - 1] = NULL;
+00155     --s.numsent;
+00156   }
+00157 }
+00158 /*---------------------------------------------------------------------------*/
+00159 static void
+00160 senddata(void)
+00161 {
+00162   static char *bufptr, *lineptr;
+00163   static int buflen, linelen;
+00164   
+00165   bufptr = uip_appdata;
+00166   buflen = 0;
+00167   for(s.numsent = 0; s.numsent < TELNETD_CONF_NUMLINES &&
+00168         s.lines[s.numsent] != NULL ; ++s.numsent) {
+00169     lineptr = s.lines[s.numsent];
+00170     linelen = strlen(lineptr);
+00171     if(linelen > TELNETD_CONF_LINELEN) {
+00172       linelen = TELNETD_CONF_LINELEN;
+00173     }
+00174     if(buflen + linelen < uip_mss()) {
+00175       memcpy(bufptr, lineptr, linelen);
+00176       bufptr += linelen;
+00177       buflen += linelen;
+00178     } else {
+00179       break;
+00180     }
+00181   }
+00182   uip_send(uip_appdata, buflen);
+00183 }
+00184 /*---------------------------------------------------------------------------*/
+00185 static void
+00186 closed(void)
+00187 {
+00188   static unsigned int i;
+00189   
+00190   for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+00191     if(s.lines[i] != NULL) {
+00192       dealloc_line(s.lines[i]);
+00193     }
+00194   }
+00195 }
+00196 /*---------------------------------------------------------------------------*/
+00197 static void
+00198 get_char(u8_t c)
+00199 {
+00200   if(c == ISO_cr) {
+00201     return;
+00202   }
+00203   
+00204   s.buf[(int)s.bufptr] = c;
+00205   if(s.buf[(int)s.bufptr] == ISO_nl ||
+00206      s.bufptr == sizeof(s.buf) - 1) {
+00207     if(s.bufptr > 0) {
+00208       s.buf[(int)s.bufptr] = 0;
+00209       /*      petsciiconv_topetscii(s.buf, TELNETD_CONF_LINELEN);*/
+00210     }
+00211     shell_input(s.buf);
+00212     s.bufptr = 0;
+00213   } else {
+00214     ++s.bufptr;
+00215   }
+00216 }
+00217 /*---------------------------------------------------------------------------*/
+00218 static void
+00219 sendopt(u8_t option, u8_t value)
+00220 {
+00221   char *line;
+00222   line = alloc_line();
+00223   if(line != NULL) {
+00224     line[0] = TELNET_IAC;
+00225     line[1] = option;
+00226     line[2] = value;
+00227     line[3] = 0;
+00228     sendline(line);
+00229   }
+00230 }
+00231 /*---------------------------------------------------------------------------*/
+00232 static void
+00233 newdata(void)
+00234 {
+00235   u16_t len;
+00236   u8_t c;
+00237   char *dataptr;
+00238     
+00239   
+00240   len = uip_datalen();
+00241   dataptr = (char *)uip_appdata;
+00242   
+00243   while(len > 0 && s.bufptr < sizeof(s.buf)) {
+00244     c = *dataptr;
+00245     ++dataptr;
+00246     --len;
+00247     switch(s.state) {
+00248     case STATE_IAC:
+00249       if(c == TELNET_IAC) {
+00250         get_char(c);
+00251         s.state = STATE_NORMAL;
+00252       } else {
+00253         switch(c) {
+00254         case TELNET_WILL:
+00255           s.state = STATE_WILL;
+00256           break;
+00257         case TELNET_WONT:
+00258           s.state = STATE_WONT;
+00259           break;
+00260         case TELNET_DO:
+00261           s.state = STATE_DO;
+00262           break;
+00263         case TELNET_DONT:
+00264           s.state = STATE_DONT;
+00265           break;
+00266         default:
+00267           s.state = STATE_NORMAL;
+00268           break;
+00269         }
+00270       }
+00271       break;
+00272     case STATE_WILL:
+00273       /* Reply with a DONT */
+00274       sendopt(TELNET_DONT, c);
+00275       s.state = STATE_NORMAL;
+00276       break;
+00277       
+00278     case STATE_WONT:
+00279       /* Reply with a DONT */
+00280       sendopt(TELNET_DONT, c);
+00281       s.state = STATE_NORMAL;
+00282       break;
+00283     case STATE_DO:
+00284       /* Reply with a WONT */
+00285       sendopt(TELNET_WONT, c);
+00286       s.state = STATE_NORMAL;
+00287       break;
+00288     case STATE_DONT:
+00289       /* Reply with a WONT */
+00290       sendopt(TELNET_WONT, c);
+00291       s.state = STATE_NORMAL;
+00292       break;
+00293     case STATE_NORMAL:
+00294       if(c == TELNET_IAC) {
+00295         s.state = STATE_IAC;
+00296       } else {
+00297         get_char(c);
+00298       }
+00299       break;
+00300     }
+00301 
+00302     
+00303   }
+00304   
+00305 }
+00306 /*---------------------------------------------------------------------------*/
+00307 void
+00308 telnetd_appcall(void)
+00309 {
+00310   static unsigned int i;
+00311   if(uip_connected()) {
+00312     /*    tcp_markconn(uip_conn, &s);*/
+00313     for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+00314       s.lines[i] = NULL;
+00315     }
+00316     s.bufptr = 0;
+00317     s.state = STATE_NORMAL;
+00318 
+00319     shell_start();
+00320   }
+00321 
+00322   if(s.state == STATE_CLOSE) {
+00323     s.state = STATE_NORMAL;
+00324     uip_close();
+00325     return;
+00326   }
+00327   
+00328   if(uip_closed() ||
+00329      uip_aborted() ||
+00330      uip_timedout()) {
+00331     closed();
+00332   }
+00333   
+00334   if(uip_acked()) {
+00335     acked();
+00336   }
+00337   
+00338   if(uip_newdata()) {
+00339     newdata();
+00340   }
+00341   
+00342   if(uip_rexmit() ||
+00343      uip_newdata() ||
+00344      uip_acked() ||
+00345      uip_connected() ||
+00346      uip_poll()) {
+00347     senddata();
+00348   }
+00349 }
+00350 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00045.html b/doc/html/a00045.html new file mode 100644 index 0000000..7ed6df9 --- /dev/null +++ b/doc/html/a00045.html @@ -0,0 +1,83 @@ + + +uIP 1.0: telnetd.h + + + + + +

telnetd.h

00001 /*
+00002  * Copyright (c) 2003, Adam Dunkels.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above
+00011  *    copyright notice, this list of conditions and the following
+00012  *    disclaimer in the documentation and/or other materials provided
+00013  *    with the distribution.
+00014  * 3. The name of the author may not be used to endorse or promote
+00015  *    products derived from this software without specific prior
+00016  *    written permission.
+00017  *
+00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00019  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00022  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00024  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00029  *
+00030  * This file is part of the uIP TCP/IP stack
+00031  *
+00032  * $Id: telnetd.h,v 1.2 2006/06/07 09:43:54 adam Exp $
+00033  *
+00034  */
+00035 #ifndef __TELNETD_H__
+00036 #define __TELNETD_H__
+00037 
+00038 #include "uipopt.h"
+00039 
+00040 void telnetd_appcall(void);
+00041 
+00042 #ifndef TELNETD_CONF_LINELEN
+00043 #define TELNETD_CONF_LINELEN 40
+00044 #endif
+00045 #ifndef TELNETD_CONF_NUMLINES
+00046 #define TELNETD_CONF_NUMLINES 16
+00047 #endif
+00048 
+00049 struct telnetd_state {
+00050   char *lines[TELNETD_CONF_NUMLINES];
+00051   char buf[TELNETD_CONF_LINELEN];
+00052   char bufptr;
+00053   u8_t numsent;
+00054   u8_t state;
+00055 };
+00056 
+00057 typedef struct telnetd_state uip_tcp_appstate_t;
+00058 
+00059 #ifndef UIP_APPCALL
+00060 #define UIP_APPCALL     telnetd_appcall
+00061 #endif
+00062 
+00063 #endif /* __TELNETD_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00046.html b/doc/html/a00046.html index 21a22e3..9e877ea 100644 --- a/doc/html/a00046.html +++ b/doc/html/a00046.html @@ -1,37 +1,484 @@ - + -uIP 0.9: uip_udp_conn struct Reference +uIP 1.0: resolv.c + - - -

uip_udp_conn Struct Reference
- -[The uIP TCP/IP stack] -

#include <uip.h> -

-


Detailed Description

-Representation of a uIP UDP connection. -

- - - - - - - - - - - - -

Data Fields

-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.

-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by + + +

resolv.c

00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup resolv DNS resolver
+00008  * @{
+00009  *
+00010  * The uIP DNS resolver functions are used to lookup a hostname and
+00011  * map it to a numerical IP address. It maintains a list of resolved
+00012  * hostnames that can be queried with the resolv_lookup()
+00013  * function. New hostnames can be resolved using the resolv_query()
+00014  * function.
+00015  *
+00016  * When a hostname has been resolved (or found to be non-existant),
+00017  * the resolver code calls a callback function called resolv_found()
+00018  * that must be implemented by the module that uses the resolver.
+00019  */
+00020 
+00021 /**
+00022  * \file
+00023  * DNS host name to IP address resolver.
+00024  * \author Adam Dunkels <adam@dunkels.com>
+00025  *
+00026  * This file implements a DNS host name to IP address resolver.
+00027  */
+00028 
+00029 /*
+00030  * Copyright (c) 2002-2003, Adam Dunkels.
+00031  * All rights reserved.
+00032  *
+00033  * Redistribution and use in source and binary forms, with or without
+00034  * modification, are permitted provided that the following conditions
+00035  * are met:
+00036  * 1. Redistributions of source code must retain the above copyright
+00037  *    notice, this list of conditions and the following disclaimer.
+00038  * 2. Redistributions in binary form must reproduce the above copyright
+00039  *    notice, this list of conditions and the following disclaimer in the
+00040  *    documentation and/or other materials provided with the distribution.
+00041  * 3. The name of the author may not be used to endorse or promote
+00042  *    products derived from this software without specific prior
+00043  *    written permission.
+00044  *
+00045  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00046  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00047  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00048  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00049  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00050  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00051  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00052  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00053  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00054  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00055  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00056  *
+00057  * This file is part of the uIP TCP/IP stack.
+00058  *
+00059  * $Id: resolv.c,v 1.5 2006/06/11 21:46:37 adam Exp $
+00060  *
+00061  */
+00062 
+00063 #include "resolv.h"
+00064 #include "uip.h"
+00065 
+00066 #include <string.h>
+00067 
+00068 #ifndef NULL
+00069 #define NULL (void *)0
+00070 #endif /* NULL */
+00071 
+00072 /** \internal The maximum number of retries when asking for a name. */
+00073 #define MAX_RETRIES 8
+00074 
+00075 /** \internal The DNS message header. */
+00076 struct dns_hdr {
+00077   u16_t id;
+00078   u8_t flags1, flags2;
+00079 #define DNS_FLAG1_RESPONSE        0x80
+00080 #define DNS_FLAG1_OPCODE_STATUS   0x10
+00081 #define DNS_FLAG1_OPCODE_INVERSE  0x08
+00082 #define DNS_FLAG1_OPCODE_STANDARD 0x00
+00083 #define DNS_FLAG1_AUTHORATIVE     0x04
+00084 #define DNS_FLAG1_TRUNC           0x02
+00085 #define DNS_FLAG1_RD              0x01
+00086 #define DNS_FLAG2_RA              0x80
+00087 #define DNS_FLAG2_ERR_MASK        0x0f
+00088 #define DNS_FLAG2_ERR_NONE        0x00
+00089 #define DNS_FLAG2_ERR_NAME        0x03
+00090   u16_t numquestions;
+00091   u16_t numanswers;
+00092   u16_t numauthrr;
+00093   u16_t numextrarr;
+00094 };
+00095 
+00096 /** \internal The DNS answer message structure. */
+00097 struct dns_answer {
+00098   /* DNS answer record starts with either a domain name or a pointer
+00099      to a name already present somewhere in the packet. */
+00100   u16_t type;
+00101   u16_t class;
+00102   u16_t ttl[2];
+00103   u16_t len;
+00104   uip_ipaddr_t ipaddr;
+00105 };
+00106 
+00107 struct namemap {
+00108 #define STATE_UNUSED 0
+00109 #define STATE_NEW    1
+00110 #define STATE_ASKING 2
+00111 #define STATE_DONE   3
+00112 #define STATE_ERROR  4
+00113   u8_t state;
+00114   u8_t tmr;
+00115   u8_t retries;
+00116   u8_t seqno;
+00117   u8_t err;
+00118   char name[32];
+00119   uip_ipaddr_t ipaddr;
+00120 };
+00121 
+00122 #ifndef UIP_CONF_RESOLV_ENTRIES
+00123 #define RESOLV_ENTRIES 4
+00124 #else /* UIP_CONF_RESOLV_ENTRIES */
+00125 #define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
+00126 #endif /* UIP_CONF_RESOLV_ENTRIES */
+00127 
+00128 
+00129 static struct namemap names[RESOLV_ENTRIES];
+00130 
+00131 static u8_t seqno;
+00132 
+00133 static struct uip_udp_conn *resolv_conn = NULL;
+00134 
+00135 
+00136 /*---------------------------------------------------------------------------*/
+00137 /** \internal
+00138  * Walk through a compact encoded DNS name and return the end of it.
+00139  *
+00140  * \return The end of the name.
+00141  */
+00142 /*---------------------------------------------------------------------------*/
+00143 static unsigned char *
+00144 parse_name(unsigned char *query)
+00145 {
+00146   unsigned char n;
+00147 
+00148   do {
+00149     n = *query++;
+00150     
+00151     while(n > 0) {
+00152       /*      printf("%c", *query);*/
+00153       ++query;
+00154       --n;
+00155     };
+00156     /*    printf(".");*/
+00157   } while(*query != 0);
+00158   /*  printf("\n");*/
+00159   return query + 1;
+00160 }
+00161 /*---------------------------------------------------------------------------*/
+00162 /** \internal
+00163  * Runs through the list of names to see if there are any that have
+00164  * not yet been queried and, if so, sends out a query.
+00165  */
+00166 /*---------------------------------------------------------------------------*/
+00167 static void
+00168 check_entries(void)
+00169 {
+00170   register struct dns_hdr *hdr;
+00171   char *query, *nptr, *nameptr;
+00172   static u8_t i;
+00173   static u8_t n;
+00174   register struct namemap *namemapptr;
+00175   
+00176   for(i = 0; i < RESOLV_ENTRIES; ++i) {
+00177     namemapptr = &names[i];
+00178     if(namemapptr->state == STATE_NEW ||
+00179        namemapptr->state == STATE_ASKING) {
+00180       if(namemapptr->state == STATE_ASKING) {
+00181         if(--namemapptr->tmr == 0) {
+00182           if(++namemapptr->retries == MAX_RETRIES) {
+00183             namemapptr->state = STATE_ERROR;
+00184             resolv_found(namemapptr->name, NULL);
+00185             continue;
+00186           }
+00187           namemapptr->tmr = namemapptr->retries;
+00188         } else {
+00189           /*      printf("Timer %d\n", namemapptr->tmr);*/
+00190           /* Its timer has not run out, so we move on to next
+00191              entry. */
+00192           continue;
+00193         }
+00194       } else {
+00195         namemapptr->state = STATE_ASKING;
+00196         namemapptr->tmr = 1;
+00197         namemapptr->retries = 0;
+00198       }
+00199       hdr = (struct dns_hdr *)uip_appdata;
+00200       memset(hdr, 0, sizeof(struct dns_hdr));
+00201       hdr->id = htons(i);
+00202       hdr->flags1 = DNS_FLAG1_RD;
+00203       hdr->numquestions = HTONS(1);
+00204       query = (char *)uip_appdata + 12;
+00205       nameptr = namemapptr->name;
+00206       --nameptr;
+00207       /* Convert hostname into suitable query format. */
+00208       do {
+00209         ++nameptr;
+00210         nptr = query;
+00211         ++query;
+00212         for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
+00213           *query = *nameptr;
+00214           ++query;
+00215           ++n;
+00216         }
+00217         *nptr = n;
+00218       } while(*nameptr != 0);
+00219       {
+00220         static unsigned char endquery[] =
+00221           {0,0,1,0,1};
+00222         memcpy(query, endquery, 5);
+00223       }
+00224       uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
+00225       break;
+00226     }
+00227   }
+00228 }
+00229 /*---------------------------------------------------------------------------*/
+00230 /** \internal
+00231  * Called when new UDP data arrives.
+00232  */
+00233 /*---------------------------------------------------------------------------*/
+00234 static void
+00235 newdata(void)
+00236 {
+00237   char *nameptr;
+00238   struct dns_answer *ans;
+00239   struct dns_hdr *hdr;
+00240   static u8_t nquestions, nanswers;
+00241   static u8_t i;
+00242   register struct namemap *namemapptr;
+00243   
+00244   hdr = (struct dns_hdr *)uip_appdata;
+00245   /*  printf("ID %d\n", htons(hdr->id));
+00246       printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
+00247       printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
+00248       printf("Num questions %d, answers %d, authrr %d, extrarr %d\n",
+00249       htons(hdr->numquestions),
+00250       htons(hdr->numanswers),
+00251       htons(hdr->numauthrr),
+00252       htons(hdr->numextrarr));
+00253   */
+00254 
+00255   /* The ID in the DNS header should be our entry into the name
+00256      table. */
+00257   i = htons(hdr->id);
+00258   namemapptr = &names[i];
+00259   if(i < RESOLV_ENTRIES &&
+00260      namemapptr->state == STATE_ASKING) {
+00261 
+00262     /* This entry is now finished. */
+00263     namemapptr->state = STATE_DONE;
+00264     namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
+00265 
+00266     /* Check for error. If so, call callback to inform. */
+00267     if(namemapptr->err != 0) {
+00268       namemapptr->state = STATE_ERROR;
+00269       resolv_found(namemapptr->name, NULL);
+00270       return;
+00271     }
+00272 
+00273     /* We only care about the question(s) and the answers. The authrr
+00274        and the extrarr are simply discarded. */
+00275     nquestions = htons(hdr->numquestions);
+00276     nanswers = htons(hdr->numanswers);
+00277 
+00278     /* Skip the name in the question. XXX: This should really be
+00279        checked agains the name in the question, to be sure that they
+00280        match. */
+00281     nameptr = parse_name((char *)uip_appdata + 12) + 4;
+00282 
+00283     while(nanswers > 0) {
+00284       /* The first byte in the answer resource record determines if it
+00285          is a compressed record or a normal one. */
+00286       if(*nameptr & 0xc0) {
+00287         /* Compressed name. */
+00288         nameptr +=2;
+00289         /*      printf("Compressed anwser\n");*/
+00290       } else {
+00291         /* Not compressed name. */
+00292         nameptr = parse_name((char *)nameptr);
+00293       }
+00294 
+00295       ans = (struct dns_answer *)nameptr;
+00296       /*      printf("Answer: type %x, class %x, ttl %x, length %x\n",
+00297              htons(ans->type), htons(ans->class), (htons(ans->ttl[0])
+00298              << 16) | htons(ans->ttl[1]), htons(ans->len));*/
+00299 
+00300       /* Check for IP address type and Internet class. Others are
+00301          discarded. */
+00302       if(ans->type == HTONS(1) &&
+00303          ans->class == HTONS(1) &&
+00304          ans->len == HTONS(4)) {
+00305         /*      printf("IP address %d.%d.%d.%d\n",
+00306                htons(ans->ipaddr[0]) >> 8,
+00307                htons(ans->ipaddr[0]) & 0xff,
+00308                htons(ans->ipaddr[1]) >> 8,
+00309                htons(ans->ipaddr[1]) & 0xff);*/
+00310         /* XXX: we should really check that this IP address is the one
+00311            we want. */
+00312         namemapptr->ipaddr[0] = ans->ipaddr[0];
+00313         namemapptr->ipaddr[1] = ans->ipaddr[1];
+00314         
+00315         resolv_found(namemapptr->name, namemapptr->ipaddr);
+00316         return;
+00317       } else {
+00318         nameptr = nameptr + 10 + htons(ans->len);
+00319       }
+00320       --nanswers;
+00321     }
+00322   }
+00323 
+00324 }
+00325 /*---------------------------------------------------------------------------*/
+00326 /** \internal
+00327  * The main UDP function.
+00328  */
+00329 /*---------------------------------------------------------------------------*/
+00330 void
+00331 resolv_appcall(void)
+00332 {
+00333   if(uip_udp_conn->rport == HTONS(53)) {
+00334     if(uip_poll()) {
+00335       check_entries();
+00336     }
+00337     if(uip_newdata()) {
+00338       newdata();
+00339     }
+00340   }
+00341 }
+00342 /*---------------------------------------------------------------------------*/
+00343 /**
+00344  * Queues a name so that a question for the name will be sent out.
+00345  *
+00346  * \param name The hostname that is to be queried.
+00347  */
+00348 /*---------------------------------------------------------------------------*/
+00349 void
+00350 resolv_query(char *name)
+00351 {
+00352   static u8_t i;
+00353   static u8_t lseq, lseqi;
+00354   register struct namemap *nameptr;
+00355       
+00356   lseq = lseqi = 0;
+00357   
+00358   for(i = 0; i < RESOLV_ENTRIES; ++i) {
+00359     nameptr = &names[i];
+00360     if(nameptr->state == STATE_UNUSED) {
+00361       break;
+00362     }
+00363     if(seqno - nameptr->seqno > lseq) {
+00364       lseq = seqno - nameptr->seqno;
+00365       lseqi = i;
+00366     }
+00367   }
+00368 
+00369   if(i == RESOLV_ENTRIES) {
+00370     i = lseqi;
+00371     nameptr = &names[i];
+00372   }
+00373 
+00374   /*  printf("Using entry %d\n", i);*/
+00375 
+00376   strcpy(nameptr->name, name);
+00377   nameptr->state = STATE_NEW;
+00378   nameptr->seqno = seqno;
+00379   ++seqno;
+00380 }
+00381 /*---------------------------------------------------------------------------*/
+00382 /**
+00383  * Look up a hostname in the array of known hostnames.
+00384  *
+00385  * \note This function only looks in the internal array of known
+00386  * hostnames, it does not send out a query for the hostname if none
+00387  * was found. The function resolv_query() can be used to send a query
+00388  * for a hostname.
+00389  *
+00390  * \return A pointer to a 4-byte representation of the hostname's IP
+00391  * address, or NULL if the hostname was not found in the array of
+00392  * hostnames.
+00393  */
+00394 /*---------------------------------------------------------------------------*/
+00395 u16_t *
+00396 resolv_lookup(char *name)
+00397 {
+00398   static u8_t i;
+00399   struct namemap *nameptr;
+00400   
+00401   /* Walk through the list to see if the name is in there. If it is
+00402      not, we return NULL. */
+00403   for(i = 0; i < RESOLV_ENTRIES; ++i) {
+00404     nameptr = &names[i];
+00405     if(nameptr->state == STATE_DONE &&
+00406        strcmp(name, nameptr->name) == 0) {
+00407       return nameptr->ipaddr;
+00408     }
+00409   }
+00410   return NULL;
+00411 }
+00412 /*---------------------------------------------------------------------------*/
+00413 /**
+00414  * Obtain the currently configured DNS server.
+00415  *
+00416  * \return A pointer to a 4-byte representation of the IP address of
+00417  * the currently configured DNS server or NULL if no DNS server has
+00418  * been configured.
+00419  */
+00420 /*---------------------------------------------------------------------------*/
+00421 u16_t *
+00422 resolv_getserver(void)
+00423 {
+00424   if(resolv_conn == NULL) {
+00425     return NULL;
+00426   }
+00427   return resolv_conn->ripaddr;
+00428 }
+00429 /*---------------------------------------------------------------------------*/
+00430 /**
+00431  * Configure which DNS server to use for queries.
+00432  *
+00433  * \param dnsserver A pointer to a 4-byte representation of the IP
+00434  * address of the DNS server to be configured.
+00435  */
+00436 /*---------------------------------------------------------------------------*/
+00437 void
+00438 resolv_conf(u16_t *dnsserver)
+00439 {
+00440   if(resolv_conn != NULL) {
+00441     uip_udp_remove(resolv_conn);
+00442   }
+00443   
+00444   resolv_conn = uip_udp_new(dnsserver, HTONS(53));
+00445 }
+00446 /*---------------------------------------------------------------------------*/
+00447 /**
+00448  * Initalize the resolver.
+00449  */
+00450 /*---------------------------------------------------------------------------*/
+00451 void
+00452 resolv_init(void)
+00453 {
+00454   static u8_t i;
+00455   
+00456   for(i = 0; i < RESOLV_ENTRIES; ++i) {
+00457     names[i].state = STATE_DONE;
+00458   }
+00459 
+00460 }
+00461 /*---------------------------------------------------------------------------*/
+00462 
+00463 /** @} */
+00464 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00047.html b/doc/html/a00047.html new file mode 100644 index 0000000..76d0ccc --- /dev/null +++ b/doc/html/a00047.html @@ -0,0 +1,95 @@ + + +uIP 1.0: resolv.h + + + + + +

resolv.h

00001 /**
+00002  * \addtogroup resolv
+00003  * @{
+00004  */
+00005 /**
+00006  * \file
+00007  * DNS resolver code header file.
+00008  * \author Adam Dunkels <adam@dunkels.com>
+00009  */
+00010 
+00011 /*
+00012  * Copyright (c) 2002-2003, Adam Dunkels.
+00013  * All rights reserved.
+00014  *
+00015  * Redistribution and use in source and binary forms, with or without
+00016  * modification, are permitted provided that the following conditions
+00017  * are met:
+00018  * 1. Redistributions of source code must retain the above copyright
+00019  *    notice, this list of conditions and the following disclaimer.
+00020  * 2. Redistributions in binary form must reproduce the above copyright
+00021  *    notice, this list of conditions and the following disclaimer in the
+00022  *    documentation and/or other materials provided with the distribution.
+00023  * 3. The name of the author may not be used to endorse or promote
+00024  *    products derived from this software without specific prior
+00025  *    written permission.
+00026  *
+00027  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00028  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00029  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00031  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00033  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00035  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00036  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00037  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00038  *
+00039  * This file is part of the uIP TCP/IP stack.
+00040  *
+00041  * $Id: resolv.h,v 1.4 2006/06/11 21:46:37 adam Exp $
+00042  *
+00043  */
+00044 #ifndef __RESOLV_H__
+00045 #define __RESOLV_H__
+00046 
+00047 typedef int uip_udp_appstate_t;
+00048 void resolv_appcall(void);
+00049 #define UIP_UDP_APPCALL resolv_appcall
+00050 
+00051 #include "uipopt.h"
+00052 
+00053 /**
+00054  * Callback function which is called when a hostname is found.
+00055  *
+00056  * This function must be implemented by the module that uses the DNS
+00057  * resolver. It is called when a hostname is found, or when a hostname
+00058  * was not found.
+00059  *
+00060  * \param name A pointer to the name that was looked up.  \param
+00061  * ipaddr A pointer to a 4-byte array containing the IP address of the
+00062  * hostname, or NULL if the hostname could not be found.
+00063  */
+00064 void resolv_found(char *name, u16_t *ipaddr);
+00065 
+00066 /* Functions. */
+00067 void resolv_conf(u16_t *dnsserver);
+00068 u16_t *resolv_getserver(void);
+00069 void resolv_init(void);
+00070 u16_t *resolv_lookup(char *name);
+00071 void resolv_query(char *name);
+00072 
+00073 #endif /* __RESOLV_H__ */
+00074 
+00075 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00048.html b/doc/html/a00048.html new file mode 100644 index 0000000..d19bf13 --- /dev/null +++ b/doc/html/a00048.html @@ -0,0 +1,376 @@ + + +uIP 1.0: dhcpc.c + + + + + +

dhcpc.c

00001 /*
+00002  * Copyright (c) 2005, Swedish Institute of Computer Science
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $
+00032  */
+00033 
+00034 #include <stdio.h>
+00035 #include <string.h>
+00036 
+00037 #include "uip.h"
+00038 #include "dhcpc.h"
+00039 #include "timer.h"
+00040 #include "pt.h"
+00041 
+00042 #define STATE_INITIAL         0
+00043 #define STATE_SENDING         1
+00044 #define STATE_OFFER_RECEIVED  2
+00045 #define STATE_CONFIG_RECEIVED 3
+00046 
+00047 static struct dhcpc_state s;
+00048 
+00049 struct dhcp_msg {
+00050   u8_t op, htype, hlen, hops;
+00051   u8_t xid[4];
+00052   u16_t secs, flags;
+00053   u8_t ciaddr[4];
+00054   u8_t yiaddr[4];
+00055   u8_t siaddr[4];
+00056   u8_t giaddr[4];
+00057   u8_t chaddr[16];
+00058 #ifndef UIP_CONF_DHCP_LIGHT
+00059   u8_t sname[64];
+00060   u8_t file[128];
+00061 #endif
+00062   u8_t options[312];
+00063 };
+00064 
+00065 #define BOOTP_BROADCAST 0x8000
+00066 
+00067 #define DHCP_REQUEST        1
+00068 #define DHCP_REPLY          2
+00069 #define DHCP_HTYPE_ETHERNET 1
+00070 #define DHCP_HLEN_ETHERNET  6
+00071 #define DHCP_MSG_LEN      236
+00072 
+00073 #define DHCPC_SERVER_PORT  67
+00074 #define DHCPC_CLIENT_PORT  68
+00075 
+00076 #define DHCPDISCOVER  1
+00077 #define DHCPOFFER     2
+00078 #define DHCPREQUEST   3
+00079 #define DHCPDECLINE   4
+00080 #define DHCPACK       5
+00081 #define DHCPNAK       6
+00082 #define DHCPRELEASE   7
+00083 
+00084 #define DHCP_OPTION_SUBNET_MASK   1
+00085 #define DHCP_OPTION_ROUTER        3
+00086 #define DHCP_OPTION_DNS_SERVER    6
+00087 #define DHCP_OPTION_REQ_IPADDR   50
+00088 #define DHCP_OPTION_LEASE_TIME   51
+00089 #define DHCP_OPTION_MSG_TYPE     53
+00090 #define DHCP_OPTION_SERVER_ID    54
+00091 #define DHCP_OPTION_REQ_LIST     55
+00092 #define DHCP_OPTION_END         255
+00093 
+00094 static const u8_t xid[4] = {0xad, 0xde, 0x12, 0x23};
+00095 static const u8_t magic_cookie[4] = {99, 130, 83, 99};
+00096 /*---------------------------------------------------------------------------*/
+00097 static u8_t *
+00098 add_msg_type(u8_t *optptr, u8_t type)
+00099 {
+00100   *optptr++ = DHCP_OPTION_MSG_TYPE;
+00101   *optptr++ = 1;
+00102   *optptr++ = type;
+00103   return optptr;
+00104 }
+00105 /*---------------------------------------------------------------------------*/
+00106 static u8_t *
+00107 add_server_id(u8_t *optptr)
+00108 {
+00109   *optptr++ = DHCP_OPTION_SERVER_ID;
+00110   *optptr++ = 4;
+00111   memcpy(optptr, s.serverid, 4);
+00112   return optptr + 4;
+00113 }
+00114 /*---------------------------------------------------------------------------*/
+00115 static u8_t *
+00116 add_req_ipaddr(u8_t *optptr)
+00117 {
+00118   *optptr++ = DHCP_OPTION_REQ_IPADDR;
+00119   *optptr++ = 4;
+00120   memcpy(optptr, s.ipaddr, 4);
+00121   return optptr + 4;
+00122 }
+00123 /*---------------------------------------------------------------------------*/
+00124 static u8_t *
+00125 add_req_options(u8_t *optptr)
+00126 {
+00127   *optptr++ = DHCP_OPTION_REQ_LIST;
+00128   *optptr++ = 3;
+00129   *optptr++ = DHCP_OPTION_SUBNET_MASK;
+00130   *optptr++ = DHCP_OPTION_ROUTER;
+00131   *optptr++ = DHCP_OPTION_DNS_SERVER;
+00132   return optptr;
+00133 }
+00134 /*---------------------------------------------------------------------------*/
+00135 static u8_t *
+00136 add_end(u8_t *optptr)
+00137 {
+00138   *optptr++ = DHCP_OPTION_END;
+00139   return optptr;
+00140 }
+00141 /*---------------------------------------------------------------------------*/
+00142 static void
+00143 create_msg(register struct dhcp_msg *m)
+00144 {
+00145   m->op = DHCP_REQUEST;
+00146   m->htype = DHCP_HTYPE_ETHERNET;
+00147   m->hlen = s.mac_len;
+00148   m->hops = 0;
+00149   memcpy(m->xid, xid, sizeof(m->xid));
+00150   m->secs = 0;
+00151   m->flags = HTONS(BOOTP_BROADCAST); /*  Broadcast bit. */
+00152   /*  uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/
+00153   memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr));
+00154   memset(m->yiaddr, 0, sizeof(m->yiaddr));
+00155   memset(m->siaddr, 0, sizeof(m->siaddr));
+00156   memset(m->giaddr, 0, sizeof(m->giaddr));
+00157   memcpy(m->chaddr, s.mac_addr, s.mac_len);
+00158   memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len);
+00159 #ifndef UIP_CONF_DHCP_LIGHT
+00160   memset(m->sname, 0, sizeof(m->sname));
+00161   memset(m->file, 0, sizeof(m->file));
+00162 #endif
+00163 
+00164   memcpy(m->options, magic_cookie, sizeof(magic_cookie));
+00165 }
+00166 /*---------------------------------------------------------------------------*/
+00167 static void
+00168 send_discover(void)
+00169 {
+00170   u8_t *end;
+00171   struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+00172 
+00173   create_msg(m);
+00174 
+00175   end = add_msg_type(&m->options[4], DHCPDISCOVER);
+00176   end = add_req_options(end);
+00177   end = add_end(end);
+00178 
+00179   uip_send(uip_appdata, end - (u8_t *)uip_appdata);
+00180 }
+00181 /*---------------------------------------------------------------------------*/
+00182 static void
+00183 send_request(void)
+00184 {
+00185   u8_t *end;
+00186   struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+00187 
+00188   create_msg(m);
+00189   
+00190   end = add_msg_type(&m->options[4], DHCPREQUEST);
+00191   end = add_server_id(end);
+00192   end = add_req_ipaddr(end);
+00193   end = add_end(end);
+00194   
+00195   uip_send(uip_appdata, end - (u8_t *)uip_appdata);
+00196 }
+00197 /*---------------------------------------------------------------------------*/
+00198 static u8_t
+00199 parse_options(u8_t *optptr, int len)
+00200 {
+00201   u8_t *end = optptr + len;
+00202   u8_t type = 0;
+00203 
+00204   while(optptr < end) {
+00205     switch(*optptr) {
+00206     case DHCP_OPTION_SUBNET_MASK:
+00207       memcpy(s.netmask, optptr + 2, 4);
+00208       break;
+00209     case DHCP_OPTION_ROUTER:
+00210       memcpy(s.default_router, optptr + 2, 4);
+00211       break;
+00212     case DHCP_OPTION_DNS_SERVER:
+00213       memcpy(s.dnsaddr, optptr + 2, 4);
+00214       break;
+00215     case DHCP_OPTION_MSG_TYPE:
+00216       type = *(optptr + 2);
+00217       break;
+00218     case DHCP_OPTION_SERVER_ID:
+00219       memcpy(s.serverid, optptr + 2, 4);
+00220       break;
+00221     case DHCP_OPTION_LEASE_TIME:
+00222       memcpy(s.lease_time, optptr + 2, 4);
+00223       break;
+00224     case DHCP_OPTION_END:
+00225       return type;
+00226     }
+00227 
+00228     optptr += optptr[1] + 2;
+00229   }
+00230   return type;
+00231 }
+00232 /*---------------------------------------------------------------------------*/
+00233 static u8_t
+00234 parse_msg(void)
+00235 {
+00236   struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+00237   
+00238   if(m->op == DHCP_REPLY &&
+00239      memcmp(m->xid, xid, sizeof(xid)) == 0 &&
+00240      memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
+00241     memcpy(s.ipaddr, m->yiaddr, 4);
+00242     return parse_options(&m->options[4], uip_datalen());
+00243   }
+00244   return 0;
+00245 }
+00246 /*---------------------------------------------------------------------------*/
+00247 static
+00248 PT_THREAD(handle_dhcp(void))
+00249 {
+00250   PT_BEGIN(&s.pt);
+00251   
+00252   /* try_again:*/
+00253   s.state = STATE_SENDING;
+00254   s.ticks = CLOCK_SECOND;
+00255 
+00256   do {
+00257     send_discover();
+00258     timer_set(&s.timer, s.ticks);
+00259     PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+00260 
+00261     if(uip_newdata() && parse_msg() == DHCPOFFER) {
+00262       s.state = STATE_OFFER_RECEIVED;
+00263       break;
+00264     }
+00265 
+00266     if(s.ticks < CLOCK_SECOND * 60) {
+00267       s.ticks *= 2;
+00268     }
+00269   } while(s.state != STATE_OFFER_RECEIVED);
+00270   
+00271   s.ticks = CLOCK_SECOND;
+00272 
+00273   do {
+00274     send_request();
+00275     timer_set(&s.timer, s.ticks);
+00276     PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+00277 
+00278     if(uip_newdata() && parse_msg() == DHCPACK) {
+00279       s.state = STATE_CONFIG_RECEIVED;
+00280       break;
+00281     }
+00282 
+00283     if(s.ticks <= CLOCK_SECOND * 10) {
+00284       s.ticks += CLOCK_SECOND;
+00285     } else {
+00286       PT_RESTART(&s.pt);
+00287     }
+00288   } while(s.state != STATE_CONFIG_RECEIVED);
+00289   
+00290 #if 0
+00291   printf("Got IP address %d.%d.%d.%d\n",
+00292          uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr),
+00293          uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr));
+00294   printf("Got netmask %d.%d.%d.%d\n",
+00295          uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask),
+00296          uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask));
+00297   printf("Got DNS server %d.%d.%d.%d\n",
+00298          uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr),
+00299          uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr));
+00300   printf("Got default router %d.%d.%d.%d\n",
+00301          uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router),
+00302          uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router));
+00303   printf("Lease expires in %ld seconds\n",
+00304          ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1]));
+00305 #endif
+00306 
+00307   dhcpc_configured(&s);
+00308   
+00309   /*  timer_stop(&s.timer);*/
+00310 
+00311   /*
+00312    * PT_END restarts the thread so we do this instead. Eventually we
+00313    * should reacquire expired leases here.
+00314    */
+00315   while(1) {
+00316     PT_YIELD(&s.pt);
+00317   }
+00318 
+00319   PT_END(&s.pt);
+00320 }
+00321 /*---------------------------------------------------------------------------*/
+00322 void
+00323 dhcpc_init(const void *mac_addr, int mac_len)
+00324 {
+00325   uip_ipaddr_t addr;
+00326   
+00327   s.mac_addr = mac_addr;
+00328   s.mac_len  = mac_len;
+00329 
+00330   s.state = STATE_INITIAL;
+00331   uip_ipaddr(addr, 255,255,255,255);
+00332   s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT));
+00333   if(s.conn != NULL) {
+00334     uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT));
+00335   }
+00336   PT_INIT(&s.pt);
+00337 }
+00338 /*---------------------------------------------------------------------------*/
+00339 void
+00340 dhcpc_appcall(void)
+00341 {
+00342   handle_dhcp();
+00343 }
+00344 /*---------------------------------------------------------------------------*/
+00345 void
+00346 dhcpc_request(void)
+00347 {
+00348   u16_t ipaddr[2];
+00349   
+00350   if(s.state == STATE_INITIAL) {
+00351     uip_ipaddr(ipaddr, 0,0,0,0);
+00352     uip_sethostaddr(ipaddr);
+00353     /*    handle_dhcp(PROCESS_EVENT_NONE, NULL);*/
+00354   }
+00355 }
+00356 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00049.html b/doc/html/a00049.html index bd9dea0..5b5a7c0 100644 --- a/doc/html/a00049.html +++ b/doc/html/a00049.html @@ -1,43 +1,88 @@ - + -uIP 0.9: cgi.c File Reference +uIP 1.0: dhcpc.h + - - -

apps/httpd/cgi.c File Reference


Detailed Description

-HTTP server script language C functions file. -

-

Author:
Adam Dunkels <adam@dunkels.com>
-This file contains functions that are called by the web server scripts. The functions takes one argument, and the return value is interpreted as follows. A zero means that the function did not complete and should be invoked for the next packet as well. A non-zero value indicates that the function has completed and that the web server should move along to the next script line. -

-#include "uip.h"
-#include "cgi.h"
-#include "httpd.h"
-#include "fs.h"
-#include <stdio.h>
-#include <string.h>
- -

-Include dependency graph for cgi.c:

Include dependency graph
- - - - - - - - - - - - - -

Variables

-cgifunction cgitab []
 A table containing pointers to C functions that can be called from a web server script.

-
Generated on Tue Oct 7 15:51:03 2003 for uIP 0.9 by + + +

dhcpc.h

00001 /*
+00002  * Copyright (c) 2005, Swedish Institute of Computer Science
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * @(#)$Id: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $
+00032  */
+00033 #ifndef __DHCPC_H__
+00034 #define __DHCPC_H__
+00035 
+00036 #include "timer.h"
+00037 #include "pt.h"
+00038 
+00039 struct dhcpc_state {
+00040   struct pt pt;
+00041   char state;
+00042   struct uip_udp_conn *conn;
+00043   struct timer timer;
+00044   u16_t ticks;
+00045   const void *mac_addr;
+00046   int mac_len;
+00047   
+00048   u8_t serverid[4];
+00049 
+00050   u16_t lease_time[2];
+00051   u16_t ipaddr[2];
+00052   u16_t netmask[2];
+00053   u16_t dnsaddr[2];
+00054   u16_t default_router[2];
+00055 };
+00056 
+00057 void dhcpc_init(const void *mac_addr, int mac_len);
+00058 void dhcpc_request(void);
+00059 
+00060 void dhcpc_appcall(void);
+00061 
+00062 void dhcpc_configured(const struct dhcpc_state *s);
+00063 
+00064 typedef struct dhcpc_state uip_udp_appstate_t;
+00065 #define UIP_UDP_APPCALL dhcpc_appcall
+00066 
+00067 
+00068 #endif /* __DHCPC_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00050.html b/doc/html/a00050.html index fddbfc4..ddfa656 100644 --- a/doc/html/a00050.html +++ b/doc/html/a00050.html @@ -1,34 +1,177 @@ - + -uIP 0.9: cgi.h File Reference +uIP 1.0: uip-conf.h + - - -

apps/httpd/cgi.h File Reference


Detailed Description

-HTTP script language header file. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

- -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - -

Variables

-cgifunction cgitab []
 A table containing pointers to C functions that can be called from a web server script.

-
Generated on Tue Oct 7 15:51:04 2003 for uIP 0.9 by + + +

uip-conf.h

00001 /**
+00002  * \addtogroup uipopt
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \name Project-specific configuration options
+00008  * @{
+00009  *
+00010  * uIP has a number of configuration options that can be overridden
+00011  * for each project. These are kept in a project-specific uip-conf.h
+00012  * file and all configuration names have the prefix UIP_CONF.
+00013  */
+00014 
+00015 /*
+00016  * Copyright (c) 2006, Swedish Institute of Computer Science.
+00017  * All rights reserved.
+00018  *
+00019  * Redistribution and use in source and binary forms, with or without
+00020  * modification, are permitted provided that the following conditions
+00021  * are met:
+00022  * 1. Redistributions of source code must retain the above copyright
+00023  *    notice, this list of conditions and the following disclaimer.
+00024  * 2. Redistributions in binary form must reproduce the above copyright
+00025  *    notice, this list of conditions and the following disclaimer in the
+00026  *    documentation and/or other materials provided with the distribution.
+00027  * 3. Neither the name of the Institute nor the names of its contributors
+00028  *    may be used to endorse or promote products derived from this software
+00029  *    without specific prior written permission.
+00030  *
+00031  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00032  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00033  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00034  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00035  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00036  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00037  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00038  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00039  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00040  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00041  * SUCH DAMAGE.
+00042  *
+00043  * This file is part of the uIP TCP/IP stack
+00044  *
+00045  * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
+00046  */
+00047 
+00048 /**
+00049  * \file
+00050  *         An example uIP configuration file
+00051  * \author
+00052  *         Adam Dunkels <adam@sics.se>
+00053  */
+00054 
+00055 #ifndef __UIP_CONF_H__
+00056 #define __UIP_CONF_H__
+00057 
+00058 #include <inttypes.h>
+00059 
+00060 /**
+00061  * 8 bit datatype
+00062  *
+00063  * This typedef defines the 8-bit type used throughout uIP.
+00064  *
+00065  * \hideinitializer
+00066  */
+00067 typedef uint8_t u8_t;
+00068 
+00069 /**
+00070  * 16 bit datatype
+00071  *
+00072  * This typedef defines the 16-bit type used throughout uIP.
+00073  *
+00074  * \hideinitializer
+00075  */
+00076 typedef uint16_t u16_t;
+00077 
+00078 /**
+00079  * Statistics datatype
+00080  *
+00081  * This typedef defines the dataype used for keeping statistics in
+00082  * uIP.
+00083  *
+00084  * \hideinitializer
+00085  */
+00086 typedef unsigned short uip_stats_t;
+00087 
+00088 /**
+00089  * Maximum number of TCP connections.
+00090  *
+00091  * \hideinitializer
+00092  */
+00093 #define UIP_CONF_MAX_CONNECTIONS 40
+00094 
+00095 /**
+00096  * Maximum number of listening TCP ports.
+00097  *
+00098  * \hideinitializer
+00099  */
+00100 #define UIP_CONF_MAX_LISTENPORTS 40
+00101 
+00102 /**
+00103  * uIP buffer size.
+00104  *
+00105  * \hideinitializer
+00106  */
+00107 #define UIP_CONF_BUFFER_SIZE     420
+00108 
+00109 /**
+00110  * CPU byte order.
+00111  *
+00112  * \hideinitializer
+00113  */
+00114 #define UIP_CONF_BYTE_ORDER      LITTLE_ENDIAN
+00115 
+00116 /**
+00117  * Logging on or off
+00118  *
+00119  * \hideinitializer
+00120  */
+00121 #define UIP_CONF_LOGGING         1
+00122 
+00123 /**
+00124  * UDP support on or off
+00125  *
+00126  * \hideinitializer
+00127  */
+00128 #define UIP_CONF_UDP             0
+00129 
+00130 /**
+00131  * UDP checksums on or off
+00132  *
+00133  * \hideinitializer
+00134  */
+00135 #define UIP_CONF_UDP_CHECKSUMS   1
+00136 
+00137 /**
+00138  * uIP statistics on or off
+00139  *
+00140  * \hideinitializer
+00141  */
+00142 #define UIP_CONF_STATISTICS      1
+00143 
+00144 /* Here we include the header file for the application(s) we use in
+00145    our project. */
+00146 /*#include "smtp.h"*/
+00147 /*#include "hello-world.h"*/
+00148 /*#include "telnetd.h"*/
+00149 #include "webserver.h"
+00150 /*#include "dhcpc.h"*/
+00151 /*#include "resolv.h"*/
+00152 /*#include "webclient.h"*/
+00153 
+00154 #endif /* __UIP_CONF_H__ */
+00155 
+00156 /** @} */
+00157 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00051.html b/doc/html/a00051.html index a1dc71c..e9197ff 100644 --- a/doc/html/a00051.html +++ b/doc/html/a00051.html @@ -1,44 +1,138 @@ - + -uIP 0.9: fs.c File Reference +uIP 1.0: uip-code-style.c + - - -

apps/httpd/fs.c File Reference


Detailed Description

-HTTP server read-only file system code. -

-

Author:
Adam Dunkels <adam@dunkels.com>
-A simple read-only filesystem. -

-#include "uip.h"
-#include "httpd.h"
-#include "fs.h"
-#include "fsdata.h"
-#include "fsdata.c"
- -

-Include dependency graph for fs.c:

Include dependency graph
- - - - - - - - - - - - - - - -

Functions

int fs_open (const char *name, struct fs_file *file)
 Open a file in the read-only file system.

-void fs_init (void)
 Initialize the read-only file system.

-
Generated on Tue Oct 7 15:51:05 2003 for uIP 0.9 by + + +

uip-code-style.c

00001 /* This is the official code style of uIP. */
+00002 
+00003 /**
+00004  * \defgroup codestyle Coding style
+00005  *
+00006  * This is how a Doxygen module is documented - start with a \defgroup
+00007  * Doxygen keyword at the beginning of the file to define a module,
+00008  * and use the \addtogroup Doxygen keyword in all other files that
+00009  * belong to the same module. Typically, the \defgroup is placed in
+00010  * the .h file and \addtogroup in the .c file.
+00011  *
+00012  * @{
+00013  */
+00014 
+00015 /**
+00016  * \file
+00017  *         A brief description of what this file is.
+00018  * \author
+00019  *         Adam Dunkels <adam@sics.se>
+00020  *
+00021  *         Every file that is part of a documented module has to have
+00022  *         a \file block, else it will not show up in the Doxygen
+00023  *         "Modules" * section.
+00024  */
+00025 
+00026 /* Single line comments look like this. */
+00027 
+00028 /*
+00029  * Multi-line comments look like this. Comments should prefferably be
+00030  * full sentences, filled to look like real paragraphs.
+00031  */
+00032 
+00033 #include "uip.h"
+00034 
+00035 /*
+00036  * Make sure that non-global variables are all maked with the static
+00037  * keyword. This keeps the size of the symbol table down.
+00038  */
+00039 static int flag;
+00040 
+00041 /*
+00042  * All variables and functions that are visible outside of the file
+00043  * should have the module name prepended to them. This makes it easy
+00044  * to know where to look for function and variable definitions.
+00045  *
+00046  * Put dividers (a single-line comment consisting only of dashes)
+00047  * between functions.
+00048  */
+00049 /*---------------------------------------------------------------------------*/
+00050 /**
+00051  * \brief      Use Doxygen documentation for functions.
+00052  * \param c    Briefly describe all parameters.
+00053  * \return     Briefly describe the return value.
+00054  * \retval 0   Functions that return a few specified values
+00055  * \retval 1   can use the \retval keyword instead of \return.
+00056  *
+00057  *             Put a longer description of what the function does
+00058  *             after the preamble of Doxygen keywords.
+00059  *
+00060  *             This template should always be used to document
+00061  *             functions. The text following the introduction is used
+00062  *             as the function's documentation.
+00063  *
+00064  *             Function prototypes have the return type on one line,
+00065  *             the name and arguments on one line (with no space
+00066  *             between the name and the first parenthesis), followed
+00067  *             by a single curly bracket on its own line.
+00068  */
+00069 void
+00070 code_style_example_function(void)
+00071 {
+00072   /*
+00073    * Local variables should always be declared at the start of the
+00074    * function.
+00075    */
+00076   int i;                   /* Use short variable names for loop
+00077                               counters. */
+00078 
+00079   /*
+00080    * There should be no space between keywords and the first
+00081    * parenthesis. There should be spaces around binary operators, no
+00082    * spaces between a unary operator and its operand.
+00083    *
+00084    * Curly brackets following for(), if(), do, and case() statements
+00085    * should follow the statement on the same line.
+00086    */
+00087   for(i = 0; i < 10; ++i) {
+00088     /*
+00089      * Always use full blocks (curly brackets) after if(), for(), and
+00090      * while() statements, even though the statement is a single line
+00091      * of code. This makes the code easier to read and modifications
+00092      * are less error prone.
+00093      */
+00094     if(i == c) {
+00095       return c;           /* No parentesis around return values. */
+00096     } else {              /* The else keyword is placed inbetween
+00097                              curly brackers, always on its own line. */
+00098       c++;
+00099     }
+00100   }
+00101 }
+00102 /*---------------------------------------------------------------------------*/
+00103 /*
+00104  * Static (non-global) functions do not need Doxygen comments. The
+00105  * name should not be prepended with the module name - doing so would
+00106  * create confusion.
+00107  */
+00108 static void
+00109 an_example_function(void)
+00110 {
+00111   
+00112 }
+00113 /*---------------------------------------------------------------------------*/
+00114 
+00115 /* The following stuff ends the \defgroup block at the beginning of
+00116    the file: */
+00117 
+00118 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00052.html b/doc/html/a00052.html deleted file mode 100644 index 9482628..0000000 --- a/doc/html/a00052.html +++ /dev/null @@ -1,51 +0,0 @@ - - -uIP 0.9: fs.h File Reference - - - - -

apps/httpd/fs.h File Reference


Detailed Description

-HTTP server read-only file system header file. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
- -

-Include dependency graph for fs.h:

Include dependency graph
- - - - - - -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - -

Data Structures

struct  fs_file
 An open file in the read-only file system. More...


Functions

int fs_open (const char *name, struct fs_file *file)
 Open a file in the read-only file system.

-void fs_init (void)
 Initialize the read-only file system.

-
Generated on Tue Oct 7 15:51:07 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00053.html b/doc/html/a00053.html deleted file mode 100644 index b9951cc..0000000 --- a/doc/html/a00053.html +++ /dev/null @@ -1,41 +0,0 @@ - - -uIP 0.9: httpd.c File Reference - - - - -

apps/httpd/httpd.c File Reference


Detailed Description

-HTTP server. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
-#include "httpd.h"
-#include "fs.h"
-#include "fsdata.h"
-#include "cgi.h"
- -

-Include dependency graph for httpd.c:

Include dependency graph
- - - - - - - - - - - - - -

Functions

void httpd_init (void)
 Initialize the web server.

-
Generated on Tue Oct 7 15:51:07 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00054.html b/doc/html/a00054.html deleted file mode 100644 index a0ee8cd..0000000 --- a/doc/html/a00054.html +++ /dev/null @@ -1,38 +0,0 @@ - - -uIP 0.9: httpd.h File Reference - - - - -

apps/httpd/httpd.h File Reference


Detailed Description

-HTTP server header file. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

- -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - -

Functions

void httpd_init (void)
 Initialize the web server.

-
Generated on Tue Oct 7 15:51:09 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00055.html b/doc/html/a00055.html deleted file mode 100644 index a3e2037..0000000 --- a/doc/html/a00055.html +++ /dev/null @@ -1,50 +0,0 @@ - - -uIP 0.9: resolv.c File Reference - - - - -

apps/resolv/resolv.c File Reference


Detailed Description

-DNS host name to IP address resolver. -

-

Author:
Adam Dunkels <adam@dunkels.com>
-This file implements a DNS host name to IP address resolver. -

-#include "resolv.h"
-#include <string.h>
- -

-Include dependency graph for resolv.c:

Include dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - -

Functions

void resolv_query (char *name)
 Queues a name so that a question for the name will be sent out.

u16_tresolv_lookup (char *name)
 Look up a hostname in the array of known hostnames.

u16_tresolv_getserver (void)
 Obtain the currently configured DNS server.

void resolv_conf (u16_t *dnsserver)
 Configure which DNS server to use for queries.

-void resolv_init (void)
 Initalize the resolver.

-
Generated on Tue Oct 7 15:51:09 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00056.html b/doc/html/a00056.html deleted file mode 100644 index eb1c2b3..0000000 --- a/doc/html/a00056.html +++ /dev/null @@ -1,58 +0,0 @@ - - -uIP 0.9: resolv.h File Reference - - - - -

apps/resolv/resolv.h File Reference


Detailed Description

-DNS resolver code header file. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
- -

-Include dependency graph for resolv.h:

Include dependency graph
- - - - - - -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - -

Functions

void resolv_found (char *name, u16_t *ipaddr)
 Callback function which is called when a hostname is found.

void resolv_conf (u16_t *dnsserver)
 Configure which DNS server to use for queries.

u16_tresolv_getserver (void)
 Obtain the currently configured DNS server.

-void resolv_init (void)
 Initalize the resolver.

u16_tresolv_lookup (char *name)
 Look up a hostname in the array of known hostnames.

void resolv_query (char *name)
 Queues a name so that a question for the name will be sent out.

-
Generated on Tue Oct 7 15:51:11 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00057.html b/doc/html/a00057.html deleted file mode 100644 index 022aed2..0000000 --- a/doc/html/a00057.html +++ /dev/null @@ -1,42 +0,0 @@ - - -uIP 0.9: smtp.c File Reference - - - - -

apps/smtp/smtp.c File Reference


Detailed Description

-SMTP example implementation. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
-#include "smtp.h"
-#include "smtp-strings.h"
-#include <string.h>
- -

-Include dependency graph for smtp.c:

Include dependency graph
- - - - - - - - - - - - - - - -

Functions

unsigned char smtp_send (char *to, char *from, char *subject, char *msg, u16_t msglen)
 Send an e-mail.

void smtp_configure (char *lhostname, u16_t *server)
 Specificy an SMTP server and hostname.

-
Generated on Tue Oct 7 15:51:12 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00058.html b/doc/html/a00058.html deleted file mode 100644 index f617cc1..0000000 --- a/doc/html/a00058.html +++ /dev/null @@ -1,59 +0,0 @@ - - -uIP 0.9: smtp.h File Reference - - - - -

apps/smtp/smtp.h File Reference


Detailed Description

-SMTP header file. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uipopt.h"
- -

-Include dependency graph for smtp.h:

Include dependency graph
- - - - - -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - -

Defines

-#define SMTP_ERR_OK   0
 Error number that signifies a non-error condition.

-#define UIP_APPCALL   smtp_appcall
 The name of the application function that uIP should call in response to TCP/IP events.

-#define UIP_APPSTATE_SIZE   (sizeof(struct smtp_state))
 The size of the application state that is to be stored in the uip_conn structure.


Functions

void smtp_done (unsigned char error)
 Callback function that is called when an e-mail transmission is done.

void smtp_configure (char *localhostname, u16_t *smtpserver)
 Specificy an SMTP server and hostname.

unsigned char smtp_send (char *to, char *from, char *subject, char *msg, u16_t msglen)
 Send an e-mail.

-
Generated on Tue Oct 7 15:51:14 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00059.html b/doc/html/a00059.html deleted file mode 100644 index 292bc97..0000000 --- a/doc/html/a00059.html +++ /dev/null @@ -1,65 +0,0 @@ - - -uIP 0.9: memb.c File Reference - - - - -

apps/telnetd/memb.c File Reference


Detailed Description

-Memory block allocation routines. -

-

Author:
Adam Dunkels <adam@sics.se>
-The memory block allocation routines provide a simple yet powerful set of functions for managing a set of memory blocks of fixed size. A set of memory blocks is statically declared with the MEMB() macro. Memory blocks are allocated from the declared memory by the memb_alloc() function, and are deallocated with the memb_free() function.

-

Note:
Because of namespace clashes only one MEMB() can be declared per C module, and the name scope of a MEMB() memory block is local to each C module.
-The following example shows how to declare and use a memory block called "cmem" which has 8 chunks of memory with each memory chunk being 20 bytes large.

-

 MEMB(cmem, 20, 8);
-
- int main(int argc, char *argv[]) {
-    char *ptr;
-    
-    memb_init(&cmem);
-
-    ptr = memb_alloc(&cmem);
-
-    if(ptr != NULL) {
-       do_something(ptr);
-    } else {
-       printf("Could not allocate memory.\n");
-    }
-
-    if(memb_free(ptr) == 0) {
-       printf("Deallocation succeeded.\n");
-    }
- }
-
-

-#include <string.h>
-#include "memb.h"
- -

-Include dependency graph for memb.c:

Include dependency graph
- - - - - - - - - - - - - - - - - - -

Functions

void memb_init (struct memb_blocks *m)
 Initialize a memory block that was declared with MEMB().

char * memb_alloc (struct memb_blocks *m)
 Allocate a memory block from a block of memory declared with MEMB().

char memb_free (struct memb_blocks *m, char *ptr)
 Deallocate a memory block from a memory block previously declared with MEMB().

char memb_ref (struct memb_blocks *m, char *ptr)
 Increase the reference count for a memory chunk.

-
Generated on Tue Oct 7 15:51:14 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00060.html b/doc/html/a00060.html deleted file mode 100644 index d0941c3..0000000 --- a/doc/html/a00060.html +++ /dev/null @@ -1,46 +0,0 @@ - - -uIP 0.9: memb.h File Reference - - - - -

apps/telnetd/memb.h File Reference


Detailed Description

-Memory block allocation routines. -

-

Author:
Adam Dunkels <adam@sics.se>
- -

- -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - - - - - - -

Defines

#define MEMB(name, size, num)
 Declare a memory block.


Functions

void memb_init (struct memb_blocks *m)
 Initialize a memory block that was declared with MEMB().

char * memb_alloc (struct memb_blocks *m)
 Allocate a memory block from a block of memory declared with MEMB().

char memb_ref (struct memb_blocks *m, char *ptr)
 Increase the reference count for a memory chunk.

char memb_free (struct memb_blocks *m, char *ptr)
 Deallocate a memory block from a memory block previously declared with MEMB().

-
Generated on Tue Oct 7 15:51:15 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00061.html b/doc/html/a00061.html deleted file mode 100644 index 1eb004b..0000000 --- a/doc/html/a00061.html +++ /dev/null @@ -1,41 +0,0 @@ - - -uIP 0.9: telnetd-shell.c File Reference - - - - -

apps/telnetd/telnetd-shell.c File Reference


Detailed Description

-An example telnet server shell. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
-#include "telnetd.h"
-#include <string.h>
- -

-Include dependency graph for telnetd-shell.c:

Include dependency graph
- - - - - - - - - - - - - - - -

Functions

void telnetd_connected (struct telnetd_state *s)
 Callback function that is called when a telnet connection has been established.

void telnetd_input (struct telnetd_state *s, char *cmd)
 Callback function that is called when a line of text has arrived on a telnet connection.

-
Generated on Tue Oct 7 15:51:16 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00062.html b/doc/html/a00062.html deleted file mode 100644 index 254217b..0000000 --- a/doc/html/a00062.html +++ /dev/null @@ -1,49 +0,0 @@ - - -uIP 0.9: telnetd.c File Reference - - - - -

apps/telnetd/telnetd.c File Reference


Detailed Description

-Implementation of the Telnet server. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
-#include "memb.h"
-#include "telnetd.h"
-#include <string.h>
- -

-Include dependency graph for telnetd.c:

Include dependency graph
- - - - - - - - - - - - - - - - - - - - - - -

Functions

void telnetd_close (struct telnetd_state *s)
 Close a telnet session.

void telnetd_prompt (struct telnetd_state *s, char *str)
 Print a prompt on a telnet connection.

void telnetd_output (struct telnetd_state *s, char *str1, char *str2)
 Print out a string on a telnet connection.

void telnetd_init (void)
 Initialize the telnet server.

-
Generated on Tue Oct 7 15:51:17 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00063.html b/doc/html/a00063.html deleted file mode 100644 index 3da5afc..0000000 --- a/doc/html/a00063.html +++ /dev/null @@ -1,70 +0,0 @@ - - -uIP 0.9: telnetd.h File Reference - - - - -

apps/telnetd/telnetd.h File Reference


Detailed Description

-Header file for the telnet server. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
- -

-Include dependency graph for telnetd.h:

Include dependency graph
- - - - - - -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Structures

struct  telnetd_state
 A telnet connection structure. More...


Defines

-#define TELNETD_LINELEN
 The maximum length of a telnet line.

-#define TELNETD_NUMLINES
 The number of output lines being buffered for all telnet connections.


Functions

void telnetd_connected (struct telnetd_state *s)
 Callback function that is called when a telnet connection has been established.

void telnetd_input (struct telnetd_state *s, char *cmd)
 Callback function that is called when a line of text has arrived on a telnet connection.

void telnetd_close (struct telnetd_state *s)
 Close a telnet session.

void telnetd_output (struct telnetd_state *s, char *s1, char *s2)
 Print out a string on a telnet connection.

void telnetd_prompt (struct telnetd_state *s, char *str)
 Print a prompt on a telnet connection.

void telnetd_init (void)
 Initialize the telnet server.

-
Generated on Tue Oct 7 15:51:21 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00064.html b/doc/html/a00064.html deleted file mode 100644 index 8a5acfd..0000000 --- a/doc/html/a00064.html +++ /dev/null @@ -1,60 +0,0 @@ - - -uIP 0.9: webclient.c File Reference - - - - -

apps/webclient/webclient.c File Reference


Detailed Description

-Implementation of the HTTP client. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
-#include "webclient.h"
-#include "resolv.h"
-#include <string.h>
- -

-Include dependency graph for webclient.c:

Include dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Functions

char * webclient_mimetype (void)
 Obtain the MIME type of the current HTTP data stream.

char * webclient_filename (void)
 Obtain the filename of the current HTTP data stream.

char * webclient_hostname (void)
 Obtain the hostname of the current HTTP data stream.

unsigned short webclient_port (void)
 Obtain the port number of the current HTTP data stream.

-void webclient_init (void)
 Initialize the webclient module.

-void webclient_close (void)
 Close the currently open HTTP connection.

unsigned char webclient_get (char *host, u16_t port, char *file)
 Open an HTTP connection to a web server and ask for a file using the GET method.

-
Generated on Tue Oct 7 15:51:24 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00065.html b/doc/html/a00065.html deleted file mode 100644 index 7a9e0fe..0000000 --- a/doc/html/a00065.html +++ /dev/null @@ -1,72 +0,0 @@ - - -uIP 0.9: webclient.h File Reference - - - - -

apps/webclient/webclient.h File Reference


Detailed Description

-Header file for the HTTP client. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "http-strings.h"
-#include "http-user-agent-string.h"
- -

-Include dependency graph for webclient.h:

Include dependency graph
- -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Functions

void webclient_datahandler (char *data, u16_t len)
 Callback function that is called from the webclient code when HTTP data has been received.

void webclient_connected (void)
 Callback function that is called from the webclient code when the HTTP connection has been connected to the web server.

void webclient_timedout (void)
 Callback function that is called from the webclient code if the HTTP connection to the web server has timed out.

void webclient_aborted (void)
 Callback function that is called from the webclient code if the HTTP connection to the web server has been aborted by the web server.

void webclient_closed (void)
 Callback function that is called from the webclient code when the HTTP connection to the web server has been closed.

-void webclient_init (void)
 Initialize the webclient module.

unsigned char webclient_get (char *host, u16_t port, char *file)
 Open an HTTP connection to a web server and ask for a file using the GET method.

-void webclient_close (void)
 Close the currently open HTTP connection.

char * webclient_mimetype (void)
 Obtain the MIME type of the current HTTP data stream.

char * webclient_filename (void)
 Obtain the filename of the current HTTP data stream.

char * webclient_hostname (void)
 Obtain the hostname of the current HTTP data stream.

unsigned short webclient_port (void)
 Obtain the port number of the current HTTP data stream.

-
Generated on Tue Oct 7 15:51:29 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00067.html b/doc/html/a00067.html deleted file mode 100644 index 984f8a1..0000000 --- a/doc/html/a00067.html +++ /dev/null @@ -1,41 +0,0 @@ - - -uIP 0.9: slipdev.c File Reference - - - - -

uip/slipdev.c File Reference


Detailed Description

-SLIP protocol implementation. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
- -

-Include dependency graph for slipdev.c:

Include dependency graph
- - - - - - - - - - - - - - - - - -

Functions

void slipdev_send (void)
 Send the packet in the uip_buf and uip_appdata buffers using the SLIP protocol.

u16_t slipdev_poll (void)
 Poll the SLIP device for an available packet.

void slipdev_init (void)
 Initialize the SLIP module.

-
Generated on Tue Oct 7 15:51:30 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00068.html b/doc/html/a00068.html deleted file mode 100644 index 0fb5a0d..0000000 --- a/doc/html/a00068.html +++ /dev/null @@ -1,47 +0,0 @@ - - -uIP 0.9: slipdev.h File Reference - - - - -

uip/slipdev.h File Reference


Detailed Description

-SLIP header file. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
- -

-Include dependency graph for slipdev.h:

Include dependency graph
- - - - - - - - - - - - - - - - - - - - - - - -

Functions

void slipdev_char_put (u8_t c)
 Put a character on the serial device.

u8_t slipdev_char_poll (u8_t *c)
 Poll the serial device for a character.

void slipdev_init (void)
 Initialize the SLIP module.

void slipdev_send (void)
 Send the packet in the uip_buf and uip_appdata buffers using the SLIP protocol.

u16_t slipdev_poll (void)
 Poll the SLIP device for an available packet.

-
Generated on Tue Oct 7 15:51:31 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00069.html b/doc/html/a00069.html deleted file mode 100644 index ed3c40f..0000000 --- a/doc/html/a00069.html +++ /dev/null @@ -1,61 +0,0 @@ - - -uIP 0.9: uip.c File Reference - - - - -

uip/uip.c File Reference


Detailed Description

-The uIP TCP/IP stack code. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
-#include "uipopt.h"
-#include "uip_arch.h"
- -

-Include dependency graph for uip.c:

Include dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Functions

void uip_init (void)
 uIP initialization function.

uip_udp_connuip_udp_new (u16_t *ripaddr, u16_t rport)
 Set up a new UDP connection.

void uip_unlisten (u16_t port)
 Stop listening to the specified port.

void uip_listen (u16_t port)
 Start listening to the specified port.

u16_t htons (u16_t val)
 Convert 16-bit quantity from host byte order to network byte order.


Variables

u8_t uip_buf [UIP_BUFSIZE+2]
 The uIP packet buffer.

volatile u8_tuip_appdata
 Pointer to the application data in the packet buffer.

-volatile u8_t uip_acc32 [4]
 4-byte array used for the 32-bit sequence number calculations.

-
Generated on Tue Oct 7 15:51:32 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00070.html b/doc/html/a00070.html deleted file mode 100644 index 6d71f1d..0000000 --- a/doc/html/a00070.html +++ /dev/null @@ -1,183 +0,0 @@ - - -uIP 0.9: uip.h File Reference - - - - -

uip/uip.h File Reference


Detailed Description

-Header file for the uIP TCP/IP stack. -

-

Author:
Adam Dunkels <adam@dunkels.com>
-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. -

-#include "uipopt.h"
- -

-Include dependency graph for uip.h:

Include dependency graph
- - - - - -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Structures

struct  uip_conn
 Representation of a uIP TCP connection. More...

struct  uip_stats
 The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1. More...

struct  uip_udp_conn
 Representation of a uIP UDP connection. More...


Defines

#define uip_sethostaddr(addr)
 Set the IP address of this host.

#define uip_gethostaddr(addr)
 Get the IP address of this host.

#define uip_input()
 Process an incoming packet.

#define uip_periodic(conn)
 Periodic processing for a connection identified by its number.

#define uip_periodic_conn(conn)
 Periodic processing for a connection identified by a pointer to its structure.

#define uip_udp_periodic(conn)
 Periodic processing for a UDP connection identified by its number.

#define uip_udp_periodic_conn(conn)
 Periodic processing for a UDP connection identified by a pointer to its structure.

#define uip_send(data, len)
 Send data on the current connection.

#define uip_datalen()
 The length of any incoming data that is currently avaliable (if avaliable) in the uip_appdata buffer.

#define uip_urgdatalen()
 The length of any out-of-band data (urgent data) that has arrived on the connection.

#define uip_close()
 Close the current connection.

#define uip_abort()
 Abort the current connection.

#define uip_stop()
 Tell the sending host to stop sending data.

-#define uip_stopped(conn)
 Find out if the current connection has been previously stopped with uip_stop().

#define uip_restart()
 Restart the current connection, if is has previously been stopped with uip_stop().

#define uip_newdata()
 Is new incoming data available?

#define uip_acked()
 Has previously sent data been acknowledged?

#define uip_connected()
 Has the connection just been connected?

#define uip_closed()
 Has the connection been closed by the other end?

#define uip_aborted()
 Has the connection been aborted by the other end?

#define uip_timedout()
 Has the connection timed out?

#define uip_rexmit()
 Do we need to retransmit previously data?

#define uip_poll()
 Is the connection being polled by uIP?

-#define uip_initialmss()
 Get the initial maxium segment size (MSS) of the current connection.

#define uip_mss()
 Get the current maxium segment size that can be sent on the current connection.

#define uip_udp_remove(conn)
 Removed a UDP connection.

#define uip_udp_send(len)
 Send a UDP datagram of length len on the current connection.

#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
 Pack an IP address into a 4-byte array which is used by uIP to represent IP addresses.

#define HTONS(n)
 Convert 16-bit quantity from host byte order to network byte order.


Functions

void uip_init (void)
 uIP initialization function.

void uip_listen (u16_t port)
 Start listening to the specified port.

void uip_unlisten (u16_t port)
 Stop listening to the specified port.

uip_connuip_connect (u16_t *ripaddr, u16_t port)
 Connect to a remote host using TCP.

uip_udp_connuip_udp_new (u16_t *ripaddr, u16_t rport)
 Set up a new UDP connection.

u16_t htons (u16_t val)
 Convert 16-bit quantity from host byte order to network byte order.


Variables

u8_t uip_buf [UIP_BUFSIZE+2]
 The uIP packet buffer.

volatile u8_tuip_appdata
 Pointer to the application data in the packet buffer.

-volatile u8_t uip_acc32 [4]
 4-byte array used for the 32-bit sequence number calculations.

uip_stats uip_stat
 The uIP TCP/IP statistics.

-
Generated on Tue Oct 7 15:51:34 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00071.html b/doc/html/a00071.html deleted file mode 100644 index f2348e6..0000000 --- a/doc/html/a00071.html +++ /dev/null @@ -1,50 +0,0 @@ - - -uIP 0.9: uip_arch.h File Reference - - - - -

uip/uip_arch.h File Reference


Detailed Description

-Declarations of architecture specific functions. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
- -

-Include dependency graph for uip_arch.h:

Include dependency graph
- - - - - - -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - -

Functions

void uip_add32 (u8_t *op32, u16_t op16)
 Carry out a 32-bit addition.

u16_t uip_chksum (u16_t *buf, u16_t len)
 Calculate the Internet checksum over a buffer.

u16_t uip_ipchksum (void)
 Calculate the IP header checksum of the packet header in uip_buf.

u16_t uip_tcpchksum (void)
 Calculate the TCP checksum of the packet in uip_buf and uip_appdata.

-
Generated on Tue Oct 7 15:51:36 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00072.html b/doc/html/a00072.html deleted file mode 100644 index 01fc222..0000000 --- a/doc/html/a00072.html +++ /dev/null @@ -1,50 +0,0 @@ - - -uIP 0.9: uip_arp.c File Reference - - - - -

uip/uip_arp.c File Reference


Detailed Description

-Implementation of the ARP Address Resolution Protocol. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip_arp.h"
-#include <string.h>
- -

-Include dependency graph for uip_arp.c:

Include dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - -

Functions

-void uip_arp_init (void)
 Initialize the ARP module.

void uip_arp_timer (void)
 Periodic ARP processing function.

void uip_arp_ipin (void)
 ARP processing for incoming IP packets.

void uip_arp_arpin (void)
 ARP processing for incoming ARP packets.

void uip_arp_out (void)
 Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request.

-
Generated on Tue Oct 7 15:51:37 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00073.html b/doc/html/a00073.html deleted file mode 100644 index 483b616..0000000 --- a/doc/html/a00073.html +++ /dev/null @@ -1,77 +0,0 @@ - - -uIP 0.9: uip_arp.h File Reference - - - - -

uip/uip_arp.h File Reference


Detailed Description

-Macros and definitions for the ARP module. -

-

Author:
Adam Dunkels <adam@dunkels.com>
- -

-#include "uip.h"
- -

-Include dependency graph for uip_arp.h:

Include dependency graph
- - - - - - -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Structures

struct  uip_eth_addr
 Representation of a 48-bit Ethernet address. More...

struct  uip_eth_hdr
 The Ethernet header. More...


Defines

#define uip_setdraddr(addr)
 Set the default router's IP address.

#define uip_setnetmask(addr)
 Set the netmask.

#define uip_getdraddr(addr)
 Get the default router's IP address.

#define uip_getnetmask(addr)
 Get the netmask.

#define uip_setethaddr(eaddr)
 Specifiy the Ethernet MAC address.


Functions

-void uip_arp_init (void)
 Initialize the ARP module.

void uip_arp_ipin (void)
 ARP processing for incoming IP packets.

void uip_arp_arpin (void)
 ARP processing for incoming ARP packets.

void uip_arp_out (void)
 Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request.

void uip_arp_timer (void)
 Periodic ARP processing function.

-
Generated on Tue Oct 7 15:51:39 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00074.html b/doc/html/a00074.html deleted file mode 100644 index 1cb69e1..0000000 --- a/doc/html/a00074.html +++ /dev/null @@ -1,209 +0,0 @@ - - -uIP 0.9: uipopt.h File Reference - - - - -

unix/uipopt.h File Reference


Detailed Description

-Configuration options for uIP. -

-

Author:
Adam Dunkels <adam@dunkels.com>
-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. -

-#include "httpd.h"
- -

-Include dependency graph for uipopt.h:

Include dependency graph
- - - - -

-This graph shows which files directly or indirectly include this file:

Included by dependency graph
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Defines

#define UIP_FIXEDADDR
 Determines if uIP should use a fixed IP address or not.

#define UIP_PINGADDRCONF
 Ping IP address asignment.

-#define UIP_IPADDR0
 The first octet of the IP address of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_IPADDR1
 The second octet of the IP address of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_IPADDR2
 The third octet of the IP address of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_IPADDR3
 The fourth octet of the IP address of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_NETMASK0
 The first octet of the netmask of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_NETMASK1
 The second octet of the netmask of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_NETMASK2
 The third octet of the netmask of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_NETMASK3
 The fourth octet of the netmask of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_DRIPADDR0
 The first octet of the IP address of the default router, if UIP_FIXEDADDR is 1.

-#define UIP_DRIPADDR1
 The second octet of the IP address of the default router, if UIP_FIXEDADDR is 1.

-#define UIP_DRIPADDR2
 The third octet of the IP address of the default router, if UIP_FIXEDADDR is 1.

-#define UIP_DRIPADDR3
 The fourth octet of the IP address of the default router, if UIP_FIXEDADDR is 1.

#define UIP_FIXEDETHADDR
 Specifies if the uIP ARP module should be compiled with a fixed Ethernet MAC address or not.

-#define UIP_ETHADDR0
 The first octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR1
 The second octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR2
 The third octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR3
 The fourth octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR4
 The fifth octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR5
 The sixth octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

#define UIP_TTL   255
 The IP TTL (time to live) of IP packets sent by uIP.

#define UIP_REASSEMBLY
 Turn on support for IP packet reassembly.

-#define UIP_REASS_MAXAGE   40
 The maximum time an IP fragment should wait in the reassembly buffer before it is dropped.

-#define UIP_UDP
 Toggles wether UDP support should be compiled in or not.

#define UIP_UDP_CHECKSUMS
 Toggles if UDP checksums should be used or not.

-#define UIP_UDP_CONNS
 The maximum amount of concurrent UDP connections.

-#define UIP_UDP_APPCALL
 The name of the function that should be called when UDP datagrams arrive.

#define UIP_ACTIVE_OPEN
 Determines if support for opening connections from uIP should be compiled in.

#define UIP_CONNS
 The maximum number of simultaneously open TCP connections.

#define UIP_LISTENPORTS
 The maximum number of simultaneously listening TCP ports.

#define UIP_RECEIVE_WINDOW
 The size of the advertised receiver's window.

#define UIP_URGDATA
 Determines if support for TCP urgent data notification should be compiled in.

#define UIP_RTO   3
 The initial retransmission timeout counted in timer pulses.

#define UIP_MAXRTX   8
 The maximum number of times a segment should be retransmitted before the connection should be aborted.

#define UIP_MAXSYNRTX   3
 The maximum number of times a SYN segment should be retransmitted before a connection request should be deemed to have been unsuccessful.

#define UIP_TCP_MSS   (UIP_BUFSIZE - UIP_LLH_LEN - 40)
 The TCP maximum segment size.

#define UIP_TIME_WAIT_TIMEOUT   120
 How long a connection should stay in the TIME_WAIT state.

#define UIP_ARPTAB_SIZE
 The size of the ARP table.

#define UIP_ARP_MAXAGE   120
 The maxium age of ARP table entries measured in 10ths of seconds.

#define UIP_BUFSIZE
 The size of the uIP packet buffer.

#define UIP_STATISTICS
 Determines if statistics support should be compiled in.

#define UIP_LOGGING
 Determines if logging of certain events should be compiled in.

#define UIP_LLH_LEN
 The link level header length.

#define BYTE_ORDER
 The byte order of the CPU architecture on which uIP is to be run.


Typedefs

typedef unsigned char u8_t
 The 8-bit unsigned data type.

typedef unsigned short u16_t
 The 16-bit unsigned data type.

typedef unsigned short uip_stats_t
 The statistics data type.


Functions

void uip_log (char *msg)
 Print out a uIP log message.

-
Generated on Tue Oct 7 15:51:41 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00075.html b/doc/html/a00075.html deleted file mode 100644 index 3cc54a6..0000000 --- a/doc/html/a00075.html +++ /dev/null @@ -1,358 +0,0 @@ - - -uIP 0.9: The uIP TCP/IP stack - - - - -

The uIP TCP/IP stack

-

- - - - - - - -

-

- - - -

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Files

file  uip.c
 The uIP TCP/IP stack code.

file  uip.h
 Header file for the uIP TCP/IP stack.


Modules

uIP configuration functions
uIP initialization functions
uIP device driver functions
uIP application functions
uIP conversion functions
uIP Address Resolution Protocol
Serial Line IP (SLIP) protocol
uIP hostname resolver functions
Architecture specific uIP functions

Data Structures

struct  uip_conn
 Representation of a uIP TCP connection. More...

struct  uip_stats
 The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1. More...

struct  uip_udp_conn
 Representation of a uIP UDP connection. More...


Functions

void uip_init (void)
 uIP initialization function.

uip_udp_connuip_udp_new (u16_t *ripaddr, u16_t rport)
 Set up a new UDP connection.

void uip_unlisten (u16_t port)
 Stop listening to the specified port.

void uip_listen (u16_t port)
 Start listening to the specified port.

u16_t htons (u16_t val)
 Convert 16-bit quantity from host byte order to network byte order.


Variables

volatile u8_tuip_appdata
 Pointer to the application data in the packet buffer.

uip_stats uip_stat
 The uIP TCP/IP statistics.

u8_t uip_buf [UIP_BUFSIZE+2]
 The uIP packet buffer.

-volatile u8_t uip_acc32 [4]
 4-byte array used for the 32-bit sequence number calculations.

-


Function Documentation

-

- - - - -
- - - - - - - - - - -
u16_t htons u16_t  val  ) 
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - - - - - - - -
void uip_init void   ) 
-
- - - - - -
-   - - -

-uIP initialization function. -

-This function should be called at boot up to initilize the uIP TCP/IP stack.

-

- - - - -
- - - - - - - - - - -
void uip_listen u16_t  port  ) 
-
- - - - - -
-   - - -

-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.
-
 uip_listen(HTONS(80)); 
-

-

Parameters:
- - -
port A 16-bit port number in network byte order.
-
-
-

- - - - -
- - - - - - - - - - - - - - - - - - - -
struct uip_udp_conn* uip_udp_new u16_t ripaddr,
u16_t  rport
-
- - - - - -
-   - - -

-Set up a new UDP connection. -

-

Parameters:
- - - -
ripaddr A pointer to a 4-byte structure representing the IP address of the remote host.
rport The remote port number in network byte order.
-
-
Returns:
The uip_udp_conn structure for the new connection or NULL if no connection could be allocated.
-
-

- - - - -
- - - - - - - - - - -
void uip_unlisten 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.
-

-

Parameters:
- - -
port A 16-bit port number in network byte order.
-
-
-


Variable Documentation

-

- - - - -
- - -
volatile u8_t* uip_appdata -
-
- - - - - -
-   - - -

-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().

-

- - - - -
- - -
u8_t uip_buf[UIP_BUFSIZE+2] -
-
- - - - - -
-   - - -

-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:
 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);
- }
-
-
-

- - - - -
- - -
struct uip_stats uip_stat -
-
- - - - - -
-   - - -

-The uIP TCP/IP statistics. -

-This is the variable in which the uIP TCP/IP statistics are gathered.

-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00076.html b/doc/html/a00076.html deleted file mode 100644 index 5bfedb8..0000000 --- a/doc/html/a00076.html +++ /dev/null @@ -1,269 +0,0 @@ - - -uIP 0.9: Example applications - - - - -

Example applications


Detailed Description

-The uIP distribution contains a number of example applications that can be either used directory or studied when learning to develop applications for uIP. -

- - - - - - - -

-

- - - -

-

- - - - - - - - - - - - - - - - - - - - - - - - - -

Files

file  memb.c
 Memory block allocation routines.

file  memb.h
 Memory block allocation routines.


Modules

Web client
SMTP E-mail sender
Telnet server
Web server

Defines

#define MEMB(name, size, num)
 Declare a memory block.


Functions

void memb_init (struct memb_blocks *m)
 Initialize a memory block that was declared with MEMB().

char * memb_alloc (struct memb_blocks *m)
 Allocate a memory block from a block of memory declared with MEMB().

char memb_ref (struct memb_blocks *m, char *ptr)
 Increase the reference count for a memory chunk.

char memb_free (struct memb_blocks *m, char *ptr)
 Deallocate a memory block from a memory block previously declared with MEMB().

-


Define Documentation

-

- - - - -
- - - - - - - - - - - - - -
#define MEMBname,
size,
num   )  -
-
- - - - - -
-   - - -

-Value:

static char memb_mem[(size + 1) * num]; \
-        static struct memb_blocks name = {size, num, memb_mem}
-
Declare a memory block. -

-

Parameters:
- - - - -
name The name of the memory block (later used with memb_init(), memb_alloc() and memb_free()).
size The size of each memory chunk, in bytes.
num The total number of memory chunks in the block.
-
-
-


Function Documentation

-

- - - - -
- - - - - - - - - - -
char* memb_alloc struct memb_blocks *  m  ) 
-
- - - - - -
-   - - -

-Allocate a memory block from a block of memory declared with MEMB(). -

-

Parameters:
- - -
m A memory block previosly declared with MEMB().
-
-
-

- - - - -
- - - - - - - - - - - - - - - - - - - -
char memb_free struct memb_blocks *  m,
char *  ptr
-
- - - - - -
-   - - -

-Deallocate a memory block from a memory block previously declared with MEMB(). -

-

Parameters:
- - - -
m m A memory block previosly declared with MEMB().
ptr A pointer to the memory block that is to be deallocated.
-
-
Returns:
The new reference count for the memory block (should be 0 if successfully deallocated) or -1 if the pointer "ptr" did not point to a legal memory block.
-
-

- - - - -
- - - - - - - - - - -
void memb_init struct memb_blocks *  m  ) 
-
- - - - - -
-   - - -

-Initialize a memory block that was declared with MEMB(). -

-

Parameters:
- - -
m A memory block previosly declared with MEMB().
-
-
-

- - - - -
- - - - - - - - - - - - - - - - - - - -
char memb_ref struct memb_blocks *  m,
char *  ptr
-
- - - - - -
-   - - -

-Increase the reference count for a memory chunk. -

-

Note:
No sanity checks are currently made.
-
Parameters:
- - - -
m m A memory block previosly declared with MEMB().
ptr A pointer to the memory chunk for which the reference count should be increased.
-
-
Returns:
The new reference count.
-
-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00077.html b/doc/html/a00077.html index 6ad8ec3..824f439 100644 --- a/doc/html/a00077.html +++ b/doc/html/a00077.html @@ -1,287 +1,78 @@ - + -uIP 0.9: uIP configuration functions +uIP 1.0: dhcpc_state Struct Reference + - - -

uIP configuration functions
- -[The uIP TCP/IP stack] -


Detailed Description

-The uIP configuration functions are used for setting run-time parameters in uIP such as IP addresses. + + + +

dhcpc_state Struct Reference


Detailed Description

+
Examples:
+

- +dhcpc.c, and dhcpc.h. +

+ +

+Definition at line 39 of file dhcpc.h.

- - + + - - + - - + - - + - - + - - + - - + - -

Defines

#define uip_sethostaddr(addr)

Data Fields

+pt pt
 Set the IP address of this host.

#define uip_gethostaddr(addr)
+char state
 Get the IP address of this host.

#define uip_setdraddr(addr)
+uip_udp_connconn
 Set the default router's IP address.

#define uip_setnetmask(addr)
+timer timer
 Set the netmask.

#define uip_getdraddr(addr)
+u16_t ticks
 Get the default router's IP address.

#define uip_getnetmask(addr)
+const void * mac_addr
 Get the netmask.

#define uip_setethaddr(eaddr)
+int mac_len
 Specifiy the Ethernet MAC address.

-


Define Documentation

-

- - - - -
- - - - - - - -
#define uip_getdraddraddr   )  -
-
- - - - -

-Get the default router's IP address. -

-

Parameters:
-
-   - +
+u8_t serverid [4]
- -
addr A pointer to a 4-byte array that will be filled in with the IP address of the default router.
-

-
-

- - - - -
- - - - - - - -
#define uip_gethostaddraddr   )  -
-
- - - - -

-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.

-

Parameters:
-
-   - +
+u16_t lease_time [2]
- -
addr A pointer to a 4-byte array that will be filled in with the currently configured IP address.
- - - - -

- - - - -
- - - - - - - -
#define uip_getnetmaskaddr   )  -
-
- - - - -

-Get the netmask. -

-

Parameters:
-
-   - +
+u16_t ipaddr [2]
- -
addr A pointer to a 4-byte array that will be filled in with the value of the netmask.
- - - - -

- - - - -
- - - - - - - -
#define uip_setdraddraddr   )  -
-
- - - - -

-Set the default router's IP address. -

-

Parameters:
-
-   - +
+u16_t netmask [2]
- -
addr A pointer to a 4-byte array containing the IP address of the default router.
- - - - -

- - - - -
- - - - - - - -
#define uip_setethaddreaddr   )  -
-
- - - - -

-Specifiy the Ethernet MAC address. -

-The ARP code needs to know the MAC address of the Ethernet card in order to be able to respond to ARP queries and to generate working Ethernet headers.

-

Note:
This macro only specifies the Ethernet MAC address to the ARP code. It cannot be used to change the MAC address of the Ethernet card.
-
Parameters:
-
-   - +
+u16_t dnsaddr [2]
- -
eaddr A pointer to a struct uip_eth_addr containing the Ethernet MAC address of the Ethernet card.
- - - - -

- - - - -
- - - - - - - -
#define uip_sethostaddraddr   )  -
-
- - - - -

-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.

-

Parameters:
-
-   - +
+u16_t default_router [2]
- -
addr A pointer to a 4-byte representation of the IP address.
- - - -

- - - - -
- - - - - - - -
#define uip_setnetmaskaddr   )  -
-
- - - - - -
-   - - -

-Set the netmask. -

-

Parameters:
- - -
addr A pointer to a 4-byte array containing the IP address of the netmask.
-
-
-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00078.html b/doc/html/a00078.html index 92b7416..ef60451 100644 --- a/doc/html/a00078.html +++ b/doc/html/a00078.html @@ -1,58 +1,51 @@ - + -uIP 0.9: uIP initialization functions +uIP 1.0: hello_world_state Struct Reference + - - -

uIP initialization functions
+ + + +

hello_world_state Struct Reference
-[The uIP TCP/IP stack] -


Detailed Description

-The uIP initialization functions are used for booting uIP. +[Hello, world] +

Detailed Description

+
Examples:
+

- +hello-world.c, and hello-world.h. +

+ +

+Definition at line 36 of file hello-world.h.

- - + + - -

Functions

void uip_init (void)

Data Fields

+psock p
 uIP initialization function.

-


Function Documentation

-

- - - - -
- - - - - - - - - + -
void uip_init void   ) 
+char inputbuffer [10]
-
- - - - -

-uIP initialization function. -

-This function should be called at boot up to initilize the uIP TCP/IP stack. -

-   - +
+char name [40]
-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00079.html b/doc/html/a00079.html index 7324265..2701b54 100644 --- a/doc/html/a00079.html +++ b/doc/html/a00079.html @@ -1,303 +1,45 @@ - + -uIP 0.9: uIP device driver functions +uIP 1.0: httpd_cgi_call Struct Reference + - - -

uIP device driver functions
+ + + +

httpd_cgi_call Struct Reference
-[The uIP TCP/IP stack] -


Detailed Description

-These functions are used by a network device driver for interacting with uIP. +[Web server] +

Detailed Description

+

- + +

+Definition at line 60 of file httpd-cgi.h.

- - + + - - + - - - - - - - - - - - - - -

Defines

#define uip_input()

Data Fields

+const char * name
 Process an incoming packet.

#define uip_periodic(conn)
+const httpd_cgifunction function
 Periodic processing for a connection identified by its number.

#define uip_periodic_conn(conn)
 Periodic processing for a connection identified by a pointer to its structure.

#define uip_udp_periodic(conn)
 Periodic processing for a UDP connection identified by its number.

#define uip_udp_periodic_conn(conn)
 Periodic processing for a UDP connection identified by a pointer to its structure.


Variables

u8_t uip_buf [UIP_BUFSIZE+2]
 The uIP packet buffer.

-


Define Documentation

-

- - - - -
- - - - -  - - -
#define uip_input  )  -
-
- - - - - -
-   - - -

-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.

  uip_len = devicedriver_poll();
-  if(uip_len > 0) {
-    uip_input();
-    if(uip_len > 0) {
-      devicedriver_send();
-    }
-  }
-

-

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:
  #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();
-      }
-    }
-
-
-

- - - - -
- - - - - - - -
#define uip_periodicconn   )  -
-
- - - - - -
-   - - -

-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:

  for(i = 0; i < UIP_CONNS; ++i) {
-    uip_periodic(i);
-    if(uip_len > 0) {
-      devicedriver_send();
-    }
-  }
-

-

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:
  for(i = 0; i < UIP_CONNS; ++i) {
-    uip_periodic(i);
-    if(uip_len > 0) {
-      uip_arp_out();
-      ethernet_devicedriver_send();
-    }
-  }
-
-
Parameters:
- - -
conn The number of the connection which is to be periodically polled.
-
-
-

- - - - -
- - - - - - - -
#define uip_periodic_connconn   )  -
-
- - - - - -
-   - - -

-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.

-

Parameters:
- - -
conn A pointer to the uip_conn struct for the connection to be processed.
-
-
-

- - - - -
- - - - - - - -
#define uip_udp_periodicconn   )  -
-
- - - - - -
-   - - -

-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:

  for(i = 0; i < UIP_UDP_CONNS; i++) {
-    uip_udp_periodic(i);
-    if(uip_len > 0) {
-      devicedriver_send();
-    }
-  }   
-

-

Note:
As for the uip_periodic() function, special care has to be taken when using uIP together with ARP and Ethernet:
  for(i = 0; i < UIP_UDP_CONNS; i++) {
-    uip_udp_periodic(i);
-    if(uip_len > 0) {
-      uip_arp_out();
-      ethernet_devicedriver_send();
-    }
-  }   
-
-
Parameters:
- - -
conn The number of the UDP connection to be processed.
-
-
-

- - - - -
- - - - - - - -
#define uip_udp_periodic_connconn   )  -
-
- - - - - -
-   - - -

-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.

-

Parameters:
- - -
conn A pointer to the uip_udp_conn struct for the connection to be processed.
-
-
-


Variable Documentation

-

- - - - -
- - -
u8_t uip_buf[UIP_BUFSIZE+2] -
-
- - - - - -
-   - - -

-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:
 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);
- }
-
-
-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00080.html b/doc/html/a00080.html index b450f87..737ea13 100644 --- a/doc/html/a00080.html +++ b/doc/html/a00080.html @@ -1,827 +1,69 @@ - + -uIP 0.9: uIP application functions +uIP 1.0: httpd_state Struct Reference + - - -

uIP application functions
- -[The uIP TCP/IP stack] -


Detailed Description

-Functions used by an application running of top of uIP. + + + +

httpd_state Struct Reference


Detailed Description

+

- + +

+Definition at line 41 of file httpd.h.

- - + + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Defines

#define uip_send(data, len)

Data Fields

+unsigned char timer
 Send data on the current connection.

#define uip_datalen()
+psock sin sout
 The length of any incoming data that is currently avaliable (if avaliable) in the uip_appdata buffer.

#define uip_urgdatalen()
+pt outputpt scriptpt
 The length of any out-of-band data (urgent data) that has arrived on the connection.

#define uip_close()
+char inputbuf [50]
 Close the current connection.

#define uip_abort()
+char filename [20]
 Abort the current connection.

#define uip_stop()
+char state
 Tell the sending host to stop sending data.

-#define uip_stopped(conn)
+httpd_fs_file file
 Find out if the current connection has been previously stopped with uip_stop().

#define uip_restart()
+int len
 Restart the current connection, if is has previously been stopped with uip_stop().

#define uip_newdata()
+char * scriptptr
 Is new incoming data available?

#define uip_acked()
+int scriptlen
 Has previously sent data been acknowledged?

#define uip_connected()
+unsigned short count
 Has the connection just been connected?

#define uip_closed()
 Has the connection been closed by the other end?

#define uip_aborted()
 Has the connection been aborted by the other end?

#define uip_timedout()
 Has the connection timed out?

#define uip_rexmit()
 Do we need to retransmit previously data?

#define uip_poll()
 Is the connection being polled by uIP?

-#define uip_initialmss()
 Get the initial maxium segment size (MSS) of the current connection.

#define uip_mss()
 Get the current maxium segment size that can be sent on the current connection.

#define uip_udp_remove(conn)
 Removed a UDP connection.

#define uip_udp_send(len)
 Send a UDP datagram of length len on the current connection.


Functions

void uip_listen (u16_t port)
 Start listening to the specified port.

void uip_unlisten (u16_t port)
 Stop listening to the specified port.

uip_connuip_connect (u16_t *ripaddr, u16_t port)
 Connect to a remote host using TCP.

uip_udp_connuip_udp_new (u16_t *ripaddr, u16_t rport)
 Set up a new UDP connection.

-


Define Documentation

-

- - - - -
- - - - -  - - -
#define uip_abort  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - -  - - -
#define uip_aborted  )  -
-
- - - - - -
-   - - -

-Has the connection been aborted by the other end? -

-Non-zero if the current connection has been aborted (reset) by the remote host.

-

- - - - -
- - - - -  - - -
#define uip_acked  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - -  - - -
#define uip_close  )  -
-
- - - - - -
-   - - -

-Close the current connection. -

-This function will close the current connection in a nice way.

-

- - - - -
- - - - -  - - -
#define uip_closed  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - -  - - -
#define uip_connected  )  -
-
- - - - - -
-   - - -

-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()).

-

- - - - -
- - - - -  - - -
#define uip_datalen  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - -  - - -
#define uip_mss  )  -
-
- - - - - -
-   - - -

-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()).

-

- - - - -
- - - - -  - - -
#define uip_newdata  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - -  - - -
#define uip_poll  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - -  - - -
#define uip_restart  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - -  - - -
#define uip_rexmit  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - - - - - - - -
#define uip_senddata,
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.
-
Parameters:
- - - -
data A pointer to the data which is to be sent.
len The maximum amount of data bytes to be sent.
-
-
-

- - - - -
- - - - -  - - -
#define uip_stop  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - -  - - -
#define uip_timedout  )  -
-
- - - - - -
-   - - -

-Has the connection timed out? -

-Non-zero if the current connection has been aborted due to too many retransmissions.

-

- - - - -
- - - - - - - -
#define uip_udp_removeconn   )  -
-
- - - - - -
-   - - -

-Removed a UDP connection. -

-

Parameters:
- - -
conn A pointer to the uip_udp_conn structure for the connection.
-
-
-

- - - - -
- - - - - - - -
#define uip_udp_sendlen   )  -
-
- - - - - -
-   - - -

-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.

-

Parameters:
- - -
len The length of the data in the uip_buf buffer.
-
-
-

- - - - -
- - - - -  - - -
#define uip_urgdatalen  )  -
-
- - - - - -
-   - - -

-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.
-
-


Function Documentation

-

- - - - -
- - - - - - - - - - - - - - - - - - - -
struct uip_conn* uip_connect u16_t ripaddr,
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.

-Since this function requires the port number to be in network byte order, a convertion using HTONS() or htons() is necessary.

-
 u16_t ipaddr[2];
-
- uip_ipaddr(ipaddr, 192,168,1,2);
- uip_connect(ipaddr, HTONS(80)); 
-

-

Parameters:
- - - -
ripaddr A pointer to a 4-byte array representing the IP address of the remote hot.
port A 16-bit port number in network byte order.
-
-
Returns:
A pointer to the uIP connection identifier for the new connection, or NULL if no connection could be allocated.
-
-

- - - - -
- - - - - - - - - - -
void uip_listen u16_t  port  ) 
-
- - - - - -
-   - - -

-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.
-
 uip_listen(HTONS(80)); 
-

-

Parameters:
- - -
port A 16-bit port number in network byte order.
-
-
-

- - - - -
- - - - - - - - - - - - - - - - - - - -
struct uip_udp_conn* uip_udp_new u16_t ripaddr,
u16_t  rport
-
- - - - - -
-   - - -

-Set up a new UDP connection. -

-

Parameters:
- - - -
ripaddr A pointer to a 4-byte structure representing the IP address of the remote host.
rport The remote port number in network byte order.
-
-
Returns:
The uip_udp_conn structure for the new connection or NULL if no connection could be allocated.
-
-

- - - - -
- - - - - - - - - - -
void uip_unlisten 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.
-

-

Parameters:
- - -
port A 16-bit port number in network byte order.
-
-
-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00081.html b/doc/html/a00081.html index ea60ddb..821207b 100644 --- a/doc/html/a00081.html +++ b/doc/html/a00081.html @@ -1,149 +1,51 @@ - + -uIP 0.9: uIP conversion functions +uIP 1.0: memb_blocks Struct Reference + - - -

uIP conversion functions
+ + + +

memb_blocks Struct Reference
-[The uIP TCP/IP stack] -


Detailed Description

-These functions can be used for converting between different data formats used by uIP. +[Memory block management functions] +

Detailed Description

+

- + +

+Definition at line 105 of file memb.h.

- - + + - - + - - - + + + -

Defines

#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)

Data Fields

+unsigned short size
 Pack an IP address into a 4-byte array which is used by uIP to represent IP addresses.

#define HTONS(n)
+unsigned short num
 Convert 16-bit quantity from host byte order to network byte order.


Functions

u16_t htons (u16_t val)
+char * count
+void * mem
 Convert 16-bit quantity from host byte order to network byte order.

-


Define Documentation

-

- - - - -
- - - - - - - -
#define HTONS  )  -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - - - - - - - - - - - - - - - - - - -
#define uip_ipaddraddr,
addr0,
addr1,
addr2,
addr3   )  -
-
- - - - - -
-   - - -

-Pack an IP address into a 4-byte array which is used by uIP to represent IP addresses. -

-Example:

 u16_t ipaddr[2];
-
- uip_ipaddr(&ipaddr, 192,168,1,2); 
-

-

Parameters:
- - - - - - -
addr A pointer to a 4-byte array that will be filled in with the IP addres.
addr0 The first octet of the IP address.
addr1 The second octet of the IP address.
addr2 The third octet of the IP address.
addr3 The forth octet of the IP address.
-
-
-


Function Documentation

-

- - - - -
- - - - - - - - - - -
u16_t htons u16_t  val  ) 
-
- - - - - -
-   - - -

-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.

-


Generated on Tue Oct 7 15:51:43 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00082.html b/doc/html/a00082.html index 531c7e2..0da540d 100644 --- a/doc/html/a00082.html +++ b/doc/html/a00082.html @@ -1,213 +1,73 @@ - + -uIP 0.9: Architecture specific uIP functions +uIP 1.0: psock Struct Reference + - - -

Architecture specific uIP functions
+ + + +

psock Struct Reference
-[The uIP TCP/IP stack] -


Detailed Description

-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. +[Protosockets library] +#include <psock.h>

- +

Detailed Description

+The representation of a protosocket. +

+The protosocket structrure is an opaque structure with no user-visible elements.

Examples:
+ +

+hello-world.h.

+

+ +

+Definition at line 106 of file psock.h.

- - + + - + -

-

- + - - + - - + - - + - - - + + + + + -

Files

file  uip_arch.h

Data Fields

+pt pt psockpt
 Declarations of architecture specific functions.

+const u8_tsendptr

Functions

void uip_add32 (u8_t *op32, u16_t op16)
+u8_treadptr
 Carry out a 32-bit addition.

u16_t uip_chksum (u16_t *buf, u16_t len)
+char * bufptr
 Calculate the Internet checksum over a buffer.

u16_t uip_ipchksum (void)
+u16_t sendlen
 Calculate the IP header checksum of the packet header in uip_buf.

u16_t uip_tcpchksum (void)
+u16_t readlen
 Calculate the TCP checksum of the packet in uip_buf and uip_appdata.


Variables

-volatile u8_t uip_acc32 [4]
+psock_buf buf
+unsigned int bufsize
+unsigned char state
 4-byte array used for the 32-bit sequence number calculations.

-


Function Documentation

-

- - - - -
- - - - - - - - - - - - - - - - - - - -
void uip_add32 u8_t op32,
u16_t  op16
-
- - - - - -
-   - - -

-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).
-
Parameters:
- - - -
op32 A pointer to a 4-byte array representing a 32-bit integer in network byte order (big endian).
op16 A 16-bit integer in host byte order.
-
-
-

- - - - -
- - - - - - - - - - - - - - - - - - - -
u16_t uip_chksum u16_t buf,
u16_t  len
-
- - - - - -
-   - - -

-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.
-
Parameters:
- - - -
buf A pointer to the buffer over which the checksum is to be computed.
len The length of the buffer over which the checksum is to be computed.
-
-
Returns:
The Internet checksum of the buffer.
-
-

- - - - -
- - - - - - - - - - -
u16_t uip_ipchksum void   ) 
-
- - - - - -
-   - - -

-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.

-

Returns:
The IP header checksum of the IP header in the uip_buf buffer.
-
-

- - - - -
- - - - - - - - - - -
u16_t uip_tcpchksum 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.
-
Returns:
The TCP checksum of the TCP segment in uip_buf and pointed to by uip_appdata.
-
-


Generated on Tue Oct 7 15:51:44 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00083.html b/doc/html/a00083.html index 12db106..2cfc033 100644 --- a/doc/html/a00083.html +++ b/doc/html/a00083.html @@ -1,190 +1,45 @@ - + -uIP 0.9: uIP Address Resolution Protocol +uIP 1.0: psock_buf Struct Reference + - - -

uIP Address Resolution Protocol
+ + + +

psock_buf Struct Reference
-[The uIP TCP/IP stack] -


Detailed Description

-The Address Resolution Protocol ARP is used for mapping between IP addresses and link level addresses such as the Ethernet MAC addresses. ARP uses broadcast queries to ask for the link level address of a known IP address and the host which is configured with the IP address for which the query was meant, will respond with its link level address.

-

Note:
This ARP implementation only supports Ethernet.
+[Protosockets library] +

Detailed Description

- + +

+Definition at line 95 of file psock.h.

- - + + - + -

-

- - - -

-

- - - - - - - - - - - - - - - - - - - - - -

Files

file  uip_arp.c

Data Fields

+u8_tptr
 Implementation of the ARP Address Resolution Protocol.

+unsigned short left
file  uip_arp.h
 Macros and definitions for the ARP module.


Data Structures

struct  uip_eth_addr
 Representation of a 48-bit Ethernet address. More...

struct  uip_eth_hdr
 The Ethernet header. More...


Functions

-void uip_arp_init (void)
 Initialize the ARP module.

void uip_arp_ipin (void)
 ARP processing for incoming IP packets.

void uip_arp_arpin (void)
 ARP processing for incoming ARP packets.

void uip_arp_out (void)
 Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request.

void uip_arp_timer (void)
 Periodic ARP processing function.

-


Function Documentation

-

- - - - -
- - - - - - - - - - -
void uip_arp_arpin void   ) 
-
- - - - - -
-   - - -

-ARP processing for incoming ARP packets. -

-This function should be called by the device driver when an ARP packet has been received. The function will act differently depending on the ARP packet type: if it is a reply for a request that we previously sent out, the ARP cache will be filled in with the values from the ARP reply. If the incoming ARP packet is an ARP request for our IP address, an ARP reply packet is created and put into the uip_buf[] buffer.

-When the function returns, the value of the global variable uip_len indicates whether the device driver should send out a packet or not. If uip_len is zero, no packet should be sent. If uip_len is non-zero, it contains the length of the outbound packet that is present in the uip_buf[] buffer.

-This function expects an ARP packet with a prepended Ethernet header in the uip_buf[] buffer, and the length of the packet in the global variable uip_len.

-

- - - - -
- - - - - - - - - - -
void uip_arp_ipin void   ) 
-
- - - - - -
-   - - -

-ARP processing for incoming IP packets. -

-This function should be called by the device driver when an IP packet has been received. The function will check if the address is in the ARP cache, and if so the ARP cache entry will be refreshed. If no ARP cache entry was found, a new one is created.

-This function expects an IP packet with a prepended Ethernet header in the uip_buf[] buffer, and the length of the packet in the global variable uip_len.

-

- - - - -
- - - - - - - - - - -
void uip_arp_out void   ) 
-
- - - - - -
-   - - -

-Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request. -

-This function should be called before sending out an IP packet. The function checks the destination IP address of the IP packet to see what Ethernet MAC address that should be used as a destination MAC address on the Ethernet.

-If the destination IP address is in the local network (determined by logical ANDing of netmask and our IP address), the function checks the ARP cache to see if an entry for the destination IP address is found. If so, an Ethernet header is prepended and the function returns. If no ARP cache entry is found for the destination IP address, the packet in the uip_buf[] is replaced by an ARP request packet for the IP address. The IP packet is dropped and it is assumed that they higher level protocols (e.g., TCP) eventually will retransmit the dropped packet.

-If the destination IP address is not on the local network, the IP address of the default router is used instead.

-When the function returns, a packet is present in the uip_buf[] buffer, and the length of the packet is in the global variable uip_len.

-

- - - - -
- - - - - - - - - - -
void uip_arp_timer void   ) 
-
- - - - - -
-   - - -

-Periodic ARP processing function. -

-This function performs periodic timer processing in the ARP module and should be called at regular intervals. The recommended interval is 10 seconds between the calls.

-


Generated on Tue Oct 7 15:51:44 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00084.html b/doc/html/a00084.html index 56d946c..7a7741f 100644 --- a/doc/html/a00084.html +++ b/doc/html/a00084.html @@ -1,239 +1,45 @@ - + -uIP 0.9: Serial Line IP (SLIP) protocol +uIP 1.0: pt Struct Reference + - - -

Serial Line IP (SLIP) protocol
+ + + +

pt Struct Reference
-[The uIP TCP/IP stack] -


Detailed Description

-The SLIP protocol is a very simple way to transmit IP packets over a serial line. It does not provide any framing or error control, and is therefore not very widely used today.

-This SLIP implementation requires two functions for accessing the serial device: slipdev_char_poll() and slipdev_char_put(). These must be implemented specifically for the system on which the SLIP protocol is to be run. +[Protothreads] +


Detailed Description

+
Examples:
+

- +dhcpc.h. +

+ +

+Definition at line 54 of file pt.h.

- - + + - - -

-

- - - -

-

- - - - - - - - - - - - - - -

Files

file  slipdev.c

Data Fields

+lc_t lc
 SLIP protocol implementation.

file  slipdev.h
 SLIP header file.


Functions

void slipdev_char_put (u8_t c)
 Put a character on the serial device.

u8_t slipdev_char_poll (u8_t *c)
 Poll the serial device for a character.

void slipdev_init (void)
 Initialize the SLIP module.

void slipdev_send (void)
 Send the packet in the uip_buf and uip_appdata buffers using the SLIP protocol.

u16_t slipdev_poll (void)
 Poll the SLIP device for an available packet.

-


Function Documentation

-

- - - - -
- - - - - - - - - - -
u8_t slipdev_char_poll u8_t c  ) 
-
- - - - - -
-   - - -

-Poll the serial device for a character. -

-This function is used by the SLIP implementation to poll the serial device for a character. It must be implemented specifically for the system on which the SLIP implementation is to be run.

-The function should return immediately regardless if a character is available or not. If a character is available it should be placed at the memory location pointed to by the pointer supplied by the arguement c.

-

Parameters:
- - -
c A pointer to a byte that is filled in by the function with the received character, if available.
-
-
Return values:
- - - -
0 If no character is available.
Non-zero If a character is available.
-
-
-

- - - - -
- - - - - - - - - - -
void slipdev_char_put u8_t  c  ) 
-
- - - - - -
-   - - -

-Put a character on the serial device. -

-This function is used by the SLIP implementation to put a character on the serial device. It must be implemented specifically for the system on which the SLIP implementation is to be run.

-

Parameters:
- - -
c The character to be put on the serial device.
-
-
-

- - - - -
- - - - - - - - - - -
void slipdev_init void   ) 
-
- - - - - -
-   - - -

-Initialize the SLIP module. -

-This function does not initialize the underlying RS232 device, but only the SLIP part.

-

- - - - -
- - - - - - - - - - -
u16_t slipdev_poll void   ) 
-
- - - - - -
-   - - -

-Poll the SLIP device for an available packet. -

-This function will poll the SLIP device to see if a packet is available. It uses a buffer in which all avaliable bytes from the RS232 interface are read into. When a full packet has been read into the buffer, the packet is copied into the uip_buf buffer and the length of the packet is returned.

-

Returns:
The length of the packet placed in the uip_buf buffer, or zero if no packet is available.
-
- -

-Here is the call graph for this function:

- - - -

- - - - -
- - - - - - - - - - -
void slipdev_send void   ) 
-
- - - - - -
-   - - -

-Send the packet in the uip_buf and uip_appdata buffers using the SLIP protocol. -

-The first 40 bytes of the packet (the IP and TCP headers) are read from the uip_buf buffer, and the following bytes (the application data) are read from the uip_appdata buffer.

- -

-Here is the call graph for this function:

- - - -
Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00084_a8_cgraph.png b/doc/html/a00084_a8_cgraph.png deleted file mode 100644 index a5575ec..0000000 Binary files a/doc/html/a00084_a8_cgraph.png and /dev/null differ diff --git a/doc/html/a00084_a9_cgraph.png b/doc/html/a00084_a9_cgraph.png deleted file mode 100644 index ba1cb6b..0000000 Binary files a/doc/html/a00084_a9_cgraph.png and /dev/null differ diff --git a/doc/html/a00085.html b/doc/html/a00085.html index 8966abe..4226e0e 100644 --- a/doc/html/a00085.html +++ b/doc/html/a00085.html @@ -1,44 +1,69 @@ - + -uIP 0.9: Configuration options for uIP +uIP 1.0: smtp_state Struct Reference + - - -

Configuration options for uIP


Detailed Description

-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. + + + +

smtp_state Struct Reference
+ +[SMTP E-mail sender] +


Detailed Description

+
Examples:
+

- +hello-world.h, smtp.c, and smtp.h. +

+ +

+Definition at line 81 of file smtp.h.

- - + + - + -

-

- + - + - + - + - + - + - - - - - +

Files

file  uipopt.h

Data Fields

+u8_t state
 Configuration options for uIP.

+char * to

Modules

uIP type definitions
+char * from
Static configuration options
+char * subject
IP configuration options
+char * msg
UDP configuration options
+u16_t msglen
TCP configuration options
+u16_t sentlen
ARP configuration options
+u16_t textlen
General configuration options
CPU architecture configuration
Appication specific configurations
+u16_t sendptr
-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00086.html b/doc/html/a00086.html index efd35a0..1611163 100644 --- a/doc/html/a00086.html +++ b/doc/html/a00086.html @@ -1,104 +1,54 @@ - + -uIP 0.9: uIP type definitions +uIP 1.0: telnetd_state Struct Reference + - - -

uIP type definitions
- -[Configuration options for uIP] -

+ + + +

telnetd_state Struct Reference


Detailed Description

+
Examples:
+

- +telnetd.c, and telnetd.h. +

+ +

+Definition at line 49 of file telnetd.h.

- - + + - - + - - + - -

Typedefs

typedef unsigned char u8_t

Data Fields

+char * lines [TELNETD_CONF_NUMLINES]
 The 8-bit unsigned data type.

typedef unsigned short u16_t
+char buf [TELNETD_CONF_LINELEN]
 The 16-bit unsigned data type.

typedef unsigned short uip_stats_t
+char bufptr
 The statistics data type.

-


Typedef Documentation

-

- - - - -
- - -
typedef unsigned short u16_t -
-
- - - - -

-The 16-bit unsigned data type. -

-This may have to be tweaked for your particular compiler. "unsigned short" works for most compilers. - -

-   - +
+u8_t numsent
-

- - - - -
- - -
typedef unsigned char u8_t -
-
- - - - -

-The 8-bit unsigned data type. -

-This may have to be tweaked for your particular compiler. "unsigned char" works for most compilers. -

-   - +
+u8_t state
-

- - - - -
- - -
typedef unsigned short uip_stats_t -
-
- - - - - -
-   - - -

-The statistics data type. -

-This datatype determines how high the statistics counters are able to count.

-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00087.html b/doc/html/a00087.html index 5a3ae33..3b2fec3 100644 --- a/doc/html/a00087.html +++ b/doc/html/a00087.html @@ -1,180 +1,52 @@ - + -uIP 0.9: Static configuration options +uIP 1.0: timer Struct Reference + - - -

Static configuration options
+ + + +

timer Struct Reference
-[Configuration options for uIP] -


Detailed Description

-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. +[Timer library] +#include <timer.h>

- +

Detailed Description

+A timer. +

+This structure is used for declaring a timer. The timer must be set with timer_set() before it can be used.

Examples:
+ +

+dhcpc.h, example-mainloop-with-arp.c, example-mainloop-without-arp.c, and webclient.h.

+

+ +

+Definition at line 74 of file timer.h.

- - + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Defines

#define UIP_FIXEDADDR

Data Fields

+clock_time_t start
 Determines if uIP should use a fixed IP address or not.

#define UIP_PINGADDRCONF
+clock_time_t interval
 Ping IP address asignment.

-#define UIP_IPADDR0
 The first octet of the IP address of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_IPADDR1
 The second octet of the IP address of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_IPADDR2
 The third octet of the IP address of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_IPADDR3
 The fourth octet of the IP address of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_NETMASK0
 The first octet of the netmask of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_NETMASK1
 The second octet of the netmask of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_NETMASK2
 The third octet of the netmask of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_NETMASK3
 The fourth octet of the netmask of this uIP node, if UIP_FIXEDADDR is 1.

-#define UIP_DRIPADDR0
 The first octet of the IP address of the default router, if UIP_FIXEDADDR is 1.

-#define UIP_DRIPADDR1
 The second octet of the IP address of the default router, if UIP_FIXEDADDR is 1.

-#define UIP_DRIPADDR2
 The third octet of the IP address of the default router, if UIP_FIXEDADDR is 1.

-#define UIP_DRIPADDR3
 The fourth octet of the IP address of the default router, if UIP_FIXEDADDR is 1.

#define UIP_FIXEDETHADDR
 Specifies if the uIP ARP module should be compiled with a fixed Ethernet MAC address or not.

-#define UIP_ETHADDR0
 The first octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR1
 The second octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR2
 The third octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR3
 The fourth octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR4
 The fifth octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-#define UIP_ETHADDR5
 The sixth octet of the Ethernet address if UIP_FIXEDETHADDR is 1.

-


Define Documentation

-

- - - - -
- - -
#define UIP_FIXEDADDR -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - -
#define UIP_FIXEDETHADDR -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - -
#define UIP_PINGADDRCONF -
-
- - - - - -
-   - - -

-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.
-
-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00088.html b/doc/html/a00088.html index 83c83d7..7ca46ae 100644 --- a/doc/html/a00088.html +++ b/doc/html/a00088.html @@ -1,83 +1,103 @@ - + -uIP 0.9: IP configuration options +uIP 1.0: uip_conn Struct Reference + - - -

IP configuration options
+ + + +

uip_conn Struct Reference
-[Configuration options for uIP] -

+[The uIP TCP/IP stack] +#include <uip.h>

- +

Detailed Description

+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 type of this field is configured in the "uipopt.h" header file. +

+ +

+Definition at line 1153 of file uip.h.

- - + + - - + + - - + + - -

Defines

#define UIP_TTL   255

Data Fields

+uip_ipaddr_t ripaddr
 The IP TTL (time to live) of IP packets sent by uIP.

#define UIP_REASSEMBLY
 The IP address of the remote host.
+u16_t lport
 Turn on support for IP packet reassembly.

-#define UIP_REASS_MAXAGE   40
 The local TCP port, in network byte order.
+u16_t rport
 The maximum time an IP fragment should wait in the reassembly buffer before it is dropped.

-


Define Documentation

-

- - - - -
- - -
#define UIP_REASSEMBLY -
-
- - - - + -

-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.
- - -
-   - +
 The local remote TCP port, in network byte order.
+u8_t rcv_nxt [4]
-

- - - - -
- - -
#define UIP_TTL   255 -
-
- - - - + -

-The IP TTL (time to live) of IP packets sent by uIP. -

-This should normally not be changed. - +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-   - +
 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.
+uip_tcp_appstate_t appstate
 The application state.
-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00089.html b/doc/html/a00089.html index 24d7327..d935ccd 100644 --- a/doc/html/a00089.html +++ b/doc/html/a00089.html @@ -1,65 +1,44 @@ - + -uIP 0.9: UDP configuration options +uIP 1.0: uip_eth_addr Struct Reference + - - -

UDP configuration options
+ + + +

uip_eth_addr Struct Reference
-[Configuration options for uIP] -


Detailed Description

-
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
+[The uIP TCP/IP stack] +#include <uip.h> +

+


Detailed Description

+Representation of a 48-bit Ethernet address. +

- +Definition at line 1542 of file uip.h.
- - + + - - - - - - - - - -

Defines

-#define UIP_UDP

Data Fields

+u8_t addr [6]
 Toggles wether UDP support should be compiled in or not.

#define UIP_UDP_CHECKSUMS
 Toggles if UDP checksums should be used or not.

-#define UIP_UDP_CONNS
 The maximum amount of concurrent UDP connections.

-#define UIP_UDP_APPCALL
 The name of the function that should be called when UDP datagrams arrive.

-


Define Documentation

-

- - - - -
- - -
#define UIP_UDP_CHECKSUMS -
-
- - - - - -
-   - - -

-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.
-
-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00090.html b/doc/html/a00090.html index c21fe00..ee37ca5 100644 --- a/doc/html/a00090.html +++ b/doc/html/a00090.html @@ -1,293 +1,50 @@ - + -uIP 0.9: TCP configuration options +uIP 1.0: uip_eth_hdr Struct Reference + - - -

TCP configuration options
+ + + +

uip_eth_hdr Struct Reference
-[Configuration options for uIP] -

+[uIP Address Resolution Protocol] +#include <uip_arp.h>

- +

Detailed Description

+The Ethernet header. +

+ +

+Definition at line 63 of file uip_arp.h.

- - + + - - + - - + - - - - - - - - - - - - - - - - - - - - - -

Defines

#define UIP_ACTIVE_OPEN

Data Fields

+uip_eth_addr dest
 Determines if support for opening connections from uIP should be compiled in.

#define UIP_CONNS
+uip_eth_addr src
 The maximum number of simultaneously open TCP connections.

#define UIP_LISTENPORTS
+u16_t type
 The maximum number of simultaneously listening TCP ports.

#define UIP_RECEIVE_WINDOW
 The size of the advertised receiver's window.

#define UIP_URGDATA
 Determines if support for TCP urgent data notification should be compiled in.

#define UIP_RTO   3
 The initial retransmission timeout counted in timer pulses.

#define UIP_MAXRTX   8
 The maximum number of times a segment should be retransmitted before the connection should be aborted.

#define UIP_MAXSYNRTX   3
 The maximum number of times a SYN segment should be retransmitted before a connection request should be deemed to have been unsuccessful.

#define UIP_TCP_MSS   (UIP_BUFSIZE - UIP_LLH_LEN - 40)
 The TCP maximum segment size.

#define UIP_TIME_WAIT_TIMEOUT   120
 How long a connection should stay in the TIME_WAIT state.

-


Define Documentation

-

- - - - -
- - -
#define UIP_ACTIVE_OPEN -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - -
#define UIP_CONNS -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - -
#define UIP_LISTENPORTS -
-
- - - - - -
-   - - -

-The maximum number of simultaneously listening TCP ports. -

-Each listening TCP port requires 2 bytes of memory.

-

- - - - -
- - -
#define UIP_MAXRTX   8 -
-
- - - - - -
-   - - -

-The maximum number of times a segment should be retransmitted before the connection should be aborted. -

-This should not be changed.

-

- - - - -
- - -
#define UIP_MAXSYNRTX   3 -
-
- - - - - -
-   - - -

-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_RECEIVE_WINDOW -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - -
#define UIP_RTO   3 -
-
- - - - - -
-   - - -

-The initial retransmission timeout counted in timer pulses. -

-This should not be changed.

-

- - - - -
- - -
#define UIP_TCP_MSS   (UIP_BUFSIZE - UIP_LLH_LEN - 40) -
-
- - - - - -
-   - - -

-The TCP maximum segment size. -

-This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.

-

- - - - -
- - -
#define UIP_TIME_WAIT_TIMEOUT   120 -
-
- - - - - -
-   - - -

-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_URGDATA -
-
- - - - - -
-   - - -

-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.

-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00091.html b/doc/html/a00091.html index ec24111..63a2a52 100644 --- a/doc/html/a00091.html +++ b/doc/html/a00091.html @@ -1,77 +1,84 @@ - + -uIP 0.9: ARP configuration options +uIP 1.0: uip_icmpip_hdr Struct Reference + - - -

ARP configuration options
+ + + +

uip_icmpip_hdr Struct Reference
-[Configuration options for uIP] -

+[The uIP TCP/IP stack] +

Detailed Description

+

- + +

+Definition at line 1423 of file uip.h.

- - + + - - + - -

Defines

#define UIP_ARPTAB_SIZE

Data Fields

+u8_t vhl
 The size of the ARP table.

#define UIP_ARP_MAXAGE   120
+u8_t tos
 The maxium age of ARP table entries measured in 10ths of seconds.

-


Define Documentation

-

- - - - -
- - -
#define UIP_ARP_MAXAGE   120 -
-
- - - - -

-The maxium age of ARP table entries measured in 10ths of seconds. -

-An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD default). - -

-   - +
+u8_t len [2]
-

- - - - -
- - -
#define UIP_ARPTAB_SIZE -
-
- - - - + + + + + + + + + + + + + + + + + + + + + + -

-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. -

-   - +
+u8_t ipid [2]
+u8_t ipoffset [2]
+u8_t ttl
+u8_t proto
+u16_t ipchksum
+u16_t srcipaddr [2]
+u16_t destipaddr [2]
+u8_t type
+u8_t icode
+u16_t icmpchksum
+u16_t id
+u16_t seqno
-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00092.html b/doc/html/a00092.html index 68a1059..93c00c2 100644 --- a/doc/html/a00092.html +++ b/doc/html/a00092.html @@ -1,167 +1,39 @@ - + -uIP 0.9: General configuration options +uIP 1.0: uip_neighbor_addr Struct Reference + - - -

General configuration options
- -[Configuration options for uIP] -

+ + + +

uip_neighbor_addr Struct Reference


Detailed Description

+

- + +

+Definition at line 47 of file uip-neighbor.h.

- - + + - - - - - - - - - - - - - -

Defines

#define UIP_BUFSIZE

Data Fields

+uip_eth_addr addr
 The size of the uIP packet buffer.

#define UIP_STATISTICS
 Determines if statistics support should be compiled in.

#define UIP_LOGGING
 Determines if logging of certain events should be compiled in.

#define UIP_LLH_LEN
 The link level header length.


Functions

void uip_log (char *msg)
 Print out a uIP log message.

-


Define Documentation

-

- - - - -
- - -
#define UIP_BUFSIZE -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - -
#define UIP_LLH_LEN -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - -
#define UIP_LOGGING -
-
- - - - - -
-   - - -

-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.

-

- - - - -
- - -
#define UIP_STATISTICS -
-
- - - - - -
-   - - -

-Determines if statistics support should be compiled in. -

-The statistics is useful for debugging and to show the user.

-


Function Documentation

-

- - - - -
- - - - - - - - - - -
void uip_log char *  msg  ) 
-
- - - - - -
-   - - -

-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.

-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00093.html b/doc/html/a00093.html index 1d115ab..2d3a91a 100644 --- a/doc/html/a00093.html +++ b/doc/html/a00093.html @@ -1,51 +1,143 @@ - + -uIP 0.9: CPU architecture configuration +uIP 1.0: uip_stats Struct Reference + - - -

CPU architecture configuration
+ + + +

uip_stats Struct Reference
-[Configuration options for uIP] -


Detailed Description

-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. +[The uIP TCP/IP stack] +#include <uip.h>

- +

Detailed Description

+The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1. +

+ +

+Definition at line 1232 of file uip.h.

- - + + - -

Defines

#define BYTE_ORDER

Data Fields

+struct {
 The byte order of the CPU architecture on which uIP is to be run.

-


Define Documentation

-

- - - - -
- - -
#define BYTE_ORDER -
-
- - - - -

-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). - +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-   - +
   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.
+struct {
   uip_stats_t   drop
 Number of dropped UDP segments.
   uip_stats_t   recv
 Number of recived UDP segments.
   uip_stats_t   sent
 Number of sent UDP segments.
   uip_stats_t   chkerr
 Number of UDP segments with a bad checksum.
udp
 UDP statistics.
-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00094.html b/doc/html/a00094.html index 2e6f3c2..7d21f8c 100644 --- a/doc/html/a00094.html +++ b/doc/html/a00094.html @@ -1,44 +1,99 @@ - + -uIP 0.9: Appication specific configurations +uIP 1.0: uip_tcpip_hdr Struct Reference + - - -

Appication specific configurations
+ + + +

uip_tcpip_hdr Struct Reference
-[Configuration options for uIP] -


Detailed Description

-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.

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))
-
+[The uIP TCP/IP stack] +

Detailed Description

+

- + +

+Definition at line 1386 of file uip.h.

- - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -

Defines

-#define UIP_APPCALL   smtp_appcall

Data Fields

+u8_t vhl
 The name of the application function that uIP should call in response to TCP/IP events.

-#define UIP_APPSTATE_SIZE   (sizeof(struct smtp_state))
+u8_t tos
+u8_t len [2]
+u8_t ipid [2]
+u8_t ipoffset [2]
+u8_t ttl
+u8_t proto
+u16_t ipchksum
+u16_t srcipaddr [2]
+u16_t destipaddr [2]
+u16_t srcport
+u16_t destport
+u8_t seqno [4]
+u8_t ackno [4]
+u8_t tcpoffset
+u8_t flags
+u8_t wnd [2]
+u16_t tcpchksum
+u8_t urgp [2]
+u8_t optdata [4]
 The size of the application state that is to be stored in the uip_conn structure.

-


Generated on Tue Oct 7 15:51:45 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00095.html b/doc/html/a00095.html index 2d49f8e..f61d897 100644 --- a/doc/html/a00095.html +++ b/doc/html/a00095.html @@ -1,447 +1,64 @@ - + -uIP 0.9: Web client +uIP 1.0: uip_udp_conn Struct Reference + - - -

Web client
+ + + +

uip_udp_conn Struct Reference
-[Example applications] -


Detailed Description

-This example shows a HTTP client that is able to download web pages and files from web servers. It requires a number of callback functions to be implemented by the module that utilizes the code: webclient_datahandler(), webclient_connected(), webclient_timedout(), webclient_aborted(), webclient_closed(). +[The uIP TCP/IP stack] +#include <uip.h>

- +

Detailed Description

+Representation of a uIP UDP connection.
Examples:
+ +

+dhcpc.h, and resolv.c.

+

+ +

+Definition at line 1210 of file uip.h.

- - + + - + + -

-

+ + - + + -

-

- + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

Files

file  webclient.c

Data Fields

+uip_ipaddr_t ripaddr
 Implementation of the HTTP client.

 The IP address of the remote peer.
+u16_t lport
file  webclient.h
 The local port number in network byte order.
+u16_t rport
 Header file for the HTTP client.

 The remote port number in network byte order.
+u8_t ttl

Functions

void webclient_datahandler (char *data, u16_t len)
 Default time-to-live.
+uip_udp_appstate_t appstate
 Callback function that is called from the webclient code when HTTP data has been received.

void webclient_connected (void)
 Callback function that is called from the webclient code when the HTTP connection has been connected to the web server.

void webclient_timedout (void)
 Callback function that is called from the webclient code if the HTTP connection to the web server has timed out.

void webclient_aborted (void)
 Callback function that is called from the webclient code if the HTTP connection to the web server has been aborted by the web server.

void webclient_closed (void)
 Callback function that is called from the webclient code when the HTTP connection to the web server has been closed.

-void webclient_init (void)
 Initialize the webclient module.

unsigned char webclient_get (char *host, u16_t port, char *file)
 Open an HTTP connection to a web server and ask for a file using the GET method.

-void webclient_close (void)
 Close the currently open HTTP connection.

char * webclient_mimetype (void)
 Obtain the MIME type of the current HTTP data stream.

char * webclient_filename (void)
 Obtain the filename of the current HTTP data stream.

char * webclient_hostname (void)
 Obtain the hostname of the current HTTP data stream.

unsigned short webclient_port (void)
 Obtain the port number of the current HTTP data stream.

 The application state.
-


Function Documentation

-

- - - - -
- - - - - - - - - - -
void webclient_aborted void   ) 
-
- - - - - -
-   - - -

-Callback function that is called from the webclient code if the HTTP connection to the web server has been aborted by the web server. -

-This function must be implemented by the module that uses the webclient code.

-

- - - - -
- - - - - - - - - - -
void webclient_closed void   ) 
-
- - - - - -
-   - - -

-Callback function that is called from the webclient code when the HTTP connection to the web server has been closed. -

-This function must be implemented by the module that uses the webclient code.

-

- - - - -
- - - - - - - - - - -
void webclient_connected void   ) 
-
- - - - - -
-   - - -

-Callback function that is called from the webclient code when the HTTP connection has been connected to the web server. -

-This function must be implemented by the module that uses the webclient code.

-

- - - - -
- - - - - - - - - - - - - - - - - - - -
void webclient_datahandler char *  data,
u16_t  len
-
- - - - - -
-   - - -

-Callback function that is called from the webclient code when HTTP data has been received. -

-This function must be implemented by the module that uses the webclient code. The function is called from the webclient module when HTTP data has been received. The function is not called when HTTP headers are received, only for the actual data.

-

Note:
This function is called many times, repetedly, when data is being received, and not once when all data has been received.
-
Parameters:
- - - -
data A pointer to the data that has been received.
len The length of the data that has been received.
-
-
-

- - - - -
- - - - - - - - - - -
char* webclient_filename void   ) 
-
- - - - - -
-   - - -

-Obtain the filename of the current HTTP data stream. -

-The filename of an HTTP request may be changed by the web server, and may therefore not be the same as when the original GET request was made with webclient_get(). This function is used for obtaining the current filename.

-

Returns:
A pointer to the current filename.
-
-

- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
unsigned char webclient_get char *  host,
u16_t  port,
char *  file
-
- - - - - -
-   - - -

-Open an HTTP connection to a web server and ask for a file using the GET method. -

-This function opens an HTTP connection to the specified web server and requests the specified file using the GET method. When the HTTP connection has been connected, the webclient_connected() callback function is called and when the HTTP data arrives the webclient_datahandler() callback function is called.

-The callback function webclient_timedout() is called if the web server could not be contacted, and the webclient_aborted() callback function is called if the HTTP connection is aborted by the web server.

-When the HTTP request has been completed and the HTTP connection is closed, the webclient_closed() callback function will be called.

-

Note:
If the function is passed a host name, it must already be in the resolver cache in order for the function to connect to the web server. It is therefore up to the calling module to implement the resolver calls and the signal handler used for reporting a resolv query answer.
-
Parameters:
- - - - -
host A pointer to a string containing either a host name or a numerical IP address in dotted decimal notation (e.g., 192.168.23.1).
port The port number to which to connect, in host byte order.
file A pointer to the name of the file to get.
-
-
Return values:
- - - -
0 if the host name could not be found in the cache, or if a TCP connection could not be created.
1 if the connection was initiated.
-
-
- -

-Here is the call graph for this function:

- - - - - -

- - - - -
- - - - - - - - - - -
char* webclient_hostname void   ) 
-
- - - - - -
-   - - -

-Obtain the hostname of the current HTTP data stream. -

-The hostname of the web server of an HTTP request may be changed by the web server, and may therefore not be the same as when the original GET request was made with webclient_get(). This function is used for obtaining the current hostname.

-

Returns:
A pointer to the current hostname.
-
-

- - - - -
- - - - - - - - - - -
char* webclient_mimetype void   ) 
-
- - - - - -
-   - - -

-Obtain the MIME type of the current HTTP data stream. -

-

Returns:
A pointer to a string contaning the MIME type. The string may be empty if no MIME type was reported by the web server.
-
-

- - - - -
- - - - - - - - - - -
unsigned short webclient_port void   ) 
-
- - - - - -
-   - - -

-Obtain the port number of the current HTTP data stream. -

-The port number of an HTTP request may be changed by the web server, and may therefore not be the same as when the original GET request was made with webclient_get(). This function is used for obtaining the current port number.

-

Returns:
The port number of the current HTTP data stream, in host byte order.
-
-

- - - - -
- - - - - - - - - - -
void webclient_timedout void   ) 
-
- - - - - -
-   - - -

-Callback function that is called from the webclient code if the HTTP connection to the web server has timed out. -

-This function must be implemented by the module that uses the webclient code.

-


Generated on Tue Oct 7 15:51:46 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00095_a20_cgraph.png b/doc/html/a00095_a20_cgraph.png deleted file mode 100644 index 7322043..0000000 Binary files a/doc/html/a00095_a20_cgraph.png and /dev/null differ diff --git a/doc/html/a00096.html b/doc/html/a00096.html index 7ba6d3e..48d6bf3 100644 --- a/doc/html/a00096.html +++ b/doc/html/a00096.html @@ -1,206 +1,81 @@ - + -uIP 0.9: SMTP E-mail sender +uIP 1.0: uip_udpip_hdr Struct Reference + - - -

SMTP E-mail sender
+ + + +

uip_udpip_hdr Struct Reference
-[Example applications] -


Detailed Description

-The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is the standard way of sending and transfering e-mail on the Internet. This simple example implementation is intended as an example of how to implement protocols in uIP, and is able to send out e-mail but has not been extensively tested. +[The uIP TCP/IP stack] +

Detailed Description

+

- + +

+Definition at line 1460 of file uip.h.

- - + + - + -

-

+ - + -

-

- + - - - + - - + - - + + + + + + + + + + + + + -

Files

file  smtp.c

Data Fields

+u8_t vhl
 SMTP example implementation.

+u8_t tos
file  smtp.h
+u8_t len [2]
 SMTP header file.

+u8_t ipid [2]

Defines

-#define SMTP_ERR_OK   0
+u8_t ipoffset [2]
 Error number that signifies a non-error condition.


Functions

void smtp_done (unsigned char error)
+u8_t ttl
 Callback function that is called when an e-mail transmission is done.

void smtp_configure (char *localhostname, u16_t *smtpserver)
+u8_t proto
 Specificy an SMTP server and hostname.

unsigned char smtp_send (char *to, char *from, char *subject, char *msg, u16_t msglen)
+u16_t ipchksum
+u16_t srcipaddr [2]
+u16_t destipaddr [2]
+u16_t srcport
+u16_t destport
+u16_t udplen
+u16_t udpchksum
 Send an e-mail.

-


Function Documentation

-

- - - - -
- - - - - - - - - - - - - - - - - - - -
void smtp_configure char *  lhostname,
u16_t server
-
- - - - - -
-   - - -

-Specificy an SMTP server and hostname. -

-This function is used to configure the SMTP module with an SMTP server and the hostname of the host.

-

Parameters:
- - - -
lhostname The hostname of the uIP host.
server A pointer to a 4-byte array representing the IP address of the SMTP server to be configured.
-
-
-

- - - - -
- - - - - - - - - - -
void smtp_done unsigned char  error  ) 
-
- - - - - -
-   - - -

-Callback function that is called when an e-mail transmission is done. -

-This function must be implemented by the module that uses the SMTP module.

-

Parameters:
- - -
error The number of the error if an error occured, or SMTP_ERR_OK.
-
-
-

- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unsigned char smtp_send char *  to,
char *  from,
char *  subject,
char *  msg,
u16_t  msglen
-
- - - - - -
-   - - -

-Send an e-mail. -

-

Parameters:
- - - - - - -
to The e-mail address of the receiver of the e-mail.
from The e-mail address of the sender of the e-mail.
subject The subject of the e-mail.
msg The actual e-mail message.
msglen The length of the e-mail message.
-
-
- -

-Here is the call graph for this function:

- - - -
Generated on Tue Oct 7 15:51:47 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00096_a23_cgraph.png b/doc/html/a00096_a23_cgraph.png deleted file mode 100644 index f035d2b..0000000 Binary files a/doc/html/a00096_a23_cgraph.png and /dev/null differ diff --git a/doc/html/a00097.html b/doc/html/a00097.html index 3bc3bc2..da7b852 100644 --- a/doc/html/a00097.html +++ b/doc/html/a00097.html @@ -1,344 +1,75 @@ - + -uIP 0.9: Telnet server +uIP 1.0: webclient_state Struct Reference + - - -

Telnet server
+ + + +

webclient_state Struct Reference
-[Example applications] -


Detailed Description

-The uIP telnet server provides a command based interface to uIP. It allows using the "telnet" application to access uIP, and implements the required telnet option negotiation.

-The code is structured in a way which makes it possible to add commands without having to rewrite the main telnet code. The main telnet code calls two callback functions, telnetd_connected() and telnetd_input(), when a telnet connection has been established and when a line of text arrives on a telnet connection. These two functions can be implemented in a way which suits the particular application or environment in which the uIP system is intended to be run.

-The uIP distribution contains an example telnet shell implementation that provides a basic set of commands. +[Web client] +


Detailed Description

+
Examples:
+

- +webclient.c, and webclient.h. +

+ +

+Definition at line 55 of file webclient.h.

- - + + - + -

-

+ - + -

-

+ - + -

-

- + - - - + - - + - - - + - - + - - - - - - - - - - - - -

Files

file  telnetd-shell.c

Data Fields

+u8_t timer
 An example telnet server shell.

+u8_t state
file  telnetd.c
+u8_t httpflag
 Implementation of the Telnet server.

+u16_t port
file  telnetd.h
+char host [40]
 Header file for the telnet server.

+char file [WEBCLIENT_CONF_MAX_URLLEN]

Data Structures

struct  telnetd_state
+u16_t getrequestptr
 A telnet connection structure. More...


Defines

-#define TELNETD_LINELEN
+u16_t getrequestleft
 The maximum length of a telnet line.

-#define TELNETD_NUMLINES
+char httpheaderline [200]
 The number of output lines being buffered for all telnet connections.


Functions

void telnetd_connected (struct telnetd_state *s)
+u16_t httpheaderlineptr
 Callback function that is called when a telnet connection has been established.

void telnetd_input (struct telnetd_state *s, char *cmd)
+char mimetype [32]
 Callback function that is called when a line of text has arrived on a telnet connection.

void telnetd_close (struct telnetd_state *s)
 Close a telnet session.

void telnetd_output (struct telnetd_state *s, char *s1, char *s2)
 Print out a string on a telnet connection.

void telnetd_prompt (struct telnetd_state *s, char *str)
 Print a prompt on a telnet connection.

void telnetd_init (void)
 Initialize the telnet server.

-


Function Documentation

-

- - - - -
- - - - - - - - - - -
void telnetd_close struct telnetd_state s  ) 
-
- - - - - -
-   - - -

-Close a telnet session. -

-This function can be called from a telnet command in order to close the connection.

-

Parameters:
- - -
s The connection which is to be closed.
-
-
-

- - - - -
- - - - - - - - - - -
void telnetd_connected struct telnetd_state s  ) 
-
- - - - - -
-   - - -

-Callback function that is called when a telnet connection has been established. -

-

Parameters:
- - -
s The telnet connection.
-
-
- -

-Here is the call graph for this function:

- - - - -

- - - - -
- - - - - - - - - - -
void telnetd_init void   ) 
-
- - - - - -
-   - - -

-Initialize the telnet server. -

-This function will perform the necessary initializations and start listening on TCP port 23.

- -

-Here is the call graph for this function:

- - - - -

- - - - -
- - - - - - - - - - - - - - - - - - - -
void telnetd_input struct telnetd_state s,
char *  cmd
-
- - - - - -
-   - - -

-Callback function that is called when a line of text has arrived on a telnet connection. -

-

Parameters:
- - - -
s The telnet connection.
cmd The line of text.
-
-
- -

-Here is the call graph for this function:

- - - -

- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
void telnetd_output struct telnetd_state s,
char *  str1,
char *  str2
-
- - - - - -
-   - - -

-Print out a string on a telnet connection. -

-This function can be called from a telnet command parser in order to print out a string of text on the connection. The two strings given as arguments to the function will be concatenated, a carrige return and a new line character will be added, and the line is sent.

-

Parameters:
- - - - -
s The telnet connection.
str1 The first string.
str2 The second string.
-
-
-

- - - - -
- - - - - - - - - - - - - - - - - - - -
void telnetd_prompt struct telnetd_state s,
char *  str
-
- - - - - -
-   - - -

-Print a prompt on a telnet connection. -

-This function can be called by the telnet command shell in order to print out a command prompt.

-

Parameters:
- - - -
s A telnet connection.
str The command prompt.
-
-
-


Generated on Tue Oct 7 15:51:49 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/a00097_a22_cgraph.png b/doc/html/a00097_a22_cgraph.png deleted file mode 100644 index 8343802..0000000 Binary files a/doc/html/a00097_a22_cgraph.png and /dev/null differ diff --git a/doc/html/a00097_a7_cgraph.png b/doc/html/a00097_a7_cgraph.png deleted file mode 100644 index 313b8ba..0000000 Binary files a/doc/html/a00097_a7_cgraph.png and /dev/null differ diff --git a/doc/html/a00097_a8_cgraph.png b/doc/html/a00097_a8_cgraph.png deleted file mode 100644 index c966a62..0000000 Binary files a/doc/html/a00097_a8_cgraph.png and /dev/null differ diff --git a/doc/html/a00098.html b/doc/html/a00098.html deleted file mode 100644 index 1ccf95b..0000000 --- a/doc/html/a00098.html +++ /dev/null @@ -1,174 +0,0 @@ - - -uIP 0.9: Web server - - - - -

Web server
- -[Example applications] -


Detailed Description

-The uIP web server is a very simplistic implementation of an HTTP server. It can serve web pages and files from a read-only ROM filesystem, and provides a very small scripting language.

-The script language is very simple and works as follows. Each script line starts with a command character, either "i", "t", "c", "#" or ".". The "i" command tells the script interpreter to "include" a file from the virtual file system and output it to the web browser. The "t" command should be followed by a line of text that is to be output to the browser. The "c" command is used to call one of the C functions from the httpd-cgi.c file. A line that starts with a "#" is ignored (i.e., the "#" denotes a comment), and the "." denotes the last script line.

-The script that produces the file statistics page looks somewhat like this:

-

i /header.html
-t <h1>File statistics</h1><br><table width="100%">
-t <tr><td><a href="/index.html">/index.html</a></td><td>
-c a /index.html
-t </td></tr> <tr><td><a href="/cgi/files">/cgi/files</a></td><td>
-c a /cgi/files
-t </td></tr> <tr><td><a href="/cgi/tcp">/cgi/tcp</a></td><td>
-c a /cgi/tcp
-t </td></tr> <tr><td><a href="/404.html">/404.html</a></td><td>
-c a /404.html
-t </td></tr></table>
-i /footer.plain
-.
-
-

- - - - - - - -

-

- - - -

-

- - - -

-

- - - -

-

- - - -

-

- - - -

-

- - - - - - - - - - - - - - - - - -

Files

file  cgi.c
 HTTP server script language C functions file.

file  cgi.h
 HTTP script language header file.

file  fs.c
 HTTP server read-only file system code.

file  fs.h
 HTTP server read-only file system header file.

file  httpd.c
 HTTP server.

file  httpd.h
 HTTP server header file.


Data Structures

struct  fs_file
 An open file in the read-only file system. More...


Functions

void httpd_init (void)
 Initialize the web server.

int fs_open (const char *name, struct fs_file *file)
 Open a file in the read-only file system.

-void fs_init (void)
 Initialize the read-only file system.


Variables

-cgifunction cgitab []
 A table containing pointers to C functions that can be called from a web server script.

-


Function Documentation

-

- - - - -
- - - - - - - - - - - - - - - - - - - -
int fs_open const char *  name,
struct fs_file file
-
- - - - - -
-   - - -

-Open a file in the read-only file system. -

-

Parameters:
- - - -
name The name of the file.
file The file pointer, which must be allocated by caller and will be filled in by the function.
-
-
-

- - - - -
- - - - - - - - - - -
void httpd_init void   ) 
-
- - - - - -
-   - - -

-Initialize the web server. -

-Starts to listen for incoming connection requests on TCP port 80.

- -

-Here is the call graph for this function:

- - - - -
Generated on Tue Oct 7 15:51:50 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00098_a27_cgraph.png b/doc/html/a00098_a27_cgraph.png deleted file mode 100644 index 8662091..0000000 Binary files a/doc/html/a00098_a27_cgraph.png and /dev/null differ diff --git a/doc/html/a00099.html b/doc/html/a00099.html deleted file mode 100644 index 73021c8..0000000 --- a/doc/html/a00099.html +++ /dev/null @@ -1,245 +0,0 @@ - - -uIP 0.9: uIP hostname resolver functions - - - - -

uIP hostname resolver functions
- -[The uIP TCP/IP stack] -


Detailed Description

-The uIP DNS resolver functions are used to lookup a hostname and map it to a numerical IP address. It maintains a list of resolved hostnames that can be queried with the resolv_lookup() function. New hostnames can be resolved using the resolv_query() function.

-When a hostname has been resolved (or found to be non-existant), the resolver code calls a callback function called resolv_found() that must be implemented by the module that uses the resolver. -

- - - - - - - -

-

- - - -

-

- - - - - - - - - - - - - - - - - - -

Files

file  resolv.c
 DNS host name to IP address resolver.

file  resolv.h
 DNS resolver code header file.


Functions

void resolv_found (char *name, u16_t *ipaddr)
 Callback function which is called when a hostname is found.

void resolv_conf (u16_t *dnsserver)
 Configure which DNS server to use for queries.

u16_tresolv_getserver (void)
 Obtain the currently configured DNS server.

-void resolv_init (void)
 Initalize the resolver.

u16_tresolv_lookup (char *name)
 Look up a hostname in the array of known hostnames.

void resolv_query (char *name)
 Queues a name so that a question for the name will be sent out.

-


Function Documentation

-

- - - - -
- - - - - - - - - - -
void resolv_conf u16_t dnsserver  ) 
-
- - - - - -
-   - - -

-Configure which DNS server to use for queries. -

-

Parameters:
- - -
dnsserver A pointer to a 4-byte representation of the IP address of the DNS server to be configured.
-
-
- -

-Here is the call graph for this function:

- - - -

- - - - -
- - - - - - - - - - - - - - - - - - - -
void resolv_found char *  name,
u16_t ipaddr
-
- - - - - -
-   - - -

-Callback function which is called when a hostname is found. -

-This function must be implemented by the module that uses the DNS resolver. It is called when a hostname is found, or when a hostname was not found.

-

Parameters:
- - - -
name A pointer to the name that was looked up.
ipaddr A pointer to a 4-byte array containing the IP address of the hostname, or NULL if the hostname could not be found.
-
-
-

- - - - -
- - - - - - - - - - -
u16_t* resolv_getserver void   ) 
-
- - - - - -
-   - - -

-Obtain the currently configured DNS server. -

-

Returns:
A pointer to a 4-byte representation of the IP address of the currently configured DNS server or NULL if no DNS server has been configured.
-
-

- - - - -
- - - - - - - - - - -
u16_t* resolv_lookup char *  name  ) 
-
- - - - - -
-   - - -

-Look up a hostname in the array of known hostnames. -

-

Note:
This function only looks in the internal array of known hostnames, it does not send out a query for the hostname if none was found. The function resolv_query() can be used to send a query for a hostname.
-
Returns:
A pointer to a 4-byte representation of the hostname's IP address, or NULL if the hostname was not found in the array of hostnames.
-
-

- - - - -
- - - - - - - - - - -
void resolv_query char *  name  ) 
-
- - - - - -
-   - - -

-Queues a name so that a question for the name will be sent out. -

-

Parameters:
- - -
name The hostname that is to be queried.
-
-
-


Generated on Tue Oct 7 15:51:51 2003 for uIP 0.9 by - -doxygen -1.3.3
- - diff --git a/doc/html/a00099_a29_cgraph.png b/doc/html/a00099_a29_cgraph.png deleted file mode 100644 index c528ba8..0000000 Binary files a/doc/html/a00099_a29_cgraph.png and /dev/null differ diff --git a/doc/html/a00100.html b/doc/html/a00100.html new file mode 100644 index 0000000..8291183 --- /dev/null +++ b/doc/html/a00100.html @@ -0,0 +1,48 @@ + + +uIP 1.0: apps/hello-world/hello-world.c File Reference + + + + + + +

apps/hello-world/hello-world.c File Reference


Detailed Description

+An example of how to write uIP applications with protosockets. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file hello-world.c. +

+#include "hello-world.h"
+#include "uip.h"
+#include <string.h>
+ +

+Go to the source code of this file. + + + + + + +

Functions

+void hello_world_init (void)
+void hello_world_appcall (void)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00101.html b/doc/html/a00101.html new file mode 100644 index 0000000..f4761b8 --- /dev/null +++ b/doc/html/a00101.html @@ -0,0 +1,54 @@ + + +uIP 1.0: apps/hello-world/hello-world.h File Reference + + + + + + +

apps/hello-world/hello-world.h File Reference


Detailed Description

+Header file for an example of how to write uIP applications with protosockets. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file hello-world.h. +

+#include "uipopt.h"
+#include "psock.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + +

Data Structures

struct  hello_world_state

Defines

+#define UIP_APPCALL   hello_world_appcall

Functions

+void hello_world_appcall (void)
+void hello_world_init (void)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00102.html b/doc/html/a00102.html new file mode 100644 index 0000000..1f4e3fa --- /dev/null +++ b/doc/html/a00102.html @@ -0,0 +1,119 @@ + + +uIP 1.0: apps/resolv/resolv.c File Reference + + + + + + +

apps/resolv/resolv.c File Reference


Detailed Description

+DNS host name to IP address resolver. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+This file implements a DNS host name to IP address resolver. +

+Definition in file resolv.c. +

+#include "resolv.h"
+#include "uip.h"
+#include <string.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

+#define NULL   (void *)0
+#define MAX_RETRIES   8
+#define DNS_FLAG1_RESPONSE   0x80
+#define DNS_FLAG1_OPCODE_STATUS   0x10
+#define DNS_FLAG1_OPCODE_INVERSE   0x08
+#define DNS_FLAG1_OPCODE_STANDARD   0x00
+#define DNS_FLAG1_AUTHORATIVE   0x04
+#define DNS_FLAG1_TRUNC   0x02
+#define DNS_FLAG1_RD   0x01
+#define DNS_FLAG2_RA   0x80
+#define DNS_FLAG2_ERR_MASK   0x0f
+#define DNS_FLAG2_ERR_NONE   0x00
+#define DNS_FLAG2_ERR_NAME   0x03
+#define STATE_UNUSED   0
+#define STATE_NEW   1
+#define STATE_ASKING   2
+#define STATE_DONE   3
+#define STATE_ERROR   4
+#define RESOLV_ENTRIES   4

Functions

+void resolv_appcall (void)
void resolv_query (char *name)
 Queues a name so that a question for the name will be sent out.
u16_tresolv_lookup (char *name)
 Look up a hostname in the array of known hostnames.
u16_tresolv_getserver (void)
 Obtain the currently configured DNS server.
void resolv_conf (u16_t *dnsserver)
 Configure which DNS server to use for queries.
+void resolv_init (void)
 Initalize the resolver.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00103.html b/doc/html/a00103.html new file mode 100644 index 0000000..cf6a03a --- /dev/null +++ b/doc/html/a00103.html @@ -0,0 +1,84 @@ + + +uIP 1.0: apps/resolv/resolv.h File Reference + + + + + + +

apps/resolv/resolv.h File Reference


Detailed Description

+DNS resolver code header file. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file resolv.h. +

+#include "uipopt.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 type of the application structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.

+The file containing the definitions must be included in the uipopt.h file.

+The following example illustrates how this can look.

void httpd_appcall(void);
+#define UIP_APPCALL     httpd_appcall
+
+struct httpd_state {
+  u8_t state;
+  u16_t count;
+  char *dataptr;
+  char *script;
+};
+typedef struct httpd_state uip_tcp_appstate_t
+


typedef int uip_udp_appstate_t
 The type of the application state that is to be stored in the uip_conn structure.

Defines

+#define UIP_UDP_APPCALL   resolv_appcall

Functions

+void resolv_appcall (void)
void resolv_found (char *name, u16_t *ipaddr)
 Callback function which is called when a hostname is found.
void resolv_conf (u16_t *dnsserver)
 Configure which DNS server to use for queries.
u16_tresolv_getserver (void)
 Obtain the currently configured DNS server.
+void resolv_init (void)
 Initalize the resolver.
u16_tresolv_lookup (char *name)
 Look up a hostname in the array of known hostnames.
void resolv_query (char *name)
 Queues a name so that a question for the name will be sent out.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00103.png b/doc/html/a00103.png deleted file mode 100644 index daf663e..0000000 Binary files a/doc/html/a00103.png and /dev/null differ diff --git a/doc/html/a00104.html b/doc/html/a00104.html new file mode 100644 index 0000000..b769a45 --- /dev/null +++ b/doc/html/a00104.html @@ -0,0 +1,78 @@ + + +uIP 1.0: apps/smtp/smtp.c File Reference + + + + + + +

apps/smtp/smtp.c File Reference


Detailed Description

+SMTP example implementation. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file smtp.c. +

+#include "smtp.h"
+#include "smtp-strings.h"
+#include "psock.h"
+#include "uip.h"
+#include <string.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

+#define ISO_nl   0x0a
+#define ISO_cr   0x0d
+#define ISO_period   0x2e
+#define ISO_2   0x32
+#define ISO_3   0x33
+#define ISO_4   0x34
+#define ISO_5   0x35

Functions

+void smtp_appcall (void)
void smtp_configure (char *lhostname, void *server)
 Specificy an SMTP server and hostname.
unsigned char smtp_send (char *to, char *cc, char *from, char *subject, char *msg, u16_t msglen)
 Send an e-mail.
+void smtp_init (void)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00104.png b/doc/html/a00104.png deleted file mode 100644 index 9ebddd4..0000000 Binary files a/doc/html/a00104.png and /dev/null differ diff --git a/doc/html/a00105.html b/doc/html/a00105.html new file mode 100644 index 0000000..4a8d15b --- /dev/null +++ b/doc/html/a00105.html @@ -0,0 +1,82 @@ + + +uIP 1.0: apps/smtp/smtp.h File Reference + + + + + + +

apps/smtp/smtp.h File Reference


Detailed Description

+SMTP header file. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file smtp.h. +

+#include "uipopt.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + +

Data Structures

struct  smtp_state

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 type of the application structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.

+The file containing the definitions must be included in the uipopt.h file.

+The following example illustrates how this can look.

void httpd_appcall(void);
+#define UIP_APPCALL     httpd_appcall
+
+struct httpd_state {
+  u8_t state;
+  u16_t count;
+  char *dataptr;
+  char *script;
+};
+typedef struct httpd_state uip_tcp_appstate_t
+


+#define UIP_APPCALL   smtp_appcall
 The name of the application function that uIP should call in response to TCP/IP events.
typedef smtp_state uip_tcp_appstate_t
 The type of the application state that is to be stored in the uip_conn structure.

Defines

+#define SMTP_ERR_OK   0
 Error number that signifies a non-error condition.
+#define SMTP_SEND(to, cc, from, subject, msg)   smtp_send(to, cc, from, subject, msg, strlen(msg))

Functions

void smtp_done (unsigned char error)
 Callback function that is called when an e-mail transmission is done.
+void smtp_init (void)
+void smtp_appcall (void)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00105.png b/doc/html/a00105.png deleted file mode 100644 index 3d468fd..0000000 Binary files a/doc/html/a00105.png and /dev/null differ diff --git a/doc/html/a00106.png b/doc/html/a00106.png deleted file mode 100644 index d3a016b..0000000 Binary files a/doc/html/a00106.png and /dev/null differ diff --git a/doc/html/a00107.html b/doc/html/a00107.html new file mode 100644 index 0000000..74d2816 --- /dev/null +++ b/doc/html/a00107.html @@ -0,0 +1,268 @@ + + +uIP 1.0: apps/telnetd/shell.h File Reference + + + + + + +

apps/telnetd/shell.h File Reference


Detailed Description

+Interface for the Contiki shell. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+Some of the functions declared in this file must be implemented as a shell back-end in the architecture specific files of a Contiki port. +

+Definition in file shell.h. +

+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + +

Functions

void shell_init (void)
 Initialize the shell.
void shell_start (void)
 Start the shell back-end.
void shell_input (char *command)
 Process a shell command.
+void shell_quit (char *)
 Quit the shell.
void shell_output (char *str1, char *str2)
 Print a string to the shell window.
void shell_prompt (char *prompt)
 Print a prompt to the shell window.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void shell_init void   ) 
+
+ + + + + +
+   + + +

+Initialize the shell. +

+Called when the shell front-end process starts. This function may be used to start listening for signals.

Examples:
+telnetd.c.
+

+Definition at line 105 of file shell.c. +

+References shell_init(). +

+Referenced by shell_init().

+

+ + + + +
+ + + + + + + + + +
void shell_input char *  command  ) 
+
+ + + + + +
+   + + +

+Process a shell command. +

+This function will be called by the shell GUI / telnet server whan a command has been entered that should be processed by the shell back-end.

+

Parameters:
+ + +
command The command to be processed.
+
+
Examples:
+telnetd.c.
+

+Definition at line 118 of file shell.c. +

+References shell_input(). +

+Referenced by shell_input().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void shell_output char *  str1,
char *  str2
+
+ + + + + +
+   + + +

+Print a string to the shell window. +

+This function is implemented by the shell GUI / telnet server and can be called by the shell back-end to output a string in the shell window. The string is automatically appended with a linebreak.

+

Parameters:
+ + + +
str1 The first half of the string to be output.
str2 The second half of the string to be output.
+
+
Examples:
+telnetd.c.
+

+Definition at line 113 of file telnetd.c. +

+References ISO_cr, ISO_nl, and NULL.

+

+ + + + +
+ + + + + + + + + +
void shell_prompt char *  prompt  ) 
+
+ + + + + +
+   + + +

+Print a prompt to the shell window. +

+This function can be used by the shell back-end to print out a prompt to the shell window.

+

Parameters:
+ + +
prompt The prompt to be printed.
+
+
Examples:
+telnetd.c.
+

+Definition at line 101 of file telnetd.c. +

+References NULL.

+

+ + + + +
+ + + + + + + + + +
void shell_start void   ) 
+
+ + + + + +
+   + + +

+Start the shell back-end. +

+Called by the front-end when a new shell is started.

Examples:
+telnetd.c.
+

+Definition at line 110 of file shell.c. +

+References shell_start(). +

+Referenced by shell_start().

+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00107.png b/doc/html/a00107.png deleted file mode 100644 index 445c7fd..0000000 Binary files a/doc/html/a00107.png and /dev/null differ diff --git a/doc/html/a00108.png b/doc/html/a00108.png deleted file mode 100644 index 0f765f5..0000000 Binary files a/doc/html/a00108.png and /dev/null differ diff --git a/doc/html/a00109.png b/doc/html/a00109.png deleted file mode 100644 index 9f5659f..0000000 Binary files a/doc/html/a00109.png and /dev/null differ diff --git a/doc/html/a00110.html b/doc/html/a00110.html new file mode 100644 index 0000000..509e813 --- /dev/null +++ b/doc/html/a00110.html @@ -0,0 +1,107 @@ + + +uIP 1.0: apps/webclient/webclient.c File Reference + + + + + + +

apps/webclient/webclient.c File Reference


Detailed Description

+Implementation of the HTTP client. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file webclient.c. +

+#include "uip.h"
+#include "uiplib.h"
+#include "webclient.h"
+#include "resolv.h"
+#include <string.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

+#define WEBCLIENT_TIMEOUT   100
+#define WEBCLIENT_STATE_STATUSLINE   0
+#define WEBCLIENT_STATE_HEADERS   1
+#define WEBCLIENT_STATE_DATA   2
+#define WEBCLIENT_STATE_CLOSE   3
+#define HTTPFLAG_NONE   0
+#define HTTPFLAG_OK   1
+#define HTTPFLAG_MOVED   2
+#define HTTPFLAG_ERROR   3
+#define ISO_nl   0x0a
+#define ISO_cr   0x0d
+#define ISO_space   0x20

Functions

char * webclient_mimetype (void)
 Obtain the MIME type of the current HTTP data stream.
char * webclient_filename (void)
 Obtain the filename of the current HTTP data stream.
char * webclient_hostname (void)
 Obtain the hostname of the current HTTP data stream.
unsigned short webclient_port (void)
 Obtain the port number of the current HTTP data stream.
+void webclient_init (void)
 Initialize the webclient module.
+void webclient_close (void)
 Close the currently open HTTP connection.
unsigned char webclient_get (char *host, u16_t port, char *file)
 Open an HTTP connection to a web server and ask for a file using the GET method.
+void webclient_appcall (void)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00110.png b/doc/html/a00110.png deleted file mode 100644 index 297bc21..0000000 Binary files a/doc/html/a00110.png and /dev/null differ diff --git a/doc/html/a00111.html b/doc/html/a00111.html new file mode 100644 index 0000000..454dbfa --- /dev/null +++ b/doc/html/a00111.html @@ -0,0 +1,96 @@ + + +uIP 1.0: apps/webclient/webclient.h File Reference + + + + + + +

apps/webclient/webclient.h File Reference


Detailed Description

+Header file for the HTTP client. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file webclient.h. +

+#include "webclient-strings.h"
+#include "uipopt.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Data Structures

struct  webclient_state

Defines

+#define WEBCLIENT_CONF_MAX_URLLEN   100
+#define UIP_APPCALL   webclient_appcall

Typedefs

+typedef webclient_state uip_tcp_appstate_t

Functions

void webclient_datahandler (char *data, u16_t len)
 Callback function that is called from the webclient code when HTTP data has been received.
void webclient_connected (void)
 Callback function that is called from the webclient code when the HTTP connection has been connected to the web server.
void webclient_timedout (void)
 Callback function that is called from the webclient code if the HTTP connection to the web server has timed out.
void webclient_aborted (void)
 Callback function that is called from the webclient code if the HTTP connection to the web server has been aborted by the web server.
void webclient_closed (void)
 Callback function that is called from the webclient code when the HTTP connection to the web server has been closed.
+void webclient_init (void)
 Initialize the webclient module.
unsigned char webclient_get (char *host, u16_t port, char *file)
 Open an HTTP connection to a web server and ask for a file using the GET method.
+void webclient_close (void)
 Close the currently open HTTP connection.
+void webclient_appcall (void)
char * webclient_mimetype (void)
 Obtain the MIME type of the current HTTP data stream.
char * webclient_filename (void)
 Obtain the filename of the current HTTP data stream.
char * webclient_hostname (void)
 Obtain the hostname of the current HTTP data stream.
unsigned short webclient_port (void)
 Obtain the port number of the current HTTP data stream.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00111.png b/doc/html/a00111.png deleted file mode 100644 index c8a3ed4..0000000 Binary files a/doc/html/a00111.png and /dev/null differ diff --git a/doc/html/a00112.html b/doc/html/a00112.html new file mode 100644 index 0000000..2132685 --- /dev/null +++ b/doc/html/a00112.html @@ -0,0 +1,49 @@ + + +uIP 1.0: apps/webserver/httpd-cgi.c File Reference + + + + + + +

apps/webserver/httpd-cgi.c File Reference


Detailed Description

+Web server script interface. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file httpd-cgi.c. +

+#include "uip.h"
+#include "psock.h"
+#include "httpd.h"
+#include "httpd-cgi.h"
+#include "httpd-fs.h"
+#include <stdio.h>
+#include <string.h>
+ +

+Go to the source code of this file. + + + + +

Functions

+httpd_cgifunction httpd_cgi (char *name)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00112.png b/doc/html/a00112.png deleted file mode 100644 index bddda68..0000000 Binary files a/doc/html/a00112.png and /dev/null differ diff --git a/doc/html/a00113.html b/doc/html/a00113.html new file mode 100644 index 0000000..62dbfa6 --- /dev/null +++ b/doc/html/a00113.html @@ -0,0 +1,51 @@ + + +uIP 1.0: apps/webserver/httpd-cgi.h File Reference + + + + + + +

apps/webserver/httpd-cgi.h File Reference


Detailed Description

+Web server script interface header file. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file httpd-cgi.h. +

+#include "psock.h"
+#include "httpd.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + +

Data Structures

struct  httpd_cgi_call

Defines

#define HTTPD_CGI_CALL(name, str, function)
 HTTPD CGI function declaration.

Functions

+httpd_cgifunction httpd_cgi (char *name)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00113.png b/doc/html/a00113.png deleted file mode 100644 index b611625..0000000 Binary files a/doc/html/a00113.png and /dev/null differ diff --git a/doc/html/a00114.html b/doc/html/a00114.html new file mode 100644 index 0000000..62d611f --- /dev/null +++ b/doc/html/a00114.html @@ -0,0 +1,79 @@ + + +uIP 1.0: apps/webserver/httpd.c File Reference + + + + + + +

apps/webserver/httpd.c File Reference


Detailed Description

+Web server. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file httpd.c. +

+#include "uip.h"
+#include "httpd.h"
+#include "httpd-fs.h"
+#include "httpd-cgi.h"
+#include "http-strings.h"
+#include <string.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

+#define STATE_WAITING   0
+#define STATE_OUTPUT   1
+#define ISO_nl   0x0a
+#define ISO_space   0x20
+#define ISO_bang   0x21
+#define ISO_percent   0x25
+#define ISO_period   0x2e
+#define ISO_slash   0x2f
+#define ISO_colon   0x3a

Functions

+void httpd_appcall (void)
void httpd_init (void)
 Initialize the web server.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00114.png b/doc/html/a00114.png deleted file mode 100644 index 7601a2f..0000000 Binary files a/doc/html/a00114.png and /dev/null differ diff --git a/doc/html/a00115.png b/doc/html/a00115.png deleted file mode 100644 index 4c612cd..0000000 Binary files a/doc/html/a00115.png and /dev/null differ diff --git a/doc/html/a00116.png b/doc/html/a00116.png deleted file mode 100644 index c9b2e21..0000000 Binary files a/doc/html/a00116.png and /dev/null differ diff --git a/doc/html/a00117.png b/doc/html/a00117.png deleted file mode 100644 index 30892dd..0000000 Binary files a/doc/html/a00117.png and /dev/null differ diff --git a/doc/html/a00118.png b/doc/html/a00118.png deleted file mode 100644 index 55440eb..0000000 Binary files a/doc/html/a00118.png and /dev/null differ diff --git a/doc/html/a00119.png b/doc/html/a00119.png deleted file mode 100644 index 9a32545..0000000 Binary files a/doc/html/a00119.png and /dev/null differ diff --git a/doc/html/a00120.html b/doc/html/a00120.html new file mode 100644 index 0000000..3043a5d --- /dev/null +++ b/doc/html/a00120.html @@ -0,0 +1,50 @@ + + +uIP 1.0: lib/memb.c File Reference + + + + + + +

lib/memb.c File Reference


Detailed Description

+Memory block allocation routines. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file memb.c. +

+#include <string.h>
+#include "memb.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + +

Functions

void memb_init (struct memb_blocks *m)
 Initialize a memory block that was declared with MEMB().
void * memb_alloc (struct memb_blocks *m)
 Allocate a memory block from a block of memory declared with MEMB().
char memb_free (struct memb_blocks *m, void *ptr)
 Deallocate a memory block from a memory block previously declared with MEMB().
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00120.png b/doc/html/a00120.png deleted file mode 100644 index 67f08c1..0000000 Binary files a/doc/html/a00120.png and /dev/null differ diff --git a/doc/html/a00121.html b/doc/html/a00121.html new file mode 100644 index 0000000..fd04d55 --- /dev/null +++ b/doc/html/a00121.html @@ -0,0 +1,61 @@ + + +uIP 1.0: lib/memb.h File Reference + + + + + + +

lib/memb.h File Reference


Detailed Description

+Memory block allocation routines. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file memb.h. +

+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + +

Data Structures

struct  memb_blocks

Defines

+#define MEMB_CONCAT2(s1, s2)   s1##s2
+#define MEMB_CONCAT(s1, s2)   MEMB_CONCAT2(s1, s2)
#define MEMB(name, structure, num)
 Declare a memory block.

Functions

void memb_init (struct memb_blocks *m)
 Initialize a memory block that was declared with MEMB().
void * memb_alloc (struct memb_blocks *m)
 Allocate a memory block from a block of memory declared with MEMB().
char memb_free (struct memb_blocks *m, void *ptr)
 Deallocate a memory block from a memory block previously declared with MEMB().
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00121.png b/doc/html/a00121.png deleted file mode 100644 index 48d4e72..0000000 Binary files a/doc/html/a00121.png and /dev/null differ diff --git a/doc/html/a00122.png b/doc/html/a00122.png deleted file mode 100644 index 9eb8b18..0000000 Binary files a/doc/html/a00122.png and /dev/null differ diff --git a/doc/html/a00123.html b/doc/html/a00123.html new file mode 100644 index 0000000..6cbb1a8 --- /dev/null +++ b/doc/html/a00123.html @@ -0,0 +1,57 @@ + + +uIP 1.0: uip/lc-addrlabels.h File Reference + + + + + + +

uip/lc-addrlabels.h File Reference


Detailed Description

+Implementation of local continuations based on the "Labels as values" feature of gcc. +

+

Author:
Adam Dunkels <adam@sics.se>
+This implementation of local continuations is based on a special feature of the GCC C compiler called "labels as values". This feature allows assigning pointers with the address of the code corresponding to a particular C label.

+For more information, see the GCC documentation: http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html

+Thanks to dividuum for finding the nice local scope label implementation. +

+Definition in file lc-addrlabels.h. +

+ +

+Go to the source code of this file. + + + + + + + + + + + + + +

Defines

+#define LC_INIT(s)   s = NULL
+#define LC_RESUME(s)
+#define LC_SET(s)   do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0)
+#define LC_END(s)

Typedefs

+typedef void * lc_t
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00123.png b/doc/html/a00123.png deleted file mode 100644 index c6528d5..0000000 Binary files a/doc/html/a00123.png and /dev/null differ diff --git a/doc/html/a00124.html b/doc/html/a00124.html new file mode 100644 index 0000000..a338d45 --- /dev/null +++ b/doc/html/a00124.html @@ -0,0 +1,59 @@ + + +uIP 1.0: uip/lc-switch.h File Reference + + + + + + +

uip/lc-switch.h File Reference


Detailed Description

+Implementation of local continuations based on switch() statment. +

+

Author:
Adam Dunkels <adam@sics.se>
+This implementation of local continuations uses the C switch() statement to resume execution of a function somewhere inside the function's body. The implementation is based on the fact that switch() statements are able to jump directly into the bodies of control structures such as if() or while() statmenets.

+This implementation borrows heavily from Simon Tatham's coroutines implementation in C: http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html +

+Definition in file lc-switch.h. +

+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + +

Defines

+#define __LC_SWTICH_H__
+#define LC_INIT(s)   s = 0;
+#define LC_RESUME(s)   switch(s) { case 0:
+#define LC_SET(s)   s = __LINE__; case __LINE__:
+#define LC_END(s)   }

Typedefs

+typedef unsigned short lc_t
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00124.png b/doc/html/a00124.png deleted file mode 100644 index 6fa3b2c..0000000 Binary files a/doc/html/a00124.png and /dev/null differ diff --git a/doc/html/a00125.html b/doc/html/a00125.html new file mode 100644 index 0000000..ddcb20b --- /dev/null +++ b/doc/html/a00125.html @@ -0,0 +1,39 @@ + + +uIP 1.0: uip/lc.h File Reference + + + + + + +

uip/lc.h File Reference


Detailed Description

+Local continuations. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file lc.h. +

+#include "lc-switch.h"
+ +

+Go to the source code of this file. + +
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00125.png b/doc/html/a00125.png deleted file mode 100644 index 290091a..0000000 Binary files a/doc/html/a00125.png and /dev/null differ diff --git a/doc/html/a00126.png b/doc/html/a00126.png deleted file mode 100644 index 95852f4..0000000 Binary files a/doc/html/a00126.png and /dev/null differ diff --git a/doc/html/a00127.html b/doc/html/a00127.html new file mode 100644 index 0000000..c4cf552 --- /dev/null +++ b/doc/html/a00127.html @@ -0,0 +1,99 @@ + + +uIP 1.0: uip/psock.h File Reference + + + + + + +

uip/psock.h File Reference


Detailed Description

+Protosocket library header file. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file psock.h. +

+#include "uipopt.h"
+#include "pt.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Data Structures

struct  psock_buf
struct  psock
 The representation of a protosocket. More...

Defines

#define PSOCK_INIT(psock, buffer, buffersize)
 Initialize a protosocket.
#define PSOCK_BEGIN(psock)
 Start the protosocket protothread in a function.
#define PSOCK_SEND(psock, data, datalen)
 Send data.
#define PSOCK_SEND_STR(psock, str)
 Send a null-terminated string.
#define PSOCK_GENERATOR_SEND(psock, generator, arg)
 Generate data with a function and send it.
#define PSOCK_CLOSE(psock)
 Close a protosocket.
#define PSOCK_READBUF(psock)
 Read data until the buffer is full.
#define PSOCK_READTO(psock, c)
 Read data up to a specified character.
#define PSOCK_DATALEN(psock)
 The length of the data that was previously read.
#define PSOCK_EXIT(psock)
 Exit the protosocket's protothread.
#define PSOCK_CLOSE_EXIT(psock)
 Close a protosocket and exit the protosocket's protothread.
#define PSOCK_END(psock)
 Declare the end of a protosocket's protothread.
#define PSOCK_NEWDATA(psock)
 Check if new data has arrived on a protosocket.
#define PSOCK_WAIT_UNTIL(psock, condition)
 Wait until a condition is true.
+#define PSOCK_WAIT_THREAD(psock, condition)   PT_WAIT_THREAD(&((psock)->pt), (condition))

Functions

+u16_t psock_datalen (struct psock *psock)
+char psock_newdata (struct psock *s)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00127.png b/doc/html/a00127.png deleted file mode 100644 index d7d2351..0000000 Binary files a/doc/html/a00127.png and /dev/null differ diff --git a/doc/html/a00128.html b/doc/html/a00128.html new file mode 100644 index 0000000..087b668 --- /dev/null +++ b/doc/html/a00128.html @@ -0,0 +1,101 @@ + + +uIP 1.0: uip/pt.h File Reference + + + + + + +

uip/pt.h File Reference


Detailed Description

+Protothreads implementation. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file pt.h. +

+#include "lc.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Data Structures

struct  pt

Initialization

#define PT_INIT(pt)
 Initialize a protothread.

Declaration and definition

#define PT_THREAD(name_args)
 Declaration of a protothread.
#define PT_BEGIN(pt)
 Declare the start of a protothread inside the C function implementing the protothread.
#define PT_END(pt)
 Declare the end of a protothread.

Blocked wait

#define PT_WAIT_UNTIL(pt, condition)
 Block and wait until condition is true.
#define PT_WAIT_WHILE(pt, cond)
 Block and wait while condition is true.

Hierarchical protothreads

#define PT_WAIT_THREAD(pt, thread)
 Block and wait until a child protothread completes.
#define PT_SPAWN(pt, child, thread)
 Spawn a child protothread and wait until it exits.

Exiting and restarting

#define PT_RESTART(pt)
 Restart the protothread.
#define PT_EXIT(pt)
 Exit the protothread.

Calling a protothread

#define PT_SCHEDULE(f)
 Schedule a protothread.

Yielding from a protothread

#define PT_YIELD(pt)
 Yield from the current protothread.
#define PT_YIELD_UNTIL(pt, cond)
 Yield from the protothread until a condition occurs.

Defines

+#define PT_WAITING   0
+#define PT_EXITED   1
+#define PT_ENDED   2
+#define PT_YIELDED   3
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00128.png b/doc/html/a00128.png deleted file mode 100644 index 053eff8..0000000 Binary files a/doc/html/a00128.png and /dev/null differ diff --git a/doc/html/a00129.html b/doc/html/a00129.html new file mode 100644 index 0000000..2d89eba --- /dev/null +++ b/doc/html/a00129.html @@ -0,0 +1,53 @@ + + +uIP 1.0: uip/timer.c File Reference + + + + + + +

uip/timer.c File Reference


Detailed Description

+Timer library implementation. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file timer.c. +

+#include "clock.h"
+#include "timer.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + +

Functions

void timer_set (struct timer *t, clock_time_t interval)
 Set a timer.
void timer_reset (struct timer *t)
 Reset the timer with the same interval.
void timer_restart (struct timer *t)
 Restart the timer from the current point in time.
int timer_expired (struct timer *t)
 Check if a timer has expired.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00129.png b/doc/html/a00129.png deleted file mode 100644 index b3962f5..0000000 Binary files a/doc/html/a00129.png and /dev/null differ diff --git a/doc/html/a00130.html b/doc/html/a00130.html new file mode 100644 index 0000000..95da033 --- /dev/null +++ b/doc/html/a00130.html @@ -0,0 +1,56 @@ + + +uIP 1.0: uip/timer.h File Reference + + + + + + +

uip/timer.h File Reference


Detailed Description

+Timer library header file. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file timer.h. +

+#include "clock.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + +

Data Structures

struct  timer
 A timer. More...

Functions

void timer_set (struct timer *t, clock_time_t interval)
 Set a timer.
void timer_reset (struct timer *t)
 Reset the timer with the same interval.
void timer_restart (struct timer *t)
 Restart the timer from the current point in time.
int timer_expired (struct timer *t)
 Check if a timer has expired.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00130.png b/doc/html/a00130.png deleted file mode 100644 index ca75f1f..0000000 Binary files a/doc/html/a00130.png and /dev/null differ diff --git a/doc/html/a00131.html b/doc/html/a00131.html new file mode 100644 index 0000000..8370948 --- /dev/null +++ b/doc/html/a00131.html @@ -0,0 +1,63 @@ + + +uIP 1.0: uip/uip-neighbor.c File Reference + + + + + + +

uip/uip-neighbor.c File Reference


Detailed Description

+Database of link-local neighbors, used by IPv6 code and to be used by a future ARP code rewrite. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file uip-neighbor.c. +

+#include "uip-neighbor.h"
+#include <string.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + +

Defines

+#define MAX_TIME   128
+#define ENTRIES   8

Functions

+void uip_neighbor_init (void)
+void uip_neighbor_periodic (void)
+void uip_neighbor_add (uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr)
+void uip_neighbor_update (uip_ipaddr_t ipaddr)
+uip_neighbor_addruip_neighbor_lookup (uip_ipaddr_t ipaddr)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00131.png b/doc/html/a00131.png deleted file mode 100644 index 25b2c82..0000000 Binary files a/doc/html/a00131.png and /dev/null differ diff --git a/doc/html/a00132.html b/doc/html/a00132.html new file mode 100644 index 0000000..dc5b649 --- /dev/null +++ b/doc/html/a00132.html @@ -0,0 +1,58 @@ + + +uIP 1.0: uip/uip-neighbor.h File Reference + + + + + + +

uip/uip-neighbor.h File Reference


Detailed Description

+Header file for database of link-local neighbors, used by IPv6 code and to be used by future ARP code. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file uip-neighbor.h. +

+#include "uip.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + +

Data Structures

struct  uip_neighbor_addr

Functions

+void uip_neighbor_init (void)
+void uip_neighbor_add (uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr)
+void uip_neighbor_update (uip_ipaddr_t ipaddr)
+uip_neighbor_addruip_neighbor_lookup (uip_ipaddr_t ipaddr)
+void uip_neighbor_periodic (void)
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00132.png b/doc/html/a00132.png deleted file mode 100644 index 5081ad3..0000000 Binary files a/doc/html/a00132.png and /dev/null differ diff --git a/doc/html/a00133.png b/doc/html/a00133.png deleted file mode 100644 index 20918b9..0000000 Binary files a/doc/html/a00133.png and /dev/null differ diff --git a/doc/html/a00134.html b/doc/html/a00134.html new file mode 100644 index 0000000..179ad8f --- /dev/null +++ b/doc/html/a00134.html @@ -0,0 +1,42 @@ + + +uIP 1.0: uip/uip-split.h File Reference + + + + + + +

uip/uip-split.h File Reference


Detailed Description

+Module for splitting outbound TCP segments in two to avoid the delayed ACK throughput degradation. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file uip-split.h. +

+ +

+Go to the source code of this file. + + + + + +

Functions

void uip_split_output (void)
 Handle outgoing packets.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00134.png b/doc/html/a00134.png deleted file mode 100644 index 3af688b..0000000 Binary files a/doc/html/a00134.png and /dev/null differ diff --git a/doc/html/a00135.html b/doc/html/a00135.html new file mode 100644 index 0000000..8cbccdc --- /dev/null +++ b/doc/html/a00135.html @@ -0,0 +1,215 @@ + + +uIP 1.0: uip/uip.c File Reference + + + + + + +

uip/uip.c File Reference


Detailed Description

+The uIP TCP/IP stack code. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file uip.c. +

+#include "uip.h"
+#include "uipopt.h"
+#include "uip_arch.h"
+#include <string.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

+#define DEBUG_PRINTF()
+#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 TCP_OPT_END   0
+#define TCP_OPT_NOOP   1
+#define TCP_OPT_MSS   2
+#define TCP_OPT_MSS_LEN   4
+#define ICMP_ECHO_REPLY   0
+#define ICMP_ECHO   8
+#define ICMP6_ECHO_REPLY   129
+#define ICMP6_ECHO   128
+#define ICMP6_NEIGHBOR_SOLICITATION   135
+#define ICMP6_NEIGHBOR_ADVERTISEMENT   136
+#define ICMP6_FLAG_S   (1 << 6)
+#define ICMP6_OPTION_SOURCE_LINK_ADDRESS   1
+#define ICMP6_OPTION_TARGET_LINK_ADDRESS   2
+#define BUF   ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define FBUF   ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
+#define ICMPBUF   ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define UDPBUF   ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define UIP_STAT(s)
+#define UIP_LOG(m)

Functions

void uip_setipid (u16_t id)
 uIP initialization function.
void uip_add32 (u8_t *op32, u16_t op16)
 Carry out a 32-bit addition.
u16_t uip_chksum (u16_t *buf, u16_t len)
 Calculate the Internet checksum over a buffer.
u16_t uip_ipchksum (void)
 Calculate the IP header checksum of the packet header in uip_buf.
u16_t uip_tcpchksum (void)
 Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
void uip_init (void)
 uIP initialization function.
uip_connuip_connect (uip_ipaddr_t *ripaddr, u16_t rport)
 Connect to a remote host using TCP.
uip_udp_connuip_udp_new (uip_ipaddr_t *ripaddr, u16_t rport)
 Set up a new UDP connection.
void uip_unlisten (u16_t port)
 Stop listening to the specified port.
void uip_listen (u16_t port)
 Start listening to the specified port.
+void uip_process (u8_t flag)
u16_t htons (u16_t val)
 Convert 16-bit quantity from host byte order to network byte order.
void uip_send (const void *data, int len)
 Send data on the current connection.

Variables

+uip_ipaddr_t uip_hostaddr
+uip_ipaddr_t uip_draddr
+uip_ipaddr_t uip_netmask
+uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}
u8_t uip_buf [UIP_BUFSIZE+2]
 The uIP packet buffer.
void * uip_appdata
 Pointer to the application data in the packet buffer.
+void * uip_sappdata
u16_t uip_len
 The length of the packet in the uip_buf buffer.
+u16_t uip_slen
+u8_t uip_flags
uip_connuip_conn
 Pointer to the current TCP connection.
+uip_conn uip_conns [UIP_CONNS]
+u16_t uip_listenports [UIP_LISTENPORTS]
+uip_udp_connuip_udp_conn
 The current UDP connection.
+uip_udp_conn uip_udp_conns [UIP_UDP_CONNS]
+u8_t uip_acc32 [4]
 4-byte array used for the 32-bit sequence number calculations.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00135.png b/doc/html/a00135.png deleted file mode 100644 index 3123563..0000000 Binary files a/doc/html/a00135.png and /dev/null differ diff --git a/doc/html/a00136.html b/doc/html/a00136.html new file mode 100644 index 0000000..341701b --- /dev/null +++ b/doc/html/a00136.html @@ -0,0 +1,400 @@ + + +uIP 1.0: uip/uip.h File Reference + + + + + + +

uip/uip.h File Reference


Detailed Description

+Header file for the uIP TCP/IP stack. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+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. +

+Definition in file uip.h. +

+#include "uipopt.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Data Structures

struct  uip_conn
 Representation of a uIP TCP connection. More...
struct  uip_udp_conn
 Representation of a uIP UDP connection. More...
struct  uip_stats
 The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1. More...
struct  uip_tcpip_hdr
struct  uip_icmpip_hdr
struct  uip_udpip_hdr
struct  uip_eth_addr
 Representation of a 48-bit Ethernet address. More...

Defines

#define uip_sethostaddr(addr)
 Set the IP address of this host.
#define uip_gethostaddr(addr)
 Get the IP address of this host.
#define uip_setdraddr(addr)
 Set the default router's IP address.
#define uip_setnetmask(addr)
 Set the netmask.
#define uip_getdraddr(addr)
 Get the default router's IP address.
#define uip_getnetmask(addr)
 Get the netmask.
#define uip_input()
 Process an incoming packet.
#define uip_periodic(conn)
 Periodic processing for a connection identified by its number.
+#define uip_conn_active(conn)   (uip_conns[conn].tcpstateflags != UIP_CLOSED)
#define uip_periodic_conn(conn)
 Perform periodic processing for a connection identified by a pointer to its structure.
#define uip_poll_conn(conn)
 Reuqest that a particular connection should be polled.
#define uip_udp_periodic(conn)
 Periodic processing for a UDP connection identified by its number.
#define uip_udp_periodic_conn(conn)
 Periodic processing for a UDP connection identified by a pointer to its structure.
+#define uip_outstanding(conn)   ((conn)->len)
#define uip_datalen()
 The length of any incoming data that is currently avaliable (if avaliable) in the uip_appdata buffer.
#define uip_urgdatalen()
 The length of any out-of-band data (urgent data) that has arrived on the connection.
#define uip_close()
 Close the current connection.
#define uip_abort()
 Abort the current connection.
#define uip_stop()
 Tell the sending host to stop sending data.
+#define uip_stopped(conn)
 Find out if the current connection has been previously stopped with uip_stop().
#define uip_restart()
 Restart the current connection, if is has previously been stopped with uip_stop().
#define uip_udpconnection()
 Is the current connection a UDP connection?
#define uip_newdata()
 Is new incoming data available?
#define uip_acked()
 Has previously sent data been acknowledged?
#define uip_connected()
 Has the connection just been connected?
#define uip_closed()
 Has the connection been closed by the other end?
#define uip_aborted()
 Has the connection been aborted by the other end?
#define uip_timedout()
 Has the connection timed out?
#define uip_rexmit()
 Do we need to retransmit previously data?
#define uip_poll()
 Is the connection being polled by uIP?
+#define uip_initialmss()
 Get the initial maxium segment size (MSS) of the current connection.
#define uip_mss()
 Get the current maxium segment size that can be sent on the current connection.
#define uip_udp_remove(conn)
 Removed a UDP connection.
#define uip_udp_bind(conn, port)
 Bind a UDP connection to a local port.
#define uip_udp_send(len)
 Send a UDP datagram of length len on the current connection.
#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
 Construct an IP address from four bytes.
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
 Construct an IPv6 address from eight 16-bit words.
#define uip_ipaddr_copy(dest, src)
 Copy an IP address to another IP address.
#define uip_ipaddr_cmp(addr1, addr2)
 Compare two IP addresses.
#define uip_ipaddr_maskcmp(addr1, addr2, mask)
 Compare two IP addresses with netmasks.
#define uip_ipaddr_mask(dest, src, mask)
 Mask out the network part of an IP address.
#define uip_ipaddr1(addr)
 Pick the first octet of an IP address.
#define uip_ipaddr2(addr)
 Pick the second octet of an IP address.
#define uip_ipaddr3(addr)
 Pick the third octet of an IP address.
#define uip_ipaddr4(addr)
 Pick the fourth octet of an IP address.
#define HTONS(n)
 Convert 16-bit quantity from host byte order to network byte order.
+#define ntohs   htons
+#define UIP_ACKDATA   1
+#define UIP_NEWDATA   2
+#define UIP_REXMIT   4
+#define UIP_POLL   8
+#define UIP_CLOSE   16
+#define UIP_ABORT   32
+#define UIP_CONNECTED   64
+#define UIP_TIMEDOUT   128
+#define UIP_DATA   1
+#define UIP_TIMER   2
+#define UIP_POLL_REQUEST   3
+#define UIP_UDP_SEND_CONN   4
+#define UIP_UDP_TIMER   5
+#define UIP_CLOSED   0
+#define UIP_SYN_RCVD   1
+#define UIP_SYN_SENT   2
+#define UIP_ESTABLISHED   3
+#define UIP_FIN_WAIT_1   4
+#define UIP_FIN_WAIT_2   5
+#define UIP_CLOSING   6
+#define UIP_TIME_WAIT   7
+#define UIP_LAST_ACK   8
+#define UIP_TS_MASK   15
+#define UIP_STOPPED   16
#define UIP_APPDATA_SIZE
 The buffer size available for user data in the uip_buf buffer.
+#define UIP_PROTO_ICMP   1
+#define UIP_PROTO_TCP   6
+#define UIP_PROTO_UDP   17
+#define UIP_PROTO_ICMP6   58
+#define UIP_IPH_LEN   20
+#define UIP_UDPH_LEN   8
+#define UIP_TCPH_LEN   20
+#define UIP_IPUDPH_LEN   (UIP_UDPH_LEN + UIP_IPH_LEN)
+#define UIP_IPTCPH_LEN   (UIP_TCPH_LEN + UIP_IPH_LEN)
+#define UIP_TCPIP_HLEN   UIP_IPTCPH_LEN

Typedefs

+typedef u16_t uip_ip4addr_t [2]
 Repressentation of an IP address.
+typedef u16_t uip_ip6addr_t [8]
+typedef uip_ip4addr_t uip_ipaddr_t

Functions

void uip_init (void)
 uIP initialization function.
void uip_setipid (u16_t id)
 uIP initialization function.
void uip_listen (u16_t port)
 Start listening to the specified port.
void uip_unlisten (u16_t port)
 Stop listening to the specified port.
uip_connuip_connect (uip_ipaddr_t *ripaddr, u16_t port)
 Connect to a remote host using TCP.
void uip_send (const void *data, int len)
 Send data on the current connection.
uip_udp_connuip_udp_new (uip_ipaddr_t *ripaddr, u16_t rport)
 Set up a new UDP connection.
u16_t htons (u16_t val)
 Convert 16-bit quantity from host byte order to network byte order.
+void uip_process (u8_t flag)
u16_t uip_chksum (u16_t *buf, u16_t len)
 Calculate the Internet checksum over a buffer.
u16_t uip_ipchksum (void)
 Calculate the IP header checksum of the packet header in uip_buf.
u16_t uip_tcpchksum (void)
 Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
u16_t uip_udpchksum (void)
 Calculate the UDP checksum of the packet in uip_buf and uip_appdata.

Variables

u8_t uip_buf [UIP_BUFSIZE+2]
 The uIP packet buffer.
void * uip_appdata
 Pointer to the application data in the packet buffer.
u16_t uip_len
 The length of the packet in the uip_buf buffer.
uip_connuip_conn
 Pointer to the current TCP connection.
+uip_conn uip_conns [UIP_CONNS]
+u8_t uip_acc32 [4]
 4-byte array used for the 32-bit sequence number calculations.
+uip_udp_connuip_udp_conn
 The current UDP connection.
+uip_udp_conn uip_udp_conns [UIP_UDP_CONNS]
uip_stats uip_stat
 The uIP TCP/IP statistics.
+u8_t uip_flags
+uip_ipaddr_t uip_hostaddr
+uip_ipaddr_t uip_netmask
+uip_ipaddr_t uip_draddr
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00136.png b/doc/html/a00136.png deleted file mode 100644 index 38b503c..0000000 Binary files a/doc/html/a00136.png and /dev/null differ diff --git a/doc/html/a00137.html b/doc/html/a00137.html new file mode 100644 index 0000000..1293889 --- /dev/null +++ b/doc/html/a00137.html @@ -0,0 +1,52 @@ + + +uIP 1.0: uip/uip_arch.h File Reference + + + + + + +

uip/uip_arch.h File Reference


Detailed Description

+Declarations of architecture specific functions. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file uip_arch.h. +

+#include "uip.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + +

Functions

void uip_add32 (u8_t *op32, u16_t op16)
 Carry out a 32-bit addition.
u16_t uip_chksum (u16_t *buf, u16_t len)
 Calculate the Internet checksum over a buffer.
u16_t uip_ipchksum (void)
 Calculate the IP header checksum of the packet header in uip_buf.
u16_t uip_tcpchksum (void)
 Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00137.png b/doc/html/a00137.png deleted file mode 100644 index 34ee2f2..0000000 Binary files a/doc/html/a00137.png and /dev/null differ diff --git a/doc/html/a00138.html b/doc/html/a00138.html new file mode 100644 index 0000000..b7845d5 --- /dev/null +++ b/doc/html/a00138.html @@ -0,0 +1,70 @@ + + +uIP 1.0: uip/uip_arp.c File Reference + + + + + + +

uip/uip_arp.c File Reference


Detailed Description

+Implementation of the ARP Address Resolution Protocol. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file uip_arp.c. +

+#include "uip_arp.h"
+#include <string.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

+#define ARP_REQUEST   1
+#define ARP_REPLY   2
+#define ARP_HWTYPE_ETH   1
+#define BUF   ((struct arp_hdr *)&uip_buf[0])
+#define IPBUF   ((struct ethip_hdr *)&uip_buf[0])

Functions

+void uip_arp_init (void)
 Initialize the ARP module.
void uip_arp_timer (void)
 Periodic ARP processing function.
void uip_arp_arpin (void)
 ARP processing for incoming ARP packets.
void uip_arp_out (void)
 Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00139.html b/doc/html/a00139.html new file mode 100644 index 0000000..00cb3b7 --- /dev/null +++ b/doc/html/a00139.html @@ -0,0 +1,77 @@ + + +uIP 1.0: uip/uip_arp.h File Reference + + + + + + +

uip/uip_arp.h File Reference


Detailed Description

+Macros and definitions for the ARP module. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+ +

+Definition in file uip_arp.h. +

+#include "uip.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Data Structures

struct  uip_eth_hdr
 The Ethernet header. More...

Defines

+#define UIP_ETHTYPE_ARP   0x0806
+#define UIP_ETHTYPE_IP   0x0800
+#define UIP_ETHTYPE_IP6   0x86dd
+#define uip_arp_ipin()
#define uip_setethaddr(eaddr)
 Specifiy the Ethernet MAC address.

Functions

+void uip_arp_init (void)
 Initialize the ARP module.
void uip_arp_arpin (void)
 ARP processing for incoming ARP packets.
void uip_arp_out (void)
 Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request.
void uip_arp_timer (void)
 Periodic ARP processing function.

Variables

+uip_eth_addr uip_ethaddr
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00140.html b/doc/html/a00140.html new file mode 100644 index 0000000..a413b00 --- /dev/null +++ b/doc/html/a00140.html @@ -0,0 +1,143 @@ + + +uIP 1.0: uip/uipopt.h File Reference + + + + + + +

uip/uipopt.h File Reference


Detailed Description

+Configuration options for uIP. +

+

Author:
Adam Dunkels <adam@dunkels.com>
+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. +

+Definition in file uipopt.h. +

+#include "uip-conf.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.

#define UIP_FIXEDADDR
 Determines if uIP should use a fixed IP address or not.
#define UIP_PINGADDRCONF
 Ping IP address asignment.
#define UIP_FIXEDETHADDR
 Specifies if the uIP ARP module should be compiled with a fixed Ethernet MAC address or not.

IP configuration options

#define UIP_TTL   64
 The IP TTL (time to live) of IP packets sent by uIP.
#define UIP_REASSEMBLY
 Turn on support for IP packet reassembly.
+#define UIP_REASS_MAXAGE   40
 The maximum time an IP fragment should wait in the reassembly buffer before it is dropped.

UDP configuration options

+#define UIP_UDP
 Toggles wether UDP support should be compiled in or not.
#define UIP_UDP_CHECKSUMS
 Toggles if UDP checksums should be used or not.
+#define UIP_UDP_CONNS
 The maximum amount of concurrent UDP connections.

TCP configuration options

#define UIP_ACTIVE_OPEN
 Determines if support for opening connections from uIP should be compiled in.
#define UIP_CONNS
 The maximum number of simultaneously open TCP connections.
#define UIP_LISTENPORTS
 The maximum number of simultaneously listening TCP ports.
#define UIP_URGDATA
 Determines if support for TCP urgent data notification should be compiled in.
#define UIP_RTO   3
 The initial retransmission timeout counted in timer pulses.
#define UIP_MAXRTX   8
 The maximum number of times a segment should be retransmitted before the connection should be aborted.
#define UIP_MAXSYNRTX   5
 The maximum number of times a SYN segment should be retransmitted before a connection request should be deemed to have been unsuccessful.
#define UIP_TCP_MSS   (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
 The TCP maximum segment size.
#define UIP_RECEIVE_WINDOW
 The size of the advertised receiver's window.
#define UIP_TIME_WAIT_TIMEOUT   120
 How long a connection should stay in the TIME_WAIT state.

ARP configuration options

#define UIP_ARPTAB_SIZE
 The size of the ARP table.
#define UIP_ARP_MAXAGE   120
 The maxium age of ARP table entries measured in 10ths of seconds.

General configuration options

#define UIP_BUFSIZE
 The size of the uIP packet buffer.
#define UIP_STATISTICS
 Determines if statistics support should be compiled in.
#define UIP_LOGGING
 Determines if logging of certain events should be compiled in.
#define UIP_BROADCAST
 Broadcast support.
#define UIP_LLH_LEN
 The link level header length.
void uip_log (char *msg)
 Print out a uIP log message.

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.

#define UIP_BYTE_ORDER
 The byte order of the CPU architecture on which uIP is to be run.

Defines

+#define UIP_LITTLE_ENDIAN   3412
+#define UIP_BIG_ENDIAN   1234
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00141.html b/doc/html/a00141.html new file mode 100644 index 0000000..4b0e595 --- /dev/null +++ b/doc/html/a00141.html @@ -0,0 +1,83 @@ + + +uIP 1.0: unix/uip-conf.h File Reference + + + + + + +

unix/uip-conf.h File Reference


Detailed Description

+An example uIP configuration file. +

+

Author:
Adam Dunkels <adam@sics.se>
+ +

+Definition in file uip-conf.h. +

+#include <inttypes.h>
+#include "webserver.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Project-specific configuration options

uIP has a number of configuration options that can be overridden for each project. These are kept in a project-specific uip-conf.h file and all configuration names have the prefix UIP_CONF.

+#define UIP_CONF_MAX_CONNECTIONS
 Maximum number of TCP connections.
+#define UIP_CONF_MAX_LISTENPORTS
 Maximum number of listening TCP ports.
+#define UIP_CONF_BUFFER_SIZE
 uIP buffer size.
+#define UIP_CONF_BYTE_ORDER
 CPU byte order.
+#define UIP_CONF_LOGGING
 Logging on or off.
+#define UIP_CONF_UDP
 UDP support on or off.
+#define UIP_CONF_UDP_CHECKSUMS
 UDP checksums on or off.
+#define UIP_CONF_STATISTICS
 uIP statistics on or off
typedef uint8_t u8_t
 8 bit datatype
typedef uint16_t u16_t
 16 bit datatype
typedef unsigned short uip_stats_t
 Statistics datatype.
+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00142.html b/doc/html/a00142.html new file mode 100644 index 0000000..c2db21d --- /dev/null +++ b/doc/html/a00142.html @@ -0,0 +1,690 @@ + + +uIP 1.0: Protothreads + + + + + +

Protothreads


Detailed Description

+Protothreads are a type of lightweight stackless threads designed for severly memory constrained systems such as deeply embedded systems or sensor network nodes. +

+Protothreads provides linear code execution for event-driven systems implemented in C. Protothreads can be used with or without an RTOS.

+Protothreads are a extremely lightweight, stackless type of threads that provides a blocking context on top of an event-driven system, without the overhead of per-thread stacks. The purpose of protothreads is to implement sequential flow of control without complex state machines or full multi-threading. Protothreads provides conditional blocking inside C functions.

+The advantage of protothreads over a purely event-driven approach is that protothreads provides a sequential code structure that allows for blocking functions. In purely event-driven systems, blocking must be implemented by manually breaking the function into two pieces - one for the piece of code before the blocking call and one for the code after the blocking call. This makes it hard to use control structures such as if() conditionals and while() loops.

+The advantage of protothreads over ordinary threads is that a protothread do not require a separate stack. In memory constrained systems, the overhead of allocating multiple stacks can consume large amounts of the available memory. In contrast, each protothread only requires between two and twelve bytes of state, depending on the architecture.

+

Note:
Because protothreads do not save the stack context across a blocking call, local variables are not preserved when the protothread blocks. This means that local variables should be used with utmost care - if in doubt, do not use local variables inside a protothread!
+Main features:

+

    +
  • No machine specific code - the protothreads library is pure C
+

+

    +
  • Does not use error-prone functions such as longjmp()
+

+

    +
  • Very small RAM overhead - only two bytes per protothread
+

+

    +
  • Can be used with or without an OS
+

+

    +
  • Provides blocking wait without full multi-threading or stack-switching
+

+Examples applications:

+

    +
  • Memory constrained systems
+

+

    +
  • Event-driven protocol stacks
+

+

    +
  • Deeply embedded systems
+

+

    +
  • Sensor network nodes
+

+The protothreads API consists of four basic operations: initialization: PT_INIT(), execution: PT_BEGIN(), conditional blocking: PT_WAIT_UNTIL() and exit: PT_END(). On top of these, two convenience functions are built: reversed condition blocking: PT_WAIT_WHILE() and protothread blocking: PT_WAIT_THREAD().

+

See also:
Protothreads API documentation
+The protothreads library is released under a BSD-style license that allows for both non-commercial and commercial usage. The only requirement is that credit is given.

+Authors

+The protothreads library was written by Adam Dunkels <adam@sics.se> with support from Oliver Schmidt <ol.sc@web.de>.

+Protothreads

+Protothreads are a extremely lightweight, stackless threads that provides a blocking context on top of an event-driven system, without the overhead of per-thread stacks. The purpose of protothreads is to implement sequential flow of control without using complex state machines or full multi-threading. Protothreads provides conditional blocking inside a C function.

+In memory constrained systems, such as deeply embedded systems, traditional multi-threading may have a too large memory overhead. In traditional multi-threading, each thread requires its own stack, that typically is over-provisioned. The stacks may use large parts of the available memory.

+The main advantage of protothreads over ordinary threads is that protothreads are very lightweight: a protothread does not require its own stack. Rather, all protothreads run on the same stack and context switching is done by stack rewinding. This is advantageous in memory constrained systems, where a stack for a thread might use a large part of the available memory. A protothread only requires only two bytes of memory per protothread. Moreover, protothreads are implemented in pure C and do not require any machine-specific assembler code.

+A protothread runs within a single C function and cannot span over other functions. A protothread may call normal C functions, but cannot block inside a called function. Blocking inside nested function calls is instead made by spawning a separate protothread for each potentially blocking function. The advantage of this approach is that blocking is explicit: the programmer knows exactly which functions that block that which functions the never blocks.

+Protothreads are similar to asymmetric co-routines. The main difference is that co-routines uses a separate stack for each co-routine, whereas protothreads are stackless. The most similar mechanism to protothreads are Python generators. These are also stackless constructs, but have a different purpose. Protothreads provides blocking contexts inside a C function, whereas Python generators provide multiple exit points from a generator function.

+Local variables

+
Note:
Because protothreads do not save the stack context across a blocking call, local variables are not preserved when the protothread blocks. This means that local variables should be used with utmost care - if in doubt, do not use local variables inside a protothread!
+

+Scheduling

+A protothread is driven by repeated calls to the function in which the protothread is running. Each time the function is called, the protothread will run until it blocks or exits. Thus the scheduling of protothreads is done by the application that uses protothreads.

+Implementation

+Protothreads are implemented using local continuations. A local continuation represents the current state of execution at a particular place in the program, but does not provide any call history or local variables. A local continuation can be set in a specific function to capture the state of the function. After a local continuation has been set can be resumed in order to restore the state of the function at the point where the local continuation was set.

+Local continuations can be implemented in a variety of ways:

+

    +
  1. by using machine specific assembler code,
  2. by using standard C constructs, or
  3. by using compiler extensions.
+

+The first way works by saving and restoring the processor state, except for stack pointers, and requires between 16 and 32 bytes of memory per protothread. The exact amount of memory required depends on the architecture.

+The standard C implementation requires only two bytes of state per protothread and utilizes the C switch() statement in a non-obvious way that is similar to Duff's device. This implementation does, however, impose a slight restriction to the code that uses protothreads in that the code cannot use switch() statements itself.

+Certain compilers has C extensions that can be used to implement protothreads. GCC supports label pointers that can be used for this purpose. With this implementation, protothreads require 4 bytes of RAM per protothread. +

+ + + + + + + +

+

+ + + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  pt.h
 Protothreads implementation.

Modules

 Local continuations
 Local continuations form the basis for implementing protothreads.

Data Structures

struct  pt

Initialization

#define PT_INIT(pt)
 Initialize a protothread.

Declaration and definition

#define PT_THREAD(name_args)
 Declaration of a protothread.
#define PT_BEGIN(pt)
 Declare the start of a protothread inside the C function implementing the protothread.
#define PT_END(pt)
 Declare the end of a protothread.

Blocked wait

#define PT_WAIT_UNTIL(pt, condition)
 Block and wait until condition is true.
#define PT_WAIT_WHILE(pt, cond)
 Block and wait while condition is true.

Hierarchical protothreads

#define PT_WAIT_THREAD(pt, thread)
 Block and wait until a child protothread completes.
#define PT_SPAWN(pt, child, thread)
 Spawn a child protothread and wait until it exits.

Exiting and restarting

#define PT_RESTART(pt)
 Restart the protothread.
#define PT_EXIT(pt)
 Exit the protothread.

Calling a protothread

#define PT_SCHEDULE(f)
 Schedule a protothread.

Yielding from a protothread

#define PT_YIELD(pt)
 Yield from the current protothread.
#define PT_YIELD_UNTIL(pt, cond)
 Yield from the protothread until a condition occurs.

Defines

+#define PT_WAITING   0
+#define PT_EXITED   1
+#define PT_ENDED   2
+#define PT_YIELDED   3
+


Define Documentation

+

+ + + + +
+ + + + + + + + + +
#define PT_BEGIN pt   ) 
+
+ + + + + +
+   + + +

+Declare the start of a protothread inside the C function implementing the protothread. +

+This macro is used to declare the starting point of a protothread. It should be placed at the start of the function in which the protothread runs. All C statements above the PT_BEGIN() invokation will be executed each time the protothread is scheduled.

+

Parameters:
+ + +
pt A pointer to the protothread control structure.
+
+
Examples:
+dhcpc.c.
+

+Definition at line 115 of file pt.h.

+

+ + + + +
+ + + + + + + + + +
#define PT_END pt   ) 
+
+ + + + + +
+   + + +

+Declare the end of a protothread. +

+This macro is used for declaring that a protothread ends. It must always be used together with a matching PT_BEGIN() macro.

+

Parameters:
+ + +
pt A pointer to the protothread control structure.
+
+
Examples:
+dhcpc.c.
+

+Definition at line 127 of file pt.h.

+

+ + + + +
+ + + + + + + + + +
#define PT_EXIT pt   ) 
+
+ + + + + +
+   + + +

+Exit the protothread. +

+This macro causes the protothread to exit. If the protothread was spawned by another protothread, the parent protothread will become unblocked and can continue to run.

+

Parameters:
+ + +
pt A pointer to the protothread control structure.
+
+ +

+Definition at line 246 of file pt.h.

+

+ + + + +
+ + + + + + + + + +
#define PT_INIT pt   ) 
+
+ + + + + +
+   + + +

+Initialize a protothread. +

+Initializes a protothread. Initialization must be done prior to starting to execute the protothread.

+

Parameters:
+ + +
pt A pointer to the protothread control structure.
+
+
See also:
PT_SPAWN()
+
Examples:
+dhcpc.c.
+

+Definition at line 80 of file pt.h. +

+Referenced by httpd_appcall().

+

+ + + + +
+ + + + + + + + + +
#define PT_RESTART pt   ) 
+
+ + + + + +
+   + + +

+Restart the protothread. +

+This macro will block and cause the running protothread to restart its execution at the place of the PT_BEGIN() call.

+

Parameters:
+ + +
pt A pointer to the protothread control structure.
+
+
Examples:
+dhcpc.c.
+

+Definition at line 229 of file pt.h.

+

+ + + + +
+ + + + + + + + + +
#define PT_SCHEDULE  ) 
+
+ + + + + +
+   + + +

+Schedule a protothread. +

+This function shedules a protothread. The return value of the function is non-zero if the protothread is running or zero if the protothread has exited.

+

Parameters:
+ + +
f The call to the C function implementing the protothread to be scheduled
+
+ +

+Definition at line 271 of file pt.h.

+

+ + + + +
+ + + + + + + + + + + + + + + +
#define PT_SPAWN pt,
child,
thread   ) 
+
+ + + + + +
+   + + +

+Spawn a child protothread and wait until it exits. +

+This macro spawns a child protothread and waits until it exits. The macro can only be used within a protothread.

+

Parameters:
+ + + + +
pt A pointer to the protothread control structure.
child A pointer to the child protothread's control structure.
thread The child protothread with arguments
+
+ +

+Definition at line 206 of file pt.h.

+

+ + + + +
+ + + + + + + + + +
#define PT_THREAD name_args   ) 
+
+ + + + + +
+   + + +

+Declaration of a protothread. +

+This macro is used to declare a protothread. All protothreads must be declared with this macro.

+

Parameters:
+ + +
name_args The name and arguments of the C function implementing the protothread.
+
+
Examples:
+dhcpc.c, and smtp.c.
+

+Definition at line 100 of file pt.h.

+

+ + + + +
+ + + + + + + + + + + + +
#define PT_WAIT_THREAD pt,
thread   ) 
+
+ + + + + +
+   + + +

+Block and wait until a child protothread completes. +

+This macro schedules a child protothread. The current protothread will block until the child protothread completes.

+

Note:
The child protothread must be manually initialized with the PT_INIT() function before this function is used.
+
Parameters:
+ + + +
pt A pointer to the protothread control structure.
thread The child protothread with arguments
+
+
See also:
PT_SPAWN()
+ +

+Definition at line 192 of file pt.h.

+

+ + + + +
+ + + + + + + + + + + + +
#define PT_WAIT_UNTIL pt,
condition   ) 
+
+ + + + + +
+   + + +

+Block and wait until condition is true. +

+This macro blocks the protothread until the specified condition is true.

+

Parameters:
+ + + +
pt A pointer to the protothread control structure.
condition The condition.
+
+
Examples:
+dhcpc.c.
+

+Definition at line 148 of file pt.h.

+

+ + + + +
+ + + + + + + + + + + + +
#define PT_WAIT_WHILE pt,
cond   ) 
+
+ + + + + +
+   + + +

+Block and wait while condition is true. +

+This function blocks and waits while condition is true. See PT_WAIT_UNTIL().

+

Parameters:
+ + + +
pt A pointer to the protothread control structure.
cond The condition.
+
+ +

+Definition at line 167 of file pt.h.

+

+ + + + +
+ + + + + + + + + +
#define PT_YIELD pt   ) 
+
+ + + + + +
+   + + +

+Yield from the current protothread. +

+This function will yield the protothread, thereby allowing other processing to take place in the system.

+

Parameters:
+ + +
pt A pointer to the protothread control structure.
+
+
Examples:
+dhcpc.c.
+

+Definition at line 290 of file pt.h.

+

+ + + + +
+ + + + + + + + + + + + +
#define PT_YIELD_UNTIL pt,
cond   ) 
+
+ + + + + +
+   + + +

+Yield from the protothread until a condition occurs. +

+

Parameters:
+ + + +
pt A pointer to the protothread control structure.
cond The condition.
+
+This function will yield the protothread, until the specified condition evaluates to true. +

+Definition at line 310 of file pt.h.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00143.html b/doc/html/a00143.html new file mode 100644 index 0000000..28224e0 --- /dev/null +++ b/doc/html/a00143.html @@ -0,0 +1,54 @@ + + +uIP 1.0: Applications + + + + + +

Applications


Detailed Description

+The uIP distribution contains a number of example applications that can be either used directory or studied when learning to develop applications for uIP. +

+ +

+ + + + + + + +

+

+ + + +

+

+ + + +

+

+ + + +

+

+ + + +

+


Modules

 DNS resolver
 The uIP DNS resolver functions are used to lookup a hostname and map it to a numerical IP address.
 SMTP E-mail sender
 The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is the standard way of sending and transfering e-mail on the Internet.
 Hello, world
 A small example showing how to write applications with protosockets.
 Web client
 This example shows a HTTP client that is able to download web pages and files from web servers.
 Web server
 The uIP web server is a very simplistic implementation of an HTTP server.
+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00144.html b/doc/html/a00144.html new file mode 100644 index 0000000..5cca5bb --- /dev/null +++ b/doc/html/a00144.html @@ -0,0 +1,328 @@ + + +uIP 1.0: uIP configuration functions + + + + + +

uIP configuration functions
+ +[The uIP TCP/IP stack] +


Detailed Description

+The uIP configuration functions are used for setting run-time parameters in uIP such as IP addresses. +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + +

Defines

#define uip_sethostaddr(addr)
 Set the IP address of this host.
#define uip_gethostaddr(addr)
 Get the IP address of this host.
#define uip_setdraddr(addr)
 Set the default router's IP address.
#define uip_setnetmask(addr)
 Set the netmask.
#define uip_getdraddr(addr)
 Get the default router's IP address.
#define uip_getnetmask(addr)
 Get the netmask.
#define uip_setethaddr(eaddr)
 Specifiy the Ethernet MAC address.
+


Define Documentation

+

+ + + + +
+ + + + + + + + + +
#define uip_getdraddr addr   ) 
+
+ + + + + +
+   + + +

+Get the default router's IP address. +

+

Parameters:
+ + +
addr A pointer to a uip_ipaddr_t variable that will be filled in with the IP address of the default router.
+
+ +

+Definition at line 161 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_gethostaddr addr   ) 
+
+ + + + + +
+   + + +

+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.

+Example:

 uip_ipaddr_t hostaddr;
+
+ uip_gethostaddr(&hostaddr);
+
Parameters:
+ + +
addr A pointer to a uip_ipaddr_t variable that will be filled in with the currently configured IP address.
+
+ +

+Definition at line 126 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_getnetmask addr   ) 
+
+ + + + + +
+   + + +

+Get the netmask. +

+

Parameters:
+ + +
addr A pointer to a uip_ipaddr_t variable that will be filled in with the value of the netmask.
+
+ +

+Definition at line 171 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_setdraddr addr   ) 
+
+ + + + + +
+   + + +

+Set the default router's IP address. +

+

Parameters:
+ + +
addr A pointer to a uip_ipaddr_t variable containing the IP address of the default router.
+
+
See also:
uip_ipaddr()
+ +

+Definition at line 138 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_setethaddr eaddr   ) 
+
+ + + + + +
+   + + +

+Specifiy the Ethernet MAC address. +

+The ARP code needs to know the MAC address of the Ethernet card in order to be able to respond to ARP queries and to generate working Ethernet headers.

+

Note:
This macro only specifies the Ethernet MAC address to the ARP code. It cannot be used to change the MAC address of the Ethernet card.
+
Parameters:
+ + +
eaddr A pointer to a struct uip_eth_addr containing the Ethernet MAC address of the Ethernet card.
+
+ +

+Definition at line 134 of file uip_arp.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_sethostaddr addr   ) 
+
+ + + + + +
+   + + +

+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.

+Example:

 uip_ipaddr_t addr;
+
+ uip_ipaddr(&addr, 192,168,1,2);
+ uip_sethostaddr(&addr);
+
Parameters:
+ + +
addr A pointer to an IP address of type uip_ipaddr_t;
+
+
See also:
uip_ipaddr()
+
Examples:
+dhcpc.c, example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 106 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_setnetmask addr   ) 
+
+ + + + + +
+   + + +

+Set the netmask. +

+

Parameters:
+ + +
addr A pointer to a uip_ipaddr_t variable containing the IP address of the netmask.
+
+
See also:
uip_ipaddr()
+ +

+Definition at line 150 of file uip.h.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00145.html b/doc/html/a00145.html new file mode 100644 index 0000000..d087f91 --- /dev/null +++ b/doc/html/a00145.html @@ -0,0 +1,106 @@ + + +uIP 1.0: uIP initialization functions + + + + + +

uIP initialization functions
+ +[The uIP TCP/IP stack] +


Detailed Description

+The uIP initialization functions are used for booting uIP. +

+ +

+ + + + + + + + + +

Functions

void uip_init (void)
 uIP initialization function.
void uip_setipid (u16_t id)
 uIP initialization function.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void uip_init void   ) 
+
+ + + + + +
+   + + +

+uIP initialization function. +

+This function should be called at boot up to initilize the uIP TCP/IP stack.

Examples:
+example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 379 of file uip.c. +

+References UIP_LISTENPORTS.

+

+ + + + +
+ + + + + + + + + +
void uip_setipid u16_t  id  ) 
+
+ + + + + +
+   + + +

+uIP initialization function. +

+This function may be used at boot time to set the initial ip_id. +

+Definition at line 181 of file uip.c.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00146.html b/doc/html/a00146.html new file mode 100644 index 0000000..33a3b5d --- /dev/null +++ b/doc/html/a00146.html @@ -0,0 +1,383 @@ + + +uIP 1.0: uIP device driver functions + + + + + +

uIP device driver functions
+ +[The uIP TCP/IP stack] +


Detailed Description

+These functions are used by a network device driver for interacting with uIP. +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

#define uip_input()
 Process an incoming packet.
#define uip_periodic(conn)
 Periodic processing for a connection identified by its number.
+#define uip_conn_active(conn)   (uip_conns[conn].tcpstateflags != UIP_CLOSED)
#define uip_periodic_conn(conn)
 Perform periodic processing for a connection identified by a pointer to its structure.
#define uip_poll_conn(conn)
 Reuqest that a particular connection should be polled.
#define uip_udp_periodic(conn)
 Periodic processing for a UDP connection identified by its number.
#define uip_udp_periodic_conn(conn)
 Periodic processing for a UDP connection identified by a pointer to its structure.

Variables

u8_t uip_buf [UIP_BUFSIZE+2]
 The uIP packet buffer.
+


Define Documentation

+

+ + + + +
+ + + + +  + + + + +
#define uip_input  ) 
+
+ + + + + +
+   + + +

+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.

  uip_len = devicedriver_poll();
+  if(uip_len > 0) {
+    uip_input();
+    if(uip_len > 0) {
+      devicedriver_send();
+    }
+  }
+

+

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:
  #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();
+      }
+    }
+
+
Examples:
+example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 257 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_periodic conn   ) 
+
+ + + + + +
+   + + +

+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:

  for(i = 0; i < UIP_CONNS; ++i) {
+    uip_periodic(i);
+    if(uip_len > 0) {
+      devicedriver_send();
+    }
+  }
+

+

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:
  for(i = 0; i < UIP_CONNS; ++i) {
+    uip_periodic(i);
+    if(uip_len > 0) {
+      uip_arp_out();
+      ethernet_devicedriver_send();
+    }
+  }
+
+
Parameters:
+ + +
conn The number of the connection which is to be periodically polled.
+
+
Examples:
+example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 301 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_periodic_conn conn   ) 
+
+ + + + + +
+   + + +

+Perform 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.

+

Parameters:
+ + +
conn A pointer to the uip_conn struct for the connection to be processed.
+
+ +

+Definition at line 323 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_poll_conn conn   ) 
+
+ + + + + +
+   + + +

+Reuqest that a particular connection should be polled. +

+Similar to uip_periodic_conn() but does not perform any timer processing. The application is polled for new data.

+

Parameters:
+ + +
conn A pointer to the uip_conn struct for the connection to be processed.
+
+ +

+Definition at line 337 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_udp_periodic conn   ) 
+
+ + + + + +
+   + + +

+Periodic processing for a UDP connection identified by its number. +

+This function is essentially the same as uip_periodic(), but for UDP connections. It is called in a similar fashion as the uip_periodic() function:

  for(i = 0; i < UIP_UDP_CONNS; i++) {
+    uip_udp_periodic(i);
+    if(uip_len > 0) {
+      devicedriver_send();
+    }
+  }
+

+

Note:
As for the uip_periodic() function, special care has to be taken when using uIP together with ARP and Ethernet:
  for(i = 0; i < UIP_UDP_CONNS; i++) {
+    uip_udp_periodic(i);
+    if(uip_len > 0) {
+      uip_arp_out();
+      ethernet_devicedriver_send();
+    }
+  }
+
+
Parameters:
+ + +
conn The number of the UDP connection to be processed.
+
+
Examples:
+example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 373 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_udp_periodic_conn conn   ) 
+
+ + + + + +
+   + + +

+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.

+

Parameters:
+ + +
conn A pointer to the uip_udp_conn struct for the connection to be processed.
+
+ +

+Definition at line 390 of file uip.h.

+


Variable Documentation

+

+ + + + +
+ + + + +
u8_t uip_buf[UIP_BUFSIZE+2]
+
+ + + + + +
+   + + +

+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:
 void
+ devicedriver_send(void)
+ {
+    hwsend(&uip_buf[0], UIP_LLH_LEN);
+    if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
+      hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
+    } else {
+      hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
+      hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
+    }
+ }
+
+ +

+Definition at line 139 of file uip.c. +

+Referenced by uip_process().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00147.html b/doc/html/a00147.html new file mode 100644 index 0000000..8e7f247 --- /dev/null +++ b/doc/html/a00147.html @@ -0,0 +1,1046 @@ + + +uIP 1.0: uIP application functions + + + + + +

uIP application functions
+ +[The uIP TCP/IP stack] +


Detailed Description

+Functions used by an application running of top of uIP. +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

+#define uip_outstanding(conn)   ((conn)->len)
#define uip_datalen()
 The length of any incoming data that is currently avaliable (if avaliable) in the uip_appdata buffer.
#define uip_urgdatalen()
 The length of any out-of-band data (urgent data) that has arrived on the connection.
#define uip_close()
 Close the current connection.
#define uip_abort()
 Abort the current connection.
#define uip_stop()
 Tell the sending host to stop sending data.
+#define uip_stopped(conn)
 Find out if the current connection has been previously stopped with uip_stop().
#define uip_restart()
 Restart the current connection, if is has previously been stopped with uip_stop().
#define uip_udpconnection()
 Is the current connection a UDP connection?
#define uip_newdata()
 Is new incoming data available?
#define uip_acked()
 Has previously sent data been acknowledged?
#define uip_connected()
 Has the connection just been connected?
#define uip_closed()
 Has the connection been closed by the other end?
#define uip_aborted()
 Has the connection been aborted by the other end?
#define uip_timedout()
 Has the connection timed out?
#define uip_rexmit()
 Do we need to retransmit previously data?
#define uip_poll()
 Is the connection being polled by uIP?
+#define uip_initialmss()
 Get the initial maxium segment size (MSS) of the current connection.
#define uip_mss()
 Get the current maxium segment size that can be sent on the current connection.
#define uip_udp_remove(conn)
 Removed a UDP connection.
#define uip_udp_bind(conn, port)
 Bind a UDP connection to a local port.
#define uip_udp_send(len)
 Send a UDP datagram of length len on the current connection.

Functions

void uip_listen (u16_t port)
 Start listening to the specified port.
void uip_unlisten (u16_t port)
 Stop listening to the specified port.
uip_connuip_connect (uip_ipaddr_t *ripaddr, u16_t port)
 Connect to a remote host using TCP.
void uip_send (const void *data, int len)
 Send data on the current connection.
uip_udp_connuip_udp_new (uip_ipaddr_t *ripaddr, u16_t rport)
 Set up a new UDP connection.
+


Define Documentation

+

+ + + + +
+ + + + +  + + + + +
#define uip_abort  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+webclient.c.
+

+Definition at line 581 of file uip.h. +

+Referenced by httpd_appcall(), and webclient_appcall().

+

+ + + + +
+ + + + +  + + + + +
#define uip_aborted  ) 
+
+ + + + + +
+   + + +

+Has the connection been aborted by the other end? +

+Non-zero if the current connection has been aborted (reset) by the remote host.

Examples:
+smtp.c, telnetd.c, and webclient.c.
+

+Definition at line 680 of file uip.h. +

+Referenced by httpd_appcall(), smtp_appcall(), and webclient_appcall().

+

+ + + + +
+ + + + +  + + + + +
#define uip_acked  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+telnetd.c, and webclient.c.
+

+Definition at line 648 of file uip.h. +

+Referenced by webclient_appcall().

+

+ + + + +
+ + + + +  + + + + +
#define uip_close  ) 
+
+ + + + + +
+   + + +

+Close the current connection. +

+This function will close the current connection in a nice way.

Examples:
+telnetd.c.
+

+Definition at line 570 of file uip.h.

+

+ + + + +
+ + + + +  + + + + +
#define uip_closed  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+smtp.c, telnetd.c, and webclient.c.
+

+Definition at line 670 of file uip.h. +

+Referenced by httpd_appcall(), smtp_appcall(), and webclient_appcall().

+

+ + + + +
+ + + + +  + + + + +
#define uip_connected  ) 
+
+ + + + + +
+   + + +

+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()).

Examples:
+hello-world.c, telnetd.c, and webclient.c.
+

+Definition at line 660 of file uip.h. +

+Referenced by hello_world_appcall(), httpd_appcall(), and webclient_appcall().

+

+ + + + +
+ + + + +  + + + + +
#define uip_datalen  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+dhcpc.c, telnetd.c, and webclient.c.
+

+Definition at line 550 of file uip.h.

+

+ + + + +
+ + + + +  + + + + +
#define uip_mss  ) 
+
+ + + + + +
+   + + +

+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()).

Examples:
+telnetd.c, and webclient.c.
+

+Definition at line 737 of file uip.h.

+

+ + + + +
+ + + + +  + + + + +
#define uip_newdata  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+dhcpc.c, resolv.c, telnetd.c, and webclient.c.
+

+Definition at line 637 of file uip.h. +

+Referenced by psock_newdata(), resolv_appcall(), and webclient_appcall().

+

+ + + + +
+ + + + +  + + + + +
#define uip_poll  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+resolv.c, telnetd.c, and webclient.c.
+

+Definition at line 716 of file uip.h. +

+Referenced by httpd_appcall(), resolv_appcall(), and webclient_appcall().

+

+ + + + +
+ + + + +  + + + + +
#define uip_restart  ) 
+
+ + + + + +
+   + + +

+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. +

+Definition at line 610 of file uip.h.

+

+ + + + +
+ + + + +  + + + + +
#define uip_rexmit  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+telnetd.c, and webclient.c.
+

+Definition at line 702 of file uip.h. +

+Referenced by webclient_appcall().

+

+ + + + +
+ + + + +  + + + + +
#define uip_stop  ) 
+
+ + + + + +
+   + + +

+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. +

+Definition at line 591 of file uip.h.

+

+ + + + +
+ + + + +  + + + + +
#define uip_timedout  ) 
+
+ + + + + +
+   + + +

+Has the connection timed out? +

+Non-zero if the current connection has been aborted due to too many retransmissions.

Examples:
+smtp.c, telnetd.c, and webclient.c.
+

+Definition at line 690 of file uip.h. +

+Referenced by httpd_appcall(), smtp_appcall(), and webclient_appcall().

+

+ + + + +
+ + + + + + + + + + + + +
#define uip_udp_bind conn,
port   ) 
+
+ + + + + +
+   + + +

+Bind a UDP connection to a local port. +

+

Parameters:
+ + + +
conn A pointer to the uip_udp_conn structure for the connection.
port The local port number, in network byte order.
+
+
Examples:
+dhcpc.c.
+

+Definition at line 787 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_udp_remove conn   ) 
+
+ + + + + +
+   + + +

+Removed a UDP connection. +

+

Parameters:
+ + +
conn A pointer to the uip_udp_conn structure for the connection.
+
+
Examples:
+resolv.c.
+

+Definition at line 775 of file uip.h. +

+Referenced by resolv_conf().

+

+ + + + +
+ + + + + + + + + +
#define uip_udp_send len   ) 
+
+ + + + + +
+   + + +

+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.

+

Parameters:
+ + +
len The length of the data in the uip_buf buffer.
+
+
Examples:
+resolv.c.
+

+Definition at line 800 of file uip.h.

+

+ + + + +
+ + + + +  + + + + +
#define uip_udpconnection  ) 
+
+ + + + + +
+   + + +

+Is the current connection a UDP connection? +

+This function checks whether the current connection is a UDP connection. +

+Definition at line 626 of file uip.h.

+

+ + + + +
+ + + + +  + + + + +
#define uip_urgdatalen  ) 
+
+ + + + + +
+   + + +

+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.
+ +

+Definition at line 561 of file uip.h.

+


Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
struct uip_conn* uip_connect uip_ipaddr_t ripaddr,
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.

+Since this function requires the port number to be in network byte order, a conversion using HTONS() or htons() is necessary.

+
 uip_ipaddr_t ipaddr;
+
+ uip_ipaddr(&ipaddr, 192,168,1,2);
+ uip_connect(&ipaddr, HTONS(80));
+

+

Parameters:
+ + + +
ripaddr The IP address of the remote hot.
port A 16-bit port number in network byte order.
+
+
Returns:
A pointer to the uIP connection identifier for the new connection, or NULL if no connection could be allocated.
+
Examples:
+smtp.c, and webclient.c.
+

+Definition at line 407 of file uip.c. +

+References htons(), uip_conn::lport, uip_conn::tcpstateflags, UIP_CLOSED, uip_conn, UIP_CONNS, and uip_conns. +

+Referenced by smtp_send(), and webclient_get().

+

+ + + + +
+ + + + + + + + + +
void uip_listen u16_t  port  ) 
+
+ + + + + +
+   + + +

+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.
+
 uip_listen(HTONS(80));
+

+

Parameters:
+ + +
port A 16-bit port number in network byte order.
+
+
Examples:
+hello-world.c, and telnetd.c.
+

+Definition at line 529 of file uip.c. +

+References UIP_LISTENPORTS. +

+Referenced by hello_world_init(), and httpd_init().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void uip_send const void *  data,
int  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.
+
Parameters:
+ + + +
data A pointer to the data which is to be sent.
len The maximum amount of data bytes to be sent.
+
+
Examples:
+dhcpc.c, telnetd.c, and webclient.c.
+

+Definition at line 1888 of file uip.c. +

+References uip_sappdata, and uip_slen.

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
struct uip_udp_conn* uip_udp_new uip_ipaddr_t ripaddr,
u16_t  rport
+
+ + + + + +
+   + + +

+Set up a new UDP connection. +

+This function sets up a new UDP connection. The function will automatically allocate an unused local port for the new connection. However, another port can be chosen by using the uip_udp_bind() call, after the uip_udp_new() function has been called.

+Example:

 uip_ipaddr_t addr;
+ struct uip_udp_conn *c;
+ 
+ uip_ipaddr(&addr, 192,168,2,1);
+ c = uip_udp_new(&addr, HTONS(12345));
+ if(c != NULL) {
+   uip_udp_bind(c, HTONS(12344));
+ }
+
Parameters:
+ + + +
ripaddr The IP address of the remote host.
rport The remote port number in network byte order.
+
+
Returns:
The uip_udp_conn structure for the new connection or NULL if no connection could be allocated.
+
Examples:
+dhcpc.c, and resolv.c.
+

+Definition at line 473 of file uip.c. +

+References htons(), uip_udp_conn::lport, uip_udp_conn, UIP_UDP_CONNS, and uip_udp_conns. +

+Referenced by resolv_conf().

+

+ + + + +
+ + + + + + + + + +
void uip_unlisten 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.
+

+

Parameters:
+ + +
port A 16-bit port number in network byte order.
+
+ +

+Definition at line 518 of file uip.c. +

+References UIP_LISTENPORTS.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00148.html b/doc/html/a00148.html new file mode 100644 index 0000000..16158a4 --- /dev/null +++ b/doc/html/a00148.html @@ -0,0 +1,634 @@ + + +uIP 1.0: uIP conversion functions + + + + + +

uIP conversion functions
+ +[The uIP TCP/IP stack] +


Detailed Description

+These functions can be used for converting between different data formats used by uIP. +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
 Construct an IP address from four bytes.
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
 Construct an IPv6 address from eight 16-bit words.
#define uip_ipaddr_copy(dest, src)
 Copy an IP address to another IP address.
#define uip_ipaddr_cmp(addr1, addr2)
 Compare two IP addresses.
#define uip_ipaddr_maskcmp(addr1, addr2, mask)
 Compare two IP addresses with netmasks.
#define uip_ipaddr_mask(dest, src, mask)
 Mask out the network part of an IP address.
#define uip_ipaddr1(addr)
 Pick the first octet of an IP address.
#define uip_ipaddr2(addr)
 Pick the second octet of an IP address.
#define uip_ipaddr3(addr)
 Pick the third octet of an IP address.
#define uip_ipaddr4(addr)
 Pick the fourth octet of an IP address.
#define HTONS(n)
 Convert 16-bit quantity from host byte order to network byte order.
+#define ntohs   htons

Functions

u16_t htons (u16_t val)
 Convert 16-bit quantity from host byte order to network byte order.
+


Define Documentation

+

+ + + + +
+ + + + + + + + + +
#define HTONS  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+dhcpc.c, hello-world.c, resolv.c, smtp.c, and telnetd.c.
+

+Definition at line 1070 of file uip.h. +

+Referenced by hello_world_init(), htons(), httpd_init(), resolv_appcall(), resolv_conf(), smtp_send(), uip_arp_arpin(), and uip_process().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#define uip_ip6addr addr,
addr0,
addr1,
addr2,
addr3,
addr4,
addr5,
addr6,
addr7   ) 
+
+ + + + + +
+   + + +

+Construct an IPv6 address from eight 16-bit words. +

+This function constructs an IPv6 address. +

+Definition at line 852 of file uip.h.

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + +
#define uip_ipaddr addr,
addr0,
addr1,
addr2,
addr3   ) 
+
+ + + + + +
+   + + +

+Construct an IP address from four bytes. +

+This function constructs an IP address of the type that uIP handles internally from four bytes. The function is handy for specifying IP addresses to use with e.g. the uip_connect() function.

+Example:

 uip_ipaddr_t ipaddr;
+ struct uip_conn *c;
+ 
+ uip_ipaddr(&ipaddr, 192,168,1,2);
+ c = uip_connect(&ipaddr, HTONS(80));
+

+

Parameters:
+ + + + + + +
addr A pointer to a uip_ipaddr_t variable that will be filled in with the IP address.
addr0 The first octet of the IP address.
addr1 The second octet of the IP address.
addr2 The third octet of the IP address.
addr3 The forth octet of the IP address.
+
+
Examples:
+dhcpc.c, example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 840 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_ipaddr1 addr   ) 
+
+ + + + + +
+   + + +

+Pick the first octet of an IP address. +

+Picks out the first octet of an IP address.

+Example:

 uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr1(&ipaddr);
+

+In the example above, the variable "octet" will contain the value 1.

Examples:
+dhcpc.c.
+

+Definition at line 995 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_ipaddr2 addr   ) 
+
+ + + + + +
+   + + +

+Pick the second octet of an IP address. +

+Picks out the second octet of an IP address.

+Example:

 uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr2(&ipaddr);
+

+In the example above, the variable "octet" will contain the value 2.

Examples:
+dhcpc.c.
+

+Definition at line 1015 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_ipaddr3 addr   ) 
+
+ + + + + +
+   + + +

+Pick the third octet of an IP address. +

+Picks out the third octet of an IP address.

+Example:

 uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr3(&ipaddr);
+

+In the example above, the variable "octet" will contain the value 3.

Examples:
+dhcpc.c.
+

+Definition at line 1035 of file uip.h.

+

+ + + + +
+ + + + + + + + + +
#define uip_ipaddr4 addr   ) 
+
+ + + + + +
+   + + +

+Pick the fourth octet of an IP address. +

+Picks out the fourth octet of an IP address.

+Example:

 uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr4(&ipaddr);
+

+In the example above, the variable "octet" will contain the value 4.

Examples:
+dhcpc.c.
+

+Definition at line 1055 of file uip.h.

+

+ + + + +
+ + + + + + + + + + + + +
#define uip_ipaddr_cmp addr1,
addr2   ) 
+
+ + + + + +
+   + + +

+Compare two IP addresses. +

+Compares two IP addresses.

+Example:

 uip_ipaddr_t ipaddr1, ipaddr2;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
+    printf("They are the same");
+ }
+

+

Parameters:
+ + + +
addr1 The first IP address.
addr2 The second IP address.
+
+ +

+Definition at line 911 of file uip.h. +

+Referenced by uip_arp_arpin(), uip_arp_out(), and uip_process().

+

+ + + + +
+ + + + + + + + + + + + +
#define uip_ipaddr_copy dest,
src   ) 
+
+ + + + + +
+   + + +

+Copy an IP address to another IP address. +

+Copies an IP address from one place to another.

+Example:

 uip_ipaddr_t ipaddr1, ipaddr2;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr_copy(&ipaddr2, &ipaddr1);
+

+

Parameters:
+ + + +
dest The destination for the copy.
src The source from where to copy.
+
+
Examples:
+smtp.c.
+

+Definition at line 882 of file uip.h. +

+Referenced by smtp_configure(), uip_arp_out(), and uip_process().

+

+ + + + +
+ + + + + + + + + + + + + + + +
#define uip_ipaddr_mask dest,
src,
mask   ) 
+
+ + + + + +
+   + + +

+Mask out the network part of an IP address. +

+Masks out the network part of an IP address, given the address and the netmask.

+Example:

 uip_ipaddr_t ipaddr1, ipaddr2, netmask;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr(&netmask, 255,255,255,0);
+ uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
+

+In the example above, the variable "ipaddr2" will contain the IP address 192.168.1.0.

+

Parameters:
+ + + + +
dest Where the result is to be placed.
src The IP address.
mask The netmask.
+
+ +

+Definition at line 972 of file uip.h.

+

+ + + + +
+ + + + + + + + + + + + + + + +
#define uip_ipaddr_maskcmp addr1,
addr2,
mask   ) 
+
+ + + + + +
+   + + +

+Compare two IP addresses with netmasks. +

+Compares two IP addresses with netmasks. The masks are used to mask out the bits that are to be compared.

+Example:

 uip_ipaddr_t ipaddr1, ipaddr2, mask;
+
+ uip_ipaddr(&mask, 255,255,255,0);
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr(&ipaddr2, 192,16,1,3);
+ if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {
+    printf("They are the same");
+ }
+

+

Parameters:
+ + + + +
addr1 The first IP address.
addr2 The second IP address.
mask The netmask.
+
+ +

+Definition at line 941 of file uip.h. +

+Referenced by uip_arp_out().

+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
u16_t htons u16_t  val  ) 
+
+ + + + + +
+   + + +

+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.

Examples:
+example-mainloop-with-arp.c, resolv.c, and webclient.c.
+

+Definition at line 1882 of file uip.c. +

+References HTONS. +

+Referenced by uip_chksum(), uip_connect(), uip_ipchksum(), uip_udp_new(), and webclient_get().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00149.html b/doc/html/a00149.html new file mode 100644 index 0000000..ad39b08 --- /dev/null +++ b/doc/html/a00149.html @@ -0,0 +1,68 @@ + + +uIP 1.0: Variables used in uIP device drivers + + + + + +

Variables used in uIP device drivers
+ +[The uIP TCP/IP stack] +


Detailed Description

+uIP has a few global variables that are used in device drivers for uIP. +

+ +

+ + + + + + +

Variables

u16_t uip_len
 The length of the packet in the uip_buf buffer.
+


Variable Documentation

+

+ + + + +
+ + + + +
u16_t uip_len
+
+ + + + + +
+   + + +

+The length of the packet in the uip_buf buffer. +

+The global variable uip_len holds the length of the packet in the uip_buf buffer.

+When the network device driver calls the uIP input function, uip_len should be set to the length of the packet in the uip_buf buffer.

+When sending packets, the device driver should use the contents of the uip_len variable to determine the length of the outgoing packet.

Examples:
+example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 155 of file uip.c. +

+Referenced by uip_arp_arpin(), uip_process(), and uip_split_output().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00150.html b/doc/html/a00150.html new file mode 100644 index 0000000..56806e0 --- /dev/null +++ b/doc/html/a00150.html @@ -0,0 +1,1248 @@ + + +uIP 1.0: The uIP TCP/IP stack + + + + + +

The uIP TCP/IP stack


Detailed Description

+uIP is an implementation of the TCP/IP protocol stack intended for small 8-bit and 16-bit microcontrollers. +

+uIP provides the necessary protocols for Internet communication, with a very small code footprint and RAM requirements - the uIP code size is on the order of a few kilobytes and RAM usage is on the order of a few hundred bytes. +

+ + + + + + + +

+

+ + + +

+

+ + + + +

+

+ + + +

+

+ + + +

+

+ + + +

+

+ + + +

+

+ + + +

+

+ + + +

+

+ + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  uip.h
 Header file for the uIP TCP/IP stack.
file  uip.c
 The uIP TCP/IP stack code.

Modules

 uIP configuration functions
 The uIP configuration functions are used for setting run-time parameters in uIP such as IP addresses.
 uIP initialization functions
 The uIP initialization functions are used for booting uIP.
 uIP device driver functions
 These functions are used by a network device driver for interacting with uIP.
 uIP application functions
 Functions used by an application running of top of uIP.
 uIP conversion functions
 These functions can be used for converting between different data formats used by uIP.
 Variables used in uIP device drivers
 uIP has a few global variables that are used in device drivers for uIP.
 uIP Address Resolution Protocol
 The Address Resolution Protocol ARP is used for mapping between IP addresses and link level addresses such as the Ethernet MAC addresses.
 uIP TCP throughput booster hack
 The basic uIP TCP implementation only allows each TCP connection to have a single TCP segment in flight at any given time.
 Architecture specific uIP functions
 The functions in the architecture specific module implement the IP check sum and 32-bit additions.

Data Structures

struct  uip_conn
 Representation of a uIP TCP connection. More...
struct  uip_udp_conn
 Representation of a uIP UDP connection. More...
struct  uip_stats
 The structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1. More...
struct  uip_tcpip_hdr
struct  uip_icmpip_hdr
struct  uip_udpip_hdr
struct  uip_eth_addr
 Representation of a 48-bit Ethernet address. More...

Defines

+#define UIP_ACKDATA   1
+#define UIP_NEWDATA   2
+#define UIP_REXMIT   4
+#define UIP_POLL   8
+#define UIP_CLOSE   16
+#define UIP_ABORT   32
+#define UIP_CONNECTED   64
+#define UIP_TIMEDOUT   128
+#define UIP_DATA   1
+#define UIP_TIMER   2
+#define UIP_POLL_REQUEST   3
+#define UIP_UDP_SEND_CONN   4
+#define UIP_UDP_TIMER   5
+#define UIP_CLOSED   0
+#define UIP_SYN_RCVD   1
+#define UIP_SYN_SENT   2
+#define UIP_ESTABLISHED   3
+#define UIP_FIN_WAIT_1   4
+#define UIP_FIN_WAIT_2   5
+#define UIP_CLOSING   6
+#define UIP_TIME_WAIT   7
+#define UIP_LAST_ACK   8
+#define UIP_TS_MASK   15
+#define UIP_STOPPED   16
#define UIP_APPDATA_SIZE
 The buffer size available for user data in the uip_buf buffer.
+#define UIP_PROTO_ICMP   1
+#define UIP_PROTO_TCP   6
+#define UIP_PROTO_UDP   17
+#define UIP_PROTO_ICMP6   58
+#define UIP_IPH_LEN   20
+#define UIP_UDPH_LEN   8
+#define UIP_TCPH_LEN   20
+#define UIP_IPUDPH_LEN   (UIP_UDPH_LEN + UIP_IPH_LEN)
+#define UIP_IPTCPH_LEN   (UIP_TCPH_LEN + UIP_IPH_LEN)
+#define UIP_TCPIP_HLEN   UIP_IPTCPH_LEN
+#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 TCP_OPT_END   0
+#define TCP_OPT_NOOP   1
+#define TCP_OPT_MSS   2
+#define TCP_OPT_MSS_LEN   4
+#define ICMP_ECHO_REPLY   0
+#define ICMP_ECHO   8
+#define ICMP6_ECHO_REPLY   129
+#define ICMP6_ECHO   128
+#define ICMP6_NEIGHBOR_SOLICITATION   135
+#define ICMP6_NEIGHBOR_ADVERTISEMENT   136
+#define ICMP6_FLAG_S   (1 << 6)
+#define ICMP6_OPTION_SOURCE_LINK_ADDRESS   1
+#define ICMP6_OPTION_TARGET_LINK_ADDRESS   2
+#define BUF   ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define FBUF   ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
+#define ICMPBUF   ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define UDPBUF   ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define UIP_STAT(s)
+#define UIP_LOG(m)

Typedefs

+typedef u16_t uip_ip4addr_t [2]
 Repressentation of an IP address.
+typedef u16_t uip_ip6addr_t [8]
+typedef uip_ip4addr_t uip_ipaddr_t

Functions

+void uip_process (u8_t flag)
u16_t uip_chksum (u16_t *buf, u16_t len)
 Calculate the Internet checksum over a buffer.
u16_t uip_ipchksum (void)
 Calculate the IP header checksum of the packet header in uip_buf.
u16_t uip_tcpchksum (void)
 Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
u16_t uip_udpchksum (void)
 Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
void uip_setipid (u16_t id)
 uIP initialization function.
void uip_add32 (u8_t *op32, u16_t op16)
 Carry out a 32-bit addition.
void uip_init (void)
 uIP initialization function.
uip_connuip_connect (uip_ipaddr_t *ripaddr, u16_t rport)
 Connect to a remote host using TCP.
uip_udp_connuip_udp_new (uip_ipaddr_t *ripaddr, u16_t rport)
 Set up a new UDP connection.
void uip_unlisten (u16_t port)
 Stop listening to the specified port.
void uip_listen (u16_t port)
 Start listening to the specified port.
u16_t htons (u16_t val)
 Convert 16-bit quantity from host byte order to network byte order.
void uip_send (const void *data, int len)
 Send data on the current connection.

Variables

void * uip_appdata
 Pointer to the application data in the packet buffer.
uip_connuip_conn
 Pointer to the current TCP connection.
+uip_conn uip_conns [UIP_CONNS]
+uip_udp_connuip_udp_conn
 The current UDP connection.
+uip_udp_conn uip_udp_conns [UIP_UDP_CONNS]
uip_stats uip_stat
 The uIP TCP/IP statistics.
+u8_t uip_flags
+uip_ipaddr_t uip_hostaddr
+uip_ipaddr_t uip_netmask
+uip_ipaddr_t uip_draddr
+uip_ipaddr_t uip_hostaddr
+uip_ipaddr_t uip_draddr
+uip_ipaddr_t uip_netmask
+uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}
u8_t uip_buf [UIP_BUFSIZE+2]
 The uIP packet buffer.
void * uip_appdata
 Pointer to the application data in the packet buffer.
+void * uip_sappdata
u16_t uip_len
 The length of the packet in the uip_buf buffer.
+u16_t uip_slen
+u8_t uip_flags
uip_connuip_conn
 Pointer to the current TCP connection.
+uip_conn uip_conns [UIP_CONNS]
+u16_t uip_listenports [UIP_LISTENPORTS]
+uip_udp_connuip_udp_conn
 The current UDP connection.
+uip_udp_conn uip_udp_conns [UIP_UDP_CONNS]
+u8_t uip_acc32 [4]
 4-byte array used for the 32-bit sequence number calculations.
+


Define Documentation

+

+ + + + +
+ + + + +
#define UIP_APPDATA_SIZE
+
+ + + + + +
+   + + +

+The buffer size available for user data in the uip_buf buffer. +

+This macro holds the available size for user data in the uip_buf buffer. The macro is intended to be used for checking bounds of available user data.

+Example:

 snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
+
+

+Definition at line 1506 of file uip.h.

+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
u16_t htons u16_t  val  ) 
+
+ + + + + +
+   + + +

+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. +

+Definition at line 1882 of file uip.c. +

+References HTONS. +

+Referenced by uip_chksum(), uip_connect(), uip_ipchksum(), uip_udp_new(), and webclient_get().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void uip_add32 u8_t op32,
u16_t  op16
+
+ + + + + +
+   + + +

+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).
+
Parameters:
+ + + +
op32 A pointer to a 4-byte array representing a 32-bit integer in network byte order (big endian).
op16 A 16-bit integer in host byte order.
+
+ +

+Definition at line 249 of file uip.c. +

+Referenced by uip_split_output().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
u16_t uip_chksum u16_t buf,
u16_t  len
+
+ + + + + +
+   + + +

+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.

+

Parameters:
+ + + +
buf A pointer to the buffer over which the checksum is to be computed.
len The length of the buffer over which the checksum is to be computed.
+
+
Returns:
The Internet checksum of the buffer.
+ +

+Definition at line 311 of file uip.c. +

+References htons().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
struct uip_conn* uip_connect uip_ipaddr_t ripaddr,
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.

+Since this function requires the port number to be in network byte order, a conversion using HTONS() or htons() is necessary.

+
 uip_ipaddr_t ipaddr;
+
+ uip_ipaddr(&ipaddr, 192,168,1,2);
+ uip_connect(&ipaddr, HTONS(80));
+

+

Parameters:
+ + + +
ripaddr The IP address of the remote hot.
port A 16-bit port number in network byte order.
+
+
Returns:
A pointer to the uIP connection identifier for the new connection, or NULL if no connection could be allocated.
+ +

+Definition at line 407 of file uip.c. +

+References htons(), uip_conn::lport, uip_conn::tcpstateflags, UIP_CLOSED, uip_conn, uip_conns, and UIP_CONNS. +

+Referenced by smtp_send(), and webclient_get().

+

+ + + + +
+ + + + + + + + + +
void uip_init void   ) 
+
+ + + + + +
+   + + +

+uIP initialization function. +

+This function should be called at boot up to initilize the uIP TCP/IP stack. +

+Definition at line 379 of file uip.c. +

+References UIP_LISTENPORTS.

+

+ + + + +
+ + + + + + + + + +
u16_t uip_ipchksum void   ) 
+
+ + + + + +
+   + + +

+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.

+

Returns:
The IP header checksum of the IP header in the uip_buf buffer.
+ +

+Definition at line 318 of file uip.c. +

+References DEBUG_PRINTF, htons(), UIP_IPH_LEN, and UIP_LLH_LEN. +

+Referenced by uip_process(), and uip_split_output().

+

+ + + + +
+ + + + + + + + + +
void uip_listen u16_t  port  ) 
+
+ + + + + +
+   + + +

+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.
+
 uip_listen(HTONS(80));
+

+

Parameters:
+ + +
port A 16-bit port number in network byte order.
+
+ +

+Definition at line 529 of file uip.c. +

+References UIP_LISTENPORTS. +

+Referenced by hello_world_init(), and httpd_init().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void uip_send const void *  data,
int  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.
+
Parameters:
+ + + +
data A pointer to the data which is to be sent.
len The maximum amount of data bytes to be sent.
+
+ +

+Definition at line 1888 of file uip.c. +

+References uip_sappdata, and uip_slen.

+

+ + + + +
+ + + + + + + + + +
void uip_setipid u16_t  id  ) 
+
+ + + + + +
+   + + +

+uIP initialization function. +

+This function may be used at boot time to set the initial ip_id. +

+Definition at line 181 of file uip.c.

+

+ + + + +
+ + + + + + + + + +
u16_t uip_tcpchksum 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.

+

Returns:
The TCP checksum of the TCP segment in uip_buf and pointed to by uip_appdata.
+ +

+Definition at line 364 of file uip.c. +

+References UIP_PROTO_TCP. +

+Referenced by uip_split_output().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
struct uip_udp_conn* uip_udp_new uip_ipaddr_t ripaddr,
u16_t  rport
+
+ + + + + +
+   + + +

+Set up a new UDP connection. +

+This function sets up a new UDP connection. The function will automatically allocate an unused local port for the new connection. However, another port can be chosen by using the uip_udp_bind() call, after the uip_udp_new() function has been called.

+Example:

 uip_ipaddr_t addr;
+ struct uip_udp_conn *c;
+ 
+ uip_ipaddr(&addr, 192,168,2,1);
+ c = uip_udp_new(&addr, HTONS(12345));
+ if(c != NULL) {
+   uip_udp_bind(c, HTONS(12344));
+ }
+
Parameters:
+ + + +
ripaddr The IP address of the remote host.
rport The remote port number in network byte order.
+
+
Returns:
The uip_udp_conn structure for the new connection or NULL if no connection could be allocated.
+ +

+Definition at line 473 of file uip.c. +

+References htons(), uip_udp_conn::lport, uip_udp_conn, uip_udp_conns, and UIP_UDP_CONNS. +

+Referenced by resolv_conf().

+

+ + + + +
+ + + + + + + + + +
u16_t uip_udpchksum void   ) 
+
+ + + + + +
+   + + +

+Calculate the UDP checksum of the packet in uip_buf and uip_appdata. +

+The UDP checksum is the Internet checksum of data contents of the UDP segment, and a pseudo-header as defined in RFC768.

+

Returns:
The UDP checksum of the UDP segment in uip_buf and pointed to by uip_appdata.
+ +

+Referenced by uip_process().

+

+ + + + +
+ + + + + + + + + +
void uip_unlisten 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.
+

+

Parameters:
+ + +
port A 16-bit port number in network byte order.
+
+ +

+Definition at line 518 of file uip.c. +

+References UIP_LISTENPORTS.

+


Variable Documentation

+

+ + + + +
+ + + + +
void* uip_appdata
+
+ + + + + +
+   + + +

+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(). +

+Definition at line 143 of file uip.c. +

+Referenced by uip_process(), and uip_split_output().

+

+ + + + +
+ + + + +
void* uip_appdata
+
+ + + + + +
+   + + +

+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().

Examples:
+dhcpc.c, resolv.c, telnetd.c, and webclient.c.
+

+Definition at line 143 of file uip.c. +

+Referenced by uip_process(), and uip_split_output().

+

+ + + + +
+ + + + +
u8_t uip_buf[UIP_BUFSIZE+2]
+
+ + + + + +
+   + + +

+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:
 void
+ devicedriver_send(void)
+ {
+    hwsend(&uip_buf[0], UIP_LLH_LEN);
+    if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
+      hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
+    } else {
+      hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
+      hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
+    }
+ }
+
+ +

+Definition at line 139 of file uip.c. +

+Referenced by uip_process().

+

+ + + + +
+ + + + +
struct uip_conn* uip_conn
+
+ + + + + +
+   + + +

+Pointer to the current TCP connection. +

+The uip_conn pointer can be used to access the current TCP connection. +

+Definition at line 163 of file uip.c. +

+Referenced by uip_connect().

+

+ + + + +
+ + + + +
struct uip_conn* uip_conn
+
+ + + + + +
+   + + +

+Pointer to the current TCP connection. +

+The uip_conn pointer can be used to access the current TCP connection.

Examples:
+hello-world.c, smtp.c, and webclient.c.
+

+Definition at line 163 of file uip.c. +

+Referenced by uip_connect().

+

+ + + + +
+ + + + +
u16_t uip_len
+
+ + + + + +
+   + + +

+The length of the packet in the uip_buf buffer. +

+The global variable uip_len holds the length of the packet in the uip_buf buffer.

+When the network device driver calls the uIP input function, uip_len should be set to the length of the packet in the uip_buf buffer.

+When sending packets, the device driver should use the contents of the uip_len variable to determine the length of the outgoing packet. +

+Definition at line 155 of file uip.c. +

+Referenced by uip_arp_arpin(), uip_process(), and uip_split_output().

+

+ + + + +
+ + + + +
struct uip_stats uip_stat
+
+ + + + + +
+   + + +

+The uIP TCP/IP statistics. +

+This is the variable in which the uIP TCP/IP statistics are gathered. +

+Referenced by uip_process().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00151.html b/doc/html/a00151.html new file mode 100644 index 0000000..aa144cf --- /dev/null +++ b/doc/html/a00151.html @@ -0,0 +1,221 @@ + + +uIP 1.0: Architecture specific uIP functions + + + + + +

Architecture specific uIP functions
+ +[The uIP TCP/IP stack] +


Detailed Description

+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. +

+ + + + + + + +

+

+ + + + + + + + + + + + + + + + +

Files

file  uip_arch.h
 Declarations of architecture specific functions.

Functions

void uip_add32 (u8_t *op32, u16_t op16)
 Carry out a 32-bit addition.
u16_t uip_chksum (u16_t *buf, u16_t len)
 Calculate the Internet checksum over a buffer.
u16_t uip_ipchksum (void)
 Calculate the IP header checksum of the packet header in uip_buf.
u16_t uip_tcpchksum (void)
 Calculate the TCP checksum of the packet in uip_buf and uip_appdata.

Variables

+u8_t uip_acc32 [4]
 4-byte array used for the 32-bit sequence number calculations.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void uip_add32 u8_t op32,
u16_t  op16
+
+ + + + + +
+   + + +

+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).
+
Parameters:
+ + + +
op32 A pointer to a 4-byte array representing a 32-bit integer in network byte order (big endian).
op16 A 16-bit integer in host byte order.
+
+ +

+Definition at line 249 of file uip.c. +

+Referenced by uip_split_output().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
u16_t uip_chksum u16_t buf,
u16_t  len
+
+ + + + + +
+   + + +

+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.
+
Parameters:
+ + + +
buf A pointer to the buffer over which the checksum is to be computed.
len The length of the buffer over which the checksum is to be computed.
+
+
Returns:
The Internet checksum of the buffer.
+
+

+ + + + +
+ + + + + + + + + +
u16_t uip_ipchksum void   ) 
+
+ + + + + +
+   + + +

+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.

+

Returns:
The IP header checksum of the IP header in the uip_buf buffer.
+
+

+ + + + +
+ + + + + + + + + +
u16_t uip_tcpchksum 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.
+
Returns:
The TCP checksum of the TCP segment in uip_buf and pointed to by uip_appdata.
+
+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00152.html b/doc/html/a00152.html new file mode 100644 index 0000000..b44513c --- /dev/null +++ b/doc/html/a00152.html @@ -0,0 +1,205 @@ + + +uIP 1.0: uIP Address Resolution Protocol + + + + + +

uIP Address Resolution Protocol
+ +[The uIP TCP/IP stack] +


Detailed Description

+The Address Resolution Protocol ARP is used for mapping between IP addresses and link level addresses such as the Ethernet MAC addresses. +

+ARP uses broadcast queries to ask for the link level address of a known IP address and the host which is configured with the IP address for which the query was meant, will respond with its link level address.

+

Note:
This ARP implementation only supports Ethernet.
+ +

+ + + + + + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  uip_arp.h
 Macros and definitions for the ARP module.
file  uip_arp.c
 Implementation of the ARP Address Resolution Protocol.

Data Structures

struct  uip_eth_hdr
 The Ethernet header. More...

Defines

+#define UIP_ETHTYPE_ARP   0x0806
+#define UIP_ETHTYPE_IP   0x0800
+#define UIP_ETHTYPE_IP6   0x86dd
+#define uip_arp_ipin()
+#define ARP_REQUEST   1
+#define ARP_REPLY   2
+#define ARP_HWTYPE_ETH   1
+#define BUF   ((struct arp_hdr *)&uip_buf[0])
+#define IPBUF   ((struct ethip_hdr *)&uip_buf[0])

Functions

+void uip_arp_init (void)
 Initialize the ARP module.
void uip_arp_arpin (void)
 ARP processing for incoming ARP packets.
void uip_arp_out (void)
 Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request.
void uip_arp_timer (void)
 Periodic ARP processing function.

Variables

+uip_eth_addr uip_ethaddr
+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void uip_arp_arpin void   ) 
+
+ + + + + +
+   + + +

+ARP processing for incoming ARP packets. +

+This function should be called by the device driver when an ARP packet has been received. The function will act differently depending on the ARP packet type: if it is a reply for a request that we previously sent out, the ARP cache will be filled in with the values from the ARP reply. If the incoming ARP packet is an ARP request for our IP address, an ARP reply packet is created and put into the uip_buf[] buffer.

+When the function returns, the value of the global variable uip_len indicates whether the device driver should send out a packet or not. If uip_len is zero, no packet should be sent. If uip_len is non-zero, it contains the length of the outbound packet that is present in the uip_buf[] buffer.

+This function expects an ARP packet with a prepended Ethernet header in the uip_buf[] buffer, and the length of the packet in the global variable uip_len.

Examples:
+example-mainloop-with-arp.c.
+

+Definition at line 278 of file uip_arp.c. +

+References uip_eth_addr::addr, ARP_REPLY, ARP_REQUEST, BUF, HTONS, uip_ethaddr, UIP_ETHTYPE_ARP, uip_hostaddr, uip_ipaddr_cmp, and uip_len.

+

+ + + + +
+ + + + + + + + + +
void uip_arp_out void   ) 
+
+ + + + + +
+   + + +

+Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request. +

+This function should be called before sending out an IP packet. The function checks the destination IP address of the IP packet to see what Ethernet MAC address that should be used as a destination MAC address on the Ethernet.

+If the destination IP address is in the local network (determined by logical ANDing of netmask and our IP address), the function checks the ARP cache to see if an entry for the destination IP address is found. If so, an Ethernet header is prepended and the function returns. If no ARP cache entry is found for the destination IP address, the packet in the uip_buf[] is replaced by an ARP request packet for the IP address. The IP packet is dropped and it is assumed that they higher level protocols (e.g., TCP) eventually will retransmit the dropped packet.

+If the destination IP address is not on the local network, the IP address of the default router is used instead.

+When the function returns, a packet is present in the uip_buf[] buffer, and the length of the packet is in the global variable uip_len.

Examples:
+example-mainloop-with-arp.c.
+

+Definition at line 354 of file uip_arp.c. +

+References uip_eth_addr::addr, IPBUF, UIP_ARPTAB_SIZE, uip_draddr, uip_hostaddr, uip_ipaddr_cmp, uip_ipaddr_copy, and uip_ipaddr_maskcmp.

+

+ + + + +
+ + + + + + + + + +
void uip_arp_timer void   ) 
+
+ + + + + +
+   + + +

+Periodic ARP processing function. +

+This function performs periodic timer processing in the ARP module and should be called at regular intervals. The recommended interval is 10 seconds between the calls.

Examples:
+example-mainloop-with-arp.c.
+

+Definition at line 142 of file uip_arp.c. +

+References UIP_ARP_MAXAGE, and UIP_ARPTAB_SIZE.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00153.html b/doc/html/a00153.html new file mode 100644 index 0000000..e303995 --- /dev/null +++ b/doc/html/a00153.html @@ -0,0 +1,1059 @@ + + +uIP 1.0: Configuration options for uIP + + + + + +

Configuration options for uIP


Detailed Description

+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.

+

Note:
Most of the configuration options in the uipopt.h should not be changed, but rather the per-project uip-conf.h file.
+ +

+ + + + + + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  uip-conf.h
 An example uIP configuration file.
file  uipopt.h
 Configuration options for uIP.

Project-specific configuration options

uIP has a number of configuration options that can be overridden for each project. These are kept in a project-specific uip-conf.h file and all configuration names have the prefix UIP_CONF.

+#define UIP_CONF_MAX_CONNECTIONS
 Maximum number of TCP connections.
+#define UIP_CONF_MAX_LISTENPORTS
 Maximum number of listening TCP ports.
+#define UIP_CONF_BUFFER_SIZE
 uIP buffer size.
+#define UIP_CONF_BYTE_ORDER
 CPU byte order.
+#define UIP_CONF_LOGGING
 Logging on or off.
+#define UIP_CONF_UDP
 UDP support on or off.
+#define UIP_CONF_UDP_CHECKSUMS
 UDP checksums on or off.
+#define UIP_CONF_STATISTICS
 uIP statistics on or off
typedef uint8_t u8_t
 8 bit datatype
typedef uint16_t u16_t
 16 bit datatype
typedef unsigned short uip_stats_t
 Statistics datatype.

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.

#define UIP_FIXEDADDR
 Determines if uIP should use a fixed IP address or not.
#define UIP_PINGADDRCONF
 Ping IP address asignment.
#define UIP_FIXEDETHADDR
 Specifies if the uIP ARP module should be compiled with a fixed Ethernet MAC address or not.

IP configuration options

#define UIP_TTL   64
 The IP TTL (time to live) of IP packets sent by uIP.
#define UIP_REASSEMBLY
 Turn on support for IP packet reassembly.
+#define UIP_REASS_MAXAGE   40
 The maximum time an IP fragment should wait in the reassembly buffer before it is dropped.

UDP configuration options

+#define UIP_UDP
 Toggles wether UDP support should be compiled in or not.
#define UIP_UDP_CHECKSUMS
 Toggles if UDP checksums should be used or not.
+#define UIP_UDP_CONNS
 The maximum amount of concurrent UDP connections.

TCP configuration options

#define UIP_ACTIVE_OPEN
 Determines if support for opening connections from uIP should be compiled in.
#define UIP_CONNS
 The maximum number of simultaneously open TCP connections.
#define UIP_LISTENPORTS
 The maximum number of simultaneously listening TCP ports.
#define UIP_URGDATA
 Determines if support for TCP urgent data notification should be compiled in.
#define UIP_RTO   3
 The initial retransmission timeout counted in timer pulses.
#define UIP_MAXRTX   8
 The maximum number of times a segment should be retransmitted before the connection should be aborted.
#define UIP_MAXSYNRTX   5
 The maximum number of times a SYN segment should be retransmitted before a connection request should be deemed to have been unsuccessful.
#define UIP_TCP_MSS   (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
 The TCP maximum segment size.
#define UIP_RECEIVE_WINDOW
 The size of the advertised receiver's window.
#define UIP_TIME_WAIT_TIMEOUT   120
 How long a connection should stay in the TIME_WAIT state.

ARP configuration options

#define UIP_ARPTAB_SIZE
 The size of the ARP table.
#define UIP_ARP_MAXAGE   120
 The maxium age of ARP table entries measured in 10ths of seconds.

General configuration options

#define UIP_BUFSIZE
 The size of the uIP packet buffer.
#define UIP_STATISTICS
 Determines if statistics support should be compiled in.
#define UIP_LOGGING
 Determines if logging of certain events should be compiled in.
#define UIP_BROADCAST
 Broadcast support.
#define UIP_LLH_LEN
 The link level header length.
void uip_log (char *msg)
 Print out a uIP log message.

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.

#define UIP_BYTE_ORDER
 The byte order of the CPU architecture on which uIP is to be run.

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 type of the application structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.

+The file containing the definitions must be included in the uipopt.h file.

+The following example illustrates how this can look.

void httpd_appcall(void);
+#define UIP_APPCALL     httpd_appcall
+
+struct httpd_state {
+  u8_t state;
+  u16_t count;
+  char *dataptr;
+  char *script;
+};
+typedef struct httpd_state uip_tcp_appstate_t
+


+#define UIP_APPCALL   smtp_appcall
 The name of the application function that uIP should call in response to TCP/IP events.
typedef smtp_state uip_tcp_appstate_t
 The type of the application state that is to be stored in the uip_conn structure.
typedef int uip_udp_appstate_t
 The type of the application state that is to be stored in the uip_conn structure.

Defines

+#define UIP_LITTLE_ENDIAN   3412
+#define UIP_BIG_ENDIAN   1234
+


Define Documentation

+

+ + + + +
+ + + + +
#define UIP_ACTIVE_OPEN
+
+ + + + + +
+   + + +

+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. +

+Definition at line 233 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_ARP_MAXAGE   120
+
+ + + + + +
+   + + +

+The maxium age of ARP table entries measured in 10ths of seconds. +

+An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD default). +

+Definition at line 358 of file uipopt.h. +

+Referenced by uip_arp_timer().

+

+ + + + +
+ + + + +
#define UIP_ARPTAB_SIZE
+
+ + + + + +
+   + + +

+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. +

+Definition at line 349 of file uipopt.h. +

+Referenced by uip_arp_init(), uip_arp_out(), and uip_arp_timer().

+

+ + + + +
+ + + + +
#define UIP_BROADCAST
+
+ + + + + +
+   + + +

+Broadcast support. +

+This flag configures IP broadcast support. This is useful only together with UDP. +

+Definition at line 423 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_BUFSIZE
+
+ + + + + +
+   + + +

+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. +

+Definition at line 379 of file uipopt.h. +

+Referenced by uip_split_output().

+

+ + + + +
+ + + + +
#define UIP_BYTE_ORDER
+
+ + + + + +
+   + + +

+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). +

+Definition at line 475 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_CONNS
+
+ + + + + +
+   + + +

+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.

Examples:
+example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 245 of file uipopt.h. +

+Referenced by uip_connect().

+

+ + + + +
+ + + + +
#define UIP_FIXEDADDR
+
+ + + + + +
+   + + +

+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. +

+Definition at line 97 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_FIXEDETHADDR
+
+ + + + + +
+   + + +

+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. +

+Definition at line 127 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_LISTENPORTS
+
+ + + + + +
+   + + +

+The maximum number of simultaneously listening TCP ports. +

+Each listening TCP port requires 2 bytes of memory. +

+Definition at line 259 of file uipopt.h. +

+Referenced by uip_init(), uip_listen(), and uip_unlisten().

+

+ + + + +
+ + + + +
#define UIP_LLH_LEN
+
+ + + + + +
+   + + +

+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. +

+Definition at line 448 of file uipopt.h. +

+Referenced by uip_ipchksum(), uip_process(), and uip_split_output().

+

+ + + + +
+ + + + +
#define UIP_LOGGING
+
+ + + + + +
+   + + +

+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. +

+Definition at line 408 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_MAXRTX   8
+
+ + + + + +
+   + + +

+The maximum number of times a segment should be retransmitted before the connection should be aborted. +

+This should not be changed. +

+Definition at line 288 of file uipopt.h. +

+Referenced by uip_process().

+

+ + + + +
+ + + + +
#define UIP_MAXSYNRTX   5
+
+ + + + + +
+   + + +

+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. +

+Definition at line 297 of file uipopt.h. +

+Referenced by uip_process().

+

+ + + + +
+ + + + +
#define UIP_PINGADDRCONF
+
+ + + + + +
+   + + +

+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.
+ +

+Definition at line 114 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_REASSEMBLY
+
+ + + + + +
+   + + +

+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.
+ +

+Definition at line 156 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_RECEIVE_WINDOW
+
+ + + + + +
+   + + +

+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. +

+Definition at line 317 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_RTO   3
+
+ + + + + +
+   + + +

+The initial retransmission timeout counted in timer pulses. +

+This should not be changed. +

+Definition at line 280 of file uipopt.h. +

+Referenced by uip_process().

+

+ + + + +
+ + + + +
#define UIP_STATISTICS
+
+ + + + + +
+   + + +

+Determines if statistics support should be compiled in. +

+The statistics is useful for debugging and to show the user. +

+Definition at line 393 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_TCP_MSS   (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
+
+ + + + + +
+   + + +

+The TCP maximum segment size. +

+This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. +

+Definition at line 305 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_TIME_WAIT_TIMEOUT   120
+
+ + + + + +
+   + + +

+How long a connection should stay in the TIME_WAIT state. +

+This configiration option has no real implication, and it should be left untouched. +

+Definition at line 328 of file uipopt.h. +

+Referenced by uip_process().

+

+ + + + +
+ + + + +
#define UIP_TTL   64
+
+ + + + + +
+   + + +

+The IP TTL (time to live) of IP packets sent by uIP. +

+This should normally not be changed. +

+Definition at line 141 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_UDP_CHECKSUMS
+
+ + + + + +
+   + + +

+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.
+ +

+Definition at line 195 of file uipopt.h.

+

+ + + + +
+ + + + +
#define UIP_URGDATA
+
+ + + + + +
+   + + +

+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. +

+Definition at line 273 of file uipopt.h.

+


Typedef Documentation

+

+ + + + +
+ + + + +
typedef uint16_t u16_t
+
+ + + + + +
+   + + +

+16 bit datatype +

+This typedef defines the 16-bit type used throughout uIP.

Examples:
+dhcpc.c, dhcpc.h, resolv.c, resolv.h, smtp.c, smtp.h, telnetd.c, and uip-conf.h.
+

+Definition at line 76 of file uip-conf.h.

+

+ + + + +
+ + + + +
typedef uint8_t u8_t
+
+ + + + + +
+   + + +

+8 bit datatype +

+This typedef defines the 8-bit type used throughout uIP.

Examples:
+dhcpc.c, dhcpc.h, resolv.c, smtp.h, telnetd.c, telnetd.h, and uip-conf.h.
+

+Definition at line 67 of file uip-conf.h.

+

+ + + + +
+ + + + +
typedef unsigned short uip_stats_t
+
+ + + + + +
+   + + +

+Statistics datatype. +

+This typedef defines the dataype used for keeping statistics in uIP. +

+Definition at line 86 of file uip-conf.h.

+

+ + + + +
+ + + + +
typedef uip_tcp_appstate_t
+
+ + + + + +
+   + + +

+The type of the application state that is to be stored in the uip_conn structure. +

+This usually is typedef:ed to a struct holding application state information.

Examples:
+smtp.h, telnetd.h, and webclient.h.
+

+Definition at line 98 of file smtp.h.

+

+ + + + +
+ + + + +
typedef uip_udp_appstate_t
+
+ + + + + +
+   + + +

+The type of the application state that is to be stored in the uip_conn structure. +

+This usually is typedef:ed to a struct holding application state information.

Examples:
+dhcpc.h.
+

+Definition at line 47 of file resolv.h.

+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void uip_log char *  msg  ) 
+
+ + + + + +
+   + + +

+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.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00154.html b/doc/html/a00154.html new file mode 100644 index 0000000..8c2a7bf --- /dev/null +++ b/doc/html/a00154.html @@ -0,0 +1,79 @@ + + +uIP 1.0: uIP TCP throughput booster hack + + + + + +

uIP TCP throughput booster hack
+ +[The uIP TCP/IP stack] +


Detailed Description

+The basic uIP TCP implementation only allows each TCP connection to have a single TCP segment in flight at any given time. +

+Because of the delayed ACK algorithm employed by most TCP receivers, uIP's limit on the amount of in-flight TCP segments seriously reduces the maximum achievable throughput for sending data from uIP.

+The uip-split module is a hack which tries to remedy this situation. By splitting maximum sized outgoing TCP segments into two, the delayed ACK algorithm is not invoked at TCP receivers. This improves the throughput when sending data from uIP by orders of magnitude.

+The uip-split module uses the uip-fw module (uIP IP packet forwarding) for sending packets. Therefore, the uip-fw module must be set up with the appropriate network interfaces for this module to work. +

+ + + + + + + +

+

+ + + +

Files

file  uip-split.h
 Module for splitting outbound TCP segments in two to avoid the delayed ACK throughput degradation.

Functions

void uip_split_output (void)
 Handle outgoing packets.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void uip_split_output void   ) 
+
+ + + + + +
+   + + +

+Handle outgoing packets. +

+This function inspects an outgoing packet in the uip_buf buffer and sends it out using the uip_fw_output() function. If the packet is a full-sized TCP segment it will be split into two segments and transmitted separately. This function should be called instead of the actual device driver output function, or the uip_fw_output() function.

+The headers of the outgoing packet is assumed to be in the uip_buf buffer and the payload is assumed to be wherever uip_appdata points. The length of the outgoing packet is assumed to be in the uip_len variable. +

+Definition at line 49 of file uip-split.c. +

+References BUF, uip_acc32, uip_add32(), uip_appdata, UIP_BUFSIZE, uip_ipchksum(), UIP_IPH_LEN, uip_len, UIP_LLH_LEN, UIP_PROTO_TCP, uip_tcpchksum(), and UIP_TCPIP_HLEN.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00155.html b/doc/html/a00155.html new file mode 100644 index 0000000..157811a --- /dev/null +++ b/doc/html/a00155.html @@ -0,0 +1,82 @@ + + +uIP 1.0: Local continuations + + + + + +

Local continuations
+ +[Protothreads] +


Detailed Description

+Local continuations form the basis for implementing protothreads. +

+A local continuation can be set in a specific function to capture the state of the function. After a local continuation has been set can be resumed in order to restore the state of the function at the point where the local continuation was set. +

+ + + + + + + +

+

+ + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + +

Files

file  lc.h
 Local continuations.
file  lc-switch.h
 Implementation of local continuations based on switch() statment.
file  lc-addrlabels.h
 Implementation of local continuations based on the "Labels as values" feature of gcc.

Defines

+#define __LC_SWTICH_H__
+#define LC_INIT(s)   s = 0;
+#define LC_RESUME(s)   switch(s) { case 0:
+#define LC_SET(s)   s = __LINE__; case __LINE__:
+#define LC_END(s)   }
+#define LC_INIT(s)   s = NULL
+#define LC_RESUME(s)
+#define LC_SET(s)   do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0)
+#define LC_END(s)

Typedefs

+typedef unsigned short lc_t
+typedef void * lc_t
+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00156.html b/doc/html/a00156.html new file mode 100644 index 0000000..9df0786 --- /dev/null +++ b/doc/html/a00156.html @@ -0,0 +1,237 @@ + + +uIP 1.0: Timer library + + + + + +

Timer library


Detailed Description

+The timer library provides functions for setting, resetting and restarting timers, and for checking if a timer has expired. +

+An application must "manually" check if its timers have expired; this is not done automatically.

+A timer is declared as a struct timer and all access to the timer is made by a pointer to the declared timer.

+

Note:
The timer library uses the Clock library to measure time. Intervals should be specified in the format used by the clock library.
+ +

+ + + + + + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + +

Files

file  timer.h
 Timer library header file.
file  timer.c
 Timer library implementation.

Data Structures

struct  timer
 A timer. More...

Functions

void timer_set (struct timer *t, clock_time_t interval)
 Set a timer.
void timer_reset (struct timer *t)
 Reset the timer with the same interval.
void timer_restart (struct timer *t)
 Restart the timer from the current point in time.
int timer_expired (struct timer *t)
 Check if a timer has expired.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
int timer_expired struct timer t  ) 
+
+ + + + + +
+   + + +

+Check if a timer has expired. +

+This function tests if a timer has expired and returns true or false depending on its status.

+

Parameters:
+ + +
t A pointer to the timer
+
+
Returns:
Non-zero if the timer has expired, zero otherwise.
+
Examples:
+dhcpc.c, example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 121 of file timer.c. +

+References clock_time(), interval, and start.

+

+ + + + +
+ + + + + + + + + +
void timer_reset struct timer t  ) 
+
+ + + + + +
+   + + +

+Reset the timer with the same interval. +

+This function resets the timer with the same interval that was given to the timer_set() function. The start point of the interval is the exact time that the timer last expired. Therefore, this function will cause the timer to be stable over time, unlike the timer_rester() function.

+

Parameters:
+ + +
t A pointer to the timer.
+
+
See also:
timer_restart()
+
Examples:
+example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 84 of file timer.c. +

+References interval, and start.

+

+ + + + +
+ + + + + + + + + +
void timer_restart struct timer t  ) 
+
+ + + + + +
+   + + +

+Restart the timer from the current point in time. +

+This function restarts a timer with the same interval that was given to the timer_set() function. The timer will start at the current time.

+

Note:
A periodic timer will drift if this function is used to reset it. For preioric timers, use the timer_reset() function instead.
+
Parameters:
+ + +
t A pointer to the timer.
+
+
See also:
timer_reset()
+ +

+Definition at line 104 of file timer.c. +

+References clock_time(), and start.

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void timer_set struct timer t,
clock_time_t  interval
+
+ + + + + +
+   + + +

+Set a timer. +

+This function is used to set a timer for a time sometime in the future. The function timer_expired() will evaluate to true after the timer has expired.

+

Parameters:
+ + + +
t A pointer to the timer
interval The interval before the timer expires.
+
+
Examples:
+dhcpc.c, example-mainloop-with-arp.c, and example-mainloop-without-arp.c.
+

+Definition at line 64 of file timer.c. +

+References clock_time(), interval, and start.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00157.html b/doc/html/a00157.html new file mode 100644 index 0000000..a89ac8d --- /dev/null +++ b/doc/html/a00157.html @@ -0,0 +1,108 @@ + + +uIP 1.0: Clock interface + + + + + +

Clock interface


Detailed Description

+The clock interface is the interface between the timer library and the platform specific clock functionality. +

+The clock interface must be implemented for each platform that uses the timer library.

+The clock interface does only one this: it measures time. The clock interface provides a macro, CLOCK_SECOND, which corresponds to one second of system time.

+

See also:
Timer library
+ +

+ + + + + + + + + + + + + +

Defines

+#define CLOCK_SECOND
 A second, measured in system clock time.

Functions

void clock_init (void)
 Initialize the clock library.
clock_time_t clock_time (void)
 Get the current clock time.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void clock_init void   ) 
+
+ + + + + +
+   + + +

+Initialize the clock library. +

+This function initializes the clock library and should be called from the main() function of the system.

+

+ + + + +
+ + + + + + + + + +
clock_time_t clock_time void   ) 
+
+ + + + + +
+   + + +

+Get the current clock time. +

+This function returns the current system clock time.

+

Returns:
The current clock time, measured in system ticks.
+ +

+Referenced by timer_expired(), timer_restart(), and timer_set().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00158.html b/doc/html/a00158.html new file mode 100644 index 0000000..4d56cce --- /dev/null +++ b/doc/html/a00158.html @@ -0,0 +1,693 @@ + + +uIP 1.0: Protosockets library + + + + + +

Protosockets library


Detailed Description

+The protosocket library provides an interface to the uIP stack that is similar to the traditional BSD socket interface. +

+Unlike programs written for the ordinary uIP event-driven interface, programs written with the protosocket library are executed in a sequential fashion and does not have to be implemented as explicit state machines.

+Protosockets only work with TCP connections.

+The protosocket library uses Protothreads protothreads to provide sequential control flow. This makes the protosockets lightweight in terms of memory, but also means that protosockets inherits the functional limitations of protothreads. Each protosocket lives only within a single function. Automatic variables (stack variables) are not retained across a protosocket library function call.

+

Note:
Because the protosocket library uses protothreads, local variables will not always be saved across a call to a protosocket library function. It is therefore advised that local variables are used with extreme care.
+The protosocket library provides functions for sending data without having to deal with retransmissions and acknowledgements, as well as functions for reading data without having to deal with data being split across more than one TCP segment.

+Because each protosocket runs as a protothread, the protosocket has to be started with a call to PSOCK_BEGIN() at the start of the function in which the protosocket is used. Similarly, the protosocket protothread can be terminated by a call to PSOCK_EXIT(). +

+ + + + + + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  psock.h
 Protosocket library header file.

Data Structures

struct  psock_buf
struct  psock
 The representation of a protosocket. More...

Defines

#define PSOCK_INIT(psock, buffer, buffersize)
 Initialize a protosocket.
#define PSOCK_BEGIN(psock)
 Start the protosocket protothread in a function.
#define PSOCK_SEND(psock, data, datalen)
 Send data.
#define PSOCK_SEND_STR(psock, str)
 Send a null-terminated string.
#define PSOCK_GENERATOR_SEND(psock, generator, arg)
 Generate data with a function and send it.
#define PSOCK_CLOSE(psock)
 Close a protosocket.
#define PSOCK_READBUF(psock)
 Read data until the buffer is full.
#define PSOCK_READTO(psock, c)
 Read data up to a specified character.
#define PSOCK_DATALEN(psock)
 The length of the data that was previously read.
#define PSOCK_EXIT(psock)
 Exit the protosocket's protothread.
#define PSOCK_CLOSE_EXIT(psock)
 Close a protosocket and exit the protosocket's protothread.
#define PSOCK_END(psock)
 Declare the end of a protosocket's protothread.
#define PSOCK_NEWDATA(psock)
 Check if new data has arrived on a protosocket.
#define PSOCK_WAIT_UNTIL(psock, condition)
 Wait until a condition is true.
+#define PSOCK_WAIT_THREAD(psock, condition)   PT_WAIT_THREAD(&((psock)->pt), (condition))

Functions

+u16_t psock_datalen (struct psock *psock)
+char psock_newdata (struct psock *s)
+


Define Documentation

+

+ + + + +
+ + + + + + + + + +
#define PSOCK_BEGIN psock   ) 
+
+ + + + + +
+   + + +

+Start the protosocket protothread in a function. +

+This macro starts the protothread associated with the protosocket and must come before other protosocket calls in the function it is used.

+

Parameters:
+ + +
psock (struct psock *) A pointer to the protosocket to be started.
+
+
Examples:
+hello-world.c, and smtp.c.
+

+Definition at line 158 of file psock.h.

+

+ + + + +
+ + + + + + + + + +
#define PSOCK_CLOSE psock   ) 
+
+ + + + + +
+   + + +

+Close a protosocket. +

+This macro closes a protosocket and can only be called from within the protothread in which the protosocket lives.

+

Parameters:
+ + +
psock (struct psock *) A pointer to the protosocket that is to be closed.
+
+
Examples:
+hello-world.c, and smtp.c.
+

+Definition at line 235 of file psock.h.

+

+ + + + +
+ + + + + + + + + +
#define PSOCK_CLOSE_EXIT psock   ) 
+
+ + + + + +
+   + + +

+Close a protosocket and exit the protosocket's protothread. +

+This macro closes a protosocket and exits the protosocket's protothread.

+

Parameters:
+ + +
psock (struct psock *) A pointer to the protosocket.
+
+ +

+Definition at line 308 of file psock.h.

+

+ + + + +
+ + + + + + + + + +
#define PSOCK_DATALEN psock   ) 
+
+ + + + + +
+   + + +

+The length of the data that was previously read. +

+This macro returns the length of the data that was previously read using PSOCK_READTO() or PSOCK_READ().

+

Parameters:
+ + +
psock (struct psock *) A pointer to the protosocket holding the data.
+
+ +

+Definition at line 281 of file psock.h.

+

+ + + + +
+ + + + + + + + + +
#define PSOCK_END psock   ) 
+
+ + + + + +
+   + + +

+Declare the end of a protosocket's protothread. +

+This macro is used for declaring that the protosocket's protothread ends. It must always be used together with a matching PSOCK_BEGIN() macro.

+

Parameters:
+ + +
psock (struct psock *) A pointer to the protosocket.
+
+
Examples:
+hello-world.c, and smtp.c.
+

+Definition at line 325 of file psock.h.

+

+ + + + +
+ + + + + + + + + +
#define PSOCK_EXIT psock   ) 
+
+ + + + + +
+   + + +

+Exit the protosocket's protothread. +

+This macro terminates the protothread of the protosocket and should almost always be used in conjunction with PSOCK_CLOSE().

+

See also:
PSOCK_CLOSE_EXIT()
+
Parameters:
+ + +
psock (struct psock *) A pointer to the protosocket.
+
+
Examples:
+smtp.c.
+

+Definition at line 297 of file psock.h.

+

+ + + + +
+ + + + + + + + + + + + + + + +
#define PSOCK_GENERATOR_SEND psock,
generator,
arg   ) 
+
+ + + + + +
+   + + +

+Generate data with a function and send it. +

+

Parameters:
+ + + + +
psock Pointer to the protosocket.
generator Pointer to the generator function
arg Argument to the generator function
+
+This function generates data and sends it over the protosocket. This can be used to dynamically generate data for a transmission, instead of generating the data in a buffer beforehand. This function reduces the need for buffer memory. The generator function is implemented by the application, and a pointer to the function is given as an argument with the call to PSOCK_GENERATOR_SEND().

+The generator function should place the generated data directly in the uip_appdata buffer, and return the length of the generated data. The generator function is called by the protosocket layer when the data first is sent, and once for every retransmission that is needed. +

+Definition at line 219 of file psock.h.

+

+ + + + +
+ + + + + + + + + + + + + + + +
#define PSOCK_INIT psock,
buffer,
buffersize   ) 
+
+ + + + + +
+   + + +

+Initialize a protosocket. +

+This macro initializes a protosocket and must be called before the protosocket is used. The initialization also specifies the input buffer for the protosocket.

+

Parameters:
+ + + + +
psock (struct psock *) A pointer to the protosocket to be initialized
buffer (char *) A pointer to the input buffer for the protosocket.
buffersize (unsigned int) The size of the input buffer.
+
+
Examples:
+hello-world.c, and smtp.c.
+

+Definition at line 144 of file psock.h. +

+Referenced by hello_world_appcall(), httpd_appcall(), and smtp_send().

+

+ + + + +
+ + + + + + + + + +
#define PSOCK_NEWDATA psock   ) 
+
+ + + + + +
+   + + +

+Check if new data has arrived on a protosocket. +

+This macro is used in conjunction with the PSOCK_WAIT_UNTIL() macro to check if data has arrived on a protosocket.

+

Parameters:
+ + +
psock (struct psock *) A pointer to the protosocket.
+
+ +

+Definition at line 339 of file psock.h.

+

+ + + + +
+ + + + + + + + + +
#define PSOCK_READBUF psock   ) 
+
+ + + + + +
+   + + +

+Read data until the buffer is full. +

+This macro will block waiting for data and read the data into the input buffer specified with the call to PSOCK_INIT(). Data is read until the buffer is full..

+

Parameters:
+ + +
psock (struct psock *) A pointer to the protosocket from which data should be read.
+
+ +

+Definition at line 250 of file psock.h.

+

+ + + + +
+ + + + + + + + + + + + +
#define PSOCK_READTO psock,
 ) 
+
+ + + + + +
+   + + +

+Read data up to a specified character. +

+This macro will block waiting for data and read the data into the input buffer specified with the call to PSOCK_INIT(). Data is only read until the specifieed character appears in the data stream.

+

Parameters:
+ + + +
psock (struct psock *) A pointer to the protosocket from which data should be read.
c (char) The character at which to stop reading.
+
+
Examples:
+hello-world.c, and smtp.c.
+

+Definition at line 268 of file psock.h.

+

+ + + + +
+ + + + + + + + + + + + + + + +
#define PSOCK_SEND psock,
data,
datalen   ) 
+
+ + + + + +
+   + + +

+Send data. +

+This macro sends data over a protosocket. The protosocket protothread blocks until all data has been sent and is known to have been received by the remote end of the TCP connection.

+

Parameters:
+ + + + +
psock (struct psock *) A pointer to the protosocket over which data is to be sent.
data (char *) A pointer to the data that is to be sent.
datalen (unsigned int) The length of the data that is to be sent.
+
+
Examples:
+smtp.c.
+

+Definition at line 178 of file psock.h.

+

+ + + + +
+ + + + + + + + + + + + +
#define PSOCK_SEND_STR psock,
str   ) 
+
+ + + + + +
+   + + +

+Send a null-terminated string. +

+

Parameters:
+ + + +
psock Pointer to the protosocket.
str The string to be sent.
+
+This function sends a null-terminated string over the protosocket.
Examples:
+hello-world.c, and smtp.c.
+

+Definition at line 191 of file psock.h.

+

+ + + + +
+ + + + + + + + + + + + +
#define PSOCK_WAIT_UNTIL psock,
condition   ) 
+
+ + + + + +
+   + + +

+Wait until a condition is true. +

+This macro blocks the protothread until the specified condition is true. The macro PSOCK_NEWDATA() can be used to check if new data arrives when the protosocket is waiting.

+Typically, this macro is used as follows:

+

 PT_THREAD(thread(struct psock *s, struct timer *t))
+ {
+   PSOCK_BEGIN(s);
+
+   PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));
+   
+   if(PSOCK_NEWDATA(s)) {
+     PSOCK_READTO(s, '\n');
+   } else {
+     handle_timed_out(s);
+   }
+   
+   PSOCK_END(s);
+ }
+

+

Parameters:
+ + + +
psock (struct psock *) A pointer to the protosocket.
condition The condition to wait for.
+
+ +

+Definition at line 372 of file psock.h.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00159.html b/doc/html/a00159.html new file mode 100644 index 0000000..3564fa9 --- /dev/null +++ b/doc/html/a00159.html @@ -0,0 +1,251 @@ + + +uIP 1.0: Memory block management functions + + + + + +

Memory block management functions


Detailed Description

+The memory block allocation routines provide a simple yet powerful set of functions for managing a set of memory blocks of fixed size. +

+A set of memory blocks is statically declared with the MEMB() macro. Memory blocks are allocated from the declared memory by the memb_alloc() function, and are deallocated with the memb_free() function.

+

Note:
Because of namespace clashes only one MEMB() can be declared per C module, and the name scope of a MEMB() memory block is local to each C module.
+The following example shows how to declare and use a memory block called "cmem" which has 8 chunks of memory with each memory chunk being 20 bytes large. +

+ + + + + + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + +

Files

file  memb.c
 Memory block allocation routines.
file  memb.h
 Memory block allocation routines.

Data Structures

struct  memb_blocks

Defines

+#define MEMB_CONCAT2(s1, s2)   s1##s2
+#define MEMB_CONCAT(s1, s2)   MEMB_CONCAT2(s1, s2)
#define MEMB(name, structure, num)
 Declare a memory block.

Functions

void memb_init (struct memb_blocks *m)
 Initialize a memory block that was declared with MEMB().
void * memb_alloc (struct memb_blocks *m)
 Allocate a memory block from a block of memory declared with MEMB().
char memb_free (struct memb_blocks *m, void *ptr)
 Deallocate a memory block from a memory block previously declared with MEMB().
+


Define Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + +
#define MEMB name,
structure,
num   ) 
+
+ + + + + +
+   + + +

+Value:

static char MEMB_CONCAT(name,_memb_count)[num]; \
+        static structure MEMB_CONCAT(name,_memb_mem)[num]; \
+        static struct memb_blocks name = {sizeof(structure), num, \
+                                          MEMB_CONCAT(name,_memb_count), \
+                                          (void *)MEMB_CONCAT(name,_memb_mem)}
+
Declare a memory block. +

+This macro is used to staticall declare a block of memory that can be used by the block allocation functions. The macro statically declares a C array with a size that matches the specified number of blocks and their individual sizes.

+Example:

MEMB(connections, sizeof(struct connection), 16);
+

+

Parameters:
+ + + + +
name The name of the memory block (later used with memb_init(), memb_alloc() and memb_free()).
size The size of each memory chunk, in bytes.
num The total number of memory chunks in the block.
+
+
Examples:
+telnetd.c.
+

+Definition at line 98 of file memb.h.

+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void * memb_alloc struct memb_blocks m  ) 
+
+ + + + + +
+   + + +

+Allocate a memory block from a block of memory declared with MEMB(). +

+

Parameters:
+ + +
m A memory block previosly declared with MEMB().
+
+
Examples:
+telnetd.c.
+

+Definition at line 59 of file memb.c. +

+References memb_blocks::count, memb_blocks::mem, memb_blocks::num, and memb_blocks::size.

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
char memb_free struct memb_blocks m,
void *  ptr
+
+ + + + + +
+   + + +

+Deallocate a memory block from a memory block previously declared with MEMB(). +

+

Parameters:
+ + + +
m m A memory block previosly declared with MEMB().
ptr A pointer to the memory block that is to be deallocated.
+
+
Returns:
The new reference count for the memory block (should be 0 if successfully deallocated) or -1 if the pointer "ptr" did not point to a legal memory block.
+
Examples:
+telnetd.c.
+

+Definition at line 79 of file memb.c. +

+References memb_blocks::count, memb_blocks::mem, and memb_blocks::size.

+

+ + + + +
+ + + + + + + + + +
void memb_init struct memb_blocks m  ) 
+
+ + + + + +
+   + + +

+Initialize a memory block that was declared with MEMB(). +

+

Parameters:
+ + +
m A memory block previosly declared with MEMB().
+
+
Examples:
+telnetd.c.
+

+Definition at line 52 of file memb.c. +

+References memb_blocks::count, memb_blocks::mem, memb_blocks::num, and memb_blocks::size.

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00160.html b/doc/html/a00160.html new file mode 100644 index 0000000..ffd42f9 --- /dev/null +++ b/doc/html/a00160.html @@ -0,0 +1,284 @@ + + +uIP 1.0: DNS resolver + + + + + +

DNS resolver
+ +[Applications] +


Detailed Description

+The uIP DNS resolver functions are used to lookup a hostname and map it to a numerical IP address. +

+It maintains a list of resolved hostnames that can be queried with the resolv_lookup() function. New hostnames can be resolved using the resolv_query() function.

+When a hostname has been resolved (or found to be non-existant), the resolver code calls a callback function called resolv_found() that must be implemented by the module that uses the resolver. +

+ + + + + + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  resolv.h
 DNS resolver code header file.
file  resolv.c
 DNS host name to IP address resolver.

Defines

+#define UIP_UDP_APPCALL   resolv_appcall
+#define NULL   (void *)0
+#define MAX_RETRIES   8
+#define RESOLV_ENTRIES   4

Functions

+void resolv_appcall (void)
void resolv_found (char *name, u16_t *ipaddr)
 Callback function which is called when a hostname is found.
void resolv_conf (u16_t *dnsserver)
 Configure which DNS server to use for queries.
u16_tresolv_getserver (void)
 Obtain the currently configured DNS server.
+void resolv_init (void)
 Initalize the resolver.
u16_tresolv_lookup (char *name)
 Look up a hostname in the array of known hostnames.
void resolv_query (char *name)
 Queues a name so that a question for the name will be sent out.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void resolv_conf u16_t dnsserver  ) 
+
+ + + + + +
+   + + +

+Configure which DNS server to use for queries. +

+

Parameters:
+ + +
dnsserver A pointer to a 4-byte representation of the IP address of the DNS server to be configured.
+
+
Examples:
+resolv.c, and resolv.h.
+

+Definition at line 438 of file resolv.c. +

+References HTONS, NULL, uip_udp_new(), and uip_udp_remove.

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void resolv_found char *  name,
u16_t ipaddr
+
+ + + + + +
+   + + +

+Callback function which is called when a hostname is found. +

+This function must be implemented by the module that uses the DNS resolver. It is called when a hostname is found, or when a hostname was not found.

+

Parameters:
+ + + +
name A pointer to the name that was looked up.
ipaddr A pointer to a 4-byte array containing the IP address of the hostname, or NULL if the hostname could not be found.
+
+
Examples:
+resolv.c, and resolv.h.
+

+ + + + +
+ + + + + + + + + +
u16_t * resolv_getserver void   ) 
+
+ + + + + +
+   + + +

+Obtain the currently configured DNS server. +

+

Returns:
A pointer to a 4-byte representation of the IP address of the currently configured DNS server or NULL if no DNS server has been configured.
+
Examples:
+resolv.c, and resolv.h.
+

+Definition at line 422 of file resolv.c. +

+References NULL, and uip_udp_conn::ripaddr.

+

+ + + + +
+ + + + + + + + + +
u16_t * resolv_lookup char *  name  ) 
+
+ + + + + +
+   + + +

+Look up a hostname in the array of known hostnames. +

+

Note:
This function only looks in the internal array of known hostnames, it does not send out a query for the hostname if none was found. The function resolv_query() can be used to send a query for a hostname.
+
Returns:
A pointer to a 4-byte representation of the hostname's IP address, or NULL if the hostname was not found in the array of hostnames.
+
Examples:
+resolv.c, resolv.h, and webclient.c.
+

+Definition at line 396 of file resolv.c. +

+References RESOLV_ENTRIES, and STATE_DONE. +

+Referenced by webclient_appcall(), and webclient_get().

+

+ + + + +
+ + + + + + + + + +
void resolv_query char *  name  ) 
+
+ + + + + +
+   + + +

+Queues a name so that a question for the name will be sent out. +

+

Parameters:
+ + +
name The hostname that is to be queried.
+
+
Examples:
+resolv.c, resolv.h, and webclient.c.
+

+Definition at line 350 of file resolv.c. +

+References RESOLV_ENTRIES, and STATE_UNUSED. +

+Referenced by webclient_appcall().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00161.html b/doc/html/a00161.html new file mode 100644 index 0000000..16d6fbb --- /dev/null +++ b/doc/html/a00161.html @@ -0,0 +1,257 @@ + + +uIP 1.0: SMTP E-mail sender + + + + + +

SMTP E-mail sender
+ +[Applications] +


Detailed Description

+The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is the standard way of sending and transfering e-mail on the Internet. +

+This simple example implementation is intended as an example of how to implement protocols in uIP, and is able to send out e-mail but has not been extensively tested. +

+ + + + + + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  smtp.h
 SMTP header file.
file  smtp.c
 SMTP example implementation.

Data Structures

struct  smtp_state

Defines

+#define SMTP_ERR_OK   0
 Error number that signifies a non-error condition.
+#define SMTP_SEND(to, cc, from, subject, msg)   smtp_send(to, cc, from, subject, msg, strlen(msg))
+#define ISO_nl   0x0a
+#define ISO_cr   0x0d
+#define ISO_period   0x2e
+#define ISO_2   0x32
+#define ISO_3   0x33
+#define ISO_4   0x34
+#define ISO_5   0x35

Functions

void smtp_done (unsigned char error)
 Callback function that is called when an e-mail transmission is done.
+void smtp_init (void)
+void smtp_appcall (void)
void smtp_configure (char *lhostname, void *server)
 Specificy an SMTP server and hostname.
unsigned char smtp_send (char *to, char *cc, char *from, char *subject, char *msg, u16_t msglen)
 Send an e-mail.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void smtp_configure char *  lhostname,
void *  server
+
+ + + + + +
+   + + +

+Specificy an SMTP server and hostname. +

+This function is used to configure the SMTP module with an SMTP server and the hostname of the host.

+

Parameters:
+ + + +
lhostname The hostname of the uIP host.
server A pointer to a 4-byte array representing the IP address of the SMTP server to be configured.
+
+ +

+Definition at line 216 of file smtp.c. +

+References uip_ipaddr_copy.

+

+ + + + +
+ + + + + + + + + +
void smtp_done unsigned char  error  ) 
+
+ + + + + +
+   + + +

+Callback function that is called when an e-mail transmission is done. +

+This function must be implemented by the module that uses the SMTP module.

+

Parameters:
+ + +
error The number of the error if an error occured, or SMTP_ERR_OK.
+
+
Examples:
+smtp.c, and smtp.h.
+

+Referenced by smtp_appcall().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
unsigned char smtp_send char *  to,
char *  cc,
char *  from,
char *  subject,
char *  msg,
u16_t  msglen
+
+ + + + + +
+   + + +

+Send an e-mail. +

+

Parameters:
+ + + + + + + +
to The e-mail address of the receiver of the e-mail.
cc The e-mail address of the CC: receivers of the e-mail.
from The e-mail address of the sender of the e-mail.
subject The subject of the e-mail.
msg The actual e-mail message.
msglen The length of the e-mail message.
+
+ +

+Definition at line 233 of file smtp.c. +

+References smtp_state::from, HTONS, smtp_state::msg, smtp_state::msglen, NULL, PSOCK_INIT, smtp_state::subject, smtp_state::to, and uip_connect().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00162.html b/doc/html/a00162.html new file mode 100644 index 0000000..8fada3b --- /dev/null +++ b/doc/html/a00162.html @@ -0,0 +1,56 @@ + + +uIP 1.0: Hello, world + + + + + +

Hello, world
+ +[Applications] +


Detailed Description

+A small example showing how to write applications with protosockets. +

+ +

+ + + + + + + +

+

+ + + +

+

+ + + + + + + + + + +

Files

file  hello-world.h
 Header file for an example of how to write uIP applications with protosockets.
file  hello-world.c
 An example of how to write uIP applications with protosockets.

Data Structures

struct  hello_world_state

Defines

+#define UIP_APPCALL   hello_world_appcall

Functions

+void hello_world_appcall (void)
+void hello_world_init (void)
+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00163.html b/doc/html/a00163.html new file mode 100644 index 0000000..96515e2 --- /dev/null +++ b/doc/html/a00163.html @@ -0,0 +1,533 @@ + + +uIP 1.0: Web client + + + + + +

Web client
+ +[Applications] +


Detailed Description

+This example shows a HTTP client that is able to download web pages and files from web servers. +

+It requires a number of callback functions to be implemented by the module that utilizes the code: webclient_datahandler(), webclient_connected(), webclient_timedout(), webclient_aborted(), webclient_closed(). +

+ + + + + + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  webclient.h
 Header file for the HTTP client.
file  webclient.c
 Implementation of the HTTP client.

Data Structures

struct  webclient_state

Defines

+#define WEBCLIENT_CONF_MAX_URLLEN   100
+#define UIP_APPCALL   webclient_appcall
+#define WEBCLIENT_TIMEOUT   100
+#define WEBCLIENT_STATE_STATUSLINE   0
+#define WEBCLIENT_STATE_HEADERS   1
+#define WEBCLIENT_STATE_DATA   2
+#define WEBCLIENT_STATE_CLOSE   3
+#define HTTPFLAG_NONE   0
+#define HTTPFLAG_OK   1
+#define HTTPFLAG_MOVED   2
+#define HTTPFLAG_ERROR   3
+#define ISO_nl   0x0a
+#define ISO_cr   0x0d
+#define ISO_space   0x20

Typedefs

+typedef webclient_state uip_tcp_appstate_t

Functions

void webclient_datahandler (char *data, u16_t len)
 Callback function that is called from the webclient code when HTTP data has been received.
void webclient_connected (void)
 Callback function that is called from the webclient code when the HTTP connection has been connected to the web server.
void webclient_timedout (void)
 Callback function that is called from the webclient code if the HTTP connection to the web server has timed out.
void webclient_aborted (void)
 Callback function that is called from the webclient code if the HTTP connection to the web server has been aborted by the web server.
void webclient_closed (void)
 Callback function that is called from the webclient code when the HTTP connection to the web server has been closed.
+void webclient_init (void)
 Initialize the webclient module.
unsigned char webclient_get (char *host, u16_t port, char *file)
 Open an HTTP connection to a web server and ask for a file using the GET method.
+void webclient_close (void)
 Close the currently open HTTP connection.
+void webclient_appcall (void)
char * webclient_mimetype (void)
 Obtain the MIME type of the current HTTP data stream.
char * webclient_filename (void)
 Obtain the filename of the current HTTP data stream.
char * webclient_hostname (void)
 Obtain the hostname of the current HTTP data stream.
unsigned short webclient_port (void)
 Obtain the port number of the current HTTP data stream.
+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void webclient_aborted void   ) 
+
+ + + + + +
+   + + +

+Callback function that is called from the webclient code if the HTTP connection to the web server has been aborted by the web server. +

+This function must be implemented by the module that uses the webclient code.

Examples:
+webclient.c, and webclient.h.
+

+Referenced by webclient_appcall().

+

+ + + + +
+ + + + + + + + + +
void webclient_closed void   ) 
+
+ + + + + +
+   + + +

+Callback function that is called from the webclient code when the HTTP connection to the web server has been closed. +

+This function must be implemented by the module that uses the webclient code.

Examples:
+webclient.c, and webclient.h.
+

+Referenced by webclient_appcall().

+

+ + + + +
+ + + + + + + + + +
void webclient_connected void   ) 
+
+ + + + + +
+   + + +

+Callback function that is called from the webclient code when the HTTP connection has been connected to the web server. +

+This function must be implemented by the module that uses the webclient code.

Examples:
+webclient.c, and webclient.h.
+

+Referenced by webclient_appcall().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + +
void webclient_datahandler char *  data,
u16_t  len
+
+ + + + + +
+   + + +

+Callback function that is called from the webclient code when HTTP data has been received. +

+This function must be implemented by the module that uses the webclient code. The function is called from the webclient module when HTTP data has been received. The function is not called when HTTP headers are received, only for the actual data.

+

Note:
This function is called many times, repetedly, when data is being received, and not once when all data has been received.
+
Parameters:
+ + + +
data A pointer to the data that has been received.
len The length of the data that has been received.
+
+
Examples:
+webclient.c, and webclient.h.
+

+Referenced by webclient_appcall().

+

+ + + + +
+ + + + + + + + + +
char * webclient_filename void   ) 
+
+ + + + + +
+   + + +

+Obtain the filename of the current HTTP data stream. +

+The filename of an HTTP request may be changed by the web server, and may therefore not be the same as when the original GET request was made with webclient_get(). This function is used for obtaining the current filename.

+

Returns:
A pointer to the current filename.
+
Examples:
+webclient.c, and webclient.h.
+

+Definition at line 93 of file webclient.c. +

+References webclient_state::file.

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
unsigned char webclient_get char *  host,
u16_t  port,
char *  file
+
+ + + + + +
+   + + +

+Open an HTTP connection to a web server and ask for a file using the GET method. +

+This function opens an HTTP connection to the specified web server and requests the specified file using the GET method. When the HTTP connection has been connected, the webclient_connected() callback function is called and when the HTTP data arrives the webclient_datahandler() callback function is called.

+The callback function webclient_timedout() is called if the web server could not be contacted, and the webclient_aborted() callback function is called if the HTTP connection is aborted by the web server.

+When the HTTP request has been completed and the HTTP connection is closed, the webclient_closed() callback function will be called.

+

Note:
If the function is passed a host name, it must already be in the resolver cache in order for the function to connect to the web server. It is therefore up to the calling module to implement the resolver calls and the signal handler used for reporting a resolv query answer.
+
Parameters:
+ + + + +
host A pointer to a string containing either a host name or a numerical IP address in dotted decimal notation (e.g., 192.168.23.1).
port The port number to which to connect, in host byte order.
file A pointer to the name of the file to get.
+
+
Return values:
+ + + +
0 if the host name could not be found in the cache, or if a TCP connection could not be created.
1 if the connection was initiated.
+
+
Examples:
+webclient.c, and webclient.h.
+

+Definition at line 140 of file webclient.c. +

+References webclient_state::file, webclient_state::host, htons(), NULL, webclient_state::port, resolv_lookup(), and uip_connect(). +

+Referenced by webclient_appcall().

+

+ + + + +
+ + + + + + + + + +
char * webclient_hostname void   ) 
+
+ + + + + +
+   + + +

+Obtain the hostname of the current HTTP data stream. +

+The hostname of the web server of an HTTP request may be changed by the web server, and may therefore not be the same as when the original GET request was made with webclient_get(). This function is used for obtaining the current hostname.

+

Returns:
A pointer to the current hostname.
+
Examples:
+webclient.c, and webclient.h.
+

+Definition at line 99 of file webclient.c. +

+References webclient_state::host.

+

+ + + + +
+ + + + + + + + + +
char * webclient_mimetype void   ) 
+
+ + + + + +
+   + + +

+Obtain the MIME type of the current HTTP data stream. +

+

Returns:
A pointer to a string contaning the MIME type. The string may be empty if no MIME type was reported by the web server.
+
Examples:
+webclient.c, and webclient.h.
+

+Definition at line 87 of file webclient.c. +

+References webclient_state::mimetype.

+

+ + + + +
+ + + + + + + + + +
unsigned short webclient_port void   ) 
+
+ + + + + +
+   + + +

+Obtain the port number of the current HTTP data stream. +

+The port number of an HTTP request may be changed by the web server, and may therefore not be the same as when the original GET request was made with webclient_get(). This function is used for obtaining the current port number.

+

Returns:
The port number of the current HTTP data stream, in host byte order.
+
Examples:
+webclient.c, and webclient.h.
+

+Definition at line 105 of file webclient.c. +

+References webclient_state::port.

+

+ + + + +
+ + + + + + + + + +
void webclient_timedout void   ) 
+
+ + + + + +
+   + + +

+Callback function that is called from the webclient code if the HTTP connection to the web server has timed out. +

+This function must be implemented by the module that uses the webclient code.

Examples:
+webclient.c, and webclient.h.
+

+Referenced by webclient_appcall().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00164.html b/doc/html/a00164.html new file mode 100644 index 0000000..67c80c7 --- /dev/null +++ b/doc/html/a00164.html @@ -0,0 +1,172 @@ + + +uIP 1.0: Web server + + + + + +

Web server
+ +[Applications] +


Detailed Description

+The uIP web server is a very simplistic implementation of an HTTP server. +

+It can serve web pages and files from a read-only ROM filesystem, and provides a very small scripting language. +

+ + + + + + + +

+

+ + + +

+

+ + + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Files

file  httpd-cgi.h
 Web server script interface header file.
file  httpd-cgi.c
 Web server script interface.
file  httpd.c
 Web server.

Data Structures

struct  httpd_cgi_call

Defines

#define HTTPD_CGI_CALL(name, str, function)
 HTTPD CGI function declaration.
+#define STATE_WAITING   0
+#define STATE_OUTPUT   1
+#define ISO_nl   0x0a
+#define ISO_space   0x20
+#define ISO_bang   0x21
+#define ISO_percent   0x25
+#define ISO_period   0x2e
+#define ISO_slash   0x2f
+#define ISO_colon   0x3a

Functions

+httpd_cgifunction httpd_cgi (char *name)
+void httpd_appcall (void)
void httpd_init (void)
 Initialize the web server.
+


Define Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + +
#define HTTPD_CGI_CALL name,
str,
function   ) 
+
+ + + + + +
+   + + +

+HTTPD CGI function declaration. +

+

Parameters:
+ + + + +
name The C variable name of the function
str The string name of the function, used in the script file
function A pointer to the function that implements it
+
+This macro is used for declaring a HTTPD CGI function. This function is then added to the list of HTTPD CGI functions with the httpd_cgi_add() function. +

+Definition at line 77 of file httpd-cgi.h.

+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void httpd_init void   ) 
+
+ + + + + +
+   + + +

+Initialize the web server. +

+This function initializes the web server and should be called at system boot-up. +

+Definition at line 333 of file httpd.c. +

+References HTONS, and uip_listen().

+


Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00168.html b/doc/html/a00168.html new file mode 100644 index 0000000..955e167 --- /dev/null +++ b/doc/html/a00168.html @@ -0,0 +1,381 @@ + + +uIP 1.0: apps/dhcpc/dhcpc.c Source File + + + + + + +

apps/dhcpc/dhcpc.c

00001 /*
+00002  * Copyright (c) 2005, Swedish Institute of Computer Science
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $
+00032  */
+00033 
+00034 #include <stdio.h>
+00035 #include <string.h>
+00036 
+00037 #include "uip.h"
+00038 #include "dhcpc.h"
+00039 #include "timer.h"
+00040 #include "pt.h"
+00041 
+00042 #define STATE_INITIAL         0
+00043 #define STATE_SENDING         1
+00044 #define STATE_OFFER_RECEIVED  2
+00045 #define STATE_CONFIG_RECEIVED 3
+00046 
+00047 static struct dhcpc_state s;
+00048 
+00049 struct dhcp_msg {
+00050   u8_t op, htype, hlen, hops;
+00051   u8_t xid[4];
+00052   u16_t secs, flags;
+00053   u8_t ciaddr[4];
+00054   u8_t yiaddr[4];
+00055   u8_t siaddr[4];
+00056   u8_t giaddr[4];
+00057   u8_t chaddr[16];
+00058 #ifndef UIP_CONF_DHCP_LIGHT
+00059   u8_t sname[64];
+00060   u8_t file[128];
+00061 #endif
+00062   u8_t options[312];
+00063 };
+00064 
+00065 #define BOOTP_BROADCAST 0x8000
+00066 
+00067 #define DHCP_REQUEST        1
+00068 #define DHCP_REPLY          2
+00069 #define DHCP_HTYPE_ETHERNET 1
+00070 #define DHCP_HLEN_ETHERNET  6
+00071 #define DHCP_MSG_LEN      236
+00072 
+00073 #define DHCPC_SERVER_PORT  67
+00074 #define DHCPC_CLIENT_PORT  68
+00075 
+00076 #define DHCPDISCOVER  1
+00077 #define DHCPOFFER     2
+00078 #define DHCPREQUEST   3
+00079 #define DHCPDECLINE   4
+00080 #define DHCPACK       5
+00081 #define DHCPNAK       6
+00082 #define DHCPRELEASE   7
+00083 
+00084 #define DHCP_OPTION_SUBNET_MASK   1
+00085 #define DHCP_OPTION_ROUTER        3
+00086 #define DHCP_OPTION_DNS_SERVER    6
+00087 #define DHCP_OPTION_REQ_IPADDR   50
+00088 #define DHCP_OPTION_LEASE_TIME   51
+00089 #define DHCP_OPTION_MSG_TYPE     53
+00090 #define DHCP_OPTION_SERVER_ID    54
+00091 #define DHCP_OPTION_REQ_LIST     55
+00092 #define DHCP_OPTION_END         255
+00093 
+00094 static const u8_t xid[4] = {0xad, 0xde, 0x12, 0x23};
+00095 static const u8_t magic_cookie[4] = {99, 130, 83, 99};
+00096 /*---------------------------------------------------------------------------*/
+00097 static u8_t *
+00098 add_msg_type(u8_t *optptr, u8_t type)
+00099 {
+00100   *optptr++ = DHCP_OPTION_MSG_TYPE;
+00101   *optptr++ = 1;
+00102   *optptr++ = type;
+00103   return optptr;
+00104 }
+00105 /*---------------------------------------------------------------------------*/
+00106 static u8_t *
+00107 add_server_id(u8_t *optptr)
+00108 {
+00109   *optptr++ = DHCP_OPTION_SERVER_ID;
+00110   *optptr++ = 4;
+00111   memcpy(optptr, s.serverid, 4);
+00112   return optptr + 4;
+00113 }
+00114 /*---------------------------------------------------------------------------*/
+00115 static u8_t *
+00116 add_req_ipaddr(u8_t *optptr)
+00117 {
+00118   *optptr++ = DHCP_OPTION_REQ_IPADDR;
+00119   *optptr++ = 4;
+00120   memcpy(optptr, s.ipaddr, 4);
+00121   return optptr + 4;
+00122 }
+00123 /*---------------------------------------------------------------------------*/
+00124 static u8_t *
+00125 add_req_options(u8_t *optptr)
+00126 {
+00127   *optptr++ = DHCP_OPTION_REQ_LIST;
+00128   *optptr++ = 3;
+00129   *optptr++ = DHCP_OPTION_SUBNET_MASK;
+00130   *optptr++ = DHCP_OPTION_ROUTER;
+00131   *optptr++ = DHCP_OPTION_DNS_SERVER;
+00132   return optptr;
+00133 }
+00134 /*---------------------------------------------------------------------------*/
+00135 static u8_t *
+00136 add_end(u8_t *optptr)
+00137 {
+00138   *optptr++ = DHCP_OPTION_END;
+00139   return optptr;
+00140 }
+00141 /*---------------------------------------------------------------------------*/
+00142 static void
+00143 create_msg(register struct dhcp_msg *m)
+00144 {
+00145   m->op = DHCP_REQUEST;
+00146   m->htype = DHCP_HTYPE_ETHERNET;
+00147   m->hlen = s.mac_len;
+00148   m->hops = 0;
+00149   memcpy(m->xid, xid, sizeof(m->xid));
+00150   m->secs = 0;
+00151   m->flags = HTONS(BOOTP_BROADCAST); /*  Broadcast bit. */
+00152   /*  uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/
+00153   memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr));
+00154   memset(m->yiaddr, 0, sizeof(m->yiaddr));
+00155   memset(m->siaddr, 0, sizeof(m->siaddr));
+00156   memset(m->giaddr, 0, sizeof(m->giaddr));
+00157   memcpy(m->chaddr, s.mac_addr, s.mac_len);
+00158   memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len);
+00159 #ifndef UIP_CONF_DHCP_LIGHT
+00160   memset(m->sname, 0, sizeof(m->sname));
+00161   memset(m->file, 0, sizeof(m->file));
+00162 #endif
+00163 
+00164   memcpy(m->options, magic_cookie, sizeof(magic_cookie));
+00165 }
+00166 /*---------------------------------------------------------------------------*/
+00167 static void
+00168 send_discover(void)
+00169 {
+00170   u8_t *end;
+00171   struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+00172 
+00173   create_msg(m);
+00174 
+00175   end = add_msg_type(&m->options[4], DHCPDISCOVER);
+00176   end = add_req_options(end);
+00177   end = add_end(end);
+00178 
+00179   uip_send(uip_appdata, end - (u8_t *)uip_appdata);
+00180 }
+00181 /*---------------------------------------------------------------------------*/
+00182 static void
+00183 send_request(void)
+00184 {
+00185   u8_t *end;
+00186   struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+00187 
+00188   create_msg(m);
+00189   
+00190   end = add_msg_type(&m->options[4], DHCPREQUEST);
+00191   end = add_server_id(end);
+00192   end = add_req_ipaddr(end);
+00193   end = add_end(end);
+00194   
+00195   uip_send(uip_appdata, end - (u8_t *)uip_appdata);
+00196 }
+00197 /*---------------------------------------------------------------------------*/
+00198 static u8_t
+00199 parse_options(u8_t *optptr, int len)
+00200 {
+00201   u8_t *end = optptr + len;
+00202   u8_t type = 0;
+00203 
+00204   while(optptr < end) {
+00205     switch(*optptr) {
+00206     case DHCP_OPTION_SUBNET_MASK:
+00207       memcpy(s.netmask, optptr + 2, 4);
+00208       break;
+00209     case DHCP_OPTION_ROUTER:
+00210       memcpy(s.default_router, optptr + 2, 4);
+00211       break;
+00212     case DHCP_OPTION_DNS_SERVER:
+00213       memcpy(s.dnsaddr, optptr + 2, 4);
+00214       break;
+00215     case DHCP_OPTION_MSG_TYPE:
+00216       type = *(optptr + 2);
+00217       break;
+00218     case DHCP_OPTION_SERVER_ID:
+00219       memcpy(s.serverid, optptr + 2, 4);
+00220       break;
+00221     case DHCP_OPTION_LEASE_TIME:
+00222       memcpy(s.lease_time, optptr + 2, 4);
+00223       break;
+00224     case DHCP_OPTION_END:
+00225       return type;
+00226     }
+00227 
+00228     optptr += optptr[1] + 2;
+00229   }
+00230   return type;
+00231 }
+00232 /*---------------------------------------------------------------------------*/
+00233 static u8_t
+00234 parse_msg(void)
+00235 {
+00236   struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+00237   
+00238   if(m->op == DHCP_REPLY &&
+00239      memcmp(m->xid, xid, sizeof(xid)) == 0 &&
+00240      memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
+00241     memcpy(s.ipaddr, m->yiaddr, 4);
+00242     return parse_options(&m->options[4], uip_datalen());
+00243   }
+00244   return 0;
+00245 }
+00246 /*---------------------------------------------------------------------------*/
+00247 static
+00248 PT_THREAD(handle_dhcp(void))
+00249 {
+00250   PT_BEGIN(&s.pt);
+00251   
+00252   /* try_again:*/
+00253   s.state = STATE_SENDING;
+00254   s.ticks = CLOCK_SECOND;
+00255 
+00256   do {
+00257     send_discover();
+00258     timer_set(&s.timer, s.ticks);
+00259     PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+00260 
+00261     if(uip_newdata() && parse_msg() == DHCPOFFER) {
+00262       s.state = STATE_OFFER_RECEIVED;
+00263       break;
+00264     }
+00265 
+00266     if(s.ticks < CLOCK_SECOND * 60) {
+00267       s.ticks *= 2;
+00268     }
+00269   } while(s.state != STATE_OFFER_RECEIVED);
+00270   
+00271   s.ticks = CLOCK_SECOND;
+00272 
+00273   do {
+00274     send_request();
+00275     timer_set(&s.timer, s.ticks);
+00276     PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+00277 
+00278     if(uip_newdata() && parse_msg() == DHCPACK) {
+00279       s.state = STATE_CONFIG_RECEIVED;
+00280       break;
+00281     }
+00282 
+00283     if(s.ticks <= CLOCK_SECOND * 10) {
+00284       s.ticks += CLOCK_SECOND;
+00285     } else {
+00286       PT_RESTART(&s.pt);
+00287     }
+00288   } while(s.state != STATE_CONFIG_RECEIVED);
+00289   
+00290 #if 0
+00291   printf("Got IP address %d.%d.%d.%d\n",
+00292          uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr),
+00293          uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr));
+00294   printf("Got netmask %d.%d.%d.%d\n",
+00295          uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask),
+00296          uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask));
+00297   printf("Got DNS server %d.%d.%d.%d\n",
+00298          uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr),
+00299          uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr));
+00300   printf("Got default router %d.%d.%d.%d\n",
+00301          uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router),
+00302          uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router));
+00303   printf("Lease expires in %ld seconds\n",
+00304          ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1]));
+00305 #endif
+00306 
+00307   dhcpc_configured(&s);
+00308   
+00309   /*  timer_stop(&s.timer);*/
+00310 
+00311   /*
+00312    * PT_END restarts the thread so we do this instead. Eventually we
+00313    * should reacquire expired leases here.
+00314    */
+00315   while(1) {
+00316     PT_YIELD(&s.pt);
+00317   }
+00318 
+00319   PT_END(&s.pt);
+00320 }
+00321 /*---------------------------------------------------------------------------*/
+00322 void
+00323 dhcpc_init(const void *mac_addr, int mac_len)
+00324 {
+00325   uip_ipaddr_t addr;
+00326   
+00327   s.mac_addr = mac_addr;
+00328   s.mac_len  = mac_len;
+00329 
+00330   s.state = STATE_INITIAL;
+00331   uip_ipaddr(addr, 255,255,255,255);
+00332   s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT));
+00333   if(s.conn != NULL) {
+00334     uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT));
+00335   }
+00336   PT_INIT(&s.pt);
+00337 }
+00338 /*---------------------------------------------------------------------------*/
+00339 void
+00340 dhcpc_appcall(void)
+00341 {
+00342   handle_dhcp();
+00343 }
+00344 /*---------------------------------------------------------------------------*/
+00345 void
+00346 dhcpc_request(void)
+00347 {
+00348   u16_t ipaddr[2];
+00349   
+00350   if(s.state == STATE_INITIAL) {
+00351     uip_ipaddr(ipaddr, 0,0,0,0);
+00352     uip_sethostaddr(ipaddr);
+00353     /*    handle_dhcp(PROCESS_EVENT_NONE, NULL);*/
+00354   }
+00355 }
+00356 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00169.html b/doc/html/a00169.html new file mode 100644 index 0000000..c3ed913 --- /dev/null +++ b/doc/html/a00169.html @@ -0,0 +1,93 @@ + + +uIP 1.0: apps/dhcpc/dhcpc.h Source File + + + + + + +

apps/dhcpc/dhcpc.h

00001 /*
+00002  * Copyright (c) 2005, Swedish Institute of Computer Science
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * @(#)$Id: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $
+00032  */
+00033 #ifndef __DHCPC_H__
+00034 #define __DHCPC_H__
+00035 
+00036 #include "timer.h"
+00037 #include "pt.h"
+00038 
+00039 struct dhcpc_state {
+00040   struct pt pt;
+00041   char state;
+00042   struct uip_udp_conn *conn;
+00043   struct timer timer;
+00044   u16_t ticks;
+00045   const void *mac_addr;
+00046   int mac_len;
+00047   
+00048   u8_t serverid[4];
+00049 
+00050   u16_t lease_time[2];
+00051   u16_t ipaddr[2];
+00052   u16_t netmask[2];
+00053   u16_t dnsaddr[2];
+00054   u16_t default_router[2];
+00055 };
+00056 
+00057 void dhcpc_init(const void *mac_addr, int mac_len);
+00058 void dhcpc_request(void);
+00059 
+00060 void dhcpc_appcall(void);
+00061 
+00062 void dhcpc_configured(const struct dhcpc_state *s);
+00063 
+00064 typedef struct dhcpc_state uip_udp_appstate_t;
+00065 #define UIP_UDP_APPCALL dhcpc_appcall
+00066 
+00067 
+00068 #endif /* __DHCPC_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00170.html b/doc/html/a00170.html new file mode 100644 index 0000000..20a39c0 --- /dev/null +++ b/doc/html/a00170.html @@ -0,0 +1,125 @@ + + +uIP 1.0: apps/hello-world/hello-world.c Source File + + + + + + +

apps/hello-world/hello-world.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup helloworld
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \file
+00008  *         An example of how to write uIP applications
+00009  *         with protosockets.
+00010  * \author
+00011  *         Adam Dunkels <adam@sics.se>
+00012  */
+00013 
+00014 /*
+00015  * This is a short example of how to write uIP applications using
+00016  * protosockets.
+00017  */
+00018 
+00019 /*
+00020  * We define the application state (struct hello_world_state) in the
+00021  * hello-world.h file, so we need to include it here. We also include
+00022  * uip.h (since this cannot be included in hello-world.h) and
+00023  * <string.h>, since we use the memcpy() function in the code.
+00024  */
+00025 #include "hello-world.h"
+00026 #include "uip.h"
+00027 #include <string.h>
+00028 
+00029 /*
+00030  * Declaration of the protosocket function that handles the connection
+00031  * (defined at the end of the code).
+00032  */
+00033 static int handle_connection(struct hello_world_state *s);
+00034 /*---------------------------------------------------------------------------*/
+00035 /*
+00036  * The initialization function. We must explicitly call this function
+00037  * from the system initialization code, some time after uip_init() is
+00038  * called.
+00039  */
+00040 void
+00041 hello_world_init(void)
+00042 {
+00043   /* We start to listen for connections on TCP port 1000. */
+00044   uip_listen(HTONS(1000));
+00045 }
+00046 /*---------------------------------------------------------------------------*/
+00047 /*
+00048  * In hello-world.h we have defined the UIP_APPCALL macro to
+00049  * hello_world_appcall so that this funcion is uIP's application
+00050  * function. This function is called whenever an uIP event occurs
+00051  * (e.g. when a new connection is established, new data arrives, sent
+00052  * data is acknowledged, data needs to be retransmitted, etc.).
+00053  */
+00054 void
+00055 hello_world_appcall(void)
+00056 {
+00057   /*
+00058    * The uip_conn structure has a field called "appstate" that holds
+00059    * the application state of the connection. We make a pointer to
+00060    * this to access it easier.
+00061    */
+00062   struct hello_world_state *s = &(uip_conn->appstate);
+00063 
+00064   /*
+00065    * If a new connection was just established, we should initialize
+00066    * the protosocket in our applications' state structure.
+00067    */
+00068   if(uip_connected()) {
+00069     PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer));
+00070   }
+00071 
+00072   /*
+00073    * Finally, we run the protosocket function that actually handles
+00074    * the communication. We pass it a pointer to the application state
+00075    * of the current connection.
+00076    */
+00077   handle_connection(s);
+00078 }
+00079 /*---------------------------------------------------------------------------*/
+00080 /*
+00081  * This is the protosocket function that handles the communication. A
+00082  * protosocket function must always return an int, but must never
+00083  * explicitly return - all return statements are hidden in the PSOCK
+00084  * macros.
+00085  */
+00086 static int
+00087 handle_connection(struct hello_world_state *s)
+00088 {
+00089   PSOCK_BEGIN(&s->p);
+00090 
+00091   PSOCK_SEND_STR(&s->p, "Hello. What is your name?\n");
+00092   PSOCK_READTO(&s->p, '\n');
+00093   strncpy(s->name, s->inputbuffer, sizeof(s->name));
+00094   PSOCK_SEND_STR(&s->p, "Hello ");
+00095   PSOCK_SEND_STR(&s->p, s->name);
+00096   PSOCK_CLOSE(&s->p);
+00097   
+00098   PSOCK_END(&s->p);
+00099 }
+00100 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00171.html b/doc/html/a00171.html new file mode 100644 index 0000000..768f61b --- /dev/null +++ b/doc/html/a00171.html @@ -0,0 +1,77 @@ + + +uIP 1.0: apps/hello-world/hello-world.h Source File + + + + + + +

apps/hello-world/hello-world.h

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup helloworld Hello, world
+00008  * @{
+00009  *
+00010  * A small example showing how to write applications with
+00011  * \ref psock "protosockets".
+00012  */
+00013 
+00014 /**
+00015  * \file
+00016  *         Header file for an example of how to write uIP applications
+00017  *         with protosockets.
+00018  * \author
+00019  *         Adam Dunkels <adam@sics.se>
+00020  */
+00021 
+00022 #ifndef __HELLO_WORLD_H__
+00023 #define __HELLO_WORLD_H__
+00024 
+00025 /* Since this file will be included by uip.h, we cannot include uip.h
+00026    here. But we might need to include uipopt.h if we need the u8_t and
+00027    u16_t datatypes. */
+00028 #include "uipopt.h"
+00029 
+00030 #include "psock.h"
+00031 
+00032 /* Next, we define the uip_tcp_appstate_t datatype. This is the state
+00033    of our application, and the memory required for this state is
+00034    allocated together with each TCP connection. One application state
+00035    for each TCP connection. */
+00036 typedef struct hello_world_state {
+00037   struct psock p;
+00038   char inputbuffer[10];
+00039   char name[40];
+00040 } uip_tcp_appstate_t;
+00041 
+00042 /* Finally we define the application function to be called by uIP. */
+00043 void hello_world_appcall(void);
+00044 #ifndef UIP_APPCALL
+00045 #define UIP_APPCALL hello_world_appcall
+00046 #endif /* UIP_APPCALL */
+00047 
+00048 void hello_world_init(void);
+00049 
+00050 #endif /* __HELLO_WORLD_H__ */
+00051 /** @} */
+00052 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00172.html b/doc/html/a00172.html new file mode 100644 index 0000000..1bf08f6 --- /dev/null +++ b/doc/html/a00172.html @@ -0,0 +1,489 @@ + + +uIP 1.0: apps/resolv/resolv.c Source File + + + + + + +

apps/resolv/resolv.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup resolv DNS resolver
+00008  * @{
+00009  *
+00010  * The uIP DNS resolver functions are used to lookup a hostname and
+00011  * map it to a numerical IP address. It maintains a list of resolved
+00012  * hostnames that can be queried with the resolv_lookup()
+00013  * function. New hostnames can be resolved using the resolv_query()
+00014  * function.
+00015  *
+00016  * When a hostname has been resolved (or found to be non-existant),
+00017  * the resolver code calls a callback function called resolv_found()
+00018  * that must be implemented by the module that uses the resolver.
+00019  */
+00020 
+00021 /**
+00022  * \file
+00023  * DNS host name to IP address resolver.
+00024  * \author Adam Dunkels <adam@dunkels.com>
+00025  *
+00026  * This file implements a DNS host name to IP address resolver.
+00027  */
+00028 
+00029 /*
+00030  * Copyright (c) 2002-2003, Adam Dunkels.
+00031  * All rights reserved.
+00032  *
+00033  * Redistribution and use in source and binary forms, with or without
+00034  * modification, are permitted provided that the following conditions
+00035  * are met:
+00036  * 1. Redistributions of source code must retain the above copyright
+00037  *    notice, this list of conditions and the following disclaimer.
+00038  * 2. Redistributions in binary form must reproduce the above copyright
+00039  *    notice, this list of conditions and the following disclaimer in the
+00040  *    documentation and/or other materials provided with the distribution.
+00041  * 3. The name of the author may not be used to endorse or promote
+00042  *    products derived from this software without specific prior
+00043  *    written permission.
+00044  *
+00045  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00046  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00047  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00048  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00049  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00050  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00051  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00052  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00053  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00054  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00055  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00056  *
+00057  * This file is part of the uIP TCP/IP stack.
+00058  *
+00059  * $Id: resolv.c,v 1.5 2006/06/11 21:46:37 adam Exp $
+00060  *
+00061  */
+00062 
+00063 #include "resolv.h"
+00064 #include "uip.h"
+00065 
+00066 #include <string.h>
+00067 
+00068 #ifndef NULL
+00069 #define NULL (void *)0
+00070 #endif /* NULL */
+00071 
+00072 /** \internal The maximum number of retries when asking for a name. */
+00073 #define MAX_RETRIES 8
+00074 
+00075 /** \internal The DNS message header. */
+00076 struct dns_hdr {
+00077   u16_t id;
+00078   u8_t flags1, flags2;
+00079 #define DNS_FLAG1_RESPONSE        0x80
+00080 #define DNS_FLAG1_OPCODE_STATUS   0x10
+00081 #define DNS_FLAG1_OPCODE_INVERSE  0x08
+00082 #define DNS_FLAG1_OPCODE_STANDARD 0x00
+00083 #define DNS_FLAG1_AUTHORATIVE     0x04
+00084 #define DNS_FLAG1_TRUNC           0x02
+00085 #define DNS_FLAG1_RD              0x01
+00086 #define DNS_FLAG2_RA              0x80
+00087 #define DNS_FLAG2_ERR_MASK        0x0f
+00088 #define DNS_FLAG2_ERR_NONE        0x00
+00089 #define DNS_FLAG2_ERR_NAME        0x03
+00090   u16_t numquestions;
+00091   u16_t numanswers;
+00092   u16_t numauthrr;
+00093   u16_t numextrarr;
+00094 };
+00095 
+00096 /** \internal The DNS answer message structure. */
+00097 struct dns_answer {
+00098   /* DNS answer record starts with either a domain name or a pointer
+00099      to a name already present somewhere in the packet. */
+00100   u16_t type;
+00101   u16_t class;
+00102   u16_t ttl[2];
+00103   u16_t len;
+00104   uip_ipaddr_t ipaddr;
+00105 };
+00106 
+00107 struct namemap {
+00108 #define STATE_UNUSED 0
+00109 #define STATE_NEW    1
+00110 #define STATE_ASKING 2
+00111 #define STATE_DONE   3
+00112 #define STATE_ERROR  4
+00113   u8_t state;
+00114   u8_t tmr;
+00115   u8_t retries;
+00116   u8_t seqno;
+00117   u8_t err;
+00118   char name[32];
+00119   uip_ipaddr_t ipaddr;
+00120 };
+00121 
+00122 #ifndef UIP_CONF_RESOLV_ENTRIES
+00123 #define RESOLV_ENTRIES 4
+00124 #else /* UIP_CONF_RESOLV_ENTRIES */
+00125 #define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
+00126 #endif /* UIP_CONF_RESOLV_ENTRIES */
+00127 
+00128 
+00129 static struct namemap names[RESOLV_ENTRIES];
+00130 
+00131 static u8_t seqno;
+00132 
+00133 static struct uip_udp_conn *resolv_conn = NULL;
+00134 
+00135 
+00136 /*---------------------------------------------------------------------------*/
+00137 /** \internal
+00138  * Walk through a compact encoded DNS name and return the end of it.
+00139  *
+00140  * \return The end of the name.
+00141  */
+00142 /*---------------------------------------------------------------------------*/
+00143 static unsigned char *
+00144 parse_name(unsigned char *query)
+00145 {
+00146   unsigned char n;
+00147 
+00148   do {
+00149     n = *query++;
+00150     
+00151     while(n > 0) {
+00152       /*      printf("%c", *query);*/
+00153       ++query;
+00154       --n;
+00155     };
+00156     /*    printf(".");*/
+00157   } while(*query != 0);
+00158   /*  printf("\n");*/
+00159   return query + 1;
+00160 }
+00161 /*---------------------------------------------------------------------------*/
+00162 /** \internal
+00163  * Runs through the list of names to see if there are any that have
+00164  * not yet been queried and, if so, sends out a query.
+00165  */
+00166 /*---------------------------------------------------------------------------*/
+00167 static void
+00168 check_entries(void)
+00169 {
+00170   register struct dns_hdr *hdr;
+00171   char *query, *nptr, *nameptr;
+00172   static u8_t i;
+00173   static u8_t n;
+00174   register struct namemap *namemapptr;
+00175   
+00176   for(i = 0; i < RESOLV_ENTRIES; ++i) {
+00177     namemapptr = &names[i];
+00178     if(namemapptr->state == STATE_NEW ||
+00179        namemapptr->state == STATE_ASKING) {
+00180       if(namemapptr->state == STATE_ASKING) {
+00181         if(--namemapptr->tmr == 0) {
+00182           if(++namemapptr->retries == MAX_RETRIES) {
+00183             namemapptr->state = STATE_ERROR;
+00184             resolv_found(namemapptr->name, NULL);
+00185             continue;
+00186           }
+00187           namemapptr->tmr = namemapptr->retries;
+00188         } else {
+00189           /*      printf("Timer %d\n", namemapptr->tmr);*/
+00190           /* Its timer has not run out, so we move on to next
+00191              entry. */
+00192           continue;
+00193         }
+00194       } else {
+00195         namemapptr->state = STATE_ASKING;
+00196         namemapptr->tmr = 1;
+00197         namemapptr->retries = 0;
+00198       }
+00199       hdr = (struct dns_hdr *)uip_appdata;
+00200       memset(hdr, 0, sizeof(struct dns_hdr));
+00201       hdr->id = htons(i);
+00202       hdr->flags1 = DNS_FLAG1_RD;
+00203       hdr->numquestions = HTONS(1);
+00204       query = (char *)uip_appdata + 12;
+00205       nameptr = namemapptr->name;
+00206       --nameptr;
+00207       /* Convert hostname into suitable query format. */
+00208       do {
+00209         ++nameptr;
+00210         nptr = query;
+00211         ++query;
+00212         for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
+00213           *query = *nameptr;
+00214           ++query;
+00215           ++n;
+00216         }
+00217         *nptr = n;
+00218       } while(*nameptr != 0);
+00219       {
+00220         static unsigned char endquery[] =
+00221           {0,0,1,0,1};
+00222         memcpy(query, endquery, 5);
+00223       }
+00224       uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
+00225       break;
+00226     }
+00227   }
+00228 }
+00229 /*---------------------------------------------------------------------------*/
+00230 /** \internal
+00231  * Called when new UDP data arrives.
+00232  */
+00233 /*---------------------------------------------------------------------------*/
+00234 static void
+00235 newdata(void)
+00236 {
+00237   char *nameptr;
+00238   struct dns_answer *ans;
+00239   struct dns_hdr *hdr;
+00240   static u8_t nquestions, nanswers;
+00241   static u8_t i;
+00242   register struct namemap *namemapptr;
+00243   
+00244   hdr = (struct dns_hdr *)uip_appdata;
+00245   /*  printf("ID %d\n", htons(hdr->id));
+00246       printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
+00247       printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
+00248       printf("Num questions %d, answers %d, authrr %d, extrarr %d\n",
+00249       htons(hdr->numquestions),
+00250       htons(hdr->numanswers),
+00251       htons(hdr->numauthrr),
+00252       htons(hdr->numextrarr));
+00253   */
+00254 
+00255   /* The ID in the DNS header should be our entry into the name
+00256      table. */
+00257   i = htons(hdr->id);
+00258   namemapptr = &names[i];
+00259   if(i < RESOLV_ENTRIES &&
+00260      namemapptr->state == STATE_ASKING) {
+00261 
+00262     /* This entry is now finished. */
+00263     namemapptr->state = STATE_DONE;
+00264     namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
+00265 
+00266     /* Check for error. If so, call callback to inform. */
+00267     if(namemapptr->err != 0) {
+00268       namemapptr->state = STATE_ERROR;
+00269       resolv_found(namemapptr->name, NULL);
+00270       return;
+00271     }
+00272 
+00273     /* We only care about the question(s) and the answers. The authrr
+00274        and the extrarr are simply discarded. */
+00275     nquestions = htons(hdr->numquestions);
+00276     nanswers = htons(hdr->numanswers);
+00277 
+00278     /* Skip the name in the question. XXX: This should really be
+00279        checked agains the name in the question, to be sure that they
+00280        match. */
+00281     nameptr = parse_name((char *)uip_appdata + 12) + 4;
+00282 
+00283     while(nanswers > 0) {
+00284       /* The first byte in the answer resource record determines if it
+00285          is a compressed record or a normal one. */
+00286       if(*nameptr & 0xc0) {
+00287         /* Compressed name. */
+00288         nameptr +=2;
+00289         /*      printf("Compressed anwser\n");*/
+00290       } else {
+00291         /* Not compressed name. */
+00292         nameptr = parse_name((char *)nameptr);
+00293       }
+00294 
+00295       ans = (struct dns_answer *)nameptr;
+00296       /*      printf("Answer: type %x, class %x, ttl %x, length %x\n",
+00297              htons(ans->type), htons(ans->class), (htons(ans->ttl[0])
+00298              << 16) | htons(ans->ttl[1]), htons(ans->len));*/
+00299 
+00300       /* Check for IP address type and Internet class. Others are
+00301          discarded. */
+00302       if(ans->type == HTONS(1) &&
+00303          ans->class == HTONS(1) &&
+00304          ans->len == HTONS(4)) {
+00305         /*      printf("IP address %d.%d.%d.%d\n",
+00306                htons(ans->ipaddr[0]) >> 8,
+00307                htons(ans->ipaddr[0]) & 0xff,
+00308                htons(ans->ipaddr[1]) >> 8,
+00309                htons(ans->ipaddr[1]) & 0xff);*/
+00310         /* XXX: we should really check that this IP address is the one
+00311            we want. */
+00312         namemapptr->ipaddr[0] = ans->ipaddr[0];
+00313         namemapptr->ipaddr[1] = ans->ipaddr[1];
+00314         
+00315         resolv_found(namemapptr->name, namemapptr->ipaddr);
+00316         return;
+00317       } else {
+00318         nameptr = nameptr + 10 + htons(ans->len);
+00319       }
+00320       --nanswers;
+00321     }
+00322   }
+00323 
+00324 }
+00325 /*---------------------------------------------------------------------------*/
+00326 /** \internal
+00327  * The main UDP function.
+00328  */
+00329 /*---------------------------------------------------------------------------*/
+00330 void
+00331 resolv_appcall(void)
+00332 {
+00333   if(uip_udp_conn->rport == HTONS(53)) {
+00334     if(uip_poll()) {
+00335       check_entries();
+00336     }
+00337     if(uip_newdata()) {
+00338       newdata();
+00339     }
+00340   }
+00341 }
+00342 /*---------------------------------------------------------------------------*/
+00343 /**
+00344  * Queues a name so that a question for the name will be sent out.
+00345  *
+00346  * \param name The hostname that is to be queried.
+00347  */
+00348 /*---------------------------------------------------------------------------*/
+00349 void
+00350 resolv_query(char *name)
+00351 {
+00352   static u8_t i;
+00353   static u8_t lseq, lseqi;
+00354   register struct namemap *nameptr;
+00355       
+00356   lseq = lseqi = 0;
+00357   
+00358   for(i = 0; i < RESOLV_ENTRIES; ++i) {
+00359     nameptr = &names[i];
+00360     if(nameptr->state == STATE_UNUSED) {
+00361       break;
+00362     }
+00363     if(seqno - nameptr->seqno > lseq) {
+00364       lseq = seqno - nameptr->seqno;
+00365       lseqi = i;
+00366     }
+00367   }
+00368 
+00369   if(i == RESOLV_ENTRIES) {
+00370     i = lseqi;
+00371     nameptr = &names[i];
+00372   }
+00373 
+00374   /*  printf("Using entry %d\n", i);*/
+00375 
+00376   strcpy(nameptr->name, name);
+00377   nameptr->state = STATE_NEW;
+00378   nameptr->seqno = seqno;
+00379   ++seqno;
+00380 }
+00381 /*---------------------------------------------------------------------------*/
+00382 /**
+00383  * Look up a hostname in the array of known hostnames.
+00384  *
+00385  * \note This function only looks in the internal array of known
+00386  * hostnames, it does not send out a query for the hostname if none
+00387  * was found. The function resolv_query() can be used to send a query
+00388  * for a hostname.
+00389  *
+00390  * \return A pointer to a 4-byte representation of the hostname's IP
+00391  * address, or NULL if the hostname was not found in the array of
+00392  * hostnames.
+00393  */
+00394 /*---------------------------------------------------------------------------*/
+00395 u16_t *
+00396 resolv_lookup(char *name)
+00397 {
+00398   static u8_t i;
+00399   struct namemap *nameptr;
+00400   
+00401   /* Walk through the list to see if the name is in there. If it is
+00402      not, we return NULL. */
+00403   for(i = 0; i < RESOLV_ENTRIES; ++i) {
+00404     nameptr = &names[i];
+00405     if(nameptr->state == STATE_DONE &&
+00406        strcmp(name, nameptr->name) == 0) {
+00407       return nameptr->ipaddr;
+00408     }
+00409   }
+00410   return NULL;
+00411 }
+00412 /*---------------------------------------------------------------------------*/
+00413 /**
+00414  * Obtain the currently configured DNS server.
+00415  *
+00416  * \return A pointer to a 4-byte representation of the IP address of
+00417  * the currently configured DNS server or NULL if no DNS server has
+00418  * been configured.
+00419  */
+00420 /*---------------------------------------------------------------------------*/
+00421 u16_t *
+00422 resolv_getserver(void)
+00423 {
+00424   if(resolv_conn == NULL) {
+00425     return NULL;
+00426   }
+00427   return resolv_conn->ripaddr;
+00428 }
+00429 /*---------------------------------------------------------------------------*/
+00430 /**
+00431  * Configure which DNS server to use for queries.
+00432  *
+00433  * \param dnsserver A pointer to a 4-byte representation of the IP
+00434  * address of the DNS server to be configured.
+00435  */
+00436 /*---------------------------------------------------------------------------*/
+00437 void
+00438 resolv_conf(u16_t *dnsserver)
+00439 {
+00440   if(resolv_conn != NULL) {
+00441     uip_udp_remove(resolv_conn);
+00442   }
+00443   
+00444   resolv_conn = uip_udp_new(dnsserver, HTONS(53));
+00445 }
+00446 /*---------------------------------------------------------------------------*/
+00447 /**
+00448  * Initalize the resolver.
+00449  */
+00450 /*---------------------------------------------------------------------------*/
+00451 void
+00452 resolv_init(void)
+00453 {
+00454   static u8_t i;
+00455   
+00456   for(i = 0; i < RESOLV_ENTRIES; ++i) {
+00457     names[i].state = STATE_DONE;
+00458   }
+00459 
+00460 }
+00461 /*---------------------------------------------------------------------------*/
+00462 
+00463 /** @} */
+00464 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00173.html b/doc/html/a00173.html new file mode 100644 index 0000000..1b9f8df --- /dev/null +++ b/doc/html/a00173.html @@ -0,0 +1,100 @@ + + +uIP 1.0: apps/resolv/resolv.h Source File + + + + + + +

apps/resolv/resolv.h

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup resolv
+00003  * @{
+00004  */
+00005 /**
+00006  * \file
+00007  * DNS resolver code header file.
+00008  * \author Adam Dunkels <adam@dunkels.com>
+00009  */
+00010 
+00011 /*
+00012  * Copyright (c) 2002-2003, Adam Dunkels.
+00013  * All rights reserved.
+00014  *
+00015  * Redistribution and use in source and binary forms, with or without
+00016  * modification, are permitted provided that the following conditions
+00017  * are met:
+00018  * 1. Redistributions of source code must retain the above copyright
+00019  *    notice, this list of conditions and the following disclaimer.
+00020  * 2. Redistributions in binary form must reproduce the above copyright
+00021  *    notice, this list of conditions and the following disclaimer in the
+00022  *    documentation and/or other materials provided with the distribution.
+00023  * 3. The name of the author may not be used to endorse or promote
+00024  *    products derived from this software without specific prior
+00025  *    written permission.
+00026  *
+00027  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00028  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00029  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00030  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00031  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00033  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00035  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00036  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00037  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00038  *
+00039  * This file is part of the uIP TCP/IP stack.
+00040  *
+00041  * $Id: resolv.h,v 1.4 2006/06/11 21:46:37 adam Exp $
+00042  *
+00043  */
+00044 #ifndef __RESOLV_H__
+00045 #define __RESOLV_H__
+00046 
+00047 typedef int uip_udp_appstate_t;
+00048 void resolv_appcall(void);
+00049 #define UIP_UDP_APPCALL resolv_appcall
+00050 
+00051 #include "uipopt.h"
+00052 
+00053 /**
+00054  * Callback function which is called when a hostname is found.
+00055  *
+00056  * This function must be implemented by the module that uses the DNS
+00057  * resolver. It is called when a hostname is found, or when a hostname
+00058  * was not found.
+00059  *
+00060  * \param name A pointer to the name that was looked up.  \param
+00061  * ipaddr A pointer to a 4-byte array containing the IP address of the
+00062  * hostname, or NULL if the hostname could not be found.
+00063  */
+00064 void resolv_found(char *name, u16_t *ipaddr);
+00065 
+00066 /* Functions. */
+00067 void resolv_conf(u16_t *dnsserver);
+00068 u16_t *resolv_getserver(void);
+00069 void resolv_init(void);
+00070 u16_t *resolv_lookup(char *name);
+00071 void resolv_query(char *name);
+00072 
+00073 #endif /* __RESOLV_H__ */
+00074 
+00075 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00174.html b/doc/html/a00174.html new file mode 100644 index 0000000..c535c4a --- /dev/null +++ b/doc/html/a00174.html @@ -0,0 +1,287 @@ + + +uIP 1.0: apps/smtp/smtp.c Source File + + + + + + +

apps/smtp/smtp.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup smtp SMTP E-mail sender
+00008  * @{
+00009  *
+00010  * The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is
+00011  * the standard way of sending and transfering e-mail on the
+00012  * Internet. This simple example implementation is intended as an
+00013  * example of how to implement protocols in uIP, and is able to send
+00014  * out e-mail but has not been extensively tested.
+00015  */
+00016 
+00017 /**
+00018  * \file
+00019  * SMTP example implementation
+00020  * \author Adam Dunkels <adam@dunkels.com>
+00021  */
+00022 
+00023 /*
+00024  * Copyright (c) 2004, Adam Dunkels.
+00025  * All rights reserved.
+00026  *
+00027  * Redistribution and use in source and binary forms, with or without
+00028  * modification, are permitted provided that the following conditions
+00029  * are met:
+00030  * 1. Redistributions of source code must retain the above copyright
+00031  *    notice, this list of conditions and the following disclaimer.
+00032  * 2. Redistributions in binary form must reproduce the above copyright
+00033  *    notice, this list of conditions and the following disclaimer in the
+00034  *    documentation and/or other materials provided with the distribution.
+00035  * 3. Neither the name of the Institute nor the names of its contributors
+00036  *    may be used to endorse or promote products derived from this software
+00037  *    without specific prior written permission.
+00038  *
+00039  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00040  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00041  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00042  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00043  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00044  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00045  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00046  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00047  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00048  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00049  * SUCH DAMAGE.
+00050  *
+00051  * This file is part of the uIP TCP/IP stack.
+00052  *
+00053  * Author: Adam Dunkels <adam@sics.se>
+00054  *
+00055  * $Id: smtp.c,v 1.4 2006/06/11 21:46:37 adam Exp $
+00056  */
+00057 #include "smtp.h"
+00058 
+00059 #include "smtp-strings.h"
+00060 #include "psock.h"
+00061 #include "uip.h"
+00062 
+00063 #include <string.h>
+00064 
+00065 static struct smtp_state s;
+00066 
+00067 static char *localhostname;
+00068 static uip_ipaddr_t smtpserver;
+00069 
+00070 #define ISO_nl 0x0a
+00071 #define ISO_cr 0x0d
+00072 
+00073 #define ISO_period 0x2e
+00074 
+00075 #define ISO_2  0x32
+00076 #define ISO_3  0x33
+00077 #define ISO_4  0x34
+00078 #define ISO_5  0x35
+00079 
+00080 
+00081 /*---------------------------------------------------------------------------*/
+00082 static
+00083 PT_THREAD(smtp_thread(void))
+00084 {
+00085   PSOCK_BEGIN(&s.psock);
+00086 
+00087   PSOCK_READTO(&s.psock, ISO_nl);
+00088    
+00089   if(strncmp(s.inputbuffer, smtp_220, 3) != 0) {
+00090     PSOCK_CLOSE(&s.psock);
+00091     smtp_done(2);
+00092     PSOCK_EXIT(&s.psock);
+00093   }
+00094   
+00095   PSOCK_SEND_STR(&s.psock, (char *)smtp_helo);
+00096   PSOCK_SEND_STR(&s.psock, localhostname);
+00097   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00098 
+00099   PSOCK_READTO(&s.psock, ISO_nl);
+00100   
+00101   if(s.inputbuffer[0] != ISO_2) {
+00102     PSOCK_CLOSE(&s.psock);
+00103     smtp_done(3);
+00104     PSOCK_EXIT(&s.psock);
+00105   }
+00106 
+00107   PSOCK_SEND_STR(&s.psock, (char *)smtp_mail_from);
+00108   PSOCK_SEND_STR(&s.psock, s.from);
+00109   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00110 
+00111   PSOCK_READTO(&s.psock, ISO_nl);
+00112   
+00113   if(s.inputbuffer[0] != ISO_2) {
+00114     PSOCK_CLOSE(&s.psock);
+00115     smtp_done(4);
+00116     PSOCK_EXIT(&s.psock);
+00117   }
+00118 
+00119   PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
+00120   PSOCK_SEND_STR(&s.psock, s.to);
+00121   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00122 
+00123   PSOCK_READTO(&s.psock, ISO_nl);
+00124   
+00125   if(s.inputbuffer[0] != ISO_2) {
+00126     PSOCK_CLOSE(&s.psock);
+00127     smtp_done(5);
+00128     PSOCK_EXIT(&s.psock);
+00129   }
+00130   
+00131   if(s.cc != 0) {
+00132     PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
+00133     PSOCK_SEND_STR(&s.psock, s.cc);
+00134     PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00135 
+00136     PSOCK_READTO(&s.psock, ISO_nl);
+00137   
+00138     if(s.inputbuffer[0] != ISO_2) {
+00139       PSOCK_CLOSE(&s.psock);
+00140       smtp_done(6);
+00141       PSOCK_EXIT(&s.psock);
+00142     }
+00143   }
+00144   
+00145   PSOCK_SEND_STR(&s.psock, (char *)smtp_data);
+00146   
+00147   PSOCK_READTO(&s.psock, ISO_nl);
+00148   
+00149   if(s.inputbuffer[0] != ISO_3) {
+00150     PSOCK_CLOSE(&s.psock);
+00151     smtp_done(7);
+00152     PSOCK_EXIT(&s.psock);
+00153   }
+00154 
+00155   PSOCK_SEND_STR(&s.psock, (char *)smtp_to);
+00156   PSOCK_SEND_STR(&s.psock, s.to);
+00157   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00158   
+00159   if(s.cc != 0) {
+00160     PSOCK_SEND_STR(&s.psock, (char *)smtp_cc);
+00161     PSOCK_SEND_STR(&s.psock, s.cc);
+00162     PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00163   }
+00164   
+00165   PSOCK_SEND_STR(&s.psock, (char *)smtp_from);
+00166   PSOCK_SEND_STR(&s.psock, s.from);
+00167   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00168   
+00169   PSOCK_SEND_STR(&s.psock, (char *)smtp_subject);
+00170   PSOCK_SEND_STR(&s.psock, s.subject);
+00171   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
+00172 
+00173   PSOCK_SEND(&s.psock, s.msg, s.msglen);
+00174   
+00175   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnlperiodcrnl);
+00176 
+00177   PSOCK_READTO(&s.psock, ISO_nl);
+00178   if(s.inputbuffer[0] != ISO_2) {
+00179     PSOCK_CLOSE(&s.psock);
+00180     smtp_done(8);
+00181     PSOCK_EXIT(&s.psock);
+00182   }
+00183 
+00184   PSOCK_SEND_STR(&s.psock, (char *)smtp_quit);
+00185   smtp_done(SMTP_ERR_OK);
+00186   PSOCK_END(&s.psock);
+00187 }
+00188 /*---------------------------------------------------------------------------*/
+00189 void
+00190 smtp_appcall(void)
+00191 {
+00192   if(uip_closed()) {
+00193     s.connected = 0;
+00194     return;
+00195   }
+00196   if(uip_aborted() || uip_timedout()) {
+00197     s.connected = 0;
+00198     smtp_done(1);
+00199     return;
+00200   }
+00201   smtp_thread();
+00202 }
+00203 /*---------------------------------------------------------------------------*/
+00204 /**
+00205  * Specificy an SMTP server and hostname.
+00206  *
+00207  * This function is used to configure the SMTP module with an SMTP
+00208  * server and the hostname of the host.
+00209  *
+00210  * \param lhostname The hostname of the uIP host.
+00211  *
+00212  * \param server A pointer to a 4-byte array representing the IP
+00213  * address of the SMTP server to be configured.
+00214  */
+00215 void
+00216 smtp_configure(char *lhostname, void *server)
+00217 {
+00218   localhostname = lhostname;
+00219   uip_ipaddr_copy(smtpserver, server);
+00220 }
+00221 /*---------------------------------------------------------------------------*/
+00222 /**
+00223  * Send an e-mail.
+00224  *
+00225  * \param to The e-mail address of the receiver of the e-mail.
+00226  * \param cc The e-mail address of the CC: receivers of the e-mail.
+00227  * \param from The e-mail address of the sender of the e-mail.
+00228  * \param subject The subject of the e-mail.
+00229  * \param msg The actual e-mail message.
+00230  * \param msglen The length of the e-mail message.
+00231  */
+00232 unsigned char
+00233 smtp_send(char *to, char *cc, char *from,
+00234           char *subject, char *msg, u16_t msglen)
+00235 {
+00236   struct uip_conn *conn;
+00237 
+00238   conn = uip_connect(smtpserver, HTONS(25));
+00239   if(conn == NULL) {
+00240     return 0;
+00241   }
+00242   s.connected = 1;
+00243   s.to = to;
+00244   s.cc = cc;
+00245   s.from = from;
+00246   s.subject = subject;
+00247   s.msg = msg;
+00248   s.msglen = msglen;
+00249 
+00250   PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer));
+00251   
+00252   return 1;
+00253 }
+00254 /*---------------------------------------------------------------------------*/
+00255 void
+00256 smtp_init(void)
+00257 {
+00258   s.connected = 0;
+00259 }
+00260 /*---------------------------------------------------------------------------*/
+00261 /** @} */
+00262 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00175.html b/doc/html/a00175.html new file mode 100644 index 0000000..98342be --- /dev/null +++ b/doc/html/a00175.html @@ -0,0 +1,128 @@ + + +uIP 1.0: apps/smtp/smtp.h Source File + + + + + + +

apps/smtp/smtp.h

Go to the documentation of this file.
00001 
+00002 /**
+00003  * \addtogroup smtp
+00004  * @{
+00005  */
+00006 
+00007 
+00008 /**
+00009  * \file
+00010  * SMTP header file
+00011  * \author Adam Dunkels <adam@dunkels.com>
+00012  */
+00013 
+00014 /*
+00015  * Copyright (c) 2002, Adam Dunkels.
+00016  * All rights reserved.
+00017  *
+00018  * Redistribution and use in source and binary forms, with or without
+00019  * modification, are permitted provided that the following conditions
+00020  * are met:
+00021  * 1. Redistributions of source code must retain the above copyright
+00022  *    notice, this list of conditions and the following disclaimer.
+00023  * 2. Redistributions in binary form must reproduce the above copyright
+00024  *    notice, this list of conditions and the following disclaimer in the
+00025  *    documentation and/or other materials provided with the distribution.
+00026  * 3. The name of the author may not be used to endorse or promote
+00027  *    products derived from this software without specific prior
+00028  *    written permission.
+00029  *
+00030  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00031  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00032  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00033  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00034  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00035  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00036  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00037  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00038  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00039  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00040  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00041  *
+00042  * This file is part of the uIP TCP/IP stack.
+00043  *
+00044  * $Id: smtp.h,v 1.4 2006/06/11 21:46:37 adam Exp $
+00045  *
+00046  */
+00047 #ifndef __SMTP_H__
+00048 #define __SMTP_H__
+00049 
+00050 #include "uipopt.h"
+00051 
+00052 /**
+00053  * Error number that signifies a non-error condition.
+00054  */
+00055 #define SMTP_ERR_OK 0
+00056 
+00057 /**
+00058  * Callback function that is called when an e-mail transmission is
+00059  * done.
+00060  *
+00061  * This function must be implemented by the module that uses the SMTP
+00062  * module.
+00063  *
+00064  * \param error The number of the error if an error occured, or
+00065  * SMTP_ERR_OK.
+00066  */
+00067 void smtp_done(unsigned char error);
+00068 
+00069 void smtp_init(void);
+00070 
+00071 /* Functions. */
+00072 void smtp_configure(char *localhostname, u16_t *smtpserver);
+00073 unsigned char smtp_send(char *to, char *from,
+00074                         char *subject, char *msg,
+00075                         u16_t msglen);
+00076 #define SMTP_SEND(to, cc, from, subject, msg) \
+00077         smtp_send(to, cc, from, subject, msg, strlen(msg))
+00078 
+00079 void smtp_appcall(void);
+00080 
+00081 struct smtp_state {
+00082   u8_t state;
+00083   char *to;
+00084   char *from;
+00085   char *subject;
+00086   char *msg;
+00087   u16_t msglen;
+00088   
+00089   u16_t sentlen, textlen;
+00090   u16_t sendptr;
+00091 
+00092 };
+00093 
+00094 
+00095 #ifndef UIP_APPCALL
+00096 #define UIP_APPCALL     smtp_appcall
+00097 #endif
+00098 typedef struct smtp_state uip_tcp_appstate_t;
+00099 
+00100 
+00101 #endif /* __SMTP_H__ */
+00102 
+00103 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00176.html b/doc/html/a00176.html new file mode 100644 index 0000000..100bf7a --- /dev/null +++ b/doc/html/a00176.html @@ -0,0 +1,148 @@ + + +uIP 1.0: apps/telnetd/shell.c Source File + + + + + + +

apps/telnetd/shell.c

00001  /*
+00002  * Copyright (c) 2003, Adam Dunkels.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. The name of the author may not be used to endorse or promote
+00014  *    products derived from this software without specific prior
+00015  *    written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00018  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00019  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00021  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00023  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00026  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00027  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack.
+00030  *
+00031  * $Id: shell.c,v 1.1 2006/06/07 09:43:54 adam Exp $
+00032  *
+00033  */
+00034 
+00035 #include "shell.h"
+00036 
+00037 #include <string.h>
+00038 
+00039 struct ptentry {
+00040   char *commandstr;
+00041   void (* pfunc)(char *str);
+00042 };
+00043 
+00044 #define SHELL_PROMPT "uIP 1.0> "
+00045 
+00046 /*---------------------------------------------------------------------------*/
+00047 static void
+00048 parse(register char *str, struct ptentry *t)
+00049 {
+00050   struct ptentry *p;
+00051   for(p = t; p->commandstr != NULL; ++p) {
+00052     if(strncmp(p->commandstr, str, strlen(p->commandstr)) == 0) {
+00053       break;
+00054     }
+00055   }
+00056 
+00057   p->pfunc(str);
+00058 }
+00059 /*---------------------------------------------------------------------------*/
+00060 static void
+00061 inttostr(register char *str, unsigned int i)
+00062 {
+00063   str[0] = '0' + i / 100;
+00064   if(str[0] == '0') {
+00065     str[0] = ' ';
+00066   }
+00067   str[1] = '0' + (i / 10) % 10;
+00068   if(str[0] == ' ' && str[1] == '0') {
+00069     str[1] = ' ';
+00070   }
+00071   str[2] = '0' + i % 10;
+00072   str[3] = ' ';
+00073   str[4] = 0;
+00074 }
+00075 /*---------------------------------------------------------------------------*/
+00076 static void
+00077 help(char *str)
+00078 {
+00079   shell_output("Available commands:", "");
+00080   shell_output("stats   - show network statistics", "");
+00081   shell_output("conn    - show TCP connections", "");
+00082   shell_output("help, ? - show help", "");
+00083   shell_output("exit    - exit shell", "");
+00084 }
+00085 /*---------------------------------------------------------------------------*/
+00086 static void
+00087 unknown(char *str)
+00088 {
+00089   if(strlen(str) > 0) {
+00090     shell_output("Unknown command: ", str);
+00091   }
+00092 }
+00093 /*---------------------------------------------------------------------------*/
+00094 static struct ptentry parsetab[] =
+00095   {{"stats", help},
+00096    {"conn", help},
+00097    {"help", help},
+00098    {"exit", shell_quit},
+00099    {"?", help},
+00100 
+00101    /* Default action */
+00102    {NULL, unknown}};
+00103 /*---------------------------------------------------------------------------*/
+00104 void
+00105 shell_init(void)
+00106 {
+00107 }
+00108 /*---------------------------------------------------------------------------*/
+00109 void
+00110 shell_start(void)
+00111 {
+00112   shell_output("uIP command shell", "");
+00113   shell_output("Type '?' and return for help", "");
+00114   shell_prompt(SHELL_PROMPT);
+00115 }
+00116 /*---------------------------------------------------------------------------*/
+00117 void
+00118 shell_input(char *cmd)
+00119 {
+00120   parse(cmd, parsetab);
+00121   shell_prompt(SHELL_PROMPT);
+00122 }
+00123 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00177.html b/doc/html/a00177.html new file mode 100644 index 0000000..2126707 --- /dev/null +++ b/doc/html/a00177.html @@ -0,0 +1,129 @@ + + +uIP 1.0: apps/telnetd/shell.h Source File + + + + + + +

apps/telnetd/shell.h

Go to the documentation of this file.
00001 /**
+00002  * \file
+00003  * Interface for the Contiki shell.
+00004  * \author Adam Dunkels <adam@dunkels.com>
+00005  *
+00006  * Some of the functions declared in this file must be implemented as
+00007  * a shell back-end in the architecture specific files of a Contiki
+00008  * port.
+00009  */
+00010 
+00011 
+00012 /*
+00013  * Copyright (c) 2003, Adam Dunkels.
+00014  * All rights reserved.
+00015  *
+00016  * Redistribution and use in source and binary forms, with or without
+00017  * modification, are permitted provided that the following conditions
+00018  * are met:
+00019  * 1. Redistributions of source code must retain the above copyright
+00020  *    notice, this list of conditions and the following disclaimer.
+00021  * 2. Redistributions in binary form must reproduce the above copyright
+00022  *    notice, this list of conditions and the following disclaimer in the
+00023  *    documentation and/or other materials provided with the distribution.
+00024  * 3. The name of the author may not be used to endorse or promote
+00025  *    products derived from this software without specific prior
+00026  *    written permission.
+00027  *
+00028  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00029  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00030  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00031  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00032  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00033  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00034  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00035  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00036  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00037  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00038  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00039  *
+00040  * This file is part of the Contiki desktop OS.
+00041  *
+00042  * $Id: shell.h,v 1.1 2006/06/07 09:43:54 adam Exp $
+00043  *
+00044  */
+00045 #ifndef __SHELL_H__
+00046 #define __SHELL_H__
+00047 
+00048 /**
+00049  * Initialize the shell.
+00050  *
+00051  * Called when the shell front-end process starts. This function may
+00052  * be used to start listening for signals.
+00053  */
+00054 void shell_init(void);
+00055 
+00056 /**
+00057  * Start the shell back-end.
+00058  *
+00059  * Called by the front-end when a new shell is started.
+00060  */
+00061 void shell_start(void);
+00062 
+00063 /**
+00064  * Process a shell command.
+00065  *
+00066  * This function will be called by the shell GUI / telnet server whan
+00067  * a command has been entered that should be processed by the shell
+00068  * back-end.
+00069  *
+00070  * \param command The command to be processed.
+00071  */
+00072 void shell_input(char *command);
+00073 
+00074 /**
+00075  * Quit the shell.
+00076  *
+00077  */
+00078 void shell_quit(char *);
+00079 
+00080 
+00081 /**
+00082  * Print a string to the shell window.
+00083  *
+00084  * This function is implemented by the shell GUI / telnet server and
+00085  * can be called by the shell back-end to output a string in the
+00086  * shell window. The string is automatically appended with a linebreak.
+00087  *
+00088  * \param str1 The first half of the string to be output.
+00089  * \param str2 The second half of the string to be output.
+00090  */
+00091 void shell_output(char *str1, char *str2);
+00092 
+00093 /**
+00094  * Print a prompt to the shell window.
+00095  *
+00096  * This function can be used by the shell back-end to print out a
+00097  * prompt to the shell window.
+00098  *
+00099  * \param prompt The prompt to be printed.
+00100  *
+00101  */
+00102 void shell_prompt(char *prompt);
+00103 
+00104 #endif /* __SHELL_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00178.html b/doc/html/a00178.html new file mode 100644 index 0000000..9b19f4e --- /dev/null +++ b/doc/html/a00178.html @@ -0,0 +1,375 @@ + + +uIP 1.0: apps/telnetd/telnetd.c Source File + + + + + + +

apps/telnetd/telnetd.c

00001 /*
+00002  * Copyright (c) 2003, Adam Dunkels.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. The name of the author may not be used to endorse or promote
+00014  *    products derived from this software without specific prior
+00015  *    written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00018  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00019  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00021  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00023  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00026  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00027  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * $Id: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $
+00032  *
+00033  */
+00034 
+00035 #include "uip.h"
+00036 #include "telnetd.h"
+00037 #include "memb.h"
+00038 #include "shell.h"
+00039 
+00040 #include <string.h>
+00041 
+00042 #define ISO_nl       0x0a
+00043 #define ISO_cr       0x0d
+00044 
+00045 struct telnetd_line {
+00046   char line[TELNETD_CONF_LINELEN];
+00047 };
+00048 MEMB(linemem, struct telnetd_line, TELNETD_CONF_NUMLINES);
+00049 
+00050 #define STATE_NORMAL 0
+00051 #define STATE_IAC    1
+00052 #define STATE_WILL   2
+00053 #define STATE_WONT   3
+00054 #define STATE_DO     4
+00055 #define STATE_DONT   5
+00056 #define STATE_CLOSE  6
+00057 
+00058 static struct telnetd_state s;
+00059 
+00060 #define TELNET_IAC   255
+00061 #define TELNET_WILL  251
+00062 #define TELNET_WONT  252
+00063 #define TELNET_DO    253
+00064 #define TELNET_DONT  254
+00065 /*---------------------------------------------------------------------------*/
+00066 static char *
+00067 alloc_line(void)
+00068 {
+00069   return memb_alloc(&linemem);
+00070 }
+00071 /*---------------------------------------------------------------------------*/
+00072 static void
+00073 dealloc_line(char *line)
+00074 {
+00075   memb_free(&linemem, line);
+00076 }
+00077 /*---------------------------------------------------------------------------*/
+00078 void
+00079 shell_quit(char *str)
+00080 {
+00081   s.state = STATE_CLOSE;
+00082 }
+00083 /*---------------------------------------------------------------------------*/
+00084 static void
+00085 sendline(char *line)
+00086 {
+00087   static unsigned int i;
+00088   
+00089   for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+00090     if(s.lines[i] == NULL) {
+00091       s.lines[i] = line;
+00092       break;
+00093     }
+00094   }
+00095   if(i == TELNETD_CONF_NUMLINES) {
+00096     dealloc_line(line);
+00097   }
+00098 }
+00099 /*---------------------------------------------------------------------------*/
+00100 void
+00101 shell_prompt(char *str)
+00102 {
+00103   char *line;
+00104   line = alloc_line();
+00105   if(line != NULL) {
+00106     strncpy(line, str, TELNETD_CONF_LINELEN);
+00107     /*    petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
+00108     sendline(line);
+00109   }
+00110 }
+00111 /*---------------------------------------------------------------------------*/
+00112 void
+00113 shell_output(char *str1, char *str2)
+00114 {
+00115   static unsigned len;
+00116   char *line;
+00117 
+00118   line = alloc_line();
+00119   if(line != NULL) {
+00120     len = strlen(str1);
+00121     strncpy(line, str1, TELNETD_CONF_LINELEN);
+00122     if(len < TELNETD_CONF_LINELEN) {
+00123       strncpy(line + len, str2, TELNETD_CONF_LINELEN - len);
+00124     }
+00125     len = strlen(line);
+00126     if(len < TELNETD_CONF_LINELEN - 2) {
+00127       line[len] = ISO_cr;
+00128       line[len+1] = ISO_nl;
+00129       line[len+2] = 0;
+00130     }
+00131     /*    petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
+00132     sendline(line);
+00133   }
+00134 }
+00135 /*---------------------------------------------------------------------------*/
+00136 void
+00137 telnetd_init(void)
+00138 {
+00139   uip_listen(HTONS(23));
+00140   memb_init(&linemem);
+00141   shell_init();
+00142 }
+00143 /*---------------------------------------------------------------------------*/
+00144 static void
+00145 acked(void)
+00146 {
+00147   static unsigned int i;
+00148   
+00149   while(s.numsent > 0) {
+00150     dealloc_line(s.lines[0]);
+00151     for(i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
+00152       s.lines[i - 1] = s.lines[i];
+00153     }
+00154     s.lines[TELNETD_CONF_NUMLINES - 1] = NULL;
+00155     --s.numsent;
+00156   }
+00157 }
+00158 /*---------------------------------------------------------------------------*/
+00159 static void
+00160 senddata(void)
+00161 {
+00162   static char *bufptr, *lineptr;
+00163   static int buflen, linelen;
+00164   
+00165   bufptr = uip_appdata;
+00166   buflen = 0;
+00167   for(s.numsent = 0; s.numsent < TELNETD_CONF_NUMLINES &&
+00168         s.lines[s.numsent] != NULL ; ++s.numsent) {
+00169     lineptr = s.lines[s.numsent];
+00170     linelen = strlen(lineptr);
+00171     if(linelen > TELNETD_CONF_LINELEN) {
+00172       linelen = TELNETD_CONF_LINELEN;
+00173     }
+00174     if(buflen + linelen < uip_mss()) {
+00175       memcpy(bufptr, lineptr, linelen);
+00176       bufptr += linelen;
+00177       buflen += linelen;
+00178     } else {
+00179       break;
+00180     }
+00181   }
+00182   uip_send(uip_appdata, buflen);
+00183 }
+00184 /*---------------------------------------------------------------------------*/
+00185 static void
+00186 closed(void)
+00187 {
+00188   static unsigned int i;
+00189   
+00190   for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+00191     if(s.lines[i] != NULL) {
+00192       dealloc_line(s.lines[i]);
+00193     }
+00194   }
+00195 }
+00196 /*---------------------------------------------------------------------------*/
+00197 static void
+00198 get_char(u8_t c)
+00199 {
+00200   if(c == ISO_cr) {
+00201     return;
+00202   }
+00203   
+00204   s.buf[(int)s.bufptr] = c;
+00205   if(s.buf[(int)s.bufptr] == ISO_nl ||
+00206      s.bufptr == sizeof(s.buf) - 1) {
+00207     if(s.bufptr > 0) {
+00208       s.buf[(int)s.bufptr] = 0;
+00209       /*      petsciiconv_topetscii(s.buf, TELNETD_CONF_LINELEN);*/
+00210     }
+00211     shell_input(s.buf);
+00212     s.bufptr = 0;
+00213   } else {
+00214     ++s.bufptr;
+00215   }
+00216 }
+00217 /*---------------------------------------------------------------------------*/
+00218 static void
+00219 sendopt(u8_t option, u8_t value)
+00220 {
+00221   char *line;
+00222   line = alloc_line();
+00223   if(line != NULL) {
+00224     line[0] = TELNET_IAC;
+00225     line[1] = option;
+00226     line[2] = value;
+00227     line[3] = 0;
+00228     sendline(line);
+00229   }
+00230 }
+00231 /*---------------------------------------------------------------------------*/
+00232 static void
+00233 newdata(void)
+00234 {
+00235   u16_t len;
+00236   u8_t c;
+00237   char *dataptr;
+00238     
+00239   
+00240   len = uip_datalen();
+00241   dataptr = (char *)uip_appdata;
+00242   
+00243   while(len > 0 && s.bufptr < sizeof(s.buf)) {
+00244     c = *dataptr;
+00245     ++dataptr;
+00246     --len;
+00247     switch(s.state) {
+00248     case STATE_IAC:
+00249       if(c == TELNET_IAC) {
+00250         get_char(c);
+00251         s.state = STATE_NORMAL;
+00252       } else {
+00253         switch(c) {
+00254         case TELNET_WILL:
+00255           s.state = STATE_WILL;
+00256           break;
+00257         case TELNET_WONT:
+00258           s.state = STATE_WONT;
+00259           break;
+00260         case TELNET_DO:
+00261           s.state = STATE_DO;
+00262           break;
+00263         case TELNET_DONT:
+00264           s.state = STATE_DONT;
+00265           break;
+00266         default:
+00267           s.state = STATE_NORMAL;
+00268           break;
+00269         }
+00270       }
+00271       break;
+00272     case STATE_WILL:
+00273       /* Reply with a DONT */
+00274       sendopt(TELNET_DONT, c);
+00275       s.state = STATE_NORMAL;
+00276       break;
+00277       
+00278     case STATE_WONT:
+00279       /* Reply with a DONT */
+00280       sendopt(TELNET_DONT, c);
+00281       s.state = STATE_NORMAL;
+00282       break;
+00283     case STATE_DO:
+00284       /* Reply with a WONT */
+00285       sendopt(TELNET_WONT, c);
+00286       s.state = STATE_NORMAL;
+00287       break;
+00288     case STATE_DONT:
+00289       /* Reply with a WONT */
+00290       sendopt(TELNET_WONT, c);
+00291       s.state = STATE_NORMAL;
+00292       break;
+00293     case STATE_NORMAL:
+00294       if(c == TELNET_IAC) {
+00295         s.state = STATE_IAC;
+00296       } else {
+00297         get_char(c);
+00298       }
+00299       break;
+00300     }
+00301 
+00302     
+00303   }
+00304   
+00305 }
+00306 /*---------------------------------------------------------------------------*/
+00307 void
+00308 telnetd_appcall(void)
+00309 {
+00310   static unsigned int i;
+00311   if(uip_connected()) {
+00312     /*    tcp_markconn(uip_conn, &s);*/
+00313     for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+00314       s.lines[i] = NULL;
+00315     }
+00316     s.bufptr = 0;
+00317     s.state = STATE_NORMAL;
+00318 
+00319     shell_start();
+00320   }
+00321 
+00322   if(s.state == STATE_CLOSE) {
+00323     s.state = STATE_NORMAL;
+00324     uip_close();
+00325     return;
+00326   }
+00327   
+00328   if(uip_closed() ||
+00329      uip_aborted() ||
+00330      uip_timedout()) {
+00331     closed();
+00332   }
+00333   
+00334   if(uip_acked()) {
+00335     acked();
+00336   }
+00337   
+00338   if(uip_newdata()) {
+00339     newdata();
+00340   }
+00341   
+00342   if(uip_rexmit() ||
+00343      uip_newdata() ||
+00344      uip_acked() ||
+00345      uip_connected() ||
+00346      uip_poll()) {
+00347     senddata();
+00348   }
+00349 }
+00350 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00179.html b/doc/html/a00179.html new file mode 100644 index 0000000..139d6f0 --- /dev/null +++ b/doc/html/a00179.html @@ -0,0 +1,88 @@ + + +uIP 1.0: apps/telnetd/telnetd.h Source File + + + + + + +

apps/telnetd/telnetd.h

00001 /*
+00002  * Copyright (c) 2003, Adam Dunkels.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above
+00011  *    copyright notice, this list of conditions and the following
+00012  *    disclaimer in the documentation and/or other materials provided
+00013  *    with the distribution.
+00014  * 3. The name of the author may not be used to endorse or promote
+00015  *    products derived from this software without specific prior
+00016  *    written permission.
+00017  *
+00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00019  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00022  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00024  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00029  *
+00030  * This file is part of the uIP TCP/IP stack
+00031  *
+00032  * $Id: telnetd.h,v 1.2 2006/06/07 09:43:54 adam Exp $
+00033  *
+00034  */
+00035 #ifndef __TELNETD_H__
+00036 #define __TELNETD_H__
+00037 
+00038 #include "uipopt.h"
+00039 
+00040 void telnetd_appcall(void);
+00041 
+00042 #ifndef TELNETD_CONF_LINELEN
+00043 #define TELNETD_CONF_LINELEN 40
+00044 #endif
+00045 #ifndef TELNETD_CONF_NUMLINES
+00046 #define TELNETD_CONF_NUMLINES 16
+00047 #endif
+00048 
+00049 struct telnetd_state {
+00050   char *lines[TELNETD_CONF_NUMLINES];
+00051   char buf[TELNETD_CONF_LINELEN];
+00052   char bufptr;
+00053   u8_t numsent;
+00054   u8_t state;
+00055 };
+00056 
+00057 typedef struct telnetd_state uip_tcp_appstate_t;
+00058 
+00059 #ifndef UIP_APPCALL
+00060 #define UIP_APPCALL     telnetd_appcall
+00061 #endif
+00062 
+00063 #endif /* __TELNETD_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00180.html b/doc/html/a00180.html new file mode 100644 index 0000000..6f1abbc --- /dev/null +++ b/doc/html/a00180.html @@ -0,0 +1,464 @@ + + +uIP 1.0: apps/webclient/webclient.c Source File + + + + + + +

apps/webclient/webclient.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup webclient Web client
+00008  * @{
+00009  *
+00010  * This example shows a HTTP client that is able to download web pages
+00011  * and files from web servers. It requires a number of callback
+00012  * functions to be implemented by the module that utilizes the code:
+00013  * webclient_datahandler(), webclient_connected(),
+00014  * webclient_timedout(), webclient_aborted(), webclient_closed().
+00015  */
+00016 
+00017 /**
+00018  * \file
+00019  * Implementation of the HTTP client.
+00020  * \author Adam Dunkels <adam@dunkels.com>
+00021  */
+00022 
+00023 /*
+00024  * Copyright (c) 2002, Adam Dunkels.
+00025  * All rights reserved.
+00026  *
+00027  * Redistribution and use in source and binary forms, with or without
+00028  * modification, are permitted provided that the following conditions
+00029  * are met:
+00030  * 1. Redistributions of source code must retain the above copyright
+00031  *    notice, this list of conditions and the following disclaimer.
+00032  * 2. Redistributions in binary form must reproduce the above
+00033  *    copyright notice, this list of conditions and the following
+00034  *    disclaimer in the documentation and/or other materials provided
+00035  *    with the distribution.
+00036  * 3. The name of the author may not be used to endorse or promote
+00037  *    products derived from this software without specific prior
+00038  *    written permission.
+00039  *
+00040  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00041  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00042  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00043  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00044  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00045  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00046  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00047  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00048  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00049  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00050  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00051  *
+00052  * This file is part of the uIP TCP/IP stack.
+00053  *
+00054  * $Id: webclient.c,v 1.2 2006/06/11 21:46:37 adam Exp $
+00055  *
+00056  */
+00057 
+00058 #include "uip.h"
+00059 #include "uiplib.h"
+00060 #include "webclient.h"
+00061 #include "resolv.h"
+00062 
+00063 #include <string.h>
+00064 
+00065 #define WEBCLIENT_TIMEOUT 100
+00066 
+00067 #define WEBCLIENT_STATE_STATUSLINE 0
+00068 #define WEBCLIENT_STATE_HEADERS    1
+00069 #define WEBCLIENT_STATE_DATA       2
+00070 #define WEBCLIENT_STATE_CLOSE      3
+00071 
+00072 #define HTTPFLAG_NONE   0
+00073 #define HTTPFLAG_OK     1
+00074 #define HTTPFLAG_MOVED  2
+00075 #define HTTPFLAG_ERROR  3
+00076 
+00077 
+00078 #define ISO_nl       0x0a
+00079 #define ISO_cr       0x0d
+00080 #define ISO_space    0x20
+00081 
+00082 
+00083 static struct webclient_state s;
+00084 
+00085 /*-----------------------------------------------------------------------------------*/
+00086 char *
+00087 webclient_mimetype(void)
+00088 {
+00089   return s.mimetype;
+00090 }
+00091 /*-----------------------------------------------------------------------------------*/
+00092 char *
+00093 webclient_filename(void)
+00094 {
+00095   return s.file;
+00096 }
+00097 /*-----------------------------------------------------------------------------------*/
+00098 char *
+00099 webclient_hostname(void)
+00100 {
+00101   return s.host;
+00102 }
+00103 /*-----------------------------------------------------------------------------------*/
+00104 unsigned short
+00105 webclient_port(void)
+00106 {
+00107   return s.port;
+00108 }
+00109 /*-----------------------------------------------------------------------------------*/
+00110 void
+00111 webclient_init(void)
+00112 {
+00113 
+00114 }
+00115 /*-----------------------------------------------------------------------------------*/
+00116 static void
+00117 init_connection(void)
+00118 {
+00119   s.state = WEBCLIENT_STATE_STATUSLINE;
+00120 
+00121   s.getrequestleft = sizeof(http_get) - 1 + 1 +
+00122     sizeof(http_10) - 1 +
+00123     sizeof(http_crnl) - 1 +
+00124     sizeof(http_host) - 1 +
+00125     sizeof(http_crnl) - 1 +
+00126     strlen(http_user_agent_fields) +
+00127     strlen(s.file) + strlen(s.host);
+00128   s.getrequestptr = 0;
+00129 
+00130   s.httpheaderlineptr = 0;
+00131 }
+00132 /*-----------------------------------------------------------------------------------*/
+00133 void
+00134 webclient_close(void)
+00135 {
+00136   s.state = WEBCLIENT_STATE_CLOSE;
+00137 }
+00138 /*-----------------------------------------------------------------------------------*/
+00139 unsigned char
+00140 webclient_get(char *host, u16_t port, char *file)
+00141 {
+00142   struct uip_conn *conn;
+00143   uip_ipaddr_t *ipaddr;
+00144   static uip_ipaddr_t addr;
+00145   
+00146   /* First check if the host is an IP address. */
+00147   ipaddr = &addr;
+00148   if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) {
+00149     ipaddr = (uip_ipaddr_t *)resolv_lookup(host);
+00150     
+00151     if(ipaddr == NULL) {
+00152       return 0;
+00153     }
+00154   }
+00155   
+00156   conn = uip_connect(ipaddr, htons(port));
+00157   
+00158   if(conn == NULL) {
+00159     return 0;
+00160   }
+00161   
+00162   s.port = port;
+00163   strncpy(s.file, file, sizeof(s.file));
+00164   strncpy(s.host, host, sizeof(s.host));
+00165   
+00166   init_connection();
+00167   return 1;
+00168 }
+00169 /*-----------------------------------------------------------------------------------*/
+00170 static unsigned char *
+00171 copy_string(unsigned char *dest,
+00172             const unsigned char *src, unsigned char len)
+00173 {
+00174   strncpy(dest, src, len);
+00175   return dest + len;
+00176 }
+00177 /*-----------------------------------------------------------------------------------*/
+00178 static void
+00179 senddata(void)
+00180 {
+00181   u16_t len;
+00182   char *getrequest;
+00183   char *cptr;
+00184   
+00185   if(s.getrequestleft > 0) {
+00186     cptr = getrequest = (char *)uip_appdata;
+00187 
+00188     cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
+00189     cptr = copy_string(cptr, s.file, strlen(s.file));
+00190     *cptr++ = ISO_space;
+00191     cptr = copy_string(cptr, http_10, sizeof(http_10) - 1);
+00192 
+00193     cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
+00194     
+00195     cptr = copy_string(cptr, http_host, sizeof(http_host) - 1);
+00196     cptr = copy_string(cptr, s.host, strlen(s.host));
+00197     cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
+00198 
+00199     cptr = copy_string(cptr, http_user_agent_fields,
+00200                        strlen(http_user_agent_fields));
+00201     
+00202     len = s.getrequestleft > uip_mss()?
+00203       uip_mss():
+00204       s.getrequestleft;
+00205     uip_send(&(getrequest[s.getrequestptr]), len);
+00206   }
+00207 }
+00208 /*-----------------------------------------------------------------------------------*/
+00209 static void
+00210 acked(void)
+00211 {
+00212   u16_t len;
+00213   
+00214   if(s.getrequestleft > 0) {
+00215     len = s.getrequestleft > uip_mss()?
+00216       uip_mss():
+00217       s.getrequestleft;
+00218     s.getrequestleft -= len;
+00219     s.getrequestptr += len;
+00220   }
+00221 }
+00222 /*-----------------------------------------------------------------------------------*/
+00223 static u16_t
+00224 parse_statusline(u16_t len)
+00225 {
+00226   char *cptr;
+00227   
+00228   while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
+00229     s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
+00230     ++((char *)uip_appdata);
+00231     --len;
+00232     if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
+00233 
+00234       if((strncmp(s.httpheaderline, http_10,
+00235                   sizeof(http_10) - 1) == 0) ||
+00236          (strncmp(s.httpheaderline, http_11,
+00237                   sizeof(http_11) - 1) == 0)) {
+00238         cptr = &(s.httpheaderline[9]);
+00239         s.httpflag = HTTPFLAG_NONE;
+00240         if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) {
+00241           /* 200 OK */
+00242           s.httpflag = HTTPFLAG_OK;
+00243         } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 ||
+00244                   strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) {
+00245           /* 301 Moved permanently or 302 Found. Location: header line
+00246              will contain thw new location. */
+00247           s.httpflag = HTTPFLAG_MOVED;
+00248         } else {
+00249           s.httpheaderline[s.httpheaderlineptr - 1] = 0;
+00250         }
+00251       } else {
+00252         uip_abort();
+00253         webclient_aborted();
+00254         return 0;
+00255       }
+00256       
+00257       /* We're done parsing the status line, so we reset the pointer
+00258          and start parsing the HTTP headers.*/
+00259       s.httpheaderlineptr = 0;
+00260       s.state = WEBCLIENT_STATE_HEADERS;
+00261       break;
+00262     } else {
+00263       ++s.httpheaderlineptr;
+00264     }
+00265   }
+00266   return len;
+00267 }
+00268 /*-----------------------------------------------------------------------------------*/
+00269 static char
+00270 casecmp(char *str1, const char *str2, char len)
+00271 {
+00272   static char c;
+00273   
+00274   while(len > 0) {
+00275     c = *str1;
+00276     /* Force lower-case characters. */
+00277     if(c & 0x40) {
+00278       c |= 0x20;
+00279     }
+00280     if(*str2 != c) {
+00281       return 1;
+00282     }
+00283     ++str1;
+00284     ++str2;
+00285     --len;
+00286   }
+00287   return 0;
+00288 }
+00289 /*-----------------------------------------------------------------------------------*/
+00290 static u16_t
+00291 parse_headers(u16_t len)
+00292 {
+00293   char *cptr;
+00294   static unsigned char i;
+00295   
+00296   while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
+00297     s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
+00298     ++((char *)uip_appdata);
+00299     --len;
+00300     if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
+00301       /* We have an entire HTTP header line in s.httpheaderline, so
+00302          we parse it. */
+00303       if(s.httpheaderline[0] == ISO_cr) {
+00304         /* This was the last header line (i.e., and empty "\r\n"), so
+00305            we are done with the headers and proceed with the actual
+00306            data. */
+00307         s.state = WEBCLIENT_STATE_DATA;
+00308         return len;
+00309       }
+00310 
+00311       s.httpheaderline[s.httpheaderlineptr - 1] = 0;
+00312       /* Check for specific HTTP header fields. */
+00313       if(casecmp(s.httpheaderline, http_content_type,
+00314                      sizeof(http_content_type) - 1) == 0) {
+00315         /* Found Content-type field. */
+00316         cptr = strchr(s.httpheaderline, ';');
+00317         if(cptr != NULL) {
+00318           *cptr = 0;
+00319         }
+00320         strncpy(s.mimetype, s.httpheaderline +
+00321                 sizeof(http_content_type) - 1, sizeof(s.mimetype));
+00322       } else if(casecmp(s.httpheaderline, http_location,
+00323                             sizeof(http_location) - 1) == 0) {
+00324         cptr = s.httpheaderline +
+00325           sizeof(http_location) - 1;
+00326         
+00327         if(strncmp(cptr, http_http, 7) == 0) {
+00328           cptr += 7;
+00329           for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
+00330             if(*cptr == 0 ||
+00331                *cptr == '/' ||
+00332                *cptr == ' ' ||
+00333                *cptr == ':') {
+00334               s.host[i] = 0;
+00335               break;
+00336             }
+00337             s.host[i] = *cptr;
+00338             ++cptr;
+00339           }
+00340         }
+00341         strncpy(s.file, cptr, sizeof(s.file));
+00342         /*      s.file[s.httpheaderlineptr - i] = 0;*/
+00343       }
+00344 
+00345 
+00346       /* We're done parsing, so we reset the pointer and start the
+00347          next line. */
+00348       s.httpheaderlineptr = 0;
+00349     } else {
+00350       ++s.httpheaderlineptr;
+00351     }
+00352   }
+00353   return len;
+00354 }
+00355 /*-----------------------------------------------------------------------------------*/
+00356 static void
+00357 newdata(void)
+00358 {
+00359   u16_t len;
+00360 
+00361   len = uip_datalen();
+00362 
+00363   if(s.state == WEBCLIENT_STATE_STATUSLINE) {
+00364     len = parse_statusline(len);
+00365   }
+00366   
+00367   if(s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
+00368     len = parse_headers(len);
+00369   }
+00370 
+00371   if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
+00372      s.httpflag != HTTPFLAG_MOVED) {
+00373     webclient_datahandler((char *)uip_appdata, len);
+00374   }
+00375 }
+00376 /*-----------------------------------------------------------------------------------*/
+00377 void
+00378 webclient_appcall(void)
+00379 {
+00380   if(uip_connected()) {
+00381     s.timer = 0;
+00382     s.state = WEBCLIENT_STATE_STATUSLINE;
+00383     senddata();
+00384     webclient_connected();
+00385     return;
+00386   }
+00387 
+00388   if(s.state == WEBCLIENT_STATE_CLOSE) {
+00389     webclient_closed();
+00390     uip_abort();
+00391     return;
+00392   }
+00393 
+00394   if(uip_aborted()) {
+00395     webclient_aborted();
+00396   }
+00397   if(uip_timedout()) {
+00398     webclient_timedout();
+00399   }
+00400 
+00401   
+00402   if(uip_acked()) {
+00403     s.timer = 0;
+00404     acked();
+00405   }
+00406   if(uip_newdata()) {
+00407     s.timer = 0;
+00408     newdata();
+00409   }
+00410   if(uip_rexmit() ||
+00411      uip_newdata() ||
+00412      uip_acked()) {
+00413     senddata();
+00414   } else if(uip_poll()) {
+00415     ++s.timer;
+00416     if(s.timer == WEBCLIENT_TIMEOUT) {
+00417       webclient_timedout();
+00418       uip_abort();
+00419       return;
+00420     }
+00421         /*    senddata();*/
+00422   }
+00423 
+00424   if(uip_closed()) {
+00425     if(s.httpflag != HTTPFLAG_MOVED) {
+00426       /* Send NULL data to signal EOF. */
+00427       webclient_datahandler(NULL, 0);
+00428     } else {
+00429       if(resolv_lookup(s.host) == NULL) {
+00430         resolv_query(s.host);
+00431       }
+00432       webclient_get(s.host, s.port, s.file);
+00433     }
+00434   }
+00435 }
+00436 /*-----------------------------------------------------------------------------------*/
+00437 
+00438 /** @} */
+00439 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00181.html b/doc/html/a00181.html new file mode 100644 index 0000000..4407232 --- /dev/null +++ b/doc/html/a00181.html @@ -0,0 +1,253 @@ + + +uIP 1.0: apps/webclient/webclient.h Source File + + + + + + +

apps/webclient/webclient.h

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup webclient
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \file
+00008  * Header file for the HTTP client.
+00009  * \author Adam Dunkels <adam@dunkels.com>
+00010  */
+00011 
+00012 /*
+00013  * Copyright (c) 2002, Adam Dunkels.
+00014  * All rights reserved.
+00015  *
+00016  * Redistribution and use in source and binary forms, with or without
+00017  * modification, are permitted provided that the following conditions
+00018  * are met:
+00019  * 1. Redistributions of source code must retain the above copyright
+00020  *    notice, this list of conditions and the following disclaimer.
+00021  * 2. Redistributions in binary form must reproduce the above
+00022  *    copyright notice, this list of conditions and the following
+00023  *    disclaimer in the documentation and/or other materials provided
+00024  *    with the distribution.
+00025  * 3. The name of the author may not be used to endorse or promote
+00026  *    products derived from this software without specific prior
+00027  *    written permission.
+00028  *
+00029  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00030  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00031  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00033  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00035  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00036  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00037  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00038  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00039  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00040  *
+00041  * This file is part of the uIP TCP/IP stack.
+00042  *
+00043  * $Id: webclient.h,v 1.2 2006/06/11 21:46:37 adam Exp $
+00044  *
+00045  */
+00046 #ifndef __WEBCLIENT_H__
+00047 #define __WEBCLIENT_H__
+00048 
+00049 
+00050 #include "webclient-strings.h"
+00051 #include "uipopt.h"
+00052 
+00053 #define WEBCLIENT_CONF_MAX_URLLEN 100
+00054 
+00055 struct webclient_state {
+00056   u8_t timer;
+00057   u8_t state;
+00058   u8_t httpflag;
+00059 
+00060   u16_t port;
+00061   char host[40];
+00062   char file[WEBCLIENT_CONF_MAX_URLLEN];
+00063   u16_t getrequestptr;
+00064   u16_t getrequestleft;
+00065   
+00066   char httpheaderline[200];
+00067   u16_t httpheaderlineptr;
+00068 
+00069   char mimetype[32];
+00070 };
+00071 
+00072 typedef struct webclient_state uip_tcp_appstate_t;
+00073 #define UIP_APPCALL webclient_appcall
+00074 
+00075 /**
+00076  * Callback function that is called from the webclient code when HTTP
+00077  * data has been received.
+00078  *
+00079  * This function must be implemented by the module that uses the
+00080  * webclient code. The function is called from the webclient module
+00081  * when HTTP data has been received. The function is not called when
+00082  * HTTP headers are received, only for the actual data.
+00083  *
+00084  * \note This function is called many times, repetedly, when data is
+00085  * being received, and not once when all data has been received.
+00086  *
+00087  * \param data A pointer to the data that has been received.
+00088  * \param len The length of the data that has been received.
+00089  */
+00090 void webclient_datahandler(char *data, u16_t len);
+00091 
+00092 /**
+00093  * Callback function that is called from the webclient code when the
+00094  * HTTP connection has been connected to the web server.
+00095  *
+00096  * This function must be implemented by the module that uses the
+00097  * webclient code.
+00098  */
+00099 void webclient_connected(void);
+00100 
+00101 /**
+00102  * Callback function that is called from the webclient code if the
+00103  * HTTP connection to the web server has timed out.
+00104  *
+00105  * This function must be implemented by the module that uses the
+00106  * webclient code.
+00107  */
+00108 void webclient_timedout(void);
+00109 
+00110 /**
+00111  * Callback function that is called from the webclient code if the
+00112  * HTTP connection to the web server has been aborted by the web
+00113  * server.
+00114  *
+00115  * This function must be implemented by the module that uses the
+00116  * webclient code.
+00117  */
+00118 void webclient_aborted(void);
+00119 
+00120 /**
+00121  * Callback function that is called from the webclient code when the
+00122  * HTTP connection to the web server has been closed.
+00123  *
+00124  * This function must be implemented by the module that uses the
+00125  * webclient code.
+00126  */
+00127 void webclient_closed(void);
+00128 
+00129 
+00130 
+00131 /**
+00132  * Initialize the webclient module.
+00133  */
+00134 void webclient_init(void);
+00135 
+00136 /**
+00137  * Open an HTTP connection to a web server and ask for a file using
+00138  * the GET method.
+00139  *
+00140  * This function opens an HTTP connection to the specified web server
+00141  * and requests the specified file using the GET method. When the HTTP
+00142  * connection has been connected, the webclient_connected() callback
+00143  * function is called and when the HTTP data arrives the
+00144  * webclient_datahandler() callback function is called.
+00145  *
+00146  * The callback function webclient_timedout() is called if the web
+00147  * server could not be contacted, and the webclient_aborted() callback
+00148  * function is called if the HTTP connection is aborted by the web
+00149  * server.
+00150  *
+00151  * When the HTTP request has been completed and the HTTP connection is
+00152  * closed, the webclient_closed() callback function will be called.
+00153  *
+00154  * \note If the function is passed a host name, it must already be in
+00155  * the resolver cache in order for the function to connect to the web
+00156  * server. It is therefore up to the calling module to implement the
+00157  * resolver calls and the signal handler used for reporting a resolv
+00158  * query answer.
+00159  *
+00160  * \param host A pointer to a string containing either a host name or
+00161  * a numerical IP address in dotted decimal notation (e.g., 192.168.23.1).
+00162  *
+00163  * \param port The port number to which to connect, in host byte order.
+00164  *
+00165  * \param file A pointer to the name of the file to get.
+00166  *
+00167  * \retval 0 if the host name could not be found in the cache, or
+00168  * if a TCP connection could not be created.
+00169  *
+00170  * \retval 1 if the connection was initiated.
+00171  */
+00172 unsigned char webclient_get(char *host, u16_t port, char *file);
+00173 
+00174 /**
+00175  * Close the currently open HTTP connection.
+00176  */
+00177 void webclient_close(void);
+00178 void webclient_appcall(void);
+00179 
+00180 /**
+00181  * Obtain the MIME type of the current HTTP data stream.
+00182  *
+00183  * \return A pointer to a string contaning the MIME type. The string
+00184  * may be empty if no MIME type was reported by the web server.
+00185  */
+00186 char *webclient_mimetype(void);
+00187 
+00188 /**
+00189  * Obtain the filename of the current HTTP data stream.
+00190  *
+00191  * The filename of an HTTP request may be changed by the web server,
+00192  * and may therefore not be the same as when the original GET request
+00193  * was made with webclient_get(). This function is used for obtaining
+00194  * the current filename.
+00195  *
+00196  * \return A pointer to the current filename.
+00197  */
+00198 char *webclient_filename(void);
+00199 
+00200 /**
+00201  * Obtain the hostname of the current HTTP data stream.
+00202  *
+00203  * The hostname of the web server of an HTTP request may be changed
+00204  * by the web server, and may therefore not be the same as when the
+00205  * original GET request was made with webclient_get(). This function
+00206  * is used for obtaining the current hostname.
+00207  *
+00208  * \return A pointer to the current hostname.
+00209  */
+00210 char *webclient_hostname(void);
+00211 
+00212 /**
+00213  * Obtain the port number of the current HTTP data stream.
+00214  *
+00215  * The port number of an HTTP request may be changed by the web
+00216  * server, and may therefore not be the same as when the original GET
+00217  * request was made with webclient_get(). This function is used for
+00218  * obtaining the current port number.
+00219  *
+00220  * \return The port number of the current HTTP data stream, in host byte order.
+00221  */
+00222 unsigned short webclient_port(void);
+00223 
+00224 
+00225 
+00226 #endif /* __WEBCLIENT_H__ */
+00227 
+00228 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00182.html b/doc/html/a00182.html new file mode 100644 index 0000000..cb9d145 --- /dev/null +++ b/doc/html/a00182.html @@ -0,0 +1,228 @@ + + +uIP 1.0: apps/webserver/httpd-cgi.c Source File + + + + + + +

apps/webserver/httpd-cgi.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup httpd
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \file
+00008  *         Web server script interface
+00009  * \author
+00010  *         Adam Dunkels <adam@sics.se>
+00011  *
+00012  */
+00013 
+00014 /*
+00015  * Copyright (c) 2001-2006, Adam Dunkels.
+00016  * All rights reserved.
+00017  *
+00018  * Redistribution and use in source and binary forms, with or without
+00019  * modification, are permitted provided that the following conditions
+00020  * are met:
+00021  * 1. Redistributions of source code must retain the above copyright
+00022  *    notice, this list of conditions and the following disclaimer.
+00023  * 2. Redistributions in binary form must reproduce the above copyright
+00024  *    notice, this list of conditions and the following disclaimer in the
+00025  *    documentation and/or other materials provided with the distribution.
+00026  * 3. The name of the author may not be used to endorse or promote
+00027  *    products derived from this software without specific prior
+00028  *    written permission.
+00029  *
+00030  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00031  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00032  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00033  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00034  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00035  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00036  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00037  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00038  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00039  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00040  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00041  *
+00042  * This file is part of the uIP TCP/IP stack.
+00043  *
+00044  * $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $
+00045  *
+00046  */
+00047 
+00048 #include "uip.h"
+00049 #include "psock.h"
+00050 #include "httpd.h"
+00051 #include "httpd-cgi.h"
+00052 #include "httpd-fs.h"
+00053 
+00054 #include <stdio.h>
+00055 #include <string.h>
+00056 
+00057 HTTPD_CGI_CALL(file, "file-stats", file_stats);
+00058 HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats);
+00059 HTTPD_CGI_CALL(net, "net-stats", net_stats);
+00060 
+00061 static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, NULL };
+00062 
+00063 /*---------------------------------------------------------------------------*/
+00064 static
+00065 PT_THREAD(nullfunction(struct httpd_state *s, char *ptr))
+00066 {
+00067   PSOCK_BEGIN(&s->sout);
+00068   PSOCK_END(&s->sout);
+00069 }
+00070 /*---------------------------------------------------------------------------*/
+00071 httpd_cgifunction
+00072 httpd_cgi(char *name)
+00073 {
+00074   const struct httpd_cgi_call **f;
+00075 
+00076   /* Find the matching name in the table, return the function. */
+00077   for(f = calls; *f != NULL; ++f) {
+00078     if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) {
+00079       return (*f)->function;
+00080     }
+00081   }
+00082   return nullfunction;
+00083 }
+00084 /*---------------------------------------------------------------------------*/
+00085 static unsigned short
+00086 generate_file_stats(void *arg)
+00087 {
+00088   char *f = (char *)arg;
+00089   return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f));
+00090 }
+00091 /*---------------------------------------------------------------------------*/
+00092 static
+00093 PT_THREAD(file_stats(struct httpd_state *s, char *ptr))
+00094 {
+00095   PSOCK_BEGIN(&s->sout);
+00096 
+00097   PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1);
+00098   
+00099   PSOCK_END(&s->sout);
+00100 }
+00101 /*---------------------------------------------------------------------------*/
+00102 static const char closed[] =   /*  "CLOSED",*/
+00103 {0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0};
+00104 static const char syn_rcvd[] = /*  "SYN-RCVD",*/
+00105 {0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56,
+00106  0x44,  0};
+00107 static const char syn_sent[] = /*  "SYN-SENT",*/
+00108 {0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e,
+00109  0x54,  0};
+00110 static const char established[] = /*  "ESTABLISHED",*/
+00111 {0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48,
+00112  0x45, 0x44, 0};
+00113 static const char fin_wait_1[] = /*  "FIN-WAIT-1",*/
+00114 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
+00115  0x54, 0x2d, 0x31, 0};
+00116 static const char fin_wait_2[] = /*  "FIN-WAIT-2",*/
+00117 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
+00118  0x54, 0x2d, 0x32, 0};
+00119 static const char closing[] = /*  "CLOSING",*/
+00120 {0x43, 0x4c, 0x4f, 0x53, 0x49,
+00121  0x4e, 0x47, 0};
+00122 static const char time_wait[] = /*  "TIME-WAIT,"*/
+00123 {0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41,
+00124  0x49, 0x54, 0};
+00125 static const char last_ack[] = /*  "LAST-ACK"*/
+00126 {0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43,
+00127  0x4b, 0};
+00128 
+00129 static const char *states[] = {
+00130   closed,
+00131   syn_rcvd,
+00132   syn_sent,
+00133   established,
+00134   fin_wait_1,
+00135   fin_wait_2,
+00136   closing,
+00137   time_wait,
+00138   last_ack};
+00139   
+00140 
+00141 static unsigned short
+00142 generate_tcp_stats(void *arg)
+00143 {
+00144   struct uip_conn *conn;
+00145   struct httpd_state *s = (struct httpd_state *)arg;
+00146     
+00147   conn = &uip_conns[s->count];
+00148   return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
+00149                  "<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n",
+00150                  htons(conn->lport),
+00151                  htons(conn->ripaddr[0]) >> 8,
+00152                  htons(conn->ripaddr[0]) & 0xff,
+00153                  htons(conn->ripaddr[1]) >> 8,
+00154                  htons(conn->ripaddr[1]) & 0xff,
+00155                  htons(conn->rport),
+00156                  states[conn->tcpstateflags & UIP_TS_MASK],
+00157                  conn->nrtx,
+00158                  conn->timer,
+00159                  (uip_outstanding(conn))? '*':' ',
+00160                  (uip_stopped(conn))? '!':' ');
+00161 }
+00162 /*---------------------------------------------------------------------------*/
+00163 static
+00164 PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr))
+00165 {
+00166   
+00167   PSOCK_BEGIN(&s->sout);
+00168 
+00169   for(s->count = 0; s->count < UIP_CONNS; ++s->count) {
+00170     if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
+00171       PSOCK_GENERATOR_SEND(&s->sout, generate_tcp_stats, s);
+00172     }
+00173   }
+00174 
+00175   PSOCK_END(&s->sout);
+00176 }
+00177 /*---------------------------------------------------------------------------*/
+00178 static unsigned short
+00179 generate_net_stats(void *arg)
+00180 {
+00181   struct httpd_state *s = (struct httpd_state *)arg;
+00182   return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
+00183                   "%5u\n", ((uip_stats_t *)&uip_stat)[s->count]);
+00184 }
+00185 
+00186 static
+00187 PT_THREAD(net_stats(struct httpd_state *s, char *ptr))
+00188 {
+00189   PSOCK_BEGIN(&s->sout);
+00190 
+00191 #if UIP_STATISTICS
+00192 
+00193   for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t);
+00194       ++s->count) {
+00195     PSOCK_GENERATOR_SEND(&s->sout, generate_net_stats, s);
+00196   }
+00197   
+00198 #endif /* UIP_STATISTICS */
+00199   
+00200   PSOCK_END(&s->sout);
+00201 }
+00202 /*---------------------------------------------------------------------------*/
+00203 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00183.html b/doc/html/a00183.html new file mode 100644 index 0000000..0c75347 --- /dev/null +++ b/doc/html/a00183.html @@ -0,0 +1,109 @@ + + +uIP 1.0: apps/webserver/httpd-cgi.h Source File + + + + + + +

apps/webserver/httpd-cgi.h

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup httpd
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \file
+00008  *         Web server script interface header file
+00009  * \author
+00010  *         Adam Dunkels <adam@sics.se>
+00011  *
+00012  */
+00013 
+00014 
+00015 
+00016 /*
+00017  * Copyright (c) 2001, Adam Dunkels.
+00018  * All rights reserved.
+00019  *
+00020  * Redistribution and use in source and binary forms, with or without
+00021  * modification, are permitted provided that the following conditions
+00022  * are met:
+00023  * 1. Redistributions of source code must retain the above copyright
+00024  *    notice, this list of conditions and the following disclaimer.
+00025  * 2. Redistributions in binary form must reproduce the above copyright
+00026  *    notice, this list of conditions and the following disclaimer in the
+00027  *    documentation and/or other materials provided with the distribution.
+00028  * 3. The name of the author may not be used to endorse or promote
+00029  *    products derived from this software without specific prior
+00030  *    written permission.
+00031  *
+00032  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00033  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00034  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00035  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00036  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00037  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00038  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00039  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00040  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00041  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00042  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00043  *
+00044  * This file is part of the uIP TCP/IP stack.
+00045  *
+00046  * $Id: httpd-cgi.h,v 1.2 2006/06/11 21:46:38 adam Exp $
+00047  *
+00048  */
+00049 
+00050 #ifndef __HTTPD_CGI_H__
+00051 #define __HTTPD_CGI_H__
+00052 
+00053 #include "psock.h"
+00054 #include "httpd.h"
+00055 
+00056 typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *));
+00057 
+00058 httpd_cgifunction httpd_cgi(char *name);
+00059 
+00060 struct httpd_cgi_call {
+00061   const char *name;
+00062   const httpd_cgifunction function;
+00063 };
+00064 
+00065 /**
+00066  * \brief      HTTPD CGI function declaration
+00067  * \param name The C variable name of the function
+00068  * \param str  The string name of the function, used in the script file
+00069  * \param function A pointer to the function that implements it
+00070  *
+00071  *             This macro is used for declaring a HTTPD CGI
+00072  *             function. This function is then added to the list of
+00073  *             HTTPD CGI functions with the httpd_cgi_add() function.
+00074  *
+00075  * \hideinitializer
+00076  */
+00077 #define HTTPD_CGI_CALL(name, str, function) \
+00078 static PT_THREAD(function(struct httpd_state *, char *)); \
+00079 static const struct httpd_cgi_call name = {str, function}
+00080 
+00081 void httpd_cgi_init(void);
+00082 #endif /* __HTTPD_CGI_H__ */
+00083 
+00084 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00184.html b/doc/html/a00184.html new file mode 100644 index 0000000..f49fd56 --- /dev/null +++ b/doc/html/a00184.html @@ -0,0 +1,363 @@ + + +uIP 1.0: apps/webserver/httpd.c Source File + + + + + + +

apps/webserver/httpd.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup apps
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup httpd Web server
+00008  * @{
+00009  * The uIP web server is a very simplistic implementation of an HTTP
+00010  * server. It can serve web pages and files from a read-only ROM
+00011  * filesystem, and provides a very small scripting language.
+00012 
+00013  */
+00014 
+00015 /**
+00016  * \file
+00017  *         Web server
+00018  * \author
+00019  *         Adam Dunkels <adam@sics.se>
+00020  */
+00021 
+00022 
+00023 /*
+00024  * Copyright (c) 2004, Adam Dunkels.
+00025  * All rights reserved.
+00026  *
+00027  * Redistribution and use in source and binary forms, with or without
+00028  * modification, are permitted provided that the following conditions
+00029  * are met:
+00030  * 1. Redistributions of source code must retain the above copyright
+00031  *    notice, this list of conditions and the following disclaimer.
+00032  * 2. Redistributions in binary form must reproduce the above copyright
+00033  *    notice, this list of conditions and the following disclaimer in the
+00034  *    documentation and/or other materials provided with the distribution.
+00035  * 3. Neither the name of the Institute nor the names of its contributors
+00036  *    may be used to endorse or promote products derived from this software
+00037  *    without specific prior written permission.
+00038  *
+00039  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00040  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00041  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00042  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00043  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00044  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00045  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00046  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00047  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00048  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00049  * SUCH DAMAGE.
+00050  *
+00051  * This file is part of the uIP TCP/IP stack.
+00052  *
+00053  * Author: Adam Dunkels <adam@sics.se>
+00054  *
+00055  * $Id: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $
+00056  */
+00057 
+00058 #include "uip.h"
+00059 #include "httpd.h"
+00060 #include "httpd-fs.h"
+00061 #include "httpd-cgi.h"
+00062 #include "http-strings.h"
+00063 
+00064 #include <string.h>
+00065 
+00066 #define STATE_WAITING 0
+00067 #define STATE_OUTPUT  1
+00068 
+00069 #define ISO_nl      0x0a
+00070 #define ISO_space   0x20
+00071 #define ISO_bang    0x21
+00072 #define ISO_percent 0x25
+00073 #define ISO_period  0x2e
+00074 #define ISO_slash   0x2f
+00075 #define ISO_colon   0x3a
+00076 
+00077 
+00078 /*---------------------------------------------------------------------------*/
+00079 static unsigned short
+00080 generate_part_of_file(void *state)
+00081 {
+00082   struct httpd_state *s = (struct httpd_state *)state;
+00083 
+00084   if(s->file.len > uip_mss()) {
+00085     s->len = uip_mss();
+00086   } else {
+00087     s->len = s->file.len;
+00088   }
+00089   memcpy(uip_appdata, s->file.data, s->len);
+00090   
+00091   return s->len;
+00092 }
+00093 /*---------------------------------------------------------------------------*/
+00094 static
+00095 PT_THREAD(send_file(struct httpd_state *s))
+00096 {
+00097   PSOCK_BEGIN(&s->sout);
+00098   
+00099   do {
+00100     PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s);
+00101     s->file.len -= s->len;
+00102     s->file.data += s->len;
+00103   } while(s->file.len > 0);
+00104       
+00105   PSOCK_END(&s->sout);
+00106 }
+00107 /*---------------------------------------------------------------------------*/
+00108 static
+00109 PT_THREAD(send_part_of_file(struct httpd_state *s))
+00110 {
+00111   PSOCK_BEGIN(&s->sout);
+00112 
+00113   PSOCK_SEND(&s->sout, s->file.data, s->len);
+00114   
+00115   PSOCK_END(&s->sout);
+00116 }
+00117 /*---------------------------------------------------------------------------*/
+00118 static void
+00119 next_scriptstate(struct httpd_state *s)
+00120 {
+00121   char *p;
+00122   p = strchr(s->scriptptr, ISO_nl) + 1;
+00123   s->scriptlen -= (unsigned short)(p - s->scriptptr);
+00124   s->scriptptr = p;
+00125 }
+00126 /*---------------------------------------------------------------------------*/
+00127 static
+00128 PT_THREAD(handle_script(struct httpd_state *s))
+00129 {
+00130   char *ptr;
+00131   
+00132   PT_BEGIN(&s->scriptpt);
+00133 
+00134 
+00135   while(s->file.len > 0) {
+00136 
+00137     /* Check if we should start executing a script. */
+00138     if(*s->file.data == ISO_percent &&
+00139        *(s->file.data + 1) == ISO_bang) {
+00140       s->scriptptr = s->file.data + 3;
+00141       s->scriptlen = s->file.len - 3;
+00142       if(*(s->scriptptr - 1) == ISO_colon) {
+00143         httpd_fs_open(s->scriptptr + 1, &s->file);
+00144         PT_WAIT_THREAD(&s->scriptpt, send_file(s));
+00145       } else {
+00146         PT_WAIT_THREAD(&s->scriptpt,
+00147                        httpd_cgi(s->scriptptr)(s, s->scriptptr));
+00148       }
+00149       next_scriptstate(s);
+00150       
+00151       /* The script is over, so we reset the pointers and continue
+00152          sending the rest of the file. */
+00153       s->file.data = s->scriptptr;
+00154       s->file.len = s->scriptlen;
+00155     } else {
+00156       /* See if we find the start of script marker in the block of HTML
+00157          to be sent. */
+00158 
+00159       if(s->file.len > uip_mss()) {
+00160         s->len = uip_mss();
+00161       } else {
+00162         s->len = s->file.len;
+00163       }
+00164 
+00165       if(*s->file.data == ISO_percent) {
+00166         ptr = strchr(s->file.data + 1, ISO_percent);
+00167       } else {
+00168         ptr = strchr(s->file.data, ISO_percent);
+00169       }
+00170       if(ptr != NULL &&
+00171          ptr != s->file.data) {
+00172         s->len = (int)(ptr - s->file.data);
+00173         if(s->len >= uip_mss()) {
+00174           s->len = uip_mss();
+00175         }
+00176       }
+00177       PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s));
+00178       s->file.data += s->len;
+00179       s->file.len -= s->len;
+00180       
+00181     }
+00182   }
+00183   
+00184   PT_END(&s->scriptpt);
+00185 }
+00186 /*---------------------------------------------------------------------------*/
+00187 static
+00188 PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr))
+00189 {
+00190   char *ptr;
+00191 
+00192   PSOCK_BEGIN(&s->sout);
+00193 
+00194   PSOCK_SEND_STR(&s->sout, statushdr);
+00195 
+00196   ptr = strrchr(s->filename, ISO_period);
+00197   if(ptr == NULL) {
+00198     PSOCK_SEND_STR(&s->sout, http_content_type_binary);
+00199   } else if(strncmp(http_html, ptr, 5) == 0 ||
+00200             strncmp(http_shtml, ptr, 6) == 0) {
+00201     PSOCK_SEND_STR(&s->sout, http_content_type_html);
+00202   } else if(strncmp(http_css, ptr, 4) == 0) {
+00203     PSOCK_SEND_STR(&s->sout, http_content_type_css);
+00204   } else if(strncmp(http_png, ptr, 4) == 0) {
+00205     PSOCK_SEND_STR(&s->sout, http_content_type_png);
+00206   } else if(strncmp(http_gif, ptr, 4) == 0) {
+00207     PSOCK_SEND_STR(&s->sout, http_content_type_gif);
+00208   } else if(strncmp(http_jpg, ptr, 4) == 0) {
+00209     PSOCK_SEND_STR(&s->sout, http_content_type_jpg);
+00210   } else {
+00211     PSOCK_SEND_STR(&s->sout, http_content_type_plain);
+00212   }
+00213   PSOCK_END(&s->sout);
+00214 }
+00215 /*---------------------------------------------------------------------------*/
+00216 static
+00217 PT_THREAD(handle_output(struct httpd_state *s))
+00218 {
+00219   char *ptr;
+00220   
+00221   PT_BEGIN(&s->outputpt);
+00222  
+00223   if(!httpd_fs_open(s->filename, &s->file)) {
+00224     httpd_fs_open(http_404_html, &s->file);
+00225     strcpy(s->filename, http_404_html);
+00226     PT_WAIT_THREAD(&s->outputpt,
+00227                    send_headers(s,
+00228                    http_header_404));
+00229     PT_WAIT_THREAD(&s->outputpt,
+00230                    send_file(s));
+00231   } else {
+00232     PT_WAIT_THREAD(&s->outputpt,
+00233                    send_headers(s,
+00234                    http_header_200));
+00235     ptr = strchr(s->filename, ISO_period);
+00236     if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) {
+00237       PT_INIT(&s->scriptpt);
+00238       PT_WAIT_THREAD(&s->outputpt, handle_script(s));
+00239     } else {
+00240       PT_WAIT_THREAD(&s->outputpt,
+00241                      send_file(s));
+00242     }
+00243   }
+00244   PSOCK_CLOSE(&s->sout);
+00245   PT_END(&s->outputpt);
+00246 }
+00247 /*---------------------------------------------------------------------------*/
+00248 static
+00249 PT_THREAD(handle_input(struct httpd_state *s))
+00250 {
+00251   PSOCK_BEGIN(&s->sin);
+00252 
+00253   PSOCK_READTO(&s->sin, ISO_space);
+00254 
+00255   
+00256   if(strncmp(s->inputbuf, http_get, 4) != 0) {
+00257     PSOCK_CLOSE_EXIT(&s->sin);
+00258   }
+00259   PSOCK_READTO(&s->sin, ISO_space);
+00260 
+00261   if(s->inputbuf[0] != ISO_slash) {
+00262     PSOCK_CLOSE_EXIT(&s->sin);
+00263   }
+00264 
+00265   if(s->inputbuf[1] == ISO_space) {
+00266     strncpy(s->filename, http_index_html, sizeof(s->filename));
+00267   } else {
+00268     s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
+00269     strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
+00270   }
+00271 
+00272   /*  httpd_log_file(uip_conn->ripaddr, s->filename);*/
+00273   
+00274   s->state = STATE_OUTPUT;
+00275 
+00276   while(1) {
+00277     PSOCK_READTO(&s->sin, ISO_nl);
+00278 
+00279     if(strncmp(s->inputbuf, http_referer, 8) == 0) {
+00280       s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
+00281       /*      httpd_log(&s->inputbuf[9]);*/
+00282     }
+00283   }
+00284   
+00285   PSOCK_END(&s->sin);
+00286 }
+00287 /*---------------------------------------------------------------------------*/
+00288 static void
+00289 handle_connection(struct httpd_state *s)
+00290 {
+00291   handle_input(s);
+00292   if(s->state == STATE_OUTPUT) {
+00293     handle_output(s);
+00294   }
+00295 }
+00296 /*---------------------------------------------------------------------------*/
+00297 void
+00298 httpd_appcall(void)
+00299 {
+00300   struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate);
+00301 
+00302   if(uip_closed() || uip_aborted() || uip_timedout()) {
+00303   } else if(uip_connected()) {
+00304     PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);
+00305     PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);
+00306     PT_INIT(&s->outputpt);
+00307     s->state = STATE_WAITING;
+00308     /*    timer_set(&s->timer, CLOCK_SECOND * 100);*/
+00309     s->timer = 0;
+00310     handle_connection(s);
+00311   } else if(s != NULL) {
+00312     if(uip_poll()) {
+00313       ++s->timer;
+00314       if(s->timer >= 20) {
+00315         uip_abort();
+00316       }
+00317     } else {
+00318       s->timer = 0;
+00319     }
+00320     handle_connection(s);
+00321   } else {
+00322     uip_abort();
+00323   }
+00324 }
+00325 /*---------------------------------------------------------------------------*/
+00326 /**
+00327  * \brief      Initialize the web server
+00328  *
+00329  *             This function initializes the web server and should be
+00330  *             called at system boot-up.
+00331  */
+00332 void
+00333 httpd_init(void)
+00334 {
+00335   uip_listen(HTONS(80));
+00336 }
+00337 /*---------------------------------------------------------------------------*/
+00338 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00185.html b/doc/html/a00185.html new file mode 100644 index 0000000..7dea1e4 --- /dev/null +++ b/doc/html/a00185.html @@ -0,0 +1,87 @@ + + +uIP 1.0: apps/webserver/httpd.h Source File + + + + + + +

apps/webserver/httpd.h

00001 /*
+00002  * Copyright (c) 2001-2005, Adam Dunkels.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. The name of the author may not be used to endorse or promote
+00014  *    products derived from this software without specific prior
+00015  *    written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00018  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00019  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00021  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00023  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00026  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00027  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack.
+00030  *
+00031  * $Id: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $
+00032  *
+00033  */
+00034 
+00035 #ifndef __HTTPD_H__
+00036 #define __HTTPD_H__
+00037 
+00038 #include "psock.h"
+00039 #include "httpd-fs.h"
+00040 
+00041 struct httpd_state {
+00042   unsigned char timer;
+00043   struct psock sin, sout;
+00044   struct pt outputpt, scriptpt;
+00045   char inputbuf[50];
+00046   char filename[20];
+00047   char state;
+00048   struct httpd_fs_file file;
+00049   int len;
+00050   char *scriptptr;
+00051   int scriptlen;
+00052   
+00053   unsigned short count;
+00054 };
+00055 
+00056 void httpd_init(void);
+00057 void httpd_appcall(void);
+00058 
+00059 void httpd_log(char *msg);
+00060 void httpd_log_file(u16_t *requester, char *file);
+00061 
+00062 #endif /* __HTTPD_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00186.html b/doc/html/a00186.html new file mode 100644 index 0000000..b563040 --- /dev/null +++ b/doc/html/a00186.html @@ -0,0 +1,129 @@ + + +uIP 1.0: lib/memb.c Source File + + + + + + +

lib/memb.c

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: memb.c,v 1.1 2006/06/12 08:21:43 adam Exp $
+00034  */
+00035 
+00036 /**
+00037  * \addtogroup memb
+00038  * @{
+00039  */
+00040 
+00041  /**
+00042  * \file
+00043  * Memory block allocation routines.
+00044  * \author Adam Dunkels <adam@sics.se>
+00045  */
+00046 #include <string.h>
+00047 
+00048 #include "memb.h"
+00049 
+00050 /*---------------------------------------------------------------------------*/
+00051 void
+00052 memb_init(struct memb_blocks *m)
+00053 {
+00054   memset(m->count, 0, m->num);
+00055   memset(m->mem, 0, m->size * m->num);
+00056 }
+00057 /*---------------------------------------------------------------------------*/
+00058 void *
+00059 memb_alloc(struct memb_blocks *m)
+00060 {
+00061   int i;
+00062 
+00063   for(i = 0; i < m->num; ++i) {
+00064     if(m->count[i] == 0) {
+00065       /* If this block was unused, we increase the reference count to
+00066          indicate that it now is used and return a pointer to the
+00067          memory block. */
+00068       ++(m->count[i]);
+00069       return (void *)((char *)m->mem + (i * m->size));
+00070     }
+00071   }
+00072 
+00073   /* No free block was found, so we return NULL to indicate failure to
+00074      allocate block. */
+00075   return NULL;
+00076 }
+00077 /*---------------------------------------------------------------------------*/
+00078 char
+00079 memb_free(struct memb_blocks *m, void *ptr)
+00080 {
+00081   int i;
+00082   char *ptr2;
+00083 
+00084   /* Walk through the list of blocks and try to find the block to
+00085      which the pointer "ptr" points to. */
+00086   ptr2 = (char *)m->mem;
+00087   for(i = 0; i < m->num; ++i) {
+00088     
+00089     if(ptr2 == (char *)ptr) {
+00090       /* We've found to block to which "ptr" points so we decrease the
+00091          reference count and return the new value of it. */
+00092       if(m->count[i] > 0) {
+00093         /* Make sure that we don't deallocate free memory. */
+00094         --(m->count[i]);
+00095       }
+00096       return m->count[i];
+00097     }
+00098     ptr2 += m->size;
+00099   }
+00100   return -1;
+00101 }
+00102 /*---------------------------------------------------------------------------*/
+00103 
+00104 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00187.html b/doc/html/a00187.html new file mode 100644 index 0000000..cd6de30 --- /dev/null +++ b/doc/html/a00187.html @@ -0,0 +1,167 @@ + + +uIP 1.0: lib/memb.h Source File + + + + + + +

lib/memb.h

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: memb.h,v 1.1 2006/06/12 08:21:43 adam Exp $
+00034  */
+00035 
+00036 /**
+00037  * \defgroup memb Memory block management functions
+00038  *
+00039  * The memory block allocation routines provide a simple yet powerful
+00040  * set of functions for managing a set of memory blocks of fixed
+00041  * size. A set of memory blocks is statically declared with the
+00042  * MEMB() macro. Memory blocks are allocated from the declared
+00043  * memory by the memb_alloc() function, and are deallocated with the
+00044  * memb_free() function.
+00045  *
+00046  * \note Because of namespace clashes only one MEMB() can be
+00047  * declared per C module, and the name scope of a MEMB() memory
+00048  * block is local to each C module.
+00049  *
+00050  * The following example shows how to declare and use a memory block
+00051  * called "cmem" which has 8 chunks of memory with each memory chunk
+00052  * being 20 bytes large.
+00053  *
+00054  * @{
+00055  */
+00056 
+00057 
+00058 /**
+00059  * \file
+00060  *         Memory block allocation routines.
+00061  * \author
+00062  *         Adam Dunkels <adam@sics.se>
+00063  *
+00064  */
+00065 
+00066 #ifndef __MEMB_H__
+00067 #define __MEMB_H__
+00068 
+00069 /*
+00070  * Here we define a C preprocessing macro for concatenating to
+00071  * strings. We need use two macros in order to allow concatenation of
+00072  * two #defined macros.
+00073  */
+00074 #define MEMB_CONCAT2(s1, s2) s1##s2
+00075 #define MEMB_CONCAT(s1, s2) MEMB_CONCAT2(s1, s2)
+00076 
+00077 /**
+00078  * Declare a memory block.
+00079  *
+00080  * This macro is used to staticall declare a block of memory that can
+00081  * be used by the block allocation functions. The macro statically
+00082  * declares a C array with a size that matches the specified number of
+00083  * blocks and their individual sizes.
+00084  *
+00085  * Example:
+00086  \code
+00087 MEMB(connections, sizeof(struct connection), 16);
+00088  \endcode
+00089  *
+00090  * \param name The name of the memory block (later used with
+00091  * memb_init(), memb_alloc() and memb_free()).
+00092  *
+00093  * \param size The size of each memory chunk, in bytes.
+00094  *
+00095  * \param num The total number of memory chunks in the block.
+00096  *
+00097  */
+00098 #define MEMB(name, structure, num) \
+00099         static char MEMB_CONCAT(name,_memb_count)[num]; \
+00100         static structure MEMB_CONCAT(name,_memb_mem)[num]; \
+00101         static struct memb_blocks name = {sizeof(structure), num, \
+00102                                           MEMB_CONCAT(name,_memb_count), \
+00103                                           (void *)MEMB_CONCAT(name,_memb_mem)}
+00104 
+00105 struct memb_blocks {
+00106   unsigned short size;
+00107   unsigned short num;
+00108   char *count;
+00109   void *mem;
+00110 };
+00111 
+00112 /**
+00113  * Initialize a memory block that was declared with MEMB().
+00114  *
+00115  * \param m A memory block previosly declared with MEMB().
+00116  */
+00117 void  memb_init(struct memb_blocks *m);
+00118 
+00119 /**
+00120  * Allocate a memory block from a block of memory declared with MEMB().
+00121  *
+00122  * \param m A memory block previosly declared with MEMB().
+00123  */
+00124 void *memb_alloc(struct memb_blocks *m);
+00125 
+00126 /**
+00127  * Deallocate a memory block from a memory block previously declared
+00128  * with MEMB().
+00129  *
+00130  * \param m m A memory block previosly declared with MEMB().
+00131  *
+00132  * \param ptr A pointer to the memory block that is to be deallocated.
+00133  *
+00134  * \return The new reference count for the memory block (should be 0
+00135  * if successfully deallocated) or -1 if the pointer "ptr" did not
+00136  * point to a legal memory block.
+00137  */
+00138 char  memb_free(struct memb_blocks *m, void *ptr);
+00139 
+00140 /** @} */
+00141 
+00142 #endif /* __MEMB_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00188.html b/doc/html/a00188.html new file mode 100644 index 0000000..383bcb3 --- /dev/null +++ b/doc/html/a00188.html @@ -0,0 +1,113 @@ + + +uIP 1.0: uip/clock.h Source File + + + + + + +

uip/clock.h

00001 /**
+00002  * \defgroup clock Clock interface
+00003  *
+00004  * The clock interface is the interface between the \ref timer "timer library"
+00005  * and the platform specific clock functionality. The clock
+00006  * interface must be implemented for each platform that uses the \ref
+00007  * timer "timer library".
+00008  *
+00009  * The clock interface does only one this: it measures time. The clock
+00010  * interface provides a macro, CLOCK_SECOND, which corresponds to one
+00011  * second of system time.
+00012  *
+00013  * \sa \ref timer "Timer library"
+00014  *
+00015  * @{
+00016  */
+00017 
+00018 /*
+00019  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00020  * All rights reserved.
+00021  *
+00022  * Redistribution and use in source and binary forms, with or without
+00023  * modification, are permitted provided that the following conditions
+00024  * are met:
+00025  * 1. Redistributions of source code must retain the above copyright
+00026  *    notice, this list of conditions and the following disclaimer.
+00027  * 2. Redistributions in binary form must reproduce the above copyright
+00028  *    notice, this list of conditions and the following disclaimer in the
+00029  *    documentation and/or other materials provided with the distribution.
+00030  * 3. Neither the name of the Institute nor the names of its contributors
+00031  *    may be used to endorse or promote products derived from this software
+00032  *    without specific prior written permission.
+00033  *
+00034  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00035  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00036  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00037  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00038  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00039  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00040  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00041  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00042  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00043  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00044  * SUCH DAMAGE.
+00045  *
+00046  * This file is part of the uIP TCP/IP stack
+00047  *
+00048  * Author: Adam Dunkels <adam@sics.se>
+00049  *
+00050  * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $
+00051  */
+00052 #ifndef __CLOCK_H__
+00053 #define __CLOCK_H__
+00054 
+00055 #include "clock-arch.h"
+00056 
+00057 /**
+00058  * Initialize the clock library.
+00059  *
+00060  * This function initializes the clock library and should be called
+00061  * from the main() function of the system.
+00062  *
+00063  */
+00064 void clock_init(void);
+00065 
+00066 /**
+00067  * Get the current clock time.
+00068  *
+00069  * This function returns the current system clock time.
+00070  *
+00071  * \return The current clock time, measured in system ticks.
+00072  */
+00073 clock_time_t clock_time(void);
+00074 
+00075 /**
+00076  * A second, measured in system clock time.
+00077  *
+00078  * \hideinitializer
+00079  */
+00080 #ifdef CLOCK_CONF_SECOND
+00081 #define CLOCK_SECOND CLOCK_CONF_SECOND
+00082 #else
+00083 #define CLOCK_SECOND (clock_time_t)32
+00084 #endif
+00085 
+00086 #endif /* __CLOCK_H__ */
+00087 
+00088 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00189.html b/doc/html/a00189.html new file mode 100644 index 0000000..16727d2 --- /dev/null +++ b/doc/html/a00189.html @@ -0,0 +1,108 @@ + + +uIP 1.0: uip/lc-addrlabels.h Source File + + + + + + +

uip/lc-addrlabels.h

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $
+00034  */
+00035 
+00036 /**
+00037  * \addtogroup lc
+00038  * @{
+00039  */
+00040 
+00041 /**
+00042  * \file
+00043  * Implementation of local continuations based on the "Labels as
+00044  * values" feature of gcc
+00045  * \author
+00046  * Adam Dunkels <adam@sics.se>
+00047  *
+00048  * This implementation of local continuations is based on a special
+00049  * feature of the GCC C compiler called "labels as values". This
+00050  * feature allows assigning pointers with the address of the code
+00051  * corresponding to a particular C label.
+00052  *
+00053  * For more information, see the GCC documentation:
+00054  * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+00055  *
+00056  * Thanks to dividuum for finding the nice local scope label
+00057  * implementation.
+00058  */
+00059 
+00060 #ifndef __LC_ADDRLABELS_H__
+00061 #define __LC_ADDRLABELS_H__
+00062 
+00063 /** \hideinitializer */
+00064 typedef void * lc_t;
+00065 
+00066 #define LC_INIT(s) s = NULL
+00067 
+00068 
+00069 #define LC_RESUME(s)                            \
+00070   do {                                          \
+00071     if(s != NULL) {                             \
+00072       goto *s;                                  \
+00073     }                                           \
+00074   } while(0)
+00075 
+00076 #define LC_SET(s)                               \
+00077   do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0)
+00078 
+00079 #define LC_END(s)
+00080 
+00081 #endif /* __LC_ADDRLABELS_H__ */
+00082 
+00083 /**  @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00190.html b/doc/html/a00190.html new file mode 100644 index 0000000..5ce94df --- /dev/null +++ b/doc/html/a00190.html @@ -0,0 +1,101 @@ + + +uIP 1.0: uip/lc-switch.h Source File + + + + + + +

uip/lc-switch.h

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+00034  */
+00035 
+00036 /**
+00037  * \addtogroup lc
+00038  * @{
+00039  */
+00040 
+00041 /**
+00042  * \file
+00043  * Implementation of local continuations based on switch() statment
+00044  * \author Adam Dunkels <adam@sics.se>
+00045  *
+00046  * This implementation of local continuations uses the C switch()
+00047  * statement to resume execution of a function somewhere inside the
+00048  * function's body. The implementation is based on the fact that
+00049  * switch() statements are able to jump directly into the bodies of
+00050  * control structures such as if() or while() statmenets.
+00051  *
+00052  * This implementation borrows heavily from Simon Tatham's coroutines
+00053  * implementation in C:
+00054  * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+00055  */
+00056 
+00057 #ifndef __LC_SWITCH_H__
+00058 #define __LC_SWTICH_H__
+00059 
+00060 /* WARNING! lc implementation using switch() does not work if an
+00061    LC_SET() is done within another switch() statement! */
+00062 
+00063 /** \hideinitializer */
+00064 typedef unsigned short lc_t;
+00065 
+00066 #define LC_INIT(s) s = 0;
+00067 
+00068 #define LC_RESUME(s) switch(s) { case 0:
+00069 
+00070 #define LC_SET(s) s = __LINE__; case __LINE__:
+00071 
+00072 #define LC_END(s) }
+00073 
+00074 #endif /* __LC_SWITCH_H__ */
+00075 
+00076 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00191.html b/doc/html/a00191.html new file mode 100644 index 0000000..9b0f676 --- /dev/null +++ b/doc/html/a00191.html @@ -0,0 +1,156 @@ + + +uIP 1.0: uip/lc.h Source File + + + + + + +

uip/lc.h

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+00034  */
+00035 
+00036 /**
+00037  * \addtogroup pt
+00038  * @{
+00039  */
+00040 
+00041 /**
+00042  * \defgroup lc Local continuations
+00043  * @{
+00044  *
+00045  * Local continuations form the basis for implementing protothreads. A
+00046  * local continuation can be <i>set</i> in a specific function to
+00047  * capture the state of the function. After a local continuation has
+00048  * been set can be <i>resumed</i> in order to restore the state of the
+00049  * function at the point where the local continuation was set.
+00050  *
+00051  *
+00052  */
+00053 
+00054 /**
+00055  * \file lc.h
+00056  * Local continuations
+00057  * \author
+00058  * Adam Dunkels <adam@sics.se>
+00059  *
+00060  */
+00061 
+00062 #ifdef DOXYGEN
+00063 /**
+00064  * Initialize a local continuation.
+00065  *
+00066  * This operation initializes the local continuation, thereby
+00067  * unsetting any previously set continuation state.
+00068  *
+00069  * \hideinitializer
+00070  */
+00071 #define LC_INIT(lc)
+00072 
+00073 /**
+00074  * Set a local continuation.
+00075  *
+00076  * The set operation saves the state of the function at the point
+00077  * where the operation is executed. As far as the set operation is
+00078  * concerned, the state of the function does <b>not</b> include the
+00079  * call-stack or local (automatic) variables, but only the program
+00080  * counter and such CPU registers that needs to be saved.
+00081  *
+00082  * \hideinitializer
+00083  */
+00084 #define LC_SET(lc)
+00085 
+00086 /**
+00087  * Resume a local continuation.
+00088  *
+00089  * The resume operation resumes a previously set local continuation, thus
+00090  * restoring the state in which the function was when the local
+00091  * continuation was set. If the local continuation has not been
+00092  * previously set, the resume operation does nothing.
+00093  *
+00094  * \hideinitializer
+00095  */
+00096 #define LC_RESUME(lc)
+00097 
+00098 /**
+00099  * Mark the end of local continuation usage.
+00100  *
+00101  * The end operation signifies that local continuations should not be
+00102  * used any more in the function. This operation is not needed for
+00103  * most implementations of local continuation, but is required by a
+00104  * few implementations.
+00105  *
+00106  * \hideinitializer
+00107  */
+00108 #define LC_END(lc)
+00109 
+00110 /**
+00111  * \var typedef lc_t;
+00112  *
+00113  * The local continuation type.
+00114  *
+00115  * \hideinitializer
+00116  */
+00117 #endif /* DOXYGEN */
+00118 
+00119 #ifndef __LC_H__
+00120 #define __LC_H__
+00121 
+00122 #ifdef LC_CONF_INCLUDE
+00123 #include LC_CONF_INCLUDE
+00124 #else
+00125 #include "lc-switch.h"
+00126 #endif /* LC_CONF_INCLUDE */
+00127 
+00128 #endif /* __LC_H__ */
+00129 
+00130 /** @} */
+00131 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00192.html b/doc/html/a00192.html new file mode 100644 index 0000000..13543d5 --- /dev/null +++ b/doc/html/a00192.html @@ -0,0 +1,363 @@ + + +uIP 1.0: uip/psock.c Source File + + + + + + +

uip/psock.c

00001 /*
+00002  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+00034  */
+00035 
+00036 #include <stdio.h>
+00037 #include <string.h>
+00038 
+00039 #include "uipopt.h"
+00040 #include "psock.h"
+00041 #include "uip.h"
+00042 
+00043 #define STATE_NONE 0
+00044 #define STATE_ACKED 1
+00045 #define STATE_READ 2
+00046 #define STATE_BLOCKED_NEWDATA 3
+00047 #define STATE_BLOCKED_CLOSE 4
+00048 #define STATE_BLOCKED_SEND 5
+00049 #define STATE_DATA_SENT 6
+00050 
+00051 /*
+00052  * Return value of the buffering functions that indicates that a
+00053  * buffer was not filled by incoming data.
+00054  *
+00055  */
+00056 #define BUF_NOT_FULL 0
+00057 #define BUF_NOT_FOUND 0
+00058 
+00059 /*
+00060  * Return value of the buffering functions that indicates that a
+00061  * buffer was completely filled by incoming data.
+00062  *
+00063  */
+00064 #define BUF_FULL 1
+00065 
+00066 /*
+00067  * Return value of the buffering functions that indicates that an
+00068  * end-marker byte was found.
+00069  *
+00070  */
+00071 #define BUF_FOUND 2
+00072 
+00073 /*---------------------------------------------------------------------------*/
+00074 static void
+00075 buf_setup(struct psock_buf *buf,
+00076           u8_t *bufptr, u16_t bufsize)
+00077 {
+00078   buf->ptr = bufptr;
+00079   buf->left = bufsize;
+00080 }
+00081 /*---------------------------------------------------------------------------*/
+00082 static u8_t
+00083 buf_bufdata(struct psock_buf *buf, u16_t len,
+00084             u8_t **dataptr, u16_t *datalen)
+00085 {
+00086   if(*datalen < buf->left) {
+00087     memcpy(buf->ptr, *dataptr, *datalen);
+00088     buf->ptr += *datalen;
+00089     buf->left -= *datalen;
+00090     *dataptr += *datalen;
+00091     *datalen = 0;
+00092     return BUF_NOT_FULL;
+00093   } else if(*datalen == buf->left) {
+00094     memcpy(buf->ptr, *dataptr, *datalen);
+00095     buf->ptr += *datalen;
+00096     buf->left = 0;
+00097     *dataptr += *datalen;
+00098     *datalen = 0;
+00099     return BUF_FULL;
+00100   } else {
+00101     memcpy(buf->ptr, *dataptr, buf->left);
+00102     buf->ptr += buf->left;
+00103     *datalen -= buf->left;
+00104     *dataptr += buf->left;
+00105     buf->left = 0;
+00106     return BUF_FULL;
+00107   }
+00108 }
+00109 /*---------------------------------------------------------------------------*/
+00110 static u8_t
+00111 buf_bufto(register struct psock_buf *buf, u8_t endmarker,
+00112           register u8_t **dataptr, register u16_t *datalen)
+00113 {
+00114   u8_t c;
+00115   while(buf->left > 0 && *datalen > 0) {
+00116     c = *buf->ptr = **dataptr;
+00117     ++*dataptr;
+00118     ++buf->ptr;
+00119     --*datalen;
+00120     --buf->left;
+00121     
+00122     if(c == endmarker) {
+00123       return BUF_FOUND;
+00124     }
+00125   }
+00126 
+00127   if(*datalen == 0) {
+00128     return BUF_NOT_FOUND;
+00129   }
+00130 
+00131   while(*datalen > 0) {
+00132     c = **dataptr;
+00133     --*datalen;
+00134     ++*dataptr;
+00135     
+00136     if(c == endmarker) {
+00137       return BUF_FOUND | BUF_FULL;
+00138     }
+00139   }
+00140   
+00141   return BUF_FULL;
+00142 }
+00143 /*---------------------------------------------------------------------------*/
+00144 static char
+00145 send_data(register struct psock *s)
+00146 {
+00147   if(s->state != STATE_DATA_SENT || uip_rexmit()) {
+00148     if(s->sendlen > uip_mss()) {
+00149       uip_send(s->sendptr, uip_mss());
+00150     } else {
+00151       uip_send(s->sendptr, s->sendlen);
+00152     }
+00153     s->state = STATE_DATA_SENT;
+00154     return 1;
+00155   }
+00156   return 0;
+00157 }
+00158 /*---------------------------------------------------------------------------*/
+00159 static char
+00160 data_acked(register struct psock *s)
+00161 {
+00162   if(s->state == STATE_DATA_SENT && uip_acked()) {
+00163     if(s->sendlen > uip_mss()) {
+00164       s->sendlen -= uip_mss();
+00165       s->sendptr += uip_mss();
+00166     } else {
+00167       s->sendptr += s->sendlen;
+00168       s->sendlen = 0;
+00169     }
+00170     s->state = STATE_ACKED;
+00171     return 1;
+00172   }
+00173   return 0;
+00174 }
+00175 /*---------------------------------------------------------------------------*/
+00176 PT_THREAD(psock_send(register struct psock *s, const char *buf,
+00177                      unsigned int len))
+00178 {
+00179   PT_BEGIN(&s->psockpt);
+00180 
+00181   /* If there is no data to send, we exit immediately. */
+00182   if(len == 0) {
+00183     PT_EXIT(&s->psockpt);
+00184   }
+00185 
+00186   /* Save the length of and a pointer to the data that is to be
+00187      sent. */
+00188   s->sendptr = buf;
+00189   s->sendlen = len;
+00190 
+00191   s->state = STATE_NONE;
+00192 
+00193   /* We loop here until all data is sent. The s->sendlen variable is
+00194      updated by the data_sent() function. */
+00195   while(s->sendlen > 0) {
+00196 
+00197     /*
+00198      * The condition for this PT_WAIT_UNTIL is a little tricky: the
+00199      * protothread will wait here until all data has been acknowledged
+00200      * (data_acked() returns true) and until all data has been sent
+00201      * (send_data() returns true). The two functions data_acked() and
+00202      * send_data() must be called in succession to ensure that all
+00203      * data is sent. Therefore the & operator is used instead of the
+00204      * && operator, which would cause only the data_acked() function
+00205      * to be called when it returns false.
+00206      */
+00207     PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+00208   }
+00209 
+00210   s->state = STATE_NONE;
+00211   
+00212   PT_END(&s->psockpt);
+00213 }
+00214 /*---------------------------------------------------------------------------*/
+00215 PT_THREAD(psock_generator_send(register struct psock *s,
+00216                                unsigned short (*generate)(void *), void *arg))
+00217 {
+00218   PT_BEGIN(&s->psockpt);
+00219 
+00220   /* Ensure that there is a generator function to call. */
+00221   if(generate == NULL) {
+00222     PT_EXIT(&s->psockpt);
+00223   }
+00224 
+00225   /* Call the generator function to generate the data in the
+00226      uip_appdata buffer. */
+00227   s->sendlen = generate(arg);
+00228   s->sendptr = uip_appdata;
+00229 
+00230   s->state = STATE_NONE;  
+00231   do {
+00232     /* Call the generator function again if we are called to perform a
+00233        retransmission. */
+00234     if(uip_rexmit()) {
+00235       generate(arg);
+00236     }
+00237     /* Wait until all data is sent and acknowledged. */
+00238     PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+00239   } while(s->sendlen > 0);
+00240   
+00241   s->state = STATE_NONE;
+00242   
+00243   PT_END(&s->psockpt);
+00244 }
+00245 /*---------------------------------------------------------------------------*/
+00246 u16_t
+00247 psock_datalen(struct psock *psock)
+00248 {
+00249   return psock->bufsize - psock->buf.left;
+00250 }
+00251 /*---------------------------------------------------------------------------*/
+00252 char
+00253 psock_newdata(struct psock *s)
+00254 {
+00255   if(s->readlen > 0) {
+00256     /* There is data in the uip_appdata buffer that has not yet been
+00257        read with the PSOCK_READ functions. */
+00258     return 1;
+00259   } else if(s->state == STATE_READ) {
+00260     /* All data in uip_appdata buffer already consumed. */
+00261     s->state = STATE_BLOCKED_NEWDATA;
+00262     return 0;
+00263   } else if(uip_newdata()) {
+00264     /* There is new data that has not been consumed. */
+00265     return 1;
+00266   } else {
+00267     /* There is no new data. */
+00268     return 0;
+00269   }
+00270 }
+00271 /*---------------------------------------------------------------------------*/
+00272 PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
+00273 {
+00274   PT_BEGIN(&psock->psockpt);
+00275 
+00276   buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
+00277   
+00278   /* XXX: Should add buf_checkmarker() before do{} loop, if
+00279      incoming data has been handled while waiting for a write. */
+00280 
+00281   do {
+00282     if(psock->readlen == 0) {
+00283       PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+00284       psock->state = STATE_READ;
+00285       psock->readptr = (u8_t *)uip_appdata;
+00286       psock->readlen = uip_datalen();
+00287     }
+00288   } while((buf_bufto(&psock->buf, c,
+00289                      &psock->readptr,
+00290                      &psock->readlen) & BUF_FOUND) == 0);
+00291   
+00292   if(psock_datalen(psock) == 0) {
+00293     psock->state = STATE_NONE;
+00294     PT_RESTART(&psock->psockpt);
+00295   }
+00296   PT_END(&psock->psockpt);
+00297 }
+00298 /*---------------------------------------------------------------------------*/
+00299 PT_THREAD(psock_readbuf(register struct psock *psock))
+00300 {
+00301   PT_BEGIN(&psock->psockpt);
+00302 
+00303   buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
+00304   
+00305   /* XXX: Should add buf_checkmarker() before do{} loop, if
+00306      incoming data has been handled while waiting for a write. */
+00307 
+00308   do {
+00309     if(psock->readlen == 0) {
+00310       PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+00311       printf("Waited for newdata\n");
+00312       psock->state = STATE_READ;
+00313       psock->readptr = (u8_t *)uip_appdata;
+00314       psock->readlen = uip_datalen();
+00315     }
+00316   } while(buf_bufdata(&psock->buf, psock->bufsize,
+00317                          &psock->readptr,
+00318                          &psock->readlen) != BUF_FULL);
+00319 
+00320   if(psock_datalen(psock) == 0) {
+00321     psock->state = STATE_NONE;
+00322     PT_RESTART(&psock->psockpt);
+00323   }
+00324   PT_END(&psock->psockpt);
+00325 }
+00326 /*---------------------------------------------------------------------------*/
+00327 void
+00328 psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
+00329 {
+00330   psock->state = STATE_NONE;
+00331   psock->readlen = 0;
+00332   psock->bufptr = buffer;
+00333   psock->bufsize = buffersize;
+00334   buf_setup(&psock->buf, buffer, buffersize);
+00335   PT_INIT(&psock->pt);
+00336   PT_INIT(&psock->psockpt);
+00337 }
+00338 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00193.html b/doc/html/a00193.html new file mode 100644 index 0000000..b0ea40f --- /dev/null +++ b/doc/html/a00193.html @@ -0,0 +1,405 @@ + + +uIP 1.0: uip/psock.h Source File + + + + + + +

uip/psock.h

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $
+00034  */
+00035 
+00036 /**
+00037  * \defgroup psock Protosockets library
+00038  * @{
+00039  *
+00040  * The protosocket library provides an interface to the uIP stack that is
+00041  * similar to the traditional BSD socket interface. Unlike programs
+00042  * written for the ordinary uIP event-driven interface, programs
+00043  * written with the protosocket library are executed in a sequential
+00044  * fashion and does not have to be implemented as explicit state
+00045  * machines.
+00046  *
+00047  * Protosockets only work with TCP connections.
+00048  *
+00049  * The protosocket library uses \ref pt protothreads to provide
+00050  * sequential control flow. This makes the protosockets lightweight in
+00051  * terms of memory, but also means that protosockets inherits the
+00052  * functional limitations of protothreads. Each protosocket lives only
+00053  * within a single function. Automatic variables (stack variables) are
+00054  * not retained across a protosocket library function call.
+00055  *
+00056  * \note Because the protosocket library uses protothreads, local
+00057  * variables will not always be saved across a call to a protosocket
+00058  * library function. It is therefore advised that local variables are
+00059  * used with extreme care.
+00060  *
+00061  * The protosocket library provides functions for sending data without
+00062  * having to deal with retransmissions and acknowledgements, as well
+00063  * as functions for reading data without having to deal with data
+00064  * being split across more than one TCP segment.
+00065  *
+00066  * Because each protosocket runs as a protothread, the protosocket has to be
+00067  * started with a call to PSOCK_BEGIN() at the start of the function
+00068  * in which the protosocket is used. Similarly, the protosocket protothread can
+00069  * be terminated by a call to PSOCK_EXIT().
+00070  *
+00071  */
+00072 
+00073 /**
+00074  * \file
+00075  * Protosocket library header file
+00076  * \author
+00077  * Adam Dunkels <adam@sics.se>
+00078  *
+00079  */
+00080 
+00081 #ifndef __PSOCK_H__
+00082 #define __PSOCK_H__
+00083 
+00084 #include "uipopt.h"
+00085 #include "pt.h"
+00086 
+00087  /*
+00088  * The structure that holds the state of a buffer.
+00089  *
+00090  * This structure holds the state of a uIP buffer. The structure has
+00091  * no user-visible elements, but is used through the functions
+00092  * provided by the library.
+00093  *
+00094  */
+00095 struct psock_buf {
+00096   u8_t *ptr;
+00097   unsigned short left;
+00098 };
+00099 
+00100 /**
+00101  * The representation of a protosocket.
+00102  *
+00103  * The protosocket structrure is an opaque structure with no user-visible
+00104  * elements.
+00105  */
+00106 struct psock {
+00107   struct pt pt, psockpt; /* Protothreads - one that's using the psock
+00108                             functions, and one that runs inside the
+00109                             psock functions. */
+00110   const u8_t *sendptr;   /* Pointer to the next data to be sent. */
+00111   u8_t *readptr;         /* Pointer to the next data to be read. */
+00112   
+00113   char *bufptr;          /* Pointer to the buffer used for buffering
+00114                             incoming data. */
+00115   
+00116   u16_t sendlen;         /* The number of bytes left to be sent. */
+00117   u16_t readlen;         /* The number of bytes left to be read. */
+00118 
+00119   struct psock_buf buf;  /* The structure holding the state of the
+00120                             input buffer. */
+00121   unsigned int bufsize;  /* The size of the input buffer. */
+00122   
+00123   unsigned char state;   /* The state of the protosocket. */
+00124 };
+00125 
+00126 void psock_init(struct psock *psock, char *buffer, unsigned int buffersize);
+00127 /**
+00128  * Initialize a protosocket.
+00129  *
+00130  * This macro initializes a protosocket and must be called before the
+00131  * protosocket is used. The initialization also specifies the input buffer
+00132  * for the protosocket.
+00133  *
+00134  * \param psock (struct psock *) A pointer to the protosocket to be
+00135  * initialized
+00136  *
+00137  * \param buffer (char *) A pointer to the input buffer for the
+00138  * protosocket.
+00139  *
+00140  * \param buffersize (unsigned int) The size of the input buffer.
+00141  *
+00142  * \hideinitializer
+00143  */
+00144 #define PSOCK_INIT(psock, buffer, buffersize) \
+00145   psock_init(psock, buffer, buffersize)
+00146 
+00147 /**
+00148  * Start the protosocket protothread in a function.
+00149  *
+00150  * This macro starts the protothread associated with the protosocket and
+00151  * must come before other protosocket calls in the function it is used.
+00152  *
+00153  * \param psock (struct psock *) A pointer to the protosocket to be
+00154  * started.
+00155  *
+00156  * \hideinitializer
+00157  */
+00158 #define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
+00159 
+00160 PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len));
+00161 /**
+00162  * Send data.
+00163  *
+00164  * This macro sends data over a protosocket. The protosocket protothread blocks
+00165  * until all data has been sent and is known to have been received by
+00166  * the remote end of the TCP connection.
+00167  *
+00168  * \param psock (struct psock *) A pointer to the protosocket over which
+00169  * data is to be sent.
+00170  *
+00171  * \param data (char *) A pointer to the data that is to be sent.
+00172  *
+00173  * \param datalen (unsigned int) The length of the data that is to be
+00174  * sent.
+00175  *
+00176  * \hideinitializer
+00177  */
+00178 #define PSOCK_SEND(psock, data, datalen)                \
+00179     PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))
+00180 
+00181 /**
+00182  * \brief      Send a null-terminated string.
+00183  * \param psock Pointer to the protosocket.
+00184  * \param str  The string to be sent.
+00185  *
+00186  *             This function sends a null-terminated string over the
+00187  *             protosocket.
+00188  *
+00189  * \hideinitializer
+00190  */
+00191 #define PSOCK_SEND_STR(psock, str)                      \
+00192     PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str)))
+00193 
+00194 PT_THREAD(psock_generator_send(struct psock *psock,
+00195                                 unsigned short (*f)(void *), void *arg));
+00196 
+00197 /**
+00198  * \brief      Generate data with a function and send it
+00199  * \param psock Pointer to the protosocket.
+00200  * \param generator Pointer to the generator function
+00201  * \param arg   Argument to the generator function
+00202  *
+00203  *             This function generates data and sends it over the
+00204  *             protosocket. This can be used to dynamically generate
+00205  *             data for a transmission, instead of generating the data
+00206  *             in a buffer beforehand. This function reduces the need for
+00207  *             buffer memory. The generator function is implemented by
+00208  *             the application, and a pointer to the function is given
+00209  *             as an argument with the call to PSOCK_GENERATOR_SEND().
+00210  *
+00211  *             The generator function should place the generated data
+00212  *             directly in the uip_appdata buffer, and return the
+00213  *             length of the generated data. The generator function is
+00214  *             called by the protosocket layer when the data first is
+00215  *             sent, and once for every retransmission that is needed.
+00216  *
+00217  * \hideinitializer
+00218  */
+00219 #define PSOCK_GENERATOR_SEND(psock, generator, arg)     \
+00220     PT_WAIT_THREAD(&((psock)->pt),                                      \
+00221                    psock_generator_send(psock, generator, arg))
+00222 
+00223 
+00224 /**
+00225  * Close a protosocket.
+00226  *
+00227  * This macro closes a protosocket and can only be called from within the
+00228  * protothread in which the protosocket lives.
+00229  *
+00230  * \param psock (struct psock *) A pointer to the protosocket that is to
+00231  * be closed.
+00232  *
+00233  * \hideinitializer
+00234  */
+00235 #define PSOCK_CLOSE(psock) uip_close()
+00236 
+00237 PT_THREAD(psock_readbuf(struct psock *psock));
+00238 /**
+00239  * Read data until the buffer is full.
+00240  *
+00241  * This macro will block waiting for data and read the data into the
+00242  * input buffer specified with the call to PSOCK_INIT(). Data is read
+00243  * until the buffer is full..
+00244  *
+00245  * \param psock (struct psock *) A pointer to the protosocket from which
+00246  * data should be read.
+00247  *
+00248  * \hideinitializer
+00249  */
+00250 #define PSOCK_READBUF(psock)                            \
+00251   PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
+00252 
+00253 PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
+00254 /**
+00255  * Read data up to a specified character.
+00256  *
+00257  * This macro will block waiting for data and read the data into the
+00258  * input buffer specified with the call to PSOCK_INIT(). Data is only
+00259  * read until the specifieed character appears in the data stream.
+00260  *
+00261  * \param psock (struct psock *) A pointer to the protosocket from which
+00262  * data should be read.
+00263  *
+00264  * \param c (char) The character at which to stop reading.
+00265  *
+00266  * \hideinitializer
+00267  */
+00268 #define PSOCK_READTO(psock, c)                          \
+00269   PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))
+00270 
+00271 /**
+00272  * The length of the data that was previously read.
+00273  *
+00274  * This macro returns the length of the data that was previously read
+00275  * using PSOCK_READTO() or PSOCK_READ().
+00276  *
+00277  * \param psock (struct psock *) A pointer to the protosocket holding the data.
+00278  *
+00279  * \hideinitializer
+00280  */
+00281 #define PSOCK_DATALEN(psock) psock_datalen(psock)
+00282 
+00283 u16_t psock_datalen(struct psock *psock);
+00284 
+00285 /**
+00286  * Exit the protosocket's protothread.
+00287  *
+00288  * This macro terminates the protothread of the protosocket and should
+00289  * almost always be used in conjunction with PSOCK_CLOSE().
+00290  *
+00291  * \sa PSOCK_CLOSE_EXIT()
+00292  *
+00293  * \param psock (struct psock *) A pointer to the protosocket.
+00294  *
+00295  * \hideinitializer
+00296  */
+00297 #define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))
+00298 
+00299 /**
+00300  * Close a protosocket and exit the protosocket's protothread.
+00301  *
+00302  * This macro closes a protosocket and exits the protosocket's protothread.
+00303  *
+00304  * \param psock (struct psock *) A pointer to the protosocket.
+00305  *
+00306  * \hideinitializer
+00307  */
+00308 #define PSOCK_CLOSE_EXIT(psock)         \
+00309   do {                                          \
+00310     PSOCK_CLOSE(psock);                 \
+00311     PSOCK_EXIT(psock);                  \
+00312   } while(0)
+00313 
+00314 /**
+00315  * Declare the end of a protosocket's protothread.
+00316  *
+00317  * This macro is used for declaring that the protosocket's protothread
+00318  * ends. It must always be used together with a matching PSOCK_BEGIN()
+00319  * macro.
+00320  *
+00321  * \param psock (struct psock *) A pointer to the protosocket.
+00322  *
+00323  * \hideinitializer
+00324  */
+00325 #define PSOCK_END(psock) PT_END(&((psock)->pt))
+00326 
+00327 char psock_newdata(struct psock *s);
+00328 
+00329 /**
+00330  * Check if new data has arrived on a protosocket.
+00331  *
+00332  * This macro is used in conjunction with the PSOCK_WAIT_UNTIL()
+00333  * macro to check if data has arrived on a protosocket.
+00334  *
+00335  * \param psock (struct psock *) A pointer to the protosocket.
+00336  *
+00337  * \hideinitializer
+00338  */
+00339 #define PSOCK_NEWDATA(psock) psock_newdata(psock)
+00340 
+00341 /**
+00342  * Wait until a condition is true.
+00343  *
+00344  * This macro blocks the protothread until the specified condition is
+00345  * true. The macro PSOCK_NEWDATA() can be used to check if new data
+00346  * arrives when the protosocket is waiting.
+00347  *
+00348  * Typically, this macro is used as follows:
+00349  *
+00350  \code
+00351  PT_THREAD(thread(struct psock *s, struct timer *t))
+00352  {
+00353    PSOCK_BEGIN(s);
+00354 
+00355    PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));
+00356    
+00357    if(PSOCK_NEWDATA(s)) {
+00358      PSOCK_READTO(s, '\n');
+00359    } else {
+00360      handle_timed_out(s);
+00361    }
+00362    
+00363    PSOCK_END(s);
+00364  }
+00365  \endcode
+00366  *
+00367  * \param psock (struct psock *) A pointer to the protosocket.
+00368  * \param condition The condition to wait for.
+00369  *
+00370  * \hideinitializer
+00371  */
+00372 #define PSOCK_WAIT_UNTIL(psock, condition)    \
+00373   PT_WAIT_UNTIL(&((psock)->pt), (condition));
+00374 
+00375 #define PSOCK_WAIT_THREAD(psock, condition)   \
+00376   PT_WAIT_THREAD(&((psock)->pt), (condition))
+00377 
+00378 #endif /* __PSOCK_H__ */
+00379 
+00380 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00194.html b/doc/html/a00194.html new file mode 100644 index 0000000..5e303b8 --- /dev/null +++ b/doc/html/a00194.html @@ -0,0 +1,348 @@ + + +uIP 1.0: uip/pt.h Source File + + + + + + +

uip/pt.h

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+00034  */
+00035 
+00036 /**
+00037  * \addtogroup pt
+00038  * @{
+00039  */
+00040 
+00041 /**
+00042  * \file
+00043  * Protothreads implementation.
+00044  * \author
+00045  * Adam Dunkels <adam@sics.se>
+00046  *
+00047  */
+00048 
+00049 #ifndef __PT_H__
+00050 #define __PT_H__
+00051 
+00052 #include "lc.h"
+00053 
+00054 struct pt {
+00055   lc_t lc;
+00056 };
+00057 
+00058 #define PT_WAITING 0
+00059 #define PT_EXITED  1
+00060 #define PT_ENDED   2
+00061 #define PT_YIELDED 3
+00062 
+00063 /**
+00064  * \name Initialization
+00065  * @{
+00066  */
+00067 
+00068 /**
+00069  * Initialize a protothread.
+00070  *
+00071  * Initializes a protothread. Initialization must be done prior to
+00072  * starting to execute the protothread.
+00073  *
+00074  * \param pt A pointer to the protothread control structure.
+00075  *
+00076  * \sa PT_SPAWN()
+00077  *
+00078  * \hideinitializer
+00079  */
+00080 #define PT_INIT(pt)   LC_INIT((pt)->lc)
+00081 
+00082 /** @} */
+00083 
+00084 /**
+00085  * \name Declaration and definition
+00086  * @{
+00087  */
+00088 
+00089 /**
+00090  * Declaration of a protothread.
+00091  *
+00092  * This macro is used to declare a protothread. All protothreads must
+00093  * be declared with this macro.
+00094  *
+00095  * \param name_args The name and arguments of the C function
+00096  * implementing the protothread.
+00097  *
+00098  * \hideinitializer
+00099  */
+00100 #define PT_THREAD(name_args) char name_args
+00101 
+00102 /**
+00103  * Declare the start of a protothread inside the C function
+00104  * implementing the protothread.
+00105  *
+00106  * This macro is used to declare the starting point of a
+00107  * protothread. It should be placed at the start of the function in
+00108  * which the protothread runs. All C statements above the PT_BEGIN()
+00109  * invokation will be executed each time the protothread is scheduled.
+00110  *
+00111  * \param pt A pointer to the protothread control structure.
+00112  *
+00113  * \hideinitializer
+00114  */
+00115 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+00116 
+00117 /**
+00118  * Declare the end of a protothread.
+00119  *
+00120  * This macro is used for declaring that a protothread ends. It must
+00121  * always be used together with a matching PT_BEGIN() macro.
+00122  *
+00123  * \param pt A pointer to the protothread control structure.
+00124  *
+00125  * \hideinitializer
+00126  */
+00127 #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
+00128                    PT_INIT(pt); return PT_ENDED; }
+00129 
+00130 /** @} */
+00131 
+00132 /**
+00133  * \name Blocked wait
+00134  * @{
+00135  */
+00136 
+00137 /**
+00138  * Block and wait until condition is true.
+00139  *
+00140  * This macro blocks the protothread until the specified condition is
+00141  * true.
+00142  *
+00143  * \param pt A pointer to the protothread control structure.
+00144  * \param condition The condition.
+00145  *
+00146  * \hideinitializer
+00147  */
+00148 #define PT_WAIT_UNTIL(pt, condition)            \
+00149   do {                                          \
+00150     LC_SET((pt)->lc);                           \
+00151     if(!(condition)) {                          \
+00152       return PT_WAITING;                        \
+00153     }                                           \
+00154   } while(0)
+00155 
+00156 /**
+00157  * Block and wait while condition is true.
+00158  *
+00159  * This function blocks and waits while condition is true. See
+00160  * PT_WAIT_UNTIL().
+00161  *
+00162  * \param pt A pointer to the protothread control structure.
+00163  * \param cond The condition.
+00164  *
+00165  * \hideinitializer
+00166  */
+00167 #define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))
+00168 
+00169 /** @} */
+00170 
+00171 /**
+00172  * \name Hierarchical protothreads
+00173  * @{
+00174  */
+00175 
+00176 /**
+00177  * Block and wait until a child protothread completes.
+00178  *
+00179  * This macro schedules a child protothread. The current protothread
+00180  * will block until the child protothread completes.
+00181  *
+00182  * \note The child protothread must be manually initialized with the
+00183  * PT_INIT() function before this function is used.
+00184  *
+00185  * \param pt A pointer to the protothread control structure.
+00186  * \param thread The child protothread with arguments
+00187  *
+00188  * \sa PT_SPAWN()
+00189  *
+00190  * \hideinitializer
+00191  */
+00192 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+00193 
+00194 /**
+00195  * Spawn a child protothread and wait until it exits.
+00196  *
+00197  * This macro spawns a child protothread and waits until it exits. The
+00198  * macro can only be used within a protothread.
+00199  *
+00200  * \param pt A pointer to the protothread control structure.
+00201  * \param child A pointer to the child protothread's control structure.
+00202  * \param thread The child protothread with arguments
+00203  *
+00204  * \hideinitializer
+00205  */
+00206 #define PT_SPAWN(pt, child, thread)             \
+00207   do {                                          \
+00208     PT_INIT((child));                           \
+00209     PT_WAIT_THREAD((pt), (thread));             \
+00210   } while(0)
+00211 
+00212 /** @} */
+00213 
+00214 /**
+00215  * \name Exiting and restarting
+00216  * @{
+00217  */
+00218 
+00219 /**
+00220  * Restart the protothread.
+00221  *
+00222  * This macro will block and cause the running protothread to restart
+00223  * its execution at the place of the PT_BEGIN() call.
+00224  *
+00225  * \param pt A pointer to the protothread control structure.
+00226  *
+00227  * \hideinitializer
+00228  */
+00229 #define PT_RESTART(pt)                          \
+00230   do {                                          \
+00231     PT_INIT(pt);                                \
+00232     return PT_WAITING;                  \
+00233   } while(0)
+00234 
+00235 /**
+00236  * Exit the protothread.
+00237  *
+00238  * This macro causes the protothread to exit. If the protothread was
+00239  * spawned by another protothread, the parent protothread will become
+00240  * unblocked and can continue to run.
+00241  *
+00242  * \param pt A pointer to the protothread control structure.
+00243  *
+00244  * \hideinitializer
+00245  */
+00246 #define PT_EXIT(pt)                             \
+00247   do {                                          \
+00248     PT_INIT(pt);                                \
+00249     return PT_EXITED;                   \
+00250   } while(0)
+00251 
+00252 /** @} */
+00253 
+00254 /**
+00255  * \name Calling a protothread
+00256  * @{
+00257  */
+00258 
+00259 /**
+00260  * Schedule a protothread.
+00261  *
+00262  * This function shedules a protothread. The return value of the
+00263  * function is non-zero if the protothread is running or zero if the
+00264  * protothread has exited.
+00265  *
+00266  * \param f The call to the C function implementing the protothread to
+00267  * be scheduled
+00268  *
+00269  * \hideinitializer
+00270  */
+00271 #define PT_SCHEDULE(f) ((f) == PT_WAITING)
+00272 
+00273 /** @} */
+00274 
+00275 /**
+00276  * \name Yielding from a protothread
+00277  * @{
+00278  */
+00279 
+00280 /**
+00281  * Yield from the current protothread.
+00282  *
+00283  * This function will yield the protothread, thereby allowing other
+00284  * processing to take place in the system.
+00285  *
+00286  * \param pt A pointer to the protothread control structure.
+00287  *
+00288  * \hideinitializer
+00289  */
+00290 #define PT_YIELD(pt)                            \
+00291   do {                                          \
+00292     PT_YIELD_FLAG = 0;                          \
+00293     LC_SET((pt)->lc);                           \
+00294     if(PT_YIELD_FLAG == 0) {                    \
+00295       return PT_YIELDED;                        \
+00296     }                                           \
+00297   } while(0)
+00298 
+00299 /**
+00300  * \brief      Yield from the protothread until a condition occurs.
+00301  * \param pt   A pointer to the protothread control structure.
+00302  * \param cond The condition.
+00303  *
+00304  *             This function will yield the protothread, until the
+00305  *             specified condition evaluates to true.
+00306  *
+00307  *
+00308  * \hideinitializer
+00309  */
+00310 #define PT_YIELD_UNTIL(pt, cond)                \
+00311   do {                                          \
+00312     PT_YIELD_FLAG = 0;                          \
+00313     LC_SET((pt)->lc);                           \
+00314     if((PT_YIELD_FLAG == 0) || !(cond)) {       \
+00315       return PT_YIELDED;                        \
+00316     }                                           \
+00317   } while(0)
+00318 
+00319 /** @} */
+00320 
+00321 #endif /* __PT_H__ */
+00322 
+00323 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00195.html b/doc/html/a00195.html new file mode 100644 index 0000000..fa2e608 --- /dev/null +++ b/doc/html/a00195.html @@ -0,0 +1,152 @@ + + +uIP 1.0: uip/timer.c Source File + + + + + + +

uip/timer.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup timer
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \file
+00008  * Timer library implementation.
+00009  * \author
+00010  * Adam Dunkels <adam@sics.se>
+00011  */
+00012 
+00013 /*
+00014  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00015  * All rights reserved.
+00016  *
+00017  * Redistribution and use in source and binary forms, with or without
+00018  * modification, are permitted provided that the following conditions
+00019  * are met:
+00020  * 1. Redistributions of source code must retain the above copyright
+00021  *    notice, this list of conditions and the following disclaimer.
+00022  * 2. Redistributions in binary form must reproduce the above copyright
+00023  *    notice, this list of conditions and the following disclaimer in the
+00024  *    documentation and/or other materials provided with the distribution.
+00025  * 3. Neither the name of the Institute nor the names of its contributors
+00026  *    may be used to endorse or promote products derived from this software
+00027  *    without specific prior written permission.
+00028  *
+00029  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00039  * SUCH DAMAGE.
+00040  *
+00041  * This file is part of the uIP TCP/IP stack
+00042  *
+00043  * Author: Adam Dunkels <adam@sics.se>
+00044  *
+00045  * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+00046  */
+00047 
+00048 #include "clock.h"
+00049 #include "timer.h"
+00050 
+00051 /*---------------------------------------------------------------------------*/
+00052 /**
+00053  * Set a timer.
+00054  *
+00055  * This function is used to set a timer for a time sometime in the
+00056  * future. The function timer_expired() will evaluate to true after
+00057  * the timer has expired.
+00058  *
+00059  * \param t A pointer to the timer
+00060  * \param interval The interval before the timer expires.
+00061  *
+00062  */
+00063 void
+00064 timer_set(struct timer *t, clock_time_t interval)
+00065 {
+00066   t->interval = interval;
+00067   t->start = clock_time();
+00068 }
+00069 /*---------------------------------------------------------------------------*/
+00070 /**
+00071  * Reset the timer with the same interval.
+00072  *
+00073  * This function resets the timer with the same interval that was
+00074  * given to the timer_set() function. The start point of the interval
+00075  * is the exact time that the timer last expired. Therefore, this
+00076  * function will cause the timer to be stable over time, unlike the
+00077  * timer_rester() function.
+00078  *
+00079  * \param t A pointer to the timer.
+00080  *
+00081  * \sa timer_restart()
+00082  */
+00083 void
+00084 timer_reset(struct timer *t)
+00085 {
+00086   t->start += t->interval;
+00087 }
+00088 /*---------------------------------------------------------------------------*/
+00089 /**
+00090  * Restart the timer from the current point in time
+00091  *
+00092  * This function restarts a timer with the same interval that was
+00093  * given to the timer_set() function. The timer will start at the
+00094  * current time.
+00095  *
+00096  * \note A periodic timer will drift if this function is used to reset
+00097  * it. For preioric timers, use the timer_reset() function instead.
+00098  *
+00099  * \param t A pointer to the timer.
+00100  *
+00101  * \sa timer_reset()
+00102  */
+00103 void
+00104 timer_restart(struct timer *t)
+00105 {
+00106   t->start = clock_time();
+00107 }
+00108 /*---------------------------------------------------------------------------*/
+00109 /**
+00110  * Check if a timer has expired.
+00111  *
+00112  * This function tests if a timer has expired and returns true or
+00113  * false depending on its status.
+00114  *
+00115  * \param t A pointer to the timer
+00116  *
+00117  * \return Non-zero if the timer has expired, zero otherwise.
+00118  *
+00119  */
+00120 int
+00121 timer_expired(struct timer *t)
+00122 {
+00123   return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
+00124 }
+00125 /*---------------------------------------------------------------------------*/
+00126 
+00127 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00196.html b/doc/html/a00196.html new file mode 100644 index 0000000..c72141b --- /dev/null +++ b/doc/html/a00196.html @@ -0,0 +1,111 @@ + + +uIP 1.0: uip/timer.h Source File + + + + + + +

uip/timer.h

Go to the documentation of this file.
00001 /**
+00002  * \defgroup timer Timer library
+00003  *
+00004  * The timer library provides functions for setting, resetting and
+00005  * restarting timers, and for checking if a timer has expired. An
+00006  * application must "manually" check if its timers have expired; this
+00007  * is not done automatically.
+00008  *
+00009  * A timer is declared as a \c struct \c timer and all access to the
+00010  * timer is made by a pointer to the declared timer.
+00011  *
+00012  * \note The timer library uses the \ref clock "Clock library" to
+00013  * measure time. Intervals should be specified in the format used by
+00014  * the clock library.
+00015  *
+00016  * @{
+00017  */
+00018 
+00019 
+00020 /**
+00021  * \file
+00022  * Timer library header file.
+00023  * \author
+00024  * Adam Dunkels <adam@sics.se>
+00025  */
+00026 
+00027 /*
+00028  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00029  * All rights reserved.
+00030  *
+00031  * Redistribution and use in source and binary forms, with or without
+00032  * modification, are permitted provided that the following conditions
+00033  * are met:
+00034  * 1. Redistributions of source code must retain the above copyright
+00035  *    notice, this list of conditions and the following disclaimer.
+00036  * 2. Redistributions in binary form must reproduce the above copyright
+00037  *    notice, this list of conditions and the following disclaimer in the
+00038  *    documentation and/or other materials provided with the distribution.
+00039  * 3. Neither the name of the Institute nor the names of its contributors
+00040  *    may be used to endorse or promote products derived from this software
+00041  *    without specific prior written permission.
+00042  *
+00043  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00044  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00045  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00046  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00047  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00048  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00049  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00050  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00051  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00052  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00053  * SUCH DAMAGE.
+00054  *
+00055  * This file is part of the uIP TCP/IP stack
+00056  *
+00057  * Author: Adam Dunkels <adam@sics.se>
+00058  *
+00059  * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
+00060  */
+00061 #ifndef __TIMER_H__
+00062 #define __TIMER_H__
+00063 
+00064 #include "clock.h"
+00065 
+00066 /**
+00067  * A timer.
+00068  *
+00069  * This structure is used for declaring a timer. The timer must be set
+00070  * with timer_set() before it can be used.
+00071  *
+00072  * \hideinitializer
+00073  */
+00074 struct timer {
+00075   clock_time_t start;
+00076   clock_time_t interval;
+00077 };
+00078 
+00079 void timer_set(struct timer *t, clock_time_t interval);
+00080 void timer_reset(struct timer *t);
+00081 void timer_restart(struct timer *t);
+00082 int timer_expired(struct timer *t);
+00083 
+00084 #endif /* __TIMER_H__ */
+00085 
+00086 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00197.html b/doc/html/a00197.html new file mode 100644 index 0000000..d8f85aa --- /dev/null +++ b/doc/html/a00197.html @@ -0,0 +1,183 @@ + + +uIP 1.0: uip/uip-neighbor.c Source File + + + + + + +

uip/uip-neighbor.c

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2006, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+00032  */
+00033 
+00034 /**
+00035  * \file
+00036  *         Database of link-local neighbors, used by IPv6 code and
+00037  *         to be used by a future ARP code rewrite.
+00038  * \author
+00039  *         Adam Dunkels <adam@sics.se>
+00040  */
+00041 
+00042 #include "uip-neighbor.h"
+00043 
+00044 #include <string.h>
+00045 
+00046 #define MAX_TIME 128
+00047 
+00048 #ifdef UIP_NEIGHBOR_CONF_ENTRIES
+00049 #define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES
+00050 #else /* UIP_NEIGHBOR_CONF_ENTRIES */
+00051 #define ENTRIES 8
+00052 #endif /* UIP_NEIGHBOR_CONF_ENTRIES */
+00053 
+00054 struct neighbor_entry {
+00055   uip_ipaddr_t ipaddr;
+00056   struct uip_neighbor_addr addr;
+00057   u8_t time;
+00058 };
+00059 static struct neighbor_entry entries[ENTRIES];
+00060 
+00061 /*---------------------------------------------------------------------------*/
+00062 void
+00063 uip_neighbor_init(void)
+00064 {
+00065   int i;
+00066 
+00067   for(i = 0; i < ENTRIES; ++i) {
+00068     entries[i].time = MAX_TIME;
+00069   }
+00070 }
+00071 /*---------------------------------------------------------------------------*/
+00072 void
+00073 uip_neighbor_periodic(void)
+00074 {
+00075   int i;
+00076 
+00077   for(i = 0; i < ENTRIES; ++i) {
+00078     if(entries[i].time < MAX_TIME) {
+00079       entries[i].time++;
+00080     }
+00081   }
+00082 }
+00083 /*---------------------------------------------------------------------------*/
+00084 void
+00085 uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr)
+00086 {
+00087   int i, oldest;
+00088   u8_t oldest_time;
+00089 
+00090   printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
+00091          addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3],
+00092          addr->addr.addr[4], addr->addr.addr[5]);
+00093   
+00094   /* Find the first unused entry or the oldest used entry. */
+00095   oldest_time = 0;
+00096   oldest = 0;
+00097   for(i = 0; i < ENTRIES; ++i) {
+00098     if(entries[i].time == MAX_TIME) {
+00099       oldest = i;
+00100       break;
+00101     }
+00102     if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) {
+00103       oldest = i;
+00104       break;
+00105     }
+00106     if(entries[i].time > oldest_time) {
+00107       oldest = i;
+00108       oldest_time = entries[i].time;
+00109     }
+00110   }
+00111 
+00112   /* Use the oldest or first free entry (either pointed to by the
+00113      "oldest" variable). */
+00114   entries[oldest].time = 0;
+00115   uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr);
+00116   memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr));
+00117 }
+00118 /*---------------------------------------------------------------------------*/
+00119 static struct neighbor_entry *
+00120 find_entry(uip_ipaddr_t ipaddr)
+00121 {
+00122   int i;
+00123   
+00124   for(i = 0; i < ENTRIES; ++i) {
+00125     if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) {
+00126       return &entries[i];
+00127     }
+00128   }
+00129   return NULL;
+00130 }
+00131 /*---------------------------------------------------------------------------*/
+00132 void
+00133 uip_neighbor_update(uip_ipaddr_t ipaddr)
+00134 {
+00135   struct neighbor_entry *e;
+00136 
+00137   e = find_entry(ipaddr);
+00138   if(e != NULL) {
+00139     e->time = 0;
+00140   }
+00141 }
+00142 /*---------------------------------------------------------------------------*/
+00143 struct uip_neighbor_addr *
+00144 uip_neighbor_lookup(uip_ipaddr_t ipaddr)
+00145 {
+00146   struct neighbor_entry *e;
+00147 
+00148   e = find_entry(ipaddr);
+00149   if(e != NULL) {
+00150     /*    printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
+00151            e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3],
+00152            e->addr.addr.addr[4], e->addr.addr.addr[5]);*/
+00153 
+00154     return &e->addr;
+00155   }
+00156   return NULL;
+00157 }
+00158 /*---------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00198.html b/doc/html/a00198.html new file mode 100644 index 0000000..ce7cb56 --- /dev/null +++ b/doc/html/a00198.html @@ -0,0 +1,86 @@ + + +uIP 1.0: uip/uip-neighbor.h Source File + + + + + + +

uip/uip-neighbor.h

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2006, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+00032  */
+00033 
+00034 /**
+00035  * \file
+00036  *         Header file for database of link-local neighbors, used by
+00037  *         IPv6 code and to be used by future ARP code.
+00038  * \author
+00039  *         Adam Dunkels <adam@sics.se>
+00040  */
+00041 
+00042 #ifndef __UIP_NEIGHBOR_H__
+00043 #define __UIP_NEIGHBOR_H__
+00044 
+00045 #include "uip.h"
+00046 
+00047 struct uip_neighbor_addr {
+00048 #if UIP_NEIGHBOR_CONF_ADDRTYPE
+00049   UIP_NEIGHBOR_CONF_ADDRTYPE addr;
+00050 #else
+00051   struct uip_eth_addr addr;
+00052 #endif
+00053 };
+00054 
+00055 void uip_neighbor_init(void);
+00056 void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr);
+00057 void uip_neighbor_update(uip_ipaddr_t ipaddr);
+00058 struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr);
+00059 void uip_neighbor_periodic(void);
+00060 
+00061 #endif /* __UIP-NEIGHBOR_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00199.html b/doc/html/a00199.html new file mode 100644 index 0000000..f33889b --- /dev/null +++ b/doc/html/a00199.html @@ -0,0 +1,161 @@ + + +uIP 1.0: uip/uip-split.c Source File + + + + + + +

uip/uip-split.c

00001 /*
+00002  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+00034  */
+00035 
+00036 #include <string.h>
+00037 
+00038 #include "uip-split.h"
+00039 #include "uip.h"
+00040 #include "uip-fw.h"
+00041 #include "uip_arch.h"
+00042 
+00043 
+00044 
+00045 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+00046 
+00047 /*-----------------------------------------------------------------------------*/
+00048 void
+00049 uip_split_output(void)
+00050 {
+00051   u16_t tcplen, len1, len2;
+00052 
+00053   /* We only try to split maximum sized TCP segments. */
+00054   if(BUF->proto == UIP_PROTO_TCP &&
+00055      uip_len == UIP_BUFSIZE - UIP_LLH_LEN) {
+00056 
+00057     tcplen = uip_len - UIP_TCPIP_HLEN;
+00058     /* Split the segment in two. If the original packet length was
+00059        odd, we make the second packet one byte larger. */
+00060     len1 = len2 = tcplen / 2;
+00061     if(len1 + len2 < tcplen) {
+00062       ++len2;
+00063     }
+00064 
+00065     /* Create the first packet. This is done by altering the length
+00066        field of the IP header and updating the checksums. */
+00067     uip_len = len1 + UIP_TCPIP_HLEN;
+00068 #if UIP_CONF_IPV6
+00069     /* For IPv6, the IP length field does not include the IPv6 IP header
+00070        length. */
+00071     BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+00072     BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+00073 #else /* UIP_CONF_IPV6 */
+00074     BUF->len[0] = uip_len >> 8;
+00075     BUF->len[1] = uip_len & 0xff;
+00076 #endif /* UIP_CONF_IPV6 */
+00077     
+00078     /* Recalculate the TCP checksum. */
+00079     BUF->tcpchksum = 0;
+00080     BUF->tcpchksum = ~(uip_tcpchksum());
+00081 
+00082 #if !UIP_CONF_IPV6
+00083     /* Recalculate the IP checksum. */
+00084     BUF->ipchksum = 0;
+00085     BUF->ipchksum = ~(uip_ipchksum());
+00086 #endif /* UIP_CONF_IPV6 */
+00087     
+00088     /* Transmit the first packet. */
+00089     /*    uip_fw_output();*/
+00090     tcpip_output();
+00091 
+00092     /* Now, create the second packet. To do this, it is not enough to
+00093        just alter the length field, but we must also update the TCP
+00094        sequence number and point the uip_appdata to a new place in
+00095        memory. This place is detemined by the length of the first
+00096        packet (len1). */
+00097     uip_len = len2 + UIP_TCPIP_HLEN;
+00098 #if UIP_CONF_IPV6
+00099     /* For IPv6, the IP length field does not include the IPv6 IP header
+00100        length. */
+00101     BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+00102     BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+00103 #else /* UIP_CONF_IPV6 */
+00104     BUF->len[0] = uip_len >> 8;
+00105     BUF->len[1] = uip_len & 0xff;
+00106 #endif /* UIP_CONF_IPV6 */
+00107     
+00108     /*    uip_appdata += len1;*/
+00109     memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);
+00110 
+00111     uip_add32(BUF->seqno, len1);
+00112     BUF->seqno[0] = uip_acc32[0];
+00113     BUF->seqno[1] = uip_acc32[1];
+00114     BUF->seqno[2] = uip_acc32[2];
+00115     BUF->seqno[3] = uip_acc32[3];
+00116     
+00117     /* Recalculate the TCP checksum. */
+00118     BUF->tcpchksum = 0;
+00119     BUF->tcpchksum = ~(uip_tcpchksum());
+00120 
+00121 #if !UIP_CONF_IPV6
+00122     /* Recalculate the IP checksum. */
+00123     BUF->ipchksum = 0;
+00124     BUF->ipchksum = ~(uip_ipchksum());
+00125 #endif /* UIP_CONF_IPV6 */
+00126 
+00127     /* Transmit the second packet. */
+00128     /*    uip_fw_output();*/
+00129     tcpip_output();
+00130   } else {
+00131     /*    uip_fw_output();*/
+00132     tcpip_output();
+00133   }
+00134      
+00135 }
+00136 /*-----------------------------------------------------------------------------*/
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00200.html b/doc/html/a00200.html new file mode 100644 index 0000000..9371423 --- /dev/null +++ b/doc/html/a00200.html @@ -0,0 +1,121 @@ + + +uIP 1.0: uip/uip-split.h Source File + + + + + + +

uip/uip-split.h

Go to the documentation of this file.
00001 /*
+00002  * Copyright (c) 2004, Swedish Institute of Computer Science.
+00003  * All rights reserved.
+00004  *
+00005  * Redistribution and use in source and binary forms, with or without
+00006  * modification, are permitted provided that the following conditions
+00007  * are met:
+00008  * 1. Redistributions of source code must retain the above copyright
+00009  *    notice, this list of conditions and the following disclaimer.
+00010  * 2. Redistributions in binary form must reproduce the above copyright
+00011  *    notice, this list of conditions and the following disclaimer in the
+00012  *    documentation and/or other materials provided with the distribution.
+00013  * 3. Neither the name of the Institute nor the names of its contributors
+00014  *    may be used to endorse or promote products derived from this software
+00015  *    without specific prior written permission.
+00016  *
+00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00027  * SUCH DAMAGE.
+00028  *
+00029  * This file is part of the uIP TCP/IP stack
+00030  *
+00031  * Author: Adam Dunkels <adam@sics.se>
+00032  *
+00033  * $Id: uip-split.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+00034  */
+00035 /**
+00036  * \addtogroup uip
+00037  * @{
+00038  */
+00039 
+00040 /**
+00041  * \defgroup uipsplit uIP TCP throughput booster hack
+00042  * @{
+00043  *
+00044  * The basic uIP TCP implementation only allows each TCP connection to
+00045  * have a single TCP segment in flight at any given time. Because of
+00046  * the delayed ACK algorithm employed by most TCP receivers, uIP's
+00047  * limit on the amount of in-flight TCP segments seriously reduces the
+00048  * maximum achievable throughput for sending data from uIP.
+00049  *
+00050  * The uip-split module is a hack which tries to remedy this
+00051  * situation. By splitting maximum sized outgoing TCP segments into
+00052  * two, the delayed ACK algorithm is not invoked at TCP
+00053  * receivers. This improves the throughput when sending data from uIP
+00054  * by orders of magnitude.
+00055  *
+00056  * The uip-split module uses the uip-fw module (uIP IP packet
+00057  * forwarding) for sending packets. Therefore, the uip-fw module must
+00058  * be set up with the appropriate network interfaces for this module
+00059  * to work.
+00060  */
+00061 
+00062 
+00063 /**
+00064  * \file
+00065  * Module for splitting outbound TCP segments in two to avoid the
+00066  * delayed ACK throughput degradation.
+00067  * \author
+00068  * Adam Dunkels <adam@sics.se>
+00069  *
+00070  */
+00071 
+00072 #ifndef __UIP_SPLIT_H__
+00073 #define __UIP_SPLIT_H__
+00074 
+00075 /**
+00076  * Handle outgoing packets.
+00077  *
+00078  * This function inspects an outgoing packet in the uip_buf buffer and
+00079  * sends it out using the uip_fw_output() function. If the packet is a
+00080  * full-sized TCP segment it will be split into two segments and
+00081  * transmitted separately. This function should be called instead of
+00082  * the actual device driver output function, or the uip_fw_output()
+00083  * function.
+00084  *
+00085  * The headers of the outgoing packet is assumed to be in the uip_buf
+00086  * buffer and the payload is assumed to be wherever uip_appdata
+00087  * points. The length of the outgoing packet is assumed to be in the
+00088  * uip_len variable.
+00089  *
+00090  */
+00091 void uip_split_output(void);
+00092 
+00093 #endif /* __UIP_SPLIT_H__ */
+00094 
+00095 /** @} */
+00096 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00201.html b/doc/html/a00201.html new file mode 100644 index 0000000..bf6878f --- /dev/null +++ b/doc/html/a00201.html @@ -0,0 +1,1922 @@ + + +uIP 1.0: uip/uip.c Source File + + + + + + +

uip/uip.c

Go to the documentation of this file.
00001 #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
+00002 
+00003 /**
+00004  * \defgroup uip The uIP TCP/IP stack
+00005  * @{
+00006  *
+00007  * uIP is an implementation of the TCP/IP protocol stack intended for
+00008  * small 8-bit and 16-bit microcontrollers.
+00009  *
+00010  * uIP provides the necessary protocols for Internet communication,
+00011  * with a very small code footprint and RAM requirements - the uIP
+00012  * code size is on the order of a few kilobytes and RAM usage is on
+00013  * the order of a few hundred bytes.
+00014  */
+00015 
+00016 /**
+00017  * \file
+00018  * The uIP TCP/IP stack code.
+00019  * \author Adam Dunkels <adam@dunkels.com>
+00020  */
+00021 
+00022 /*
+00023  * Copyright (c) 2001-2003, Adam Dunkels.
+00024  * All rights reserved.
+00025  *
+00026  * Redistribution and use in source and binary forms, with or without
+00027  * modification, are permitted provided that the following conditions
+00028  * are met:
+00029  * 1. Redistributions of source code must retain the above copyright
+00030  *    notice, this list of conditions and the following disclaimer.
+00031  * 2. Redistributions in binary form must reproduce the above copyright
+00032  *    notice, this list of conditions and the following disclaimer in the
+00033  *    documentation and/or other materials provided with the distribution.
+00034  * 3. The name of the author may not be used to endorse or promote
+00035  *    products derived from this software without specific prior
+00036  *    written permission.
+00037  *
+00038  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00039  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00040  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00041  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00042  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00043  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00044  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00045  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00046  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00047  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00048  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00049  *
+00050  * This file is part of the uIP TCP/IP stack.
+00051  *
+00052  * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $
+00053  *
+00054  */
+00055 
+00056 /*
+00057  * uIP is a small implementation of the IP, UDP and TCP protocols (as
+00058  * well as some basic ICMP stuff). The implementation couples the IP,
+00059  * UDP, TCP and the application layers very tightly. To keep the size
+00060  * of the compiled code down, this code frequently uses the goto
+00061  * statement. While it would be possible to break the uip_process()
+00062  * function into many smaller functions, this would increase the code
+00063  * size because of the overhead of parameter passing and the fact that
+00064  * the optimier would not be as efficient.
+00065  *
+00066  * The principle is that we have a small buffer, called the uip_buf,
+00067  * in which the device driver puts an incoming packet. The TCP/IP
+00068  * stack parses the headers in the packet, and calls the
+00069  * application. If the remote host has sent data to the application,
+00070  * this data is present in the uip_buf and the application read the
+00071  * data from there. It is up to the application to put this data into
+00072  * a byte stream if needed. The application will not be fed with data
+00073  * that is out of sequence.
+00074  *
+00075  * If the application whishes to send data to the peer, it should put
+00076  * its data into the uip_buf. The uip_appdata pointer points to the
+00077  * first available byte. The TCP/IP stack will calculate the
+00078  * checksums, and fill in the necessary header fields and finally send
+00079  * the packet back to the peer.
+00080 */
+00081 
+00082 #include "uip.h"
+00083 #include "uipopt.h"
+00084 #include "uip_arch.h"
+00085 
+00086 #if UIP_CONF_IPV6
+00087 #include "uip-neighbor.h"
+00088 #endif /* UIP_CONF_IPV6 */
+00089 
+00090 #include <string.h>
+00091 
+00092 /*---------------------------------------------------------------------------*/
+00093 /* Variable definitions. */
+00094 
+00095 
+00096 /* The IP address of this host. If it is defined to be fixed (by
+00097    setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
+00098    here. Otherwise, the address */
+00099 #if UIP_FIXEDADDR > 0
+00100 const uip_ipaddr_t uip_hostaddr =
+00101   {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
+00102    HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
+00103 const uip_ipaddr_t uip_draddr =
+00104   {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
+00105    HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
+00106 const uip_ipaddr_t uip_netmask =
+00107   {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
+00108    HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
+00109 #else
+00110 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
+00111 #endif /* UIP_FIXEDADDR */
+00112 
+00113 static const uip_ipaddr_t all_ones_addr =
+00114 #if UIP_CONF_IPV6
+00115   {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
+00116 #else /* UIP_CONF_IPV6 */
+00117   {0xffff,0xffff};
+00118 #endif /* UIP_CONF_IPV6 */
+00119 static const uip_ipaddr_t all_zeroes_addr =
+00120 #if UIP_CONF_IPV6
+00121   {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
+00122 #else /* UIP_CONF_IPV6 */
+00123   {0x0000,0x0000};
+00124 #endif /* UIP_CONF_IPV6 */
+00125 
+00126 
+00127 #if UIP_FIXEDETHADDR
+00128 const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
+00129                                           UIP_ETHADDR1,
+00130                                           UIP_ETHADDR2,
+00131                                           UIP_ETHADDR3,
+00132                                           UIP_ETHADDR4,
+00133                                           UIP_ETHADDR5}};
+00134 #else
+00135 struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};
+00136 #endif
+00137 
+00138 #ifndef UIP_CONF_EXTERNAL_BUFFER
+00139 u8_t uip_buf[UIP_BUFSIZE + 2];   /* The packet buffer that contains
+00140                                     incoming packets. */
+00141 #endif /* UIP_CONF_EXTERNAL_BUFFER */
+00142 
+00143 void *uip_appdata;               /* The uip_appdata pointer points to
+00144                                     application data. */
+00145 void *uip_sappdata;              /* The uip_appdata pointer points to
+00146                                     the application data which is to
+00147                                     be sent. */
+00148 #if UIP_URGDATA > 0
+00149 void *uip_urgdata;               /* The uip_urgdata pointer points to
+00150                                     urgent data (out-of-band data), if
+00151                                     present. */
+00152 u16_t uip_urglen, uip_surglen;
+00153 #endif /* UIP_URGDATA > 0 */
+00154 
+00155 u16_t uip_len, uip_slen;
+00156                              /* The uip_len is either 8 or 16 bits,
+00157                                 depending on the maximum packet
+00158                                 size. */
+00159 
+00160 u8_t uip_flags;     /* The uip_flags variable is used for
+00161                                 communication between the TCP/IP stack
+00162                                 and the application program. */
+00163 struct uip_conn *uip_conn;   /* uip_conn always points to the current
+00164                                 connection. */
+00165 
+00166 struct uip_conn uip_conns[UIP_CONNS];
+00167                              /* The uip_conns array holds all TCP
+00168                                 connections. */
+00169 u16_t uip_listenports[UIP_LISTENPORTS];
+00170                              /* The uip_listenports list all currently
+00171                                 listning ports. */
+00172 #if UIP_UDP
+00173 struct uip_udp_conn *uip_udp_conn;
+00174 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
+00175 #endif /* UIP_UDP */
+00176 
+00177 static u16_t ipid;           /* Ths ipid variable is an increasing
+00178                                 number that is used for the IP ID
+00179                                 field. */
+00180 
+00181 void uip_setipid(u16_t id) { ipid = id; }
+00182 
+00183 static u8_t iss[4];          /* The iss variable is used for the TCP
+00184                                 initial sequence number. */
+00185 
+00186 #if UIP_ACTIVE_OPEN
+00187 static u16_t lastport;       /* Keeps track of the last port used for
+00188                                 a new connection. */
+00189 #endif /* UIP_ACTIVE_OPEN */
+00190 
+00191 /* Temporary variables. */
+00192 u8_t uip_acc32[4];
+00193 static u8_t c, opt;
+00194 static u16_t tmp16;
+00195 
+00196 /* Structures and definitions. */
+00197 #define TCP_FIN 0x01
+00198 #define TCP_SYN 0x02
+00199 #define TCP_RST 0x04
+00200 #define TCP_PSH 0x08
+00201 #define TCP_ACK 0x10
+00202 #define TCP_URG 0x20
+00203 #define TCP_CTL 0x3f
+00204 
+00205 #define TCP_OPT_END     0   /* End of TCP options list */
+00206 #define TCP_OPT_NOOP    1   /* "No-operation" TCP option */
+00207 #define TCP_OPT_MSS     2   /* Maximum segment size TCP option */
+00208 
+00209 #define TCP_OPT_MSS_LEN 4   /* Length of TCP MSS option. */
+00210 
+00211 #define ICMP_ECHO_REPLY 0
+00212 #define ICMP_ECHO       8
+00213 
+00214 #define ICMP6_ECHO_REPLY             129
+00215 #define ICMP6_ECHO                   128
+00216 #define ICMP6_NEIGHBOR_SOLICITATION  135
+00217 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136
+00218 
+00219 #define ICMP6_FLAG_S (1 << 6)
+00220 
+00221 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
+00222 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
+00223 
+00224 
+00225 /* Macros. */
+00226 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+00227 #define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
+00228 #define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
+00229 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
+00230 
+00231 
+00232 #if UIP_STATISTICS == 1
+00233 struct uip_stats uip_stat;
+00234 #define UIP_STAT(s) s
+00235 #else
+00236 #define UIP_STAT(s)
+00237 #endif /* UIP_STATISTICS == 1 */
+00238 
+00239 #if UIP_LOGGING == 1
+00240 #include <stdio.h>
+00241 void uip_log(char *msg);
+00242 #define UIP_LOG(m) uip_log(m)
+00243 #else
+00244 #define UIP_LOG(m)
+00245 #endif /* UIP_LOGGING == 1 */
+00246 
+00247 #if ! UIP_ARCH_ADD32
+00248 void
+00249 uip_add32(u8_t *op32, u16_t op16)
+00250 {
+00251   uip_acc32[3] = op32[3] + (op16 & 0xff);
+00252   uip_acc32[2] = op32[2] + (op16 >> 8);
+00253   uip_acc32[1] = op32[1];
+00254   uip_acc32[0] = op32[0];
+00255   
+00256   if(uip_acc32[2] < (op16 >> 8)) {
+00257     ++uip_acc32[1];
+00258     if(uip_acc32[1] == 0) {
+00259       ++uip_acc32[0];
+00260     }
+00261   }
+00262   
+00263   
+00264   if(uip_acc32[3] < (op16 & 0xff)) {
+00265     ++uip_acc32[2];
+00266     if(uip_acc32[2] == 0) {
+00267       ++uip_acc32[1];
+00268       if(uip_acc32[1] == 0) {
+00269         ++uip_acc32[0];
+00270       }
+00271     }
+00272   }
+00273 }
+00274 
+00275 #endif /* UIP_ARCH_ADD32 */
+00276 
+00277 #if ! UIP_ARCH_CHKSUM
+00278 /*---------------------------------------------------------------------------*/
+00279 static u16_t
+00280 chksum(u16_t sum, const u8_t *data, u16_t len)
+00281 {
+00282   u16_t t;
+00283   const u8_t *dataptr;
+00284   const u8_t *last_byte;
+00285 
+00286   dataptr = data;
+00287   last_byte = data + len - 1;
+00288   
+00289   while(dataptr < last_byte) {  /* At least two more bytes */
+00290     t = (dataptr[0] << 8) + dataptr[1];
+00291     sum += t;
+00292     if(sum < t) {
+00293       sum++;            /* carry */
+00294     }
+00295     dataptr += 2;
+00296   }
+00297   
+00298   if(dataptr == last_byte) {
+00299     t = (dataptr[0] << 8) + 0;
+00300     sum += t;
+00301     if(sum < t) {
+00302       sum++;            /* carry */
+00303     }
+00304   }
+00305 
+00306   /* Return sum in host byte order. */
+00307   return sum;
+00308 }
+00309 /*---------------------------------------------------------------------------*/
+00310 u16_t
+00311 uip_chksum(u16_t *data, u16_t len)
+00312 {
+00313   return htons(chksum(0, (u8_t *)data, len));
+00314 }
+00315 /*---------------------------------------------------------------------------*/
+00316 #ifndef UIP_ARCH_IPCHKSUM
+00317 u16_t
+00318 uip_ipchksum(void)
+00319 {
+00320   u16_t sum;
+00321 
+00322   sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
+00323   DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
+00324   return (sum == 0) ? 0xffff : htons(sum);
+00325 }
+00326 #endif
+00327 /*---------------------------------------------------------------------------*/
+00328 static u16_t
+00329 upper_layer_chksum(u8_t proto)
+00330 {
+00331   u16_t upper_layer_len;
+00332   u16_t sum;
+00333   
+00334 #if UIP_CONF_IPV6
+00335   upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
+00336 #else /* UIP_CONF_IPV6 */
+00337   upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
+00338 #endif /* UIP_CONF_IPV6 */
+00339   
+00340   /* First sum pseudoheader. */
+00341   
+00342   /* IP protocol and length fields. This addition cannot carry. */
+00343   sum = upper_layer_len + proto;
+00344   /* Sum IP source and destination addresses. */
+00345   sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
+00346 
+00347   /* Sum TCP header and data. */
+00348   sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
+00349                upper_layer_len);
+00350     
+00351   return (sum == 0) ? 0xffff : htons(sum);
+00352 }
+00353 /*---------------------------------------------------------------------------*/
+00354 #if UIP_CONF_IPV6
+00355 u16_t
+00356 uip_icmp6chksum(void)
+00357 {
+00358   return upper_layer_chksum(UIP_PROTO_ICMP6);
+00359   
+00360 }
+00361 #endif /* UIP_CONF_IPV6 */
+00362 /*---------------------------------------------------------------------------*/
+00363 u16_t
+00364 uip_tcpchksum(void)
+00365 {
+00366   return upper_layer_chksum(UIP_PROTO_TCP);
+00367 }
+00368 /*---------------------------------------------------------------------------*/
+00369 #if UIP_UDP_CHECKSUMS
+00370 u16_t
+00371 uip_udpchksum(void)
+00372 {
+00373   return upper_layer_chksum(UIP_PROTO_UDP);
+00374 }
+00375 #endif /* UIP_UDP_CHECKSUMS */
+00376 #endif /* UIP_ARCH_CHKSUM */
+00377 /*---------------------------------------------------------------------------*/
+00378 void
+00379 uip_init(void)
+00380 {
+00381   for(c = 0; c < UIP_LISTENPORTS; ++c) {
+00382     uip_listenports[c] = 0;
+00383   }
+00384   for(c = 0; c < UIP_CONNS; ++c) {
+00385     uip_conns[c].tcpstateflags = UIP_CLOSED;
+00386   }
+00387 #if UIP_ACTIVE_OPEN
+00388   lastport = 1024;
+00389 #endif /* UIP_ACTIVE_OPEN */
+00390 
+00391 #if UIP_UDP
+00392   for(c = 0; c < UIP_UDP_CONNS; ++c) {
+00393     uip_udp_conns[c].lport = 0;
+00394   }
+00395 #endif /* UIP_UDP */
+00396   
+00397 
+00398   /* IPv4 initialization. */
+00399 #if UIP_FIXEDADDR == 0
+00400   /*  uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
+00401 #endif /* UIP_FIXEDADDR */
+00402 
+00403 }
+00404 /*---------------------------------------------------------------------------*/
+00405 #if UIP_ACTIVE_OPEN
+00406 struct uip_conn *
+00407 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
+00408 {
+00409   register struct uip_conn *conn, *cconn;
+00410   
+00411   /* Find an unused local port. */
+00412  again:
+00413   ++lastport;
+00414 
+00415   if(lastport >= 32000) {
+00416     lastport = 4096;
+00417   }
+00418 
+00419   /* Check if this port is already in use, and if so try to find
+00420      another one. */
+00421   for(c = 0; c < UIP_CONNS; ++c) {
+00422     conn = &uip_conns[c];
+00423     if(conn->tcpstateflags != UIP_CLOSED &&
+00424        conn->lport == htons(lastport)) {
+00425       goto again;
+00426     }
+00427   }
+00428 
+00429   conn = 0;
+00430   for(c = 0; c < UIP_CONNS; ++c) {
+00431     cconn = &uip_conns[c];
+00432     if(cconn->tcpstateflags == UIP_CLOSED) {
+00433       conn = cconn;
+00434       break;
+00435     }
+00436     if(cconn->tcpstateflags == UIP_TIME_WAIT) {
+00437       if(conn == 0 ||
+00438          cconn->timer > conn->timer) {
+00439         conn = cconn;
+00440       }
+00441     }
+00442   }
+00443 
+00444   if(conn == 0) {
+00445     return 0;
+00446   }
+00447   
+00448   conn->tcpstateflags = UIP_SYN_SENT;
+00449 
+00450   conn->snd_nxt[0] = iss[0];
+00451   conn->snd_nxt[1] = iss[1];
+00452   conn->snd_nxt[2] = iss[2];
+00453   conn->snd_nxt[3] = iss[3];
+00454 
+00455   conn->initialmss = conn->mss = UIP_TCP_MSS;
+00456   
+00457   conn->len = 1;   /* TCP length of the SYN is one. */
+00458   conn->nrtx = 0;
+00459   conn->timer = 1; /* Send the SYN next time around. */
+00460   conn->rto = UIP_RTO;
+00461   conn->sa = 0;
+00462   conn->sv = 16;   /* Initial value of the RTT variance. */
+00463   conn->lport = htons(lastport);
+00464   conn->rport = rport;
+00465   uip_ipaddr_copy(&conn->ripaddr, ripaddr);
+00466   
+00467   return conn;
+00468 }
+00469 #endif /* UIP_ACTIVE_OPEN */
+00470 /*---------------------------------------------------------------------------*/
+00471 #if UIP_UDP
+00472 struct uip_udp_conn *
+00473 uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
+00474 {
+00475   register struct uip_udp_conn *conn;
+00476   
+00477   /* Find an unused local port. */
+00478  again:
+00479   ++lastport;
+00480 
+00481   if(lastport >= 32000) {
+00482     lastport = 4096;
+00483   }
+00484   
+00485   for(c = 0; c < UIP_UDP_CONNS; ++c) {
+00486     if(uip_udp_conns[c].lport == htons(lastport)) {
+00487       goto again;
+00488     }
+00489   }
+00490 
+00491 
+00492   conn = 0;
+00493   for(c = 0; c < UIP_UDP_CONNS; ++c) {
+00494     if(uip_udp_conns[c].lport == 0) {
+00495       conn = &uip_udp_conns[c];
+00496       break;
+00497     }
+00498   }
+00499 
+00500   if(conn == 0) {
+00501     return 0;
+00502   }
+00503   
+00504   conn->lport = HTONS(lastport);
+00505   conn->rport = rport;
+00506   if(ripaddr == NULL) {
+00507     memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
+00508   } else {
+00509     uip_ipaddr_copy(&conn->ripaddr, ripaddr);
+00510   }
+00511   conn->ttl = UIP_TTL;
+00512   
+00513   return conn;
+00514 }
+00515 #endif /* UIP_UDP */
+00516 /*---------------------------------------------------------------------------*/
+00517 void
+00518 uip_unlisten(u16_t port)
+00519 {
+00520   for(c = 0; c < UIP_LISTENPORTS; ++c) {
+00521     if(uip_listenports[c] == port) {
+00522       uip_listenports[c] = 0;
+00523       return;
+00524     }
+00525   }
+00526 }
+00527 /*---------------------------------------------------------------------------*/
+00528 void
+00529 uip_listen(u16_t port)
+00530 {
+00531   for(c = 0; c < UIP_LISTENPORTS; ++c) {
+00532     if(uip_listenports[c] == 0) {
+00533       uip_listenports[c] = port;
+00534       return;
+00535     }
+00536   }
+00537 }
+00538 /*---------------------------------------------------------------------------*/
+00539 /* XXX: IP fragment reassembly: not well-tested. */
+00540 
+00541 #if UIP_REASSEMBLY && !UIP_CONF_IPV6
+00542 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
+00543 static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
+00544 static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
+00545 static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
+00546                                     0x0f, 0x07, 0x03, 0x01};
+00547 static u16_t uip_reasslen;
+00548 static u8_t uip_reassflags;
+00549 #define UIP_REASS_FLAG_LASTFRAG 0x01
+00550 static u8_t uip_reasstmr;
+00551 
+00552 #define IP_MF   0x20
+00553 
+00554 static u8_t
+00555 uip_reass(void)
+00556 {
+00557   u16_t offset, len;
+00558   u16_t i;
+00559 
+00560   /* If ip_reasstmr is zero, no packet is present in the buffer, so we
+00561      write the IP header of the fragment into the reassembly
+00562      buffer. The timer is updated with the maximum age. */
+00563   if(uip_reasstmr == 0) {
+00564     memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
+00565     uip_reasstmr = UIP_REASS_MAXAGE;
+00566     uip_reassflags = 0;
+00567     /* Clear the bitmap. */
+00568     memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
+00569   }
+00570 
+00571   /* Check if the incoming fragment matches the one currently present
+00572      in the reasembly buffer. If so, we proceed with copying the
+00573      fragment into the buffer. */
+00574   if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
+00575      BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
+00576      BUF->destipaddr[0] == FBUF->destipaddr[0] &&
+00577      BUF->destipaddr[1] == FBUF->destipaddr[1] &&
+00578      BUF->ipid[0] == FBUF->ipid[0] &&
+00579      BUF->ipid[1] == FBUF->ipid[1]) {
+00580 
+00581     len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
+00582     offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
+00583 
+00584     /* If the offset or the offset + fragment length overflows the
+00585        reassembly buffer, we discard the entire packet. */
+00586     if(offset > UIP_REASS_BUFSIZE ||
+00587        offset + len > UIP_REASS_BUFSIZE) {
+00588       uip_reasstmr = 0;
+00589       goto nullreturn;
+00590     }
+00591 
+00592     /* Copy the fragment into the reassembly buffer, at the right
+00593        offset. */
+00594     memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
+00595            (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
+00596            len);
+00597       
+00598     /* Update the bitmap. */
+00599     if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
+00600       /* If the two endpoints are in the same byte, we only update
+00601          that byte. */
+00602              
+00603       uip_reassbitmap[offset / (8 * 8)] |=
+00604              bitmap_bits[(offset / 8 ) & 7] &
+00605              ~bitmap_bits[((offset + len) / 8 ) & 7];
+00606     } else {
+00607       /* If the two endpoints are in different bytes, we update the
+00608          bytes in the endpoints and fill the stuff inbetween with
+00609          0xff. */
+00610       uip_reassbitmap[offset / (8 * 8)] |=
+00611         bitmap_bits[(offset / 8 ) & 7];
+00612       for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
+00613         uip_reassbitmap[i] = 0xff;
+00614       }
+00615       uip_reassbitmap[(offset + len) / (8 * 8)] |=
+00616         ~bitmap_bits[((offset + len) / 8 ) & 7];
+00617     }
+00618     
+00619     /* If this fragment has the More Fragments flag set to zero, we
+00620        know that this is the last fragment, so we can calculate the
+00621        size of the entire packet. We also set the
+00622        IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
+00623        the final fragment. */
+00624 
+00625     if((BUF->ipoffset[0] & IP_MF) == 0) {
+00626       uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
+00627       uip_reasslen = offset + len;
+00628     }
+00629     
+00630     /* Finally, we check if we have a full packet in the buffer. We do
+00631        this by checking if we have the last fragment and if all bits
+00632        in the bitmap are set. */
+00633     if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
+00634       /* Check all bytes up to and including all but the last byte in
+00635          the bitmap. */
+00636       for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
+00637         if(uip_reassbitmap[i] != 0xff) {
+00638           goto nullreturn;
+00639         }
+00640       }
+00641       /* Check the last byte in the bitmap. It should contain just the
+00642          right amount of bits. */
+00643       if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
+00644          (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
+00645         goto nullreturn;
+00646       }
+00647 
+00648       /* If we have come this far, we have a full packet in the
+00649          buffer, so we allocate a pbuf and copy the packet into it. We
+00650          also reset the timer. */
+00651       uip_reasstmr = 0;
+00652       memcpy(BUF, FBUF, uip_reasslen);
+00653 
+00654       /* Pretend to be a "normal" (i.e., not fragmented) IP packet
+00655          from now on. */
+00656       BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
+00657       BUF->len[0] = uip_reasslen >> 8;
+00658       BUF->len[1] = uip_reasslen & 0xff;
+00659       BUF->ipchksum = 0;
+00660       BUF->ipchksum = ~(uip_ipchksum());
+00661 
+00662       return uip_reasslen;
+00663     }
+00664   }
+00665 
+00666  nullreturn:
+00667   return 0;
+00668 }
+00669 #endif /* UIP_REASSEMBLY */
+00670 /*---------------------------------------------------------------------------*/
+00671 static void
+00672 uip_add_rcv_nxt(u16_t n)
+00673 {
+00674   uip_add32(uip_conn->rcv_nxt, n);
+00675   uip_conn->rcv_nxt[0] = uip_acc32[0];
+00676   uip_conn->rcv_nxt[1] = uip_acc32[1];
+00677   uip_conn->rcv_nxt[2] = uip_acc32[2];
+00678   uip_conn->rcv_nxt[3] = uip_acc32[3];
+00679 }
+00680 /*---------------------------------------------------------------------------*/
+00681 void
+00682 uip_process(u8_t flag)
+00683 {
+00684   register struct uip_conn *uip_connr = uip_conn;
+00685 
+00686 #if UIP_UDP
+00687   if(flag == UIP_UDP_SEND_CONN) {
+00688     goto udp_send;
+00689   }
+00690 #endif /* UIP_UDP */
+00691   
+00692   uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
+00693 
+00694   /* Check if we were invoked because of a poll request for a
+00695      particular connection. */
+00696   if(flag == UIP_POLL_REQUEST) {
+00697     if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
+00698        !uip_outstanding(uip_connr)) {
+00699         uip_flags = UIP_POLL;
+00700         UIP_APPCALL();
+00701         goto appsend;
+00702     }
+00703     goto drop;
+00704     
+00705     /* Check if we were invoked because of the perodic timer fireing. */
+00706   } else if(flag == UIP_TIMER) {
+00707 #if UIP_REASSEMBLY
+00708     if(uip_reasstmr != 0) {
+00709       --uip_reasstmr;
+00710     }
+00711 #endif /* UIP_REASSEMBLY */
+00712     /* Increase the initial sequence number. */
+00713     if(++iss[3] == 0) {
+00714       if(++iss[2] == 0) {
+00715         if(++iss[1] == 0) {
+00716           ++iss[0];
+00717         }
+00718       }
+00719     }
+00720 
+00721     /* Reset the length variables. */
+00722     uip_len = 0;
+00723     uip_slen = 0;
+00724 
+00725     /* Check if the connection is in a state in which we simply wait
+00726        for the connection to time out. If so, we increase the
+00727        connection's timer and remove the connection if it times
+00728        out. */
+00729     if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
+00730        uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
+00731       ++(uip_connr->timer);
+00732       if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
+00733         uip_connr->tcpstateflags = UIP_CLOSED;
+00734       }
+00735     } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
+00736       /* If the connection has outstanding data, we increase the
+00737          connection's timer and see if it has reached the RTO value
+00738          in which case we retransmit. */
+00739       if(uip_outstanding(uip_connr)) {
+00740         if(uip_connr->timer-- == 0) {
+00741           if(uip_connr->nrtx == UIP_MAXRTX ||
+00742              ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
+00743                uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
+00744               uip_connr->nrtx == UIP_MAXSYNRTX)) {
+00745             uip_connr->tcpstateflags = UIP_CLOSED;
+00746 
+00747             /* We call UIP_APPCALL() with uip_flags set to
+00748                UIP_TIMEDOUT to inform the application that the
+00749                connection has timed out. */
+00750             uip_flags = UIP_TIMEDOUT;
+00751             UIP_APPCALL();
+00752 
+00753             /* We also send a reset packet to the remote host. */
+00754             BUF->flags = TCP_RST | TCP_ACK;
+00755             goto tcp_send_nodata;
+00756           }
+00757 
+00758           /* Exponential backoff. */
+00759           uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
+00760                                          4:
+00761                                          uip_connr->nrtx);
+00762           ++(uip_connr->nrtx);
+00763           
+00764           /* Ok, so we need to retransmit. We do this differently
+00765              depending on which state we are in. In ESTABLISHED, we
+00766              call upon the application so that it may prepare the
+00767              data for the retransmit. In SYN_RCVD, we resend the
+00768              SYNACK that we sent earlier and in LAST_ACK we have to
+00769              retransmit our FINACK. */
+00770           UIP_STAT(++uip_stat.tcp.rexmit);
+00771           switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
+00772           case UIP_SYN_RCVD:
+00773             /* In the SYN_RCVD state, we should retransmit our
+00774                SYNACK. */
+00775             goto tcp_send_synack;
+00776             
+00777 #if UIP_ACTIVE_OPEN
+00778           case UIP_SYN_SENT:
+00779             /* In the SYN_SENT state, we retransmit out SYN. */
+00780             BUF->flags = 0;
+00781             goto tcp_send_syn;
+00782 #endif /* UIP_ACTIVE_OPEN */
+00783             
+00784           case UIP_ESTABLISHED:
+00785             /* In the ESTABLISHED state, we call upon the application
+00786                to do the actual retransmit after which we jump into
+00787                the code for sending out the packet (the apprexmit
+00788                label). */
+00789             uip_flags = UIP_REXMIT;
+00790             UIP_APPCALL();
+00791             goto apprexmit;
+00792             
+00793           case UIP_FIN_WAIT_1:
+00794           case UIP_CLOSING:
+00795           case UIP_LAST_ACK:
+00796             /* In all these states we should retransmit a FINACK. */
+00797             goto tcp_send_finack;
+00798             
+00799           }
+00800         }
+00801       } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
+00802         /* If there was no need for a retransmission, we poll the
+00803            application for new data. */
+00804         uip_flags = UIP_POLL;
+00805         UIP_APPCALL();
+00806         goto appsend;
+00807       }
+00808     }
+00809     goto drop;
+00810   }
+00811 #if UIP_UDP
+00812   if(flag == UIP_UDP_TIMER) {
+00813     if(uip_udp_conn->lport != 0) {
+00814       uip_conn = NULL;
+00815       uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+00816       uip_len = uip_slen = 0;
+00817       uip_flags = UIP_POLL;
+00818       UIP_UDP_APPCALL();
+00819       goto udp_send;
+00820     } else {
+00821       goto drop;
+00822     }
+00823   }
+00824 #endif
+00825 
+00826   /* This is where the input processing starts. */
+00827   UIP_STAT(++uip_stat.ip.recv);
+00828 
+00829   /* Start of IP input header processing code. */
+00830   
+00831 #if UIP_CONF_IPV6
+00832   /* Check validity of the IP header. */
+00833   if((BUF->vtc & 0xf0) != 0x60)  { /* IP version and header length. */
+00834     UIP_STAT(++uip_stat.ip.drop);
+00835     UIP_STAT(++uip_stat.ip.vhlerr);
+00836     UIP_LOG("ipv6: invalid version.");
+00837     goto drop;
+00838   }
+00839 #else /* UIP_CONF_IPV6 */
+00840   /* Check validity of the IP header. */
+00841   if(BUF->vhl != 0x45)  { /* IP version and header length. */
+00842     UIP_STAT(++uip_stat.ip.drop);
+00843     UIP_STAT(++uip_stat.ip.vhlerr);
+00844     UIP_LOG("ip: invalid version or header length.");
+00845     goto drop;
+00846   }
+00847 #endif /* UIP_CONF_IPV6 */
+00848   
+00849   /* Check the size of the packet. If the size reported to us in
+00850      uip_len is smaller the size reported in the IP header, we assume
+00851      that the packet has been corrupted in transit. If the size of
+00852      uip_len is larger than the size reported in the IP packet header,
+00853      the packet has been padded and we set uip_len to the correct
+00854      value.. */
+00855 
+00856   if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
+00857     uip_len = (BUF->len[0] << 8) + BUF->len[1];
+00858 #if UIP_CONF_IPV6
+00859     uip_len += 40; /* The length reported in the IPv6 header is the
+00860                       length of the payload that follows the
+00861                       header. However, uIP uses the uip_len variable
+00862                       for holding the size of the entire packet,
+00863                       including the IP header. For IPv4 this is not a
+00864                       problem as the length field in the IPv4 header
+00865                       contains the length of the entire packet. But
+00866                       for IPv6 we need to add the size of the IPv6
+00867                       header (40 bytes). */
+00868 #endif /* UIP_CONF_IPV6 */
+00869   } else {
+00870     UIP_LOG("ip: packet shorter than reported in IP header.");
+00871     goto drop;
+00872   }
+00873 
+00874 #if !UIP_CONF_IPV6
+00875   /* Check the fragment flag. */
+00876   if((BUF->ipoffset[0] & 0x3f) != 0 ||
+00877      BUF->ipoffset[1] != 0) {
+00878 #if UIP_REASSEMBLY
+00879     uip_len = uip_reass();
+00880     if(uip_len == 0) {
+00881       goto drop;
+00882     }
+00883 #else /* UIP_REASSEMBLY */
+00884     UIP_STAT(++uip_stat.ip.drop);
+00885     UIP_STAT(++uip_stat.ip.fragerr);
+00886     UIP_LOG("ip: fragment dropped.");
+00887     goto drop;
+00888 #endif /* UIP_REASSEMBLY */
+00889   }
+00890 #endif /* UIP_CONF_IPV6 */
+00891 
+00892   if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
+00893     /* If we are configured to use ping IP address configuration and
+00894        hasn't been assigned an IP address yet, we accept all ICMP
+00895        packets. */
+00896 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
+00897     if(BUF->proto == UIP_PROTO_ICMP) {
+00898       UIP_LOG("ip: possible ping config packet received.");
+00899       goto icmp_input;
+00900     } else {
+00901       UIP_LOG("ip: packet dropped since no address assigned.");
+00902       goto drop;
+00903     }
+00904 #endif /* UIP_PINGADDRCONF */
+00905 
+00906   } else {
+00907     /* If IP broadcast support is configured, we check for a broadcast
+00908        UDP packet, which may be destined to us. */
+00909 #if UIP_BROADCAST
+00910     DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
+00911     if(BUF->proto == UIP_PROTO_UDP &&
+00912        uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
+00913        /*&&
+00914          uip_ipchksum() == 0xffff*/) {
+00915       goto udp_input;
+00916     }
+00917 #endif /* UIP_BROADCAST */
+00918     
+00919     /* Check if the packet is destined for our IP address. */
+00920 #if !UIP_CONF_IPV6
+00921     if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
+00922       UIP_STAT(++uip_stat.ip.drop);
+00923       goto drop;
+00924     }
+00925 #else /* UIP_CONF_IPV6 */
+00926     /* For IPv6, packet reception is a little trickier as we need to
+00927        make sure that we listen to certain multicast addresses (all
+00928        hosts multicast address, and the solicited-node multicast
+00929        address) as well. However, we will cheat here and accept all
+00930        multicast packets that are sent to the ff02::/16 addresses. */
+00931     if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
+00932        BUF->destipaddr[0] != HTONS(0xff02)) {
+00933       UIP_STAT(++uip_stat.ip.drop);
+00934       goto drop;
+00935     }
+00936 #endif /* UIP_CONF_IPV6 */
+00937   }
+00938 
+00939 #if !UIP_CONF_IPV6
+00940   if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
+00941                                     checksum. */
+00942     UIP_STAT(++uip_stat.ip.drop);
+00943     UIP_STAT(++uip_stat.ip.chkerr);
+00944     UIP_LOG("ip: bad checksum.");
+00945     goto drop;
+00946   }
+00947 #endif /* UIP_CONF_IPV6 */
+00948 
+00949   if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
+00950                                        proceed with TCP input
+00951                                        processing. */
+00952     goto tcp_input;
+00953   }
+00954 
+00955 #if UIP_UDP
+00956   if(BUF->proto == UIP_PROTO_UDP) {
+00957     goto udp_input;
+00958   }
+00959 #endif /* UIP_UDP */
+00960 
+00961 #if !UIP_CONF_IPV6
+00962   /* ICMPv4 processing code follows. */
+00963   if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
+00964                                         here. */
+00965     UIP_STAT(++uip_stat.ip.drop);
+00966     UIP_STAT(++uip_stat.ip.protoerr);
+00967     UIP_LOG("ip: neither tcp nor icmp.");
+00968     goto drop;
+00969   }
+00970 
+00971 #if UIP_PINGADDRCONF
+00972  icmp_input:
+00973 #endif /* UIP_PINGADDRCONF */
+00974   UIP_STAT(++uip_stat.icmp.recv);
+00975 
+00976   /* ICMP echo (i.e., ping) processing. This is simple, we only change
+00977      the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
+00978      checksum before we return the packet. */
+00979   if(ICMPBUF->type != ICMP_ECHO) {
+00980     UIP_STAT(++uip_stat.icmp.drop);
+00981     UIP_STAT(++uip_stat.icmp.typeerr);
+00982     UIP_LOG("icmp: not icmp echo.");
+00983     goto drop;
+00984   }
+00985 
+00986   /* If we are configured to use ping IP address assignment, we use
+00987      the destination IP address of this ping packet and assign it to
+00988      ourself. */
+00989 #if UIP_PINGADDRCONF
+00990   if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
+00991     uip_hostaddr[0] = BUF->destipaddr[0];
+00992     uip_hostaddr[1] = BUF->destipaddr[1];
+00993   }
+00994 #endif /* UIP_PINGADDRCONF */
+00995 
+00996   ICMPBUF->type = ICMP_ECHO_REPLY;
+00997 
+00998   if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
+00999     ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
+01000   } else {
+01001     ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
+01002   }
+01003 
+01004   /* Swap IP addresses. */
+01005   uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+01006   uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+01007 
+01008   UIP_STAT(++uip_stat.icmp.sent);
+01009   goto send;
+01010 
+01011   /* End of IPv4 input header processing code. */
+01012 #else /* !UIP_CONF_IPV6 */
+01013 
+01014   /* This is IPv6 ICMPv6 processing code. */
+01015   DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
+01016 
+01017   if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from
+01018                                          here. */
+01019     UIP_STAT(++uip_stat.ip.drop);
+01020     UIP_STAT(++uip_stat.ip.protoerr);
+01021     UIP_LOG("ip: neither tcp nor icmp6.");
+01022     goto drop;
+01023   }
+01024 
+01025   UIP_STAT(++uip_stat.icmp.recv);
+01026 
+01027   /* If we get a neighbor solicitation for our address we should send
+01028      a neighbor advertisement message back. */
+01029   if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
+01030     if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
+01031 
+01032       if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
+01033         /* Save the sender's address in our neighbor list. */
+01034         uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
+01035       }
+01036       
+01037       /* We should now send a neighbor advertisement back to where the
+01038          neighbor solicication came from. */
+01039       ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
+01040       ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
+01041       
+01042       ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
+01043       
+01044       uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
+01045       uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
+01046       ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
+01047       ICMPBUF->options[1] = 1;  /* Options length, 1 = 8 bytes. */
+01048       memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
+01049       ICMPBUF->icmpchksum = 0;
+01050       ICMPBUF->icmpchksum = ~uip_icmp6chksum();
+01051       goto send;
+01052       
+01053     }
+01054     goto drop;
+01055   } else if(ICMPBUF->type == ICMP6_ECHO) {
+01056     /* ICMP echo (i.e., ping) processing. This is simple, we only
+01057        change the ICMP type from ECHO to ECHO_REPLY and update the
+01058        ICMP checksum before we return the packet. */
+01059 
+01060     ICMPBUF->type = ICMP6_ECHO_REPLY;
+01061     
+01062     uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+01063     uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+01064     ICMPBUF->icmpchksum = 0;
+01065     ICMPBUF->icmpchksum = ~uip_icmp6chksum();
+01066     
+01067     UIP_STAT(++uip_stat.icmp.sent);
+01068     goto send;
+01069   } else {
+01070     DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
+01071     UIP_STAT(++uip_stat.icmp.drop);
+01072     UIP_STAT(++uip_stat.icmp.typeerr);
+01073     UIP_LOG("icmp: unknown ICMP message.");
+01074     goto drop;
+01075   }
+01076 
+01077   /* End of IPv6 ICMP processing. */
+01078   
+01079 #endif /* !UIP_CONF_IPV6 */
+01080 
+01081 #if UIP_UDP
+01082   /* UDP input processing. */
+01083  udp_input:
+01084   /* UDP processing is really just a hack. We don't do anything to the
+01085      UDP/IP headers, but let the UDP application do all the hard
+01086      work. If the application sets uip_slen, it has a packet to
+01087      send. */
+01088 #if UIP_UDP_CHECKSUMS
+01089   uip_len = uip_len - UIP_IPUDPH_LEN;
+01090   uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+01091   if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
+01092     UIP_STAT(++uip_stat.udp.drop);
+01093     UIP_STAT(++uip_stat.udp.chkerr);
+01094     UIP_LOG("udp: bad checksum.");
+01095     goto drop;
+01096   }
+01097 #else /* UIP_UDP_CHECKSUMS */
+01098   uip_len = uip_len - UIP_IPUDPH_LEN;
+01099 #endif /* UIP_UDP_CHECKSUMS */
+01100 
+01101   /* Demultiplex this UDP packet between the UDP "connections". */
+01102   for(uip_udp_conn = &uip_udp_conns[0];
+01103       uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
+01104       ++uip_udp_conn) {
+01105     /* If the local UDP port is non-zero, the connection is considered
+01106        to be used. If so, the local port number is checked against the
+01107        destination port number in the received packet. If the two port
+01108        numbers match, the remote port number is checked if the
+01109        connection is bound to a remote port. Finally, if the
+01110        connection is bound to a remote IP address, the source IP
+01111        address of the packet is checked. */
+01112     if(uip_udp_conn->lport != 0 &&
+01113        UDPBUF->destport == uip_udp_conn->lport &&
+01114        (uip_udp_conn->rport == 0 ||
+01115         UDPBUF->srcport == uip_udp_conn->rport) &&
+01116        (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
+01117         uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
+01118         uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
+01119       goto udp_found;
+01120     }
+01121   }
+01122   UIP_LOG("udp: no matching connection found");
+01123   goto drop;
+01124   
+01125  udp_found:
+01126   uip_conn = NULL;
+01127   uip_flags = UIP_NEWDATA;
+01128   uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+01129   uip_slen = 0;
+01130   UIP_UDP_APPCALL();
+01131  udp_send:
+01132   if(uip_slen == 0) {
+01133     goto drop;
+01134   }
+01135   uip_len = uip_slen + UIP_IPUDPH_LEN;
+01136 
+01137 #if UIP_CONF_IPV6
+01138   /* For IPv6, the IP length field does not include the IPv6 IP header
+01139      length. */
+01140   BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+01141   BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+01142 #else /* UIP_CONF_IPV6 */
+01143   BUF->len[0] = (uip_len >> 8);
+01144   BUF->len[1] = (uip_len & 0xff);
+01145 #endif /* UIP_CONF_IPV6 */
+01146 
+01147   BUF->ttl = uip_udp_conn->ttl;
+01148   BUF->proto = UIP_PROTO_UDP;
+01149 
+01150   UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
+01151   UDPBUF->udpchksum = 0;
+01152 
+01153   BUF->srcport  = uip_udp_conn->lport;
+01154   BUF->destport = uip_udp_conn->rport;
+01155 
+01156   uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+01157   uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
+01158    
+01159   uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
+01160 
+01161 #if UIP_UDP_CHECKSUMS
+01162   /* Calculate UDP checksum. */
+01163   UDPBUF->udpchksum = ~(uip_udpchksum());
+01164   if(UDPBUF->udpchksum == 0) {
+01165     UDPBUF->udpchksum = 0xffff;
+01166   }
+01167 #endif /* UIP_UDP_CHECKSUMS */
+01168   
+01169   goto ip_send_nolen;
+01170 #endif /* UIP_UDP */
+01171   
+01172   /* TCP input processing. */
+01173  tcp_input:
+01174   UIP_STAT(++uip_stat.tcp.recv);
+01175 
+01176   /* Start of TCP input header processing code. */
+01177   
+01178   if(uip_tcpchksum() != 0xffff) {   /* Compute and check the TCP
+01179                                        checksum. */
+01180     UIP_STAT(++uip_stat.tcp.drop);
+01181     UIP_STAT(++uip_stat.tcp.chkerr);
+01182     UIP_LOG("tcp: bad checksum.");
+01183     goto drop;
+01184   }
+01185   
+01186   
+01187   /* Demultiplex this segment. */
+01188   /* First check any active connections. */
+01189   for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
+01190       ++uip_connr) {
+01191     if(uip_connr->tcpstateflags != UIP_CLOSED &&
+01192        BUF->destport == uip_connr->lport &&
+01193        BUF->srcport == uip_connr->rport &&
+01194        uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
+01195       goto found;
+01196     }
+01197   }
+01198 
+01199   /* If we didn't find and active connection that expected the packet,
+01200      either this packet is an old duplicate, or this is a SYN packet
+01201      destined for a connection in LISTEN. If the SYN flag isn't set,
+01202      it is an old packet and we send a RST. */
+01203   if((BUF->flags & TCP_CTL) != TCP_SYN) {
+01204     goto reset;
+01205   }
+01206   
+01207   tmp16 = BUF->destport;
+01208   /* Next, check listening connections. */
+01209   for(c = 0; c < UIP_LISTENPORTS; ++c) {
+01210     if(tmp16 == uip_listenports[c])
+01211       goto found_listen;
+01212   }
+01213   
+01214   /* No matching connection found, so we send a RST packet. */
+01215   UIP_STAT(++uip_stat.tcp.synrst);
+01216  reset:
+01217 
+01218   /* We do not send resets in response to resets. */
+01219   if(BUF->flags & TCP_RST) {
+01220     goto drop;
+01221   }
+01222 
+01223   UIP_STAT(++uip_stat.tcp.rst);
+01224   
+01225   BUF->flags = TCP_RST | TCP_ACK;
+01226   uip_len = UIP_IPTCPH_LEN;
+01227   BUF->tcpoffset = 5 << 4;
+01228 
+01229   /* Flip the seqno and ackno fields in the TCP header. */
+01230   c = BUF->seqno[3];
+01231   BUF->seqno[3] = BUF->ackno[3];
+01232   BUF->ackno[3] = c;
+01233   
+01234   c = BUF->seqno[2];
+01235   BUF->seqno[2] = BUF->ackno[2];
+01236   BUF->ackno[2] = c;
+01237   
+01238   c = BUF->seqno[1];
+01239   BUF->seqno[1] = BUF->ackno[1];
+01240   BUF->ackno[1] = c;
+01241   
+01242   c = BUF->seqno[0];
+01243   BUF->seqno[0] = BUF->ackno[0];
+01244   BUF->ackno[0] = c;
+01245 
+01246   /* We also have to increase the sequence number we are
+01247      acknowledging. If the least significant byte overflowed, we need
+01248      to propagate the carry to the other bytes as well. */
+01249   if(++BUF->ackno[3] == 0) {
+01250     if(++BUF->ackno[2] == 0) {
+01251       if(++BUF->ackno[1] == 0) {
+01252         ++BUF->ackno[0];
+01253       }
+01254     }
+01255   }
+01256  
+01257   /* Swap port numbers. */
+01258   tmp16 = BUF->srcport;
+01259   BUF->srcport = BUF->destport;
+01260   BUF->destport = tmp16;
+01261   
+01262   /* Swap IP addresses. */
+01263   uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+01264   uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+01265   
+01266   /* And send out the RST packet! */
+01267   goto tcp_send_noconn;
+01268 
+01269   /* This label will be jumped to if we matched the incoming packet
+01270      with a connection in LISTEN. In that case, we should create a new
+01271      connection and send a SYNACK in return. */
+01272  found_listen:
+01273   /* First we check if there are any connections avaliable. Unused
+01274      connections are kept in the same table as used connections, but
+01275      unused ones have the tcpstate set to CLOSED. Also, connections in
+01276      TIME_WAIT are kept track of and we'll use the oldest one if no
+01277      CLOSED connections are found. Thanks to Eddie C. Dost for a very
+01278      nice algorithm for the TIME_WAIT search. */
+01279   uip_connr = 0;
+01280   for(c = 0; c < UIP_CONNS; ++c) {
+01281     if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
+01282       uip_connr = &uip_conns[c];
+01283       break;
+01284     }
+01285     if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
+01286       if(uip_connr == 0 ||
+01287          uip_conns[c].timer > uip_connr->timer) {
+01288         uip_connr = &uip_conns[c];
+01289       }
+01290     }
+01291   }
+01292 
+01293   if(uip_connr == 0) {
+01294     /* All connections are used already, we drop packet and hope that
+01295        the remote end will retransmit the packet at a time when we
+01296        have more spare connections. */
+01297     UIP_STAT(++uip_stat.tcp.syndrop);
+01298     UIP_LOG("tcp: found no unused connections.");
+01299     goto drop;
+01300   }
+01301   uip_conn = uip_connr;
+01302   
+01303   /* Fill in the necessary fields for the new connection. */
+01304   uip_connr->rto = uip_connr->timer = UIP_RTO;
+01305   uip_connr->sa = 0;
+01306   uip_connr->sv = 4;
+01307   uip_connr->nrtx = 0;
+01308   uip_connr->lport = BUF->destport;
+01309   uip_connr->rport = BUF->srcport;
+01310   uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
+01311   uip_connr->tcpstateflags = UIP_SYN_RCVD;
+01312 
+01313   uip_connr->snd_nxt[0] = iss[0];
+01314   uip_connr->snd_nxt[1] = iss[1];
+01315   uip_connr->snd_nxt[2] = iss[2];
+01316   uip_connr->snd_nxt[3] = iss[3];
+01317   uip_connr->len = 1;
+01318 
+01319   /* rcv_nxt should be the seqno from the incoming packet + 1. */
+01320   uip_connr->rcv_nxt[3] = BUF->seqno[3];
+01321   uip_connr->rcv_nxt[2] = BUF->seqno[2];
+01322   uip_connr->rcv_nxt[1] = BUF->seqno[1];
+01323   uip_connr->rcv_nxt[0] = BUF->seqno[0];
+01324   uip_add_rcv_nxt(1);
+01325 
+01326   /* Parse the TCP MSS option, if present. */
+01327   if((BUF->tcpoffset & 0xf0) > 0x50) {
+01328     for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
+01329       opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
+01330       if(opt == TCP_OPT_END) {
+01331         /* End of options. */
+01332         break;
+01333       } else if(opt == TCP_OPT_NOOP) {
+01334         ++c;
+01335         /* NOP option. */
+01336       } else if(opt == TCP_OPT_MSS &&
+01337                 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
+01338         /* An MSS option with the right option length. */
+01339         tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
+01340           (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
+01341         uip_connr->initialmss = uip_connr->mss =
+01342           tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
+01343         
+01344         /* And we are done processing options. */
+01345         break;
+01346       } else {
+01347         /* All other options have a length field, so that we easily
+01348            can skip past them. */
+01349         if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
+01350           /* If the length field is zero, the options are malformed
+01351              and we don't process them further. */
+01352           break;
+01353         }
+01354         c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
+01355       }
+01356     }
+01357   }
+01358   
+01359   /* Our response will be a SYNACK. */
+01360 #if UIP_ACTIVE_OPEN
+01361  tcp_send_synack:
+01362   BUF->flags = TCP_ACK;
+01363   
+01364  tcp_send_syn:
+01365   BUF->flags |= TCP_SYN;
+01366 #else /* UIP_ACTIVE_OPEN */
+01367  tcp_send_synack:
+01368   BUF->flags = TCP_SYN | TCP_ACK;
+01369 #endif /* UIP_ACTIVE_OPEN */
+01370   
+01371   /* We send out the TCP Maximum Segment Size option with our
+01372      SYNACK. */
+01373   BUF->optdata[0] = TCP_OPT_MSS;
+01374   BUF->optdata[1] = TCP_OPT_MSS_LEN;
+01375   BUF->optdata[2] = (UIP_TCP_MSS) / 256;
+01376   BUF->optdata[3] = (UIP_TCP_MSS) & 255;
+01377   uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
+01378   BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
+01379   goto tcp_send;
+01380 
+01381   /* This label will be jumped to if we found an active connection. */
+01382  found:
+01383   uip_conn = uip_connr;
+01384   uip_flags = 0;
+01385   /* We do a very naive form of TCP reset processing; we just accept
+01386      any RST and kill our connection. We should in fact check if the
+01387      sequence number of this reset is wihtin our advertised window
+01388      before we accept the reset. */
+01389   if(BUF->flags & TCP_RST) {
+01390     uip_connr->tcpstateflags = UIP_CLOSED;
+01391     UIP_LOG("tcp: got reset, aborting connection.");
+01392     uip_flags = UIP_ABORT;
+01393     UIP_APPCALL();
+01394     goto drop;
+01395   }
+01396   /* Calculated the length of the data, if the application has sent
+01397      any data to us. */
+01398   c = (BUF->tcpoffset >> 4) << 2;
+01399   /* uip_len will contain the length of the actual TCP data. This is
+01400      calculated by subtracing the length of the TCP header (in
+01401      c) and the length of the IP header (20 bytes). */
+01402   uip_len = uip_len - c - UIP_IPH_LEN;
+01403 
+01404   /* First, check if the sequence number of the incoming packet is
+01405      what we're expecting next. If not, we send out an ACK with the
+01406      correct numbers in. */
+01407   if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
+01408        ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
+01409     if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
+01410        (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
+01411         BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
+01412         BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
+01413         BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
+01414       goto tcp_send_ack;
+01415     }
+01416   }
+01417 
+01418   /* Next, check if the incoming segment acknowledges any outstanding
+01419      data. If so, we update the sequence number, reset the length of
+01420      the outstanding data, calculate RTT estimations, and reset the
+01421      retransmission timer. */
+01422   if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
+01423     uip_add32(uip_connr->snd_nxt, uip_connr->len);
+01424 
+01425     if(BUF->ackno[0] == uip_acc32[0] &&
+01426        BUF->ackno[1] == uip_acc32[1] &&
+01427        BUF->ackno[2] == uip_acc32[2] &&
+01428        BUF->ackno[3] == uip_acc32[3]) {
+01429       /* Update sequence number. */
+01430       uip_connr->snd_nxt[0] = uip_acc32[0];
+01431       uip_connr->snd_nxt[1] = uip_acc32[1];
+01432       uip_connr->snd_nxt[2] = uip_acc32[2];
+01433       uip_connr->snd_nxt[3] = uip_acc32[3];
+01434         
+01435 
+01436       /* Do RTT estimation, unless we have done retransmissions. */
+01437       if(uip_connr->nrtx == 0) {
+01438         signed char m;
+01439         m = uip_connr->rto - uip_connr->timer;
+01440         /* This is taken directly from VJs original code in his paper */
+01441         m = m - (uip_connr->sa >> 3);
+01442         uip_connr->sa += m;
+01443         if(m < 0) {
+01444           m = -m;
+01445         }
+01446         m = m - (uip_connr->sv >> 2);
+01447         uip_connr->sv += m;
+01448         uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
+01449 
+01450       }
+01451       /* Set the acknowledged flag. */
+01452       uip_flags = UIP_ACKDATA;
+01453       /* Reset the retransmission timer. */
+01454       uip_connr->timer = uip_connr->rto;
+01455 
+01456       /* Reset length of outstanding data. */
+01457       uip_connr->len = 0;
+01458     }
+01459     
+01460   }
+01461 
+01462   /* Do different things depending on in what state the connection is. */
+01463   switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
+01464     /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
+01465         implemented, since we force the application to close when the
+01466         peer sends a FIN (hence the application goes directly from
+01467         ESTABLISHED to LAST_ACK). */
+01468   case UIP_SYN_RCVD:
+01469     /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
+01470        we are waiting for an ACK that acknowledges the data we sent
+01471        out the last time. Therefore, we want to have the UIP_ACKDATA
+01472        flag set. If so, we enter the ESTABLISHED state. */
+01473     if(uip_flags & UIP_ACKDATA) {
+01474       uip_connr->tcpstateflags = UIP_ESTABLISHED;
+01475       uip_flags = UIP_CONNECTED;
+01476       uip_connr->len = 0;
+01477       if(uip_len > 0) {
+01478         uip_flags |= UIP_NEWDATA;
+01479         uip_add_rcv_nxt(uip_len);
+01480       }
+01481       uip_slen = 0;
+01482       UIP_APPCALL();
+01483       goto appsend;
+01484     }
+01485     goto drop;
+01486 #if UIP_ACTIVE_OPEN
+01487   case UIP_SYN_SENT:
+01488     /* In SYN_SENT, we wait for a SYNACK that is sent in response to
+01489        our SYN. The rcv_nxt is set to sequence number in the SYNACK
+01490        plus one, and we send an ACK. We move into the ESTABLISHED
+01491        state. */
+01492     if((uip_flags & UIP_ACKDATA) &&
+01493        (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
+01494 
+01495       /* Parse the TCP MSS option, if present. */
+01496       if((BUF->tcpoffset & 0xf0) > 0x50) {
+01497         for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
+01498           opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
+01499           if(opt == TCP_OPT_END) {
+01500             /* End of options. */
+01501             break;
+01502           } else if(opt == TCP_OPT_NOOP) {
+01503             ++c;
+01504             /* NOP option. */
+01505           } else if(opt == TCP_OPT_MSS &&
+01506                     uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
+01507             /* An MSS option with the right option length. */
+01508             tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
+01509               uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
+01510             uip_connr->initialmss =
+01511               uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
+01512 
+01513             /* And we are done processing options. */
+01514             break;
+01515           } else {
+01516             /* All other options have a length field, so that we easily
+01517                can skip past them. */
+01518             if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
+01519               /* If the length field is zero, the options are malformed
+01520                  and we don't process them further. */
+01521               break;
+01522             }
+01523             c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
+01524           }
+01525         }
+01526       }
+01527       uip_connr->tcpstateflags = UIP_ESTABLISHED;
+01528       uip_connr->rcv_nxt[0] = BUF->seqno[0];
+01529       uip_connr->rcv_nxt[1] = BUF->seqno[1];
+01530       uip_connr->rcv_nxt[2] = BUF->seqno[2];
+01531       uip_connr->rcv_nxt[3] = BUF->seqno[3];
+01532       uip_add_rcv_nxt(1);
+01533       uip_flags = UIP_CONNECTED | UIP_NEWDATA;
+01534       uip_connr->len = 0;
+01535       uip_len = 0;
+01536       uip_slen = 0;
+01537       UIP_APPCALL();
+01538       goto appsend;
+01539     }
+01540     /* Inform the application that the connection failed */
+01541     uip_flags = UIP_ABORT;
+01542     UIP_APPCALL();
+01543     /* The connection is closed after we send the RST */
+01544     uip_conn->tcpstateflags = UIP_CLOSED;
+01545     goto reset;
+01546 #endif /* UIP_ACTIVE_OPEN */
+01547     
+01548   case UIP_ESTABLISHED:
+01549     /* In the ESTABLISHED state, we call upon the application to feed
+01550     data into the uip_buf. If the UIP_ACKDATA flag is set, the
+01551     application should put new data into the buffer, otherwise we are
+01552     retransmitting an old segment, and the application should put that
+01553     data into the buffer.
+01554 
+01555     If the incoming packet is a FIN, we should close the connection on
+01556     this side as well, and we send out a FIN and enter the LAST_ACK
+01557     state. We require that there is no outstanding data; otherwise the
+01558     sequence numbers will be screwed up. */
+01559 
+01560     if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
+01561       if(uip_outstanding(uip_connr)) {
+01562         goto drop;
+01563       }
+01564       uip_add_rcv_nxt(1 + uip_len);
+01565       uip_flags |= UIP_CLOSE;
+01566       if(uip_len > 0) {
+01567         uip_flags |= UIP_NEWDATA;
+01568       }
+01569       UIP_APPCALL();
+01570       uip_connr->len = 1;
+01571       uip_connr->tcpstateflags = UIP_LAST_ACK;
+01572       uip_connr->nrtx = 0;
+01573     tcp_send_finack:
+01574       BUF->flags = TCP_FIN | TCP_ACK;
+01575       goto tcp_send_nodata;
+01576     }
+01577 
+01578     /* Check the URG flag. If this is set, the segment carries urgent
+01579        data that we must pass to the application. */
+01580     if((BUF->flags & TCP_URG) != 0) {
+01581 #if UIP_URGDATA > 0
+01582       uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
+01583       if(uip_urglen > uip_len) {
+01584         /* There is more urgent data in the next segment to come. */
+01585         uip_urglen = uip_len;
+01586       }
+01587       uip_add_rcv_nxt(uip_urglen);
+01588       uip_len -= uip_urglen;
+01589       uip_urgdata = uip_appdata;
+01590       uip_appdata += uip_urglen;
+01591     } else {
+01592       uip_urglen = 0;
+01593 #else /* UIP_URGDATA > 0 */
+01594       uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
+01595       uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
+01596 #endif /* UIP_URGDATA > 0 */
+01597     }
+01598 
+01599     /* If uip_len > 0 we have TCP data in the packet, and we flag this
+01600        by setting the UIP_NEWDATA flag and update the sequence number
+01601        we acknowledge. If the application has stopped the dataflow
+01602        using uip_stop(), we must not accept any data packets from the
+01603        remote host. */
+01604     if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
+01605       uip_flags |= UIP_NEWDATA;
+01606       uip_add_rcv_nxt(uip_len);
+01607     }
+01608 
+01609     /* Check if the available buffer space advertised by the other end
+01610        is smaller than the initial MSS for this connection. If so, we
+01611        set the current MSS to the window size to ensure that the
+01612        application does not send more data than the other end can
+01613        handle.
+01614 
+01615        If the remote host advertises a zero window, we set the MSS to
+01616        the initial MSS so that the application will send an entire MSS
+01617        of data. This data will not be acknowledged by the receiver,
+01618        and the application will retransmit it. This is called the
+01619        "persistent timer" and uses the retransmission mechanim.
+01620     */
+01621     tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
+01622     if(tmp16 > uip_connr->initialmss ||
+01623        tmp16 == 0) {
+01624       tmp16 = uip_connr->initialmss;
+01625     }
+01626     uip_connr->mss = tmp16;
+01627 
+01628     /* If this packet constitutes an ACK for outstanding data (flagged
+01629        by the UIP_ACKDATA flag, we should call the application since it
+01630        might want to send more data. If the incoming packet had data
+01631        from the peer (as flagged by the UIP_NEWDATA flag), the
+01632        application must also be notified.
+01633 
+01634        When the application is called, the global variable uip_len
+01635        contains the length of the incoming data. The application can
+01636        access the incoming data through the global pointer
+01637        uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
+01638        bytes into the uip_buf array.
+01639 
+01640        If the application wishes to send any data, this data should be
+01641        put into the uip_appdata and the length of the data should be
+01642        put into uip_len. If the application don't have any data to
+01643        send, uip_len must be set to 0. */
+01644     if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
+01645       uip_slen = 0;
+01646       UIP_APPCALL();
+01647 
+01648     appsend:
+01649       
+01650       if(uip_flags & UIP_ABORT) {
+01651         uip_slen = 0;
+01652         uip_connr->tcpstateflags = UIP_CLOSED;
+01653         BUF->flags = TCP_RST | TCP_ACK;
+01654         goto tcp_send_nodata;
+01655       }
+01656 
+01657       if(uip_flags & UIP_CLOSE) {
+01658         uip_slen = 0;
+01659         uip_connr->len = 1;
+01660         uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
+01661         uip_connr->nrtx = 0;
+01662         BUF->flags = TCP_FIN | TCP_ACK;
+01663         goto tcp_send_nodata;
+01664       }
+01665 
+01666       /* If uip_slen > 0, the application has data to be sent. */
+01667       if(uip_slen > 0) {
+01668 
+01669         /* If the connection has acknowledged data, the contents of
+01670            the ->len variable should be discarded. */
+01671         if((uip_flags & UIP_ACKDATA) != 0) {
+01672           uip_connr->len = 0;
+01673         }
+01674 
+01675         /* If the ->len variable is non-zero the connection has
+01676            already data in transit and cannot send anymore right
+01677            now. */
+01678         if(uip_connr->len == 0) {
+01679 
+01680           /* The application cannot send more than what is allowed by
+01681              the mss (the minumum of the MSS and the available
+01682              window). */
+01683           if(uip_slen > uip_connr->mss) {
+01684             uip_slen = uip_connr->mss;
+01685           }
+01686 
+01687           /* Remember how much data we send out now so that we know
+01688              when everything has been acknowledged. */
+01689           uip_connr->len = uip_slen;
+01690         } else {
+01691 
+01692           /* If the application already had unacknowledged data, we
+01693              make sure that the application does not send (i.e.,
+01694              retransmit) out more than it previously sent out. */
+01695           uip_slen = uip_connr->len;
+01696         }
+01697       }
+01698       uip_connr->nrtx = 0;
+01699     apprexmit:
+01700       uip_appdata = uip_sappdata;
+01701       
+01702       /* If the application has data to be sent, or if the incoming
+01703          packet had new data in it, we must send out a packet. */
+01704       if(uip_slen > 0 && uip_connr->len > 0) {
+01705         /* Add the length of the IP and TCP headers. */
+01706         uip_len = uip_connr->len + UIP_TCPIP_HLEN;
+01707         /* We always set the ACK flag in response packets. */
+01708         BUF->flags = TCP_ACK | TCP_PSH;
+01709         /* Send the packet. */
+01710         goto tcp_send_noopts;
+01711       }
+01712       /* If there is no data to send, just send out a pure ACK if
+01713          there is newdata. */
+01714       if(uip_flags & UIP_NEWDATA) {
+01715         uip_len = UIP_TCPIP_HLEN;
+01716         BUF->flags = TCP_ACK;
+01717         goto tcp_send_noopts;
+01718       }
+01719     }
+01720     goto drop;
+01721   case UIP_LAST_ACK:
+01722     /* We can close this connection if the peer has acknowledged our
+01723        FIN. This is indicated by the UIP_ACKDATA flag. */
+01724     if(uip_flags & UIP_ACKDATA) {
+01725       uip_connr->tcpstateflags = UIP_CLOSED;
+01726       uip_flags = UIP_CLOSE;
+01727       UIP_APPCALL();
+01728     }
+01729     break;
+01730     
+01731   case UIP_FIN_WAIT_1:
+01732     /* The application has closed the connection, but the remote host
+01733        hasn't closed its end yet. Thus we do nothing but wait for a
+01734        FIN from the other side. */
+01735     if(uip_len > 0) {
+01736       uip_add_rcv_nxt(uip_len);
+01737     }
+01738     if(BUF->flags & TCP_FIN) {
+01739       if(uip_flags & UIP_ACKDATA) {
+01740         uip_connr->tcpstateflags = UIP_TIME_WAIT;
+01741         uip_connr->timer = 0;
+01742         uip_connr->len = 0;
+01743       } else {
+01744         uip_connr->tcpstateflags = UIP_CLOSING;
+01745       }
+01746       uip_add_rcv_nxt(1);
+01747       uip_flags = UIP_CLOSE;
+01748       UIP_APPCALL();
+01749       goto tcp_send_ack;
+01750     } else if(uip_flags & UIP_ACKDATA) {
+01751       uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
+01752       uip_connr->len = 0;
+01753       goto drop;
+01754     }
+01755     if(uip_len > 0) {
+01756       goto tcp_send_ack;
+01757     }
+01758     goto drop;
+01759       
+01760   case UIP_FIN_WAIT_2:
+01761     if(uip_len > 0) {
+01762       uip_add_rcv_nxt(uip_len);
+01763     }
+01764     if(BUF->flags & TCP_FIN) {
+01765       uip_connr->tcpstateflags = UIP_TIME_WAIT;
+01766       uip_connr->timer = 0;
+01767       uip_add_rcv_nxt(1);
+01768       uip_flags = UIP_CLOSE;
+01769       UIP_APPCALL();
+01770       goto tcp_send_ack;
+01771     }
+01772     if(uip_len > 0) {
+01773       goto tcp_send_ack;
+01774     }
+01775     goto drop;
+01776 
+01777   case UIP_TIME_WAIT:
+01778     goto tcp_send_ack;
+01779     
+01780   case UIP_CLOSING:
+01781     if(uip_flags & UIP_ACKDATA) {
+01782       uip_connr->tcpstateflags = UIP_TIME_WAIT;
+01783       uip_connr->timer = 0;
+01784     }
+01785   }
+01786   goto drop;
+01787   
+01788 
+01789   /* We jump here when we are ready to send the packet, and just want
+01790      to set the appropriate TCP sequence numbers in the TCP header. */
+01791  tcp_send_ack:
+01792   BUF->flags = TCP_ACK;
+01793  tcp_send_nodata:
+01794   uip_len = UIP_IPTCPH_LEN;
+01795  tcp_send_noopts:
+01796   BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
+01797  tcp_send:
+01798   /* We're done with the input processing. We are now ready to send a
+01799      reply. Our job is to fill in all the fields of the TCP and IP
+01800      headers before calculating the checksum and finally send the
+01801      packet. */
+01802   BUF->ackno[0] = uip_connr->rcv_nxt[0];
+01803   BUF->ackno[1] = uip_connr->rcv_nxt[1];
+01804   BUF->ackno[2] = uip_connr->rcv_nxt[2];
+01805   BUF->ackno[3] = uip_connr->rcv_nxt[3];
+01806   
+01807   BUF->seqno[0] = uip_connr->snd_nxt[0];
+01808   BUF->seqno[1] = uip_connr->snd_nxt[1];
+01809   BUF->seqno[2] = uip_connr->snd_nxt[2];
+01810   BUF->seqno[3] = uip_connr->snd_nxt[3];
+01811 
+01812   BUF->proto = UIP_PROTO_TCP;
+01813   
+01814   BUF->srcport  = uip_connr->lport;
+01815   BUF->destport = uip_connr->rport;
+01816 
+01817   uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+01818   uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);
+01819 
+01820   if(uip_connr->tcpstateflags & UIP_STOPPED) {
+01821     /* If the connection has issued uip_stop(), we advertise a zero
+01822        window so that the remote host will stop sending data. */
+01823     BUF->wnd[0] = BUF->wnd[1] = 0;
+01824   } else {
+01825     BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
+01826     BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
+01827   }
+01828 
+01829  tcp_send_noconn:
+01830   BUF->ttl = UIP_TTL;
+01831 #if UIP_CONF_IPV6
+01832   /* For IPv6, the IP length field does not include the IPv6 IP header
+01833      length. */
+01834   BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+01835   BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+01836 #else /* UIP_CONF_IPV6 */
+01837   BUF->len[0] = (uip_len >> 8);
+01838   BUF->len[1] = (uip_len & 0xff);
+01839 #endif /* UIP_CONF_IPV6 */
+01840 
+01841   BUF->urgp[0] = BUF->urgp[1] = 0;
+01842   
+01843   /* Calculate TCP checksum. */
+01844   BUF->tcpchksum = 0;
+01845   BUF->tcpchksum = ~(uip_tcpchksum());
+01846   
+01847  ip_send_nolen:
+01848 
+01849 #if UIP_CONF_IPV6
+01850   BUF->vtc = 0x60;
+01851   BUF->tcflow = 0x00;
+01852   BUF->flow = 0x00;
+01853 #else /* UIP_CONF_IPV6 */
+01854   BUF->vhl = 0x45;
+01855   BUF->tos = 0;
+01856   BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
+01857   ++ipid;
+01858   BUF->ipid[0] = ipid >> 8;
+01859   BUF->ipid[1] = ipid & 0xff;
+01860   /* Calculate IP checksum. */
+01861   BUF->ipchksum = 0;
+01862   BUF->ipchksum = ~(uip_ipchksum());
+01863   DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
+01864 #endif /* UIP_CONF_IPV6 */
+01865    
+01866   UIP_STAT(++uip_stat.tcp.sent);
+01867  send:
+01868   DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
+01869                (BUF->len[0] << 8) | BUF->len[1]);
+01870   
+01871   UIP_STAT(++uip_stat.ip.sent);
+01872   /* Return and let the caller do the actual transmission. */
+01873   uip_flags = 0;
+01874   return;
+01875  drop:
+01876   uip_len = 0;
+01877   uip_flags = 0;
+01878   return;
+01879 }
+01880 /*---------------------------------------------------------------------------*/
+01881 u16_t
+01882 htons(u16_t val)
+01883 {
+01884   return HTONS(val);
+01885 }
+01886 /*---------------------------------------------------------------------------*/
+01887 void
+01888 uip_send(const void *data, int len)
+01889 {
+01890   if(len > 0) {
+01891     uip_slen = len;
+01892     if(data != uip_sappdata) {
+01893       memcpy(uip_sappdata, (data), uip_slen);
+01894     }
+01895   }
+01896 }
+01897 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00202.html b/doc/html/a00202.html new file mode 100644 index 0000000..ff2306c --- /dev/null +++ b/doc/html/a00202.html @@ -0,0 +1,1626 @@ + + +uIP 1.0: uip/uip.h Source File + + + + + + +

uip/uip.h

Go to the documentation of this file.
00001 
+00002 /**
+00003  * \addtogroup uip
+00004  * @{
+00005  */
+00006 
+00007 /**
+00008  * \file
+00009  * Header file for the uIP TCP/IP stack.
+00010  * \author Adam Dunkels <adam@dunkels.com>
+00011  *
+00012  * The uIP TCP/IP stack header file contains definitions for a number
+00013  * of C macros that are used by uIP programs as well as internal uIP
+00014  * structures, TCP/IP header structures and function declarations.
+00015  *
+00016  */
+00017 
+00018 
+00019 /*
+00020  * Copyright (c) 2001-2003, Adam Dunkels.
+00021  * All rights reserved.
+00022  *
+00023  * Redistribution and use in source and binary forms, with or without
+00024  * modification, are permitted provided that the following conditions
+00025  * are met:
+00026  * 1. Redistributions of source code must retain the above copyright
+00027  *    notice, this list of conditions and the following disclaimer.
+00028  * 2. Redistributions in binary form must reproduce the above copyright
+00029  *    notice, this list of conditions and the following disclaimer in the
+00030  *    documentation and/or other materials provided with the distribution.
+00031  * 3. The name of the author may not be used to endorse or promote
+00032  *    products derived from this software without specific prior
+00033  *    written permission.
+00034  *
+00035  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00036  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00037  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00038  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00039  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00040  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00041  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00042  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00043  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00044  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00045  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00046  *
+00047  * This file is part of the uIP TCP/IP stack.
+00048  *
+00049  * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $
+00050  *
+00051  */
+00052 
+00053 #ifndef __UIP_H__
+00054 #define __UIP_H__
+00055 
+00056 #include "uipopt.h"
+00057 
+00058 /**
+00059  * Repressentation of an IP address.
+00060  *
+00061  */
+00062 typedef u16_t uip_ip4addr_t[2];
+00063 typedef u16_t uip_ip6addr_t[8];
+00064 #if UIP_CONF_IPV6
+00065 typedef uip_ip6addr_t uip_ipaddr_t;
+00066 #else /* UIP_CONF_IPV6 */
+00067 typedef uip_ip4addr_t uip_ipaddr_t;
+00068 #endif /* UIP_CONF_IPV6 */
+00069 
+00070 /*---------------------------------------------------------------------------*/
+00071 /* First, the functions that should be called from the
+00072  * system. Initialization, the periodic timer and incoming packets are
+00073  * handled by the following three functions.
+00074  */
+00075 
+00076 /**
+00077  * \defgroup uipconffunc uIP configuration functions
+00078  * @{
+00079  *
+00080  * The uIP configuration functions are used for setting run-time
+00081  * parameters in uIP such as IP addresses.
+00082  */
+00083 
+00084 /**
+00085  * Set the IP address of this host.
+00086  *
+00087  * The IP address is represented as a 4-byte array where the first
+00088  * octet of the IP address is put in the first member of the 4-byte
+00089  * array.
+00090  *
+00091  * Example:
+00092  \code
+00093 
+00094  uip_ipaddr_t addr;
+00095 
+00096  uip_ipaddr(&addr, 192,168,1,2);
+00097  uip_sethostaddr(&addr);
+00098  
+00099  \endcode
+00100  * \param addr A pointer to an IP address of type uip_ipaddr_t;
+00101  *
+00102  * \sa uip_ipaddr()
+00103  *
+00104  * \hideinitializer
+00105  */
+00106 #define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))
+00107 
+00108 /**
+00109  * Get the IP address of this host.
+00110  *
+00111  * The IP address is represented as a 4-byte array where the first
+00112  * octet of the IP address is put in the first member of the 4-byte
+00113  * array.
+00114  *
+00115  * Example:
+00116  \code
+00117  uip_ipaddr_t hostaddr;
+00118 
+00119  uip_gethostaddr(&hostaddr);
+00120  \endcode
+00121  * \param addr A pointer to a uip_ipaddr_t variable that will be
+00122  * filled in with the currently configured IP address.
+00123  *
+00124  * \hideinitializer
+00125  */
+00126 #define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr)
+00127 
+00128 /**
+00129  * Set the default router's IP address.
+00130  *
+00131  * \param addr A pointer to a uip_ipaddr_t variable containing the IP
+00132  * address of the default router.
+00133  *
+00134  * \sa uip_ipaddr()
+00135  *
+00136  * \hideinitializer
+00137  */
+00138 #define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
+00139 
+00140 /**
+00141  * Set the netmask.
+00142  *
+00143  * \param addr A pointer to a uip_ipaddr_t variable containing the IP
+00144  * address of the netmask.
+00145  *
+00146  * \sa uip_ipaddr()
+00147  *
+00148  * \hideinitializer
+00149  */
+00150 #define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))
+00151 
+00152 
+00153 /**
+00154  * Get the default router's IP address.
+00155  *
+00156  * \param addr A pointer to a uip_ipaddr_t variable that will be
+00157  * filled in with the IP address of the default router.
+00158  *
+00159  * \hideinitializer
+00160  */
+00161 #define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)
+00162 
+00163 /**
+00164  * Get the netmask.
+00165  *
+00166  * \param addr A pointer to a uip_ipaddr_t variable that will be
+00167  * filled in with the value of the netmask.
+00168  *
+00169  * \hideinitializer
+00170  */
+00171 #define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask)
+00172 
+00173 /** @} */
+00174 
+00175 /**
+00176  * \defgroup uipinit uIP initialization functions
+00177  * @{
+00178  *
+00179  * The uIP initialization functions are used for booting uIP.
+00180  */
+00181 
+00182 /**
+00183  * uIP initialization function.
+00184  *
+00185  * This function should be called at boot up to initilize the uIP
+00186  * TCP/IP stack.
+00187  */
+00188 void uip_init(void);
+00189 
+00190 /**
+00191  * uIP initialization function.
+00192  *
+00193  * This function may be used at boot time to set the initial ip_id.
+00194  */
+00195 void uip_setipid(u16_t id);
+00196 
+00197 /** @} */
+00198 
+00199 /**
+00200  * \defgroup uipdevfunc uIP device driver functions
+00201  * @{
+00202  *
+00203  * These functions are used by a network device driver for interacting
+00204  * with uIP.
+00205  */
+00206 
+00207 /**
+00208  * Process an incoming packet.
+00209  *
+00210  * This function should be called when the device driver has received
+00211  * a packet from the network. The packet from the device driver must
+00212  * be present in the uip_buf buffer, and the length of the packet
+00213  * should be placed in the uip_len variable.
+00214  *
+00215  * When the function returns, there may be an outbound packet placed
+00216  * in the uip_buf packet buffer. If so, the uip_len variable is set to
+00217  * the length of the packet. If no packet is to be sent out, the
+00218  * uip_len variable is set to 0.
+00219  *
+00220  * The usual way of calling the function is presented by the source
+00221  * code below.
+00222  \code
+00223   uip_len = devicedriver_poll();
+00224   if(uip_len > 0) {
+00225     uip_input();
+00226     if(uip_len > 0) {
+00227       devicedriver_send();
+00228     }
+00229   }
+00230  \endcode
+00231  *
+00232  * \note If you are writing a uIP device driver that needs ARP
+00233  * (Address Resolution Protocol), e.g., when running uIP over
+00234  * Ethernet, you will need to call the uIP ARP code before calling
+00235  * this function:
+00236  \code
+00237   #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+00238   uip_len = ethernet_devicedrver_poll();
+00239   if(uip_len > 0) {
+00240     if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
+00241       uip_arp_ipin();
+00242       uip_input();
+00243       if(uip_len > 0) {
+00244         uip_arp_out();
+00245         ethernet_devicedriver_send();
+00246       }
+00247     } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
+00248       uip_arp_arpin();
+00249       if(uip_len > 0) {
+00250         ethernet_devicedriver_send();
+00251       }
+00252     }
+00253  \endcode
+00254  *
+00255  * \hideinitializer
+00256  */
+00257 #define uip_input()        uip_process(UIP_DATA)
+00258 
+00259 /**
+00260  * Periodic processing for a connection identified by its number.
+00261  *
+00262  * This function does the necessary periodic processing (timers,
+00263  * polling) for a uIP TCP conneciton, and should be called when the
+00264  * periodic uIP timer goes off. It should be called for every
+00265  * connection, regardless of whether they are open of closed.
+00266  *
+00267  * When the function returns, it may have an outbound packet waiting
+00268  * for service in the uIP packet buffer, and if so the uip_len
+00269  * variable is set to a value larger than zero. The device driver
+00270  * should be called to send out the packet.
+00271  *
+00272  * The ususal way of calling the function is through a for() loop like
+00273  * this:
+00274  \code
+00275   for(i = 0; i < UIP_CONNS; ++i) {
+00276     uip_periodic(i);
+00277     if(uip_len > 0) {
+00278       devicedriver_send();
+00279     }
+00280   }
+00281  \endcode
+00282  *
+00283  * \note If you are writing a uIP device driver that needs ARP
+00284  * (Address Resolution Protocol), e.g., when running uIP over
+00285  * Ethernet, you will need to call the uip_arp_out() function before
+00286  * calling the device driver:
+00287  \code
+00288   for(i = 0; i < UIP_CONNS; ++i) {
+00289     uip_periodic(i);
+00290     if(uip_len > 0) {
+00291       uip_arp_out();
+00292       ethernet_devicedriver_send();
+00293     }
+00294   }
+00295  \endcode
+00296  *
+00297  * \param conn The number of the connection which is to be periodically polled.
+00298  *
+00299  * \hideinitializer
+00300  */
+00301 #define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
+00302                                 uip_process(UIP_TIMER); } while (0)
+00303 
+00304 /**
+00305  *
+00306  *
+00307  */
+00308 #define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
+00309 
+00310 /**
+00311  * Perform periodic processing for a connection identified by a pointer
+00312  * to its structure.
+00313  *
+00314  * Same as uip_periodic() but takes a pointer to the actual uip_conn
+00315  * struct instead of an integer as its argument. This function can be
+00316  * used to force periodic processing of a specific connection.
+00317  *
+00318  * \param conn A pointer to the uip_conn struct for the connection to
+00319  * be processed.
+00320  *
+00321  * \hideinitializer
+00322  */
+00323 #define uip_periodic_conn(conn) do { uip_conn = conn; \
+00324                                      uip_process(UIP_TIMER); } while (0)
+00325 
+00326 /**
+00327  * Reuqest that a particular connection should be polled.
+00328  *
+00329  * Similar to uip_periodic_conn() but does not perform any timer
+00330  * processing. The application is polled for new data.
+00331  *
+00332  * \param conn A pointer to the uip_conn struct for the connection to
+00333  * be processed.
+00334  *
+00335  * \hideinitializer
+00336  */
+00337 #define uip_poll_conn(conn) do { uip_conn = conn; \
+00338                                  uip_process(UIP_POLL_REQUEST); } while (0)
+00339 
+00340 
+00341 #if UIP_UDP
+00342 /**
+00343  * Periodic processing for a UDP connection identified by its number.
+00344  *
+00345  * This function is essentially the same as uip_periodic(), but for
+00346  * UDP connections. It is called in a similar fashion as the
+00347  * uip_periodic() function:
+00348  \code
+00349   for(i = 0; i < UIP_UDP_CONNS; i++) {
+00350     uip_udp_periodic(i);
+00351     if(uip_len > 0) {
+00352       devicedriver_send();
+00353     }
+00354   }
+00355  \endcode
+00356  *
+00357  * \note As for the uip_periodic() function, special care has to be
+00358  * taken when using uIP together with ARP and Ethernet:
+00359  \code
+00360   for(i = 0; i < UIP_UDP_CONNS; i++) {
+00361     uip_udp_periodic(i);
+00362     if(uip_len > 0) {
+00363       uip_arp_out();
+00364       ethernet_devicedriver_send();
+00365     }
+00366   }
+00367  \endcode
+00368  *
+00369  * \param conn The number of the UDP connection to be processed.
+00370  *
+00371  * \hideinitializer
+00372  */
+00373 #define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
+00374                                 uip_process(UIP_UDP_TIMER); } while (0)
+00375 
+00376 /**
+00377  * Periodic processing for a UDP connection identified by a pointer to
+00378  * its structure.
+00379  *
+00380  * Same as uip_udp_periodic() but takes a pointer to the actual
+00381  * uip_conn struct instead of an integer as its argument. This
+00382  * function can be used to force periodic processing of a specific
+00383  * connection.
+00384  *
+00385  * \param conn A pointer to the uip_udp_conn struct for the connection
+00386  * to be processed.
+00387  *
+00388  * \hideinitializer
+00389  */
+00390 #define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
+00391                                          uip_process(UIP_UDP_TIMER); } while (0)
+00392 
+00393 
+00394 #endif /* UIP_UDP */
+00395 
+00396 /**
+00397  * The uIP packet buffer.
+00398  *
+00399  * The uip_buf array is used to hold incoming and outgoing
+00400  * packets. The device driver should place incoming data into this
+00401  * buffer. When sending data, the device driver should read the link
+00402  * level headers and the TCP/IP headers from this buffer. The size of
+00403  * the link level headers is configured by the UIP_LLH_LEN define.
+00404  *
+00405  * \note The application data need not be placed in this buffer, so
+00406  * the device driver must read it from the place pointed to by the
+00407  * uip_appdata pointer as illustrated by the following example:
+00408  \code
+00409  void
+00410  devicedriver_send(void)
+00411  {
+00412     hwsend(&uip_buf[0], UIP_LLH_LEN);
+00413     if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
+00414       hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
+00415     } else {
+00416       hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
+00417       hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
+00418     }
+00419  }
+00420  \endcode
+00421  */
+00422 extern u8_t uip_buf[UIP_BUFSIZE+2];
+00423 
+00424 /** @} */
+00425 
+00426 /*---------------------------------------------------------------------------*/
+00427 /* Functions that are used by the uIP application program. Opening and
+00428  * closing connections, sending and receiving data, etc. is all
+00429  * handled by the functions below.
+00430 */
+00431 /**
+00432  * \defgroup uipappfunc uIP application functions
+00433  * @{
+00434  *
+00435  * Functions used by an application running of top of uIP.
+00436  */
+00437 
+00438 /**
+00439  * Start listening to the specified port.
+00440  *
+00441  * \note Since this function expects the port number in network byte
+00442  * order, a conversion using HTONS() or htons() is necessary.
+00443  *
+00444  \code
+00445  uip_listen(HTONS(80));
+00446  \endcode
+00447  *
+00448  * \param port A 16-bit port number in network byte order.
+00449  */
+00450 void uip_listen(u16_t port);
+00451 
+00452 /**
+00453  * Stop listening to the specified port.
+00454  *
+00455  * \note Since this function expects the port number in network byte
+00456  * order, a conversion using HTONS() or htons() is necessary.
+00457  *
+00458  \code
+00459  uip_unlisten(HTONS(80));
+00460  \endcode
+00461  *
+00462  * \param port A 16-bit port number in network byte order.
+00463  */
+00464 void uip_unlisten(u16_t port);
+00465 
+00466 /**
+00467  * Connect to a remote host using TCP.
+00468  *
+00469  * This function is used to start a new connection to the specified
+00470  * port on the specied host. It allocates a new connection identifier,
+00471  * sets the connection to the SYN_SENT state and sets the
+00472  * retransmission timer to 0. This will cause a TCP SYN segment to be
+00473  * sent out the next time this connection is periodically processed,
+00474  * which usually is done within 0.5 seconds after the call to
+00475  * uip_connect().
+00476  *
+00477  * \note This function is avaliable only if support for active open
+00478  * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
+00479  *
+00480  * \note Since this function requires the port number to be in network
+00481  * byte order, a conversion using HTONS() or htons() is necessary.
+00482  *
+00483  \code
+00484  uip_ipaddr_t ipaddr;
+00485 
+00486  uip_ipaddr(&ipaddr, 192,168,1,2);
+00487  uip_connect(&ipaddr, HTONS(80));
+00488  \endcode
+00489  *
+00490  * \param ripaddr The IP address of the remote hot.
+00491  *
+00492  * \param port A 16-bit port number in network byte order.
+00493  *
+00494  * \return A pointer to the uIP connection identifier for the new connection,
+00495  * or NULL if no connection could be allocated.
+00496  *
+00497  */
+00498 struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);
+00499 
+00500 
+00501 
+00502 /**
+00503  * \internal
+00504  *
+00505  * Check if a connection has outstanding (i.e., unacknowledged) data.
+00506  *
+00507  * \param conn A pointer to the uip_conn structure for the connection.
+00508  *
+00509  * \hideinitializer
+00510  */
+00511 #define uip_outstanding(conn) ((conn)->len)
+00512 
+00513 /**
+00514  * Send data on the current connection.
+00515  *
+00516  * This function is used to send out a single segment of TCP
+00517  * data. Only applications that have been invoked by uIP for event
+00518  * processing can send data.
+00519  *
+00520  * The amount of data that actually is sent out after a call to this
+00521  * funcion is determined by the maximum amount of data TCP allows. uIP
+00522  * will automatically crop the data so that only the appropriate
+00523  * amount of data is sent. The function uip_mss() can be used to query
+00524  * uIP for the amount of data that actually will be sent.
+00525  *
+00526  * \note This function does not guarantee that the sent data will
+00527  * arrive at the destination. If the data is lost in the network, the
+00528  * application will be invoked with the uip_rexmit() event being
+00529  * set. The application will then have to resend the data using this
+00530  * function.
+00531  *
+00532  * \param data A pointer to the data which is to be sent.
+00533  *
+00534  * \param len The maximum amount of data bytes to be sent.
+00535  *
+00536  * \hideinitializer
+00537  */
+00538 void uip_send(const void *data, int len);
+00539 
+00540 /**
+00541  * The length of any incoming data that is currently avaliable (if avaliable)
+00542  * in the uip_appdata buffer.
+00543  *
+00544  * The test function uip_data() must first be used to check if there
+00545  * is any data available at all.
+00546  *
+00547  * \hideinitializer
+00548  */
+00549 /*void uip_datalen(void);*/
+00550 #define uip_datalen()       uip_len
+00551 
+00552 /**
+00553  * The length of any out-of-band data (urgent data) that has arrived
+00554  * on the connection.
+00555  *
+00556  * \note The configuration parameter UIP_URGDATA must be set for this
+00557  * function to be enabled.
+00558  *
+00559  * \hideinitializer
+00560  */
+00561 #define uip_urgdatalen()    uip_urglen
+00562 
+00563 /**
+00564  * Close the current connection.
+00565  *
+00566  * This function will close the current connection in a nice way.
+00567  *
+00568  * \hideinitializer
+00569  */
+00570 #define uip_close()         (uip_flags = UIP_CLOSE)
+00571 
+00572 /**
+00573  * Abort the current connection.
+00574  *
+00575  * This function will abort (reset) the current connection, and is
+00576  * usually used when an error has occured that prevents using the
+00577  * uip_close() function.
+00578  *
+00579  * \hideinitializer
+00580  */
+00581 #define uip_abort()         (uip_flags = UIP_ABORT)
+00582 
+00583 /**
+00584  * Tell the sending host to stop sending data.
+00585  *
+00586  * This function will close our receiver's window so that we stop
+00587  * receiving data for the current connection.
+00588  *
+00589  * \hideinitializer
+00590  */
+00591 #define uip_stop()          (uip_conn->tcpstateflags |= UIP_STOPPED)
+00592 
+00593 /**
+00594  * Find out if the current connection has been previously stopped with
+00595  * uip_stop().
+00596  *
+00597  * \hideinitializer
+00598  */
+00599 #define uip_stopped(conn)   ((conn)->tcpstateflags & UIP_STOPPED)
+00600 
+00601 /**
+00602  * Restart the current connection, if is has previously been stopped
+00603  * with uip_stop().
+00604  *
+00605  * This function will open the receiver's window again so that we
+00606  * start receiving data for the current connection.
+00607  *
+00608  * \hideinitializer
+00609  */
+00610 #define uip_restart()         do { uip_flags |= UIP_NEWDATA; \
+00611                                    uip_conn->tcpstateflags &= ~UIP_STOPPED; \
+00612                               } while(0)
+00613 
+00614 
+00615 /* uIP tests that can be made to determine in what state the current
+00616    connection is, and what the application function should do. */
+00617 
+00618 /**
+00619  * Is the current connection a UDP connection?
+00620  *
+00621  * This function checks whether the current connection is a UDP connection.
+00622  *
+00623  * \hideinitializer
+00624  *
+00625  */
+00626 #define uip_udpconnection() (uip_conn == NULL)
+00627 
+00628 /**
+00629  * Is new incoming data available?
+00630  *
+00631  * Will reduce to non-zero if there is new data for the application
+00632  * present at the uip_appdata pointer. The size of the data is
+00633  * avaliable through the uip_len variable.
+00634  *
+00635  * \hideinitializer
+00636  */
+00637 #define uip_newdata()   (uip_flags & UIP_NEWDATA)
+00638 
+00639 /**
+00640  * Has previously sent data been acknowledged?
+00641  *
+00642  * Will reduce to non-zero if the previously sent data has been
+00643  * acknowledged by the remote host. This means that the application
+00644  * can send new data.
+00645  *
+00646  * \hideinitializer
+00647  */
+00648 #define uip_acked()   (uip_flags & UIP_ACKDATA)
+00649 
+00650 /**
+00651  * Has the connection just been connected?
+00652  *
+00653  * Reduces to non-zero if the current connection has been connected to
+00654  * a remote host. This will happen both if the connection has been
+00655  * actively opened (with uip_connect()) or passively opened (with
+00656  * uip_listen()).
+00657  *
+00658  * \hideinitializer
+00659  */
+00660 #define uip_connected() (uip_flags & UIP_CONNECTED)
+00661 
+00662 /**
+00663  * Has the connection been closed by the other end?
+00664  *
+00665  * Is non-zero if the connection has been closed by the remote
+00666  * host. The application may then do the necessary clean-ups.
+00667  *
+00668  * \hideinitializer
+00669  */
+00670 #define uip_closed()    (uip_flags & UIP_CLOSE)
+00671 
+00672 /**
+00673  * Has the connection been aborted by the other end?
+00674  *
+00675  * Non-zero if the current connection has been aborted (reset) by the
+00676  * remote host.
+00677  *
+00678  * \hideinitializer
+00679  */
+00680 #define uip_aborted()    (uip_flags & UIP_ABORT)
+00681 
+00682 /**
+00683  * Has the connection timed out?
+00684  *
+00685  * Non-zero if the current connection has been aborted due to too many
+00686  * retransmissions.
+00687  *
+00688  * \hideinitializer
+00689  */
+00690 #define uip_timedout()    (uip_flags & UIP_TIMEDOUT)
+00691 
+00692 /**
+00693  * Do we need to retransmit previously data?
+00694  *
+00695  * Reduces to non-zero if the previously sent data has been lost in
+00696  * the network, and the application should retransmit it. The
+00697  * application should send the exact same data as it did the last
+00698  * time, using the uip_send() function.
+00699  *
+00700  * \hideinitializer
+00701  */
+00702 #define uip_rexmit()     (uip_flags & UIP_REXMIT)
+00703 
+00704 /**
+00705  * Is the connection being polled by uIP?
+00706  *
+00707  * Is non-zero if the reason the application is invoked is that the
+00708  * current connection has been idle for a while and should be
+00709  * polled.
+00710  *
+00711  * The polling event can be used for sending data without having to
+00712  * wait for the remote host to send data.
+00713  *
+00714  * \hideinitializer
+00715  */
+00716 #define uip_poll()       (uip_flags & UIP_POLL)
+00717 
+00718 /**
+00719  * Get the initial maxium segment size (MSS) of the current
+00720  * connection.
+00721  *
+00722  * \hideinitializer
+00723  */
+00724 #define uip_initialmss()             (uip_conn->initialmss)
+00725 
+00726 /**
+00727  * Get the current maxium segment size that can be sent on the current
+00728  * connection.
+00729  *
+00730  * The current maxiumum segment size that can be sent on the
+00731  * connection is computed from the receiver's window and the MSS of
+00732  * the connection (which also is available by calling
+00733  * uip_initialmss()).
+00734  *
+00735  * \hideinitializer
+00736  */
+00737 #define uip_mss()             (uip_conn->mss)
+00738 
+00739 /**
+00740  * Set up a new UDP connection.
+00741  *
+00742  * This function sets up a new UDP connection. The function will
+00743  * automatically allocate an unused local port for the new
+00744  * connection. However, another port can be chosen by using the
+00745  * uip_udp_bind() call, after the uip_udp_new() function has been
+00746  * called.
+00747  *
+00748  * Example:
+00749  \code
+00750  uip_ipaddr_t addr;
+00751  struct uip_udp_conn *c;
+00752  
+00753  uip_ipaddr(&addr, 192,168,2,1);
+00754  c = uip_udp_new(&addr, HTONS(12345));
+00755  if(c != NULL) {
+00756    uip_udp_bind(c, HTONS(12344));
+00757  }
+00758  \endcode
+00759  * \param ripaddr The IP address of the remote host.
+00760  *
+00761  * \param rport The remote port number in network byte order.
+00762  *
+00763  * \return The uip_udp_conn structure for the new connection or NULL
+00764  * if no connection could be allocated.
+00765  */
+00766 struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);
+00767 
+00768 /**
+00769  * Removed a UDP connection.
+00770  *
+00771  * \param conn A pointer to the uip_udp_conn structure for the connection.
+00772  *
+00773  * \hideinitializer
+00774  */
+00775 #define uip_udp_remove(conn) (conn)->lport = 0
+00776 
+00777 /**
+00778  * Bind a UDP connection to a local port.
+00779  *
+00780  * \param conn A pointer to the uip_udp_conn structure for the
+00781  * connection.
+00782  *
+00783  * \param port The local port number, in network byte order.
+00784  *
+00785  * \hideinitializer
+00786  */
+00787 #define uip_udp_bind(conn, port) (conn)->lport = port
+00788 
+00789 /**
+00790  * Send a UDP datagram of length len on the current connection.
+00791  *
+00792  * This function can only be called in response to a UDP event (poll
+00793  * or newdata). The data must be present in the uip_buf buffer, at the
+00794  * place pointed to by the uip_appdata pointer.
+00795  *
+00796  * \param len The length of the data in the uip_buf buffer.
+00797  *
+00798  * \hideinitializer
+00799  */
+00800 #define uip_udp_send(len) uip_send((char *)uip_appdata, len)
+00801 
+00802 /** @} */
+00803 
+00804 /* uIP convenience and converting functions. */
+00805 
+00806 /**
+00807  * \defgroup uipconvfunc uIP conversion functions
+00808  * @{
+00809  *
+00810  * These functions can be used for converting between different data
+00811  * formats used by uIP.
+00812  */
+00813  
+00814 /**
+00815  * Construct an IP address from four bytes.
+00816  *
+00817  * This function constructs an IP address of the type that uIP handles
+00818  * internally from four bytes. The function is handy for specifying IP
+00819  * addresses to use with e.g. the uip_connect() function.
+00820  *
+00821  * Example:
+00822  \code
+00823  uip_ipaddr_t ipaddr;
+00824  struct uip_conn *c;
+00825  
+00826  uip_ipaddr(&ipaddr, 192,168,1,2);
+00827  c = uip_connect(&ipaddr, HTONS(80));
+00828  \endcode
+00829  *
+00830  * \param addr A pointer to a uip_ipaddr_t variable that will be
+00831  * filled in with the IP address.
+00832  *
+00833  * \param addr0 The first octet of the IP address.
+00834  * \param addr1 The second octet of the IP address.
+00835  * \param addr2 The third octet of the IP address.
+00836  * \param addr3 The forth octet of the IP address.
+00837  *
+00838  * \hideinitializer
+00839  */
+00840 #define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
+00841                      ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \
+00842                      ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \
+00843                   } while(0)
+00844 
+00845 /**
+00846  * Construct an IPv6 address from eight 16-bit words.
+00847  *
+00848  * This function constructs an IPv6 address.
+00849  *
+00850  * \hideinitializer
+00851  */
+00852 #define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \
+00853                      ((u16_t *)(addr))[0] = HTONS((addr0)); \
+00854                      ((u16_t *)(addr))[1] = HTONS((addr1)); \
+00855                      ((u16_t *)(addr))[2] = HTONS((addr2)); \
+00856                      ((u16_t *)(addr))[3] = HTONS((addr3)); \
+00857                      ((u16_t *)(addr))[4] = HTONS((addr4)); \
+00858                      ((u16_t *)(addr))[5] = HTONS((addr5)); \
+00859                      ((u16_t *)(addr))[6] = HTONS((addr6)); \
+00860                      ((u16_t *)(addr))[7] = HTONS((addr7)); \
+00861                   } while(0)
+00862 
+00863 /**
+00864  * Copy an IP address to another IP address.
+00865  *
+00866  * Copies an IP address from one place to another.
+00867  *
+00868  * Example:
+00869  \code
+00870  uip_ipaddr_t ipaddr1, ipaddr2;
+00871 
+00872  uip_ipaddr(&ipaddr1, 192,16,1,2);
+00873  uip_ipaddr_copy(&ipaddr2, &ipaddr1);
+00874  \endcode
+00875  *
+00876  * \param dest The destination for the copy.
+00877  * \param src The source from where to copy.
+00878  *
+00879  * \hideinitializer
+00880  */
+00881 #if !UIP_CONF_IPV6
+00882 #define uip_ipaddr_copy(dest, src) do { \
+00883                      ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \
+00884                      ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \
+00885                   } while(0)
+00886 #else /* !UIP_CONF_IPV6 */
+00887 #define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
+00888 #endif /* !UIP_CONF_IPV6 */
+00889 
+00890 /**
+00891  * Compare two IP addresses
+00892  *
+00893  * Compares two IP addresses.
+00894  *
+00895  * Example:
+00896  \code
+00897  uip_ipaddr_t ipaddr1, ipaddr2;
+00898 
+00899  uip_ipaddr(&ipaddr1, 192,16,1,2);
+00900  if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
+00901     printf("They are the same");
+00902  }
+00903  \endcode
+00904  *
+00905  * \param addr1 The first IP address.
+00906  * \param addr2 The second IP address.
+00907  *
+00908  * \hideinitializer
+00909  */
+00910 #if !UIP_CONF_IPV6
+00911 #define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \
+00912                                       ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1])
+00913 #else /* !UIP_CONF_IPV6 */
+00914 #define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
+00915 #endif /* !UIP_CONF_IPV6 */
+00916 
+00917 /**
+00918  * Compare two IP addresses with netmasks
+00919  *
+00920  * Compares two IP addresses with netmasks. The masks are used to mask
+00921  * out the bits that are to be compared.
+00922  *
+00923  * Example:
+00924  \code
+00925  uip_ipaddr_t ipaddr1, ipaddr2, mask;
+00926 
+00927  uip_ipaddr(&mask, 255,255,255,0);
+00928  uip_ipaddr(&ipaddr1, 192,16,1,2);
+00929  uip_ipaddr(&ipaddr2, 192,16,1,3);
+00930  if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {
+00931     printf("They are the same");
+00932  }
+00933  \endcode
+00934  *
+00935  * \param addr1 The first IP address.
+00936  * \param addr2 The second IP address.
+00937  * \param mask The netmask.
+00938  *
+00939  * \hideinitializer
+00940  */
+00941 #define uip_ipaddr_maskcmp(addr1, addr2, mask) \
+00942                           (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \
+00943                             (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \
+00944                            ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \
+00945                             (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))
+00946 
+00947 
+00948 /**
+00949  * Mask out the network part of an IP address.
+00950  *
+00951  * Masks out the network part of an IP address, given the address and
+00952  * the netmask.
+00953  *
+00954  * Example:
+00955  \code
+00956  uip_ipaddr_t ipaddr1, ipaddr2, netmask;
+00957 
+00958  uip_ipaddr(&ipaddr1, 192,16,1,2);
+00959  uip_ipaddr(&netmask, 255,255,255,0);
+00960  uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
+00961  \endcode
+00962  *
+00963  * In the example above, the variable "ipaddr2" will contain the IP
+00964  * address 192.168.1.0.
+00965  *
+00966  * \param dest Where the result is to be placed.
+00967  * \param src The IP address.
+00968  * \param mask The netmask.
+00969  *
+00970  * \hideinitializer
+00971  */
+00972 #define uip_ipaddr_mask(dest, src, mask) do { \
+00973                      ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \
+00974                      ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \
+00975                   } while(0)
+00976 
+00977 /**
+00978  * Pick the first octet of an IP address.
+00979  *
+00980  * Picks out the first octet of an IP address.
+00981  *
+00982  * Example:
+00983  \code
+00984  uip_ipaddr_t ipaddr;
+00985  u8_t octet;
+00986 
+00987  uip_ipaddr(&ipaddr, 1,2,3,4);
+00988  octet = uip_ipaddr1(&ipaddr);
+00989  \endcode
+00990  *
+00991  * In the example above, the variable "octet" will contain the value 1.
+00992  *
+00993  * \hideinitializer
+00994  */
+00995 #define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8)
+00996 
+00997 /**
+00998  * Pick the second octet of an IP address.
+00999  *
+01000  * Picks out the second octet of an IP address.
+01001  *
+01002  * Example:
+01003  \code
+01004  uip_ipaddr_t ipaddr;
+01005  u8_t octet;
+01006 
+01007  uip_ipaddr(&ipaddr, 1,2,3,4);
+01008  octet = uip_ipaddr2(&ipaddr);
+01009  \endcode
+01010  *
+01011  * In the example above, the variable "octet" will contain the value 2.
+01012  *
+01013  * \hideinitializer
+01014  */
+01015 #define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff)
+01016 
+01017 /**
+01018  * Pick the third octet of an IP address.
+01019  *
+01020  * Picks out the third octet of an IP address.
+01021  *
+01022  * Example:
+01023  \code
+01024  uip_ipaddr_t ipaddr;
+01025  u8_t octet;
+01026 
+01027  uip_ipaddr(&ipaddr, 1,2,3,4);
+01028  octet = uip_ipaddr3(&ipaddr);
+01029  \endcode
+01030  *
+01031  * In the example above, the variable "octet" will contain the value 3.
+01032  *
+01033  * \hideinitializer
+01034  */
+01035 #define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8)
+01036 
+01037 /**
+01038  * Pick the fourth octet of an IP address.
+01039  *
+01040  * Picks out the fourth octet of an IP address.
+01041  *
+01042  * Example:
+01043  \code
+01044  uip_ipaddr_t ipaddr;
+01045  u8_t octet;
+01046 
+01047  uip_ipaddr(&ipaddr, 1,2,3,4);
+01048  octet = uip_ipaddr4(&ipaddr);
+01049  \endcode
+01050  *
+01051  * In the example above, the variable "octet" will contain the value 4.
+01052  *
+01053  * \hideinitializer
+01054  */
+01055 #define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff)
+01056 
+01057 /**
+01058  * Convert 16-bit quantity from host byte order to network byte order.
+01059  *
+01060  * This macro is primarily used for converting constants from host
+01061  * byte order to network byte order. For converting variables to
+01062  * network byte order, use the htons() function instead.
+01063  *
+01064  * \hideinitializer
+01065  */
+01066 #ifndef HTONS
+01067 #   if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
+01068 #      define HTONS(n) (n)
+01069 #   else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+01070 #      define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
+01071 #   endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+01072 #else
+01073 #error "HTONS already defined!"
+01074 #endif /* HTONS */
+01075 
+01076 /**
+01077  * Convert 16-bit quantity from host byte order to network byte order.
+01078  *
+01079  * This function is primarily used for converting variables from host
+01080  * byte order to network byte order. For converting constants to
+01081  * network byte order, use the HTONS() macro instead.
+01082  */
+01083 #ifndef htons
+01084 u16_t htons(u16_t val);
+01085 #endif /* htons */
+01086 #ifndef ntohs
+01087 #define ntohs htons
+01088 #endif
+01089 
+01090 /** @} */
+01091 
+01092 /**
+01093  * Pointer to the application data in the packet buffer.
+01094  *
+01095  * This pointer points to the application data when the application is
+01096  * called. If the application wishes to send data, the application may
+01097  * use this space to write the data into before calling uip_send().
+01098  */
+01099 extern void *uip_appdata;
+01100 
+01101 #if UIP_URGDATA > 0
+01102 /* u8_t *uip_urgdata:
+01103  *
+01104  * This pointer points to any urgent data that has been received. Only
+01105  * present if compiled with support for urgent data (UIP_URGDATA).
+01106  */
+01107 extern void *uip_urgdata;
+01108 #endif /* UIP_URGDATA > 0 */
+01109 
+01110 
+01111 /**
+01112  * \defgroup uipdrivervars Variables used in uIP device drivers
+01113  * @{
+01114  *
+01115  * uIP has a few global variables that are used in device drivers for
+01116  * uIP.
+01117  */
+01118 
+01119 /**
+01120  * The length of the packet in the uip_buf buffer.
+01121  *
+01122  * The global variable uip_len holds the length of the packet in the
+01123  * uip_buf buffer.
+01124  *
+01125  * When the network device driver calls the uIP input function,
+01126  * uip_len should be set to the length of the packet in the uip_buf
+01127  * buffer.
+01128  *
+01129  * When sending packets, the device driver should use the contents of
+01130  * the uip_len variable to determine the length of the outgoing
+01131  * packet.
+01132  *
+01133  */
+01134 extern u16_t uip_len;
+01135 
+01136 /** @} */
+01137 
+01138 #if UIP_URGDATA > 0
+01139 extern u16_t uip_urglen, uip_surglen;
+01140 #endif /* UIP_URGDATA > 0 */
+01141 
+01142 
+01143 /**
+01144  * Representation of a uIP TCP connection.
+01145  *
+01146  * The uip_conn structure is used for identifying a connection. All
+01147  * but one field in the structure are to be considered read-only by an
+01148  * application. The only exception is the appstate field whos purpose
+01149  * is to let the application store application-specific state (e.g.,
+01150  * file pointers) for the connection. The type of this field is
+01151  * configured in the "uipopt.h" header file.
+01152  */
+01153 struct uip_conn {
+01154   uip_ipaddr_t ripaddr;   /**< The IP address of the remote host. */
+01155   
+01156   u16_t lport;        /**< The local TCP port, in network byte order. */
+01157   u16_t rport;        /**< The local remote TCP port, in network byte
+01158                          order. */
+01159   
+01160   u8_t rcv_nxt[4];    /**< The sequence number that we expect to
+01161                          receive next. */
+01162   u8_t snd_nxt[4];    /**< The sequence number that was last sent by
+01163                          us. */
+01164   u16_t len;          /**< Length of the data that was previously sent. */
+01165   u16_t mss;          /**< Current maximum segment size for the
+01166                          connection. */
+01167   u16_t initialmss;   /**< Initial maximum segment size for the
+01168                          connection. */
+01169   u8_t sa;            /**< Retransmission time-out calculation state
+01170                          variable. */
+01171   u8_t sv;            /**< Retransmission time-out calculation state
+01172                          variable. */
+01173   u8_t rto;           /**< Retransmission time-out. */
+01174   u8_t tcpstateflags; /**< TCP state and flags. */
+01175   u8_t timer;         /**< The retransmission timer. */
+01176   u8_t nrtx;          /**< The number of retransmissions for the last
+01177                          segment sent. */
+01178 
+01179   /** The application state. */
+01180   uip_tcp_appstate_t appstate;
+01181 };
+01182 
+01183 
+01184 /**
+01185  * Pointer to the current TCP connection.
+01186  *
+01187  * The uip_conn pointer can be used to access the current TCP
+01188  * connection.
+01189  */
+01190 extern struct uip_conn *uip_conn;
+01191 /* The array containing all uIP connections. */
+01192 extern struct uip_conn uip_conns[UIP_CONNS];
+01193 /**
+01194  * \addtogroup uiparch
+01195  * @{
+01196  */
+01197 
+01198 /**
+01199  * 4-byte array used for the 32-bit sequence number calculations.
+01200  */
+01201 extern u8_t uip_acc32[4];
+01202 
+01203 /** @} */
+01204 
+01205 
+01206 #if UIP_UDP
+01207 /**
+01208  * Representation of a uIP UDP connection.
+01209  */
+01210 struct uip_udp_conn {
+01211   uip_ipaddr_t ripaddr;   /**< The IP address of the remote peer. */
+01212   u16_t lport;        /**< The local port number in network byte order. */
+01213   u16_t rport;        /**< The remote port number in network byte order. */
+01214   u8_t  ttl;          /**< Default time-to-live. */
+01215 
+01216   /** The application state. */
+01217   uip_udp_appstate_t appstate;
+01218 };
+01219 
+01220 /**
+01221  * The current UDP connection.
+01222  */
+01223 extern struct uip_udp_conn *uip_udp_conn;
+01224 extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
+01225 #endif /* UIP_UDP */
+01226 
+01227 /**
+01228  * The structure holding the TCP/IP statistics that are gathered if
+01229  * UIP_STATISTICS is set to 1.
+01230  *
+01231  */
+01232 struct uip_stats {
+01233   struct {
+01234     uip_stats_t drop;     /**< Number of dropped packets at the IP
+01235                              layer. */
+01236     uip_stats_t recv;     /**< Number of received packets at the IP
+01237                              layer. */
+01238     uip_stats_t sent;     /**< Number of sent packets at the IP
+01239                              layer. */
+01240     uip_stats_t vhlerr;   /**< Number of packets dropped due to wrong
+01241                              IP version or header length. */
+01242     uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
+01243                              IP length, high byte. */
+01244     uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
+01245                              IP length, low byte. */
+01246     uip_stats_t fragerr;  /**< Number of packets dropped since they
+01247                              were IP fragments. */
+01248     uip_stats_t chkerr;   /**< Number of packets dropped due to IP
+01249                              checksum errors. */
+01250     uip_stats_t protoerr; /**< Number of packets dropped since they
+01251                              were neither ICMP, UDP nor TCP. */
+01252   } ip;                   /**< IP statistics. */
+01253   struct {
+01254     uip_stats_t drop;     /**< Number of dropped ICMP packets. */
+01255     uip_stats_t recv;     /**< Number of received ICMP packets. */
+01256     uip_stats_t sent;     /**< Number of sent ICMP packets. */
+01257     uip_stats_t typeerr;  /**< Number of ICMP packets with a wrong
+01258                              type. */
+01259   } icmp;                 /**< ICMP statistics. */
+01260   struct {
+01261     uip_stats_t drop;     /**< Number of dropped TCP segments. */
+01262     uip_stats_t recv;     /**< Number of recived TCP segments. */
+01263     uip_stats_t sent;     /**< Number of sent TCP segments. */
+01264     uip_stats_t chkerr;   /**< Number of TCP segments with a bad
+01265                              checksum. */
+01266     uip_stats_t ackerr;   /**< Number of TCP segments with a bad ACK
+01267                              number. */
+01268     uip_stats_t rst;      /**< Number of recevied TCP RST (reset) segments. */
+01269     uip_stats_t rexmit;   /**< Number of retransmitted TCP segments. */
+01270     uip_stats_t syndrop;  /**< Number of dropped SYNs due to too few
+01271                              connections was avaliable. */
+01272     uip_stats_t synrst;   /**< Number of SYNs for closed ports,
+01273                              triggering a RST. */
+01274   } tcp;                  /**< TCP statistics. */
+01275 #if UIP_UDP
+01276   struct {
+01277     uip_stats_t drop;     /**< Number of dropped UDP segments. */
+01278     uip_stats_t recv;     /**< Number of recived UDP segments. */
+01279     uip_stats_t sent;     /**< Number of sent UDP segments. */
+01280     uip_stats_t chkerr;   /**< Number of UDP segments with a bad
+01281                              checksum. */
+01282   } udp;                  /**< UDP statistics. */
+01283 #endif /* UIP_UDP */
+01284 };
+01285 
+01286 /**
+01287  * The uIP TCP/IP statistics.
+01288  *
+01289  * This is the variable in which the uIP TCP/IP statistics are gathered.
+01290  */
+01291 extern struct uip_stats uip_stat;
+01292 
+01293 
+01294 /*---------------------------------------------------------------------------*/
+01295 /* All the stuff below this point is internal to uIP and should not be
+01296  * used directly by an application or by a device driver.
+01297  */
+01298 /*---------------------------------------------------------------------------*/
+01299 /* u8_t uip_flags:
+01300  *
+01301  * When the application is called, uip_flags will contain the flags
+01302  * that are defined in this file. Please read below for more
+01303  * infomation.
+01304  */
+01305 extern u8_t uip_flags;
+01306 
+01307 /* The following flags may be set in the global variable uip_flags
+01308    before calling the application callback. The UIP_ACKDATA,
+01309    UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time,
+01310    whereas the others are mutualy exclusive. Note that these flags
+01311    should *NOT* be accessed directly, but only through the uIP
+01312    functions/macros. */
+01313 
+01314 #define UIP_ACKDATA   1     /* Signifies that the outstanding data was
+01315                                acked and the application should send
+01316                                out new data instead of retransmitting
+01317                                the last data. */
+01318 #define UIP_NEWDATA   2     /* Flags the fact that the peer has sent
+01319                                us new data. */
+01320 #define UIP_REXMIT    4     /* Tells the application to retransmit the
+01321                                data that was last sent. */
+01322 #define UIP_POLL      8     /* Used for polling the application, to
+01323                                check if the application has data that
+01324                                it wants to send. */
+01325 #define UIP_CLOSE     16    /* The remote host has closed the
+01326                                connection, thus the connection has
+01327                                gone away. Or the application signals
+01328                                that it wants to close the
+01329                                connection. */
+01330 #define UIP_ABORT     32    /* The remote host has aborted the
+01331                                connection, thus the connection has
+01332                                gone away. Or the application signals
+01333                                that it wants to abort the
+01334                                connection. */
+01335 #define UIP_CONNECTED 64    /* We have got a connection from a remote
+01336                                host and have set up a new connection
+01337                                for it, or an active connection has
+01338                                been successfully established. */
+01339 
+01340 #define UIP_TIMEDOUT  128   /* The connection has been aborted due to
+01341                                too many retransmissions. */
+01342 
+01343 /* uip_process(flag):
+01344  *
+01345  * The actual uIP function which does all the work.
+01346  */
+01347 void uip_process(u8_t flag);
+01348 
+01349 /* The following flags are passed as an argument to the uip_process()
+01350    function. They are used to distinguish between the two cases where
+01351    uip_process() is called. It can be called either because we have
+01352    incoming data that should be processed, or because the periodic
+01353    timer has fired. These values are never used directly, but only in
+01354    the macrose defined in this file. */
+01355  
+01356 #define UIP_DATA          1     /* Tells uIP that there is incoming
+01357                                    data in the uip_buf buffer. The
+01358                                    length of the data is stored in the
+01359                                    global variable uip_len. */
+01360 #define UIP_TIMER         2     /* Tells uIP that the periodic timer
+01361                                    has fired. */
+01362 #define UIP_POLL_REQUEST  3     /* Tells uIP that a connection should
+01363                                    be polled. */
+01364 #define UIP_UDP_SEND_CONN 4     /* Tells uIP that a UDP datagram
+01365                                    should be constructed in the
+01366                                    uip_buf buffer. */
+01367 #if UIP_UDP
+01368 #define UIP_UDP_TIMER     5
+01369 #endif /* UIP_UDP */
+01370 
+01371 /* The TCP states used in the uip_conn->tcpstateflags. */
+01372 #define UIP_CLOSED      0
+01373 #define UIP_SYN_RCVD    1
+01374 #define UIP_SYN_SENT    2
+01375 #define UIP_ESTABLISHED 3
+01376 #define UIP_FIN_WAIT_1  4
+01377 #define UIP_FIN_WAIT_2  5
+01378 #define UIP_CLOSING     6
+01379 #define UIP_TIME_WAIT   7
+01380 #define UIP_LAST_ACK    8
+01381 #define UIP_TS_MASK     15
+01382   
+01383 #define UIP_STOPPED      16
+01384 
+01385 /* The TCP and IP headers. */
+01386 struct uip_tcpip_hdr {
+01387 #if UIP_CONF_IPV6
+01388   /* IPv6 header. */
+01389   u8_t vtc,
+01390     tcflow;
+01391   u16_t flow;
+01392   u8_t len[2];
+01393   u8_t proto, ttl;
+01394   uip_ip6addr_t srcipaddr, destipaddr;
+01395 #else /* UIP_CONF_IPV6 */
+01396   /* IPv4 header. */
+01397   u8_t vhl,
+01398     tos,
+01399     len[2],
+01400     ipid[2],
+01401     ipoffset[2],
+01402     ttl,
+01403     proto;
+01404   u16_t ipchksum;
+01405   u16_t srcipaddr[2],
+01406     destipaddr[2];
+01407 #endif /* UIP_CONF_IPV6 */
+01408   
+01409   /* TCP header. */
+01410   u16_t srcport,
+01411     destport;
+01412   u8_t seqno[4],
+01413     ackno[4],
+01414     tcpoffset,
+01415     flags,
+01416     wnd[2];
+01417   u16_t tcpchksum;
+01418   u8_t urgp[2];
+01419   u8_t optdata[4];
+01420 };
+01421 
+01422 /* The ICMP and IP headers. */
+01423 struct uip_icmpip_hdr {
+01424 #if UIP_CONF_IPV6
+01425   /* IPv6 header. */
+01426   u8_t vtc,
+01427     tcf;
+01428   u16_t flow;
+01429   u8_t len[2];
+01430   u8_t proto, ttl;
+01431   uip_ip6addr_t srcipaddr, destipaddr;
+01432 #else /* UIP_CONF_IPV6 */
+01433   /* IPv4 header. */
+01434   u8_t vhl,
+01435     tos,
+01436     len[2],
+01437     ipid[2],
+01438     ipoffset[2],
+01439     ttl,
+01440     proto;
+01441   u16_t ipchksum;
+01442   u16_t srcipaddr[2],
+01443     destipaddr[2];
+01444 #endif /* UIP_CONF_IPV6 */
+01445   
+01446   /* ICMP (echo) header. */
+01447   u8_t type, icode;
+01448   u16_t icmpchksum;
+01449 #if !UIP_CONF_IPV6
+01450   u16_t id, seqno;
+01451 #else /* !UIP_CONF_IPV6 */
+01452   u8_t flags, reserved1, reserved2, reserved3;
+01453   u8_t icmp6data[16];
+01454   u8_t options[1];
+01455 #endif /* !UIP_CONF_IPV6 */
+01456 };
+01457 
+01458 
+01459 /* The UDP and IP headers. */
+01460 struct uip_udpip_hdr {
+01461 #if UIP_CONF_IPV6
+01462   /* IPv6 header. */
+01463   u8_t vtc,
+01464     tcf;
+01465   u16_t flow;
+01466   u8_t len[2];
+01467   u8_t proto, ttl;
+01468   uip_ip6addr_t srcipaddr, destipaddr;
+01469 #else /* UIP_CONF_IPV6 */
+01470   /* IP header. */
+01471   u8_t vhl,
+01472     tos,
+01473     len[2],
+01474     ipid[2],
+01475     ipoffset[2],
+01476     ttl,
+01477     proto;
+01478   u16_t ipchksum;
+01479   u16_t srcipaddr[2],
+01480     destipaddr[2];
+01481 #endif /* UIP_CONF_IPV6 */
+01482   
+01483   /* UDP header. */
+01484   u16_t srcport,
+01485     destport;
+01486   u16_t udplen;
+01487   u16_t udpchksum;
+01488 };
+01489 
+01490 
+01491 
+01492 /**
+01493  * The buffer size available for user data in the \ref uip_buf buffer.
+01494  *
+01495  * This macro holds the available size for user data in the \ref
+01496  * uip_buf buffer. The macro is intended to be used for checking
+01497  * bounds of available user data.
+01498  *
+01499  * Example:
+01500  \code
+01501  snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
+01502  \endcode
+01503  *
+01504  * \hideinitializer
+01505  */
+01506 #define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
+01507 
+01508 
+01509 #define UIP_PROTO_ICMP  1
+01510 #define UIP_PROTO_TCP   6
+01511 #define UIP_PROTO_UDP   17
+01512 #define UIP_PROTO_ICMP6 58
+01513 
+01514 /* Header sizes. */
+01515 #if UIP_CONF_IPV6
+01516 #define UIP_IPH_LEN    40
+01517 #else /* UIP_CONF_IPV6 */
+01518 #define UIP_IPH_LEN    20    /* Size of IP header */
+01519 #endif /* UIP_CONF_IPV6 */
+01520 #define UIP_UDPH_LEN    8    /* Size of UDP header */
+01521 #define UIP_TCPH_LEN   20    /* Size of TCP header */
+01522 #define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN)    /* Size of IP +
+01523                                                           UDP
+01524                                                           header */
+01525 #define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN)    /* Size of IP +
+01526                                                           TCP
+01527                                                           header */
+01528 #define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
+01529 
+01530 
+01531 #if UIP_FIXEDADDR
+01532 extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+01533 #else /* UIP_FIXEDADDR */
+01534 extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+01535 #endif /* UIP_FIXEDADDR */
+01536 
+01537 
+01538 
+01539 /**
+01540  * Representation of a 48-bit Ethernet address.
+01541  */
+01542 struct uip_eth_addr {
+01543   u8_t addr[6];
+01544 };
+01545 
+01546 /**
+01547  * Calculate the Internet checksum over a buffer.
+01548  *
+01549  * The Internet checksum is the one's complement of the one's
+01550  * complement sum of all 16-bit words in the buffer.
+01551  *
+01552  * See RFC1071.
+01553  *
+01554  * \param buf A pointer to the buffer over which the checksum is to be
+01555  * computed.
+01556  *
+01557  * \param len The length of the buffer over which the checksum is to
+01558  * be computed.
+01559  *
+01560  * \return The Internet checksum of the buffer.
+01561  */
+01562 u16_t uip_chksum(u16_t *buf, u16_t len);
+01563 
+01564 /**
+01565  * Calculate the IP header checksum of the packet header in uip_buf.
+01566  *
+01567  * The IP header checksum is the Internet checksum of the 20 bytes of
+01568  * the IP header.
+01569  *
+01570  * \return The IP header checksum of the IP header in the uip_buf
+01571  * buffer.
+01572  */
+01573 u16_t uip_ipchksum(void);
+01574 
+01575 /**
+01576  * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
+01577  *
+01578  * The TCP checksum is the Internet checksum of data contents of the
+01579  * TCP segment, and a pseudo-header as defined in RFC793.
+01580  *
+01581  * \return The TCP checksum of the TCP segment in uip_buf and pointed
+01582  * to by uip_appdata.
+01583  */
+01584 u16_t uip_tcpchksum(void);
+01585 
+01586 /**
+01587  * Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
+01588  *
+01589  * The UDP checksum is the Internet checksum of data contents of the
+01590  * UDP segment, and a pseudo-header as defined in RFC768.
+01591  *
+01592  * \return The UDP checksum of the UDP segment in uip_buf and pointed
+01593  * to by uip_appdata.
+01594  */
+01595 u16_t uip_udpchksum(void);
+01596 
+01597 
+01598 #endif /* __UIP_H__ */
+01599 
+01600 
+01601 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00203.html b/doc/html/a00203.html new file mode 100644 index 0000000..acdd37f --- /dev/null +++ b/doc/html/a00203.html @@ -0,0 +1,163 @@ + + +uIP 1.0: uip/uip_arch.h Source File + + + + + + +

uip/uip_arch.h

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup uip
+00003  * {@
+00004  */
+00005 
+00006 /**
+00007  * \defgroup uiparch Architecture specific uIP functions
+00008  * @{
+00009  *
+00010  * The functions in the architecture specific module implement the IP
+00011  * check sum and 32-bit additions.
+00012  *
+00013  * The IP checksum calculation is the most computationally expensive
+00014  * operation in the TCP/IP stack and it therefore pays off to
+00015  * implement this in efficient assembler. The purpose of the uip-arch
+00016  * module is to let the checksum functions to be implemented in
+00017  * architecture specific assembler.
+00018  *
+00019  */
+00020 
+00021 /**
+00022  * \file
+00023  * Declarations of architecture specific functions.
+00024  * \author Adam Dunkels <adam@dunkels.com>
+00025  */
+00026 
+00027 /*
+00028  * Copyright (c) 2001, Adam Dunkels.
+00029  * All rights reserved.
+00030  *
+00031  * Redistribution and use in source and binary forms, with or without
+00032  * modification, are permitted provided that the following conditions
+00033  * are met:
+00034  * 1. Redistributions of source code must retain the above copyright
+00035  *    notice, this list of conditions and the following disclaimer.
+00036  * 2. Redistributions in binary form must reproduce the above copyright
+00037  *    notice, this list of conditions and the following disclaimer in the
+00038  *    documentation and/or other materials provided with the distribution.
+00039  * 3. The name of the author may not be used to endorse or promote
+00040  *    products derived from this software without specific prior
+00041  *    written permission.
+00042  *
+00043  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00044  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00045  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00046  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00047  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00048  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00049  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00050  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00051  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00052  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00053  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00054  *
+00055  * This file is part of the uIP TCP/IP stack.
+00056  *
+00057  * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $
+00058  *
+00059  */
+00060 
+00061 #ifndef __UIP_ARCH_H__
+00062 #define __UIP_ARCH_H__
+00063 
+00064 #include "uip.h"
+00065 
+00066 /**
+00067  * Carry out a 32-bit addition.
+00068  *
+00069  * Because not all architectures for which uIP is intended has native
+00070  * 32-bit arithmetic, uIP uses an external C function for doing the
+00071  * required 32-bit additions in the TCP protocol processing. This
+00072  * function should add the two arguments and place the result in the
+00073  * global variable uip_acc32.
+00074  *
+00075  * \note The 32-bit integer pointed to by the op32 parameter and the
+00076  * result in the uip_acc32 variable are in network byte order (big
+00077  * endian).
+00078  *
+00079  * \param op32 A pointer to a 4-byte array representing a 32-bit
+00080  * integer in network byte order (big endian).
+00081  *
+00082  * \param op16 A 16-bit integer in host byte order.
+00083  */
+00084 void uip_add32(u8_t *op32, u16_t op16);
+00085 
+00086 /**
+00087  * Calculate the Internet checksum over a buffer.
+00088  *
+00089  * The Internet checksum is the one's complement of the one's
+00090  * complement sum of all 16-bit words in the buffer.
+00091  *
+00092  * See RFC1071.
+00093  *
+00094  * \note This function is not called in the current version of uIP,
+00095  * but future versions might make use of it.
+00096  *
+00097  * \param buf A pointer to the buffer over which the checksum is to be
+00098  * computed.
+00099  *
+00100  * \param len The length of the buffer over which the checksum is to
+00101  * be computed.
+00102  *
+00103  * \return The Internet checksum of the buffer.
+00104  */
+00105 u16_t uip_chksum(u16_t *buf, u16_t len);
+00106 
+00107 /**
+00108  * Calculate the IP header checksum of the packet header in uip_buf.
+00109  *
+00110  * The IP header checksum is the Internet checksum of the 20 bytes of
+00111  * the IP header.
+00112  *
+00113  * \return The IP header checksum of the IP header in the uip_buf
+00114  * buffer.
+00115  */
+00116 u16_t uip_ipchksum(void);
+00117 
+00118 /**
+00119  * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
+00120  *
+00121  * The TCP checksum is the Internet checksum of data contents of the
+00122  * TCP segment, and a pseudo-header as defined in RFC793.
+00123  *
+00124  * \note The uip_appdata pointer that points to the packet data may
+00125  * point anywhere in memory, so it is not possible to simply calculate
+00126  * the Internet checksum of the contents of the uip_buf buffer.
+00127  *
+00128  * \return The TCP checksum of the TCP segment in uip_buf and pointed
+00129  * to by uip_appdata.
+00130  */
+00131 u16_t uip_tcpchksum(void);
+00132 
+00133 u16_t uip_udpchksum(void);
+00134 
+00135 /** @} */
+00136 /** @} */
+00137 
+00138 #endif /* __UIP_ARCH_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00204.html b/doc/html/a00204.html new file mode 100644 index 0000000..def45e9 --- /dev/null +++ b/doc/html/a00204.html @@ -0,0 +1,448 @@ + + +uIP 1.0: uip/uip_arp.c Source File + + + + + + +

uip/uip_arp.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup uip
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup uiparp uIP Address Resolution Protocol
+00008  * @{
+00009  *
+00010  * The Address Resolution Protocol ARP is used for mapping between IP
+00011  * addresses and link level addresses such as the Ethernet MAC
+00012  * addresses. ARP uses broadcast queries to ask for the link level
+00013  * address of a known IP address and the host which is configured with
+00014  * the IP address for which the query was meant, will respond with its
+00015  * link level address.
+00016  *
+00017  * \note This ARP implementation only supports Ethernet.
+00018  */
+00019  
+00020 /**
+00021  * \file
+00022  * Implementation of the ARP Address Resolution Protocol.
+00023  * \author Adam Dunkels <adam@dunkels.com>
+00024  *
+00025  */
+00026 
+00027 /*
+00028  * Copyright (c) 2001-2003, Adam Dunkels.
+00029  * All rights reserved.
+00030  *
+00031  * Redistribution and use in source and binary forms, with or without
+00032  * modification, are permitted provided that the following conditions
+00033  * are met:
+00034  * 1. Redistributions of source code must retain the above copyright
+00035  *    notice, this list of conditions and the following disclaimer.
+00036  * 2. Redistributions in binary form must reproduce the above copyright
+00037  *    notice, this list of conditions and the following disclaimer in the
+00038  *    documentation and/or other materials provided with the distribution.
+00039  * 3. The name of the author may not be used to endorse or promote
+00040  *    products derived from this software without specific prior
+00041  *    written permission.
+00042  *
+00043  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00044  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00045  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00046  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00047  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00048  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00049  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00050  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00051  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00052  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00053  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00054  *
+00055  * This file is part of the uIP TCP/IP stack.
+00056  *
+00057  * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $
+00058  *
+00059  */
+00060 
+00061 
+00062 #include "uip_arp.h"
+00063 
+00064 #include <string.h>
+00065 
+00066 struct arp_hdr {
+00067   struct uip_eth_hdr ethhdr;
+00068   u16_t hwtype;
+00069   u16_t protocol;
+00070   u8_t hwlen;
+00071   u8_t protolen;
+00072   u16_t opcode;
+00073   struct uip_eth_addr shwaddr;
+00074   u16_t sipaddr[2];
+00075   struct uip_eth_addr dhwaddr;
+00076   u16_t dipaddr[2];
+00077 };
+00078 
+00079 struct ethip_hdr {
+00080   struct uip_eth_hdr ethhdr;
+00081   /* IP header. */
+00082   u8_t vhl,
+00083     tos,
+00084     len[2],
+00085     ipid[2],
+00086     ipoffset[2],
+00087     ttl,
+00088     proto;
+00089   u16_t ipchksum;
+00090   u16_t srcipaddr[2],
+00091     destipaddr[2];
+00092 };
+00093 
+00094 #define ARP_REQUEST 1
+00095 #define ARP_REPLY   2
+00096 
+00097 #define ARP_HWTYPE_ETH 1
+00098 
+00099 struct arp_entry {
+00100   u16_t ipaddr[2];
+00101   struct uip_eth_addr ethaddr;
+00102   u8_t time;
+00103 };
+00104 
+00105 static const struct uip_eth_addr broadcast_ethaddr =
+00106   {{0xff,0xff,0xff,0xff,0xff,0xff}};
+00107 static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
+00108 
+00109 static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
+00110 static u16_t ipaddr[2];
+00111 static u8_t i, c;
+00112 
+00113 static u8_t arptime;
+00114 static u8_t tmpage;
+00115 
+00116 #define BUF   ((struct arp_hdr *)&uip_buf[0])
+00117 #define IPBUF ((struct ethip_hdr *)&uip_buf[0])
+00118 /*-----------------------------------------------------------------------------------*/
+00119 /**
+00120  * Initialize the ARP module.
+00121  *
+00122  */
+00123 /*-----------------------------------------------------------------------------------*/
+00124 void
+00125 uip_arp_init(void)
+00126 {
+00127   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00128     memset(arp_table[i].ipaddr, 0, 4);
+00129   }
+00130 }
+00131 /*-----------------------------------------------------------------------------------*/
+00132 /**
+00133  * Periodic ARP processing function.
+00134  *
+00135  * This function performs periodic timer processing in the ARP module
+00136  * and should be called at regular intervals. The recommended interval
+00137  * is 10 seconds between the calls.
+00138  *
+00139  */
+00140 /*-----------------------------------------------------------------------------------*/
+00141 void
+00142 uip_arp_timer(void)
+00143 {
+00144   struct arp_entry *tabptr;
+00145   
+00146   ++arptime;
+00147   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00148     tabptr = &arp_table[i];
+00149     if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
+00150        arptime - tabptr->time >= UIP_ARP_MAXAGE) {
+00151       memset(tabptr->ipaddr, 0, 4);
+00152     }
+00153   }
+00154 
+00155 }
+00156 /*-----------------------------------------------------------------------------------*/
+00157 static void
+00158 uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
+00159 {
+00160   register struct arp_entry *tabptr;
+00161   /* Walk through the ARP mapping table and try to find an entry to
+00162      update. If none is found, the IP -> MAC address mapping is
+00163      inserted in the ARP table. */
+00164   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00165 
+00166     tabptr = &arp_table[i];
+00167     /* Only check those entries that are actually in use. */
+00168     if(tabptr->ipaddr[0] != 0 &&
+00169        tabptr->ipaddr[1] != 0) {
+00170 
+00171       /* Check if the source IP address of the incoming packet matches
+00172          the IP address in this ARP table entry. */
+00173       if(ipaddr[0] == tabptr->ipaddr[0] &&
+00174          ipaddr[1] == tabptr->ipaddr[1]) {
+00175          
+00176         /* An old entry found, update this and return. */
+00177         memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
+00178         tabptr->time = arptime;
+00179 
+00180         return;
+00181       }
+00182     }
+00183   }
+00184 
+00185   /* If we get here, no existing ARP table entry was found, so we
+00186      create one. */
+00187 
+00188   /* First, we try to find an unused entry in the ARP table. */
+00189   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00190     tabptr = &arp_table[i];
+00191     if(tabptr->ipaddr[0] == 0 &&
+00192        tabptr->ipaddr[1] == 0) {
+00193       break;
+00194     }
+00195   }
+00196 
+00197   /* If no unused entry is found, we try to find the oldest entry and
+00198      throw it away. */
+00199   if(i == UIP_ARPTAB_SIZE) {
+00200     tmpage = 0;
+00201     c = 0;
+00202     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00203       tabptr = &arp_table[i];
+00204       if(arptime - tabptr->time > tmpage) {
+00205         tmpage = arptime - tabptr->time;
+00206         c = i;
+00207       }
+00208     }
+00209     i = c;
+00210     tabptr = &arp_table[i];
+00211   }
+00212 
+00213   /* Now, i is the ARP table entry which we will fill with the new
+00214      information. */
+00215   memcpy(tabptr->ipaddr, ipaddr, 4);
+00216   memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
+00217   tabptr->time = arptime;
+00218 }
+00219 /*-----------------------------------------------------------------------------------*/
+00220 /**
+00221  * ARP processing for incoming IP packets
+00222  *
+00223  * This function should be called by the device driver when an IP
+00224  * packet has been received. The function will check if the address is
+00225  * in the ARP cache, and if so the ARP cache entry will be
+00226  * refreshed. If no ARP cache entry was found, a new one is created.
+00227  *
+00228  * This function expects an IP packet with a prepended Ethernet header
+00229  * in the uip_buf[] buffer, and the length of the packet in the global
+00230  * variable uip_len.
+00231  */
+00232 /*-----------------------------------------------------------------------------------*/
+00233 #if 0
+00234 void
+00235 uip_arp_ipin(void)
+00236 {
+00237   uip_len -= sizeof(struct uip_eth_hdr);
+00238         
+00239   /* Only insert/update an entry if the source IP address of the
+00240      incoming IP packet comes from a host on the local network. */
+00241   if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
+00242      (uip_hostaddr[0] & uip_netmask[0])) {
+00243     return;
+00244   }
+00245   if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
+00246      (uip_hostaddr[1] & uip_netmask[1])) {
+00247     return;
+00248   }
+00249   uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
+00250   
+00251   return;
+00252 }
+00253 #endif /* 0 */
+00254 /*-----------------------------------------------------------------------------------*/
+00255 /**
+00256  * ARP processing for incoming ARP packets.
+00257  *
+00258  * This function should be called by the device driver when an ARP
+00259  * packet has been received. The function will act differently
+00260  * depending on the ARP packet type: if it is a reply for a request
+00261  * that we previously sent out, the ARP cache will be filled in with
+00262  * the values from the ARP reply. If the incoming ARP packet is an ARP
+00263  * request for our IP address, an ARP reply packet is created and put
+00264  * into the uip_buf[] buffer.
+00265  *
+00266  * When the function returns, the value of the global variable uip_len
+00267  * indicates whether the device driver should send out a packet or
+00268  * not. If uip_len is zero, no packet should be sent. If uip_len is
+00269  * non-zero, it contains the length of the outbound packet that is
+00270  * present in the uip_buf[] buffer.
+00271  *
+00272  * This function expects an ARP packet with a prepended Ethernet
+00273  * header in the uip_buf[] buffer, and the length of the packet in the
+00274  * global variable uip_len.
+00275  */
+00276 /*-----------------------------------------------------------------------------------*/
+00277 void
+00278 uip_arp_arpin(void)
+00279 {
+00280   
+00281   if(uip_len < sizeof(struct arp_hdr)) {
+00282     uip_len = 0;
+00283     return;
+00284   }
+00285   uip_len = 0;
+00286   
+00287   switch(BUF->opcode) {
+00288   case HTONS(ARP_REQUEST):
+00289     /* ARP request. If it asked for our address, we send out a
+00290        reply. */
+00291     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+00292       /* First, we register the one who made the request in our ARP
+00293          table, since it is likely that we will do more communication
+00294          with this host in the future. */
+00295       uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+00296       
+00297       /* The reply opcode is 2. */
+00298       BUF->opcode = HTONS(2);
+00299 
+00300       memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
+00301       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+00302       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+00303       memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
+00304       
+00305       BUF->dipaddr[0] = BUF->sipaddr[0];
+00306       BUF->dipaddr[1] = BUF->sipaddr[1];
+00307       BUF->sipaddr[0] = uip_hostaddr[0];
+00308       BUF->sipaddr[1] = uip_hostaddr[1];
+00309 
+00310       BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+00311       uip_len = sizeof(struct arp_hdr);
+00312     }
+00313     break;
+00314   case HTONS(ARP_REPLY):
+00315     /* ARP reply. We insert or update the ARP table if it was meant
+00316        for us. */
+00317     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+00318       uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+00319     }
+00320     break;
+00321   }
+00322 
+00323   return;
+00324 }
+00325 /*-----------------------------------------------------------------------------------*/
+00326 /**
+00327  * Prepend Ethernet header to an outbound IP packet and see if we need
+00328  * to send out an ARP request.
+00329  *
+00330  * This function should be called before sending out an IP packet. The
+00331  * function checks the destination IP address of the IP packet to see
+00332  * what Ethernet MAC address that should be used as a destination MAC
+00333  * address on the Ethernet.
+00334  *
+00335  * If the destination IP address is in the local network (determined
+00336  * by logical ANDing of netmask and our IP address), the function
+00337  * checks the ARP cache to see if an entry for the destination IP
+00338  * address is found. If so, an Ethernet header is prepended and the
+00339  * function returns. If no ARP cache entry is found for the
+00340  * destination IP address, the packet in the uip_buf[] is replaced by
+00341  * an ARP request packet for the IP address. The IP packet is dropped
+00342  * and it is assumed that they higher level protocols (e.g., TCP)
+00343  * eventually will retransmit the dropped packet.
+00344  *
+00345  * If the destination IP address is not on the local network, the IP
+00346  * address of the default router is used instead.
+00347  *
+00348  * When the function returns, a packet is present in the uip_buf[]
+00349  * buffer, and the length of the packet is in the global variable
+00350  * uip_len.
+00351  */
+00352 /*-----------------------------------------------------------------------------------*/
+00353 void
+00354 uip_arp_out(void)
+00355 {
+00356   struct arp_entry *tabptr;
+00357   
+00358   /* Find the destination IP address in the ARP table and construct
+00359      the Ethernet header. If the destination IP addres isn't on the
+00360      local network, we use the default router's IP address instead.
+00361 
+00362      If not ARP table entry is found, we overwrite the original IP
+00363      packet with an ARP request for the IP address. */
+00364 
+00365   /* First check if destination is a local broadcast. */
+00366   if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
+00367     memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
+00368   } else {
+00369     /* Check if the destination address is on the local network. */
+00370     if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
+00371       /* Destination address was not on the local network, so we need to
+00372          use the default router's IP address instead of the destination
+00373          address when determining the MAC address. */
+00374       uip_ipaddr_copy(ipaddr, uip_draddr);
+00375     } else {
+00376       /* Else, we use the destination IP address. */
+00377       uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
+00378     }
+00379       
+00380     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00381       tabptr = &arp_table[i];
+00382       if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
+00383         break;
+00384       }
+00385     }
+00386 
+00387     if(i == UIP_ARPTAB_SIZE) {
+00388       /* The destination address was not in our ARP table, so we
+00389          overwrite the IP packet with an ARP request. */
+00390 
+00391       memset(BUF->ethhdr.dest.addr, 0xff, 6);
+00392       memset(BUF->dhwaddr.addr, 0x00, 6);
+00393       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+00394       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+00395     
+00396       uip_ipaddr_copy(BUF->dipaddr, ipaddr);
+00397       uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
+00398       BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
+00399       BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
+00400       BUF->protocol = HTONS(UIP_ETHTYPE_IP);
+00401       BUF->hwlen = 6;
+00402       BUF->protolen = 4;
+00403       BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+00404 
+00405       uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
+00406     
+00407       uip_len = sizeof(struct arp_hdr);
+00408       return;
+00409     }
+00410 
+00411     /* Build an ethernet header. */
+00412     memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
+00413   }
+00414   memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+00415   
+00416   IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
+00417 
+00418   uip_len += sizeof(struct uip_eth_hdr);
+00419 }
+00420 /*-----------------------------------------------------------------------------------*/
+00421 
+00422 /** @} */
+00423 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00205.html b/doc/html/a00205.html new file mode 100644 index 0000000..9d4feea --- /dev/null +++ b/doc/html/a00205.html @@ -0,0 +1,169 @@ + + +uIP 1.0: uip/uip_arp.h Source File + + + + + + +

uip/uip_arp.h

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup uip
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \addtogroup uiparp
+00008  * @{
+00009  */
+00010  
+00011 /**
+00012  * \file
+00013  * Macros and definitions for the ARP module.
+00014  * \author Adam Dunkels <adam@dunkels.com>
+00015  */
+00016   
+00017 
+00018 /*
+00019  * Copyright (c) 2001-2003, Adam Dunkels.
+00020  * All rights reserved.
+00021  *
+00022  * Redistribution and use in source and binary forms, with or without
+00023  * modification, are permitted provided that the following conditions
+00024  * are met:
+00025  * 1. Redistributions of source code must retain the above copyright
+00026  *    notice, this list of conditions and the following disclaimer.
+00027  * 2. Redistributions in binary form must reproduce the above copyright
+00028  *    notice, this list of conditions and the following disclaimer in the
+00029  *    documentation and/or other materials provided with the distribution.
+00030  * 3. The name of the author may not be used to endorse or promote
+00031  *    products derived from this software without specific prior
+00032  *    written permission.
+00033  *
+00034  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00035  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00036  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00037  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00038  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00039  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00040  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00041  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00042  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00043  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00044  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00045  *
+00046  * This file is part of the uIP TCP/IP stack.
+00047  *
+00048  * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $
+00049  *
+00050  */
+00051 
+00052 #ifndef __UIP_ARP_H__
+00053 #define __UIP_ARP_H__
+00054 
+00055 #include "uip.h"
+00056 
+00057 
+00058 extern struct uip_eth_addr uip_ethaddr;
+00059 
+00060 /**
+00061  * The Ethernet header.
+00062  */
+00063 struct uip_eth_hdr {
+00064   struct uip_eth_addr dest;
+00065   struct uip_eth_addr src;
+00066   u16_t type;
+00067 };
+00068 
+00069 #define UIP_ETHTYPE_ARP 0x0806
+00070 #define UIP_ETHTYPE_IP  0x0800
+00071 #define UIP_ETHTYPE_IP6 0x86dd
+00072 
+00073 
+00074 /* The uip_arp_init() function must be called before any of the other
+00075    ARP functions. */
+00076 void uip_arp_init(void);
+00077 
+00078 /* The uip_arp_ipin() function should be called whenever an IP packet
+00079    arrives from the Ethernet. This function refreshes the ARP table or
+00080    inserts a new mapping if none exists. The function assumes that an
+00081    IP packet with an Ethernet header is present in the uip_buf buffer
+00082    and that the length of the packet is in the uip_len variable. */
+00083 /*void uip_arp_ipin(void);*/
+00084 #define uip_arp_ipin()
+00085 
+00086 /* The uip_arp_arpin() should be called when an ARP packet is received
+00087    by the Ethernet driver. This function also assumes that the
+00088    Ethernet frame is present in the uip_buf buffer. When the
+00089    uip_arp_arpin() function returns, the contents of the uip_buf
+00090    buffer should be sent out on the Ethernet if the uip_len variable
+00091    is > 0. */
+00092 void uip_arp_arpin(void);
+00093 
+00094 /* The uip_arp_out() function should be called when an IP packet
+00095    should be sent out on the Ethernet. This function creates an
+00096    Ethernet header before the IP header in the uip_buf buffer. The
+00097    Ethernet header will have the correct Ethernet MAC destination
+00098    address filled in if an ARP table entry for the destination IP
+00099    address (or the IP address of the default router) is present. If no
+00100    such table entry is found, the IP packet is overwritten with an ARP
+00101    request and we rely on TCP to retransmit the packet that was
+00102    overwritten. In any case, the uip_len variable holds the length of
+00103    the Ethernet frame that should be transmitted. */
+00104 void uip_arp_out(void);
+00105 
+00106 /* The uip_arp_timer() function should be called every ten seconds. It
+00107    is responsible for flushing old entries in the ARP table. */
+00108 void uip_arp_timer(void);
+00109 
+00110 /** @} */
+00111 
+00112 /**
+00113  * \addtogroup uipconffunc
+00114  * @{
+00115  */
+00116 
+00117 
+00118 /**
+00119  * Specifiy the Ethernet MAC address.
+00120  *
+00121  * The ARP code needs to know the MAC address of the Ethernet card in
+00122  * order to be able to respond to ARP queries and to generate working
+00123  * Ethernet headers.
+00124  *
+00125  * \note This macro only specifies the Ethernet MAC address to the ARP
+00126  * code. It cannot be used to change the MAC address of the Ethernet
+00127  * card.
+00128  *
+00129  * \param eaddr A pointer to a struct uip_eth_addr containing the
+00130  * Ethernet MAC address of the Ethernet card.
+00131  *
+00132  * \hideinitializer
+00133  */
+00134 #define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
+00135                               uip_ethaddr.addr[1] = eaddr.addr[1];\
+00136                               uip_ethaddr.addr[2] = eaddr.addr[2];\
+00137                               uip_ethaddr.addr[3] = eaddr.addr[3];\
+00138                               uip_ethaddr.addr[4] = eaddr.addr[4];\
+00139                               uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
+00140 
+00141 /** @} */
+00142 /** @} */
+00143 
+00144 #endif /* __UIP_ARP_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00206.html b/doc/html/a00206.html new file mode 100644 index 0000000..3272565 --- /dev/null +++ b/doc/html/a00206.html @@ -0,0 +1,564 @@ + + +uIP 1.0: uip/uipopt.h Source File + + + + + + +

uip/uipopt.h

Go to the documentation of this file.
00001 /**
+00002  * \defgroup uipopt Configuration options for uIP
+00003  * @{
+00004  *
+00005  * uIP is configured using the per-project configuration file
+00006  * uipopt.h. This file contains all compile-time options for uIP and
+00007  * should be tweaked to match each specific project. The uIP
+00008  * distribution contains a documented example "uipopt.h" that can be
+00009  * copied and modified for each project.
+00010  *
+00011  * \note Most of the configuration options in the uipopt.h should not
+00012  * be changed, but rather the per-project uip-conf.h file.
+00013  */
+00014 
+00015 /**
+00016  * \file
+00017  * Configuration options for uIP.
+00018  * \author Adam Dunkels <adam@dunkels.com>
+00019  *
+00020  * This file is used for tweaking various configuration options for
+00021  * uIP. You should make a copy of this file into one of your project's
+00022  * directories instead of editing this example "uipopt.h" file that
+00023  * comes with the uIP distribution.
+00024  */
+00025 
+00026 /*
+00027  * Copyright (c) 2001-2003, Adam Dunkels.
+00028  * All rights reserved.
+00029  *
+00030  * Redistribution and use in source and binary forms, with or without
+00031  * modification, are permitted provided that the following conditions
+00032  * are met:
+00033  * 1. Redistributions of source code must retain the above copyright
+00034  *    notice, this list of conditions and the following disclaimer.
+00035  * 2. Redistributions in binary form must reproduce the above copyright
+00036  *    notice, this list of conditions and the following disclaimer in the
+00037  *    documentation and/or other materials provided with the distribution.
+00038  * 3. The name of the author may not be used to endorse or promote
+00039  *    products derived from this software without specific prior
+00040  *    written permission.
+00041  *
+00042  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00043  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00044  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00045  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00046  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00047  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00048  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00049  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00050  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00051  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00052  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00053  *
+00054  * This file is part of the uIP TCP/IP stack.
+00055  *
+00056  * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $
+00057  *
+00058  */
+00059 
+00060 #ifndef __UIPOPT_H__
+00061 #define __UIPOPT_H__
+00062 
+00063 #ifndef UIP_LITTLE_ENDIAN
+00064 #define UIP_LITTLE_ENDIAN  3412
+00065 #endif /* UIP_LITTLE_ENDIAN */
+00066 #ifndef UIP_BIG_ENDIAN
+00067 #define UIP_BIG_ENDIAN     1234
+00068 #endif /* UIP_BIG_ENDIAN */
+00069 
+00070 #include "uip-conf.h"
+00071 
+00072 /*------------------------------------------------------------------------------*/
+00073 
+00074 /**
+00075  * \name Static configuration options
+00076  * @{
+00077  *
+00078  * These configuration options can be used for setting the IP address
+00079  * settings statically, but only if UIP_FIXEDADDR is set to 1. The
+00080  * configuration options for a specific node includes IP address,
+00081  * netmask and default router as well as the Ethernet address. The
+00082  * netmask, default router and Ethernet address are appliciable only
+00083  * if uIP should be run over Ethernet.
+00084  *
+00085  * All of these should be changed to suit your project.
+00086 */
+00087 
+00088 /**
+00089  * Determines if uIP should use a fixed IP address or not.
+00090  *
+00091  * If uIP should use a fixed IP address, the settings are set in the
+00092  * uipopt.h file. If not, the macros uip_sethostaddr(),
+00093  * uip_setdraddr() and uip_setnetmask() should be used instead.
+00094  *
+00095  * \hideinitializer
+00096  */
+00097 #define UIP_FIXEDADDR    0
+00098 
+00099 /**
+00100  * Ping IP address asignment.
+00101  *
+00102  * uIP uses a "ping" packets for setting its own IP address if this
+00103  * option is set. If so, uIP will start with an empty IP address and
+00104  * the destination IP address of the first incoming "ping" (ICMP echo)
+00105  * packet will be used for setting the hosts IP address.
+00106  *
+00107  * \note This works only if UIP_FIXEDADDR is 0.
+00108  *
+00109  * \hideinitializer
+00110  */
+00111 #ifdef UIP_CONF_PINGADDRCONF
+00112 #define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF
+00113 #else /* UIP_CONF_PINGADDRCONF */
+00114 #define UIP_PINGADDRCONF 0
+00115 #endif /* UIP_CONF_PINGADDRCONF */
+00116 
+00117 
+00118 /**
+00119  * Specifies if the uIP ARP module should be compiled with a fixed
+00120  * Ethernet MAC address or not.
+00121  *
+00122  * If this configuration option is 0, the macro uip_setethaddr() can
+00123  * be used to specify the Ethernet address at run-time.
+00124  *
+00125  * \hideinitializer
+00126  */
+00127 #define UIP_FIXEDETHADDR 0
+00128 
+00129 /** @} */
+00130 /*------------------------------------------------------------------------------*/
+00131 /**
+00132  * \name IP configuration options
+00133  * @{
+00134  *
+00135  */
+00136 /**
+00137  * The IP TTL (time to live) of IP packets sent by uIP.
+00138  *
+00139  * This should normally not be changed.
+00140  */
+00141 #define UIP_TTL         64
+00142 
+00143 /**
+00144  * Turn on support for IP packet reassembly.
+00145  *
+00146  * uIP supports reassembly of fragmented IP packets. This features
+00147  * requires an additonal amount of RAM to hold the reassembly buffer
+00148  * and the reassembly code size is approximately 700 bytes.  The
+00149  * reassembly buffer is of the same size as the uip_buf buffer
+00150  * (configured by UIP_BUFSIZE).
+00151  *
+00152  * \note IP packet reassembly is not heavily tested.
+00153  *
+00154  * \hideinitializer
+00155  */
+00156 #define UIP_REASSEMBLY 0
+00157 
+00158 /**
+00159  * The maximum time an IP fragment should wait in the reassembly
+00160  * buffer before it is dropped.
+00161  *
+00162  */
+00163 #define UIP_REASS_MAXAGE 40
+00164 
+00165 /** @} */
+00166 
+00167 /*------------------------------------------------------------------------------*/
+00168 /**
+00169  * \name UDP configuration options
+00170  * @{
+00171  */
+00172 
+00173 /**
+00174  * Toggles wether UDP support should be compiled in or not.
+00175  *
+00176  * \hideinitializer
+00177  */
+00178 #ifdef UIP_CONF_UDP
+00179 #define UIP_UDP UIP_CONF_UDP
+00180 #else /* UIP_CONF_UDP */
+00181 #define UIP_UDP           0
+00182 #endif /* UIP_CONF_UDP */
+00183 
+00184 /**
+00185  * Toggles if UDP checksums should be used or not.
+00186  *
+00187  * \note Support for UDP checksums is currently not included in uIP,
+00188  * so this option has no function.
+00189  *
+00190  * \hideinitializer
+00191  */
+00192 #ifdef UIP_CONF_UDP_CHECKSUMS
+00193 #define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS
+00194 #else
+00195 #define UIP_UDP_CHECKSUMS 0
+00196 #endif
+00197 
+00198 /**
+00199  * The maximum amount of concurrent UDP connections.
+00200  *
+00201  * \hideinitializer
+00202  */
+00203 #ifdef UIP_CONF_UDP_CONNS
+00204 #define UIP_UDP_CONNS UIP_CONF_UDP_CONNS
+00205 #else /* UIP_CONF_UDP_CONNS */
+00206 #define UIP_UDP_CONNS    10
+00207 #endif /* UIP_CONF_UDP_CONNS */
+00208 
+00209 /**
+00210  * The name of the function that should be called when UDP datagrams arrive.
+00211  *
+00212  * \hideinitializer
+00213  */
+00214 
+00215 
+00216 /** @} */
+00217 /*------------------------------------------------------------------------------*/
+00218 /**
+00219  * \name TCP configuration options
+00220  * @{
+00221  */
+00222 
+00223 /**
+00224  * Determines if support for opening connections from uIP should be
+00225  * compiled in.
+00226  *
+00227  * If the applications that are running on top of uIP for this project
+00228  * do not need to open outgoing TCP connections, this configration
+00229  * option can be turned off to reduce the code size of uIP.
+00230  *
+00231  * \hideinitializer
+00232  */
+00233 #define UIP_ACTIVE_OPEN 1
+00234 
+00235 /**
+00236  * The maximum number of simultaneously open TCP connections.
+00237  *
+00238  * Since the TCP connections are statically allocated, turning this
+00239  * configuration knob down results in less RAM used. Each TCP
+00240  * connection requires approximatly 30 bytes of memory.
+00241  *
+00242  * \hideinitializer
+00243  */
+00244 #ifndef UIP_CONF_MAX_CONNECTIONS
+00245 #define UIP_CONNS       10
+00246 #else /* UIP_CONF_MAX_CONNECTIONS */
+00247 #define UIP_CONNS UIP_CONF_MAX_CONNECTIONS
+00248 #endif /* UIP_CONF_MAX_CONNECTIONS */
+00249 
+00250 
+00251 /**
+00252  * The maximum number of simultaneously listening TCP ports.
+00253  *
+00254  * Each listening TCP port requires 2 bytes of memory.
+00255  *
+00256  * \hideinitializer
+00257  */
+00258 #ifndef UIP_CONF_MAX_LISTENPORTS
+00259 #define UIP_LISTENPORTS 20
+00260 #else /* UIP_CONF_MAX_LISTENPORTS */
+00261 #define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS
+00262 #endif /* UIP_CONF_MAX_LISTENPORTS */
+00263 
+00264 /**
+00265  * Determines if support for TCP urgent data notification should be
+00266  * compiled in.
+00267  *
+00268  * Urgent data (out-of-band data) is a rarely used TCP feature that
+00269  * very seldom would be required.
+00270  *
+00271  * \hideinitializer
+00272  */
+00273 #define UIP_URGDATA      0
+00274 
+00275 /**
+00276  * The initial retransmission timeout counted in timer pulses.
+00277  *
+00278  * This should not be changed.
+00279  */
+00280 #define UIP_RTO         3
+00281 
+00282 /**
+00283  * The maximum number of times a segment should be retransmitted
+00284  * before the connection should be aborted.
+00285  *
+00286  * This should not be changed.
+00287  */
+00288 #define UIP_MAXRTX      8
+00289 
+00290 /**
+00291  * The maximum number of times a SYN segment should be retransmitted
+00292  * before a connection request should be deemed to have been
+00293  * unsuccessful.
+00294  *
+00295  * This should not need to be changed.
+00296  */
+00297 #define UIP_MAXSYNRTX      5
+00298 
+00299 /**
+00300  * The TCP maximum segment size.
+00301  *
+00302  * This is should not be to set to more than
+00303  * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
+00304  */
+00305 #define UIP_TCP_MSS     (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
+00306 
+00307 /**
+00308  * The size of the advertised receiver's window.
+00309  *
+00310  * Should be set low (i.e., to the size of the uip_buf buffer) is the
+00311  * application is slow to process incoming data, or high (32768 bytes)
+00312  * if the application processes data quickly.
+00313  *
+00314  * \hideinitializer
+00315  */
+00316 #ifndef UIP_CONF_RECEIVE_WINDOW
+00317 #define UIP_RECEIVE_WINDOW UIP_TCP_MSS
+00318 #else
+00319 #define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW
+00320 #endif
+00321 
+00322 /**
+00323  * How long a connection should stay in the TIME_WAIT state.
+00324  *
+00325  * This configiration option has no real implication, and it should be
+00326  * left untouched.
+00327  */
+00328 #define UIP_TIME_WAIT_TIMEOUT 120
+00329 
+00330 
+00331 /** @} */
+00332 /*------------------------------------------------------------------------------*/
+00333 /**
+00334  * \name ARP configuration options
+00335  * @{
+00336  */
+00337 
+00338 /**
+00339  * The size of the ARP table.
+00340  *
+00341  * This option should be set to a larger value if this uIP node will
+00342  * have many connections from the local network.
+00343  *
+00344  * \hideinitializer
+00345  */
+00346 #ifdef UIP_CONF_ARPTAB_SIZE
+00347 #define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE
+00348 #else
+00349 #define UIP_ARPTAB_SIZE 8
+00350 #endif
+00351 
+00352 /**
+00353  * The maxium age of ARP table entries measured in 10ths of seconds.
+00354  *
+00355  * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
+00356  * default).
+00357  */
+00358 #define UIP_ARP_MAXAGE 120
+00359 
+00360 /** @} */
+00361 
+00362 /*------------------------------------------------------------------------------*/
+00363 
+00364 /**
+00365  * \name General configuration options
+00366  * @{
+00367  */
+00368 
+00369 /**
+00370  * The size of the uIP packet buffer.
+00371  *
+00372  * The uIP packet buffer should not be smaller than 60 bytes, and does
+00373  * not need to be larger than 1500 bytes. Lower size results in lower
+00374  * TCP throughput, larger size results in higher TCP throughput.
+00375  *
+00376  * \hideinitializer
+00377  */
+00378 #ifndef UIP_CONF_BUFFER_SIZE
+00379 #define UIP_BUFSIZE     400
+00380 #else /* UIP_CONF_BUFFER_SIZE */
+00381 #define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
+00382 #endif /* UIP_CONF_BUFFER_SIZE */
+00383 
+00384 
+00385 /**
+00386  * Determines if statistics support should be compiled in.
+00387  *
+00388  * The statistics is useful for debugging and to show the user.
+00389  *
+00390  * \hideinitializer
+00391  */
+00392 #ifndef UIP_CONF_STATISTICS
+00393 #define UIP_STATISTICS  0
+00394 #else /* UIP_CONF_STATISTICS */
+00395 #define UIP_STATISTICS UIP_CONF_STATISTICS
+00396 #endif /* UIP_CONF_STATISTICS */
+00397 
+00398 /**
+00399  * Determines if logging of certain events should be compiled in.
+00400  *
+00401  * This is useful mostly for debugging. The function uip_log()
+00402  * must be implemented to suit the architecture of the project, if
+00403  * logging is turned on.
+00404  *
+00405  * \hideinitializer
+00406  */
+00407 #ifndef UIP_CONF_LOGGING
+00408 #define UIP_LOGGING     0
+00409 #else /* UIP_CONF_LOGGING */
+00410 #define UIP_LOGGING     UIP_CONF_LOGGING
+00411 #endif /* UIP_CONF_LOGGING */
+00412 
+00413 /**
+00414  * Broadcast support.
+00415  *
+00416  * This flag configures IP broadcast support. This is useful only
+00417  * together with UDP.
+00418  *
+00419  * \hideinitializer
+00420  *
+00421  */
+00422 #ifndef UIP_CONF_BROADCAST
+00423 #define UIP_BROADCAST 0
+00424 #else /* UIP_CONF_BROADCAST */
+00425 #define UIP_BROADCAST UIP_CONF_BROADCAST
+00426 #endif /* UIP_CONF_BROADCAST */
+00427 
+00428 /**
+00429  * Print out a uIP log message.
+00430  *
+00431  * This function must be implemented by the module that uses uIP, and
+00432  * is called by uIP whenever a log message is generated.
+00433  */
+00434 void uip_log(char *msg);
+00435 
+00436 /**
+00437  * The link level header length.
+00438  *
+00439  * This is the offset into the uip_buf where the IP header can be
+00440  * found. For Ethernet, this should be set to 14. For SLIP, this
+00441  * should be set to 0.
+00442  *
+00443  * \hideinitializer
+00444  */
+00445 #ifdef UIP_CONF_LLH_LEN
+00446 #define UIP_LLH_LEN UIP_CONF_LLH_LEN
+00447 #else /* UIP_CONF_LLH_LEN */
+00448 #define UIP_LLH_LEN     14
+00449 #endif /* UIP_CONF_LLH_LEN */
+00450 
+00451 /** @} */
+00452 /*------------------------------------------------------------------------------*/
+00453 /**
+00454  * \name CPU architecture configuration
+00455  * @{
+00456  *
+00457  * The CPU architecture configuration is where the endianess of the
+00458  * CPU on which uIP is to be run is specified. Most CPUs today are
+00459  * little endian, and the most notable exception are the Motorolas
+00460  * which are big endian. The BYTE_ORDER macro should be changed to
+00461  * reflect the CPU architecture on which uIP is to be run.
+00462  */
+00463 
+00464 /**
+00465  * The byte order of the CPU architecture on which uIP is to be run.
+00466  *
+00467  * This option can be either BIG_ENDIAN (Motorola byte order) or
+00468  * LITTLE_ENDIAN (Intel byte order).
+00469  *
+00470  * \hideinitializer
+00471  */
+00472 #ifdef UIP_CONF_BYTE_ORDER
+00473 #define UIP_BYTE_ORDER     UIP_CONF_BYTE_ORDER
+00474 #else /* UIP_CONF_BYTE_ORDER */
+00475 #define UIP_BYTE_ORDER     UIP_LITTLE_ENDIAN
+00476 #endif /* UIP_CONF_BYTE_ORDER */
+00477 
+00478 /** @} */
+00479 /*------------------------------------------------------------------------------*/
+00480 
+00481 /**
+00482  * \name Appication specific configurations
+00483  * @{
+00484  *
+00485  * An uIP application is implemented using a single application
+00486  * function that is called by uIP whenever a TCP/IP event occurs. The
+00487  * name of this function must be registered with uIP at compile time
+00488  * using the UIP_APPCALL definition.
+00489  *
+00490  * uIP applications can store the application state within the
+00491  * uip_conn structure by specifying the type of the application
+00492  * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
+00493  *
+00494  * The file containing the definitions must be included in the
+00495  * uipopt.h file.
+00496  *
+00497  * The following example illustrates how this can look.
+00498  \code
+00499 
+00500 void httpd_appcall(void);
+00501 #define UIP_APPCALL     httpd_appcall
+00502 
+00503 struct httpd_state {
+00504   u8_t state;
+00505   u16_t count;
+00506   char *dataptr;
+00507   char *script;
+00508 };
+00509 typedef struct httpd_state uip_tcp_appstate_t
+00510  \endcode
+00511  */
+00512 
+00513 /**
+00514  * \var #define UIP_APPCALL
+00515  *
+00516  * The name of the application function that uIP should call in
+00517  * response to TCP/IP events.
+00518  *
+00519  */
+00520 
+00521 /**
+00522  * \var typedef uip_tcp_appstate_t
+00523  *
+00524  * The type of the application state that is to be stored in the
+00525  * uip_conn structure. This usually is typedef:ed to a struct holding
+00526  * application state information.
+00527  */
+00528 
+00529 /**
+00530  * \var typedef uip_udp_appstate_t
+00531  *
+00532  * The type of the application state that is to be stored in the
+00533  * uip_conn structure. This usually is typedef:ed to a struct holding
+00534  * application state information.
+00535  */
+00536 /** @} */
+00537 /** @} */
+00538 
+00539 #endif /* __UIPOPT_H__ */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/a00207.html b/doc/html/a00207.html new file mode 100644 index 0000000..937d9a6 --- /dev/null +++ b/doc/html/a00207.html @@ -0,0 +1,182 @@ + + +uIP 1.0: unix/uip-conf.h Source File + + + + + + +

unix/uip-conf.h

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup uipopt
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \name Project-specific configuration options
+00008  * @{
+00009  *
+00010  * uIP has a number of configuration options that can be overridden
+00011  * for each project. These are kept in a project-specific uip-conf.h
+00012  * file and all configuration names have the prefix UIP_CONF.
+00013  */
+00014 
+00015 /*
+00016  * Copyright (c) 2006, Swedish Institute of Computer Science.
+00017  * All rights reserved.
+00018  *
+00019  * Redistribution and use in source and binary forms, with or without
+00020  * modification, are permitted provided that the following conditions
+00021  * are met:
+00022  * 1. Redistributions of source code must retain the above copyright
+00023  *    notice, this list of conditions and the following disclaimer.
+00024  * 2. Redistributions in binary form must reproduce the above copyright
+00025  *    notice, this list of conditions and the following disclaimer in the
+00026  *    documentation and/or other materials provided with the distribution.
+00027  * 3. Neither the name of the Institute nor the names of its contributors
+00028  *    may be used to endorse or promote products derived from this software
+00029  *    without specific prior written permission.
+00030  *
+00031  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+00032  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+00033  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00034  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+00035  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00036  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+00037  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+00038  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+00039  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+00040  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+00041  * SUCH DAMAGE.
+00042  *
+00043  * This file is part of the uIP TCP/IP stack
+00044  *
+00045  * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
+00046  */
+00047 
+00048 /**
+00049  * \file
+00050  *         An example uIP configuration file
+00051  * \author
+00052  *         Adam Dunkels <adam@sics.se>
+00053  */
+00054 
+00055 #ifndef __UIP_CONF_H__
+00056 #define __UIP_CONF_H__
+00057 
+00058 #include <inttypes.h>
+00059 
+00060 /**
+00061  * 8 bit datatype
+00062  *
+00063  * This typedef defines the 8-bit type used throughout uIP.
+00064  *
+00065  * \hideinitializer
+00066  */
+00067 typedef uint8_t u8_t;
+00068 
+00069 /**
+00070  * 16 bit datatype
+00071  *
+00072  * This typedef defines the 16-bit type used throughout uIP.
+00073  *
+00074  * \hideinitializer
+00075  */
+00076 typedef uint16_t u16_t;
+00077 
+00078 /**
+00079  * Statistics datatype
+00080  *
+00081  * This typedef defines the dataype used for keeping statistics in
+00082  * uIP.
+00083  *
+00084  * \hideinitializer
+00085  */
+00086 typedef unsigned short uip_stats_t;
+00087 
+00088 /**
+00089  * Maximum number of TCP connections.
+00090  *
+00091  * \hideinitializer
+00092  */
+00093 #define UIP_CONF_MAX_CONNECTIONS 40
+00094 
+00095 /**
+00096  * Maximum number of listening TCP ports.
+00097  *
+00098  * \hideinitializer
+00099  */
+00100 #define UIP_CONF_MAX_LISTENPORTS 40
+00101 
+00102 /**
+00103  * uIP buffer size.
+00104  *
+00105  * \hideinitializer
+00106  */
+00107 #define UIP_CONF_BUFFER_SIZE     420
+00108 
+00109 /**
+00110  * CPU byte order.
+00111  *
+00112  * \hideinitializer
+00113  */
+00114 #define UIP_CONF_BYTE_ORDER      LITTLE_ENDIAN
+00115 
+00116 /**
+00117  * Logging on or off
+00118  *
+00119  * \hideinitializer
+00120  */
+00121 #define UIP_CONF_LOGGING         1
+00122 
+00123 /**
+00124  * UDP support on or off
+00125  *
+00126  * \hideinitializer
+00127  */
+00128 #define UIP_CONF_UDP             0
+00129 
+00130 /**
+00131  * UDP checksums on or off
+00132  *
+00133  * \hideinitializer
+00134  */
+00135 #define UIP_CONF_UDP_CHECKSUMS   1
+00136 
+00137 /**
+00138  * uIP statistics on or off
+00139  *
+00140  * \hideinitializer
+00141  */
+00142 #define UIP_CONF_STATISTICS      1
+00143 
+00144 /* Here we include the header file for the application(s) we use in
+00145    our project. */
+00146 /*#include "smtp.h"*/
+00147 /*#include "hello-world.h"*/
+00148 /*#include "telnetd.h"*/
+00149 #include "webserver.h"
+00150 /*#include "dhcpc.h"*/
+00151 /*#include "resolv.h"*/
+00152 /*#include "webclient.h"*/
+00153 
+00154 #endif /* __UIP_CONF_H__ */
+00155 
+00156 /** @} */
+00157 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/annotated.html b/doc/html/annotated.html index 905c81d..e649361 100644 --- a/doc/html/annotated.html +++ b/doc/html/annotated.html @@ -1,22 +1,50 @@ - + -uIP 0.9: Annotated Index +uIP 1.0: Data Structures + - - -

uIP 0.9 Data Structures

Here are the data structures with brief descriptions: - - - - - - - + + + +

uIP 1.0 Data Structures

Here are the data structures with brief descriptions:
fs_fileAn open file in the read-only file system
telnetd_stateA telnet connection structure
uip_connRepresentation of a uIP TCP connection
uip_eth_addrRepresentation of a 48-bit Ethernet address
uip_eth_hdrThe Ethernet header
uip_statsThe structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1
uip_udp_connRepresentation of a uIP UDP connection
+ + + + + + + + + + + + + + + + + + + + +
dhcpc_state
hello_world_state
httpd_cgi_call
httpd_state
memb_blocks
psockThe representation of a protosocket
psock_buf
pt
smtp_state
telnetd_state
timerA timer
uip_connRepresentation of a uIP TCP connection
uip_eth_addrRepresentation of a 48-bit Ethernet address
uip_eth_hdrThe Ethernet header
uip_icmpip_hdr
uip_neighbor_addr
uip_statsThe structure holding the TCP/IP statistics that are gathered if UIP_STATISTICS is set to 1
uip_tcpip_hdr
uip_udp_connRepresentation of a uIP UDP connection
uip_udpip_hdr
webclient_state
-
Generated on Tue Oct 7 15:51:41 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/classes.html b/doc/html/classes.html index 96e6f78..7a937cb 100644 --- a/doc/html/classes.html +++ b/doc/html/classes.html @@ -1,17 +1,38 @@ - + -uIP 0.9: Alphabetical index +uIP 1.0: Alphabetical List + - - -

uIP 0.9 Data Structure Index

-
  F  
-
  T  
-
  U  
-
uip_eth_addr   uip_stats   
fs_file   telnetd_state   uip_conn   uip_eth_hdr   uip_udp_conn   

Generated on Tue Oct 7 15:51:41 2003 for uIP 0.9 by + + + +

uIP 1.0 Data Structure Index

D | H | M | P | S | T | U | W

+ +
  D  
+
  M  
+
  S  
+
uip_conn   uip_tcpip_hdr   
dhcpc_state   memb_blocks   smtp_state   uip_eth_addr   uip_udp_conn   
  H  
+
  P  
+
  T  
+
uip_eth_hdr   uip_udpip_hdr   
hello_world_state   psock   telnetd_state   uip_icmpip_hdr   
  W  
+
httpd_cgi_call   psock_buf   timer   uip_neighbor_addr   webclient_state   
httpd_state   pt   
  U  
+
uip_stats   

D | H | M | P | S | T | U | W

+


Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/doxygen.css b/doc/html/doxygen.css index 0564e82..05615b2 100644 --- a/doc/html/doxygen.css +++ b/doc/html/doxygen.css @@ -1,79 +1,147 @@ -H1 { - text-align: center; - font-family: Arial, Helvetica, sans-serif; -} -H2 { +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } -CAPTION { font-weight: bold } -DIV.qindex { width: 100%; - background-color: #eeeeff; - border: 4px solid #eeeeff; - text-align: center; - margin-bottom: 2px +BODY,TD { + font-size: 90%; } -A.qindex { text-decoration: none; font-weight: bold; } -A.qindex:hover { text-decoration: none; background-color: #ddddff } -A.qindexHL { text-decoration: none; font-weight: bold; - background-color: #6666cc; - color: #ffffff - } -A.qindexHL:hover { text-decoration: none; background-color: #6666cc } -A.qindexRef { text-decoration: none; font-weight: bold; } -A.qindexRef:hover { text-decoration: none; background-color: #ddddff } -A.qindexRefHL { text-decoration: none; font-weight: bold; - background-color: #6666cc; - color: #ffffff - } -A.qindexRefHL:hover { text-decoration: none; background-color: #6666cc } +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } -A.code { text-decoration: none; font-weight: normal; color: #4444ee } -A.codeRef { font-weight: normal; color: #4444ee } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } -DIV.fragment { - width: 98%; +.fragment { + font-family: Fixed, monospace; + font-size: 95%; +} +PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; - padding-left: 4px; - margin: 4px; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } -TD.md { background-color: #f2f2ff; font-weight: bold; } -TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; } -TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; } -DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } -DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } +TD.md { background-color: #F4F4FB; font-weight: bold; } +TD.mdPrefix { + background-color: #F4F4FB; + color: #606060; + font-size: 80%; +} +TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; } +TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; } +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } -TD.indexkey { - background-color: #eeeeff; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; } -TD.indexvalue { - background-color: #eeeeff; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; @@ -90,16 +158,16 @@ SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdTable { border: 1px solid #868686; - background-color: #f2f2ff; + background-color: #F4F4FB; } .mdRow { - padding: 8px 20px; + padding: 8px 10px; } .mdescLeft { - font-size: smaller; - font-family: Arial, Helvetica, sans-serif; + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; background-color: #FAFAFA; - padding-left: 8px; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; @@ -107,18 +175,15 @@ SPAN.charliteral { color: #008080 } margin: 0px; } .mdescRight { - font-size: smaller; - font-family: Arial, Helvetica, sans-serif; + padding: 0px 8px 4px 8px; + font-size: 80%; font-style: italic; background-color: #FAFAFA; - padding-left: 4px; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; - padding-bottom: 0px; - padding-right: 8px; } .memItemLeft { padding: 1px 0px 0px 8px; @@ -127,34 +192,119 @@ SPAN.charliteral { color: #008080 } border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; - border-top-style: solid; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; + border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; - font-family: Geneva, Arial, Helvetica, sans-serif; - font-size: 12px; + font-size: 80%; } .memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; - border-top-style: solid; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; + border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; - font-family: Geneva, Arial, Helvetica, sans-serif; - font-size: 13px; + font-size: 80%; } +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { background: #e8eef2; + font-weight: bold; +} +HR { height: 1px; + border: none; + border-top: 1px solid black; +} + diff --git a/doc/html/doxygen.png b/doc/html/doxygen.png index 96ae72c..f0a274b 100644 Binary files a/doc/html/doxygen.png and b/doc/html/doxygen.png differ diff --git a/doc/html/examples.html b/doc/html/examples.html new file mode 100644 index 0000000..d51b041 --- /dev/null +++ b/doc/html/examples.html @@ -0,0 +1,38 @@ + + +uIP 1.0: Examples + + + + + +

uIP 1.0 Examples

Here is a list of all examples: +
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/files.html b/doc/html/files.html index 354ae61..45982f9 100644 --- a/doc/html/files.html +++ b/doc/html/files.html @@ -1,40 +1,67 @@ - + -uIP 0.9: File Index +uIP 1.0: File Index + - - -

uIP 0.9 File List

Here is a list of all documented files with brief descriptions: - - - - - - - - - - - - - - - - - - - - - - - - - + + + +

uIP 1.0 File List

Here is a list of all documented files with brief descriptions:
apps/httpd/cgi.cHTTP server script language C functions file
apps/httpd/cgi.hHTTP script language header file
apps/httpd/fs.cHTTP server read-only file system code
apps/httpd/fs.hHTTP server read-only file system header file
apps/httpd/httpd.cHTTP server
apps/httpd/httpd.hHTTP server header file
apps/resolv/resolv.cDNS host name to IP address resolver
apps/resolv/resolv.hDNS resolver code header file
apps/smtp/smtp.cSMTP example implementation
apps/smtp/smtp.hSMTP header file
apps/telnetd/memb.cMemory block allocation routines
apps/telnetd/memb.hMemory block allocation routines
apps/telnetd/telnetd-shell.cAn example telnet server shell
apps/telnetd/telnetd.cImplementation of the Telnet server
apps/telnetd/telnetd.hHeader file for the telnet server
apps/webclient/webclient.cImplementation of the HTTP client
apps/webclient/webclient.hHeader file for the HTTP client
uip/slipdev.cSLIP protocol implementation
uip/slipdev.hSLIP header file
uip/uip.cThe uIP TCP/IP stack code
uip/uip.hHeader file for the uIP TCP/IP stack
uip/uip_arch.hDeclarations of architecture specific functions
uip/uip_arp.cImplementation of the ARP Address Resolution Protocol
uip/uip_arp.hMacros and definitions for the ARP module
unix/uipopt.hConfiguration options for uIP
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
apps/dhcpc/dhcpc.c [code]
apps/dhcpc/dhcpc.h [code]
apps/hello-world/hello-world.c [code]An example of how to write uIP applications with protosockets
apps/hello-world/hello-world.h [code]Header file for an example of how to write uIP applications with protosockets
apps/resolv/resolv.c [code]DNS host name to IP address resolver
apps/resolv/resolv.h [code]DNS resolver code header file
apps/smtp/smtp.c [code]SMTP example implementation
apps/smtp/smtp.h [code]SMTP header file
apps/telnetd/shell.c [code]
apps/telnetd/shell.h [code]Interface for the Contiki shell
apps/telnetd/telnetd.c [code]
apps/telnetd/telnetd.h [code]
apps/webclient/webclient.c [code]Implementation of the HTTP client
apps/webclient/webclient.h [code]Header file for the HTTP client
apps/webserver/httpd-cgi.c [code]Web server script interface
apps/webserver/httpd-cgi.h [code]Web server script interface header file
apps/webserver/httpd.c [code]Web server
apps/webserver/httpd.h [code]
lib/memb.c [code]Memory block allocation routines
lib/memb.h [code]Memory block allocation routines
uip/clock.h [code]
uip/lc-addrlabels.h [code]Implementation of local continuations based on the "Labels as values" feature of gcc
uip/lc-switch.h [code]Implementation of local continuations based on switch() statment
uip/lc.h [code]Local continuations
uip/psock.c [code]
uip/psock.h [code]Protosocket library header file
uip/pt.h [code]Protothreads implementation
uip/timer.c [code]Timer library implementation
uip/timer.h [code]Timer library header file
uip/uip-neighbor.c [code]Database of link-local neighbors, used by IPv6 code and to be used by a future ARP code rewrite
uip/uip-neighbor.h [code]Header file for database of link-local neighbors, used by IPv6 code and to be used by future ARP code
uip/uip-split.c [code]
uip/uip-split.h [code]Module for splitting outbound TCP segments in two to avoid the delayed ACK throughput degradation
uip/uip.c [code]The uIP TCP/IP stack code
uip/uip.h [code]Header file for the uIP TCP/IP stack
uip/uip_arch.h [code]Declarations of architecture specific functions
uip/uip_arp.c [code]Implementation of the ARP Address Resolution Protocol
uip/uip_arp.h [code]Macros and definitions for the ARP module
uip/uipopt.h [code]Configuration options for uIP
unix/uip-conf.h [code]An example uIP configuration file
-
Generated on Tue Oct 7 15:51:00 2003 for uIP 0.9 by +
Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/functions.html b/doc/html/functions.html index 4e07f49..ab3e8e7 100644 --- a/doc/html/functions.html +++ b/doc/html/functions.html @@ -1,95 +1,217 @@ - + -uIP 0.9: Compound Member Index +uIP 1.0: Data Fields + - - - -
a | c | d | f | h | i | l | m | n | p | r | s | t | v
+ + + +
+ +
+
+ +

- +Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:

-Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:

- a - -

+

- u -

+

- v -

+

- w -

+
Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/functions_vars.html b/doc/html/functions_vars.html index 3d2eaa0..466d78a 100644 --- a/doc/html/functions_vars.html +++ b/doc/html/functions_vars.html @@ -1,95 +1,217 @@ - + -uIP 0.9: Compound Member Index +uIP 1.0: Data Fields - Variables + - - - -
a | c | d | f | h | i | l | m | n | p | r | s | t | v
+ + + +
+ +
+
+ +

- + 

-

- a - -

+

- u -

+

- v -

+

- w -

+
Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/globals.html b/doc/html/globals.html index 51aba16..31796bf 100644 --- a/doc/html/globals.html +++ b/doc/html/globals.html @@ -1,197 +1,62 @@ - + -uIP 0.9: File Member Index +uIP 1.0: Data Fields + - - - -
b | c | f | h | m | r | s | t | u | w
+ + + + +
+ +

- +Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

-Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- b - -

-

- c - -

-

- f - -

-

- h - -

-

- m - -

-

- r - -

-

- s - -

-

- t - -

-

- u - -

-

- w - -

-
Generated on Tue Oct 7 15:51:52 2003 for uIP 0.9 by +

- _ -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/globals_0x61.html b/doc/html/globals_0x61.html new file mode 100644 index 0000000..15a80fa --- /dev/null +++ b/doc/html/globals_0x61.html @@ -0,0 +1,64 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- a -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x62.html b/doc/html/globals_0x62.html new file mode 100644 index 0000000..a5c8798 --- /dev/null +++ b/doc/html/globals_0x62.html @@ -0,0 +1,62 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- b -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x64.html b/doc/html/globals_0x64.html new file mode 100644 index 0000000..b676eee --- /dev/null +++ b/doc/html/globals_0x64.html @@ -0,0 +1,73 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- d -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x65.html b/doc/html/globals_0x65.html new file mode 100644 index 0000000..c47f60d --- /dev/null +++ b/doc/html/globals_0x65.html @@ -0,0 +1,62 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- e -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x66.html b/doc/html/globals_0x66.html new file mode 100644 index 0000000..cc2bf8a --- /dev/null +++ b/doc/html/globals_0x66.html @@ -0,0 +1,62 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- f -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x68.html b/doc/html/globals_0x68.html new file mode 100644 index 0000000..d01ae96 --- /dev/null +++ b/doc/html/globals_0x68.html @@ -0,0 +1,73 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- h -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x69.html b/doc/html/globals_0x69.html new file mode 100644 index 0000000..fe45608 --- /dev/null +++ b/doc/html/globals_0x69.html @@ -0,0 +1,84 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- i -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x6c.html b/doc/html/globals_0x6c.html new file mode 100644 index 0000000..eaeb84d --- /dev/null +++ b/doc/html/globals_0x6c.html @@ -0,0 +1,66 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- l -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x6d.html b/doc/html/globals_0x6d.html new file mode 100644 index 0000000..c3f3c12 --- /dev/null +++ b/doc/html/globals_0x6d.html @@ -0,0 +1,69 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- m -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x6e.html b/doc/html/globals_0x6e.html new file mode 100644 index 0000000..324dbb3 --- /dev/null +++ b/doc/html/globals_0x6e.html @@ -0,0 +1,63 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- n -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x70.html b/doc/html/globals_0x70.html new file mode 100644 index 0000000..cf5972c --- /dev/null +++ b/doc/html/globals_0x70.html @@ -0,0 +1,95 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- p -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x72.html b/doc/html/globals_0x72.html new file mode 100644 index 0000000..ba708eb --- /dev/null +++ b/doc/html/globals_0x72.html @@ -0,0 +1,69 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- r -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x73.html b/doc/html/globals_0x73.html new file mode 100644 index 0000000..19f8c41 --- /dev/null +++ b/doc/html/globals_0x73.html @@ -0,0 +1,81 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- s -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x74.html b/doc/html/globals_0x74.html new file mode 100644 index 0000000..af197ed --- /dev/null +++ b/doc/html/globals_0x74.html @@ -0,0 +1,76 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- t -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x75.html b/doc/html/globals_0x75.html new file mode 100644 index 0000000..1f487bc --- /dev/null +++ b/doc/html/globals_0x75.html @@ -0,0 +1,237 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- u -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_0x77.html b/doc/html/globals_0x77.html new file mode 100644 index 0000000..8b56378 --- /dev/null +++ b/doc/html/globals_0x77.html @@ -0,0 +1,80 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: +

+

- w -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs.html b/doc/html/globals_defs.html index 8674983..8bcd193 100644 --- a/doc/html/globals_defs.html +++ b/doc/html/globals_defs.html @@ -1,122 +1,62 @@ - + -uIP 0.9: File Member Index +uIP 1.0: Data Fields + - - - -
b | h | m | s | t | u
+ + + + +
+ +

- + 

-

- b - -

-

- h - -

-

- m - -

-

- s - -

-

- t - -

-

- u - -

-
Generated on Tue Oct 7 15:51:52 2003 for uIP 0.9 by +

- _ -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/globals_defs_0x61.html b/doc/html/globals_defs_0x61.html new file mode 100644 index 0000000..82c84b8 --- /dev/null +++ b/doc/html/globals_defs_0x61.html @@ -0,0 +1,64 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- a -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x62.html b/doc/html/globals_defs_0x62.html new file mode 100644 index 0000000..c41b24b --- /dev/null +++ b/doc/html/globals_defs_0x62.html @@ -0,0 +1,62 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- b -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x64.html b/doc/html/globals_defs_0x64.html new file mode 100644 index 0000000..ff1fcbd --- /dev/null +++ b/doc/html/globals_defs_0x64.html @@ -0,0 +1,73 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- d -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x65.html b/doc/html/globals_defs_0x65.html new file mode 100644 index 0000000..b08aab4 --- /dev/null +++ b/doc/html/globals_defs_0x65.html @@ -0,0 +1,62 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- e -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x66.html b/doc/html/globals_defs_0x66.html new file mode 100644 index 0000000..1bd4a6e --- /dev/null +++ b/doc/html/globals_defs_0x66.html @@ -0,0 +1,62 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- f -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x68.html b/doc/html/globals_defs_0x68.html new file mode 100644 index 0000000..8c1a772 --- /dev/null +++ b/doc/html/globals_defs_0x68.html @@ -0,0 +1,67 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- h -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x69.html b/doc/html/globals_defs_0x69.html new file mode 100644 index 0000000..7478ca0 --- /dev/null +++ b/doc/html/globals_defs_0x69.html @@ -0,0 +1,84 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- i -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x6c.html b/doc/html/globals_defs_0x6c.html new file mode 100644 index 0000000..14730df --- /dev/null +++ b/doc/html/globals_defs_0x6c.html @@ -0,0 +1,65 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- l -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x6d.html b/doc/html/globals_defs_0x6d.html new file mode 100644 index 0000000..ccb1969 --- /dev/null +++ b/doc/html/globals_defs_0x6d.html @@ -0,0 +1,66 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- m -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x6e.html b/doc/html/globals_defs_0x6e.html new file mode 100644 index 0000000..5244c1d --- /dev/null +++ b/doc/html/globals_defs_0x6e.html @@ -0,0 +1,63 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- n -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x70.html b/doc/html/globals_defs_0x70.html new file mode 100644 index 0000000..abd98a9 --- /dev/null +++ b/doc/html/globals_defs_0x70.html @@ -0,0 +1,93 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- p -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x72.html b/doc/html/globals_defs_0x72.html new file mode 100644 index 0000000..a80c5cb --- /dev/null +++ b/doc/html/globals_defs_0x72.html @@ -0,0 +1,62 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- r -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x73.html b/doc/html/globals_defs_0x73.html new file mode 100644 index 0000000..f334e9e --- /dev/null +++ b/doc/html/globals_defs_0x73.html @@ -0,0 +1,70 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- s -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x74.html b/doc/html/globals_defs_0x74.html new file mode 100644 index 0000000..8224ebf --- /dev/null +++ b/doc/html/globals_defs_0x74.html @@ -0,0 +1,72 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- t -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x75.html b/doc/html/globals_defs_0x75.html new file mode 100644 index 0000000..8f0ec88 --- /dev/null +++ b/doc/html/globals_defs_0x75.html @@ -0,0 +1,188 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- u -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_defs_0x77.html b/doc/html/globals_defs_0x77.html new file mode 100644 index 0000000..9f19416 --- /dev/null +++ b/doc/html/globals_defs_0x77.html @@ -0,0 +1,67 @@ + + +uIP 1.0: Data Fields + + + + + + + +
+ +
+ +

+  +

+

- w -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + diff --git a/doc/html/globals_func.html b/doc/html/globals_func.html index 729e8ce..49f1393 100644 --- a/doc/html/globals_func.html +++ b/doc/html/globals_func.html @@ -1,98 +1,136 @@ - + -uIP 0.9: File Member Index +uIP 1.0: Data Fields + - - - -
f | h | m | r | s | t | u | w
+ + + + +
+ +

- + 

-

- f - -

-

- h - -

-

- m - -

+
Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
+doxygen 1.4.6
diff --git a/doc/html/globals_type.html b/doc/html/globals_type.html index f14f00c..084f32d 100644 --- a/doc/html/globals_type.html +++ b/doc/html/globals_type.html @@ -1,21 +1,47 @@ - + -uIP 0.9: File Member Index +uIP 1.0: Data Fields + - - - - + + + +

-
Generated on Tue Oct 7 15:51:52 2003 for uIP 0.9 by +
  • lc_t +: lc-addrlabels.h, lc-switch.h
  • u16_t +: uip-conf.h
  • u8_t +: uip-conf.h
  • uip_ip4addr_t +: uip.h
  • uip_ip6addr_t +: uip.h
  • uip_ipaddr_t +: uip.h
  • uip_stats_t +: uip-conf.h
  • uip_tcp_appstate_t +: webclient.h, smtp.h
  • uip_udp_appstate_t +: resolv.h +
    Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
    +doxygen 1.4.6
  • diff --git a/doc/html/globals_vars.html b/doc/html/globals_vars.html index 0e55ac9..beddb50 100644 --- a/doc/html/globals_vars.html +++ b/doc/html/globals_vars.html @@ -1,23 +1,55 @@ - + -uIP 0.9: File Member Index +uIP 1.0: Data Fields + - - - - + + + +

    -
    Generated on Tue Oct 7 15:51:52 2003 for uIP 0.9 by +
  • uip_acc32 +: uip.c, uip.h
  • uip_appdata +: uip.c, uip.h
  • uip_buf +: uip.c, uip.h
  • uip_conn +: uip.c, uip.h
  • uip_conns +: uip.c, uip.h
  • uip_draddr +: uip.c, uip.h
  • uip_ethaddr +: uip_arp.h, uip.c
  • uip_flags +: uip.c, uip.h
  • uip_hostaddr +: uip.c, uip.h
  • uip_len +: uip.c, uip.h
  • uip_listenports +: uip.c
  • uip_netmask +: uip.c, uip.h
  • uip_sappdata +: uip.c
  • uip_slen +: uip.c
  • uip_stat +: uip.h
  • uip_udp_conn +: uip.c, uip.h
  • uip_udp_conns +: uip.c, uip.h +
    Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
    +doxygen 1.4.6
  • diff --git a/doc/html/graph_legend.dot b/doc/html/graph_legend.dot deleted file mode 100644 index 5420927..0000000 --- a/doc/html/graph_legend.dot +++ /dev/null @@ -1,22 +0,0 @@ -digraph G -{ - edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; - node [fontname="Helvetica",fontsize=10,shape=record]; - Node9 [shape="box",label="Inherited",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",style="filled" fontcolor="white"]; - Node10 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; - Node10 [shape="box",label="PublicBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classPublicBase.html"]; - Node11 -> Node10 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; - Node11 [shape="box",label="Truncated",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="red",URL="$classTruncated.html"]; - Node13 -> Node9 [dir=back,color="darkgreen",fontsize=10,style="solid",fontname="Helvetica"]; - Node13 [shape="box",label="ProtectedBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classProtectedBase.html"]; - Node14 -> Node9 [dir=back,color="firebrick4",fontsize=10,style="solid",fontname="Helvetica"]; - Node14 [shape="box",label="PrivateBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classPrivateBase.html"]; - Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; - Node15 [shape="box",label="Undocumented",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="grey75"]; - Node16 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; - Node16 [shape="box",label="Templ< int >",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classTempl.html"]; - Node17 -> Node16 [dir=back,color="orange",fontsize=10,style="dashed",label="< int >",fontname="Helvetica"]; - Node17 [shape="box",label="Templ< T >",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classTempl.html"]; - Node18 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="m_usedClass",fontname="Helvetica"]; - Node18 [shape="box",label="Used",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classUsed.html"]; -} diff --git a/doc/html/graph_legend.html b/doc/html/graph_legend.html deleted file mode 100644 index eaf61c9..0000000 --- a/doc/html/graph_legend.html +++ /dev/null @@ -1,75 +0,0 @@ - - -uIP 0.9: Graph Legend - - - - -

    Graph Legend

    This page explains how to interpret the graphs that are generated by doxygen.

    -Consider the following example:

    /*! Invisible class because of truncation */
    -class Invisible { };
    -
    -/*! Truncated class, inheritance relation is hidden */
    -class Truncated : public Invisible { };
    -
    -/* Class not documented with doxygen comments */
    -class Undocumented { };
    -
    -/*! Class that is inherited using public inheritance */
    -class PublicBase : public Truncated { };
    -
    -/*! A template class */
    -template<class T> class Templ { };
    -
    -/*! Class that is inherited using protected inheritance */
    -class ProtectedBase { };
    -
    -/*! Class that is inherited using private inheritance */
    -class PrivateBase { };
    -
    -/*! Class that is used by the Inherited class */
    -class Used { };
    -
    -/*! Super class that inherits a number of other classes */
    -class Inherited : public PublicBase,
    -                  protected ProtectedBase,
    -                  private PrivateBase,
    -                  public Undocumented
    -                  public Templ<int>
    -{
    -  private:
    -    Used *m_usedClass;
    -};
    -
    If the MAX_DOT_GRAPH_HEIGHT tag in the configuration file is set to 240 this will result in the following graph:

    -

    -graph_legend.png -
    -

    -The boxes in the above graph have the following meaning:

      -
    • -A filled black box represents the struct or class for which the graph is generated.
    • -
    • -A box with a black border denotes a documented struct or class.
    • -
    • -A box with a grey border denotes an undocumented struct or class.
    • -
    • -A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
    • -
    -The arrows have the following meaning:
      -
    • -A dark blue arrow is used to visualize a public inheritance relation between two classes.
    • -
    • -A dark green arrow is used for protected inheritance.
    • -
    • -A dark red arrow is used for private inheritance.
    • -
    • -A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
    • -
    • -A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
    • -
    -
    Generated on Tue Oct 7 15:51:52 2003 for uIP 0.9 by - -doxygen -1.3.3
    - - diff --git a/doc/html/graph_legend.png b/doc/html/graph_legend.png deleted file mode 100644 index 8a116c2..0000000 Binary files a/doc/html/graph_legend.png and /dev/null differ diff --git a/doc/html/hierarchy.html b/doc/html/hierarchy.html new file mode 100644 index 0000000..4b3ba98 --- /dev/null +++ b/doc/html/hierarchy.html @@ -0,0 +1,50 @@ + + +uIP 1.0: Hierarchical Index + + + + + + +

    uIP 1.0 Class Hierarchy

    This inheritance list is sorted roughly, but not completely, alphabetically: +
    Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
    + + diff --git a/doc/html/index.hhc b/doc/html/index.hhc index 3d7036c..be5830e 100644 --- a/doc/html/index.hhc +++ b/doc/html/index.hhc @@ -7,120 +7,186 @@
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    +
  • +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
        +
      • +
          +
        +
      +
    • +
        +
      • +
          +
        +
      • +
          +
        +
      • +
          +
        +
      • +
          +
        +
      • +
          +
        +
      • -
      • +
        -
      • +
        -
      • +
        -
      • +
        -
      • +
        -
      • +
        -
      • +
        -
      • +
        -
      • +
      -
    • +
      • -
      • -
          -
        -
      • -
          -
        -
      • -
          -
        -
      • -
          -
      -
    • +
      • -
      • -
          -
        -
      • -
          -
        -
      • -
          -
        -
      • -
          -
        -
      • -
          -
        -
      • -
          -
        -
      • -
          -
        -
      • -
          -
        -
      • -
          -
      +
    • +
        +
      +
    • +
        +
      +
    • +
        +
      +
    +
  • +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
  • diff --git a/doc/html/index.hhk b/doc/html/index.hhk index 664e519..ac1b196 100644 --- a/doc/html/index.hhk +++ b/doc/html/index.hhk @@ -4,722 +4,447 @@
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • -
      -
    • -
        -
      • +
      • +
          +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        • +
        +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
          +
        • +
        • +
        +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
          +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        • +
        +
      • +
          +
        • +
        • +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      diff --git a/doc/html/index.hhp b/doc/html/index.hhp index 50ec072..d7d0725 100644 --- a/doc/html/index.hhp +++ b/doc/html/index.hhp @@ -8,52 +8,106 @@ Index file=index.hhk Language=0x409 English (United States) Binary TOC=YES Create CHI file=YES -Title=uIP 0.9 +Title=uIP 1.0 [WINDOWS] -main="uIP 0.9","index.hhc","index.hhk","main.html","main.html",,,,,0x23520,,0x387e,,,,,,,,0 +main="uIP 1.0","index.hhc","index.hhk","main.html","main.html",,,,,0x23520,,0x387e,,,,,,,,0 [FILES] main.html files.html +a00048.html a00049.html -a00050.html -a00051.html -a00052.html -a00053.html -a00054.html -a00055.html -a00056.html -a00057.html -a00058.html -a00059.html -a00060.html -a00061.html -a00062.html -a00063.html -a00064.html -a00065.html -a00067.html -a00068.html -a00069.html -a00070.html -a00071.html -a00072.html -a00073.html -a00074.html -annotated.html -classes.html -functions.html -functions_vars.html -a00030.html +a00042.html +a00043.html a00036.html a00037.html +a00046.html +a00047.html a00038.html a00039.html +a00044.html +a00045.html +a00051.html +a00050.html +a00040.html a00041.html -a00046.html -a00075.html -a00076.html +a00168.html +a00169.html +a00170.html +a00171.html +a00172.html +a00173.html +a00174.html +a00175.html +a00176.html +a00177.html +a00178.html +a00179.html +a00180.html +a00181.html +a00182.html +a00183.html +a00184.html +a00185.html +a00186.html +a00187.html +a00188.html +a00189.html +a00190.html +a00191.html +a00192.html +a00193.html +a00194.html +a00195.html +a00196.html +a00197.html +a00198.html +a00199.html +a00200.html +a00201.html +a00202.html +a00203.html +a00204.html +a00205.html +a00206.html +a00207.html +a00100.html +a00101.html +a00102.html +a00103.html +a00104.html +a00105.html +a00107.html +a00110.html +a00111.html +a00112.html +a00113.html +a00114.html +a00120.html +a00121.html +a00123.html +a00124.html +a00125.html +a00127.html +a00128.html +a00129.html +a00130.html +a00131.html +a00132.html +a00134.html +a00135.html +a00136.html +a00137.html +a00138.html +a00139.html +a00140.html +a00141.html +annotated.html +classes.html +hierarchy.html +functions.html +functions_vars.html a00077.html a00078.html a00079.html @@ -75,12 +129,69 @@ a00094.html a00095.html a00096.html a00097.html -a00098.html -a00099.html +a00142.html +a00143.html +a00144.html +a00145.html +a00146.html +a00147.html +a00148.html +a00149.html +a00150.html +a00151.html +a00152.html +a00153.html +a00154.html +a00155.html +a00156.html +a00157.html +a00158.html +a00159.html +a00160.html +a00161.html +a00162.html +a00163.html +a00164.html modules.html +examples.html globals.html +globals_0x61.html +globals_0x62.html +globals_0x64.html +globals_0x65.html +globals_0x66.html +globals_0x68.html +globals_0x69.html +globals_0x6c.html +globals_0x6d.html +globals_0x6e.html +globals_0x70.html +globals_0x72.html +globals_0x73.html +globals_0x74.html +globals_0x75.html +globals_0x77.html globals_func.html globals_vars.html globals_type.html globals_defs.html -graph_legend.html +globals_defs_0x61.html +globals_defs_0x62.html +globals_defs_0x64.html +globals_defs_0x65.html +globals_defs_0x66.html +globals_defs_0x68.html +globals_defs_0x69.html +globals_defs_0x6c.html +globals_defs_0x6d.html +globals_defs_0x6e.html +globals_defs_0x70.html +globals_defs_0x72.html +globals_defs_0x73.html +globals_defs_0x74.html +globals_defs_0x75.html +globals_defs_0x77.html +tabs.css +tab_b.gif +tab_l.gif +tab_r.gif diff --git a/doc/html/index.html b/doc/html/index.html index c1594de..b4bd670 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -1,6 +1,6 @@ -uIP 0.9 +uIP 1.0 diff --git a/doc/html/main.html b/doc/html/main.html index 605809b..ab1b46a 100644 --- a/doc/html/main.html +++ b/doc/html/main.html @@ -1,290 +1,314 @@ - + -uIP 0.9: The uIP TCP/IP stack +uIP 1.0: The uIP TCP/IP stack + - - -

      The uIP TCP/IP stack

      + + +

      The uIP TCP/IP stack

      -

      Author:
      Adam Dunkels <adam@dunkels.com>
      -The uIP TCP/IP stack is intended to make it possible to communicate using the TCP/IP protocol suite even on small 8-bit micro-controllers. Despite being small and simple, uIP do not require their peers to have complex, full-size stacks, but can communicate with peers running a similarly light-weight stack. The code size is on the order of a few kilobytes and RAM usage can be configured to be as low as a few hundred bytes.

      -uIP introduction

      +
      Author:
      Adam Dunkels, http://www.sics.se/~adam/
      +The uIP TCP/IP stack is intended to make it possible to communicate using the TCP/IP protocol suite even on small 8-bit micro-controllers. Despite being small and simple, uIP do not require their peers to have complex, full-size stacks, but can communicate with peers running a similarly light-weight stack. The code size is on the order of a few kilobytes and RAM usage can be configured to be as low as a few hundred bytes.

      +uIP can be found at the uIP web page: http://www.sics.se/~adam/uip/

      +

      See also:
      Application programs

      +Compile-time configuration options

      +Run-time configuration functions

      +Initialization functions

      +Device driver interface and variables used by device drivers

      +uIP functions called from application programs (see below) and the protosockets API and their underlying protothreads

      +

      +Introduction

      With the success of the Internet, the TCP/IP protocol suite has become a global standard for communication. TCP/IP is the underlying protocol used for web page transfers, e-mail transmissions, file transfers, and peer-to-peer networking over the Internet. For embedded systems, being able to run native TCP/IP makes it possible to connect the system directly to an intranet or even the global Internet. Embedded devices with full TCP/IP support will be first-class network citizens, thus being able to fully communicate with other hosts in the network.

      Traditional TCP/IP implementations have required far too much resources both in terms of code size and memory usage to be useful in small 8 or 16-bit systems. Code size of a few hundred kilobytes and RAM requirements of several hundreds of kilobytes have made it impossible to fit the full TCP/IP stack into systems with a few tens of kilobytes of RAM and room for less than 100 kilobytes of code.

      -The uIP implementation is designed to have only the absolute minimal set of features needed for a full TCP/IP stack. It can only handle a single network interface and contains only a rudimentary UDP implementation, but focuses on the IP, ICMP and TCP protocols. uIP is written in the C programming language.

      -Many other TCP/IP implementations for small systems assume that the embedded device always will communicate with a full-scale TCP/IP implementation running on a workstation-class machine. Under this assumption, it is possible to remove certain TCP/IP mechanisms that are very rarely used in such situations. Many of those mechanisms are essential, however, if the embedded device is to communicate with another equally limited device, e.g., when running distributed peer-to-peer services and protocols. uIP is designed to be RFC compliant in order to let the embedded devices to act as first-class network citizens. The uIP TCP/IP implementation that is not tailored for any specific application.

      -TCP/IP communication

      +The uIP implementation is designed to have only the absolute minimal set of features needed for a full TCP/IP stack. It can only handle a single network interface and contains the IP, ICMP, UDP and TCP protocols. uIP is written in the C programming language.

      +Many other TCP/IP implementations for small systems assume that the embedded device always will communicate with a full-scale TCP/IP implementation running on a workstation-class machine. Under this assumption, it is possible to remove certain TCP/IP mechanisms that are very rarely used in such situations. Many of those mechanisms are essential, however, if the embedded device is to communicate with another equally limited device, e.g., when running distributed peer-to-peer services and protocols. uIP is designed to be RFC compliant in order to let the embedded devices to act as first-class network citizens. The uIP TCP/IP implementation that is not tailored for any specific application.

      +TCP/IP Communication

      The full TCP/IP suite consists of numerous protocols, ranging from low level protocols such as ARP which translates IP addresses to MAC addresses, to application level protocols such as SMTP that is used to transfer e-mail. The uIP is mostly concerned with the TCP and IP protocols and upper layer protocols will be referred to as "the application". Lower layer protocols are often implemented in hardware or firmware and will be referred to as "the network device" that are controlled by the network device driver.

      TCP provides a reliable byte stream to the upper layer protocols. It breaks the byte stream into appropriately sized segments and each segment is sent in its own IP packet. The IP packets are sent out on the network by the network device driver. If the destination is not on the physically connected network, the IP packet is forwarded onto another network by a router that is situated between the two networks. If the maximum packet size of the other network is smaller than the size of the IP packet, the packet is fragmented into smaller packets by the router. If possible, the size of the TCP segments are chosen so that fragmentation is minimized. The final recipient of the packet will have to reassemble any fragmented IP packets before they can be passed to higher layers.

      The formal requirements for the protocols in the TCP/IP stack is specified in a number of RFC documents published by the Internet Engineering Task Force, IETF. Each of the protocols in the stack is defined in one more RFC documents and RFC1122 collects all requirements and updates the previous RFCs.

      The RFC1122 requirements can be divided into two categories; those that deal with the host to host communication and those that deal with communication between the application and the networking stack. An example of the first kind is "A TCP MUST be able to receive a TCP option in any segment" and an example of the second kind is "There MUST be a mechanism for reporting soft TCP error conditions to the application." A TCP/IP implementation that violates requirements of the first kind may not be able to communicate with other TCP/IP implementations and may even lead to network failures. Violation of the second kind of requirements will only affect the communication within the system and will not affect host-to-host communication.

      -In uIP, all RFC requirements that affect host-to-host communication are implemented. However, in order to reduce code size, we have removed certain mechanisms in the interface between the application and the stack, such as the soft error reporting mechanism and dynamically configurable type-of-service bits for TCP connections. Since there are only very few applications that make use of those features they can be removed without loss of generality.

      -Memory management

      +In uIP, all RFC requirements that affect host-to-host communication are implemented. However, in order to reduce code size, we have removed certain mechanisms in the interface between the application and the stack, such as the soft error reporting mechanism and dynamically configurable type-of-service bits for TCP connections. Since there are only very few applications that make use of those features they can be removed without loss of generality.

      +Main Control Loop

      +The uIP stack can be run either as a task in a multitasking system, or as the main program in a singletasking system. In both cases, the main control loop does two things repeatedly:

      +

        +
      • Check if a packet has arrived from the network.
      • Check if a periodic timeout has occurred.
      +

      +If a packet has arrived, the input handler function, uip_input(), should be invoked by the main control loop. The input handler function will never block, but will return at once. When it returns, the stack or the application for which the incoming packet was intended may have produced one or more reply packets which should be sent out. If so, the network device driver should be called to send out these packets.

      +Periodic timeouts are used to drive TCP mechanisms that depend on timers, such as delayed acknowledgments, retransmissions and round-trip time estimations. When the main control loop infers that the periodic timer should fire, it should invoke the timer handler function uip_periodic(). Because the TCP/IP stack may perform retransmissions when dealing with a timer event, the network device driver should called to send out the packets that may have been produced.

      +Architecture Specific Functions

      +uIP requires a few functions to be implemented specifically for the architecture on which uIP is intended to run. These functions should be hand-tuned for the particular architecture, but generic C implementations are given as part of the uIP distribution.

      +Checksum Calculation

      +The TCP and IP protocols implement a checksum that covers the data and header portions of the TCP and IP packets. Since the calculation of this checksum is made over all bytes in every packet being sent and received it is important that the function that calculates the checksum is efficient. Most often, this means that the checksum calculation must be fine-tuned for the particular architecture on which the uIP stack runs.

      +While uIP includes a generic checksum function, it also leaves it open for an architecture specific implementation of the two functions uip_ipchksum() and uip_tcpchksum(). The checksum calculations in those functions can be written in highly optimized assembler rather than generic C code.

      +32-bit Arithmetic

      +The TCP protocol uses 32-bit sequence numbers, and a TCP implementation will have to do a number of 32-bit additions as part of the normal protocol processing. Since 32-bit arithmetic is not natively available on many of the platforms for which uIP is intended, uIP leaves the 32-bit additions to be implemented by the architecture specific module and does not make use of any 32-bit arithmetic in the main code base.

      +While uIP implements a generic 32-bit addition, there is support for having an architecture specific implementation of the uip_add32() function.

      +Memory Management

      In the architectures for which uIP is intended, RAM is the most scarce resource. With only a few kilobytes of RAM available for the TCP/IP stack to use, mechanisms used in traditional TCP/IP cannot be directly applied.

      The uIP stack does not use explicit dynamic memory allocation. Instead, it uses a single global buffer for holding packets and has a fixed table for holding connection state. The global packet buffer is large enough to contain one packet of maximum size. When a packet arrives from the network, the device driver places it in the global buffer and calls the TCP/IP stack. If the packet contains data, the TCP/IP stack will notify the corresponding application. Because the data in the buffer will be overwritten by the next incoming packet, the application will either have to act immediately on the data or copy the data into a secondary buffer for later processing. The packet buffer will not be overwritten by new packets before the application has processed the data. Packets that arrive when the application is processing the data must be queued, either by the network device or by the device driver. Most single-chip Ethernet controllers have on-chip buffers that are large enough to contain at least 4 maximum sized Ethernet frames. Devices that are handled by the processor, such as RS-232 ports, can copy incoming bytes to a separate buffer during application processing. If the buffers are full, the incoming packet is dropped. This will cause performance degradation, but only when multiple connections are running in parallel. This is because uIP advertises a very small receiver window, which means that only a single TCP segment will be in the network per connection.

      In uIP, the same global packet buffer that is used for incoming packets is also used for the TCP/IP headers of outgoing data. If the application sends dynamic data, it may use the parts of the global packet buffer that are not used for headers as a temporary storage buffer. To send the data, the application passes a pointer to the data as well as the length of the data to the stack. The TCP/IP headers are written into the global buffer and once the headers have been produced, the device driver sends the headers and the application data out on the network. The data is not queued for retransmissions. Instead, the application will have to reproduce the data if a retransmission is necessary.

      -The total amount of memory usage for uIP depends heavily on the applications of the particular device in which the implementations are to be run. The memory configuration determines both the amount of traffic the system should be able to handle and the maximum amount of simultaneous connections. A device that will be sending large e-mails while at the same time running a web server with highly dynamic web pages and multiple simultaneous clients, will require more RAM than a simple Telnet server. It is possible to run the uIP implementation with as little as 200 bytes of RAM, but such a configuration will provide extremely low throughput and will only allow a small number of simultaneous connections.

      -Application program interface (API)

      +The total amount of memory usage for uIP depends heavily on the applications of the particular device in which the implementations are to be run. The memory configuration determines both the amount of traffic the system should be able to handle and the maximum amount of simultaneous connections. A device that will be sending large e-mails while at the same time running a web server with highly dynamic web pages and multiple simultaneous clients, will require more RAM than a simple Telnet server. It is possible to run the uIP implementation with as little as 200 bytes of RAM, but such a configuration will provide extremely low throughput and will only allow a small number of simultaneous connections.

      +Application Program Interface (API)

      The Application Program Interface (API) defines the way the application program interacts with the TCP/IP stack. The most commonly used API for TCP/IP is the BSD socket API which is used in most Unix systems and has heavily influenced the Microsoft Windows WinSock API. Because the socket API uses stop-and-wait semantics, it requires support from an underlying multitasking operating system. Since the overhead of task management, context switching and allocation of stack space for the tasks might be too high in the intended uIP target architectures, the BSD socket interface is not suitable for our purposes.

      -Instead, uIP uses an event driven interface where the application is invoked in response to certain events. An application running on top of uIP is implemented as a C function that is called by uIP in response to certain events. uIP calls the application when data is received, when data has been successfully delivered to the other end of the connection, when a new connection has been set up, or when data has to be retransmitted. The application is also periodically polled for new data. The application program provides only one callback function; it is up to the application to deal with mapping different network services to different ports and connections. Because the application is able to act on incoming data and connection requests as soon as the TCP/IP stack receives the packet, low response times can be achieved even in low-end systems.

      +uIP provides two APIs to programmers: protosockets, a BSD socket-like API without the overhead of full multi-threading, and a "raw" event-based API that is nore low-level than protosockets but uses less memory.

      +

      See also:
      Protosockets library

      +Protothreads

      +

      +The uIP raw API

      +The "raw" uIP API uses an event driven interface where the application is invoked in response to certain events. An application running on top of uIP is implemented as a C function that is called by uIP in response to certain events. uIP calls the application when data is received, when data has been successfully delivered to the other end of the connection, when a new connection has been set up, or when data has to be retransmitted. The application is also periodically polled for new data. The application program provides only one callback function; it is up to the application to deal with mapping different network services to different ports and connections. Because the application is able to act on incoming data and connection requests as soon as the TCP/IP stack receives the packet, low response times can be achieved even in low-end systems.

      uIP is different from other TCP/IP stacks in that it requires help from the application when doing retransmissions. Other TCP/IP stacks buffer the transmitted data in memory until the data is known to be successfully delivered to the remote end of the connection. If the data needs to be retransmitted, the stack takes care of the retransmission without notifying the application. With this approach, the data has to be buffered in memory while waiting for an acknowledgment even if the application might be able to quickly regenerate the data if a retransmission has to be made.

      -In order to reduce memory usage, uIP utilizes the fact that the application may be able to regenerate sent data and lets the application take part in retransmissions. uIP does not keep track of packet contents after they have been sent by the device driver, and uIP requires that the application takes an active part in performing the retransmission. When uIP decides that a segment should be retransmitted, it calls the application with a flag set indicating that a retransmission is required. The application checks the retransmission flag and produces the same data that was previously sent. From the application's standpoint, performing a retransmission is not different from how the data originally was sent. Therefore the application can be written in such a way that the same code is used both for sending data and retransmitting data. Also, it is important to note that even though the actual retransmission operation is carried out by the application, it is the responsibility of the stack to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions.

      -Application events

      -The application must be implemented as a C function, UIP_APPCALL(), that uIP calls whenever an event occurs. Each event has a corresponding test function that is used to distinguish between different events. The functions are implemented as C macros that will evaluate to either zero or non-zero. Note that certain events can happen in conjunction with each other (i.e., new data can arrive at the same time as data is acknowledged).

      -The connection pointer

      -When the application is called by uIP, the global variable uip_conn is set to point to the uip_conn structure for the connection that currently is handled, and is called the "current connection". The fields in the uip_conn structure for the current connection can be used, e.g., to distinguish between different services, or to check to which IP address the connection is connected. One typical use would be to inspect the uip_conn->lport (the local TCP port number) to decide which service the connection should provide. For instance, an application might decide to act as an HTTP server if the value of uip_conn->lport is equal to 80 and act as a TELNET server if the value is 23.

      -Receiving data

      -If the uIP test function uip_newdata() is non-zero, the remote host of the connection has sent new data. The uip_appdata pointer point to the actual data. The size of the data is obtained through the uIP function uip_datalen(). The data is not buffered by uIP, but will be overwritten after the application function returns, and the application will therefor have to either act directly on the incoming data, or by itself copy the incoming data into a buffer for later processing.

      -Sending data

      -When sending data, uIP adjusts the length of the data sent by the application according to the available buffer space and the current TCP window advertised by the receiver. The amount of buffer space is dictated by the memory configuration. It is therefore possible that all data sent from the application does not arrive at the receiver, and the application may use the uip_mss() function to see how much data that actually will be sent by the stack.

      -The application sends data by using the uIP function uip_send(). The uip_send() function takes two arguments; a pointer to the data to be sent and the length of the data. If the application needs RAM space for producing the actual data that should be sent, the packet buffer (pointed to by the uip_appdata pointer) can be used for this purpose.

      -The application can send only one chunk of data at a time on a connection and it is not possible to call uip_send() more than once per application invocation; only the data from the last call will be sent.

      -Retransmitting data

      -Retransmissions are driven by the periodic TCP timer. Every time the periodic timer is invoked, the retransmission timer for each connection is decremented. If the timer reaches zero, a retransmission should be made. As uIP does not keep track of packet contents after they have been sent by the device driver, uIP requires that the application takes an active part in performing the retransmission. When uIP decides that a segment should be retransmitted, the application function is called with the uip_rexmit() flag set, indicating that a retransmission is required.

      -The application must check the uip_rexmit() flag and produce the same data that was previously sent. From the application's standpoint, performing a retransmission is not different from how the data originally was sent. Therefor, the application can be written in such a way that the same code is used both for sending data and retransmitting data. Also, it is important to note that even though the actual retransmission operation is carried out by the application, it is the responsibility of the stack to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions.

      -Closing connections

      -The application closes the current connection by calling the uip_close() during an application call. This will cause the connection to be cleanly closed. In order to indicate a fatal error, the application might want to abort the connection and does so by calling the uip_abort() function.

      -If the connection has been closed by the remote end, the test function uip_closed() is true. The application may then do any necessary cleanups.

      -Reporting errors

      -There are two fatal errors that can happen to a connection, either that the connection was aborted by the remote host, or that the connection retransmitted the last data too many times and has been aborted. uIP reports this by calling the application function. The application can use the two test functions uip_aborted() and uip_timedout() to test for those error conditions.

      -Polling

      -When a connection is idle, uIP polls the application every time the periodic timer fires. The application uses the test function uip_poll() to check if it is being polled by uIP.

      -The polling event has two purposes. The first is to let the application periodically know that a connection is idle, which allows the application to close connections that have been idle for too long. The other purpose is to let the application send new data that has been produced. The application can only send data when invoked by uIP, and therefore the poll event is the only way to send data on an otherwise idle connection.

      -Listening ports

      -uIP maintains a list of listening TCP ports. A new port is opened for listening with the uip_listen() function. When a connection request arrives on a listening port, uIP creates a new connection and calls the application function. The test function uip_connected() is true if the application was invoked because a new connection was created.

      -The application can check the lport field in the uip_conn structure to check to which port the new connection was connected.

      -Opening connections

      -New connections can be opened from within uIP by the function uip_connect(). This function allocates a new connection and sets a flag in the connection state which will open a TCP connection to the specified IP address and port the next time the connection is polled by uIP. The uip_connect() function returns a pointer to the uip_conn structure for the new connection. If there are no free connection slots, the function returns NULL.

      -The function uip_ipaddr() may be used to pack an IP address into the two element 16-bit array used by uIP to represent IP addresses.

      -Two examples of usage are shown below. The first example shows how to open a connection to TCP port 8080 of the remote end of the current connection. If there are not enough TCP connection slots to allow a new connection to be opened, the uip_connect() function returns NULL and the current connection is aborted by uip_abort().

      -

      void connect_example1_app(void) {
      -   if(uip_connect(uip_conn->ripaddr, HTONS(8080)) == NULL) {
      -      uip_abort();
      +In order to reduce memory usage, uIP utilizes the fact that the application may be able to regenerate sent data and lets the application take part in retransmissions. uIP does not keep track of packet contents after they have been sent by the device driver, and uIP requires that the application takes an active part in performing the retransmission. When uIP decides that a segment should be retransmitted, it calls the application with a flag set indicating that a retransmission is required. The application checks the retransmission flag and produces the same data that was previously sent. From the application's standpoint, performing a retransmission is not different from how the data originally was sent. Therefore the application can be written in such a way that the same code is used both for sending data and retransmitting data. Also, it is important to note that even though the actual retransmission operation is carried out by the application, it is the responsibility of the stack to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions.

      +Application Events

      +The application must be implemented as a C function, UIP_APPCALL(), that uIP calls whenever an event occurs. Each event has a corresponding test function that is used to distinguish between different events. The functions are implemented as C macros that will evaluate to either zero or non-zero. Note that certain events can happen in conjunction with each other (i.e., new data can arrive at the same time as data is acknowledged).

      +The Connection Pointer

      +When the application is called by uIP, the global variable uip_conn is set to point to the uip_conn structure for the connection that currently is handled, and is called the "current connection". The fields in the uip_conn structure for the current connection can be used, e.g., to distinguish between different services, or to check to which IP address the connection is connected. One typical use would be to inspect the uip_conn->lport (the local TCP port number) to decide which service the connection should provide. For instance, an application might decide to act as an HTTP server if the value of uip_conn->lport is equal to 80 and act as a TELNET server if the value is 23.

      +Receiving Data

      +If the uIP test function uip_newdata() is non-zero, the remote host of the connection has sent new data. The uip_appdata pointer point to the actual data. The size of the data is obtained through the uIP function uip_datalen(). The data is not buffered by uIP, but will be overwritten after the application function returns, and the application will therefor have to either act directly on the incoming data, or by itself copy the incoming data into a buffer for later processing.

      +Sending Data

      +When sending data, uIP adjusts the length of the data sent by the application according to the available buffer space and the current TCP window advertised by the receiver. The amount of buffer space is dictated by the memory configuration. It is therefore possible that all data sent from the application does not arrive at the receiver, and the application may use the uip_mss() function to see how much data that actually will be sent by the stack.

      +The application sends data by using the uIP function uip_send(). The uip_send() function takes two arguments; a pointer to the data to be sent and the length of the data. If the application needs RAM space for producing the actual data that should be sent, the packet buffer (pointed to by the uip_appdata pointer) can be used for this purpose.

      +The application can send only one chunk of data at a time on a connection and it is not possible to call uip_send() more than once per application invocation; only the data from the last call will be sent.

      +Retransmitting Data

      +Retransmissions are driven by the periodic TCP timer. Every time the periodic timer is invoked, the retransmission timer for each connection is decremented. If the timer reaches zero, a retransmission should be made. As uIP does not keep track of packet contents after they have been sent by the device driver, uIP requires that the application takes an active part in performing the retransmission. When uIP decides that a segment should be retransmitted, the application function is called with the uip_rexmit() flag set, indicating that a retransmission is required.

      +The application must check the uip_rexmit() flag and produce the same data that was previously sent. From the application's standpoint, performing a retransmission is not different from how the data originally was sent. Therefor, the application can be written in such a way that the same code is used both for sending data and retransmitting data. Also, it is important to note that even though the actual retransmission operation is carried out by the application, it is the responsibility of the stack to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions.

      +Closing Connections

      +The application closes the current connection by calling the uip_close() during an application call. This will cause the connection to be cleanly closed. In order to indicate a fatal error, the application might want to abort the connection and does so by calling the uip_abort() function.

      +If the connection has been closed by the remote end, the test function uip_closed() is true. The application may then do any necessary cleanups.

      +Reporting Errors

      +There are two fatal errors that can happen to a connection, either that the connection was aborted by the remote host, or that the connection retransmitted the last data too many times and has been aborted. uIP reports this by calling the application function. The application can use the two test functions uip_aborted() and uip_timedout() to test for those error conditions.

      +Polling

      +When a connection is idle, uIP polls the application every time the periodic timer fires. The application uses the test function uip_poll() to check if it is being polled by uIP.

      +The polling event has two purposes. The first is to let the application periodically know that a connection is idle, which allows the application to close connections that have been idle for too long. The other purpose is to let the application send new data that has been produced. The application can only send data when invoked by uIP, and therefore the poll event is the only way to send data on an otherwise idle connection.

      +Listening Ports

      +uIP maintains a list of listening TCP ports. A new port is opened for listening with the uip_listen() function. When a connection request arrives on a listening port, uIP creates a new connection and calls the application function. The test function uip_connected() is true if the application was invoked because a new connection was created.

      +The application can check the lport field in the uip_conn structure to check to which port the new connection was connected.

      +Opening Connections

      +New connections can be opened from within uIP by the function uip_connect(). This function allocates a new connection and sets a flag in the connection state which will open a TCP connection to the specified IP address and port the next time the connection is polled by uIP. The uip_connect() function returns a pointer to the uip_conn structure for the new connection. If there are no free connection slots, the function returns NULL.

      +The function uip_ipaddr() may be used to pack an IP address into the two element 16-bit array used by uIP to represent IP addresses.

      +Two examples of usage are shown below. The first example shows how to open a connection to TCP port 8080 of the remote end of the current connection. If there are not enough TCP connection slots to allow a new connection to be opened, the uip_connect() function returns NULL and the current connection is aborted by uip_abort().

      +

      void connect_example1_app(void) {
      +   if(uip_connect(uip_conn->ripaddr, HTONS(8080)) == NULL) {
      +      uip_abort();
          }
       }   
       

      The second example shows how to open a new connection to a specific IP address. No error checks are made in this example.

      -

      void connect_example2(void) {
      -   u16_t ipaddr[2];
      +
      void connect_example2(void) {
      +   u16_t ipaddr[2];
       
      -   uip_ipaddr(ipaddr, 192,168,0,1);
      -   uip_connect(ipaddr, HTONS(8080));
      +   uip_ipaddr(ipaddr, 192,168,0,1);
      +   uip_connect(ipaddr, HTONS(8080));
       }
      -

      -uIP device drivers

      -From the network device driver's standpoint, uIP consists of two C functions: uip_input() and uip_periodic(). The uip_input() function should be called by the device driver when an IP packet has been received and put into the uip_buf packet buffer. The uip_input() function will process the packet, and when it returns an outbound packet may have been placed in the same uip_buf packet buffer (indicated by the uip_len variable being non-zero). The device driver should then send out this packet onto the network.

      -The uip_periodic() function should be invoked periodically once per connection by the device driver, typically one per second. This function is used by uIP to drive protocol timers and retransmissions, and when it returns it may have placed an outbound packet in the uip_buf buffer.

      -Architecture specific functions

      -uIP requires a few functions to be implemented specifically for the architecture on which uIP is intended to run. These functions should be hand-tuned for the particular architecture, but generic C implementations are given as part of the uIP distribution.

      -Checksum calculation

      -The TCP and IP protocols implement a checksum that covers the data and header portions of the TCP and IP packets. Since the calculation of this checksum is made over all bytes in every packet being sent and received it is important that the function that calculates the checksum is efficient. Most often, this means that the checksum calculation must be fine-tuned for the particular architecture on which the uIP stack runs.

      -Because of this, uIP does not implement a generic checksum function, but leaves this to the architecture specific files which must implement the two functions uip_ipchksum() and uip_tcpchksum(). The checksum calculations in those functions can be written in highly optimized assembler rather than generic C code.

      -An example C implementation of the checksum function is provided in the uIP distribution.

      -32-bit arithmetic

      -The TCP protocol uses 32-bit sequence numbers, and a TCP implementation will have to do a number of 32-bit additions as part of the normal protocol processing. Since 32-bit arithmetic is not natively available on many of the platforms for which uIP is intended, uIP leaves the 32-bit additions to be implemented by the architecture specific module and does not make use of any 32-bit arithmetic in the main code base.

      -The architecture specific code must implement a function uip_add32() which does a 32-bit addition and stores the result in a global variable uip_acc32.

      -Examples

      -This section presents a number of very simple uIP applications. The uIP code distribution contains several more complex applications.

      -A very simple application

      +

      +Examples

      +This section presents a number of very simple uIP applications. The uIP code distribution contains several more complex applications.

      +A Very Simple Application

      This first example shows a very simple application. The application listens for incoming connections on port 1234. When a connection has been established, the application replies to all data sent to it by saying "ok"

      The implementation of this application is shown below. The application is initialized with the function called example1_init() and the uIP callback function is called example1_app(). For this application, the configuration variable UIP_APPCALL should be defined to be example1_app().

      -

      void example1_init(void) {
      -   uip_listen(HTONS(1234));
      +
      void example1_init(void) {
      +   uip_listen(HTONS(1234));
       }
       
       void example1_app(void) {
      -   if(uip_newdata() || uip_rexmit()) {
      -      uip_send("ok\n", 3);
      +   if(uip_newdata() || uip_rexmit()) {
      +      uip_send("ok\n", 3);
          }
       }
       

      -The initialization function calls the uIP function uip_listen() to register a listening port. The actual application function example1_app() uses the test functions uip_newdata() and uip_rexmit() to determine why it was called. If the application was called because the remote end has sent it data, it responds with an "ok". If the application function was called because data was lost in the network and has to be retransmitted, it also sends an "ok". Note that this example actually shows a complete uIP application. It is not required for an application to deal with all types of events such as uip_connected() or uip_timedout().

      -A more advanced application

      -This second example is slightly more advanced than the previous one, and shows how the application state field in the uip_conn structure is used.

      +The initialization function calls the uIP function uip_listen() to register a listening port. The actual application function example1_app() uses the test functions uip_newdata() and uip_rexmit() to determine why it was called. If the application was called because the remote end has sent it data, it responds with an "ok". If the application function was called because data was lost in the network and has to be retransmitted, it also sends an "ok". Note that this example actually shows a complete uIP application. It is not required for an application to deal with all types of events such as uip_connected() or uip_timedout().

      +A More Advanced Application

      +This second example is slightly more advanced than the previous one, and shows how the application state field in the uip_conn structure is used.

      This application is similar to the first application in that it listens to a port for incoming connections and responds to data sent to it with a single "ok". The big difference is that this application prints out a welcoming "Welcome!" message when the connection has been established.

      This seemingly small change of operation makes a big difference in how the application is implemented. The reason for the increase in complexity is that if data should be lost in the network, the application must know what data to retransmit. If the "Welcome!" message was lost, the application must retransmit the welcome and if one of the "ok" messages is lost, the application must send a new "ok".

      The application knows that as long as the "Welcome!" message has not been acknowledged by the remote host, it might have been dropped in the network. But once the remote host has sent an acknowledgment back, the application can be sure that the welcome has been received and knows that any lost data must be an "ok" message. Thus the application can be in either of two states: either in the WELCOME-SENT state where the "Welcome!" has been sent but not acknowledged, or in the WELCOME-ACKED state where the "Welcome!" has been acknowledged.

      When a remote host connects to the application, the application sends the "Welcome!" message and sets it's state to WELCOME-SENT. When the welcome message is acknowledged, the application moves to the WELCOME-ACKED state. If the application receives any new data from the remote host, it responds by sending an "ok" back.

      If the application is requested to retransmit the last message, it looks at in which state the application is. If the application is in the WELCOME-SENT state, it sends a "Welcome!" message since it knows that the previous welcome message hasn't been acknowledged. If the application is in the WELCOME-ACKED state, it knows that the last message was an "ok" message and sends such a message.

      The implementation of this application is seen below. This configuration settings for the application is follows after its implementation.

      -

      struct example2_state {
      +
      struct example2_state {
          enum {WELCOME_SENT, WELCOME_ACKED} state;
       };
       
       void example2_init(void) {
      -   uip_listen(HTONS(2345));
      +   uip_listen(HTONS(2345));
       }
       
       void example2_app(void) {
          struct example2_state *s;
       
      -   s = (struct example2_state *)uip_conn->appstate;
      +   s = (struct example2_state *)uip_conn->appstate;
          
      -   if(uip_connected()) {
      +   if(uip_connected()) {
             s->state = WELCOME_SENT;
      -      uip_send("Welcome!\n", 9);
      +      uip_send("Welcome!\n", 9);
             return;
          } 
       
      -   if(uip_acked() && s->state == WELCOME_SENT) {
      +   if(uip_acked() && s->state == WELCOME_SENT) {
             s->state = WELCOME_ACKED;
          }
       
      -   if(uip_newdata()) {
      -      uip_send("ok\n", 3);
      +   if(uip_newdata()) {
      +      uip_send("ok\n", 3);
          }
       
      -   if(uip_rexmit()) {
      +   if(uip_rexmit()) {
             switch(s->state) {
             case WELCOME_SENT:
      -         uip_send("Welcome!\n", 9);
      +         uip_send("Welcome!\n", 9);
                break;
             case WELCOME_ACKED:
      -         uip_send("ok\n", 3);
      +         uip_send("ok\n", 3);
                break;
             }
          }
       }
       

      The configuration for the application:

      -

      #define UIP_APPCALL       example2_app
      +
      #define UIP_APPCALL       example2_app
       #define UIP_APPSTATE_SIZE sizeof(struct example2_state)
      -

      -Differentiating between applications

      +

      +Differentiating Between Applications

      If the system should run multiple applications, one technique to differentiate between them is to use the TCP port number of either the remote end or the local end of the connection. The example below shows how the two examples above can be combined into one application.

      -

      void example3_init(void) {
      +
      void example3_init(void) {
          example1_init();
          example2_init();   
       }
       
       void example3_app(void) {
      -   switch(uip_conn->lport) {
      -   case HTONS(1234):
      +   switch(uip_conn->lport) {
      +   case HTONS(1234):
             example1_app();
             break;
      -   case HTONS(2345):
      +   case HTONS(2345):
             example2_app();
             break;
          }
       }
      -

      -Utilizing TCP flow control

      +

      +Utilizing TCP Flow Control

      This example shows a simple application that connects to a host, sends an HTTP request for a file and downloads it to a slow device such a disk drive. This shows how to use the flow control functions of uIP.

      -

      void example4_init(void) {
      -   u16_t ipaddr[2];
      -   uip_ipaddr(ipaddr, 192,168,0,1);
      -   uip_connect(ipaddr, HTONS(80));
      +
      void example4_init(void) {
      +   u16_t ipaddr[2];
      +   uip_ipaddr(ipaddr, 192,168,0,1);
      +   uip_connect(ipaddr, HTONS(80));
       }
       
       void example4_app(void) {
      -   if(uip_connected() || uip_rexmit()) {
      -      uip_send("GET /file HTTP/1.0\r\nServer:192.186.0.1\r\n\r\n",
      +   if(uip_connected() || uip_rexmit()) {
      +      uip_send("GET /file HTTP/1.0\r\nServer:192.186.0.1\r\n\r\n",
                      48);
             return;
          }
       
      -   if(uip_newdata()) {
      -      device_enqueue(uip_appdata, uip_datalen());
      +   if(uip_newdata()) {
      +      device_enqueue(uip_appdata, uip_datalen());
             if(device_queue_full()) {
      -         uip_stop();
      +         uip_stop();
             }
          }
       
      -   if(uip_poll() && uip_stopped()) {
      +   if(uip_poll() && uip_stopped()) {
             if(!device_queue_full()) {
      -         uip_restart();
      +         uip_restart();
             }
          }
       }
       

      When the connection has been established, an HTTP request is sent to the server. Since this is the only data that is sent, the application knows that if it needs to retransmit any data, it is that request that should be retransmitted. It is therefore possible to combine these two events as is done in the example.

      When the application receives new data from the remote host, it sends this data to the device by using the function device_enqueue(). It is important to note that this example assumes that this function copies the data into its own buffers. The data in the uip_appdata buffer will be overwritten by the next incoming packet.

      -If the device's queue is full, the application stops the data from the remote host by calling the uIP function uip_stop(). The application can then be sure that it will not receive any new data until uip_restart() is called. The application polling event is used to check if the device's queue is no longer full and if so, the data flow is restarted with uip_restart().

      -A simple web server

      +If the device's queue is full, the application stops the data from the remote host by calling the uIP function uip_stop(). The application can then be sure that it will not receive any new data until uip_restart() is called. The application polling event is used to check if the device's queue is no longer full and if so, the data flow is restarted with uip_restart().

      +A Simple Web Server

      This example shows a very simple file server application that listens to two ports and uses the port number to determine which file to send. If the files are properly formatted, this simple application can be used as a web server with static pages. The implementation follows.

      -

      struct example5_state {
      +
      struct example5_state {
          char *dataptr;
          unsigned int dataleft;
       };
       
       void example5_init(void) {
      -   uip_listen(HTONS(80));
      -   uip_listen(HTONS(81));
      +   uip_listen(HTONS(80));
      +   uip_listen(HTONS(81));
       }
       
       void example5_app(void) {
          struct example5_state *s;
      -   s = (struct example5_state)uip_conn->appstate;
      +   s = (struct example5_state)uip_conn->appstate;
          
      -   if(uip_connected()) {
      -      switch(uip_conn->lport) {
      -      case HTONS(80):
      +   if(uip_connected()) {
      +      switch(uip_conn->lport) {
      +      case HTONS(80):
                s->dataptr = data_port_80;
                s->dataleft = datalen_port_80;
                break;
      -      case HTONS(81):
      +      case HTONS(81):
                s->dataptr = data_port_81;
                s->dataleft = datalen_port_81;
                break;
             }
      -      uip_send(s->dataptr, s->dataleft);
      +      uip_send(s->dataptr, s->dataleft);
             return;      
          }
       
      -   if(uip_acked()) {
      -      if(s->dataleft < uip_mss()) {
      -         uip_close();
      +   if(uip_acked()) {
      +      if(s->dataleft < uip_mss()) {
      +         uip_close();
                return;
             }
      -      s->dataptr += uip_conn->len;
      -      s->dataleft -= uip_conn->len;
      -      uip_send(s->dataptr, s->dataleft);      
      +      s->dataptr += uip_conn->len;
      +      s->dataleft -= uip_conn->len;
      +      uip_send(s->dataptr, s->dataleft);      
          }
       }
       

      -The application state consists of a pointer to the data that should be sent and the size of the data that is left to send. When a remote host connects to the application, the local port number is used to determine which file to send. The first chunk of data is sent using uip_send(). uIP makes sure that no more than MSS bytes of data is actually sent, even though s->dataleft may be larger than the MSS.

      -The application is driven by incoming acknowledgments. When data has been acknowledged, new data can be sent. If there is no more data to send, the connection is closed using uip_close().

      -Structured application program design

      -When writing larger programs using uIP it is useful to be able to utilize the uIP API in a structured way. The following example provides a structured design that has showed itself to be useful for writing larger protocol implementations than the previous examples showed here. The program is divided into an uIP event handler function that calls seven application handler functions that process new data, act on acknowledged data, send new data, deal with connection establishment or closure events and handle errors. The functions are called newdata(), acked(), senddata(), connected(), closed(), aborted(), and timedout(), and needs to be written specifically for the protocol that is being implemented.

      +The application state consists of a pointer to the data that should be sent and the size of the data that is left to send. When a remote host connects to the application, the local port number is used to determine which file to send. The first chunk of data is sent using uip_send(). uIP makes sure that no more than MSS bytes of data is actually sent, even though s->dataleft may be larger than the MSS.

      +The application is driven by incoming acknowledgments. When data has been acknowledged, new data can be sent. If there is no more data to send, the connection is closed using uip_close().

      +Structured Application Program Design

      +When writing larger programs using uIP it is useful to be able to utilize the uIP API in a structured way. The following example provides a structured design that has showed itself to be useful for writing larger protocol implementations than the previous examples showed here. The program is divided into an uIP event handler function that calls seven application handler functions that process new data, act on acknowledged data, send new data, deal with connection establishment or closure events and handle errors. The functions are called newdata(), acked(), senddata(), connected(), closed(), aborted(), and timedout(), and needs to be written specifically for the protocol that is being implemented.

      The uIP event handler function is shown below.

      -

      void example6_app(void) {
      -  if(uip_aborted()) {
      +
      void example6_app(void) {
      +  if(uip_aborted()) {
           aborted();
         }
      -  if(uip_timedout()) {
      +  if(uip_timedout()) {
           timedout();
         }
      -  if(uip_closed()) {
      +  if(uip_closed()) {
           closed();
         }
      -  if(uip_connected()) {
      +  if(uip_connected()) {
           connected();
         }
      -  if(uip_acked()) {
      +  if(uip_acked()) {
           acked();
         }
      -  if(uip_newdata()) {
      +  if(uip_newdata()) {
           newdata();
         }
      -  if(uip_rexmit() ||
      -     uip_newdata() ||
      -     uip_acked() ||
      -     uip_connected() ||
      -     uip_poll()) {
      +  if(uip_rexmit() ||
      +     uip_newdata() ||
      +     uip_acked() ||
      +     uip_connected() ||
      +     uip_poll()) {
           senddata();
         }
       }
       

      -The function starts with dealing with any error conditions that might have happened by checking if uip_aborted() or uip_timedout() are true. If so, the appropriate error function is called. Also, if the connection has been closed, the closed() function is called to the it deal with the event.

      -Next, the function checks if the connection has just been established by checking if uip_connected() is true. The connected() function is called and is supposed to do whatever needs to be done when the connection is established, such as intializing the application state for the connection. Since it may be the case that data should be sent out, the senddata() function is called to deal with the outgoing data.

      +The function starts with dealing with any error conditions that might have happened by checking if uip_aborted() or uip_timedout() are true. If so, the appropriate error function is called. Also, if the connection has been closed, the closed() function is called to the it deal with the event.

      +Next, the function checks if the connection has just been established by checking if uip_connected() is true. The connected() function is called and is supposed to do whatever needs to be done when the connection is established, such as intializing the application state for the connection. Since it may be the case that data should be sent out, the senddata() function is called to deal with the outgoing data.

      The following very simple application serves as an example of how the application handler functions might look. This application simply waits for any data to arrive on the connection, and responds to the data by sending out the message "Hello world!". To illustrate how to develop an application state machine, this message is sent in two parts, first the "Hello" part and then the "world!" part.

      -

      #define STATE_WAITING 0
      +
      #define STATE_WAITING 0
       #define STATE_HELLO   1
       #define STATE_WORLD   2
       
       struct example6_state {
      -  u8_t state;
      +  u8_t state;
         char *textptr;
         int  textlen;
       };
      @@ -294,16 +318,16 @@ The following very simple application serves as an example of how the applicatio
       static void closed(void) {}
       
       static void connected(void) {
      -  struct example6_state *s = (struct example6_state *)uip_conn->appstate;
      +  struct example6_state *s = (struct example6_state *)uip_conn->appstate;
       
      -  s->state   = STATE_WAITING;
      +  s->state   = STATE_WAITING;
         s->textlen = 0;
       }
       
       static void newdata(void) {
      -  struct example6_state *s = (struct example6_state *)uip_conn->appstate;
      +  struct example6_state *s = (struct example6_state *)uip_conn->appstate;
       
      -  if(s->state == STATE_WAITING) {
      +  if(s->state == STATE_WAITING) {
           s->state   = STATE_HELLO;
           s->textptr = "Hello ";
           s->textlen = 6;
      @@ -311,10 +335,10 @@ The following very simple application serves as an example of how the applicatio
       }
       
       static void acked(void) {
      -  struct example6_state *s = (struct example6_state *)uip_conn->appstate;
      +  struct example6_state *s = (struct example6_state *)uip_conn->appstate;
         
      -  s->textlen -= uip_conn->len;
      -  s->textptr += uip_conn->len;
      +  s->textlen -= uip_conn->len;
      +  s->textptr += uip_conn->len;
         if(s->textlen == 0) {
           switch(s->state) {
           case STATE_HELLO:
      @@ -323,29 +347,75 @@ The following very simple application serves as an example of how the applicatio
             s->textlen = 7;
             break;
           case STATE_WORLD:
      -      uip_close();
      +      uip_close();
             break;
           }
         }
       }
       
       static void senddata(void) {
      -  struct example6_state *s = (struct example6_state *)uip_conn->appstate;
      +  struct example6_state *s = (struct example6_state *)uip_conn->appstate;
       
         if(s->textlen > 0) {
      -    uip_send(s->textptr, s->textlen);
      +    uip_send(s->textptr, s->textlen);
         }
       }
       

      The application state consists of a "state" variable, a "textptr" pointer to a text message and the "textlen" length of the text message. The "state" variable can be either "STATE_WAITING", meaning that the application is waiting for data to arrive from the network, "STATE_HELLO", in which the application is sending the "Hello" part of the message, or "STATE_WORLD", in which the application is sending the "world!" message.

      -The application does not handle errors or connection closing events, and therefore the aborted(), timedout() and closed() functions are implemented as empty functions.

      +The application does not handle errors or connection closing events, and therefore the aborted(), timedout() and closed() functions are implemented as empty functions.

      The connected() function will be called when a connection has been established, and in this case sets the "state" variable to be "STATE_WAITING" and the "textlen" variable to be zero, indicating that there is no message to be sent out.

      -When new data arrives from the network, the newdata() function will be called by the event handler function. The newdata() function will check if the connection is in the "STATE_WAITING" state, and if so switches to the "STATE_HELLO" state and registers a 6 byte long "Hello " message with the connection. This message will later be sent out by the senddata() function.

      -The acked() function is called whenever data that previously was sent has been acknowleged by the receiving host. This acked() function first reduces the amount of data that is left to send, by subtracting the length of the previously sent data (obtained from "uip_conn->len") from the "textlen" variable, and also adjusts the "textptr" pointer accordingly. It then checks if the "textlen" variable now is zero, which indicates that all data now has been successfully received, and if so changes application state. If the application was in the "STATE_HELLO" state, it switches state to "STATE_WORLD" and sets up a 7 byte "world!\n" message to be sent. If the application was in the "STATE_WORLD" state, it closes the connection.

      -Finally, the senddata() function takes care of actually sending the data that is to be sent. It is called by the event handler function when new data has been received, when data has been acknowledged, when a new connection has been established, when the connection is polled because of inactivity, or when a retransmission should be made. The purpose of the senddata() function is to optionally format the data that is to be sent, and to call the uip_send() function to actually send out the data. In this particular example, the function simply calls uip_send() with the appropriate arguments if data is to be sent, after checking if data should be sent out or not as indicated by the "textlen" variable.

      -It is important to note that the senddata() function never should affect the application state; this should only be done in the acked() and newdata() functions.


      Generated on Tue Oct 7 15:51:00 2003 for uIP 0.9 by +When new data arrives from the network, the newdata() function will be called by the event handler function. The newdata() function will check if the connection is in the "STATE_WAITING" state, and if so switches to the "STATE_HELLO" state and registers a 6 byte long "Hello " message with the connection. This message will later be sent out by the senddata() function.

      +The acked() function is called whenever data that previously was sent has been acknowleged by the receiving host. This acked() function first reduces the amount of data that is left to send, by subtracting the length of the previously sent data (obtained from "uip_conn->len") from the "textlen" variable, and also adjusts the "textptr" pointer accordingly. It then checks if the "textlen" variable now is zero, which indicates that all data now has been successfully received, and if so changes application state. If the application was in the "STATE_HELLO" state, it switches state to "STATE_WORLD" and sets up a 7 byte "world!\n" message to be sent. If the application was in the "STATE_WORLD" state, it closes the connection.

      +Finally, the senddata() function takes care of actually sending the data that is to be sent. It is called by the event handler function when new data has been received, when data has been acknowledged, when a new connection has been established, when the connection is polled because of inactivity, or when a retransmission should be made. The purpose of the senddata() function is to optionally format the data that is to be sent, and to call the uip_send() function to actually send out the data. In this particular example, the function simply calls uip_send() with the appropriate arguments if data is to be sent, after checking if data should be sent out or not as indicated by the "textlen" variable.

      +It is important to note that the senddata() function never should affect the application state; this should only be done in the acked() and newdata() functions.

      +Protocol Implementations

      +The protocols in the TCP/IP protocol suite are designed in a layered fashion where each protocol performs a specific function and the interactions between the protocol layers are strictly defined. While the layered approach is a good way to design protocols, it is not always the best way to implement them. In uIP, the protocol implementations are tightly coupled in order to save code space.

      +This section gives detailed information on the specific protocol implementations in uIP.

      +IP --- Internet Protocol

      +When incoming packets are processed by uIP, the IP layer is the first protocol that examines the packet. The IP layer does a few simple checks such as if the destination IP address of the incoming packet matches any of the local IP address and verifies the IP header checksum. Since there are no IP options that are strictly required and because they are very uncommon, any IP options in received packets are dropped.

      +IP Fragment Reassembly

      +IP fragment reassembly is implemented using a separate buffer that holds the packet to be reassembled. An incoming fragment is copied into the right place in the buffer and a bit map is used to keep track of which fragments have been received. Because the first byte of an IP fragment is aligned on an 8-byte boundary, the bit map requires a small amount of memory. When all fragments have been reassembled, the resulting IP packet is passed to the transport layer. If all fragments have not been received within a specified time frame, the packet is dropped.

      +The current implementation only has a single buffer for holding packets to be reassembled, and therefore does not support simultaneous reassembly of more than one packet. Since fragmented packets are uncommon, this ought to be a reasonable decision. Extending the implementation to support multiple buffers would be straightforward, however.

      +Broadcasts and Multicasts

      +IP has the ability to broadcast and multicast packets on the local network. Such packets are addressed to special broadcast and multicast addresses. Broadcast is used heavily in many UDP based protocols such as the Microsoft Windows file-sharing SMB protocol. Multicast is primarily used in protocols used for multimedia distribution such as RTP. TCP is a point-to-point protocol and does not use broadcast or multicast packets. uIP current supports broadcast packets as well as sending multicast packets. Joining multicast groups (IGMP) and receiving non-local multicast packets is not currently supported.

      +ICMP --- Internet Control Message Protocol

      +The ICMP protocol is used for reporting soft error conditions and for querying host parameters. Its main use is, however, the echo mechanism which is used by the "ping" program.

      +The ICMP implementation in uIP is very simple as itis restricted to only implement ICMP echo messages. Replies to echo messages are constructed by simply swapping the source and destination IP addresses of incoming echo requests and rewriting the ICMP header with the Echo-Reply message type. The ICMP checksum is adjusted using standard techniques (see RFC1624).

      +Since only the ICMP echo message is implemented, there is no support for Path MTU discovery or ICMP redirect messages. Neither of these is strictly required for interoperability; they are performance enhancement mechanisms.

      +TCP --- Transmission Control Protocol

      +The TCP implementation in uIP is driven by incoming packets and timer events. Incoming packets are parsed by TCP and if the packet contains data that is to be delivered to the application, the application is invoked by the means of the application function call. If the incoming packet acknowledges previously sent data, the connection state is updated and the application is informed, allowing it to send out new data.

      +Listening Connections

      +TCP allows a connection to listen for incoming connection requests. In uIP, a listening connection is identified by the 16-bit port number and incoming connection requests are checked against the list of listening connections. This list of listening connections is dynamic and can be altered by the applications in the system.

      +Sliding Window

      +Most TCP implementations use a sliding window mechanism for sending data. Multiple data segments are sent in succession without waiting for an acknowledgment for each segment.

      +The sliding window algorithm uses a lot of 32-bit operations and because 32-bit arithmetic is fairly expensive on most 8-bit CPUs, uIP does not implement it. Also, uIP does not buffer sent packets and a sliding window implementation that does not buffer sent packets will have to be supported by a complex application layer. Instead, uIP allows only a single TCP segment per connection to be unacknowledged at any given time.

      +It is important to note that even though most TCP implementations use the sliding window algorithm, it is not required by the TCP specifications. Removing the sliding window mechanism does not affect interoperability in any way.

      +Round-Trip Time Estimation

      +TCP continuously estimates the current Round-Trip Time (RTT) of every active connection in order to find a suitable value for the retransmission time-out.

      +The RTT estimation in uIP is implemented using TCP's periodic timer. Each time the periodic timer fires, it increments a counter for each connection that has unacknowledged data in the network. When an acknowledgment is received, the current value of the counter is used as a sample of the RTT. The sample is used together with Van Jacobson's standard TCP RTT estimation function to calculate an estimate of the RTT. Karn's algorithm is used to ensure that retransmissions do not skew the estimates.

      +Retransmissions

      +Retransmissions are driven by the periodic TCP timer. Every time the periodic timer is invoked, the retransmission timer for each connection is decremented. If the timer reaches zero, a retransmission should be made.

      +As uIP does not keep track of packet contents after they have been sent by the device driver, uIP requires that the application takes an active part in performing the retransmission. When uIP decides that a segment should be retransmitted, it calls the application with a flag set indicating that a retransmission is required. The application checks the retransmission flag and produces the same data that was previously sent. From the application's standpoint, performing a retransmission is not different from how the data originally was sent. Therefore the application can be written in such a way that the same code is used both for sending data and retransmitting data. Also, it is important to note that even though the actual retransmission operation is carried out by the application, it is the responsibility of the stack to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions.

      +Flow Control

      +The purpose of TCP's flow control mechanisms is to allow communication between hosts with wildly varying memory dimensions. In each TCP segment, the sender of the segment indicates its available buffer space. A TCP sender must not send more data than the buffer space indicated by the receiver.

      +In uIP, the application cannot send more data than the receiving host can buffer. And application cannot send more data than the amount of bytes it is allowed to send by the receiving host. If the remote host cannot accept any data at all, the stack initiates the zero window probing mechanism.

      +Congestion Control

      +The congestion control mechanisms limit the number of simultaneous TCP segments in the network. The algorithms used for congestion control are designed to be simple to implement and require only a few lines of code.

      +Since uIP only handles one in-flight TCP segment per connection, the amount of simultaneous segments cannot be further limited, thus the congestion control mechanisms are not needed.

      +Urgent Data

      +TCP's urgent data mechanism provides an application-to-application notification mechanism, which can be used by an application to mark parts of the data stream as being more urgent than the normal stream. It is up to the receiving application to interpret the meaning of the urgent data.

      +In many TCP implementations, including the BSD implementation, the urgent data feature increases the complexity of the implementation because it requires an asynchronous notification mechanism in an otherwise synchronous API. As uIP already use an asynchronous event based API, the implementation of the urgent data feature does not lead to increased complexity.

      +Performance

      +In TCP/IP implementations for high-end systems, processing time is dominated by the checksum calculation loop, the operation of copying packet data and context switching. Operating systems for high-end systems often have multiple protection domains for protecting kernel data from user processes and user processes from each other. Because the TCP/IP stack is run in the kernel, data has to be copied between the kernel space and the address space of the user processes and a context switch has to be performed once the data has been copied. Performance can be enhanced by combining the copy operation with the checksum calculation. Because high-end systems usually have numerous active connections, packet demultiplexing is also an expensive operation.

      +A small embedded device does not have the necessary processing power to have multiple protection domains and the power to run a multitasking operating system. Therefore there is no need to copy data between the TCP/IP stack and the application program. With an event based API there is no context switch between the TCP/IP stack and the applications.

      +In such limited systems, the TCP/IP processing overhead is dominated by the copying of packet data from the network device to host memory, and checksum calculation. Apart from the checksum calculation and copying, the TCP processing done for an incoming packet involves only updating a few counters and flags before handing the data over to the application. Thus an estimate of the CPU overhead of our TCP/IP implementations can be obtained by calculating the amount of CPU cycles needed for the checksum calculation and copying of a maximum sized packet.

      +The Impact of Delayed Acknowledgments

      +Most TCP receivers implement the delayed acknowledgment algorithm for reducing the number of pure acknowledgment packets sent. A TCP receiver using this algorithm will only send acknowledgments for every other received segment. If no segment is received within a specific time-frame, an acknowledgment is sent. The time-frame can be as high as 500 ms but typically is 200 ms.

      +A TCP sender such as uIP that only handles a single outstanding TCP segment will interact poorly with the delayed acknowledgment algorithm. Because the receiver only receives a single segment at a time, it will wait as much as 500 ms before an acknowledgment is sent. This means that the maximum possible throughput is severely limited by the 500 ms idle time.

      +Thus the maximum throughput equation when sending data from uIP will be $p = s / (t + t_d)$ where $s$ is the segment size and $t_d$ is the delayed acknowledgment timeout, which typically is between 200 and 500 ms. With a segment size of 1000 bytes, a round-trip time of 40 ms and a delayed acknowledgment timeout of 200 ms, the maximum throughput will be 4166 bytes per second. With the delayed acknowledgment algorithm disabled at the receiver, the maximum throughput would be 25000 bytes per second.

      +It should be noted, however, that since small systems running uIP are not very likely to have large amounts of data to send, the delayed acknowledgmen t throughput degradation of uIP need not be very severe. Small amounts of data sent by such a system will not span more than a single TCP segment, and would therefore not be affected by the throughput degradation anyway.

      +The maximum throughput when uIP acts as a receiver is not affected by the delayed acknowledgment throughput degradation.


      Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  -doxygen -1.3.3
      +doxygen 1.4.6
      diff --git a/doc/html/modules.html b/doc/html/modules.html index e694773..254612a 100644 --- a/doc/html/modules.html +++ b/doc/html/modules.html @@ -1,46 +1,51 @@ - + -uIP 0.9: Module Index +uIP 1.0: Module Index + - - -

      uIP 0.9 Modules

      Here is a list of all modules:
        -
      • The uIP TCP/IP stack + + +

        uIP 1.0 Modules

        Here is a list of all modules: -
        Generated on Tue Oct 7 15:51:51 2003 for uIP 0.9 by +
        Generated on Mon Jun 12 10:23:02 2006 for uIP 1.0 by  -doxygen -1.3.3
        +doxygen 1.4.6
        diff --git a/doc/html/tab_b.gif b/doc/html/tab_b.gif new file mode 100644 index 0000000..0d62348 Binary files /dev/null and b/doc/html/tab_b.gif differ diff --git a/doc/html/tab_l.gif b/doc/html/tab_l.gif new file mode 100644 index 0000000..9b1e633 Binary files /dev/null and b/doc/html/tab_l.gif differ diff --git a/doc/html/tab_r.gif b/doc/html/tab_r.gif new file mode 100644 index 0000000..ce9dd9f Binary files /dev/null and b/doc/html/tab_r.gif differ diff --git a/doc/html/tabs.css b/doc/html/tabs.css new file mode 100644 index 0000000..a61552a --- /dev/null +++ b/doc/html/tabs.css @@ -0,0 +1,102 @@ +/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ + +DIV.tabs +{ + float : left; + width : 100%; + background : url("tab_b.gif") repeat-x bottom; + margin-bottom : 4px; +} + +DIV.tabs UL +{ + margin : 0px; + padding-left : 10px; + list-style : none; +} + +DIV.tabs LI, DIV.tabs FORM +{ + display : inline; + margin : 0px; + padding : 0px; +} + +DIV.tabs FORM +{ + float : right; +} + +DIV.tabs A +{ + float : left; + background : url("tab_r.gif") no-repeat right top; + border-bottom : 1px solid #84B0C7; + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + +DIV.tabs A:hover +{ + background-position: 100% -150px; +} + +DIV.tabs A:link, DIV.tabs A:visited, +DIV.tabs A:active, DIV.tabs A:hover +{ + color: #1A419D; +} + +DIV.tabs SPAN +{ + float : left; + display : block; + background : url("tab_l.gif") no-repeat left top; + padding : 5px 9px; + white-space : nowrap; +} + +DIV.tabs INPUT +{ + float : right; + display : inline; + font-size : 1em; +} + +DIV.tabs TD +{ + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + + + +/* Commented Backslash Hack hides rule from IE5-Mac \*/ +DIV.tabs SPAN {float : none;} +/* End IE5-Mac hack */ + +DIV.tabs A:hover SPAN +{ + background-position: 0% -150px; +} + +DIV.tabs LI#current A +{ + background-position: 100% -150px; + border-width : 0px; +} + +DIV.tabs LI#current SPAN +{ + background-position: 0% -150px; + padding-bottom : 6px; +} + +DIV.nav +{ + background : none; + border : none; + border-bottom : 1px solid #84B0C7; +} diff --git a/doc/html/tree.html b/doc/html/tree.html index 66dba9c..ba4787f 100644 --- a/doc/html/tree.html +++ b/doc/html/tree.html @@ -1,6 +1,6 @@ - + @@ -17,54 +17,23 @@ - +
        -

        uIP 0.9

        +

        uIP 1.0

        o*The uIP TCP/IP stack

        o+File List

        o+Data Structures

        +

        o+Class Hierarchy

        +

        o*Data Fields

        -

        o+Modules

        -
        -

        |o+The uIP TCP/IP stack

        - -

        |o+Example applications

        +

        o+Modules

        + +

        o+Examples

        +

        \*Globals

        diff --git a/doc/pt-doc.txt b/doc/pt-doc.txt new file mode 100644 index 0000000..b26c651 --- /dev/null +++ b/doc/pt-doc.txt @@ -0,0 +1,173 @@ +/** +\defgroup pt Protothreads + +Protothreads are a type of lightweight stackless threads designed for +severly memory constrained systems such as deeply embedded systems or +sensor network nodes. Protothreads provides linear code execution for +event-driven systems implemented in C. Protothreads can be used with +or without an RTOS. + +Protothreads are a extremely lightweight, stackless type of threads +that provides a blocking context on top of an event-driven system, +without the overhead of per-thread stacks. The purpose of protothreads +is to implement sequential flow of control without complex state +machines or full multi-threading. Protothreads provides conditional +blocking inside C functions. + +The advantage of protothreads over a purely event-driven approach is +that protothreads provides a sequential code structure that allows for +blocking functions. In purely event-driven systems, blocking must be +implemented by manually breaking the function into two pieces - one +for the piece of code before the blocking call and one for the code +after the blocking call. This makes it hard to use control structures +such as if() conditionals and while() loops. + +The advantage of protothreads over ordinary threads is that a +protothread do not require a separate stack. In memory constrained +systems, the overhead of allocating multiple stacks can consume large +amounts of the available memory. In contrast, each protothread only +requires between two and twelve bytes of state, depending on the +architecture. + +\note Because protothreads do not save the stack context across a +blocking call, local variables are not preserved when the +protothread blocks. This means that local variables should be used +with utmost care - if in doubt, do not use local variables inside a +protothread! + + +Main features: + + - No machine specific code - the protothreads library is pure C + + - Does not use error-prone functions such as longjmp() + + - Very small RAM overhead - only two bytes per protothread + + - Can be used with or without an OS + + - Provides blocking wait without full multi-threading or + stack-switching + +Examples applications: + + - Memory constrained systems + + - Event-driven protocol stacks + + - Deeply embedded systems + + - Sensor network nodes + +The protothreads API consists of four basic operations: +initialization: PT_INIT(), execution: PT_BEGIN(), conditional +blocking: PT_WAIT_UNTIL() and exit: PT_END(). On top of these, two +convenience functions are built: reversed condition blocking: +PT_WAIT_WHILE() and protothread blocking: PT_WAIT_THREAD(). + +\sa \ref pt "Protothreads API documentation" + +The protothreads library is released under a BSD-style license that +allows for both non-commercial and commercial usage. The only +requirement is that credit is given. + +\section authors Authors + +The protothreads library was written by Adam Dunkels +with support from Oliver Schmidt . + +\section pt-desc Protothreads + +Protothreads are a extremely lightweight, stackless threads that +provides a blocking context on top of an event-driven system, without +the overhead of per-thread stacks. The purpose of protothreads is to +implement sequential flow of control without using complex state +machines or full multi-threading. Protothreads provides conditional +blocking inside a C function. + +In memory constrained systems, such as deeply embedded systems, +traditional multi-threading may have a too large memory overhead. In +traditional multi-threading, each thread requires its own stack, that +typically is over-provisioned. The stacks may use large parts of the +available memory. + +The main advantage of protothreads over ordinary threads is that +protothreads are very lightweight: a protothread does not require its +own stack. Rather, all protothreads run on the same stack and context +switching is done by stack rewinding. This is advantageous in memory +constrained systems, where a stack for a thread might use a large part +of the available memory. A protothread only requires only two bytes of +memory per protothread. Moreover, protothreads are implemented in pure +C and do not require any machine-specific assembler code. + +A protothread runs within a single C function and cannot span over +other functions. A protothread may call normal C functions, but cannot +block inside a called function. Blocking inside nested function calls +is instead made by spawning a separate protothread for each +potentially blocking function. The advantage of this approach is that +blocking is explicit: the programmer knows exactly which functions +that block that which functions the never blocks. + +Protothreads are similar to asymmetric co-routines. The main +difference is that co-routines uses a separate stack for each +co-routine, whereas protothreads are stackless. The most similar +mechanism to protothreads are Python generators. These are also +stackless constructs, but have a different purpose. Protothreads +provides blocking contexts inside a C function, whereas Python +generators provide multiple exit points from a generator function. + +\section pt-autovars Local variables + +\note +Because protothreads do not save the stack context across a blocking +call, local variables are not preserved when the protothread +blocks. This means that local variables should be used with utmost +care - if in doubt, do not use local variables inside a protothread! + +\section pt-scheduling Scheduling + +A protothread is driven by repeated calls to the function in which the +protothread is running. Each time the function is called, the +protothread will run until it blocks or exits. Thus the scheduling of +protothreads is done by the application that uses protothreads. + +\section pt-impl Implementation + +Protothreads are implemented using \ref lc "local continuations". A +local continuation represents the current state of execution at a +particular place in the program, but does not provide any call history +or local variables. A local continuation can be set in a specific +function to capture the state of the function. After a local +continuation has been set can be resumed in order to restore the state +of the function at the point where the local continuation was set. + + +Local continuations can be implemented in a variety of ways: + + -# by using machine specific assembler code, + -# by using standard C constructs, or + -# by using compiler extensions. + +The first way works by saving and restoring the processor state, +except for stack pointers, and requires between 16 and 32 bytes of +memory per protothread. The exact amount of memory required depends on +the architecture. + +The standard C implementation requires only two bytes of state per +protothread and utilizes the C switch() statement in a non-obvious way +that is similar to Duff's device. This implementation does, however, +impose a slight restriction to the code that uses protothreads in that +the code cannot use switch() statements itself. + +Certain compilers has C extensions that can be used to implement +protothreads. GCC supports label pointers that can be used for this +purpose. With this implementation, protothreads require 4 bytes of RAM +per protothread. + +@{ + + +*/ + +/** @} */ + diff --git a/doc/sicslogo.pdf b/doc/sicslogo.pdf new file mode 100644 index 0000000..239a1bf Binary files /dev/null and b/doc/sicslogo.pdf differ diff --git a/doc/uip-code-style.c b/doc/uip-code-style.c new file mode 100644 index 0000000..b62c5b1 --- /dev/null +++ b/doc/uip-code-style.c @@ -0,0 +1,118 @@ +/* This is the official code style of uIP. */ + +/** + * \defgroup codestyle Coding style + * + * This is how a Doxygen module is documented - start with a \defgroup + * Doxygen keyword at the beginning of the file to define a module, + * and use the \addtogroup Doxygen keyword in all other files that + * belong to the same module. Typically, the \defgroup is placed in + * the .h file and \addtogroup in the .c file. + * + * @{ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + * + * Every file that is part of a documented module has to have + * a \file block, else it will not show up in the Doxygen + * "Modules" * section. + */ + +/* Single line comments look like this. */ + +/* + * Multi-line comments look like this. Comments should prefferably be + * full sentences, filled to look like real paragraphs. + */ + +#include "uip.h" + +/* + * Make sure that non-global variables are all maked with the static + * keyword. This keeps the size of the symbol table down. + */ +static int flag; + +/* + * All variables and functions that are visible outside of the file + * should have the module name prepended to them. This makes it easy + * to know where to look for function and variable definitions. + * + * Put dividers (a single-line comment consisting only of dashes) + * between functions. + */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Use Doxygen documentation for functions. + * \param c Briefly describe all parameters. + * \return Briefly describe the return value. + * \retval 0 Functions that return a few specified values + * \retval 1 can use the \retval keyword instead of \return. + * + * Put a longer description of what the function does + * after the preamble of Doxygen keywords. + * + * This template should always be used to document + * functions. The text following the introduction is used + * as the function's documentation. + * + * Function prototypes have the return type on one line, + * the name and arguments on one line (with no space + * between the name and the first parenthesis), followed + * by a single curly bracket on its own line. + */ +void +code_style_example_function(void) +{ + /* + * Local variables should always be declared at the start of the + * function. + */ + int i; /* Use short variable names for loop + counters. */ + + /* + * There should be no space between keywords and the first + * parenthesis. There should be spaces around binary operators, no + * spaces between a unary operator and its operand. + * + * Curly brackets following for(), if(), do, and case() statements + * should follow the statement on the same line. + */ + for(i = 0; i < 10; ++i) { + /* + * Always use full blocks (curly brackets) after if(), for(), and + * while() statements, even though the statement is a single line + * of code. This makes the code easier to read and modifications + * are less error prone. + */ + if(i == c) { + return c; /* No parentesis around return values. */ + } else { /* The else keyword is placed inbetween + curly brackers, always on its own line. */ + c++; + } + } +} +/*---------------------------------------------------------------------------*/ +/* + * Static (non-global) functions do not need Doxygen comments. The + * name should not be prepended with the module name - doing so would + * create confusion. + */ +static void +an_example_function(void) +{ + +} +/*---------------------------------------------------------------------------*/ + +/* The following stuff ends the \defgroup block at the beginning of + the file: */ + +/** @} */ diff --git a/doc/uip-code-style.txt b/doc/uip-code-style.txt new file mode 100644 index 0000000..db6a632 --- /dev/null +++ b/doc/uip-code-style.txt @@ -0,0 +1,3 @@ +/** + \example uip-code-style.c + */ diff --git a/doc/uip-doc.txt b/doc/uip-doc.txt index 73d13b0..894b1bc 100644 --- a/doc/uip-doc.txt +++ b/doc/uip-doc.txt @@ -1,12 +1,8 @@ -/** -\defgroup uip The uIP TCP/IP stack -@{ -*/ /** \mainpage The uIP TCP/IP stack -\author Adam Dunkels +\author Adam Dunkels, http://www.sics.se/~adam/ The uIP TCP/IP stack is intended to make it possible to communicate using the TCP/IP protocol suite even on small 8-bit @@ -16,7 +12,19 @@ with peers running a similarly light-weight stack. The code size is on the order of a few kilobytes and RAM usage can be configured to be as low as a few hundred bytes. -\section uIPIntroduction uIP introduction +uIP can be found at the uIP web page: http://www.sics.se/~adam/uip/ + +\sa \ref apps "Application programs" +\sa \ref uipopt "Compile-time configuration options" +\sa \ref uipconffunc "Run-time configuration functions" +\sa \ref uipinit "Initialization functions" +\sa \ref uipdevfunc "Device driver interface" and + \ref uipdrivervars "variables used by device drivers" +\sa \ref uipappfunc "uIP functions called from application programs" +(see below) and the \ref psock "protosockets API" and their underlying +\ref pt "protothreads" + +\section uIPIntroduction Introduction With the success of the Internet, the TCP/IP protocol suite has become a global standard for communication. TCP/IP is the underlying protocol @@ -37,9 +45,8 @@ code. The uIP implementation is designed to have only the absolute minimal set of features needed for a full TCP/IP stack. It can only handle a -single network interface and contains only a rudimentary UDP -implementation, but focuses on the IP, ICMP and TCP protocols. uIP is -written in the C programming language. +single network interface and contains the IP, ICMP, UDP and TCP +protocols. uIP is written in the C programming language. Many other TCP/IP implementations for small systems assume that the embedded device always will communicate with a full-scale TCP/IP @@ -54,7 +61,7 @@ network citizens. The uIP TCP/IP implementation that is not tailored for any specific application. -\section tcpip TCP/IP communication +\section tcpip TCP/IP Communication The full TCP/IP suite consists of numerous protocols, ranging from low level protocols such as ARP which translates IP addresses to MAC @@ -104,7 +111,69 @@ dynamically configurable type-of-service bits for TCP connections. Since there are only very few applications that make use of those features they can be removed without loss of generality. -\section memory Memory management +\section mainloop Main Control Loop + +The uIP stack can be run either as a task in a multitasking system, or +as the main program in a singletasking system. In both cases, the main +control loop does two things repeatedly: + + - Check if a packet has arrived from the network. + - Check if a periodic timeout has occurred. + +If a packet has arrived, the input handler function, uip_input(), +should be invoked by the main control loop. The input handler function +will never block, but will return at once. When it returns, the stack +or the application for which the incoming packet was intended may have +produced one or more reply packets which should be sent out. If so, +the network device driver should be called to send out these packets. + +Periodic timeouts are used to drive TCP mechanisms that depend on +timers, such as delayed acknowledgments, retransmissions and +round-trip time estimations. When the main control loop infers that +the periodic timer should fire, it should invoke the timer handler +function uip_periodic(). Because the TCP/IP stack may perform +retransmissions when dealing with a timer event, the network device +driver should called to send out the packets that may have been produced. + +\section arch Architecture Specific Functions + +uIP requires a few functions to be implemented specifically for the +architecture on which uIP is intended to run. These functions should +be hand-tuned for the particular architecture, but generic C +implementations are given as part of the uIP distribution. + +\subsection checksums Checksum Calculation + +The TCP and IP protocols implement a checksum that covers the data and +header portions of the TCP and IP packets. Since the calculation of +this checksum is made over all bytes in every packet being sent and +received it is important that the function that calculates the +checksum is efficient. Most often, this means that the checksum +calculation must be fine-tuned for the particular architecture on +which the uIP stack runs. + +While uIP includes a generic checksum function, it also leaves it open +for an architecture specific implementation of the two functions +uip_ipchksum() and uip_tcpchksum(). The checksum calculations in those +functions can be written in highly optimized assembler rather than +generic C code. + +\subsection longarith 32-bit Arithmetic + +The TCP protocol uses 32-bit sequence numbers, and a TCP +implementation will have to do a number of 32-bit additions as part of +the normal protocol processing. Since 32-bit arithmetic is not +natively available on many of the platforms for which uIP is intended, +uIP leaves the 32-bit additions to be implemented by the architecture +specific module and does not make use of any 32-bit arithmetic in the +main code base. + +While uIP implements a generic 32-bit addition, there is support for +having an architecture specific implementation of the uip_add32() +function. + + +\section memory Memory Management In the architectures for which uIP is intended, RAM is the most scarce resource. With only a few kilobytes of RAM available for the @@ -160,7 +229,8 @@ with as little as 200 bytes of RAM, but such a configuration will provide extremely low throughput and will only allow a small number of simultaneous connections. -\section api Application program interface (API) +\section api Application Program Interface (API) + The Application Program Interface (API) defines the way the application program interacts with the TCP/IP stack. The most commonly @@ -173,7 +243,18 @@ space for the tasks might be too high in the intended uIP target architectures, the BSD socket interface is not suitable for our purposes. -Instead, uIP uses an event driven interface where the application is +uIP provides two APIs to programmers: protosockets, a BSD socket-like +API without the overhead of full multi-threading, and a "raw" +event-based API that is nore low-level than protosockets but uses less +memory. + +\sa \ref psock +\sa \ref pt + + +\subsection rawapi The uIP raw API + +The "raw" uIP API uses an event driven interface where the application is invoked in response to certain events. An application running on top of uIP is implemented as a C function that is called by uIP in response to certain events. uIP calls the application when data is @@ -216,7 +297,7 @@ to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions. -\subsection appevents Application events +\subsubsection appevents Application Events The application must be implemented as a C function, UIP_APPCALL(), that uIP calls whenever an event occurs. Each event has a corresponding @@ -226,7 +307,7 @@ to either zero or non-zero. Note that certain events can happen in conjunction with each other (i.e., new data can arrive at the same time as data is acknowledged). -\subsection connstate The connection pointer +\subsubsection connstate The Connection Pointer When the application is called by uIP, the global variable uip_conn is set to point to the uip_conn structure for the connection that @@ -240,7 +321,7 @@ application might decide to act as an HTTP server if the value of uip_conn->lport is equal to 80 and act as a TELNET server if the value is 23. -\subsection recvdata Receiving data +\subsubsection recvdata Receiving Data If the uIP test function uip_newdata() is non-zero, the remote host of the connection has sent new data. The uip_appdata pointer point to the @@ -251,7 +332,7 @@ application will therefor have to either act directly on the incoming data, or by itself copy the incoming data into a buffer for later processing. -\subsection senddata Sending data +\subsubsection senddata Sending Data When sending data, uIP adjusts the length of the data sent by the application according to the available buffer space and the current @@ -272,7 +353,7 @@ connection and it is not possible to call uip_send() more than once per application invocation; only the data from the last call will be sent. -\subsection rexmitdata Retransmitting data +\subsubsection rexmitdata Retransmitting Data Retransmissions are driven by the periodic TCP timer. Every time the periodic timer is invoked, the retransmission timer for each @@ -297,7 +378,7 @@ should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions. -\subsection closing Closing connections +\subsubsection closing Closing Connections The application closes the current connection by calling the uip_close() during an application call. This will cause the connection @@ -309,7 +390,7 @@ If the connection has been closed by the remote end, the test function uip_closed() is true. The application may then do any necessary cleanups. -\subsection errors Reporting errors +\subsubsection errors Reporting Errors There are two fatal errors that can happen to a connection, either that the connection was aborted by the remote host, or that the @@ -318,7 +399,7 @@ aborted. uIP reports this by calling the application function. The application can use the two test functions uip_aborted() and uip_timedout() to test for those error conditions. -\subsection polling Polling +\subsubsection polling Polling When a connection is idle, uIP polls the application every time the periodic timer fires. The application uses the test function @@ -332,7 +413,7 @@ has been produced. The application can only send data when invoked by uIP, and therefore the poll event is the only way to send data on an otherwise idle connection. -\subsection listen Listening ports +\subsubsection listen Listening Ports uIP maintains a list of listening TCP ports. A new port is opened for listening with the uip_listen() function. When a connection request @@ -343,7 +424,7 @@ the application was invoked because a new connection was created. The application can check the lport field in the uip_conn structure to check to which port the new connection was connected. -\subsection connect Opening connections +\subsubsection connect Opening Connections New connections can be opened from within uIP by the function uip_connect(). This function @@ -384,69 +465,12 @@ void connect_example2(void) { } \endcode -\section drivers uIP device drivers - -From the network device driver's standpoint, uIP consists of two C -functions: uip_input() and uip_periodic(). The uip_input() function -should be called by the device driver when an IP packet has been -received and put into the uip_buf packet buffer. The uip_input() -function will process the packet, and when it returns an outbound -packet may have been placed in the same uip_buf packet buffer -(indicated by the uip_len variable being non-zero). The device driver -should then send out this packet onto the network. - -The uip_periodic() function should be invoked periodically once per -connection by the device driver, typically one per second. This -function is used by uIP to drive protocol timers and retransmissions, -and when it returns it may have placed an outbound packet in the -uip_buf buffer. - -\section arch Architecture specific functions - -uIP requires a few functions to be implemented specifically for the -architecture on which uIP is intended to run. These functions should -be hand-tuned for the particular architecture, but generic C -implementations are given as part of the uIP distribution. - -\subsection checksums Checksum calculation - -The TCP and IP protocols implement a checksum that covers the data and -header portions of the TCP and IP packets. Since the calculation of -this checksum is made over all bytes in every packet being sent and -received it is important that the function that calculates the -checksum is efficient. Most often, this means that the checksum -calculation must be fine-tuned for the particular architecture on -which the uIP stack runs. - -Because of this, uIP does not implement a generic checksum function, -but leaves this to the architecture specific files which must -implement the two functions uip_ipchksum() and uip_tcpchksum(). The -checksum calculations in those functions can be written in highly -optimized assembler rather than generic C code. - -An example C implementation of the checksum function is provided in -the uIP distribution. - -\subsection longarith 32-bit arithmetic - -The TCP protocol uses 32-bit sequence numbers, and a TCP -implementation will have to do a number of 32-bit additions as part of -the normal protocol processing. Since 32-bit arithmetic is not -natively available on many of the platforms for which uIP is intended, -uIP leaves the 32-bit additions to be implemented by the architecture -specific module and does not make use of any 32-bit arithmetic in the -main code base. - -The architecture specific code must implement a function uip_add32() -which does a 32-bit addition and stores the result in a global -variable uip_acc32. - \section examples Examples This section presents a number of very simple uIP applications. The uIP code distribution contains several more complex applications. -\subsection example1 A very simple application +\subsection example1 A Very Simple Application This first example shows a very simple application. The application listens for incoming connections on port 1234. When a connection has @@ -482,7 +506,7 @@ example actually shows a complete uIP application. It is not required for an application to deal with all types of events such as uip_connected() or uip_timedout(). -\subsection example2 A more advanced application +\subsection example2 A More Advanced Application This second example is slightly more advanced than the previous one, and shows how the application state field in the uip_conn structure is @@ -576,7 +600,7 @@ The configuration for the application: #define UIP_APPSTATE_SIZE sizeof(struct example2_state) \endcode -\subsection example3 Differentiating between applications +\subsection example3 Differentiating Between Applications If the system should run multiple applications, one technique to differentiate between them is to use the TCP port number of either the @@ -601,7 +625,7 @@ void example3_app(void) { } \endcode -\subsection example4 Utilizing TCP flow control +\subsection example4 Utilizing TCP Flow Control This example shows a simple application that connects to a host, sends an HTTP request for a file and downloads it to a slow device such a @@ -655,7 +679,7 @@ uip_restart() is called. The application polling event is used to check if the device's queue is no longer full and if so, the data flow is restarted with uip_restart(). -\subsection example5 A simple web server +\subsection example5 A Simple Web Server This example shows a very simple file server application that listens to two ports and uses the port number to determine which file to @@ -715,7 +739,7 @@ The application is driven by incoming acknowledgments. When data has been acknowledged, new data can be sent. If there is no more data to send, the connection is closed using uip_close(). -\subsection example6 Structured application program design +\subsection example6 Structured Application Program Design When writing larger programs using uIP it is useful to be able to utilize the uIP API in a structured way. The following example @@ -893,19 +917,264 @@ It is important to note that the senddata() function never should affect the application state; this should only be done in the acked() and newdata() functions. +\section protoimpl Protocol Implementations + +The protocols in the TCP/IP protocol suite are designed in a layered +fashion where each protocol performs a specific function and the +interactions between the protocol layers are strictly defined. While +the layered approach is a good way to design protocols, it is not +always the best way to implement them. In uIP, the protocol +implementations are tightly coupled in order to save code space. + +This section gives detailed information on the specific protocol +implementations in uIP. + +\subsection ip IP --- Internet Protocol + +When incoming packets are processed by uIP, the IP layer is the first +protocol that examines the packet. The IP layer does a few simple +checks such as if the destination IP address of the incoming packet +matches any of the local IP address and verifies the IP header +checksum. Since there are no IP options that are strictly required and +because they are very uncommon, any IP options in received packets are +dropped. + +\subsubsection ipreass IP Fragment Reassembly + +IP fragment reassembly is implemented using a separate buffer that +holds the packet to be reassembled. An incoming fragment is copied +into the right place in the buffer and a bit map is used to keep track +of which fragments have been received. Because the first byte of an IP +fragment is aligned on an 8-byte boundary, the bit map requires a +small amount of memory. When all fragments have been reassembled, the +resulting IP packet is passed to the transport layer. If all fragments +have not been received within a specified time frame, the packet is +dropped. + +The current implementation only has a single buffer for holding +packets to be reassembled, and therefore does not support simultaneous +reassembly of more than one packet. Since fragmented packets are +uncommon, this ought to be a reasonable decision. Extending the +implementation to support multiple buffers would be straightforward, +however. + +\subsubsection ipbroadcast Broadcasts and Multicasts + +IP has the ability to broadcast and multicast packets on the local +network. Such packets are addressed to special broadcast and multicast +addresses. Broadcast is used heavily in many UDP based protocols such +as the Microsoft Windows file-sharing SMB protocol. Multicast is +primarily used in protocols used for multimedia distribution such as +RTP. TCP is a point-to-point protocol and does not use broadcast or +multicast packets. uIP current supports broadcast packets as well as +sending multicast packets. Joining multicast groups (IGMP) and +receiving non-local multicast packets is not currently supported. + +\subsection icmp ICMP --- Internet Control Message Protocol + +The ICMP protocol is used for reporting soft error conditions and for +querying host parameters. Its main use is, however, the echo mechanism +which is used by the "ping" program. + +The ICMP implementation in uIP is very simple as itis restricted to +only implement ICMP echo messages. Replies to echo messages are +constructed by simply swapping the source and destination IP addresses +of incoming echo requests and rewriting the ICMP header with the +Echo-Reply message type. The ICMP checksum is adjusted using standard +techniques (see RFC1624). + +Since only the ICMP echo message is implemented, there is no support +for Path MTU discovery or ICMP redirect messages. Neither of these is +strictly required for interoperability; they are performance +enhancement mechanisms. + +\subsection tcp TCP --- Transmission Control Protocol + +The TCP implementation in uIP is driven by incoming packets and timer +events. Incoming packets are parsed by TCP and if the packet contains +data that is to be delivered to the application, the application is +invoked by the means of the application function call. If the incoming +packet acknowledges previously sent data, the connection state is +updated and the application is informed, allowing it to send out new +data. + +\subsubsection listeb Listening Connections + +TCP allows a connection to listen for incoming connection requests. In +uIP, a listening connection is identified by the 16-bit port number +and incoming connection requests are checked against the list of +listening connections. This list of listening connections is dynamic +and can be altered by the applications in the system. + +\subsubsection slidingwindow Sliding Window + +Most TCP implementations use a sliding window mechanism for sending +data. Multiple data segments are sent in succession without waiting +for an acknowledgment for each segment. + +The sliding window algorithm uses a lot of 32-bit operations and +because 32-bit arithmetic is fairly expensive on most 8-bit CPUs, uIP +does not implement it. Also, uIP does not buffer sent packets and a +sliding window implementation that does not buffer sent packets will have +to be supported by a complex application layer. Instead, uIP allows +only a single TCP segment per connection to be unacknowledged at any +given time. + +It is important to note that even though most TCP implementations use +the sliding window algorithm, it is not required by the TCP +specifications. Removing the sliding window mechanism does not affect +interoperability in any way. + +\subsubsection rttest Round-Trip Time Estimation + +TCP continuously estimates the current Round-Trip Time (RTT) of every +active connection in order to find a suitable value for the +retransmission time-out. + +The RTT estimation in uIP is implemented using TCP's periodic +timer. Each time the periodic timer fires, it increments a counter for +each connection that has unacknowledged data in the network. When an +acknowledgment is received, the current value of the counter is used +as a sample of the RTT. The sample is used together with Van +Jacobson's standard TCP RTT estimation function to calculate an +estimate of the RTT. Karn's algorithm is used to ensure that +retransmissions do not skew the estimates. + +\subsubsection rexmit Retransmissions + +Retransmissions are driven by the periodic TCP timer. Every time the +periodic timer is invoked, the retransmission timer for each +connection is decremented. If the timer reaches zero, a retransmission +should be made. + +As uIP does not keep track of packet contents after they have +been sent by the device driver, uIP requires that the +application takes an active part in performing the +retransmission. When uIP decides that a segment should be +retransmitted, it calls the application with a flag set indicating +that a retransmission is required. The application checks the +retransmission flag and produces the same data that was previously +sent. From the application's standpoint, performing a retransmission +is not different from how the data originally was sent. Therefore the +application can be written in such a way that the same code is used +both for sending data and retransmitting data. Also, it is important +to note that even though the actual retransmission operation is +carried out by the application, it is the responsibility of the stack +to know when the retransmission should be made. Thus the complexity of +the application does not necessarily increase because it takes an +active part in doing retransmissions. + +\subsubsection flowcontrol Flow Control + +The purpose of TCP's flow control mechanisms is to allow communication +between hosts with wildly varying memory dimensions. In each TCP +segment, the sender of the segment indicates its available buffer +space. A TCP sender must not send more data than the buffer space +indicated by the receiver. + +In uIP, the application cannot send more data than the receiving host +can buffer. And application cannot send more data than the amount of +bytes it is allowed to send by the receiving host. If the remote host +cannot accept any data at all, the stack initiates the zero window +probing mechanism. + +\subsubsection congestioncontrol Congestion Control + +The congestion control mechanisms limit the number of simultaneous TCP +segments in the network. The algorithms used for congestion control +are designed to be simple to implement and require only a few lines of +code. + +Since uIP only handles one in-flight TCP segment per connection, +the amount of simultaneous segments cannot be further limited, thus +the congestion control mechanisms are not needed. + +\subsubsection urgdata Urgent Data + +TCP's urgent data mechanism provides an application-to-application +notification mechanism, which can be used by an application to mark +parts of the data stream as being more urgent than the normal +stream. It is up to the receiving application to interpret the meaning +of the urgent data. + +In many TCP implementations, including the BSD implementation, the +urgent data feature increases the complexity of the implementation +because it requires an asynchronous notification mechanism in an +otherwise synchronous API. As uIP already use an asynchronous event +based API, the implementation of the urgent data feature does not lead +to increased complexity. + +\section performance Performance + +In TCP/IP implementations for high-end systems, processing time is +dominated by the checksum calculation loop, the operation of copying +packet data and context switching. Operating systems for high-end +systems often have multiple protection domains for protecting kernel +data from user processes and user processes from each other. Because +the TCP/IP stack is run in the kernel, data has to be copied between +the kernel space and the address space of the user processes and a +context switch has to be performed once the data has been +copied. Performance can be enhanced by combining the copy operation +with the checksum calculation. Because high-end systems usually have +numerous active connections, packet demultiplexing is also an +expensive operation. + +A small embedded device does not have the necessary processing power +to have multiple protection domains and the power to run a +multitasking operating system. Therefore there is no need to copy +data between the TCP/IP stack and the application program. With an +event based API there is no context switch between the TCP/IP stack +and the applications. + +In such limited systems, the TCP/IP processing overhead is dominated +by the copying of packet data from the network device to host memory, +and checksum calculation. Apart from the checksum calculation and +copying, the TCP processing done for an incoming packet involves only +updating a few counters and flags before handing the data over to the +application. Thus an estimate of the CPU overhead of our TCP/IP +implementations can be obtained by calculating the amount of CPU +cycles needed for the checksum calculation and copying of a maximum +sized packet. + +\subsection delack The Impact of Delayed Acknowledgments + +Most TCP receivers implement the delayed acknowledgment algorithm for +reducing the number of pure acknowledgment packets sent. A TCP +receiver using this algorithm will only send acknowledgments for every +other received segment. If no segment is received within a specific +time-frame, an acknowledgment is sent. The time-frame can be as high +as 500 ms but typically is 200 ms. + +A TCP sender such as uIP that only handles a single outstanding TCP +segment will interact poorly with the delayed acknowledgment +algorithm. Because the receiver only receives a single segment at a +time, it will wait as much as 500 ms before an acknowledgment is +sent. This means that the maximum possible throughput is severely +limited by the 500 ms idle time. + +Thus the maximum throughput equation when sending data from uIP will +be $p = s / (t + t_d)$ where $s$ is the segment size and $t_d$ is the +delayed acknowledgment timeout, which typically is between 200 and +500 ms. With a segment size of 1000 bytes, a round-trip time of 40 ms +and a delayed acknowledgment timeout of 200 ms, the maximum +throughput will be 4166 bytes per second. With the delayed acknowledgment +algorithm disabled at the receiver, the maximum throughput would be +25000 bytes per second. + +It should be noted, however, that since small systems running uIP are +not very likely to have large amounts of data to send, the delayed +acknowledgmen t throughput degradation of uIP need not be very +severe. Small amounts of data sent by such a system will not span more +than a single TCP segment, and would therefore not be affected by the +throughput degradation anyway. + +The maximum throughput when uIP acts as a receiver is not affected by +the delayed acknowledgment throughput degradation. + + + */ /** @} */ -/** -\defgroup exampleapps Example applications -@{ - -The uIP distribution contains a number of example applications that -can be either used directory or studied when learning to develop -applications for uIP. - -*/ - -/** @} */ \ No newline at end of file diff --git a/doc/uip-refman.pdf b/doc/uip-refman.pdf index cd91aff..8dc8005 100644 Binary files a/doc/uip-refman.pdf and b/doc/uip-refman.pdf differ diff --git a/lib/memb.c b/lib/memb.c new file mode 100644 index 0000000..777b52f --- /dev/null +++ b/lib/memb.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: memb.c,v 1.1 2006/06/12 08:21:43 adam Exp $ + */ + +/** + * \addtogroup memb + * @{ + */ + + /** + * \file + * Memory block allocation routines. + * \author Adam Dunkels + */ +#include + +#include "memb.h" + +/*---------------------------------------------------------------------------*/ +void +memb_init(struct memb_blocks *m) +{ + memset(m->count, 0, m->num); + memset(m->mem, 0, m->size * m->num); +} +/*---------------------------------------------------------------------------*/ +void * +memb_alloc(struct memb_blocks *m) +{ + int i; + + for(i = 0; i < m->num; ++i) { + if(m->count[i] == 0) { + /* If this block was unused, we increase the reference count to + indicate that it now is used and return a pointer to the + memory block. */ + ++(m->count[i]); + return (void *)((char *)m->mem + (i * m->size)); + } + } + + /* No free block was found, so we return NULL to indicate failure to + allocate block. */ + return NULL; +} +/*---------------------------------------------------------------------------*/ +char +memb_free(struct memb_blocks *m, void *ptr) +{ + int i; + char *ptr2; + + /* Walk through the list of blocks and try to find the block to + which the pointer "ptr" points to. */ + ptr2 = (char *)m->mem; + for(i = 0; i < m->num; ++i) { + + if(ptr2 == (char *)ptr) { + /* We've found to block to which "ptr" points so we decrease the + reference count and return the new value of it. */ + if(m->count[i] > 0) { + /* Make sure that we don't deallocate free memory. */ + --(m->count[i]); + } + return m->count[i]; + } + ptr2 += m->size; + } + return -1; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/lib/memb.h b/lib/memb.h new file mode 100644 index 0000000..b725ebe --- /dev/null +++ b/lib/memb.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: memb.h,v 1.1 2006/06/12 08:21:43 adam Exp $ + */ + +/** + * \defgroup memb Memory block management functions + * + * The memory block allocation routines provide a simple yet powerful + * set of functions for managing a set of memory blocks of fixed + * size. A set of memory blocks is statically declared with the + * MEMB() macro. Memory blocks are allocated from the declared + * memory by the memb_alloc() function, and are deallocated with the + * memb_free() function. + * + * \note Because of namespace clashes only one MEMB() can be + * declared per C module, and the name scope of a MEMB() memory + * block is local to each C module. + * + * The following example shows how to declare and use a memory block + * called "cmem" which has 8 chunks of memory with each memory chunk + * being 20 bytes large. + * + * @{ + */ + + +/** + * \file + * Memory block allocation routines. + * \author + * Adam Dunkels + * + */ + +#ifndef __MEMB_H__ +#define __MEMB_H__ + +/* + * Here we define a C preprocessing macro for concatenating to + * strings. We need use two macros in order to allow concatenation of + * two #defined macros. + */ +#define MEMB_CONCAT2(s1, s2) s1##s2 +#define MEMB_CONCAT(s1, s2) MEMB_CONCAT2(s1, s2) + +/** + * Declare a memory block. + * + * This macro is used to staticall declare a block of memory that can + * be used by the block allocation functions. The macro statically + * declares a C array with a size that matches the specified number of + * blocks and their individual sizes. + * + * Example: + \code +MEMB(connections, sizeof(struct connection), 16); + \endcode + * + * \param name The name of the memory block (later used with + * memb_init(), memb_alloc() and memb_free()). + * + * \param size The size of each memory chunk, in bytes. + * + * \param num The total number of memory chunks in the block. + * + */ +#define MEMB(name, structure, num) \ + static char MEMB_CONCAT(name,_memb_count)[num]; \ + static structure MEMB_CONCAT(name,_memb_mem)[num]; \ + static struct memb_blocks name = {sizeof(structure), num, \ + MEMB_CONCAT(name,_memb_count), \ + (void *)MEMB_CONCAT(name,_memb_mem)} + +struct memb_blocks { + unsigned short size; + unsigned short num; + char *count; + void *mem; +}; + +/** + * Initialize a memory block that was declared with MEMB(). + * + * \param m A memory block previosly declared with MEMB(). + */ +void memb_init(struct memb_blocks *m); + +/** + * Allocate a memory block from a block of memory declared with MEMB(). + * + * \param m A memory block previosly declared with MEMB(). + */ +void *memb_alloc(struct memb_blocks *m); + +/** + * Deallocate a memory block from a memory block previously declared + * with MEMB(). + * + * \param m m A memory block previosly declared with MEMB(). + * + * \param ptr A pointer to the memory block that is to be deallocated. + * + * \return The new reference count for the memory block (should be 0 + * if successfully deallocated) or -1 if the pointer "ptr" did not + * point to a legal memory block. + */ +char memb_free(struct memb_blocks *m, void *ptr); + +/** @} */ + +#endif /* __MEMB_H__ */ diff --git a/uip-1.0-changelog.txt b/uip-1.0-changelog.txt new file mode 100644 index 0000000..1e6c61c --- /dev/null +++ b/uip-1.0-changelog.txt @@ -0,0 +1,98 @@ +* A new API: protosockets that are similar to BSD sockets but does not + require any underlying multithreading system. + +* Very rudimentary IPv6 support + +* New application: DHCP client. Web server rewritten with protosockets. + +* Removed uIP zero-copy functionality in order to simplify uIP device + driver coding: outbound packets are now *always* stored in full in + the uip_buf buffer. + +* Checksum computation is now part of uip.c, but it still is possible + to implement them in assembly code by specifying a configuration + option. Checksum code now runs on architectures with 2-byte alignment. + +* Added TCP persistent timer. + +* Made all IP address representations use the new uip_ipaddr_ip + datatype for clarity. + +* Updated window behavior so that sending to a host with a small open + window works better now. + +* UDP API change: uip_udp_new() now takes port numbers in network byte + order like TCP functions. + +* Allow reception of packets when no IP address is configured to make + DHCP work. + +* Moved Ethernet address into main uIP module from ARP module. + +* Made constants explicit #defines and moved them out of the code + (header sizes, TCP options, TCP header length field). + +* If uip_len is less than that reported by the IP header, the packet + is discarded. If uip_len is greater than the length reported by the + IP header, uip_len is adjusted. + +* Moved header size definitions into header file. + +* Added uIP call for polling an application without triggering any + timer events. Removed redundant assignments of uip_len and uip_slen. + +* Removed compiler warning about icmp_input label being defined when + UIP_PINGADDRCONF was not used. + +* Added UIP_APPDATA_SIZE macro that holds the available buffer size + for user data. + +* Added uip_udp_bind() call. + +* Moved checksum code into main uIP module. + +* Switched the TCP, UDP and IP header structures to be structs rather + than typedefs. + +* Prefixed TCP state names with UIP_ to avoid name space + contamination. + +* Changed declarations of uip_appdatap and friends to void * to avoid + explicit typecasts. + +* Bugfixes + + o TCP: Fixed bug with high byte of peer window size. + + o TCP: Fixed bug that in some cases prevented concurrent reception and + transmission of TCP data. + + o TCP: uip_connect() didn't correctly calculate age of TIME_WAIT + connections. + + o TCP: Array index for uip_conns[] array was out of bounds in + comparison. Comparison changed to make index within bounds. + + o TCP: if the remote host crashes and tries to reestablish an old + connection, uIP should respond with an ACK with the correct + sequence and acknowledgment numbers, to which the remote host + should respond with an ACK. uIP did not respond with the correct + ACK. + + o TCP: Fixed check for SYNACK segment: now checks only relevant TCP + control flags and discards flags reserved for future expansion. + + o TCP: Fixed bug where uIP did not inform application that a connection + had been aborted during an active open. + + o TCP: FIN segment was accepted even though application had stopped + incoming data with uip_stop(). + + o TCP: A FINACK segment would not always correctly acknowledge data. + + o UDP: checksums are now calculated after all fields have been + filled in. + + o UDP: network byte order on lastport in uip_udp_new(). + + o IP: memset() bugs in IP fragment reassembly code fixed. diff --git a/uip/Makefile.include b/uip/Makefile.include new file mode 100644 index 0000000..b4d8a94 --- /dev/null +++ b/uip/Makefile.include @@ -0,0 +1,47 @@ + + +ifdef APPS + APPDIRS = $(foreach APP, $(APPS), ../apps/$(APP)) + -include $(foreach APP, $(APPS), ../apps/$(APP)/Makefile.$(APP)) + CFLAGS += $(addprefix -I../apps/,$(APPS)) +endif + +ifndef CCDEP + CCDEP = $(CC) +endif +ifndef CCDEPCFLAGS + CCDEPCFLAGS = $(CFLAGS) +endif +ifndef OBJECTDIR + OBJECTDIR = obj +endif + +ifeq (${wildcard $(OBJECTDIR)},) + DUMMY := ${shell mkdir $(OBJECTDIR)} +endif + + +vpath %.c . ../uip ../lib $(APPDIRS) + +$(OBJECTDIR)/%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJECTDIR)/%.d: %.c + @set -e; rm -f $@; \ + $(CCDEP) -MM $(CCDEPCFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,$(OBJECTDIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +UIP_SOURCES=uip.c uip_arp.c uiplib.c psock.c timer.c uip-neighbor.c + + +ifneq ($(MAKECMDGOALS),clean) +-include $(addprefix $(OBJECTDIR)/,$(UIP_SOURCES:.c=.d) \ + $(APP_SOURCES:.c=.d)) +endif + +uip.a: ${addprefix $(OBJECTDIR)/, $(UIP_SOURCES:.c=.o)} + $(AR) rcf $@ $^ + +apps.a: ${addprefix $(OBJECTDIR)/, $(APP_SOURCES:.c=.o)} + $(AR) rcf $@ $^ diff --git a/uip/clock.h b/uip/clock.h new file mode 100644 index 0000000..f34d78f --- /dev/null +++ b/uip/clock.h @@ -0,0 +1,88 @@ +/** + * \defgroup clock Clock interface + * + * The clock interface is the interface between the \ref timer "timer library" + * and the platform specific clock functionality. The clock + * interface must be implemented for each platform that uses the \ref + * timer "timer library". + * + * The clock interface does only one this: it measures time. The clock + * interface provides a macro, CLOCK_SECOND, which corresponds to one + * second of system time. + * + * \sa \ref timer "Timer library" + * + * @{ + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $ + */ +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include "clock-arch.h" + +/** + * Initialize the clock library. + * + * This function initializes the clock library and should be called + * from the main() function of the system. + * + */ +void clock_init(void); + +/** + * Get the current clock time. + * + * This function returns the current system clock time. + * + * \return The current clock time, measured in system ticks. + */ +clock_time_t clock_time(void); + +/** + * A second, measured in system clock time. + * + * \hideinitializer + */ +#ifdef CLOCK_CONF_SECOND +#define CLOCK_SECOND CLOCK_CONF_SECOND +#else +#define CLOCK_SECOND (clock_time_t)32 +#endif + +#endif /* __CLOCK_H__ */ + +/** @} */ diff --git a/uip/lc-addrlabels.h b/uip/lc-addrlabels.h new file mode 100644 index 0000000..fe1387e --- /dev/null +++ b/uip/lc-addrlabels.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on the "Labels as + * values" feature of gcc + * \author + * Adam Dunkels + * + * This implementation of local continuations is based on a special + * feature of the GCC C compiler called "labels as values". This + * feature allows assigning pointers with the address of the code + * corresponding to a particular C label. + * + * For more information, see the GCC documentation: + * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html + * + * Thanks to dividuum for finding the nice local scope label + * implementation. + */ + +#ifndef __LC_ADDRLABELS_H__ +#define __LC_ADDRLABELS_H__ + +/** \hideinitializer */ +typedef void * lc_t; + +#define LC_INIT(s) s = NULL + + +#define LC_RESUME(s) \ + do { \ + if(s != NULL) { \ + goto *s; \ + } \ + } while(0) + +#define LC_SET(s) \ + do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0) + +#define LC_END(s) + +#endif /* __LC_ADDRLABELS_H__ */ + +/** @} */ diff --git a/uip/lc-switch.h b/uip/lc-switch.h new file mode 100644 index 0000000..f32885f --- /dev/null +++ b/uip/lc-switch.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on switch() statment + * \author Adam Dunkels + * + * This implementation of local continuations uses the C switch() + * statement to resume execution of a function somewhere inside the + * function's body. The implementation is based on the fact that + * switch() statements are able to jump directly into the bodies of + * control structures such as if() or while() statmenets. + * + * This implementation borrows heavily from Simon Tatham's coroutines + * implementation in C: + * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html + */ + +#ifndef __LC_SWITCH_H__ +#define __LC_SWTICH_H__ + +/* WARNING! lc implementation using switch() does not work if an + LC_SET() is done within another switch() statement! */ + +/** \hideinitializer */ +typedef unsigned short lc_t; + +#define LC_INIT(s) s = 0; + +#define LC_RESUME(s) switch(s) { case 0: + +#define LC_SET(s) s = __LINE__; case __LINE__: + +#define LC_END(s) } + +#endif /* __LC_SWITCH_H__ */ + +/** @} */ diff --git a/uip/lc.h b/uip/lc.h new file mode 100644 index 0000000..a9e9d46 --- /dev/null +++ b/uip/lc.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \defgroup lc Local continuations + * @{ + * + * Local continuations form the basis for implementing protothreads. A + * local continuation can be set in a specific function to + * capture the state of the function. After a local continuation has + * been set can be resumed in order to restore the state of the + * function at the point where the local continuation was set. + * + * + */ + +/** + * \file lc.h + * Local continuations + * \author + * Adam Dunkels + * + */ + +#ifdef DOXYGEN +/** + * Initialize a local continuation. + * + * This operation initializes the local continuation, thereby + * unsetting any previously set continuation state. + * + * \hideinitializer + */ +#define LC_INIT(lc) + +/** + * Set a local continuation. + * + * The set operation saves the state of the function at the point + * where the operation is executed. As far as the set operation is + * concerned, the state of the function does not include the + * call-stack or local (automatic) variables, but only the program + * counter and such CPU registers that needs to be saved. + * + * \hideinitializer + */ +#define LC_SET(lc) + +/** + * Resume a local continuation. + * + * The resume operation resumes a previously set local continuation, thus + * restoring the state in which the function was when the local + * continuation was set. If the local continuation has not been + * previously set, the resume operation does nothing. + * + * \hideinitializer + */ +#define LC_RESUME(lc) + +/** + * Mark the end of local continuation usage. + * + * The end operation signifies that local continuations should not be + * used any more in the function. This operation is not needed for + * most implementations of local continuation, but is required by a + * few implementations. + * + * \hideinitializer + */ +#define LC_END(lc) + +/** + * \var typedef lc_t; + * + * The local continuation type. + * + * \hideinitializer + */ +#endif /* DOXYGEN */ + +#ifndef __LC_H__ +#define __LC_H__ + +#ifdef LC_CONF_INCLUDE +#include LC_CONF_INCLUDE +#else +#include "lc-switch.h" +#endif /* LC_CONF_INCLUDE */ + +#endif /* __LC_H__ */ + +/** @} */ +/** @} */ diff --git a/uip/psock.c b/uip/psock.c new file mode 100644 index 0000000..f284cb9 --- /dev/null +++ b/uip/psock.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +#include +#include + +#include "uipopt.h" +#include "psock.h" +#include "uip.h" + +#define STATE_NONE 0 +#define STATE_ACKED 1 +#define STATE_READ 2 +#define STATE_BLOCKED_NEWDATA 3 +#define STATE_BLOCKED_CLOSE 4 +#define STATE_BLOCKED_SEND 5 +#define STATE_DATA_SENT 6 + +/* + * Return value of the buffering functions that indicates that a + * buffer was not filled by incoming data. + * + */ +#define BUF_NOT_FULL 0 +#define BUF_NOT_FOUND 0 + +/* + * Return value of the buffering functions that indicates that a + * buffer was completely filled by incoming data. + * + */ +#define BUF_FULL 1 + +/* + * Return value of the buffering functions that indicates that an + * end-marker byte was found. + * + */ +#define BUF_FOUND 2 + +/*---------------------------------------------------------------------------*/ +static void +buf_setup(struct psock_buf *buf, + u8_t *bufptr, u16_t bufsize) +{ + buf->ptr = bufptr; + buf->left = bufsize; +} +/*---------------------------------------------------------------------------*/ +static u8_t +buf_bufdata(struct psock_buf *buf, u16_t len, + u8_t **dataptr, u16_t *datalen) +{ + if(*datalen < buf->left) { + memcpy(buf->ptr, *dataptr, *datalen); + buf->ptr += *datalen; + buf->left -= *datalen; + *dataptr += *datalen; + *datalen = 0; + return BUF_NOT_FULL; + } else if(*datalen == buf->left) { + memcpy(buf->ptr, *dataptr, *datalen); + buf->ptr += *datalen; + buf->left = 0; + *dataptr += *datalen; + *datalen = 0; + return BUF_FULL; + } else { + memcpy(buf->ptr, *dataptr, buf->left); + buf->ptr += buf->left; + *datalen -= buf->left; + *dataptr += buf->left; + buf->left = 0; + return BUF_FULL; + } +} +/*---------------------------------------------------------------------------*/ +static u8_t +buf_bufto(register struct psock_buf *buf, u8_t endmarker, + register u8_t **dataptr, register u16_t *datalen) +{ + u8_t c; + while(buf->left > 0 && *datalen > 0) { + c = *buf->ptr = **dataptr; + ++*dataptr; + ++buf->ptr; + --*datalen; + --buf->left; + + if(c == endmarker) { + return BUF_FOUND; + } + } + + if(*datalen == 0) { + return BUF_NOT_FOUND; + } + + while(*datalen > 0) { + c = **dataptr; + --*datalen; + ++*dataptr; + + if(c == endmarker) { + return BUF_FOUND | BUF_FULL; + } + } + + return BUF_FULL; +} +/*---------------------------------------------------------------------------*/ +static char +send_data(register struct psock *s) +{ + if(s->state != STATE_DATA_SENT || uip_rexmit()) { + if(s->sendlen > uip_mss()) { + uip_send(s->sendptr, uip_mss()); + } else { + uip_send(s->sendptr, s->sendlen); + } + s->state = STATE_DATA_SENT; + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static char +data_acked(register struct psock *s) +{ + if(s->state == STATE_DATA_SENT && uip_acked()) { + if(s->sendlen > uip_mss()) { + s->sendlen -= uip_mss(); + s->sendptr += uip_mss(); + } else { + s->sendptr += s->sendlen; + s->sendlen = 0; + } + s->state = STATE_ACKED; + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_send(register struct psock *s, const char *buf, + unsigned int len)) +{ + PT_BEGIN(&s->psockpt); + + /* If there is no data to send, we exit immediately. */ + if(len == 0) { + PT_EXIT(&s->psockpt); + } + + /* Save the length of and a pointer to the data that is to be + sent. */ + s->sendptr = buf; + s->sendlen = len; + + s->state = STATE_NONE; + + /* We loop here until all data is sent. The s->sendlen variable is + updated by the data_sent() function. */ + while(s->sendlen > 0) { + + /* + * The condition for this PT_WAIT_UNTIL is a little tricky: the + * protothread will wait here until all data has been acknowledged + * (data_acked() returns true) and until all data has been sent + * (send_data() returns true). The two functions data_acked() and + * send_data() must be called in succession to ensure that all + * data is sent. Therefore the & operator is used instead of the + * && operator, which would cause only the data_acked() function + * to be called when it returns false. + */ + PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); + } + + s->state = STATE_NONE; + + PT_END(&s->psockpt); +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_generator_send(register struct psock *s, + unsigned short (*generate)(void *), void *arg)) +{ + PT_BEGIN(&s->psockpt); + + /* Ensure that there is a generator function to call. */ + if(generate == NULL) { + PT_EXIT(&s->psockpt); + } + + /* Call the generator function to generate the data in the + uip_appdata buffer. */ + s->sendlen = generate(arg); + s->sendptr = uip_appdata; + + s->state = STATE_NONE; + do { + /* Call the generator function again if we are called to perform a + retransmission. */ + if(uip_rexmit()) { + generate(arg); + } + /* Wait until all data is sent and acknowledged. */ + PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); + } while(s->sendlen > 0); + + s->state = STATE_NONE; + + PT_END(&s->psockpt); +} +/*---------------------------------------------------------------------------*/ +u16_t +psock_datalen(struct psock *psock) +{ + return psock->bufsize - psock->buf.left; +} +/*---------------------------------------------------------------------------*/ +char +psock_newdata(struct psock *s) +{ + if(s->readlen > 0) { + /* There is data in the uip_appdata buffer that has not yet been + read with the PSOCK_READ functions. */ + return 1; + } else if(s->state == STATE_READ) { + /* All data in uip_appdata buffer already consumed. */ + s->state = STATE_BLOCKED_NEWDATA; + return 0; + } else if(uip_newdata()) { + /* There is new data that has not been consumed. */ + return 1; + } else { + /* There is no new data. */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_readto(register struct psock *psock, unsigned char c)) +{ + PT_BEGIN(&psock->psockpt); + + buf_setup(&psock->buf, psock->bufptr, psock->bufsize); + + /* XXX: Should add buf_checkmarker() before do{} loop, if + incoming data has been handled while waiting for a write. */ + + do { + if(psock->readlen == 0) { + PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); + psock->state = STATE_READ; + psock->readptr = (u8_t *)uip_appdata; + psock->readlen = uip_datalen(); + } + } while((buf_bufto(&psock->buf, c, + &psock->readptr, + &psock->readlen) & BUF_FOUND) == 0); + + if(psock_datalen(psock) == 0) { + psock->state = STATE_NONE; + PT_RESTART(&psock->psockpt); + } + PT_END(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_readbuf(register struct psock *psock)) +{ + PT_BEGIN(&psock->psockpt); + + buf_setup(&psock->buf, psock->bufptr, psock->bufsize); + + /* XXX: Should add buf_checkmarker() before do{} loop, if + incoming data has been handled while waiting for a write. */ + + do { + if(psock->readlen == 0) { + PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); + printf("Waited for newdata\n"); + psock->state = STATE_READ; + psock->readptr = (u8_t *)uip_appdata; + psock->readlen = uip_datalen(); + } + } while(buf_bufdata(&psock->buf, psock->bufsize, + &psock->readptr, + &psock->readlen) != BUF_FULL); + + if(psock_datalen(psock) == 0) { + psock->state = STATE_NONE; + PT_RESTART(&psock->psockpt); + } + PT_END(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ +void +psock_init(register struct psock *psock, char *buffer, unsigned int buffersize) +{ + psock->state = STATE_NONE; + psock->readlen = 0; + psock->bufptr = buffer; + psock->bufsize = buffersize; + buf_setup(&psock->buf, buffer, buffersize); + PT_INIT(&psock->pt); + PT_INIT(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ diff --git a/uip/psock.h b/uip/psock.h new file mode 100644 index 0000000..3dffa73 --- /dev/null +++ b/uip/psock.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \defgroup psock Protosockets library + * @{ + * + * The protosocket library provides an interface to the uIP stack that is + * similar to the traditional BSD socket interface. Unlike programs + * written for the ordinary uIP event-driven interface, programs + * written with the protosocket library are executed in a sequential + * fashion and does not have to be implemented as explicit state + * machines. + * + * Protosockets only work with TCP connections. + * + * The protosocket library uses \ref pt protothreads to provide + * sequential control flow. This makes the protosockets lightweight in + * terms of memory, but also means that protosockets inherits the + * functional limitations of protothreads. Each protosocket lives only + * within a single function. Automatic variables (stack variables) are + * not retained across a protosocket library function call. + * + * \note Because the protosocket library uses protothreads, local + * variables will not always be saved across a call to a protosocket + * library function. It is therefore advised that local variables are + * used with extreme care. + * + * The protosocket library provides functions for sending data without + * having to deal with retransmissions and acknowledgements, as well + * as functions for reading data without having to deal with data + * being split across more than one TCP segment. + * + * Because each protosocket runs as a protothread, the protosocket has to be + * started with a call to PSOCK_BEGIN() at the start of the function + * in which the protosocket is used. Similarly, the protosocket protothread can + * be terminated by a call to PSOCK_EXIT(). + * + */ + +/** + * \file + * Protosocket library header file + * \author + * Adam Dunkels + * + */ + +#ifndef __PSOCK_H__ +#define __PSOCK_H__ + +#include "uipopt.h" +#include "pt.h" + + /* + * The structure that holds the state of a buffer. + * + * This structure holds the state of a uIP buffer. The structure has + * no user-visible elements, but is used through the functions + * provided by the library. + * + */ +struct psock_buf { + u8_t *ptr; + unsigned short left; +}; + +/** + * The representation of a protosocket. + * + * The protosocket structrure is an opaque structure with no user-visible + * elements. + */ +struct psock { + struct pt pt, psockpt; /* Protothreads - one that's using the psock + functions, and one that runs inside the + psock functions. */ + const u8_t *sendptr; /* Pointer to the next data to be sent. */ + u8_t *readptr; /* Pointer to the next data to be read. */ + + char *bufptr; /* Pointer to the buffer used for buffering + incoming data. */ + + u16_t sendlen; /* The number of bytes left to be sent. */ + u16_t readlen; /* The number of bytes left to be read. */ + + struct psock_buf buf; /* The structure holding the state of the + input buffer. */ + unsigned int bufsize; /* The size of the input buffer. */ + + unsigned char state; /* The state of the protosocket. */ +}; + +void psock_init(struct psock *psock, char *buffer, unsigned int buffersize); +/** + * Initialize a protosocket. + * + * This macro initializes a protosocket and must be called before the + * protosocket is used. The initialization also specifies the input buffer + * for the protosocket. + * + * \param psock (struct psock *) A pointer to the protosocket to be + * initialized + * + * \param buffer (char *) A pointer to the input buffer for the + * protosocket. + * + * \param buffersize (unsigned int) The size of the input buffer. + * + * \hideinitializer + */ +#define PSOCK_INIT(psock, buffer, buffersize) \ + psock_init(psock, buffer, buffersize) + +/** + * Start the protosocket protothread in a function. + * + * This macro starts the protothread associated with the protosocket and + * must come before other protosocket calls in the function it is used. + * + * \param psock (struct psock *) A pointer to the protosocket to be + * started. + * + * \hideinitializer + */ +#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt)) + +PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len)); +/** + * Send data. + * + * This macro sends data over a protosocket. The protosocket protothread blocks + * until all data has been sent and is known to have been received by + * the remote end of the TCP connection. + * + * \param psock (struct psock *) A pointer to the protosocket over which + * data is to be sent. + * + * \param data (char *) A pointer to the data that is to be sent. + * + * \param datalen (unsigned int) The length of the data that is to be + * sent. + * + * \hideinitializer + */ +#define PSOCK_SEND(psock, data, datalen) \ + PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen)) + +/** + * \brief Send a null-terminated string. + * \param psock Pointer to the protosocket. + * \param str The string to be sent. + * + * This function sends a null-terminated string over the + * protosocket. + * + * \hideinitializer + */ +#define PSOCK_SEND_STR(psock, str) \ + PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str))) + +PT_THREAD(psock_generator_send(struct psock *psock, + unsigned short (*f)(void *), void *arg)); + +/** + * \brief Generate data with a function and send it + * \param psock Pointer to the protosocket. + * \param generator Pointer to the generator function + * \param arg Argument to the generator function + * + * This function generates data and sends it over the + * protosocket. This can be used to dynamically generate + * data for a transmission, instead of generating the data + * in a buffer beforehand. This function reduces the need for + * buffer memory. The generator function is implemented by + * the application, and a pointer to the function is given + * as an argument with the call to PSOCK_GENERATOR_SEND(). + * + * The generator function should place the generated data + * directly in the uip_appdata buffer, and return the + * length of the generated data. The generator function is + * called by the protosocket layer when the data first is + * sent, and once for every retransmission that is needed. + * + * \hideinitializer + */ +#define PSOCK_GENERATOR_SEND(psock, generator, arg) \ + PT_WAIT_THREAD(&((psock)->pt), \ + psock_generator_send(psock, generator, arg)) + + +/** + * Close a protosocket. + * + * This macro closes a protosocket and can only be called from within the + * protothread in which the protosocket lives. + * + * \param psock (struct psock *) A pointer to the protosocket that is to + * be closed. + * + * \hideinitializer + */ +#define PSOCK_CLOSE(psock) uip_close() + +PT_THREAD(psock_readbuf(struct psock *psock)); +/** + * Read data until the buffer is full. + * + * This macro will block waiting for data and read the data into the + * input buffer specified with the call to PSOCK_INIT(). Data is read + * until the buffer is full.. + * + * \param psock (struct psock *) A pointer to the protosocket from which + * data should be read. + * + * \hideinitializer + */ +#define PSOCK_READBUF(psock) \ + PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock)) + +PT_THREAD(psock_readto(struct psock *psock, unsigned char c)); +/** + * Read data up to a specified character. + * + * This macro will block waiting for data and read the data into the + * input buffer specified with the call to PSOCK_INIT(). Data is only + * read until the specifieed character appears in the data stream. + * + * \param psock (struct psock *) A pointer to the protosocket from which + * data should be read. + * + * \param c (char) The character at which to stop reading. + * + * \hideinitializer + */ +#define PSOCK_READTO(psock, c) \ + PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c)) + +/** + * The length of the data that was previously read. + * + * This macro returns the length of the data that was previously read + * using PSOCK_READTO() or PSOCK_READ(). + * + * \param psock (struct psock *) A pointer to the protosocket holding the data. + * + * \hideinitializer + */ +#define PSOCK_DATALEN(psock) psock_datalen(psock) + +u16_t psock_datalen(struct psock *psock); + +/** + * Exit the protosocket's protothread. + * + * This macro terminates the protothread of the protosocket and should + * almost always be used in conjunction with PSOCK_CLOSE(). + * + * \sa PSOCK_CLOSE_EXIT() + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt)) + +/** + * Close a protosocket and exit the protosocket's protothread. + * + * This macro closes a protosocket and exits the protosocket's protothread. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_CLOSE_EXIT(psock) \ + do { \ + PSOCK_CLOSE(psock); \ + PSOCK_EXIT(psock); \ + } while(0) + +/** + * Declare the end of a protosocket's protothread. + * + * This macro is used for declaring that the protosocket's protothread + * ends. It must always be used together with a matching PSOCK_BEGIN() + * macro. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_END(psock) PT_END(&((psock)->pt)) + +char psock_newdata(struct psock *s); + +/** + * Check if new data has arrived on a protosocket. + * + * This macro is used in conjunction with the PSOCK_WAIT_UNTIL() + * macro to check if data has arrived on a protosocket. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_NEWDATA(psock) psock_newdata(psock) + +/** + * Wait until a condition is true. + * + * This macro blocks the protothread until the specified condition is + * true. The macro PSOCK_NEWDATA() can be used to check if new data + * arrives when the protosocket is waiting. + * + * Typically, this macro is used as follows: + * + \code + PT_THREAD(thread(struct psock *s, struct timer *t)) + { + PSOCK_BEGIN(s); + + PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t)); + + if(PSOCK_NEWDATA(s)) { + PSOCK_READTO(s, '\n'); + } else { + handle_timed_out(s); + } + + PSOCK_END(s); + } + \endcode + * + * \param psock (struct psock *) A pointer to the protosocket. + * \param condition The condition to wait for. + * + * \hideinitializer + */ +#define PSOCK_WAIT_UNTIL(psock, condition) \ + PT_WAIT_UNTIL(&((psock)->pt), (condition)); + +#define PSOCK_WAIT_THREAD(psock, condition) \ + PT_WAIT_THREAD(&((psock)->pt), (condition)) + +#endif /* __PSOCK_H__ */ + +/** @} */ diff --git a/uip/pt.h b/uip/pt.h new file mode 100644 index 0000000..9f1f64d --- /dev/null +++ b/uip/pt.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \file + * Protothreads implementation. + * \author + * Adam Dunkels + * + */ + +#ifndef __PT_H__ +#define __PT_H__ + +#include "lc.h" + +struct pt { + lc_t lc; +}; + +#define PT_WAITING 0 +#define PT_EXITED 1 +#define PT_ENDED 2 +#define PT_YIELDED 3 + +/** + * \name Initialization + * @{ + */ + +/** + * Initialize a protothread. + * + * Initializes a protothread. Initialization must be done prior to + * starting to execute the protothread. + * + * \param pt A pointer to the protothread control structure. + * + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PT_INIT(pt) LC_INIT((pt)->lc) + +/** @} */ + +/** + * \name Declaration and definition + * @{ + */ + +/** + * Declaration of a protothread. + * + * This macro is used to declare a protothread. All protothreads must + * be declared with this macro. + * + * \param name_args The name and arguments of the C function + * implementing the protothread. + * + * \hideinitializer + */ +#define PT_THREAD(name_args) char name_args + +/** + * Declare the start of a protothread inside the C function + * implementing the protothread. + * + * This macro is used to declare the starting point of a + * protothread. It should be placed at the start of the function in + * which the protothread runs. All C statements above the PT_BEGIN() + * invokation will be executed each time the protothread is scheduled. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) + +/** + * Declare the end of a protothread. + * + * This macro is used for declaring that a protothread ends. It must + * always be used together with a matching PT_BEGIN() macro. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ + PT_INIT(pt); return PT_ENDED; } + +/** @} */ + +/** + * \name Blocked wait + * @{ + */ + +/** + * Block and wait until condition is true. + * + * This macro blocks the protothread until the specified condition is + * true. + * + * \param pt A pointer to the protothread control structure. + * \param condition The condition. + * + * \hideinitializer + */ +#define PT_WAIT_UNTIL(pt, condition) \ + do { \ + LC_SET((pt)->lc); \ + if(!(condition)) { \ + return PT_WAITING; \ + } \ + } while(0) + +/** + * Block and wait while condition is true. + * + * This function blocks and waits while condition is true. See + * PT_WAIT_UNTIL(). + * + * \param pt A pointer to the protothread control structure. + * \param cond The condition. + * + * \hideinitializer + */ +#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) + +/** @} */ + +/** + * \name Hierarchical protothreads + * @{ + */ + +/** + * Block and wait until a child protothread completes. + * + * This macro schedules a child protothread. The current protothread + * will block until the child protothread completes. + * + * \note The child protothread must be manually initialized with the + * PT_INIT() function before this function is used. + * + * \param pt A pointer to the protothread control structure. + * \param thread The child protothread with arguments + * + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) + +/** + * Spawn a child protothread and wait until it exits. + * + * This macro spawns a child protothread and waits until it exits. The + * macro can only be used within a protothread. + * + * \param pt A pointer to the protothread control structure. + * \param child A pointer to the child protothread's control structure. + * \param thread The child protothread with arguments + * + * \hideinitializer + */ +#define PT_SPAWN(pt, child, thread) \ + do { \ + PT_INIT((child)); \ + PT_WAIT_THREAD((pt), (thread)); \ + } while(0) + +/** @} */ + +/** + * \name Exiting and restarting + * @{ + */ + +/** + * Restart the protothread. + * + * This macro will block and cause the running protothread to restart + * its execution at the place of the PT_BEGIN() call. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_RESTART(pt) \ + do { \ + PT_INIT(pt); \ + return PT_WAITING; \ + } while(0) + +/** + * Exit the protothread. + * + * This macro causes the protothread to exit. If the protothread was + * spawned by another protothread, the parent protothread will become + * unblocked and can continue to run. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_EXIT(pt) \ + do { \ + PT_INIT(pt); \ + return PT_EXITED; \ + } while(0) + +/** @} */ + +/** + * \name Calling a protothread + * @{ + */ + +/** + * Schedule a protothread. + * + * This function shedules a protothread. The return value of the + * function is non-zero if the protothread is running or zero if the + * protothread has exited. + * + * \param f The call to the C function implementing the protothread to + * be scheduled + * + * \hideinitializer + */ +#define PT_SCHEDULE(f) ((f) == PT_WAITING) + +/** @} */ + +/** + * \name Yielding from a protothread + * @{ + */ + +/** + * Yield from the current protothread. + * + * This function will yield the protothread, thereby allowing other + * processing to take place in the system. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_YIELD(pt) \ + do { \ + PT_YIELD_FLAG = 0; \ + LC_SET((pt)->lc); \ + if(PT_YIELD_FLAG == 0) { \ + return PT_YIELDED; \ + } \ + } while(0) + +/** + * \brief Yield from the protothread until a condition occurs. + * \param pt A pointer to the protothread control structure. + * \param cond The condition. + * + * This function will yield the protothread, until the + * specified condition evaluates to true. + * + * + * \hideinitializer + */ +#define PT_YIELD_UNTIL(pt, cond) \ + do { \ + PT_YIELD_FLAG = 0; \ + LC_SET((pt)->lc); \ + if((PT_YIELD_FLAG == 0) || !(cond)) { \ + return PT_YIELDED; \ + } \ + } while(0) + +/** @} */ + +#endif /* __PT_H__ */ + +/** @} */ diff --git a/uip/slipdev.c b/uip/slipdev.c deleted file mode 100644 index 4e25b51..0000000 --- a/uip/slipdev.c +++ /dev/null @@ -1,202 +0,0 @@ -/** - * \addtogroup uip - * @{ - */ - -/** - * \defgroup slip Serial Line IP (SLIP) protocol - * @{ - * - * The SLIP protocol is a very simple way to transmit IP packets over - * a serial line. It does not provide any framing or error control, - * and is therefore not very widely used today. - * - * This SLIP implementation requires two functions for accessing the - * serial device: slipdev_char_poll() and slipdev_char_put(). These - * must be implemented specifically for the system on which the SLIP - * protocol is to be run. - */ - -/** - * \file - * SLIP protocol implementation - * \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: slipdev.c,v 1.1.2.3 2003/10/07 13:23:01 adam Exp $ - * - */ - -/* - * This is a generic implementation of the SLIP protocol over an RS232 - * (serial) device. - * - * Huge thanks to Ullrich von Bassewitz of cc65 fame for - * and endless supply of bugfixes, insightsful comments and - * suggestions, and improvements to this code! - */ - -#include "uip.h" - -#define SLIP_END 0300 -#define SLIP_ESC 0333 -#define SLIP_ESC_END 0334 -#define SLIP_ESC_ESC 0335 - -static u8_t slip_buf[UIP_BUFSIZE]; - -static u16_t len, tmplen; -static u8_t lastc; - -/*-----------------------------------------------------------------------------------*/ -/** - * Send the packet in the uip_buf and uip_appdata buffers using the - * SLIP protocol. - * - * The first 40 bytes of the packet (the IP and TCP headers) are read - * from the uip_buf buffer, and the following bytes (the application - * data) are read from the uip_appdata buffer. - * - */ -/*-----------------------------------------------------------------------------------*/ -void -slipdev_send(void) -{ - u16_t i; - u8_t *ptr; - u8_t c; - - slipdev_char_put(SLIP_END); - - ptr = uip_buf; - for(i = 0; i < uip_len; ++i) { - if(i == 40) { - ptr = (char *)uip_appdata; - } - c = *ptr++; - switch(c) { - case SLIP_END: - slipdev_char_put(SLIP_ESC); - slipdev_char_put(SLIP_ESC_END); - break; - case SLIP_ESC: - slipdev_char_put(SLIP_ESC); - slipdev_char_put(SLIP_ESC_ESC); - break; - default: - slipdev_char_put(c); - break; - } - } - slipdev_char_put(SLIP_END); -} -/*-----------------------------------------------------------------------------------*/ -/** - * Poll the SLIP device for an available packet. - * - * This function will poll the SLIP device to see if a packet is - * available. It uses a buffer in which all avaliable bytes from the - * RS232 interface are read into. When a full packet has been read - * into the buffer, the packet is copied into the uip_buf buffer and - * the length of the packet is returned. - * - * \return The length of the packet placed in the uip_buf buffer, or - * zero if no packet is available. - */ -/*-----------------------------------------------------------------------------------*/ -u16_t -slipdev_poll(void) -{ - u8_t c; - - while(slipdev_char_poll(c)) { - switch(c) { - case SLIP_ESC: - lastc = c; - break; - - case SLIP_END: - lastc = c; - /* End marker found, we copy our input buffer to the uip_buf - buffer and return the size of the packet we copied. */ - memcpy(uip_buf, slip_buf, len); - tmplen = len; - len = 0; - return tmplen; - - default: - if(lastc == SLIP_ESC) { - lastc = c; - /* Previous read byte was an escape byte, so this byte will be - interpreted differently from others. */ - switch(c) { - case SLIP_ESC_END: - c = SLIP_END; - break; - case SLIP_ESC_ESC: - c = SLIP_ESC; - break; - } - } else { - lastc = c; - } - - slip_buf[len] = c; - ++len; - - if(len > UIP_BUFSIZE) { - len = 0; - } - - break; - } - } - return 0; -} -/*-----------------------------------------------------------------------------------*/ -/** - * Initialize the SLIP module. - * - * This function does not initialize the underlying RS232 device, but - * only the SLIP part. - */ -/*-----------------------------------------------------------------------------------*/ -void -slipdev_init(void) -{ - lastc = len = 0; -} -/*-----------------------------------------------------------------------------------*/ - -/** @} */ -/** @} */ diff --git a/uip/slipdev.h b/uip/slipdev.h deleted file mode 100644 index b040b50..0000000 --- a/uip/slipdev.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * \addtogroup slip - * @{ - */ - -/** - * \file - * SLIP header file. - * \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: slipdev.h,v 1.1.2.3 2003/10/06 22:42:51 adam Exp $ - * - */ - -#ifndef __SLIPDEV_H__ -#define __SLIPDEV_H__ - -#include "uip.h" - -/** - * Put a character on the serial device. - * - * This function is used by the SLIP implementation to put a character - * on the serial device. It must be implemented specifically for the - * system on which the SLIP implementation is to be run. - * - * \param c The character to be put on the serial device. - */ -void slipdev_char_put(u8_t c); - -/** - * Poll the serial device for a character. - * - * This function is used by the SLIP implementation to poll the serial - * device for a character. It must be implemented specifically for the - * system on which the SLIP implementation is to be run. - * - * The function should return immediately regardless if a character is - * available or not. If a character is available it should be placed - * at the memory location pointed to by the pointer supplied by the - * arguement c. - * - * \param c A pointer to a byte that is filled in by the function with - * the received character, if available. - * - * \retval 0 If no character is available. - * \retval Non-zero If a character is available. - */ -u8_t slipdev_char_poll(u8_t *c); - -void slipdev_init(void); -void slipdev_send(void); -u16_t slipdev_poll(void); - -#endif /* __SLIPDEV_H__ */ - -/** @} */ diff --git a/uip/timer.c b/uip/timer.c new file mode 100644 index 0000000..74eedf6 --- /dev/null +++ b/uip/timer.c @@ -0,0 +1,127 @@ +/** + * \addtogroup timer + * @{ + */ + +/** + * \file + * Timer library implementation. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +#include "clock.h" +#include "timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function is used to set a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * \param t A pointer to the timer + * \param interval The interval before the timer expires. + * + */ +void +timer_set(struct timer *t, clock_time_t interval) +{ + t->interval = interval; + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_rester() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +timer_reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +timer_restart(struct timer *t) +{ + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +timer_expired(struct timer *t) +{ + return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/uip/timer.h b/uip/timer.h new file mode 100644 index 0000000..057bea4 --- /dev/null +++ b/uip/timer.h @@ -0,0 +1,86 @@ +/** + * \defgroup timer Timer library + * + * The timer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c timer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The timer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the format used by + * the clock library. + * + * @{ + */ + + +/** + * \file + * Timer library header file. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $ + */ +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#include "clock.h" + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with timer_set() before it can be used. + * + * \hideinitializer + */ +struct timer { + clock_time_t start; + clock_time_t interval; +}; + +void timer_set(struct timer *t, clock_time_t interval); +void timer_reset(struct timer *t); +void timer_restart(struct timer *t); +int timer_expired(struct timer *t); + +#endif /* __TIMER_H__ */ + +/** @} */ diff --git a/uip/uip-fw.c b/uip/uip-fw.c new file mode 100644 index 0000000..01858ea --- /dev/null +++ b/uip/uip-fw.c @@ -0,0 +1,532 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipfw uIP packet forwarding + * @{ + * + */ + +/** + * \file + * uIP packet forwarding. + * \author Adam Dunkels + * + * This file implements a number of simple functions which do packet + * forwarding over multiple network interfaces with uIP. + * + */ + +#include "uip.h" +#include "uip_arch.h" +#include "uip-fw.h" + +#include /* for memcpy() */ + +/* + * The list of registered network interfaces. + */ +static struct uip_fw_netif *netifs = NULL; + +/* + * A pointer to the default network interface. + */ +static struct uip_fw_netif *defaultnetif = NULL; + +struct tcpip_hdr { + /* IP header. */ + u8_t vhl, + tos; + u16_t len, + ipid, + ipoffset; + u8_t 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]; +}; + +struct icmpip_hdr { + /* 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; + u8_t payload[1]; +}; + +/* ICMP ECHO. */ +#define ICMP_ECHO 8 + +/* ICMP TIME-EXCEEDED. */ +#define ICMP_TE 11 + +/* + * Pointer to the TCP/IP headers of the packet in the uip_buf buffer. + */ +#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/* + * Pointer to the ICMP/IP headers of the packet in the uip_buf buffer. + */ +#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/* + * Certain fields of an IP packet that are used for identifying + * duplicate packets. + */ +struct fwcache_entry { + u16_t timer; + + u16_t srcipaddr[2]; + u16_t destipaddr[2]; + u16_t ipid; + u8_t proto; + u8_t unused; + +#if notdef + u16_t payload[2]; +#endif + +#if UIP_REASSEMBLY > 0 + u16_t len, offset; +#endif +}; + +/* + * The number of packets to remember when looking for duplicates. + */ +#ifdef UIP_CONF_FWCACHE_SIZE +#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE +#else +#define FWCACHE_SIZE 2 +#endif + + +/* + * A cache of packet header fields which are used for + * identifying duplicate packets. + */ +static struct fwcache_entry fwcache[FWCACHE_SIZE]; + +/** + * \internal + * The time that a packet cache is active. + */ +#define FW_TIME 20 + +/*------------------------------------------------------------------------------*/ +/** + * Initialize the uIP packet forwarding module. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_init(void) +{ + struct uip_fw_netif *t; + defaultnetif = NULL; + while(netifs != NULL) { + t = netifs; + netifs = netifs->next; + t->next = NULL; + } +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Check if an IP address is within the network defined by an IP + * address and a netmask. + * + * \param ipaddr The IP address to be checked. + * \param netipaddr The IP address of the network. + * \param netmask The netmask of the network. + * + * \return Non-zero if IP address is in network, zero otherwise. + */ +/*------------------------------------------------------------------------------*/ +static unsigned char +ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask) +{ + return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) && + (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]); +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Send out an ICMP TIME-EXCEEDED message. + * + * This function replaces the packet in the uip_buf buffer with the + * ICMP packet. + */ +/*------------------------------------------------------------------------------*/ +static void +time_exceeded(void) +{ + u16_t tmp16; + + /* We don't send out ICMP errors for ICMP messages. */ + if(ICMPBUF->proto == UIP_PROTO_ICMP) { + uip_len = 0; + return; + } + /* Copy fields from packet header into payload of this ICMP packet. */ + memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28); + + /* Set the ICMP type and code. */ + ICMPBUF->type = ICMP_TE; + ICMPBUF->icode = 0; + + /* Calculate the ICMP checksum. */ + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36); + + /* Set the IP destination address to be the source address of the + original packet. */ + 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; + + /* Set our IP address as the source address. */ + BUF->srcipaddr[0] = uip_hostaddr[0]; + BUF->srcipaddr[1] = uip_hostaddr[1]; + + /* The size of the ICMP time exceeded packet is 36 + the size of the + IP header (20) = 56. */ + uip_len = 56; + ICMPBUF->len[0] = 0; + ICMPBUF->len[1] = uip_len; + + /* Fill in the other fields in the IP header. */ + ICMPBUF->vhl = 0x45; + ICMPBUF->tos = 0; + ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0; + ICMPBUF->ttl = UIP_TTL; + ICMPBUF->proto = UIP_PROTO_ICMP; + + /* Calculate IP checksum. */ + ICMPBUF->ipchksum = 0; + ICMPBUF->ipchksum = ~(uip_ipchksum()); + + +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Register a packet in the forwarding cache so that it won't be + * forwarded again. + */ +/*------------------------------------------------------------------------------*/ +static void +fwcache_register(void) +{ + struct fwcache_entry *fw; + int i, oldest; + + oldest = FW_TIME; + fw = NULL; + + /* Find the oldest entry in the cache. */ + for(i = 0; i < FWCACHE_SIZE; ++i) { + if(fwcache[i].timer == 0) { + fw = &fwcache[i]; + break; + } else if(fwcache[i].timer <= oldest) { + fw = &fwcache[i]; + oldest = fwcache[i].timer; + } + } + + fw->timer = FW_TIME; + fw->ipid = BUF->ipid; + fw->srcipaddr[0] = BUF->srcipaddr[0]; + fw->srcipaddr[1] = BUF->srcipaddr[1]; + fw->destipaddr[0] = BUF->destipaddr[0]; + fw->destipaddr[1] = BUF->destipaddr[1]; + fw->proto = BUF->proto; +#if notdef + fw->payload[0] = BUF->srcport; + fw->payload[1] = BUF->destport; +#endif +#if UIP_REASSEMBLY > 0 + fw->len = BUF->len; + fw->offset = BUF->ipoffset; +#endif +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Find a network interface for the IP packet in uip_buf. + */ +/*------------------------------------------------------------------------------*/ +static struct uip_fw_netif * +find_netif(void) +{ + struct uip_fw_netif *netif; + + /* Walk through every network interface to check for a match. */ + for(netif = netifs; netif != NULL; netif = netif->next) { + if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr, + netif->netmask)) { + /* If there was a match, we break the loop. */ + return netif; + } + } + + /* If no matching netif was found, we use default netif. */ + return defaultnetif; +} +/*------------------------------------------------------------------------------*/ +/** + * Output an IP packet on the correct network interface. + * + * The IP packet should be present in the uip_buf buffer and its + * length in the global uip_len variable. + * + * \retval UIP_FW_ZEROLEN Indicates that a zero-length packet + * transmission was attempted and that no packet was sent. + * + * \retval UIP_FW_NOROUTE No suitable network interface could be found + * for the outbound packet, and the packet was not sent. + * + * \return The return value from the actual network interface output + * function is passed unmodified as a return value. + */ +/*------------------------------------------------------------------------------*/ +u8_t +uip_fw_output(void) +{ + struct uip_fw_netif *netif; + + if(uip_len == 0) { + return UIP_FW_ZEROLEN; + } + + fwcache_register(); + +#if UIP_BROADCAST + /* Link local broadcasts go out on all interfaces. */ + if(/*BUF->proto == UIP_PROTO_UDP &&*/ + BUF->destipaddr[0] == 0xffff && + BUF->destipaddr[1] == 0xffff) { + if(defaultnetif != NULL) { + defaultnetif->output(); + } + for(netif = netifs; netif != NULL; netif = netif->next) { + netif->output(); + } + return UIP_FW_OK; + } +#endif /* UIP_BROADCAST */ + + netif = find_netif(); + /* printf("uip_fw_output: netif %p ->output %p len %d\n", netif, + netif->output, + uip_len);*/ + + if(netif == NULL) { + return UIP_FW_NOROUTE; + } + /* If we now have found a suitable network interface, we call its + output function to send out the packet. */ + return netif->output(); +} +/*------------------------------------------------------------------------------*/ +/** + * Forward an IP packet in the uip_buf buffer. + * + * + * + * \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if + * the packet should be processed locally. + */ +/*------------------------------------------------------------------------------*/ +u8_t +uip_fw_forward(void) +{ + struct fwcache_entry *fw; + + /* First check if the packet is destined for ourselves and return 0 + to indicate that the packet should be processed locally. */ + if(BUF->destipaddr[0] == uip_hostaddr[0] && + BUF->destipaddr[1] == uip_hostaddr[1]) { + return UIP_FW_LOCAL; + } + + /* If we use ping IP address configuration, and our IP address is + not yet configured, we should intercept all ICMP echo packets. */ +#if UIP_PINGADDRCONF + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 && + BUF->proto == UIP_PROTO_ICMP && + ICMPBUF->type == ICMP_ECHO) { + return UIP_FW_LOCAL; + } +#endif /* UIP_PINGADDRCONF */ + + /* Check if the packet is in the forwarding cache already, and if so + we drop it. */ + + for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { + if(fw->timer != 0 && +#if UIP_REASSEMBLY > 0 + fw->len == BUF->len && + fw->offset == BUF->ipoffset && +#endif + fw->ipid == BUF->ipid && + fw->srcipaddr[0] == BUF->srcipaddr[0] && + fw->srcipaddr[1] == BUF->srcipaddr[1] && + fw->destipaddr[0] == BUF->destipaddr[0] && + fw->destipaddr[1] == BUF->destipaddr[1] && +#if notdef + fw->payload[0] == BUF->srcport && + fw->payload[1] == BUF->destport && +#endif + fw->proto == BUF->proto) { + /* Drop packet. */ + return UIP_FW_FORWARDED; + } + } + + /* If the TTL reaches zero we produce an ICMP time exceeded message + in the uip_buf buffer and forward that packet back to the sender + of the packet. */ + if(BUF->ttl <= 1) { + /* No time exceeded for broadcasts and multicasts! */ + if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { + return UIP_FW_LOCAL; + } + time_exceeded(); + } + + /* Decrement the TTL (time-to-live) value in the IP header */ + BUF->ttl = BUF->ttl - 1; + + /* Update the IP checksum. */ + if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) { + BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1; + } else { + BUF->ipchksum = BUF->ipchksum + HTONS(0x0100); + } + + if(uip_len > 0) { + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]; + uip_fw_output(); + } + +#if UIP_BROADCAST + if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { + return UIP_FW_LOCAL; + } +#endif /* UIP_BROADCAST */ + + /* Return non-zero to indicate that the packet was forwarded and that no + other processing should be made. */ + return UIP_FW_FORWARDED; +} +/*------------------------------------------------------------------------------*/ +/** + * Register a network interface with the forwarding module. + * + * \param netif A pointer to the network interface that is to be + * registered. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_register(struct uip_fw_netif *netif) +{ + netif->next = netifs; + netifs = netif; +} +/*------------------------------------------------------------------------------*/ +/** + * Register a default network interface. + * + * All packets that don't go out on any of the other interfaces will + * be routed to the default interface. + * + * \param netif A pointer to the network interface that is to be + * registered. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_default(struct uip_fw_netif *netif) +{ + defaultnetif = netif; +} +/*------------------------------------------------------------------------------*/ +/** + * Perform periodic processing. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_periodic(void) +{ + struct fwcache_entry *fw; + for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { + if(fw->timer > 0) { + --fw->timer; + } + } +} +/*------------------------------------------------------------------------------*/ diff --git a/uip/uip-fw.h b/uip/uip-fw.h new file mode 100644 index 0000000..9033850 --- /dev/null +++ b/uip/uip-fw.h @@ -0,0 +1,176 @@ +/** + * \addtogroup uipfw + * @{ + */ + +/** + * \file + * uIP packet forwarding header file. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ +#ifndef __UIP_FW_H__ +#define __UIP_FW_H__ + +#include "uip.h" + +/** + * Representation of a uIP network interface. + */ +struct uip_fw_netif { + struct uip_fw_netif *next; /**< Pointer to the next interface when + linked in a list. */ + u16_t ipaddr[2]; /**< The IP address of this interface. */ + u16_t netmask[2]; /**< The netmask of the interface. */ + u8_t (* output)(void); + /**< A pointer to the function that + sends a packet. */ +}; + +/** + * Intantiating macro for a uIP network interface. + * + * Example: + \code + struct uip_fw_netif slipnetif = + {UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)}; + \endcode + * \param ip1,ip2,ip3,ip4 The IP address of the network interface. + * + * \param nm1,nm2,nm3,nm4 The netmask of the network interface. + * + * \param outputfunc A pointer to the output function of the network interface. + * + * \hideinitializer + */ +#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \ + NULL, \ + {HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \ + {HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \ + outputfunc + +/** + * Set the IP address of a network interface. + * + * \param netif A pointer to the uip_fw_netif structure for the network interface. + * + * \param addr A pointer to an IP address. + * + * \hideinitializer + */ +#define uip_fw_setipaddr(netif, addr) \ + do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \ + (netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0) +/** + * Set the netmask of a network interface. + * + * \param netif A pointer to the uip_fw_netif structure for the network interface. + * + * \param addr A pointer to an IP address representing the netmask. + * + * \hideinitializer + */ +#define uip_fw_setnetmask(netif, addr) \ + do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \ + (netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0) + +void uip_fw_init(void); +u8_t uip_fw_forward(void); +u8_t uip_fw_output(void); +void uip_fw_register(struct uip_fw_netif *netif); +void uip_fw_default(struct uip_fw_netif *netif); +void uip_fw_periodic(void); + + +/** + * A non-error message that indicates that a packet should be + * processed locally. + * + * \hideinitializer + */ +#define UIP_FW_LOCAL 0 + +/** + * A non-error message that indicates that something went OK. + * + * \hideinitializer + */ +#define UIP_FW_OK 0 + +/** + * A non-error message that indicates that a packet was forwarded. + * + * \hideinitializer + */ +#define UIP_FW_FORWARDED 1 + +/** + * A non-error message that indicates that a zero-length packet + * transmission was attempted, and that no packet was sent. + * + * \hideinitializer + */ +#define UIP_FW_ZEROLEN 2 + +/** + * An error message that indicates that a packet that was too large + * for the outbound network interface was detected. + * + * \hideinitializer + */ +#define UIP_FW_TOOLARGE 3 + +/** + * An error message that indicates that no suitable interface could be + * found for an outbound packet. + * + * \hideinitializer + */ +#define UIP_FW_NOROUTE 4 + +/** + * An error message that indicates that a packet that should be + * forwarded or output was dropped. + * + * \hideinitializer + */ +#define UIP_FW_DROPPED 5 + + +#endif /* __UIP_FW_H__ */ + +/** @} */ diff --git a/uip/uip-neighbor.c b/uip/uip-neighbor.c new file mode 100644 index 0000000..739c03e --- /dev/null +++ b/uip/uip-neighbor.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \file + * Database of link-local neighbors, used by IPv6 code and + * to be used by a future ARP code rewrite. + * \author + * Adam Dunkels + */ + +#include "uip-neighbor.h" + +#include + +#define MAX_TIME 128 + +#ifdef UIP_NEIGHBOR_CONF_ENTRIES +#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES +#else /* UIP_NEIGHBOR_CONF_ENTRIES */ +#define ENTRIES 8 +#endif /* UIP_NEIGHBOR_CONF_ENTRIES */ + +struct neighbor_entry { + uip_ipaddr_t ipaddr; + struct uip_neighbor_addr addr; + u8_t time; +}; +static struct neighbor_entry entries[ENTRIES]; + +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_init(void) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + entries[i].time = MAX_TIME; + } +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_periodic(void) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time < MAX_TIME) { + entries[i].time++; + } + } +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr) +{ + int i, oldest; + u8_t oldest_time; + + printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3], + addr->addr.addr[4], addr->addr.addr[5]); + + /* Find the first unused entry or the oldest used entry. */ + oldest_time = 0; + oldest = 0; + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time == MAX_TIME) { + oldest = i; + break; + } + if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) { + oldest = i; + break; + } + if(entries[i].time > oldest_time) { + oldest = i; + oldest_time = entries[i].time; + } + } + + /* Use the oldest or first free entry (either pointed to by the + "oldest" variable). */ + entries[oldest].time = 0; + uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr); + memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr)); +} +/*---------------------------------------------------------------------------*/ +static struct neighbor_entry * +find_entry(uip_ipaddr_t ipaddr) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) { + return &entries[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_update(uip_ipaddr_t ipaddr) +{ + struct neighbor_entry *e; + + e = find_entry(ipaddr); + if(e != NULL) { + e->time = 0; + } +} +/*---------------------------------------------------------------------------*/ +struct uip_neighbor_addr * +uip_neighbor_lookup(uip_ipaddr_t ipaddr) +{ + struct neighbor_entry *e; + + e = find_entry(ipaddr); + if(e != NULL) { + /* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3], + e->addr.addr.addr[4], e->addr.addr.addr[5]);*/ + + return &e->addr; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ diff --git a/uip/uip-neighbor.h b/uip/uip-neighbor.h new file mode 100644 index 0000000..d3b351c --- /dev/null +++ b/uip/uip-neighbor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \file + * Header file for database of link-local neighbors, used by + * IPv6 code and to be used by future ARP code. + * \author + * Adam Dunkels + */ + +#ifndef __UIP_NEIGHBOR_H__ +#define __UIP_NEIGHBOR_H__ + +#include "uip.h" + +struct uip_neighbor_addr { +#if UIP_NEIGHBOR_CONF_ADDRTYPE + UIP_NEIGHBOR_CONF_ADDRTYPE addr; +#else + struct uip_eth_addr addr; +#endif +}; + +void uip_neighbor_init(void); +void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr); +void uip_neighbor_update(uip_ipaddr_t ipaddr); +struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr); +void uip_neighbor_periodic(void); + +#endif /* __UIP-NEIGHBOR_H__ */ diff --git a/uip/uip-split.c b/uip/uip-split.c new file mode 100644 index 0000000..a910ee6 --- /dev/null +++ b/uip/uip-split.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +#include + +#include "uip-split.h" +#include "uip.h" +#include "uip-fw.h" +#include "uip_arch.h" + + + +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/*-----------------------------------------------------------------------------*/ +void +uip_split_output(void) +{ + u16_t tcplen, len1, len2; + + /* We only try to split maximum sized TCP segments. */ + if(BUF->proto == UIP_PROTO_TCP && + uip_len == UIP_BUFSIZE - UIP_LLH_LEN) { + + tcplen = uip_len - UIP_TCPIP_HLEN; + /* Split the segment in two. If the original packet length was + odd, we make the second packet one byte larger. */ + len1 = len2 = tcplen / 2; + if(len1 + len2 < tcplen) { + ++len2; + } + + /* Create the first packet. This is done by altering the length + field of the IP header and updating the checksums. */ + uip_len = len1 + UIP_TCPIP_HLEN; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = uip_len >> 8; + BUF->len[1] = uip_len & 0xff; +#endif /* UIP_CONF_IPV6 */ + + /* Recalculate the TCP checksum. */ + BUF->tcpchksum = 0; + BUF->tcpchksum = ~(uip_tcpchksum()); + +#if !UIP_CONF_IPV6 + /* Recalculate the IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + + /* Transmit the first packet. */ + /* uip_fw_output();*/ + tcpip_output(); + + /* Now, create the second packet. To do this, it is not enough to + just alter the length field, but we must also update the TCP + sequence number and point the uip_appdata to a new place in + memory. This place is detemined by the length of the first + packet (len1). */ + uip_len = len2 + UIP_TCPIP_HLEN; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = uip_len >> 8; + BUF->len[1] = uip_len & 0xff; +#endif /* UIP_CONF_IPV6 */ + + /* uip_appdata += len1;*/ + memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2); + + uip_add32(BUF->seqno, len1); + BUF->seqno[0] = uip_acc32[0]; + BUF->seqno[1] = uip_acc32[1]; + BUF->seqno[2] = uip_acc32[2]; + BUF->seqno[3] = uip_acc32[3]; + + /* Recalculate the TCP checksum. */ + BUF->tcpchksum = 0; + BUF->tcpchksum = ~(uip_tcpchksum()); + +#if !UIP_CONF_IPV6 + /* Recalculate the IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + + /* Transmit the second packet. */ + /* uip_fw_output();*/ + tcpip_output(); + } else { + /* uip_fw_output();*/ + tcpip_output(); + } + +} +/*-----------------------------------------------------------------------------*/ diff --git a/uip/uip-split.h b/uip/uip-split.h new file mode 100644 index 0000000..c2c1789 --- /dev/null +++ b/uip/uip-split.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 + * + * Author: Adam Dunkels + * + * $Id: uip-split.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipsplit uIP TCP throughput booster hack + * @{ + * + * The basic uIP TCP implementation only allows each TCP connection to + * have a single TCP segment in flight at any given time. Because of + * the delayed ACK algorithm employed by most TCP receivers, uIP's + * limit on the amount of in-flight TCP segments seriously reduces the + * maximum achievable throughput for sending data from uIP. + * + * The uip-split module is a hack which tries to remedy this + * situation. By splitting maximum sized outgoing TCP segments into + * two, the delayed ACK algorithm is not invoked at TCP + * receivers. This improves the throughput when sending data from uIP + * by orders of magnitude. + * + * The uip-split module uses the uip-fw module (uIP IP packet + * forwarding) for sending packets. Therefore, the uip-fw module must + * be set up with the appropriate network interfaces for this module + * to work. + */ + + +/** + * \file + * Module for splitting outbound TCP segments in two to avoid the + * delayed ACK throughput degradation. + * \author + * Adam Dunkels + * + */ + +#ifndef __UIP_SPLIT_H__ +#define __UIP_SPLIT_H__ + +/** + * Handle outgoing packets. + * + * This function inspects an outgoing packet in the uip_buf buffer and + * sends it out using the uip_fw_output() function. If the packet is a + * full-sized TCP segment it will be split into two segments and + * transmitted separately. This function should be called instead of + * the actual device driver output function, or the uip_fw_output() + * function. + * + * The headers of the outgoing packet is assumed to be in the uip_buf + * buffer and the payload is assumed to be wherever uip_appdata + * points. The length of the outgoing packet is assumed to be in the + * uip_len variable. + * + */ +void uip_split_output(void); + +#endif /* __UIP_SPLIT_H__ */ + +/** @} */ +/** @} */ diff --git a/uip/uip.c b/uip/uip.c index 120c48e..ee88514 100644 --- a/uip/uip.c +++ b/uip/uip.c @@ -1,6 +1,16 @@ +#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ + /** - * \addtogroup uip + * \defgroup uip The uIP TCP/IP stack * @{ + * + * uIP is an implementation of the TCP/IP protocol stack intended for + * small 8-bit and 16-bit microcontrollers. + * + * uIP provides the necessary protocols for Internet communication, + * with a very small code footprint and RAM requirements - the uIP + * code size is on the order of a few kilobytes and RAM usage is on + * the order of a few hundred bytes. */ /** @@ -11,19 +21,19 @@ /* * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -35,77 +45,119 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $ + * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $ * */ /* -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. + * uIP is a small implementation of the IP, UDP and TCP protocols (as + * well as some basic ICMP stuff). The implementation couples the IP, + * UDP, TCP and the application layers very tightly. To keep the size + * of the compiled code down, this code frequently uses the goto + * statement. While it would be possible to break the uip_process() + * function into many smaller functions, this would increase the code + * size because of the overhead of parameter passing and the fact that + * the optimier would not be as efficient. + * + * 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 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. The uip_appdata pointer points to the + * first available byte. 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 "uip.h" #include "uipopt.h" #include "uip_arch.h" -/*-----------------------------------------------------------------------------------*/ +#if UIP_CONF_IPV6 +#include "uip-neighbor.h" +#endif /* UIP_CONF_IPV6 */ + +#include + +/*---------------------------------------------------------------------------*/ /* Variable definitions. */ -/* The IP address of this host. If it is defined to be fixed (by setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set here. Otherwise, the address */ +/* The IP address of this host. If it is defined to be fixed (by + setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set + here. Otherwise, the address */ #if UIP_FIXEDADDR > 0 -const u16_t uip_hostaddr[2] = +const uip_ipaddr_t uip_hostaddr = {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; -const u16_t uip_arp_draddr[2] = +const uip_ipaddr_t uip_draddr = {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; -const u16_t uip_arp_netmask[2] = +const uip_ipaddr_t uip_netmask = {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]; +uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; #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. */ +static const uip_ipaddr_t all_ones_addr = +#if UIP_CONF_IPV6 + {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; +#else /* UIP_CONF_IPV6 */ + {0xffff,0xffff}; +#endif /* UIP_CONF_IPV6 */ +static const uip_ipaddr_t all_zeroes_addr = +#if UIP_CONF_IPV6 + {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; +#else /* UIP_CONF_IPV6 */ + {0x0000,0x0000}; +#endif /* UIP_CONF_IPV6 */ + + +#if UIP_FIXEDETHADDR +const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, + UIP_ETHADDR1, + UIP_ETHADDR2, + UIP_ETHADDR3, + UIP_ETHADDR4, + UIP_ETHADDR5}}; +#else +struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}; +#endif + +#ifndef UIP_CONF_EXTERNAL_BUFFER +u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains + incoming packets. */ +#endif /* UIP_CONF_EXTERNAL_BUFFER */ + +void *uip_appdata; /* The uip_appdata pointer points to + application data. */ +void *uip_sappdata; /* The uip_appdata pointer points to + the application data which is to + be sent. */ #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; +void *uip_urgdata; /* The uip_urgdata pointer points to + urgent data (out-of-band data), if + present. */ +u16_t uip_urglen, uip_surglen; #endif /* UIP_URGDATA > 0 */ -volatile u16_t uip_len, uip_slen; +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 +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 @@ -122,11 +174,12 @@ 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. */ +void uip_setipid(u16_t id) { ipid = id; } + static u8_t iss[4]; /* The iss variable is used for the TCP initial sequence number. */ @@ -136,7 +189,7 @@ static u16_t lastport; /* Keeps track of the last port used for #endif /* UIP_ACTIVE_OPEN */ /* Temporary variables. */ -volatile u8_t uip_acc32[4]; +u8_t uip_acc32[4]; static u8_t c, opt; static u16_t tmp16; @@ -149,14 +202,32 @@ static u16_t tmp16; #define TCP_URG 0x20 #define TCP_CTL 0x3f +#define TCP_OPT_END 0 /* End of TCP options list */ +#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ +#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ + +#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ + #define ICMP_ECHO_REPLY 0 -#define ICMP_ECHO 8 +#define ICMP_ECHO 8 + +#define ICMP6_ECHO_REPLY 129 +#define ICMP6_ECHO 128 +#define ICMP6_NEIGHBOR_SOLICITATION 135 +#define ICMP6_NEIGHBOR_ADVERTISEMENT 136 + +#define ICMP6_FLAG_S (1 << 6) + +#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 +#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 + /* 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]) +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) +#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) + #if UIP_STATISTICS == 1 struct uip_stats uip_stat; @@ -173,7 +244,137 @@ void uip_log(char *msg); #define UIP_LOG(m) #endif /* UIP_LOGGING == 1 */ -/*-----------------------------------------------------------------------------------*/ +#if ! UIP_ARCH_ADD32 +void +uip_add32(u8_t *op32, u16_t op16) +{ + uip_acc32[3] = op32[3] + (op16 & 0xff); + uip_acc32[2] = op32[2] + (op16 >> 8); + uip_acc32[1] = op32[1]; + uip_acc32[0] = op32[0]; + + if(uip_acc32[2] < (op16 >> 8)) { + ++uip_acc32[1]; + if(uip_acc32[1] == 0) { + ++uip_acc32[0]; + } + } + + + if(uip_acc32[3] < (op16 & 0xff)) { + ++uip_acc32[2]; + if(uip_acc32[2] == 0) { + ++uip_acc32[1]; + if(uip_acc32[1] == 0) { + ++uip_acc32[0]; + } + } + } +} + +#endif /* UIP_ARCH_ADD32 */ + +#if ! UIP_ARCH_CHKSUM +/*---------------------------------------------------------------------------*/ +static u16_t +chksum(u16_t sum, const u8_t *data, u16_t len) +{ + u16_t t; + const u8_t *dataptr; + const u8_t *last_byte; + + dataptr = data; + last_byte = data + len - 1; + + while(dataptr < last_byte) { /* At least two more bytes */ + t = (dataptr[0] << 8) + dataptr[1]; + sum += t; + if(sum < t) { + sum++; /* carry */ + } + dataptr += 2; + } + + if(dataptr == last_byte) { + t = (dataptr[0] << 8) + 0; + sum += t; + if(sum < t) { + sum++; /* carry */ + } + } + + /* Return sum in host byte order. */ + return sum; +} +/*---------------------------------------------------------------------------*/ +u16_t +uip_chksum(u16_t *data, u16_t len) +{ + return htons(chksum(0, (u8_t *)data, len)); +} +/*---------------------------------------------------------------------------*/ +#ifndef UIP_ARCH_IPCHKSUM +u16_t +uip_ipchksum(void) +{ + u16_t sum; + + sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); + DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum); + return (sum == 0) ? 0xffff : htons(sum); +} +#endif +/*---------------------------------------------------------------------------*/ +static u16_t +upper_layer_chksum(u8_t proto) +{ + u16_t upper_layer_len; + u16_t sum; + +#if UIP_CONF_IPV6 + upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]); +#else /* UIP_CONF_IPV6 */ + upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; +#endif /* UIP_CONF_IPV6 */ + + /* First sum pseudoheader. */ + + /* IP protocol and length fields. This addition cannot carry. */ + sum = upper_layer_len + proto; + /* Sum IP source and destination addresses. */ + sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); + + /* Sum TCP header and data. */ + sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], + upper_layer_len); + + return (sum == 0) ? 0xffff : htons(sum); +} +/*---------------------------------------------------------------------------*/ +#if UIP_CONF_IPV6 +u16_t +uip_icmp6chksum(void) +{ + return upper_layer_chksum(UIP_PROTO_ICMP6); + +} +#endif /* UIP_CONF_IPV6 */ +/*---------------------------------------------------------------------------*/ +u16_t +uip_tcpchksum(void) +{ + return upper_layer_chksum(UIP_PROTO_TCP); +} +/*---------------------------------------------------------------------------*/ +#if UIP_UDP_CHECKSUMS +u16_t +uip_udpchksum(void) +{ + return upper_layer_chksum(UIP_PROTO_UDP); +} +#endif /* UIP_UDP_CHECKSUMS */ +#endif /* UIP_ARCH_CHKSUM */ +/*---------------------------------------------------------------------------*/ void uip_init(void) { @@ -181,7 +382,7 @@ uip_init(void) uip_listenports[c] = 0; } for(c = 0; c < UIP_CONNS; ++c) { - uip_conns[c].tcpstateflags = CLOSED; + uip_conns[c].tcpstateflags = UIP_CLOSED; } #if UIP_ACTIVE_OPEN lastport = 1024; @@ -196,14 +397,14 @@ uip_init(void) /* IPv4 initialization. */ #if UIP_FIXEDADDR == 0 - uip_hostaddr[0] = uip_hostaddr[1] = 0; + /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/ #endif /* UIP_FIXEDADDR */ } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ #if UIP_ACTIVE_OPEN struct uip_conn * -uip_connect(u16_t *ripaddr, u16_t rport) +uip_connect(uip_ipaddr_t *ripaddr, u16_t rport) { register struct uip_conn *conn, *cconn; @@ -219,23 +420,22 @@ uip_connect(u16_t *ripaddr, u16_t rport) another one. */ for(c = 0; c < UIP_CONNS; ++c) { conn = &uip_conns[c]; - if(conn->tcpstateflags != CLOSED && + if(conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(lastport)) { goto again; } } - conn = 0; for(c = 0; c < UIP_CONNS; ++c) { - cconn = &uip_conns[c]; - if(cconn->tcpstateflags == CLOSED) { + cconn = &uip_conns[c]; + if(cconn->tcpstateflags == UIP_CLOSED) { conn = cconn; break; } - if(cconn->tcpstateflags == TIME_WAIT) { + if(cconn->tcpstateflags == UIP_TIME_WAIT) { if(conn == 0 || - cconn->timer > uip_conn->timer) { + cconn->timer > conn->timer) { conn = cconn; } } @@ -245,7 +445,7 @@ uip_connect(u16_t *ripaddr, u16_t rport) return 0; } - conn->tcpstateflags = SYN_SENT; + conn->tcpstateflags = UIP_SYN_SENT; conn->snd_nxt[0] = iss[0]; conn->snd_nxt[1] = iss[1]; @@ -259,19 +459,18 @@ uip_connect(u16_t *ripaddr, u16_t rport) conn->timer = 1; /* Send the SYN next time around. */ conn->rto = UIP_RTO; conn->sa = 0; - conn->sv = 16; + conn->sv = 16; /* Initial value of the RTT variance. */ conn->lport = htons(lastport); conn->rport = rport; - conn->ripaddr[0] = ripaddr[0]; - conn->ripaddr[1] = ripaddr[1]; + uip_ipaddr_copy(&conn->ripaddr, ripaddr); return conn; } #endif /* UIP_ACTIVE_OPEN */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ #if UIP_UDP struct uip_udp_conn * -uip_udp_new(u16_t *ripaddr, u16_t rport) +uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) { register struct uip_udp_conn *conn; @@ -284,7 +483,7 @@ uip_udp_new(u16_t *ripaddr, u16_t rport) } for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == lastport) { + if(uip_udp_conns[c].lport == htons(lastport)) { goto again; } } @@ -293,7 +492,7 @@ uip_udp_new(u16_t *ripaddr, u16_t rport) conn = 0; for(c = 0; c < UIP_UDP_CONNS; ++c) { if(uip_udp_conns[c].lport == 0) { - conn = &uip_udp_conns[c]; + conn = &uip_udp_conns[c]; break; } } @@ -303,14 +502,18 @@ uip_udp_new(u16_t *ripaddr, u16_t rport) } conn->lport = HTONS(lastport); - conn->rport = HTONS(rport); - conn->ripaddr[0] = ripaddr[0]; - conn->ripaddr[1] = ripaddr[1]; + conn->rport = rport; + if(ripaddr == NULL) { + memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t)); + } else { + uip_ipaddr_copy(&conn->ripaddr, ripaddr); + } + conn->ttl = UIP_TTL; return conn; } #endif /* UIP_UDP */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void uip_unlisten(u16_t port) { @@ -321,7 +524,7 @@ uip_unlisten(u16_t port) } } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void uip_listen(u16_t port) { @@ -332,10 +535,10 @@ uip_listen(u16_t port) } } } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /* XXX: IP fragment reassembly: not well-tested. */ -#if UIP_REASSEMBLY +#if UIP_REASSEMBLY && !UIP_CONF_IPV6 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; @@ -346,7 +549,6 @@ 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 @@ -359,11 +561,11 @@ uip_reass(void) 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); + memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); uip_reasstmr = UIP_REASS_MAXAGE; uip_reassflags = 0; /* Clear the bitmap. */ - memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0); + memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); } /* Check if the incoming fragment matches the one currently present @@ -389,7 +591,7 @@ uip_reass(void) /* Copy the fragment into the reassembly buffer, at the right offset. */ - memcpy(&uip_reassbuf[IP_HLEN + offset], + memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), len); @@ -409,7 +611,7 @@ uip_reass(void) 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]; } @@ -464,8 +666,8 @@ uip_reass(void) nullreturn: return 0; } -#endif /* UIP_REASSEMBL */ -/*-----------------------------------------------------------------------------------*/ +#endif /* UIP_REASSEMBLY */ +/*---------------------------------------------------------------------------*/ static void uip_add_rcv_nxt(u16_t n) { @@ -475,17 +677,33 @@ uip_add_rcv_nxt(u16_t n) 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]; +#if UIP_UDP + if(flag == UIP_UDP_SEND_CONN) { + goto udp_send; + } +#endif /* UIP_UDP */ - /* Check if we were invoked because of the perodic timer fireing. */ - if(flag == UIP_TIMER) { + uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; + + /* Check if we were invoked because of a poll request for a + particular connection. */ + if(flag == UIP_POLL_REQUEST) { + if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && + !uip_outstanding(uip_connr)) { + uip_flags = UIP_POLL; + UIP_APPCALL(); + goto appsend; + } + goto drop; + + /* Check if we were invoked because of the perodic timer fireing. */ + } else if(flag == UIP_TIMER) { #if UIP_REASSEMBLY if(uip_reasstmr != 0) { --uip_reasstmr; @@ -498,25 +716,33 @@ uip_process(u8_t flag) ++iss[0]; } } - } + } + + /* Reset the length variables. */ uip_len = 0; - if(uip_connr->tcpstateflags == TIME_WAIT || - uip_connr->tcpstateflags == FIN_WAIT_2) { + uip_slen = 0; + + /* Check if the connection is in a state in which we simply wait + for the connection to time out. If so, we increase the + connection's timer and remove the connection if it times + out. */ + if(uip_connr->tcpstateflags == UIP_TIME_WAIT || + uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { ++(uip_connr->timer); if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { - uip_connr->tcpstateflags = CLOSED; + uip_connr->tcpstateflags = UIP_CLOSED; } - } else if(uip_connr->tcpstateflags != CLOSED) { + } else if(uip_connr->tcpstateflags != UIP_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->tcpstateflags == UIP_SYN_SENT || + uip_connr->tcpstateflags == UIP_SYN_RCVD) && uip_connr->nrtx == UIP_MAXSYNRTX)) { - uip_connr->tcpstateflags = CLOSED; + uip_connr->tcpstateflags = UIP_CLOSED; /* We call UIP_APPCALL() with uip_flags set to UIP_TIMEDOUT to inform the application that the @@ -542,43 +768,39 @@ uip_process(u8_t flag) 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: + switch(uip_connr->tcpstateflags & UIP_TS_MASK) { + case UIP_SYN_RCVD: /* In the SYN_RCVD state, we should retransmit our SYNACK. */ goto tcp_send_synack; #if UIP_ACTIVE_OPEN - case SYN_SENT: + case UIP_SYN_SENT: /* In the SYN_SENT state, we retransmit out SYN. */ BUF->flags = 0; goto tcp_send_syn; #endif /* UIP_ACTIVE_OPEN */ - case ESTABLISHED: + case UIP_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: + case UIP_FIN_WAIT_1: + case UIP_CLOSING: + case UIP_LAST_ACK: /* In all these states we should retransmit a FINACK. */ goto tcp_send_finack; } } - } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) { + } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_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; @@ -586,10 +808,11 @@ uip_process(u8_t flag) } goto drop; } -#if UIP_UDP +#if UIP_UDP if(flag == UIP_UDP_TIMER) { if(uip_udp_conn->lport != 0) { - uip_appdata = &uip_buf[UIP_LLH_LEN + 28]; + uip_conn = NULL; + uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; uip_len = uip_slen = 0; uip_flags = UIP_POLL; UIP_UDP_APPCALL(); @@ -603,49 +826,74 @@ uip_process(u8_t flag) /* This is where the input processing starts. */ UIP_STAT(++uip_stat.ip.recv); - - /* Start of IPv4 input header processing code. */ + /* Start of IP input header processing code. */ - /* Check validity of the IP header. */ +#if UIP_CONF_IPV6 + /* Check validity of the IP header. */ + if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.vhlerr); + UIP_LOG("ipv6: invalid version."); + goto drop; + } +#else /* UIP_CONF_IPV6 */ + /* Check validity of the IP header. */ if(BUF->vhl != 0x45) { /* IP version and header length. */ UIP_STAT(++uip_stat.ip.drop); UIP_STAT(++uip_stat.ip.vhlerr); UIP_LOG("ip: invalid version or header length."); goto drop; } +#endif /* UIP_CONF_IPV6 */ /* 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]; + uip_len is smaller the size reported in the IP header, we assume + that the packet has been corrupted in transit. If the size of + uip_len is larger than the size reported in the IP packet header, + the packet has been padded and we set uip_len to the correct + value.. */ + + if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) { + uip_len = (BUF->len[0] << 8) + BUF->len[1]; +#if UIP_CONF_IPV6 + uip_len += 40; /* The length reported in the IPv6 header is the + length of the payload that follows the + header. However, uIP uses the uip_len variable + for holding the size of the entire packet, + including the IP header. For IPv4 this is not a + problem as the length field in the IPv4 header + contains the length of the entire packet. But + for IPv6 we need to add the size of the IPv6 + header (40 bytes). */ +#endif /* UIP_CONF_IPV6 */ + } else { + UIP_LOG("ip: packet shorter than reported in IP header."); + goto drop; } +#if !UIP_CONF_IPV6 /* Check the fragment flag. */ if((BUF->ipoffset[0] & 0x3f) != 0 || - BUF->ipoffset[1] != 0) { + BUF->ipoffset[1] != 0) { #if UIP_REASSEMBLY uip_len = uip_reass(); if(uip_len == 0) { goto drop; } -#else +#else /* UIP_REASSEMBLY */ UIP_STAT(++uip_stat.ip.drop); UIP_STAT(++uip_stat.ip.fragerr); - UIP_LOG("ip: fragment dropped."); + UIP_LOG("ip: fragment dropped."); goto drop; #endif /* UIP_REASSEMBLY */ } +#endif /* UIP_CONF_IPV6 */ - /* 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(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) { + /* If we are configured to use ping IP address configuration and + hasn't been assigned an IP address yet, we accept all ICMP + packets. */ +#if UIP_PINGADDRCONF && !UIP_CONF_IPV6 if(BUF->proto == UIP_PROTO_ICMP) { UIP_LOG("ip: possible ping config packet received."); goto icmp_input; @@ -653,49 +901,78 @@ uip_process(u8_t flag) 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; + + } else { + /* If IP broadcast support is configured, we check for a broadcast + UDP packet, which may be destined to us. */ +#if UIP_BROADCAST + DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); + if(BUF->proto == UIP_PROTO_UDP && + uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr) + /*&& + uip_ipchksum() == 0xffff*/) { + goto udp_input; + } +#endif /* UIP_BROADCAST */ + + /* Check if the packet is destined for our IP address. */ +#if !UIP_CONF_IPV6 + if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) { + UIP_STAT(++uip_stat.ip.drop); + goto drop; + } +#else /* UIP_CONF_IPV6 */ + /* For IPv6, packet reception is a little trickier as we need to + make sure that we listen to certain multicast addresses (all + hosts multicast address, and the solicited-node multicast + address) as well. However, we will cheat here and accept all + multicast packets that are sent to the ff02::/16 addresses. */ + if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) && + BUF->destipaddr[0] != HTONS(0xff02)) { + UIP_STAT(++uip_stat.ip.drop); + goto drop; + } +#endif /* UIP_CONF_IPV6 */ } +#if !UIP_CONF_IPV6 if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header checksum. */ UIP_STAT(++uip_stat.ip.drop); UIP_STAT(++uip_stat.ip.chkerr); - UIP_LOG("ip: bad checksum."); + UIP_LOG("ip: bad checksum."); goto drop; } +#endif /* UIP_CONF_IPV6 */ - if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump - to the tcp_input label. */ + if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, + proceed with TCP input + processing. */ goto tcp_input; + } #if UIP_UDP - if(BUF->proto == UIP_PROTO_UDP) + if(BUF->proto == UIP_PROTO_UDP) { goto udp_input; + } #endif /* UIP_UDP */ +#if !UIP_CONF_IPV6 + /* ICMPv4 processing code follows. */ if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from here. */ UIP_STAT(++uip_stat.ip.drop); UIP_STAT(++uip_stat.ip.protoerr); - UIP_LOG("ip: neither tcp nor icmp."); + UIP_LOG("ip: neither tcp nor icmp."); goto drop; } - + +#if UIP_PINGADDRCONF icmp_input: +#endif /* UIP_PINGADDRCONF */ UIP_STAT(++uip_stat.icmp.recv); - + /* ICMP echo (i.e., ping) processing. This is simple, we only change the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP checksum before we return the packet. */ @@ -714,29 +991,92 @@ uip_process(u8_t flag) uip_hostaddr[0] = BUF->destipaddr[0]; uip_hostaddr[1] = BUF->destipaddr[1]; } -#endif /* UIP_PINGADDRCONF */ - +#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_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); UIP_STAT(++uip_stat.icmp.sent); goto send; /* End of IPv4 input header processing code. */ +#else /* !UIP_CONF_IPV6 */ + + /* This is IPv6 ICMPv6 processing code. */ + DEBUG_PRINTF("icmp6_input: length %d\n", uip_len); + + if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from + here. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.protoerr); + UIP_LOG("ip: neither tcp nor icmp6."); + goto drop; + } + + UIP_STAT(++uip_stat.icmp.recv); + + /* If we get a neighbor solicitation for our address we should send + a neighbor advertisement message back. */ + if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { + if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) { + + if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { + /* Save the sender's address in our neighbor list. */ + uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); + } + + /* We should now send a neighbor advertisement back to where the + neighbor solicication came from. */ + ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; + ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ + + ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; + + uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); + uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr); + ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; + ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ + memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr)); + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + goto send; + + } + goto drop; + } else if(ICMPBUF->type == ICMP6_ECHO) { + /* ICMP echo (i.e., ping) processing. This is simple, we only + change the ICMP type from ECHO to ECHO_REPLY and update the + ICMP checksum before we return the packet. */ + + ICMPBUF->type = ICMP6_ECHO_REPLY; + + uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + + UIP_STAT(++uip_stat.icmp.sent); + goto send; + } else { + DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type); + UIP_STAT(++uip_stat.icmp.drop); + UIP_STAT(++uip_stat.icmp.typeerr); + UIP_LOG("icmp: unknown ICMP message."); + goto drop; + } + + /* End of IPv6 ICMP processing. */ +#endif /* !UIP_CONF_IPV6 */ #if UIP_UDP /* UDP input processing. */ @@ -746,69 +1086,90 @@ uip_process(u8_t flag) work. If the application sets uip_slen, it has a packet to send. */ #if UIP_UDP_CHECKSUMS - if(uip_udpchksum() != 0xffff) { + uip_len = uip_len - UIP_IPUDPH_LEN; + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; + if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { UIP_STAT(++uip_stat.udp.drop); UIP_STAT(++uip_stat.udp.chkerr); - UIP_LOG("udp: bad checksum."); + UIP_LOG("udp: bad checksum."); goto drop; - } + } +#else /* UIP_UDP_CHECKSUMS */ + uip_len = uip_len - UIP_IPUDPH_LEN; #endif /* UIP_UDP_CHECKSUMS */ /* Demultiplex this UDP packet between the UDP "connections". */ for(uip_udp_conn = &uip_udp_conns[0]; uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; ++uip_udp_conn) { + /* If the local UDP port is non-zero, the connection is considered + to be used. If so, the local port number is checked against the + destination port number in the received packet. If the two port + numbers match, the remote port number is checked if the + connection is bound to a remote port. Finally, if the + connection is bound to a remote IP address, the source IP + address of the packet is checked. */ if(uip_udp_conn->lport != 0 && UDPBUF->destport == uip_udp_conn->lport && (uip_udp_conn->rport == 0 || UDPBUF->srcport == uip_udp_conn->rport) && - BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] && - BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) { - goto udp_found; + (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || + uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) || + uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) { + goto udp_found; } } + UIP_LOG("udp: no matching connection found"); goto drop; udp_found: - uip_len = uip_len - 28; - uip_appdata = &uip_buf[UIP_LLH_LEN + 28]; + uip_conn = NULL; uip_flags = UIP_NEWDATA; + uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; uip_slen = 0; UIP_UDP_APPCALL(); udp_send: if(uip_slen == 0) { - goto drop; + goto drop; } - uip_len = uip_slen + 28; + uip_len = uip_slen + UIP_IPUDPH_LEN; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ BUF->len[0] = (uip_len >> 8); BUF->len[1] = (uip_len & 0xff); - +#endif /* UIP_CONF_IPV6 */ + + BUF->ttl = uip_udp_conn->ttl; BUF->proto = UIP_PROTO_UDP; - UDPBUF->udplen = HTONS(uip_slen + 8); + UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN); UDPBUF->udpchksum = 0; -#if UIP_UDP_CHECKSUMS + + BUF->srcport = uip_udp_conn->lport; + BUF->destport = uip_udp_conn->rport; + + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr); + + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; + +#if UIP_UDP_CHECKSUMS /* Calculate UDP checksum. */ UDPBUF->udpchksum = ~(uip_udpchksum()); if(UDPBUF->udpchksum == 0) { UDPBUF->udpchksum = 0xffff; } #endif /* UIP_UDP_CHECKSUMS */ - - 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 processing. */ tcp_input: UIP_STAT(++uip_stat.tcp.recv); @@ -818,19 +1179,20 @@ uip_process(u8_t flag) checksum. */ UIP_STAT(++uip_stat.tcp.drop); UIP_STAT(++uip_stat.tcp.chkerr); - UIP_LOG("tcp: bad checksum."); + 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 && + for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; + ++uip_connr) { + if(uip_connr->tcpstateflags != UIP_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; + uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) { + goto found; } } @@ -838,11 +1200,12 @@ uip_process(u8_t flag) 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) + if((BUF->flags & TCP_CTL) != TCP_SYN) { goto reset; + } tmp16 = BUF->destport; - /* Next, check listening connections. */ + /* Next, check listening connections. */ for(c = 0; c < UIP_LISTENPORTS; ++c) { if(tmp16 == uip_listenports[c]) goto found_listen; @@ -853,22 +1216,23 @@ uip_process(u8_t flag) reset: /* We do not send resets in response to resets. */ - if(BUF->flags & TCP_RST) + if(BUF->flags & TCP_RST) { goto drop; + } UIP_STAT(++uip_stat.tcp.rst); BUF->flags = TCP_RST | TCP_ACK; - uip_len = 40; + uip_len = UIP_IPTCPH_LEN; 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->seqno[3] = BUF->ackno[3]; BUF->ackno[3] = c; c = BUF->seqno[2]; - BUF->seqno[2] = BUF->ackno[2]; + BUF->seqno[2] = BUF->ackno[2]; BUF->ackno[2] = c; c = BUF->seqno[1]; @@ -876,7 +1240,7 @@ uip_process(u8_t flag) BUF->ackno[1] = c; c = BUF->seqno[0]; - BUF->seqno[0] = BUF->ackno[0]; + BUF->seqno[0] = BUF->ackno[0]; BUF->ackno[0] = c; /* We also have to increase the sequence number we are @@ -896,13 +1260,8 @@ uip_process(u8_t flag) 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; - + uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); /* And send out the RST packet! */ goto tcp_send_noconn; @@ -919,11 +1278,11 @@ uip_process(u8_t flag) nice algorithm for the TIME_WAIT search. */ uip_connr = 0; for(c = 0; c < UIP_CONNS; ++c) { - if(uip_conns[c].tcpstateflags == CLOSED) { + if(uip_conns[c].tcpstateflags == UIP_CLOSED) { uip_connr = &uip_conns[c]; break; } - if(uip_conns[c].tcpstateflags == TIME_WAIT) { + if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { if(uip_connr == 0 || uip_conns[c].timer > uip_connr->timer) { uip_connr = &uip_conns[c]; @@ -944,13 +1303,12 @@ uip_process(u8_t flag) /* 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->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_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); + uip_connr->tcpstateflags = UIP_SYN_RCVD; uip_connr->snd_nxt[0] = iss[0]; uip_connr->snd_nxt[1] = iss[1]; @@ -969,17 +1327,17 @@ uip_process(u8_t flag) 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. */ + if(opt == TCP_OPT_END) { + /* End of options. */ break; - } else if(opt == 0x01) { + } else if(opt == TCP_OPT_NOOP) { ++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. */ + } else if(opt == TCP_OPT_MSS && + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { + /* An MSS option with the right option length. */ tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | - (u16_t)uip_buf[40 + UIP_LLH_LEN + 3 + c]; + (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; uip_connr->initialmss = uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; @@ -994,65 +1352,67 @@ uip_process(u8_t flag) 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; + BUF->flags = TCP_ACK; tcp_send_syn: - BUF->flags |= TCP_SYN; + BUF->flags |= TCP_SYN; #else /* UIP_ACTIVE_OPEN */ tcp_send_synack: - BUF->flags = TCP_SYN | TCP_ACK; + 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[0] = TCP_OPT_MSS; + BUF->optdata[1] = TCP_OPT_MSS_LEN; BUF->optdata[2] = (UIP_TCP_MSS) / 256; BUF->optdata[3] = (UIP_TCP_MSS) & 255; - uip_len = 44; - BUF->tcpoffset = 6 << 4; + uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; + BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 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_connr->tcpstateflags = UIP_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; + uip_len = uip_len - c - UIP_IPH_LEN; /* First, check if the sequence number of the incoming packet is what we're expecting next. If not, we send out an ACK with the correct numbers in. */ - 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; + if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && + ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { + if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && + (BUF->seqno[0] != uip_connr->rcv_nxt[0] || + BUF->seqno[1] != uip_connr->rcv_nxt[1] || + BUF->seqno[2] != uip_connr->rcv_nxt[2] || + BUF->seqno[3] != uip_connr->rcv_nxt[3])) { + goto tcp_send_ack; + } } /* Next, check if the incoming segment acknowledges any outstanding @@ -1061,6 +1421,7 @@ uip_process(u8_t flag) 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] && @@ -1091,23 +1452,26 @@ uip_process(u8_t flag) uip_flags = UIP_ACKDATA; /* Reset the retransmission timer. */ uip_connr->timer = uip_connr->rto; + + /* Reset length of outstanding data. */ + uip_connr->len = 0; } } /* Do different things depending on in what state the connection is. */ - switch(uip_connr->tcpstateflags & TS_MASK) { + switch(uip_connr->tcpstateflags & UIP_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: + case UIP_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_connr->tcpstateflags = UIP_ESTABLISHED; uip_flags = UIP_CONNECTED; uip_connr->len = 0; if(uip_len > 0) { @@ -1120,26 +1484,26 @@ uip_process(u8_t flag) } goto drop; #if UIP_ACTIVE_OPEN - case SYN_SENT: + case UIP_SYN_SENT: /* In SYN_SENT, we wait for a SYNACK that is sent in response to our SYN. The rcv_nxt is set to sequence number in the SYNACK plus one, and we send an ACK. We move into the ESTABLISHED state. */ if((uip_flags & UIP_ACKDATA) && - BUF->flags == (TCP_SYN | TCP_ACK)) { + (BUF->flags & TCP_CTL) == (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. */ + opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; + if(opt == TCP_OPT_END) { + /* End of options. */ break; - } else if(opt == 0x01) { + } else if(opt == TCP_OPT_NOOP) { ++c; /* NOP option. */ - } else if(opt == 0x02 && - uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) { + } else if(opt == TCP_OPT_MSS && + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { /* An MSS option with the right option length. */ tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; @@ -1157,10 +1521,10 @@ uip_process(u8_t flag) break; } c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; - } + } } } - uip_connr->tcpstateflags = ESTABLISHED; + uip_connr->tcpstateflags = UIP_ESTABLISHED; uip_connr->rcv_nxt[0] = BUF->seqno[0]; uip_connr->rcv_nxt[1] = BUF->seqno[1]; uip_connr->rcv_nxt[2] = BUF->seqno[2]; @@ -1173,10 +1537,15 @@ uip_process(u8_t flag) UIP_APPCALL(); goto appsend; } + /* Inform the application that the connection failed */ + uip_flags = UIP_ABORT; + UIP_APPCALL(); + /* The connection is closed after we send the RST */ + uip_conn->tcpstateflags = UIP_CLOSED; goto reset; #endif /* UIP_ACTIVE_OPEN */ - case ESTABLISHED: + case UIP_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 @@ -1188,27 +1557,27 @@ uip_process(u8_t flag) state. We require that there is no outstanding data; otherwise the sequence numbers will be screwed up. */ - if(BUF->flags & TCP_FIN) { + if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { if(uip_outstanding(uip_connr)) { goto drop; } - uip_add_rcv_nxt(1 + uip_len); - uip_flags = UIP_CLOSE; + 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->tcpstateflags = UIP_LAST_ACK; uip_connr->nrtx = 0; tcp_send_finack: - BUF->flags = TCP_FIN | TCP_ACK; + 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((BUF->flags & TCP_URG) != 0) { #if UIP_URGDATA > 0 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1]; if(uip_urglen > uip_len) { @@ -1221,12 +1590,12 @@ uip_process(u8_t flag) uip_appdata += uip_urglen; } else { uip_urglen = 0; -#endif /* UIP_URGDATA > 0 */ - uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1]; +#else /* UIP_URGDATA > 0 */ + uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]); uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1]; +#endif /* UIP_URGDATA > 0 */ } - - + /* If uip_len > 0 we have TCP data in the packet, and we flag this by setting the UIP_NEWDATA flag and update the sequence number we acknowledge. If the application has stopped the dataflow @@ -1265,8 +1634,8 @@ uip_process(u8_t flag) 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. + uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN + 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 @@ -1280,7 +1649,7 @@ uip_process(u8_t flag) if(uip_flags & UIP_ABORT) { uip_slen = 0; - uip_connr->tcpstateflags = CLOSED; + uip_connr->tcpstateflags = UIP_CLOSED; BUF->flags = TCP_RST | TCP_ACK; goto tcp_send_nodata; } @@ -1288,17 +1657,17 @@ uip_process(u8_t flag) if(uip_flags & UIP_CLOSE) { uip_slen = 0; uip_connr->len = 1; - uip_connr->tcpstateflags = FIN_WAIT_1; + uip_connr->tcpstateflags = UIP_FIN_WAIT_1; uip_connr->nrtx = 0; BUF->flags = TCP_FIN | TCP_ACK; - goto tcp_send_nodata; + 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. */ + the ->len variable should be discarded. */ if((uip_flags & UIP_ACKDATA) != 0) { uip_connr->len = 0; } @@ -1325,8 +1694,6 @@ uip_process(u8_t flag) retransmit) out more than it previously sent out. */ uip_slen = uip_connr->len; } - } else { - uip_connr->len = 0; } uip_connr->nrtx = 0; apprexmit: @@ -1351,17 +1718,17 @@ uip_process(u8_t flag) } } goto drop; - case LAST_ACK: + case UIP_LAST_ACK: /* We can close this connection if the peer has acknowledged our - FIN. This is indicated by the UIP_ACKDATA flag. */ + FIN. This is indicated by the UIP_ACKDATA flag. */ if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = CLOSED; + uip_connr->tcpstateflags = UIP_CLOSED; uip_flags = UIP_CLOSE; UIP_APPCALL(); } break; - case FIN_WAIT_1: + case UIP_FIN_WAIT_1: /* The application has closed the connection, but the remote host hasn't closed its end yet. Thus we do nothing but wait for a FIN from the other side. */ @@ -1370,18 +1737,18 @@ uip_process(u8_t flag) } if(BUF->flags & TCP_FIN) { if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = TIME_WAIT; + uip_connr->tcpstateflags = UIP_TIME_WAIT; uip_connr->timer = 0; uip_connr->len = 0; } else { - uip_connr->tcpstateflags = CLOSING; + uip_connr->tcpstateflags = UIP_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->tcpstateflags = UIP_FIN_WAIT_2; uip_connr->len = 0; goto drop; } @@ -1390,12 +1757,12 @@ uip_process(u8_t flag) } goto drop; - case FIN_WAIT_2: + case UIP_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->tcpstateflags = UIP_TIME_WAIT; uip_connr->timer = 0; uip_add_rcv_nxt(1); uip_flags = UIP_CLOSE; @@ -1407,15 +1774,15 @@ uip_process(u8_t flag) } goto drop; - case TIME_WAIT: + case UIP_TIME_WAIT: goto tcp_send_ack; - case CLOSING: + case UIP_CLOSING: if(uip_flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = TIME_WAIT; + uip_connr->tcpstateflags = UIP_TIME_WAIT; uip_connr->timer = 0; } - } + } goto drop; @@ -1424,9 +1791,9 @@ uip_process(u8_t flag) tcp_send_ack: BUF->flags = TCP_ACK; tcp_send_nodata: - uip_len = 40; + uip_len = UIP_IPTCPH_LEN; tcp_send_noopts: - BUF->tcpoffset = 5 << 4; + BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 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 @@ -1447,11 +1814,8 @@ uip_process(u8_t flag) 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]; - + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr); if(uip_connr->tcpstateflags & UIP_STOPPED) { /* If the connection has issued uip_stop(), we advertise a zero @@ -1459,46 +1823,75 @@ uip_process(u8_t flag) BUF->wnd[0] = BUF->wnd[1] = 0; } else { BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); - BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); + BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); } tcp_send_noconn: - + BUF->ttl = UIP_TTL; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ BUF->len[0] = (uip_len >> 8); BUF->len[1] = (uip_len & 0xff); +#endif /* UIP_CONF_IPV6 */ + BUF->urgp[0] = BUF->urgp[1] = 0; + /* Calculate TCP checksum. */ BUF->tcpchksum = 0; BUF->tcpchksum = ~(uip_tcpchksum()); ip_send_nolen: +#if UIP_CONF_IPV6 + BUF->vtc = 0x60; + BUF->tcflow = 0x00; + BUF->flow = 0x00; +#else /* UIP_CONF_IPV6 */ BUF->vhl = 0x45; BUF->tos = 0; BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - 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()); - + DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + UIP_STAT(++uip_stat.tcp.sent); send: + DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, + (BUF->len[0] << 8) | BUF->len[1]); + UIP_STAT(++uip_stat.ip.sent); /* Return and let the caller do the actual transmission. */ + uip_flags = 0; return; drop: uip_len = 0; + uip_flags = 0; return; } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ u16_t htons(u16_t val) { return HTONS(val); } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +void +uip_send(const void *data, int len) +{ + if(len > 0) { + uip_slen = len; + if(data != uip_sappdata) { + memcpy(uip_sappdata, (data), uip_slen); + } + } +} /** @} */ diff --git a/uip/uip.h b/uip/uip.h index 19e146b..4fc0452 100644 --- a/uip/uip.h +++ b/uip/uip.h @@ -1,3 +1,4 @@ + /** * \addtogroup uip * @{ @@ -17,19 +18,19 @@ /* * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -41,11 +42,11 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $ + * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $ * */ @@ -54,7 +55,19 @@ #include "uipopt.h" -/*-----------------------------------------------------------------------------------*/ +/** + * Repressentation of an IP address. + * + */ +typedef u16_t uip_ip4addr_t[2]; +typedef u16_t uip_ip6addr_t[8]; +#if UIP_CONF_IPV6 +typedef uip_ip6addr_t uip_ipaddr_t; +#else /* UIP_CONF_IPV6 */ +typedef uip_ip4addr_t uip_ipaddr_t; +#endif /* UIP_CONF_IPV6 */ + +/*---------------------------------------------------------------------------*/ /* First, the functions that should be called from the * system. Initialization, the periodic timer and incoming packets are * handled by the following three functions. @@ -65,7 +78,7 @@ * @{ * * The uIP configuration functions are used for setting run-time - * parameters in uIP such as IP addresses. + * parameters in uIP such as IP addresses. */ /** @@ -75,12 +88,22 @@ * 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. + * Example: + \code + + uip_ipaddr_t addr; + + uip_ipaddr(&addr, 192,168,1,2); + uip_sethostaddr(&addr); + + \endcode + * \param addr A pointer to an IP address of type uip_ipaddr_t; + * + * \sa uip_ipaddr() * * \hideinitializer */ -#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \ - uip_hostaddr[1] = addr[1]; } while(0) +#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr)) /** * Get the IP address of this host. @@ -89,13 +112,63 @@ * 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. + * Example: + \code + uip_ipaddr_t hostaddr; + + uip_gethostaddr(&hostaddr); + \endcode + * \param addr A pointer to a uip_ipaddr_t variable 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) +#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr) + +/** + * Set the default router's IP address. + * + * \param addr A pointer to a uip_ipaddr_t variable containing the IP + * address of the default router. + * + * \sa uip_ipaddr() + * + * \hideinitializer + */ +#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr)) + +/** + * Set the netmask. + * + * \param addr A pointer to a uip_ipaddr_t variable containing the IP + * address of the netmask. + * + * \sa uip_ipaddr() + * + * \hideinitializer + */ +#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr)) + + +/** + * Get the default router's IP address. + * + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the IP address of the default router. + * + * \hideinitializer + */ +#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr) + +/** + * Get the netmask. + * + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the value of the netmask. + * + * \hideinitializer + */ +#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask) /** @} */ @@ -114,6 +187,13 @@ */ void uip_init(void); +/** + * uIP initialization function. + * + * This function may be used at boot time to set the initial ip_id. + */ +void uip_setipid(u16_t id); + /** @} */ /** @@ -178,7 +258,7 @@ void uip_init(void); /** * 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 @@ -212,7 +292,7 @@ void uip_init(void); ethernet_devicedriver_send(); } } - \endcode + \endcode * * \param conn The number of the connection which is to be periodically polled. * @@ -222,7 +302,14 @@ void uip_init(void); uip_process(UIP_TIMER); } while (0) /** - * Periodic processing for a connection identified by a pointer to its structure. + * + * + */ +#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED) + +/** + * Perform 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 @@ -236,11 +323,26 @@ void uip_init(void); #define uip_periodic_conn(conn) do { uip_conn = conn; \ uip_process(UIP_TIMER); } while (0) +/** + * Reuqest that a particular connection should be polled. + * + * Similar to uip_periodic_conn() but does not perform any timer + * processing. The application is polled for new data. + * + * \param conn A pointer to the uip_conn struct for the connection to + * be processed. + * + * \hideinitializer + */ +#define uip_poll_conn(conn) do { uip_conn = conn; \ + uip_process(UIP_POLL_REQUEST); } 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 + * This function is essentially the same as uip_periodic(), but for * UDP connections. It is called in a similar fashion as the * uip_periodic() function: \code @@ -249,7 +351,7 @@ void uip_init(void); if(uip_len > 0) { devicedriver_send(); } - } + } \endcode * * \note As for the uip_periodic() function, special care has to be @@ -261,7 +363,7 @@ void uip_init(void); uip_arp_out(); ethernet_devicedriver_send(); } - } + } \endcode * * \param conn The number of the UDP connection to be processed. @@ -308,8 +410,12 @@ void uip_init(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); + if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { + hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); + } else { + hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); + hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); + } } \endcode */ @@ -317,7 +423,7 @@ 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. @@ -336,7 +442,7 @@ extern u8_t uip_buf[UIP_BUFSIZE+2]; * order, a conversion using HTONS() or htons() is necessary. * \code - uip_listen(HTONS(80)); + uip_listen(HTONS(80)); \endcode * * \param port A 16-bit port number in network byte order. @@ -350,7 +456,7 @@ void uip_listen(u16_t port); * order, a conversion using HTONS() or htons() is necessary. * \code - uip_unlisten(HTONS(80)); + uip_unlisten(HTONS(80)); \endcode * * \param port A 16-bit port number in network byte order. @@ -372,25 +478,24 @@ void uip_unlisten(u16_t port); * 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. + * byte order, a conversion using HTONS() or htons() is necessary. * \code - u16_t ipaddr[2]; + uip_ipaddr_t ipaddr; - uip_ipaddr(ipaddr, 192,168,1,2); - uip_connect(ipaddr, HTONS(80)); + 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 ripaddr 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. + * or NULL if no connection could be allocated. * */ -struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port); +struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port); @@ -410,27 +515,27 @@ struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port); * * 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. + * 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) +void uip_send(const void *data, int len); /** * The length of any incoming data that is currently avaliable (if avaliable) @@ -441,6 +546,7 @@ struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port); * * \hideinitializer */ +/*void uip_datalen(void);*/ #define uip_datalen() uip_len /** @@ -509,6 +615,16 @@ struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port); /* uIP tests that can be made to determine in what state the current connection is, and what the application function should do. */ +/** + * Is the current connection a UDP connection? + * + * This function checks whether the current connection is a UDP connection. + * + * \hideinitializer + * + */ +#define uip_udpconnection() (uip_conn == NULL) + /** * Is new incoming data available? * @@ -525,14 +641,14 @@ struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port); * * 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. + * can send new data. * * \hideinitializer */ #define uip_acked() (uip_flags & UIP_ACKDATA) /** - * Has the connection just been connected? + * 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 @@ -596,7 +712,7 @@ struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port); * wait for the remote host to send data. * * \hideinitializer - */ + */ #define uip_poll() (uip_flags & UIP_POLL) /** @@ -623,15 +739,31 @@ struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port); /** * Set up a new UDP connection. * - * \param ripaddr A pointer to a 4-byte structure representing the IP - * address of the remote host. + * This function sets up a new UDP connection. The function will + * automatically allocate an unused local port for the new + * connection. However, another port can be chosen by using the + * uip_udp_bind() call, after the uip_udp_new() function has been + * called. + * + * Example: + \code + uip_ipaddr_t addr; + struct uip_udp_conn *c; + + uip_ipaddr(&addr, 192,168,2,1); + c = uip_udp_new(&addr, HTONS(12345)); + if(c != NULL) { + uip_udp_bind(c, HTONS(12344)); + } + \endcode + * \param ripaddr 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); +struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); /** * Removed a UDP connection. @@ -642,6 +774,18 @@ struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport); */ #define uip_udp_remove(conn) (conn)->lport = 0 +/** + * Bind a UDP connection to a local port. + * + * \param conn A pointer to the uip_udp_conn structure for the + * connection. + * + * \param port The local port number, in network byte order. + * + * \hideinitializer + */ +#define uip_udp_bind(conn, port) (conn)->lport = port + /** * Send a UDP datagram of length len on the current connection. * @@ -653,7 +797,7 @@ struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport); * * \hideinitializer */ -#define uip_udp_send(len) uip_slen = (len) +#define uip_udp_send(len) uip_send((char *)uip_appdata, len) /** @} */ @@ -668,30 +812,248 @@ struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport); */ /** - * Pack an IP address into a 4-byte array which is used by uIP to - * represent IP addresses. + * Construct an IP address from four bytes. + * + * This function constructs an IP address of the type that uIP handles + * internally from four bytes. The function is handy for specifying IP + * addresses to use with e.g. the uip_connect() function. * * Example: \code - u16_t ipaddr[2]; - - uip_ipaddr(&ipaddr, 192,168,1,2); + uip_ipaddr_t ipaddr; + struct uip_conn *c; + + uip_ipaddr(&ipaddr, 192,168,1,2); + c = uip_connect(&ipaddr, HTONS(80)); \endcode * - * \param addr A pointer to a 4-byte array that will be filled in with - * the IP addres. + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the IP address. + * * \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. + * \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)); \ + ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \ + ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \ } while(0) +/** + * Construct an IPv6 address from eight 16-bit words. + * + * This function constructs an IPv6 address. + * + * \hideinitializer + */ +#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \ + ((u16_t *)(addr))[0] = HTONS((addr0)); \ + ((u16_t *)(addr))[1] = HTONS((addr1)); \ + ((u16_t *)(addr))[2] = HTONS((addr2)); \ + ((u16_t *)(addr))[3] = HTONS((addr3)); \ + ((u16_t *)(addr))[4] = HTONS((addr4)); \ + ((u16_t *)(addr))[5] = HTONS((addr5)); \ + ((u16_t *)(addr))[6] = HTONS((addr6)); \ + ((u16_t *)(addr))[7] = HTONS((addr7)); \ + } while(0) + +/** + * Copy an IP address to another IP address. + * + * Copies an IP address from one place to another. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr_copy(&ipaddr2, &ipaddr1); + \endcode + * + * \param dest The destination for the copy. + * \param src The source from where to copy. + * + * \hideinitializer + */ +#if !UIP_CONF_IPV6 +#define uip_ipaddr_copy(dest, src) do { \ + ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \ + ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \ + } while(0) +#else /* !UIP_CONF_IPV6 */ +#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) +#endif /* !UIP_CONF_IPV6 */ + +/** + * Compare two IP addresses + * + * Compares two IP addresses. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { + printf("They are the same"); + } + \endcode + * + * \param addr1 The first IP address. + * \param addr2 The second IP address. + * + * \hideinitializer + */ +#if !UIP_CONF_IPV6 +#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \ + ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1]) +#else /* !UIP_CONF_IPV6 */ +#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) +#endif /* !UIP_CONF_IPV6 */ + +/** + * Compare two IP addresses with netmasks + * + * Compares two IP addresses with netmasks. The masks are used to mask + * out the bits that are to be compared. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2, mask; + + uip_ipaddr(&mask, 255,255,255,0); + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr(&ipaddr2, 192,16,1,3); + if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) { + printf("They are the same"); + } + \endcode + * + * \param addr1 The first IP address. + * \param addr2 The second IP address. + * \param mask The netmask. + * + * \hideinitializer + */ +#define uip_ipaddr_maskcmp(addr1, addr2, mask) \ + (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \ + (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \ + ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \ + (((u16_t *)addr2)[1] & ((u16_t *)mask)[1]))) + + +/** + * Mask out the network part of an IP address. + * + * Masks out the network part of an IP address, given the address and + * the netmask. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2, netmask; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr(&netmask, 255,255,255,0); + uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask); + \endcode + * + * In the example above, the variable "ipaddr2" will contain the IP + * address 192.168.1.0. + * + * \param dest Where the result is to be placed. + * \param src The IP address. + * \param mask The netmask. + * + * \hideinitializer + */ +#define uip_ipaddr_mask(dest, src, mask) do { \ + ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \ + ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \ + } while(0) + +/** + * Pick the first octet of an IP address. + * + * Picks out the first octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr1(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 1. + * + * \hideinitializer + */ +#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8) + +/** + * Pick the second octet of an IP address. + * + * Picks out the second octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr2(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 2. + * + * \hideinitializer + */ +#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff) + +/** + * Pick the third octet of an IP address. + * + * Picks out the third octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr3(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 3. + * + * \hideinitializer + */ +#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8) + +/** + * Pick the fourth octet of an IP address. + * + * Picks out the fourth octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr4(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 4. + * + * \hideinitializer + */ +#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff) + /** * Convert 16-bit quantity from host byte order to network byte order. * @@ -702,11 +1064,13 @@ struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport); * \hideinitializer */ #ifndef HTONS -# if BYTE_ORDER == BIG_ENDIAN +# if UIP_BYTE_ORDER == UIP_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 */ +# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) +# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +#else +#error "HTONS already defined!" #endif /* HTONS */ /** @@ -719,6 +1083,9 @@ struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport); #ifndef htons u16_t htons(u16_t val); #endif /* htons */ +#ifndef ntohs +#define ntohs htons +#endif /** @} */ @@ -729,32 +1096,47 @@ u16_t htons(u16_t val); * 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; +extern void *uip_appdata; -#if UIP_URGDATA > 0 +#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; +extern void *uip_urgdata; #endif /* UIP_URGDATA > 0 */ -/* u[8|16]_t uip_len: +/** + * \defgroup uipdrivervars Variables used in uIP device drivers + * @{ * - * 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. + * uIP has a few global variables that are used in device drivers for + * uIP. */ -extern volatile u16_t uip_len, uip_slen; -#if UIP_URGDATA > 0 -extern volatile u8_t uip_urglen, uip_surglen; +/** + * The length of the packet in the uip_buf buffer. + * + * The global variable uip_len holds the length of the packet in the + * uip_buf buffer. + * + * When the network device driver calls the uIP input function, + * uip_len should be set to the length of the packet in the uip_buf + * buffer. + * + * When sending packets, the device driver should use the contents of + * the uip_len variable to determine the length of the outgoing + * packet. + * + */ +extern u16_t uip_len; + +/** @} */ + +#if UIP_URGDATA > 0 +extern u16_t uip_urglen, uip_surglen; #endif /* UIP_URGDATA > 0 */ @@ -765,15 +1147,15 @@ extern volatile u8_t uip_urglen, uip_surglen; * 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 + * file pointers) for the connection. The type 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. */ + uip_ipaddr_t ripaddr; /**< 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. */ + order. */ u8_t rcv_nxt[4]; /**< The sequence number that we expect to receive next. */ @@ -783,7 +1165,7 @@ struct uip_conn { u16_t mss; /**< Current maximum segment size for the connection. */ u16_t initialmss; /**< Initial maximum segment size for the - connection. */ + connection. */ u8_t sa; /**< Retransmission time-out calculation state variable. */ u8_t sv; /**< Retransmission time-out calculation state @@ -795,11 +1177,16 @@ struct uip_conn { segment sent. */ /** The application state. */ - u8_t appstate[UIP_APPSTATE_SIZE]; + uip_tcp_appstate_t appstate; }; -/* Pointer to the current connection. */ +/** + * Pointer to the current TCP connection. + * + * The uip_conn pointer can be used to access the current TCP + * connection. + */ extern struct uip_conn *uip_conn; /* The array containing all uIP connections. */ extern struct uip_conn uip_conns[UIP_CONNS]; @@ -811,7 +1198,7 @@ extern struct uip_conn uip_conns[UIP_CONNS]; /** * 4-byte array used for the 32-bit sequence number calculations. */ -extern volatile u8_t uip_acc32[4]; +extern u8_t uip_acc32[4]; /** @} */ @@ -821,11 +1208,18 @@ extern volatile u8_t uip_acc32[4]; * Representation of a uIP UDP connection. */ struct uip_udp_conn { - u16_t ripaddr[2]; /**< The IP address of the remote peer. */ + uip_ipaddr_t ripaddr; /**< 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. */ + u8_t ttl; /**< Default time-to-live. */ + + /** The application state. */ + uip_udp_appstate_t appstate; }; +/** + * The current UDP connection. + */ extern struct uip_udp_conn *uip_udp_conn; extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; #endif /* UIP_UDP */ @@ -878,6 +1272,15 @@ struct uip_stats { uip_stats_t synrst; /**< Number of SYNs for closed ports, triggering a RST. */ } tcp; /**< TCP statistics. */ +#if UIP_UDP + struct { + uip_stats_t drop; /**< Number of dropped UDP segments. */ + uip_stats_t recv; /**< Number of recived UDP segments. */ + uip_stats_t sent; /**< Number of sent UDP segments. */ + uip_stats_t chkerr; /**< Number of UDP segments with a bad + checksum. */ + } udp; /**< UDP statistics. */ +#endif /* UIP_UDP */ }; /** @@ -888,24 +1291,25 @@ struct uip_stats { 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; +extern 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. */ + before calling the application callback. The UIP_ACKDATA, + UIP_NEWDATA, and UIP_CLOSE 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 only through the uIP + functions/macros. */ #define UIP_ACKDATA 1 /* Signifies that the outstanding data was acked and the application should send @@ -936,7 +1340,6 @@ extern volatile u8_t uip_flags; #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. @@ -947,114 +1350,252 @@ void uip_process(u8_t flag); 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. */ + timer has fired. These values are never used directly, but only in + the macrose defined in this file. */ + +#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. */ +#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should + be polled. */ +#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram + should be constructed in the + uip_buf buffer. */ #if UIP_UDP -#define UIP_UDP_TIMER 3 +#define UIP_UDP_TIMER 5 #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_CLOSED 0 +#define UIP_SYN_RCVD 1 +#define UIP_SYN_SENT 2 +#define UIP_ESTABLISHED 3 +#define UIP_FIN_WAIT_1 4 +#define UIP_FIN_WAIT_2 5 +#define UIP_CLOSING 6 +#define UIP_TIME_WAIT 7 +#define UIP_LAST_ACK 8 +#define UIP_TS_MASK 15 #define UIP_STOPPED 16 -#define UIP_TCPIP_HLEN 40 - /* The TCP and IP headers. */ -typedef struct { - /* IP header. */ +struct uip_tcpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcflow; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IPv4 header. */ u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; u16_t ipchksum; - u16_t srcipaddr[2], + u16_t srcipaddr[2], destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ /* TCP header. */ u16_t srcport, destport; - u8_t seqno[4], + u8_t seqno[4], ackno[4], tcpoffset, flags, - wnd[2]; + 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. */ +struct uip_icmpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcf; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IPv4 header. */ u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; u16_t ipchksum; - u16_t srcipaddr[2], + u16_t srcipaddr[2], destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ + /* ICMP (echo) header. */ u8_t type, icode; u16_t icmpchksum; - u16_t id, seqno; -} uip_icmpip_hdr; +#if !UIP_CONF_IPV6 + u16_t id, seqno; +#else /* !UIP_CONF_IPV6 */ + u8_t flags, reserved1, reserved2, reserved3; + u8_t icmp6data[16]; + u8_t options[1]; +#endif /* !UIP_CONF_IPV6 */ +}; /* The UDP and IP headers. */ -typedef struct { +struct uip_udpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcf; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ /* IP header. */ u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; u16_t ipchksum; - u16_t srcipaddr[2], + u16_t srcipaddr[2], destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ /* UDP header. */ u16_t srcport, destport; u16_t udplen; u16_t udpchksum; -} uip_udpip_hdr; +}; + + + +/** + * The buffer size available for user data in the \ref uip_buf buffer. + * + * This macro holds the available size for user data in the \ref + * uip_buf buffer. The macro is intended to be used for checking + * bounds of available user data. + * + * Example: + \code + snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i); + \endcode + * + * \hideinitializer + */ +#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) + #define UIP_PROTO_ICMP 1 #define UIP_PROTO_TCP 6 #define UIP_PROTO_UDP 17 +#define UIP_PROTO_ICMP6 58 + +/* Header sizes. */ +#if UIP_CONF_IPV6 +#define UIP_IPH_LEN 40 +#else /* UIP_CONF_IPV6 */ +#define UIP_IPH_LEN 20 /* Size of IP header */ +#endif /* UIP_CONF_IPV6 */ +#define UIP_UDPH_LEN 8 /* Size of UDP header */ +#define UIP_TCPH_LEN 20 /* Size of TCP header */ +#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + + UDP + header */ +#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + + TCP + header */ +#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN + #if UIP_FIXEDADDR -extern const u16_t uip_hostaddr[2]; +extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; #else /* UIP_FIXEDADDR */ -extern u16_t uip_hostaddr[2]; +extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; #endif /* UIP_FIXEDADDR */ + + +/** + * Representation of a 48-bit Ethernet address. + */ +struct uip_eth_addr { + u8_t addr[6]; +}; + +/** + * 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. + * + * \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. + * + * \return The TCP checksum of the TCP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_tcpchksum(void); + +/** + * Calculate the UDP checksum of the packet in uip_buf and uip_appdata. + * + * The UDP checksum is the Internet checksum of data contents of the + * UDP segment, and a pseudo-header as defined in RFC768. + * + * \return The UDP checksum of the UDP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_udpchksum(void); + + #endif /* __UIP_H__ */ /** @} */ - diff --git a/uip/uip_arch.h b/uip/uip_arch.h index 947d84c..71fd84b 100644 --- a/uip/uip_arch.h +++ b/uip/uip_arch.h @@ -1,3 +1,8 @@ +/** + * \addtogroup uip + * {@ + */ + /** * \defgroup uiparch Architecture specific uIP functions * @{ @@ -21,19 +26,19 @@ /* * Copyright (c) 2001, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -45,11 +50,11 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $ + * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $ * */ @@ -125,6 +130,9 @@ u16_t uip_ipchksum(void); */ u16_t uip_tcpchksum(void); +u16_t uip_udpchksum(void); + +/** @} */ /** @} */ #endif /* __UIP_ARCH_H__ */ diff --git a/uip/uip_arp.c b/uip/uip_arp.c index 6752925..75ade64 100644 --- a/uip/uip_arp.c +++ b/uip/uip_arp.c @@ -6,7 +6,7 @@ /** * \defgroup uiparp uIP Address Resolution Protocol * @{ - * + * * The Address Resolution Protocol ARP is used for mapping between IP * addresses and link level addresses such as the Ethernet MAC * addresses. ARP uses broadcast queries to ask for the link level @@ -26,19 +26,19 @@ /* * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -50,11 +50,11 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $ + * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $ * */ @@ -73,21 +73,21 @@ struct arp_hdr { struct uip_eth_addr shwaddr; u16_t sipaddr[2]; struct uip_eth_addr dhwaddr; - u16_t dipaddr[2]; + u16_t dipaddr[2]; }; struct ethip_hdr { struct uip_eth_hdr ethhdr; /* IP header. */ u8_t vhl, - tos, - len[2], - ipid[2], - ipoffset[2], - ttl, - proto; + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; u16_t ipchksum; - u16_t srcipaddr[2], + u16_t srcipaddr[2], destipaddr[2]; }; @@ -102,12 +102,9 @@ struct arp_entry { u8_t time; }; -struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, - UIP_ETHADDR1, - UIP_ETHADDR2, - UIP_ETHADDR3, - UIP_ETHADDR4, - UIP_ETHADDR5}}; +static const struct uip_eth_addr broadcast_ethaddr = + {{0xff,0xff,0xff,0xff,0xff,0xff}}; +static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff}; static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; static u16_t ipaddr[2]; @@ -210,6 +207,7 @@ uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) } } i = c; + tabptr = &arp_table[i]; } /* Now, i is the ARP table entry which we will fill with the new @@ -232,6 +230,7 @@ uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) * variable uip_len. */ /*-----------------------------------------------------------------------------------*/ +#if 0 void uip_arp_ipin(void) { @@ -239,18 +238,19 @@ uip_arp_ipin(void) /* Only insert/update an entry if the source IP address of the incoming IP packet comes from a host on the local network. */ - if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) != - (uip_hostaddr[0] & uip_arp_netmask[0])) { + if((IPBUF->srcipaddr[0] & uip_netmask[0]) != + (uip_hostaddr[0] & uip_netmask[0])) { return; } - if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) != - (uip_hostaddr[1] & uip_arp_netmask[1])) { + if((IPBUF->srcipaddr[1] & uip_netmask[1]) != + (uip_hostaddr[1] & uip_netmask[1])) { return; } uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src)); return; } +#endif /* 0 */ /*-----------------------------------------------------------------------------------*/ /** * ARP processing for incoming ARP packets. @@ -277,20 +277,23 @@ uip_arp_ipin(void) void uip_arp_arpin(void) { - + if(uip_len < sizeof(struct arp_hdr)) { uip_len = 0; return; } - uip_len = 0; switch(BUF->opcode) { case HTONS(ARP_REQUEST): /* ARP request. If it asked for our address, we send out a reply. */ - if(BUF->dipaddr[0] == uip_hostaddr[0] && - BUF->dipaddr[1] == uip_hostaddr[1]) { + if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { + /* First, we register the one who made the request in our ARP + table, since it is likely that we will do more communication + with this host in the future. */ + uip_arp_update(BUF->sipaddr, &BUF->shwaddr); + /* The reply opcode is 2. */ BUF->opcode = HTONS(2); @@ -304,16 +307,14 @@ uip_arp_arpin(void) BUF->sipaddr[0] = uip_hostaddr[0]; BUF->sipaddr[1] = uip_hostaddr[1]; - BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); uip_len = sizeof(struct arp_hdr); - } + } break; case HTONS(ARP_REPLY): /* ARP reply. We insert or update the ARP table if it was meant for us. */ - if(BUF->dipaddr[0] == uip_hostaddr[0] && - BUF->dipaddr[1] == uip_hostaddr[1]) { - + if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { uip_arp_update(BUF->sipaddr, &BUF->shwaddr); } break; @@ -353,6 +354,7 @@ void uip_arp_out(void) { struct arp_entry *tabptr; + /* Find the destination IP address in the ARP table and construct the Ethernet header. If the destination IP addres isn't on the local network, we use the default router's IP address instead. @@ -360,57 +362,55 @@ uip_arp_out(void) If not ARP table entry is found, we overwrite the original IP packet with an ARP request for the IP address. */ - /* Check if the destination address is on the local network. */ - if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) != - (uip_hostaddr[0] & uip_arp_netmask[0]) || - (IPBUF->destipaddr[1] & uip_arp_netmask[1]) != - (uip_hostaddr[1] & uip_arp_netmask[1])) { - /* Destination address was not on the local network, so we need to - use the default router's IP address instead of the destination - address when determining the MAC address. */ - ipaddr[0] = uip_arp_draddr[0]; - ipaddr[1] = uip_arp_draddr[1]; + /* First check if destination is a local broadcast. */ + if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) { + memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); } else { - /* Else, we use the destination IP address. */ - ipaddr[0] = IPBUF->destipaddr[0]; - ipaddr[1] = IPBUF->destipaddr[1]; - } + /* Check if the destination address is on the local network. */ + if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) { + /* Destination address was not on the local network, so we need to + use the default router's IP address instead of the destination + address when determining the MAC address. */ + uip_ipaddr_copy(ipaddr, uip_draddr); + } else { + /* Else, we use the destination IP address. */ + uip_ipaddr_copy(ipaddr, IPBUF->destipaddr); + } - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if(ipaddr[0] == tabptr->ipaddr[0] && - ipaddr[1] == tabptr->ipaddr[1]) - break; - } + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) { + break; + } + } - if(i == UIP_ARPTAB_SIZE) { - /* The destination address was not in our ARP table, so we - overwrite the IP packet with an ARP request. */ + if(i == UIP_ARPTAB_SIZE) { + /* The destination address was not in our ARP table, so we + overwrite the IP packet with an ARP request. */ - memset(BUF->ethhdr.dest.addr, 0xff, 6); - memset(BUF->dhwaddr.addr, 0x00, 6); - memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); - memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); + memset(BUF->ethhdr.dest.addr, 0xff, 6); + memset(BUF->dhwaddr.addr, 0x00, 6); + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); - BUF->dipaddr[0] = ipaddr[0]; - BUF->dipaddr[1] = ipaddr[1]; - BUF->sipaddr[0] = uip_hostaddr[0]; - BUF->sipaddr[1] = uip_hostaddr[1]; - BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */ - BUF->hwtype = HTONS(ARP_HWTYPE_ETH); - BUF->protocol = HTONS(UIP_ETHTYPE_IP); - BUF->hwlen = 6; - BUF->protolen = 4; - BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); + uip_ipaddr_copy(BUF->dipaddr, ipaddr); + uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr); + BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */ + BUF->hwtype = HTONS(ARP_HWTYPE_ETH); + BUF->protocol = HTONS(UIP_ETHTYPE_IP); + BUF->hwlen = 6; + BUF->protolen = 4; + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); - uip_appdata = &uip_buf[40 + UIP_LLH_LEN]; + uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN]; - uip_len = sizeof(struct arp_hdr); - return; - } + uip_len = sizeof(struct arp_hdr); + return; + } - /* Build an ethernet header. */ - memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); + /* Build an ethernet header. */ + memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); + } memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6); IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP); diff --git a/uip/uip_arp.h b/uip/uip_arp.h index 0371cd6..e32594d 100644 --- a/uip/uip_arp.h +++ b/uip/uip_arp.h @@ -4,7 +4,7 @@ */ /** - * \addtogroup uiparp + * \addtogroup uiparp * @{ */ @@ -17,19 +17,19 @@ /* * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -41,11 +41,11 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $ + * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $ * */ @@ -55,17 +55,10 @@ #include "uip.h" -/** - * Representation of a 48-bit Ethernet address. - */ -struct uip_eth_addr { - u8_t addr[6]; -}; - extern struct uip_eth_addr uip_ethaddr; /** - * The Ethernet header. + * The Ethernet header. */ struct uip_eth_hdr { struct uip_eth_addr dest; @@ -75,7 +68,7 @@ struct uip_eth_hdr { #define UIP_ETHTYPE_ARP 0x0806 #define UIP_ETHTYPE_IP 0x0800 -#define UIP_ETHTYPE_IP6 0x86dd +#define UIP_ETHTYPE_IP6 0x86dd /* The uip_arp_init() function must be called before any of the other @@ -87,7 +80,8 @@ void uip_arp_init(void); inserts a new mapping if none exists. The function assumes that an IP packet with an Ethernet header is present in the uip_buf buffer and that the length of the packet is in the uip_len variable. */ -void uip_arp_ipin(void); +/*void uip_arp_ipin(void);*/ +#define uip_arp_ipin() /* The uip_arp_arpin() should be called when an ARP packet is received by the Ethernet driver. This function also assumes that the @@ -120,51 +114,6 @@ void uip_arp_timer(void); * @{ */ -/** - * Set the default router's IP address. - * - * \param addr A pointer to a 4-byte array containing the IP address - * of the default router. - * - * \hideinitializer - */ -#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \ - uip_arp_draddr[1] = addr[1]; } while(0) - -/** - * Set the netmask. - * - * \param addr A pointer to a 4-byte array containing the IP address - * of the netmask. - * - * \hideinitializer - */ -#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \ - uip_arp_netmask[1] = addr[1]; } while(0) - - -/** - * Get the default router's IP address. - * - * \param addr A pointer to a 4-byte array that will be filled in with - * the IP address of the default router. - * - * \hideinitializer - */ -#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \ - addr[1] = uip_arp_draddr[1]; } while(0) - -/** - * Get the netmask. - * - * \param addr A pointer to a 4-byte array that will be filled in with - * the value of the netmask. - * - * \hideinitializer - */ -#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \ - addr[1] = uip_arp_netmask[1]; } while(0) - /** * Specifiy the Ethernet MAC address. @@ -190,12 +139,6 @@ void uip_arp_timer(void); uip_ethaddr.addr[5] = eaddr.addr[5];} while(0) /** @} */ +/** @} */ -/** - * \internal Internal variables that are set using the macros - * uip_setdraddr and uip_setnetmask. - */ -extern u16_t uip_arp_draddr[2], uip_arp_netmask[2]; #endif /* __UIP_ARP_H__ */ - - diff --git a/apps/telnet/telnet.h b/uip/uiplib.c similarity index 51% rename from apps/telnet/telnet.h rename to uip/uiplib.c index 0d68780..cb5af2c 100644 --- a/apps/telnet/telnet.h +++ b/uip/uiplib.c @@ -1,18 +1,19 @@ /* - * Copyright (c) 2002, Adam Dunkels. - * All rights reserved. + * Copyright (c) 2004, Adam Dunkels and the Swedish Institute of + * Computer Science. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -24,43 +25,50 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * This file is part of the uIP TCP/IP stack. + * This file is part of the uIP TCP/IP stack * - * $Id: telnet.h,v 1.1.2.4 2003/10/06 22:56:45 adam Exp $ + * $Id: uiplib.c,v 1.2 2006/06/12 08:00:31 adam Exp $ * */ -#ifndef __TELNET_H__ -#define __TELNET_H__ - -struct telnet_state { - unsigned char flags; - char *text; - u16_t textlen; - u16_t sentlen; -}; - -void telnet_app(void); - -#ifndef UIP_APPCALL -#define UIP_APPCALL telnet_app -#endif - -#ifndef UIP_APPSTATE_SIZE -#define UIP_APPSTATE_SIZE (sizeof(struct telnet_state)) -#endif -unsigned char telnet_send(struct telnet_state *s, char *text, u16_t len); -unsigned char telnet_close(struct telnet_state *s); -unsigned char telnet_abort(struct telnet_state *s); +#include "uip.h" +#include "uiplib.h" -/* Callbacks, must be implemented by the caller. */ -void telnet_connected(struct telnet_state *s); -void telnet_closed(struct telnet_state *s); -void telnet_sent(struct telnet_state *s); -void telnet_aborted(struct telnet_state *s); -void telnet_timedout(struct telnet_state *s); -void telnet_newdata(struct telnet_state *s, char *data, u16_t len); -#endif /* __TELNET_H__ */ + +/*-----------------------------------------------------------------------------------*/ +unsigned char +uiplib_ipaddrconv(char *addrstr, unsigned char *ipaddr) +{ + unsigned char tmp; + char c; + unsigned char i, j; + + tmp = 0; + + for(i = 0; i < 4; ++i) { + j = 0; + do { + c = *addrstr; + ++j; + if(j > 4) { + return 0; + } + if(c == '.' || c == 0) { + *ipaddr = tmp; + ++ipaddr; + tmp = 0; + } else if(c >= '0' && c <= '9') { + tmp = (tmp * 10) + (c - '0'); + } else { + return 0; + } + ++addrstr; + } while(c != '.' && c != 0); + } + return 1; +} + +/*-----------------------------------------------------------------------------------*/ diff --git a/uip/uiplib.h b/uip/uiplib.h new file mode 100644 index 0000000..c676849 --- /dev/null +++ b/uip/uiplib.h @@ -0,0 +1,71 @@ +/** + * \file + * Various uIP library functions. + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2002, 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: uiplib.h,v 1.1 2006/06/07 09:15:19 adam Exp $ + * + */ +#ifndef __UIPLIB_H__ +#define __UIPLIB_H__ + +/** + * \addtogroup uipconvfunc + * @{ + */ + +/** + * Convert a textual representation of an IP address to a numerical representation. + * + * This function takes a textual representation of an IP address in + * the form a.b.c.d and converts it into a 4-byte array that can be + * used by other uIP functions. + * + * \param addrstr A pointer to a string containing the IP address in + * textual form. + * + * \param addr A pointer to a 4-byte array that will be filled in with + * the numerical representation of the address. + * + * \retval 0 If the IP address could not be parsed. + * \retval Non-zero If the IP address was parsed. + */ +unsigned char uiplib_ipaddrconv(char *addrstr, unsigned char *addr); + +/** @} */ + +#endif /* __UIPLIB_H__ */ diff --git a/unix/uipopt.h b/uip/uipopt.h similarity index 66% rename from unix/uipopt.h rename to uip/uipopt.h index bbf3ef0..b1ef8e5 100644 --- a/unix/uipopt.h +++ b/uip/uipopt.h @@ -3,10 +3,13 @@ * @{ * * uIP is configured using the per-project configuration file - * "uipopt.h". This file contains all compile-time options for uIP and + * 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. + * + * \note Most of the configuration options in the uipopt.h should not + * be changed, but rather the per-project uip-conf.h file. */ /** @@ -22,19 +25,19 @@ /* * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. + * 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. + * 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. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -46,53 +49,30 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: uipopt.h,v 1.16.2.5 2003/10/07 13:22:51 adam Exp $ + * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $ * */ #ifndef __UIPOPT_H__ #define __UIPOPT_H__ -/*------------------------------------------------------------------------------*/ -/** - * \defgroup uipopttypedef uIP type definitions - * @{ - */ +#ifndef UIP_LITTLE_ENDIAN +#define UIP_LITTLE_ENDIAN 3412 +#endif /* UIP_LITTLE_ENDIAN */ +#ifndef UIP_BIG_ENDIAN +#define UIP_BIG_ENDIAN 1234 +#endif /* UIP_BIG_ENDIAN */ -/** - * 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; - -/** @} */ +#include "uip-conf.h" /*------------------------------------------------------------------------------*/ /** - * \defgroup uipoptstaticconf Static configuration options + * \name Static configuration options * @{ * * These configuration options can be used for setting the IP address @@ -114,7 +94,7 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ -#define UIP_FIXEDADDR 1 +#define UIP_FIXEDADDR 0 /** * Ping IP address asignment. @@ -128,46 +108,12 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ +#ifdef UIP_CONF_PINGADDRCONF +#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF +#else /* UIP_CONF_PINGADDRCONF */ #define UIP_PINGADDRCONF 0 +#endif /* UIP_CONF_PINGADDRCONF */ -#define UIP_IPADDR0 192 /**< The first octet of the IP address of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_IPADDR1 168 /**< 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 2 /**< The fourth octet of the IP address of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ - -#define UIP_NETMASK0 255 /**< The first octet of the netmask of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_NETMASK1 255 /**< The second octet of the netmask of - this uIP node, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_NETMASK2 255 /**< 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 192 /**< The first octet of the IP address of - the default router, if UIP_FIXEDADDR is - 1. \hideinitializer */ -#define UIP_DRIPADDR1 168 /**< 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 1 /**< 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 @@ -180,29 +126,10 @@ typedef unsigned short uip_stats_t; */ #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 + * \name IP configuration options * @{ * */ @@ -211,7 +138,7 @@ typedef unsigned short uip_stats_t; * * This should normally not be changed. */ -#define UIP_TTL 255 +#define UIP_TTL 64 /** * Turn on support for IP packet reassembly. @@ -239,13 +166,8 @@ typedef unsigned short uip_stats_t; /*------------------------------------------------------------------------------*/ /** - * \defgroup uipoptudp UDP configuration options + * \name 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 */ /** @@ -253,7 +175,11 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ +#ifdef UIP_CONF_UDP +#define UIP_UDP UIP_CONF_UDP +#else /* UIP_CONF_UDP */ #define UIP_UDP 0 +#endif /* UIP_CONF_UDP */ /** * Toggles if UDP checksums should be used or not. @@ -263,26 +189,34 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ +#ifdef UIP_CONF_UDP_CHECKSUMS +#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS +#else #define UIP_UDP_CHECKSUMS 0 +#endif /** * The maximum amount of concurrent UDP connections. * * \hideinitializer */ +#ifdef UIP_CONF_UDP_CONNS +#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS +#else /* UIP_CONF_UDP_CONNS */ #define UIP_UDP_CONNS 10 +#endif /* UIP_CONF_UDP_CONNS */ /** * The name of the function that should be called when UDP datagrams arrive. * * \hideinitializer */ -#define UIP_UDP_APPCALL udp_appcall + /** @} */ /*------------------------------------------------------------------------------*/ /** - * \defgroup uipopttcp TCP configuration options + * \name TCP configuration options * @{ */ @@ -307,7 +241,12 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ +#ifndef UIP_CONF_MAX_CONNECTIONS #define UIP_CONNS 10 +#else /* UIP_CONF_MAX_CONNECTIONS */ +#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS +#endif /* UIP_CONF_MAX_CONNECTIONS */ + /** * The maximum number of simultaneously listening TCP ports. @@ -316,18 +255,11 @@ typedef unsigned short uip_stats_t; * * \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 +#ifndef UIP_CONF_MAX_LISTENPORTS +#define UIP_LISTENPORTS 20 +#else /* UIP_CONF_MAX_LISTENPORTS */ +#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS +#endif /* UIP_CONF_MAX_LISTENPORTS */ /** * Determines if support for TCP urgent data notification should be @@ -338,7 +270,7 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ -#define UIP_URGDATA 1 +#define UIP_URGDATA 0 /** * The initial retransmission timeout counted in timer pulses. @@ -362,28 +294,44 @@ typedef unsigned short uip_stats_t; * * This should not need to be changed. */ -#define UIP_MAXSYNRTX 3 +#define UIP_MAXSYNRTX 5 /** * The TCP maximum segment size. * - * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40. + * This is should not be to set to more than + * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. */ -#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40) +#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) + +/** + * 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 + */ +#ifndef UIP_CONF_RECEIVE_WINDOW +#define UIP_RECEIVE_WINDOW UIP_TCP_MSS +#else +#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW +#endif /** * 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 + * \name ARP configuration options * @{ */ @@ -395,7 +343,11 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ +#ifdef UIP_CONF_ARPTAB_SIZE +#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE +#else #define UIP_ARPTAB_SIZE 8 +#endif /** * The maxium age of ARP table entries measured in 10ths of seconds. @@ -410,7 +362,7 @@ typedef unsigned short uip_stats_t; /*------------------------------------------------------------------------------*/ /** - * \defgroup uipoptgeneral General configuration options + * \name General configuration options * @{ */ @@ -423,7 +375,11 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ -#define UIP_BUFSIZE 1500 +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_BUFSIZE 400 +#else /* UIP_CONF_BUFFER_SIZE */ +#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE +#endif /* UIP_CONF_BUFFER_SIZE */ /** @@ -433,7 +389,11 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ -#define UIP_STATISTICS 1 +#ifndef UIP_CONF_STATISTICS +#define UIP_STATISTICS 0 +#else /* UIP_CONF_STATISTICS */ +#define UIP_STATISTICS UIP_CONF_STATISTICS +#endif /* UIP_CONF_STATISTICS */ /** * Determines if logging of certain events should be compiled in. @@ -444,7 +404,26 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ +#ifndef UIP_CONF_LOGGING #define UIP_LOGGING 0 +#else /* UIP_CONF_LOGGING */ +#define UIP_LOGGING UIP_CONF_LOGGING +#endif /* UIP_CONF_LOGGING */ + +/** + * Broadcast support. + * + * This flag configures IP broadcast support. This is useful only + * together with UDP. + * + * \hideinitializer + * + */ +#ifndef UIP_CONF_BROADCAST +#define UIP_BROADCAST 0 +#else /* UIP_CONF_BROADCAST */ +#define UIP_BROADCAST UIP_CONF_BROADCAST +#endif /* UIP_CONF_BROADCAST */ /** * Print out a uIP log message. @@ -463,13 +442,16 @@ void uip_log(char *msg); * * \hideinitializer */ +#ifdef UIP_CONF_LLH_LEN +#define UIP_LLH_LEN UIP_CONF_LLH_LEN +#else /* UIP_CONF_LLH_LEN */ #define UIP_LLH_LEN 14 - +#endif /* UIP_CONF_LLH_LEN */ /** @} */ /*------------------------------------------------------------------------------*/ /** - * \defgroup uipoptcpu CPU architecture configuration + * \name CPU architecture configuration * @{ * * The CPU architecture configuration is where the endianess of the @@ -478,12 +460,6 @@ void uip_log(char *msg); * 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. @@ -493,15 +469,17 @@ void uip_log(char *msg); * * \hideinitializer */ -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif /* BYTE_ORDER */ +#ifdef UIP_CONF_BYTE_ORDER +#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER +#else /* UIP_CONF_BYTE_ORDER */ +#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN +#endif /* UIP_CONF_BYTE_ORDER */ /** @} */ /*------------------------------------------------------------------------------*/ /** - * \defgroup uipoptapp Appication specific configurations + * \name Appication specific configurations * @{ * * An uIP application is implemented using a single application @@ -510,8 +488,8 @@ void uip_log(char *msg); * 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. + * uip_conn structure by specifying the type of the application + * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t. * * The file containing the definitions must be included in the * uipopt.h file. @@ -523,12 +501,12 @@ void httpd_appcall(void); #define UIP_APPCALL httpd_appcall struct httpd_state { - u8_t state; + u8_t state; u16_t count; char *dataptr; char *script; }; -#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state)) +typedef struct httpd_state uip_tcp_appstate_t \endcode */ @@ -541,17 +519,21 @@ struct httpd_state { */ /** - * \var #define UIP_APPSTATE_SIZE + * \var typedef uip_tcp_appstate_t * - * The size of the application state that is to be stored in the - * uip_conn structure. + * The type of the application state that is to be stored in the + * uip_conn structure. This usually is typedef:ed to a struct holding + * application state information. + */ + +/** + * \var typedef uip_udp_appstate_t + * + * The type of the application state that is to be stored in the + * uip_conn structure. This usually is typedef:ed to a struct holding + * application state information. */ /** @} */ - -/* 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" - +/** @} */ #endif /* __UIPOPT_H__ */ diff --git a/unix/Makefile b/unix/Makefile index 8f99cc4..ed64927 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -1,20 +1,17 @@ # Copyright (c) 2001, Adam Dunkels. -# All rights reserved. +# 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. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by Adam Dunkels. -# 4. The name of the author may not be used to endorse or promote +# 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. +# written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -26,49 +23,22 @@ # 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. +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # This file is part of the uIP TCP/IP stack. # -# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $ +# $Id: Makefile,v 1.13 2006/06/11 21:55:03 adam Exp $ # -CC=gcc -CFLAGS=-Wall -g -I../uip -I. -I../apps/httpd -I../apps/resolv -I../apps/webclient -I../apps/smtp -I../apps/telnet -fpack-struct +all: uip -%.o: - $(CC) $(CFLAGS) -c $(<:.o=.c) +CC = gcc +AR = ar +APPS = webserver +CFLAGS = -Wall -g -I../uip -I. -fpack-struct -Os +-include ../uip/Makefile.include - -uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o cgi.o - -tapdev.o: tapdev.c uipopt.h -main.o: main.c ../uip/uip.h uipopt.h ../apps/httpd/httpd.h \ - tapdev.h -uip_arch.o: uip_arch.c ../uip/uip_arch.h ../uip/uip.h uipopt.h \ - ../apps/httpd/httpd.h -uip.o: ../uip/uip.c ../uip/uip.h uipopt.h ../apps/httpd/httpd.h - -uip_arp.o: ../uip/uip_arp.c ../uip/uip_arp.h ../uip/uip.h uipopt.h \ - ../apps/httpd/httpd.h - $(CC) -o uip_arp.o $(CFLAGS) -fpack-struct -c ../uip/uip_arp.c - - -cgi.o: ../apps/httpd/cgi.c ../uip/uip.h uipopt.h ../apps/smtp/smtp.h \ - ../apps/httpd/cgi.h ../apps/httpd/httpd.h ../apps/httpd/fs.h -fs.o: ../apps/httpd/fs.c ../uip/uip.h uipopt.h ../apps/smtp/smtp.h \ - ../apps/httpd/httpd.h ../apps/httpd/fs.h ../apps/httpd/fsdata.h \ - ../apps/httpd/fsdata.c -fsdata.o: ../apps/httpd/fsdata.c -httpd.o: ../apps/httpd/httpd.c ../uip/uip.h uipopt.h \ - ../apps/smtp/smtp.h ../apps/httpd/httpd.h ../apps/httpd/fs.h \ - ../apps/httpd/fsdata.h ../apps/httpd/cgi.h +uip: $(addprefix $(OBJECTDIR)/, main.o tapdev.o clock-arch.o) apps.a uip.a clean: - rm -f *.o *~ *core uip - - - - - - + rm -fr *.o *~ *core uip $(OBJECTDIR) *.a diff --git a/unix/clock-arch.c b/unix/clock-arch.c new file mode 100644 index 0000000..d140aaf --- /dev/null +++ b/unix/clock-arch.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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: clock-arch.c,v 1.2 2006/06/12 08:00:31 adam Exp $ + */ + +/** + * \file + * Implementation of architecture-specific clock functionality + * \author + * Adam Dunkels + */ + +#include "clock-arch.h" +#include + +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} +/*---------------------------------------------------------------------------*/ diff --git a/unix/clock-arch.h b/unix/clock-arch.h new file mode 100644 index 0000000..e51eee9 --- /dev/null +++ b/unix/clock-arch.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $ + */ + +#ifndef __CLOCK_ARCH_H__ +#define __CLOCK_ARCH_H__ + +typedef int clock_time_t; +#define CLOCK_CONF_SECOND 1000 + +#endif /* __CLOCK_ARCH_H__ */ diff --git a/unix/main.c b/unix/main.c index 3930513..e4130e9 100644 --- a/unix/main.c +++ b/unix/main.c @@ -1,18 +1,21 @@ /* - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. + * 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 + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. The name of the author may not be used to endorse or promote * products derived from this software without specific prior - * written permission. + * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -24,11 +27,11 @@ * 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. + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the uIP TCP/IP stack. * - * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $ + * $Id: main.c,v 1.16 2006/06/11 21:55:03 adam Exp $ * */ @@ -36,8 +39,8 @@ #include "uip.h" #include "uip_arp.h" #include "tapdev.h" -#include "httpd.h" -#include "telnet.h" + +#include "timer.h" #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) @@ -45,31 +48,78 @@ #define NULL (void *)0 #endif /* NULL */ -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ int main(void) { - u8_t i, arptimer; + int i; + uip_ipaddr_t ipaddr; + struct timer periodic_timer, arp_timer; - /* Initialize the device driver. */ + timer_set(&periodic_timer, CLOCK_SECOND / 2); + timer_set(&arp_timer, CLOCK_SECOND * 10); + tapdev_init(); - - /* Initialize the uIP TCP/IP stack. */ uip_init(); - /* Initialize the HTTP server. */ + uip_ipaddr(ipaddr, 192,168,0,2); + uip_sethostaddr(ipaddr); + uip_ipaddr(ipaddr, 192,168,0,1); + uip_setdraddr(ipaddr); + uip_ipaddr(ipaddr, 255,255,255,0); + uip_setnetmask(ipaddr); + httpd_init(); - arptimer = 0; + /* telnetd_init();*/ + + /* hello_world_init();*/ + + /* { + u8_t mac[6] = {1,2,3,4,5,6}; + dhcpc_init(&mac, 6); + }*/ + + /*uip_ipaddr(ipaddr, 127,0,0,1); + smtp_configure("localhost", ipaddr); + SMTP_SEND("adam@sics.se", NULL, "uip-testing@example.com", + "Testing SMTP from uIP", + "Test message sent by uIP\r\n");*/ + + /* + webclient_init(); + resolv_init(); + uip_ipaddr(ipaddr, 195,54,122,204); + resolv_conf(ipaddr); + resolv_query("www.sics.se");*/ + + while(1) { - /* Let the tapdev network device driver read an entire IP packet - into the uip_buf. If it must wait for more than 0.5 seconds, it - will return with the return value 0. If so, we know that it is - time to call upon the uip_periodic(). Otherwise, the tapdev has - received an IP packet that is to be processed by uIP. */ uip_len = tapdev_read(); - if(uip_len == 0) { + if(uip_len > 0) { + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + tapdev_send(); + } + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + tapdev_send(); + } + } + + } else if(timer_expired(&periodic_timer)) { + timer_reset(&periodic_timer); for(i = 0; i < UIP_CONNS; i++) { uip_periodic(i); /* If the above function invocation resulted in data that @@ -95,40 +145,74 @@ main(void) #endif /* UIP_UDP */ /* Call the ARP timer function every 10 seconds. */ - if(++arptimer == 20) { + if(timer_expired(&arp_timer)) { + timer_reset(&arp_timer); uip_arp_timer(); - arptimer = 0; - } - - } else { - if(BUF->type == htons(UIP_ETHTYPE_IP)) { - uip_arp_ipin(); - uip_input(); - /* If the above function invocation resulted in data that - should be sent out on the network, the global variable - uip_len is set to a value > 0. */ - if(uip_len > 0) { - uip_arp_out(); - tapdev_send(); - } - } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { - uip_arp_arpin(); - /* If the above function invocation resulted in data that - should be sent out on the network, the global variable - uip_len is set to a value > 0. */ - if(uip_len > 0) { - tapdev_send(); - } } } - } return 0; } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void uip_log(char *m) { printf("uIP log message: %s\n", m); } -/*-----------------------------------------------------------------------------------*/ +void +resolv_found(char *name, u16_t *ipaddr) +{ + u16_t *ipaddr2; + + if(ipaddr == NULL) { + printf("Host '%s' not found.\n", name); + } else { + printf("Found name '%s' = %d.%d.%d.%d\n", name, + htons(ipaddr[0]) >> 8, + htons(ipaddr[0]) & 0xff, + htons(ipaddr[1]) >> 8, + htons(ipaddr[1]) & 0xff); + /* webclient_get("www.sics.se", 80, "/~adam/uip");*/ + } +} +#ifdef __DHCPC_H__ +void +dhcpc_configured(const struct dhcpc_state *s) +{ + uip_sethostaddr(s->ipaddr); + uip_setnetmask(s->netmask); + uip_setdraddr(s->default_router); + resolv_conf(s->dnsaddr); +} +#endif /* __DHCPC_H__ */ +void +smtp_done(unsigned char code) +{ + printf("SMTP done with code %d\n", code); +} +void +webclient_closed(void) +{ + printf("Webclient: connection closed\n"); +} +void +webclient_aborted(void) +{ + printf("Webclient: connection aborted\n"); +} +void +webclient_timedout(void) +{ + printf("Webclient: connection timed out\n"); +} +void +webclient_connected(void) +{ + printf("Webclient: connected, waiting for data...\n"); +} +void +webclient_datahandler(char *data, u16_t len) +{ + printf("Webclient: got %d bytes of data.\n", len); +} +/*---------------------------------------------------------------------------*/ diff --git a/unix/tapdev.c b/unix/tapdev.c index aae0f91..417b288 100644 --- a/unix/tapdev.c +++ b/unix/tapdev.c @@ -1,39 +1,43 @@ /* * Copyright (c) 2001, Swedish Institute of Computer Science. - * All rights reserved. + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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. * * Author: Adam Dunkels * - * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $ + * $Id: tapdev.c,v 1.8 2006/06/07 08:39:58 adam Exp $ */ +#define UIP_DRIPADDR0 192 +#define UIP_DRIPADDR1 168 +#define UIP_DRIPADDR2 0 +#define UIP_DRIPADDR3 1 #include #include @@ -58,12 +62,11 @@ #include "uip.h" +static int drop = 0; static int fd; -static unsigned long lasttime; -static struct timezone tz; -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void tapdev_init(void) { @@ -91,9 +94,8 @@ tapdev_init(void) UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3); system(buf); - lasttime = 0; } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ unsigned int tapdev_read(void) { @@ -101,71 +103,50 @@ tapdev_read(void) struct timeval tv, now; int ret; - if(lasttime >= 500000) { - lasttime = 0; - return 0; - } - tv.tv_sec = 0; - tv.tv_usec = 500000 - lasttime; + tv.tv_usec = 1000; FD_ZERO(&fdset); FD_SET(fd, &fdset); - gettimeofday(&now, &tz); ret = select(fd + 1, &fdset, NULL, NULL, &tv); if(ret == 0) { - lasttime = 0; return 0; - } - ret = read(fd, uip_buf, UIP_BUFSIZE); + } + ret = read(fd, uip_buf, UIP_BUFSIZE); if(ret == -1) { perror("tap_dev: tapdev_read: read"); } - gettimeofday(&tv, &tz); - lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec); + /* printf("--- tap_dev: tapdev_read: read %d bytes\n", ret);*/ + /* { + int i; + for(i = 0; i < 20; i++) { + printf("%x ", uip_buf[i]); + } + printf("\n"); + }*/ + /* check_checksum(uip_buf, ret);*/ return ret; } -/*-----------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ void tapdev_send(void) { int ret; - struct iovec iov[2]; - -#ifdef linux - { - char tmpbuf[UIP_BUFSIZE]; - int i; + /* printf("tapdev_send: sending %d bytes\n", size);*/ + /* check_checksum(uip_buf, size);*/ - for(i = 0; i < 40 + UIP_LLH_LEN; i++) { - tmpbuf[i] = uip_buf[i]; - } - - for(; i < uip_len; i++) { - tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN]; - } - - ret = write(fd, tmpbuf, uip_len); - } -#else - - if(uip_len < 40 + UIP_LLH_LEN) { - ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN); - } else { - iov[0].iov_base = uip_buf; - iov[0].iov_len = 40 + UIP_LLH_LEN; - iov[1].iov_base = (char *)uip_appdata; - iov[1].iov_len = uip_len - (40 + UIP_LLH_LEN); - - ret = writev(fd, iov, 2); - } -#endif + /* drop++; + if(drop % 8 == 7) { + printf("Dropped a packet!\n"); + return; + }*/ + ret = write(fd, uip_buf, uip_len); if(ret == -1) { perror("tap_dev: tapdev_send: writev"); exit(1); } -} -/*-----------------------------------------------------------------------------------*/ +} +/*---------------------------------------------------------------------------*/ diff --git a/unix/tapdev.h b/unix/tapdev.h index 5b947ef..280bc52 100644 --- a/unix/tapdev.h +++ b/unix/tapdev.h @@ -10,7 +10,10 @@ * 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 + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * @@ -28,7 +31,7 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: tapdev.h,v 1.1.2.1 2003/10/04 22:54:17 adam Exp $ + * $Id: tapdev.h,v 1.1 2002/01/10 06:22:56 adam Exp $ * */ diff --git a/unix/uip-conf.h b/unix/uip-conf.h new file mode 100644 index 0000000..2878c85 --- /dev/null +++ b/unix/uip-conf.h @@ -0,0 +1,157 @@ +/** + * \addtogroup uipopt + * @{ + */ + +/** + * \name Project-specific configuration options + * @{ + * + * uIP has a number of configuration options that can be overridden + * for each project. These are kept in a project-specific uip-conf.h + * file and all configuration names have the prefix UIP_CONF. + */ + +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $ + */ + +/** + * \file + * An example uIP configuration file + * \author + * Adam Dunkels + */ + +#ifndef __UIP_CONF_H__ +#define __UIP_CONF_H__ + +#include + +/** + * 8 bit datatype + * + * This typedef defines the 8-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef uint8_t u8_t; + +/** + * 16 bit datatype + * + * This typedef defines the 16-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef uint16_t u16_t; + +/** + * Statistics datatype + * + * This typedef defines the dataype used for keeping statistics in + * uIP. + * + * \hideinitializer + */ +typedef unsigned short uip_stats_t; + +/** + * Maximum number of TCP connections. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_CONNECTIONS 40 + +/** + * Maximum number of listening TCP ports. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_LISTENPORTS 40 + +/** + * uIP buffer size. + * + * \hideinitializer + */ +#define UIP_CONF_BUFFER_SIZE 420 + +/** + * CPU byte order. + * + * \hideinitializer + */ +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN + +/** + * Logging on or off + * + * \hideinitializer + */ +#define UIP_CONF_LOGGING 1 + +/** + * UDP support on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP 0 + +/** + * UDP checksums on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP_CHECKSUMS 1 + +/** + * uIP statistics on or off + * + * \hideinitializer + */ +#define UIP_CONF_STATISTICS 1 + +/* Here we include the header file for the application(s) we use in + our project. */ +/*#include "smtp.h"*/ +/*#include "hello-world.h"*/ +/*#include "telnetd.h"*/ +#include "webserver.h" +/*#include "dhcpc.h"*/ +/*#include "resolv.h"*/ +/*#include "webclient.h"*/ + +#endif /* __UIP_CONF_H__ */ + +/** @} */ +/** @} */ diff --git a/unix/uip_arch.c b/unix/uip_arch.c deleted file mode 100644 index cb3952b..0000000 --- a/unix/uip_arch.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $ - * - */ - - -#include "uip.h" -#include "uip_arch.h" - -#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define IP_PROTO_TCP 6 - -/*-----------------------------------------------------------------------------------*/ -void -uip_add32(u8_t *op32, u16_t op16) -{ - - uip_acc32[3] = op32[3] + (op16 & 0xff); - uip_acc32[2] = op32[2] + (op16 >> 8); - uip_acc32[1] = op32[1]; - uip_acc32[0] = op32[0]; - - if(uip_acc32[2] < (op16 >> 8)) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - - - if(uip_acc32[3] < (op16 & 0xff)) { - ++uip_acc32[2]; - if(uip_acc32[2] == 0) { - ++uip_acc32[1]; - if(uip_acc32[1] == 0) { - ++uip_acc32[0]; - } - } - } -} -/*-----------------------------------------------------------------------------------*/ -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; -} -/*-----------------------------------------------------------------------------------*/