2 * bridge.c from Access Point SNMP Utils for Linux
4 * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
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.
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.
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
23 #include <sys/types.h>
25 #include "ap-curses.h"
27 #define IPADDR _("[I] IP: ")
28 #define NETMASK _("[N] Netmask: ")
29 #define GATEWAY _("[G] Gateway: ")
30 #define IP_FILTER _("[F] Filter non-IP traffic: ")
31 #define PR_PORT _("[P] Primary port: ")
32 #define SB_ATTMAC _("Attached station MAC: ")
33 #define DHCP _("[D] DHCP client: ")
34 #define OPER _("[O] Operational mode: ")
35 #define REMOTE_MAC _("[M] Preferred BSSID (remote MAC addr.): ")
36 #define CF_PORT _("[C] Configuration-enabled port(s): ")
37 #define TRAP_PORT _("[T] Trap-sending port(s): ")
38 #define FW_BCAST _("[R] Forward broadcast traffic: ")
39 #define SB_BCAST _("[B] Isolate wireless clients (broadcast traffic): ")
40 #define SB_UCAST _("[U] Isolate wireless clients (unicast traffic): ")
41 #define HELP _("INGFPDOMSCTRBU - set; W - write conf; Q - quit to menu")
48 char sysTrapSwitch[] =
49 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x03,
53 char operIPAddress[] =
54 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x01,
58 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x02,
61 char operEthernetAddress[] =
62 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x03,
66 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x04,
70 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x05,
74 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x06,
77 /* This one is ATMEL12350 MIB specific. */
79 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x02, 0x07,
82 /* This one is ATMEL12350 TELLUS MIB specific. */
84 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x02, 0x08,
89 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x03, 0x01,
93 /* These 3 are ATMEL12350 MIB specific. */
94 char ForwardBroadcast[] =
95 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x03, 0x02,
98 char SendBackBcast[] =
99 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x03, 0x03,
102 char SendBackUnicast[] =
103 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x03, 0x04,
107 char bridgeOperationalMode[] =
108 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x04, 0x01,
111 char bridgeRemoteBridgeBSSID[] =
112 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x04, 0x02,
116 extern WINDOW *main_sub;
117 varbind varbinds[15];
118 struct in_addr ip, mask, gw;
119 unsigned char message[1024], filter, primary_port, dhcp, RemoteBSSID[6],
120 bridge_mode, traps, config_port, fw_bcast, sb_bcast,
122 char m_filter = 0, m_bridge_mode = 0, m_primary_port = 0, m_traps = 0,
123 m_dhcp = 0, m_ip = 0, m_mask = 0, m_gw = 0, m_remote_bssid = 0,
124 m_config_port = 0, m_trap_port = 0, m_fw_bcast = 0, m_sb_bcast = 0,
126 char *bridge_modes[6] = {
127 _("Wireless Bridge Point to MultiPoint"),
129 _("Access Point client"),
130 _("Wireless Bridge Point to Point"),
136 }, *cf_trap_ports[3] = {
141 oui_sbridges[3] = { 0x00, 0x30, 0x1A },
142 oui_tellus[3] = { 0x00, 0x04, 0xDB },
143 IS_ATMEL410_SBRIDGES = 0,
144 IS_ATMEL12350_TELLUS = 0;
146 unsigned int trap_port = 0;
148 if (ap_type == ATMEL12350) {
149 operEthernetAddress[5] = 0xE0;
150 operEthernetAddress[6] = 0x3E;
153 PrimaryPort[5] = 0xE0;
154 PrimaryPort[6] = 0x3E;
157 operIPAddress[5] = 0xE0;
158 operIPAddress[6] = 0x3E;
159 operIPMask[5] = 0xE0;
160 operIPMask[6] = 0x3E;
161 operGateway[5] = 0xE0;
162 operGateway[6] = 0x3E;
163 bridgeOperationalMode[5] = 0xE0;
164 bridgeOperationalMode[6] = 0x3E;
165 bridgeRemoteBridgeBSSID[5] = 0xE0;
166 bridgeRemoteBridgeBSSID[6] = 0x3E;
167 sysTrapSwitch[5] = 0xE0;
168 sysTrapSwitch[6] = 0x3E;
172 /* Determine the advanced MIB subtype of the device from its MAC address. */
173 varbinds[0].type = NULL_VALUE;
174 varbinds[0].oid = operEthernetAddress;
175 varbinds[0].len_oid = sizeof(operEthernetAddress);
176 varbinds[0].len_val = 0;
178 print_help(WAIT_RET);
179 if (snmp(varbinds, 1, GET) <= 0) {
180 print_helperr(ERR_RET);
184 if (ap_type == ATMEL410 && (memcmp(oui_sbridges, varbinds[0].value, 3) ==0))
185 IS_ATMEL410_SBRIDGES = 1;
187 if (ap_type == ATMEL12350 && (memcmp(oui_tellus, varbinds[0].value, 3) ==0))
188 IS_ATMEL12350_TELLUS = 1;
191 for (i = 1; i < 15; i++) {
192 varbinds[i].type = NULL_VALUE;
193 varbinds[i].len_val = 0;
194 varbinds[i].len_oid = sizeof(sysTrapSwitch);
199 varbinds[i++].oid = IPFilter;
200 varbinds[i++].oid = PrimaryPort;
201 varbinds[i++].oid = operDHCP;
202 varbinds[i++].oid = operIPAddress;
203 varbinds[i++].oid = operIPMask;
204 varbinds[i++].oid = operGateway;
205 varbinds[i++].oid = bridgeOperationalMode;
206 varbinds[i++].oid = sysTrapSwitch;
207 varbinds[i++].oid = bridgeRemoteBridgeBSSID;
208 if (ap_type == ATMEL12350) {
209 varbinds[i++].oid = ConfigPort;
210 varbinds[i++].oid = ForwardBroadcast;
211 varbinds[i++].oid = SendBackBcast;
212 varbinds[i++].oid = SendBackUnicast;
213 if (IS_ATMEL12350_TELLUS)
214 varbinds[i++].oid = TrapPort;
217 if (snmp(varbinds, i, GET) <= 0) {
218 print_helperr(ERR_RET);
222 print_title(_("Bridging"));
224 sprintf(message, "%s%02X%02X%02X%02X%02X%02X", MAC,
225 varbinds[0].value[0] & 0xFF,
226 varbinds[0].value[1] & 0xFF,
227 varbinds[0].value[2] & 0xFF,
228 varbinds[0].value[3] & 0xFF,
229 varbinds[0].value[4] & 0xFF,
230 varbinds[0].value[5] & 0xFF);
231 mvwaddstr(main_sub, 0, 0, message);
233 memcpy(&ip.s_addr, varbinds[4].value, 4);
234 sprintf(message, "%s%s", IPADDR, inet_ntoa(ip));
235 mvwaddstr(main_sub, 1, 0, message);
237 memcpy(&mask.s_addr, varbinds[5].value, 4);
238 sprintf(message, "%s%s", NETMASK, inet_ntoa(mask));
239 mvwaddstr(main_sub, 1, 24, message);
241 memcpy(&gw.s_addr, varbinds[6].value, 4);
242 sprintf(message, "%s%s", GATEWAY, inet_ntoa(gw));
243 mvwaddstr(main_sub, 2, 0, message);
245 filter = *(varbinds[1].value);
246 sprintf(message, "%s%s", IP_FILTER, (filter == 1) ? ON : OFF);
247 mvwaddstr(main_sub, 3, 0, message);
249 if (IS_ATMEL410_SBRIDGES) {
250 sprintf(message, "%s%02X%02X%02X%02X%02X%02X", SB_ATTMAC,
251 *(varbinds[2].value +0) & 0xFF, *(varbinds[1].value +1) & 0xFF,
252 *(varbinds[2].value +2) & 0xFF, *(varbinds[1].value +3) & 0xFF,
253 *(varbinds[2].value +4) & 0xFF, *(varbinds[1].value +5) & 0xFF);
255 primary_port = *(varbinds[2].value);
256 if (primary_port < 1 || primary_port > 2) {
259 sprintf(message, "%s%s", PR_PORT, pr_ports[primary_port - 1]);
261 mvwaddstr(main_sub, 4, 0, message);
263 dhcp = *(varbinds[3].value);
264 sprintf(message, "%s%s", DHCP, (dhcp == 1) ? ON : OFF);
265 mvwaddstr(main_sub, 5, 0, message);
267 memcpy(RemoteBSSID, varbinds[9].value, 6);
268 if ((bridge_mode = *(varbinds[7].value)) != 2) {
269 sprintf(message, "%s%02X%02X%02X%02X%02X%02X", REMOTE_MAC,
270 *(RemoteBSSID + 0) & 0xFF, *(RemoteBSSID + 1) & 0xFF,
271 *(RemoteBSSID + 2) & 0xFF, *(RemoteBSSID + 3) & 0xFF,
272 *(RemoteBSSID + 4) & 0xFF, *(RemoteBSSID + 5) & 0xFF);
273 mvwaddstr(main_sub, 7, 0, message);
277 sprintf(message, "%s%s", OPER, bridge_modes[bridge_mode - 1]);
278 mvwaddstr(main_sub, 6, 0, message);
280 traps = *(varbinds[8].value);
281 sprintf(message, "%s%s", TRAPS, (traps == 1) ? ON : OFF);
282 mvwaddstr(main_sub, 8, 0, message);
284 if (ap_type == ATMEL12350) {
285 config_port = *(varbinds[10].value);
286 sprintf(message, "%s%s", CF_PORT, cf_trap_ports[config_port]);
287 mvwaddstr(main_sub, 9, 0, message);
289 if (IS_ATMEL12350_TELLUS) {
290 for (i = 0; i < varbinds[14].len_val;
291 trap_port += varbinds[14].value[i] *
292 (1 << ((varbinds[14].len_val - i - 1) * 8)), i++);
293 sprintf(message, "%s%u", TRAP_PORT, trap_port);
294 mvwaddstr(main_sub, 10, 0, message);
297 fw_bcast = *(varbinds[11].value);
298 sprintf(message, "%s%s", FW_BCAST, (fw_bcast == 1) ? ON : OFF);
299 mvwaddstr(main_sub, 11, 0, message);
301 sb_bcast = *(varbinds[12].value);
302 sprintf(message, "%s%s", SB_BCAST, (sb_bcast == 1) ? ON : OFF);
303 mvwaddstr(main_sub, 12, 0, message);
305 sb_ucast = *(varbinds[13].value);
306 sprintf(message, "%s%s", SB_UCAST, (sb_ucast == 1) ? ON : OFF);
307 mvwaddstr(main_sub, 13, 0, message);
317 get_ip(&ip, 1, strlen(IPADDR), HELP);
322 get_mask(&mask, 1, strlen(IPADDR) + 16 + strlen(NETMASK), HELP);
327 get_ip(&gw, 2, strlen(GATEWAY), HELP);
332 filter = on_off(3, strlen(IP_FILTER));
333 clear_main_new(3, 4);
334 print_menusel(3, 0, IP_FILTER, (filter == 1) ? ON : OFF);
339 if (!IS_ATMEL410_SBRIDGES) {
340 primary_port = menu_choose(4, strlen(PR_PORT), pr_ports, 2) + 1;
341 clear_main_new(4, 5);
342 print_menusel(4, 0, PR_PORT, pr_ports[primary_port - 1]);
348 dhcp = on_off(5, strlen(DHCP));
349 clear_main_new(5, 6);
350 print_menusel(5, 0, DHCP, (dhcp == 1) ? ON : OFF);
355 bridge_mode = menu_choose(6, strlen(OPER), bridge_modes, 5) + 1;
356 clear_main_new(6, 8);
357 print_menusel(6, 0, OPER, bridge_modes[bridge_mode - 1]);
358 if (bridge_mode != 2) {
359 sprintf(message, "%02X%02X%02X%02X%02X%02X",
360 *(RemoteBSSID + 0) & 0xFF,
361 *(RemoteBSSID + 1) & 0xFF,
362 *(RemoteBSSID + 2) & 0xFF,
363 *(RemoteBSSID + 3) & 0xFF,
364 *(RemoteBSSID + 4) & 0xFF,
365 *(RemoteBSSID + 5) & 0xFF);
366 print_menusel(7, 0, REMOTE_MAC, message);
372 if (bridge_mode == 2)
375 get_mac(RemoteBSSID, 7, strlen(REMOTE_MAC));
376 /* mvwaddstr(main_sub, 7, 21, " : : : : : ");
377 for (i = 0; i < 6; i++) {
378 get_value(message, 7, 21 + i * 3, 3, ANY_STRING, 0, 0, NULL);
379 RemoteBSSID[i] = strtol(message, NULL, 16);
381 sprintf(message, "%s%02X%02X%02X%02X%02X%02X", REMOTE_MAC,
382 *(RemoteBSSID + 0) & 0xFF, *(RemoteBSSID + 1) & 0xFF,
383 *(RemoteBSSID + 2) & 0xFF, *(RemoteBSSID + 3) & 0xFF,
384 *(RemoteBSSID + 4) & 0xFF, *(RemoteBSSID + 5) & 0xFF);
390 traps = on_off(8, strlen(TRAPS));
391 clear_main_new(8, 9);
392 print_menusel(8, 0, TRAPS, (traps == 1) ? ON : OFF);
397 if (ap_type == ATMEL12350) {
398 config_port = menu_choose(9, strlen(CF_PORT), cf_trap_ports, 3);
399 clear_main_new(9, 10);
400 print_menusel(9, 0, CF_PORT, cf_trap_ports[config_port]);
406 if (IS_ATMEL12350_TELLUS) {
407 get_value(message, 10, strlen(TRAP_PORT), 6, INT_STRING,
409 trap_port = atoi(message);
415 if (ap_type == ATMEL12350) {
416 fw_bcast = on_off(11, strlen(FW_BCAST));
417 clear_main_new(11, 12);
418 print_menusel(11, 0, FW_BCAST, (fw_bcast == 1) ? ON : OFF);
424 if (ap_type == ATMEL12350) {
425 sb_bcast = on_off(12, strlen(SB_BCAST));
426 clear_main_new(12, 13);
427 print_menusel(12, 0, SB_BCAST, (sb_bcast == 1) ? ON : OFF);
433 if (ap_type == ATMEL12350) {
434 sb_ucast = on_off(13, strlen(SB_UCAST));
435 clear_main_new(13, 14);
436 print_menusel(13, 0, SB_UCAST, (sb_ucast == 1) ? ON : OFF);
444 varbinds[i].oid = IPFilter;
445 varbinds[i].len_oid = sizeof(IPFilter);
446 varbinds[i].type = INT_VALUE;
447 varbinds[i].value = (char *) &filter;
448 varbinds[i].len_val = 1;
451 if (m_primary_port) {
452 varbinds[i].oid = PrimaryPort;
453 varbinds[i].len_oid = sizeof(PrimaryPort);
454 varbinds[i].type = INT_VALUE;
455 varbinds[i].value = (char *) &primary_port;
456 varbinds[i].len_val = 1;
460 varbinds[i].oid = operDHCP;
461 varbinds[i].len_oid = sizeof(operDHCP);
462 varbinds[i].type = INT_VALUE;
463 varbinds[i].value = (char *) &dhcp;
464 varbinds[i].len_val = 1;
468 varbinds[i].oid = operIPAddress;
469 varbinds[i].len_oid = sizeof(operIPAddress);
470 ip.s_addr = htonl(ip.s_addr);
471 ip.s_addr = swap4(ip.s_addr);
472 varbinds[i].value = (char *) &ip.s_addr;
473 varbinds[i].len_val = 4;
474 varbinds[i].type = INT_VALUE;
478 varbinds[i].oid = operIPMask;
479 varbinds[i].len_oid = sizeof(operIPMask);
480 mask.s_addr = htonl(mask.s_addr);
481 mask.s_addr = swap4(mask.s_addr);
482 varbinds[i].value = (char *) &mask.s_addr;
483 varbinds[i].len_val = 4;
484 varbinds[i].type = INT_VALUE;
488 varbinds[i].oid = operGateway;
489 gw.s_addr = htonl(gw.s_addr);
490 gw.s_addr = swap4(gw.s_addr);
491 varbinds[i].len_oid = sizeof(operGateway);
492 varbinds[i].value = (char *) &gw.s_addr;
493 varbinds[i].len_val = 4;
494 varbinds[i].type = INT_VALUE;
498 varbinds[i].oid = sysTrapSwitch;
499 varbinds[i].len_oid = sizeof(sysTrapSwitch);
500 varbinds[i].value = &traps;
501 varbinds[i].len_val = 1;
502 varbinds[i].type = INT_VALUE;
506 varbinds[i].oid = bridgeOperationalMode;
507 varbinds[i].len_oid = sizeof(bridgeOperationalMode);
508 varbinds[i].value = (char *) &bridge_mode;
509 varbinds[i].len_val = 1;
510 varbinds[i].type = INT_VALUE;
513 if (m_remote_bssid) {
514 varbinds[i].oid = bridgeRemoteBridgeBSSID;
515 varbinds[i].len_oid = sizeof(bridgeRemoteBridgeBSSID);
516 varbinds[i].value = RemoteBSSID;
517 varbinds[i].len_val = 6;
518 varbinds[i].type = STRING_VALUE;
522 varbinds[i].oid = ConfigPort;
523 varbinds[i].len_oid = sizeof(ConfigPort);
524 varbinds[i].type = INT_VALUE;
525 varbinds[i].value = (char *) &config_port;
526 varbinds[i].len_val = 1;
530 varbinds[i].oid = ForwardBroadcast;
531 varbinds[i].len_oid = sizeof(ForwardBroadcast);
532 varbinds[i].type = INT_VALUE;
533 varbinds[i].value = (char *) &fw_bcast;
534 varbinds[i].len_val = 1;
538 varbinds[i].oid = SendBackBcast;
539 varbinds[i].len_oid = sizeof(SendBackBcast);
540 varbinds[i].type = INT_VALUE;
541 varbinds[i].value = (char *) &sb_bcast;
542 varbinds[i].len_val = 1;
546 varbinds[i].oid = SendBackUnicast;
547 varbinds[i].len_oid = sizeof(SendBackUnicast);
548 varbinds[i].type = INT_VALUE;
549 varbinds[i].value = (char *) &sb_ucast;
550 varbinds[i].len_val = 1;
556 len_val = (trap_port > 0x7fff) ? 3 : (trap_port > 0x7f) ? 2 : 1;
557 varbinds[i].oid = TrapPort;
558 varbinds[i].len_oid = sizeof(TrapPort);
559 varbinds[i].type = STRING_VALUE;
560 varbinds[i].value = (char *) &trap_port;
561 varbinds[i].len_val = len_val;
565 print_help(WAIT_SET);
566 if (snmp(varbinds, i, SET) <= 0)
567 print_helperr(ERR_SET);
569 print_help(DONE_SET);