inet_ntop.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #include <sys/socket.h>
  2. #include <arpa/inet.h>
  3. #include <errno.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen_t l)
  7. {
  8. const unsigned char *a = a0;
  9. int i, j, max, best;
  10. char buf[100];
  11. switch (af) {
  12. case AF_INET:
  13. if (snprintf(s, l, "%d.%d.%d.%d", a[0],a[1],a[2],a[3]) < l)
  14. return s;
  15. break;
  16. case AF_INET6:
  17. if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12))
  18. snprintf(buf, sizeof buf,
  19. "%x:%x:%x:%x:%x:%x:%x:%x",
  20. 256*a[0]+a[1],256*a[2]+a[3],
  21. 256*a[4]+a[5],256*a[6]+a[7],
  22. 256*a[8]+a[9],256*a[10]+a[11],
  23. 256*a[12]+a[13],256*a[14]+a[15]);
  24. else
  25. snprintf(buf, sizeof buf,
  26. "%x:%x:%x:%x:%x:%x:%d.%d.%d.%d",
  27. 256*a[0]+a[1],256*a[2]+a[3],
  28. 256*a[4]+a[5],256*a[6]+a[7],
  29. 256*a[8]+a[9],256*a[10]+a[11],
  30. a[12],a[13],a[14],a[15]);
  31. /* Replace longest /(^0|:)[:0]{2,}/ with "::" */
  32. for (i=best=0, max=2; buf[i]; i++) {
  33. if (i && buf[i] != ':') continue;
  34. j = strspn(buf+i, ":0");
  35. if (j>max) best=i, max=j;
  36. }
  37. if (max>2) {
  38. buf[best] = buf[best+1] = ':';
  39. memmove(buf+best+2, buf+best+max, i-best-max+1);
  40. }
  41. if (strlen(buf) < l) {
  42. strcpy(s, buf);
  43. return s;
  44. }
  45. break;
  46. default:
  47. errno = EAFNOSUPPORT;
  48. return 0;
  49. }
  50. errno = ENOSPC;
  51. return 0;
  52. }