inet.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/IPv6Address.h>
  7. #include <arpa/inet.h>
  8. #include <errno.h>
  9. #include <netinet/in.h>
  10. #include <stdio.h>
  11. extern "C" {
  12. char const* inet_ntop(int af, void const* src, char* dst, socklen_t len)
  13. {
  14. if (af == AF_INET) {
  15. if (len < INET_ADDRSTRLEN) {
  16. errno = ENOSPC;
  17. return nullptr;
  18. }
  19. auto* bytes = (unsigned char const*)src;
  20. snprintf(dst, len, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2], bytes[3]);
  21. return (char const*)dst;
  22. } else if (af == AF_INET6) {
  23. if (len < INET6_ADDRSTRLEN) {
  24. errno = ENOSPC;
  25. return nullptr;
  26. }
  27. auto str = IPv6Address(((in6_addr const*)src)->s6_addr).to_deprecated_string();
  28. if (!str.copy_characters_to_buffer(dst, len)) {
  29. errno = ENOSPC;
  30. return nullptr;
  31. }
  32. return (char const*)dst;
  33. }
  34. errno = EAFNOSUPPORT;
  35. return nullptr;
  36. }
  37. int inet_pton(int af, char const* src, void* dst)
  38. {
  39. if (af == AF_INET) {
  40. unsigned a, b, c, d;
  41. int count = sscanf(src, "%u.%u.%u.%u", &a, &b, &c, &d);
  42. if (count != 4) {
  43. errno = EINVAL;
  44. return 0;
  45. }
  46. union {
  47. struct {
  48. uint8_t a;
  49. uint8_t b;
  50. uint8_t c;
  51. uint8_t d;
  52. };
  53. uint32_t l;
  54. } u;
  55. u.a = a;
  56. u.b = b;
  57. u.c = c;
  58. u.d = d;
  59. *(uint32_t*)dst = u.l;
  60. return 1;
  61. } else if (af == AF_INET6) {
  62. auto addr = IPv6Address::from_string({ src, strlen(src) });
  63. if (!addr.has_value()) {
  64. errno = EINVAL;
  65. return 0;
  66. }
  67. memcpy(dst, addr->to_in6_addr_t(), sizeof(in6_addr));
  68. return 1;
  69. }
  70. errno = EAFNOSUPPORT;
  71. return -1;
  72. }
  73. in_addr_t inet_addr(char const* str)
  74. {
  75. in_addr_t tmp {};
  76. int rc = inet_pton(AF_INET, str, &tmp);
  77. if (rc <= 0)
  78. return INADDR_NONE;
  79. return tmp;
  80. }
  81. char* inet_ntoa(struct in_addr in)
  82. {
  83. static char buffer[32];
  84. inet_ntop(AF_INET, &in.s_addr, buffer, sizeof(buffer));
  85. return buffer;
  86. }
  87. }