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