From 60a456f75721ce31b1fd7f5ac80fd7586f7c33cf Mon Sep 17 00:00:00 2001 From: goldsimon Date: Mon, 5 Jul 2010 14:20:58 +0000 Subject: [PATCH] Added ip_addr_netmask_valid() to check if a netmask is valid (starting with ones, then only zeros) --- src/core/ipv4/ip_addr.c | 35 ++++++++++++++++++++++++++++++--- src/include/ipv4/lwip/ip_addr.h | 3 +++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/core/ipv4/ip_addr.c b/src/core/ipv4/ip_addr.c index 58c92aff..7e953d37 100644 --- a/src/core/ipv4/ip_addr.c +++ b/src/core/ipv4/ip_addr.c @@ -51,7 +51,8 @@ const ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST }; * @param netif the network interface against which the address is checked * @return returns non-zero if the address is a broadcast address */ -u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) +u8_t +ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) { ip_addr_t ipaddr; ip4_addr_set_u32(&ipaddr, addr); @@ -80,6 +81,34 @@ u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) } } +/** Checks if a netmask is valid (starting with ones, then only zeros) + * + * @param netmask the IPv4 netmask to check (in network byte order!) + * @return 1 if the netmask is valid, 0 if it is not + */ +u8_t +ip4_addr_netmask_valid(u32_t netmask) +{ + u32_t mask; + u32_t nm_hostorder = lwip_htonl(netmask); + + /* first, check for the first zero */ + for (mask = 1U << 31 ; mask != 0; mask >>= 1) { + if ((nm_hostorder & mask) == 0) { + break; + } + } + /* then check that there is no one */ + for (; mask != 0; mask >>= 1) { + if ((nm_hostorder & mask) != 0) { + /* there is a one after the first zero -> invalid */ + return 0; + } + } + /* no one after the first zero -> valid */ + return 1; +} + /* Here for now until needed in other places in lwIP */ #ifndef isprint #define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) @@ -88,8 +117,8 @@ u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) #define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) #define islower(c) in_range(c, 'a', 'z') #define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') -#endif - +#endif + /** * Ascii internet address interpretation routine. * The value returned is in network order. diff --git a/src/include/ipv4/lwip/ip_addr.h b/src/include/ipv4/lwip/ip_addr.h index 4d3e38ad..77f84e02 100644 --- a/src/include/ipv4/lwip/ip_addr.h +++ b/src/include/ipv4/lwip/ip_addr.h @@ -202,6 +202,9 @@ extern const ip_addr_t ip_addr_broadcast; #define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); +#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) +u8_t ip4_addr_netmask_valid(u32_t netmask); + #define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) #define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL))