1 /* 2 * Copyright (C) 2003 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 7 * Use is subject to license terms. 8 */ 9 10 #pragma ident "%Z%%M% %I% %E% SMI" 11 12 #include <sys/types.h> 13 #include <sys/time.h> 14 #include <sys/param.h> 15 #include <sys/socket.h> 16 #if defined(BSD) && (BSD >= 199306) 17 # include <sys/cdefs.h> 18 #endif 19 #include <sys/ioctl.h> 20 21 #include <net/if.h> 22 #if __FreeBSD_version >= 300000 23 # include <net/if_var.h> 24 #endif 25 #include <netinet/in.h> 26 27 #include <arpa/inet.h> 28 29 #include <stdio.h> 30 #include <fcntl.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <netdb.h> 34 #include <ctype.h> 35 #include <unistd.h> 36 37 #include "ipf.h" 38 #if SOLARIS2 >= 10 39 #include "ip_lookup.h" 40 #include "ip_pool.h" 41 #include "ip_htable.h" 42 #else 43 #include "netinet/ip_lookup.h" 44 #include "netinet/ip_pool.h" 45 #include "netinet/ip_htable.h" 46 #endif 47 #include "kmem.h" 48 49 50 extern int ippool_yyparse __P((void)); 51 extern int ippool_yydebug; 52 extern FILE *ippool_yyin; 53 extern char *optarg; 54 extern int lineNum; 55 56 void showpools __P((ip_pool_stat_t *)); 57 void usage __P((char *)); 58 int main __P((int, char **)); 59 int poolcommand __P((int, int, char *[])); 60 int poolnodecommand __P((int, int, char *[])); 61 int loadpoolfile __P((int, char *[], char *)); 62 int poollist __P((int, char *[])); 63 int poolflush __P((int, char *[])); 64 int poolstats __P((int, char *[])); 65 int gettype __P((char *, u_int *)); 66 int getrole __P((char *)); 67 68 int opts = 0; 69 int fd = -1; 70 int use_inet6 = 0; 71 72 73 void usage(prog) 74 char *prog; 75 { 76 fprintf(stderr, "Usage:\t%s\n", prog); 77 fprintf(stderr, "\t\t\t-a [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n"); 78 fprintf(stderr, "\t\t\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n"); 79 fprintf(stderr, "\t\t\t-f <file> [-dnuv]\n"); 80 fprintf(stderr, "\t\t\t-F [-dv] [-o <role>] [-t <type>]\n"); 81 fprintf(stderr, "\t\t\t-l [-dv] [-m <name>] [-t <type>]\n"); 82 fprintf(stderr, "\t\t\t-r [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n"); 83 fprintf(stderr, "\t\t\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n"); 84 fprintf(stderr, "\t\t\t-s [-dtv] [-M <core>] [-N <namelist>]\n"); 85 exit(1); 86 } 87 88 89 int main(argc, argv) 90 int argc; 91 char *argv[]; 92 { 93 int err; 94 95 if (argc < 2) 96 usage(argv[0]); 97 98 switch (getopt(argc, argv, "aAf:FlrRs")) 99 { 100 case 'a' : 101 err = poolnodecommand(0, argc, argv); 102 break; 103 case 'A' : 104 err = poolcommand(0, argc, argv); 105 break; 106 case 'f' : 107 err = loadpoolfile(argc, argv, optarg); 108 break; 109 case 'F' : 110 err = poolflush(argc, argv); 111 break; 112 case 'l' : 113 err = poollist(argc, argv); 114 break; 115 case 'r' : 116 err = poolnodecommand(1, argc, argv); 117 break; 118 case 'R' : 119 err = poolcommand(1, argc, argv); 120 break; 121 case 's' : 122 err = poolstats(argc, argv); 123 break; 124 default : 125 exit(1); 126 } 127 128 return err; 129 } 130 131 132 int poolnodecommand(remove, argc, argv) 133 int remove, argc; 134 char *argv[]; 135 { 136 char *poolname = NULL, *s; 137 int err, c, ipset, role; 138 ip_pool_node_t node; 139 struct in_addr mask; 140 141 ipset = 0; 142 role = IPL_LOGIPF; 143 bzero((char *)&node, sizeof(node)); 144 145 while ((c = getopt(argc, argv, "di:m:no:v")) != -1) 146 switch (c) 147 { 148 case 'd' : 149 opts |= OPT_DEBUG; 150 ippool_yydebug++; 151 break; 152 case 'i' : 153 s = strchr(optarg, '/'); 154 if (s == NULL) 155 mask.s_addr = 0xffffffff; 156 else if (strchr(s, '.') == NULL) { 157 if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0) 158 return -1; 159 } else { 160 mask.s_addr = inet_addr(s + 1); 161 } 162 if (s != NULL) 163 *s = '\0'; 164 ipset = 1; 165 node.ipn_addr.adf_addr.in4.s_addr = inet_addr(optarg); 166 node.ipn_mask.adf_addr.in4.s_addr = mask.s_addr; 167 break; 168 case 'm' : 169 poolname = optarg; 170 break; 171 case 'n' : 172 opts |= OPT_DONOTHING; 173 break; 174 case 'o' : 175 role = getrole(optarg); 176 if (role == IPL_LOGNONE) 177 return -1; 178 break; 179 case 'v' : 180 opts |= OPT_VERBOSE; 181 break; 182 } 183 184 if (ipset == 0) 185 return -1; 186 if (poolname == NULL) { 187 fprintf(stderr, "poolname not given with add/remove node\n"); 188 return -1; 189 } 190 191 if (remove == 0) 192 err = load_poolnode(0, poolname, &node, ioctl); 193 else 194 err = remove_poolnode(0, poolname, &node, ioctl); 195 return err; 196 } 197 198 199 int poolcommand(remove, argc, argv) 200 int remove, argc; 201 char *argv[]; 202 { 203 int type, role, c, err; 204 char *poolname; 205 iphtable_t iph; 206 ip_pool_t pool; 207 208 err = 1; 209 role = 0; 210 type = 0; 211 poolname = NULL; 212 role = IPL_LOGIPF; 213 bzero((char *)&iph, sizeof(iph)); 214 bzero((char *)&pool, sizeof(pool)); 215 216 while ((c = getopt(argc, argv, "dm:no:S:t:v")) != -1) 217 switch (c) 218 { 219 case 'd' : 220 opts |= OPT_DEBUG; 221 ippool_yydebug++; 222 break; 223 case 'm' : 224 poolname = optarg; 225 break; 226 case 'n' : 227 opts |= OPT_DONOTHING; 228 break; 229 case 'o' : 230 role = getrole(optarg); 231 if (role == IPL_LOGNONE) { 232 fprintf(stderr, "unknown role '%s'\n", optarg); 233 return -1; 234 } 235 break; 236 case 'S' : 237 iph.iph_seed = atoi(optarg); 238 break; 239 case 't' : 240 type = gettype(optarg, &iph.iph_type); 241 if (type == IPLT_NONE) { 242 fprintf(stderr, "unknown type '%s'\n", optarg); 243 return -1; 244 } 245 break; 246 case 'v' : 247 opts |= OPT_VERBOSE; 248 break; 249 } 250 251 if (poolname == NULL) { 252 fprintf(stderr, "poolname not given with add/remove pool\n"); 253 return -1; 254 } 255 256 if (type == IPLT_HASH) { 257 strncpy(iph.iph_name, poolname, sizeof(iph.iph_name)); 258 iph.iph_name[sizeof(iph.iph_name) - 1] = '\0'; 259 iph.iph_unit = role; 260 } else if (type == IPLT_POOL) { 261 strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name)); 262 pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0'; 263 pool.ipo_unit = role; 264 } 265 266 if (remove == 0) { 267 switch (type) 268 { 269 case IPLT_HASH : 270 err = load_hash(&iph, NULL, ioctl); 271 break; 272 case IPLT_POOL : 273 err = load_pool(&pool, ioctl); 274 break; 275 } 276 } else { 277 switch (type) 278 { 279 case IPLT_HASH : 280 err = remove_hash(&iph, ioctl); 281 break; 282 case IPLT_POOL : 283 err = remove_pool(&pool, ioctl); 284 break; 285 } 286 } 287 return err; 288 } 289 290 291 int loadpoolfile(argc, argv, infile) 292 int argc; 293 char *argv[], *infile; 294 { 295 int c; 296 297 infile = optarg; 298 299 while ((c = getopt(argc, argv, "dnrv")) != -1) 300 switch (c) 301 { 302 case 'd' : 303 opts |= OPT_DEBUG; 304 ippool_yydebug++; 305 break; 306 case 'n' : 307 opts |= OPT_DONOTHING; 308 break; 309 case 'r' : 310 opts |= OPT_REMOVE; 311 break; 312 case 'v' : 313 opts |= OPT_VERBOSE; 314 break; 315 } 316 317 if (!(opts & OPT_DONOTHING) && (fd == -1)) { 318 fd = open(IPLOOKUP_NAME, O_RDWR); 319 if (fd == -1) { 320 perror("open(IPLOOKUP_NAME)"); 321 exit(1); 322 } 323 } 324 325 if (ippool_parsefile(fd, infile, ioctl) != 0) 326 return -1; 327 return 0; 328 } 329 330 331 int poollist(argc, argv) 332 int argc; 333 char *argv[]; 334 { 335 char *kernel, *core, *poolname; 336 int c, role, type, live_kernel; 337 ip_pool_stat_t *plstp, plstat; 338 iphtstat_t *htstp, htstat; 339 iphtable_t *hptr; 340 iplookupop_t op; 341 ip_pool_t *ptr; 342 343 core = NULL; 344 kernel = NULL; 345 live_kernel = 1; 346 type = IPLT_ALL; 347 poolname = NULL; 348 role = IPL_LOGALL; 349 350 while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1) 351 switch (c) 352 { 353 case 'd' : 354 opts |= OPT_DEBUG; 355 break; 356 case 'm' : 357 poolname = optarg; 358 break; 359 case 'M' : 360 live_kernel = 0; 361 core = optarg; 362 break; 363 case 'N' : 364 live_kernel = 0; 365 kernel = optarg; 366 break; 367 case 'o' : 368 role = getrole(optarg); 369 if (role == IPL_LOGNONE) { 370 fprintf(stderr, "unknown role '%s'\n", optarg); 371 return -1; 372 } 373 break; 374 case 't' : 375 type = gettype(optarg, NULL); 376 if (type == IPLT_NONE) { 377 fprintf(stderr, "unknown type '%s'\n", optarg); 378 return -1; 379 } 380 break; 381 case 'v' : 382 opts |= OPT_VERBOSE; 383 break; 384 } 385 386 if (opts & OPT_DEBUG) 387 fprintf(stderr, "poollist: opts = %#x\n", opts); 388 389 if (!(opts & OPT_DONOTHING) && (fd == -1)) { 390 fd = open(IPLOOKUP_NAME, O_RDWR); 391 if (fd == -1) { 392 perror("open(IPLOOKUP_NAME)"); 393 exit(1); 394 } 395 } 396 397 bzero((char *)&op, sizeof(op)); 398 if (poolname != NULL) { 399 strncpy(op.iplo_name, poolname, sizeof(op.iplo_name)); 400 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 401 } 402 op.iplo_unit = role; 403 404 if (openkmem(kernel, core) == -1) 405 exit(-1); 406 407 if (type == IPLT_ALL || type == IPLT_POOL) { 408 plstp = &plstat; 409 op.iplo_type = IPLT_POOL; 410 op.iplo_size = sizeof(plstat); 411 op.iplo_struct = &plstat; 412 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 413 if (c == -1) { 414 perror("ioctl(SIOCLOOKUPSTAT)"); 415 return -1; 416 } 417 418 if (role != IPL_LOGALL) { 419 ptr = plstp->ipls_list[role]; 420 while (ptr != NULL) { 421 ptr = printpool(ptr, kmemcpywrap, opts); 422 } 423 } else { 424 for (role = 0; role <= IPL_LOGMAX; role++) { 425 ptr = plstp->ipls_list[role]; 426 while (ptr != NULL) { 427 ptr = printpool(ptr, kmemcpywrap, 428 opts); 429 } 430 } 431 role = IPL_LOGALL; 432 } 433 } 434 if (type == IPLT_ALL || type == IPLT_HASH) { 435 htstp = &htstat; 436 op.iplo_type = IPLT_HASH; 437 op.iplo_size = sizeof(htstat); 438 op.iplo_struct = &htstat; 439 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 440 if (c == -1) { 441 perror("ioctl(SIOCLOOKUPSTAT)"); 442 return -1; 443 } 444 445 if (role != IPL_LOGALL) { 446 hptr = htstp->iphs_tables; 447 while (hptr != NULL) { 448 hptr = printhash(hptr, kmemcpywrap, opts); 449 } 450 } else { 451 for (role = 0; role <= IPL_LOGMAX; role++) { 452 hptr = htstp->iphs_tables; 453 while (hptr != NULL) { 454 hptr = printhash(hptr, kmemcpywrap, 455 opts); 456 } 457 458 op.iplo_unit = role; 459 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 460 if (c == -1) { 461 perror("ioctl(SIOCLOOKUPSTAT)"); 462 return -1; 463 } 464 } 465 } 466 } 467 return 0; 468 } 469 470 471 int poolstats(argc, argv) 472 int argc; 473 char *argv[]; 474 { 475 int c, type, role, live_kernel; 476 ip_pool_stat_t plstat; 477 char *kernel, *core; 478 iphtstat_t htstat; 479 iplookupop_t op; 480 481 core = NULL; 482 kernel = NULL; 483 live_kernel = 1; 484 type = IPLT_ALL; 485 role = IPL_LOGALL; 486 487 bzero((char *)&op, sizeof(op)); 488 489 while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1) 490 switch (c) 491 { 492 case 'd' : 493 opts |= OPT_DEBUG; 494 break; 495 case 'M' : 496 live_kernel = 0; 497 core = optarg; 498 break; 499 case 'N' : 500 live_kernel = 0; 501 kernel = optarg; 502 break; 503 case 'o' : 504 role = getrole(optarg); 505 if (role == IPL_LOGNONE) { 506 fprintf(stderr, "unknown role '%s'\n", optarg); 507 return -1; 508 } 509 break; 510 case 't' : 511 type = gettype(optarg, NULL); 512 if (type != IPLT_POOL) { 513 fprintf(stderr, 514 "-s not supported for this type yet\n"); 515 return -1; 516 } 517 break; 518 case 'v' : 519 opts |= OPT_VERBOSE; 520 break; 521 } 522 523 if (opts & OPT_DEBUG) 524 fprintf(stderr, "poolstats: opts = %#x\n", opts); 525 526 if (!(opts & OPT_DONOTHING) && (fd == -1)) { 527 fd = open(IPLOOKUP_NAME, O_RDWR); 528 if (fd == -1) { 529 perror("open(IPLOOKUP_NAME)"); 530 exit(1); 531 } 532 } 533 534 if (type == IPLT_ALL || type == IPLT_POOL) { 535 op.iplo_type = IPLT_POOL; 536 op.iplo_struct = &plstat; 537 op.iplo_size = sizeof(plstat); 538 if (!(opts & OPT_DONOTHING)) { 539 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 540 if (c == -1) { 541 perror("ioctl(SIOCLOOKUPSTAT)"); 542 return -1; 543 } 544 printf("Pools:\t%lu\n", plstat.ipls_pools); 545 printf("Nodes:\t%lu\n", plstat.ipls_nodes); 546 } 547 } 548 549 if (type == IPLT_ALL || type == IPLT_HASH) { 550 op.iplo_type = IPLT_HASH; 551 op.iplo_struct = &htstat; 552 op.iplo_size = sizeof(htstat); 553 if (!(opts & OPT_DONOTHING)) { 554 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 555 if (c == -1) { 556 perror("ioctl(SIOCLOOKUPSTAT)"); 557 return -1; 558 } 559 printf("Hash Tables:\t%lu\n", htstat.iphs_numtables); 560 printf("Nodes:\t%lu\n", htstat.iphs_numnodes); 561 printf("Out of Memory:\t%lu\n", htstat.iphs_nomem); 562 } 563 } 564 return 0; 565 } 566 567 568 int poolflush(argc, argv) 569 int argc; 570 char *argv[]; 571 { 572 int c, role, type, arg; 573 iplookupflush_t flush; 574 575 arg = IPLT_ALL; 576 type = IPLT_ALL; 577 role = IPL_LOGALL; 578 579 while ((c = getopt(argc, argv, "do:t:v")) != -1) 580 switch (c) 581 { 582 case 'd' : 583 opts |= OPT_DEBUG; 584 break; 585 case 'o' : 586 role = getrole(optarg); 587 if (role == IPL_LOGNONE) { 588 fprintf(stderr, "unknown role '%s'\n", optarg); 589 return -1; 590 } 591 break; 592 case 't' : 593 type = gettype(optarg, NULL); 594 if (type == IPLT_NONE) { 595 fprintf(stderr, "unknown type '%s'\n", optarg); 596 return -1; 597 } 598 break; 599 case 'v' : 600 opts |= OPT_VERBOSE; 601 break; 602 } 603 604 if (!(opts & OPT_DONOTHING) && (fd == -1)) { 605 fd = open(IPLOOKUP_NAME, O_RDWR); 606 if (fd == -1) { 607 perror("open(IPLOOKUP_NAME)"); 608 exit(1); 609 } 610 } 611 612 bzero((char *)&flush, sizeof(flush)); 613 flush.iplf_type = type; 614 flush.iplf_unit = role; 615 flush.iplf_arg = arg; 616 617 if (!(opts & OPT_DONOTHING)) { 618 if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) { 619 perror("ioctl(SIOCLOOKUPFLUSH)"); 620 exit(1); 621 } 622 623 } 624 printf("%u object%s flushed\n", flush.iplf_count, 625 (flush.iplf_count == 1) ? "" : "s"); 626 627 return 0; 628 } 629 630 631 int getrole(rolename) 632 char *rolename; 633 { 634 int role; 635 636 if (!strcasecmp(rolename, "ipf")) { 637 role = IPL_LOGIPF; 638 #if 0 639 } else if (!strcasecmp(rolename, "nat")) { 640 role = IPL_LOGNAT; 641 } else if (!strcasecmp(rolename, "state")) { 642 role = IPL_LOGSTATE; 643 } else if (!strcasecmp(rolename, "auth")) { 644 role = IPL_LOGAUTH; 645 } else if (!strcasecmp(rolename, "sync")) { 646 role = IPL_LOGSYNC; 647 } else if (!strcasecmp(rolename, "scan")) { 648 role = IPL_LOGSCAN; 649 } else if (!strcasecmp(rolename, "pool")) { 650 role = IPL_LOGLOOKUP; 651 } else if (!strcasecmp(rolename, "count")) { 652 role = IPL_LOGCOUNT; 653 #endif 654 } else { 655 role = IPL_LOGNONE; 656 } 657 658 return role; 659 } 660 661 662 int gettype(typename, minor) 663 char *typename; 664 u_int *minor; 665 { 666 int type; 667 668 if (!strcasecmp(optarg, "pool")) { 669 type = IPLT_POOL; 670 } else if (!strcasecmp(optarg, "hash")) { 671 type = IPLT_HASH; 672 if (minor != NULL) 673 *minor = IPHASH_LOOKUP; 674 } else if (!strcasecmp(optarg, "group-map")) { 675 type = IPLT_HASH; 676 if (minor != NULL) 677 *minor = IPHASH_GROUPMAP; 678 } else { 679 type = IPLT_NONE; 680 } 681 return type; 682 } 683