1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef _ESP_NETIF_IP_ADDR_H_
8 #define _ESP_NETIF_IP_ADDR_H_
9
10 #include <stdint.h>
11 #include <machine/endian.h>
12 #include "sdkconfig.h"
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 #if BYTE_ORDER == BIG_ENDIAN
19 #define esp_netif_htonl(x) ((uint32_t)(x))
20 #else
21 #define esp_netif_htonl(x) ((((x) & (uint32_t)0x000000ffUL) << 24) | \
22 (((x) & (uint32_t)0x0000ff00UL) << 8) | \
23 (((x) & (uint32_t)0x00ff0000UL) >> 8) | \
24 (((x) & (uint32_t)0xff000000UL) >> 24))
25 #endif
26
27 #define esp_netif_ip4_makeu32(a,b,c,d) (((uint32_t)((a) & 0xff) << 24) | \
28 ((uint32_t)((b) & 0xff) << 16) | \
29 ((uint32_t)((c) & 0xff) << 8) | \
30 (uint32_t)((d) & 0xff))
31
32 // Access address in 16-bit block
33 #define ESP_IP6_ADDR_BLOCK1(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[0]) >> 16) & 0xffff))
34 #define ESP_IP6_ADDR_BLOCK2(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[0])) & 0xffff))
35 #define ESP_IP6_ADDR_BLOCK3(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[1]) >> 16) & 0xffff))
36 #define ESP_IP6_ADDR_BLOCK4(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[1])) & 0xffff))
37 #define ESP_IP6_ADDR_BLOCK5(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[2]) >> 16) & 0xffff))
38 #define ESP_IP6_ADDR_BLOCK6(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[2])) & 0xffff))
39 #define ESP_IP6_ADDR_BLOCK7(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[3]) >> 16) & 0xffff))
40 #define ESP_IP6_ADDR_BLOCK8(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[3])) & 0xffff))
41
42 #define IPSTR "%d.%d.%d.%d"
43 #define esp_ip4_addr_get_byte(ipaddr, idx) (((const uint8_t*)(&(ipaddr)->addr))[idx])
44 #define esp_ip4_addr1(ipaddr) esp_ip4_addr_get_byte(ipaddr, 0)
45 #define esp_ip4_addr2(ipaddr) esp_ip4_addr_get_byte(ipaddr, 1)
46 #define esp_ip4_addr3(ipaddr) esp_ip4_addr_get_byte(ipaddr, 2)
47 #define esp_ip4_addr4(ipaddr) esp_ip4_addr_get_byte(ipaddr, 3)
48
49
50 #define esp_ip4_addr1_16(ipaddr) ((uint16_t)esp_ip4_addr1(ipaddr))
51 #define esp_ip4_addr2_16(ipaddr) ((uint16_t)esp_ip4_addr2(ipaddr))
52 #define esp_ip4_addr3_16(ipaddr) ((uint16_t)esp_ip4_addr3(ipaddr))
53 #define esp_ip4_addr4_16(ipaddr) ((uint16_t)esp_ip4_addr4(ipaddr))
54
55 #define IP2STR(ipaddr) esp_ip4_addr1_16(ipaddr), \
56 esp_ip4_addr2_16(ipaddr), \
57 esp_ip4_addr3_16(ipaddr), \
58 esp_ip4_addr4_16(ipaddr)
59
60 #define IPV6STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
61
62 #define IPV62STR(ipaddr) ESP_IP6_ADDR_BLOCK1(&(ipaddr)), \
63 ESP_IP6_ADDR_BLOCK2(&(ipaddr)), \
64 ESP_IP6_ADDR_BLOCK3(&(ipaddr)), \
65 ESP_IP6_ADDR_BLOCK4(&(ipaddr)), \
66 ESP_IP6_ADDR_BLOCK5(&(ipaddr)), \
67 ESP_IP6_ADDR_BLOCK6(&(ipaddr)), \
68 ESP_IP6_ADDR_BLOCK7(&(ipaddr)), \
69 ESP_IP6_ADDR_BLOCK8(&(ipaddr))
70
71 #define ESP_IPADDR_TYPE_V4 0U
72 #define ESP_IPADDR_TYPE_V6 6U
73 #define ESP_IPADDR_TYPE_ANY 46U
74
75 #define ESP_IP4TOUINT32(a,b,c,d) (((uint32_t)((a) & 0xffU) << 24) | \
76 ((uint32_t)((b) & 0xffU) << 16) | \
77 ((uint32_t)((c) & 0xffU) << 8) | \
78 (uint32_t)((d) & 0xffU))
79
80 #define ESP_IP4TOADDR(a,b,c,d) esp_netif_htonl(ESP_IP4TOUINT32(a, b, c, d))
81
82 #define ESP_IP4ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V4, .u_addr = { .ip4 = { .addr = ESP_IP4TOADDR(a, b, c, d) }}};
83 #define ESP_IP6ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V6, .u_addr = { .ip6 = { .addr = { a, b, c, d }, .zone = 0 }}};
84
85 #ifndef IP4ADDR_STRLEN_MAX
86 #define IP4ADDR_STRLEN_MAX 16
87 #endif
88
89 #if defined(CONFIG_LWIP_IPV4) && defined(CONFIG_LWIP_IPV6)
90 #define ESP_IP_IS_ANY(addr) ((addr.type == ESP_IPADDR_TYPE_V4 && ip4_addr_isany_val(addr.u_addr.ip4)) || \
91 (addr.type == ESP_IPADDR_TYPE_V6 && ip6_addr_isany_val(addr.u_addr.ip6)))
92 #elif defined(CONFIG_LWIP_IPV4)
93 #define ESP_IP_IS_ANY(addr) (ip4_addr_isany_val(addr.u_addr.ip4))
94 #elif defined(CONFIG_LWIP_IPV6)
95 #define ESP_IP_IS_ANY(addr) (ip6_addr_isany_val(addr.u_addr.ip6))
96 #endif
97
98 /**
99 * @brief IPv6 address
100 *
101 */
102 struct esp_ip6_addr {
103 uint32_t addr[4]; /*!< IPv6 address */
104 uint8_t zone; /*!< zone ID */
105 };
106
107 /**
108 * @brief IPv4 address
109 *
110 */
111 struct esp_ip4_addr {
112 uint32_t addr; /*!< IPv4 address */
113 };
114
115 typedef struct esp_ip4_addr esp_ip4_addr_t;
116
117 typedef struct esp_ip6_addr esp_ip6_addr_t;
118
119 /**
120 * @brief IP address
121 *
122 */
123 typedef struct _ip_addr {
124 union {
125 esp_ip6_addr_t ip6; /*!< IPv6 address type */
126 esp_ip4_addr_t ip4; /*!< IPv4 address type */
127 } u_addr; /*!< IP address union */
128 uint8_t type; /*!< ipaddress type */
129 } esp_ip_addr_t;
130
131 typedef enum {
132 ESP_IP6_ADDR_IS_UNKNOWN,
133 ESP_IP6_ADDR_IS_GLOBAL,
134 ESP_IP6_ADDR_IS_LINK_LOCAL,
135 ESP_IP6_ADDR_IS_SITE_LOCAL,
136 ESP_IP6_ADDR_IS_UNIQUE_LOCAL,
137 ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6
138 } esp_ip6_addr_type_t;
139
140 /**
141 * @brief Get the IPv6 address type
142 *
143 * @param[in] ip6_addr IPv6 type
144 *
145 * @return IPv6 type in form of enum esp_ip6_addr_type_t
146 */
147 esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr);
148
149 /**
150 * @brief Copy IP addresses
151 *
152 * @param[out] dest destination IP
153 * @param[in] src source IP
154 */
esp_netif_ip_addr_copy(esp_ip_addr_t * dest,const esp_ip_addr_t * src)155 static inline void esp_netif_ip_addr_copy(esp_ip_addr_t *dest, const esp_ip_addr_t *src)
156 {
157 dest->type = src->type;
158 if (src->type == ESP_IPADDR_TYPE_V6) {
159 dest->u_addr.ip6.addr[0] = src->u_addr.ip6.addr[0];
160 dest->u_addr.ip6.addr[1] = src->u_addr.ip6.addr[1];
161 dest->u_addr.ip6.addr[2] = src->u_addr.ip6.addr[2];
162 dest->u_addr.ip6.addr[3] = src->u_addr.ip6.addr[3];
163 dest->u_addr.ip6.zone = src->u_addr.ip6.zone;
164 } else {
165 dest->u_addr.ip4.addr = src->u_addr.ip4.addr;
166 dest->u_addr.ip6.addr[1] = 0;
167 dest->u_addr.ip6.addr[2] = 0;
168 dest->u_addr.ip6.addr[3] = 0;
169 dest->u_addr.ip6.zone = 0;
170 }
171 }
172
173 #ifdef __cplusplus
174 }
175 #endif
176
177 #endif //_ESP_NETIF_IP_ADDR_H_
178