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