00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <net-snmp/net-snmp-config.h>
00021
00022 #ifndef HAVE_INET_PTON
00023
00024 #if HAVE_ARPA_NAMESER_H
00025 #include <arpa/nameser.h>
00026 #endif
00027
00028
00029
00030
00031 #if defined(HAVE_WINSOCK_H) || defined(cygwin)
00032 #include <winsock2.h>
00033 #include <ws2tcpip.h>
00034 #include <errno.h>
00035 #include <stdio.h>
00036 #endif
00037
00038 #ifndef EAFNOSUPPORT
00039 #define EAFNOSUPPORT WSAEAFNOSUPPORT
00040 #endif
00041
00042 #ifndef IN6ADDRSZ
00043 #define IN6ADDRSZ 16
00044 #endif
00045
00046 #ifndef INT16SZ
00047 #define INT16SZ 2
00048 #endif
00049
00050
00051
00052
00053 #ifndef INADDRSZ
00054 #define INADDRSZ 4
00055 #endif
00056
00057
00058
00059
00060
00061
00062 static int inet_pton4(const char *src, u_char *dst, int pton);
00063 #ifdef INET6
00064 static int inet_pton6(const char *src, u_char *dst);
00065 #endif
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 int
00079 inet_pton(af, src, dst)
00080 int af;
00081 const char *src;
00082 void *dst;
00083 {
00084
00085 switch (af) {
00086 case AF_INET:
00087 return (inet_pton4(src, dst, 1));
00088 #ifdef INET6
00089 case AF_INET6:
00090 return (inet_pton6(src, dst));
00091 #endif
00092 default:
00093 errno = EAFNOSUPPORT;
00094 return (-1);
00095 }
00096
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 static int
00111 inet_pton4(src, dst, pton)
00112 const char *src;
00113 u_char *dst;
00114 int pton;
00115 {
00116 u_int val;
00117 u_int digit;
00118 int base, n;
00119 unsigned char c;
00120 u_int parts[4];
00121 register u_int *pp = parts;
00122
00123 c = *src;
00124 for (;;) {
00125
00126
00127
00128
00129
00130 if (!isdigit(c))
00131 return (0);
00132 val = 0; base = 10;
00133 if (c == '0') {
00134 c = *++src;
00135 if (c == 'x' || c == 'X')
00136 base = 16, c = *++src;
00137 else if (isdigit(c) && c != '9')
00138 base = 8;
00139 }
00140
00141 if (pton && base != 10)
00142 return (0);
00143 for (;;) {
00144 if (isdigit(c)) {
00145 digit = c - '0';
00146 if ((int)digit >= base)
00147 break;
00148 val = (val * base) + digit;
00149 c = *++src;
00150 } else if (base == 16 && isxdigit(c)) {
00151 digit = c + 10 - (islower(c) ? 'a' : 'A');
00152 if (digit >= 16)
00153 break;
00154 val = (val << 4) | digit;
00155 c = *++src;
00156 } else
00157 break;
00158 }
00159 if (c == '.') {
00160
00161
00162
00163
00164
00165
00166
00167 if (pp >= parts + 3)
00168 return (0);
00169 *pp++ = val;
00170 c = *++src;
00171 } else
00172 break;
00173 }
00174
00175
00176
00177 if (c != '\0' && !isspace(c))
00178 return (0);
00179
00180
00181
00182
00183 n = pp - parts + 1;
00184
00185 if (pton && n != 4)
00186 return (0);
00187 switch (n) {
00188
00189 case 0:
00190 return (0);
00191
00192 case 1:
00193 break;
00194
00195 case 2:
00196 if (parts[0] > 0xff || val > 0xffffff)
00197 return (0);
00198 val |= parts[0] << 24;
00199 break;
00200
00201 case 3:
00202 if ((parts[0] | parts[1]) > 0xff || val > 0xffff)
00203 return (0);
00204 val |= (parts[0] << 24) | (parts[1] << 16);
00205 break;
00206
00207 case 4:
00208 if ((parts[0] | parts[1] | parts[2] | val) > 0xff)
00209 return (0);
00210 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
00211 break;
00212 }
00213 if (dst) {
00214 val = htonl(val);
00215 memcpy(dst, &val, INADDRSZ);
00216 }
00217 return (1);
00218 }
00219
00220 #ifdef INET6
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 static int
00235 inet_pton6(src, dst)
00236 const char *src;
00237 u_char *dst;
00238 {
00239 static const char xdigits_l[] = "0123456789abcdef",
00240 xdigits_u[] = "0123456789ABCDEF";
00241 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
00242 const char *xdigits, *curtok;
00243 int ch, saw_xdigit;
00244 u_int val;
00245
00246 memset((tp = tmp), '\0', IN6ADDRSZ);
00247 endp = tp + IN6ADDRSZ;
00248 colonp = NULL;
00249
00250 if (*src == ':')
00251 if (*++src != ':')
00252 return (0);
00253 curtok = src;
00254 saw_xdigit = 0;
00255 val = 0;
00256 while ((ch = *src++) != '\0') {
00257 const char *pch;
00258
00259 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
00260 pch = strchr((xdigits = xdigits_u), ch);
00261 if (pch != NULL) {
00262 val <<= 4;
00263 val |= (pch - xdigits);
00264 if (val > 0xffff)
00265 return (0);
00266 saw_xdigit = 1;
00267 continue;
00268 }
00269 if (ch == ':') {
00270 curtok = src;
00271 if (!saw_xdigit) {
00272 if (colonp)
00273 return (0);
00274 colonp = tp;
00275 continue;
00276 } else if (*src == '\0')
00277 return (0);
00278 if (tp + INT16SZ > endp)
00279 return (0);
00280 *tp++ = (u_char) (val >> 8) & 0xff;
00281 *tp++ = (u_char) val & 0xff;
00282 saw_xdigit = 0;
00283 val = 0;
00284 continue;
00285 }
00286 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
00287 inet_pton4(curtok, tp, 1) > 0) {
00288 tp += INADDRSZ;
00289 saw_xdigit = 0;
00290 break;
00291 }
00292 return (0);
00293 }
00294 if (saw_xdigit) {
00295 if (tp + INT16SZ > endp)
00296 return (0);
00297 *tp++ = (u_char) (val >> 8) & 0xff;
00298 *tp++ = (u_char) val & 0xff;
00299 }
00300 if (colonp != NULL) {
00301
00302
00303
00304
00305 const int n = tp - colonp;
00306 int i;
00307
00308 if (tp == endp)
00309 return (0);
00310 for (i = 1; i <= n; i++) {
00311 endp[- i] = colonp[n - i];
00312 colonp[n - i] = 0;
00313 }
00314 tp = endp;
00315 }
00316 if (tp != endp)
00317 return (0);
00318 memcpy(dst, tmp, IN6ADDRSZ);
00319 return (1);
00320 }
00321 #endif
00322
00323 #endif