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