ban4jp -
/
uIP-1-0_webserver
uIP 1.0 based webserver for LPC1114 + ENC28J60
Revision 3:a2715e9c7737, committed 2014-06-30
- Comitter:
- ban4jp
- Date:
- Mon Jun 30 16:00:08 2014 +0000
- Parent:
- 2:4da9ed411bdc
- Commit message:
- backported from Contiki 2.7
Changed in this revision
--- a/README.txt Sat Jun 21 11:54:24 2014 +0000 +++ b/README.txt Mon Jun 30 16:00:08 2014 +0000 @@ -8,6 +8,11 @@ https://github.com/adamdunkels/uip/releases/tag/uip-1-0 http://dunkels.com/adam/ +* Contiki 2.7 [backported about uIP core] by Adam Dunkels + + http://sourceforge.net/projects/contiki/files/Contiki/Contiki%202.7/ + http://www.contiki-os.org/ + -------------------------------- ENC28J60 Ethernet Driver
--- a/apps/webserver/httpd-cgi.cpp Sat Jun 21 11:54:24 2014 +0000 +++ b/apps/webserver/httpd-cgi.cpp Mon Jun 30 16:00:08 2014 +0000 @@ -137,12 +137,12 @@ conn = &uip_conns[s->count]; return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "<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>\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), + uip_htons(conn->lport), + conn->ripaddr.u8[0], + conn->ripaddr.u8[1], + conn->ripaddr.u8[2], + conn->ripaddr.u8[3], + uip_htons(conn->rport), states[conn->tcpstateflags & UIP_TS_MASK], conn->nrtx, conn->timer, @@ -190,15 +190,20 @@ PSOCK_END(&s->sout); } /*---------------------------------------------------------------------------*/ +static unsigned short +generate_tmp102_stats(void *arg) +{ + struct httpd_state *s = (struct httpd_state *)arg; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, + "%f", tmp102.read()); +} + static PT_THREAD(tmp102_stats(struct httpd_state *s, char *ptr)) { - char buff[10]; - PSOCK_BEGIN(&s->sout); - sprintf(buff, "%f", tmp102.read()); - PSOCK_SEND_STR(&s->sout, buff); + PSOCK_GENERATOR_SEND(&s->sout, generate_tmp102_stats, s); PSOCK_END(&s->sout); }
--- a/apps/webserver/httpd-fs-data.h Sat Jun 21 11:54:24 2014 +0000 +++ b/apps/webserver/httpd-fs-data.h Mon Jun 30 16:00:08 2014 +0000 @@ -257,6 +257,7 @@ "<tr><td><pre>\n" "IP Packets received\n" " Packets sent\n" + " Packets forwarded\n" " Packets dropped\n" "IP errors IP version/header length\n" " IP length, high byte\n" @@ -268,6 +269,8 @@ " Packets sent\n" " Packets dropped\n" " Type errors\n" + " Checksum errors\n" +#if UIP_TCP "TCP Packets received\n" " Packets sent\n" " Packets dropped\n" @@ -277,6 +280,18 @@ " Retransmissions\n" " No connection avaliable\n" " Connection attempts to closed ports\n" +#endif +#if UIP_UDP + "UDP Packets dropped\n" + " Packets received\n" + " Packets sent\n" + " Checksum errors\n" +#endif /* UIP_UDP */ +#if UIP_CONF_IPV6 + "IPv6 ND6 Packets dropped\n" + " Packets received\n" + " Packets sent\n" +#endif /*UIP_CONF_IPV6*/ "</pre></td><td><pre>%! net-stats\n" "</pre></td></tr></table>\n" "</center>\n"
--- a/apps/webserver/httpd.cpp Sat Jun 21 11:54:24 2014 +0000 +++ b/apps/webserver/httpd.cpp Mon Jun 30 16:00:08 2014 +0000 @@ -121,9 +121,14 @@ 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; + + if((p = strchr(s->scriptptr, ISO_nl)) != NULL) { + p += 1; + s->scriptlen -= (unsigned short)(p - s->scriptptr); + s->scriptptr = p; + } else { + s->scriptlen = 0; + } } /*---------------------------------------------------------------------------*/ static @@ -274,7 +279,7 @@ 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)); + strncpy(s->filename, s->inputbuf, sizeof(s->filename)); } /* httpd_log_file(uip_conn->ripaddr, s->filename);*/ @@ -340,7 +345,7 @@ extern "C" void httpd_init(void) { - uip_listen(HTONS(80)); + uip_listen(UIP_HTONS(80)); } /*---------------------------------------------------------------------------*/ /** @} */
--- a/dev-enc28j60/enc28j60.cpp Sat Jun 21 11:54:24 2014 +0000 +++ b/dev-enc28j60/enc28j60.cpp Mon Jun 30 16:00:08 2014 +0000 @@ -157,7 +157,8 @@ // perform system reset this->writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); // check CLKRDY bit to see if reset is complete - wait_us(50); + /* Fix Errata */ + wait_ms(1); while(!(this->read(ESTAT) & ESTAT_CLKRDY)); // do bank 0 stuff @@ -167,6 +168,9 @@ NextPacketPtr = RXSTART_INIT; this->write(ERXSTL, RXSTART_INIT&0xFF); this->write(ERXSTH, RXSTART_INIT>>8); + // set read pointer address + //this->write(ERDPTL, 0); + //this->write(ERDPTH, 0); // set receive pointer address this->write(ERXRDPTL, RXSTART_INIT&0xFF); this->write(ERXRDPTH, RXSTART_INIT>>8); @@ -252,6 +256,7 @@ { //Errata: Transmit Logic reset this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); + wait_us(10); this->writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); // Set the write pointer to start of transmit buffer area @@ -269,6 +274,11 @@ // send the contents of the transmit buffer onto the network this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); + + while(this->readOp(ENC28J60_BIT_FIELD_SET, ECON1) & ECON1_TXRTS) + { + wait_us(10); + } } void ENC28J60::packetSend2(unsigned int len1, unsigned char* packet1, unsigned int len2, unsigned char* packet2) @@ -302,7 +312,12 @@ // check if a packet has been received and buffered if( !(this->read(EIR) & EIR_PKTIF) ) - return 0; + { + if(this->read(EPKTCNT) == 0) + { + return 0; + } + } // Make absolutely certain that any previous packet was discarded //if( WasDiscarded == FALSE) @@ -332,11 +347,21 @@ // Move the RX read pointer to the start of the next received packet // This frees the memory we just read out - this->write(ERXRDPTL, (NextPacketPtr)); - this->write(ERXRDPTH, (NextPacketPtr)>>8); + /* Fix Errata */ + if(NextPacketPtr == RXSTART_INIT) + { + this->write(ERXRDPTL, (RXSTOP_INIT)); + this->write(ERXRDPTH, (RXSTOP_INIT)>>8); + } + else + { + this->write(ERXRDPTL, (NextPacketPtr)); + this->write(ERXRDPTH, (NextPacketPtr)>>8); + } // decrement the packet counter indicate we are done with this packet this->writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); + wait_us(11); return len; } @@ -352,35 +377,35 @@ { printf("RevID: 0x%x\n", this->read(EREVID)); - printf("Cntrl:\n"); + printf("Ctrl: "); printf("ECON1=%x ",this->read(ECON1)); printf("ECON2=%x ",this->read(ECON2)); printf("ESTAT=%x ",this->read(ESTAT)); - printf("EIR=%x\n",this->read(EIR)); + printf("EIR=%x ",this->read(EIR)); printf("EIE=%x\n",this->read(EIE)); - printf("MAC:\n"); + printf("MAC: "); printf("MACON1=%x ",this->read(MACON1)); printf("MACON2=%x ",this->read(MACON2)); printf("MACON3=%x ",this->read(MACON3)); - printf("MACON4=%x\n",this->read(MACON4)); + printf("MACON4=%x ",this->read(MACON4)); printf("MAD=%x%x\n", this->read(MAADR5)*0x1000000+this->read(MAADR4)*0x10000+this->read(MAADR3)*0x100+this->read(MAADR2), this->read(MAADR1)*0x1000000+this->read(MAADR0)*0x10000+0xffff); - printf("Rx:\n"); - printf("ERXST=%x ",this->read(ERXSTH)*0x100+this->read(ERXSTL)); - printf("ERXND=%x ",this->read(ERXNDH)*0x100+this->read(ERXNDL)); + printf("Rx: "); + printf("ERXST=%04x ",this->read(ERXSTH)*0x100+this->read(ERXSTL)); + printf("ERXND=%04x ",this->read(ERXNDH)*0x100+this->read(ERXNDL)); printf("ERXWRPT=%x ",this->read(ERXWRPTH)*0x100+this->read(ERXWRPTL)); - printf("ERXRDPT=%x\n",this->read(ERXRDPTH)*0x100+this->read(ERXRDPTL)); + printf("ERXRDPT=%x ",this->read(ERXRDPTH)*0x100+this->read(ERXRDPTL)); printf("ERXFCON=%x ",this->read(ERXFCON)); printf("EPKTCNT=%x ",this->read(EPKTCNT)); - printf("MAMXFL=%x ",this->read(MAMXFLH)*0x100+this->read(MAMXFLL)); + printf("MAMXFL=%x\n",this->read(MAMXFLH)*0x100+this->read(MAMXFLL)); - printf("Tx:\n"); - printf("ETXST=%x ",this->read(ETXSTH)*0x100+this->read(ETXSTL)); - printf("ETXND=%x ",this->read(ETXNDH)*0x100+this->read(ETXNDL)); + printf("Tx: "); + printf("ETXST=%04x ",this->read(ETXSTH)*0x100+this->read(ETXSTL)); + printf("ETXND=%04x ",this->read(ETXNDH)*0x100+this->read(ETXNDL)); printf("MACLCON1=%x ",this->read(MACLCON1)); - printf("MACLCON2=%x\n",this->read(MACLCON2)); + printf("MACLCON2=%x ",this->read(MACLCON2)); printf("MAPHSUP=%x\n",this->read(MAPHSUP)); }
--- a/dev-enc28j60/tapdev.cpp Sat Jun 21 11:54:24 2014 +0000 +++ b/dev-enc28j60/tapdev.cpp Mon Jun 30 16:00:08 2014 +0000 @@ -54,6 +54,9 @@ tapdev_init(void) { enc28j60.init(); + + //enc28j60.regDump(); + } /*---------------------------------------------------------------------------*/ unsigned int @@ -67,10 +70,14 @@ void tapdev_send(void) { + enc28j60.packetSend(uip_len, (u8 *)uip_buf); + + /* if(uip_len <= 40 + UIP_LLH_LEN){ enc28j60.packetSend(uip_len, (u8 *)uip_buf); }else{ enc28j60.packetSend2(54, (u8 *)uip_buf, uip_len -40 - UIP_LLH_LEN, (u8 *)uip_appdata); } + */ } /*---------------------------------------------------------------------------*/
--- a/main.cpp Sat Jun 21 11:54:24 2014 +0000 +++ b/main.cpp Mon Jun 30 16:00:08 2014 +0000 @@ -18,7 +18,15 @@ => /dev-enc28j60/tapdev.cpp */ +//Serial pc(USBTX, USBRX); // tx, rx +//RawSerial pc(USBTX, USBRX); // tx, rx + int main() { + //pc.baud(9600); + //pc.baud(115200); + + wait_ms(100); + int i; uip_ipaddr_t ipaddr; Timer periodic_timer, arp_timer; @@ -37,12 +45,12 @@ struct uip_eth_addr mac = {UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5}; uip_setethaddr(mac); - uip_ipaddr(ipaddr, 192,168,0,12); - uip_sethostaddr(ipaddr); - uip_ipaddr(ipaddr, 192,168,0,1); - uip_setdraddr(ipaddr); - uip_ipaddr(ipaddr, 255,255,255,0); - uip_setnetmask(ipaddr); + uip_ipaddr(&ipaddr, 192,168,0,12); + uip_sethostaddr(&ipaddr); + uip_ipaddr(&ipaddr, 192,168,0,1); + uip_setdraddr(&ipaddr); + uip_ipaddr(&ipaddr, 255,255,255,0); + uip_setnetmask(&ipaddr); printf("httpd_init()\n"); httpd_init(); @@ -77,7 +85,7 @@ if(uip_len > 0) { //printf("recv = %d\n", uip_len); - if(BUF->type == htons(UIP_ETHTYPE_IP)) { + if(BUF->type == UIP_HTONS(UIP_ETHTYPE_IP)) { uip_arp_ipin(); uip_input(); /* If the above function invocation resulted in data that @@ -87,7 +95,7 @@ uip_arp_out(); tapdev_send(); } - } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + } else if(BUF->type == UIP_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
--- a/uip-conf.h Sat Jun 21 11:54:24 2014 +0000 +++ b/uip-conf.h Mon Jun 30 16:00:08 2014 +0000 @@ -104,7 +104,7 @@ * * \hideinitializer */ -#define UIP_CONF_BUFFER_SIZE 840 +#define UIP_CONF_BUFFER_SIZE 512 /** * CPU byte order.
--- a/uip/psock.c Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/psock.c Mon Jun 30 16:00:08 2014 +0000 @@ -33,7 +33,6 @@ * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $ */ -#include <stdio.h> #include <string.h> #include "uipopt.h" @@ -128,22 +127,15 @@ 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) +data_is_sent_and_acked(register struct psock *s) { + /* If data has previously been sent, and the data has been acked, we + increase the send pointer and call send_data() to send more + data. */ if(s->state != STATE_DATA_SENT || uip_rexmit()) { if(s->sendlen > uip_mss()) { uip_send(s->sendptr, uip_mss()); @@ -151,15 +143,8 @@ 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()) { + return 0; + } else if(s->state == STATE_DATA_SENT && uip_acked()) { if(s->sendlen > uip_mss()) { s->sendlen -= uip_mss(); s->sendptr += uip_mss(); @@ -195,16 +180,10 @@ 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. + * The protothread will wait here until all data has been + * acknowledged and sent (data_is_acked_and_send() returns 1). */ - PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); + PT_WAIT_UNTIL(&s->psockpt, data_is_sent_and_acked(s)); } s->state = STATE_NONE; @@ -222,21 +201,24 @@ 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; + s->state = STATE_NONE; do { - /* Call the generator function again if we are called to perform a - retransmission. */ - if(uip_rexmit()) { - generate(arg); + /* Call the generator function to generate the data in the + uip_appdata buffer. */ + s->sendlen = generate(arg); + s->sendptr = uip_appdata; + + if(s->sendlen > uip_mss()) { + uip_send(s->sendptr, uip_mss()); + } else { + uip_send(s->sendptr, s->sendlen); } + s->state = STATE_DATA_SENT; + /* Wait until all data is sent and acknowledged. */ - PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); - } while(s->sendlen > 0); + // if (!s->sendlen) break; //useful debugging aid + PT_YIELD_UNTIL(&s->psockpt, uip_acked() || uip_rexmit()); + } while(!uip_acked()); s->state = STATE_NONE; @@ -285,9 +267,9 @@ psock->readptr = (u8_t *)uip_appdata; psock->readlen = uip_datalen(); } - } while((buf_bufto(&psock->buf, c, - &psock->readptr, - &psock->readlen) & BUF_FOUND) == 0); + } while(buf_bufto(&psock->buf, c, + &psock->readptr, + &psock->readlen) == BUF_NOT_FOUND); if(psock_datalen(psock) == 0) { psock->state = STATE_NONE; @@ -296,7 +278,7 @@ PT_END(&psock->psockpt); } /*---------------------------------------------------------------------------*/ -PT_THREAD(psock_readbuf(register struct psock *psock)) +PT_THREAD(psock_readbuf_len(register struct psock *psock, uint16_t len)) { PT_BEGIN(&psock->psockpt); @@ -308,15 +290,14 @@ 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); - + &psock->readptr, &psock->readlen) == BUF_NOT_FULL && + psock_datalen(psock) < len); + if(psock_datalen(psock) == 0) { psock->state = STATE_NONE; PT_RESTART(&psock->psockpt);
--- a/uip/psock.h Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/psock.h Mon Jun 30 16:00:08 2014 +0000 @@ -234,7 +234,7 @@ */ #define PSOCK_CLOSE(psock) uip_close() -PT_THREAD(psock_readbuf(struct psock *psock)); +PT_THREAD(psock_readbuf_len(struct psock *psock, u16_t len)); /** * Read data until the buffer is full. * @@ -247,8 +247,27 @@ * * \hideinitializer */ +/* #define PSOCK_READBUF(psock) \ - PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock)) + PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, 1)) +*/ + + +/** + * Read data until at least len bytes have been read. + * + * 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 or len bytes have been read. + * + * \param psock (struct psock *) A pointer to the protosocket from which + * data should be read. + * \param len (uint16_t) The minimum number of bytes to read. + * + * \hideinitializer + */ +#define PSOCK_READBUF_LEN(psock, len) \ + PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, len)) PT_THREAD(psock_readto(struct psock *psock, unsigned char c)); /** @@ -256,7 +275,7 @@ * * 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. + * read until the specified character appears in the data stream. * * \param psock (struct psock *) A pointer to the protosocket from which * data should be read. @@ -352,7 +371,7 @@ { PSOCK_BEGIN(s); - PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t)); + PSOCK_WAIT_UNTIL(s, PSOCK_NEWDATA(s) || timer_expired(t)); if(PSOCK_NEWDATA(s)) { PSOCK_READTO(s, '\n');
--- a/uip/pt.h Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/pt.h Mon Jun 30 16:00:08 2014 +0000 @@ -26,11 +26,10 @@ * 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 + * This file is part of the Contiki operating system. * * Author: Adam Dunkels <adam@sics.se> * - * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $ */ /** @@ -56,9 +55,9 @@ }; #define PT_WAITING 0 -#define PT_EXITED 1 -#define PT_ENDED 2 -#define PT_YIELDED 3 +#define PT_YIELDED 1 +#define PT_EXITED 2 +#define PT_ENDED 3 /** * \name Initialization @@ -112,7 +111,7 @@ * * \hideinitializer */ -#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) +#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; if (PT_YIELD_FLAG) {;} LC_RESUME((pt)->lc) /** * Declare the end of a protothread. @@ -259,7 +258,7 @@ /** * Schedule a protothread. * - * This function shedules a protothread. The return value of the + * This function schedules a protothread. The return value of the * function is non-zero if the protothread is running or zero if the * protothread has exited. * @@ -268,7 +267,7 @@ * * \hideinitializer */ -#define PT_SCHEDULE(f) ((f) == PT_WAITING) +#define PT_SCHEDULE(f) ((f) < PT_EXITED) /** @} */
--- a/uip/uip-fw.c Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uip-fw.c Mon Jun 30 16:00:08 2014 +0000 @@ -26,11 +26,10 @@ * 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 + * This file is part of the Contiki operating system. * * Author: Adam Dunkels <adam@sics.se> * - * $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $ */ /** * \addtogroup uip @@ -53,11 +52,16 @@ * */ +#include <string.h> + +#include "uip-conf.h" + #include "uip.h" #include "uip_arch.h" #include "uip-fw.h" - -#include <string.h> /* for memcpy() */ +#ifdef AODV_COMPLIANCE +#include "uaodv-def.h" +#endif /* * The list of registered network interfaces. @@ -71,47 +75,45 @@ struct tcpip_hdr { /* IP header. */ - u8_t vhl, + uint8_t vhl, tos; - u16_t len, + uint16_t len, ipid, ipoffset; - u8_t ttl, + uint8_t ttl, proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uint16_t ipchksum; + uip_ipaddr_t srcipaddr, destipaddr; /* TCP header. */ - u16_t srcport, + uint16_t srcport, destport; - u8_t seqno[4], + uint8_t seqno[4], ackno[4], tcpoffset, flags, wnd[2]; - u16_t tcpchksum; - u8_t urgp[2]; - u8_t optdata[4]; + uint16_t tcpchksum; + uint8_t urgp[2]; + uint8_t optdata[4]; }; struct icmpip_hdr { /* IP header. */ - u8_t vhl, + uint8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uint16_t ipchksum; + uip_ipaddr_t srcipaddr, destipaddr; /* ICMP (echo) header. */ - u8_t type, icode; - u16_t icmpchksum; - u16_t id, seqno; - u8_t payload[1]; + uint8_t type, icode; + uint16_t icmpchksum; + uint16_t id, seqno; + uint8_t payload[1]; }; /* ICMP ECHO. */ @@ -135,20 +137,20 @@ * duplicate packets. */ struct fwcache_entry { - u16_t timer; + uint16_t timer; - u16_t srcipaddr[2]; - u16_t destipaddr[2]; - u16_t ipid; - u8_t proto; - u8_t unused; + uip_ipaddr_t srcipaddr; + uip_ipaddr_t destipaddr; + uint16_t ipid; + uint8_t proto; + uint8_t unused; #if notdef - u16_t payload[2]; + uint16_t payload[2]; #endif #if UIP_REASSEMBLY > 0 - u16_t len, offset; + uint16_t len, offset; #endif }; @@ -204,10 +206,12 @@ */ /*------------------------------------------------------------------------------*/ static unsigned char -ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask) +ipaddr_maskcmp(uip_ipaddr_t *ipaddr, + uip_ipaddr_t *netipaddr, + uip_ipaddr_t *netmask) { - return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) && - (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]); + return (ipaddr->u16[0] & netmask->u16[0]) == (netipaddr->u16[0] & netmask->u16[0]) && + (ipaddr->u16[1] & netmask->u16[1]) == (netipaddr->u16[1] & netmask->u16[1]); } /*------------------------------------------------------------------------------*/ /** @@ -221,15 +225,15 @@ static void time_exceeded(void) { - u16_t tmp16; - /* We don't send out ICMP errors for ICMP messages. */ - if(ICMPBUF->proto == UIP_PROTO_ICMP) { + /* We don't send out ICMP errors for ICMP messages (unless they are pings). */ + if(ICMPBUF->proto == UIP_PROTO_ICMP && + ICMPBUF->type != ICMP_ECHO) { uip_len = 0; return; } /* Copy fields from packet header into payload of this ICMP packet. */ - memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28); + memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8); /* Set the ICMP type and code. */ ICMPBUF->type = ICMP_TE; @@ -237,26 +241,20 @@ /* Calculate the ICMP checksum. */ ICMPBUF->icmpchksum = 0; - ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36); + ICMPBUF->icmpchksum = ~uip_chksum((uint16_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; + uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); /* Set our IP address as the source address. */ - BUF->srcipaddr[0] = uip_hostaddr[0]; - BUF->srcipaddr[1] = uip_hostaddr[1]; + uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); /* 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; + ICMPBUF->len[1] = (uint8_t)uip_len; /* Fill in the other fields in the IP header. */ ICMPBUF->vhl = 0x45; @@ -300,10 +298,8 @@ 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]; + uip_ipaddr_copy(&fw->srcipaddr, &BUF->srcipaddr); + uip_ipaddr_copy(&fw->destipaddr, &BUF->destipaddr); fw->proto = BUF->proto; #if notdef fw->payload[0] = BUF->srcport; @@ -327,8 +323,8 @@ /* 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(ipaddr_maskcmp(&BUF->destipaddr, &netif->ipaddr, + &netif->netmask)) { /* If there was a match, we break the loop. */ return netif; } @@ -354,10 +350,13 @@ * function is passed unmodified as a return value. */ /*------------------------------------------------------------------------------*/ -u8_t +uint8_t uip_fw_output(void) { struct uip_fw_netif *netif; +#if UIP_BROADCAST + const struct uip_udpip_hdr *udp = (void *)BUF; +#endif /* UIP_BROADCAST */ if(uip_len == 0) { return UIP_FW_ZEROLEN; @@ -367,9 +366,7 @@ #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(uip_ipaddr_cmp(&udp->destipaddr, &uip_broadcast_addr)) { if(defaultnetif != NULL) { defaultnetif->output(); } @@ -402,22 +399,28 @@ * the packet should be processed locally. */ /*------------------------------------------------------------------------------*/ -u8_t +uint8_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]) { + if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) { return UIP_FW_LOCAL; } +#ifdef AODV_COMPLIANCE +#define udp ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) + if(udp->proto == UIP_PROTO_UDP && udp->destport == UIP_HTONS(UAODV_UDPPORT)) { + return UIP_FW_LOCAL; + } +#endif + /* 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 && + if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) && BUF->proto == UIP_PROTO_ICMP && ICMPBUF->type == ICMP_ECHO) { return UIP_FW_LOCAL; @@ -434,10 +437,8 @@ 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] && + uip_ipaddr_cmp(&fw->srcipaddr, &BUF->srcipaddr) && + uip_ipaddr_cmp(&fw->destipaddr, &BUF->destipaddr) && #if notdef fw->payload[0] == BUF->srcport && fw->payload[1] == BUF->destport && @@ -451,9 +452,10 @@ /* 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) { + if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) { return UIP_FW_LOCAL; } time_exceeded(); @@ -463,10 +465,10 @@ BUF->ttl = BUF->ttl - 1; /* Update the IP checksum. */ - if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) { - BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1; + if(BUF->ipchksum >= UIP_HTONS(0xffff - 0x0100)) { + BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100) + 1; } else { - BUF->ipchksum = BUF->ipchksum + HTONS(0x0100); + BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100); } if(uip_len > 0) { @@ -475,7 +477,7 @@ } #if UIP_BROADCAST - if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { + if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) { return UIP_FW_LOCAL; } #endif /* UIP_BROADCAST */ @@ -530,3 +532,5 @@ } } /*------------------------------------------------------------------------------*/ +/** @} */ +/** @} */
--- a/uip/uip-fw.h Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uip-fw.h Mon Jun 30 16:00:08 2014 +0000 @@ -11,37 +11,36 @@ /* * Copyright (c) 2004, 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 uIP TCP/IP stack - * + * This file is part of the Contiki operating system. + * * Author: Adam Dunkels <adam@sics.se> * - * $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $ */ #ifndef __UIP_FW_H__ #define __UIP_FW_H__ @@ -54,15 +53,15 @@ 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); + uip_ipaddr_t ipaddr; /**< The IP address of this interface. */ + uip_ipaddr_t netmask; /**< The netmask of the interface. */ + uint8_t (* output)(void); /**< A pointer to the function that sends a packet. */ }; /** - * Intantiating macro for a uIP network interface. + * Instantiating macro for a uIP network interface. * * Example: \code @@ -79,8 +78,8 @@ */ #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)}, \ + { {ip1, ip2, ip3, ip4} }, \ + { {nm1, nm2, nm3, nm4} }, \ outputfunc /** @@ -93,8 +92,8 @@ * \hideinitializer */ #define uip_fw_setipaddr(netif, addr) \ - do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \ - (netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0) + do { (netif)->ipaddr[0] = ((uint16_t *)(addr))[0]; \ + (netif)->ipaddr[1] = ((uint16_t *)(addr))[1]; } while(0) /** * Set the netmask of a network interface. * @@ -105,12 +104,12 @@ * \hideinitializer */ #define uip_fw_setnetmask(netif, addr) \ - do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \ - (netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0) + do { (netif)->netmask[0] = ((uint16_t *)(addr))[0]; \ + (netif)->netmask[1] = ((uint16_t *)(addr))[1]; } while(0) void uip_fw_init(void); -u8_t uip_fw_forward(void); -u8_t uip_fw_output(void); +uint8_t uip_fw_forward(void); +uint8_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/uip/uip-neighbor.c Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uip-neighbor.c Mon Jun 30 16:00:08 2014 +0000 @@ -26,9 +26,8 @@ * 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 + * This file is part of the Contiki operating system. * - * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $ */ /** @@ -54,7 +53,7 @@ struct neighbor_entry { uip_ipaddr_t ipaddr; struct uip_neighbor_addr addr; - u8_t time; + uint8_t time; }; static struct neighbor_entry entries[ENTRIES]; @@ -82,14 +81,14 @@ } /*---------------------------------------------------------------------------*/ void -uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr) +uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr) { int i, oldest; - u8_t oldest_time; + uint8_t oldest_time; - printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + /* 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]); + addr->addr.addr[4], addr->addr.addr[5]);*/ /* Find the first unused entry or the oldest used entry. */ oldest_time = 0; @@ -99,7 +98,7 @@ oldest = i; break; } - if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) { + if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) { oldest = i; break; } @@ -112,17 +111,17 @@ /* 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); + 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) +find_entry(uip_ipaddr_t *ipaddr) { int i; for(i = 0; i < ENTRIES; ++i) { - if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) { + if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) { return &entries[i]; } } @@ -130,7 +129,7 @@ } /*---------------------------------------------------------------------------*/ void -uip_neighbor_update(uip_ipaddr_t ipaddr) +uip_neighbor_update(uip_ipaddr_t *ipaddr) { struct neighbor_entry *e; @@ -141,7 +140,7 @@ } /*---------------------------------------------------------------------------*/ struct uip_neighbor_addr * -uip_neighbor_lookup(uip_ipaddr_t ipaddr) +uip_neighbor_lookup(uip_ipaddr_t *ipaddr) { struct neighbor_entry *e;
--- a/uip/uip-neighbor.h Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uip-neighbor.h Mon Jun 30 16:00:08 2014 +0000 @@ -26,9 +26,8 @@ * 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 + * This file is part of the Contiki operating system. * - * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $ */ /** @@ -53,9 +52,9 @@ }; 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_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__ */
--- a/uip/uip.c Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uip.c Mon Jun 30 16:00:08 2014 +0000 @@ -1,16 +1,8 @@ #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ /** - * \defgroup uip The uIP TCP/IP stack + * \addtogroup uip * @{ - * - * 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. */ /** @@ -49,7 +41,6 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $ * */ @@ -81,8 +72,15 @@ #include "uip.h" #include "uipopt.h" +#include "uip_arp.h" #include "uip_arch.h" +#if !UIP_CONF_IPV6 /* If UIP_CONF_IPV6 is defined, we compile the + uip6.c file instead of this one. Therefore + this #ifndef removes the entire compilation + output of the uip.c file */ + + #if UIP_CONF_IPV6 #include "uip-neighbor.h" #endif /* UIP_CONF_IPV6 */ @@ -98,47 +96,37 @@ here. Otherwise, the address */ #if UIP_FIXEDADDR > 0 const uip_ipaddr_t uip_hostaddr = - {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), - HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; + { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 }; const uip_ipaddr_t uip_draddr = - {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), - HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; + { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 }; const uip_ipaddr_t uip_netmask = - {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), - HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; + { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 }; #else uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; #endif /* UIP_FIXEDADDR */ -static const uip_ipaddr_t all_ones_addr = +const uip_ipaddr_t uip_broadcast_addr = #if UIP_CONF_IPV6 - {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; + { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; #else /* UIP_CONF_IPV6 */ - {0xffff,0xffff}; + { { 0xff, 0xff, 0xff, 0xff } }; #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 */ - +const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } }; #if UIP_FIXEDETHADDR -const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, +const uip_lladdr_t uip_lladdr = {{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}}; +uip_lladdr_t uip_lladdr = {{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 */ +/* The packet buffer that contains incoming packets. */ +uip_buf_t uip_aligned_buf; void *uip_appdata; /* The uip_appdata pointer points to application data. */ @@ -149,15 +137,15 @@ void *uip_urgdata; /* The uip_urgdata pointer points to urgent data (out-of-band data), if present. */ -u16_t uip_urglen, uip_surglen; +uint16_t uip_urglen, uip_surglen; #endif /* UIP_URGDATA > 0 */ -u16_t uip_len, uip_slen; +uint16_t uip_len, uip_slen; /* The uip_len is either 8 or 16 bits, depending on the maximum packet size. */ -u8_t uip_flags; /* The uip_flags variable is used for +uint8_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 @@ -166,7 +154,7 @@ struct uip_conn uip_conns[UIP_CONNS]; /* The uip_conns array holds all TCP connections. */ -u16_t uip_listenports[UIP_LISTENPORTS]; +uint16_t uip_listenports[UIP_LISTENPORTS]; /* The uip_listenports list all currently listning ports. */ #if UIP_UDP @@ -174,24 +162,24 @@ struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; #endif /* UIP_UDP */ -static u16_t ipid; /* Ths ipid variable is an increasing +static uint16_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; } +void uip_setipid(uint16_t id) { ipid = id; } -static u8_t iss[4]; /* The iss variable is used for the TCP +static uint8_t iss[4]; /* The iss variable is used for the TCP initial sequence number. */ -#if UIP_ACTIVE_OPEN -static u16_t lastport; /* Keeps track of the last port used for +#if UIP_ACTIVE_OPEN || UIP_UDP +static uint16_t lastport; /* Keeps track of the last port used for a new connection. */ -#endif /* UIP_ACTIVE_OPEN */ +#endif /* UIP_ACTIVE_OPEN || UIP_UDP */ /* Temporary variables. */ -u8_t uip_acc32[4]; -static u8_t c, opt; -static u16_t tmp16; +uint8_t uip_acc32[4]; +static uint8_t c, opt; +static uint16_t tmp16; /* Structures and definitions. */ #define TCP_FIN 0x01 @@ -211,6 +199,9 @@ #define ICMP_ECHO_REPLY 0 #define ICMP_ECHO 8 +#define ICMP_DEST_UNREACHABLE 3 +#define ICMP_PORT_UNREACHABLE 3 + #define ICMP6_ECHO_REPLY 129 #define ICMP6_ECHO 128 #define ICMP6_NEIGHBOR_SOLICITATION 135 @@ -246,7 +237,7 @@ #if ! UIP_ARCH_ADD32 void -uip_add32(u8_t *op32, u16_t op16) +uip_add32(uint8_t *op32, uint16_t op16) { uip_acc32[3] = op32[3] + (op16 & 0xff); uip_acc32[2] = op32[2] + (op16 >> 8); @@ -276,12 +267,12 @@ #if ! UIP_ARCH_CHKSUM /*---------------------------------------------------------------------------*/ -static u16_t -chksum(u16_t sum, const u8_t *data, u16_t len) +static uint16_t +chksum(uint16_t sum, const uint8_t *data, uint16_t len) { - u16_t t; - const u8_t *dataptr; - const u8_t *last_byte; + uint16_t t; + const uint8_t *dataptr; + const uint8_t *last_byte; dataptr = data; last_byte = data + len - 1; @@ -307,34 +298,34 @@ return sum; } /*---------------------------------------------------------------------------*/ -u16_t -uip_chksum(u16_t *data, u16_t len) +uint16_t +uip_chksum(uint16_t *data, uint16_t len) { - return htons(chksum(0, (u8_t *)data, len)); + return uip_htons(chksum(0, (uint8_t *)data, len)); } /*---------------------------------------------------------------------------*/ #ifndef UIP_ARCH_IPCHKSUM -u16_t +uint16_t uip_ipchksum(void) { - u16_t sum; + uint16_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); + return (sum == 0) ? 0xffff : uip_htons(sum); } #endif /*---------------------------------------------------------------------------*/ -static u16_t -upper_layer_chksum(u8_t proto) +static uint16_t +upper_layer_chksum(uint8_t proto) { - u16_t upper_layer_len; - u16_t sum; + uint16_t upper_layer_len; + uint16_t sum; #if UIP_CONF_IPV6 - upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]); + upper_layer_len = (((uint16_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; + upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; #endif /* UIP_CONF_IPV6 */ /* First sum pseudoheader. */ @@ -342,17 +333,17 @@ /* 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 = chksum(sum, (uint8_t *)&BUF->srcipaddr, 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); + return (sum == 0) ? 0xffff : uip_htons(sum); } /*---------------------------------------------------------------------------*/ #if UIP_CONF_IPV6 -u16_t +uint16_t uip_icmp6chksum(void) { return upper_layer_chksum(UIP_PROTO_ICMP6); @@ -360,14 +351,14 @@ } #endif /* UIP_CONF_IPV6 */ /*---------------------------------------------------------------------------*/ -u16_t +uint16_t uip_tcpchksum(void) { return upper_layer_chksum(UIP_PROTO_TCP); } /*---------------------------------------------------------------------------*/ #if UIP_UDP_CHECKSUMS -u16_t +uint16_t uip_udpchksum(void) { return upper_layer_chksum(UIP_PROTO_UDP); @@ -384,9 +375,9 @@ for(c = 0; c < UIP_CONNS; ++c) { uip_conns[c].tcpstateflags = UIP_CLOSED; } -#if UIP_ACTIVE_OPEN +#if UIP_ACTIVE_OPEN || UIP_UDP lastport = 1024; -#endif /* UIP_ACTIVE_OPEN */ +#endif /* UIP_ACTIVE_OPEN || UIP_UDP */ #if UIP_UDP for(c = 0; c < UIP_UDP_CONNS; ++c) { @@ -404,7 +395,7 @@ /*---------------------------------------------------------------------------*/ #if UIP_ACTIVE_OPEN struct uip_conn * -uip_connect(uip_ipaddr_t *ripaddr, u16_t rport) +uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport) { register struct uip_conn *conn, *cconn; @@ -421,7 +412,7 @@ for(c = 0; c < UIP_CONNS; ++c) { conn = &uip_conns[c]; if(conn->tcpstateflags != UIP_CLOSED && - conn->lport == htons(lastport)) { + conn->lport == uip_htons(lastport)) { goto again; } } @@ -460,7 +451,7 @@ conn->rto = UIP_RTO; conn->sa = 0; conn->sv = 16; /* Initial value of the RTT variance. */ - conn->lport = htons(lastport); + conn->lport = uip_htons(lastport); conn->rport = rport; uip_ipaddr_copy(&conn->ripaddr, ripaddr); @@ -470,7 +461,7 @@ /*---------------------------------------------------------------------------*/ #if UIP_UDP struct uip_udp_conn * -uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) +uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport) { register struct uip_udp_conn *conn; @@ -483,7 +474,7 @@ } for(c = 0; c < UIP_UDP_CONNS; ++c) { - if(uip_udp_conns[c].lport == htons(lastport)) { + if(uip_udp_conns[c].lport == uip_htons(lastport)) { goto again; } } @@ -501,10 +492,10 @@ return 0; } - conn->lport = HTONS(lastport); + conn->lport = UIP_HTONS(lastport); conn->rport = rport; if(ripaddr == NULL) { - memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t)); + memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t)); } else { uip_ipaddr_copy(&conn->ripaddr, ripaddr); } @@ -515,7 +506,7 @@ #endif /* UIP_UDP */ /*---------------------------------------------------------------------------*/ void -uip_unlisten(u16_t port) +uip_unlisten(uint16_t port) { for(c = 0; c < UIP_LISTENPORTS; ++c) { if(uip_listenports[c] == port) { @@ -526,7 +517,7 @@ } /*---------------------------------------------------------------------------*/ void -uip_listen(u16_t port) +uip_listen(uint16_t port) { for(c = 0; c < UIP_LISTENPORTS; ++c) { if(uip_listenports[c] == 0) { @@ -540,22 +531,22 @@ #if UIP_REASSEMBLY && !UIP_CONF_IPV6 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) -static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; -static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; -static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, +static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE]; +static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; +static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01}; -static u16_t uip_reasslen; -static u8_t uip_reassflags; +static uint16_t uip_reasslen; +static uint8_t uip_reassflags; #define UIP_REASS_FLAG_LASTFRAG 0x01 -static u8_t uip_reasstmr; +static uint8_t uip_reasstmr; #define IP_MF 0x20 -static u8_t +static uint8_t uip_reass(void) { - u16_t offset, len; - u16_t i; + uint16_t offset, len; + uint16_t i; /* If ip_reasstmr is zero, no packet is present in the buffer, so we write the IP header of the fragment into the reassembly @@ -641,7 +632,7 @@ /* Check the last byte in the bitmap. It should contain just the right amount of bits. */ if(uip_reassbitmap[uip_reasslen / (8 * 8)] != - (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) { + (uint8_t)~bitmap_bits[uip_reasslen / 8 & 7]) { goto nullreturn; } @@ -669,7 +660,7 @@ #endif /* UIP_REASSEMBLY */ /*---------------------------------------------------------------------------*/ static void -uip_add_rcv_nxt(u16_t n) +uip_add_rcv_nxt(uint16_t n) { uip_add32(uip_conn->rcv_nxt, n); uip_conn->rcv_nxt[0] = uip_acc32[0]; @@ -679,7 +670,7 @@ } /*---------------------------------------------------------------------------*/ void -uip_process(u8_t flag) +uip_process(uint8_t flag) { register struct uip_conn *uip_connr = uip_conn; @@ -699,6 +690,12 @@ uip_flags = UIP_POLL; UIP_APPCALL(); goto appsend; +#if UIP_ACTIVE_OPEN && UIP_TCP + } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) { + /* In the SYN_SENT state, we retransmit out SYN. */ + BUF->flags = 0; + goto tcp_send_syn; +#endif /* UIP_ACTIVE_OPEN */ } goto drop; @@ -722,6 +719,7 @@ uip_len = 0; uip_slen = 0; +#if UIP_TCP /* 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 @@ -736,6 +734,7 @@ /* 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 || @@ -806,6 +805,7 @@ goto appsend; } } +#endif goto drop; } #if UIP_UDP @@ -889,7 +889,7 @@ } #endif /* UIP_CONF_IPV6 */ - if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) { + if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) { /* If we are configured to use ping IP address configuration and hasn't been assigned an IP address yet, we accept all ICMP packets. */ @@ -909,16 +909,23 @@ #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*/) { + (uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) || + (BUF->destipaddr.u8[0] & 224) == 224)) { /* XXX this is a + hack to be able + to receive UDP + multicast + packets. We check + for the bit + pattern of the + multicast + prefix. */ 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)) { + if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) { UIP_STAT(++uip_stat.ip.drop); goto drop; } @@ -928,8 +935,8 @@ 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)) { + if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) && + BUF->destipaddr.u16[0] != UIP_HTONS(0xff02)) { UIP_STAT(++uip_stat.ip.drop); goto drop; } @@ -946,11 +953,13 @@ } #endif /* UIP_CONF_IPV6 */ +#if UIP_TCP if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, proceed with TCP input processing. */ goto tcp_input; } +#endif #if UIP_UDP if(BUF->proto == UIP_PROTO_UDP) { @@ -987,26 +996,26 @@ the destination IP address of this ping packet and assign it to ourself. */ #if UIP_PINGADDRCONF - if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) { - uip_hostaddr[0] = BUF->destipaddr[0]; - uip_hostaddr[1] = BUF->destipaddr[1]; + if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) { + uip_hostaddr = BUF->destipaddr; } #endif /* UIP_PINGADDRCONF */ ICMPBUF->type = ICMP_ECHO_REPLY; - if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) { - ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1; + if(ICMPBUF->icmpchksum >= UIP_HTONS(0xffff - (ICMP_ECHO << 8))) { + ICMPBUF->icmpchksum += UIP_HTONS(ICMP_ECHO << 8) + 1; } else { - ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8); + ICMPBUF->icmpchksum += UIP_HTONS(ICMP_ECHO << 8); } /* Swap IP addresses. */ - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); + uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); UIP_STAT(++uip_stat.icmp.sent); - goto send; + BUF->ttl = UIP_TTL; + goto ip_send_nolen; /* End of IPv4 input header processing code. */ #else /* !UIP_CONF_IPV6 */ @@ -1027,11 +1036,11 @@ /* If we get a neighbor solicitation for our address we should send a neighbor advertisement message back. */ if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { - if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) { + if(uip_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])); + uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); } /* We should now send a neighbor advertisement back to where the @@ -1041,13 +1050,14 @@ ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; - uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); - uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr); + 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)); + memcpy(&(ICMPBUF->options[2]), &uip_lladdr, sizeof(uip_lladdr)); ICMPBUF->icmpchksum = 0; ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + goto send; } @@ -1059,8 +1069,8 @@ ICMPBUF->type = ICMP6_ECHO_REPLY; - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); + uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); ICMPBUF->icmpchksum = 0; ICMPBUF->icmpchksum = ~uip_icmp6chksum(); @@ -1098,6 +1108,12 @@ uip_len = uip_len - UIP_IPUDPH_LEN; #endif /* UIP_UDP_CHECKSUMS */ + /* Make sure that the UDP destination port number is not zero. */ + if(UDPBUF->destport == 0) { + UIP_LOG("udp: zero port."); + goto drop; + } + /* 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]; @@ -1113,14 +1129,44 @@ UDPBUF->destport == uip_udp_conn->lport && (uip_udp_conn->rport == 0 || UDPBUF->srcport == uip_udp_conn->rport) && - (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))) { + (uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) || + uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) || + uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr))) { goto udp_found; } } UIP_LOG("udp: no matching connection found"); +#if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6 + /* Copy fields from packet header into payload of this ICMP packet. */ + memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8); + + /* Set the ICMP type and code. */ + ICMPBUF->type = ICMP_DEST_UNREACHABLE; + ICMPBUF->icode = ICMP_PORT_UNREACHABLE; + + /* Calculate the ICMP checksum. */ + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_chksum((uint16_t *)&(ICMPBUF->type), 36); + + /* Set the IP destination address to be the source address of the + original packet. */ + uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); + + /* Set our IP address as the source address. */ + uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); + + /* The size of the ICMP destination unreachable packet is 36 + the + size of the IP header (20) = 56. */ + uip_len = 36 + UIP_IPH_LEN; + ICMPBUF->len[0] = 0; + ICMPBUF->len[1] = (uint8_t)uip_len; + ICMPBUF->ttl = UIP_TTL; + ICMPBUF->proto = UIP_PROTO_ICMP; + + goto ip_send_nolen; +#else /* UIP_CONF_ICMP_DEST_UNREACH */ goto drop; +#endif /* UIP_CONF_ICMP_DEST_UNREACH */ udp_found: uip_conn = NULL; @@ -1128,6 +1174,7 @@ 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; @@ -1147,14 +1194,14 @@ BUF->ttl = uip_udp_conn->ttl; BUF->proto = UIP_PROTO_UDP; - UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN); + UDPBUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN); UDPBUF->udpchksum = 0; 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_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]; @@ -1170,6 +1217,7 @@ #endif /* UIP_UDP */ /* TCP input processing. */ +#if UIP_TCP tcp_input: UIP_STAT(++uip_stat.tcp.recv); @@ -1182,7 +1230,12 @@ UIP_LOG("tcp: bad checksum."); goto drop; } - + + /* Make sure that the TCP port number is not zero. */ + if(BUF->destport == 0 || BUF->srcport == 0) { + UIP_LOG("tcp: zero port."); + goto drop; + } /* Demultiplex this segment. */ /* First check any active connections. */ @@ -1191,7 +1244,7 @@ if(uip_connr->tcpstateflags != UIP_CLOSED && BUF->destport == uip_connr->lport && BUF->srcport == uip_connr->rport && - uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) { + uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->ripaddr)) { goto found; } } @@ -1207,14 +1260,15 @@ tmp16 = BUF->destport; /* Next, check listening connections. */ for(c = 0; c < UIP_LISTENPORTS; ++c) { - if(tmp16 == uip_listenports[c]) + if(tmp16 == uip_listenports[c]) { goto found_listen; + } } /* No matching connection found, so we send a RST packet. */ UIP_STAT(++uip_stat.tcp.synrst); + reset: - /* We do not send resets in response to resets. */ if(BUF->flags & TCP_RST) { goto drop; @@ -1260,8 +1314,8 @@ BUF->destport = tmp16; /* Swap IP addresses. */ - uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); + uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); /* And send out the RST packet! */ goto tcp_send_noconn; @@ -1307,7 +1361,7 @@ uip_connr->nrtx = 0; uip_connr->lport = BUF->destport; uip_connr->rport = BUF->srcport; - uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); + uip_ipaddr_copy(&uip_connr->ripaddr, &BUF->srcipaddr); uip_connr->tcpstateflags = UIP_SYN_RCVD; uip_connr->snd_nxt[0] = iss[0]; @@ -1336,8 +1390,8 @@ } 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[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; + tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | + (uint16_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; @@ -1393,7 +1447,7 @@ UIP_APPCALL(); goto drop; } - /* Calculated the length of the data, if the application has sent + /* Calculate 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 @@ -1403,9 +1457,13 @@ /* 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_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && - ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { + correct numbers in, unless we are in the SYN_RCVD state and + receive a SYN, in which case we should retransmit our SYNACK + (which is done futher down). */ + if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && + ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) || + (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) && + ((BUF->flags & TCP_CTL) == TCP_SYN)))) { 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] || @@ -1432,7 +1490,6 @@ uip_connr->snd_nxt[2] = uip_acc32[2]; uip_connr->snd_nxt[3] = uip_acc32[3]; - /* Do RTT estimation, unless we have done retransmissions. */ if(uip_connr->nrtx == 0) { signed char m; @@ -1482,6 +1539,10 @@ UIP_APPCALL(); goto appsend; } + /* We need to retransmit the SYNACK */ + if((BUF->flags & TCP_CTL) == TCP_SYN) { + goto tcp_send_synack; + } goto drop; #if UIP_ACTIVE_OPEN case UIP_SYN_SENT: @@ -1618,7 +1679,7 @@ and the application will retransmit it. This is called the "persistent timer" and uses the retransmission mechanim. */ - tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1]; + tmp16 = ((uint16_t)BUF->wnd[0] << 8) + (uint16_t)BUF->wnd[1]; if(tmp16 > uip_connr->initialmss || tmp16 == 0) { tmp16 = uip_connr->initialmss; @@ -1785,20 +1846,22 @@ } goto drop; - /* We jump here when we are ready to send the packet, and just want to set the appropriate TCP sequence numbers in the TCP header. */ tcp_send_ack: BUF->flags = TCP_ACK; + tcp_send_nodata: uip_len = UIP_IPTCPH_LEN; + tcp_send_noopts: 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 headers before calculating the checksum and finally send the packet. */ + tcp_send: BUF->ackno[0] = uip_connr->rcv_nxt[0]; BUF->ackno[1] = uip_connr->rcv_nxt[1]; BUF->ackno[2] = uip_connr->rcv_nxt[2]; @@ -1814,8 +1877,8 @@ BUF->srcport = uip_connr->lport; BUF->destport = uip_connr->rport; - uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); - uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr); + 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 @@ -1825,7 +1888,7 @@ BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); } - + tcp_send_noconn: BUF->ttl = UIP_TTL; #if UIP_CONF_IPV6 @@ -1843,9 +1906,9 @@ /* Calculate TCP checksum. */ BUF->tcpchksum = 0; BUF->tcpchksum = ~(uip_tcpchksum()); - +#endif + ip_send_nolen: - #if UIP_CONF_IPV6 BUF->vtc = 0x60; BUF->tcflow = 0x00; @@ -1861,10 +1924,11 @@ 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); +#if UIP_CONF_IPV6 + send: #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]); @@ -1872,26 +1936,39 @@ /* 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) +uint16_t +uip_htons(uint16_t val) { - return HTONS(val); + return UIP_HTONS(val); +} + +uint32_t +uip_htonl(uint32_t val) +{ + return UIP_HTONL(val); } /*---------------------------------------------------------------------------*/ void uip_send(const void *data, int len) { - if(len > 0) { - uip_slen = len; + int copylen; +#define MIN(a,b) ((a) < (b)? (a): (b)) + copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - + (int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN])); + if(copylen > 0) { + uip_slen = copylen; if(data != uip_sappdata) { memcpy(uip_sappdata, (data), uip_slen); } } } +/*---------------------------------------------------------------------------*/ /** @} */ +#endif /* UIP_CONF_IPV6 */
--- a/uip/uip.h Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uip.h Mon Jun 30 16:00:08 2014 +0000 @@ -7,7 +7,9 @@ /** * \file * Header file for the uIP TCP/IP stack. - * \author Adam Dunkels <adam@dunkels.com> + * \author Adam Dunkels <adam@dunkels.com> + * \author Julien Abeille <jabeille@cisco.com> (IPv6 related code) + * \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code) * * 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 @@ -15,7 +17,6 @@ * */ - /* * Copyright (c) 2001-2003, Adam Dunkels. * All rights reserved. @@ -46,7 +47,6 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $ * */ @@ -56,23 +56,73 @@ #include "uipopt.h" /** - * Repressentation of an IP address. + * Representation of an IP address. * */ -typedef u16_t uip_ip4addr_t[2]; -typedef u16_t uip_ip6addr_t[8]; +typedef union uip_ip4addr_t { + uint8_t u8[4]; /* Initializer, must come first. */ + uint16_t u16[2]; +} uip_ip4addr_t; + +typedef union uip_ip6addr_t { + uint8_t u8[16]; /* Initializer, must come first. */ + uint16_t u16[8]; +} uip_ip6addr_t; + #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 */ + +/*---------------------------------------------------------------------------*/ + +/** \brief 16 bit 802.15.4 address */ +typedef struct uip_802154_shortaddr { + uint8_t addr[2]; +} uip_802154_shortaddr; +/** \brief 64 bit 802.15.4 address */ +typedef struct uip_802154_longaddr { + uint8_t addr[8]; +} uip_802154_longaddr; + +/** \brief 802.11 address */ +typedef struct uip_80211_addr { + uint8_t addr[6]; +} uip_80211_addr; + +/** \brief 802.3 address */ +typedef struct uip_eth_addr { + uint8_t addr[6]; +} uip_eth_addr; + + +#if UIP_CONF_LL_802154 +/** \brief 802.15.4 address */ +typedef uip_802154_longaddr uip_lladdr_t; +#define UIP_802154_SHORTADDR_LEN 2 +#define UIP_802154_LONGADDR_LEN 8 +#define UIP_LLADDR_LEN UIP_802154_LONGADDR_LEN +#else /*UIP_CONF_LL_802154*/ +#if UIP_CONF_LL_80211 +/** \brief 802.11 address */ +typedef uip_80211_addr uip_lladdr_t; +#define UIP_LLADDR_LEN 6 +#else /*UIP_CONF_LL_80211*/ +/** \brief Ethernet address */ +typedef uip_eth_addr uip_lladdr_t; +#define UIP_LLADDR_LEN 6 +#endif /*UIP_CONF_LL_80211*/ +#endif /*UIP_CONF_LL_802154*/ + +//#include "tcpip.h" + /*---------------------------------------------------------------------------*/ /* First, the functions that should be called from the - * system. Initialization, the periodic timer and incoming packets are + * system. Initialization, the periodic timer, and incoming packets are * handled by the following three functions. */ - /** * \defgroup uipconffunc uIP configuration functions * @{ @@ -103,7 +153,7 @@ * * \hideinitializer */ -#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr)) +#define uip_sethostaddr(addr) uip_ipaddr_copy(&uip_hostaddr, (addr)) /** * Get the IP address of this host. @@ -123,7 +173,7 @@ * * \hideinitializer */ -#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr) +#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), &uip_hostaddr) /** * Set the default router's IP address. @@ -135,7 +185,7 @@ * * \hideinitializer */ -#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr)) +#define uip_setdraddr(addr) uip_ipaddr_copy(&uip_draddr, (addr)) /** * Set the netmask. @@ -147,7 +197,7 @@ * * \hideinitializer */ -#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr)) +#define uip_setnetmask(addr) uip_ipaddr_copy(&uip_netmask, (addr)) /** @@ -158,7 +208,7 @@ * * \hideinitializer */ -#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr) +#define uip_getdraddr(addr) uip_ipaddr_copy((addr), &uip_draddr) /** * Get the netmask. @@ -168,7 +218,7 @@ * * \hideinitializer */ -#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask) +#define uip_getnetmask(addr) uip_ipaddr_copy((addr), &uip_netmask) /** @} */ @@ -192,7 +242,7 @@ * * This function may be used at boot time to set the initial ip_id. */ -void uip_setipid(u16_t id); +void uip_setipid(uint16_t id); /** @} */ @@ -220,13 +270,13 @@ * The usual way of calling the function is presented by the source * code below. \code - uip_len = devicedriver_poll(); - if(uip_len > 0) { - uip_input(); - if(uip_len > 0) { - devicedriver_send(); - } - } + uip_len = devicedriver_poll(); + if(uip_len > 0) { + uip_input(); + if(uip_len > 0) { + devicedriver_send(); + } + } \endcode * * \note If you are writing a uIP device driver that needs ARP @@ -234,28 +284,29 @@ * Ethernet, you will need to call the uIP ARP code before calling * this function: \code - #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) - uip_len = ethernet_devicedrver_poll(); - if(uip_len > 0) { - if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { - uip_arp_ipin(); - uip_input(); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { - uip_arp_arpin(); - if(uip_len > 0) { - ethernet_devicedriver_send(); - } - } + #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + uip_len = ethernet_devicedrver_poll(); + if(uip_len > 0) { + if(BUF->type == UIP_HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } else if(BUF->type == UIP_HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if(uip_len > 0) { + ethernet_devicedriver_send(); + } + } \endcode * * \hideinitializer */ #define uip_input() uip_process(UIP_DATA) + /** * Periodic processing for a connection identified by its number. * @@ -269,15 +320,15 @@ * 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 + * The usual way of calling the function is through a for() loop like * this: \code - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - devicedriver_send(); - } - } + for(i = 0; i < UIP_CONNS; ++i) { + uip_periodic(i); + if(uip_len > 0) { + devicedriver_send(); + } + } \endcode * * \note If you are writing a uIP device driver that needs ARP @@ -285,21 +336,22 @@ * Ethernet, you will need to call the uip_arp_out() function before * calling the device driver: \code - for(i = 0; i < UIP_CONNS; ++i) { - uip_periodic(i); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } + for(i = 0; i < UIP_CONNS; ++i) { + uip_periodic(i); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } \endcode * * \param conn The number of the connection which is to be periodically polled. * * \hideinitializer */ -#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \ - uip_process(UIP_TIMER); } while (0) +#if UIP_TCP +#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \ + uip_process(UIP_TIMER); } while (0) /** * @@ -320,11 +372,11 @@ * * \hideinitializer */ -#define uip_periodic_conn(conn) do { uip_conn = conn; \ - uip_process(UIP_TIMER); } while (0) +#define uip_periodic_conn(conn) do { uip_conn = conn; \ + uip_process(UIP_TIMER); } while (0) /** - * Reuqest that a particular connection should be polled. + * Request 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. @@ -334,9 +386,10 @@ * * \hideinitializer */ -#define uip_poll_conn(conn) do { uip_conn = conn; \ - uip_process(UIP_POLL_REQUEST); } while (0) +#define uip_poll_conn(conn) do { uip_conn = conn; \ + uip_process(UIP_POLL_REQUEST); } while (0) +#endif /* UIP_TCP */ #if UIP_UDP /** @@ -346,24 +399,24 @@ * UDP connections. It is called in a similar fashion as the * uip_periodic() function: \code - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - devicedriver_send(); - } - } + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + devicedriver_send(); + } + } \endcode * * \note As for the uip_periodic() function, special care has to be * taken when using uIP together with ARP and Ethernet: \code - for(i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - if(uip_len > 0) { - uip_arp_out(); - ethernet_devicedriver_send(); - } - } + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } \endcode * * \param conn The number of the UDP connection to be processed. @@ -371,7 +424,7 @@ * \hideinitializer */ #define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \ - uip_process(UIP_UDP_TIMER); } while (0) + uip_process(UIP_UDP_TIMER); } while(0) /** * Periodic processing for a UDP connection identified by a pointer to @@ -387,11 +440,12 @@ * * \hideinitializer */ -#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \ - uip_process(UIP_UDP_TIMER); } while (0) +#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \ + uip_process(UIP_UDP_TIMER); } while(0) +#endif /* UIP_UDP */ - -#endif /* UIP_UDP */ +/** \brief Abandon the reassembly of the current packet */ +void uip_reass_over(void); /** * The uIP packet buffer. @@ -409,17 +463,25 @@ 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); - } + 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); + } } \endcode - */ -extern u8_t uip_buf[UIP_BUFSIZE+2]; +*/ + +typedef union { + uint32_t u32[(UIP_BUFSIZE + 3) / 4]; + uint8_t u8[UIP_BUFSIZE]; +} uip_buf_t; + +CCIF extern uip_buf_t uip_aligned_buf; +#define uip_buf (uip_aligned_buf.u8) + /** @} */ @@ -427,7 +489,7 @@ /* Functions that are used by the uIP application program. Opening and * closing connections, sending and receiving data, etc. is all * handled by the functions below. -*/ + */ /** * \defgroup uipappfunc uIP application functions * @{ @@ -439,55 +501,55 @@ * 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. + * order, a conversion using UIP_HTONS() or uip_htons() is necessary. * \code - uip_listen(HTONS(80)); + uip_listen(UIP_HTONS(80)); \endcode * * \param port A 16-bit port number in network byte order. */ -void uip_listen(u16_t port); +void uip_listen(uint16_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. + * order, a conversion using UIP_HTONS() or uip_htons() is necessary. * \code - uip_unlisten(HTONS(80)); + uip_unlisten(UIP_HTONS(80)); \endcode * * \param port A 16-bit port number in network byte order. */ -void uip_unlisten(u16_t port); +void uip_unlisten(uint16_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, + * port on the specified 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 + * \note This function is available only if support for active open * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h. * * \note Since this function requires the port number to be in network - * byte order, a conversion using HTONS() or htons() is necessary. + * byte order, a conversion using UIP_HTONS() or uip_htons() is necessary. * \code uip_ipaddr_t ipaddr; uip_ipaddr(&ipaddr, 192,168,1,2); - uip_connect(&ipaddr, HTONS(80)); + uip_connect(&ipaddr, UIP_HTONS(80)); \endcode * - * \param ripaddr The IP address of the remote hot. + * \param ripaddr The IP address of the remote host. * * \param port A 16-bit port number in network byte order. * @@ -495,7 +557,7 @@ * or NULL if no connection could be allocated. * */ -struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port); +struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, uint16_t port); @@ -518,7 +580,7 @@ * 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 + * function 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. @@ -535,10 +597,10 @@ * * \hideinitializer */ -void uip_send(const void *data, int len); +CCIF void uip_send(const void *data, int len); /** - * The length of any incoming data that is currently avaliable (if avaliable) + * The length of any incoming data that is currently available (if available) * in the uip_appdata buffer. * * The test function uip_data() must first be used to check if there @@ -573,7 +635,7 @@ * 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 + * usually used when an error has occurred that prevents using the * uip_close() function. * * \hideinitializer @@ -607,9 +669,9 @@ * * \hideinitializer */ -#define uip_restart() do { uip_flags |= UIP_NEWDATA; \ - uip_conn->tcpstateflags &= ~UIP_STOPPED; \ - } while(0) +#define uip_restart() do { uip_flags |= UIP_NEWDATA; \ + uip_conn->tcpstateflags &= ~UIP_STOPPED; \ + } while(0) /* uIP tests that can be made to determine in what state the current @@ -630,7 +692,7 @@ * * 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. + * available through the uip_len variable. * * \hideinitializer */ @@ -716,7 +778,7 @@ #define uip_poll() (uip_flags & UIP_POLL) /** - * Get the initial maxium segment size (MSS) of the current + * Get the initial maximum segment size (MSS) of the current * connection. * * \hideinitializer @@ -724,10 +786,10 @@ #define uip_initialmss() (uip_conn->initialmss) /** - * Get the current maxium segment size that can be sent on the current + * Get the current maximum segment size that can be sent on the current * connection. * - * The current maxiumum segment size that can be sent on the + * The current maximum 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()). @@ -751,22 +813,22 @@ struct uip_udp_conn *c; uip_ipaddr(&addr, 192,168,2,1); - c = uip_udp_new(&addr, HTONS(12345)); + c = uip_udp_new(&addr, UIP_HTONS(12345)); if(c != NULL) { - uip_udp_bind(c, HTONS(12344)); + uip_udp_bind(c, UIP_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 + * \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(uip_ipaddr_t *ripaddr, u16_t rport); +struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport); /** - * Removed a UDP connection. + * Remove a UDP connection. * * \param conn A pointer to the uip_udp_conn structure for the connection. * @@ -812,6 +874,20 @@ */ /** + * Convert an IP address to four bytes separated by commas. + * + * Example: + \code + uip_ipaddr_t ipaddr; + printf("ipaddr=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&ipaddr)); + \endcode + * + * \param a A pointer to a uip_ipaddr_t. + * \hideinitializer + */ +#define uip_ipaddr_to_quad(a) (a)->u8[0],(a)->u8[1],(a)->u8[2],(a)->u8[3] + +/** * Construct an IP address from four bytes. * * This function constructs an IP address of the type that uIP handles @@ -824,7 +900,7 @@ struct uip_conn *c; uip_ipaddr(&ipaddr, 192,168,1,2); - c = uip_connect(&ipaddr, HTONS(80)); + c = uip_connect(&ipaddr, UIP_HTONS(80)); \endcode * * \param addr A pointer to a uip_ipaddr_t variable that will be @@ -837,10 +913,12 @@ * * \hideinitializer */ -#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ - ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \ - ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \ - } while(0) +#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ + (addr)->u8[0] = addr0; \ + (addr)->u8[1] = addr1; \ + (addr)->u8[2] = addr2; \ + (addr)->u8[3] = addr3; \ + } while(0) /** * Construct an IPv6 address from eight 16-bit words. @@ -850,18 +928,45 @@ * \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) + (addr)->u16[0] = UIP_HTONS(addr0); \ + (addr)->u16[1] = UIP_HTONS(addr1); \ + (addr)->u16[2] = UIP_HTONS(addr2); \ + (addr)->u16[3] = UIP_HTONS(addr3); \ + (addr)->u16[4] = UIP_HTONS(addr4); \ + (addr)->u16[5] = UIP_HTONS(addr5); \ + (addr)->u16[6] = UIP_HTONS(addr6); \ + (addr)->u16[7] = UIP_HTONS(addr7); \ + } while(0) /** - * Copy an IP address to another IP address. + * Construct an IPv6 address from sixteen 8-bit words. + * + * This function constructs an IPv6 address. + * + * \hideinitializer + */ +#define uip_ip6addr_u8(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7,addr8,addr9,addr10,addr11,addr12,addr13,addr14,addr15) do { \ + (addr)->u8[0] = addr0; \ + (addr)->u8[1] = addr1; \ + (addr)->u8[2] = addr2; \ + (addr)->u8[3] = addr3; \ + (addr)->u8[4] = addr4; \ + (addr)->u8[5] = addr5; \ + (addr)->u8[6] = addr6; \ + (addr)->u8[7] = addr7; \ + (addr)->u8[8] = addr8; \ + (addr)->u8[9] = addr9; \ + (addr)->u8[10] = addr10; \ + (addr)->u8[11] = addr11; \ + (addr)->u8[12] = addr12; \ + (addr)->u8[13] = addr13; \ + (addr)->u8[14] = addr14; \ + (addr)->u8[15] = addr15; \ + } while(0) + + +/** + * Copy an IP address from one place to another. * * Copies an IP address from one place to another. * @@ -878,14 +983,15 @@ * * \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 */ +#ifndef uip_ipaddr_copy +#define uip_ipaddr_copy(dest, src) (*(dest) = *(src)) +#endif +#ifndef uip_ip4addr_copy +#define uip_ip4addr_copy(dest, src) (*(dest) = *(src)) +#endif +#ifndef uip_ip6addr_copy +#define uip_ip6addr_copy(dest, src) (*(dest) = *(src)) +#endif /** * Compare two IP addresses @@ -898,7 +1004,7 @@ uip_ipaddr(&ipaddr1, 192,16,1,2); if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { - printf("They are the same"); + printf("They are the same"); } \endcode * @@ -907,12 +1013,15 @@ * * \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 */ +#define uip_ip4addr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \ + (addr1)->u16[1] == (addr2)->u16[1]) +#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) + +#if UIP_CONF_IPV6 +#define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2) +#else /* UIP_CONF_IPV6 */ +#define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2) +#endif /* UIP_CONF_IPV6 */ /** * Compare two IP addresses with netmasks @@ -928,7 +1037,7 @@ 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"); + printf("They are the same"); } \endcode * @@ -938,11 +1047,33 @@ * * \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]))) + +#define uip_ipaddr_maskcmp(addr1, addr2, mask) \ + (((((uint16_t *)addr1)[0] & ((uint16_t *)mask)[0]) == \ + (((uint16_t *)addr2)[0] & ((uint16_t *)mask)[0])) && \ + ((((uint16_t *)addr1)[1] & ((uint16_t *)mask)[1]) == \ + (((uint16_t *)addr2)[1] & ((uint16_t *)mask)[1]))) + +#define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0) + + + +/** + * Check if an address is a broadcast address for a network. + * + * Checks if an address is the broadcast address for a network. The + * network is defined by an IP address that is on the network and the + * network's netmask. + * + * \param addr The IP address. + * \param netaddr The network's IP address. + * \param netmask The network's netmask. + * + * \hideinitializer + */ +/*#define uip_ipaddr_isbroadcast(addr, netaddr, netmask) + ((uip_ipaddr_t *)(addr)).u16 & ((uip_ipaddr_t *)(addr)).u16*/ + /** @@ -969,10 +1100,10 @@ * * \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) +#define uip_ipaddr_mask(dest, src, mask) do { \ + ((uint16_t *)dest)[0] = ((uint16_t *)src)[0] & ((uint16_t *)mask)[0]; \ + ((uint16_t *)dest)[1] = ((uint16_t *)src)[1] & ((uint16_t *)mask)[1]; \ + } while(0) /** * Pick the first octet of an IP address. @@ -982,7 +1113,7 @@ * Example: \code uip_ipaddr_t ipaddr; - u8_t octet; + uint8_t octet; uip_ipaddr(&ipaddr, 1,2,3,4); octet = uip_ipaddr1(&ipaddr); @@ -992,7 +1123,7 @@ * * \hideinitializer */ -#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8) +#define uip_ipaddr1(addr) ((addr)->u8[0]) /** * Pick the second octet of an IP address. @@ -1002,7 +1133,7 @@ * Example: \code uip_ipaddr_t ipaddr; - u8_t octet; + uint8_t octet; uip_ipaddr(&ipaddr, 1,2,3,4); octet = uip_ipaddr2(&ipaddr); @@ -1012,7 +1143,7 @@ * * \hideinitializer */ -#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff) +#define uip_ipaddr2(addr) ((addr)->u8[1]) /** * Pick the third octet of an IP address. @@ -1022,7 +1153,7 @@ * Example: \code uip_ipaddr_t ipaddr; - u8_t octet; + uint8_t octet; uip_ipaddr(&ipaddr, 1,2,3,4); octet = uip_ipaddr3(&ipaddr); @@ -1032,7 +1163,7 @@ * * \hideinitializer */ -#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8) +#define uip_ipaddr3(addr) ((addr)->u8[2]) /** * Pick the fourth octet of an IP address. @@ -1042,7 +1173,7 @@ * Example: \code uip_ipaddr_t ipaddr; - u8_t octet; + uint8_t octet; uip_ipaddr(&ipaddr, 1,2,3,4); octet = uip_ipaddr4(&ipaddr); @@ -1052,39 +1183,48 @@ * * \hideinitializer */ -#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff) +#define uip_ipaddr4(addr) ((addr)->u8[3]) /** * 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. + * network byte order, use the uip_htons() function instead. * * \hideinitializer */ -#ifndef HTONS +#ifndef UIP_HTONS # if UIP_BYTE_ORDER == UIP_BIG_ENDIAN -# define HTONS(n) (n) +# define UIP_HTONS(n) (n) +# define UIP_HTONL(n) (n) # else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ -# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) +# define UIP_HTONS(n) (uint16_t)((((uint16_t) (n)) << 8) | (((uint16_t) (n)) >> 8)) +# define UIP_HTONL(n) (((uint32_t)UIP_HTONS(n) << 16) | UIP_HTONS((uint32_t)(n) >> 16)) # endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ #else -#error "HTONS already defined!" -#endif /* HTONS */ +#error "UIP_HTONS already defined!" +#endif /* UIP_HTONS */ /** - * Convert 16-bit quantity from host byte order to network byte order. + * Convert a 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. + * network byte order, use the UIP_HTONS() macro instead. */ -#ifndef htons -u16_t htons(u16_t val); -#endif /* htons */ -#ifndef ntohs -#define ntohs htons +#ifndef uip_htons +CCIF uint16_t uip_htons(uint16_t val); +#endif /* uip_htons */ +#ifndef uip_ntohs +#define uip_ntohs uip_htons +#endif + +#ifndef uip_htonl +CCIF uint32_t uip_htonl(uint32_t val); +#endif /* uip_htonl */ +#ifndef uip_ntohl +#define uip_ntohl uip_htonl #endif /** @} */ @@ -1096,10 +1236,10 @@ * called. If the application wishes to send data, the application may * use this space to write the data into before calling uip_send(). */ -extern void *uip_appdata; +CCIF extern void *uip_appdata; #if UIP_URGDATA > 0 -/* u8_t *uip_urgdata: +/* uint8_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). @@ -1131,12 +1271,16 @@ * packet. * */ -extern u16_t uip_len; +CCIF extern uint16_t uip_len; +/** + * The length of the extension headers + */ +extern uint8_t uip_ext_len; /** @} */ #if UIP_URGDATA > 0 -extern u16_t uip_urglen, uip_surglen; +extern uint16_t uip_urglen, uip_surglen; #endif /* UIP_URGDATA > 0 */ @@ -1145,7 +1289,7 @@ * * 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 + * application. The only exception is the appstate field whose 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. @@ -1153,27 +1297,27 @@ struct uip_conn { 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 + uint16_t lport; /**< The local TCP port, in network byte order. */ + uint16_t rport; /**< The local remote TCP port, in network byte order. */ - u8_t rcv_nxt[4]; /**< The sequence number that we expect to + uint8_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 + uint8_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 + uint16_t len; /**< Length of the data that was previously sent. */ + uint16_t mss; /**< Current maximum segment size for the connection. */ - u16_t initialmss; /**< Initial maximum segment size for the + uint16_t initialmss; /**< Initial maximum segment size for the connection. */ - u8_t sa; /**< Retransmission time-out calculation state + uint8_t sa; /**< Retransmission time-out calculation state variable. */ - u8_t sv; /**< Retransmission time-out calculation state + uint8_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 + uint8_t rto; /**< Retransmission time-out. */ + uint8_t tcpstateflags; /**< TCP state and flags. */ + uint8_t timer; /**< The retransmission timer. */ + uint8_t nrtx; /**< The number of retransmissions for the last segment sent. */ /** The application state. */ @@ -1187,9 +1331,13 @@ * The uip_conn pointer can be used to access the current TCP * connection. */ -extern struct uip_conn *uip_conn; + +CCIF extern struct uip_conn *uip_conn; +#if UIP_TCP /* The array containing all uIP connections. */ -extern struct uip_conn uip_conns[UIP_CONNS]; +CCIF extern struct uip_conn uip_conns[UIP_CONNS]; +#endif + /** * \addtogroup uiparch * @{ @@ -1198,8 +1346,7 @@ /** * 4-byte array used for the 32-bit sequence number calculations. */ -extern u8_t uip_acc32[4]; - +extern uint8_t uip_acc32[4]; /** @} */ @@ -1209,9 +1356,9 @@ */ struct uip_udp_conn { 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. */ + uint16_t lport; /**< The local port number in network byte order. */ + uint16_t rport; /**< The remote port number in network byte order. */ + uint8_t ttl; /**< Default time-to-live. */ /** The application state. */ uip_udp_appstate_t appstate; @@ -1224,6 +1371,30 @@ extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; #endif /* UIP_UDP */ +struct uip_fallback_interface { + void (*init)(void); + void (*output)(void); +}; + +#if UIP_CONF_ICMP6 +struct uip_icmp6_conn { + uip_icmp6_appstate_t appstate; +}; +extern struct uip_icmp6_conn uip_icmp6_conns; +#endif /*UIP_CONF_ICMP6*/ + +/** + * The uIP TCP/IP statistics. + * + * This is the variable in which the uIP TCP/IP statistics are gathered. + */ +#if UIP_STATISTICS == 1 +extern struct uip_stats uip_stat; +#define UIP_STAT(s) s +#else +#define UIP_STAT(s) +#endif /* UIP_STATISTICS == 1 */ + /** * The structure holding the TCP/IP statistics that are gathered if * UIP_STATISTICS is set to 1. @@ -1231,47 +1402,53 @@ */ struct uip_stats { struct { - uip_stats_t drop; /**< Number of dropped packets at the IP - layer. */ uip_stats_t recv; /**< Number of received packets at the IP layer. */ uip_stats_t sent; /**< Number of sent packets at the IP layer. */ + uip_stats_t forwarded;/**< Number of forwarded packets at the IP + layer. */ + uip_stats_t drop; /**< Number of dropped 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 + uip_stats_t fragerr; /**< Number of packets dropped because 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 + uip_stats_t protoerr; /**< Number of packets dropped because 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 drop; /**< Number of dropped ICMP packets. */ uip_stats_t typeerr; /**< Number of ICMP packets with a wrong type. */ + uip_stats_t chkerr; /**< Number of ICMP packets with a bad + checksum. */ } icmp; /**< ICMP statistics. */ +#if UIP_TCP 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 drop; /**< Number of dropped 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 rst; /**< Number of received 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 syndrop; /**< Number of dropped SYNs because too few + connections were available. */ uip_stats_t synrst; /**< Number of SYNs for closed ports, triggering a RST. */ } tcp; /**< TCP statistics. */ +#endif #if UIP_UDP struct { uip_stats_t drop; /**< Number of dropped UDP segments. */ @@ -1281,33 +1458,36 @@ checksum. */ } udp; /**< UDP statistics. */ #endif /* UIP_UDP */ +#if UIP_CONF_IPV6 + struct { + uip_stats_t drop; /**< Number of dropped ND6 packets. */ + uip_stats_t recv; /**< Number of recived ND6 packets */ + uip_stats_t sent; /**< Number of sent ND6 packets */ + } nd6; +#endif /*UIP_CONF_IPV6*/ }; -/** - * The uIP TCP/IP statistics. - * - * This is the variable in which the uIP TCP/IP statistics are gathered. - */ -extern struct uip_stats uip_stat; - /*---------------------------------------------------------------------------*/ /* All the stuff below this point is internal to uIP and should not be * used directly by an application or by a device driver. */ /*---------------------------------------------------------------------------*/ -/* u8_t uip_flags: + + + +/* uint8_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. + * information. */ -extern u8_t uip_flags; +CCIF extern uint8_t uip_flags; /* The following flags may be set in the global variable uip_flags 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 + whereas the others are mutually exclusive. Note that these flags should *NOT* be accessed directly, but only through the uIP functions/macros. */ @@ -1340,18 +1520,28 @@ #define UIP_TIMEDOUT 128 /* The connection has been aborted due to too many retransmissions. */ + +/** + * \brief process the options within a hop by hop or destination option header + * \retval 0: nothing to send, + * \retval 1: drop pkt + * \retval 2: ICMP error message to send +*/ +/*static uint8_t +uip_ext_hdr_options_process(); */ + /* uip_process(flag): * * The actual uIP function which does all the work. */ -void uip_process(u8_t flag); - -/* The following flags are passed as an argument to the uip_process() +void uip_process(uint8_t flag); + + /* The following flags are passed as an argument to the uip_process() function. They are used to distinguish between the two cases where uip_process() is called. It can be called either because we have incoming data that should be processed, or because the periodic timer has fired. These values are never used directly, but only in - the macrose defined in this file. */ + the macros defined in this file. */ #define UIP_DATA 1 /* Tells uIP that there is incoming data in the uip_buf buffer. The @@ -1386,72 +1576,67 @@ struct uip_tcpip_hdr { #if UIP_CONF_IPV6 /* IPv6 header. */ - u8_t vtc, + uint8_t vtc, tcflow; - u16_t flow; - u8_t len[2]; - u8_t proto, ttl; + uint16_t flow; + uint8_t len[2]; + uint8_t proto, ttl; uip_ip6addr_t srcipaddr, destipaddr; #else /* UIP_CONF_IPV6 */ /* IPv4 header. */ - u8_t vhl, + uint8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uint16_t ipchksum; + uip_ipaddr_t srcipaddr, destipaddr; #endif /* UIP_CONF_IPV6 */ /* TCP header. */ - u16_t srcport, + uint16_t srcport, destport; - u8_t seqno[4], + uint8_t seqno[4], ackno[4], tcpoffset, flags, wnd[2]; - u16_t tcpchksum; - u8_t urgp[2]; - u8_t optdata[4]; + uint16_t tcpchksum; + uint8_t urgp[2]; + uint8_t optdata[4]; }; /* The ICMP and IP headers. */ struct uip_icmpip_hdr { #if UIP_CONF_IPV6 /* IPv6 header. */ - u8_t vtc, + uint8_t vtc, tcf; - u16_t flow; - u8_t len[2]; - u8_t proto, ttl; + uint16_t flow; + uint8_t len[2]; + uint8_t proto, ttl; uip_ip6addr_t srcipaddr, destipaddr; #else /* UIP_CONF_IPV6 */ /* IPv4 header. */ - u8_t vhl, + uint8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uint16_t ipchksum; + uip_ipaddr_t srcipaddr, destipaddr; #endif /* UIP_CONF_IPV6 */ - /* ICMP (echo) header. */ - u8_t type, icode; - u16_t icmpchksum; + /* ICMP header. */ + uint8_t type, icode; + uint16_t icmpchksum; #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]; + uint16_t id, seqno; + uint8_t payload[1]; #endif /* !UIP_CONF_IPV6 */ }; @@ -1460,34 +1645,181 @@ struct uip_udpip_hdr { #if UIP_CONF_IPV6 /* IPv6 header. */ - u8_t vtc, + uint8_t vtc, tcf; - u16_t flow; - u8_t len[2]; - u8_t proto, ttl; + uint16_t flow; + uint8_t len[2]; + uint8_t proto, ttl; uip_ip6addr_t srcipaddr, destipaddr; #else /* UIP_CONF_IPV6 */ /* IP header. */ - u8_t vhl, + uint8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + uint16_t ipchksum; + uip_ipaddr_t srcipaddr, destipaddr; +#endif /* UIP_CONF_IPV6 */ + + /* UDP header. */ + uint16_t srcport, + destport; + uint16_t udplen; + uint16_t udpchksum; +}; + +/* + * In IPv6 the length of the L3 headers before the transport header is + * not fixed, due to the possibility to include extension option headers + * after the IP header. hence we split here L3 and L4 headers + */ +/* The IP header */ +struct uip_ip_hdr { +#if UIP_CONF_IPV6 + /* IPV6 header */ + uint8_t vtc; + uint8_t tcflow; + uint16_t flow; + uint8_t len[2]; + uint8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IPV4 header */ + uint8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uint16_t ipchksum; + uip_ipaddr_t srcipaddr, destipaddr; #endif /* UIP_CONF_IPV6 */ - - /* UDP header. */ - u16_t srcport, - destport; - u16_t udplen; - u16_t udpchksum; }; +/* + * IPv6 extension option headers: we are able to process + * the 4 extension headers defined in RFC2460 (IPv6): + * - Hop by hop option header, destination option header: + * These two are not used by any core IPv6 protocol, hence + * we just read them and go to the next. They convey options, + * the options defined in RFC2460 are Pad1 and PadN, which do + * some padding, and that we do not need to read (the length + * field in the header is enough) + * - Routing header: this one is most notably used by MIPv6, + * which we do not implement, hence we just read it and go + * to the next + * - Fragmentation header: we read this header and are able to + * reassemble packets + * + * We do not offer any means to send packets with extension headers + * + * We do not implement Authentication and ESP headers, which are + * used in IPSec and defined in RFC4302,4303,4305,4385 + */ +/* common header part */ +typedef struct uip_ext_hdr { + uint8_t next; + uint8_t len; +} uip_ext_hdr; + +/* Hop by Hop option header */ +typedef struct uip_hbho_hdr { + uint8_t next; + uint8_t len; +} uip_hbho_hdr; + +/* destination option header */ +typedef struct uip_desto_hdr { + uint8_t next; + uint8_t len; +} uip_desto_hdr; + +/* We do not define structures for PAD1 and PADN options */ + +/* + * routing header + * the routing header as 4 common bytes, then routing header type + * specific data there are several types of routing header. Type 0 was + * deprecated as per RFC5095 most notable other type is 2, used in + * RFC3775 (MIPv6) here we do not implement MIPv6, so we just need to + * parse the 4 first bytes + */ +typedef struct uip_routing_hdr { + uint8_t next; + uint8_t len; + uint8_t routing_type; + uint8_t seg_left; +} uip_routing_hdr; + +/* fragmentation header */ +typedef struct uip_frag_hdr { + uint8_t next; + uint8_t res; + uint16_t offsetresmore; + uint32_t id; +} uip_frag_hdr; + +/* + * an option within the destination or hop by hop option headers + * it contains type an length, which is true for all options but PAD1 + */ +typedef struct uip_ext_hdr_opt { + uint8_t type; + uint8_t len; +} uip_ext_hdr_opt; + +/* PADN option */ +typedef struct uip_ext_hdr_opt_padn { + uint8_t opt_type; + uint8_t opt_len; +} uip_ext_hdr_opt_padn; + +/* RPL option */ +typedef struct uip_ext_hdr_opt_rpl { + uint8_t opt_type; + uint8_t opt_len; + uint8_t flags; + uint8_t instance; + uint16_t senderrank; +} uip_ext_hdr_opt_rpl; + +/* TCP header */ +struct uip_tcp_hdr { + uint16_t srcport; + uint16_t destport; + uint8_t seqno[4]; + uint8_t ackno[4]; + uint8_t tcpoffset; + uint8_t flags; + uint8_t wnd[2]; + uint16_t tcpchksum; + uint8_t urgp[2]; + uint8_t optdata[4]; +}; + +/* The ICMP headers. */ +struct uip_icmp_hdr { + uint8_t type, icode; + uint16_t icmpchksum; +#if !UIP_CONF_IPV6 + uint16_t id, seqno; +#endif /* !UIP_CONF_IPV6 */ +}; + + +/* The UDP headers. */ +struct uip_udp_hdr { + uint16_t srcport; + uint16_t destport; + uint16_t udplen; + uint16_t udpchksum; +}; + /** * The buffer size available for user data in the \ref uip_buf buffer. @@ -1504,44 +1836,306 @@ * \hideinitializer */ #define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) - +#define UIP_APPDATA_PTR (void *)&uip_buf[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 + +#if UIP_CONF_IPV6 +/** @{ */ +/** \brief extension headers types */ +#define UIP_PROTO_HBHO 0 +#define UIP_PROTO_DESTO 60 +#define UIP_PROTO_ROUTING 43 +#define UIP_PROTO_FRAG 44 +#define UIP_PROTO_NONE 59 +/** @} */ + +/** @{ */ +/** \brief Destination and Hop By Hop extension headers option types */ +#define UIP_EXT_HDR_OPT_PAD1 0 +#define UIP_EXT_HDR_OPT_PADN 1 +#define UIP_EXT_HDR_OPT_RPL 0x63 + +/** @} */ + +/** @{ */ +/** + * \brief Bitmaps for extension header processing + * + * When processing extension headers, we should record somehow which one we + * see, because you cannot have twice the same header, except for destination + * We store all this in one uint8_t bitmap one bit for each header expected. The + * order in the bitmap is the order recommended in RFC2460 + */ +#define UIP_EXT_HDR_BITMAP_HBHO 0x01 +#define UIP_EXT_HDR_BITMAP_DESTO1 0x02 +#define UIP_EXT_HDR_BITMAP_ROUTING 0x04 +#define UIP_EXT_HDR_BITMAP_FRAG 0x08 +#define UIP_EXT_HDR_BITMAP_AH 0x10 +#define UIP_EXT_HDR_BITMAP_ESP 0x20 +#define UIP_EXT_HDR_BITMAP_DESTO2 0x40 +/** @} */ + + +#endif /* UIP_CONF_IPV6 */ + + /* Header sizes. */ #if UIP_CONF_IPV6 #define UIP_IPH_LEN 40 +#define UIP_FRAGH_LEN 8 #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 */ +#ifdef UIP_IPH_LEN +#define UIP_ICMPH_LEN 4 /* Size of ICMP header */ +#endif #define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + - UDP - header */ + * UDP + * header */ #define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + - TCP - header */ + * TCP + * header */ #define UIP_TCPIP_HLEN UIP_IPTCPH_LEN +#define UIP_IPICMPH_LEN (UIP_IPH_LEN + UIP_ICMPH_LEN) /* size of ICMP + + IP header */ +#define UIP_LLIPH_LEN (UIP_LLH_LEN + UIP_IPH_LEN) /* size of L2 + + IP header */ +#if UIP_CONF_IPV6 +/** + * The sums below are quite used in ND. When used for uip_buf, we + * include link layer length when used for uip_len, we do not, hence + * we need values with and without LLH_LEN we do not use capital + * letters as these values are variable + */ +#define uip_l2_l3_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len) +#define uip_l2_l3_icmp_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN) +#define uip_l3_hdr_len (UIP_IPH_LEN + uip_ext_len) +#define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN) +#endif /*UIP_CONF_IPV6*/ #if UIP_FIXEDADDR -extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; +CCIF extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; #else /* UIP_FIXEDADDR */ -extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; +CCIF extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; #endif /* UIP_FIXEDADDR */ +CCIF extern const uip_ipaddr_t uip_broadcast_addr; +CCIF extern const uip_ipaddr_t uip_all_zeroes_addr; + +#if UIP_FIXEDETHADDR +CCIF extern const uip_lladdr_t uip_lladdr; +#else +CCIF extern uip_lladdr_t uip_lladdr; +#endif + +#if UIP_CONF_IPV6 +/** Length of the link local prefix */ +#define UIP_LLPREF_LEN 10 + /** - * Representation of a 48-bit Ethernet address. + * \brief Is IPv6 address a the unspecified address + * a is of type uip_ipaddr_t + */ +#define uip_is_addr_loopback(a) \ + ((((a)->u16[0]) == 0) && \ + (((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0) && \ + (((a)->u16[6]) == 0) && \ + (((a)->u8[14]) == 0) && \ + (((a)->u8[15]) == 0x01)) +/** + * \brief Is IPv6 address a the unspecified address + * a is of type uip_ipaddr_t + */ +#define uip_is_addr_unspecified(a) \ + ((((a)->u16[0]) == 0) && \ + (((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0) && \ + (((a)->u16[6]) == 0) && \ + (((a)->u16[7]) == 0)) + +/** \brief Is IPv6 address a the link local all-nodes multicast address */ +#define uip_is_addr_linklocal_allnodes_mcast(a) \ + ((((a)->u8[0]) == 0xff) && \ + (((a)->u8[1]) == 0x02) && \ + (((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0) && \ + (((a)->u16[6]) == 0) && \ + (((a)->u8[14]) == 0) && \ + (((a)->u8[15]) == 0x01)) + +/** \brief Is IPv6 address a the link local all-routers multicast address */ +#define uip_is_addr_linklocal_allrouters_mcast(a) \ + ((((a)->u8[0]) == 0xff) && \ + (((a)->u8[1]) == 0x02) && \ + (((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0) && \ + (((a)->u16[6]) == 0) && \ + (((a)->u8[14]) == 0) && \ + (((a)->u8[15]) == 0x02)) + +/** + * \brief Checks whether the address a is link local. + * a is of type uip_ipaddr_t + */ +#define uip_is_addr_linklocal(a) \ + ((a)->u8[0] == 0xfe && \ + (a)->u8[1] == 0x80) + +/** \brief set IP address a to unspecified */ +#define uip_create_unspecified(a) uip_ip6addr(a, 0, 0, 0, 0, 0, 0, 0, 0) + +/** \brief set IP address a to the link local all-nodes multicast address */ +#define uip_create_linklocal_allnodes_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001) + +/** \brief set IP address a to the link local all-routers multicast address */ +#define uip_create_linklocal_allrouters_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002) +#define uip_create_linklocal_prefix(addr) do { \ + (addr)->u16[0] = UIP_HTONS(0xfe80); \ + (addr)->u16[1] = 0; \ + (addr)->u16[2] = 0; \ + (addr)->u16[3] = 0; \ + } while(0) + +/** + * \brief is addr (a) a solicited node multicast address, see RFC3513 + * a is of type uip_ipaddr_t* */ -struct uip_eth_addr { - u8_t addr[6]; -}; +#define uip_is_addr_solicited_node(a) \ + ((((a)->u8[0]) == 0xFF) && \ + (((a)->u8[1]) == 0x02) && \ + (((a)->u16[1]) == 0x00) && \ + (((a)->u16[2]) == 0x00) && \ + (((a)->u16[3]) == 0x00) && \ + (((a)->u16[4]) == 0x00) && \ + (((a)->u8[10]) == 0x00) && \ + (((a)->u8[11]) == 0x01) && \ + (((a)->u8[12]) == 0xFF)) + +/** + * \briefput in b the solicited node address corresponding to address a + * both a and b are of type uip_ipaddr_t* + * */ +#define uip_create_solicited_node(a, b) \ + (((b)->u8[0]) = 0xFF); \ + (((b)->u8[1]) = 0x02); \ + (((b)->u16[1]) = 0); \ + (((b)->u16[2]) = 0); \ + (((b)->u16[3]) = 0); \ + (((b)->u16[4]) = 0); \ + (((b)->u8[10]) = 0); \ + (((b)->u8[11]) = 0x01); \ + (((b)->u8[12]) = 0xFF); \ + (((b)->u8[13]) = ((a)->u8[13])); \ + (((b)->u16[7]) = ((a)->u16[7])) + +/** + * \brief is addr (a) a link local unicast address, see RFC3513 + * i.e. is (a) on prefix FE80::/10 + * a is of type uip_ipaddr_t* + */ +#define uip_is_addr_link_local(a) \ + ((((a)->u8[0]) == 0xFE) && \ + (((a)->u8[1]) == 0x80)) + +/** + * \brief was addr (a) forged based on the mac address m + * a type is uip_ipaddr_t + * m type is uiplladdr_t + */ +#if UIP_CONF_LL_802154 +#define uip_is_addr_mac_addr_based(a, m) \ + ((((a)->u8[8]) == (((m)->addr[0]) ^ 0x02)) && \ + (((a)->u8[9]) == (m)->addr[1]) && \ + (((a)->u8[10]) == (m)->addr[2]) && \ + (((a)->u8[11]) == (m)->addr[3]) && \ + (((a)->u8[12]) == (m)->addr[4]) && \ + (((a)->u8[13]) == (m)->addr[5]) && \ + (((a)->u8[14]) == (m)->addr[6]) && \ + (((a)->u8[15]) == (m)->addr[7])) +#else + +#define uip_is_addr_mac_addr_based(a, m) \ + ((((a)->u8[8]) == (((m)->addr[0]) | 0x02)) && \ + (((a)->u8[9]) == (m)->addr[1]) && \ + (((a)->u8[10]) == (m)->addr[2]) && \ + (((a)->u8[11]) == 0xff) && \ + (((a)->u8[12]) == 0xfe) && \ + (((a)->u8[13]) == (m)->addr[3]) && \ + (((a)->u8[14]) == (m)->addr[4]) && \ + (((a)->u8[15]) == (m)->addr[5])) + +#endif /*UIP_CONF_LL_802154*/ + +/** + * \brief is address a multicast address, see RFC 3513 + * a is of type uip_ipaddr_t* + * */ +#define uip_is_addr_mcast(a) \ + (((a)->u8[0]) == 0xFF) + +/** + * \brief is group-id of multicast address a + * the all nodes group-id + */ +#define uip_is_mcast_group_id_all_nodes(a) \ + ((((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0) && \ + (((a)->u16[6]) == 0) && \ + (((a)->u8[14]) == 0) && \ + (((a)->u8[15]) == 1)) + +/** + * \brief is group-id of multicast address a + * the all routers group-id + */ +#define uip_is_mcast_group_id_all_routers(a) \ + ((((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0) && \ + (((a)->u16[6]) == 0) && \ + (((a)->u8[14]) == 0) && \ + (((a)->u8[15]) == 2)) + + +/** + * \brief are last three bytes of both addresses equal? + * This is used to compare solicited node multicast addresses + */ +#define uip_are_solicited_bytes_equal(a, b) \ + ((((a)->u8[13]) == ((b)->u8[13])) && \ + (((a)->u8[14]) == ((b)->u8[14])) && \ + (((a)->u8[15]) == ((b)->u8[15]))) + +#endif /*UIP_CONF_IPV6*/ /** * Calculate the Internet checksum over a buffer. @@ -1559,7 +2153,7 @@ * * \return The Internet checksum of the buffer. */ -u16_t uip_chksum(u16_t *buf, u16_t len); +uint16_t uip_chksum(uint16_t *buf, uint16_t len); /** * Calculate the IP header checksum of the packet header in uip_buf. @@ -1570,7 +2164,7 @@ * \return The IP header checksum of the IP header in the uip_buf * buffer. */ -u16_t uip_ipchksum(void); +uint16_t uip_ipchksum(void); /** * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. @@ -1581,7 +2175,7 @@ * \return The TCP checksum of the TCP segment in uip_buf and pointed * to by uip_appdata. */ -u16_t uip_tcpchksum(void); +uint16_t uip_tcpchksum(void); /** * Calculate the UDP checksum of the packet in uip_buf and uip_appdata. @@ -1592,7 +2186,14 @@ * \return The UDP checksum of the UDP segment in uip_buf and pointed * to by uip_appdata. */ -u16_t uip_udpchksum(void); +uint16_t uip_udpchksum(void); + +/** + * Calculate the ICMP checksum of the packet in uip_buf. + * + * \return The ICMP checksum of the ICMP packet in uip_buf + */ +uint16_t uip_icmp6chksum(void); #endif /* __UIP_H__ */
--- a/uip/uip_arp.c Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uip_arp.c Mon Jun 30 16:00:08 2014 +0000 @@ -54,7 +54,6 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $ * */ @@ -65,30 +64,29 @@ struct arp_hdr { struct uip_eth_hdr ethhdr; - u16_t hwtype; - u16_t protocol; - u8_t hwlen; - u8_t protolen; - u16_t opcode; + uint16_t hwtype; + uint16_t protocol; + uint8_t hwlen; + uint8_t protolen; + uint16_t opcode; struct uip_eth_addr shwaddr; - u16_t sipaddr[2]; + uip_ipaddr_t sipaddr; struct uip_eth_addr dhwaddr; - u16_t dipaddr[2]; + uip_ipaddr_t dipaddr; }; struct ethip_hdr { struct uip_eth_hdr ethhdr; /* IP header. */ - u8_t vhl, + uint8_t vhl, tos, len[2], ipid[2], ipoffset[2], ttl, proto; - u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uint16_t ipchksum; + uip_ipaddr_t srcipaddr, destipaddr; }; #define ARP_REQUEST 1 @@ -97,24 +95,33 @@ #define ARP_HWTYPE_ETH 1 struct arp_entry { - u16_t ipaddr[2]; + uip_ipaddr_t ipaddr; struct uip_eth_addr ethaddr; - u8_t time; + uint8_t time; }; static const struct uip_eth_addr broadcast_ethaddr = {{0xff,0xff,0xff,0xff,0xff,0xff}}; -static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff}; +static const uint16_t broadcast_ipaddr[2] = {0xffff,0xffff}; static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; -static u16_t ipaddr[2]; -static u8_t i, c; +static uip_ipaddr_t ipaddr; +static uint8_t i, c; -static u8_t arptime; -static u8_t tmpage; +static uint8_t arptime; +static uint8_t tmpage; #define BUF ((struct arp_hdr *)&uip_buf[0]) #define IPBUF ((struct ethip_hdr *)&uip_buf[0]) + +#define DEBUG 0 +#if DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + /*-----------------------------------------------------------------------------------*/ /** * Initialize the ARP module. @@ -125,7 +132,7 @@ uip_arp_init(void) { for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - memset(arp_table[i].ipaddr, 0, 4); + memset(&arp_table[i].ipaddr, 0, 4); } } /*-----------------------------------------------------------------------------------*/ @@ -146,32 +153,32 @@ ++arptime; for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { tabptr = &arp_table[i]; - if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && + if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) && arptime - tabptr->time >= UIP_ARP_MAXAGE) { - memset(tabptr->ipaddr, 0, 4); + memset(&tabptr->ipaddr, 0, 4); } } } + /*-----------------------------------------------------------------------------------*/ static void -uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) +uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr) { - register struct arp_entry *tabptr; + register struct arp_entry *tabptr = arp_table; + /* Walk through the ARP mapping table and try to find an entry to update. If none is found, the IP -> MAC address mapping is inserted in the ARP table. */ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; - tabptr = &arp_table[i]; /* Only check those entries that are actually in use. */ - if(tabptr->ipaddr[0] != 0 && - tabptr->ipaddr[1] != 0) { + if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) { /* Check if the source IP address of the incoming packet matches the IP address in this ARP table entry. */ - if(ipaddr[0] == tabptr->ipaddr[0] && - ipaddr[1] == tabptr->ipaddr[1]) { + if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) { /* An old entry found, update this and return. */ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); @@ -180,6 +187,7 @@ return; } } + tabptr++; } /* If we get here, no existing ARP table entry was found, so we @@ -188,8 +196,7 @@ /* First, we try to find an unused entry in the ARP table. */ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { tabptr = &arp_table[i]; - if(tabptr->ipaddr[0] == 0 && - tabptr->ipaddr[1] == 0) { + if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) { break; } } @@ -212,7 +219,7 @@ /* Now, i is the ARP table entry which we will fill with the new information. */ - memcpy(tabptr->ipaddr, ipaddr, 4); + uip_ipaddr_copy(&tabptr->ipaddr, ipaddr); memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); tabptr->time = arptime; } @@ -285,37 +292,41 @@ uip_len = 0; switch(BUF->opcode) { - case HTONS(ARP_REQUEST): + case UIP_HTONS(ARP_REQUEST): /* ARP request. If it asked for our address, we send out a reply. */ - if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { + /* if(BUF->dipaddr[0] == uip_hostaddr[0] && + BUF->dipaddr[1] == uip_hostaddr[1]) {*/ + PRINTF("uip_arp_arpin: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n", + BUF->dipaddr.u8[0], BUF->dipaddr.u8[1], + BUF->dipaddr.u8[2], BUF->dipaddr.u8[3], + uip_hostaddr.u8[0], uip_hostaddr.u8[1], + uip_hostaddr.u8[2], uip_hostaddr.u8[3]); + 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); + uip_arp_update(&BUF->sipaddr, &BUF->shwaddr); - /* The reply opcode is 2. */ - BUF->opcode = HTONS(2); + BUF->opcode = UIP_HTONS(ARP_REPLY); memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6); - memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); - memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + memcpy(BUF->shwaddr.addr, uip_lladdr.addr, 6); + memcpy(BUF->ethhdr.src.addr, uip_lladdr.addr, 6); memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6); - BUF->dipaddr[0] = BUF->sipaddr[0]; - BUF->dipaddr[1] = BUF->sipaddr[1]; - BUF->sipaddr[0] = uip_hostaddr[0]; - BUF->sipaddr[1] = uip_hostaddr[1]; + uip_ipaddr_copy(&BUF->dipaddr, &BUF->sipaddr); + uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr); - BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); + BUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP); uip_len = sizeof(struct arp_hdr); } break; - case HTONS(ARP_REPLY): + case UIP_HTONS(ARP_REPLY): /* ARP reply. We insert or update the ARP table if it was meant for us. */ - if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { - uip_arp_update(BUF->sipaddr, &BUF->shwaddr); + if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) { + uip_arp_update(&BUF->sipaddr, &BUF->shwaddr); } break; } @@ -353,7 +364,7 @@ void uip_arp_out(void) { - struct arp_entry *tabptr; + struct arp_entry *tabptr = arp_table; /* Find the destination IP address in the ARP table and construct the Ethernet header. If the destination IP addres isn't on the @@ -363,25 +374,32 @@ packet with an ARP request for the IP address. */ /* First check if destination is a local broadcast. */ - if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) { + if(uip_ipaddr_cmp(&IPBUF->destipaddr, &uip_broadcast_addr)) { memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); + } else if(IPBUF->destipaddr.u8[0] == 224) { + /* Multicast. */ + IPBUF->ethhdr.dest.addr[0] = 0x01; + IPBUF->ethhdr.dest.addr[1] = 0x00; + IPBUF->ethhdr.dest.addr[2] = 0x5e; + IPBUF->ethhdr.dest.addr[3] = IPBUF->destipaddr.u8[1]; + IPBUF->ethhdr.dest.addr[4] = IPBUF->destipaddr.u8[2]; + IPBUF->ethhdr.dest.addr[5] = IPBUF->destipaddr.u8[3]; } else { /* Check if the destination address is on the local network. */ - if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) { + 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); + uip_ipaddr_copy(&ipaddr, &uip_draddr); } else { /* Else, we use the destination IP address. */ - uip_ipaddr_copy(ipaddr, IPBUF->destipaddr); + uip_ipaddr_copy(&ipaddr, &IPBUF->destipaddr); } - for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { - tabptr = &arp_table[i]; - if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) { + if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) { break; } + tabptr++; } if(i == UIP_ARPTAB_SIZE) { @@ -390,17 +408,17 @@ 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); + memcpy(BUF->ethhdr.src.addr, uip_lladdr.addr, 6); + memcpy(BUF->shwaddr.addr, uip_lladdr.addr, 6); - 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); + uip_ipaddr_copy(&BUF->dipaddr, &ipaddr); + uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr); + BUF->opcode = UIP_HTONS(ARP_REQUEST); /* ARP request. */ + BUF->hwtype = UIP_HTONS(ARP_HWTYPE_ETH); + BUF->protocol = UIP_HTONS(UIP_ETHTYPE_IP); BUF->hwlen = 6; BUF->protolen = 4; - BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); + BUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP); uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN]; @@ -411,9 +429,9 @@ /* Build an ethernet header. */ memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); } - memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + memcpy(IPBUF->ethhdr.src.addr, uip_lladdr.addr, 6); - IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP); + IPBUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_IP); uip_len += sizeof(struct uip_eth_hdr); } @@ -421,3 +439,4 @@ /** @} */ /** @} */ +
--- a/uip/uip_arp.h Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uip_arp.h Mon Jun 30 16:00:08 2014 +0000 @@ -45,7 +45,6 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $ * */ @@ -55,7 +54,6 @@ #include "uip.h" -extern struct uip_eth_addr uip_ethaddr; /** * The Ethernet header. @@ -63,12 +61,12 @@ struct uip_eth_hdr { struct uip_eth_addr dest; struct uip_eth_addr src; - u16_t type; + uint16_t type; }; -#define UIP_ETHTYPE_ARP 0x0806 -#define UIP_ETHTYPE_IP 0x0800 -#define UIP_ETHTYPE_IP6 0x86dd +#define UIP_ETHTYPE_ARP 0x0806 +#define UIP_ETHTYPE_IP 0x0800 +#define UIP_ETHTYPE_IPV6 0x86dd /* The uip_arp_init() function must be called before any of the other @@ -131,14 +129,15 @@ * * \hideinitializer */ -#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \ - uip_ethaddr.addr[1] = eaddr.addr[1];\ - uip_ethaddr.addr[2] = eaddr.addr[2];\ - uip_ethaddr.addr[3] = eaddr.addr[3];\ - uip_ethaddr.addr[4] = eaddr.addr[4];\ - uip_ethaddr.addr[5] = eaddr.addr[5];} while(0) +#define uip_setethaddr(eaddr) do {uip_lladdr.addr[0] = eaddr.addr[0]; \ + uip_lladdr.addr[1] = eaddr.addr[1];\ + uip_lladdr.addr[2] = eaddr.addr[2];\ + uip_lladdr.addr[3] = eaddr.addr[3];\ + uip_lladdr.addr[4] = eaddr.addr[4];\ + uip_lladdr.addr[5] = eaddr.addr[5];} while(0) /** @} */ -/** @} */ + #endif /* __UIP_ARP_H__ */ +/** @} */
--- a/uip/uipopt.h Sat Jun 21 11:54:24 2014 +0000 +++ b/uip/uipopt.h Mon Jun 30 16:00:08 2014 +0000 @@ -69,6 +69,9 @@ #include "uip-conf.h" +#define CCIF +#define CLIF + /*------------------------------------------------------------------------------*/ /** @@ -79,11 +82,11 @@ * 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 + * netmask, default router and Ethernet address are applicable only * if uIP should be run over Ethernet. * * All of these should be changed to suit your project. -*/ + */ /** * Determines if uIP should use a fixed IP address or not. @@ -97,7 +100,7 @@ #define UIP_FIXEDADDR 0 /** - * Ping IP address asignment. + * Ping IP address assignment. * * 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 @@ -144,7 +147,7 @@ * 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 + * requires an additional 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). @@ -171,7 +174,7 @@ */ /** - * Toggles wether UDP support should be compiled in or not. + * Toggles whether UDP support should be compiled in or not. * * \hideinitializer */ @@ -221,11 +224,22 @@ */ /** + * Toggles whether TCP support should be compiled in or not. + * + * \hideinitializer + */ +#ifdef UIP_CONF_TCP +#define UIP_TCP (UIP_CONF_TCP) +#else /* UIP_CONF_TCP */ +#define UIP_TCP 1 +#endif /* UIP_CONF_TCP */ + +/** * 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 + * do not need to open outgoing TCP connections, this configuration * option can be turned off to reduce the code size of uIP. * * \hideinitializer @@ -237,7 +251,7 @@ * * 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. + * connection requires approximately 30 bytes of memory. * * \hideinitializer */ @@ -307,7 +321,7 @@ /** * The size of the advertised receiver's window. * - * Should be set low (i.e., to the size of the uip_buf buffer) is the + * Should be set low (i.e., to the size of the uip_buf buffer) if the * application is slow to process incoming data, or high (32768 bytes) * if the application processes data quickly. * @@ -350,7 +364,7 @@ #endif /** - * The maxium age of ARP table entries measured in 10ths of seconds. + * The maximum age of ARP table entries measured in 10ths of seconds. * * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD * default). @@ -479,7 +493,7 @@ /*------------------------------------------------------------------------------*/ /** - * \name Appication specific configurations + * \name Application specific configurations * @{ * * An uIP application is implemented using a single application