__ipparse.c 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. #include "__dns.h"
  8. int __ipparse(void *dest, int family, const char *s0)
  9. {
  10. const char *s = s0;
  11. unsigned char *d = dest;
  12. unsigned long a[16] = { 0 };
  13. char *z;
  14. int i;
  15. if (family == AF_INET6) goto not_v4;
  16. for (i=0; i<4; i++) {
  17. a[i] = strtoul(s, &z, 0);
  18. if (z==s || (*z && *z != '.') || !isdigit(*s)) {
  19. if (family == AF_INET) return -1;
  20. goto not_v4;
  21. }
  22. if (!*z) break;
  23. s=z+1;
  24. }
  25. if (i==4) return -1;
  26. switch (i) {
  27. case 0:
  28. a[1] = a[0] & 0xffffff;
  29. a[0] >>= 24;
  30. case 1:
  31. a[2] = a[1] & 0xffff;
  32. a[1] >>= 16;
  33. case 2:
  34. a[3] = a[2] & 0xff;
  35. a[2] >>= 8;
  36. }
  37. ((struct sockaddr_in *)d)->sin_family = AF_INET;
  38. d = (void *)&((struct sockaddr_in *)d)->sin_addr;
  39. for (i=0; i<4; i++) {
  40. if (a[i] > 255) return -1;
  41. d[i] = a[i];
  42. }
  43. return 0;
  44. not_v4:
  45. s = s0;
  46. ((struct sockaddr_in6 *)d)->sin6_family = AF_INET6;
  47. return inet_pton(AF_INET6, s, (void *)&((struct sockaddr_in6 *)d)->sin6_addr) <= 0 ? -1 : 0;
  48. }