ipfw3: shorten func show_filter and MACRO
[dragonfly.git] / lib / libipfw3 / basic / ipfw3_basic.c
blob25c4ae1103315abceb253c440268b7dd1ac57fdb
1 /*
2 * Copyright (c) 2014 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Bill Yuan <bycn82@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
35 #include <ctype.h>
36 #include <err.h>
37 #include <errno.h>
38 #include <grp.h>
39 #include <limits.h>
40 #include <netdb.h>
41 #include <pwd.h>
42 #include <signal.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <stdarg.h>
46 #include <string.h>
47 #include <sysexits.h>
48 #include <timeconv.h>
49 #include <unistd.h>
51 #include <netinet/in.h>
53 #include <arpa/inet.h>
54 #include <net/if.h>
55 #include <net/route.h>
56 #include <net/pfil.h>
58 #include "../../../sys/net/ipfw3/ip_fw3.h"
59 #include "../../../sbin/ipfw3/ipfw.h"
60 #include "ipfw3_basic.h"
63 #define IP_MASK_ALL 0xffffffff
65 * we use IPPROTO_ETHERTYPE as a fake protocol id to call the print routines
66 * This is only used in this code.
68 #define IPPROTO_ETHERTYPE 0x1000
71 struct char_int_map limit_types[] = {
72 { "src-addr", 1 },
73 { "src-port", 2 },
74 { "dst-addr", 3 },
75 { "dst-port", 4 },
76 { NULL, 0 }
79 static struct char_int_map ether_types[] = {
80 { "ip", 0x0800 },
81 { "ipv4", 0x0800 },
82 { "ipv6", 0x86dd },
83 { "arp", 0x0806 },
84 { "rarp", 0x8035 },
85 { "vlan", 0x8100 },
86 { "loop", 0x9000 },
87 { "trail", 0x1000 },
88 { "pppoe_disc", 0x8863 },
89 { "pppoe_sess", 0x8864 },
90 { "ipx_8022", 0x00E0 },
91 { "ipx_8023", 0x0000 },
92 { "ipx_ii", 0x8137 },
93 { "ipx_snap", 0x8137 },
94 { "ipx", 0x8137 },
95 { "ns", 0x0600 },
96 { NULL, 0 }
99 /**
100 * match_token takes a table and a string, returns the value associated
101 * with the string (0 meaning an error in most cases)
103 static int
104 match_token(struct char_int_map *table, char *string)
106 while (table->key) {
107 if (strcmp(table->key, string) == 0)
108 return table->val;
110 table++;
112 return 0;
115 static char *
116 match_token2(struct char_int_map *table, int val)
118 while (table->val) {
119 if (table->val == val)
120 return table->key;
122 table++;
124 return NULL;
127 static void
128 fill_iface(ipfw_insn_if *cmd, char *arg)
130 cmd->name[0] = '\0';
131 cmd->o.len |= F_INSN_SIZE(ipfw_insn_if);
133 /* Parse the interface or address */
134 if (!strcmp(arg, "any")){
135 cmd->o.len = 0;
136 } else if (!isdigit(*arg)) {
137 strlcpy(cmd->name, arg, sizeof(cmd->name));
138 cmd->p.glob = strpbrk(arg, "*?[") != NULL ? 1 : 0;
139 } else if (!inet_aton(arg, &cmd->p.ip))
140 errx(EX_DATAERR, "bad ip address ``%s''", arg);
143 static int
144 lookup_host (char *host, struct in_addr *ipaddr)
146 struct hostent *he;
148 if (!inet_aton(host, ipaddr)) {
149 if ((he = gethostbyname(host)) == NULL)
150 return(-1);
151 *ipaddr = *(struct in_addr *)he->h_addr_list[0];
153 return(0);
157 * Like strtol, but also translates service names into port numbers
158 * for some protocols.
159 * In particular:
160 * proto == -1 disables the protocol check;
161 * proto == IPPROTO_ETHERTYPE looks up an internal table
162 * proto == <some value in /etc/protocols> matches the values there.
163 * Returns *end == s in case the parameter is not found.
165 static int
166 strtoport(char *s, char **end, int base, int proto)
168 char *p, *buf;
169 char *s1;
170 int i;
172 *end = s; /* default - not found */
173 if ( *s == '\0')
174 return 0; /* not found */
176 if (isdigit(*s))
177 return strtol(s, end, base);
180 * find separator. '\\' escapes the next char.
182 for (s1 = s; *s1 && (isalnum(*s1) || *s1 == '\\') ; s1++) {
183 if (*s1 == '\\' && s1[1] != '\0')
184 s1++;
187 buf = malloc(s1 - s + 1);
188 if (buf == NULL)
189 return 0;
192 * copy into a buffer skipping backslashes
194 for (p = s, i = 0; p != s1 ; p++)
195 if ( *p != '\\')
196 buf[i++] = *p;
197 buf[i++] = '\0';
199 if (proto == IPPROTO_ETHERTYPE) {
200 i = match_token(ether_types, buf);
201 free(buf);
202 if (i != -1) { /* found */
203 *end = s1;
204 return i;
206 } else {
207 struct protoent *pe = NULL;
208 struct servent *se;
210 if (proto != 0)
211 pe = getprotobynumber(proto);
212 setservent(1);
213 se = getservbyname(buf, pe ? pe->p_name : NULL);
214 free(buf);
215 if (se != NULL) {
216 *end = s1;
217 return ntohs(se->s_port);
220 return 0; /* not found */
223 static int
224 contigmask(u_char *p, int len)
226 int i, n;
227 for (i=0; i<len ; i++) {
228 if ( (p[i/8] & (1 << (7 - (i%8)))) == 0) /* first bit unset */
229 break;
231 for (n=i+1; n < len; n++) {
232 if ( (p[n/8] & (1 << (7 - (n%8)))) != 0)
233 return -1; /* mask not contiguous */
235 return i;
238 static ipfw_insn *add_proto(ipfw_insn *cmd, char *av)
240 struct protoent *pe;
241 u_char proto = 0;
242 if (!strncmp(av, "all", strlen(av))) {
244 } else if ((proto = atoi(av)) > 0) {
246 } else if ((pe = getprotobyname(av)) != NULL) {
247 proto = pe->p_proto;
248 } else {
249 errx(EX_USAGE, "protocol `%s' not recognizable\n", av);
251 if (proto != IPPROTO_IP) {
252 cmd->opcode = O_BASIC_PROTO;
253 cmd->module = MODULE_BASIC_ID;
254 cmd->len = cmd->len|LEN_OF_IPFWINSN;
255 cmd->arg1 = proto;
257 return cmd;
260 void
261 parse_count(ipfw_insn **cmd, int *ac, char **av[])
263 (*cmd)->opcode = O_BASIC_COUNT;
264 (*cmd)->module = MODULE_BASIC_ID;
265 (*cmd)->len = LEN_OF_IPFWINSN;
266 NEXT_ARG1;
269 void
270 parse_skipto(ipfw_insn **cmd, int *ac, char **av[])
272 NEXT_ARG1;
273 (*cmd)->opcode = O_BASIC_SKIPTO;
274 (*cmd)->module = MODULE_BASIC_ID;
275 (*cmd)->len = LEN_OF_IPFWINSN;
276 (*cmd)->arg1 = strtoul(**av, NULL, 10);
277 NEXT_ARG1;
281 * cmd->arg3 is count of the destination
282 * cmd->arg1 is the type, random 0, round-robin 1, sticky 2
284 void
285 parse_forward(ipfw_insn **cmd, int *ac, char **av[])
287 ipfw_insn_sa *p = (ipfw_insn_sa *)(*cmd);
288 struct sockaddr_in *sa;
289 char *tok, *end = '\0';
290 char *str;
291 int count, port;
293 (*cmd)->opcode = O_BASIC_FORWARD;
294 NEXT_ARG1;
296 * multiple forward destinations are seperated by colon
297 * ip address and port are seperated by comma
298 * e.g. 192.168.1.1:80,192.168.1.2:8080
299 * 192.168.1.1,192.168.1.2 or keep the port the same
301 tok = strtok(**av, ",");
302 sa = &p->sa;
303 count = 0;
304 while (tok != NULL) {
305 sa->sin_len = sizeof(struct sockaddr_in);
306 sa->sin_family = AF_INET;
307 sa->sin_port = 0;
308 str = strchr(tok,':');
309 if (str != NULL) {
310 *(str++) = '\0';
311 port = strtoport(str, &end, 0, 0);
312 sa->sin_port = (u_short)port;
314 lookup_host(tok, &(sa->sin_addr));
315 tok = strtok (NULL, ",");
316 sa++;
317 count++;
319 (*cmd)->arg3 = count;
320 if (count == 0) {
321 errx(EX_DATAERR, "forward `%s' not recognizable", **av);
323 NEXT_ARG1;
324 if (count > 1) {
325 if (strcmp(**av, "round-robin") == 0) {
326 NEXT_ARG1;
327 (*cmd)->arg1 = 1;
328 } else if (strcmp(**av, "sticky") == 0) {
329 NEXT_ARG1;
330 (*cmd)->arg1 = 2;
331 } else {
332 /* random */
333 (*cmd)->arg1 = 0;
336 (*cmd)->len = LEN_OF_IPFWINSN + count * sizeof(struct sockaddr_in);
339 void
340 parse_in(ipfw_insn **cmd, int *ac, char **av[])
342 (*cmd)->opcode = O_BASIC_IN;
343 (*cmd)->module = MODULE_BASIC_ID;
344 (*cmd)->len = LEN_OF_IPFWINSN;
345 (*cmd)->arg1 = 0;
346 NEXT_ARG1;
349 void
350 parse_out(ipfw_insn **cmd, int *ac, char **av[])
352 (*cmd)->opcode = O_BASIC_OUT;
353 (*cmd)->module = MODULE_BASIC_ID;
354 (*cmd)->len = LEN_OF_IPFWINSN;
355 (*cmd)->arg1 = 0;
356 NEXT_ARG1;
360 void
361 parse_via(ipfw_insn **cmd, int *ac, char **av[])
363 (*cmd)->module = MODULE_BASIC_ID;
364 (*cmd)->len = LEN_OF_IPFWINSN;
365 if (strcmp(*av[0], "via")==0) {
366 (*cmd)->opcode = O_BASIC_VIA;
367 } else if (strcmp(*av[0], "xmit")==0) {
368 (*cmd)->opcode = O_BASIC_XMIT;
369 } else if (strcmp(*av[0], "recv")==0) {
370 (*cmd)->opcode = O_BASIC_RECV;
372 NEXT_ARG1;
373 fill_iface((ipfw_insn_if *)(*cmd), *av[0]);
374 NEXT_ARG1;
378 * Below formats are supported:
379 * from table 1 O_BASIC_IP_SRC_LOOKUP
380 * from any return 0 len instruction
381 * from me O_BASIC_IP_SRC_ME
382 * from 1.2.3.4 O_BASIC_IP_SRC
383 * from 1.2.3.4/24 O_BASIC_IP_SRC_MASK
385 void
386 parse_from(ipfw_insn **cmd, int *ac, char **av[])
388 ipfw_insn_ip *p = (ipfw_insn_ip *)(*cmd);
389 int i;
391 (*cmd)->module = MODULE_BASIC_ID;
392 NEXT_ARG1;
393 if (strcmp(**av, "table") == 0) {
394 NEXT_ARG1;
395 NEED(*ac, 1, "table id missing");
396 (*cmd)->len = F_INSN_SIZE(ipfw_insn);
397 (*cmd)->opcode = O_BASIC_IP_SRC_LOOKUP;
398 (*cmd)->arg1 = strtoul(**av, NULL, 10);
399 } else if (strcmp(**av, "any") == 0) {
400 (*cmd)->len &= ~F_LEN_MASK;
401 } else if (strcmp(**av, "me") == 0) {
402 (*cmd)->len |= F_INSN_SIZE(ipfw_insn);
403 (*cmd)->opcode = O_BASIC_IP_SRC_ME;
404 } else {
405 char *c = NULL, md = 0;
406 c = strchr(**av, '/');
407 if (c) {
408 md = *c;
409 *c++ = '\0';
411 if (lookup_host(**av, &p->addr) != 0)
412 errx(EX_NOHOST, "hostname ``%s'' unknown", **av);
413 switch (md) {
414 case '/':
415 i = atoi(c);
416 if (i == 0)
417 p->mask.s_addr = htonl(0);
418 else if (i > 32)
419 errx(EX_DATAERR, "bad width ``%s''", c);
420 else
421 p->mask.s_addr = htonl(~0 << (32 - i));
422 break;
423 default:
424 p->mask.s_addr = htonl(~0);
425 break;
427 p->addr.s_addr &= p->mask.s_addr;
428 if (p->mask.s_addr == 0) {
429 /* high kneel */
430 } else if (p->mask.s_addr == IP_MASK_ALL) {
431 (*cmd)->len |= F_INSN_SIZE(ipfw_insn_u32);
432 (*cmd)->opcode = O_BASIC_IP_SRC;
433 } else {
434 (*cmd)->len |= F_INSN_SIZE(ipfw_insn_ip);
435 (*cmd)->opcode = O_BASIC_IP_SRC_MASK;
438 NEXT_ARG1;
441 void
442 parse_to(ipfw_insn **cmd, int *ac, char **av[])
444 ipfw_insn_ip *p = (ipfw_insn_ip *)(*cmd);
445 int i;
447 (*cmd)->module = MODULE_BASIC_ID;
448 NEXT_ARG1;
449 if (strcmp(**av, "table") == 0) {
450 NEXT_ARG1;
451 NEED(*ac, 1, "table id missing");
452 (*cmd)->len = F_INSN_SIZE(ipfw_insn);
453 (*cmd)->opcode = O_BASIC_IP_DST_LOOKUP;
454 (*cmd)->arg1 = strtoul(**av, NULL, 10);
455 }else if (strcmp(**av, "any") == 0) {
456 (*cmd)->len &= ~F_LEN_MASK;
457 } else if (strcmp(**av, "me") == 0) {
458 (*cmd)->len |= F_INSN_SIZE(ipfw_insn);
459 (*cmd)->opcode = O_BASIC_IP_DST_ME;
460 } else {
461 char *c = NULL, md = 0;
462 c = strchr(**av, '/');
463 if (c) {
464 md = *c;
465 *c++ = '\0';
467 if (lookup_host(**av, &p->addr) != 0)
468 errx(EX_NOHOST, "hostname ``%s'' unknown", **av);
469 switch (md) {
470 case '/':
471 i = atoi(c);
472 if (i == 0)
473 p->mask.s_addr = htonl(0);
474 else if (i > 32)
475 errx(EX_DATAERR, "bad width ``%s''", c);
476 else
477 p->mask.s_addr = htonl(~0 << (32 - i));
478 break;
479 default:
480 p->mask.s_addr = htonl(~0);
481 break;
483 p->addr.s_addr &= p->mask.s_addr;
484 if (p->mask.s_addr == 0) {
485 /* high kneel */
486 } else if (p->mask.s_addr == IP_MASK_ALL) {
487 (*cmd)->len |= F_INSN_SIZE(ipfw_insn_u32);
488 (*cmd)->opcode = O_BASIC_IP_DST;
489 } else {
490 (*cmd)->len |= F_INSN_SIZE(ipfw_insn_ip);
491 (*cmd)->opcode = O_BASIC_IP_DST_MASK;
494 NEXT_ARG1;
497 void
498 parse_proto(ipfw_insn **cmd, int *ac, char **av[])
500 add_proto(*cmd, **av);
501 NEXT_ARG1;
504 void
505 parse_prob(ipfw_insn **cmd, int *ac, char **av[])
507 NEXT_ARG1;
508 (*cmd)->opcode = O_BASIC_PROB;
509 (*cmd)->module = MODULE_BASIC_ID;
510 (*cmd)->len = LEN_OF_IPFWINSN;
511 (*cmd)->arg1 = strtoul(**av, NULL, 10);
512 NEXT_ARG1;
515 void
516 parse_keep_state(ipfw_insn **cmd, int *ac, char **av[])
518 NEXT_ARG1;
519 (*cmd)->opcode = O_BASIC_KEEP_STATE;
520 (*cmd)->module = MODULE_BASIC_ID;
521 (*cmd)->len = LEN_OF_IPFWINSN;
522 if (strcmp(**av, "limit") == 0) {
523 NEXT_ARG1;
524 (*cmd)->arg3 = match_token(limit_types, **av);
525 if ((*cmd)->arg3 == 0)
526 errx(EX_DATAERR, "limit `%s' not recognizable", **av);
528 NEXT_ARG1;
529 (*cmd)->arg1 = strtoul(**av, NULL, 10);
530 if ((*cmd)->arg1 == 0)
531 errx(EX_DATAERR, "bad limit `%s'", **av);
533 NEXT_ARG1;
535 if (strcmp(**av, "live") == 0) {
536 NEXT_ARG1;
537 (*cmd)->arg2 = strtoul(**av, NULL, 10);
538 NEXT_ARG1;
542 void
543 parse_check_state(ipfw_insn **cmd, int *ac, char **av[])
545 NEXT_ARG1;
546 (*cmd)->opcode = O_BASIC_CHECK_STATE;
547 (*cmd)->module = MODULE_BASIC_ID;
548 (*cmd)->len = LEN_OF_IPFWINSN;
551 void
552 parse_tagged(ipfw_insn **cmd, int *ac, char **av[])
554 NEXT_ARG1;
555 (*cmd)->opcode = O_BASIC_TAGGED;
556 (*cmd)->module = MODULE_BASIC_ID;
557 (*cmd)->len = LEN_OF_IPFWINSN;
558 (*cmd)->arg1 = strtoul(**av, NULL, 10);
559 NEXT_ARG1;
562 void
563 parse_comment(ipfw_insn **cmd, int *ac, char **av[])
565 int l = 0;
566 char *p = (char *)((*cmd) + 1);
568 NEXT_ARG1;
569 (*cmd)->opcode = O_BASIC_COMMENT;
570 (*cmd)->module = MODULE_BASIC_ID;
572 while (*ac > 0) {
573 l += strlen(**av) + 1;
574 if (l > 84) {
575 errx(EX_DATAERR, "comment too long (max 80 chars)");
577 strcpy(p, **av);
578 p += strlen(**av);
579 *p++ = ' ';
580 NEXT_ARG1;
582 l = 1 + (l + 3) / 4;
583 (*cmd)->len = l;
584 *(--p) = '\0';
587 void
588 parse_tag(ipfw_insn **cmd, int *ac, char **av[])
590 NEXT_ARG1;
591 (*cmd)->opcode = O_BASIC_TAG;
592 (*cmd)->module = MODULE_BASIC_ID;
593 (*cmd)->len = LEN_OF_IPFWINSN;
594 (*cmd)->arg1 = strtoul(**av, NULL, 10);
595 NEXT_ARG1;
598 void
599 parse_untag(ipfw_insn **cmd, int *ac, char **av[])
601 NEXT_ARG1;
602 (*cmd)->opcode = O_BASIC_UNTAG;
603 (*cmd)->module = MODULE_BASIC_ID;
604 (*cmd)->len = LEN_OF_IPFWINSN;
605 (*cmd)->arg1 = strtoul(**av, NULL, 10);
606 NEXT_ARG1;
609 void
610 show_count(ipfw_insn *cmd, int show_or)
612 printf(" count");
615 void
616 show_skipto(ipfw_insn *cmd, int show_or)
618 printf(" skipto %u", cmd->arg1);
621 void
622 show_forward(ipfw_insn *cmd, int show_or)
624 struct sockaddr_in *sa;
625 int i;
627 ipfw_insn_sa *s = (ipfw_insn_sa *)cmd;
628 sa = &s->sa;
629 printf(" forward");
630 for (i = 0; i < cmd->arg3; i++){
631 if (i > 0)
632 printf(",");
633 else
634 printf(" ");
636 printf("%s", inet_ntoa(sa->sin_addr));
637 if (sa->sin_port != 0)
638 printf(":%d", sa->sin_port);
640 sa++;
642 if (cmd->arg1 == 1)
643 printf(" round-robin");
644 else if (cmd->arg1 == 2)
645 printf(" sticky");
649 void
650 show_in(ipfw_insn *cmd, int show_or)
652 printf(" in");
655 void
656 show_out(ipfw_insn *cmd, int show_or)
658 printf(" out");
661 void
662 show_via(ipfw_insn *cmd, int show_or)
664 char *s;
665 ipfw_insn_if *cmdif = (ipfw_insn_if *)cmd;
667 if ((int)cmd->opcode == O_BASIC_XMIT)
668 s = "xmit";
669 else if ((int)cmd->opcode == O_BASIC_RECV)
670 s = "recv";
671 else if ((int)cmd->opcode == O_BASIC_VIA)
672 s = "via";
673 else
674 s = "?huh?";
675 if (show_or)
676 s = "or";
677 if (cmdif->name[0] == '\0')
678 printf(" %s %s", s, inet_ntoa(cmdif->p.ip));
680 printf(" %s %s", s, cmdif->name);
683 void
684 show_from(ipfw_insn *cmd, int show_or)
686 char *word = "from";
687 if (show_or)
688 word = "or";
689 printf(" %s %s", word, inet_ntoa(((ipfw_insn_ip *)cmd)->addr));
692 void
693 show_from_lookup(ipfw_insn *cmd, int show_or)
695 char *word = "from";
696 if (show_or)
697 word = "or";
698 printf(" %s table %d", word, cmd->arg1);
701 void
702 show_from_me(ipfw_insn *cmd, int show_or)
704 char *word = "from";
705 if (show_or)
706 word = "or";
707 printf(" %s me", word);
710 void
711 show_from_mask(ipfw_insn *cmd, int show_or)
713 int mask;
714 char *word = "from";
715 if (show_or)
716 word = "or";
717 ipfw_insn_ip *p = (ipfw_insn_ip *)cmd;
718 printf(" %s %s", word, inet_ntoa(p->addr));
720 mask = contigmask((u_char *)&(p->mask.s_addr), 32);
721 if (mask < 32)
722 printf("/%d", mask);
725 void
726 show_to(ipfw_insn *cmd, int show_or)
728 char *word = "to";
729 if (show_or)
730 word = "or";
731 printf(" %s %s", word, inet_ntoa(((ipfw_insn_ip *)cmd)->addr));
734 void
735 show_to_lookup(ipfw_insn *cmd, int show_or)
737 char *word = "to";
738 if (show_or)
739 word = "or";
740 printf(" %s table %d", word, cmd->arg1);
743 void
744 show_to_me(ipfw_insn *cmd, int show_or)
746 char *word = "to";
747 if (show_or)
748 word = "or";
749 printf(" %s me", word);
752 void
753 show_to_mask(ipfw_insn *cmd, int show_or)
755 int mask;
756 char *word = "to";
757 if (show_or)
758 word = "or";
759 ipfw_insn_ip *p = (ipfw_insn_ip *)cmd;
760 printf(" %s %s", word, inet_ntoa(p->addr));
762 mask = contigmask((u_char *)&(p->mask.s_addr), 32);
763 if (mask < 32)
764 printf("/%d", mask);
767 void
768 show_proto(ipfw_insn *cmd, int show_or)
770 struct protoent *pe;
771 u_char proto = 0;
772 proto = cmd->arg1;
773 pe = getprotobynumber(cmd->arg1);
774 printf(" %s", pe->p_name);
777 void
778 show_prob(ipfw_insn *cmd, int show_or)
780 printf(" prob %d%%", cmd->arg1);
783 void
784 show_keep_state(ipfw_insn *cmd, int show_or)
786 printf(" keep-state");
787 if (cmd->arg1 != 0) {
788 char *type=match_token2(limit_types, cmd->arg3);
789 printf(" limit %s %d", type, cmd->arg1);
791 if (cmd->arg2 != 0) {
792 printf(" live %d", cmd->arg2);
796 void
797 show_check_state(ipfw_insn *cmd, int show_or)
799 printf(" check-state");
802 void
803 show_tagged(ipfw_insn *cmd, int show_or)
805 printf(" tagged %d", cmd->arg1);
808 void
809 show_comment(ipfw_insn *cmd, int show_or)
811 printf(" // %s", (char *)(cmd + 1));
814 void
815 show_tag(ipfw_insn *cmd, int show_or)
817 printf(" tag %d", cmd->arg1);
820 void
821 show_untag(ipfw_insn *cmd, int show_or)
823 printf(" untag %d", cmd->arg1);
826 void
827 load_module(register_func function, register_keyword keyword)
829 keyword(MODULE_BASIC_ID, O_BASIC_COUNT, "count", ACTION);
830 function(MODULE_BASIC_ID, O_BASIC_COUNT,
831 (parser_func)parse_count, (shower_func)show_count);
833 keyword(MODULE_BASIC_ID, O_BASIC_SKIPTO, "skipto", ACTION);
834 function(MODULE_BASIC_ID, O_BASIC_SKIPTO,
835 (parser_func)parse_skipto, (shower_func)show_skipto);
837 keyword(MODULE_BASIC_ID, O_BASIC_FORWARD, "forward", ACTION);
838 function(MODULE_BASIC_ID, O_BASIC_FORWARD,
839 (parser_func)parse_forward, (shower_func)show_forward);
841 keyword(MODULE_BASIC_ID, O_BASIC_IN, "in", FILTER);
842 function(MODULE_BASIC_ID, O_BASIC_IN,
843 (parser_func)parse_in, (shower_func)show_in);
845 keyword(MODULE_BASIC_ID, O_BASIC_OUT, "out", FILTER);
846 function(MODULE_BASIC_ID, O_BASIC_OUT,
847 (parser_func)parse_out, (shower_func)show_out);
849 keyword(MODULE_BASIC_ID, O_BASIC_VIA, "via", FILTER);
850 function(MODULE_BASIC_ID, O_BASIC_VIA,
851 (parser_func)parse_via, (shower_func)show_via);
853 keyword(MODULE_BASIC_ID, O_BASIC_XMIT, "xmit", FILTER);
854 function(MODULE_BASIC_ID, O_BASIC_XMIT,
855 (parser_func)parse_via, (shower_func)show_via);
857 keyword(MODULE_BASIC_ID, O_BASIC_RECV, "recv", FILTER);
858 function(MODULE_BASIC_ID, O_BASIC_RECV,
859 (parser_func)parse_via, (shower_func)show_via);
861 keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC, "from", FROM);
862 function(MODULE_BASIC_ID, O_BASIC_IP_SRC,
863 (parser_func)parse_from, (shower_func)show_from);
865 keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC_LOOKUP, "[from table]", FROM);
866 function(MODULE_BASIC_ID, O_BASIC_IP_SRC_LOOKUP,
867 (parser_func)parse_from, (shower_func)show_from_lookup);
869 keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC_ME, "[from me]", FROM);
870 function(MODULE_BASIC_ID, O_BASIC_IP_SRC_ME,
871 (parser_func)parse_from, (shower_func)show_from_me);
872 keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC_MASK, "[from mask]", FROM);
873 function(MODULE_BASIC_ID, O_BASIC_IP_SRC_MASK,
874 (parser_func)parse_from, (shower_func)show_from_mask);
875 keyword(MODULE_BASIC_ID, O_BASIC_IP_DST, "to", TO);
876 function(MODULE_BASIC_ID, O_BASIC_IP_DST,
877 (parser_func)parse_to, (shower_func)show_to);
879 keyword(MODULE_BASIC_ID, O_BASIC_IP_DST_LOOKUP, "[to table]", TO);
880 function(MODULE_BASIC_ID, O_BASIC_IP_DST_LOOKUP,
881 (parser_func)parse_to, (shower_func)show_to_lookup);
883 keyword(MODULE_BASIC_ID, O_BASIC_IP_DST_ME, "[to me]", TO);
884 function(MODULE_BASIC_ID, O_BASIC_IP_DST_ME,
885 (parser_func)parse_to, (shower_func)show_to_me);
886 keyword(MODULE_BASIC_ID, O_BASIC_IP_DST_MASK, "[to mask]", TO);
887 function(MODULE_BASIC_ID, O_BASIC_IP_DST_MASK,
888 (parser_func)parse_to, (shower_func)show_to_mask);
890 keyword(MODULE_BASIC_ID, O_BASIC_PROTO, "proto", PROTO);
891 function(MODULE_BASIC_ID, O_BASIC_PROTO,
892 (parser_func)parse_proto, (shower_func)show_proto);
894 keyword(MODULE_BASIC_ID, O_BASIC_PROB, "prob", FILTER);
895 function(MODULE_BASIC_ID, O_BASIC_PROB,
896 (parser_func)parse_prob, (shower_func)show_prob);
898 keyword(MODULE_BASIC_ID, O_BASIC_KEEP_STATE, "keep-state", FILTER);
899 function(MODULE_BASIC_ID, O_BASIC_KEEP_STATE,
900 (parser_func)parse_keep_state,
901 (shower_func)show_keep_state);
903 keyword(MODULE_BASIC_ID, O_BASIC_CHECK_STATE, "check-state", ACTION);
904 function(MODULE_BASIC_ID, O_BASIC_CHECK_STATE,
905 (parser_func)parse_check_state,
906 (shower_func)show_check_state);
908 keyword(MODULE_BASIC_ID, O_BASIC_TAG, "tag", ACTION);
909 function(MODULE_BASIC_ID, O_BASIC_TAG,
910 (parser_func)parse_tag, (shower_func)show_tag);
912 keyword(MODULE_BASIC_ID, O_BASIC_UNTAG, "untag", ACTION);
913 function(MODULE_BASIC_ID, O_BASIC_UNTAG,
914 (parser_func)parse_untag, (shower_func)show_untag);
916 keyword(MODULE_BASIC_ID, O_BASIC_TAGGED, "tagged", FILTER);
917 function(MODULE_BASIC_ID, O_BASIC_TAGGED,
918 (parser_func)parse_tagged, (shower_func)show_tagged);
920 keyword(MODULE_BASIC_ID, O_BASIC_COMMENT, "//", AFTER);
921 function(MODULE_BASIC_ID, O_BASIC_COMMENT,
922 (parser_func)parse_comment, (shower_func)show_comment);