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