xref: /freebsd-src/contrib/wpa/src/common/ctrl_iface_common.c (revision 67350cb56a69468c118bd4ccf6e361b7ebfa9eb4)
1780fb4a2SCy Schubert /*
2780fb4a2SCy Schubert  * Common hostapd/wpa_supplicant ctrl iface code.
3780fb4a2SCy Schubert  * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
4780fb4a2SCy Schubert  * Copyright (c) 2015, Qualcomm Atheros, Inc.
5780fb4a2SCy Schubert  *
6780fb4a2SCy Schubert  * This software may be distributed under the terms of the BSD license.
7780fb4a2SCy Schubert  * See README for more details.
8780fb4a2SCy Schubert  */
9780fb4a2SCy Schubert 
10780fb4a2SCy Schubert #include "utils/includes.h"
11780fb4a2SCy Schubert #include <netdb.h>
12780fb4a2SCy Schubert #include <sys/un.h>
13780fb4a2SCy Schubert 
14780fb4a2SCy Schubert #include "utils/common.h"
15780fb4a2SCy Schubert #include "ctrl_iface_common.h"
16780fb4a2SCy Schubert 
sockaddr_compare(struct sockaddr_storage * a,socklen_t a_len,struct sockaddr_storage * b,socklen_t b_len)17780fb4a2SCy Schubert static int sockaddr_compare(struct sockaddr_storage *a, socklen_t a_len,
18780fb4a2SCy Schubert 			    struct sockaddr_storage *b, socklen_t b_len)
19780fb4a2SCy Schubert {
20780fb4a2SCy Schubert 	if (a->ss_family != b->ss_family)
21780fb4a2SCy Schubert 		return 1;
22780fb4a2SCy Schubert 
23780fb4a2SCy Schubert 	switch (a->ss_family) {
24780fb4a2SCy Schubert #ifdef CONFIG_CTRL_IFACE_UDP
25780fb4a2SCy Schubert 	case AF_INET:
26780fb4a2SCy Schubert 	{
27780fb4a2SCy Schubert 		struct sockaddr_in *in_a, *in_b;
28780fb4a2SCy Schubert 
29780fb4a2SCy Schubert 		in_a = (struct sockaddr_in *) a;
30780fb4a2SCy Schubert 		in_b = (struct sockaddr_in *) b;
31780fb4a2SCy Schubert 
32780fb4a2SCy Schubert 		if (in_a->sin_port != in_b->sin_port)
33780fb4a2SCy Schubert 			return 1;
34780fb4a2SCy Schubert 		if (in_a->sin_addr.s_addr != in_b->sin_addr.s_addr)
35780fb4a2SCy Schubert 			return 1;
36780fb4a2SCy Schubert 		break;
37780fb4a2SCy Schubert 	}
38780fb4a2SCy Schubert 	case AF_INET6:
39780fb4a2SCy Schubert 	{
40780fb4a2SCy Schubert 		struct sockaddr_in6 *in6_a, *in6_b;
41780fb4a2SCy Schubert 
42780fb4a2SCy Schubert 		in6_a = (struct sockaddr_in6 *) a;
43780fb4a2SCy Schubert 		in6_b = (struct sockaddr_in6 *) b;
44780fb4a2SCy Schubert 
45780fb4a2SCy Schubert 		if (in6_a->sin6_port != in6_b->sin6_port)
46780fb4a2SCy Schubert 			return 1;
47780fb4a2SCy Schubert 		if (os_memcmp(&in6_a->sin6_addr, &in6_b->sin6_addr,
48780fb4a2SCy Schubert 			      sizeof(in6_a->sin6_addr)) != 0)
49780fb4a2SCy Schubert 			return 1;
50780fb4a2SCy Schubert 		break;
51780fb4a2SCy Schubert 	}
52780fb4a2SCy Schubert #endif /* CONFIG_CTRL_IFACE_UDP */
53780fb4a2SCy Schubert #ifdef CONFIG_CTRL_IFACE_UNIX
54780fb4a2SCy Schubert 	case AF_UNIX:
55780fb4a2SCy Schubert 	{
56780fb4a2SCy Schubert 		struct sockaddr_un *u_a, *u_b;
57780fb4a2SCy Schubert 
58780fb4a2SCy Schubert 		u_a = (struct sockaddr_un *) a;
59780fb4a2SCy Schubert 		u_b = (struct sockaddr_un *) b;
60780fb4a2SCy Schubert 
61780fb4a2SCy Schubert 		if (a_len != b_len ||
62780fb4a2SCy Schubert 		    os_memcmp(u_a->sun_path, u_b->sun_path,
63780fb4a2SCy Schubert 			      a_len - offsetof(struct sockaddr_un, sun_path))
64780fb4a2SCy Schubert 		    != 0)
65780fb4a2SCy Schubert 			return 1;
66780fb4a2SCy Schubert 		break;
67780fb4a2SCy Schubert 	}
68780fb4a2SCy Schubert #endif /* CONFIG_CTRL_IFACE_UNIX */
69780fb4a2SCy Schubert 	default:
70780fb4a2SCy Schubert 		return 1;
71780fb4a2SCy Schubert 	}
72780fb4a2SCy Schubert 
73780fb4a2SCy Schubert 	return 0;
74780fb4a2SCy Schubert }
75780fb4a2SCy Schubert 
76780fb4a2SCy Schubert 
sockaddr_print(int level,const char * msg,struct sockaddr_storage * sock,socklen_t socklen)77780fb4a2SCy Schubert void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
78780fb4a2SCy Schubert 		    socklen_t socklen)
79780fb4a2SCy Schubert {
80780fb4a2SCy Schubert 	switch (sock->ss_family) {
81780fb4a2SCy Schubert #ifdef CONFIG_CTRL_IFACE_UDP
82780fb4a2SCy Schubert 	case AF_INET:
83780fb4a2SCy Schubert 	case AF_INET6:
84780fb4a2SCy Schubert 	{
85780fb4a2SCy Schubert 		char host[NI_MAXHOST] = { 0 };
86780fb4a2SCy Schubert 		char service[NI_MAXSERV] = { 0 };
87780fb4a2SCy Schubert 
88780fb4a2SCy Schubert 		getnameinfo((struct sockaddr *) sock, socklen,
89780fb4a2SCy Schubert 			    host, sizeof(host),
90780fb4a2SCy Schubert 			    service, sizeof(service),
91780fb4a2SCy Schubert 			    NI_NUMERICHOST);
92780fb4a2SCy Schubert 
93780fb4a2SCy Schubert 		wpa_printf(level, "%s %s:%s", msg, host, service);
94780fb4a2SCy Schubert 		break;
95780fb4a2SCy Schubert 	}
96780fb4a2SCy Schubert #endif /* CONFIG_CTRL_IFACE_UDP */
97780fb4a2SCy Schubert #ifdef CONFIG_CTRL_IFACE_UNIX
98780fb4a2SCy Schubert 	case AF_UNIX:
99780fb4a2SCy Schubert 	{
100780fb4a2SCy Schubert 		char addr_txt[200];
101780fb4a2SCy Schubert 
102780fb4a2SCy Schubert 		printf_encode(addr_txt, sizeof(addr_txt),
103780fb4a2SCy Schubert 			      (u8 *) ((struct sockaddr_un *) sock)->sun_path,
104780fb4a2SCy Schubert 			      socklen - offsetof(struct sockaddr_un, sun_path));
105780fb4a2SCy Schubert 		wpa_printf(level, "%s %s", msg, addr_txt);
106780fb4a2SCy Schubert 		break;
107780fb4a2SCy Schubert 	}
108780fb4a2SCy Schubert #endif /* CONFIG_CTRL_IFACE_UNIX */
109780fb4a2SCy Schubert 	default:
110780fb4a2SCy Schubert 		wpa_printf(level, "%s", msg);
111780fb4a2SCy Schubert 		break;
112780fb4a2SCy Schubert 	}
113780fb4a2SCy Schubert }
114780fb4a2SCy Schubert 
115780fb4a2SCy Schubert 
ctrl_set_events(struct wpa_ctrl_dst * dst,const char * input)116*85732ac8SCy Schubert static int ctrl_set_events(struct wpa_ctrl_dst *dst, const char *input)
117*85732ac8SCy Schubert {
118*85732ac8SCy Schubert 	const char *value;
119*85732ac8SCy Schubert 	int val;
120*85732ac8SCy Schubert 
121*85732ac8SCy Schubert 	if (!input)
122*85732ac8SCy Schubert 		return 0;
123*85732ac8SCy Schubert 
124*85732ac8SCy Schubert 	value = os_strchr(input, '=');
125*85732ac8SCy Schubert 	if (!value)
126*85732ac8SCy Schubert 		return -1;
127*85732ac8SCy Schubert 	value++;
128*85732ac8SCy Schubert 	val = atoi(value);
129*85732ac8SCy Schubert 	if (val < 0 || val > 1)
130*85732ac8SCy Schubert 		return -1;
131*85732ac8SCy Schubert 
132*85732ac8SCy Schubert 	if (str_starts(input, "probe_rx_events=")) {
133*85732ac8SCy Schubert 		if (val)
134*85732ac8SCy Schubert 			dst->events |= WPA_EVENT_RX_PROBE_REQUEST;
135*85732ac8SCy Schubert 		else
136*85732ac8SCy Schubert 			dst->events &= ~WPA_EVENT_RX_PROBE_REQUEST;
137*85732ac8SCy Schubert 	}
138*85732ac8SCy Schubert 
139*85732ac8SCy Schubert 	return 0;
140*85732ac8SCy Schubert }
141*85732ac8SCy Schubert 
142*85732ac8SCy Schubert 
ctrl_iface_attach(struct dl_list * ctrl_dst,struct sockaddr_storage * from,socklen_t fromlen,const char * input)143780fb4a2SCy Schubert int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
144*85732ac8SCy Schubert 		      socklen_t fromlen, const char *input)
145780fb4a2SCy Schubert {
146780fb4a2SCy Schubert 	struct wpa_ctrl_dst *dst;
147780fb4a2SCy Schubert 
148*85732ac8SCy Schubert 	/* Update event registration if already attached */
149*85732ac8SCy Schubert 	dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
150*85732ac8SCy Schubert 		if (!sockaddr_compare(from, fromlen,
151*85732ac8SCy Schubert 				      &dst->addr, dst->addrlen))
152*85732ac8SCy Schubert 			return ctrl_set_events(dst, input);
153*85732ac8SCy Schubert 	}
154*85732ac8SCy Schubert 
155*85732ac8SCy Schubert 	/* New attachment */
156780fb4a2SCy Schubert 	dst = os_zalloc(sizeof(*dst));
157780fb4a2SCy Schubert 	if (dst == NULL)
158780fb4a2SCy Schubert 		return -1;
159780fb4a2SCy Schubert 	os_memcpy(&dst->addr, from, fromlen);
160780fb4a2SCy Schubert 	dst->addrlen = fromlen;
161780fb4a2SCy Schubert 	dst->debug_level = MSG_INFO;
162*85732ac8SCy Schubert 	ctrl_set_events(dst, input);
163780fb4a2SCy Schubert 	dl_list_add(ctrl_dst, &dst->list);
164780fb4a2SCy Schubert 
165780fb4a2SCy Schubert 	sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor attached", from, fromlen);
166780fb4a2SCy Schubert 	return 0;
167780fb4a2SCy Schubert }
168780fb4a2SCy Schubert 
169780fb4a2SCy Schubert 
ctrl_iface_detach(struct dl_list * ctrl_dst,struct sockaddr_storage * from,socklen_t fromlen)170780fb4a2SCy Schubert int ctrl_iface_detach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
171780fb4a2SCy Schubert 		      socklen_t fromlen)
172780fb4a2SCy Schubert {
173780fb4a2SCy Schubert 	struct wpa_ctrl_dst *dst;
174780fb4a2SCy Schubert 
175780fb4a2SCy Schubert 	dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
176780fb4a2SCy Schubert 		if (!sockaddr_compare(from, fromlen,
177780fb4a2SCy Schubert 				      &dst->addr, dst->addrlen)) {
178780fb4a2SCy Schubert 			sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor detached",
179780fb4a2SCy Schubert 				       from, fromlen);
180780fb4a2SCy Schubert 			dl_list_del(&dst->list);
181780fb4a2SCy Schubert 			os_free(dst);
182780fb4a2SCy Schubert 			return 0;
183780fb4a2SCy Schubert 		}
184780fb4a2SCy Schubert 	}
185780fb4a2SCy Schubert 
186780fb4a2SCy Schubert 	return -1;
187780fb4a2SCy Schubert }
188780fb4a2SCy Schubert 
189780fb4a2SCy Schubert 
ctrl_iface_level(struct dl_list * ctrl_dst,struct sockaddr_storage * from,socklen_t fromlen,const char * level)190780fb4a2SCy Schubert int ctrl_iface_level(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
191780fb4a2SCy Schubert 		     socklen_t fromlen, const char *level)
192780fb4a2SCy Schubert {
193780fb4a2SCy Schubert 	struct wpa_ctrl_dst *dst;
194780fb4a2SCy Schubert 
195780fb4a2SCy Schubert 	wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
196780fb4a2SCy Schubert 
197780fb4a2SCy Schubert 	dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
198780fb4a2SCy Schubert 		if (!sockaddr_compare(from, fromlen,
199780fb4a2SCy Schubert 				      &dst->addr, dst->addrlen)) {
200780fb4a2SCy Schubert 			sockaddr_print(MSG_DEBUG,
201780fb4a2SCy Schubert 				       "CTRL_IFACE changed monitor level",
202780fb4a2SCy Schubert 				       from, fromlen);
203780fb4a2SCy Schubert 			dst->debug_level = atoi(level);
204780fb4a2SCy Schubert 			return 0;
205780fb4a2SCy Schubert 		}
206780fb4a2SCy Schubert 	}
207780fb4a2SCy Schubert 
208780fb4a2SCy Schubert 	return -1;
209780fb4a2SCy Schubert }
210