diff --git a/src/core/inet.c b/src/core/inet.c index c3056f67..91ddec9b 100644 --- a/src/core/inet.c +++ b/src/core/inet.c @@ -168,6 +168,156 @@ inet_chksum_pbuf(struct pbuf *p) return ~(acc & 0xffffUL); } +/*-----------------------------------------------------------------------------------*/ + /* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ + + /* */ + /* inet_addr */ + u32_t inet_addr(const char *cp) + { + struct in_addr val; + + if (inet_aton(cp, &val)) { + return (val.s_addr); + } + return (INADDR_NONE); + } + + /* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ + /* */ + /* inet_aton */ + int inet_aton(const char *cp, struct in_addr *addr) + { + u32_t val; + int base, n; + char c; + u32_t parts[4]; + u32_t* pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); + } + +/* Convert numeric IP address into decimal dotted ASCII representation. + * returns ptr to static buffer; not reentrant! + */ +u8_t *inet_ntoa(u32_t addr) +{ + static u8_t str[16]; + u8_t inv[3]; + u8_t *rp; + u8_t *ap; + u8_t rem; + u8_t n; + u8_t i; + + rp = str; + ap = (u8_t *)&addr; + for(n = 0; n < 4; n++) { + i = 0; + do { + rem = *ap % (u8_t)10; + *ap /= (u8_t)10; + inv[i++] = '0' + rem; + } while(*ap); + while(i--) + *rp++ = inv[i]; + *rp++ = '.'; + ap++; + } + *--rp = 0; + return str; +} + +/*-----------------------------------------------------------------------------------*/ #ifndef BYTE_ORDER #error BYTE_ORDER is not defined #endif diff --git a/src/include/ipv4/lwip/inet.h b/src/include/ipv4/lwip/inet.h index 8b2aa412..f16a2a79 100644 --- a/src/include/ipv4/lwip/inet.h +++ b/src/include/ipv4/lwip/inet.h @@ -43,6 +43,11 @@ u16_t inet_chksum_pbuf(struct pbuf *p); u16_t inet_chksum_pseudo(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t proto, u16_t proto_len); + +u32_t inet_addr(const char *cp); +int inet_aton(const char *cp, struct in_addr *addr); +u8_t *inet_ntoa(u32_t addr); /* returns ptr to static buffer; not reentrant! */ + #ifdef htons #undef htons #endif /* htons */ diff --git a/src/include/ipv4/lwip/ip_addr.h b/src/include/ipv4/lwip/ip_addr.h index 75daaff8..0fdf02af 100644 --- a/src/include/ipv4/lwip/ip_addr.h +++ b/src/include/ipv4/lwip/ip_addr.h @@ -40,6 +40,42 @@ #define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any) #define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast) +#define INADDR_NONE ((u32_t) 0xffffffff) /* 255.255.255.255 */ +#define INADDR_LOOPBACK ((u32_t) 0x7f000001) /* 127.0.0.1 */ + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ + +#define IN_CLASSA(a) ((((u32_t)(a)) & 0x80000000) == 0) +#define IN_CLASSA_NET 0xff000000 +#define IN_CLASSA_NSHIFT 24 +#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) +#define IN_CLASSA_MAX 128 + +#define IN_CLASSB(a) ((((u32_t)(a)) & 0xc0000000) == 0x80000000) +#define IN_CLASSB_NET 0xffff0000 +#define IN_CLASSB_NSHIFT 16 +#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) +#define IN_CLASSB_MAX 65536 + +#define IN_CLASSC(a) ((((u32_t)(a)) & 0xe0000000) == 0xc0000000) +#define IN_CLASSC_NET 0xffffff00 +#define IN_CLASSC_NSHIFT 8 +#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) + +#define IN_CLASSD(a) (((u32_t)(a) & 0xf0000000) == 0xe0000000) +#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */ +#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */ +#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */ +#define IN_MULTICAST(a) IN_CLASSD(a) + +#define IN_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000) == 0xf0000000) +#define IN_BADCLASS(a) (((u32_t)(a) & 0xf0000000) == 0xf0000000) + +#define IN_LOOPBACKNET 127 /* official! */ + #ifdef PACK_STRUCT_USE_INCLUDES # include "arch/bpstruct.h" #endif @@ -52,6 +88,11 @@ PACK_STRUCT_END # include "arch/epstruct.h" #endif +/* For compatibility with BSD code */ +struct in_addr { + u32_t s_addr; +}; + extern const struct ip_addr ip_addr_any; extern const struct ip_addr ip_addr_broadcast; diff --git a/src/include/ipv6/lwip/inet.h b/src/include/ipv6/lwip/inet.h index bc1f21f4..e32d5e61 100644 --- a/src/include/ipv6/lwip/inet.h +++ b/src/include/ipv6/lwip/inet.h @@ -44,6 +44,8 @@ u16_t inet_chksum_pseudo(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t proto, u32_t proto_len); +u32_t inet_addr(const char *cp); +int inet_aton(const char *cp, struct in_addr *addr); #ifndef _MACHINE_ENDIAN_H_ #ifndef _NETINET_IN_H diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h index 0975ad78..fb5b304d 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h @@ -33,11 +33,7 @@ #ifndef __LWIP_SOCKETS_H__ #define __LWIP_SOCKETS_H__ - -struct in_addr { - u32_t s_addr; -}; - +#include "lwip/ip_addr.h" struct sockaddr_in { u8_t sin_len; @@ -163,7 +159,7 @@ struct linger { #endif #ifndef O_NONBLOCK -#define O_NONBLOCK 04000 +#define O_NONBLOCK 04000U #endif #ifndef FD_SET