aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hostap/hostap_ap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_ap.c')
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c375
1 files changed, 219 insertions, 156 deletions
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index dd9a18f8dbca..19c45e363aa7 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
20#include <linux/seq_file.h>
20#include <linux/delay.h> 21#include <linux/delay.h>
21#include <linux/random.h> 22#include <linux/random.h>
22#include <linux/if_arp.h> 23#include <linux/if_arp.h>
@@ -64,28 +65,32 @@ static void prism2_send_mgmt(struct net_device *dev,
64 65
65 66
66#ifndef PRISM2_NO_PROCFS_DEBUG 67#ifndef PRISM2_NO_PROCFS_DEBUG
67static int ap_debug_proc_read(char *page, char **start, off_t off, 68static int ap_debug_proc_show(struct seq_file *m, void *v)
68 int count, int *eof, void *data) 69{
69{ 70 struct ap_data *ap = m->private;
70 char *p = page; 71
71 struct ap_data *ap = (struct ap_data *) data; 72 seq_printf(m, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
72 73 seq_printf(m, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
73 if (off != 0) { 74 seq_printf(m, "max_inactivity=%u\n", ap->max_inactivity / HZ);
74 *eof = 1; 75 seq_printf(m, "bridge_packets=%u\n", ap->bridge_packets);
75 return 0; 76 seq_printf(m, "nullfunc_ack=%u\n", ap->nullfunc_ack);
76 } 77 seq_printf(m, "autom_ap_wds=%u\n", ap->autom_ap_wds);
77 78 seq_printf(m, "auth_algs=%u\n", ap->local->auth_algs);
78 p += sprintf(p, "BridgedUnicastFrames=%u\n", ap->bridged_unicast); 79 seq_printf(m, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);
79 p += sprintf(p, "BridgedMulticastFrames=%u\n", ap->bridged_multicast); 80 return 0;
80 p += sprintf(p, "max_inactivity=%u\n", ap->max_inactivity / HZ); 81}
81 p += sprintf(p, "bridge_packets=%u\n", ap->bridge_packets);
82 p += sprintf(p, "nullfunc_ack=%u\n", ap->nullfunc_ack);
83 p += sprintf(p, "autom_ap_wds=%u\n", ap->autom_ap_wds);
84 p += sprintf(p, "auth_algs=%u\n", ap->local->auth_algs);
85 p += sprintf(p, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);
86 82
87 return (p - page); 83static int ap_debug_proc_open(struct inode *inode, struct file *file)
84{
85 return single_open(file, ap_debug_proc_show, PDE_DATA(inode));
88} 86}
87
88static const struct file_operations ap_debug_proc_fops = {
89 .open = ap_debug_proc_open,
90 .read = seq_read,
91 .llseek = seq_lseek,
92 .release = seq_release,
93};
89#endif /* PRISM2_NO_PROCFS_DEBUG */ 94#endif /* PRISM2_NO_PROCFS_DEBUG */
90 95
91 96
@@ -325,50 +330,81 @@ void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
325} 330}
326 331
327 332
328static int ap_control_proc_read(char *page, char **start, off_t off, 333static int ap_control_proc_show(struct seq_file *m, void *v)
329 int count, int *eof, void *data)
330{ 334{
331 char *p = page; 335 struct ap_data *ap = m->private;
332 struct ap_data *ap = (struct ap_data *) data;
333 char *policy_txt; 336 char *policy_txt;
334 struct mac_entry *entry; 337 struct mac_entry *entry;
335 338
336 if (off != 0) { 339 if (v == SEQ_START_TOKEN) {
337 *eof = 1; 340 switch (ap->mac_restrictions.policy) {
341 case MAC_POLICY_OPEN:
342 policy_txt = "open";
343 break;
344 case MAC_POLICY_ALLOW:
345 policy_txt = "allow";
346 break;
347 case MAC_POLICY_DENY:
348 policy_txt = "deny";
349 break;
350 default:
351 policy_txt = "unknown";
352 break;
353 }
354 seq_printf(m, "MAC policy: %s\n", policy_txt);
355 seq_printf(m, "MAC entries: %u\n", ap->mac_restrictions.entries);
356 seq_puts(m, "MAC list:\n");
338 return 0; 357 return 0;
339 } 358 }
340 359
341 switch (ap->mac_restrictions.policy) { 360 entry = v;
342 case MAC_POLICY_OPEN: 361 seq_printf(m, "%pM\n", entry->addr);
343 policy_txt = "open"; 362 return 0;
344 break; 363}
345 case MAC_POLICY_ALLOW: 364
346 policy_txt = "allow"; 365static void *ap_control_proc_start(struct seq_file *m, loff_t *_pos)
347 break; 366{
348 case MAC_POLICY_DENY: 367 struct ap_data *ap = m->private;
349 policy_txt = "deny";
350 break;
351 default:
352 policy_txt = "unknown";
353 break;
354 }
355 p += sprintf(p, "MAC policy: %s\n", policy_txt);
356 p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
357 p += sprintf(p, "MAC list:\n");
358 spin_lock_bh(&ap->mac_restrictions.lock); 368 spin_lock_bh(&ap->mac_restrictions.lock);
359 list_for_each_entry(entry, &ap->mac_restrictions.mac_list, list) { 369 return seq_list_start_head(&ap->mac_restrictions.mac_list, *_pos);
360 if (p - page > PAGE_SIZE - 80) { 370}
361 p += sprintf(p, "All entries did not fit one page.\n");
362 break;
363 }
364 371
365 p += sprintf(p, "%pM\n", entry->addr); 372static void *ap_control_proc_next(struct seq_file *m, void *v, loff_t *_pos)
366 } 373{
374 struct ap_data *ap = m->private;
375 return seq_list_next(v, &ap->mac_restrictions.mac_list, _pos);
376}
377
378static void ap_control_proc_stop(struct seq_file *m, void *v)
379{
380 struct ap_data *ap = m->private;
367 spin_unlock_bh(&ap->mac_restrictions.lock); 381 spin_unlock_bh(&ap->mac_restrictions.lock);
382}
368 383
369 return (p - page); 384static const struct seq_operations ap_control_proc_seqops = {
385 .start = ap_control_proc_start,
386 .next = ap_control_proc_next,
387 .stop = ap_control_proc_stop,
388 .show = ap_control_proc_show,
389};
390
391static int ap_control_proc_open(struct inode *inode, struct file *file)
392{
393 int ret = seq_open(file, &ap_control_proc_seqops);
394 if (ret == 0) {
395 struct seq_file *m = file->private_data;
396 m->private = PDE_DATA(inode);
397 }
398 return ret;
370} 399}
371 400
401static const struct file_operations ap_control_proc_fops = {
402 .open = ap_control_proc_open,
403 .read = seq_read,
404 .llseek = seq_lseek,
405 .release = seq_release,
406};
407
372 408
373int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac) 409int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
374{ 410{
@@ -510,61 +546,84 @@ void ap_control_kickall(struct ap_data *ap)
510 546
511#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT 547#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
512 548
513#define PROC_LIMIT (PAGE_SIZE - 80) 549static int prism2_ap_proc_show(struct seq_file *m, void *v)
514
515static int prism2_ap_proc_read(char *page, char **start, off_t off,
516 int count, int *eof, void *data)
517{ 550{
518 char *p = page; 551 struct sta_info *sta = v;
519 struct ap_data *ap = (struct ap_data *) data;
520 struct sta_info *sta;
521 int i; 552 int i;
522 553
523 if (off > PROC_LIMIT) { 554 if (v == SEQ_START_TOKEN) {
524 *eof = 1; 555 seq_printf(m, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
525 return 0; 556 return 0;
526 } 557 }
527 558
528 p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n"); 559 if (!sta->ap)
529 spin_lock_bh(&ap->sta_table_lock); 560 return 0;
530 list_for_each_entry(sta, &ap->sta_list, list) {
531 if (!sta->ap)
532 continue;
533 561
534 p += sprintf(p, "%pM %d %d %d %d '", 562 seq_printf(m, "%pM %d %d %d %d '",
535 sta->addr, 563 sta->addr,
536 sta->u.ap.channel, sta->last_rx_signal, 564 sta->u.ap.channel, sta->last_rx_signal,
537 sta->last_rx_silence, sta->last_rx_rate); 565 sta->last_rx_silence, sta->last_rx_rate);
538 for (i = 0; i < sta->u.ap.ssid_len; i++)
539 p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
540 sta->u.ap.ssid[i] < 127) ?
541 "%c" : "<%02x>"),
542 sta->u.ap.ssid[i]);
543 p += sprintf(p, "'");
544 if (sta->capability & WLAN_CAPABILITY_ESS)
545 p += sprintf(p, " [ESS]");
546 if (sta->capability & WLAN_CAPABILITY_IBSS)
547 p += sprintf(p, " [IBSS]");
548 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
549 p += sprintf(p, " [WEP]");
550 p += sprintf(p, "\n");
551
552 if ((p - page) > PROC_LIMIT) {
553 printk(KERN_DEBUG "hostap: ap proc did not fit\n");
554 break;
555 }
556 }
557 spin_unlock_bh(&ap->sta_table_lock);
558 566
559 if ((p - page) <= off) { 567 for (i = 0; i < sta->u.ap.ssid_len; i++) {
560 *eof = 1; 568 if (sta->u.ap.ssid[i] >= 32 && sta->u.ap.ssid[i] < 127)
561 return 0; 569 seq_putc(m, sta->u.ap.ssid[i]);
570 else
571 seq_printf(m, "<%02x>", sta->u.ap.ssid[i]);
562 } 572 }
563 573
564 *start = page + off; 574 seq_putc(m, '\'');
575 if (sta->capability & WLAN_CAPABILITY_ESS)
576 seq_puts(m, " [ESS]");
577 if (sta->capability & WLAN_CAPABILITY_IBSS)
578 seq_puts(m, " [IBSS]");
579 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
580 seq_puts(m, " [WEP]");
581 seq_putc(m, '\n');
582 return 0;
583}
584
585static void *prism2_ap_proc_start(struct seq_file *m, loff_t *_pos)
586{
587 struct ap_data *ap = m->private;
588 spin_lock_bh(&ap->sta_table_lock);
589 return seq_list_start_head(&ap->sta_list, *_pos);
590}
565 591
566 return (p - page - off); 592static void *prism2_ap_proc_next(struct seq_file *m, void *v, loff_t *_pos)
593{
594 struct ap_data *ap = m->private;
595 return seq_list_next(v, &ap->sta_list, _pos);
567} 596}
597
598static void prism2_ap_proc_stop(struct seq_file *m, void *v)
599{
600 struct ap_data *ap = m->private;
601 spin_unlock_bh(&ap->sta_table_lock);
602}
603
604static const struct seq_operations prism2_ap_proc_seqops = {
605 .start = prism2_ap_proc_start,
606 .next = prism2_ap_proc_next,
607 .stop = prism2_ap_proc_stop,
608 .show = prism2_ap_proc_show,
609};
610
611static int prism2_ap_proc_open(struct inode *inode, struct file *file)
612{
613 int ret = seq_open(file, &prism2_ap_proc_seqops);
614 if (ret == 0) {
615 struct seq_file *m = file->private_data;
616 m->private = PDE_DATA(inode);
617 }
618 return ret;
619}
620
621static const struct file_operations prism2_ap_proc_fops = {
622 .open = prism2_ap_proc_open,
623 .read = seq_read,
624 .llseek = seq_lseek,
625 .release = seq_release,
626};
568#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 627#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
569 628
570 629
@@ -836,15 +895,12 @@ void hostap_init_ap_proc(local_info_t *local)
836 return; 895 return;
837 896
838#ifndef PRISM2_NO_PROCFS_DEBUG 897#ifndef PRISM2_NO_PROCFS_DEBUG
839 create_proc_read_entry("ap_debug", 0, ap->proc, 898 proc_create_data("ap_debug", 0, ap->proc, &ap_debug_proc_fops, ap);
840 ap_debug_proc_read, ap);
841#endif /* PRISM2_NO_PROCFS_DEBUG */ 899#endif /* PRISM2_NO_PROCFS_DEBUG */
842 900
843#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT 901#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
844 create_proc_read_entry("ap_control", 0, ap->proc, 902 proc_create_data("ap_control", 0, ap->proc, &ap_control_proc_fops, ap);
845 ap_control_proc_read, ap); 903 proc_create_data("ap", 0, ap->proc, &prism2_ap_proc_fops, ap);
846 create_proc_read_entry("ap", 0, ap->proc,
847 prism2_ap_proc_read, ap);
848#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 904#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
849 905
850} 906}
@@ -982,79 +1038,86 @@ static void prism2_send_mgmt(struct net_device *dev,
982#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 1038#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
983 1039
984 1040
985static int prism2_sta_proc_read(char *page, char **start, off_t off, 1041static int prism2_sta_proc_show(struct seq_file *m, void *v)
986 int count, int *eof, void *data)
987{ 1042{
988 char *p = page; 1043 struct sta_info *sta = m->private;
989 struct sta_info *sta = (struct sta_info *) data;
990 int i; 1044 int i;
991 1045
992 /* FIX: possible race condition.. the STA data could have just expired, 1046 /* FIX: possible race condition.. the STA data could have just expired,
993 * but proc entry was still here so that the read could have started; 1047 * but proc entry was still here so that the read could have started;
994 * some locking should be done here.. */ 1048 * some locking should be done here.. */
995 1049
996 if (off != 0) { 1050 seq_printf(m,
997 *eof = 1; 1051 "%s=%pM\nusers=%d\naid=%d\n"
998 return 0; 1052 "flags=0x%04x%s%s%s%s%s%s%s\n"
999 } 1053 "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
1000 1054 sta->ap ? "AP" : "STA",
1001 p += sprintf(p, "%s=%pM\nusers=%d\naid=%d\n" 1055 sta->addr, atomic_read(&sta->users), sta->aid,
1002 "flags=0x%04x%s%s%s%s%s%s%s\n" 1056 sta->flags,
1003 "capability=0x%02x\nlisten_interval=%d\nsupported_rates=", 1057 sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
1004 sta->ap ? "AP" : "STA", 1058 sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
1005 sta->addr, atomic_read(&sta->users), sta->aid, 1059 sta->flags & WLAN_STA_PS ? " PS" : "",
1006 sta->flags, 1060 sta->flags & WLAN_STA_TIM ? " TIM" : "",
1007 sta->flags & WLAN_STA_AUTH ? " AUTH" : "", 1061 sta->flags & WLAN_STA_PERM ? " PERM" : "",
1008 sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "", 1062 sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
1009 sta->flags & WLAN_STA_PS ? " PS" : "", 1063 sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
1010 sta->flags & WLAN_STA_TIM ? " TIM" : "", 1064 sta->capability, sta->listen_interval);
1011 sta->flags & WLAN_STA_PERM ? " PERM" : "",
1012 sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
1013 sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
1014 sta->capability, sta->listen_interval);
1015 /* supported_rates: 500 kbit/s units with msb ignored */ 1065 /* supported_rates: 500 kbit/s units with msb ignored */
1016 for (i = 0; i < sizeof(sta->supported_rates); i++) 1066 for (i = 0; i < sizeof(sta->supported_rates); i++)
1017 if (sta->supported_rates[i] != 0) 1067 if (sta->supported_rates[i] != 0)
1018 p += sprintf(p, "%d%sMbps ", 1068 seq_printf(m, "%d%sMbps ",
1019 (sta->supported_rates[i] & 0x7f) / 2, 1069 (sta->supported_rates[i] & 0x7f) / 2,
1020 sta->supported_rates[i] & 1 ? ".5" : ""); 1070 sta->supported_rates[i] & 1 ? ".5" : "");
1021 p += sprintf(p, "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n" 1071 seq_printf(m,
1022 "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n" 1072 "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n"
1023 "tx_packets=%lu\n" 1073 "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n"
1024 "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n" 1074 "tx_packets=%lu\n"
1025 "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n" 1075 "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n"
1026 "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n" 1076 "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n"
1027 "tx[11M]=%d\n" 1077 "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n"
1028 "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n", 1078 "tx[11M]=%d\n"
1029 jiffies, sta->last_auth, sta->last_assoc, sta->last_rx, 1079 "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n",
1030 sta->last_tx, 1080 jiffies, sta->last_auth, sta->last_assoc, sta->last_rx,
1031 sta->rx_packets, sta->tx_packets, sta->rx_bytes, 1081 sta->last_tx,
1032 sta->tx_bytes, skb_queue_len(&sta->tx_buf), 1082 sta->rx_packets, sta->tx_packets, sta->rx_bytes,
1033 sta->last_rx_silence, 1083 sta->tx_bytes, skb_queue_len(&sta->tx_buf),
1034 sta->last_rx_signal, sta->last_rx_rate / 10, 1084 sta->last_rx_silence,
1035 sta->last_rx_rate % 10 ? ".5" : "", 1085 sta->last_rx_signal, sta->last_rx_rate / 10,
1036 sta->tx_rate, sta->tx_count[0], sta->tx_count[1], 1086 sta->last_rx_rate % 10 ? ".5" : "",
1037 sta->tx_count[2], sta->tx_count[3], sta->rx_count[0], 1087 sta->tx_rate, sta->tx_count[0], sta->tx_count[1],
1038 sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]); 1088 sta->tx_count[2], sta->tx_count[3], sta->rx_count[0],
1089 sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]);
1039 if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats) 1090 if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats)
1040 p = sta->crypt->ops->print_stats(p, sta->crypt->priv); 1091 sta->crypt->ops->print_stats(m, sta->crypt->priv);
1041#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT 1092#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1042 if (sta->ap) { 1093 if (sta->ap) {
1043 if (sta->u.ap.channel >= 0) 1094 if (sta->u.ap.channel >= 0)
1044 p += sprintf(p, "channel=%d\n", sta->u.ap.channel); 1095 seq_printf(m, "channel=%d\n", sta->u.ap.channel);
1045 p += sprintf(p, "ssid="); 1096 seq_puts(m, "ssid=");
1046 for (i = 0; i < sta->u.ap.ssid_len; i++) 1097 for (i = 0; i < sta->u.ap.ssid_len; i++) {
1047 p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 && 1098 if (sta->u.ap.ssid[i] >= 32 && sta->u.ap.ssid[i] < 127)
1048 sta->u.ap.ssid[i] < 127) ? 1099 seq_putc(m, sta->u.ap.ssid[i]);
1049 "%c" : "<%02x>"), 1100 else
1050 sta->u.ap.ssid[i]); 1101 seq_printf(m, "<%02x>", sta->u.ap.ssid[i]);
1051 p += sprintf(p, "\n"); 1102 }
1103 seq_putc(m, '\n');
1052 } 1104 }
1053#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 1105#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1054 1106
1055 return (p - page); 1107 return 0;
1108}
1109
1110static int prism2_sta_proc_open(struct inode *inode, struct file *file)
1111{
1112 return single_open(file, prism2_sta_proc_show, PDE_DATA(inode));
1056} 1113}
1057 1114
1115static const struct file_operations prism2_sta_proc_fops = {
1116 .open = prism2_sta_proc_open,
1117 .read = seq_read,
1118 .llseek = seq_lseek,
1119 .release = seq_release,
1120};
1058 1121
1059static void handle_add_proc_queue(struct work_struct *work) 1122static void handle_add_proc_queue(struct work_struct *work)
1060{ 1123{
@@ -1076,9 +1139,9 @@ static void handle_add_proc_queue(struct work_struct *work)
1076 1139
1077 if (sta) { 1140 if (sta) {
1078 sprintf(name, "%pM", sta->addr); 1141 sprintf(name, "%pM", sta->addr);
1079 sta->proc = create_proc_read_entry( 1142 sta->proc = proc_create_data(
1080 name, 0, ap->proc, 1143 name, 0, ap->proc,
1081 prism2_sta_proc_read, sta); 1144 &prism2_sta_proc_fops, sta);
1082 1145
1083 atomic_dec(&sta->users); 1146 atomic_dec(&sta->users);
1084 } 1147 }