]> git.decadent.org.uk Git - ap-utils.git/blob - lib/common.c
e8c0b7c116df502a2dddc700ac82d2339ecc8f9a
[ap-utils.git] / lib / common.c
1 /*
2  *      common.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
21 #include <stdlib.h>
22 #include <string.h>
23 #include <menu.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/ioctl.h>
28 #include "ap-utils.h"
29
30 #define AUTODETECT _("Autodetect AP type? ")
31 #define APIP _("Access Point IP-address: ")
32 #define APPASS _("Password (community): ")
33 #define APNAME _("Access Point name: ")
34 #define WANT_APNAME _("Do you want to define name for this AP? ") 
35 #define APTYPE _("AP type: ")
36 #define SAVESETTINGS _("Save connect-settings: ")
37
38 char IS_ATMEL410_SBRIDGES;
39 char IS_ATMEL12350_TELLUS;
40 char IS_ATMEL12350_VERNET;
41
42 extern WINDOW *main_sub;
43 extern char *community, *prog_title;
44 extern short ap_type;
45 extern int sockfd;
46 extern struct in_addr ap_ip;
47 extern char *ap_types[];
48
49 void about()
50 {
51     int nrow = 12, ncol = 47, brow = (LINES - 4 - nrow) / 2, bcol =
52         (COLS - MCOLS - 2 - ncol) / 2, i;
53     char message[100];
54
55     noecho();
56     curs_set(0);
57
58     print_title(_("About"));
59
60     /* drawing the box */
61     mvwaddch(main_sub, brow, bcol, ACS_ULCORNER);
62     mvwaddch(main_sub, brow, bcol + ncol, ACS_URCORNER);
63     mvwaddch(main_sub, brow + nrow, bcol, ACS_LLCORNER);
64     mvwaddch(main_sub, brow + nrow, bcol + ncol, ACS_LRCORNER);
65     for (i = 1; i < ncol; i++) {
66         mvwaddch(main_sub, brow, bcol + i, ACS_HLINE);
67         mvwaddch(main_sub, brow + nrow, bcol + i, ACS_HLINE);
68     }
69     for (i = 1; i < nrow; i++) {
70         mvwaddch(main_sub, brow + i, bcol, ACS_VLINE);
71         mvwaddch(main_sub, brow + i, bcol + ncol, ACS_VLINE);
72     }
73
74     mvwaddstr(main_sub, brow + 1, bcol + 2, prog_title);
75     sprintf(message, _("From %s"), TITLE);
76     mvwaddstr(main_sub, brow + 2, bcol + 2, message);
77     sprintf(message, _("Version %s"), VERSION);
78     mvwaddstr(main_sub, brow + 3, bcol + 2, message);
79     mvwaddstr(main_sub, brow + 5, bcol + 2,
80               _("Written by Roman Festchook roma@polesye.net"));
81     mvwaddstr(main_sub, brow + 6, bcol + 2,
82               _("Copyright (c) Roman Festchook 2001-2004"));
83     mvwaddstr(main_sub, brow + 7, bcol + 2, "http://ap-utils.polesye.net/");
84     mvwaddstr(main_sub, brow + 9, bcol + 2,
85               _("This program is distributed under the terms"));
86     mvwaddstr(main_sub, brow +10, bcol + 2,
87               _("of the GNU General Public License version 2."));
88     mvwaddstr(main_sub, brow + 11, bcol + 2,
89               _("See the included COPYING file for details."));
90
91
92     wrefresh(main_sub);
93
94     print_help(ANY_KEY);
95     getch();
96     print_help("");
97     print_title("");
98     clear_main(0);
99     return;
100 }
101
102 void connect_options(unsigned long int ip, int type)
103 {
104     int i;
105     struct sockaddr_in client;
106     unsigned char message[256];
107     unsigned char name[17];
108     int fd;
109     char *home_dir;
110     char save_settings=1;
111
112     memset(&client, 0, sizeof client);
113     client.sin_family = AF_INET;
114     client.sin_port = INADDR_ANY;
115     client.sin_addr.s_addr = INADDR_ANY;
116
117     if (sockfd)
118         close(sockfd);
119
120     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
121         print_helperr(CREATE_SOCKET_ERROR);
122         getch();
123         goto exit;
124     }
125
126     if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) {
127         print_helperr(BIND_SOCKET_ERROR);
128         getch();
129         goto exit;
130     }
131
132     noecho();
133     curs_set(0);
134
135     print_title(_("Connect options"));
136
137 get_all_again:
138     mvwaddstr(main_sub, 1, 1, APIP);
139     if (ip) {
140         ap_ip.s_addr = ip;
141         mvwaddstr(main_sub, 1, 1 + strlen(APIP), inet_ntoa(ap_ip));
142     } else {
143         print_help(_("Enter IP address of your Access Point."));
144         get_ip(&ap_ip, 1, 1 + strlen(APIP), NULL);
145     }
146
147     mvwaddstr(main_sub, 2, 1, APPASS);
148     print_help(_("Entered characters will not be displayed "
149         "for security reason."));
150     get_pass(message, 2, 1 + strlen(APPASS), 16);
151     if (community)
152         free(community);
153     i = strlen(message) + 1;
154     community = (char *) malloc(i);
155     strncpy(community, message, i);
156
157     print_help(_("Display name for the Access point "
158         "(NOT the name defined inside the AP!)"));
159     mvwaddstr(main_sub, 3, 1, WANT_APNAME);
160     wrefresh(main_sub);
161     i = yes_no(3, 1 + strlen(WANT_APNAME));
162     if (i == 2) { /* NO */
163         name[0] = '\0';
164         mvwaddstr(main_sub, 3, 1 + strlen(WANT_APNAME), "No");
165     } else { /* YES */
166         clear_main_new(3, 4);
167         mvwaddstr(main_sub, 3, 1, APNAME);
168         get_value(message, 3, 1 + strlen(APNAME), sizeof(name),
169             ANY_STRING, 0, 0, NULL);
170         strncpy(name, message, strlen(message) + 1);
171     }
172
173     print_help("");
174     if (type) {
175         ap_type = --type;
176         mvwaddstr(main_sub, 4, 1, APTYPE);
177     } else {
178         mvwaddstr(main_sub, 4, 1, AUTODETECT);
179         wrefresh(main_sub);
180         i = yes_no(4, 1 + strlen(AUTODETECT));
181         clear_main_new(4, 5);
182         mvwaddstr(main_sub, 4, 1, APTYPE);
183         if (i == 2) { /* NO */
184             wrefresh(main_sub);
185             ap_type = menu_choose(4, 1 + strlen(APTYPE), ap_types, 3);
186         } else { /* YES */
187             print_help(_("Determining AP type. Please wait..."));
188             if (get_mib_details() == -1) {
189                 clear_main_new(1, 5);
190                 goto get_all_again;
191             }
192         }
193         wattrset(main_sub, A_BOLD);
194     }
195     waddstr(main_sub, ap_types[ap_type]);
196     wattrset(main_sub, A_NORMAL);
197
198     mvwaddstr(main_sub, 5, 1, SAVESETTINGS);
199     wrefresh(main_sub);
200     save_settings = on_off(5, 1 + strlen(SAVESETTINGS));
201
202     print_bottom(inet_ntoa(ap_ip));
203
204     if(save_settings == 1) {
205         if ((home_dir = getenv("HOME"))) {
206             sprintf(message, "%s/.ap-config", home_dir);
207             if ((fd = open(message, O_CREAT | O_WRONLY | O_APPEND, 0600)) != -1) {
208                 sprintf(message, "%s:%s:%s:%d\n", inet_ntoa(ap_ip),
209                     community, name, ap_type);
210                 write(fd, message, strlen(message));
211                 close(fd);
212             }
213         }
214     }
215   exit:
216     print_help("");
217     print_title("");
218     clear_main(0);
219     return;
220 }
221
222 /*
223  * Determines AP MIB type (fills ap_type), and AP MIB vendor extensions
224  * (changes values of IS_ATMEL* globals). Returns with -1 on error or 0
225  * if everything is OK.
226  */
227 int get_mib_details()
228 {
229     char sysDescr_NWN[] = {
230         0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00
231     };
232     char sysDescr_ATMEL[] = {
233         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00
234     };
235     char operEthernetAddress_ATMEL[] = {
236         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x03, 0x00
237     };
238     char Wireless_ATMEL[] = {
239         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01, 0x00
240     };
241     varbind varbinds[2];
242     char oui_sbridges[3] = { 0x00, 0x30, 0x1A };
243     char oui_tellus[3] = { 0x00, 0x04, 0xDB };
244
245     /* first, determine the private MIB types according to enterprises ID */
246     varbinds[0].oid = sysDescr_NWN;
247     varbinds[0].len_oid = sizeof(sysDescr_NWN);
248     varbinds[0].value = NULL;
249     varbinds[0].len_val = 0;
250     varbinds[0].type = NULL_VALUE;
251     if (snmp(varbinds, 1, GET) > 0) {
252         ap_type = NWN;
253     } else {
254         varbinds[0].oid = sysDescr_ATMEL;
255         varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
256         varbinds[0].value = NULL;
257         varbinds[0].len_val = 0;
258         varbinds[0].type = NULL_VALUE;
259         if (snmp(varbinds, 1, GET) > 0) {
260             ap_type = ATMEL410;
261         } else {
262             sysDescr_ATMEL[5] = 0xE0;
263             sysDescr_ATMEL[6] = 0x3E;
264             varbinds[0].oid = sysDescr_ATMEL;
265             varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
266             varbinds[0].value = NULL;
267             varbinds[0].len_val = 0;
268             varbinds[0].type = NULL_VALUE;
269             if (snmp(varbinds, 1, GET) > 0) {
270                 ap_type = ATMEL12350;
271             } else {
272                 print_helperr(_("Unable to determine AP type "
273                     "(no response). Press any key."));
274                 getch();
275                 return -1;
276             }
277         }
278     }
279
280     /*
281      * It is best to do the following HERE and FOR ONCE ONLY: find out more
282      * about specific MIB modifications - we'll use them on different places
283      * later.
284      */
285     IS_ATMEL410_SBRIDGES = 0;
286     IS_ATMEL12350_TELLUS = 0;
287     IS_ATMEL12350_VERNET = 0;
288
289     varbinds[0].type = NULL_VALUE;
290     varbinds[0].oid = operEthernetAddress_ATMEL;
291     varbinds[0].len_oid = sizeof(operEthernetAddress_ATMEL);
292     varbinds[0].len_val = 0;
293     varbinds[1].type = NULL_VALUE;
294     varbinds[1].oid = Wireless_ATMEL;
295     varbinds[1].len_oid = sizeof(Wireless_ATMEL);
296     varbinds[1].len_val = 0;
297     if (ap_type == ATMEL12350) {
298         operEthernetAddress_ATMEL[5] = 0xE0;
299         operEthernetAddress_ATMEL[6] = 0x3E;
300         Wireless_ATMEL[5] = 0xE0;
301         Wireless_ATMEL[6] = 0x3E;
302     }
303     if (snmp(varbinds, 2, GET) <= 0) {
304         print_helperr(ERR_RET);
305         getch();
306         return -1;
307     }
308
309     /* detection of different vendor-modified ATMEL private MIBs */
310     if (ap_type == ATMEL410 && (memcmp(oui_sbridges, varbinds[0].value, 3) ==0))
311         IS_ATMEL410_SBRIDGES = 1;
312
313     if (ap_type == ATMEL12350 && (memcmp(oui_tellus, varbinds[0].value, 3) ==0))
314         IS_ATMEL12350_TELLUS = 1;
315
316     if (ap_type == ATMEL12350 && varbinds[1].len_val == 104)
317         IS_ATMEL12350_VERNET = 1;
318
319     return 0;
320 }
321
322 void exit_program()
323 {
324     endwin();
325     exit(0);
326 }
327
328 void exit_shell()
329 {
330     def_prog_mode();
331     endwin();
332     system("sh");
333     curs_set(0);
334     refresh();
335 }
336
337 /* 
338  * Fill channels list string array using regulation domain
339  * restrictions and return number of the channels
340  */
341 int ch_list(int regulation_domain, char **list)
342 {
343     int FIRST_CHANNEL, LAST_CHANNEL, i;
344
345 #ifndef NO_REG_DOMAIN
346     switch (regulation_domain) {
347     case 0x10:
348     case 0x20:
349         FIRST_CHANNEL = 1;
350         LAST_CHANNEL = 11;
351         break;
352     case 0x30:
353         FIRST_CHANNEL = 1;
354         LAST_CHANNEL = 13;
355         break;
356     case 0x31:
357         FIRST_CHANNEL = 10;
358         LAST_CHANNEL = 11;
359         break;
360     case 0x32:
361         FIRST_CHANNEL = 10;
362         LAST_CHANNEL = 13;
363         break;
364     default: /* also case 0x40 */
365 #endif    
366         FIRST_CHANNEL = 1;
367         LAST_CHANNEL = 14;
368 #ifndef NO_REG_DOMAIN
369     }
370 #endif    
371
372     for (i = 0; i < LAST_CHANNEL - FIRST_CHANNEL + 1; i++) {
373         list[i] = (char *) malloc(3);
374         sprintf(list[i], "%02u", FIRST_CHANNEL + i);
375     }
376     return i;
377 }
378