ban4jp -
/
uIP-1-0_webserver
uIP 1.0 based webserver for LPC1114 + ENC28J60
Diff: uip/uip.h
- Revision:
- 3:a2715e9c7737
- Parent:
- 0:685224d2f66d
--- 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__ */