iwinfo: Add support for WPA3
[oweals/iwinfo.git] / iwinfo_lua.c
1 /*
2  * iwinfo - Wireless Information Library - Lua Bindings
3  *
4  *   Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
5  *
6  * The iwinfo library is free software: you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License version 2
8  * as published by the Free Software Foundation.
9  *
10  * The iwinfo library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with the iwinfo library. If not, see http://www.gnu.org/licenses/.
17  */
18
19 #include "iwinfo/lua.h"
20
21
22 /* Determine type */
23 static int iwinfo_L_type(lua_State *L)
24 {
25         const char *ifname = luaL_checkstring(L, 1);
26         const char *type = iwinfo_type(ifname);
27
28         if (type)
29                 lua_pushstring(L, type);
30         else
31                 lua_pushnil(L);
32
33         return 1;
34 }
35
36 /* Shutdown backends */
37 static int iwinfo_L__gc(lua_State *L)
38 {
39         iwinfo_finish();
40         return 0;
41 }
42
43 /*
44  * Build a short textual description of the crypto info
45  */
46
47 static char * iwinfo_crypto_print_ciphers(int ciphers)
48 {
49         static char str[128] = { 0 };
50         char *pos = str;
51
52         if (ciphers & IWINFO_CIPHER_WEP40)
53                 pos += sprintf(pos, "WEP-40, ");
54
55         if (ciphers & IWINFO_CIPHER_WEP104)
56                 pos += sprintf(pos, "WEP-104, ");
57
58         if (ciphers & IWINFO_CIPHER_TKIP)
59                 pos += sprintf(pos, "TKIP, ");
60
61         if (ciphers & IWINFO_CIPHER_CCMP)
62                 pos += sprintf(pos, "CCMP, ");
63
64         if (ciphers & IWINFO_CIPHER_WRAP)
65                 pos += sprintf(pos, "WRAP, ");
66
67         if (ciphers & IWINFO_CIPHER_AESOCB)
68                 pos += sprintf(pos, "AES-OCB, ");
69
70         if (ciphers & IWINFO_CIPHER_CKIP)
71                 pos += sprintf(pos, "CKIP, ");
72
73         if (!ciphers || (ciphers & IWINFO_CIPHER_NONE))
74                 pos += sprintf(pos, "NONE, ");
75
76         *(pos - 2) = 0;
77
78         return str;
79 }
80
81 static char * iwinfo_crypto_print_suites(int suites)
82 {
83         static char str[64] = { 0 };
84         char *pos = str;
85
86         if (suites & IWINFO_KMGMT_PSK)
87                 pos += sprintf(pos, "PSK/");
88
89         if (suites & IWINFO_KMGMT_8021x)
90                 pos += sprintf(pos, "802.1X/");
91
92         if (suites & IWINFO_KMGMT_SAE)
93                 pos += sprintf(pos, "SAE/");
94
95         if (suites & IWINFO_KMGMT_OWE)
96                 pos += sprintf(pos, "OWE/");
97
98         if (!suites || (suites & IWINFO_KMGMT_NONE))
99                 pos += sprintf(pos, "NONE/");
100
101         *(pos - 1) = 0;
102
103         return str;
104 }
105
106 static char * iwinfo_crypto_desc(struct iwinfo_crypto_entry *c)
107 {
108         static char desc[512] = { 0 };
109
110         if (c)
111         {
112                 if (c->enabled)
113                 {
114                         /* WEP */
115                         if (c->auth_algs && !c->wpa_version)
116                         {
117                                 if ((c->auth_algs & IWINFO_AUTH_OPEN) &&
118                                     (c->auth_algs & IWINFO_AUTH_SHARED))
119                                 {
120                                         sprintf(desc, "WEP Open/Shared (%s)",
121                                                 iwinfo_crypto_print_ciphers(c->pair_ciphers));
122                                 }
123                                 else if (c->auth_algs & IWINFO_AUTH_OPEN)
124                                 {
125                                         sprintf(desc, "WEP Open System (%s)",
126                                                 iwinfo_crypto_print_ciphers(c->pair_ciphers));
127                                 }
128                                 else if (c->auth_algs & IWINFO_AUTH_SHARED)
129                                 {
130                                         sprintf(desc, "WEP Shared Auth (%s)",
131                                                 iwinfo_crypto_print_ciphers(c->pair_ciphers));
132                                 }
133                         }
134
135                         /* WPA */
136                         else if (c->wpa_version)
137                         {
138                                 switch (c->wpa_version) {
139                                         case 4:
140                                                 sprintf(desc, "WPA3 %s (%s)",
141                                                         iwinfo_crypto_print_suites(c->auth_suites),
142                                                         iwinfo_crypto_print_ciphers(
143                                                                 c->pair_ciphers | c->group_ciphers));
144                                                 break;
145
146                                         case 3:
147                                                 sprintf(desc, "mixed WPA/WPA2 %s (%s)",
148                                                         iwinfo_crypto_print_suites(c->auth_suites),
149                                                         iwinfo_crypto_print_ciphers(
150                                                                 c->pair_ciphers | c->group_ciphers));
151                                                 break;
152
153                                         case 2:
154                                                 sprintf(desc, "WPA2 %s (%s)",
155                                                         iwinfo_crypto_print_suites(c->auth_suites),
156                                                         iwinfo_crypto_print_ciphers(
157                                                                 c->pair_ciphers | c->group_ciphers));
158                                                 break;
159
160                                         case 1:
161                                                 sprintf(desc, "WPA %s (%s)",
162                                                         iwinfo_crypto_print_suites(c->auth_suites),
163                                                         iwinfo_crypto_print_ciphers(
164                                                                 c->pair_ciphers | c->group_ciphers));
165                                                 break;
166                                 }
167                         }
168                         else
169                         {
170                                 sprintf(desc, "None");
171                         }
172                 }
173                 else
174                 {
175                         sprintf(desc, "None");
176                 }
177         }
178         else
179         {
180                 sprintf(desc, "Unknown");
181         }
182
183         return desc;
184 }
185
186 /* Build Lua table from crypto data */
187 static void iwinfo_L_cryptotable(lua_State *L, struct iwinfo_crypto_entry *c)
188 {
189         int i, j;
190
191         lua_newtable(L);
192
193         lua_pushboolean(L, c->enabled);
194         lua_setfield(L, -2, "enabled");
195
196         lua_pushstring(L, iwinfo_crypto_desc(c));
197         lua_setfield(L, -2, "description");
198
199         lua_pushboolean(L, (c->enabled && !c->wpa_version));
200         lua_setfield(L, -2, "wep");
201
202         lua_pushinteger(L, c->wpa_version);
203         lua_setfield(L, -2, "wpa");
204
205         lua_newtable(L);
206         for (i = 0, j = 1; i < ARRAY_SIZE(IWINFO_CIPHER_NAMES); i++)
207         {
208                 if (c->pair_ciphers & (1 << i))
209                 {
210                         lua_pushstring(L, IWINFO_CIPHER_NAMES[i]);
211                         lua_rawseti(L, -2, j++);
212                 }
213         }
214         lua_setfield(L, -2, "pair_ciphers");
215
216         lua_newtable(L);
217         for (i = 0, j = 1; i < ARRAY_SIZE(IWINFO_CIPHER_NAMES); i++)
218         {
219                 if (c->group_ciphers & (1 << i))
220                 {
221                         lua_pushstring(L, IWINFO_CIPHER_NAMES[i]);
222                         lua_rawseti(L, -2, j++);
223                 }
224         }
225         lua_setfield(L, -2, "group_ciphers");
226
227         lua_newtable(L);
228         for (i = 0, j = 1; i < ARRAY_SIZE(IWINFO_KMGMT_NAMES); i++)
229         {
230                 if (c->auth_suites & (1 << i))
231                 {
232                         lua_pushstring(L, IWINFO_KMGMT_NAMES[i]);
233                         lua_rawseti(L, -2, j++);
234                 }
235         }
236         lua_setfield(L, -2, "auth_suites");
237
238         lua_newtable(L);
239         for (i = 0, j = 1; i < ARRAY_SIZE(IWINFO_AUTH_NAMES); i++)
240         {
241                 if (c->auth_algs & (1 << i))
242                 {
243                         lua_pushstring(L, IWINFO_AUTH_NAMES[i]);
244                         lua_rawseti(L, -2, j++);
245                 }
246         }
247         lua_setfield(L, -2, "auth_algs");
248 }
249
250
251 /* Wrapper for mode */
252 static int iwinfo_L_mode(lua_State *L, int (*func)(const char *, int *))
253 {
254         int mode;
255         const char *ifname = luaL_checkstring(L, 1);
256
257         if ((*func)(ifname, &mode))
258                 mode = IWINFO_OPMODE_UNKNOWN;
259
260         lua_pushstring(L, IWINFO_OPMODE_NAMES[mode]);
261         return 1;
262 }
263
264 static void set_rateinfo(lua_State *L, struct iwinfo_rate_entry *r, bool rx)
265 {
266         lua_pushnumber(L, r->rate);
267         lua_setfield(L, -2, rx ? "rx_rate" : "tx_rate");
268
269         lua_pushboolean(L, r->is_ht);
270         lua_setfield(L, -2, rx ? "rx_ht" : "tx_ht");
271
272         lua_pushboolean(L, r->is_vht);
273         lua_setfield(L, -2, rx ? "rx_vht" : "tx_vht");
274
275         lua_pushnumber(L, r->mhz);
276         lua_setfield(L, -2, rx ? "rx_mhz" : "tx_mhz");
277
278         if (r->is_ht)
279         {
280                 lua_pushboolean(L, r->is_40mhz);
281                 lua_setfield(L, -2, rx ? "rx_40mhz" : "tx_40mhz");
282
283                 lua_pushnumber(L, r->mcs);
284                 lua_setfield(L, -2, rx ? "rx_mcs" : "tx_mcs");
285
286                 lua_pushboolean(L, r->is_short_gi);
287                 lua_setfield(L, -2, rx ? "rx_short_gi" : "tx_short_gi");
288         }
289         else if (r->is_vht)
290         {
291                 lua_pushnumber(L, r->mcs);
292                 lua_setfield(L, -2, rx ? "rx_mcs" : "tx_mcs");
293
294                 lua_pushnumber(L, r->nss);
295                 lua_setfield(L, -2, rx ? "rx_nss" : "tx_nss");
296
297                 lua_pushboolean(L, r->is_short_gi);
298                 lua_setfield(L, -2, rx ? "rx_short_gi" : "tx_short_gi");
299         }
300 }
301
302 /* Wrapper for assoclist */
303 static int iwinfo_L_assoclist(lua_State *L, int (*func)(const char *, char *, int *))
304 {
305         int i, len;
306         char rv[IWINFO_BUFSIZE];
307         char macstr[18];
308         const char *ifname = luaL_checkstring(L, 1);
309         struct iwinfo_assoclist_entry *e;
310
311         lua_newtable(L);
312         memset(rv, 0, sizeof(rv));
313
314         if (!(*func)(ifname, rv, &len))
315         {
316                 for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry))
317                 {
318                         e = (struct iwinfo_assoclist_entry *) &rv[i];
319
320                         sprintf(macstr, "%02X:%02X:%02X:%02X:%02X:%02X",
321                                 e->mac[0], e->mac[1], e->mac[2],
322                                 e->mac[3], e->mac[4], e->mac[5]);
323
324                         lua_newtable(L);
325
326                         lua_pushnumber(L, e->signal);
327                         lua_setfield(L, -2, "signal");
328
329                         lua_pushnumber(L, e->noise);
330                         lua_setfield(L, -2, "noise");
331
332                         lua_pushnumber(L, e->inactive);
333                         lua_setfield(L, -2, "inactive");
334
335                         lua_pushnumber(L, e->rx_packets);
336                         lua_setfield(L, -2, "rx_packets");
337
338                         lua_pushnumber(L, e->tx_packets);
339                         lua_setfield(L, -2, "tx_packets");
340
341                         set_rateinfo(L, &e->rx_rate, true);
342                         set_rateinfo(L, &e->tx_rate, false);
343
344                         if (e->thr) {
345                                 lua_pushnumber(L, e->thr);
346                                 lua_setfield(L, -2, "expected_throughput");
347                         }
348
349                         lua_setfield(L, -2, macstr);
350                 }
351         }
352
353         return 1;
354 }
355
356 /* Wrapper for tx power list */
357 static int iwinfo_L_txpwrlist(lua_State *L, int (*func)(const char *, char *, int *))
358 {
359         int i, x, len;
360         char rv[IWINFO_BUFSIZE];
361         const char *ifname = luaL_checkstring(L, 1);
362         struct iwinfo_txpwrlist_entry *e;
363
364         memset(rv, 0, sizeof(rv));
365
366         if (!(*func)(ifname, rv, &len))
367         {
368                 lua_newtable(L);
369
370                 for (i = 0, x = 1; i < len; i += sizeof(struct iwinfo_txpwrlist_entry), x++)
371                 {
372                         e = (struct iwinfo_txpwrlist_entry *) &rv[i];
373
374                         lua_newtable(L);
375
376                         lua_pushnumber(L, e->mw);
377                         lua_setfield(L, -2, "mw");
378
379                         lua_pushnumber(L, e->dbm);
380                         lua_setfield(L, -2, "dbm");
381
382                         lua_rawseti(L, -2, x);
383                 }
384
385                 return 1;
386         }
387
388         return 0;
389 }
390
391 /* Wrapper for scan list */
392 static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int *))
393 {
394         int i, x, len = 0;
395         char rv[IWINFO_BUFSIZE];
396         char macstr[18];
397         const char *ifname = luaL_checkstring(L, 1);
398         struct iwinfo_scanlist_entry *e;
399
400         lua_newtable(L);
401         memset(rv, 0, sizeof(rv));
402
403         if (!(*func)(ifname, rv, &len))
404         {
405                 for (i = 0, x = 1; i < len; i += sizeof(struct iwinfo_scanlist_entry), x++)
406                 {
407                         e = (struct iwinfo_scanlist_entry *) &rv[i];
408
409                         lua_newtable(L);
410
411                         /* BSSID */
412                         sprintf(macstr, "%02X:%02X:%02X:%02X:%02X:%02X",
413                                 e->mac[0], e->mac[1], e->mac[2],
414                                 e->mac[3], e->mac[4], e->mac[5]);
415
416                         lua_pushstring(L, macstr);
417                         lua_setfield(L, -2, "bssid");
418
419                         /* ESSID */
420                         if (e->ssid[0])
421                         {
422                                 lua_pushstring(L, (char *) e->ssid);
423                                 lua_setfield(L, -2, "ssid");
424                         }
425
426                         /* Channel */
427                         lua_pushinteger(L, e->channel);
428                         lua_setfield(L, -2, "channel");
429
430                         /* Mode */
431                         lua_pushstring(L, IWINFO_OPMODE_NAMES[e->mode]);
432                         lua_setfield(L, -2, "mode");
433
434                         /* Quality, Signal */
435                         lua_pushinteger(L, e->quality);
436                         lua_setfield(L, -2, "quality");
437
438                         lua_pushinteger(L, e->quality_max);
439                         lua_setfield(L, -2, "quality_max");
440
441                         lua_pushnumber(L, (e->signal - 0x100));
442                         lua_setfield(L, -2, "signal");
443
444                         /* Crypto */
445                         iwinfo_L_cryptotable(L, &e->crypto);
446                         lua_setfield(L, -2, "encryption");
447
448                         lua_rawseti(L, -2, x);
449                 }
450         }
451
452         return 1;
453 }
454
455 /* Wrapper for frequency list */
456 static int iwinfo_L_freqlist(lua_State *L, int (*func)(const char *, char *, int *))
457 {
458         int i, x, len;
459         char rv[IWINFO_BUFSIZE];
460         const char *ifname = luaL_checkstring(L, 1);
461         struct iwinfo_freqlist_entry *e;
462
463         lua_newtable(L);
464         memset(rv, 0, sizeof(rv));
465
466         if (!(*func)(ifname, rv, &len))
467         {
468                 for (i = 0, x = 1; i < len; i += sizeof(struct iwinfo_freqlist_entry), x++)
469                 {
470                         e = (struct iwinfo_freqlist_entry *) &rv[i];
471
472                         lua_newtable(L);
473
474                         /* MHz */
475                         lua_pushinteger(L, e->mhz);
476                         lua_setfield(L, -2, "mhz");
477
478                         /* Channel */
479                         lua_pushinteger(L, e->channel);
480                         lua_setfield(L, -2, "channel");
481
482                         /* Restricted (DFS/TPC/Radar) */
483                         lua_pushboolean(L, e->restricted);
484                         lua_setfield(L, -2, "restricted");
485
486                         lua_rawseti(L, -2, x);
487                 }
488         }
489
490         return 1;
491 }
492
493 /* Wrapper for crypto settings */
494 static int iwinfo_L_encryption(lua_State *L, int (*func)(const char *, char *))
495 {
496         const char *ifname = luaL_checkstring(L, 1);
497         struct iwinfo_crypto_entry c = { 0 };
498
499         if (!(*func)(ifname, (char *)&c))
500         {
501                 iwinfo_L_cryptotable(L, &c);
502                 return 1;
503         }
504
505         lua_pushnil(L);
506         return 1;
507 }
508
509 /* Wrapper for hwmode list */
510 static int iwinfo_L_hwmodelist(lua_State *L, int (*func)(const char *, int *))
511 {
512         const char *ifname = luaL_checkstring(L, 1);
513         int hwmodes = 0;
514
515         if (!(*func)(ifname, &hwmodes))
516         {
517                 lua_newtable(L);
518
519                 lua_pushboolean(L, hwmodes & IWINFO_80211_A);
520                 lua_setfield(L, -2, "a");
521
522                 lua_pushboolean(L, hwmodes & IWINFO_80211_B);
523                 lua_setfield(L, -2, "b");
524
525                 lua_pushboolean(L, hwmodes & IWINFO_80211_G);
526                 lua_setfield(L, -2, "g");
527
528                 lua_pushboolean(L, hwmodes & IWINFO_80211_N);
529                 lua_setfield(L, -2, "n");
530
531                 lua_pushboolean(L, hwmodes & IWINFO_80211_AC);
532                 lua_setfield(L, -2, "ac");
533
534                 lua_pushboolean(L, hwmodes & IWINFO_80211_AD);
535                 lua_setfield(L, -2, "ad");
536
537                 return 1;
538         }
539
540         lua_pushnil(L);
541         return 1;
542 }
543
544 /* Wrapper for htmode list */
545 static int iwinfo_L_htmodelist(lua_State *L, int (*func)(const char *, int *))
546 {
547         const char *ifname = luaL_checkstring(L, 1);
548         int i, htmodes = 0;
549
550         if (!(*func)(ifname, &htmodes))
551         {
552                 lua_newtable(L);
553
554                 for (i = 0; i < ARRAY_SIZE(IWINFO_HTMODE_NAMES); i++)
555                 {
556                         lua_pushboolean(L, htmodes & (1 << i));
557                         lua_setfield(L, -2, IWINFO_HTMODE_NAMES[i]);
558                 }
559
560                 return 1;
561         }
562
563         lua_pushnil(L);
564         return 1;
565 }
566
567 /* Wrapper for mbssid_support */
568 static int iwinfo_L_mbssid_support(lua_State *L, int (*func)(const char *, int *))
569 {
570         const char *ifname = luaL_checkstring(L, 1);
571         int support = 0;
572
573         if (!(*func)(ifname, &support))
574         {
575                 lua_pushboolean(L, support);
576                 return 1;
577         }
578
579         lua_pushnil(L);
580         return 1;
581 }
582
583 /* Wrapper for hardware_id */
584 static int iwinfo_L_hardware_id(lua_State *L, int (*func)(const char *, char *))
585 {
586         const char *ifname = luaL_checkstring(L, 1);
587         struct iwinfo_hardware_id ids;
588
589         if (!(*func)(ifname, (char *)&ids))
590         {
591                 lua_newtable(L);
592
593                 lua_pushnumber(L, ids.vendor_id);
594                 lua_setfield(L, -2, "vendor_id");
595
596                 lua_pushnumber(L, ids.device_id);
597                 lua_setfield(L, -2, "device_id");
598
599                 lua_pushnumber(L, ids.subsystem_vendor_id);
600                 lua_setfield(L, -2, "subsystem_vendor_id");
601
602                 lua_pushnumber(L, ids.subsystem_device_id);
603                 lua_setfield(L, -2, "subsystem_device_id");
604         }
605         else
606         {
607                 lua_pushnil(L);
608         }
609
610         return 1;
611 }
612
613 /* Wrapper for country list */
614 static char * iwinfo_L_country_lookup(char *buf, int len, int iso3166)
615 {
616         int i;
617         struct iwinfo_country_entry *c;
618
619         for (i = 0; i < len; i += sizeof(struct iwinfo_country_entry))
620         {
621                 c = (struct iwinfo_country_entry *) &buf[i];
622
623                 if (c->iso3166 == iso3166)
624                         return c->ccode;
625         }
626
627         return NULL;
628 }
629
630 static int iwinfo_L_countrylist(lua_State *L, int (*func)(const char *, char *, int *))
631 {
632         int len, i;
633         char rv[IWINFO_BUFSIZE], alpha2[3];
634         char *ccode;
635         const char *ifname = luaL_checkstring(L, 1);
636         const struct iwinfo_iso3166_label *l;
637
638         lua_newtable(L);
639         memset(rv, 0, sizeof(rv));
640
641         if (!(*func)(ifname, rv, &len))
642         {
643                 for (l = IWINFO_ISO3166_NAMES, i = 1; l->iso3166; l++)
644                 {
645                         if ((ccode = iwinfo_L_country_lookup(rv, len, l->iso3166)) != NULL)
646                         {
647                                 sprintf(alpha2, "%c%c",
648                                         (l->iso3166 / 256), (l->iso3166 % 256));
649
650                                 lua_newtable(L);
651
652                                 lua_pushstring(L, alpha2);
653                                 lua_setfield(L, -2, "alpha2");
654
655                                 lua_pushstring(L, ccode);
656                                 lua_setfield(L, -2, "ccode");
657
658                                 lua_pushstring(L, l->name);
659                                 lua_setfield(L, -2, "name");
660
661                                 lua_rawseti(L, -2, i++);
662                         }
663                 }
664         }
665
666         return 1;
667 }
668
669
670 #ifdef USE_WL
671 /* Broadcom */
672 LUA_WRAP_INT_OP(wl,channel)
673 LUA_WRAP_INT_OP(wl,frequency)
674 LUA_WRAP_INT_OP(wl,frequency_offset)
675 LUA_WRAP_INT_OP(wl,txpower)
676 LUA_WRAP_INT_OP(wl,txpower_offset)
677 LUA_WRAP_INT_OP(wl,bitrate)
678 LUA_WRAP_INT_OP(wl,signal)
679 LUA_WRAP_INT_OP(wl,noise)
680 LUA_WRAP_INT_OP(wl,quality)
681 LUA_WRAP_INT_OP(wl,quality_max)
682 LUA_WRAP_STRING_OP(wl,ssid)
683 LUA_WRAP_STRING_OP(wl,bssid)
684 LUA_WRAP_STRING_OP(wl,country)
685 LUA_WRAP_STRING_OP(wl,hardware_name)
686 LUA_WRAP_STRING_OP(wl,phyname)
687 LUA_WRAP_STRUCT_OP(wl,mode)
688 LUA_WRAP_STRUCT_OP(wl,assoclist)
689 LUA_WRAP_STRUCT_OP(wl,txpwrlist)
690 LUA_WRAP_STRUCT_OP(wl,scanlist)
691 LUA_WRAP_STRUCT_OP(wl,freqlist)
692 LUA_WRAP_STRUCT_OP(wl,countrylist)
693 LUA_WRAP_STRUCT_OP(wl,hwmodelist)
694 LUA_WRAP_STRUCT_OP(wl,htmodelist)
695 LUA_WRAP_STRUCT_OP(wl,encryption)
696 LUA_WRAP_STRUCT_OP(wl,mbssid_support)
697 LUA_WRAP_STRUCT_OP(wl,hardware_id)
698 #endif
699
700 #ifdef USE_MADWIFI
701 /* Madwifi */
702 LUA_WRAP_INT_OP(madwifi,channel)
703 LUA_WRAP_INT_OP(madwifi,frequency)
704 LUA_WRAP_INT_OP(madwifi,frequency_offset)
705 LUA_WRAP_INT_OP(madwifi,txpower)
706 LUA_WRAP_INT_OP(madwifi,txpower_offset)
707 LUA_WRAP_INT_OP(madwifi,bitrate)
708 LUA_WRAP_INT_OP(madwifi,signal)
709 LUA_WRAP_INT_OP(madwifi,noise)
710 LUA_WRAP_INT_OP(madwifi,quality)
711 LUA_WRAP_INT_OP(madwifi,quality_max)
712 LUA_WRAP_STRING_OP(madwifi,ssid)
713 LUA_WRAP_STRING_OP(madwifi,bssid)
714 LUA_WRAP_STRING_OP(madwifi,country)
715 LUA_WRAP_STRING_OP(madwifi,hardware_name)
716 LUA_WRAP_STRING_OP(madwifi,phyname)
717 LUA_WRAP_STRUCT_OP(madwifi,mode)
718 LUA_WRAP_STRUCT_OP(madwifi,assoclist)
719 LUA_WRAP_STRUCT_OP(madwifi,txpwrlist)
720 LUA_WRAP_STRUCT_OP(madwifi,scanlist)
721 LUA_WRAP_STRUCT_OP(madwifi,freqlist)
722 LUA_WRAP_STRUCT_OP(madwifi,countrylist)
723 LUA_WRAP_STRUCT_OP(madwifi,hwmodelist)
724 LUA_WRAP_STRUCT_OP(madwifi,htmodelist)
725 LUA_WRAP_STRUCT_OP(madwifi,encryption)
726 LUA_WRAP_STRUCT_OP(madwifi,mbssid_support)
727 LUA_WRAP_STRUCT_OP(madwifi,hardware_id)
728 #endif
729
730 #ifdef USE_NL80211
731 /* NL80211 */
732 LUA_WRAP_INT_OP(nl80211,channel)
733 LUA_WRAP_INT_OP(nl80211,frequency)
734 LUA_WRAP_INT_OP(nl80211,frequency_offset)
735 LUA_WRAP_INT_OP(nl80211,txpower)
736 LUA_WRAP_INT_OP(nl80211,txpower_offset)
737 LUA_WRAP_INT_OP(nl80211,bitrate)
738 LUA_WRAP_INT_OP(nl80211,signal)
739 LUA_WRAP_INT_OP(nl80211,noise)
740 LUA_WRAP_INT_OP(nl80211,quality)
741 LUA_WRAP_INT_OP(nl80211,quality_max)
742 LUA_WRAP_STRING_OP(nl80211,ssid)
743 LUA_WRAP_STRING_OP(nl80211,bssid)
744 LUA_WRAP_STRING_OP(nl80211,country)
745 LUA_WRAP_STRING_OP(nl80211,hardware_name)
746 LUA_WRAP_STRING_OP(nl80211,phyname)
747 LUA_WRAP_STRUCT_OP(nl80211,mode)
748 LUA_WRAP_STRUCT_OP(nl80211,assoclist)
749 LUA_WRAP_STRUCT_OP(nl80211,txpwrlist)
750 LUA_WRAP_STRUCT_OP(nl80211,scanlist)
751 LUA_WRAP_STRUCT_OP(nl80211,freqlist)
752 LUA_WRAP_STRUCT_OP(nl80211,countrylist)
753 LUA_WRAP_STRUCT_OP(nl80211,hwmodelist)
754 LUA_WRAP_STRUCT_OP(nl80211,htmodelist)
755 LUA_WRAP_STRUCT_OP(nl80211,encryption)
756 LUA_WRAP_STRUCT_OP(nl80211,mbssid_support)
757 LUA_WRAP_STRUCT_OP(nl80211,hardware_id)
758 #endif
759
760 /* Wext */
761 LUA_WRAP_INT_OP(wext,channel)
762 LUA_WRAP_INT_OP(wext,frequency)
763 LUA_WRAP_INT_OP(wext,frequency_offset)
764 LUA_WRAP_INT_OP(wext,txpower)
765 LUA_WRAP_INT_OP(wext,txpower_offset)
766 LUA_WRAP_INT_OP(wext,bitrate)
767 LUA_WRAP_INT_OP(wext,signal)
768 LUA_WRAP_INT_OP(wext,noise)
769 LUA_WRAP_INT_OP(wext,quality)
770 LUA_WRAP_INT_OP(wext,quality_max)
771 LUA_WRAP_STRING_OP(wext,ssid)
772 LUA_WRAP_STRING_OP(wext,bssid)
773 LUA_WRAP_STRING_OP(wext,country)
774 LUA_WRAP_STRING_OP(wext,hardware_name)
775 LUA_WRAP_STRING_OP(wext,phyname)
776 LUA_WRAP_STRUCT_OP(wext,mode)
777 LUA_WRAP_STRUCT_OP(wext,assoclist)
778 LUA_WRAP_STRUCT_OP(wext,txpwrlist)
779 LUA_WRAP_STRUCT_OP(wext,scanlist)
780 LUA_WRAP_STRUCT_OP(wext,freqlist)
781 LUA_WRAP_STRUCT_OP(wext,countrylist)
782 LUA_WRAP_STRUCT_OP(wext,hwmodelist)
783 LUA_WRAP_STRUCT_OP(wext,htmodelist)
784 LUA_WRAP_STRUCT_OP(wext,encryption)
785 LUA_WRAP_STRUCT_OP(wext,mbssid_support)
786 LUA_WRAP_STRUCT_OP(wext,hardware_id)
787
788 #ifdef USE_WL
789 /* Broadcom table */
790 static const luaL_reg R_wl[] = {
791         LUA_REG(wl,channel),
792         LUA_REG(wl,frequency),
793         LUA_REG(wl,frequency_offset),
794         LUA_REG(wl,txpower),
795         LUA_REG(wl,txpower_offset),
796         LUA_REG(wl,bitrate),
797         LUA_REG(wl,signal),
798         LUA_REG(wl,noise),
799         LUA_REG(wl,quality),
800         LUA_REG(wl,quality_max),
801         LUA_REG(wl,mode),
802         LUA_REG(wl,ssid),
803         LUA_REG(wl,bssid),
804         LUA_REG(wl,country),
805         LUA_REG(wl,assoclist),
806         LUA_REG(wl,txpwrlist),
807         LUA_REG(wl,scanlist),
808         LUA_REG(wl,freqlist),
809         LUA_REG(wl,countrylist),
810         LUA_REG(wl,hwmodelist),
811         LUA_REG(wl,htmodelist),
812         LUA_REG(wl,encryption),
813         LUA_REG(wl,mbssid_support),
814         LUA_REG(wl,hardware_id),
815         LUA_REG(wl,hardware_name),
816         LUA_REG(wl,phyname),
817         { NULL, NULL }
818 };
819 #endif
820
821 #ifdef USE_MADWIFI
822 /* Madwifi table */
823 static const luaL_reg R_madwifi[] = {
824         LUA_REG(madwifi,channel),
825         LUA_REG(madwifi,frequency),
826         LUA_REG(madwifi,frequency_offset),
827         LUA_REG(madwifi,txpower),
828         LUA_REG(madwifi,txpower_offset),
829         LUA_REG(madwifi,bitrate),
830         LUA_REG(madwifi,signal),
831         LUA_REG(madwifi,noise),
832         LUA_REG(madwifi,quality),
833         LUA_REG(madwifi,quality_max),
834         LUA_REG(madwifi,mode),
835         LUA_REG(madwifi,ssid),
836         LUA_REG(madwifi,bssid),
837         LUA_REG(madwifi,country),
838         LUA_REG(madwifi,assoclist),
839         LUA_REG(madwifi,txpwrlist),
840         LUA_REG(madwifi,scanlist),
841         LUA_REG(madwifi,freqlist),
842         LUA_REG(madwifi,countrylist),
843         LUA_REG(madwifi,hwmodelist),
844         LUA_REG(madwifi,htmodelist),
845         LUA_REG(madwifi,encryption),
846         LUA_REG(madwifi,mbssid_support),
847         LUA_REG(madwifi,hardware_id),
848         LUA_REG(madwifi,hardware_name),
849         LUA_REG(madwifi,phyname),
850         { NULL, NULL }
851 };
852 #endif
853
854 #ifdef USE_NL80211
855 /* NL80211 table */
856 static const luaL_reg R_nl80211[] = {
857         LUA_REG(nl80211,channel),
858         LUA_REG(nl80211,frequency),
859         LUA_REG(nl80211,frequency_offset),
860         LUA_REG(nl80211,txpower),
861         LUA_REG(nl80211,txpower_offset),
862         LUA_REG(nl80211,bitrate),
863         LUA_REG(nl80211,signal),
864         LUA_REG(nl80211,noise),
865         LUA_REG(nl80211,quality),
866         LUA_REG(nl80211,quality_max),
867         LUA_REG(nl80211,mode),
868         LUA_REG(nl80211,ssid),
869         LUA_REG(nl80211,bssid),
870         LUA_REG(nl80211,country),
871         LUA_REG(nl80211,assoclist),
872         LUA_REG(nl80211,txpwrlist),
873         LUA_REG(nl80211,scanlist),
874         LUA_REG(nl80211,freqlist),
875         LUA_REG(nl80211,countrylist),
876         LUA_REG(nl80211,hwmodelist),
877         LUA_REG(nl80211,htmodelist),
878         LUA_REG(nl80211,encryption),
879         LUA_REG(nl80211,mbssid_support),
880         LUA_REG(nl80211,hardware_id),
881         LUA_REG(nl80211,hardware_name),
882         LUA_REG(nl80211,phyname),
883         { NULL, NULL }
884 };
885 #endif
886
887 /* Wext table */
888 static const luaL_reg R_wext[] = {
889         LUA_REG(wext,channel),
890         LUA_REG(wext,frequency),
891         LUA_REG(wext,frequency_offset),
892         LUA_REG(wext,txpower),
893         LUA_REG(wext,txpower_offset),
894         LUA_REG(wext,bitrate),
895         LUA_REG(wext,signal),
896         LUA_REG(wext,noise),
897         LUA_REG(wext,quality),
898         LUA_REG(wext,quality_max),
899         LUA_REG(wext,mode),
900         LUA_REG(wext,ssid),
901         LUA_REG(wext,bssid),
902         LUA_REG(wext,country),
903         LUA_REG(wext,assoclist),
904         LUA_REG(wext,txpwrlist),
905         LUA_REG(wext,scanlist),
906         LUA_REG(wext,freqlist),
907         LUA_REG(wext,countrylist),
908         LUA_REG(wext,hwmodelist),
909         LUA_REG(wext,htmodelist),
910         LUA_REG(wext,encryption),
911         LUA_REG(wext,mbssid_support),
912         LUA_REG(wext,hardware_id),
913         LUA_REG(wext,hardware_name),
914         LUA_REG(wext,phyname),
915         { NULL, NULL }
916 };
917
918 /* Common */
919 static const luaL_reg R_common[] = {
920         { "type", iwinfo_L_type },
921         { "__gc", iwinfo_L__gc  },
922         { NULL, NULL }
923 };
924
925
926 LUALIB_API int luaopen_iwinfo(lua_State *L) {
927         luaL_register(L, IWINFO_META, R_common);
928
929 #ifdef USE_WL
930         luaL_newmetatable(L, IWINFO_WL_META);
931         luaL_register(L, NULL, R_common);
932         luaL_register(L, NULL, R_wl);
933         lua_pushvalue(L, -1);
934         lua_setfield(L, -2, "__index");
935         lua_setfield(L, -2, "wl");
936 #endif
937
938 #ifdef USE_MADWIFI
939         luaL_newmetatable(L, IWINFO_MADWIFI_META);
940         luaL_register(L, NULL, R_common);
941         luaL_register(L, NULL, R_madwifi);
942         lua_pushvalue(L, -1);
943         lua_setfield(L, -2, "__index");
944         lua_setfield(L, -2, "madwifi");
945 #endif
946
947 #ifdef USE_NL80211
948         luaL_newmetatable(L, IWINFO_NL80211_META);
949         luaL_register(L, NULL, R_common);
950         luaL_register(L, NULL, R_nl80211);
951         lua_pushvalue(L, -1);
952         lua_setfield(L, -2, "__index");
953         lua_setfield(L, -2, "nl80211");
954 #endif
955
956         luaL_newmetatable(L, IWINFO_WEXT_META);
957         luaL_register(L, NULL, R_common);
958         luaL_register(L, NULL, R_wext);
959         lua_pushvalue(L, -1);
960         lua_setfield(L, -2, "__index");
961         lua_setfield(L, -2, "wext");
962
963         return 1;
964 }