xref: /linux/net/wireless/nl80211.c (revision ed3174d93c342b8b2eeba6bbd124707d55304a7b)
1 /*
2  * This is the new netlink-based wireless configuration interface.
3  *
4  * Copyright 2006, 2007	Johannes Berg <johannes@sipsolutions.net>
5  */
6 
7 #include <linux/if.h>
8 #include <linux/module.h>
9 #include <linux/err.h>
10 #include <linux/mutex.h>
11 #include <linux/list.h>
12 #include <linux/if_ether.h>
13 #include <linux/ieee80211.h>
14 #include <linux/nl80211.h>
15 #include <linux/rtnetlink.h>
16 #include <linux/netlink.h>
17 #include <net/genetlink.h>
18 #include <net/cfg80211.h>
19 #include "core.h"
20 #include "nl80211.h"
21 
22 /* the netlink family */
23 static struct genl_family nl80211_fam = {
24 	.id = GENL_ID_GENERATE,	/* don't bother with a hardcoded ID */
25 	.name = "nl80211",	/* have users key off the name instead */
26 	.hdrsize = 0,		/* no private header */
27 	.version = 1,		/* no particular meaning now */
28 	.maxattr = NL80211_ATTR_MAX,
29 };
30 
31 /* internal helper: get drv and dev */
32 static int get_drv_dev_by_info_ifindex(struct genl_info *info,
33 				       struct cfg80211_registered_device **drv,
34 				       struct net_device **dev)
35 {
36 	int ifindex;
37 
38 	if (!info->attrs[NL80211_ATTR_IFINDEX])
39 		return -EINVAL;
40 
41 	ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
42 	*dev = dev_get_by_index(&init_net, ifindex);
43 	if (!*dev)
44 		return -ENODEV;
45 
46 	*drv = cfg80211_get_dev_from_ifindex(ifindex);
47 	if (IS_ERR(*drv)) {
48 		dev_put(*dev);
49 		return PTR_ERR(*drv);
50 	}
51 
52 	return 0;
53 }
54 
55 /* policy for the attributes */
56 static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
57 	[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
58 	[NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
59 				      .len = BUS_ID_SIZE-1 },
60 
61 	[NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
62 	[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
63 	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
64 
65 	[NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
66 
67 	[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
68 				    .len = WLAN_MAX_KEY_LEN },
69 	[NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
70 	[NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
71 	[NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
72 
73 	[NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
74 	[NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
75 	[NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
76 				       .len = IEEE80211_MAX_DATA_LEN },
77 	[NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
78 				       .len = IEEE80211_MAX_DATA_LEN },
79 	[NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
80 	[NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
81 	[NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
82 	[NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
83 					       .len = NL80211_MAX_SUPP_RATES },
84 	[NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
85 };
86 
87 /* message building helper */
88 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
89 				   int flags, u8 cmd)
90 {
91 	/* since there is no private header just add the generic one */
92 	return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
93 }
94 
95 /* netlink command implementations */
96 
97 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
98 			      struct cfg80211_registered_device *dev)
99 {
100 	void *hdr;
101 
102 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
103 	if (!hdr)
104 		return -1;
105 
106 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
107 	NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
108 	return genlmsg_end(msg, hdr);
109 
110  nla_put_failure:
111 	return genlmsg_cancel(msg, hdr);
112 }
113 
114 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
115 {
116 	int idx = 0;
117 	int start = cb->args[0];
118 	struct cfg80211_registered_device *dev;
119 
120 	mutex_lock(&cfg80211_drv_mutex);
121 	list_for_each_entry(dev, &cfg80211_drv_list, list) {
122 		if (++idx < start)
123 			continue;
124 		if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
125 				       cb->nlh->nlmsg_seq, NLM_F_MULTI,
126 				       dev) < 0)
127 			break;
128 	}
129 	mutex_unlock(&cfg80211_drv_mutex);
130 
131 	cb->args[0] = idx;
132 
133 	return skb->len;
134 }
135 
136 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
137 {
138 	struct sk_buff *msg;
139 	struct cfg80211_registered_device *dev;
140 
141 	dev = cfg80211_get_dev_from_info(info);
142 	if (IS_ERR(dev))
143 		return PTR_ERR(dev);
144 
145 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
146 	if (!msg)
147 		goto out_err;
148 
149 	if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
150 		goto out_free;
151 
152 	cfg80211_put_dev(dev);
153 
154 	return genlmsg_unicast(msg, info->snd_pid);
155 
156  out_free:
157 	nlmsg_free(msg);
158  out_err:
159 	cfg80211_put_dev(dev);
160 	return -ENOBUFS;
161 }
162 
163 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
164 {
165 	struct cfg80211_registered_device *rdev;
166 	int result;
167 
168 	if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
169 		return -EINVAL;
170 
171 	rdev = cfg80211_get_dev_from_info(info);
172 	if (IS_ERR(rdev))
173 		return PTR_ERR(rdev);
174 
175 	result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
176 
177 	cfg80211_put_dev(rdev);
178 	return result;
179 }
180 
181 
182 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
183 			      struct net_device *dev)
184 {
185 	void *hdr;
186 
187 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
188 	if (!hdr)
189 		return -1;
190 
191 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
192 	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
193 	/* TODO: interface type */
194 	return genlmsg_end(msg, hdr);
195 
196  nla_put_failure:
197 	return genlmsg_cancel(msg, hdr);
198 }
199 
200 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
201 {
202 	int wp_idx = 0;
203 	int if_idx = 0;
204 	int wp_start = cb->args[0];
205 	int if_start = cb->args[1];
206 	struct cfg80211_registered_device *dev;
207 	struct wireless_dev *wdev;
208 
209 	mutex_lock(&cfg80211_drv_mutex);
210 	list_for_each_entry(dev, &cfg80211_drv_list, list) {
211 		if (++wp_idx < wp_start)
212 			continue;
213 		if_idx = 0;
214 
215 		mutex_lock(&dev->devlist_mtx);
216 		list_for_each_entry(wdev, &dev->netdev_list, list) {
217 			if (++if_idx < if_start)
218 				continue;
219 			if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
220 					       cb->nlh->nlmsg_seq, NLM_F_MULTI,
221 					       wdev->netdev) < 0)
222 				break;
223 		}
224 		mutex_unlock(&dev->devlist_mtx);
225 	}
226 	mutex_unlock(&cfg80211_drv_mutex);
227 
228 	cb->args[0] = wp_idx;
229 	cb->args[1] = if_idx;
230 
231 	return skb->len;
232 }
233 
234 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
235 {
236 	struct sk_buff *msg;
237 	struct cfg80211_registered_device *dev;
238 	struct net_device *netdev;
239 	int err;
240 
241 	err = get_drv_dev_by_info_ifindex(info, &dev, &netdev);
242 	if (err)
243 		return err;
244 
245 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
246 	if (!msg)
247 		goto out_err;
248 
249 	if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
250 		goto out_free;
251 
252 	dev_put(netdev);
253 	cfg80211_put_dev(dev);
254 
255 	return genlmsg_unicast(msg, info->snd_pid);
256 
257  out_free:
258 	nlmsg_free(msg);
259  out_err:
260 	dev_put(netdev);
261 	cfg80211_put_dev(dev);
262 	return -ENOBUFS;
263 }
264 
265 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
266 {
267 	struct cfg80211_registered_device *drv;
268 	int err, ifindex;
269 	enum nl80211_iftype type;
270 	struct net_device *dev;
271 
272 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
273 		type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
274 		if (type > NL80211_IFTYPE_MAX)
275 			return -EINVAL;
276 	} else
277 		return -EINVAL;
278 
279 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
280 	if (err)
281 		return err;
282 	ifindex = dev->ifindex;
283 	dev_put(dev);
284 
285 	if (!drv->ops->change_virtual_intf) {
286 		err = -EOPNOTSUPP;
287 		goto unlock;
288 	}
289 
290 	rtnl_lock();
291 	err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, type);
292 	rtnl_unlock();
293 
294  unlock:
295 	cfg80211_put_dev(drv);
296 	return err;
297 }
298 
299 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
300 {
301 	struct cfg80211_registered_device *drv;
302 	int err;
303 	enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
304 
305 	if (!info->attrs[NL80211_ATTR_IFNAME])
306 		return -EINVAL;
307 
308 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
309 		type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
310 		if (type > NL80211_IFTYPE_MAX)
311 			return -EINVAL;
312 	}
313 
314 	drv = cfg80211_get_dev_from_info(info);
315 	if (IS_ERR(drv))
316 		return PTR_ERR(drv);
317 
318 	if (!drv->ops->add_virtual_intf) {
319 		err = -EOPNOTSUPP;
320 		goto unlock;
321 	}
322 
323 	rtnl_lock();
324 	err = drv->ops->add_virtual_intf(&drv->wiphy,
325 		nla_data(info->attrs[NL80211_ATTR_IFNAME]), type);
326 	rtnl_unlock();
327 
328  unlock:
329 	cfg80211_put_dev(drv);
330 	return err;
331 }
332 
333 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
334 {
335 	struct cfg80211_registered_device *drv;
336 	int ifindex, err;
337 	struct net_device *dev;
338 
339 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
340 	if (err)
341 		return err;
342 	ifindex = dev->ifindex;
343 	dev_put(dev);
344 
345 	if (!drv->ops->del_virtual_intf) {
346 		err = -EOPNOTSUPP;
347 		goto out;
348 	}
349 
350 	rtnl_lock();
351 	err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
352 	rtnl_unlock();
353 
354  out:
355 	cfg80211_put_dev(drv);
356 	return err;
357 }
358 
359 struct get_key_cookie {
360 	struct sk_buff *msg;
361 	int error;
362 };
363 
364 static void get_key_callback(void *c, struct key_params *params)
365 {
366 	struct get_key_cookie *cookie = c;
367 
368 	if (params->key)
369 		NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
370 			params->key_len, params->key);
371 
372 	if (params->seq)
373 		NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
374 			params->seq_len, params->seq);
375 
376 	if (params->cipher)
377 		NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
378 			    params->cipher);
379 
380 	return;
381  nla_put_failure:
382 	cookie->error = 1;
383 }
384 
385 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
386 {
387 	struct cfg80211_registered_device *drv;
388 	int err;
389 	struct net_device *dev;
390 	u8 key_idx = 0;
391 	u8 *mac_addr = NULL;
392 	struct get_key_cookie cookie = {
393 		.error = 0,
394 	};
395 	void *hdr;
396 	struct sk_buff *msg;
397 
398 	if (info->attrs[NL80211_ATTR_KEY_IDX])
399 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
400 
401 	if (key_idx > 3)
402 		return -EINVAL;
403 
404 	if (info->attrs[NL80211_ATTR_MAC])
405 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
406 
407 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
408 	if (err)
409 		return err;
410 
411 	if (!drv->ops->get_key) {
412 		err = -EOPNOTSUPP;
413 		goto out;
414 	}
415 
416 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
417 	if (!msg) {
418 		err = -ENOMEM;
419 		goto out;
420 	}
421 
422 	hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
423 			     NL80211_CMD_NEW_KEY);
424 
425 	if (IS_ERR(hdr)) {
426 		err = PTR_ERR(hdr);
427 		goto out;
428 	}
429 
430 	cookie.msg = msg;
431 
432 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
433 	NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
434 	if (mac_addr)
435 		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
436 
437 	rtnl_lock();
438 	err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
439 				&cookie, get_key_callback);
440 	rtnl_unlock();
441 
442 	if (err)
443 		goto out;
444 
445 	if (cookie.error)
446 		goto nla_put_failure;
447 
448 	genlmsg_end(msg, hdr);
449 	err = genlmsg_unicast(msg, info->snd_pid);
450 	goto out;
451 
452  nla_put_failure:
453 	err = -ENOBUFS;
454 	nlmsg_free(msg);
455  out:
456 	cfg80211_put_dev(drv);
457 	dev_put(dev);
458 	return err;
459 }
460 
461 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
462 {
463 	struct cfg80211_registered_device *drv;
464 	int err;
465 	struct net_device *dev;
466 	u8 key_idx;
467 
468 	if (!info->attrs[NL80211_ATTR_KEY_IDX])
469 		return -EINVAL;
470 
471 	key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
472 
473 	if (key_idx > 3)
474 		return -EINVAL;
475 
476 	/* currently only support setting default key */
477 	if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
478 		return -EINVAL;
479 
480 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
481 	if (err)
482 		return err;
483 
484 	if (!drv->ops->set_default_key) {
485 		err = -EOPNOTSUPP;
486 		goto out;
487 	}
488 
489 	rtnl_lock();
490 	err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
491 	rtnl_unlock();
492 
493  out:
494 	cfg80211_put_dev(drv);
495 	dev_put(dev);
496 	return err;
497 }
498 
499 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
500 {
501 	struct cfg80211_registered_device *drv;
502 	int err;
503 	struct net_device *dev;
504 	struct key_params params;
505 	u8 key_idx = 0;
506 	u8 *mac_addr = NULL;
507 
508 	memset(&params, 0, sizeof(params));
509 
510 	if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
511 		return -EINVAL;
512 
513 	if (info->attrs[NL80211_ATTR_KEY_DATA]) {
514 		params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
515 		params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
516 	}
517 
518 	if (info->attrs[NL80211_ATTR_KEY_IDX])
519 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
520 
521 	params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
522 
523 	if (info->attrs[NL80211_ATTR_MAC])
524 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
525 
526 	if (key_idx > 3)
527 		return -EINVAL;
528 
529 	/*
530 	 * Disallow pairwise keys with non-zero index unless it's WEP
531 	 * (because current deployments use pairwise WEP keys with
532 	 * non-zero indizes but 802.11i clearly specifies to use zero)
533 	 */
534 	if (mac_addr && key_idx &&
535 	    params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
536 	    params.cipher != WLAN_CIPHER_SUITE_WEP104)
537 		return -EINVAL;
538 
539 	/* TODO: add definitions for the lengths to linux/ieee80211.h */
540 	switch (params.cipher) {
541 	case WLAN_CIPHER_SUITE_WEP40:
542 		if (params.key_len != 5)
543 			return -EINVAL;
544 		break;
545 	case WLAN_CIPHER_SUITE_TKIP:
546 		if (params.key_len != 32)
547 			return -EINVAL;
548 		break;
549 	case WLAN_CIPHER_SUITE_CCMP:
550 		if (params.key_len != 16)
551 			return -EINVAL;
552 		break;
553 	case WLAN_CIPHER_SUITE_WEP104:
554 		if (params.key_len != 13)
555 			return -EINVAL;
556 		break;
557 	default:
558 		return -EINVAL;
559 	}
560 
561 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
562 	if (err)
563 		return err;
564 
565 	if (!drv->ops->add_key) {
566 		err = -EOPNOTSUPP;
567 		goto out;
568 	}
569 
570 	rtnl_lock();
571 	err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
572 	rtnl_unlock();
573 
574  out:
575 	cfg80211_put_dev(drv);
576 	dev_put(dev);
577 	return err;
578 }
579 
580 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
581 {
582 	struct cfg80211_registered_device *drv;
583 	int err;
584 	struct net_device *dev;
585 	u8 key_idx = 0;
586 	u8 *mac_addr = NULL;
587 
588 	if (info->attrs[NL80211_ATTR_KEY_IDX])
589 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
590 
591 	if (key_idx > 3)
592 		return -EINVAL;
593 
594 	if (info->attrs[NL80211_ATTR_MAC])
595 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
596 
597 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
598 	if (err)
599 		return err;
600 
601 	if (!drv->ops->del_key) {
602 		err = -EOPNOTSUPP;
603 		goto out;
604 	}
605 
606 	rtnl_lock();
607 	err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
608 	rtnl_unlock();
609 
610  out:
611 	cfg80211_put_dev(drv);
612 	dev_put(dev);
613 	return err;
614 }
615 
616 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
617 {
618         int (*call)(struct wiphy *wiphy, struct net_device *dev,
619 		    struct beacon_parameters *info);
620 	struct cfg80211_registered_device *drv;
621 	int err;
622 	struct net_device *dev;
623 	struct beacon_parameters params;
624 	int haveinfo = 0;
625 
626 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
627 	if (err)
628 		return err;
629 
630 	switch (info->genlhdr->cmd) {
631 	case NL80211_CMD_NEW_BEACON:
632 		/* these are required for NEW_BEACON */
633 		if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
634 		    !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
635 		    !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
636 			err = -EINVAL;
637 			goto out;
638 		}
639 
640 		call = drv->ops->add_beacon;
641 		break;
642 	case NL80211_CMD_SET_BEACON:
643 		call = drv->ops->set_beacon;
644 		break;
645 	default:
646 		WARN_ON(1);
647 		err = -EOPNOTSUPP;
648 		goto out;
649 	}
650 
651 	if (!call) {
652 		err = -EOPNOTSUPP;
653 		goto out;
654 	}
655 
656 	memset(&params, 0, sizeof(params));
657 
658 	if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
659 		params.interval =
660 		    nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
661 		haveinfo = 1;
662 	}
663 
664 	if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
665 		params.dtim_period =
666 		    nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
667 		haveinfo = 1;
668 	}
669 
670 	if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
671 		params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
672 		params.head_len =
673 		    nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
674 		haveinfo = 1;
675 	}
676 
677 	if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
678 		params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
679 		params.tail_len =
680 		    nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
681 		haveinfo = 1;
682 	}
683 
684 	if (!haveinfo) {
685 		err = -EINVAL;
686 		goto out;
687 	}
688 
689 	rtnl_lock();
690 	err = call(&drv->wiphy, dev, &params);
691 	rtnl_unlock();
692 
693  out:
694 	cfg80211_put_dev(drv);
695 	dev_put(dev);
696 	return err;
697 }
698 
699 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
700 {
701 	struct cfg80211_registered_device *drv;
702 	int err;
703 	struct net_device *dev;
704 
705 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
706 	if (err)
707 		return err;
708 
709 	if (!drv->ops->del_beacon) {
710 		err = -EOPNOTSUPP;
711 		goto out;
712 	}
713 
714 	rtnl_lock();
715 	err = drv->ops->del_beacon(&drv->wiphy, dev);
716 	rtnl_unlock();
717 
718  out:
719 	cfg80211_put_dev(drv);
720 	dev_put(dev);
721 	return err;
722 }
723 
724 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
725 	[NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
726 	[NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
727 	[NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
728 };
729 
730 static int parse_station_flags(struct nlattr *nla, u32 *staflags)
731 {
732 	struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
733 	int flag;
734 
735 	*staflags = 0;
736 
737 	if (!nla)
738 		return 0;
739 
740 	if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
741 			     nla, sta_flags_policy))
742 		return -EINVAL;
743 
744 	*staflags = STATION_FLAG_CHANGED;
745 
746 	for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
747 		if (flags[flag])
748 			*staflags |= (1<<flag);
749 
750 	return 0;
751 }
752 
753 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
754 				int flags, struct net_device *dev,
755 				u8 *mac_addr, struct station_stats *stats)
756 {
757 	void *hdr;
758 	struct nlattr *statsattr;
759 
760 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
761 	if (!hdr)
762 		return -1;
763 
764 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
765 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
766 
767 	statsattr = nla_nest_start(msg, NL80211_ATTR_STA_STATS);
768 	if (!statsattr)
769 		goto nla_put_failure;
770 	if (stats->filled & STATION_STAT_INACTIVE_TIME)
771 		NLA_PUT_U32(msg, NL80211_STA_STAT_INACTIVE_TIME,
772 			    stats->inactive_time);
773 	if (stats->filled & STATION_STAT_RX_BYTES)
774 		NLA_PUT_U32(msg, NL80211_STA_STAT_RX_BYTES,
775 			    stats->rx_bytes);
776 	if (stats->filled & STATION_STAT_TX_BYTES)
777 		NLA_PUT_U32(msg, NL80211_STA_STAT_TX_BYTES,
778 			    stats->tx_bytes);
779 
780 	nla_nest_end(msg, statsattr);
781 
782 	return genlmsg_end(msg, hdr);
783 
784  nla_put_failure:
785 	return genlmsg_cancel(msg, hdr);
786 }
787 
788 
789 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
790 {
791 	struct cfg80211_registered_device *drv;
792 	int err;
793 	struct net_device *dev;
794 	struct station_stats stats;
795 	struct sk_buff *msg;
796 	u8 *mac_addr = NULL;
797 
798 	memset(&stats, 0, sizeof(stats));
799 
800 	if (!info->attrs[NL80211_ATTR_MAC])
801 		return -EINVAL;
802 
803 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
804 
805 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
806 	if (err)
807 		return err;
808 
809 	if (!drv->ops->get_station) {
810 		err = -EOPNOTSUPP;
811 		goto out;
812 	}
813 
814 	rtnl_lock();
815 	err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &stats);
816 	rtnl_unlock();
817 
818 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
819 	if (!msg)
820 		goto out;
821 
822 	if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
823 				 dev, mac_addr, &stats) < 0)
824 		goto out_free;
825 
826 	err = genlmsg_unicast(msg, info->snd_pid);
827 	goto out;
828 
829  out_free:
830 	nlmsg_free(msg);
831 
832  out:
833 	cfg80211_put_dev(drv);
834 	dev_put(dev);
835 	return err;
836 }
837 
838 /*
839  * Get vlan interface making sure it is on the right wiphy.
840  */
841 static int get_vlan(struct nlattr *vlanattr,
842 		    struct cfg80211_registered_device *rdev,
843 		    struct net_device **vlan)
844 {
845 	*vlan = NULL;
846 
847 	if (vlanattr) {
848 		*vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
849 		if (!*vlan)
850 			return -ENODEV;
851 		if (!(*vlan)->ieee80211_ptr)
852 			return -EINVAL;
853 		if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
854 			return -EINVAL;
855 	}
856 	return 0;
857 }
858 
859 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
860 {
861 	struct cfg80211_registered_device *drv;
862 	int err;
863 	struct net_device *dev;
864 	struct station_parameters params;
865 	u8 *mac_addr = NULL;
866 
867 	memset(&params, 0, sizeof(params));
868 
869 	params.listen_interval = -1;
870 
871 	if (info->attrs[NL80211_ATTR_STA_AID])
872 		return -EINVAL;
873 
874 	if (!info->attrs[NL80211_ATTR_MAC])
875 		return -EINVAL;
876 
877 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
878 
879 	if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
880 		params.supported_rates =
881 			nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
882 		params.supported_rates_len =
883 			nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
884 	}
885 
886 	if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
887 		params.listen_interval =
888 		    nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
889 
890 	if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
891 				&params.station_flags))
892 		return -EINVAL;
893 
894 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
895 	if (err)
896 		return err;
897 
898 	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
899 	if (err)
900 		goto out;
901 
902 	if (!drv->ops->change_station) {
903 		err = -EOPNOTSUPP;
904 		goto out;
905 	}
906 
907 	rtnl_lock();
908 	err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
909 	rtnl_unlock();
910 
911  out:
912 	if (params.vlan)
913 		dev_put(params.vlan);
914 	cfg80211_put_dev(drv);
915 	dev_put(dev);
916 	return err;
917 }
918 
919 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
920 {
921 	struct cfg80211_registered_device *drv;
922 	int err;
923 	struct net_device *dev;
924 	struct station_parameters params;
925 	u8 *mac_addr = NULL;
926 
927 	memset(&params, 0, sizeof(params));
928 
929 	if (!info->attrs[NL80211_ATTR_MAC])
930 		return -EINVAL;
931 
932 	if (!info->attrs[NL80211_ATTR_STA_AID])
933 		return -EINVAL;
934 
935 	if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
936 		return -EINVAL;
937 
938 	if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
939 		return -EINVAL;
940 
941 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
942 	params.supported_rates =
943 		nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
944 	params.supported_rates_len =
945 		nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
946 	params.listen_interval =
947 		nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
948 	params.listen_interval = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
949 
950 	if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
951 				&params.station_flags))
952 		return -EINVAL;
953 
954 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
955 	if (err)
956 		return err;
957 
958 	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
959 	if (err)
960 		goto out;
961 
962 	if (!drv->ops->add_station) {
963 		err = -EOPNOTSUPP;
964 		goto out;
965 	}
966 
967 	rtnl_lock();
968 	err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
969 	rtnl_unlock();
970 
971  out:
972 	if (params.vlan)
973 		dev_put(params.vlan);
974 	cfg80211_put_dev(drv);
975 	dev_put(dev);
976 	return err;
977 }
978 
979 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
980 {
981 	struct cfg80211_registered_device *drv;
982 	int err;
983 	struct net_device *dev;
984 	u8 *mac_addr = NULL;
985 
986 	if (info->attrs[NL80211_ATTR_MAC])
987 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
988 
989 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
990 	if (err)
991 		return err;
992 
993 	if (!drv->ops->del_station) {
994 		err = -EOPNOTSUPP;
995 		goto out;
996 	}
997 
998 	rtnl_lock();
999 	err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1000 	rtnl_unlock();
1001 
1002  out:
1003 	cfg80211_put_dev(drv);
1004 	dev_put(dev);
1005 	return err;
1006 }
1007 
1008 static struct genl_ops nl80211_ops[] = {
1009 	{
1010 		.cmd = NL80211_CMD_GET_WIPHY,
1011 		.doit = nl80211_get_wiphy,
1012 		.dumpit = nl80211_dump_wiphy,
1013 		.policy = nl80211_policy,
1014 		/* can be retrieved by unprivileged users */
1015 	},
1016 	{
1017 		.cmd = NL80211_CMD_SET_WIPHY,
1018 		.doit = nl80211_set_wiphy,
1019 		.policy = nl80211_policy,
1020 		.flags = GENL_ADMIN_PERM,
1021 	},
1022 	{
1023 		.cmd = NL80211_CMD_GET_INTERFACE,
1024 		.doit = nl80211_get_interface,
1025 		.dumpit = nl80211_dump_interface,
1026 		.policy = nl80211_policy,
1027 		/* can be retrieved by unprivileged users */
1028 	},
1029 	{
1030 		.cmd = NL80211_CMD_SET_INTERFACE,
1031 		.doit = nl80211_set_interface,
1032 		.policy = nl80211_policy,
1033 		.flags = GENL_ADMIN_PERM,
1034 	},
1035 	{
1036 		.cmd = NL80211_CMD_NEW_INTERFACE,
1037 		.doit = nl80211_new_interface,
1038 		.policy = nl80211_policy,
1039 		.flags = GENL_ADMIN_PERM,
1040 	},
1041 	{
1042 		.cmd = NL80211_CMD_DEL_INTERFACE,
1043 		.doit = nl80211_del_interface,
1044 		.policy = nl80211_policy,
1045 		.flags = GENL_ADMIN_PERM,
1046 	},
1047 	{
1048 		.cmd = NL80211_CMD_GET_KEY,
1049 		.doit = nl80211_get_key,
1050 		.policy = nl80211_policy,
1051 		.flags = GENL_ADMIN_PERM,
1052 	},
1053 	{
1054 		.cmd = NL80211_CMD_SET_KEY,
1055 		.doit = nl80211_set_key,
1056 		.policy = nl80211_policy,
1057 		.flags = GENL_ADMIN_PERM,
1058 	},
1059 	{
1060 		.cmd = NL80211_CMD_NEW_KEY,
1061 		.doit = nl80211_new_key,
1062 		.policy = nl80211_policy,
1063 		.flags = GENL_ADMIN_PERM,
1064 	},
1065 	{
1066 		.cmd = NL80211_CMD_DEL_KEY,
1067 		.doit = nl80211_del_key,
1068 		.policy = nl80211_policy,
1069 		.flags = GENL_ADMIN_PERM,
1070 	},
1071 	{
1072 		.cmd = NL80211_CMD_SET_BEACON,
1073 		.policy = nl80211_policy,
1074 		.flags = GENL_ADMIN_PERM,
1075 		.doit = nl80211_addset_beacon,
1076 	},
1077 	{
1078 		.cmd = NL80211_CMD_NEW_BEACON,
1079 		.policy = nl80211_policy,
1080 		.flags = GENL_ADMIN_PERM,
1081 		.doit = nl80211_addset_beacon,
1082 	},
1083 	{
1084 		.cmd = NL80211_CMD_DEL_BEACON,
1085 		.policy = nl80211_policy,
1086 		.flags = GENL_ADMIN_PERM,
1087 		.doit = nl80211_del_beacon,
1088 	},
1089 	{
1090 		.cmd = NL80211_CMD_GET_STATION,
1091 		.doit = nl80211_get_station,
1092 		/* TODO: implement dumpit */
1093 		.policy = nl80211_policy,
1094 		.flags = GENL_ADMIN_PERM,
1095 	},
1096 	{
1097 		.cmd = NL80211_CMD_SET_STATION,
1098 		.doit = nl80211_set_station,
1099 		.policy = nl80211_policy,
1100 		.flags = GENL_ADMIN_PERM,
1101 	},
1102 	{
1103 		.cmd = NL80211_CMD_NEW_STATION,
1104 		.doit = nl80211_new_station,
1105 		.policy = nl80211_policy,
1106 		.flags = GENL_ADMIN_PERM,
1107 	},
1108 	{
1109 		.cmd = NL80211_CMD_DEL_STATION,
1110 		.doit = nl80211_del_station,
1111 		.policy = nl80211_policy,
1112 		.flags = GENL_ADMIN_PERM,
1113 	},
1114 };
1115 
1116 /* multicast groups */
1117 static struct genl_multicast_group nl80211_config_mcgrp = {
1118 	.name = "config",
1119 };
1120 
1121 /* notification functions */
1122 
1123 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
1124 {
1125 	struct sk_buff *msg;
1126 
1127 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1128 	if (!msg)
1129 		return;
1130 
1131 	if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
1132 		nlmsg_free(msg);
1133 		return;
1134 	}
1135 
1136 	genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
1137 }
1138 
1139 /* initialisation/exit functions */
1140 
1141 int nl80211_init(void)
1142 {
1143 	int err, i;
1144 
1145 	err = genl_register_family(&nl80211_fam);
1146 	if (err)
1147 		return err;
1148 
1149 	for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
1150 		err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
1151 		if (err)
1152 			goto err_out;
1153 	}
1154 
1155 	err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
1156 	if (err)
1157 		goto err_out;
1158 
1159 	return 0;
1160  err_out:
1161 	genl_unregister_family(&nl80211_fam);
1162 	return err;
1163 }
1164 
1165 void nl80211_exit(void)
1166 {
1167 	genl_unregister_family(&nl80211_fam);
1168 }
1169