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