ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
ip_address.h
Go to the documentation of this file.
1#pragma once
3#ifdef USE_NETWORK
4#include <cstdint>
5#include <string>
6#include <cstdio>
7#include <array>
8#include <cstring>
10#include "esphome/core/macros.h"
11
12#if defined(USE_ESP32) || defined(USE_LIBRETINY) || USE_ARDUINO_VERSION_CODE > VERSION_CODE(3, 0, 0)
13#include <lwip/ip_addr.h>
14#endif
15#if USE_ARDUINO
16#include <Arduino.h>
17#include <IPAddress.h>
18#endif /* USE_ADRDUINO */
19
20#ifdef USE_HOST
21#include <arpa/inet.h>
22using ip_addr_t = in_addr;
23using ip4_addr_t = in_addr;
24#define ipaddr_aton(x, y) inet_aton((x), (y))
25#endif
26
27#ifdef USE_ZEPHYR
28#include <zephyr/net/net_ip.h>
29#include <zephyr/net/socket.h>
30#include <zephyr/posix/arpa/inet.h>
31using ip_addr_t = struct in6_addr;
32static inline int ipaddr_aton(const char *cp, ip_addr_t *addr) { return inet_pton(AF_INET6, cp, addr) == 1 ? 1 : 0; }
33#endif
34
35#if USE_ESP32_FRAMEWORK_ARDUINO
36#define arduino_ns Arduino_h
37#elif USE_LIBRETINY
38#define arduino_ns arduino
39#elif USE_ARDUINO
40#define arduino_ns
41#endif
42
43#ifdef USE_ESP32
44#include <esp_netif.h>
45#endif
46
48
50static constexpr size_t IP_ADDRESS_BUFFER_SIZE = 40;
51
53inline void lowercase_ip_str(char *buf) {
54 for (char *p = buf; *p; ++p) {
55 if (*p >= 'A' && *p <= 'F')
56 *p += 32;
57 }
58}
59
60struct IPAddress {
61 public:
62#ifdef USE_ZEPHYR
63 IPAddress() { memset(&ip_addr_, 0, sizeof(ip_addr_)); }
64 IPAddress(const std::string &in_address) : ip_addr_{} { ipaddr_aton(in_address.c_str(), &ip_addr_); }
65 IPAddress(const struct in6_addr *other_ip) { ip_addr_ = *other_ip; }
66 IPAddress(const struct sockaddr_in6 *addr) { ip_addr_ = addr->sin6_addr; }
67
68 operator struct in6_addr() const { return ip_addr_; }
69
70 bool is_set() const { return !net_ipv6_is_addr_unspecified(&ip_addr_); }
71 bool is_ip4() const { return false; }
72 bool is_ip6() const { return this->is_set(); }
73 bool is_multicast() const { return net_ipv6_is_addr_mcast(&ip_addr_); }
74 // Remove before 2026.8.0
76 "str() is deprecated: use 'char buf[IP_ADDRESS_BUFFER_SIZE]; ip.str_to(buf);' instead. Removed in 2026.8.0",
77 "2026.2.0")
78 std::string str() const {
79 char buf[IP_ADDRESS_BUFFER_SIZE];
80 this->str_to(buf);
81 return buf;
82 }
83 char *str_to(char *buf) const {
84 if (inet_ntop(AF_INET6, &ip_addr_, buf, IP_ADDRESS_BUFFER_SIZE) == nullptr)
85 buf[0] = '\0';
86 return buf;
87 }
88 bool operator==(const IPAddress &other) const { return net_ipv6_addr_cmp(&ip_addr_, &other.ip_addr_); }
89 bool operator!=(const IPAddress &other) const { return !net_ipv6_addr_cmp(&ip_addr_, &other.ip_addr_); }
90
91#elif defined(USE_HOST)
92 IPAddress() { ip_addr_.s_addr = 0; }
93 IPAddress(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth) {
94 this->ip_addr_.s_addr = htonl((first << 24) | (second << 16) | (third << 8) | fourth);
95 }
96 IPAddress(const std::string &in_address) { inet_aton(in_address.c_str(), &ip_addr_); }
97 IPAddress(const ip_addr_t *other_ip) { ip_addr_ = *other_ip; }
98 // Remove before 2026.8.0
100 "str() is deprecated: use 'char buf[IP_ADDRESS_BUFFER_SIZE]; ip.str_to(buf);' instead. Removed in 2026.8.0",
101 "2026.2.0")
102 std::string str() const {
103 char buf[IP_ADDRESS_BUFFER_SIZE];
104 this->str_to(buf);
105 return buf;
106 }
108 char *str_to(char *buf) const {
109 inet_ntop(AF_INET, &ip_addr_, buf, IP_ADDRESS_BUFFER_SIZE);
110 return buf; // IPv4 only, no hex letters to lowercase
111 }
112#else
113 IPAddress() { ip_addr_set_zero(&ip_addr_); }
114 IPAddress(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth) {
115 IP_ADDR4(&ip_addr_, first, second, third, fourth);
116 }
117 IPAddress(const ip_addr_t *other_ip) { ip_addr_copy(ip_addr_, *other_ip); }
118 IPAddress(const char *in_address) { ipaddr_aton(in_address, &ip_addr_); }
119 IPAddress(const std::string &in_address) { ipaddr_aton(in_address.c_str(), &ip_addr_); }
121 memcpy((void *) &ip_addr_, (void *) other_ip, sizeof(ip4_addr_t));
122#if USE_ESP32 && LWIP_IPV6
123 ip_addr_.type = IPADDR_TYPE_V4;
124#endif
125 }
126#if USE_ARDUINO
127 IPAddress(const arduino_ns::IPAddress &other_ip) { ip_addr_set_ip4_u32(&ip_addr_, other_ip); }
128#endif
129#if LWIP_IPV6
130 IPAddress(ip6_addr_t *other_ip) {
131 memcpy((void *) &ip_addr_, (void *) other_ip, sizeof(ip6_addr_t));
132 ip_addr_.type = IPADDR_TYPE_V6;
133 }
134#endif /* LWIP_IPV6 */
135
136#ifdef USE_ESP32
137#if LWIP_IPV6
138 IPAddress(esp_ip6_addr_t *other_ip) {
139 memcpy((void *) &ip_addr_.u_addr.ip6, (void *) other_ip, sizeof(esp_ip6_addr_t));
140 ip_addr_.type = IPADDR_TYPE_V6;
141 }
142#endif /* LWIP_IPV6 */
143 IPAddress(esp_ip4_addr_t *other_ip) {
144 memcpy((void *) &ip_addr_, (void *) other_ip, sizeof(esp_ip4_addr_t));
145#if LWIP_IPV6
146 ip_addr_.type = IPADDR_TYPE_V4;
147#endif
148 }
149 IPAddress(esp_ip_addr_t *other_ip) {
150#if LWIP_IPV6
151 memcpy((void *) &ip_addr_, (void *) other_ip, sizeof(ip_addr_));
152#else
153 memcpy((void *) &ip_addr_, (void *) &other_ip->u_addr.ip4, sizeof(ip_addr_));
154#endif
155 }
156 operator esp_ip_addr_t() const {
157 esp_ip_addr_t tmp;
158#if LWIP_IPV6
159 memcpy((void *) &tmp, (void *) &ip_addr_, sizeof(ip_addr_));
160#else
161 memcpy((void *) &tmp.u_addr.ip4, (void *) &ip_addr_, sizeof(ip_addr_));
162#endif /* LWIP_IPV6 */
163 return tmp;
164 }
165 operator esp_ip4_addr_t() const {
166 esp_ip4_addr_t tmp;
167#if LWIP_IPV6
168 memcpy((void *) &tmp, (void *) &ip_addr_.u_addr.ip4, sizeof(esp_ip4_addr_t));
169#else
170 memcpy((void *) &tmp, (void *) &ip_addr_, sizeof(ip_addr_));
171#endif /* LWIP_IPV6 */
172 return tmp;
173 }
174#endif /* USE_ESP32 */
175
176 operator ip_addr_t() const { return ip_addr_; }
177#if LWIP_IPV6
178 operator ip4_addr_t() const { return *ip_2_ip4(&ip_addr_); }
179#endif /* LWIP_IPV6 */
180
181#if USE_ARDUINO
182 operator arduino_ns::IPAddress() const { return ip_addr_get_ip4_u32(&ip_addr_); }
183#endif
184
185 bool is_set() const { return !ip_addr_isany(&ip_addr_); } // NOLINT(readability-simplify-boolean-expr)
186 bool is_ip4() const { return IP_IS_V4(&ip_addr_); }
187 bool is_ip6() const { return IP_IS_V6(&ip_addr_); }
188 bool is_multicast() const { return ip_addr_ismulticast(&ip_addr_); }
189 // Remove before 2026.8.0
191 "str() is deprecated: use 'char buf[IP_ADDRESS_BUFFER_SIZE]; ip.str_to(buf);' instead. Removed in 2026.8.0",
192 "2026.2.0")
193 std::string str() const {
194 char buf[IP_ADDRESS_BUFFER_SIZE];
195 this->str_to(buf);
196 return buf;
197 }
200 char *str_to(char *buf) const {
201 ipaddr_ntoa_r(&ip_addr_, buf, IP_ADDRESS_BUFFER_SIZE);
202 lowercase_ip_str(buf);
203 return buf;
204 }
205 bool operator==(const IPAddress &other) const { return ip_addr_cmp(&ip_addr_, &other.ip_addr_); }
206 bool operator!=(const IPAddress &other) const { return !ip_addr_cmp(&ip_addr_, &other.ip_addr_); }
207 IPAddress &operator+=(uint8_t increase) {
208 if (IP_IS_V4(&ip_addr_)) {
209#if LWIP_IPV6
210 (((u8_t *) (&ip_addr_.u_addr.ip4))[3]) += increase;
211#else
212 (((u8_t *) (&ip_addr_.addr))[3]) += increase;
213#endif /* LWIP_IPV6 */
214 }
215 return *this;
216 }
217#endif
218
219 protected:
221};
222
223using IPAddresses = std::array<IPAddress, 5>;
224
225} // namespace esphome::network
226#endif
uint8_t second
in_addr ip_addr_t
Definition ip_address.h:22
in_addr ip4_addr_t
Definition ip_address.h:23
void lowercase_ip_str(char *buf)
Lowercase hex digits in IP address string (A-F -> a-f for IPv6 per RFC 5952)
Definition ip_address.h:53
std::array< IPAddress, 5 > IPAddresses
Definition ip_address.h:223
bool operator!=(const StringRef &lhs, const StringRef &rhs)
Definition string_ref.h:154
std::string & operator+=(std::string &lhs, const StringRef &rhs)
Definition string_ref.h:185
bool operator==(const StringRef &lhs, const StringRef &rhs)
Definition string_ref.h:138
IPAddress(const struct sockaddr_in6 *addr)
Definition ip_address.h:66
IPAddress(const char *in_address)
Definition ip_address.h:118
IPAddress(ip6_addr_t *other_ip)
Definition ip_address.h:130
ESPDEPRECATED("str() is deprecated: use 'char buf[IP_ADDRESS_BUFFER_SIZE]; ip.str_to(buf);' instead. Removed in 2026.8.0", "2026.2.0") std
Definition ip_address.h:75
IPAddress(esp_ip_addr_t *other_ip)
Definition ip_address.h:149
IPAddress(const ip_addr_t *other_ip)
Definition ip_address.h:97
IPAddress(esp_ip6_addr_t *other_ip)
Definition ip_address.h:138
IPAddress(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth)
Definition ip_address.h:93
IPAddress(const struct in6_addr *other_ip)
Definition ip_address.h:65
IPAddress(esp_ip4_addr_t *other_ip)
Definition ip_address.h:143
IPAddress(ip4_addr_t *other_ip)
Definition ip_address.h:120
IPAddress(const std::string &in_address)
Definition ip_address.h:64
IPAddress(const arduino_ns::IPAddress &other_ip)
Definition ip_address.h:127
struct in6_addr sin6_addr
Definition headers.h:79