diff options
Diffstat (limited to 'Projects/Webserver/Lib/uip/uip.h')
-rw-r--r-- | Projects/Webserver/Lib/uip/uip.h | 886 |
1 files changed, 707 insertions, 179 deletions
diff --git a/Projects/Webserver/Lib/uip/uip.h b/Projects/Webserver/Lib/uip/uip.h index 4fc04524d..a10699dc1 100644 --- a/Projects/Webserver/Lib/uip/uip.h +++ b/Projects/Webserver/Lib/uip/uip.h @@ -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,7 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $ + * $Id: uip.h,v 1.24 2009/04/06 13:18:50 nvt-se Exp $ * */ @@ -56,23 +57,72 @@ #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]; #if UIP_CONF_IPV6 +typedef union uip_ip6addr_t { + u8_t u8[16]; /* Initializer, must come first!!! */ + u16_t u16[8]; +} uip_ip6addr_t; + typedef uip_ip6addr_t uip_ipaddr_t; #else /* UIP_CONF_IPV6 */ +typedef union uip_ip4addr_t { + u8_t u8[4]; /* Initializer, must come first!!! */ + u16_t u16[2]; +#if 0 + u32_t u32; +#endif +} uip_ip4addr_t; typedef uip_ip4addr_t uip_ipaddr_t; #endif /* UIP_CONF_IPV6 */ + +/*---------------------------------------------------------------------------*/ + +/** \brief 16 bit 802.15.4 address */ +struct uip_802154_shortaddr { + u8_t addr[2]; +}; +/** \brief 64 bit 802.15.4 address */ +struct uip_802154_longaddr { + u8_t addr[8]; +}; + +/** \brief 802.11 address */ +struct uip_80211_addr { + u8_t addr[6]; +}; + +/** \brief 802.3 address */ +struct uip_eth_addr { + u8_t addr[6]; +}; + +#if UIP_CONF_LL_802154 +/** \brief 802.15.4 address */ +typedef struct 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 struct uip_80211_addr uip_lladdr_t; +#define UIP_LLADDR_LEN 6 +#else /*UIP_CONF_LL_80211*/ +/** \brief Ethernet address */ +typedef struct uip_eth_addr uip_lladdr_t; +#define UIP_LLADDR_LEN 6 +#endif /*UIP_CONF_LL_80211*/ +#endif /*UIP_CONF_LL_802154*/ + /*---------------------------------------------------------------------------*/ /* 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 @@ typedef uip_ip4addr_t uip_ipaddr_t; * * \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 @@ typedef uip_ip4addr_t uip_ipaddr_t; * * \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 @@ typedef uip_ip4addr_t uip_ipaddr_t; * * \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 @@ typedef uip_ip4addr_t uip_ipaddr_t; * * \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 @@ typedef uip_ip4addr_t uip_ipaddr_t; * * \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 @@ typedef uip_ip4addr_t uip_ipaddr_t; * * \hideinitializer */ -#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask) +#define uip_getnetmask(addr) uip_ipaddr_copy((addr), &uip_netmask) /** @} */ @@ -220,13 +270,13 @@ void uip_setipid(u16_t id); * 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 @@ void uip_setipid(u16_t id); * 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 == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if(uip_len > 0) { + ethernet_devicedriver_send(); + } + } \endcode * * \hideinitializer */ #define uip_input() uip_process(UIP_DATA) + /** * Periodic processing for a connection identified by its number. * @@ -269,15 +320,15 @@ void uip_setipid(u16_t id); * 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 @@ void uip_setipid(u16_t id); * 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 @@ void uip_setipid(u16_t id); * * \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 @@ void uip_setipid(u16_t id); * * \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 @@ void uip_setipid(u16_t id); * 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 @@ void uip_setipid(u16_t id); * \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,12 +440,13 @@ void uip_setipid(u16_t id); * * \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 */ +/** \brief Abandon the reassembly of the current packet */ +void uip_reass_over(void); + /** * The uIP packet buffer. * @@ -409,25 +463,27 @@ void uip_setipid(u16_t id); 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]; + + /** @} */ /*---------------------------------------------------------------------------*/ /* 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 * @{ @@ -467,14 +523,14 @@ void uip_unlisten(u16_t port); * Connect to a remote host using TCP. * * This function is used to start a new connection to the specified - * port on the specied host. It allocates a new connection identifier, + * 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 @@ -487,7 +543,7 @@ void uip_unlisten(u16_t port); uip_connect(&ipaddr, 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. * @@ -518,7 +574,7 @@ struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port); * 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. @@ -538,7 +594,7 @@ struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port); 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 +629,7 @@ void uip_send(const void *data, int len); * 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 +663,9 @@ void uip_send(const void *data, int len); * * \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 +686,7 @@ void uip_send(const void *data, int len); * * 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 +772,7 @@ void uip_send(const void *data, int len); #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 +780,10 @@ void uip_send(const void *data, int len); #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()). @@ -753,7 +809,7 @@ void uip_send(const void *data, int len); uip_ipaddr(&addr, 192,168,2,1); c = uip_udp_new(&addr, HTONS(12345)); if(c != NULL) { - uip_udp_bind(c, HTONS(12344)); + uip_udp_bind(c, HTONS(12344)); } \endcode * \param ripaddr The IP address of the remote host. @@ -763,7 +819,7 @@ void uip_send(const void *data, int len); * \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, u16_t rport); /** * Removed a UDP connection. @@ -812,6 +868,20 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); */ /** + * 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 @@ -837,10 +907,12 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * * \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,15 +922,42 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * \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] = HTONS(addr0); \ + (addr)->u16[1] = HTONS(addr1); \ + (addr)->u16[2] = HTONS(addr2); \ + (addr)->u16[3] = HTONS(addr3); \ + (addr)->u16[4] = HTONS(addr4); \ + (addr)->u16[5] = HTONS(addr5); \ + (addr)->u16[6] = HTONS(addr6); \ + (addr)->u16[7] = HTONS(addr7); \ + } while(0) + +/** + * Construct an IPv6 address from eight 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 to another IP address. @@ -878,14 +977,9 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * * \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 /** * Compare two IP addresses @@ -898,7 +992,7 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); uip_ipaddr(&ipaddr1, 192,16,1,2); if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { - printf("They are the same"); + printf("They are the same"); } \endcode * @@ -908,8 +1002,8 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * \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]) +#define uip_ipaddr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \ + (addr1)->u16[1] == (addr2)->u16[1]) #else /* !UIP_CONF_IPV6 */ #define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) #endif /* !UIP_CONF_IPV6 */ @@ -928,7 +1022,7 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); 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 +1032,33 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * * \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]))) +#if !UIP_CONF_IPV6 +#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]))) +#else +#define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0) +#endif + + +/** + * 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 +1085,10 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * * \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 { \ + ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \ + ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \ + } while(0) /** * Pick the first octet of an IP address. @@ -992,7 +1108,7 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * * \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. @@ -1012,7 +1128,7 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * * \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. @@ -1032,7 +1148,7 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * * \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. @@ -1052,7 +1168,7 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); * * \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. @@ -1066,8 +1182,10 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); #ifndef HTONS # if UIP_BYTE_ORDER == UIP_BIG_ENDIAN # define HTONS(n) (n) +# define HTONL(n) (n) # else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ # define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) +# define HTONL(n) (((u32_t)HTONS(n) << 16) | HTONS((u32_t)(n) >> 16)) # endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ #else #error "HTONS already defined!" @@ -1087,6 +1205,13 @@ u16_t htons(u16_t val); #define ntohs htons #endif +#ifndef htonl +u32_t htonl(u32_t val); +#endif /* htonl */ +#ifndef ntohl +#define ntohl htonl +#endif + /** @} */ /** @@ -1133,6 +1258,10 @@ extern void *uip_urgdata; */ extern u16_t uip_len; +/** + * The length of the extension headers + */ +extern u8_t uip_ext_len; /** @} */ #if UIP_URGDATA > 0 @@ -1145,7 +1274,7 @@ extern u16_t uip_urglen, uip_surglen; * * 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. @@ -1187,9 +1316,13 @@ struct uip_conn { * The uip_conn pointer can be used to access the current TCP * connection. */ + extern struct uip_conn *uip_conn; +#if UIP_TCP /* The array containing all uIP connections. */ extern struct uip_conn uip_conns[UIP_CONNS]; +#endif + /** * \addtogroup uiparch * @{ @@ -1199,11 +1332,8 @@ extern struct uip_conn uip_conns[UIP_CONNS]; * 4-byte array used for the 32-bit sequence number calculations. */ extern u8_t uip_acc32[4]; - /** @} */ - -#if UIP_UDP /** * Representation of a uIP UDP connection. */ @@ -1222,7 +1352,40 @@ struct uip_udp_conn { */ extern struct uip_udp_conn *uip_udp_conn; extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; -#endif /* UIP_UDP */ + +struct uip_router { + int (*activate)(void); + int (*deactivate)(void); + uip_ipaddr_t *(*lookup)(uip_ipaddr_t *destipaddr, uip_ipaddr_t *nexthop); +}; + +#if UIP_CONF_ROUTER +extern const struct uip_router *uip_router; + +/** + * uIP routing driver registration function. + */ +void uip_router_register(const struct uip_router *router); +#endif /*UIP_CONF_ROUTER*/ + +#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 @@ -1231,12 +1394,14 @@ extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; */ 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 @@ -1251,16 +1416,19 @@ struct uip_stats { 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 @@ -1272,6 +1440,7 @@ struct uip_stats { 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 +1450,36 @@ struct uip_stats { 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: * * 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; /* 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 +1512,28 @@ extern u8_t uip_flags; #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 u8_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() + + /* 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 @@ -1402,8 +1584,7 @@ struct uip_tcpip_hdr { ttl, proto; u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uip_ipaddr_t srcipaddr, destipaddr; #endif /* UIP_CONF_IPV6 */ /* TCP header. */ @@ -1439,19 +1620,15 @@ struct uip_icmpip_hdr { ttl, proto; u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uip_ipaddr_t srcipaddr, destipaddr; #endif /* UIP_CONF_IPV6 */ - /* ICMP (echo) header. */ + /* ICMP header. */ u8_t type, icode; u16_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]; + u8_t payload[1]; #endif /* !UIP_CONF_IPV6 */ }; @@ -1476,8 +1653,7 @@ struct uip_udpip_hdr { ttl, proto; u16_t ipchksum; - u16_t srcipaddr[2], - destipaddr[2]; + uip_ipaddr_t srcipaddr, destipaddr; #endif /* UIP_CONF_IPV6 */ /* UDP header. */ @@ -1487,6 +1663,145 @@ struct uip_udpip_hdr { u16_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 */ + u8_t vtc; + u8_t tcflow; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IPV4 header */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + uip_ipaddr_t srcipaddr, destipaddr; +#endif /* UIP_CONF_IPV6 */ +}; + + +/* + * 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 */ +struct uip_ext_hdr { + u8_t next; + u8_t len; +}; + +/* Hop by Hop option header */ +struct uip_hbho_hdr { + u8_t next; + u8_t len; +}; + +/* destination option header */ +struct uip_desto_hdr { + u8_t next; + u8_t len; +}; + +/* 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 + */ +struct uip_routing_hdr { + u8_t next; + u8_t len; + u8_t routing_type; + u8_t seg_left; +}; + +/* fragmentation header */ +struct uip_frag_hdr { + u8_t next; + u8_t res; + u16_t offsetresmore; + u32_t id; +}; + +/* + * an option within the destination or hop by hop option headers + * it contains type an length, which is true for all options but PAD1 + */ +struct uip_ext_hdr_opt { + u8_t type; + u8_t len; +}; + +/* PADN option */ +struct uip_ext_hdr_opt_padn { + u8_t opt_type; + u8_t opt_len; +}; + +/* TCP header */ +struct uip_tcp_hdr { + u16_t srcport; + u16_t destport; + u8_t seqno[4]; + u8_t ackno[4]; + u8_t tcpoffset; + u8_t flags; + u8_t wnd[2]; + u16_t tcpchksum; + u8_t urgp[2]; + u8_t optdata[4]; +}; + +/* The ICMP headers. */ +struct uip_icmp_hdr { + u8_t type, icode; + u16_t icmpchksum; +#if !UIP_CONF_IPV6 + u16_t id, seqno; +#endif /* !UIP_CONF_IPV6 */ +}; + + +/* The UDP headers. */ +struct uip_udp_hdr { + u16_t srcport; + u16_t destport; + u16_t udplen; + u16_t udpchksum; +}; /** @@ -1504,28 +1819,88 @@ struct uip_udpip_hdr { * \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 +/** @} */ + +/** @{ */ +/** + * \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 u8_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 @@ -1533,15 +1908,161 @@ extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; #else /* UIP_FIXEDADDR */ extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; #endif /* UIP_FIXEDADDR */ +extern const uip_ipaddr_t uip_broadcast_addr; +extern const uip_ipaddr_t uip_all_zeroes_addr; + +#if UIP_FIXEDETHADDR +extern const uip_lladdr_t uip_lladdr; +#else +extern uip_lladdr_t uip_lladdr; +#endif + + + + +#ifdef UIP_CONF_IPV6 +/** + * \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 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) + +/** + * \brief is addr (a) a solicited node multicast address, see RFC3513 + * a is of type uip_ipaddr_t* + */ +#define uip_is_addr_solicited_node(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]) == 1) && \ + (((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) /** - * Representation of a 48-bit Ethernet address. + * \brief is group-id of multicast address a + * the all nodes group-id */ -struct uip_eth_addr { - u8_t addr[6]; -}; +#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)) + + +#endif /*UIP_CONF_IPV6*/ /** * Calculate the Internet checksum over a buffer. @@ -1594,6 +2115,13 @@ u16_t uip_tcpchksum(void); */ u16_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 + */ +u16_t uip_icmp6chksum(void); + #endif /* __UIP_H__ */ |