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.
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
10 #include "utils/includes.h"
14 #include "utils/common.h"
15 #include "ctrl_iface_common.h"
17 static int sockaddr_compare(struct sockaddr_storage *a, socklen_t a_len,
18 struct sockaddr_storage *b, socklen_t b_len)
20 struct sockaddr_in *in_a, *in_b;
21 struct sockaddr_in6 *in6_a, *in6_b;
22 struct sockaddr_un *u_a, *u_b;
24 if (a->ss_family != b->ss_family)
27 switch (a->ss_family) {
29 in_a = (struct sockaddr_in *) a;
30 in_b = (struct sockaddr_in *) b;
32 if (in_a->sin_port != in_b->sin_port)
34 if (in_a->sin_addr.s_addr != in_b->sin_addr.s_addr)
38 in6_a = (struct sockaddr_in6 *) a;
39 in6_b = (struct sockaddr_in6 *) b;
41 if (in6_a->sin6_port != in6_b->sin6_port)
43 if (os_memcmp(&in6_a->sin6_addr, &in6_b->sin6_addr,
44 sizeof(in6_a->sin6_addr)) != 0)
48 u_a = (struct sockaddr_un *) a;
49 u_b = (struct sockaddr_un *) b;
52 os_memcmp(u_a->sun_path, u_b->sun_path,
53 a_len - offsetof(struct sockaddr_un, sun_path))
65 void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
68 char host[NI_MAXHOST] = { 0 };
69 char service[NI_MAXSERV] = { 0 };
72 switch (sock->ss_family) {
75 getnameinfo((struct sockaddr *) sock, socklen,
77 service, sizeof(service),
80 wpa_printf(level, "%s %s:%s", msg, host, service);
83 printf_encode(addr_txt, sizeof(addr_txt),
84 (u8 *) ((struct sockaddr_un *) sock)->sun_path,
85 socklen - offsetof(struct sockaddr_un, sun_path));
86 wpa_printf(level, "%s %s", msg, addr_txt);
89 wpa_printf(level, "%s", msg);
95 int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_un *from,
98 struct wpa_ctrl_dst *dst;
100 dst = os_zalloc(sizeof(*dst));
103 os_memcpy(&dst->addr, from, fromlen);
104 dst->addrlen = fromlen;
105 dst->debug_level = MSG_INFO;
106 dl_list_add(ctrl_dst, &dst->list);
108 sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor attached",
109 (struct sockaddr_storage *) from, fromlen);
114 int ctrl_iface_detach(struct dl_list *ctrl_dst, struct sockaddr_un *from,
117 struct wpa_ctrl_dst *dst;
119 dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
120 if (!sockaddr_compare((struct sockaddr_storage *) from,
122 (struct sockaddr_storage *) &dst->addr,
124 sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor detached",
125 (struct sockaddr_storage *) from,
127 dl_list_del(&dst->list);
137 int ctrl_iface_level(struct dl_list *ctrl_dst, struct sockaddr_un *from,
138 socklen_t fromlen, const char *level)
140 struct wpa_ctrl_dst *dst;
142 wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
144 dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
145 if (!sockaddr_compare((struct sockaddr_storage *) from,
147 (struct sockaddr_storage *) &dst->addr,
149 sockaddr_print(MSG_DEBUG,
150 "CTRL_IFACE changed monitor level",
151 (struct sockaddr_storage *) from,
153 dst->debug_level = atoi(level);