1/* 2 * Routines for managing persistent storage of port mappings, etc. 3 * 4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: nvparse.c,v 1.35 2010/07/30 06:38:12 Exp $ 19 */ 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <stdarg.h> 24#include <string.h> 25#include <ctype.h> 26#include <unistd.h> 27#include <limits.h> 28#include <sys/types.h> 29#include <netinet/in.h> 30#include <arpa/inet.h> 31#include <assert.h> 32 33#include <typedefs.h> 34#include <netconf.h> 35#include <bcmnvram.h> 36#include <shutils.h> 37#include <nvparse.h> 38#include <bcmconfig.h> 39 40char * 41safe_snprintf(char *str, int *len, const char *fmt, ...) 42{ 43 va_list ap; 44 int n; 45 46 va_start(ap, fmt); 47 n = vsnprintf(str, *len, fmt, ap); 48 va_end(ap); 49 50 if (n > 0) { 51 str += n; 52 *len -= n; 53 } else if (n < 0) { 54 *len = 0; 55 } 56 57 return str; 58} 59 60#ifdef __CONFIG_NAT__ 61bool 62valid_autofw_port(const netconf_app_t *app) 63{ 64 /* Check outbound protocol */ 65 if (app->match.ipproto != IPPROTO_TCP && app->match.ipproto != IPPROTO_UDP) 66 return FALSE; 67 68 /* Check outbound port range */ 69 if (ntohs(app->match.dst.ports[0]) > ntohs(app->match.dst.ports[1])) 70 return FALSE; 71 72 /* Check related protocol */ 73 if (app->proto != IPPROTO_TCP && app->proto != IPPROTO_UDP) 74 return FALSE; 75 76 /* Check related destination port range */ 77 if (ntohs(app->dport[0]) > ntohs(app->dport[1])) 78 return FALSE; 79 80 /* Check mapped destination port range */ 81 if (ntohs(app->to[0]) > ntohs(app->to[1])) 82 return FALSE; 83 84 /* Check port range size */ 85 if ((ntohs(app->dport[1]) - ntohs(app->dport[0])) != 86 (ntohs(app->to[1]) - ntohs(app->to[0]))) 87 return FALSE; 88 89 return TRUE; 90} 91 92bool 93get_autofw_port(int which, netconf_app_t *app) 94{ 95 char name[] = "autofw_portXXXXXXXXXX", value[1000]; 96 char *out_proto, *out_start, *out_end, *in_proto, *in_start, *in_end, *to_start, *to_end; 97 char *enable, *desc; 98 99 memset(app, 0, sizeof(netconf_app_t)); 100 101 /* Parse out_proto:out_start-out_end,in_proto:in_start-in_end>to_start-to_end,enable,desc */ 102 snprintf(name, sizeof(name), "autofw_port%d", which); 103 if (!nvram_invmatch(name, "")) 104 return FALSE; 105 strncpy(value, nvram_get(name), sizeof(value)); 106 107 /* Check for outbound port specification */ 108 out_start = value; 109 out_proto = strsep(&out_start, ":"); 110 if (!out_start) 111 return FALSE; 112 113 /* Check for related protocol specification */ 114 in_proto = out_start; 115 out_start = strsep(&in_proto, ","); 116 if (!in_proto) 117 return FALSE; 118 119 /* Check for related destination port specification */ 120 in_start = in_proto; 121 in_proto = strsep(&in_start, ":"); 122 if (!in_start) 123 return FALSE; 124 125 /* Check for mapped destination port specification */ 126 to_start = in_start; 127 in_start = strsep(&to_start, ">"); 128 if (!to_start) 129 return FALSE; 130 131 /* Check for enable specification */ 132 enable = to_start; 133 to_end = strsep(&enable, ","); 134 if (!enable) 135 return FALSE; 136 137 /* Check for description specification (optional) */ 138 desc = enable; 139 enable = strsep(&desc, ","); 140 141 /* Check for outbound port range (optional) */ 142 out_end = out_start; 143 out_start = strsep(&out_end, "-"); 144 if (!out_end) 145 out_end = out_start; 146 147 /* Check for related destination port range (optional) */ 148 in_end = in_start; 149 in_start = strsep(&in_end, "-"); 150 if (!in_end) 151 in_end = in_start; 152 153 /* Check for mapped destination port range (optional) */ 154 to_end = to_start; 155 to_start = strsep(&to_end, "-"); 156 if (!to_end) 157 to_end = to_start; 158 159 /* Parse outbound protocol */ 160 if (!strncasecmp(out_proto, "tcp", 3)) 161 app->match.ipproto = IPPROTO_TCP; 162 else if (!strncasecmp(out_proto, "udp", 3)) 163 app->match.ipproto = IPPROTO_UDP; 164 else 165 return FALSE; 166 167 /* Parse outbound port range */ 168 app->match.dst.ports[0] = htons(atoi(out_start)); 169 app->match.dst.ports[1] = htons(atoi(out_end)); 170 171 /* Parse related protocol */ 172 if (!strncasecmp(in_proto, "tcp", 3)) 173 app->proto = IPPROTO_TCP; 174 else if (!strncasecmp(in_proto, "udp", 3)) 175 app->proto = IPPROTO_UDP; 176 else 177 return FALSE; 178 179 /* Parse related destination port range */ 180 app->dport[0] = htons(atoi(in_start)); 181 app->dport[1] = htons(atoi(in_end)); 182 183 /* Parse mapped destination port range */ 184 app->to[0] = htons(atoi(to_start)); 185 app->to[1] = htons(atoi(to_end)); 186 187 /* Parse enable */ 188 if (!strncasecmp(enable, "off", 3)) 189 app->match.flags = NETCONF_DISABLED; 190 191 /* Parse description */ 192 if (desc) 193 strncpy(app->desc, desc, sizeof(app->desc)); 194 195 /* Set interface name (match packets entering LAN interface) */ 196 strncpy(app->match.in.name, nvram_safe_get("lan_ifname"), IFNAMSIZ); 197 198 /* Set LAN source port range (match packets from any source port) */ 199 app->match.src.ports[1] = htons(0xffff); 200 201 /* Set target (application specific port forward) */ 202 app->target = NETCONF_APP; 203 204 return valid_autofw_port(app); 205} 206 207bool 208set_autofw_port(int which, const netconf_app_t *app) 209{ 210 char name[] = "autofw_portXXXXXXXXXX", value[1000], *cur = value; 211 int len; 212 213 if (!valid_autofw_port(app)) 214 return FALSE; 215 216 /* Set out_proto:out_start-out_end,in_proto:in_start-in_end>to_start-to_end,enable,desc */ 217 snprintf(name, sizeof(name), "autofw_port%d", which); 218 len = sizeof(value); 219 220 /* Set outbound protocol */ 221 if (app->match.ipproto == IPPROTO_TCP) 222 cur = safe_snprintf(cur, &len, "tcp"); 223 else if (app->match.ipproto == IPPROTO_UDP) 224 cur = safe_snprintf(cur, &len, "udp"); 225 226 /* Set outbound port */ 227 cur = safe_snprintf(cur, &len, ":"); 228 cur = safe_snprintf(cur, &len, "%d", ntohs(app->match.dst.ports[0])); 229 cur = safe_snprintf(cur, &len, "-"); 230 cur = safe_snprintf(cur, &len, "%d", ntohs(app->match.dst.ports[1])); 231 232 /* Set related protocol */ 233 cur = safe_snprintf(cur, &len, ","); 234 if (app->proto == IPPROTO_TCP) 235 cur = safe_snprintf(cur, &len, "tcp"); 236 else if (app->proto == IPPROTO_UDP) 237 cur = safe_snprintf(cur, &len, "udp"); 238 239 /* Set related destination port range */ 240 cur = safe_snprintf(cur, &len, ":"); 241 cur = safe_snprintf(cur, &len, "%d", ntohs(app->dport[0])); 242 cur = safe_snprintf(cur, &len, "-"); 243 cur = safe_snprintf(cur, &len, "%d", ntohs(app->dport[1])); 244 245 /* Set mapped destination port range */ 246 cur = safe_snprintf(cur, &len, ">"); 247 cur = safe_snprintf(cur, &len, "%d", ntohs(app->to[0])); 248 cur = safe_snprintf(cur, &len, "-"); 249 cur = safe_snprintf(cur, &len, "%d", ntohs(app->to[1])); 250 251 /* Set enable */ 252 cur = safe_snprintf(cur, &len, ","); 253 if (app->match.flags & NETCONF_DISABLED) 254 cur = safe_snprintf(cur, &len, "off"); 255 else 256 cur = safe_snprintf(cur, &len, "on"); 257 258 /* Set description */ 259 if (*app->desc) { 260 cur = safe_snprintf(cur, &len, ","); 261 cur = safe_snprintf(cur, &len, app->desc); 262 } 263 264 /* Do it */ 265 if (nvram_set(name, value)) 266 return FALSE; 267 268 return TRUE; 269} 270 271bool 272del_autofw_port(int which) 273{ 274 char name[] = "autofw_portXXXXXXXXXX"; 275 276 snprintf(name, sizeof(name), "autofw_port%d", which); 277 return (nvram_unset(name) == 0) ? TRUE : FALSE; 278} 279 280bool 281valid_forward_port(const netconf_nat_t *nat) 282{ 283 /* Check WAN destination port range */ 284 if (ntohs(nat->match.dst.ports[0]) > ntohs(nat->match.dst.ports[1])) 285 return FALSE; 286 287 /* Check protocol */ 288 if (nat->match.ipproto != IPPROTO_TCP && nat->match.ipproto != IPPROTO_UDP) 289 return FALSE; 290 291 /* Check LAN IP address */ 292 if (nat->ipaddr.s_addr == htonl(0)) 293 return FALSE; 294 295 /* Check LAN destination port range */ 296 if (ntohs(nat->ports[0]) > ntohs(nat->ports[1])) 297 return FALSE; 298 299 /* Check port range size */ 300 if ((ntohs(nat->match.dst.ports[1]) - ntohs(nat->match.dst.ports[0])) != 301 (ntohs(nat->ports[1]) - ntohs(nat->ports[0]))) 302 return FALSE; 303 304 return TRUE; 305} 306 307bool 308get_forward_port(int which, netconf_nat_t *nat) 309{ 310 char name[] = "forward_portXXXXXXXXXX", value[1000]; 311 char *wan_port0, *wan_port1, *lan_ipaddr, *lan_port0, *lan_port1, *proto; 312 char *enable, *desc; 313 314 memset(nat, 0, sizeof(netconf_nat_t)); 315 316 /* Parse wan_port0-wan_port1>lan_ipaddr:lan_port0-lan_port1[:,]proto[:,]enable[:,]desc */ 317 snprintf(name, sizeof(name), "forward_port%d", which); 318 if (!nvram_invmatch(name, "")) 319 return FALSE; 320 strncpy(value, nvram_get(name), sizeof(value)); 321 322 /* Check for LAN IP address specification */ 323 lan_ipaddr = value; 324 wan_port0 = strsep(&lan_ipaddr, ">"); 325 if (!lan_ipaddr) 326 return FALSE; 327 328 /* Check for LAN destination port specification */ 329 lan_port0 = lan_ipaddr; 330 lan_ipaddr = strsep(&lan_port0, ":"); 331 if (!lan_port0) 332 return FALSE; 333 334 /* Check for protocol specification */ 335 proto = lan_port0; 336 lan_port0 = strsep(&proto, ":,"); 337 if (!proto) 338 return FALSE; 339 340 /* Check for enable specification */ 341 enable = proto; 342 proto = strsep(&enable, ":,"); 343 if (!enable) 344 return FALSE; 345 346 /* Check for description specification (optional) */ 347 desc = enable; 348 enable = strsep(&desc, ":,"); 349 350 /* Check for WAN destination port range (optional) */ 351 wan_port1 = wan_port0; 352 wan_port0 = strsep(&wan_port1, "-"); 353 if (!wan_port1) 354 wan_port1 = wan_port0; 355 356 /* Check for LAN destination port range (optional) */ 357 lan_port1 = lan_port0; 358 lan_port0 = strsep(&lan_port1, "-"); 359 if (!lan_port1) 360 lan_port1 = lan_port0; 361 362 /* Parse WAN destination port range */ 363 nat->match.dst.ports[0] = htons(atoi(wan_port0)); 364 nat->match.dst.ports[1] = htons(atoi(wan_port1)); 365 366 /* Parse LAN IP address */ 367 (void) inet_aton(lan_ipaddr, &nat->ipaddr); 368 369 /* Parse LAN destination port range */ 370 nat->ports[0] = htons(atoi(lan_port0)); 371 nat->ports[1] = htons(atoi(lan_port1)); 372 373 /* Parse protocol */ 374 if (!strncasecmp(proto, "tcp", 3)) 375 nat->match.ipproto = IPPROTO_TCP; 376 else if (!strncasecmp(proto, "udp", 3)) 377 nat->match.ipproto = IPPROTO_UDP; 378 else 379 return FALSE; 380 381 /* Parse enable */ 382 if (!strncasecmp(enable, "off", 3)) 383 nat->match.flags = NETCONF_DISABLED; 384 385 /* Parse description */ 386 if (desc) 387 strncpy(nat->desc, desc, sizeof(nat->desc)); 388 /* Set WAN source port range (match packets from any source port) */ 389 nat->match.src.ports[1] = htons(0xffff); 390 391 /* Set target (DNAT) */ 392 nat->target = NETCONF_DNAT; 393 394 return valid_forward_port(nat); 395} 396 397bool 398set_forward_port(int which, const netconf_nat_t *nat) 399{ 400 char name[] = "forward_portXXXXXXXXXX", value[1000], *cur = value; 401 int len; 402 403 if (!valid_forward_port(nat)) 404 return FALSE; 405 406 /* Set wan_port0-wan_port1>lan_ipaddr:lan_port0-lan_port1,proto,enable,desc */ 407 snprintf(name, sizeof(name), "forward_port%d", which); 408 len = sizeof(value); 409 410 /* Set WAN destination port range */ 411 cur = safe_snprintf(cur, &len, "%d", ntohs(nat->match.dst.ports[0])); 412 cur = safe_snprintf(cur, &len, "-"); 413 cur = safe_snprintf(cur, &len, "%d", ntohs(nat->match.dst.ports[1])); 414 415 /* Set LAN IP address */ 416 cur = safe_snprintf(cur, &len, ">"); 417 cur = safe_snprintf(cur, &len, inet_ntoa(nat->ipaddr)); 418 419 /* Set LAN destination port range */ 420 cur = safe_snprintf(cur, &len, ":"); 421 cur = safe_snprintf(cur, &len, "%d", ntohs(nat->ports[0])); 422 cur = safe_snprintf(cur, &len, "-"); 423 cur = safe_snprintf(cur, &len, "%d", ntohs(nat->ports[1])); 424 425 /* Set protocol */ 426 cur = safe_snprintf(cur, &len, ","); 427 if (nat->match.ipproto == IPPROTO_TCP) 428 cur = safe_snprintf(cur, &len, "tcp"); 429 else if (nat->match.ipproto == IPPROTO_UDP) 430 cur = safe_snprintf(cur, &len, "udp"); 431 432 /* Set enable */ 433 cur = safe_snprintf(cur, &len, ","); 434 if (nat->match.flags & NETCONF_DISABLED) 435 cur = safe_snprintf(cur, &len, "off"); 436 else 437 cur = safe_snprintf(cur, &len, "on"); 438 439 /* Set description */ 440 if (*nat->desc) { 441 cur = safe_snprintf(cur, &len, ","); 442 cur = safe_snprintf(cur, &len, nat->desc); 443 } 444 445 /* Do it */ 446 if (nvram_set(name, value)) 447 return FALSE; 448 449 return TRUE; 450} 451 452bool 453del_forward_port(int which) 454{ 455 char name[] = "forward_portXXXXXXXXXX"; 456 457 snprintf(name, sizeof(name), "forward_port%d", which); 458 return (nvram_unset(name) == 0) ? TRUE : FALSE; 459} 460 461static void 462convert_forward_proto(const char *name, int ipproto) 463{ 464 char var[1000], *next; 465 char *wan_port0, *wan_port1, *lan_ipaddr, *lan_port0, *lan_port1; 466 netconf_nat_t nat, unused; 467 bool valid; 468 int i; 469 470 foreach(var, nvram_safe_get(name), next) { 471 /* Parse wan_port0-wan_port1>lan_ipaddr:lan_port0-lan_port1 */ 472 lan_ipaddr = var; 473 wan_port0 = strsep(&lan_ipaddr, ">"); 474 if (!lan_ipaddr) 475 continue; 476 lan_port0 = lan_ipaddr; 477 lan_ipaddr = strsep(&lan_port0, ":"); 478 if (!lan_port0) 479 continue; 480 wan_port1 = wan_port0; 481 wan_port0 = strsep(&wan_port1, "-"); 482 if (!wan_port1) 483 wan_port1 = wan_port0; 484 lan_port1 = lan_port0; 485 lan_port0 = strsep(&lan_port1, "-"); 486 if (!lan_port1) 487 lan_port1 = lan_port0; 488 489 /* Set up parameters */ 490 memset(&nat, 0, sizeof(netconf_nat_t)); 491 nat.match.ipproto = ipproto; 492 nat.match.dst.ports[0] = htons(atoi(wan_port0)); 493 nat.match.dst.ports[1] = htons(atoi(wan_port1)); 494 (void) inet_aton(lan_ipaddr, &nat.ipaddr); 495 nat.ports[0] = htons(atoi(lan_port0)); 496 nat.ports[1] = htons(atoi(lan_port1)); 497 498 /* Replace an unused or invalid entry */ 499 for (i = 0; get_forward_port(i, &unused); i++); 500 valid = set_forward_port(i, &nat); 501 assert(valid); 502 } 503 504 nvram_unset(name); 505} 506 507bool 508valid_filter_client(const netconf_filter_t *start, const netconf_filter_t *end) 509{ 510 /* Check address range */ 511 if (start->match.src.netmask.s_addr) { 512 if (start->match.src.netmask.s_addr != htonl(0xffffffff) || 513 start->match.src.netmask.s_addr != end->match.src.netmask.s_addr) 514 return FALSE; 515 if (ntohl(start->match.src.ipaddr.s_addr) > ntohl(end->match.src.ipaddr.s_addr)) 516 return FALSE; 517 } 518 519 /* Check destination port range */ 520 if (ntohs(start->match.dst.ports[0]) > ntohs(start->match.dst.ports[1]) || 521 start->match.dst.ports[0] != end->match.dst.ports[0] || 522 start->match.dst.ports[1] != end->match.dst.ports[1]) 523 return FALSE; 524 525 /* Check protocol */ 526 if ((start->match.ipproto != IPPROTO_TCP && start->match.ipproto != IPPROTO_UDP) || 527 start->match.ipproto != end->match.ipproto) 528 return FALSE; 529 530 /* Check day range */ 531 if (start->match.days[0] < 0 || start->match.days[0] > 6 || 532 start->match.days[1] < 0 || start->match.days[1] > 6 || 533 start->match.days[0] != end->match.days[0] || 534 start->match.days[1] != end->match.days[1]) 535 return FALSE; 536 537 /* Check time range */ 538 if (start->match.secs[0] < 0 || start->match.secs[0] >= (24*60*60) || 539 start->match.secs[1] < 0 || start->match.secs[1] >= (24*60*60) || 540 start->match.secs[0] != end->match.secs[0] || 541 start->match.secs[1] != end->match.secs[1]) 542 return FALSE; 543 544 return TRUE; 545} 546 547bool 548get_filter_client(int which, netconf_filter_t *start, netconf_filter_t *end) 549{ 550 char name[] = "filter_clientXXXXXXXXXX", value[1000]; 551 char *lan_ipaddr0, *lan_ipaddr1, *lan_port0, *lan_port1, *proto; 552 char *day_start, *day_end, *sec_start, *sec_end; 553 char *enable, *desc; 554 555 memset(start, 0, sizeof(netconf_filter_t)); 556 memset(end, 0, sizeof(netconf_filter_t)); 557 558 /* Parse 559 * [lan_ipaddr0-lan_ipaddr1|*]:lan_port0-lan_port1,proto,day_start-day_end, 560 * sec_start-sec_end,enable,desc 561 */ 562 snprintf(name, sizeof(name), "filter_client%d", which); 563 if (!nvram_invmatch(name, "")) 564 return FALSE; 565 strncpy(value, nvram_get(name), sizeof(value)); 566 567 /* Check for port specification */ 568 lan_port0 = value; 569 lan_ipaddr0 = strsep(&lan_port0, ":"); 570 if (!lan_port0) 571 return FALSE; 572 573 /* Check for protocol specification */ 574 proto = lan_port0; 575 lan_port0 = strsep(&proto, ","); 576 if (!proto) 577 return FALSE; 578 579 /* Check for day specification */ 580 day_start = proto; 581 proto = strsep(&day_start, ","); 582 if (!day_start) 583 return FALSE; 584 585 /* Check for time specification */ 586 sec_start = day_start; 587 day_start = strsep(&sec_start, ","); 588 if (!sec_start) 589 return FALSE; 590 591 /* Check for enable specification */ 592 enable = sec_start; 593 sec_start = strsep(&enable, ","); 594 if (!enable) 595 return FALSE; 596 597 /* Check for description specification (optional) */ 598 desc = enable; 599 enable = strsep(&desc, ","); 600 601 /* Check for address range (optional) */ 602 lan_ipaddr1 = lan_ipaddr0; 603 lan_ipaddr0 = strsep(&lan_ipaddr1, "-"); 604 if (!lan_ipaddr1) 605 lan_ipaddr1 = lan_ipaddr0; 606 607 /* Check for port range (optional) */ 608 lan_port1 = lan_port0; 609 lan_port0 = strsep(&lan_port1, "-"); 610 if (!lan_port1) 611 lan_port1 = lan_port0; 612 613 /* Check for day range (optional) */ 614 day_end = day_start; 615 day_start = strsep(&day_end, "-"); 616 if (!day_end) 617 day_end = day_start; 618 619 /* Check for time range (optional) */ 620 sec_end = sec_start; 621 sec_start = strsep(&sec_end, "-"); 622 if (!sec_end) 623 sec_end = sec_start; 624 625 /* Parse address range */ 626 if (*lan_ipaddr0 == '*') { 627 /* Match any IP address */ 628 start->match.src.ipaddr.s_addr = end->match.src.ipaddr.s_addr = htonl(0); 629 start->match.src.netmask.s_addr = end->match.src.netmask.s_addr = htonl(0); 630 } else { 631 /* Match a range of IP addresses */ 632 inet_aton(lan_ipaddr0, &start->match.src.ipaddr); 633 inet_aton(lan_ipaddr1, &end->match.src.ipaddr); 634 start->match.src.netmask.s_addr = end->match.src.netmask.s_addr = htonl(0xffffffff); 635 } 636 637 /* Parse destination port range */ 638 start->match.dst.ports[0] = end->match.dst.ports[0] = htons(atoi(lan_port0)); 639 start->match.dst.ports[1] = end->match.dst.ports[1] = htons(atoi(lan_port1)); 640 641 /* Parse protocol */ 642 if (!strncasecmp(proto, "tcp", 3)) 643 start->match.ipproto = end->match.ipproto = IPPROTO_TCP; 644 else if (!strncasecmp(proto, "udp", 3)) 645 start->match.ipproto = end->match.ipproto = IPPROTO_UDP; 646 else 647 return FALSE; 648 649 /* Parse day range */ 650 start->match.days[0] = end->match.days[0] = atoi(day_start); 651 start->match.days[1] = end->match.days[1] = atoi(day_end); 652 653 /* Parse time range */ 654 start->match.secs[0] = end->match.secs[0] = atoi(sec_start); 655 start->match.secs[1] = end->match.secs[1] = atoi(sec_end); 656 657 /* Parse enable */ 658 if (!strncasecmp(enable, "off", 3)) 659 start->match.flags = end->match.flags = NETCONF_DISABLED; 660 661 /* Parse description */ 662 if (desc) { 663 strncpy(start->desc, desc, sizeof(start->desc)); 664 strncpy(end->desc, desc, sizeof(end->desc)); 665 } 666 667 /* Set interface name (match packets entering LAN interface) */ 668 strncpy(start->match.in.name, nvram_safe_get("lan_ifname"), IFNAMSIZ); 669 670 /* Set source port range (match packets from any source port) */ 671 start->match.src.ports[1] = end->match.src.ports[1] = htons(0xffff); 672 673 /* Set default target (drop) */ 674 start->target = NETCONF_DROP; 675 676 return valid_filter_client(start, end); 677} 678 679bool 680set_filter_client(int which, const netconf_filter_t *start, const netconf_filter_t *end) 681{ 682 char name[] = "filter_clientXXXXXXXXXX", value[1000], *cur = value; 683 int len; 684 685 if (!valid_filter_client(start, end)) 686 return FALSE; 687 688 /* Set 689 * [lan_ipaddr0-lan_ipaddr1|*]:lan_port0-lan_port1,proto,day_start-day_end, 690 * sec_start-sec_end,enable,desc 691 */ 692 snprintf(name, sizeof(name), "filter_client%d", which); 693 len = sizeof(value); 694 695 /* Set address range */ 696 if (start->match.src.ipaddr.s_addr == htonl(0) && 697 end->match.src.ipaddr.s_addr == htonl(0) && 698 start->match.src.netmask.s_addr == htonl(0) && 699 end->match.src.netmask.s_addr == htonl(0)) 700 cur = safe_snprintf(cur, &len, "*"); 701 else { 702 cur = safe_snprintf(cur, &len, inet_ntoa(start->match.src.ipaddr)); 703 cur = safe_snprintf(cur, &len, "-"); 704 cur = safe_snprintf(cur, &len, inet_ntoa(end->match.src.ipaddr)); 705 } 706 707 /* Set port range */ 708 cur = safe_snprintf(cur, &len, ":"); 709 cur = safe_snprintf(cur, &len, "%d", ntohs(start->match.dst.ports[0])); 710 cur = safe_snprintf(cur, &len, "-"); 711 cur = safe_snprintf(cur, &len, "%d", ntohs(start->match.dst.ports[1])); 712 713 /* Set protocol */ 714 cur = safe_snprintf(cur, &len, ","); 715 if (start->match.ipproto == IPPROTO_TCP) 716 cur = safe_snprintf(cur, &len, "tcp"); 717 else if (start->match.ipproto == IPPROTO_UDP) 718 cur = safe_snprintf(cur, &len, "udp"); 719 720 /* Set day range */ 721 cur = safe_snprintf(cur, &len, ","); 722 cur = safe_snprintf(cur, &len, "%d", start->match.days[0]); 723 cur = safe_snprintf(cur, &len, "-"); 724 cur = safe_snprintf(cur, &len, "%d", start->match.days[1]); 725 726 /* Set time range */ 727 cur = safe_snprintf(cur, &len, ","); 728 cur = safe_snprintf(cur, &len, "%d", start->match.secs[0]); 729 cur = safe_snprintf(cur, &len, "-"); 730 cur = safe_snprintf(cur, &len, "%d", start->match.secs[1]); 731 732 /* Set enable */ 733 cur = safe_snprintf(cur, &len, ","); 734 if (start->match.flags & NETCONF_DISABLED) 735 cur = safe_snprintf(cur, &len, "off"); 736 else 737 cur = safe_snprintf(cur, &len, "on"); 738 739 /* Set description */ 740 if (*start->desc) { 741 cur = safe_snprintf(cur, &len, ","); 742 cur = safe_snprintf(cur, &len, start->desc); 743 } 744 745 /* Do it */ 746 if (nvram_set(name, value)) 747 return FALSE; 748 749 return TRUE; 750} 751 752bool 753del_filter_client(int which) 754{ 755 char name[] = "filter_clientXXXXXXXXXX"; 756 757 snprintf(name, sizeof(name), "filter_client%d", which); 758 return (nvram_unset(name) == 0) ? TRUE : FALSE; 759} 760 761#ifdef __CONFIG_URLFILTER__ 762bool 763valid_filter_url(const netconf_urlfilter_t *start, const netconf_urlfilter_t *end) 764{ 765 /* Check address range */ 766 if (start->match.src.netmask.s_addr) { 767 if (start->match.src.netmask.s_addr != htonl(0xffffffff) || 768 start->match.src.netmask.s_addr != end->match.src.netmask.s_addr) 769 return FALSE; 770 if (ntohl(start->match.src.ipaddr.s_addr) > ntohl(end->match.src.ipaddr.s_addr)) 771 return FALSE; 772 } 773 774 return TRUE; 775} 776 777bool 778get_filter_url(int which, netconf_urlfilter_t *start, netconf_urlfilter_t *end) 779{ 780 char name[] = "filter_urlXXXXXXXXXX", value[1000]; 781 char *lan_ipaddr0, *lan_ipaddr1; 782 char *url, *enable, *desc; 783 784 memset(start, 0, sizeof(netconf_urlfilter_t)); 785 memset(end, 0, sizeof(netconf_urlfilter_t)); 786 787 /* Parse 788 * [lan_ipaddr0-lan_ipaddr1|*]:url,enable,desc 789 */ 790 snprintf(name, sizeof(name), "filter_url%d", which); 791 if (!nvram_invmatch(name, "")) 792 return FALSE; 793 strncpy(value, nvram_get(name), sizeof(value)); 794 795 /* Check for URL */ 796 url = value; 797 lan_ipaddr0 = strsep(&url, ":"); 798 if (!url) 799 return FALSE; 800 801 /* Check for enable specification */ 802 enable = url; 803 url = strsep(&enable, ","); 804 if (!enable) 805 return FALSE; 806 807 /* Check for description specification (optional) */ 808 desc = enable; 809 enable = strsep(&desc, ","); 810 811 /* Check for address range (optional) */ 812 lan_ipaddr1 = lan_ipaddr0; 813 lan_ipaddr0 = strsep(&lan_ipaddr1, "-"); 814 if (!lan_ipaddr1) 815 lan_ipaddr1 = lan_ipaddr0; 816 817 /* Parse address range */ 818 if (*lan_ipaddr0 == '*') { 819 /* Match any IP address */ 820 start->match.src.ipaddr.s_addr = end->match.src.ipaddr.s_addr = htonl(0); 821 start->match.src.netmask.s_addr = end->match.src.netmask.s_addr = htonl(0); 822 } else { 823 /* Match a range of IP addresses */ 824 inet_aton(lan_ipaddr0, &start->match.src.ipaddr); 825 inet_aton(lan_ipaddr1, &end->match.src.ipaddr); 826 start->match.src.netmask.s_addr = end->match.src.netmask.s_addr = htonl(0xffffffff); 827 } 828 829 /* Parse enable */ 830 if (!strncasecmp(enable, "off", 3)) 831 start->match.flags = end->match.flags = NETCONF_DISABLED; 832 833 /* Parse description */ 834 if (url) { 835 strncpy(start->url, url, sizeof(start->url)); 836 strncpy(end->url, url, sizeof(end->url)); 837 } 838 839 /* Parse description */ 840 if (desc) { 841 strncpy(start->desc, desc, sizeof(start->desc)); 842 strncpy(end->desc, desc, sizeof(end->desc)); 843 } 844 845 /* Set interface name (match packets entering LAN interface) */ 846 strncpy(start->match.in.name, nvram_safe_get("lan_ifname"), IFNAMSIZ); 847 848 /* Set default target (drop) */ 849 start->target = NETCONF_DROP; 850 851 return valid_filter_url(start, end); 852} 853 854bool 855set_filter_url(int which, const netconf_urlfilter_t *start, const netconf_urlfilter_t *end) 856{ 857 char name[] = "filter_urlXXXXXXXXXX", value[1000], *cur = value; 858 int len; 859 860 if (!valid_filter_url(start, end)) 861 return FALSE; 862 863 /* Set 864 * [lan_ipaddr0-lan_ipaddr1|*]:url,enable 865 */ 866 snprintf(name, sizeof(name), "filter_url%d", which); 867 len = sizeof(value); 868 869 /* Set address range */ 870 if (start->match.src.ipaddr.s_addr == htonl(0) && 871 end->match.src.ipaddr.s_addr == htonl(0) && 872 start->match.src.netmask.s_addr == htonl(0) && 873 end->match.src.netmask.s_addr == htonl(0)) 874 cur = safe_snprintf(cur, &len, "*"); 875 else { 876 cur = safe_snprintf(cur, &len, inet_ntoa(start->match.src.ipaddr)); 877 cur = safe_snprintf(cur, &len, "-"); 878 cur = safe_snprintf(cur, &len, inet_ntoa(end->match.src.ipaddr)); 879 } 880 881 /* Set URL */ 882 cur = safe_snprintf(cur, &len, ":"); 883 cur = safe_snprintf(cur, &len, "%s", start->url); 884 885 /* Set enable */ 886 cur = safe_snprintf(cur, &len, ","); 887 if (start->match.flags & NETCONF_DISABLED) 888 cur = safe_snprintf(cur, &len, "off"); 889 else 890 cur = safe_snprintf(cur, &len, "on"); 891 892 /* Set description */ 893 if (*start->desc) { 894 cur = safe_snprintf(cur, &len, ","); 895 cur = safe_snprintf(cur, &len, start->desc); 896 } 897 898 /* Do it */ 899 if (nvram_set(name, value)) 900 return FALSE; 901 902 return TRUE; 903} 904 905bool 906del_filter_url(int which) 907{ 908 char name[] = "filter_urlXXXXXXXXXX"; 909 910 snprintf(name, sizeof(name), "filter_url%d", which); 911 return (nvram_unset(name) == 0) ? TRUE : FALSE; 912} 913#endif /* __CONFIG_URLFILTER__ */ 914#endif /* __CONFIG_NAT__ */ 915 916/* 917 * wl_wds<N> is authentication protocol dependant. 918 * when auth is "psk": 919 * wl_wds<N>=mac,role,crypto,auth,ssid,passphrase 920 */ 921bool 922get_wds_wsec(int unit, int which, unsigned char *mac, char *role, 923 char *crypto, char *auth, ...) 924{ 925 char name[] = "wlXXXXXXX_wdsXXXXXXX", value[1000], *next; 926 927 snprintf(name, sizeof(name), "wl%d_wds%d", unit, which); 928 strncpy(value, nvram_safe_get(name), sizeof(value)); 929 next = value; 930 931 /* separate mac */ 932 strcpy((char *)mac, strsep(&next, ",")); 933 if (!next) 934 return FALSE; 935 936 /* separate role */ 937 strcpy(role, strsep(&next, ",")); 938 if (!next) 939 return FALSE; 940 941 /* separate crypto */ 942 strcpy(crypto, strsep(&next, ",")); 943 if (!next) 944 return FALSE; 945 946 /* separate auth */ 947 strcpy(auth, strsep(&next, ",")); 948 if (!next) 949 return FALSE; 950 951 if (!strcmp(auth, "psk")) { 952 va_list va; 953 954 va_start(va, auth); 955 956 /* separate ssid */ 957 strcpy(va_arg(va, char *), strsep(&next, ",")); 958 if (!next) 959 goto fail; 960 961 /* separate passphrase */ 962 strcpy(va_arg(va, char *), next); 963 964 va_end(va); 965 return TRUE; 966fail: 967 va_end(va); 968 return FALSE; 969 } 970 971 return FALSE; 972} 973 974bool 975set_wds_wsec(int unit, int which, unsigned char *mac, char *role, 976 char *crypto, char *auth, ...) 977{ 978 char name[] = "wlXXXXXXX_wdsXXXXXXX", value[10000]; 979 980 snprintf(name, sizeof(name), "wl%d_wds%d", unit, which); 981 snprintf(value, sizeof(value), "%s,%s,%s,%s", 982 mac, role, crypto, auth); 983 984 if (!strcmp(auth, "psk")) { 985 int offset; 986 char *str1, *str2; 987 va_list va; 988 989 va_start(va, auth); 990 offset = strlen(value); 991 str1 = va_arg(va, char *); 992 str2 = va_arg(va, char *); 993 994 snprintf(&value[offset], sizeof(value) - offset, ",%s,%s", str1, str2); 995 va_end(va); 996 997 if (nvram_set(name, value)) 998 return FALSE; 999 1000 return TRUE; 1001 } 1002 1003 return FALSE; 1004} 1005 1006bool 1007del_wds_wsec(int unit, int which) 1008{ 1009 char name[] = "wlXXXXXXX_wdsXXXXXXX"; 1010 1011 snprintf(name, sizeof(name), "wl%d_wds%d", unit, which); 1012 1013 nvram_unset(name); 1014 1015 return TRUE; 1016} 1017 1018#ifdef __CONFIG_NAT__ 1019static void 1020convert_filter_ip(void) 1021{ 1022 char var[1000], *next; 1023 char *lan_ipaddr0, *lan_ipaddr1; 1024 netconf_filter_t start, end, unused; 1025 bool valid; 1026 int i; 1027 1028 foreach(var, nvram_safe_get("filter_ip"), next) { 1029 /* Parse lan_ipaddr0-lan_ipaddr1 */ 1030 lan_ipaddr1 = var; 1031 lan_ipaddr0 = strsep(&lan_ipaddr1, "-"); 1032 if (!lan_ipaddr0 || !lan_ipaddr1) 1033 continue; 1034 1035 /* Set up parameters */ 1036 memset(&start, 0, sizeof(netconf_filter_t)); 1037 (void) inet_aton(lan_ipaddr0, &start.match.src.ipaddr); 1038 start.match.src.netmask.s_addr = htonl(0xffffffff); 1039 start.match.dst.ports[1] = htons(0xffff); 1040 memcpy(&end, &start, sizeof(netconf_filter_t)); 1041 (void) inet_aton(lan_ipaddr1, &end.match.src.ipaddr); 1042 1043 /* Replace an unused or invalid entry */ 1044 start.match.ipproto = end.match.ipproto = IPPROTO_TCP; 1045 for (i = 0; get_filter_client(i, &unused, &unused); i++); 1046 valid = set_filter_client(i, &start, &end); 1047 assert(valid); 1048 1049 /* Replace an unused or invalid entry */ 1050 start.match.ipproto = end.match.ipproto = IPPROTO_UDP; 1051 for (; get_filter_client(i, &unused, &unused); i++); 1052 valid = set_filter_client(i, &start, &end); 1053 assert(valid); 1054 } 1055 1056 nvram_unset("filter_ip"); 1057} 1058 1059static void 1060convert_filter_proto(const char *name, int ipproto) 1061{ 1062 char var[1000], *next; 1063 char *lan_ipaddr, *lan_port0, *lan_port1; 1064 netconf_filter_t start, end, unused; 1065 bool valid; 1066 int i; 1067 1068 foreach(var, nvram_safe_get(name), next) { 1069 /* Parse [lan_ipaddr|*]:lan_port0-lan_port1 */ 1070 lan_port0 = var; 1071 lan_ipaddr = strsep(&lan_port0, ":"); 1072 if (!lan_ipaddr || !lan_port0) 1073 continue; 1074 lan_port1 = lan_port0; 1075 lan_port0 = strsep(&lan_port1, "-"); 1076 if (!lan_port0 || !lan_port1) 1077 continue; 1078 1079 /* Set up parameters */ 1080 memset(&start, 0, sizeof(netconf_filter_t)); 1081 (void) inet_aton(lan_ipaddr, &start.match.src.ipaddr); 1082 start.match.src.netmask.s_addr = htonl(0xffffffff); 1083 start.match.ipproto = ipproto; 1084 start.match.dst.ports[0] = htons(atoi(lan_port0)); 1085 start.match.dst.ports[1] = htons(atoi(lan_port1)); 1086 memcpy(&end, &start, sizeof(netconf_filter_t)); 1087 1088 /* Replace an unused or invalid entry */ 1089 for (i = 0; get_filter_client(i, &unused, &unused); i++); 1090 valid = set_filter_client(i, &start, &end); 1091 assert(valid); 1092 } 1093 1094 nvram_unset(name); 1095} 1096 1097static void 1098convert_filter_port(void) 1099{ 1100 char name[1000], *value, *colon; 1101 netconf_filter_t start, end, unused; 1102 bool valid; 1103 int i, j; 1104 1105 /* Maximum number of filter_port entries was 6 */ 1106 for (i = 1; i <= 6; i++) { 1107 snprintf(name, sizeof(name), "filter_port%d", i); 1108 if (!(value = nvram_get(name)) || !*value) 1109 goto fail; 1110 1111 memset(&start, 0, sizeof(netconf_filter_t)); 1112 memset(&end, 0, sizeof(netconf_filter_t)); 1113 1114 /* Only the last bytes of IP addresses were stored in NVRAM */ 1115 (void) inet_aton(nvram_safe_get("lan_ipaddr"), &start.match.src.ipaddr); 1116 (void) inet_aton(nvram_safe_get("lan_ipaddr"), &end.match.src.ipaddr); 1117 1118 /* id (unused) */ 1119 if (!(colon = strchr(value, ':'))) 1120 goto fail; 1121 value = colon + 1; 1122 1123 /* active */ 1124 if (!(colon = strchr(value, ':'))) 1125 goto fail; 1126 if (!strtoul(value, NULL, 0)) 1127 start.match.flags = end.match.flags = NETCONF_DISABLED; 1128 value = colon + 1; 1129 1130 /* flags (unused) */ 1131 if (!(colon = strchr(value, ':'))) 1132 goto fail; 1133 value = colon + 1; 1134 1135 /* from_ip */ 1136 if (!(colon = strchr(value, ':'))) 1137 goto fail; 1138 start.match.src.ipaddr.s_addr = htonl((ntohl(start.match.src.ipaddr.s_addr) & ~0xff) 1139 | strtoul(value, NULL, 0)); 1140 value = colon + 1; 1141 1142 /* to_ip */ 1143 if (!(colon = strchr(value, ':'))) 1144 goto fail; 1145 end.match.src.ipaddr.s_addr = htonl((ntohl(end.match.src.ipaddr.s_addr) & ~0xff) | 1146 strtoul(value, NULL, 0)); 1147 value = colon + 1; 1148 1149 /* from_port */ 1150 if (!(colon = strchr(value, ':'))) 1151 goto fail; 1152 start.match.dst.ports[0] = end.match.dst.ports[0] = htons(strtoul(value, NULL, 0)); 1153 value = colon + 1; 1154 1155 /* to_port */ 1156 if (!(colon = strchr(value, ':'))) 1157 goto fail; 1158 start.match.dst.ports[1] = end.match.dst.ports[1] = htons(strtoul(value, NULL, 0)); 1159 value = colon + 1; 1160 1161 /* protocol */ 1162 if (!(colon = strchr(value, ':'))) 1163 goto fail; 1164 start.match.ipproto = end.match.ipproto = strtoul(value, NULL, 0); 1165 value = colon + 1; 1166 1167 /* always */ 1168 if (!(colon = strchr(value, ':'))) 1169 goto fail; 1170 if (strtoul(value, NULL, 0)) 1171 goto done; 1172 value = colon + 1; 1173 1174 /* from_day_of_week */ 1175 if (!(colon = strchr(value, ':'))) 1176 goto fail; 1177 start.match.days[0] = end.match.days[0] = strtoul(value, NULL, 0); 1178 value = colon + 1; 1179 1180 /* to_day_of_week */ 1181 if (!(colon = strchr(value, ':'))) 1182 goto fail; 1183 start.match.days[1] = end.match.days[1] = strtoul(value, NULL, 0); 1184 value = colon + 1; 1185 1186 /* from_time_of_day */ 1187 if (!(colon = strchr(value, ':'))) 1188 goto fail; 1189 start.match.secs[0] = end.match.secs[0] = strtoul(value, NULL, 0); 1190 value = colon + 1; 1191 1192 /* to_time_of_day */ 1193 start.match.secs[1] = end.match.secs[1] = strtoul(value, NULL, 0); 1194 1195 done: 1196 /* Replace an unused or invalid entry */ 1197 for (j = 0; get_filter_client(j, &unused, &unused); j++); 1198 valid = set_filter_client(j, &start, &end); 1199 assert(valid); 1200 1201 fail: 1202 nvram_unset(name); 1203 } 1204 1205 nvram_unset("filter_port"); 1206} 1207#endif /* __CONFIG_NAT__ */ 1208 1209static void 1210convert_maclist(char *prefix) 1211{ 1212 char mac[1000], maclist[1000], macmode[1000]; 1213 char *value; 1214 1215 snprintf(mac, sizeof(mac), "%s_mac", prefix); 1216 snprintf(maclist, sizeof(maclist), "%s_maclist", prefix); 1217 snprintf(macmode, sizeof(maclist), "%s_macmode", prefix); 1218 1219 if ((value = nvram_get(mac))) { 1220 nvram_set(maclist, value); 1221 /* An empty *_mac used to imply *_macmode=disabled */ 1222 if (!*value) 1223 nvram_set(macmode, "disabled"); 1224 nvram_unset(mac); 1225 } 1226} 1227 1228#ifdef __CONFIG_NAT__ 1229static void 1230convert_autofw_port(void) 1231{ 1232 char name[] = "autofw_portXXXXXXXXXX", value[1000]; 1233 char *out_proto, *out_start, *out_end, *in_proto, *in_start, *in_end, *to_start, *to_end; 1234 char *enable, *desc; 1235 netconf_app_t app; 1236 bool valid; 1237 int i; 1238 1239 /* Maximum number of autofw_port entries was 10 */ 1240 for (i = 0; i < 10; i++) { 1241 memset(&app, 0, sizeof(netconf_app_t)); 1242 1243 /* Parse out_proto:out_port,in_proto:in_start-in_end>to_start-to_end,enable,desc */ 1244 snprintf(name, sizeof(name), "autofw_port%d", i); 1245 if (!nvram_invmatch(name, "")) 1246 goto fail; 1247 strncpy(value, nvram_get(name), sizeof(value)); 1248 1249 /* Check for outbound port specification */ 1250 out_start = value; 1251 out_proto = strsep(&out_start, ":"); 1252 if (!out_start) 1253 goto fail; 1254 1255 /* Check for related protocol specification */ 1256 in_proto = out_start; 1257 out_start = strsep(&in_proto, ","); 1258 if (!in_proto) 1259 goto fail; 1260 1261 /* Check for related destination port specification */ 1262 in_start = in_proto; 1263 in_proto = strsep(&in_start, ":"); 1264 if (!in_start) 1265 goto fail; 1266 1267 /* Check for mapped destination port specification */ 1268 to_start = in_start; 1269 in_start = strsep(&to_start, ">"); 1270 if (!to_start) 1271 goto fail; 1272 1273 /* Check for enable specification */ 1274 enable = to_start; 1275 to_end = strsep(&enable, ","); 1276 if (!enable) 1277 goto fail; 1278 1279 /* Check for description specification (optional) */ 1280 desc = enable; 1281 enable = strsep(&desc, ","); 1282 1283 /* Check for outbound port range (new format) */ 1284 out_end = out_start; 1285 out_start = strsep(&out_end, "-"); 1286 if (!out_end) 1287 out_end = out_start; 1288 /* !new format already! */ 1289 else 1290 continue; 1291 1292 /* Check for related destination port range (optional) */ 1293 in_end = in_start; 1294 in_start = strsep(&in_end, "-"); 1295 if (!in_end) 1296 in_end = in_start; 1297 1298 /* Check for mapped destination port range (optional) */ 1299 to_end = to_start; 1300 to_start = strsep(&to_end, "-"); 1301 if (!to_end) 1302 to_end = to_start; 1303 1304 /* Parse outbound protocol */ 1305 if (!strncasecmp(out_proto, "tcp", 3)) 1306 app.match.ipproto = IPPROTO_TCP; 1307 else if (!strncasecmp(out_proto, "udp", 3)) 1308 app.match.ipproto = IPPROTO_UDP; 1309 else 1310 goto fail; 1311 1312 /* Parse outbound port */ 1313 app.match.dst.ports[0] = htons(atoi(out_start)); 1314 app.match.dst.ports[1] = htons(atoi(out_end)); 1315 1316 /* Parse related protocol */ 1317 if (!strncasecmp(in_proto, "tcp", 3)) 1318 app.proto = IPPROTO_TCP; 1319 else if (!strncasecmp(in_proto, "udp", 3)) 1320 app.proto = IPPROTO_UDP; 1321 else 1322 goto fail; 1323 1324 /* Parse related destination port range */ 1325 app.dport[0] = htons(atoi(in_start)); 1326 app.dport[1] = htons(atoi(in_end)); 1327 1328 /* Parse mapped destination port range */ 1329 app.to[0] = htons(atoi(to_start)); 1330 app.to[1] = htons(atoi(to_end)); 1331 1332 /* Parse enable */ 1333 if (!strncasecmp(enable, "off", 3)) 1334 app.match.flags = NETCONF_DISABLED; 1335 1336 /* Parse description */ 1337 if (desc) 1338 strncpy(app.desc, desc, sizeof(app.desc)); 1339 1340 /* Set interface name (match packets entering LAN interface) */ 1341 strncpy(app.match.in.name, nvram_safe_get("lan_ifname"), IFNAMSIZ); 1342 1343 /* Set LAN source port range (match packets from any source port) */ 1344 app.match.src.ports[1] = htons(0xffff); 1345 1346 /* Set target (application specific port forward) */ 1347 app.target = NETCONF_APP; 1348 1349 /* Replace an unused or invalid entry */ 1350 valid = set_autofw_port(i, &app); 1351 assert(valid); 1352 1353 /* Next filter */ 1354 continue; 1355 1356 fail: 1357 nvram_unset(name); 1358 } 1359} 1360 1361static void 1362convert_pppoe(void) 1363{ 1364 char *old[] = { 1365 "pppoe_ifname", /* PPPoE enslaved interface */ 1366 "pppoe_username", /* PPP username */ 1367 "pppoe_passwd", /* PPP password */ 1368 "pppoe_idletime", /* Dial on demand max idle time (seconds) */ 1369 "pppoe_keepalive", /* Restore link automatically */ 1370 "pppoe_demand", /* Dial on demand */ 1371 "pppoe_mru", /* Negotiate MRU to this value */ 1372 "pppoe_mtu", /* Negotiate MTU to the smaller of this value or the peer MRU */ 1373 "pppoe_service", /* PPPoE service name */ 1374 "pppoe_ac", /* PPPoE access concentrator name */ 1375 NULL 1376 }; 1377 char new[] = "wan_pppoe_XXXXXXXXXXXXXXXXXX"; 1378 char *value; 1379 int i; 1380 for (i = 0; old[i] != NULL; i ++) { 1381 if ((value = nvram_get(old[i]))) { 1382 snprintf(new, sizeof(new), "wan_%s", old[i]); 1383 nvram_set(new, value); 1384 nvram_unset(old[i]); 1385 } 1386 } 1387} 1388#endif /* __CONFIG_NAT__ */ 1389 1390static void 1391convert_static_route(void) 1392{ 1393 char word[80], *next; 1394 char *ipaddr, *netmask, *gateway, *metric, *ifname; 1395 char lan_route[1000] = ""; 1396 char *lan_cur = lan_route; 1397#ifdef __CONFIG_NAT__ 1398 char wan_route[1000] = ""; 1399 char *wan_cur = wan_route; 1400#endif /* __CONFIG_NAT__ */ 1401 1402 foreach(word, nvram_safe_get("static_route"), next) { 1403 netmask = word; 1404 ipaddr = strsep(&netmask, ":"); 1405 if (!ipaddr || !netmask) 1406 continue; 1407 gateway = netmask; 1408 netmask = strsep(&gateway, ":"); 1409 if (!netmask || !gateway) 1410 continue; 1411 metric = gateway; 1412 gateway = strsep(&metric, ":"); 1413 if (!gateway || !metric) 1414 continue; 1415 ifname = metric; 1416 metric = strsep(&ifname, ":"); 1417 if (!metric || !ifname) 1418 continue; 1419 1420 if (strcmp(ifname, "lan") == 0) { 1421 lan_cur += snprintf(lan_cur, lan_route + sizeof(lan_route) - lan_cur, 1422 "%s%s:%s:%s:%s", 1423 lan_cur == lan_route ? "" : " ", ipaddr, netmask, 1424 gateway, metric); 1425 } 1426#ifdef __CONFIG_NAT__ 1427 else if (strcmp(ifname, "wan") == 0) { 1428 wan_cur += snprintf(wan_cur, wan_route + sizeof(wan_route) - wan_cur, 1429 "%s%s:%s:%s:%s", 1430 wan_cur == wan_route ? "" : " ", ipaddr, netmask, gateway, metric); 1431 } 1432#endif /* __CONFIG_NAT__ */ 1433 /* what to do? */ 1434 else {} 1435 } 1436 1437 if (lan_cur != lan_route) 1438 nvram_set("lan_route", lan_route); 1439 1440#ifdef __CONFIG_NAT__ 1441 if (wan_cur != wan_route) 1442 nvram_set("wan_route", wan_route); 1443#endif /* __CONFIG_NAT__ */ 1444 1445 nvram_unset("static_route"); 1446} 1447 1448/* 1449 * convert wl_wep - separate WEP encryption from WPA cryptos: 1450 * wep|on|restricted|off -> enabled|disabled 1451 * tkip|ase|tkip+aes -> wl_crypto 1452 * combine wl_auth_mode and wl_auth: 1453 * wl_auth 0|1 -> wl_auth_mode open|shared (when wl_auth_mode is disabled) 1454 */ 1455static void 1456convert_wsec(void) 1457{ 1458 char prefix[] = "wlXXXXXXXXXX_", tmp[64], *wep; 1459 int i; 1460 1461 for (i = 0; i < MAX_NVPARSE; i ++) { 1462 sprintf(prefix, "wl%d_", i); 1463 wep = nvram_get(strcat_r(prefix, "wep", tmp)); 1464 if (!wep) 1465 continue; 1466 /* 3.60.xx */ 1467 /* convert wep, restricted, or on to enabled */ 1468 if (!strcmp(wep, "wep") || !strcmp(wep, "restricted") || 1469 !strcmp(wep, "on")) 1470 nvram_set(strcat_r(prefix, "wep", tmp), "enabled"); 1471 /* split wep and wpa to wl_wep and wl_crypto */ 1472 else if (!strcmp(wep, "tkip") || !strcmp(wep, "aes") || 1473 !strcmp(wep, "tkip+aes")) { 1474 nvram_set(strcat_r(prefix, "crypto", tmp), wep); 1475 nvram_set(strcat_r(prefix, "wep", tmp), "disabled"); 1476 } 1477 /* treat everything else as disabled */ 1478 else if (strcmp(wep, "enabled")) 1479 nvram_set(strcat_r(prefix, "wep", tmp), "disabled"); 1480 /* combine 802.11 open/shared authentication mode with WPA to wl_auth_mode */ 1481 if (nvram_match(strcat_r(prefix, "auth_mode", tmp), "disabled")) { 1482 if (nvram_match(strcat_r(prefix, "auth", tmp), "1")) 1483 nvram_set(strcat_r(prefix, "auth_mode", tmp), "shared"); 1484 else 1485 nvram_set(strcat_r(prefix, "auth_mode", tmp), "open"); 1486 } 1487 /* 3.80.xx 1488 * 1489 * check only if the wl_auth_mode is set to "shared" 1490 * wl_auth_carries a default value of "0" 1491 */ 1492 /* split 802.11 auth from wl_auth_mode */ 1493 if (nvram_match(strcat_r(prefix, "auth_mode", tmp), "shared")) 1494 nvram_set(strcat_r(prefix, "auth", tmp), "1"); 1495 /* split wpa akm from wl_auth_mode */ 1496 if (nvram_match(strcat_r(prefix, "auth_mode", tmp), "wpa")) 1497 nvram_set(strcat_r(prefix, "akm", tmp), "wpa"); 1498 else if (nvram_match(strcat_r(prefix, "auth_mode", tmp), "psk")) 1499 nvram_set(strcat_r(prefix, "akm", tmp), "psk"); 1500 /* preserve radius only in wl_auth_mode */ 1501 if (nvram_invmatch(strcat_r(prefix, "auth_mode", tmp), "radius")) 1502 nvram_set(strcat_r(prefix, "auth_mode", tmp), "none"); 1503 } 1504} 1505 1506void 1507convert_deprecated(void) 1508{ 1509#ifdef __CONFIG_NAT__ 1510 /* forward_tcp and forward_udp were space separated lists of port forwards */ 1511 convert_forward_proto("forward_tcp", IPPROTO_TCP); 1512 convert_forward_proto("forward_udp", IPPROTO_UDP); 1513 1514 /* filter_ip was a space separated list of IP address ranges */ 1515 convert_filter_ip(); 1516 1517 /* filter_tcp and filter_udp were space separated lists of IP address and TCP port ranges */ 1518 convert_filter_proto("filter_tcp", IPPROTO_TCP); 1519 convert_filter_proto("filter_udp", IPPROTO_UDP); 1520 1521 /* filter_port was a short-lived implementation of filter_client */ 1522 convert_filter_port(); 1523#endif /* __CONFIG_NAT__ */ 1524 1525 convert_maclist("filter"); 1526 convert_maclist("wl"); 1527 1528#ifdef __CONFIG_NAT__ 1529 /* pppoe_ifname used to save the underlying WAN interface name */ 1530 if (nvram_invmatch("pppoe_ifname", "") && nvram_match("wan_proto", "pppoe")) 1531 nvram_set("wan_ifname", nvram_get("pppoe_ifname")); 1532 nvram_unset("pppoe_ifname"); 1533 1534 /* autofw_port were single destination port and now support a port range */ 1535 convert_autofw_port(); 1536 1537 /* pppoe_XXXXXXXX are now wan_pppoe_XXXXXXXX */ 1538 convert_pppoe(); 1539#endif /* __CONFIG_NAT__ */ 1540 1541 /* static_route used to save routes for LAN and WAN and is now between lan_route and 1542 * wan_route 1543 */ 1544 /* convert_static_route(); */ 1545 1546 /* convert wl_wep and combine wl_auth_mode and wl_auth */ 1547 convert_wsec(); 1548} 1549