]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ipfilter/tools/ippool.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ipfilter / tools / ippool.c
1 /*      $FreeBSD$       */
2
3 /*
4  * Copyright (C) 2002-2006 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 #if __FreeBSD_version >= 300000
19 # include <net/if_var.h>
20 #endif
21 #include <netinet/in.h>
22
23 #include <arpa/inet.h>
24
25 #include <stdio.h>
26 #include <fcntl.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <netdb.h>
30 #include <ctype.h>
31 #include <unistd.h>
32 #ifdef linux
33 # include <linux/a.out.h>
34 #else
35 # include <nlist.h>
36 #endif
37
38 #include "ipf.h"
39 #include "netinet/ipl.h"
40 #include "netinet/ip_lookup.h"
41 #include "netinet/ip_pool.h"
42 #include "netinet/ip_htable.h"
43 #include "kmem.h"
44
45
46 extern  int     ippool_yyparse __P((void));
47 extern  int     ippool_yydebug;
48 extern  FILE    *ippool_yyin;
49 extern  char    *optarg;
50 extern  int     lineNum;
51
52 void    usage __P((char *));
53 int     main __P((int, char **));
54 int     poolcommand __P((int, int, char *[]));
55 int     poolnodecommand __P((int, int, char *[]));
56 int     loadpoolfile __P((int, char *[], char *));
57 int     poollist __P((int, char *[]));
58 void    poollist_dead __P((int, char *, int, char *, char *));
59 void    poollist_live __P((int, char *, int, int));
60 int     poolflush __P((int, char *[]));
61 int     poolstats __P((int, char *[]));
62 int     gettype __P((char *, u_int *));
63 int     getrole __P((char *));
64 int     setnodeaddr __P((ip_pool_node_t *node, char *arg));
65 void    showpools_live __P((int, int, ip_pool_stat_t *, char *));
66 void    showhashs_live __P((int, int, iphtstat_t *, char *));
67
68 int     opts = 0;
69 int     fd = -1;
70 int     use_inet6 = 0;
71
72
73 void usage(prog)
74 char *prog;
75 {
76         fprintf(stderr, "Usage:\t%s\n", prog);
77         fprintf(stderr, "\t\t\t-a [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
78         fprintf(stderr, "\t\t\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
79         fprintf(stderr, "\t\t\t-f <file> [-dnuv]\n");
80         fprintf(stderr, "\t\t\t-F [-dv] [-o <role>] [-t <type>]\n");
81         fprintf(stderr, "\t\t\t-l [-dv] [-m <name>] [-t <type>]\n");
82         fprintf(stderr, "\t\t\t-r [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
83         fprintf(stderr, "\t\t\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
84         fprintf(stderr, "\t\t\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
85         exit(1);
86 }
87
88
89 int main(argc, argv)
90 int argc;
91 char *argv[];
92 {
93         int err;
94
95         if (argc < 2)
96                 usage(argv[0]);
97
98         switch (getopt(argc, argv, "aAf:FlrRs"))
99         {
100         case 'a' :
101                 err = poolnodecommand(0, argc, argv);
102                 break;
103         case 'A' :
104                 err = poolcommand(0, argc, argv);
105                 break;
106         case 'f' :
107                 err = loadpoolfile(argc, argv, optarg);
108                 break;
109         case 'F' :
110                 err = poolflush(argc, argv);
111                 break;
112         case 'l' :
113                 err = poollist(argc, argv);
114                 break;
115         case 'r' :
116                 err = poolnodecommand(1, argc, argv);
117                 break;
118         case 'R' :
119                 err = poolcommand(1, argc, argv);
120                 break;
121         case 's' :
122                 err = poolstats(argc, argv);
123                 break;
124         default :
125                 exit(1);
126         }
127
128         if (err != 0)
129                 exit(1);
130         return 0;
131 }
132
133
134 int poolnodecommand(remove, argc, argv)
135 int remove, argc;
136 char *argv[];
137 {
138         int err, c, ipset, role;
139         char *poolname = NULL;
140         ip_pool_node_t node;
141
142         ipset = 0;
143         role = IPL_LOGIPF;
144         bzero((char *)&node, sizeof(node));
145
146         while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1)
147                 switch (c)
148                 {
149                 case 'd' :
150                         opts |= OPT_DEBUG;
151                         ippool_yydebug++;
152                         break;
153                 case 'i' :
154                         if (setnodeaddr(&node, optarg) == 0)
155                                 ipset = 1;
156                         break;
157                 case 'm' :
158                         poolname = optarg;
159                         break;
160                 case 'n' :
161                         opts |= OPT_DONOTHING;
162                         break;
163                 case 'o' :
164                         role = getrole(optarg);
165                         if (role == IPL_LOGNONE)
166                                 return -1;
167                         break;
168                 case 'R' :
169                         opts |= OPT_NORESOLVE;
170                         break;
171                 case 'v' :
172                         opts |= OPT_VERBOSE;
173                         break;
174                 }
175
176         if (argv[optind] != NULL && ipset == 0) {
177                 if (setnodeaddr(&node, argv[optind]) == 0)
178                         ipset = 1;
179         }
180
181         if (opts & OPT_DEBUG)
182                 fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
183
184         if (ipset == 0) {
185                 fprintf(stderr, "no IP address given with -i\n");
186                 return -1;
187         }
188
189         if (poolname == NULL) {
190                 fprintf(stderr, "poolname not given with add/remove node\n");
191                 return -1;
192         }
193
194         if (remove == 0)
195                 err = load_poolnode(0, poolname, &node, ioctl);
196         else
197                 err = remove_poolnode(0, poolname, &node, ioctl);
198         return err;
199 }
200
201
202 int poolcommand(remove, argc, argv)
203 int remove, argc;
204 char *argv[];
205 {
206         int type, role, c, err;
207         char *poolname;
208         iphtable_t iph;
209         ip_pool_t pool;
210
211         err = 1;
212         role = 0;
213         type = 0;
214         poolname = NULL;
215         role = IPL_LOGIPF;
216         bzero((char *)&iph, sizeof(iph));
217         bzero((char *)&pool, sizeof(pool));
218
219         while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1)
220                 switch (c)
221                 {
222                 case 'd' :
223                         opts |= OPT_DEBUG;
224                         ippool_yydebug++;
225                         break;
226                 case 'm' :
227                         poolname = optarg;
228                         break;
229                 case 'n' :
230                         opts |= OPT_DONOTHING;
231                         break;
232                 case 'o' :
233                         role = getrole(optarg);
234                         if (role == IPL_LOGNONE) {
235                                 fprintf(stderr, "unknown role '%s'\n", optarg);
236                                 return -1;
237                         }
238                         break;
239                 case 'R' :
240                         opts |= OPT_NORESOLVE;
241                         break;
242                 case 'S' :
243                         iph.iph_seed = atoi(optarg);
244                         break;
245                 case 't' :
246                         type = gettype(optarg, &iph.iph_type);
247                         if (type == IPLT_NONE) {
248                                 fprintf(stderr, "unknown type '%s'\n", optarg);
249                                 return -1;
250                         }
251                         break;
252                 case 'v' :
253                         opts |= OPT_VERBOSE;
254                         break;
255                 }
256
257         if (opts & OPT_DEBUG)
258                 fprintf(stderr, "poolcommand: opts = %#x\n", opts);
259
260         if (poolname == NULL) {
261                 fprintf(stderr, "poolname not given with add/remove pool\n");
262                 return -1;
263         }
264
265         if (type == IPLT_HASH) {
266                 strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
267                 iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
268                 iph.iph_unit = role;
269         } else if (type == IPLT_POOL) {
270                 strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
271                 pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
272                 pool.ipo_unit = role;
273         }
274
275         if (remove == 0) {
276                 switch (type)
277                 {
278                 case IPLT_HASH :
279                         err = load_hash(&iph, NULL, ioctl);
280                         break;
281                 case IPLT_POOL :
282                         err = load_pool(&pool, ioctl);
283                         break;
284                 }
285         } else {
286                 switch (type)
287                 {
288                 case IPLT_HASH :
289                         err = remove_hash(&iph, ioctl);
290                         break;
291                 case IPLT_POOL :
292                         err = remove_pool(&pool, ioctl);
293                         break;
294                 }
295         }
296         return err;
297 }
298
299
300 int loadpoolfile(argc, argv, infile)
301 int argc;
302 char *argv[], *infile;
303 {
304         int c;
305
306         infile = optarg;
307
308         while ((c = getopt(argc, argv, "dnRuv")) != -1)
309                 switch (c)
310                 {
311                 case 'd' :
312                         opts |= OPT_DEBUG;
313                         ippool_yydebug++;
314                         break;
315                 case 'n' :
316                         opts |= OPT_DONOTHING;
317                         break;
318                 case 'R' :
319                         opts |= OPT_NORESOLVE;
320                         break;
321                 case 'u' :
322                         opts |= OPT_REMOVE;
323                         break;
324                 case 'v' :
325                         opts |= OPT_VERBOSE;
326                         break;
327                 }
328
329         if (opts & OPT_DEBUG)
330                 fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
331
332         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
333                 fd = open(IPLOOKUP_NAME, O_RDWR);
334                 if (fd == -1) {
335                         perror("open(IPLOOKUP_NAME)");
336                         exit(1);
337                 }
338         }
339
340         if (ippool_parsefile(fd, infile, ioctl) != 0)
341                 return -1;
342         return 0;
343 }
344
345
346 int poolstats(argc, argv)
347 int argc;
348 char *argv[];
349 {
350         int c, type, role, live_kernel;
351         ip_pool_stat_t plstat;
352         char *kernel, *core;
353         iphtstat_t htstat;
354         iplookupop_t op;
355
356         core = NULL;
357         kernel = NULL;
358         live_kernel = 1;
359         type = IPLT_ALL;
360         role = IPL_LOGALL;
361
362         bzero((char *)&op, sizeof(op));
363
364         while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
365                 switch (c)
366                 {
367                 case 'd' :
368                         opts |= OPT_DEBUG;
369                         break;
370                 case 'M' :
371                         live_kernel = 0;
372                         core = optarg;
373                         break;
374                 case 'N' :
375                         live_kernel = 0;
376                         kernel = optarg;
377                         break;
378                 case 'o' :
379                         role = getrole(optarg);
380                         if (role == IPL_LOGNONE) {
381                                 fprintf(stderr, "unknown role '%s'\n", optarg);
382                                 return -1;
383                         }
384                         break;
385                 case 't' :
386                         type = gettype(optarg, NULL);
387                         if (type != IPLT_POOL) {
388                                 fprintf(stderr,
389                                         "-s not supported for this type yet\n");
390                                 return -1;
391                         }
392                         break;
393                 case 'v' :
394                         opts |= OPT_VERBOSE;
395                         break;
396                 }
397
398         if (opts & OPT_DEBUG)
399                 fprintf(stderr, "poolstats: opts = %#x\n", opts);
400
401         if (!(opts & OPT_DONOTHING) && (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 (type == IPLT_ALL || type == IPLT_POOL) {
410                 op.iplo_type = IPLT_POOL;
411                 op.iplo_struct = &plstat;
412                 op.iplo_size = sizeof(plstat);
413                 if (!(opts & OPT_DONOTHING)) {
414                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
415                         if (c == -1) {
416                                 perror("ioctl(SIOCLOOKUPSTAT)");
417                                 return -1;
418                         }
419                         printf("Pools:\t%lu\n", plstat.ipls_pools);
420                         printf("Nodes:\t%lu\n", plstat.ipls_nodes);
421                 }
422         }
423
424         if (type == IPLT_ALL || type == IPLT_HASH) {
425                 op.iplo_type = IPLT_HASH;
426                 op.iplo_struct = &htstat;
427                 op.iplo_size = sizeof(htstat);
428                 if (!(opts & OPT_DONOTHING)) {
429                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
430                         if (c == -1) {
431                                 perror("ioctl(SIOCLOOKUPSTAT)");
432                                 return -1;
433                         }
434                         printf("Hash Tables:\t%lu\n", htstat.iphs_numtables);
435                         printf("Nodes:\t%lu\n", htstat.iphs_numnodes);
436                         printf("Out of Memory:\t%lu\n", htstat.iphs_nomem);
437                 }
438         }
439         return 0;
440 }
441
442
443 int poolflush(argc, argv)
444 int argc;
445 char *argv[];
446 {
447         int c, role, type, arg;
448         iplookupflush_t flush;
449
450         arg = IPLT_ALL;
451         type = IPLT_ALL;
452         role = IPL_LOGALL;
453
454         while ((c = getopt(argc, argv, "do:t:v")) != -1)
455                 switch (c)
456                 {
457                 case 'd' :
458                         opts |= OPT_DEBUG;
459                         break;
460                 case 'o' :
461                         role = getrole(optarg);
462                         if (role == IPL_LOGNONE) {
463                                 fprintf(stderr, "unknown role '%s'\n", optarg);
464                                 return -1;
465                         }
466                         break;
467                 case 't' :
468                         type = gettype(optarg, NULL);
469                         if (type == IPLT_NONE) {
470                                 fprintf(stderr, "unknown type '%s'\n", optarg);
471                                 return -1;
472                         }
473                         break;
474                 case 'v' :
475                         opts |= OPT_VERBOSE;
476                         break;
477                 }
478
479         if (opts & OPT_DEBUG)
480                 fprintf(stderr, "poolflush: opts = %#x\n", opts);
481
482         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
483                 fd = open(IPLOOKUP_NAME, O_RDWR);
484                 if (fd == -1) {
485                         perror("open(IPLOOKUP_NAME)");
486                         exit(1);
487                 }
488         }
489
490         bzero((char *)&flush, sizeof(flush));
491         flush.iplf_type = type;
492         flush.iplf_unit = role;
493         flush.iplf_arg = arg;
494
495         if (!(opts & OPT_DONOTHING)) {
496                 if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
497                         perror("ioctl(SIOCLOOKUPFLUSH)");
498                         exit(1);
499                 }
500
501         }
502         printf("%zd object%s flushed\n", flush.iplf_count,
503                (flush.iplf_count == 1) ? "" : "s");
504
505         return 0;
506 }
507
508
509 int getrole(rolename)
510 char *rolename;
511 {
512         int role;
513
514         if (!strcasecmp(rolename, "ipf")) {
515                 role = IPL_LOGIPF;
516 #if 0
517         } else if (!strcasecmp(rolename, "nat")) {
518                 role = IPL_LOGNAT;
519         } else if (!strcasecmp(rolename, "state")) {
520                 role = IPL_LOGSTATE;
521         } else if (!strcasecmp(rolename, "auth")) {
522                 role = IPL_LOGAUTH;
523         } else if (!strcasecmp(rolename, "sync")) {
524                 role = IPL_LOGSYNC;
525         } else if (!strcasecmp(rolename, "scan")) {
526                 role = IPL_LOGSCAN;
527         } else if (!strcasecmp(rolename, "pool")) {
528                 role = IPL_LOGLOOKUP;
529         } else if (!strcasecmp(rolename, "count")) {
530                 role = IPL_LOGCOUNT;
531 #endif
532         } else {
533                 role = IPL_LOGNONE;
534         }
535
536         return role;
537 }
538
539
540 int gettype(typename, minor)
541 char *typename;
542 u_int *minor;
543 {
544         int type;
545
546         if (!strcasecmp(optarg, "tree") || !strcasecmp(optarg, "pool")) {
547                 type = IPLT_POOL;
548         } else if (!strcasecmp(optarg, "hash")) {
549                 type = IPLT_HASH;
550                 if (minor != NULL)
551                         *minor = IPHASH_LOOKUP;
552         } else if (!strcasecmp(optarg, "group-map")) {
553                 type = IPLT_HASH;
554                 if (minor != NULL)
555                         *minor = IPHASH_GROUPMAP;
556         } else {
557                 type = IPLT_NONE;
558         }
559         return type;
560 }
561
562
563 int poollist(argc, argv)
564 int argc;
565 char *argv[];
566 {
567         char *kernel, *core, *poolname;
568         int c, role, type, live_kernel;
569         iplookupop_t op;
570
571         core = NULL;
572         kernel = NULL;
573         live_kernel = 1;
574         type = IPLT_ALL;
575         poolname = NULL;
576         role = IPL_LOGALL;
577
578         while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
579                 switch (c)
580                 {
581                 case 'd' :
582                         opts |= OPT_DEBUG;
583                         break;
584                 case 'm' :
585                         poolname = optarg;
586                         break;
587                 case 'M' :
588                         live_kernel = 0;
589                         core = optarg;
590                         break;
591                 case 'N' :
592                         live_kernel = 0;
593                         kernel = optarg;
594                         break;
595                 case 'o' :
596                         role = getrole(optarg);
597                         if (role == IPL_LOGNONE) {
598                                 fprintf(stderr, "unknown role '%s'\n", optarg);
599                                 return -1;
600                         }
601                         break;
602                 case 'R' :
603                         opts |= OPT_NORESOLVE;
604                         break;
605                 case 't' :
606                         type = gettype(optarg, NULL);
607                         if (type == IPLT_NONE) {
608                                 fprintf(stderr, "unknown type '%s'\n", optarg);
609                                 return -1;
610                         }
611                         break;
612                 case 'v' :
613                         opts |= OPT_VERBOSE;
614                         break;
615                 }
616
617         if (opts & OPT_DEBUG)
618                 fprintf(stderr, "poollist: opts = %#x\n", opts);
619
620         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
621                 fd = open(IPLOOKUP_NAME, O_RDWR);
622                 if (fd == -1) {
623                         perror("open(IPLOOKUP_NAME)");
624                         exit(1);
625                 }
626         }
627
628         bzero((char *)&op, sizeof(op));
629         if (poolname != NULL) {
630                 strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
631                 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
632         }
633         op.iplo_unit = role;
634
635         if (live_kernel)
636                 poollist_live(role, poolname, type, fd);
637         else
638                 poollist_dead(role, poolname, type, kernel, core);
639         return 0;
640 }
641
642
643 void poollist_dead(role, poolname, type, kernel, core)
644 int role, type;
645 char *poolname, *kernel, *core;
646 {
647         iphtable_t *hptr;
648         ip_pool_t *ptr;
649
650         if (openkmem(kernel, core) == -1)
651                 exit(-1);
652
653         if (type == IPLT_ALL || type == IPLT_POOL) {
654                 ip_pool_t *pools[IPL_LOGSIZE];
655                 struct nlist names[2] = { { "ip_pool_list" } , { "" } };
656
657                 if (nlist(kernel, names) != 1)
658                         return;
659
660                 bzero(&pools, sizeof(pools));
661                 if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
662                         return;
663
664                 if (role != IPL_LOGALL) {
665                         ptr = pools[role];
666                         while (ptr != NULL) {
667                                 ptr = printpool(ptr, kmemcpywrap, poolname,
668                                                 opts);
669                         }
670                 } else {
671                         for (role = 0; role <= IPL_LOGMAX; role++) {
672                                 ptr = pools[role];
673                                 while (ptr != NULL) {
674                                         ptr = printpool(ptr, kmemcpywrap,
675                                                         poolname, opts);
676                                 }
677                         }
678                         role = IPL_LOGALL;
679                 }
680         }
681         if (type == IPLT_ALL || type == IPLT_HASH) {
682                 iphtable_t *tables[IPL_LOGSIZE];
683                 struct nlist names[2] = { { "ipf_htables" } , { "" } };
684
685                 if (nlist(kernel, names) != 1)
686                         return;
687
688                 bzero(&tables, sizeof(tables));
689                 if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
690                         return;
691
692                 if (role != IPL_LOGALL) {
693                         hptr = tables[role];
694                         while (hptr != NULL) {
695                                 hptr = printhash(hptr, kmemcpywrap,
696                                                  poolname, opts);
697                         }
698                 } else {
699                         for (role = 0; role <= IPL_LOGMAX; role++) {
700                                 hptr = tables[role];
701                                 while (hptr != NULL) {
702                                         hptr = printhash(hptr, kmemcpywrap,
703                                                          poolname, opts);
704                                 }
705                         }
706                 }
707         }
708 }
709
710
711 void poollist_live(role, poolname, type, fd)
712 int role, type, fd;
713 char *poolname;
714 {
715         ip_pool_stat_t plstat;
716         iphtstat_t htstat;
717         iplookupop_t op;
718         int c;
719
720         if (type == IPLT_ALL || type == IPLT_POOL) {
721                 op.iplo_type = IPLT_POOL;
722                 op.iplo_size = sizeof(plstat);
723                 op.iplo_struct = &plstat;
724                 op.iplo_name[0] = '\0';
725                 op.iplo_arg = 0;
726
727                 if (role != IPL_LOGALL) {
728                         op.iplo_unit = role;
729
730                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
731                         if (c == -1) {
732                                 perror("ioctl(SIOCLOOKUPSTAT)");
733                                 return;
734                         }
735
736                         showpools_live(fd, role, &plstat, poolname);
737                 } else {
738                         for (role = 0; role <= IPL_LOGMAX; role++) {
739                                 op.iplo_unit = role;
740
741                                 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
742                                 if (c == -1) {
743                                         perror("ioctl(SIOCLOOKUPSTAT)");
744                                         return;
745                                 }
746
747                                 showpools_live(fd, role, &plstat, poolname);
748                         }
749
750                         role = IPL_LOGALL;
751                 }
752         }
753
754         if (type == IPLT_ALL || type == IPLT_HASH) {
755                 op.iplo_type = IPLT_HASH;
756                 op.iplo_size = sizeof(htstat);
757                 op.iplo_struct = &htstat;
758                 op.iplo_name[0] = '\0';
759                 op.iplo_arg = 0;
760
761                 if (role != IPL_LOGALL) {
762                         op.iplo_unit = role;
763
764                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
765                         if (c == -1) {
766                                 perror("ioctl(SIOCLOOKUPSTAT)");
767                                 return;
768                         }
769                         showhashs_live(fd, role, &htstat, poolname);
770                 } else {
771                         for (role = 0; role <= IPL_LOGMAX; role++) {
772
773                                 op.iplo_unit = role;
774                                 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
775                                 if (c == -1) {
776                                         perror("ioctl(SIOCLOOKUPSTAT)");
777                                         return;
778                                 }
779
780                                 showhashs_live(fd, role, &htstat, poolname);
781                         }
782                 }
783         }
784 }
785
786
787 void showpools_live(fd, role, plstp, poolname)
788 int fd, role;
789 ip_pool_stat_t *plstp;
790 char *poolname;
791 {
792         ipflookupiter_t iter;
793         ip_pool_t pool;
794         ipfobj_t obj;
795
796         obj.ipfo_rev = IPFILTER_VERSION;
797         obj.ipfo_type = IPFOBJ_LOOKUPITER;
798         obj.ipfo_size = sizeof(iter);
799         obj.ipfo_ptr = &iter;
800
801         iter.ili_type = IPLT_POOL;
802         iter.ili_otype = IPFLOOKUPITER_LIST;
803         iter.ili_ival = IPFGENITER_LOOKUP;
804         iter.ili_nitems = 1;
805         iter.ili_data = &pool;
806         iter.ili_unit = role;
807         *iter.ili_name = '\0';
808
809         while (plstp->ipls_list[role] != NULL) {
810                 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
811                         perror("ioctl(SIOCLOOKUPITER)");
812                         break;
813                 }
814                 printpool_live(&pool, fd, poolname, opts);
815
816                 plstp->ipls_list[role] = pool.ipo_next;
817         }
818 }
819
820
821 void showhashs_live(fd, role, htstp, poolname)
822 int fd, role;
823 iphtstat_t *htstp;
824 char *poolname;
825 {
826         ipflookupiter_t iter;
827         iphtable_t table;
828         ipfobj_t obj;
829
830         obj.ipfo_rev = IPFILTER_VERSION;
831         obj.ipfo_type = IPFOBJ_LOOKUPITER;
832         obj.ipfo_size = sizeof(iter);
833         obj.ipfo_ptr = &iter;
834
835         iter.ili_type = IPLT_HASH;
836         iter.ili_otype = IPFLOOKUPITER_LIST;
837         iter.ili_ival = IPFGENITER_LOOKUP;
838         iter.ili_nitems = 1;
839         iter.ili_data = &table;
840         iter.ili_unit = role;
841         *iter.ili_name = '\0';
842
843         while (htstp->iphs_tables != NULL) {
844                 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
845                         perror("ioctl(SIOCLOOKUPITER)");
846                         break;
847                 }
848
849                 printhash_live(&table, fd, poolname, opts);
850
851                 htstp->iphs_tables = table.iph_next;
852         }
853 }
854
855
856 int setnodeaddr(ip_pool_node_t *node, char *arg)
857 {
858         struct in_addr mask;
859         char *s;
860
861         s = strchr(arg, '/');
862         if (s == NULL)
863                 mask.s_addr = 0xffffffff;
864         else if (strchr(s, '.') == NULL) {
865                 if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0)
866                         return -1;
867         } else {
868                 mask.s_addr = inet_addr(s + 1);
869         }
870         if (s != NULL)
871                 *s = '\0';
872         node->ipn_addr.adf_len = sizeof(node->ipn_addr);
873         node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
874         node->ipn_mask.adf_len = sizeof(node->ipn_mask);
875         node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
876
877         return 0;
878 }