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