diff options
| -rw-r--r-- | docs/defines.txt | 7 | ||||
| -rw-r--r-- | libc/inet/ether_addr.c | 52 | ||||
| -rw-r--r-- | libc/inet/ntop.c | 86 | 
3 files changed, 70 insertions, 75 deletions
diff --git a/docs/defines.txt b/docs/defines.txt index 677335e2f..2af8f0cae 100644 --- a/docs/defines.txt +++ b/docs/defines.txt @@ -40,10 +40,15 @@ __USE_EXTERN_INLINES      out-of-line version of every inlined function in case user program      calls it instead of using an inline.  _EXTERN_INLINE -    Define it to replace "extern __inline" string in inline definitions +    If not defined by user prior to #include, will be defined to +    "extern inline" or equivalent. IOW, if user defines it prior +    #include, it replaces "extern __inline" string in inline definitions      (those enabled by __USE_EXTERN_INLINES) with something else.      A few uclibc .c files use it to create non-inlined functions      by defining it to "". +__extern_inline +    Defined to "extern inline", modulo gcc/C standard deviations. +    Can't be used by user to play tricks as with _EXTERN_INLINE.  _LIBC  UCLIBC_INTERNAL diff --git a/libc/inet/ether_addr.c b/libc/inet/ether_addr.c index 82b067157..621c62989 100644 --- a/libc/inet/ether_addr.c +++ b/libc/inet/ether_addr.c @@ -31,49 +31,45 @@  #include <netinet/ether.h>  #include <netinet/if_ether.h> -/* libc_hidden_proto(ether_ntoa_r) */ -/* libc_hidden_proto(sprintf) */ -#ifdef __UCLIBC_HAS_XLOCALE__ -/* libc_hidden_proto(__ctype_b_loc) */ -/* libc_hidden_proto(__ctype_tolower_loc) */ -#elif defined __UCLIBC_HAS_CTYPE_TABLES__ -/* libc_hidden_proto(__ctype_b) */ -/* libc_hidden_proto(__ctype_tolower) */ -#endif -  struct ether_addr *ether_aton_r(const char *asc, struct ether_addr *addr)  { -	size_t cnt; +	/* asc is "X:XX:XX:x:xx:xX" */ +	int cnt;  	for (cnt = 0; cnt < 6; ++cnt) { -		unsigned int number; +		unsigned char number;  		char ch; -		ch = _tolower(*asc++); +		/* | 0x20 is cheap tolower(), valid for letters/numbers only */ +		ch = (*asc++) | 0x20;  		if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f'))  			return NULL; -		number = isdigit(ch) ? (ch - '0') : (ch - 'a' + 10); - -		ch = _tolower(*asc); -		if ((cnt < 5 && ch != ':') -			|| (cnt == 5 && ch != '\0' && !isspace(ch))) { -			++asc; +		number = !(ch > '9') ? (ch - '0') : (ch - 'a' + 10); + +		ch = *asc++; +		if ((cnt != 5 && ch != ':') /* not last group */ +		/* What standard says ASCII ether address representation +		 * may also finish with whitespace, not only NUL? +		 * We can get rid of isspace() otherwise */ +		 || (cnt == 5 && ch != '\0' /*&& !isspace(ch)*/) +		) { +			ch |= 0x20; /* cheap tolower() */  			if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f'))  				return NULL; -			number <<= 4; -			number += isdigit(ch) ? (ch - '0') : (ch - 'a' + 10); +			number = (number << 4) + (!(ch > '9') ? (ch - '0') : (ch - 'a' + 10)); -			ch = *asc; -			if (cnt < 5 && ch != ':') -				return NULL; +			if (cnt != 5) { +				ch = *asc++; +				if (ch != ':') +					return NULL; +			}  		}  		/* Store result.  */ -		addr->ether_addr_octet[cnt] = (unsigned char) number; - -		/* Skip ':'.  */ -		++asc; +		addr->ether_addr_octet[cnt] = number;  	} +	/* Looks like we allow garbage after last group? +	 * "1:2:3:4:5:66anything_at_all"? */  	return addr;  } diff --git a/libc/inet/ntop.c b/libc/inet/ntop.c index dbc71815a..4583fc47f 100644 --- a/libc/inet/ntop.c +++ b/libc/inet/ntop.c @@ -67,8 +67,8 @@ inet_ntop4(const u_char *src, char *dst, size_t size)  #if 0	/* since src is unsigned char, it will never be > 255 ... */  		if (src[octet] > 255) { -			__set_errno (ENOSPC); -			return (NULL); +			__set_errno(ENOSPC); +			return NULL;  		}  #endif  		tmp[i++] = '0' + src[octet] / 100; @@ -83,9 +83,9 @@ inet_ntop4(const u_char *src, char *dst, size_t size)  	}  	tmp[i - 1] = '\0'; -	if (strlen (tmp) > size) { -		__set_errno (ENOSPC); -		return (NULL); +	if (strlen(tmp) > size) { +		__set_errno(ENOSPC); +		return NULL;  	}  	return strcpy(dst, tmp); @@ -168,7 +168,7 @@ inet_ntop6(const u_char *src, char *dst, size_t size)  		if (i == 6 && best.base == 0 &&  		    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {  			if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) -				return (NULL); +				return NULL;  			tp += strlen(tp);  			break;  		} @@ -183,8 +183,8 @@ inet_ntop6(const u_char *src, char *dst, size_t size)  	 * Check for overflow, copy, and we're done.  	 */  	if ((size_t)(tp - tmp) > size) { -		__set_errno (ENOSPC); -		return (NULL); +		__set_errno(ENOSPC); +		return NULL;  	}  	return strcpy(dst, tmp);  } @@ -216,25 +216,25 @@ inet_pton4(const char *src, u_char *dst)  			u_int new = *tp * 10 + (ch - '0');  			if (new > 255) -				return (0); +				return 0;  			*tp = new;  			if (! saw_digit) {  				if (++octets > 4) -					return (0); +					return 0;  				saw_digit = 1;  			}  		} else if (ch == '.' && saw_digit) {  			if (octets == 4) -				return (0); +				return 0;  			*++tp = 0;  			saw_digit = 0;  		} else -			return (0); +			return 0;  	}  	if (octets < 4) -		return (0); +		return 0;  	memcpy(dst, tmp, 4); -	return (1); +	return 1;  }  /* int @@ -253,13 +253,6 @@ inet_pton4(const char *src, u_char *dst)  #ifdef __UCLIBC_HAS_IPV6__ -/* We cannot use the macro version of tolower() or very bad - * things happen when '*src++' gets evaluated multiple times. - * So undef it here so we get the function version of tolower - * instead. - */ -#undef tolower -  static int  inet_pton6(const char *src, u_char *dst)  { @@ -276,19 +269,20 @@ inet_pton6(const char *src, u_char *dst)  	/* Leading :: requires some special handling. */  	if (*src == ':')  		if (*++src != ':') -			return (0); +			return 0;  	curtok = src;  	saw_xdigit = 0;  	val = 0; -	while ((ch = tolower (*src++)) != '\0') { +	while ((ch = *src++) != '\0') {  		const char *pch; -		pch = strchr(xdigits, ch); +		/* | 0x20 is cheap tolower(), valid for letters/numbers only */ +		pch = strchr(xdigits, (ch | 0x20));  		if (pch != NULL) {  			val <<= 4;  			val |= (pch - xdigits);  			if (val > 0xffff) -				return (0); +				return 0;  			saw_xdigit = 1;  			continue;  		} @@ -296,16 +290,16 @@ inet_pton6(const char *src, u_char *dst)  			curtok = src;  			if (!saw_xdigit) {  				if (colonp) -					return (0); +					return 0;  				colonp = tp;  				continue; -			} else if (*src == '\0') { -				return (0);  			} +			if (*src == '\0') +				return 0;  			if (tp + 2 > endp) -				return (0); -			*tp++ = (u_char) (val >> 8) & 0xff; -			*tp++ = (u_char) val & 0xff; +				return 0; +			*tp++ = (u_char) (val >> 8); +			*tp++ = (u_char) val;  			saw_xdigit = 0;  			val = 0;  			continue; @@ -316,13 +310,13 @@ inet_pton6(const char *src, u_char *dst)  			saw_xdigit = 0;  			break;	/* '\0' was seen by inet_pton4(). */  		} -		return (0); +		return 0;  	}  	if (saw_xdigit) {  		if (tp + 2 > endp) -			return (0); -		*tp++ = (u_char) (val >> 8) & 0xff; -		*tp++ = (u_char) val & 0xff; +			return 0; +		*tp++ = (u_char) (val >> 8); +		*tp++ = (u_char) val;  	}  	if (colonp != NULL) {  		/* @@ -333,7 +327,7 @@ inet_pton6(const char *src, u_char *dst)  		int i;  		if (tp == endp) -			return (0); +			return 0;  		for (i = 1; i <= n; i++) {  			endp[- i] = colonp[n - i];  			colonp[n - i] = 0; @@ -341,9 +335,9 @@ inet_pton6(const char *src, u_char *dst)  		tp = endp;  	}  	if (tp != endp) -		return (0); +		return 0;  	memcpy(dst, tmp, 16); -	return (1); +	return 1;  }  #endif /* __UCLIBC_HAS_IPV6__ */ @@ -364,14 +358,14 @@ inet_ntop(int af, const void *src, char *dst, socklen_t size)  {  	switch (af) {  	case AF_INET: -		return (inet_ntop4(src, dst, size)); +		return inet_ntop4(src, dst, size);  #ifdef __UCLIBC_HAS_IPV6__  	case AF_INET6: -		return (inet_ntop6(src, dst, size)); +		return inet_ntop6(src, dst, size);  #endif  	default: -		__set_errno (EAFNOSUPPORT); -		return (NULL); +		__set_errno(EAFNOSUPPORT); +		return NULL;  	}  	/* NOTREACHED */  } @@ -395,14 +389,14 @@ inet_pton(int af, const char *src, void *dst)  {  	switch (af) {  	case AF_INET: -		return (inet_pton4(src, dst)); +		return inet_pton4(src, dst);  #ifdef __UCLIBC_HAS_IPV6__  	case AF_INET6: -		return (inet_pton6(src, dst)); +		return inet_pton6(src, dst);  #endif  	default: -		__set_errno (EAFNOSUPPORT); -		return (-1); +		__set_errno(EAFNOSUPPORT); +		return -1;  	}  	/* NOTREACHED */  }  | 
