1 /* $NetBSD: ippool.c,v 1.4 2013/10/20 03:09:11 christos Exp $ */
2
3 /*
4 * Copyright (C) 2012 by Darren Reed.
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8 #include <sys/types.h>
9 #include <sys/time.h>
10 #include <sys/param.h>
11 #include <sys/socket.h>
12 #if defined(BSD) && (BSD >= 199306)
13 # include <sys/cdefs.h>
14 #endif
15 #include <sys/ioctl.h>
16
17 #include <net/if.h>
18 #if __FreeBSD_version >= 300000
19 # include <net/if_var.h>
20 #endif
21 #include <netinet/in.h>
22
23 #include <arpa/inet.h>
24
25 #include <stdio.h>
26 #include <fcntl.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <netdb.h>
30 #include <ctype.h>
31 #include <unistd.h>
32 #ifdef linux
33 # include <linux/a.out.h>
34 #else
35 # include <nlist.h>
36 #endif
37
38 #include "ipf.h"
39 #include "netinet/ipl.h"
40 #include "netinet/ip_lookup.h"
41 #include "netinet/ip_pool.h"
42 #include "netinet/ip_htable.h"
43 #include "kmem.h"
44
45
46 extern int ippool_yyparse __P((void));
47 extern int ippool_yydebug;
48 extern FILE *ippool_yyin;
49 extern char *optarg;
50 extern int lineNum;
51
52 void usage __P((char *));
53 int main __P((int, char **));
54 int poolcommand __P((int, int, char *[]));
55 int poolnodecommand __P((int, int, char *[]));
56 int loadpoolfile __P((int, char *[], char *));
57 int poollist __P((int, char *[]));
58 void poollist_dead __P((int, char *, int, char *, char *));
59 void poollist_live __P((int, char *, int, int));
60 int poolflush __P((int, char *[]));
61 int poolstats __P((int, char *[]));
62 int gettype __P((char *, u_int *));
63 int getrole __P((char *));
64 int setnodeaddr __P((int, int, void *ptr, char *arg));
65 void showpools_live __P((int, int, ipf_pool_stat_t *, char *));
66 void showhashs_live __P((int, int, iphtstat_t *, char *));
67 void showdstls_live __P((int, int, ipf_dstl_stat_t *, char *));
68
69 int opts = 0;
70 int fd = -1;
71 int use_inet6 = 0;
72 wordtab_t *pool_fields = NULL;
73 int nohdrfields = 0;
74
75
76 void
usage(prog)77 usage(prog)
78 char *prog;
79 {
80 fprintf(stderr, "Usage:\t%s\n", prog);
81 fprintf(stderr, "\t-a [-dnv] [-m <name>] [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n");
82 fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
83 fprintf(stderr, "\t-f <file> [-dnuv]\n");
84 fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
85 fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>] [-O <fields>]\n");
86 fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n");
87 fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
88 fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
89 exit(1);
90 }
91
92
93 int
main(argc,argv)94 main(argc, argv)
95 int argc;
96 char *argv[];
97 {
98 int err = 1;
99
100 if (argc < 2)
101 usage(argv[0]);
102
103 assigndefined(getenv("IPPOOL_PREDEFINED"));
104
105 switch (getopt(argc, argv, "aAf:FlnrRsv"))
106 {
107 case 'a' :
108 err = poolnodecommand(0, argc, argv);
109 break;
110 case 'A' :
111 err = poolcommand(0, argc, argv);
112 break;
113 case 'f' :
114 err = loadpoolfile(argc, argv, optarg);
115 break;
116 case 'F' :
117 err = poolflush(argc, argv);
118 break;
119 case 'l' :
120 err = poollist(argc, argv);
121 break;
122 case 'n' :
123 opts |= OPT_DONOTHING|OPT_DONTOPEN;
124 break;
125 case 'r' :
126 err = poolnodecommand(1, argc, argv);
127 break;
128 case 'R' :
129 err = poolcommand(1, argc, argv);
130 break;
131 case 's' :
132 err = poolstats(argc, argv);
133 break;
134 case 'v' :
135 opts |= OPT_VERBOSE;
136 break;
137 default :
138 exit(1);
139 }
140
141 if (err != 0)
142 exit(1);
143 return 0;
144 }
145
146
147 int
poolnodecommand(remove,argc,argv)148 poolnodecommand(remove, argc, argv)
149 int remove, argc;
150 char *argv[];
151 {
152 int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
153 char *poolname = NULL;
154 ip_pool_node_t pnode;
155 iphtent_t hnode;
156 void *ptr = &pnode;
157
158 ipset = 0;
159 role = IPL_LOGIPF;
160 bzero((char *)&pnode, sizeof(pnode));
161 bzero((char *)&hnode, sizeof(hnode));
162
163 while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1)
164 switch (c)
165 {
166 case 'd' :
167 opts |= OPT_DEBUG;
168 ippool_yydebug++;
169 break;
170 case 'i' :
171 if (setnodeaddr(type, role, ptr, optarg) == 0)
172 ipset = 1;
173 break;
174 case 'm' :
175 poolname = optarg;
176 break;
177 case 'n' :
178 opts |= OPT_DONOTHING|OPT_DONTOPEN;
179 break;
180 case 'o' :
181 if (ipset == 1) {
182 fprintf(stderr,
183 "cannot set role after ip address\n");
184 return -1;
185 }
186 role = getrole(optarg);
187 if (role == IPL_LOGNONE)
188 return -1;
189 break;
190 case 'R' :
191 opts |= OPT_NORESOLVE;
192 break;
193 case 't' :
194 if (ipset == 1) {
195 fprintf(stderr,
196 "cannot set type after ip address\n");
197 return -1;
198 }
199 type = gettype(optarg, NULL);
200 switch (type) {
201 case IPLT_NONE :
202 fprintf(stderr, "unknown type '%s'\n", optarg);
203 return -1;
204 case IPLT_HASH :
205 ptr = &hnode;
206 break;
207 case IPLT_POOL :
208 default :
209 break;
210 }
211 break;
212 case 'T' :
213 ttl = atoi(optarg);
214 if (ttl < 0) {
215 fprintf(stderr, "cannot set negative ttl\n");
216 return -1;
217 }
218 break;
219 case 'v' :
220 opts |= OPT_VERBOSE;
221 break;
222 }
223
224 if (argv[optind] != NULL && ipset == 0) {
225 if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
226 ipset = 1;
227 }
228
229 if (opts & OPT_DEBUG)
230 fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
231
232 if (ipset == 0) {
233 fprintf(stderr, "no IP address given with -i\n");
234 return -1;
235 }
236
237 if (poolname == NULL) {
238 fprintf(stderr, "poolname not given with add/remove node\n");
239 return -1;
240 }
241
242 switch (type) {
243 case IPLT_POOL :
244 if (remove == 0)
245 err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
246 else
247 err = remove_poolnode(role, poolname, &pnode, ioctl);
248 break;
249 case IPLT_HASH :
250 if (remove == 0)
251 err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
252 else
253 err = remove_hashnode(role, poolname, &hnode, ioctl);
254 break;
255 default :
256 break;
257 }
258 return err;
259 }
260
261
262 int
poolcommand(remove,argc,argv)263 poolcommand(remove, argc, argv)
264 int remove, argc;
265 char *argv[];
266 {
267 int type, role, c, err;
268 char *poolname;
269 iphtable_t iph;
270 ip_pool_t pool;
271
272 err = 1;
273 role = 0;
274 type = 0;
275 poolname = NULL;
276 role = IPL_LOGIPF;
277 bzero((char *)&iph, sizeof(iph));
278 bzero((char *)&pool, sizeof(pool));
279
280 while ((c = getopt(argc, argv, "dm:no:RSv")) != -1)
281 switch (c)
282 {
283 case 'd' :
284 opts |= OPT_DEBUG;
285 ippool_yydebug++;
286 break;
287 case 'm' :
288 poolname = optarg;
289 break;
290 case 'n' :
291 opts |= OPT_DONOTHING|OPT_DONTOPEN;
292 break;
293 case 'o' :
294 role = getrole(optarg);
295 if (role == IPL_LOGNONE) {
296 fprintf(stderr, "unknown role '%s'\n", optarg);
297 return -1;
298 }
299 break;
300 case 'R' :
301 opts |= OPT_NORESOLVE;
302 break;
303 case 'S' :
304 iph.iph_seed = atoi(optarg);
305 break;
306 case 'v' :
307 opts |= OPT_VERBOSE;
308 break;
309 }
310
311 if (opts & OPT_DEBUG)
312 fprintf(stderr, "poolcommand: opts = %#x\n", opts);
313
314 if (poolname == NULL) {
315 fprintf(stderr, "poolname not given with add/remove pool\n");
316 return -1;
317 }
318
319 type = gettype(argv[optind], &iph.iph_type);
320 if (type == IPLT_NONE) {
321 fprintf(stderr, "unknown type '%s'\n", argv[optind]);
322 return -1;
323 }
324
325 if (type == IPLT_HASH) {
326 strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
327 iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
328 iph.iph_unit = role;
329 } else if (type == IPLT_POOL) {
330 strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
331 pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
332 pool.ipo_unit = role;
333 }
334
335 if (remove == 0) {
336 switch (type)
337 {
338 case IPLT_HASH :
339 err = load_hash(&iph, NULL, ioctl);
340 break;
341 case IPLT_POOL :
342 err = load_pool(&pool, ioctl);
343 break;
344 }
345 } else {
346 switch (type)
347 {
348 case IPLT_HASH :
349 err = remove_hash(&iph, ioctl);
350 break;
351 case IPLT_POOL :
352 err = remove_pool(&pool, ioctl);
353 break;
354 }
355 }
356 return err;
357 }
358
359
360 int
loadpoolfile(argc,argv,infile)361 loadpoolfile(argc, argv, infile)
362 int argc;
363 char *argv[], *infile;
364 {
365 int c;
366
367 infile = optarg;
368
369 while ((c = getopt(argc, argv, "dnRuv")) != -1)
370 switch (c)
371 {
372 case 'd' :
373 opts |= OPT_DEBUG;
374 ippool_yydebug++;
375 break;
376 case 'n' :
377 opts |= OPT_DONOTHING|OPT_DONTOPEN;
378 break;
379 case 'R' :
380 opts |= OPT_NORESOLVE;
381 break;
382 case 'u' :
383 opts |= OPT_REMOVE;
384 break;
385 case 'v' :
386 opts |= OPT_VERBOSE;
387 break;
388 }
389
390 if (opts & OPT_DEBUG)
391 fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
392
393 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
394 fd = open(IPLOOKUP_NAME, O_RDWR);
395 if (fd == -1) {
396 perror("open(IPLOOKUP_NAME)");
397 exit(1);
398 }
399 }
400
401 if (ippool_parsefile(fd, infile, ioctl) != 0)
402 return -1;
403 return 0;
404 }
405
406
407 int
poolstats(argc,argv)408 poolstats(argc, argv)
409 int argc;
410 char *argv[];
411 {
412 int c, type, role;
413 ipf_pool_stat_t plstat;
414 ipf_dstl_stat_t dlstat;
415 iphtstat_t htstat;
416 iplookupop_t op;
417
418 type = IPLT_ALL;
419 role = IPL_LOGALL;
420
421 bzero((char *)&op, sizeof(op));
422
423 while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
424 switch (c)
425 {
426 case 'd' :
427 opts |= OPT_DEBUG;
428 break;
429 case 'M' :
430 break;
431 case 'N' :
432 break;
433 case 'o' :
434 role = getrole(optarg);
435 if (role == IPL_LOGNONE) {
436 fprintf(stderr, "unknown role '%s'\n", optarg);
437 return -1;
438 }
439 break;
440 case 't' :
441 type = gettype(optarg, NULL);
442 if (type != IPLT_POOL) {
443 fprintf(stderr,
444 "-s not supported for this type yet\n");
445 return -1;
446 }
447 break;
448 case 'v' :
449 opts |= OPT_VERBOSE;
450 break;
451 }
452
453 if (opts & OPT_DEBUG)
454 fprintf(stderr, "poolstats: opts = %#x\n", opts);
455
456 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
457 fd = open(IPLOOKUP_NAME, O_RDWR);
458 if (fd == -1) {
459 perror("open(IPLOOKUP_NAME)");
460 exit(1);
461 }
462 }
463
464 if (type == IPLT_ALL || type == IPLT_POOL) {
465 op.iplo_type = IPLT_POOL;
466 op.iplo_struct = &plstat;
467 op.iplo_size = sizeof(plstat);
468 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
469 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
470 if (c == -1) {
471 ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
472 return -1;
473 }
474 printf("%lu\taddress pools\n", plstat.ipls_pools);
475 printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
476 }
477 }
478
479 if (type == IPLT_ALL || type == IPLT_HASH) {
480 op.iplo_type = IPLT_HASH;
481 op.iplo_struct = &htstat;
482 op.iplo_size = sizeof(htstat);
483 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
484 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
485 if (c == -1) {
486 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
487 return -1;
488 }
489 printf("%lu\thash tables\n", htstat.iphs_numtables);
490 printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
491 printf("%lu\thash table no memory \n",
492 htstat.iphs_nomem);
493 }
494 }
495
496 if (type == IPLT_ALL || type == IPLT_DSTLIST) {
497 op.iplo_type = IPLT_DSTLIST;
498 op.iplo_struct = &dlstat;
499 op.iplo_size = sizeof(dlstat);
500 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
501 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
502 if (c == -1) {
503 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
504 return -1;
505 }
506 printf("%u\tdestination lists\n",
507 dlstat.ipls_numlists);
508 printf("%u\tdestination list nodes\n",
509 dlstat.ipls_numnodes);
510 printf("%lu\tdestination list no memory\n",
511 dlstat.ipls_nomem);
512 printf("%u\tdestination list zombies\n",
513 dlstat.ipls_numdereflists);
514 printf("%u\tdesetination list node zombies\n",
515 dlstat.ipls_numderefnodes);
516 }
517 }
518 return 0;
519 }
520
521
522 int
poolflush(argc,argv)523 poolflush(argc, argv)
524 int argc;
525 char *argv[];
526 {
527 int c, role, type, arg;
528 iplookupflush_t flush;
529
530 arg = IPLT_ALL;
531 type = IPLT_ALL;
532 role = IPL_LOGALL;
533
534 while ((c = getopt(argc, argv, "do:t:v")) != -1)
535 switch (c)
536 {
537 case 'd' :
538 opts |= OPT_DEBUG;
539 break;
540 case 'o' :
541 role = getrole(optarg);
542 if (role == IPL_LOGNONE) {
543 fprintf(stderr, "unknown role '%s'\n", optarg);
544 return -1;
545 }
546 break;
547 case 't' :
548 type = gettype(optarg, NULL);
549 if (type == IPLT_NONE) {
550 fprintf(stderr, "unknown type '%s'\n", optarg);
551 return -1;
552 }
553 break;
554 case 'v' :
555 opts |= OPT_VERBOSE;
556 break;
557 }
558
559 if (opts & OPT_DEBUG)
560 fprintf(stderr, "poolflush: opts = %#x\n", opts);
561
562 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
563 fd = open(IPLOOKUP_NAME, O_RDWR);
564 if (fd == -1) {
565 perror("open(IPLOOKUP_NAME)");
566 exit(1);
567 }
568 }
569
570 bzero((char *)&flush, sizeof(flush));
571 flush.iplf_type = type;
572 flush.iplf_unit = role;
573 flush.iplf_arg = arg;
574
575 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
576 if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
577 ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
578 exit(1);
579 }
580
581 }
582 printf("%u object%s flushed\n", flush.iplf_count,
583 (flush.iplf_count == 1) ? "" : "s");
584
585 return 0;
586 }
587
588
589 int
getrole(rolename)590 getrole(rolename)
591 char *rolename;
592 {
593 int role;
594
595 if (!strcasecmp(rolename, "ipf")) {
596 role = IPL_LOGIPF;
597 #if 0
598 } else if (!strcasecmp(rolename, "nat")) {
599 role = IPL_LOGNAT;
600 } else if (!strcasecmp(rolename, "state")) {
601 role = IPL_LOGSTATE;
602 } else if (!strcasecmp(rolename, "auth")) {
603 role = IPL_LOGAUTH;
604 } else if (!strcasecmp(rolename, "sync")) {
605 role = IPL_LOGSYNC;
606 } else if (!strcasecmp(rolename, "scan")) {
607 role = IPL_LOGSCAN;
608 } else if (!strcasecmp(rolename, "pool")) {
609 role = IPL_LOGLOOKUP;
610 } else if (!strcasecmp(rolename, "count")) {
611 role = IPL_LOGCOUNT;
612 #endif
613 } else {
614 role = IPL_LOGNONE;
615 }
616
617 return role;
618 }
619
620
621 int
gettype(typename,minor)622 gettype(typename, minor)
623 char *typename;
624 u_int *minor;
625 {
626 int type;
627
628 if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
629 type = IPLT_POOL;
630 } else if (!strcasecmp(typename, "hash")) {
631 type = IPLT_HASH;
632 if (minor != NULL)
633 *minor = IPHASH_LOOKUP;
634 } else if (!strcasecmp(typename, "group-map")) {
635 type = IPLT_HASH;
636 if (minor != NULL)
637 *minor = IPHASH_GROUPMAP;
638 } else {
639 type = IPLT_NONE;
640 }
641 return type;
642 }
643
644
645 int
poollist(argc,argv)646 poollist(argc, argv)
647 int argc;
648 char *argv[];
649 {
650 char *kernel, *core, *poolname;
651 int c, role, type, live_kernel;
652 iplookupop_t op;
653
654 core = NULL;
655 kernel = NULL;
656 live_kernel = 1;
657 type = IPLT_ALL;
658 poolname = NULL;
659 role = IPL_LOGALL;
660
661 while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
662 switch (c)
663 {
664 case 'd' :
665 opts |= OPT_DEBUG;
666 break;
667 case 'm' :
668 poolname = optarg;
669 break;
670 case 'M' :
671 live_kernel = 0;
672 core = optarg;
673 break;
674 case 'N' :
675 live_kernel = 0;
676 kernel = optarg;
677 break;
678 case 'o' :
679 role = getrole(optarg);
680 if (role == IPL_LOGNONE) {
681 fprintf(stderr, "unknown role '%s'\n", optarg);
682 return -1;
683 }
684 break;
685 case 'O' :
686 pool_fields = parsefields(poolfields, optarg);
687 break;
688 case 'R' :
689 opts |= OPT_NORESOLVE;
690 break;
691 case 't' :
692 type = gettype(optarg, NULL);
693 if (type == IPLT_NONE) {
694 fprintf(stderr, "unknown type '%s'\n", optarg);
695 return -1;
696 }
697 break;
698 case 'v' :
699 opts |= OPT_VERBOSE;
700 break;
701 }
702
703 if (opts & OPT_DEBUG)
704 fprintf(stderr, "poollist: opts = %#x\n", opts);
705
706 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
707 fd = open(IPLOOKUP_NAME, O_RDWR);
708 if (fd == -1) {
709 perror("open(IPLOOKUP_NAME)");
710 exit(1);
711 }
712 }
713
714 bzero((char *)&op, sizeof(op));
715 if (poolname != NULL) {
716 strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
717 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
718 }
719 op.iplo_unit = role;
720
721 if (live_kernel)
722 poollist_live(role, poolname, type, fd);
723 else
724 poollist_dead(role, poolname, type, kernel, core);
725 return 0;
726 }
727
728
729 void
poollist_dead(role,poolname,type,kernel,core)730 poollist_dead(role, poolname, type, kernel, core)
731 int role, type;
732 char *poolname, *kernel, *core;
733 {
734 iphtable_t *hptr;
735 ip_pool_t *ptr;
736
737 if (openkmem(kernel, core) == -1)
738 exit(-1);
739
740 if (type == IPLT_ALL || type == IPLT_POOL) {
741 ip_pool_t *pools[IPL_LOGSIZE];
742 struct nlist names[2] = { { "ip_pool_list" } , { "" } };
743
744 if (nlist(kernel, names) != 1)
745 return;
746
747 bzero(&pools, sizeof(pools));
748 if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
749 return;
750
751 if (role != IPL_LOGALL) {
752 ptr = pools[role];
753 while (ptr != NULL) {
754 ptr = printpool(ptr, kmemcpywrap, poolname,
755 opts, pool_fields);
756 }
757 } else {
758 for (role = 0; role <= IPL_LOGMAX; role++) {
759 ptr = pools[role];
760 while (ptr != NULL) {
761 ptr = printpool(ptr, kmemcpywrap,
762 poolname, opts,
763 pool_fields);
764 }
765 }
766 role = IPL_LOGALL;
767 }
768 }
769 if (type == IPLT_ALL || type == IPLT_HASH) {
770 iphtable_t *tables[IPL_LOGSIZE];
771 struct nlist names[2] = { { "ipf_htables" } , { "" } };
772
773 if (nlist(kernel, names) != 1)
774 return;
775
776 bzero(&tables, sizeof(tables));
777 if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
778 return;
779
780 if (role != IPL_LOGALL) {
781 hptr = tables[role];
782 while (hptr != NULL) {
783 hptr = printhash(hptr, kmemcpywrap,
784 poolname, opts, pool_fields);
785 }
786 } else {
787 for (role = 0; role <= IPL_LOGMAX; role++) {
788 hptr = tables[role];
789 while (hptr != NULL) {
790 hptr = printhash(hptr, kmemcpywrap,
791 poolname, opts,
792 pool_fields);
793 }
794 }
795 }
796 }
797 }
798
799
800 void
poollist_live(role,poolname,type,fd)801 poollist_live(role, poolname, type, fd)
802 int role, type, fd;
803 char *poolname;
804 {
805 ipf_pool_stat_t plstat;
806 iplookupop_t op;
807 int unit;
808 int c;
809
810 if (type == IPLT_ALL || type == IPLT_POOL) {
811 op.iplo_type = IPLT_POOL;
812 op.iplo_size = sizeof(plstat);
813 op.iplo_struct = &plstat;
814 op.iplo_name[0] = '\0';
815 op.iplo_arg = 0;
816
817 if (role != IPL_LOGALL) {
818 op.iplo_unit = role;
819
820 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
821 if (c == -1) {
822 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
823 return;
824 }
825
826 showpools_live(fd, role, &plstat, poolname);
827 } else {
828 for (unit = -1; unit <= IPL_LOGMAX; unit++) {
829 op.iplo_unit = unit;
830
831 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
832 if (c == -1) {
833 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
834 return;
835 }
836
837 showpools_live(fd, unit, &plstat, poolname);
838 }
839 }
840 }
841
842 if (type == IPLT_ALL || type == IPLT_HASH) {
843 iphtstat_t htstat;
844
845 op.iplo_type = IPLT_HASH;
846 op.iplo_size = sizeof(htstat);
847 op.iplo_struct = &htstat;
848 op.iplo_name[0] = '\0';
849 op.iplo_arg = 0;
850
851 if (role != IPL_LOGALL) {
852 op.iplo_unit = role;
853
854 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
855 if (c == -1) {
856 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
857 return;
858 }
859 showhashs_live(fd, role, &htstat, poolname);
860 } else {
861 for (unit = 0; unit <= IPL_LOGMAX; unit++) {
862
863 op.iplo_unit = unit;
864 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
865 if (c == -1) {
866 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
867 return;
868 }
869
870 showhashs_live(fd, unit, &htstat, poolname);
871 }
872 }
873 }
874
875 if (type == IPLT_ALL || type == IPLT_DSTLIST) {
876 ipf_dstl_stat_t dlstat;
877
878 op.iplo_type = IPLT_DSTLIST;
879 op.iplo_size = sizeof(dlstat);
880 op.iplo_struct = &dlstat;
881 op.iplo_name[0] = '\0';
882 op.iplo_arg = 0;
883
884 if (role != IPL_LOGALL) {
885 op.iplo_unit = role;
886
887 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
888 if (c == -1) {
889 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
890 return;
891 }
892 showdstls_live(fd, role, &dlstat, poolname);
893 } else {
894 for (unit = 0; unit <= IPL_LOGMAX; unit++) {
895
896 op.iplo_unit = unit;
897 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
898 if (c == -1) {
899 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
900 return;
901 }
902
903 showdstls_live(fd, unit, &dlstat, poolname);
904 }
905 }
906 }
907 }
908
909
910 void
showpools_live(fd,role,plstp,poolname)911 showpools_live(fd, role, plstp, poolname)
912 int fd, role;
913 ipf_pool_stat_t *plstp;
914 char *poolname;
915 {
916 ipflookupiter_t iter;
917 ip_pool_t pool;
918 ipfobj_t obj;
919
920 obj.ipfo_rev = IPFILTER_VERSION;
921 obj.ipfo_type = IPFOBJ_LOOKUPITER;
922 obj.ipfo_size = sizeof(iter);
923 obj.ipfo_ptr = &iter;
924
925 iter.ili_type = IPLT_POOL;
926 iter.ili_otype = IPFLOOKUPITER_LIST;
927 iter.ili_ival = IPFGENITER_LOOKUP;
928 iter.ili_nitems = 1;
929 iter.ili_data = &pool;
930 iter.ili_unit = role;
931 *iter.ili_name = '\0';
932
933 bzero((char *)&pool, sizeof(pool));
934
935 while (plstp->ipls_list[role + 1] != NULL) {
936 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
937 ipferror(fd, "ioctl(SIOCLOOKUPITER)");
938 break;
939 }
940 if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
941 ((opts & OPT_DEBUG) != 0))
942 printpool_live(&pool, fd, poolname, opts, pool_fields);
943
944 plstp->ipls_list[role + 1] = pool.ipo_next;
945 }
946 }
947
948
949 void
showhashs_live(fd,role,htstp,poolname)950 showhashs_live(fd, role, htstp, poolname)
951 int fd, role;
952 iphtstat_t *htstp;
953 char *poolname;
954 {
955 ipflookupiter_t iter;
956 iphtable_t table;
957 ipfobj_t obj;
958
959 obj.ipfo_rev = IPFILTER_VERSION;
960 obj.ipfo_type = IPFOBJ_LOOKUPITER;
961 obj.ipfo_size = sizeof(iter);
962 obj.ipfo_ptr = &iter;
963
964 iter.ili_type = IPLT_HASH;
965 iter.ili_otype = IPFLOOKUPITER_LIST;
966 iter.ili_ival = IPFGENITER_LOOKUP;
967 iter.ili_nitems = 1;
968 iter.ili_data = &table;
969 iter.ili_unit = role;
970 *iter.ili_name = '\0';
971
972 while (htstp->iphs_tables != NULL) {
973 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
974 ipferror(fd, "ioctl(SIOCLOOKUPITER)");
975 break;
976 }
977
978 printhash_live(&table, fd, poolname, opts, pool_fields);
979
980 htstp->iphs_tables = table.iph_next;
981 }
982 }
983
984
985 void
showdstls_live(fd,role,dlstp,poolname)986 showdstls_live(fd, role, dlstp, poolname)
987 int fd, role;
988 ipf_dstl_stat_t *dlstp;
989 char *poolname;
990 {
991 ipflookupiter_t iter;
992 ippool_dst_t table;
993 ipfobj_t obj;
994
995 obj.ipfo_rev = IPFILTER_VERSION;
996 obj.ipfo_type = IPFOBJ_LOOKUPITER;
997 obj.ipfo_size = sizeof(iter);
998 obj.ipfo_ptr = &iter;
999
1000 iter.ili_type = IPLT_DSTLIST;
1001 iter.ili_otype = IPFLOOKUPITER_LIST;
1002 iter.ili_ival = IPFGENITER_LOOKUP;
1003 iter.ili_nitems = 1;
1004 iter.ili_data = &table;
1005 iter.ili_unit = role;
1006 *iter.ili_name = '\0';
1007
1008 while (dlstp->ipls_list[role] != NULL) {
1009 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1010 ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1011 break;
1012 }
1013
1014 printdstl_live(&table, fd, poolname, opts, pool_fields);
1015
1016 dlstp->ipls_list[role] = table.ipld_next;
1017 }
1018 }
1019
1020
1021 int
setnodeaddr(int type,int role,void * ptr,char * arg)1022 setnodeaddr(int type, int role, void *ptr, char *arg)
1023 {
1024 struct in_addr mask;
1025 char *s;
1026
1027 s = strchr(arg, '/');
1028 if (s == NULL)
1029 mask.s_addr = 0xffffffff;
1030 else if (strchr(s, '.') == NULL) {
1031 if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
1032 return -1;
1033 } else {
1034 mask.s_addr = inet_addr(s + 1);
1035 }
1036 if (s != NULL)
1037 *s = '\0';
1038
1039 if (type == IPLT_POOL) {
1040 ip_pool_node_t *node = ptr;
1041
1042 if (node->ipn_addr.adf_family == AF_INET)
1043 node->ipn_addr.adf_len = offsetof(addrfamily_t,
1044 adf_addr) +
1045 sizeof(struct in_addr);
1046 #ifdef USE_INET6
1047 else
1048 node->ipn_addr.adf_len = offsetof(addrfamily_t,
1049 adf_addr) +
1050 sizeof(struct in6_addr);
1051 #endif
1052 node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
1053 node->ipn_mask.adf_len = node->ipn_addr.adf_len;
1054 node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
1055 } else if (type == IPLT_HASH) {
1056 iphtent_t *node = ptr;
1057
1058 node->ipe_addr.in4.s_addr = inet_addr(arg);
1059 node->ipe_mask.in4.s_addr = mask.s_addr;
1060 node->ipe_family = AF_INET;
1061 node->ipe_unit = role;
1062 }
1063
1064 return 0;
1065 }
1066