]> git.decadent.org.uk Git - ap-utils.git/blob - lib/wlan.c
Imported Upstream version 1.5
[ap-utils.git] / lib / wlan.c
1 /*
2  *      wlan.c from Access Point SNMP Utils for Linux
3  *
4  * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License Version 2 from
8  * June 1991 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  */
20 #include <string.h>
21 #include <stdlib.h>
22 #include <menu.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include "ap-utils.h"
26
27 #define ESSID _("[E] ESSID: ")
28 #define AP_NAME _("[N] AP name: ")
29
30 #define CONTACT _("[K] AP contact: ")
31 #define LOCATION _("[L] AP location: ")
32
33 #define RTS_TR _("[R] RTS threshold: ")
34 #define FRG_TR _("[F] Fragmentation threshold: ")
35 #define PREAMBULE _("[P] Preambule type: ")
36 #define AUTH _("[A] Auth type: ")
37 #define   OSYS _("Open system")
38 #define   SH_KEY _("Shared key")
39 #define   BOTH_TYPE _("Both types")
40 #define RETRAIN _("[U] Auto rate fallback: ")
41 #define HIDE_ESSID _("[S] Insert ESSID in broadcast packets: ")
42 #define RATES _("Basic and Supported rates:")
43 #define RATES_HEAD _("Key   Rate  Status")
44 #define   RATES_RECORD "[%d]  %4.1fM   "
45 #define INT_ROAMING _("[I] International roaming: ")
46 #define BEACON_PER _("[B] Beacon period (msec): ")
47 #define DTIM_I _("[D] DTIM sending interval (beacons): ")
48 #define SIFS_T _("[T] SIFS time (2nd+ interframe spacing, usec): ")
49 #define WLAN_HELP _("[key] - set option; W - write conf; Q - quit to menu")
50
51 extern short ap_type, ap_vendorext;
52
53 void atmel_wireless()
54 {
55     char sysDeviceInfo[] = {
56         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x05, 0x00
57     };
58
59     char operChannelID[] = {
60         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x01, 0x00
61     };
62     char operESSIDLength[] = {
63         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x02, 0x00
64     };
65     char operESSID[] = {
66         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x03, 0x00
67     };
68     char operRTSThreshold[] = {
69         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x04, 0x00
70     };
71     char operFragmentationThreshold[] = {
72         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x05, 0x00
73     };
74     char operPreambleType[] = {
75         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x06, 0x00
76     };
77     char operAuthenticationType[] = {
78         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x07, 0x00
79     };
80     char operBasicRates[] = {
81         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x08, 0x00
82     };
83     char operAutoRateFallBack[] = {
84         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x09, 0x00
85     };
86     char operAccessPointName[] = {
87         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A, 0x00
88     };
89     char operSSIDBroadcasting[] = {
90         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0B, 0x00
91     };
92
93     /* This one is ATMEL12350 MIB specific. */
94     char operInterRoaming[] = {
95         0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x01, 0x0D, 0x00
96     };
97     /* These two are ATMEL12350 GEMTEK MIB specific. */
98     char operBeaconPeriod[] = {
99         0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x01, 0x0E, 0x00
100     };
101     char operDTIM[] = {
102         0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x01, 0x0F, 0x00
103     };
104     /* This one is ATMEL12350 EZYNET MIB specific. */
105     char operSIFSTIME[] = {
106         0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x01, 0x10, 0x00
107     };
108
109     extern WINDOW *main_sub;
110     extern rdprops regdom_types[];
111     extern char *channels[];
112     varbind varbinds[16];
113     unsigned short int RTSThreshold, FragmentationThreshold,
114         InterRoaming, m_basic_rates = 0, BeaconPeriod = 0, sifs = 0;
115     unsigned char dtim, ch;
116     char *AuthenticationTypes[3] = { OSYS, SH_KEY, BOTH_TYPE },
117         message[1024];
118     char domain[33], basic_rates[4], AutoRateFallBack, SSIDBroadcasting,
119         ap_name[33], PreambleType, AuthenticationType, channel;
120     char m_channel = 0, m_essid = 0, m_broadcast = 0, m_rts = 0,
121         m_fragment = 0, m_auth = 0, m_ap_name = 0, m_preambule = 0,
122         m_auto_rate = 0, m_inter_roaming = 0, m_beacon = 0, m_dtim = 0,
123         m_sifs = 0;
124     char *rates[3] = { ON, OFF, BASIC }, *preambules[2] = {
125     _("Short"), _("Long")};
126     short __rates[4] = { 2, 4, 11, 22 };
127     int i, c = 0, rd_idx;
128     unsigned short ap_regdomain;
129     struct sysDeviceInfo_128 str128;
130     struct sysDeviceInfo_160 str160;
131
132
133     if (ap_type == ATMEL12350) {
134         sysDeviceInfo[5] = 0xE0;
135         sysDeviceInfo[6] = 0x3E;
136         operChannelID[5] = 0xE0;
137         operChannelID[6] = 0x3E;
138         operESSIDLength[5] = 0xE0;
139         operESSIDLength[6] = 0x3E;
140         operESSID[5] = 0xE0;
141         operESSID[6] = 0x3E;
142         operRTSThreshold[5] = 0xE0;
143         operRTSThreshold[6] = 0x3E;
144         operFragmentationThreshold[5] = 0xE0;
145         operFragmentationThreshold[6] = 0x3E;
146         operPreambleType[5] = 0xE0;
147         operPreambleType[6] = 0x3E;
148         operAuthenticationType[5] = 0xE0;
149         operAuthenticationType[6] = 0x3E;
150         operBasicRates[5] = 0xE0;
151         operBasicRates[6] = 0x3E;
152         operAutoRateFallBack[5] = 0xE0;
153         operAutoRateFallBack[6] = 0x3E;
154         operAccessPointName[5] = 0xE0;
155         operAccessPointName[6] = 0x3E;
156         operSSIDBroadcasting[5] = 0xE0;
157         operSSIDBroadcasting[6] = 0x3E;
158     }
159
160     for (i = 0; i < 16; i++) {
161         varbinds[i].type = NULL_VALUE;
162         varbinds[i].len_val = 0;
163         varbinds[i].len_oid = sizeof(operChannelID);
164     }
165
166     i = 0;
167
168     varbinds[i++].oid = operChannelID;
169     varbinds[i++].oid = operESSIDLength;
170     varbinds[i++].oid = operESSID;
171     varbinds[i++].oid = operSSIDBroadcasting;
172     varbinds[i++].oid = operBasicRates;
173     varbinds[i++].oid = operAutoRateFallBack;
174     varbinds[i++].oid = operRTSThreshold;
175     varbinds[i++].oid = operFragmentationThreshold;
176     varbinds[i++].oid = operPreambleType;
177     varbinds[i++].oid = operAuthenticationType;
178     varbinds[i++].oid = operAccessPointName;
179     varbinds[i++].oid = sysDeviceInfo;
180     if (ap_type == ATMEL12350) {
181         varbinds[i++].oid = operInterRoaming;
182         if (ap_vendorext == GEMTEK || ap_vendorext == EZYNET) {
183             varbinds[i++].oid = operBeaconPeriod;
184             varbinds[i++].oid = operDTIM;
185         }
186         if (ap_vendorext == EZYNET)
187             varbinds[i++].oid = operSIFSTIME;
188     }
189
190     print_help(WAIT_RET);
191     if (snmp(varbinds, i, GET) < i) {
192         print_helperr(ERR_RET);
193         goto exit;
194     }
195
196     channel = *(varbinds[0].value);
197     c = *(varbinds[1].value);
198     memcpy(domain, varbinds[2].value, 32);
199     domain[32] = '\0';
200     SSIDBroadcasting = *(varbinds[3].value);
201     memcpy(basic_rates, varbinds[4].value, 4);
202     AutoRateFallBack = *(varbinds[5].value);
203     memcpy(&RTSThreshold, varbinds[6].value, 2);
204     RTSThreshold = ntohs(RTSThreshold);
205     memcpy(&FragmentationThreshold, varbinds[7].value, 2);
206     FragmentationThreshold = ntohs(FragmentationThreshold);
207     PreambleType = *(varbinds[8].value);
208     AuthenticationType = *(varbinds[9].value);
209     memcpy(ap_name, varbinds[10].value, 32);
210     ap_name[32] = '\0';
211     if (ap_type == ATMEL12350) {
212         InterRoaming = *(varbinds[12].value);
213         if (ap_vendorext == GEMTEK || ap_vendorext == EZYNET) {
214             BeaconPeriod = varbinds[13].len_val == 2 ?
215                 (varbinds[13].value[0] << 8) | varbinds[13].value[1] :
216                 varbinds[13].value[0] < 0x80 ?
217                 varbinds[13].value[0] : 0xff00 | varbinds[13].value[0];
218             dtim = *(varbinds[14].value);
219         }
220         if (ap_vendorext == EZYNET)
221             sifs = varbinds[15].len_val == 2 ?
222                 (varbinds[15].value[0] << 8) | varbinds[15].value[1] :
223                 varbinds[15].value[0] < 0x80 ?
224                 varbinds[15].value[0] : 0xff00 | varbinds[15].value[0];
225     }
226
227     if (varbinds[11].len_val == 160) {
228         memcpy(&str160, varbinds[11].value,
229             sizeof(struct sysDeviceInfo_160));
230         ap_regdomain = str160.RegulatoryDomain;
231     } else { /* varbinds[11].len_val == 92 || varbinds[11].len_val == 128 */
232         memcpy(&str128, varbinds[11].value,
233             sizeof(struct sysDeviceInfo_128));
234         ap_regdomain = swap4(str128.RegulatoryDomain);
235     }
236
237     rd_idx = regdom_idx(ap_regdomain);
238
239     print_top(NULL, _("Wireless Settings"));
240
241     sprintf(message, "%s%02u (%u MHz)", CHANNEL, channel, 2407 + 5 * channel);
242     mvwaddstr(main_sub, 0, 0, message);
243     mvwaddstr(main_sub, 1, 0, ESSID);
244     waddnstr(main_sub, domain, c);
245     mvwaddstr(main_sub, 2, 0, AP_NAME);
246     for (i = 0; i < 32 && ap_name[i]; i++)
247         mvwaddch(main_sub, 2, strlen(AP_NAME) + i, ap_name[i]);
248     sprintf(message, "%s%d", RTS_TR, RTSThreshold);
249     mvwaddstr(main_sub, 3, 0, message);
250     sprintf(message, "%s%d", FRG_TR, FragmentationThreshold);
251     mvwaddstr(main_sub, 4, 0, message);
252     sprintf(message, "%s%s", PREAMBULE, preambules[PreambleType - 1]);
253     mvwaddstr(main_sub, 5, 0, message);
254     sprintf(message, "%s%s", AUTH, AuthenticationTypes[AuthenticationType - 1]);
255     mvwaddstr(main_sub, 6, 0, message);
256     sprintf(message, "%s%s", RETRAIN, (AutoRateFallBack == 1) ? ON : OFF);
257     mvwaddstr(main_sub, 7, 0, message);
258     sprintf(message, "%s%s", HIDE_ESSID, (SSIDBroadcasting == 1) ? ON : OFF);
259     mvwaddstr(main_sub, 8, 0, message);
260     mvwaddstr(main_sub, 9, 0, RATES);
261     mvwaddstr(main_sub, 10, 2, RATES_HEAD);
262     for (i = 0; i < 4; i++) {
263         sprintf(message, RATES_RECORD "%s", i + 1, (float) __rates[i] / 2,
264                 basic(basic_rates[i]));
265         mvwaddstr(main_sub, 11 + i, 2, message);
266     }
267     if (ap_type == ATMEL12350) {
268         sprintf(message, "%s%s", INT_ROAMING, (InterRoaming == 1) ? ON : OFF);
269         mvwaddstr(main_sub, 15, 0, message);
270         if (ap_vendorext == GEMTEK || ap_vendorext == EZYNET) {
271             sprintf(message, "%s%u", BEACON_PER, BeaconPeriod);
272             mvwaddstr(main_sub, 16, 0, message);
273             sprintf(message, "%s%u", DTIM_I, dtim);
274             mvwaddstr(main_sub, 17, 0, message);
275         }
276         if (ap_vendorext == EZYNET) {
277             sprintf(message, "%s%u", SIFS_T, sifs);
278             mvwaddstr(main_sub, 18, 0, message);
279         }
280     }
281
282     wrefresh(main_sub);
283     noecho();
284     print_help(WLAN_HELP);
285
286     while (1) {
287         c = getch();
288         switch (c) {
289         case 'Q':
290         case 'q':
291             goto quit;
292         case '1':
293         case '2':
294         case '3':
295         case '4':
296             message[0] = c;
297             message[1] = '\0';
298             i = atoi(message);
299             switch (menu_choose(10 + i, 15, rates, 3)) {
300             case 0:
301                 basic_rates[i - 1] = __rates[i - 1];
302                 break;
303             case 1:
304                 basic_rates[i - 1] = 0;
305                 break;
306             case 2:
307                 basic_rates[i - 1] = __rates[i - 1] + 0x80;
308             }
309             clear_main_new(10 + i, 11 + i);
310             sprintf(message, RATES_RECORD, i, (float) __rates[i - 1] / 2);
311             print_menusel(10 + i, 2, message, basic(basic_rates[i - 1]));
312             m_basic_rates = 1;
313             break;
314         case 'C':
315         case 'c':
316             channel = menu_choose(0, strlen(CHANNEL),
317 #ifndef NO_REG_DOMAIN
318                 channels + regdom_types[rd_idx].first_ch - 1,
319                 regdom_types[rd_idx].chans) + regdom_types[rd_idx].first_ch;
320 #else
321                 channels, 14) + 1;
322 #endif
323             sprintf(message, "%02u (%u MHz)", channel, 2407 + 5 * channel);
324             print_menusel(0, 0, CHANNEL, message);
325             m_channel = 1;
326             continue;
327         case 'A':
328         case 'a':
329             AuthenticationType =
330                 menu_choose(6, strlen(AUTH), AuthenticationTypes, 3) + 1;
331             clear_main_new(6, 7);
332             print_menusel(6, 0, AUTH,
333                     AuthenticationTypes[AuthenticationType - 1]);
334             m_auth = 1;
335             continue;
336         case 'P':
337         case 'p':
338             PreambleType = menu_choose(5, strlen(PREAMBULE), preambules, 2) + 1;
339             clear_main_new(5, 6);
340             print_menusel(5, 0, PREAMBULE, preambules[PreambleType - 1]);
341             m_preambule = 1;
342             continue;
343         case 'U':
344         case 'u':
345             AutoRateFallBack = on_off(7, strlen(RETRAIN));
346             clear_main_new(7, 8);
347             print_menusel(7, 0, RETRAIN, (AutoRateFallBack == 1) ? ON : OFF);
348             m_auto_rate = 1;
349             continue;
350         case 'S':
351         case 's':
352             SSIDBroadcasting = on_off(8, strlen(HIDE_ESSID));
353             clear_main_new(8, 9);
354             print_menusel(8, 0, HIDE_ESSID, (SSIDBroadcasting == 1) ? ON : OFF);
355             m_broadcast = 1;
356             continue;
357         case 'N':
358         case 'n':
359 //          make_field(2, strlen(AP_NAME), 33);
360             get_value(ap_name, 2, strlen(AP_NAME), -33, ANY_STRING, 0, 0, NULL);
361             m_ap_name = 1;
362             continue;
363         case 'E':
364         case 'e':
365 //          make_field(1, strlen(ESSID), 33);
366             get_value(domain, 1, strlen(ESSID), 33, ANY_STRING, 0, 0, NULL);
367             m_essid = 1;
368             continue;
369         case 'F':
370         case 'f':
371 //          make_field(4, strlen(FRG_TR), 6);
372             get_value(message, 4, strlen(FRG_TR), 5, INT_STRING, 256, 2346,
373                 WLAN_HELP);
374             FragmentationThreshold = atoi(message);
375             m_fragment = 1;
376             continue;
377         case 'R':
378         case 'r':
379 //          make_field(3, strlen(RTS_TR), 6);
380             get_value(message, 3, strlen(RTS_TR), 5, INT_STRING, 0, 2347,
381                 WLAN_HELP);
382             RTSThreshold = atoi(message);
383             m_rts = 1;
384             continue;
385         case 'I':
386         case 'i':
387             if (ap_type == ATMEL410)
388                 continue;
389             InterRoaming = on_off(15, strlen(INT_ROAMING));
390             clear_main_new(15, 16);
391             print_menusel(15, 0, INT_ROAMING, (InterRoaming == 1) ? ON : OFF);
392             m_inter_roaming = 1;
393             continue;
394         case 'B':
395         case 'b':
396             if (ap_vendorext != GEMTEK && ap_vendorext != EZYNET)
397                 continue;
398             get_value(message, 16, strlen(BEACON_PER), 6, INT_STRING, 0, 65535,
399                 WLAN_HELP);
400             BeaconPeriod = atoi(message);
401             m_beacon = 1;
402             continue;
403         case 'D':
404         case 'd':
405             if (ap_vendorext != GEMTEK && ap_vendorext != EZYNET)
406                 continue;
407             get_value(message, 17, strlen(DTIM_I), 4, INT_STRING, 0, 255,
408                 WLAN_HELP);
409             dtim = atoi(message);
410             m_dtim = 1;
411             continue;
412         case 'T':
413         case 't':
414             if (ap_vendorext != EZYNET)
415                 continue;
416             get_value(message, 18, strlen(SIFS_T), 6, INT_STRING, 0, 65535,
417                 WLAN_HELP);
418             sifs = atoi(message);
419             m_sifs = 1;
420             continue;
421         case 'w':
422         case 'W':
423             i = 0;
424             if (m_channel) {
425                 varbinds[i].oid = operChannelID;
426                 varbinds[i].len_oid = sizeof(operChannelID);
427                 varbinds[i].value = (char *) &channel;
428                 varbinds[i].len_val = 1;
429                 varbinds[i].type = INT_VALUE;
430                 i++;
431             }
432             if (m_basic_rates) {
433                 for (m_basic_rates = 0; m_basic_rates < 2; m_basic_rates++) {
434                     c = basic_rates[3 - m_basic_rates];
435                     basic_rates[3 - m_basic_rates] =
436                         basic_rates[m_basic_rates];
437                     basic_rates[m_basic_rates] = c;
438                 }
439                 varbinds[i].oid = operBasicRates;
440                 varbinds[i].len_oid = sizeof(operBasicRates);
441                 varbinds[i].value = basic_rates;
442                 varbinds[i].len_val = 4;
443                 varbinds[i].type = INT_VALUE;
444                 i++;
445             }
446             if (m_broadcast) {
447                 varbinds[i].oid = operSSIDBroadcasting;
448                 varbinds[i].len_oid = sizeof(operSSIDBroadcasting);
449                 varbinds[i].value = (char *) &SSIDBroadcasting;
450                 varbinds[i].len_val = 1;
451                 varbinds[i].type = INT_VALUE;
452                 i++;
453             }
454             if (m_auth) {
455                 varbinds[i].oid = operAuthenticationType;
456                 varbinds[i].len_oid = sizeof(operAuthenticationType);
457                 varbinds[i].value = &AuthenticationType;
458                 varbinds[i].len_val = 1;
459                 varbinds[i].type = INT_VALUE;
460                 i++;
461             }
462             if (m_preambule) {
463                 varbinds[i].oid = operPreambleType;
464                 varbinds[i].len_oid = sizeof(operPreambleType);
465                 varbinds[i].value = &PreambleType;
466                 varbinds[i].len_val = 1;
467                 varbinds[i].type = INT_VALUE;
468                 i++;
469             }
470             if (m_auto_rate) {
471                 varbinds[i].oid = operAutoRateFallBack;
472                 varbinds[i].len_oid = sizeof(operAutoRateFallBack);
473                 varbinds[i].value = &AutoRateFallBack;
474                 varbinds[i].len_val = 1;
475                 varbinds[i].type = INT_VALUE;
476                 i++;
477             }
478             if (m_ap_name) {
479                 c = strlen(ap_name);
480                 varbinds[i].oid = operAccessPointName;
481                 varbinds[i].len_oid = sizeof(operAccessPointName);
482                 varbinds[i].value = ap_name;
483                 varbinds[i].len_val = c;
484                 varbinds[i].type = STRING_VALUE;
485                 i++;
486             }
487             if (m_fragment) {
488                 varbinds[i].oid = operFragmentationThreshold;
489                 varbinds[i].len_oid = sizeof(operFragmentationThreshold);
490                 FragmentationThreshold = htons(FragmentationThreshold);
491                 varbinds[i].value = (char *) &FragmentationThreshold;
492                 varbinds[i].len_val = 2;
493                 varbinds[i].type = INT_VALUE;
494                 i++;
495             }
496             if (m_rts) {
497                 varbinds[i].oid = operRTSThreshold;
498                 varbinds[i].len_oid = sizeof(operRTSThreshold);
499                 RTSThreshold = htons(RTSThreshold);
500                 varbinds[i].value = (char *) &RTSThreshold;
501                 varbinds[i].len_val = 2;
502                 varbinds[i].type = INT_VALUE;
503                 i++;
504             }
505             if (m_essid) {
506                 ch = strlen(domain);
507                 varbinds[i].oid = operESSIDLength;
508                 varbinds[i].len_oid = sizeof(operESSIDLength);
509                 varbinds[i].value = (char *)&ch;
510                 varbinds[i].len_val = 1;
511                 varbinds[i].type = INT_VALUE;
512                 i++;
513                 varbinds[i].oid = operESSID;
514                 varbinds[i].len_oid = sizeof(operESSID);
515                 varbinds[i].value = domain;
516                 varbinds[i].len_val = ch;
517                 varbinds[i].type = STRING_VALUE;
518                 i++;
519             }
520             if (m_inter_roaming) {
521                 varbinds[i].oid = operInterRoaming;
522                 varbinds[i].len_oid = sizeof(operInterRoaming);
523                 varbinds[i].value = (char *) &InterRoaming;
524                 varbinds[i].len_val = 1;
525                 varbinds[i].type = INT_VALUE;
526                 i++;
527             }
528             if (m_beacon) {
529                 varbinds[i].oid = operBeaconPeriod;
530                 varbinds[i].len_oid = sizeof(operBeaconPeriod);
531                 BeaconPeriod = htons(BeaconPeriod);
532                 varbinds[i].value = (char *) &BeaconPeriod;
533                 varbinds[i].len_val = 2;
534                 varbinds[i].type = INT_VALUE;
535                 i++;
536             }
537             if (m_dtim) {
538                 varbinds[i].oid = operDTIM;
539                 varbinds[i].len_oid = sizeof(operDTIM);
540                 varbinds[i].value = (char *) &dtim;
541                 varbinds[i].len_val = 1;
542                 varbinds[i].type = INT_VALUE;
543                 i++;
544             }
545             if (m_sifs) {
546                 varbinds[i].oid = operSIFSTIME;
547                 varbinds[i].len_oid = sizeof(operSIFSTIME);
548                 sifs = htons(sifs);
549                 varbinds[i].value = (char *) &sifs;
550                 varbinds[i].len_val = 2;
551                 varbinds[i].type = INT_VALUE;
552                 i++;
553             }
554
555             print_help(WAIT_SET);
556             if (snmp(varbinds, i, SET) <= 0) {
557                 print_helperr(ERR_SET);
558                 goto exit;
559             }
560             wbkgd(main_sub, A_NORMAL);
561             wrefresh(main_sub);
562             print_help(DONE_SET);
563             goto exit;
564         }
565     }
566
567   exit:
568     getch();
569   quit:
570     print_top(NULL, NULL);
571     clear_main(0);
572 }
573
574 void nwn_wireless()
575 {
576     char operESSID[] =
577         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x01, 0x01, 0x01, 0x09, 0x01 };
578     char operBasicRates[] =
579         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x01, 0x01, 0x01, 0x0b, 0x01 };
580     char OpenSystem[] =
581         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x01, 0x02, 0x01, 0x03, 0x01, 0x01 };
582     char SharedKey[] =
583         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x01, 0x02, 0x01, 0x03, 0x01, 0x02 };
584     char operRTSThreshold[] =
585         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x02, 0x01, 0x01, 0x02, 0x01 };
586     char operFragmentationThreshold[] =
587         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x02, 0x01, 0x01, 0x05, 0x01 };
588     char operChannelID[] =
589         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x04, 0x05, 0x01, 0x01, 0x01 };
590     char oid_dot11SupportedAntenna[][11] = {
591         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x04, 0x08, 0x01, 0x02, 0x01, 0x01 },
592         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x04, 0x08, 0x01, 0x02, 0x01, 0x02 },
593         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x04, 0x08, 0x01, 0x03, 0x01, 0x01 },
594         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x04, 0x08, 0x01, 0x03, 0x01, 0x02 },
595         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x04, 0x08, 0x01, 0x04, 0x01, 0x01 },
596         { 0x2a, 0x86, 0x48, 0xce, 0x34, 0x04, 0x08, 0x01, 0x04, 0x01, 0x02 }
597     };
598     char operAccessPointContact[] =
599         { 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x04, 0x00 };
600     char operAccessPointName[] =
601         { 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x05, 0x00 };
602     char operAccessPointLocation[] =
603         { 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x06, 0x00 };
604     char sysTrapSwitch[] =
605         { 0x2b, 0x06, 0x01, 0x02, 0x01, 0x0b, 0x1e, 0x00 };
606     char ChannelPref[] =
607         { 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x02, 0x01,
608         0x06, 0x00 };
609
610     unsigned short int i, RTSThreshold, FragmentationThreshold,
611         m_basic_rates = 0, authi;
612     char *auth[3] = { OSYS, SH_KEY, BOTH_TYPE },
613          *rates[3] = { ON, OFF, BASIC },
614          message[1024],
615          m_antenna[6] = { 0, 0, 0, 0, 0, 0 },
616          antenna[6],
617          channel_pref[2] = { 0, 0 };
618     extern WINDOW *main_sub;
619     extern rdprops regdom_types[];
620     extern char *channels[];
621     char *domain, basic_rates[] =
622         { 0, 0, 0, 0 }, *ap_name, ap_location[32], ap_contact[32],
623         m_ap_contact = 0, m_ap_location = 0;
624     char m_channel = 0, m_essid = 0, m_rts = 0, m_fragment = 0, m_auth =
625         0, m_ap_name = 0, channel, traps, m_traps = 0;
626     varbind varbinds[11];
627     int c = 0, reg_domain = 0, rd_idx;
628     short __rates[4] = { 2, 4, 11, 22};
629
630     domain = (char *) calloc(32, 1);
631     ap_name = (char *) calloc(32, 1);
632
633     for (i = 0; i < 8; i++) {
634         varbinds[i].len_val = 0;
635         varbinds[i].type = NULL_VALUE;
636     }
637     varbinds[0].oid = operChannelID;
638     varbinds[0].len_oid = sizeof(operChannelID);
639     varbinds[1].oid = operESSID;
640     varbinds[1].len_oid = sizeof(operESSID);
641     varbinds[2].oid = operRTSThreshold;
642     varbinds[2].len_oid = sizeof(operRTSThreshold);
643     varbinds[3].oid = operFragmentationThreshold;
644     varbinds[3].len_oid = sizeof(operFragmentationThreshold);
645     varbinds[4].oid = operBasicRates;
646     varbinds[4].len_oid = sizeof(operBasicRates);
647     varbinds[5].oid = OpenSystem;
648     varbinds[5].len_oid = sizeof(OpenSystem);
649     varbinds[6].oid = SharedKey;
650     varbinds[6].len_oid = sizeof(SharedKey);
651     varbinds[7].oid = operAccessPointName;
652     varbinds[7].len_oid = sizeof(operAccessPointName);
653     print_help(WAIT_RET);
654     if (snmp(varbinds, 8, GET) < 8) {
655         print_helperr(ERR_RET);
656         goto exit;
657     }
658
659     channel = *(varbinds[0].value);
660     memcpy(domain, varbinds[1].value, varbinds[1].len_val);
661     memcpy(basic_rates, varbinds[4].value, varbinds[4].len_val);
662     memcpy(&RTSThreshold, (varbinds[2].value), 2);
663     RTSThreshold = ntohs(RTSThreshold);
664     memcpy(&FragmentationThreshold, (varbinds[3].value), 2);
665     FragmentationThreshold = ntohs(FragmentationThreshold);
666     authi = (*(varbinds[5].value) == 1 && *(varbinds[6].value) == 1) ? 2 :
667         (*(varbinds[5].value) == 1) ? 0 : 1;
668     memcpy(ap_name, varbinds[7].value, varbinds[7].len_val);
669
670     sprintf(message, "%s%02u (%u MHz)", CHANNEL, channel, 2407 + 5 * channel);
671     mvwaddstr(main_sub, 0, 0, message);
672     mvwaddstr(main_sub, 1, 0, ESSID);
673     for (i = 0; i < 32 && domain[i]; i++)
674         mvwaddch(main_sub, 1, strlen(ESSID) + i, domain[i]);
675     mvwaddstr(main_sub, 2, 0, AP_NAME);
676     for (i = 0; i < 32 && ap_name[i]; i++)
677         mvwaddch(main_sub, 2, strlen(AP_NAME) + i, ap_name[i]);
678     sprintf(message, "%s%d", RTS_TR, RTSThreshold);
679     mvwaddstr(main_sub, 3, 0, message);
680     sprintf(message, "%s%d", FRG_TR, FragmentationThreshold);
681     mvwaddstr(main_sub, 4, 0, message);
682     sprintf(message, "%s%s", AUTH, auth[authi]);
683     mvwaddstr(main_sub, 6, 0, message);
684     mvwaddstr(main_sub, 9, 0, RATES);
685     mvwaddstr(main_sub, 10, 2, RATES_HEAD);
686     for(i = 0; i < 4; i++) {
687         sprintf(message, RATES_RECORD "%s", i + 1, (float) __rates[i] / 2,
688                 basic(basic_rates[i]));
689         mvwaddstr(main_sub, 11+i, 2, message);
690     }
691
692     reg_domain = get_RegDomain();
693     rd_idx = regdom_idx(reg_domain);
694
695     for (i = 0; i < 9; i++) {
696         varbinds[i].len_val = 0;
697         varbinds[i].type = NULL_VALUE;
698     }
699
700     for (i = 0; i < 6; i++) {
701         varbinds[i].oid = oid_dot11SupportedAntenna[i];
702         varbinds[i].len_oid = sizeof(oid_dot11SupportedAntenna[i]);
703     }
704     varbinds[6].oid = sysTrapSwitch;
705     varbinds[6].len_oid = sizeof(sysTrapSwitch);
706     varbinds[7].oid = operAccessPointContact;
707     varbinds[7].len_oid = sizeof(operAccessPointContact);
708     varbinds[8].oid = operAccessPointLocation;
709     varbinds[8].len_oid = sizeof(operAccessPointLocation);
710
711     if (snmp(varbinds, 9, GET) < 9) {
712         print_helperr(ERR_RET);
713         goto exit;
714     }
715
716     for (i = 0; i < 6; i++) {
717         antenna[i] = *varbinds[i].value;
718     }
719
720     traps = *(varbinds[6].value);
721     memcpy(ap_contact, varbinds[7].value, varbinds[7].len_val);
722     if (varbinds[7].len_val < 32)
723         ap_contact[varbinds[7].len_val] = '\0';
724     memcpy(ap_location, varbinds[8].value, varbinds[8].len_val);
725     if (varbinds[8].len_val < 32)
726         ap_location[varbinds[8].len_val] = '\0';
727
728     sprintf(message, "%s%s", LOCATION, ap_location);
729     mvwaddstr(main_sub, 7, 0, message);
730     sprintf(message, "%s%s", CONTACT, ap_contact);
731     mvwaddstr(main_sub, 8, 0, message);
732     sprintf(message, "%s%s", TRAPS, (traps == 1) ? ON : OFF);
733     mvwaddstr(main_sub, 5, 0, message);
734
735     mvwaddstr(main_sub, 16, 0, _("Antenna Configuration:"));
736     sprintf(message, "%s %s %3s, %s %3s",
737             ANTENNA_RX,
738             ANTENNA_RX_LEFT, (antenna[2] == 1) ? ON : OFF,
739             ANTENNA_RX_RIGHT, (antenna[3] == 1) ? ON : OFF);
740     mvwaddstr(main_sub, 17, 1, message);
741     sprintf(message, "%s %s %3s, %s %3s",
742             ANTENNA_TX,
743             ANTENNA_TX_LEFT, (antenna[0] == 1) ? ON : OFF,
744             ANTENNA_TX_RIGHT, (antenna[1] == 1) ? ON : OFF);
745     mvwaddstr(main_sub, 18, 1, message);
746     sprintf(message, "%s %s %3s, %s %3s",
747             ANTENNA_DV,
748             ANTENNA_DV_LEFT, (antenna[4] == 1) ? ON : OFF,
749             ANTENNA_DV_RIGHT, (antenna[5] == 1) ? ON : OFF);
750     mvwaddstr(main_sub, 19, 1, message);
751
752     print_top(NULL, _("General Options"));
753     print_help(_
754                ("UIOPTY - antenna; SCANLEDFR1234 - options; W - write conf; Q - quit to menu"));
755     wrefresh(main_sub);
756
757
758     noecho();
759     while (1) {
760         c = getch();
761         switch (c) {
762         case 'i':
763         case 'I':
764             i = strlen(ANTENNA_RX) + 1 +
765                 strlen(ANTENNA_RX_LEFT) + 6 +
766                 strlen(ANTENNA_RX_RIGHT) + 2;
767             antenna[3] = on_off(17, i);
768             sprintf(message, "%3s", (antenna[3] == 1) ? ON : OFF);
769             print_menusel(17, i, NULL, message);
770             m_antenna[3] = 1;
771             continue;
772         case 'u':
773         case 'U':
774             i = strlen(ANTENNA_RX) + 1 +
775                 strlen(ANTENNA_RX_LEFT) + 2;
776             antenna[2] = on_off(17, i);
777             sprintf(message, "%3s", (antenna[2] == 1) ? ON : OFF);
778             print_menusel(17, i, NULL, message);
779             m_antenna[2] = 1;
780             continue;
781         case 'p':
782         case 'P':
783             i = strlen(ANTENNA_TX) + 1 +
784                 strlen(ANTENNA_TX_LEFT) + 6 +
785                 strlen(ANTENNA_TX_RIGHT) + 2;
786             antenna[1] = on_off(18, i);
787             sprintf(message, "%3s", (antenna[1] == 1) ? ON : OFF);
788             print_menusel(18, i, NULL, message);
789             m_antenna[1] = 1;
790             continue;
791         case 'o':
792         case 'O':
793             i = strlen(ANTENNA_TX) + 1 +
794                 strlen(ANTENNA_TX_LEFT) + 2;
795             antenna[0] = on_off(18, i);
796             sprintf(message, "%3s", (antenna[0] == 1) ? ON : OFF);
797             print_menusel(18, i, NULL, message);
798             m_antenna[0] = 1;
799             continue;
800         case 'T':
801         case 't':
802             i = strlen(ANTENNA_DV) + 1 +
803                 strlen(ANTENNA_DV_LEFT) + 2;
804             antenna[4] = on_off(19, i);
805             sprintf(message, "%3s", (antenna[4] == 1) ? ON : OFF);
806             print_menusel(19, i, NULL, message);
807             m_antenna[4] = 1;
808             continue;
809         case 'Y':
810         case 'y':
811             i = strlen(ANTENNA_DV) + 1 +
812                 strlen(ANTENNA_DV_LEFT) + 6 +
813                 strlen(ANTENNA_DV_RIGHT) + 2;
814             antenna[5] = on_off(19, i);
815             sprintf(message, "%3s", (antenna[5] == 1) ? ON : OFF);
816             print_menusel(19, i, NULL, message);
817             m_antenna[5] = 1;
818             continue;
819         case 'S':
820         case 's':
821             traps = on_off(5, strlen(TRAPS));
822             clear_main_new(5, 6);
823             print_menusel(5, 0, TRAPS, (traps == 1) ? ON : OFF);
824             m_traps = 1;
825             continue;
826         case 'Q':
827         case 'q':
828             goto quit;
829         case '1':
830         case '2':
831         case '3':
832         case '4':
833                 i = c - '0';
834             switch (menu_choose(10 + i, 15, rates, 3)) {
835                 case 0:
836                     basic_rates[i-1] = __rates[i-1];
837                     break;
838                 case 1:
839                     basic_rates[i-1] = 0;
840                     break;
841                 case 2:
842                     basic_rates[i-1] = __rates[i-1] + 0x80;
843                 }
844             clear_main_new(10 + i, 11 + i);
845             sprintf(message, RATES_RECORD, i, (float) __rates[i-1] / 2);
846             print_menusel(10 + i, 2, message, basic(basic_rates[i-1]));
847             m_basic_rates = 1;
848             break;
849         case 'C':
850         case 'c':
851             channel = menu_choose(0, strlen(CHANNEL),
852 #ifndef NO_REG_DOMAIN
853                 channels + regdom_types[rd_idx].first_ch - 1,
854                 regdom_types[rd_idx].chans) + regdom_types[rd_idx].first_ch;
855 #else
856                 channels, 14) + 1;
857 #endif
858             sprintf(message, "%02u (%u MHz)", channel, 2407 + 5 * channel);
859             print_menusel(0, 0, CHANNEL, message);
860             m_channel = 1;
861             continue;
862         case 'A':
863         case 'a':
864             authi = menu_choose(6, strlen(AUTH), auth, 3);
865             clear_main_new(6, 7);
866             print_menusel(6, 0, AUTH, auth[authi]);
867             m_auth = 1;
868             continue;
869         case 'N':
870         case 'n':
871             get_value(ap_name, 2, strlen(AP_NAME), 32, ANY_STRING, 0, 0, NULL);
872             m_ap_name = 1;
873             continue;
874         case 'L':
875         case 'l':
876             get_value(ap_location, 7, strlen(LOCATION), 32, ANY_STRING, 0, 0,
877                 NULL);
878             m_ap_location = 1;
879             continue;
880         case 'K':
881         case 'k':
882             get_value(ap_contact, 8, strlen(CONTACT), 32, ANY_STRING, 0, 0,
883                 NULL);
884             m_ap_contact = 1;
885             continue;
886         case 'E':
887         case 'e':
888             get_value(domain, 1, strlen(ESSID), 32, ANY_STRING, 0, 0, NULL);
889             m_essid = 1;
890             continue;
891         case 'F':
892         case 'f':
893             get_value(message, 4, strlen(FRG_TR), 5, INT_STRING, 256, 2346,
894                 WLAN_HELP);
895             FragmentationThreshold = atoi(message);
896             m_fragment = 1;
897             continue;
898         case 'R':
899         case 'r':
900             get_value(message, 3, strlen(RTS_TR), 5, INT_STRING, 0, 2347,
901                 WLAN_HELP);
902             RTSThreshold = atoi(message);
903             m_rts = 1;
904             continue;
905         case 'w':
906         case 'W':
907             i = 0;
908             if (m_channel) {
909                 channel_pref[0] = channel;
910                 varbinds[i].oid = ChannelPref;
911                 varbinds[i].len_oid = sizeof(ChannelPref);
912                 varbinds[i].value = channel_pref;
913                 varbinds[i].len_val = 2;
914                 varbinds[i].type = STRING_VALUE;
915                 i++;
916                 varbinds[i].oid = operChannelID;
917                 varbinds[i].len_oid = sizeof(operChannelID);
918                 varbinds[i].value = (char *) &channel;
919                 varbinds[i].len_val = 1;
920                 varbinds[i].type = 0x02;
921                 i++;
922             }
923             if (m_basic_rates) {
924                 varbinds[i].oid = operBasicRates;
925                 varbinds[i].len_oid = sizeof(operBasicRates);
926                 varbinds[i].value = basic_rates;
927                 varbinds[i].len_val = 4;
928                 varbinds[i].type = STRING_VALUE;
929                 i++;
930             }
931
932             print_help(WAIT_SET);
933
934             if (snmp(varbinds, i, SET) <= 0) {
935                 print_helperr(ERR_SET);
936                 goto exit;
937             }
938
939             i = 0;
940             if (m_auth) {
941                 m_auth = (authi == 1) ? 2 : 1;
942                 m_basic_rates = (authi == 0) ? 2 : 1;
943                 varbinds[i].oid = OpenSystem;
944                 varbinds[i].len_oid = sizeof(OpenSystem);
945                 varbinds[i].value = (char *) &m_auth;
946                 varbinds[i].len_val = 1;
947                 varbinds[i].type = INT_VALUE;
948                 i++;
949                 varbinds[i].oid = SharedKey;
950                 varbinds[i].len_oid = sizeof(SharedKey);
951                 varbinds[i].value = (char *) &m_basic_rates;
952                 varbinds[i].len_val = 1;
953                 varbinds[i].type = INT_VALUE;
954                 i++;
955             }
956
957             if (snmp(varbinds, i, SET) <= 0) {
958                 print_helperr(ERR_SET);
959                 goto exit;
960             }
961
962             i = 0;
963             if (m_ap_name) {
964                 c = strlen(ap_name);
965                 varbinds[i].oid = operAccessPointName;
966                 varbinds[i].len_oid = sizeof(operAccessPointName);
967                 varbinds[i].value = ap_name;
968                 varbinds[i].len_val = c;
969                 varbinds[i].type = STRING_VALUE;
970                 i++;
971             }
972             if (m_ap_location) {
973                 c = strlen(ap_location);
974                 varbinds[i].oid = operAccessPointLocation;
975                 varbinds[i].len_oid = sizeof(operAccessPointLocation);
976                 varbinds[i].value = ap_location;
977                 varbinds[i].len_val = c;
978                 varbinds[i].type = STRING_VALUE;
979                 i++;
980             }
981
982             if (snmp(varbinds, i, SET) <= 0) {
983                 print_helperr(ERR_SET);
984                 goto exit;
985             }
986
987             i = 0;
988             if (m_ap_contact) {
989                 c = strlen(ap_contact);
990                 varbinds[i].oid = operAccessPointContact;
991                 varbinds[i].len_oid = sizeof(operAccessPointContact);
992                 varbinds[i].value = ap_contact;
993                 varbinds[i].len_val = c;
994                 varbinds[i].type = STRING_VALUE;
995                 i++;
996             }
997             if (m_fragment) {
998                 varbinds[i].oid = operFragmentationThreshold;
999                 varbinds[i].len_oid = sizeof(operFragmentationThreshold);
1000                 FragmentationThreshold = htons(FragmentationThreshold);
1001                 varbinds[i].value = (char *) &FragmentationThreshold;
1002                 varbinds[i].len_val = 2;
1003                 varbinds[i].type = 0x02;
1004                 i++;
1005             }
1006             if (m_rts) {
1007                 varbinds[i].oid = operRTSThreshold;
1008                 varbinds[i].len_oid = sizeof(operRTSThreshold);
1009                 RTSThreshold = htons(RTSThreshold);
1010                 varbinds[i].value = (char *) &RTSThreshold;
1011                 varbinds[i].len_val = 2;
1012                 varbinds[i].type = 0x02;
1013                 i++;
1014             }
1015             if (m_traps) {
1016                 varbinds[i].oid = sysTrapSwitch;
1017                 varbinds[i].len_oid = sizeof(sysTrapSwitch);
1018                 varbinds[i].value = &traps;
1019                 varbinds[i].len_val = 1;
1020                 varbinds[i].type = 0x02;
1021                 i++;
1022             }
1023
1024             if (snmp(varbinds, i, SET) <= 0) {
1025                 print_helperr(ERR_SET);
1026                 goto exit;
1027             }
1028
1029             c = 0;
1030             for (i = 0; i < 4; i++)
1031                 if (m_antenna[i]) {
1032                     varbinds[c].oid = oid_dot11SupportedAntenna[i];
1033                     varbinds[c].len_oid =
1034                         sizeof(oid_dot11SupportedAntenna[i]);
1035                     varbinds[c].value = &antenna[i];
1036                     varbinds[c].len_val = 1;
1037                     varbinds[c].type = INT_VALUE;
1038                     c++;
1039                 }
1040
1041             if (snmp(varbinds, c, SET) <= 0) {
1042                 print_helperr(ERR_SET);
1043                 goto exit;
1044             }
1045
1046             c = 0;
1047             for (i = i; i < 6; i++)
1048                 if (m_antenna[i]) {
1049                     varbinds[c].oid = oid_dot11SupportedAntenna[i];
1050                     varbinds[c].len_oid =
1051                         sizeof(oid_dot11SupportedAntenna[i]);
1052                     varbinds[c].value = &antenna[i];
1053                     varbinds[c].len_val = 1;
1054                     varbinds[c].type = INT_VALUE;
1055                     c++;
1056                 }
1057
1058             if (snmp(varbinds, c, SET) <= 0) {
1059                 print_helperr(ERR_SET);
1060                 goto exit;
1061             }
1062
1063             i = 0;
1064             if (m_essid) {
1065                 c = strlen(domain);
1066                 varbinds[i].oid = operESSID;
1067                 varbinds[i].len_oid = sizeof(operESSID);
1068                 varbinds[i].value = domain;
1069                 varbinds[i].len_val = c;
1070                 varbinds[i].type = 0x04;
1071                 i++;
1072             }
1073
1074             if (snmp(varbinds, i, SET) <= 0) {
1075                 print_helperr(ERR_SET);
1076                 goto exit;
1077             }
1078
1079             wbkgd(main_sub, A_NORMAL);
1080             wrefresh(main_sub);
1081             print_help(DONE_SET);
1082             goto exit;
1083         default:
1084             continue;
1085         }
1086     }
1087
1088   exit:
1089     getch();
1090   quit:
1091     print_top(NULL, NULL);
1092
1093     free(domain);
1094     free(ap_name);
1095     clear_main(0);
1096 }