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