00001
00008 #include <netinet/in.h>
00009 #include <assert.h>
00010 #include <errno.h>
00011 #include "tm_macros.h"
00012 #include "libc_internal.h"
00013
00014 #undef htons
00015 #undef ntohs
00016
00017 #define NS_INADDRSZ 4
00018
00019
00020 TM_WAIVER unsigned long int strtoul(const char *nptr, char **endptr, int base);
00021 TM_WAIVER int isspace(int c);
00022
00023 uint16_t
00024 txc_libc_htons (uint16_t x)
00025 {
00026 #if BYTE_ORDER == BIG_ENDIAN
00027 return x;
00028 #elif BYTE_ORDER == LITTLE_ENDIAN
00029 return __bswap_16 (x);
00030 #else
00031 # error "What kind of system is this?"
00032 #endif
00033 }
00034
00035
00036
00037
00038
00039
00040
00041
00042 int
00043 txc_libc_inet_aton(const char *cp, struct in_addr *addr)
00044 {
00045 u_long parts[4];
00046 in_addr_t val;
00047 char *c;
00048 char *endptr;
00049 int gotend, n;
00050
00051 c = (char *)cp;
00052 n = 0;
00053
00054
00055
00056
00057 TM_BEGIN
00058 gotend = 0;
00059 while (!gotend) {
00060 errno = 0;
00061 val = strtoul(c, &endptr, 0);
00062
00063 if (errno == ERANGE)
00064 return (0);
00065
00066
00067
00068
00069
00070
00071
00072 if (endptr == c)
00073 return (0);
00074 parts[n] = val;
00075 c = endptr;
00076
00077
00078 switch (*c) {
00079 case '.' :
00080
00081 if (n == 3)
00082 return (0);
00083 n++;
00084 c++;
00085 break;
00086
00087 case '\0':
00088 gotend = 1;
00089 break;
00090
00091 default:
00092 if (isspace((unsigned char)*c)) {
00093 gotend = 1;
00094 break;
00095 } else
00096 return (0);
00097 }
00098
00099 }
00100
00101
00102
00103
00104
00105
00106 switch (n) {
00107 case 0:
00108
00109
00110
00111
00112 break;
00113 case 1:
00114 if (val > 0xffffff || parts[0] > 0xff)
00115 return (0);
00116 val |= parts[0] << 24;
00117 break;
00118
00119 case 2:
00120 if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)
00121 return (0);
00122 val |= (parts[0] << 24) | (parts[1] << 16);
00123 break;
00124
00125 case 3:
00126 if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||
00127 parts[2] > 0xff)
00128 return (0);
00129 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
00130 break;
00131 }
00132
00133 if (addr != NULL)
00134 addr->s_addr = htonl(val);
00135 return (1);
00136
00137 TM_END
00138 }
00139
00140
00141 TM_WAIVER
00142 static int inet_ntop4_sprintf(char *tmp, const char *fmt, const u_char arg1, const u_char arg2, const u_char arg3, const u_char arg4) {
00143 return sprintf(tmp, fmt, arg1, arg2, arg3, arg4);
00144 }
00145
00146
00147 TM_CALLABLE
00148 static const char *
00149 inet_ntop4(const u_char *src, char *dst, socklen_t size)
00150 {
00151
00152 char tmp[sizeof "255.255.255.255"];
00153
00154 TM_BEGIN
00155
00156 if (inet_ntop4_sprintf(tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]) >= size) {
00157 errno = ENOSPC;
00158
00159 return (NULL);
00160 }
00161 return strcpy(dst, tmp);
00162 TM_END
00163 }
00164
00165 const char *
00166 txc_libc_inet_ntop(int af, const void *src, char *dst, socklen_t size)
00167 {
00168 TM_BEGIN
00169 switch (af) {
00170 case AF_INET:
00171 return (inet_ntop4(src, dst, size));
00172 case AF_INET6:
00173 assert(0);
00174 default:
00175 errno = EAFNOSUPPORT;
00176
00177 return (NULL);
00178 }
00179 TM_END
00180 }
00181