4#ifndef SRC_SUPLA_NETWORK_NETIF_CONFIG_H_
5#define SRC_SUPLA_NETWORK_NETIF_CONFIG_H_
14enum class NetifIpMode : uint8_t {
19constexpr uint8_t NETIF_CONFIG_BLOB_VERSION = 1;
23 uint8_t version = NETIF_CONFIG_BLOB_VERSION;
24 uint8_t ipMode =
static_cast<uint8_t
>(NetifIpMode::DHCP);
25 uint8_t reserved[2] = {};
35 "Unexpected NetifConfigBlob size");
37inline bool parseUnsignedDecimal(
const char* text,
40 if (text ==
nullptr || result ==
nullptr || text[0] ==
'\0') {
45 for (
const char* ptr = text; *ptr; ++ptr) {
46 if (*ptr <
'0' || *ptr >
'9') {
49 uint32_t digit =
static_cast<uint32_t
>(*ptr -
'0');
50 if (value > (UINT32_MAX - digit) / 10) {
53 value = value * 10 + digit;
54 if (value > maxValue) {
63inline bool parseUnsignedDecimalRange(
const char* begin,
67 if (begin ==
nullptr || end ==
nullptr || result ==
nullptr ||
73 for (
const char* ptr = begin; ptr < end; ++ptr) {
74 if (*ptr <
'0' || *ptr >
'9') {
77 uint32_t digit =
static_cast<uint32_t
>(*ptr -
'0');
78 if (value > (UINT32_MAX - digit) / 10) {
81 value = value * 10 + digit;
82 if (value > maxValue) {
91inline bool parseIpv4Address(
const char* text, uint32_t* result) {
92 if (text ==
nullptr || result ==
nullptr) {
97 const char* ptr = text;
98 for (
int i = 0; i < 4; i++) {
99 const char* end = (i < 3) ? strchr(ptr,
'.') : ptr + strlen(ptr);
100 if (end ==
nullptr) {
104 if (!parseUnsignedDecimalRange(ptr, end, &value, 255)) {
115 }
else if (*end !=
'\0') {
132inline bool formatIpv4Address(uint32_t ip,
char* out,
size_t outSize) {
133 if (out ==
nullptr || outSize == 0) {
137 int size = snprintf(out,
140 static_cast<unsigned int>((ip >> 24) & 0xFF),
141 static_cast<unsigned int>((ip >> 16) & 0xFF),
142 static_cast<unsigned int>((ip >> 8) & 0xFF),
143 static_cast<unsigned int>(ip & 0xFF));
144 return size > 0 &&
static_cast<size_t>(size) < outSize;
147inline bool isValidNetmask(uint32_t netmask) {
152 uint32_t inverted = ~netmask;
153 return (inverted & (inverted + 1)) == 0;
156inline bool isValidIpv4Address(uint32_t ip) {
157 uint8_t firstOctet =
static_cast<uint8_t
>((ip >> 24) & 0xFF);
158 if (ip == 0 || ip == 0xFFFFFFFFu) {
161 if (firstOctet == 127) {
164 if (firstOctet >= 224) {
170inline bool isSameSubnet(uint32_t ip, uint32_t netmask, uint32_t gateway) {
171 return (ip & netmask) == (gateway & netmask);
174inline bool isUsableSubnetHostAddress(uint32_t ip, uint32_t netmask) {
175 uint32_t hostMask = ~netmask;
180 uint32_t hostPart = ip & hostMask;
181 return hostPart != 0 && hostPart != hostMask;
184inline bool parseNetmaskOrPrefix(
const char* text, uint32_t* result) {
185 if (text ==
nullptr || result ==
nullptr) {
189 if (text[0] ==
'/') {
193 if (strchr(text,
'.') !=
nullptr) {
194 if (!parseIpv4Address(text, result)) {
197 return isValidNetmask(*result);
201 if (!parseUnsignedDecimal(text, &prefix, 32)) {
204 if (prefix == 0 || prefix > 32) {
209 *result = 0xFFFFFFFFu;
211 *result = 0xFFFFFFFFu << (32 - prefix);
213 return isValidNetmask(*result);
216inline void normalizeDhcpNetifConfig(NetifConfigBlob* cfg) {
217 if (cfg ==
nullptr) {
221 cfg->version = NETIF_CONFIG_BLOB_VERSION;
222 cfg->ipMode =
static_cast<uint8_t
>(NetifIpMode::DHCP);
223 cfg->reserved[0] = 0;
224 cfg->reserved[1] = 0;
232inline bool isValidStaticNetifConfig(
const NetifConfigBlob& cfg) {
233 if (cfg.version != NETIF_CONFIG_BLOB_VERSION) {
236 if (cfg.ipMode !=
static_cast<uint8_t
>(NetifIpMode::Static)) {
240 if (!isValidIpv4Address(cfg.ip) || !isValidNetmask(cfg.netmask) ||
241 !isUsableSubnetHostAddress(cfg.ip, cfg.netmask) ||
242 !isValidIpv4Address(cfg.gateway) ||
243 !isUsableSubnetHostAddress(cfg.gateway, cfg.netmask) ||
244 !isSameSubnet(cfg.ip, cfg.netmask, cfg.gateway) ||
245 cfg.ip == cfg.gateway ||
246 !isValidIpv4Address(cfg.dns1)) {
250 if (cfg.dns2 != 0 && !isValidIpv4Address(cfg.dns2)) {
257inline bool isValidNetifConfigBlob(
const NetifConfigBlob& cfg) {
258 if (cfg.version != NETIF_CONFIG_BLOB_VERSION) {
261 if (cfg.ipMode ==
static_cast<uint8_t
>(NetifIpMode::DHCP)) {
264 if (cfg.ipMode ==
static_cast<uint8_t
>(NetifIpMode::Static)) {
265 return isValidStaticNetifConfig(cfg);
Definition netif_config.h:22