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