luci-0.10: merge r8034
[project/luci.git] / contrib / package / iwinfo / src / iwinfo_lualib.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_lualib.h"
20
21
22 /*
23 * ISO3166 country labels
24 */
25
26 struct iwinfo_iso3166_label ISO3166_Names[] = {
27 { 0x3030 /* 00 */, "World" },
28 { 0x4144 /* AD */, "Andorra" },
29 { 0x4145 /* AE */, "United Arab Emirates" },
30 { 0x4146 /* AF */, "Afghanistan" },
31 { 0x4147 /* AG */, "Antigua and Barbuda" },
32 { 0x4149 /* AI */, "Anguilla" },
33 { 0x414C /* AL */, "Albania" },
34 { 0x414D /* AM */, "Armenia" },
35 { 0x414E /* AN */, "Netherlands Antilles" },
36 { 0x414F /* AO */, "Angola" },
37 { 0x4151 /* AQ */, "Antarctica" },
38 { 0x4152 /* AR */, "Argentina" },
39 { 0x4153 /* AS */, "American Samoa" },
40 { 0x4154 /* AT */, "Austria" },
41 { 0x4155 /* AU */, "Australia" },
42 { 0x4157 /* AW */, "Aruba" },
43 { 0x4158 /* AX */, "Aland Islands" },
44 { 0x415A /* AZ */, "Azerbaijan" },
45 { 0x4241 /* BA */, "Bosnia and Herzegovina" },
46 { 0x4242 /* BB */, "Barbados" },
47 { 0x4244 /* BD */, "Bangladesh" },
48 { 0x4245 /* BE */, "Belgium" },
49 { 0x4246 /* BF */, "Burkina Faso" },
50 { 0x4247 /* BG */, "Bulgaria" },
51 { 0x4248 /* BH */, "Bahrain" },
52 { 0x4249 /* BI */, "Burundi" },
53 { 0x424A /* BJ */, "Benin" },
54 { 0x424C /* BL */, "Saint Barthelemy" },
55 { 0x424D /* BM */, "Bermuda" },
56 { 0x424E /* BN */, "Brunei Darussalam" },
57 { 0x424F /* BO */, "Bolivia" },
58 { 0x4252 /* BR */, "Brazil" },
59 { 0x4253 /* BS */, "Bahamas" },
60 { 0x4254 /* BT */, "Bhutan" },
61 { 0x4256 /* BV */, "Bouvet Island" },
62 { 0x4257 /* BW */, "Botswana" },
63 { 0x4259 /* BY */, "Belarus" },
64 { 0x425A /* BZ */, "Belize" },
65 { 0x4341 /* CA */, "Canada" },
66 { 0x4343 /* CC */, "Cocos (Keeling) Islands" },
67 { 0x4344 /* CD */, "Congo" },
68 { 0x4346 /* CF */, "Central African Republic" },
69 { 0x4347 /* CG */, "Congo" },
70 { 0x4348 /* CH */, "Switzerland" },
71 { 0x4349 /* CI */, "Cote d'Ivoire" },
72 { 0x434B /* CK */, "Cook Islands" },
73 { 0x434C /* CL */, "Chile" },
74 { 0x434D /* CM */, "Cameroon" },
75 { 0x434E /* CN */, "China" },
76 { 0x434F /* CO */, "Colombia" },
77 { 0x4352 /* CR */, "Costa Rica" },
78 { 0x4355 /* CU */, "Cuba" },
79 { 0x4356 /* CV */, "Cape Verde" },
80 { 0x4358 /* CX */, "Christmas Island" },
81 { 0x4359 /* CY */, "Cyprus" },
82 { 0x435A /* CZ */, "Czech Republic" },
83 { 0x4445 /* DE */, "Germany" },
84 { 0x444A /* DJ */, "Djibouti" },
85 { 0x444B /* DK */, "Denmark" },
86 { 0x444D /* DM */, "Dominica" },
87 { 0x444F /* DO */, "Dominican Republic" },
88 { 0x445A /* DZ */, "Algeria" },
89 { 0x4543 /* EC */, "Ecuador" },
90 { 0x4545 /* EE */, "Estonia" },
91 { 0x4547 /* EG */, "Egypt" },
92 { 0x4548 /* EH */, "Western Sahara" },
93 { 0x4552 /* ER */, "Eritrea" },
94 { 0x4553 /* ES */, "Spain" },
95 { 0x4554 /* ET */, "Ethiopia" },
96 { 0x4649 /* FI */, "Finland" },
97 { 0x464A /* FJ */, "Fiji" },
98 { 0x464B /* FK */, "Falkland Islands" },
99 { 0x464D /* FM */, "Micronesia" },
100 { 0x464F /* FO */, "Faroe Islands" },
101 { 0x4652 /* FR */, "France" },
102 { 0x4741 /* GA */, "Gabon" },
103 { 0x4742 /* GB */, "United Kingdom" },
104 { 0x4744 /* GD */, "Grenada" },
105 { 0x4745 /* GE */, "Georgia" },
106 { 0x4746 /* GF */, "French Guiana" },
107 { 0x4747 /* GG */, "Guernsey" },
108 { 0x4748 /* GH */, "Ghana" },
109 { 0x4749 /* GI */, "Gibraltar" },
110 { 0x474C /* GL */, "Greenland" },
111 { 0x474D /* GM */, "Gambia" },
112 { 0x474E /* GN */, "Guinea" },
113 { 0x4750 /* GP */, "Guadeloupe" },
114 { 0x4751 /* GQ */, "Equatorial Guinea" },
115 { 0x4752 /* GR */, "Greece" },
116 { 0x4753 /* GS */, "South Georgia" },
117 { 0x4754 /* GT */, "Guatemala" },
118 { 0x4755 /* GU */, "Guam" },
119 { 0x4757 /* GW */, "Guinea-Bissau" },
120 { 0x4759 /* GY */, "Guyana" },
121 { 0x484B /* HK */, "Hong Kong" },
122 { 0x484D /* HM */, "Heard and McDonald Islands" },
123 { 0x484E /* HN */, "Honduras" },
124 { 0x4852 /* HR */, "Croatia" },
125 { 0x4854 /* HT */, "Haiti" },
126 { 0x4855 /* HU */, "Hungary" },
127 { 0x4944 /* ID */, "Indonesia" },
128 { 0x4945 /* IE */, "Ireland" },
129 { 0x494C /* IL */, "Israel" },
130 { 0x494D /* IM */, "Isle of Man" },
131 { 0x494E /* IN */, "India" },
132 { 0x494F /* IO */, "Chagos Islands" },
133 { 0x4951 /* IQ */, "Iraq" },
134 { 0x4952 /* IR */, "Iran" },
135 { 0x4953 /* IS */, "Iceland" },
136 { 0x4954 /* IT */, "Italy" },
137 { 0x4A45 /* JE */, "Jersey" },
138 { 0x4A4D /* JM */, "Jamaica" },
139 { 0x4A4F /* JO */, "Jordan" },
140 { 0x4A50 /* JP */, "Japan" },
141 { 0x4B45 /* KE */, "Kenya" },
142 { 0x4B47 /* KG */, "Kyrgyzstan" },
143 { 0x4B48 /* KH */, "Cambodia" },
144 { 0x4B49 /* KI */, "Kiribati" },
145 { 0x4B4D /* KM */, "Comoros" },
146 { 0x4B4E /* KN */, "Saint Kitts and Nevis" },
147 { 0x4B50 /* KP */, "North Korea" },
148 { 0x4B52 /* KR */, "South Korea" },
149 { 0x4B57 /* KW */, "Kuwait" },
150 { 0x4B59 /* KY */, "Cayman Islands" },
151 { 0x4B5A /* KZ */, "Kazakhstan" },
152 { 0x4C41 /* LA */, "Laos" },
153 { 0x4C42 /* LB */, "Lebanon" },
154 { 0x4C43 /* LC */, "Saint Lucia" },
155 { 0x4C49 /* LI */, "Liechtenstein" },
156 { 0x4C4B /* LK */, "Sri Lanka" },
157 { 0x4C52 /* LR */, "Liberia" },
158 { 0x4C53 /* LS */, "Lesotho" },
159 { 0x4C54 /* LT */, "Lithuania" },
160 { 0x4C55 /* LU */, "Luxembourg" },
161 { 0x4C56 /* LV */, "Latvia" },
162 { 0x4C59 /* LY */, "Libyan Arab Jamahiriya" },
163 { 0x4D41 /* MA */, "Morocco" },
164 { 0x4D43 /* MC */, "Monaco" },
165 { 0x4D44 /* MD */, "Moldova" },
166 { 0x4D45 /* ME */, "Montenegro" },
167 { 0x4D46 /* MF */, "Saint Martin (French part)" },
168 { 0x4D47 /* MG */, "Madagascar" },
169 { 0x4D48 /* MH */, "Marshall Islands" },
170 { 0x4D4B /* MK */, "Macedonia" },
171 { 0x4D4C /* ML */, "Mali" },
172 { 0x4D4D /* MM */, "Myanmar" },
173 { 0x4D4E /* MN */, "Mongolia" },
174 { 0x4D4F /* MO */, "Macao" },
175 { 0x4D50 /* MP */, "Northern Mariana Islands" },
176 { 0x4D51 /* MQ */, "Martinique" },
177 { 0x4D52 /* MR */, "Mauritania" },
178 { 0x4D53 /* MS */, "Montserrat" },
179 { 0x4D54 /* MT */, "Malta" },
180 { 0x4D55 /* MU */, "Mauritius" },
181 { 0x4D56 /* MV */, "Maldives" },
182 { 0x4D57 /* MW */, "Malawi" },
183 { 0x4D58 /* MX */, "Mexico" },
184 { 0x4D59 /* MY */, "Malaysia" },
185 { 0x4D5A /* MZ */, "Mozambique" },
186 { 0x4E41 /* NA */, "Namibia" },
187 { 0x4E43 /* NC */, "New Caledonia" },
188 { 0x4E45 /* NE */, "Niger" },
189 { 0x4E46 /* NF */, "Norfolk Island" },
190 { 0x4E47 /* NG */, "Nigeria" },
191 { 0x4E49 /* NI */, "Nicaragua" },
192 { 0x4E4C /* NL */, "Netherlands" },
193 { 0x4E4F /* NO */, "Norway" },
194 { 0x4E50 /* NP */, "Nepal" },
195 { 0x4E52 /* NR */, "Nauru" },
196 { 0x4E55 /* NU */, "Niue" },
197 { 0x4E5A /* NZ */, "New Zealand" },
198 { 0x4F4D /* OM */, "Oman" },
199 { 0x5041 /* PA */, "Panama" },
200 { 0x5045 /* PE */, "Peru" },
201 { 0x5046 /* PF */, "French Polynesia" },
202 { 0x5047 /* PG */, "Papua New Guinea" },
203 { 0x5048 /* PH */, "Philippines" },
204 { 0x504B /* PK */, "Pakistan" },
205 { 0x504C /* PL */, "Poland" },
206 { 0x504D /* PM */, "Saint Pierre and Miquelon" },
207 { 0x504E /* PN */, "Pitcairn" },
208 { 0x5052 /* PR */, "Puerto Rico" },
209 { 0x5053 /* PS */, "Palestinian Territory" },
210 { 0x5054 /* PT */, "Portugal" },
211 { 0x5057 /* PW */, "Palau" },
212 { 0x5059 /* PY */, "Paraguay" },
213 { 0x5141 /* QA */, "Qatar" },
214 { 0x5245 /* RE */, "Reunion" },
215 { 0x524F /* RO */, "Romania" },
216 { 0x5253 /* RS */, "Serbia" },
217 { 0x5255 /* RU */, "Russian Federation" },
218 { 0x5257 /* RW */, "Rwanda" },
219 { 0x5341 /* SA */, "Saudi Arabia" },
220 { 0x5342 /* SB */, "Solomon Islands" },
221 { 0x5343 /* SC */, "Seychelles" },
222 { 0x5344 /* SD */, "Sudan" },
223 { 0x5345 /* SE */, "Sweden" },
224 { 0x5347 /* SG */, "Singapore" },
225 { 0x5348 /* SH */, "St. Helena and Dependencies" },
226 { 0x5349 /* SI */, "Slovenia" },
227 { 0x534A /* SJ */, "Svalbard and Jan Mayen" },
228 { 0x534B /* SK */, "Slovakia" },
229 { 0x534C /* SL */, "Sierra Leone" },
230 { 0x534D /* SM */, "San Marino" },
231 { 0x534E /* SN */, "Senegal" },
232 { 0x534F /* SO */, "Somalia" },
233 { 0x5352 /* SR */, "Suriname" },
234 { 0x5354 /* ST */, "Sao Tome and Principe" },
235 { 0x5356 /* SV */, "El Salvador" },
236 { 0x5359 /* SY */, "Syrian Arab Republic" },
237 { 0x535A /* SZ */, "Swaziland" },
238 { 0x5443 /* TC */, "Turks and Caicos Islands" },
239 { 0x5444 /* TD */, "Chad" },
240 { 0x5446 /* TF */, "French Southern Territories" },
241 { 0x5447 /* TG */, "Togo" },
242 { 0x5448 /* TH */, "Thailand" },
243 { 0x544A /* TJ */, "Tajikistan" },
244 { 0x544B /* TK */, "Tokelau" },
245 { 0x544C /* TL */, "Timor-Leste" },
246 { 0x544D /* TM */, "Turkmenistan" },
247 { 0x544E /* TN */, "Tunisia" },
248 { 0x544F /* TO */, "Tonga" },
249 { 0x5452 /* TR */, "Turkey" },
250 { 0x5454 /* TT */, "Trinidad and Tobago" },
251 { 0x5456 /* TV */, "Tuvalu" },
252 { 0x5457 /* TW */, "Taiwan" },
253 { 0x545A /* TZ */, "Tanzania" },
254 { 0x5541 /* UA */, "Ukraine" },
255 { 0x5547 /* UG */, "Uganda" },
256 { 0x554D /* UM */, "U.S. Minor Outlying Islands" },
257 { 0x5553 /* US */, "United States" },
258 { 0x5559 /* UY */, "Uruguay" },
259 { 0x555A /* UZ */, "Uzbekistan" },
260 { 0x5641 /* VA */, "Vatican City State" },
261 { 0x5643 /* VC */, "St. Vincent and Grenadines" },
262 { 0x5645 /* VE */, "Venezuela" },
263 { 0x5647 /* VG */, "Virgin Islands, British" },
264 { 0x5649 /* VI */, "Virgin Islands, U.S." },
265 { 0x564E /* VN */, "Viet Nam" },
266 { 0x5655 /* VU */, "Vanuatu" },
267 { 0x5746 /* WF */, "Wallis and Futuna" },
268 { 0x5753 /* WS */, "Samoa" },
269 { 0x5945 /* YE */, "Yemen" },
270 { 0x5954 /* YT */, "Mayotte" },
271 { 0x5A41 /* ZA */, "South Africa" },
272 { 0x5A4D /* ZM */, "Zambia" },
273 { 0x5A57 /* ZW */, "Zimbabwe" },
274 { 0, "" }
275 };
276
277
278
279 /* Determine type */
280 static int iwinfo_L_type(lua_State *L)
281 {
282 const char *ifname = luaL_checkstring(L, 1);
283
284 #ifdef USE_NL80211
285 if( nl80211_probe(ifname) )
286 lua_pushstring(L, "nl80211");
287 else
288 #endif
289
290 #ifdef USE_MADWIFI
291 if( madwifi_probe(ifname) )
292 lua_pushstring(L, "madwifi");
293 else
294 #endif
295
296 #ifdef USE_WL
297 if( wl_probe(ifname) )
298 lua_pushstring(L, "wl");
299 else
300 #endif
301
302 if( wext_probe(ifname) )
303 lua_pushstring(L, "wext");
304
305 else
306 lua_pushnil(L);
307
308 return 1;
309 }
310
311 /* Shutdown backends */
312 static int iwinfo_L__gc(lua_State *L)
313 {
314 #ifdef USE_WL
315 wl_close();
316 #endif
317 #ifdef USE_MADWIFI
318 madwifi_close();
319 #endif
320 #ifdef USE_NL80211
321 nl80211_close();
322 #endif
323 wext_close();
324 iwinfo_close();
325 }
326
327 /*
328 * Build a short textual description of the crypto info
329 */
330
331 static char * iwinfo_crypto_print_ciphers(int ciphers)
332 {
333 static char str[128] = { 0 };
334 char *pos = str;
335
336 if( ciphers & IWINFO_CIPHER_WEP40 )
337 pos += sprintf(pos, "WEP-40, ");
338
339 if( ciphers & IWINFO_CIPHER_WEP104 )
340 pos += sprintf(pos, "WEP-104, ");
341
342 if( ciphers & IWINFO_CIPHER_TKIP )
343 pos += sprintf(pos, "TKIP, ");
344
345 if( ciphers & IWINFO_CIPHER_CCMP )
346 pos += sprintf(pos, "CCMP, ");
347
348 if( ciphers & IWINFO_CIPHER_WRAP )
349 pos += sprintf(pos, "WRAP, ");
350
351 if( ciphers & IWINFO_CIPHER_AESOCB )
352 pos += sprintf(pos, "AES-OCB, ");
353
354 if( ciphers & IWINFO_CIPHER_CKIP )
355 pos += sprintf(pos, "CKIP, ");
356
357 if( !ciphers || (ciphers & IWINFO_CIPHER_NONE) )
358 pos += sprintf(pos, "NONE, ");
359
360 *(pos - 2) = 0;
361
362 return str;
363 }
364
365 static char * iwinfo_crypto_print_suites(int suites)
366 {
367 static char str[64] = { 0 };
368 char *pos = str;
369
370 if( suites & IWINFO_KMGMT_PSK )
371 pos += sprintf(pos, "PSK/");
372
373 if( suites & IWINFO_KMGMT_8021x )
374 pos += sprintf(pos, "802.1X/");
375
376 if( !suites || (suites & IWINFO_KMGMT_NONE) )
377 pos += sprintf(pos, "NONE/");
378
379 *(pos - 1) = 0;
380
381 return str;
382 }
383
384 static char * iwinfo_crypto_desc(struct iwinfo_crypto_entry *c)
385 {
386 static char desc[512] = { 0 };
387
388 if( c )
389 {
390 if( c->enabled )
391 {
392 /* WEP */
393 if( c->auth_algs && !c->wpa_version )
394 {
395 if( (c->auth_algs & IWINFO_AUTH_OPEN) &&
396 (c->auth_algs & IWINFO_AUTH_SHARED) )
397 {
398 sprintf(desc, "WEP Open/Shared (%s)",
399 iwinfo_crypto_print_ciphers(c->pair_ciphers));
400 }
401 else if( c->auth_algs & IWINFO_AUTH_OPEN )
402 {
403 sprintf(desc, "WEP Open System (%s)",
404 iwinfo_crypto_print_ciphers(c->pair_ciphers));
405 }
406 else if( c->auth_algs & IWINFO_AUTH_SHARED )
407 {
408 sprintf(desc, "WEP Shared Auth (%s)",
409 iwinfo_crypto_print_ciphers(c->pair_ciphers));
410 }
411 }
412
413 /* WPA */
414 else if( c->wpa_version )
415 {
416 switch(c->wpa_version) {
417 case 3:
418 sprintf(desc, "mixed WPA/WPA2 %s (%s)",
419 iwinfo_crypto_print_suites(c->auth_suites),
420 iwinfo_crypto_print_ciphers(
421 c->pair_ciphers & c->group_ciphers));
422 break;
423
424 case 2:
425 sprintf(desc, "WPA2 %s (%s)",
426 iwinfo_crypto_print_suites(c->auth_suites),
427 iwinfo_crypto_print_ciphers(
428 c->pair_ciphers & c->group_ciphers));
429 break;
430
431 case 1:
432 sprintf(desc, "WPA %s (%s)",
433 iwinfo_crypto_print_suites(c->auth_suites),
434 iwinfo_crypto_print_ciphers(
435 c->pair_ciphers & c->group_ciphers));
436 break;
437 }
438 }
439 else
440 {
441 sprintf(desc, "None");
442 }
443 }
444 else
445 {
446 sprintf(desc, "None");
447 }
448 }
449 else
450 {
451 sprintf(desc, "Unknown");
452 }
453
454 return desc;
455 }
456
457 /* Build Lua table from crypto data */
458 static void iwinfo_L_cryptotable(lua_State *L, struct iwinfo_crypto_entry *c)
459 {
460 int i, j;
461
462 lua_newtable(L);
463
464 lua_pushboolean(L, c->enabled);
465 lua_setfield(L, -2, "enabled");
466
467 lua_pushstring(L, iwinfo_crypto_desc(c));
468 lua_setfield(L, -2, "description");
469
470 lua_pushboolean(L, (c->enabled && !c->wpa_version));
471 lua_setfield(L, -2, "wep");
472
473 lua_pushinteger(L, c->wpa_version);
474 lua_setfield(L, -2, "wpa");
475
476 lua_newtable(L);
477 for( i = 0, j = 1; i < 8; i++ )
478 {
479 if( c->pair_ciphers & (1 << i) )
480 {
481 lua_pushstring(L, IWINFO_CIPHER_NAMES[i]);
482 lua_rawseti(L, -2, j++);
483 }
484 }
485 lua_setfield(L, -2, "pair_ciphers");
486
487 lua_newtable(L);
488 for( i = 0, j = 1; i < 8; i++ )
489 {
490 if( c->group_ciphers & (1 << i) )
491 {
492 lua_pushstring(L, IWINFO_CIPHER_NAMES[i]);
493 lua_rawseti(L, -2, j++);
494 }
495 }
496 lua_setfield(L, -2, "group_ciphers");
497
498 lua_newtable(L);
499 for( i = 0, j = 1; i < 8; i++ )
500 {
501 if( c->auth_suites & (1 << i) )
502 {
503 lua_pushstring(L, IWINFO_KMGMT_NAMES[i]);
504 lua_rawseti(L, -2, j++);
505 }
506 }
507 lua_setfield(L, -2, "auth_suites");
508
509 lua_newtable(L);
510 for( i = 0, j = 1; i < 8; i++ )
511 {
512 if( c->auth_algs & (1 << i) )
513 {
514 lua_pushstring(L, IWINFO_AUTH_NAMES[i]);
515 lua_rawseti(L, -2, j++);
516 }
517 }
518 lua_setfield(L, -2, "auth_algs");
519 }
520
521
522 /* Wrapper for assoclist */
523 static int iwinfo_L_assoclist(lua_State *L, int (*func)(const char *, char *, int *))
524 {
525 int i, len;
526 char rv[IWINFO_BUFSIZE];
527 char macstr[18];
528 const char *ifname = luaL_checkstring(L, 1);
529 struct iwinfo_assoclist_entry *e;
530
531 lua_newtable(L);
532 memset(rv, 0, sizeof(rv));
533
534 if( !(*func)(ifname, rv, &len) )
535 {
536 for( i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry) )
537 {
538 e = (struct iwinfo_assoclist_entry *) &rv[i];
539
540 sprintf(macstr, "%02X:%02X:%02X:%02X:%02X:%02X",
541 e->mac[0], e->mac[1], e->mac[2],
542 e->mac[3], e->mac[4], e->mac[5]);
543
544 lua_newtable(L);
545
546 lua_pushnumber(L, e->signal);
547 lua_setfield(L, -2, "signal");
548
549 lua_pushnumber(L, e->noise);
550 lua_setfield(L, -2, "noise");
551
552 lua_setfield(L, -2, macstr);
553 }
554 }
555
556 return 1;
557 }
558
559 /* Wrapper for tx power list */
560 static int iwinfo_L_txpwrlist(lua_State *L, int (*func)(const char *, char *, int *))
561 {
562 int i, x, len;
563 char rv[IWINFO_BUFSIZE];
564 const char *ifname = luaL_checkstring(L, 1);
565 struct iwinfo_txpwrlist_entry *e;
566
567 lua_newtable(L);
568 memset(rv, 0, sizeof(rv));
569
570 if( !(*func)(ifname, rv, &len) )
571 {
572 for( i = 0, x = 1; i < len; i += sizeof(struct iwinfo_txpwrlist_entry), x++ )
573 {
574 e = (struct iwinfo_txpwrlist_entry *) &rv[i];
575
576 lua_newtable(L);
577
578 lua_pushnumber(L, e->mw);
579 lua_setfield(L, -2, "mw");
580
581 lua_pushnumber(L, e->dbm);
582 lua_setfield(L, -2, "dbm");
583
584 lua_rawseti(L, -2, x);
585 }
586 }
587
588 return 1;
589 }
590
591 /* Wrapper for scan list */
592 static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int *))
593 {
594 int i, x, len;
595 char rv[IWINFO_BUFSIZE];
596 char macstr[18];
597 const char *ifname = luaL_checkstring(L, 1);
598 struct iwinfo_scanlist_entry *e;
599
600 lua_newtable(L);
601 memset(rv, 0, sizeof(rv));
602
603 if( !(*func)(ifname, rv, &len) )
604 {
605 for( i = 0, x = 1; i < len; i += sizeof(struct iwinfo_scanlist_entry), x++ )
606 {
607 e = (struct iwinfo_scanlist_entry *) &rv[i];
608
609 lua_newtable(L);
610
611 /* BSSID */
612 sprintf(macstr, "%02X:%02X:%02X:%02X:%02X:%02X",
613 e->mac[0], e->mac[1], e->mac[2],
614 e->mac[3], e->mac[4], e->mac[5]);
615
616 lua_pushstring(L, macstr);
617 lua_setfield(L, -2, "bssid");
618
619 /* ESSID */
620 if( e->ssid[0] )
621 {
622 lua_pushstring(L, (char *) e->ssid);
623 lua_setfield(L, -2, "ssid");
624 }
625
626 /* Channel */
627 lua_pushinteger(L, e->channel);
628 lua_setfield(L, -2, "channel");
629
630 /* Mode */
631 lua_pushstring(L, (char *) e->mode);
632 lua_setfield(L, -2, "mode");
633
634 /* Quality, Signal */
635 lua_pushinteger(L, e->quality);
636 lua_setfield(L, -2, "quality");
637
638 lua_pushinteger(L, e->quality_max);
639 lua_setfield(L, -2, "quality_max");
640
641 lua_pushnumber(L, (e->signal - 0x100));
642 lua_setfield(L, -2, "signal");
643
644 /* Crypto */
645 iwinfo_L_cryptotable(L, &e->crypto);
646 lua_setfield(L, -2, "encryption");
647
648 lua_rawseti(L, -2, x);
649 }
650 }
651
652 return 1;
653 }
654
655 /* Wrapper for frequency list */
656 static int iwinfo_L_freqlist(lua_State *L, int (*func)(const char *, char *, int *))
657 {
658 int i, x, len;
659 char rv[IWINFO_BUFSIZE];
660 const char *ifname = luaL_checkstring(L, 1);
661 struct iwinfo_freqlist_entry *e;
662
663 lua_newtable(L);
664 memset(rv, 0, sizeof(rv));
665
666 if( !(*func)(ifname, rv, &len) )
667 {
668 for( i = 0, x = 1; i < len; i += sizeof(struct iwinfo_freqlist_entry), x++ )
669 {
670 e = (struct iwinfo_freqlist_entry *) &rv[i];
671
672 lua_newtable(L);
673
674 /* MHz */
675 lua_pushinteger(L, e->mhz);
676 lua_setfield(L, -2, "mhz");
677
678 /* Channel */
679 lua_pushinteger(L, e->channel);
680 lua_setfield(L, -2, "channel");
681
682 /* Restricted (DFS/TPC/Radar) */
683 lua_pushboolean(L, e->restricted);
684 lua_setfield(L, -2, "restricted");
685
686 lua_rawseti(L, -2, x);
687 }
688 }
689
690 return 1;
691 }
692
693 /* Wrapper for crypto settings */
694 static int iwinfo_L_encryption(lua_State *L, int (*func)(const char *, char *))
695 {
696 const char *ifname = luaL_checkstring(L, 1);
697 struct iwinfo_crypto_entry c = { 0 };
698
699 if( !(*func)(ifname, (char *)&c) )
700 {
701 iwinfo_L_cryptotable(L, &c);
702 return 1;
703 }
704
705 lua_pushnil(L);
706 return 1;
707 }
708
709 /* Wrapper for hwmode list */
710 static int iwinfo_L_hwmodelist(lua_State *L, int (*func)(const char *, int *))
711 {
712 const char *ifname = luaL_checkstring(L, 1);
713 int hwmodes = 0;
714
715 if( !(*func)(ifname, &hwmodes) )
716 {
717 lua_newtable(L);
718
719 lua_pushboolean(L, hwmodes & IWINFO_80211_A);
720 lua_setfield(L, -2, "a");
721
722 lua_pushboolean(L, hwmodes & IWINFO_80211_B);
723 lua_setfield(L, -2, "b");
724
725 lua_pushboolean(L, hwmodes & IWINFO_80211_G);
726 lua_setfield(L, -2, "g");
727
728 lua_pushboolean(L, hwmodes & IWINFO_80211_N);
729 lua_setfield(L, -2, "n");
730
731 return 1;
732 }
733
734 lua_pushnil(L);
735 return 1;
736 }
737
738 /* Wrapper for mbbsid_support */
739 static int iwinfo_L_mbssid_support(lua_State *L, int (*func)(const char *, int *))
740 {
741 const char *ifname = luaL_checkstring(L, 1);
742 int support = 0;
743
744 if( !(*func)(ifname, &support) )
745 {
746 lua_pushboolean(L, support);
747 return 1;
748 }
749
750 lua_pushnil(L);
751 return 1;
752 }
753
754 /* Wrapper for country list */
755 static char * iwinfo_L_country_lookup(char *buf, int len, int iso3166)
756 {
757 int i;
758 struct iwinfo_country_entry *c;
759
760 for( i = 0; i < len; i += sizeof(struct iwinfo_country_entry) )
761 {
762 c = (struct iwinfo_country_entry *) &buf[i];
763
764 if( c->iso3166 == iso3166 )
765 return c->ccode;
766 }
767
768 return NULL;
769 }
770
771 static int iwinfo_L_countrylist(lua_State *L, int (*func)(const char *, char *, int *))
772 {
773 int len, i, j;
774 char rv[IWINFO_BUFSIZE], alpha2[3];
775 char *ccode;
776 const char *ifname = luaL_checkstring(L, 1);
777 struct iwinfo_iso3166_label *l;
778
779 lua_newtable(L);
780 memset(rv, 0, sizeof(rv));
781
782 if( !(*func)(ifname, rv, &len) )
783 {
784 for( l = ISO3166_Names, j = 1; l->iso3166; l++ )
785 {
786 if( (ccode = iwinfo_L_country_lookup(rv, len, l->iso3166)) != NULL )
787 {
788 sprintf(alpha2, "%c%c",
789 (l->iso3166 / 256), (l->iso3166 % 256));
790
791 lua_newtable(L);
792
793 lua_pushstring(L, alpha2);
794 lua_setfield(L, -2, "alpha2");
795
796 lua_pushstring(L, ccode);
797 lua_setfield(L, -2, "ccode");
798
799 lua_pushstring(L, l->name);
800 lua_setfield(L, -2, "name");
801
802 lua_rawseti(L, -2, j++);
803 }
804 }
805 }
806
807 return 1;
808 }
809
810
811 #ifdef USE_WL
812 /* Broadcom */
813 LUA_WRAP_INT(wl,channel)
814 LUA_WRAP_INT(wl,frequency)
815 LUA_WRAP_INT(wl,txpower)
816 LUA_WRAP_INT(wl,bitrate)
817 LUA_WRAP_INT(wl,signal)
818 LUA_WRAP_INT(wl,noise)
819 LUA_WRAP_INT(wl,quality)
820 LUA_WRAP_INT(wl,quality_max)
821 LUA_WRAP_STRING(wl,mode)
822 LUA_WRAP_STRING(wl,ssid)
823 LUA_WRAP_STRING(wl,bssid)
824 LUA_WRAP_STRING(wl,country)
825 LUA_WRAP_LIST(wl,assoclist)
826 LUA_WRAP_LIST(wl,txpwrlist)
827 LUA_WRAP_LIST(wl,scanlist)
828 LUA_WRAP_LIST(wl,freqlist)
829 LUA_WRAP_LIST(wl,countrylist)
830 LUA_WRAP_LIST(wl,hwmodelist)
831 LUA_WRAP_LIST(wl,encryption)
832 LUA_WRAP_LIST(wl,mbssid_support)
833 #endif
834
835 #ifdef USE_MADWIFI
836 /* Madwifi */
837 LUA_WRAP_INT(madwifi,channel)
838 LUA_WRAP_INT(madwifi,frequency)
839 LUA_WRAP_INT(madwifi,txpower)
840 LUA_WRAP_INT(madwifi,bitrate)
841 LUA_WRAP_INT(madwifi,signal)
842 LUA_WRAP_INT(madwifi,noise)
843 LUA_WRAP_INT(madwifi,quality)
844 LUA_WRAP_INT(madwifi,quality_max)
845 LUA_WRAP_STRING(madwifi,mode)
846 LUA_WRAP_STRING(madwifi,ssid)
847 LUA_WRAP_STRING(madwifi,bssid)
848 LUA_WRAP_STRING(madwifi,country)
849 LUA_WRAP_LIST(madwifi,assoclist)
850 LUA_WRAP_LIST(madwifi,txpwrlist)
851 LUA_WRAP_LIST(madwifi,scanlist)
852 LUA_WRAP_LIST(madwifi,freqlist)
853 LUA_WRAP_LIST(madwifi,countrylist)
854 LUA_WRAP_LIST(madwifi,hwmodelist)
855 LUA_WRAP_LIST(madwifi,encryption)
856 LUA_WRAP_LIST(madwifi,mbssid_support)
857 #endif
858
859 #ifdef USE_NL80211
860 /* NL80211 */
861 LUA_WRAP_INT(nl80211,channel)
862 LUA_WRAP_INT(nl80211,frequency)
863 LUA_WRAP_INT(nl80211,txpower)
864 LUA_WRAP_INT(nl80211,bitrate)
865 LUA_WRAP_INT(nl80211,signal)
866 LUA_WRAP_INT(nl80211,noise)
867 LUA_WRAP_INT(nl80211,quality)
868 LUA_WRAP_INT(nl80211,quality_max)
869 LUA_WRAP_STRING(nl80211,mode)
870 LUA_WRAP_STRING(nl80211,ssid)
871 LUA_WRAP_STRING(nl80211,bssid)
872 LUA_WRAP_STRING(nl80211,country)
873 LUA_WRAP_LIST(nl80211,assoclist)
874 LUA_WRAP_LIST(nl80211,txpwrlist)
875 LUA_WRAP_LIST(nl80211,scanlist)
876 LUA_WRAP_LIST(nl80211,freqlist)
877 LUA_WRAP_LIST(nl80211,countrylist)
878 LUA_WRAP_LIST(nl80211,hwmodelist)
879 LUA_WRAP_LIST(nl80211,encryption)
880 LUA_WRAP_LIST(nl80211,mbssid_support)
881 #endif
882
883 /* Wext */
884 LUA_WRAP_INT(wext,channel)
885 LUA_WRAP_INT(wext,frequency)
886 LUA_WRAP_INT(wext,txpower)
887 LUA_WRAP_INT(wext,bitrate)
888 LUA_WRAP_INT(wext,signal)
889 LUA_WRAP_INT(wext,noise)
890 LUA_WRAP_INT(wext,quality)
891 LUA_WRAP_INT(wext,quality_max)
892 LUA_WRAP_STRING(wext,mode)
893 LUA_WRAP_STRING(wext,ssid)
894 LUA_WRAP_STRING(wext,bssid)
895 LUA_WRAP_STRING(wext,country)
896 LUA_WRAP_LIST(wext,assoclist)
897 LUA_WRAP_LIST(wext,txpwrlist)
898 LUA_WRAP_LIST(wext,scanlist)
899 LUA_WRAP_LIST(wext,freqlist)
900 LUA_WRAP_LIST(wext,countrylist)
901 LUA_WRAP_LIST(wext,hwmodelist)
902 LUA_WRAP_LIST(wext,encryption)
903 LUA_WRAP_LIST(wext,mbssid_support)
904
905 #ifdef USE_WL
906 /* Broadcom table */
907 static const luaL_reg R_wl[] = {
908 LUA_REG(wl,channel),
909 LUA_REG(wl,frequency),
910 LUA_REG(wl,txpower),
911 LUA_REG(wl,bitrate),
912 LUA_REG(wl,signal),
913 LUA_REG(wl,noise),
914 LUA_REG(wl,quality),
915 LUA_REG(wl,quality_max),
916 LUA_REG(wl,mode),
917 LUA_REG(wl,ssid),
918 LUA_REG(wl,bssid),
919 LUA_REG(wl,country),
920 LUA_REG(wl,assoclist),
921 LUA_REG(wl,txpwrlist),
922 LUA_REG(wl,scanlist),
923 LUA_REG(wl,freqlist),
924 LUA_REG(wl,countrylist),
925 LUA_REG(wl,hwmodelist),
926 LUA_REG(wl,encryption),
927 LUA_REG(wl,mbssid_support),
928 { NULL, NULL }
929 };
930 #endif
931
932 #ifdef USE_MADWIFI
933 /* Madwifi table */
934 static const luaL_reg R_madwifi[] = {
935 LUA_REG(madwifi,channel),
936 LUA_REG(madwifi,frequency),
937 LUA_REG(madwifi,txpower),
938 LUA_REG(madwifi,bitrate),
939 LUA_REG(madwifi,signal),
940 LUA_REG(madwifi,noise),
941 LUA_REG(madwifi,quality),
942 LUA_REG(madwifi,quality_max),
943 LUA_REG(madwifi,mode),
944 LUA_REG(madwifi,ssid),
945 LUA_REG(madwifi,bssid),
946 LUA_REG(madwifi,country),
947 LUA_REG(madwifi,assoclist),
948 LUA_REG(madwifi,txpwrlist),
949 LUA_REG(madwifi,scanlist),
950 LUA_REG(madwifi,freqlist),
951 LUA_REG(madwifi,countrylist),
952 LUA_REG(madwifi,hwmodelist),
953 LUA_REG(madwifi,encryption),
954 LUA_REG(madwifi,mbssid_support),
955 { NULL, NULL }
956 };
957 #endif
958
959 #ifdef USE_NL80211
960 /* NL80211 table */
961 static const luaL_reg R_nl80211[] = {
962 LUA_REG(nl80211,channel),
963 LUA_REG(nl80211,frequency),
964 LUA_REG(nl80211,txpower),
965 LUA_REG(nl80211,bitrate),
966 LUA_REG(nl80211,signal),
967 LUA_REG(nl80211,noise),
968 LUA_REG(nl80211,quality),
969 LUA_REG(nl80211,quality_max),
970 LUA_REG(nl80211,mode),
971 LUA_REG(nl80211,ssid),
972 LUA_REG(nl80211,bssid),
973 LUA_REG(nl80211,country),
974 LUA_REG(nl80211,assoclist),
975 LUA_REG(nl80211,txpwrlist),
976 LUA_REG(nl80211,scanlist),
977 LUA_REG(nl80211,freqlist),
978 LUA_REG(nl80211,countrylist),
979 LUA_REG(nl80211,hwmodelist),
980 LUA_REG(nl80211,encryption),
981 LUA_REG(nl80211,mbssid_support),
982 { NULL, NULL }
983 };
984 #endif
985
986 /* Wext table */
987 static const luaL_reg R_wext[] = {
988 LUA_REG(wext,channel),
989 LUA_REG(wext,frequency),
990 LUA_REG(wext,txpower),
991 LUA_REG(wext,bitrate),
992 LUA_REG(wext,signal),
993 LUA_REG(wext,noise),
994 LUA_REG(wext,quality),
995 LUA_REG(wext,quality_max),
996 LUA_REG(wext,mode),
997 LUA_REG(wext,ssid),
998 LUA_REG(wext,bssid),
999 LUA_REG(wext,country),
1000 LUA_REG(wext,assoclist),
1001 LUA_REG(wext,txpwrlist),
1002 LUA_REG(wext,scanlist),
1003 LUA_REG(wext,freqlist),
1004 LUA_REG(wext,countrylist),
1005 LUA_REG(wext,hwmodelist),
1006 LUA_REG(wext,encryption),
1007 LUA_REG(wext,mbssid_support),
1008 { NULL, NULL }
1009 };
1010
1011 /* Common */
1012 static const luaL_reg R_common[] = {
1013 { "type", iwinfo_L_type },
1014 { "__gc", iwinfo_L__gc },
1015 { NULL, NULL }
1016 };
1017
1018
1019 LUALIB_API int luaopen_iwinfo(lua_State *L) {
1020 luaL_register(L, IWINFO_META, R_common);
1021
1022 #ifdef USE_WL
1023 luaL_newmetatable(L, IWINFO_WL_META);
1024 luaL_register(L, NULL, R_wl);
1025 lua_pushvalue(L, -1);
1026 lua_setfield(L, -2, "__index");
1027 lua_setfield(L, -2, "wl");
1028 #endif
1029
1030 #ifdef USE_MADWIFI
1031 luaL_newmetatable(L, IWINFO_MADWIFI_META);
1032 luaL_register(L, NULL, R_madwifi);
1033 lua_pushvalue(L, -1);
1034 lua_setfield(L, -2, "__index");
1035 lua_setfield(L, -2, "madwifi");
1036 #endif
1037
1038 #ifdef USE_NL80211
1039 luaL_newmetatable(L, IWINFO_NL80211_META);
1040 luaL_register(L, NULL, R_nl80211);
1041 lua_pushvalue(L, -1);
1042 lua_setfield(L, -2, "__index");
1043 lua_setfield(L, -2, "nl80211");
1044 #endif
1045
1046 luaL_newmetatable(L, IWINFO_WEXT_META);
1047 luaL_register(L, NULL, R_wext);
1048 lua_pushvalue(L, -1);
1049 lua_setfield(L, -2, "__index");
1050 lua_setfield(L, -2, "wext");
1051
1052 return 1;
1053 }