Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "curl_setup.h"
00020
00021 #ifndef HAVE_INET_PTON
00022
00023 #ifdef HAVE_SYS_PARAM_H
00024 #include <sys/param.h>
00025 #endif
00026 #ifdef HAVE_NETINET_IN_H
00027 #include <netinet/in.h>
00028 #endif
00029 #ifdef HAVE_ARPA_INET_H
00030 #include <arpa/inet.h>
00031 #endif
00032
00033 #include "inet_pton.h"
00034
00035 #define IN6ADDRSZ 16
00036 #define INADDRSZ 4
00037 #define INT16SZ 2
00038
00039
00040
00041
00042
00043
00044 static int inet_pton4(const char *src, unsigned char *dst);
00045 #ifdef ENABLE_IPV6
00046 static int inet_pton6(const char *src, unsigned char *dst);
00047 #endif
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 int
00066 Curl_inet_pton(int af, const char *src, void *dst)
00067 {
00068 switch(af) {
00069 case AF_INET:
00070 return (inet_pton4(src, (unsigned char *)dst));
00071 #ifdef ENABLE_IPV6
00072 case AF_INET6:
00073 return (inet_pton6(src, (unsigned char *)dst));
00074 #endif
00075 default:
00076 SET_ERRNO(EAFNOSUPPORT);
00077 return (-1);
00078 }
00079
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 static int
00093 inet_pton4(const char *src, unsigned char *dst)
00094 {
00095 static const char digits[] = "0123456789";
00096 int saw_digit, octets, ch;
00097 unsigned char tmp[INADDRSZ], *tp;
00098
00099 saw_digit = 0;
00100 octets = 0;
00101 tp = tmp;
00102 *tp = 0;
00103 while((ch = *src++) != '\0') {
00104 const char *pch;
00105
00106 pch = strchr(digits, ch);
00107 if(pch) {
00108 unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
00109
00110 if(saw_digit && *tp == 0)
00111 return (0);
00112 if(val > 255)
00113 return (0);
00114 *tp = (unsigned char)val;
00115 if(! saw_digit) {
00116 if(++octets > 4)
00117 return (0);
00118 saw_digit = 1;
00119 }
00120 }
00121 else if(ch == '.' && saw_digit) {
00122 if(octets == 4)
00123 return (0);
00124 *++tp = 0;
00125 saw_digit = 0;
00126 }
00127 else
00128 return (0);
00129 }
00130 if(octets < 4)
00131 return (0);
00132 memcpy(dst, tmp, INADDRSZ);
00133 return (1);
00134 }
00135
00136 #ifdef ENABLE_IPV6
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 static int
00151 inet_pton6(const char *src, unsigned char *dst)
00152 {
00153 static const char xdigits_l[] = "0123456789abcdef",
00154 xdigits_u[] = "0123456789ABCDEF";
00155 unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
00156 const char *xdigits, *curtok;
00157 int ch, saw_xdigit;
00158 size_t val;
00159
00160 memset((tp = tmp), 0, IN6ADDRSZ);
00161 endp = tp + IN6ADDRSZ;
00162 colonp = NULL;
00163
00164 if(*src == ':')
00165 if(*++src != ':')
00166 return (0);
00167 curtok = src;
00168 saw_xdigit = 0;
00169 val = 0;
00170 while((ch = *src++) != '\0') {
00171 const char *pch;
00172
00173 pch = strchr((xdigits = xdigits_l), ch);
00174 if(!pch)
00175 pch = strchr((xdigits = xdigits_u), ch);
00176 if(pch != NULL) {
00177 val <<= 4;
00178 val |= (pch - xdigits);
00179 if(++saw_xdigit > 4)
00180 return (0);
00181 continue;
00182 }
00183 if(ch == ':') {
00184 curtok = src;
00185 if(!saw_xdigit) {
00186 if(colonp)
00187 return (0);
00188 colonp = tp;
00189 continue;
00190 }
00191 if(tp + INT16SZ > endp)
00192 return (0);
00193 *tp++ = (unsigned char) ((val >> 8) & 0xff);
00194 *tp++ = (unsigned char) (val & 0xff);
00195 saw_xdigit = 0;
00196 val = 0;
00197 continue;
00198 }
00199 if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
00200 inet_pton4(curtok, tp) > 0) {
00201 tp += INADDRSZ;
00202 saw_xdigit = 0;
00203 break;
00204 }
00205 return (0);
00206 }
00207 if(saw_xdigit) {
00208 if(tp + INT16SZ > endp)
00209 return (0);
00210 *tp++ = (unsigned char) ((val >> 8) & 0xff);
00211 *tp++ = (unsigned char) (val & 0xff);
00212 }
00213 if(colonp != NULL) {
00214
00215
00216
00217
00218 const ssize_t n = tp - colonp;
00219 ssize_t i;
00220
00221 if(tp == endp)
00222 return (0);
00223 for(i = 1; i <= n; i++) {
00224 *(endp - i) = *(colonp + n - i);
00225 *(colonp + n - i) = 0;
00226 }
00227 tp = endp;
00228 }
00229 if(tp != endp)
00230 return (0);
00231 memcpy(dst, tmp, IN6ADDRSZ);
00232 return (1);
00233 }
00234 #endif
00235
00236 #endif