inet.cpp 1.5 KB

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