ctrl_iface_common.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Common hostapd/wpa_supplicant ctrl iface code.
  3. * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
  4. * Copyright (c) 2015, Qualcomm Atheros, Inc.
  5. *
  6. * This software may be distributed under the terms of the BSD license.
  7. * See README for more details.
  8. */
  9. #include "utils/includes.h"
  10. #include <netdb.h>
  11. #include <sys/un.h>
  12. #include "utils/common.h"
  13. #include "ctrl_iface_common.h"
  14. static int sockaddr_compare(struct sockaddr_storage *a, socklen_t a_len,
  15. struct sockaddr_storage *b, socklen_t b_len)
  16. {
  17. if (a->ss_family != b->ss_family)
  18. return 1;
  19. switch (a->ss_family) {
  20. #ifdef CONFIG_CTRL_IFACE_UDP
  21. case AF_INET:
  22. {
  23. struct sockaddr_in *in_a, *in_b;
  24. in_a = (struct sockaddr_in *) a;
  25. in_b = (struct sockaddr_in *) b;
  26. if (in_a->sin_port != in_b->sin_port)
  27. return 1;
  28. if (in_a->sin_addr.s_addr != in_b->sin_addr.s_addr)
  29. return 1;
  30. break;
  31. }
  32. case AF_INET6:
  33. {
  34. struct sockaddr_in6 *in6_a, *in6_b;
  35. in6_a = (struct sockaddr_in6 *) a;
  36. in6_b = (struct sockaddr_in6 *) b;
  37. if (in6_a->sin6_port != in6_b->sin6_port)
  38. return 1;
  39. if (os_memcmp(&in6_a->sin6_addr, &in6_b->sin6_addr,
  40. sizeof(in6_a->sin6_addr)) != 0)
  41. return 1;
  42. break;
  43. }
  44. #endif /* CONFIG_CTRL_IFACE_UDP */
  45. #ifdef CONFIG_CTRL_IFACE_UNIX
  46. case AF_UNIX:
  47. {
  48. struct sockaddr_un *u_a, *u_b;
  49. u_a = (struct sockaddr_un *) a;
  50. u_b = (struct sockaddr_un *) b;
  51. if (a_len != b_len ||
  52. os_memcmp(u_a->sun_path, u_b->sun_path,
  53. a_len - offsetof(struct sockaddr_un, sun_path))
  54. != 0)
  55. return 1;
  56. break;
  57. }
  58. #endif /* CONFIG_CTRL_IFACE_UNIX */
  59. default:
  60. return 1;
  61. }
  62. return 0;
  63. }
  64. void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
  65. socklen_t socklen)
  66. {
  67. switch (sock->ss_family) {
  68. #ifdef CONFIG_CTRL_IFACE_UDP
  69. case AF_INET:
  70. case AF_INET6:
  71. {
  72. char host[NI_MAXHOST] = { 0 };
  73. char service[NI_MAXSERV] = { 0 };
  74. getnameinfo((struct sockaddr *) sock, socklen,
  75. host, sizeof(host),
  76. service, sizeof(service),
  77. NI_NUMERICHOST);
  78. wpa_printf(level, "%s %s:%s", msg, host, service);
  79. break;
  80. }
  81. #endif /* CONFIG_CTRL_IFACE_UDP */
  82. #ifdef CONFIG_CTRL_IFACE_UNIX
  83. case AF_UNIX:
  84. {
  85. char addr_txt[200];
  86. printf_encode(addr_txt, sizeof(addr_txt),
  87. (u8 *) ((struct sockaddr_un *) sock)->sun_path,
  88. socklen - offsetof(struct sockaddr_un, sun_path));
  89. wpa_printf(level, "%s %s", msg, addr_txt);
  90. break;
  91. }
  92. #endif /* CONFIG_CTRL_IFACE_UNIX */
  93. default:
  94. wpa_printf(level, "%s", msg);
  95. break;
  96. }
  97. }
  98. int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
  99. socklen_t fromlen)
  100. {
  101. struct wpa_ctrl_dst *dst;
  102. dst = os_zalloc(sizeof(*dst));
  103. if (dst == NULL)
  104. return -1;
  105. os_memcpy(&dst->addr, from, fromlen);
  106. dst->addrlen = fromlen;
  107. dst->debug_level = MSG_INFO;
  108. dl_list_add(ctrl_dst, &dst->list);
  109. sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor attached", from, fromlen);
  110. return 0;
  111. }
  112. int ctrl_iface_detach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
  113. socklen_t fromlen)
  114. {
  115. struct wpa_ctrl_dst *dst;
  116. dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
  117. if (!sockaddr_compare(from, fromlen,
  118. &dst->addr, dst->addrlen)) {
  119. sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor detached",
  120. from, fromlen);
  121. dl_list_del(&dst->list);
  122. os_free(dst);
  123. return 0;
  124. }
  125. }
  126. return -1;
  127. }
  128. int ctrl_iface_level(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
  129. socklen_t fromlen, const char *level)
  130. {
  131. struct wpa_ctrl_dst *dst;
  132. wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
  133. dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
  134. if (!sockaddr_compare(from, fromlen,
  135. &dst->addr, dst->addrlen)) {
  136. sockaddr_print(MSG_DEBUG,
  137. "CTRL_IFACE changed monitor level",
  138. from, fromlen);
  139. dst->debug_level = atoi(level);
  140. return 0;
  141. }
  142. }
  143. return -1;
  144. }