#define _SUSV2_SOURCE #include #include #include #include #include #include #include #include #include #include #include #define nil ((void*)0) typedef unsigned char uchar; int classnetbytes[] = {1, 1, 2, 3, }; static char* parseip4(uchar *u, char *s) { char *v; int i, d, b, n; for(i = 0; i < 4; i++){ v = s; d = strtoul(s, &s, 0); if(d > 255) return nil; u[i] = d; if(*s == '.') s++; else if(s == v) break; } if(i < 4 && i > (b = classnetbytes[u[0]>>6])){ n = i - b; memmove(u+4-n, u+b, n); memset(u+b, 0, 4-(b+n)); i = 4; } if(i != 4) return nil; return s; } static char* parseip6(uchar *u, char *s) { char *v; int i, d, cc, is4; is4 = 1; cc = -1; for(i = 0; i < 16;){ v = s; d = strtoul(s, &s, 16); switch(*s){ case '.': if(i + 4 > 16) return nil; s = parseip4(u+i, v); if(s == nil) return nil; i += 4; break; case ':': is4 = 0; s++; default: if(d > 0xffff) return nil; u[i++] = d>>8; u[i++] = d; if(*s == ':'){ if(cc != -1) return nil; cc = i; s++; } if(s == v) i -= 2; break; } if(s == v) break; } if(is4 && i == 4){ memmove(u+12, u, 4); memset(u, 0, 4); memset(u+10, 0xff, 2); } else if(cc != -1 && i < 16){ memmove(u+cc+(16-i), u+cc, i-cc); memset(u+cc, 0, 16-i); } else if(i != 16) return nil; return s; } int inet_pton(int af, const char *src, void *dst) { uchar u[16]; struct in_addr *ia; struct in6_addr *ia6; memset(u, 0, sizeof u); switch(af){ default: errno = EAFNOSUPPORT; return -1; case AF_INET: if(parseip4(u, src) == nil) return 0; ia = (struct in_addr*)dst; memmove(&ia->s_addr, u, 4); return 1; case AF_INET6: if(parseip6(u, src) == nil) return 0; ia6 = (struct in6_addr*)dst; memmove(ia6->s6_addr, u, 16); return 1; } }