123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /*
- * Common hostapd/wpa_supplicant ctrl iface code.
- * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2015, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
- #include "utils/includes.h"
- #include <netdb.h>
- #include <sys/un.h>
- #include "utils/common.h"
- #include "ctrl_iface_common.h"
- static int sockaddr_compare(struct sockaddr_storage *a, socklen_t a_len,
- struct sockaddr_storage *b, socklen_t b_len)
- {
- if (a->ss_family != b->ss_family)
- return 1;
- switch (a->ss_family) {
- #ifdef CONFIG_CTRL_IFACE_UDP
- case AF_INET:
- {
- struct sockaddr_in *in_a, *in_b;
- in_a = (struct sockaddr_in *) a;
- in_b = (struct sockaddr_in *) b;
- if (in_a->sin_port != in_b->sin_port)
- return 1;
- if (in_a->sin_addr.s_addr != in_b->sin_addr.s_addr)
- return 1;
- break;
- }
- case AF_INET6:
- {
- struct sockaddr_in6 *in6_a, *in6_b;
- in6_a = (struct sockaddr_in6 *) a;
- in6_b = (struct sockaddr_in6 *) b;
- if (in6_a->sin6_port != in6_b->sin6_port)
- return 1;
- if (os_memcmp(&in6_a->sin6_addr, &in6_b->sin6_addr,
- sizeof(in6_a->sin6_addr)) != 0)
- return 1;
- break;
- }
- #endif /* CONFIG_CTRL_IFACE_UDP */
- #ifdef CONFIG_CTRL_IFACE_UNIX
- case AF_UNIX:
- {
- struct sockaddr_un *u_a, *u_b;
- u_a = (struct sockaddr_un *) a;
- u_b = (struct sockaddr_un *) b;
- if (a_len != b_len ||
- os_memcmp(u_a->sun_path, u_b->sun_path,
- a_len - offsetof(struct sockaddr_un, sun_path))
- != 0)
- return 1;
- break;
- }
- #endif /* CONFIG_CTRL_IFACE_UNIX */
- default:
- return 1;
- }
- return 0;
- }
- void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
- socklen_t socklen)
- {
- switch (sock->ss_family) {
- #ifdef CONFIG_CTRL_IFACE_UDP
- case AF_INET:
- case AF_INET6:
- {
- char host[NI_MAXHOST] = { 0 };
- char service[NI_MAXSERV] = { 0 };
- getnameinfo((struct sockaddr *) sock, socklen,
- host, sizeof(host),
- service, sizeof(service),
- NI_NUMERICHOST);
- wpa_printf(level, "%s %s:%s", msg, host, service);
- break;
- }
- #endif /* CONFIG_CTRL_IFACE_UDP */
- #ifdef CONFIG_CTRL_IFACE_UNIX
- case AF_UNIX:
- {
- char addr_txt[200];
- printf_encode(addr_txt, sizeof(addr_txt),
- (u8 *) ((struct sockaddr_un *) sock)->sun_path,
- socklen - offsetof(struct sockaddr_un, sun_path));
- wpa_printf(level, "%s %s", msg, addr_txt);
- break;
- }
- #endif /* CONFIG_CTRL_IFACE_UNIX */
- default:
- wpa_printf(level, "%s", msg);
- break;
- }
- }
- int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
- socklen_t fromlen)
- {
- struct wpa_ctrl_dst *dst;
- dst = os_zalloc(sizeof(*dst));
- if (dst == NULL)
- return -1;
- os_memcpy(&dst->addr, from, fromlen);
- dst->addrlen = fromlen;
- dst->debug_level = MSG_INFO;
- dl_list_add(ctrl_dst, &dst->list);
- sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor attached", from, fromlen);
- return 0;
- }
- int ctrl_iface_detach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
- socklen_t fromlen)
- {
- struct wpa_ctrl_dst *dst;
- dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
- if (!sockaddr_compare(from, fromlen,
- &dst->addr, dst->addrlen)) {
- sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor detached",
- from, fromlen);
- dl_list_del(&dst->list);
- os_free(dst);
- return 0;
- }
- }
- return -1;
- }
- int ctrl_iface_level(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
- socklen_t fromlen, const char *level)
- {
- struct wpa_ctrl_dst *dst;
- wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
- dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
- if (!sockaddr_compare(from, fromlen,
- &dst->addr, dst->addrlen)) {
- sockaddr_print(MSG_DEBUG,
- "CTRL_IFACE changed monitor level",
- from, fromlen);
- dst->debug_level = atoi(level);
- return 0;
- }
- }
- return -1;
- }
|