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