1 /* 2 * Copyright (C) 2003 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 * Copyright 2004 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 iplookupop_t op; 339 ip_pool_t *ptr; 340 341 core = NULL; 342 kernel = NULL; 343 live_kernel = 1; 344 type = IPLT_ALL; 345 poolname = NULL; 346 role = IPL_LOGALL; 347 348 while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1) 349 switch (c) 350 { 351 case 'd' : 352 opts |= OPT_DEBUG; 353 break; 354 case 'm' : 355 poolname = optarg; 356 break; 357 case 'M' : 358 live_kernel = 0; 359 core = optarg; 360 break; 361 case 'N' : 362 live_kernel = 0; 363 kernel = optarg; 364 break; 365 case 'o' : 366 role = getrole(optarg); 367 if (role == IPL_LOGNONE) { 368 fprintf(stderr, "unknown role '%s'\n", optarg); 369 return -1; 370 } 371 break; 372 case 't' : 373 type = gettype(optarg, NULL); 374 if (type == IPLT_NONE) { 375 fprintf(stderr, "unknown type '%s'\n", optarg); 376 return -1; 377 } 378 break; 379 case 'v' : 380 opts |= OPT_VERBOSE; 381 break; 382 } 383 384 if (!(opts & OPT_DONOTHING) && (fd == -1)) { 385 fd = open(IPLOOKUP_NAME, O_RDWR); 386 if (fd == -1) { 387 perror("open(IPLOOKUP_NAME)"); 388 exit(1); 389 } 390 } 391 392 bzero((char *)&op, sizeof(op)); 393 if (poolname != NULL) { 394 strncpy(op.iplo_name, poolname, sizeof(op.iplo_name)); 395 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 396 } 397 op.iplo_type = type; 398 op.iplo_unit = role; 399 op.iplo_size = sizeof(plstat); 400 op.iplo_struct = &plstat; 401 plstp = &plstat; 402 403 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 404 if (c == -1) { 405 perror("ioctl(SIOCLOOKUPSTAT)"); 406 return -1; 407 } 408 409 if (openkmem(kernel, core) == -1) 410 exit(-1); 411 412 if (role != IPL_LOGALL) { 413 ptr = plstp->ipls_list[role]; 414 while (ptr != NULL) { 415 ptr = printpool(ptr, kmemcpywrap, opts); 416 } 417 } else { 418 for (role = 0; role <= IPL_LOGMAX; role++) { 419 ptr = plstp->ipls_list[role]; 420 while (ptr != NULL) { 421 ptr = printpool(ptr, kmemcpywrap, opts); 422 } 423 } 424 } 425 return 0; 426 } 427 428 429 int poolstats(argc, argv) 430 int argc; 431 char *argv[]; 432 { 433 int c, type, role, live_kernel; 434 ip_pool_stat_t plstat; 435 char *kernel, *core; 436 iplookupop_t op; 437 438 core = NULL; 439 kernel = NULL; 440 live_kernel = 1; 441 type = IPLT_ALL; 442 role = IPL_LOGALL; 443 444 bzero((char *)&op, sizeof(op)); 445 op.iplo_struct = &plstat; 446 op.iplo_size = sizeof(plstat); 447 448 while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1) 449 switch (c) 450 { 451 case 'd' : 452 opts |= OPT_DEBUG; 453 break; 454 case 'M' : 455 live_kernel = 0; 456 core = optarg; 457 break; 458 case 'N' : 459 live_kernel = 0; 460 kernel = optarg; 461 break; 462 case 'o' : 463 role = getrole(optarg); 464 if (role == IPL_LOGNONE) { 465 fprintf(stderr, "unknown role '%s'\n", optarg); 466 return -1; 467 } 468 break; 469 case 't' : 470 type = gettype(optarg, NULL); 471 if (type != IPLT_POOL) { 472 fprintf(stderr, 473 "-s not supported for this type yet\n"); 474 return -1; 475 } 476 break; 477 case 'v' : 478 opts |= OPT_VERBOSE; 479 break; 480 } 481 482 if (!(opts & OPT_DONOTHING) && (fd == -1)) { 483 fd = open(IPLOOKUP_NAME, O_RDWR); 484 if (fd == -1) { 485 perror("open(IPLOOKUP_NAME)"); 486 exit(1); 487 } 488 } 489 490 if (!(opts & OPT_DONOTHING)) { 491 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 492 if (c == -1) { 493 perror("ioctl(SIOCLOOKUPSTAT)"); 494 return -1; 495 } 496 printf("Pools:\t%lu\n", plstat.ipls_pools); 497 printf("Hash Tables:\t%lu\n", plstat.ipls_tables); 498 printf("Nodes:\t%lu\n", plstat.ipls_nodes); 499 } 500 return 0; 501 } 502 503 504 int poolflush(argc, argv) 505 int argc; 506 char *argv[]; 507 { 508 int c, role, type, arg; 509 iplookupflush_t flush; 510 511 arg = IPLT_ALL; 512 type = IPLT_ALL; 513 role = IPL_LOGALL; 514 515 while ((c = getopt(argc, argv, "do:t:v")) != -1) 516 switch (c) 517 { 518 case 'd' : 519 opts |= OPT_DEBUG; 520 break; 521 case 'o' : 522 role = getrole(optarg); 523 if (role == IPL_LOGNONE) { 524 fprintf(stderr, "unknown role '%s'\n", optarg); 525 return -1; 526 } 527 break; 528 case 't' : 529 type = gettype(optarg, NULL); 530 if (type == IPLT_NONE) { 531 fprintf(stderr, "unknown type '%s'\n", optarg); 532 return -1; 533 } 534 break; 535 case 'v' : 536 opts |= OPT_VERBOSE; 537 break; 538 } 539 540 if (!(opts & OPT_DONOTHING) && (fd == -1)) { 541 fd = open(IPLOOKUP_NAME, O_RDWR); 542 if (fd == -1) { 543 perror("open(IPLOOKUP_NAME)"); 544 exit(1); 545 } 546 } 547 548 bzero((char *)&flush, sizeof(flush)); 549 flush.iplf_type = type; 550 flush.iplf_unit = role; 551 flush.iplf_arg = arg; 552 553 if (!(opts & OPT_DONOTHING)) { 554 if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) { 555 perror("ioctl(SIOCLOOKUPFLUSH)"); 556 exit(1); 557 } 558 559 } 560 printf("%u object%s flushed\n", flush.iplf_count, 561 (flush.iplf_count == 1) ? "" : "s"); 562 563 return 0; 564 } 565 566 567 int getrole(rolename) 568 char *rolename; 569 { 570 int role; 571 572 if (!strcasecmp(rolename, "ipf")) { 573 role = IPL_LOGIPF; 574 #if 0 575 } else if (!strcasecmp(rolename, "nat")) { 576 role = IPL_LOGNAT; 577 } else if (!strcasecmp(rolename, "state")) { 578 role = IPL_LOGSTATE; 579 } else if (!strcasecmp(rolename, "auth")) { 580 role = IPL_LOGAUTH; 581 } else if (!strcasecmp(rolename, "sync")) { 582 role = IPL_LOGSYNC; 583 } else if (!strcasecmp(rolename, "scan")) { 584 role = IPL_LOGSCAN; 585 } else if (!strcasecmp(rolename, "pool")) { 586 role = IPL_LOGLOOKUP; 587 } else if (!strcasecmp(rolename, "count")) { 588 role = IPL_LOGCOUNT; 589 #endif 590 } else { 591 role = IPL_LOGNONE; 592 } 593 594 return role; 595 } 596 597 598 int gettype(typename, minor) 599 char *typename; 600 u_int *minor; 601 { 602 int type; 603 604 if (!strcasecmp(optarg, "pool")) { 605 type = IPLT_POOL; 606 } else if (!strcasecmp(optarg, "hash")) { 607 type = IPLT_HASH; 608 if (minor != NULL) 609 *minor = IPHASH_LOOKUP; 610 } else if (!strcasecmp(optarg, "group-map")) { 611 type = IPLT_HASH; 612 if (minor != NULL) 613 *minor = IPHASH_GROUPMAP; 614 } else { 615 type = IPLT_NONE; 616 } 617 return type; 618 } 619