1 /*
2  * Wired Ethernet driver interface
3  * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2004, Gunter Burchardt <tira@isx.de>
5  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9 
10 #include "includes.h"
11 
12 #include "common.h"
13 #include "eloop.h"
14 #include "driver.h"
15 #include "driver_wired_common.h"
16 
17 #include <sys/ioctl.h>
18 #ifdef __linux__
19 #include <netpacket/packet.h>
20 #include <net/if_arp.h>
21 #endif /* __linux__ */
22 #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
23 #include <net/if_dl.h>
24 #include <net/if_media.h>
25 #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */
26 #ifdef __sun__
27 #include <sys/sockio.h>
28 #endif /* __sun__ */
29 
30 #ifdef _MSC_VER
31 #pragma pack(push, 1)
32 #endif /* _MSC_VER */
33 
34 struct ieee8023_hdr {
35 	u8 dest[6];
36 	u8 src[6];
37 	u16 ethertype;
38 } STRUCT_PACKED;
39 
40 #ifdef _MSC_VER
41 #pragma pack(pop)
42 #endif /* _MSC_VER */
43 
44 
45 struct wpa_driver_wired_data {
46 	struct driver_wired_common_data common;
47 
48 	int dhcp_sock; /* socket for dhcp packets */
49 	int use_pae_group_addr;
50 };
51 
52 
53 /* TODO: detecting new devices should eventually be changed from using DHCP
54  * snooping to trigger on any packet from a new layer 2 MAC address, e.g.,
55  * based on ebtables, etc. */
56 
57 struct dhcp_message {
58 	u_int8_t op;
59 	u_int8_t htype;
60 	u_int8_t hlen;
61 	u_int8_t hops;
62 	u_int32_t xid;
63 	u_int16_t secs;
64 	u_int16_t flags;
65 	u_int32_t ciaddr;
66 	u_int32_t yiaddr;
67 	u_int32_t siaddr;
68 	u_int32_t giaddr;
69 	u_int8_t chaddr[16];
70 	u_int8_t sname[64];
71 	u_int8_t file[128];
72 	u_int32_t cookie;
73 	u_int8_t options[308]; /* 312 - cookie */
74 };
75 
76 
77 #ifdef __linux__
handle_data(void * ctx,unsigned char * buf,size_t len)78 static void handle_data(void *ctx, unsigned char *buf, size_t len)
79 {
80 #ifdef HOSTAPD
81 	struct ieee8023_hdr *hdr;
82 	u8 *pos, *sa;
83 	size_t left;
84 	union wpa_event_data event;
85 
86 	/* must contain at least ieee8023_hdr 6 byte source, 6 byte dest,
87 	 * 2 byte ethertype */
88 	if (len < 14) {
89 		wpa_printf(MSG_MSGDUMP, "handle_data: too short (%lu)",
90 			   (unsigned long) len);
91 		return;
92 	}
93 
94 	hdr = (struct ieee8023_hdr *) buf;
95 
96 	switch (ntohs(hdr->ethertype)) {
97 	case ETH_P_PAE:
98 		wpa_printf(MSG_MSGDUMP, "Received EAPOL packet");
99 		sa = hdr->src;
100 		os_memset(&event, 0, sizeof(event));
101 		event.new_sta.addr = sa;
102 		wpa_supplicant_event(ctx, EVENT_NEW_STA, &event);
103 
104 		pos = (u8 *) (hdr + 1);
105 		left = len - sizeof(*hdr);
106 		drv_event_eapol_rx(ctx, sa, pos, left);
107 		break;
108 
109 	default:
110 		wpa_printf(MSG_DEBUG, "Unknown ethertype 0x%04x in data frame",
111 			   ntohs(hdr->ethertype));
112 		break;
113 	}
114 #endif /* HOSTAPD */
115 }
116 
117 
handle_read(int sock,void * eloop_ctx,void * sock_ctx)118 static void handle_read(int sock, void *eloop_ctx, void *sock_ctx)
119 {
120 	int len;
121 	unsigned char buf[3000];
122 
123 	len = recv(sock, buf, sizeof(buf), 0);
124 	if (len < 0) {
125 		wpa_printf(MSG_ERROR, "recv: %s", strerror(errno));
126 		return;
127 	}
128 
129 	handle_data(eloop_ctx, buf, len);
130 }
131 
132 
handle_dhcp(int sock,void * eloop_ctx,void * sock_ctx)133 static void handle_dhcp(int sock, void *eloop_ctx, void *sock_ctx)
134 {
135 	int len;
136 	unsigned char buf[3000];
137 	struct dhcp_message *msg;
138 	u8 *mac_address;
139 	union wpa_event_data event;
140 
141 	len = recv(sock, buf, sizeof(buf), 0);
142 	if (len < 0) {
143 		wpa_printf(MSG_ERROR, "recv: %s", strerror(errno));
144 		return;
145 	}
146 
147 	/* must contain at least dhcp_message->chaddr */
148 	if (len < 44) {
149 		wpa_printf(MSG_MSGDUMP, "handle_dhcp: too short (%d)", len);
150 		return;
151 	}
152 
153 	msg = (struct dhcp_message *) buf;
154 	mac_address = (u8 *) &(msg->chaddr);
155 
156 	wpa_printf(MSG_MSGDUMP, "Got DHCP broadcast packet from " MACSTR,
157 		   MAC2STR(mac_address));
158 
159 	os_memset(&event, 0, sizeof(event));
160 	event.new_sta.addr = mac_address;
161 	wpa_supplicant_event(eloop_ctx, EVENT_NEW_STA, &event);
162 }
163 #endif /* __linux__ */
164 
165 
wired_init_sockets(struct wpa_driver_wired_data * drv,u8 * own_addr)166 static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr)
167 {
168 #ifdef __linux__
169 	struct ifreq ifr;
170 	struct sockaddr_ll addr;
171 	struct sockaddr_in addr2;
172 	int n = 1;
173 
174 	drv->common.sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE));
175 	if (drv->common.sock < 0) {
176 		wpa_printf(MSG_ERROR, "socket[PF_PACKET,SOCK_RAW]: %s",
177 			   strerror(errno));
178 		return -1;
179 	}
180 
181 	if (eloop_register_read_sock(drv->common.sock, handle_read,
182 				     drv->common.ctx, NULL)) {
183 		wpa_printf(MSG_INFO, "Could not register read socket");
184 		return -1;
185 	}
186 
187 	os_memset(&ifr, 0, sizeof(ifr));
188 	os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name));
189 	if (ioctl(drv->common.sock, SIOCGIFINDEX, &ifr) != 0) {
190 		wpa_printf(MSG_ERROR, "ioctl(SIOCGIFINDEX): %s",
191 			   strerror(errno));
192 		return -1;
193 	}
194 
195 	os_memset(&addr, 0, sizeof(addr));
196 	addr.sll_family = AF_PACKET;
197 	addr.sll_ifindex = ifr.ifr_ifindex;
198 	wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d",
199 		   addr.sll_ifindex);
200 
201 	if (bind(drv->common.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
202 	{
203 		wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
204 		return -1;
205 	}
206 
207 	/* filter multicast address */
208 	if (wired_multicast_membership(drv->common.sock, ifr.ifr_ifindex,
209 				       pae_group_addr, 1) < 0) {
210 		wpa_printf(MSG_ERROR, "wired: Failed to add multicast group "
211 			   "membership");
212 		return -1;
213 	}
214 
215 	os_memset(&ifr, 0, sizeof(ifr));
216 	os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name));
217 	if (ioctl(drv->common.sock, SIOCGIFHWADDR, &ifr) != 0) {
218 		wpa_printf(MSG_ERROR, "ioctl(SIOCGIFHWADDR): %s",
219 			   strerror(errno));
220 		return -1;
221 	}
222 
223 	if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
224 		wpa_printf(MSG_INFO, "Invalid HW-addr family 0x%04x",
225 			   ifr.ifr_hwaddr.sa_family);
226 		return -1;
227 	}
228 	os_memcpy(own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
229 
230 	/* setup dhcp listen socket for sta detection */
231 	if ((drv->dhcp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
232 		wpa_printf(MSG_ERROR, "socket call failed for dhcp: %s",
233 			   strerror(errno));
234 		return -1;
235 	}
236 
237 	if (eloop_register_read_sock(drv->dhcp_sock, handle_dhcp,
238 				     drv->common.ctx, NULL)) {
239 		wpa_printf(MSG_INFO, "Could not register read socket");
240 		return -1;
241 	}
242 
243 	os_memset(&addr2, 0, sizeof(addr2));
244 	addr2.sin_family = AF_INET;
245 	addr2.sin_port = htons(67);
246 	addr2.sin_addr.s_addr = INADDR_ANY;
247 
248 	if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_REUSEADDR, (char *) &n,
249 		       sizeof(n)) == -1) {
250 		wpa_printf(MSG_ERROR, "setsockopt[SOL_SOCKET,SO_REUSEADDR]: %s",
251 			   strerror(errno));
252 		return -1;
253 	}
254 	if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BROADCAST, (char *) &n,
255 		       sizeof(n)) == -1) {
256 		wpa_printf(MSG_ERROR, "setsockopt[SOL_SOCKET,SO_BROADCAST]: %s",
257 			   strerror(errno));
258 		return -1;
259 	}
260 
261 	os_memset(&ifr, 0, sizeof(ifr));
262 	os_strlcpy(ifr.ifr_ifrn.ifrn_name, drv->common.ifname, IFNAMSIZ);
263 	if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BINDTODEVICE,
264 		       (char *) &ifr, sizeof(ifr)) < 0) {
265 		wpa_printf(MSG_ERROR,
266 			   "setsockopt[SOL_SOCKET,SO_BINDTODEVICE]: %s",
267 			   strerror(errno));
268 		return -1;
269 	}
270 
271 	if (bind(drv->dhcp_sock, (struct sockaddr *) &addr2,
272 		 sizeof(struct sockaddr)) == -1) {
273 		wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
274 		return -1;
275 	}
276 
277 	return 0;
278 #else /* __linux__ */
279 	return -1;
280 #endif /* __linux__ */
281 }
282 
283 
wired_send_eapol(void * priv,const u8 * addr,const u8 * data,size_t data_len,int encrypt,const u8 * own_addr,u32 flags)284 static int wired_send_eapol(void *priv, const u8 *addr,
285 			    const u8 *data, size_t data_len, int encrypt,
286 			    const u8 *own_addr, u32 flags)
287 {
288 	struct wpa_driver_wired_data *drv = priv;
289 	struct ieee8023_hdr *hdr;
290 	size_t len;
291 	u8 *pos;
292 	int res;
293 
294 	len = sizeof(*hdr) + data_len;
295 	hdr = os_zalloc(len);
296 	if (hdr == NULL) {
297 		wpa_printf(MSG_INFO,
298 			   "malloc() failed for wired_send_eapol(len=%lu)",
299 			   (unsigned long) len);
300 		return -1;
301 	}
302 
303 	os_memcpy(hdr->dest, drv->use_pae_group_addr ? pae_group_addr : addr,
304 		  ETH_ALEN);
305 	os_memcpy(hdr->src, own_addr, ETH_ALEN);
306 	hdr->ethertype = htons(ETH_P_PAE);
307 
308 	pos = (u8 *) (hdr + 1);
309 	os_memcpy(pos, data, data_len);
310 
311 	res = send(drv->common.sock, (u8 *) hdr, len, 0);
312 	os_free(hdr);
313 
314 	if (res < 0) {
315 		wpa_printf(MSG_ERROR,
316 			   "wired_send_eapol - packet len: %lu - failed: send: %s",
317 			   (unsigned long) len, strerror(errno));
318 	}
319 
320 	return res;
321 }
322 
323 
wired_driver_hapd_init(struct hostapd_data * hapd,struct wpa_init_params * params)324 static void * wired_driver_hapd_init(struct hostapd_data *hapd,
325 				     struct wpa_init_params *params)
326 {
327 	struct wpa_driver_wired_data *drv;
328 
329 	drv = os_zalloc(sizeof(struct wpa_driver_wired_data));
330 	if (drv == NULL) {
331 		wpa_printf(MSG_INFO,
332 			   "Could not allocate memory for wired driver data");
333 		return NULL;
334 	}
335 
336 	drv->common.ctx = hapd;
337 	os_strlcpy(drv->common.ifname, params->ifname,
338 		   sizeof(drv->common.ifname));
339 	drv->use_pae_group_addr = params->use_pae_group_addr;
340 
341 	if (wired_init_sockets(drv, params->own_addr)) {
342 		os_free(drv);
343 		return NULL;
344 	}
345 
346 	return drv;
347 }
348 
349 
wired_driver_hapd_deinit(void * priv)350 static void wired_driver_hapd_deinit(void *priv)
351 {
352 	struct wpa_driver_wired_data *drv = priv;
353 
354 	if (drv->common.sock >= 0) {
355 		eloop_unregister_read_sock(drv->common.sock);
356 		close(drv->common.sock);
357 	}
358 
359 	if (drv->dhcp_sock >= 0) {
360 		eloop_unregister_read_sock(drv->dhcp_sock);
361 		close(drv->dhcp_sock);
362 	}
363 
364 	os_free(drv);
365 }
366 
367 
wpa_driver_wired_init(void * ctx,const char * ifname)368 static void * wpa_driver_wired_init(void *ctx, const char *ifname)
369 {
370 	struct wpa_driver_wired_data *drv;
371 
372 	drv = os_zalloc(sizeof(*drv));
373 	if (drv == NULL)
374 		return NULL;
375 
376 	if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
377 		os_free(drv);
378 		return NULL;
379 	}
380 
381 	return drv;
382 }
383 
384 
wpa_driver_wired_deinit(void * priv)385 static void wpa_driver_wired_deinit(void *priv)
386 {
387 	struct wpa_driver_wired_data *drv = priv;
388 
389 	driver_wired_deinit_common(&drv->common);
390 	os_free(drv);
391 }
392 
393 
394 const struct wpa_driver_ops wpa_driver_wired_ops = {
395 	.name = "wired",
396 	.desc = "Wired Ethernet driver",
397 	.hapd_init = wired_driver_hapd_init,
398 	.hapd_deinit = wired_driver_hapd_deinit,
399 	.hapd_send_eapol = wired_send_eapol,
400 	.get_ssid = driver_wired_get_ssid,
401 	.get_bssid = driver_wired_get_bssid,
402 	.get_capa = driver_wired_get_capa,
403 	.init = wpa_driver_wired_init,
404 	.deinit = wpa_driver_wired_deinit,
405 };
406