From a8fb9f2b84321baf1ff0e4f28e458c23f02a05e1 Mon Sep 17 00:00:00 2001 From: tzx Date: Thu, 10 Nov 2016 11:24:31 +0800 Subject: [PATCH] ipv6 interface: add branch for ipv6 interface --- components/esp32/include/esp_event.h | 8 ++- components/lwip/api/sockets.c | 6 +- components/lwip/core/ipv4/autoip.c | 7 ++ components/lwip/core/ipv6/nd6.c | 22 ++++++ components/lwip/core/netif.c | 41 ------------ components/lwip/include/lwip/lwip/autoip.h | 5 ++ components/lwip/include/lwip/lwip/nd6.h | 4 ++ components/lwip/include/lwip/lwip/netif.h | 9 ++- components/lwip/include/lwip/port/lwipopts.h | 50 +++++++++++++- .../tcpip_adapter/include/tcpip_adapter.h | 37 +++++++++- components/tcpip_adapter/tcpip_adapter_lwip.c | 67 ++++++++++++++++++- 11 files changed, 202 insertions(+), 54 deletions(-) diff --git a/components/esp32/include/esp_event.h b/components/esp32/include/esp_event.h index 55575b13a..06e35d6ad 100644 --- a/components/esp32/include/esp_event.h +++ b/components/esp32/include/esp_event.h @@ -44,6 +44,7 @@ typedef enum { SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */ SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */ SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ + SYSTEM_EVENT_AP_STA_GOT_IP6, /**< ESP32 station or ap interface v6IP addr is preferred */ SYSTEM_EVENT_MAX } system_event_id_t; @@ -79,7 +80,11 @@ typedef struct { typedef struct { uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */ -}system_event_sta_wps_er_pin_t; +} system_event_sta_wps_er_pin_t; + +typedef struct { + tcpip_adapter_ip6_info_t ip6_info; +} system_event_ap_sta_got_ip6_t; typedef struct { uint8_t mac[6]; /**< MAC address of the station connected to ESP32 soft-AP */ @@ -106,6 +111,7 @@ typedef union { system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP32 soft-AP */ system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP32 soft-AP */ system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP32 soft-AP receive probe request packet */ + system_event_ap_sta_got_ip6_t got_ip6; /**< ESP32 station or ap ipv6 addr state change to preferred */ } system_event_info_t; typedef struct { diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 1529382f5..4acf518cc 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -2775,8 +2775,12 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ case IPPROTO_IPV6: switch (optname) { case IPV6_V6ONLY: - /* @todo: this does not work for datagram sockets, yet */ + /* @todo: this does not work for datagram sockets, yet */ +#if CONFIG_MDNS + //LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); +#else LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); +#endif if (*(const int*)optval) { netconn_set_ipv6only(sock->conn, 1); } else { diff --git a/components/lwip/core/ipv4/autoip.c b/components/lwip/core/ipv4/autoip.c index 19b192836..faac4957c 100755 --- a/components/lwip/core/ipv4/autoip.c +++ b/components/lwip/core/ipv4/autoip.c @@ -72,6 +72,7 @@ #include "lwip/netif.h" #include "lwip/autoip.h" #include "netif/etharp.h" +#include "lwip/dhcp.h" #include #include @@ -269,6 +270,12 @@ autoip_bind(struct netif *netif) netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr); /* interface is used by routing now that an address is set */ +#if ESP_LWIP + struct dhcp *dhcp = netif->dhcp; + if (dhcp->cb != NULL) { + dhcp->cb(); + } +#endif return ERR_OK; } diff --git a/components/lwip/core/ipv6/nd6.c b/components/lwip/core/ipv6/nd6.c index 36f8f78c3..1cec55db9 100755 --- a/components/lwip/core/ipv6/nd6.c +++ b/components/lwip/core/ipv6/nd6.c @@ -632,6 +632,22 @@ nd6_input(struct pbuf *p, struct netif *inp) pbuf_free(p); } +#ifdef ESP_LWIP + +/** Set callback for ipv6 addr status changed . + * + * @param netif the netif from which to remove the struct dhcp + * @param cb callback for dhcp + */ +void nd6_set_cb(struct netif *netif, void (*cb)(struct netif *netif, u8_t ip_index)) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + + if (netif != NULL && netif_is_up(netif)) { + netif->ipv6_addr_cb = cb; + } +} +#endif /** * Periodic timer for Neighbor discovery functions: @@ -797,6 +813,12 @@ nd6_tmr(void) if ((netif->ip6_addr_state[i] & 0x07) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) { /* No NA received in response. Mark address as valid. */ netif->ip6_addr_state[i] = IP6_ADDR_PREFERRED; +#ifdef ESP_LWIP + if (netif->ipv6_addr_cb != NULL) { + netif->ipv6_addr_cb(netif, i); + } +#endif + /* TODO implement preferred and valid lifetimes. */ } else if (netif->flags & NETIF_FLAG_UP) { #if LWIP_IPV6_MLD diff --git a/components/lwip/core/netif.c b/components/lwip/core/netif.c index 5c308a957..f745f29ac 100755 --- a/components/lwip/core/netif.c +++ b/components/lwip/core/netif.c @@ -968,9 +968,6 @@ netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit) } } -#if ESP_LWIP - ip6_addr_set( ip_2_ip6(&netif->link_local_addr), ip_2_ip6(&netif->ip6_addr[0]) ); -#endif /* Set address state. */ #if LWIP_IPV6_DUP_DETECT_ATTEMPTS @@ -1022,44 +1019,6 @@ netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chos return ERR_VAL; } - -#if ESP_LWIP -void -netif_create_ip4_linklocal_address(struct netif * netif) -{ -#if 1 - ip_addr_t linklocal; - ip_addr_t linklocal_mask; - ip4_addr_t addr = {0}; - /* Link-local prefix and mask. */ - IP4_ADDR(ip_2_ip4(&linklocal), 169, 254, 0, 0); - IP4_ADDR(ip_2_ip4(&linklocal_mask), 255, 255, 0, 0); - - if (!ip4_addr_netcmp( ip_2_ip4(&linklocal), ip_2_ip4(&netif->link_local_addr), ip_2_ip4(&linklocal_mask) ) && - !ip4_addr_isany(ip_2_ip4(&netif->ip_addr)) ) { - IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3( ip_2_ip4(&netif->ip_addr) ) - , ip4_addr4( ip_2_ip4(&netif->ip_addr) ) ); - return; - } - - while ( !(addr.addr) || !ip4_addr4(&addr) ) - //os_get_random((unsigned char *)&addr, sizeof(addr)); - addr.addr = LWIP_RAND(); - - - if ( ip_2_ip4(&netif->netmask)->addr > IP_CLASSB_NET && - !ip4_addr_isany( ip_2_ip4(&netif->ip_addr) )) { // random host address - IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3( ip_2_ip4(&netif->ip_addr)) - , ip4_addr4(&addr)); - } else { - IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3(&addr), ip4_addr4(&addr) ); - } -#endif -} - -#endif - - /** Dummy IPv6 output function for netifs not supporting IPv6 */ static err_t diff --git a/components/lwip/include/lwip/lwip/autoip.h b/components/lwip/include/lwip/lwip/autoip.h index c89fe3ff1..3bb413f49 100755 --- a/components/lwip/include/lwip/lwip/autoip.h +++ b/components/lwip/include/lwip/lwip/autoip.h @@ -68,8 +68,13 @@ extern "C" { #define ANNOUNCE_NUM 2 /* (number of announcement packets) */ #define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ #define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ +#if CONFIG_MDNS +#define MAX_CONFLICTS 9 /* (max conflicts before rate limiting) */ +#define RATE_LIMIT_INTERVAL 20 /* seconds (delay between successive attempts) */ +#else #define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ #define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ +#endif #define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ /* AutoIP client states */ diff --git a/components/lwip/include/lwip/lwip/nd6.h b/components/lwip/include/lwip/lwip/nd6.h index d0646f1b4..27a4c8137 100755 --- a/components/lwip/include/lwip/lwip/nd6.h +++ b/components/lwip/include/lwip/lwip/nd6.h @@ -352,6 +352,10 @@ err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf * p); void nd6_reachability_hint(const ip6_addr_t * ip6addr); #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ +#if ESP_LWIP +/** set nd6 callback when ipv6 addr state pref*/ +void nd6_set_cb(struct netif *netif, void (*cb)(struct netif *netif, u8_t ip_index)); +#endif #ifdef __cplusplus } #endif diff --git a/components/lwip/include/lwip/lwip/netif.h b/components/lwip/include/lwip/lwip/netif.h index 666f77eb9..34e6d4489 100755 --- a/components/lwip/include/lwip/lwip/netif.h +++ b/components/lwip/include/lwip/lwip/netif.h @@ -190,11 +190,6 @@ struct netif { /** pointer to next in linked list */ struct netif *next; -#if ESP_LWIP -//ip_addr_t is changed by marco IPV4, IPV6 - ip_addr_t link_local_addr; -#endif - #if LWIP_IPV4 /** IP address configuration in network byte order */ ip_addr_t ip_addr; @@ -207,6 +202,10 @@ struct netif { /** The state of each IPv6 address (Tentative, Preferred, etc). * @see ip6_addr.h */ u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES]; +#if ESP_LWIP + void (*ipv6_addr_cb)(struct netif* netif, u8_t ip_idex); /* callback for ipv6 addr states changed */ +#endif + #endif /* LWIP_IPV6 */ /** This function is called by the network device driver * to pass a packet up the TCP/IP stack. */ diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 26bdc3a4e..b63fc80e5 100755 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -65,8 +65,8 @@ */ #define SMEMCPY(dst,src,len) memcpy(dst,src,len) -extern unsigned long os_random(void); -#define LWIP_RAND rand +#define LWIP_RAND rand + /* ------------------------------------ ---------- Memory options ---------- @@ -200,13 +200,35 @@ extern unsigned long os_random(void); */ #define LWIP_DHCP 1 +#define DHCP_MAXRTX 0 -#define DHCP_MAXRTX 0 //(*(volatile uint32*)0x600011E0) /* ------------------------------------ ---------- AUTOIP options ---------- ------------------------------------ */ +#if CONFIG_MDNS + /** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#define LWIP_AUTOIP 1 + +/** +* LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on +* the same interface at the same time. +*/ +#define LWIP_DHCP_AUTOIP_COOP 1 + +/** +* LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes +* that should be sent before falling back on AUTOIP. This can be set +* as low as 1 to get an AutoIP address very quickly, but you should +* be prepared to handle a changing IP address when DHCP overrides +* AutoIP. +*/ +#define LWIP_DHCP_AUTOIP_COOP_TRIES 2 +#endif + /* ---------------------------------- ---------- SNMP options ---------- @@ -308,6 +330,19 @@ extern unsigned long os_random(void); ---------- LOOPIF options ---------- ------------------------------------ */ +#if CONFIG_MDNS +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#define LWIP_NETIF_LOOPBACK 1 + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#define LWIP_LOOPBACK_MAX_PBUFS 8 +#endif /* ------------------------------------ @@ -414,6 +449,15 @@ extern unsigned long os_random(void); */ #define SO_REUSE CONFIG_LWIP_SO_REUSE +#if CONFIG_MDNS +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#define SO_REUSE_RXTOALL 1 +#endif + /* ---------------------------------------- ---------- Statistics options ---------- diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index 45d6ade30..f7063a8e1 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -64,18 +64,22 @@ typedef struct { ip4_addr_t gw; } tcpip_adapter_ip_info_t; +typedef struct { + ip6_addr_t ip; +} tcpip_adapter_ip6_info_t; + typedef dhcps_lease_t tcpip_adapter_dhcps_lease_t; #if CONFIG_DHCP_STA_LIST typedef struct { uint8_t mac[6]; ip4_addr_t ip; -}tcpip_adapter_sta_info_t; +} tcpip_adapter_sta_info_t; typedef struct { tcpip_adapter_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; int num; -}tcpip_adapter_sta_list_t; +} tcpip_adapter_sta_list_t; #endif #endif @@ -211,6 +215,35 @@ esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i */ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info); +/** + * @brief create interface's linklocal IPv6 information + * + * @note this function will create a linklocal IPv6 address about input interface, + * if this address status changed to preferred, will call event call back , + * notify user linklocal IPv6 address has been verified + * + * @param[in] tcpip_if: the interface which we want to set IP information + * + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + */ +esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if); + +/** + * @brief get interface's linkloacl IPv6 information + * + * There has an IPv6 information copy in adapter library, if interface is up,and IPv6 info + * is preferred,it will get IPv6 linklocal IP successfully + * + * @param[in] tcpip_if: the interface which we want to set IP information + * @param[in] if_ip6: If successful, IPv6 information will be returned in this argument. + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + */ +esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6); + #if 0 esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t *mac); diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 3edc90509..25c801bd0 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -23,7 +23,8 @@ #include "lwip/tcpip.h" #include "lwip/dhcp.h" #include "lwip/ip_addr.h" - +#include "lwip/ip6_addr.h" +#include "lwip/nd6.h" #include "netif/wlanif.h" #include "apps/dhcpserver.h" @@ -32,6 +33,7 @@ static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX]; static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX]; +static tcpip_adapter_ip6_info_t esp_ip6[TCPIP_ADAPTER_IF_MAX]; static tcpip_adapter_dhcp_status_t dhcps_status = TCPIP_ADAPTER_DHCP_INIT; static tcpip_adapter_dhcp_status_t dhcpc_status = TCPIP_ADAPTER_DHCP_INIT; @@ -234,6 +236,69 @@ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i return ESP_OK; } +static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex) +{ + tcpip_adapter_ip6_info_t *ip6_info; + + if (!p_netif) { + TCPIP_ADAPTER_DEBUG("null p_netif=%p\n", p_netif); + return; + } + + if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) { + ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_STA]; + } else if(p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) { + ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_AP]; + } else { + return; + } + + system_event_t evt; + + ip6_addr_set(&ip6_info->ip, ip_2_ip6(&p_netif->ip6_addr[ip_idex])); + + //notify event + evt.event_id = SYSTEM_EVENT_AP_STA_GOT_IP6; + memcpy(&evt.event_info.got_ip6.ip6_info, ip6_info, sizeof(tcpip_adapter_ip6_info_t)); + esp_event_send(&evt); +} + +esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if) +{ + struct netif *p_netif; + + if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + + p_netif = esp_netif[tcpip_if]; + if(p_netif != NULL && netif_is_up(p_netif)) { + netif_create_ip6_linklocal_address(p_netif, 1); + nd6_set_cb(p_netif, tcpip_adapter_nd6_cb); + + return ESP_OK; + } else { + return ESP_FAIL; + } +} + +esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6) +{ + struct netif *p_netif; + + if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip6 == NULL) { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + + p_netif = esp_netif[tcpip_if]; + if (p_netif != NULL && netif_is_up(p_netif) && ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, 0))) { + memcpy(if_ip6, &p_netif->ip6_addr[0], sizeof(ip6_addr_t)); + } else { + return ESP_FAIL; + } + return ESP_OK; +} + #if 0 esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6]) {