]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ipfilter/tools/ippool.c
This commit was generated by cvs2svn to compensate for changes in r169765,
[FreeBSD/FreeBSD.git] / contrib / ipfilter / tools / ippool.c
1 /*      $FreeBSD$       */
2
3 /*
4  * Copyright (C) 2003 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
33 #include "ipf.h"
34 #include "netinet/ip_lookup.h"
35 #include "netinet/ip_pool.h"
36 #include "netinet/ip_htable.h"
37 #include "kmem.h"
38
39
40 extern  int     ippool_yyparse __P((void));
41 extern  int     ippool_yydebug;
42 extern  FILE    *ippool_yyin;
43 extern  char    *optarg;
44 extern  int     lineNum;
45
46 void    showpools __P((ip_pool_stat_t *));
47 void    usage __P((char *));
48 int     main __P((int, char **));
49 int     poolcommand __P((int, int, char *[]));
50 int     poolnodecommand __P((int, int, char *[]));
51 int     loadpoolfile __P((int, char *[], char *));
52 int     poollist __P((int, char *[]));
53 int     poolflush __P((int, char *[]));
54 int     poolstats __P((int, char *[]));
55 int     gettype __P((char *, u_int *));
56 int     getrole __P((char *));
57
58 int     opts = 0;
59 int     fd = -1;
60 int     use_inet6 = 0;
61
62
63 void usage(prog)
64 char *prog;
65 {
66         fprintf(stderr, "Usage:\t%s\n", prog);
67         fprintf(stderr, "\t\t\t-a [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
68         fprintf(stderr, "\t\t\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
69         fprintf(stderr, "\t\t\t-f <file> [-dnuv]\n");
70         fprintf(stderr, "\t\t\t-F [-dv] [-o <role>] [-t <type>]\n");
71         fprintf(stderr, "\t\t\t-l [-dv] [-m <name>] [-t <type>]\n");
72         fprintf(stderr, "\t\t\t-r [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
73         fprintf(stderr, "\t\t\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
74         fprintf(stderr, "\t\t\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
75         exit(1);
76 }
77
78
79 int main(argc, argv)
80 int argc;
81 char *argv[];
82 {
83         int err;
84
85         if (argc < 2)
86                 usage(argv[0]);
87
88         switch (getopt(argc, argv, "aAf:FlrRs"))
89         {
90         case 'a' :
91                 err = poolnodecommand(0, argc, argv);
92                 break;
93         case 'A' :
94                 err = poolcommand(0, argc, argv);
95                 break;
96         case 'f' :
97                 err = loadpoolfile(argc, argv, optarg);
98                 break;
99         case 'F' :
100                 err = poolflush(argc, argv);
101                 break;
102         case 'l' :
103                 err = poollist(argc, argv);
104                 break;
105         case 'r' :
106                 err = poolnodecommand(1, argc, argv);
107                 break;
108         case 'R' :
109                 err = poolcommand(1, argc, argv);
110                 break;
111         case 's' :
112                 err = poolstats(argc, argv);
113                 break;
114         default :
115                 exit(1);
116         }
117
118         return err;
119 }
120
121
122 int poolnodecommand(remove, argc, argv)
123 int remove, argc;
124 char *argv[];
125 {
126         char *poolname = NULL, *s;
127         int err, c, ipset, role;
128         ip_pool_node_t node;
129         struct in_addr mask;
130
131         ipset = 0;
132         role = IPL_LOGIPF;
133         bzero((char *)&node, sizeof(node));
134
135         while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1)
136                 switch (c)
137                 {
138                 case 'd' :
139                         opts |= OPT_DEBUG;
140                         ippool_yydebug++;
141                         break;
142                 case 'i' :
143                         s = strchr(optarg, '/');
144                         if (s == NULL)
145                                 mask.s_addr = 0xffffffff;
146                         else if (strchr(s, '.') == NULL) {
147                                 if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0)
148                                         return -1;
149                         } else {
150                                 mask.s_addr = inet_addr(s + 1);
151                         }
152                         if (s != NULL)
153                                 *s = '\0';
154                         ipset = 1;
155                         node.ipn_addr.adf_len = sizeof(node.ipn_addr);
156                         node.ipn_addr.adf_addr.in4.s_addr = inet_addr(optarg);
157                         node.ipn_mask.adf_len = sizeof(node.ipn_mask);
158                         node.ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
159                         break;
160                 case 'm' :
161                         poolname = optarg;
162                         break;
163                 case 'n' :
164                         opts |= OPT_DONOTHING;
165                         break;
166                 case 'o' :
167                         role = getrole(optarg);
168                         if (role == IPL_LOGNONE)
169                                 return -1;
170                         break;
171                 case 'R' :
172                         opts |= OPT_NORESOLVE;
173                         break;
174                 case 'v' :
175                         opts |= OPT_VERBOSE;
176                         break;
177                 }
178
179         if (opts & OPT_DEBUG)
180                 fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
181
182         if (ipset == 0)
183                 return -1;
184         if (poolname == NULL) {
185                 fprintf(stderr, "poolname not given with add/remove node\n");
186                 return -1;
187         }
188
189         if (remove == 0)
190                 err = load_poolnode(0, poolname, &node, ioctl);
191         else
192                 err = remove_poolnode(0, poolname, &node, ioctl);
193         return err;
194 }
195
196
197 int poolcommand(remove, argc, argv)
198 int remove, argc;
199 char *argv[];
200 {
201         int type, role, c, err;
202         char *poolname;
203         iphtable_t iph;
204         ip_pool_t pool;
205
206         err = 1;
207         role = 0;
208         type = 0;
209         poolname = NULL;
210         role = IPL_LOGIPF;
211         bzero((char *)&iph, sizeof(iph));
212         bzero((char *)&pool, sizeof(pool));
213
214         while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1)
215                 switch (c)
216                 {
217                 case 'd' :
218                         opts |= OPT_DEBUG;
219                         ippool_yydebug++;
220                         break;
221                 case 'm' :
222                         poolname = optarg;
223                         break;
224                 case 'n' :
225                         opts |= OPT_DONOTHING;
226                         break;
227                 case 'o' :
228                         role = getrole(optarg);
229                         if (role == IPL_LOGNONE) {
230                                 fprintf(stderr, "unknown role '%s'\n", optarg);
231                                 return -1;
232                         }
233                         break;
234                 case 'R' :
235                         opts |= OPT_NORESOLVE;
236                         break;
237                 case 'S' :
238                         iph.iph_seed = atoi(optarg);
239                         break;
240                 case 't' :
241                         type = gettype(optarg, &iph.iph_type);
242                         if (type == IPLT_NONE) {
243                                 fprintf(stderr, "unknown type '%s'\n", optarg);
244                                 return -1;
245                         }
246                         break;
247                 case 'v' :
248                         opts |= OPT_VERBOSE;
249                         break;
250                 }
251
252         if (opts & OPT_DEBUG)
253                 fprintf(stderr, "poolcommand: opts = %#x\n", opts);
254
255         if (poolname == NULL) {
256                 fprintf(stderr, "poolname not given with add/remove pool\n");
257                 return -1;
258         }
259
260         if (type == IPLT_HASH) {
261                 strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
262                 iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
263                 iph.iph_unit = role;
264         } else if (type == IPLT_POOL) {
265                 strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
266                 pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
267                 pool.ipo_unit = role;
268         }
269
270         if (remove == 0) {
271                 switch (type)
272                 {
273                 case IPLT_HASH :
274                         err = load_hash(&iph, NULL, ioctl);
275                         break;
276                 case IPLT_POOL :
277                         err = load_pool(&pool, ioctl);
278                         break;
279                 }
280         } else {
281                 switch (type)
282                 {
283                 case IPLT_HASH :
284                         err = remove_hash(&iph, ioctl);
285                         break;
286                 case IPLT_POOL :
287                         err = remove_pool(&pool, ioctl);
288                         break;
289                 }
290         }
291         return err;
292 }
293
294
295 int loadpoolfile(argc, argv, infile)
296 int argc;
297 char *argv[], *infile;
298 {
299         int c;
300
301         infile = optarg;
302
303         while ((c = getopt(argc, argv, "dnRuv")) != -1)
304                 switch (c)
305                 {
306                 case 'd' :
307                         opts |= OPT_DEBUG;
308                         ippool_yydebug++;
309                         break;
310                 case 'n' :
311                         opts |= OPT_DONOTHING;
312                         break;
313                 case 'R' :
314                         opts |= OPT_NORESOLVE;
315                         break;
316                 case 'u' :
317                         opts |= OPT_REMOVE;
318                         break;
319                 case 'v' :
320                         opts |= OPT_VERBOSE;
321                         break;
322                 }
323
324         if (opts & OPT_DEBUG)
325                 fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
326
327         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
328                 fd = open(IPLOOKUP_NAME, O_RDWR);
329                 if (fd == -1) {
330                         perror("open(IPLOOKUP_NAME)");
331                         exit(1);
332                 }
333         }
334
335         if (ippool_parsefile(fd, infile, ioctl) != 0)
336                 return -1;
337         return 0;
338 }
339
340
341 int poollist(argc, argv)
342 int argc;
343 char *argv[];
344 {
345         char *kernel, *core, *poolname;
346         int c, role, type, live_kernel;
347         ip_pool_stat_t *plstp, plstat;
348         iphtstat_t *htstp, htstat;
349         iphtable_t *hptr;
350         iplookupop_t op;
351         ip_pool_t *ptr;
352
353         core = NULL;
354         kernel = NULL;
355         live_kernel = 1;
356         type = IPLT_ALL;
357         poolname = NULL;
358         role = IPL_LOGALL;
359
360         while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
361                 switch (c)
362                 {
363                 case 'd' :
364                         opts |= OPT_DEBUG;
365                         break;
366                 case 'm' :
367                         poolname = optarg;
368                         break;
369                 case 'M' :
370                         live_kernel = 0;
371                         core = optarg;
372                         break;
373                 case 'N' :
374                         live_kernel = 0;
375                         kernel = optarg;
376                         break;
377                 case 'o' :
378                         role = getrole(optarg);
379                         if (role == IPL_LOGNONE) {
380                                 fprintf(stderr, "unknown role '%s'\n", optarg);
381                                 return -1;
382                         }
383                         break;
384                 case 'R' :
385                         opts |= OPT_NORESOLVE;
386                         break;
387                 case 't' :
388                         type = gettype(optarg, NULL);
389                         if (type == IPLT_NONE) {
390                                 fprintf(stderr, "unknown type '%s'\n", optarg);
391                                 return -1;
392                         }
393                         break;
394                 case 'v' :
395                         opts |= OPT_VERBOSE;
396                         break;
397                 }
398
399         if (opts & OPT_DEBUG)
400                 fprintf(stderr, "poollist: opts = %#x\n", opts);
401
402         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
403                 fd = open(IPLOOKUP_NAME, O_RDWR);
404                 if (fd == -1) {
405                         perror("open(IPLOOKUP_NAME)");
406                         exit(1);
407                 }
408         }
409
410         bzero((char *)&op, sizeof(op));
411         if (poolname != NULL) {
412                 strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
413                 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
414         }
415         op.iplo_unit = role;
416
417         if (openkmem(kernel, core) == -1)
418                 exit(-1);
419
420         if (type == IPLT_ALL || type == IPLT_POOL) {
421                 plstp = &plstat;
422                 op.iplo_type = IPLT_POOL;
423                 op.iplo_size = sizeof(plstat);
424                 op.iplo_struct = &plstat;
425                 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
426                 if (c == -1) {
427                         perror("ioctl(SIOCLOOKUPSTAT)");
428                         return -1;
429                 }
430
431                 if (role != IPL_LOGALL) {
432                         ptr = plstp->ipls_list[role];
433                         while (ptr != NULL) {
434                                 ptr = printpool(ptr, kmemcpywrap, poolname,
435                                                 opts);
436                         }
437                 } else {
438                         for (role = 0; role <= IPL_LOGMAX; role++) {
439                                 ptr = plstp->ipls_list[role];
440                                 while (ptr != NULL) {
441                                         ptr = printpool(ptr, kmemcpywrap,
442                                                         poolname, opts);
443                                 }
444                         }
445                         role = IPL_LOGALL;
446                 }
447         }
448         if (type == IPLT_ALL || type == IPLT_HASH) {
449                 htstp = &htstat;
450                 op.iplo_type = IPLT_HASH;
451                 op.iplo_size = sizeof(htstat);
452                 op.iplo_struct = &htstat;
453                 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
454                 if (c == -1) {
455                         perror("ioctl(SIOCLOOKUPSTAT)");
456                         return -1;
457                 }
458
459                 if (role != IPL_LOGALL) {
460                         hptr = htstp->iphs_tables;
461                         while (hptr != NULL) {
462                                 hptr = printhash(hptr, kmemcpywrap,
463                                                  poolname, opts);
464                         }
465                 } else {
466                         for (role = 0; role <= IPL_LOGMAX; role++) {
467                                 hptr = htstp->iphs_tables;
468                                 while (hptr != NULL) {
469                                         hptr = printhash(hptr, kmemcpywrap,
470                                                          poolname, opts);
471                                 }
472
473                                 op.iplo_unit = role;
474                                 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
475                                 if (c == -1) {
476                                         perror("ioctl(SIOCLOOKUPSTAT)");
477                                         return -1;
478                                 }
479                         }
480                 }
481         }
482         return 0;
483 }
484
485
486 int poolstats(argc, argv)
487 int argc;
488 char *argv[];
489 {
490         int c, type, role, live_kernel;
491         ip_pool_stat_t plstat;
492         char *kernel, *core;
493         iphtstat_t htstat;
494         iplookupop_t op;
495
496         core = NULL;
497         kernel = NULL;
498         live_kernel = 1;
499         type = IPLT_ALL;
500         role = IPL_LOGALL;
501
502         bzero((char *)&op, sizeof(op));
503
504         while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
505                 switch (c)
506                 {
507                 case 'd' :
508                         opts |= OPT_DEBUG;
509                         break;
510                 case 'M' :
511                         live_kernel = 0;
512                         core = optarg;
513                         break;
514                 case 'N' :
515                         live_kernel = 0;
516                         kernel = optarg;
517                         break;
518                 case 'o' :
519                         role = getrole(optarg);
520                         if (role == IPL_LOGNONE) {
521                                 fprintf(stderr, "unknown role '%s'\n", optarg);
522                                 return -1;
523                         }
524                         break;
525                 case 't' :
526                         type = gettype(optarg, NULL);
527                         if (type != IPLT_POOL) {
528                                 fprintf(stderr,
529                                         "-s not supported for this type yet\n");
530                                 return -1;
531                         }
532                         break;
533                 case 'v' :
534                         opts |= OPT_VERBOSE;
535                         break;
536                 }
537
538         if (opts & OPT_DEBUG)
539                 fprintf(stderr, "poolstats: opts = %#x\n", opts);
540
541         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
542                 fd = open(IPLOOKUP_NAME, O_RDWR);
543                 if (fd == -1) {
544                         perror("open(IPLOOKUP_NAME)");
545                         exit(1);
546                 }
547         }
548
549         if (type == IPLT_ALL || type == IPLT_POOL) {
550                 op.iplo_type = IPLT_POOL;
551                 op.iplo_struct = &plstat;
552                 op.iplo_size = sizeof(plstat);
553                 if (!(opts & OPT_DONOTHING)) {
554                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
555                         if (c == -1) {
556                                 perror("ioctl(SIOCLOOKUPSTAT)");
557                                 return -1;
558                         }
559                         printf("Pools:\t%lu\n", plstat.ipls_pools);
560                         printf("Nodes:\t%lu\n", plstat.ipls_nodes);
561                 }
562         }
563
564         if (type == IPLT_ALL || type == IPLT_HASH) {
565                 op.iplo_type = IPLT_HASH;
566                 op.iplo_struct = &htstat;
567                 op.iplo_size = sizeof(htstat);
568                 if (!(opts & OPT_DONOTHING)) {
569                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
570                         if (c == -1) {
571                                 perror("ioctl(SIOCLOOKUPSTAT)");
572                                 return -1;
573                         }
574                         printf("Hash Tables:\t%lu\n", htstat.iphs_numtables);
575                         printf("Nodes:\t%lu\n", htstat.iphs_numnodes);
576                         printf("Out of Memory:\t%lu\n", htstat.iphs_nomem);
577                 }
578         }
579         return 0;
580 }
581
582
583 int poolflush(argc, argv)
584 int argc;
585 char *argv[];
586 {
587         int c, role, type, arg;
588         iplookupflush_t flush;
589
590         arg = IPLT_ALL;
591         type = IPLT_ALL;
592         role = IPL_LOGALL;
593
594         while ((c = getopt(argc, argv, "do:t:v")) != -1)
595                 switch (c)
596                 {
597                 case 'd' :
598                         opts |= OPT_DEBUG;
599                         break;
600                 case 'o' :
601                         role = getrole(optarg);
602                         if (role == IPL_LOGNONE) {
603                                 fprintf(stderr, "unknown role '%s'\n", optarg);
604                                 return -1;
605                         }
606                         break;
607                 case 't' :
608                         type = gettype(optarg, NULL);
609                         if (type == IPLT_NONE) {
610                                 fprintf(stderr, "unknown type '%s'\n", optarg);
611                                 return -1;
612                         }
613                         break;
614                 case 'v' :
615                         opts |= OPT_VERBOSE;
616                         break;
617                 }
618
619         if (opts & OPT_DEBUG)
620                 fprintf(stderr, "poolflush: opts = %#x\n", opts);
621
622         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
623                 fd = open(IPLOOKUP_NAME, O_RDWR);
624                 if (fd == -1) {
625                         perror("open(IPLOOKUP_NAME)");
626                         exit(1);
627                 }
628         }
629
630         bzero((char *)&flush, sizeof(flush));
631         flush.iplf_type = type;
632         flush.iplf_unit = role;
633         flush.iplf_arg = arg;
634
635         if (!(opts & OPT_DONOTHING)) {
636                 if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
637                         perror("ioctl(SIOCLOOKUPFLUSH)");
638                         exit(1);
639                 }
640
641         }
642         printf("%zd object%s flushed\n", flush.iplf_count,
643                (flush.iplf_count == 1) ? "" : "s");
644
645         return 0;
646 }
647
648
649 int getrole(rolename)
650 char *rolename;
651 {
652         int role;
653
654         if (!strcasecmp(rolename, "ipf")) {
655                 role = IPL_LOGIPF;
656 #if 0
657         } else if (!strcasecmp(rolename, "nat")) {
658                 role = IPL_LOGNAT;
659         } else if (!strcasecmp(rolename, "state")) {
660                 role = IPL_LOGSTATE;
661         } else if (!strcasecmp(rolename, "auth")) {
662                 role = IPL_LOGAUTH;
663         } else if (!strcasecmp(rolename, "sync")) {
664                 role = IPL_LOGSYNC;
665         } else if (!strcasecmp(rolename, "scan")) {
666                 role = IPL_LOGSCAN;
667         } else if (!strcasecmp(rolename, "pool")) {
668                 role = IPL_LOGLOOKUP;
669         } else if (!strcasecmp(rolename, "count")) {
670                 role = IPL_LOGCOUNT;
671 #endif
672         } else {
673                 role = IPL_LOGNONE;
674         }
675
676         return role;
677 }
678
679
680 int gettype(typename, minor)
681 char *typename;
682 u_int *minor;
683 {
684         int type;
685
686         if (!strcasecmp(optarg, "tree")) {
687                 type = IPLT_POOL;
688         } else if (!strcasecmp(optarg, "hash")) {
689                 type = IPLT_HASH;
690                 if (minor != NULL)
691                         *minor = IPHASH_LOOKUP;
692         } else if (!strcasecmp(optarg, "group-map")) {
693                 type = IPLT_HASH;
694                 if (minor != NULL)
695                         *minor = IPHASH_GROUPMAP;
696         } else {
697                 type = IPLT_NONE;
698         }
699         return type;
700 }