1 #include <sys/socket.h> 2 #include <arpa/inet.h> 3 #include <ctype.h> 4 #include <errno.h> 5 #include <string.h> 6 7 #if __GNUC__ < 4 8 #define restrict 9 #endif 10 11 static int hexval(unsigned c) 12 { 13 if (c-'0'<10) return c-'0'; 14 c |= 32; 15 if (c-'a'<6) return c-'a'+10; 16 return -1; 17 } 18 19 int inet_pton(int af, const char *restrict s, void *restrict a0) 20 { 21 uint16_t ip[8]; 22 unsigned char *a = a0; 23 int i, j, v, d, brk=-1, need_v4=0; 24 25 if (af==AF_INET) { 26 for (i=0; i<4; i++) { 27 for (v=j=0; j<3 && isdigit(s[j]); j++) 28 v = 10*v + s[j]-'0'; 29 if (j==0 || (j>1 && s[0]=='0') || v>255) return 0; 30 a[i] = v; 31 if (s[j]==0 && i==3) return 1; 32 if (s[j]!='.') return 0; 33 s += j+1; 34 } 35 return 0; 36 } else if (af!=AF_INET6) { 37 errno = EAFNOSUPPORT; 38 return -1; 39 } 40 41 if (*s==':' && *++s!=':') return 0; 42 43 for (i=0; ; i++) { 44 if (s[0]==':' && brk<0) { 45 brk=i; 46 ip[i&7]=0; 47 if (!*++s) break; 48 if (i==7) return 0; 49 continue; 50 } 51 for (v=j=0; j<4 && (d=hexval(s[j]))>=0; j++) 52 v=16*v+d; 53 if (j==0) return 0; 54 ip[i&7] = v; 55 if (!s[j] && (brk>=0 || i==7)) break; 56 if (i==7) return 0; 57 if (s[j]!=':') { 58 if (s[j]!='.' || (i<6 && brk<0)) return 0; 59 need_v4=1; 60 i++; 61 break; 62 } 63 s += j+1; 64 } 65 if (brk>=0) { 66 memmove(ip+brk+7-i, ip+brk, 2*(i+1-brk)); 67 for (j=0; j<7-i; j++) ip[brk+j] = 0; 68 } 69 for (j=0; j<8; j++) { 70 *a++ = ip[j]>>8; 71 *a++ = ip[j]; 72 } 73 if (need_v4 && inet_pton(AF_INET, (void *)s, a-4) <= 0) return 0; 74 return 1; 75 } 76