util.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "util.h"
  2. #include <arpa/inet.h>
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <unistd.h>
  9. unsigned long get_tick_count(void)
  10. {
  11. struct timespec ts;
  12. clock_gettime(CLOCK_MONOTONIC, &ts);
  13. return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
  14. }
  15. char *gethost_by_addr(char *host, struct sockaddr *addr, socklen_t addr_len)
  16. {
  17. struct sockaddr_storage *addr_store = (struct sockaddr_storage *)addr;
  18. host[0] = 0;
  19. switch (addr_store->ss_family) {
  20. case AF_INET: {
  21. struct sockaddr_in *addr_in;
  22. addr_in = (struct sockaddr_in *)addr;
  23. inet_ntop(AF_INET, &addr_in->sin_addr, host, addr_len);
  24. } break;
  25. case AF_INET6: {
  26. struct sockaddr_in6 *addr_in6;
  27. addr_in6 = (struct sockaddr_in6 *)addr;
  28. if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
  29. struct sockaddr_in addr_in4;
  30. memset(&addr_in4, 0, sizeof(addr_in4));
  31. memcpy(&addr_in4.sin_addr.s_addr, addr_in6->sin6_addr.s6_addr + 12, sizeof(addr_in4.sin_addr.s_addr));
  32. inet_ntop(AF_INET, &addr_in4.sin_addr, host, addr_len);
  33. } else {
  34. inet_ntop(AF_INET6, &addr_in6->sin6_addr, host, addr_len);
  35. }
  36. } break;
  37. default:
  38. goto errout;
  39. break;
  40. }
  41. return host;
  42. errout:
  43. return NULL;
  44. }
  45. int getaddr_by_host(char *host, struct sockaddr *addr, socklen_t *addr_len)
  46. {
  47. struct addrinfo hints;
  48. struct addrinfo *result = NULL;
  49. int ret = 0;
  50. memset(&hints, 0, sizeof(hints));
  51. hints.ai_family = AF_UNSPEC;
  52. hints.ai_socktype = SOCK_STREAM;
  53. ret = getaddrinfo(host, "53", &hints, &result);
  54. if (ret != 0) {
  55. goto errout;
  56. }
  57. if (result->ai_addrlen > *addr_len) {
  58. result->ai_addrlen = *addr_len;
  59. }
  60. memcpy(addr, result->ai_addr, result->ai_addrlen);
  61. *addr_len = result->ai_addrlen;
  62. freeaddrinfo(result);
  63. return 0;
  64. errout:
  65. if (result) {
  66. freeaddrinfo(result);
  67. }
  68. return -1;
  69. }
  70. int parse_ip(const char *value, char *ip, int *port)
  71. {
  72. int offset = 0;
  73. char *colon = NULL;
  74. colon = strstr(value, ":");
  75. if (strstr(value, "[")) {
  76. /* ipv6 with port */
  77. char *bracket_end = strstr(value, "]");
  78. if (bracket_end == NULL) {
  79. return -1;
  80. }
  81. offset = bracket_end - value - 1;
  82. memcpy(ip, value + 1, offset);
  83. ip[offset] = 0;
  84. colon = strstr(bracket_end, ":");
  85. if (colon) {
  86. colon++;
  87. }
  88. } else if (colon && strstr(colon + 1, ":")) {
  89. /* ipv6 without port */
  90. strncpy(ip, value, MAX_IP_LEN);
  91. colon = NULL;
  92. } else {
  93. /* ipv4 */
  94. colon = strstr(value, ":");
  95. if (colon == NULL) {
  96. /* without port */
  97. strncpy(ip, value, MAX_IP_LEN);
  98. } else {
  99. /* with port */
  100. offset = colon - value;
  101. colon++;
  102. memcpy(ip, value, offset);
  103. ip[offset] = 0;
  104. }
  105. }
  106. if (colon) {
  107. /* get port num */
  108. *port = atoi(colon);
  109. } else {
  110. *port = PORT_NOT_DEFINED;
  111. }
  112. if (ip[0] == 0) {
  113. return -1;
  114. }
  115. return 0;
  116. }
  117. int set_fd_nonblock(int fd, int nonblock)
  118. {
  119. int ret;
  120. int flags = fcntl(fd, F_GETFL);
  121. if (flags == -1) {
  122. return -1;
  123. }
  124. flags = (nonblock) ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK);
  125. ret = fcntl(fd, F_SETFL, flags);
  126. if (ret == -1) {
  127. return -1;
  128. }
  129. return 0;
  130. }
  131. char *reverse_string(char *output, char *input, int len)
  132. {
  133. char *begin = output;
  134. if (len <= 0) {
  135. *output = 0;
  136. return output;
  137. }
  138. len--;
  139. while (len >= 0) {
  140. *output = *(input + len);
  141. output++;
  142. len--;
  143. }
  144. *output = 0;
  145. return begin;
  146. }