16a03354eSMatthew Dillon /*
24408d548SBill Yuan * Copyright (c) 2014 - 2018 The DragonFly Project. All rights reserved.
36a03354eSMatthew Dillon *
46a03354eSMatthew Dillon * This code is derived from software contributed to The DragonFly Project
59187b359SBill Yuan * by Bill Yuan <bycn82@dragonflybsd.org>
66a03354eSMatthew Dillon *
76a03354eSMatthew Dillon * Redistribution and use in source and binary forms, with or without
86a03354eSMatthew Dillon * modification, are permitted provided that the following conditions
96a03354eSMatthew Dillon * are met:
106a03354eSMatthew Dillon *
116a03354eSMatthew Dillon * 1. Redistributions of source code must retain the above copyright
126a03354eSMatthew Dillon * notice, this list of conditions and the following disclaimer.
136a03354eSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright
146a03354eSMatthew Dillon * notice, this list of conditions and the following disclaimer in
156a03354eSMatthew Dillon * the documentation and/or other materials provided with the
166a03354eSMatthew Dillon * distribution.
176a03354eSMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its
186a03354eSMatthew Dillon * contributors may be used to endorse or promote products derived
196a03354eSMatthew Dillon * from this software without specific, prior written permission.
206a03354eSMatthew Dillon *
216a03354eSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
226a03354eSMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
236a03354eSMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
246a03354eSMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
256a03354eSMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
266a03354eSMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
276a03354eSMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
286a03354eSMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
296a03354eSMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
306a03354eSMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
316a03354eSMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
326a03354eSMatthew Dillon * SUCH DAMAGE.
336a03354eSMatthew Dillon */
346a03354eSMatthew Dillon
356a03354eSMatthew Dillon #include <ctype.h>
366a03354eSMatthew Dillon #include <err.h>
376a03354eSMatthew Dillon #include <errno.h>
386a03354eSMatthew Dillon #include <grp.h>
396a03354eSMatthew Dillon #include <limits.h>
406a03354eSMatthew Dillon #include <netdb.h>
416a03354eSMatthew Dillon #include <pwd.h>
426a03354eSMatthew Dillon #include <signal.h>
436a03354eSMatthew Dillon #include <stdio.h>
446a03354eSMatthew Dillon #include <stdlib.h>
456a03354eSMatthew Dillon #include <stdarg.h>
466a03354eSMatthew Dillon #include <string.h>
476a03354eSMatthew Dillon #include <sysexits.h>
486a03354eSMatthew Dillon #include <timeconv.h>
496a03354eSMatthew Dillon #include <unistd.h>
506a03354eSMatthew Dillon
516a03354eSMatthew Dillon #include <netinet/in.h>
526a03354eSMatthew Dillon
536a03354eSMatthew Dillon #include <arpa/inet.h>
546a03354eSMatthew Dillon #include <net/if.h>
556a03354eSMatthew Dillon #include <net/route.h>
566a03354eSMatthew Dillon #include <net/pfil.h>
576a03354eSMatthew Dillon
5859ea0e34SBill Yuan #include <net/ipfw3/ip_fw3.h>
599187b359SBill Yuan #include "../../../sbin/ipfw3/ipfw3.h"
606a03354eSMatthew Dillon #include "ipfw3_basic.h"
616a03354eSMatthew Dillon
626a03354eSMatthew Dillon
636a03354eSMatthew Dillon #define IP_MASK_ALL 0xffffffff
646a03354eSMatthew Dillon /*
656a03354eSMatthew Dillon * we use IPPROTO_ETHERTYPE as a fake protocol id to call the print routines
666a03354eSMatthew Dillon * This is only used in this code.
676a03354eSMatthew Dillon */
686a03354eSMatthew Dillon #define IPPROTO_ETHERTYPE 0x1000
696a03354eSMatthew Dillon
706a03354eSMatthew Dillon
716a03354eSMatthew Dillon struct char_int_map limit_types[] = {
726a03354eSMatthew Dillon { "src-addr", 1 },
736a03354eSMatthew Dillon { "src-port", 2 },
746a03354eSMatthew Dillon { "dst-addr", 3 },
756a03354eSMatthew Dillon { "dst-port", 4 },
766a03354eSMatthew Dillon { NULL, 0 }
776a03354eSMatthew Dillon };
786a03354eSMatthew Dillon
796a03354eSMatthew Dillon static struct char_int_map ether_types[] = {
806a03354eSMatthew Dillon { "ip", 0x0800 },
816a03354eSMatthew Dillon { "ipv4", 0x0800 },
826a03354eSMatthew Dillon { "ipv6", 0x86dd },
836a03354eSMatthew Dillon { "arp", 0x0806 },
846a03354eSMatthew Dillon { "rarp", 0x8035 },
856a03354eSMatthew Dillon { "vlan", 0x8100 },
866a03354eSMatthew Dillon { "loop", 0x9000 },
876a03354eSMatthew Dillon { "trail", 0x1000 },
886a03354eSMatthew Dillon { "pppoe_disc", 0x8863 },
896a03354eSMatthew Dillon { "pppoe_sess", 0x8864 },
906a03354eSMatthew Dillon { "ipx_8022", 0x00E0 },
916a03354eSMatthew Dillon { "ipx_8023", 0x0000 },
926a03354eSMatthew Dillon { "ipx_ii", 0x8137 },
936a03354eSMatthew Dillon { "ipx_snap", 0x8137 },
946a03354eSMatthew Dillon { "ipx", 0x8137 },
956a03354eSMatthew Dillon { "ns", 0x0600 },
966a03354eSMatthew Dillon { NULL, 0 }
976a03354eSMatthew Dillon };
986a03354eSMatthew Dillon
996a03354eSMatthew Dillon
1002ca766abSBill Yuan int
match_token(struct char_int_map * table,char * string)1012ca766abSBill Yuan match_token(struct char_int_map *table, char *string)
1022ca766abSBill Yuan {
1032ca766abSBill Yuan while (table->key) {
1042ca766abSBill Yuan if (strcmp(table->key, string) == 0) {
1052ca766abSBill Yuan return table->val;
1062ca766abSBill Yuan }
1072ca766abSBill Yuan table++;
1082ca766abSBill Yuan }
1092ca766abSBill Yuan return 0;
1102ca766abSBill Yuan }
1116a03354eSMatthew Dillon
1126a03354eSMatthew Dillon static char *
match_token2(struct char_int_map * table,int val)1136a03354eSMatthew Dillon match_token2(struct char_int_map *table, int val)
1146a03354eSMatthew Dillon {
1156a03354eSMatthew Dillon while (table->val) {
1166a03354eSMatthew Dillon if (table->val == val)
1176a03354eSMatthew Dillon return table->key;
1186a03354eSMatthew Dillon
1196a03354eSMatthew Dillon table++;
1206a03354eSMatthew Dillon }
1216a03354eSMatthew Dillon return NULL;
1226a03354eSMatthew Dillon };
1236a03354eSMatthew Dillon
1246a03354eSMatthew Dillon static void
fill_iface(ipfw_insn_if * cmd,char * arg)1256a03354eSMatthew Dillon fill_iface(ipfw_insn_if *cmd, char *arg)
1266a03354eSMatthew Dillon {
1276a03354eSMatthew Dillon cmd->name[0] = '\0';
1286a03354eSMatthew Dillon cmd->o.len |= F_INSN_SIZE(ipfw_insn_if);
1296a03354eSMatthew Dillon
1306a03354eSMatthew Dillon /* Parse the interface or address */
1316a03354eSMatthew Dillon if (!strcmp(arg, "any")){
1326a03354eSMatthew Dillon cmd->o.len = 0;
1336a03354eSMatthew Dillon } else if (!isdigit(*arg)) {
1346a03354eSMatthew Dillon strlcpy(cmd->name, arg, sizeof(cmd->name));
1356a03354eSMatthew Dillon cmd->p.glob = strpbrk(arg, "*?[") != NULL ? 1 : 0;
1366a03354eSMatthew Dillon } else if (!inet_aton(arg, &cmd->p.ip))
1376a03354eSMatthew Dillon errx(EX_DATAERR, "bad ip address ``%s''", arg);
1386a03354eSMatthew Dillon }
1396a03354eSMatthew Dillon
1406a03354eSMatthew Dillon static int
lookup_host(char * host,struct in_addr * ipaddr)1416a03354eSMatthew Dillon lookup_host (char *host, struct in_addr *ipaddr)
1426a03354eSMatthew Dillon {
1436a03354eSMatthew Dillon struct hostent *he;
1446a03354eSMatthew Dillon
1456a03354eSMatthew Dillon if (!inet_aton(host, ipaddr)) {
1466a03354eSMatthew Dillon if ((he = gethostbyname(host)) == NULL)
1478b5a5700SBill Yuan return -1;
1486a03354eSMatthew Dillon *ipaddr = *(struct in_addr *)he->h_addr_list[0];
1496a03354eSMatthew Dillon }
150dd95fb5dSBill Yuan return 0;
1516a03354eSMatthew Dillon }
1526a03354eSMatthew Dillon
1536a03354eSMatthew Dillon /*
1546a03354eSMatthew Dillon * Like strtol, but also translates service names into port numbers
1556a03354eSMatthew Dillon * for some protocols.
1566a03354eSMatthew Dillon * In particular:
1576a03354eSMatthew Dillon * proto == -1 disables the protocol check;
1586a03354eSMatthew Dillon * proto == IPPROTO_ETHERTYPE looks up an internal table
1596a03354eSMatthew Dillon * proto == <some value in /etc/protocols> matches the values there.
1606a03354eSMatthew Dillon * Returns *end == s in case the parameter is not found.
1616a03354eSMatthew Dillon */
1626a03354eSMatthew Dillon static int
strtoport(char * s,char ** end,int base,int proto)1636a03354eSMatthew Dillon strtoport(char *s, char **end, int base, int proto)
1646a03354eSMatthew Dillon {
1656a03354eSMatthew Dillon char *p, *buf;
1666a03354eSMatthew Dillon char *s1;
1676a03354eSMatthew Dillon int i;
1686a03354eSMatthew Dillon
1696a03354eSMatthew Dillon *end = s; /* default - not found */
1706a03354eSMatthew Dillon if ( *s == '\0')
1716a03354eSMatthew Dillon return 0; /* not found */
1726a03354eSMatthew Dillon
1736a03354eSMatthew Dillon if (isdigit(*s))
1746a03354eSMatthew Dillon return strtol(s, end, base);
1756a03354eSMatthew Dillon
1766a03354eSMatthew Dillon /*
1776a03354eSMatthew Dillon * find separator. '\\' escapes the next char.
1786a03354eSMatthew Dillon */
1796a03354eSMatthew Dillon for (s1 = s; *s1 && (isalnum(*s1) || *s1 == '\\') ; s1++) {
1806a03354eSMatthew Dillon if (*s1 == '\\' && s1[1] != '\0')
1816a03354eSMatthew Dillon s1++;
1826a03354eSMatthew Dillon }
1836a03354eSMatthew Dillon
1846a03354eSMatthew Dillon buf = malloc(s1 - s + 1);
1856a03354eSMatthew Dillon if (buf == NULL)
1866a03354eSMatthew Dillon return 0;
1876a03354eSMatthew Dillon
1886a03354eSMatthew Dillon /*
1896a03354eSMatthew Dillon * copy into a buffer skipping backslashes
1906a03354eSMatthew Dillon */
1916a03354eSMatthew Dillon for (p = s, i = 0; p != s1 ; p++)
1926a03354eSMatthew Dillon if ( *p != '\\')
1936a03354eSMatthew Dillon buf[i++] = *p;
1946a03354eSMatthew Dillon buf[i++] = '\0';
1956a03354eSMatthew Dillon
1966a03354eSMatthew Dillon if (proto == IPPROTO_ETHERTYPE) {
1976a03354eSMatthew Dillon i = match_token(ether_types, buf);
1986a03354eSMatthew Dillon free(buf);
1996a03354eSMatthew Dillon if (i != -1) { /* found */
2006a03354eSMatthew Dillon *end = s1;
2016a03354eSMatthew Dillon return i;
2026a03354eSMatthew Dillon }
2036a03354eSMatthew Dillon } else {
2046a03354eSMatthew Dillon struct protoent *pe = NULL;
2056a03354eSMatthew Dillon struct servent *se;
2066a03354eSMatthew Dillon
2076a03354eSMatthew Dillon if (proto != 0)
2086a03354eSMatthew Dillon pe = getprotobynumber(proto);
2096a03354eSMatthew Dillon setservent(1);
2106a03354eSMatthew Dillon se = getservbyname(buf, pe ? pe->p_name : NULL);
2116a03354eSMatthew Dillon free(buf);
2126a03354eSMatthew Dillon if (se != NULL) {
2136a03354eSMatthew Dillon *end = s1;
2146a03354eSMatthew Dillon return ntohs(se->s_port);
2156a03354eSMatthew Dillon }
2166a03354eSMatthew Dillon }
2176a03354eSMatthew Dillon return 0; /* not found */
2186a03354eSMatthew Dillon }
2196a03354eSMatthew Dillon
2206a03354eSMatthew Dillon static int
contigmask(u_char * p,int len)2216a03354eSMatthew Dillon contigmask(u_char *p, int len)
2226a03354eSMatthew Dillon {
2236a03354eSMatthew Dillon int i, n;
2246a03354eSMatthew Dillon for (i=0; i<len ; i++) {
2256a03354eSMatthew Dillon if ( (p[i/8] & (1 << (7 - (i%8)))) == 0) /* first bit unset */
2266a03354eSMatthew Dillon break;
2276a03354eSMatthew Dillon }
2286a03354eSMatthew Dillon for (n=i+1; n < len; n++) {
2296a03354eSMatthew Dillon if ( (p[n/8] & (1 << (7 - (n%8)))) != 0)
2306a03354eSMatthew Dillon return -1; /* mask not contiguous */
2316a03354eSMatthew Dillon }
2326a03354eSMatthew Dillon return i;
2336a03354eSMatthew Dillon }
2346a03354eSMatthew Dillon
2355f62bb52SBill Yuan static ipfw_insn
add_proto(ipfw_insn * cmd,char * av)2365f62bb52SBill Yuan *add_proto(ipfw_insn *cmd, char *av)
2376a03354eSMatthew Dillon {
2386a03354eSMatthew Dillon struct protoent *pe;
2396a03354eSMatthew Dillon u_char proto = 0;
2406a03354eSMatthew Dillon if (!strncmp(av, "all", strlen(av))) {
2416a03354eSMatthew Dillon ;
2426a03354eSMatthew Dillon } else if ((proto = atoi(av)) > 0) {
2436a03354eSMatthew Dillon ;
2446a03354eSMatthew Dillon } else if ((pe = getprotobyname(av)) != NULL) {
2456a03354eSMatthew Dillon proto = pe->p_proto;
2466a03354eSMatthew Dillon } else {
2476a03354eSMatthew Dillon errx(EX_USAGE, "protocol `%s' not recognizable\n", av);
2486a03354eSMatthew Dillon }
2496a03354eSMatthew Dillon if (proto != IPPROTO_IP) {
2506a03354eSMatthew Dillon cmd->opcode = O_BASIC_PROTO;
2516a03354eSMatthew Dillon cmd->module = MODULE_BASIC_ID;
2525f62bb52SBill Yuan cmd->len |= LEN_OF_IPFWINSN;
2536a03354eSMatthew Dillon cmd->arg1 = proto;
2546a03354eSMatthew Dillon }
2556a03354eSMatthew Dillon return cmd;
2566a03354eSMatthew Dillon }
2576a03354eSMatthew Dillon
2586a03354eSMatthew Dillon void
parse_count(ipfw_insn ** cmd,int * ac,char ** av[])2596a03354eSMatthew Dillon parse_count(ipfw_insn **cmd, int *ac, char **av[])
2606a03354eSMatthew Dillon {
2616a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_COUNT;
2626a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
2635f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
2646a03354eSMatthew Dillon NEXT_ARG1;
2656a03354eSMatthew Dillon }
2666a03354eSMatthew Dillon
2676a03354eSMatthew Dillon void
parse_skipto(ipfw_insn ** cmd,int * ac,char ** av[])2686a03354eSMatthew Dillon parse_skipto(ipfw_insn **cmd, int *ac, char **av[])
2696a03354eSMatthew Dillon {
2706a03354eSMatthew Dillon NEXT_ARG1;
2716a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_SKIPTO;
2726a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
2735f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
2746a03354eSMatthew Dillon (*cmd)->arg1 = strtoul(**av, NULL, 10);
2756a03354eSMatthew Dillon NEXT_ARG1;
2766a03354eSMatthew Dillon }
2776a03354eSMatthew Dillon
2786a03354eSMatthew Dillon /*
2796a03354eSMatthew Dillon * cmd->arg3 is count of the destination
2806a03354eSMatthew Dillon * cmd->arg1 is the type, random 0, round-robin 1, sticky 2
2816a03354eSMatthew Dillon */
2826a03354eSMatthew Dillon void
parse_forward(ipfw_insn ** cmd,int * ac,char ** av[])2836a03354eSMatthew Dillon parse_forward(ipfw_insn **cmd, int *ac, char **av[])
2846a03354eSMatthew Dillon {
2856a03354eSMatthew Dillon ipfw_insn_sa *p = (ipfw_insn_sa *)(*cmd);
2866a03354eSMatthew Dillon struct sockaddr_in *sa;
287*10f846f5SSascha Wildner char *tok, *end = NULL;
2886a03354eSMatthew Dillon char *str;
2896a03354eSMatthew Dillon int count, port;
2906a03354eSMatthew Dillon
2916a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_FORWARD;
2926a03354eSMatthew Dillon NEXT_ARG1;
2936a03354eSMatthew Dillon /*
2946a03354eSMatthew Dillon * multiple forward destinations are seperated by colon
2956a03354eSMatthew Dillon * ip address and port are seperated by comma
2966a03354eSMatthew Dillon * e.g. 192.168.1.1:80,192.168.1.2:8080
2976a03354eSMatthew Dillon * 192.168.1.1,192.168.1.2 or keep the port the same
2986a03354eSMatthew Dillon */
2996a03354eSMatthew Dillon tok = strtok(**av, ",");
3006a03354eSMatthew Dillon sa = &p->sa;
3016a03354eSMatthew Dillon count = 0;
3026a03354eSMatthew Dillon while (tok != NULL) {
3036a03354eSMatthew Dillon sa->sin_len = sizeof(struct sockaddr_in);
3046a03354eSMatthew Dillon sa->sin_family = AF_INET;
3056a03354eSMatthew Dillon sa->sin_port = 0;
3066a03354eSMatthew Dillon str = strchr(tok,':');
3076a03354eSMatthew Dillon if (str != NULL) {
3086a03354eSMatthew Dillon *(str++) = '\0';
3096a03354eSMatthew Dillon port = strtoport(str, &end, 0, 0);
3106a03354eSMatthew Dillon sa->sin_port = (u_short)port;
3116a03354eSMatthew Dillon }
3128b5a5700SBill Yuan if (lookup_host(tok, &(sa->sin_addr)) != 0)
3138b5a5700SBill Yuan errx(EX_DATAERR, "forward `%s' invalid dst", tok);
3146a03354eSMatthew Dillon tok = strtok (NULL, ",");
3156a03354eSMatthew Dillon sa++;
3166a03354eSMatthew Dillon count++;
3176a03354eSMatthew Dillon }
3186a03354eSMatthew Dillon (*cmd)->arg3 = count;
3196a03354eSMatthew Dillon if (count == 0) {
3206a03354eSMatthew Dillon errx(EX_DATAERR, "forward `%s' not recognizable", **av);
3216a03354eSMatthew Dillon }
3226a03354eSMatthew Dillon NEXT_ARG1;
3236a03354eSMatthew Dillon if (count > 1) {
3246a03354eSMatthew Dillon if (strcmp(**av, "round-robin") == 0) {
3256a03354eSMatthew Dillon NEXT_ARG1;
3266a03354eSMatthew Dillon (*cmd)->arg1 = 1;
3276a03354eSMatthew Dillon } else if (strcmp(**av, "sticky") == 0) {
3286a03354eSMatthew Dillon NEXT_ARG1;
3296a03354eSMatthew Dillon (*cmd)->arg1 = 2;
3306a03354eSMatthew Dillon } else {
3316a03354eSMatthew Dillon /* random */
3326a03354eSMatthew Dillon (*cmd)->arg1 = 0;
3336a03354eSMatthew Dillon }
3346a03354eSMatthew Dillon }
3356a03354eSMatthew Dillon (*cmd)->len = LEN_OF_IPFWINSN + count * sizeof(struct sockaddr_in);
3366a03354eSMatthew Dillon }
3376a03354eSMatthew Dillon
3386a03354eSMatthew Dillon void
parse_in(ipfw_insn ** cmd,int * ac,char ** av[])3396a03354eSMatthew Dillon parse_in(ipfw_insn **cmd, int *ac, char **av[])
3406a03354eSMatthew Dillon {
3416a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_IN;
3426a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
3435f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
3446a03354eSMatthew Dillon (*cmd)->arg1 = 0;
3456a03354eSMatthew Dillon NEXT_ARG1;
3466a03354eSMatthew Dillon }
3476a03354eSMatthew Dillon
3486a03354eSMatthew Dillon void
parse_out(ipfw_insn ** cmd,int * ac,char ** av[])3496a03354eSMatthew Dillon parse_out(ipfw_insn **cmd, int *ac, char **av[])
3506a03354eSMatthew Dillon {
3516a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_OUT;
3526a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
3535f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
3546a03354eSMatthew Dillon (*cmd)->arg1 = 0;
3556a03354eSMatthew Dillon NEXT_ARG1;
3566a03354eSMatthew Dillon }
3576a03354eSMatthew Dillon
3586a03354eSMatthew Dillon
3596a03354eSMatthew Dillon void
parse_via(ipfw_insn ** cmd,int * ac,char ** av[])3606a03354eSMatthew Dillon parse_via(ipfw_insn **cmd, int *ac, char **av[])
3616a03354eSMatthew Dillon {
3626a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
3635f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
3646a03354eSMatthew Dillon if (strcmp(*av[0], "via")==0) {
3656a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_VIA;
3666a03354eSMatthew Dillon } else if (strcmp(*av[0], "xmit")==0) {
3676a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_XMIT;
3686a03354eSMatthew Dillon } else if (strcmp(*av[0], "recv")==0) {
3696a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_RECV;
3706a03354eSMatthew Dillon }
3716a03354eSMatthew Dillon NEXT_ARG1;
3726a03354eSMatthew Dillon fill_iface((ipfw_insn_if *)(*cmd), *av[0]);
3736a03354eSMatthew Dillon NEXT_ARG1;
3746a03354eSMatthew Dillon }
3756a03354eSMatthew Dillon
376c1bde762SBill Yuan void
parse_src_port(ipfw_insn ** cmd,int * ac,char ** av[])377c1bde762SBill Yuan parse_src_port(ipfw_insn **cmd, int *ac, char **av[])
378c1bde762SBill Yuan {
379c1bde762SBill Yuan NEXT_ARG1;
380c1bde762SBill Yuan (*cmd)->opcode = O_BASIC_IP_SRCPORT;
381c1bde762SBill Yuan (*cmd)->module = MODULE_BASIC_ID;
3825f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
383c1bde762SBill Yuan double v = strtol(**av, NULL, 0);
384c1bde762SBill Yuan if (v <= 0 || v >= 65535)
385c1bde762SBill Yuan errx(EX_NOHOST, "port `%s' invalid", **av);
386c1bde762SBill Yuan (*cmd)->arg1 = v;
387c1bde762SBill Yuan NEXT_ARG1;
388c1bde762SBill Yuan }
389c1bde762SBill Yuan
390c1bde762SBill Yuan void
parse_dst_port(ipfw_insn ** cmd,int * ac,char ** av[])391c1bde762SBill Yuan parse_dst_port(ipfw_insn **cmd, int *ac, char **av[])
392c1bde762SBill Yuan {
393c1bde762SBill Yuan NEXT_ARG1;
394c1bde762SBill Yuan (*cmd)->opcode = O_BASIC_IP_DSTPORT;
395c1bde762SBill Yuan (*cmd)->module = MODULE_BASIC_ID;
3965f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
397c1bde762SBill Yuan double v = strtol(**av, NULL, 0);
398c1bde762SBill Yuan if (v <= 0 || v >= 65535)
399c1bde762SBill Yuan errx(EX_NOHOST, "port `%s' invalid", **av);
400c1bde762SBill Yuan (*cmd)->arg1 = v;
401c1bde762SBill Yuan NEXT_ARG1;
402c1bde762SBill Yuan }
403c1bde762SBill Yuan
40463317b93SBill Yuan /*
40563317b93SBill Yuan * Below formats are supported:
4065284582fSBill Yuan * from table 1 O_BASIC_IP_SRC_LOOKUP
40763317b93SBill Yuan * from any return 0 len instruction
40863317b93SBill Yuan * from me O_BASIC_IP_SRC_ME
40963317b93SBill Yuan * from 1.2.3.4 O_BASIC_IP_SRC
41063317b93SBill Yuan * from 1.2.3.4/24 O_BASIC_IP_SRC_MASK
41163317b93SBill Yuan */
4126a03354eSMatthew Dillon void
parse_from(ipfw_insn ** cmd,int * ac,char ** av[])4136a03354eSMatthew Dillon parse_from(ipfw_insn **cmd, int *ac, char **av[])
4146a03354eSMatthew Dillon {
41563317b93SBill Yuan ipfw_insn_ip *p = (ipfw_insn_ip *)(*cmd);
416c1bde762SBill Yuan double port;
41763317b93SBill Yuan int i;
41863317b93SBill Yuan
4196a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
4206a03354eSMatthew Dillon NEXT_ARG1;
4215284582fSBill Yuan if (strcmp(**av, "table") == 0) {
4225284582fSBill Yuan NEXT_ARG1;
4235284582fSBill Yuan NEED(*ac, 1, "table id missing");
4245f62bb52SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn);
4255284582fSBill Yuan (*cmd)->opcode = O_BASIC_IP_SRC_LOOKUP;
4265284582fSBill Yuan (*cmd)->arg1 = strtoul(**av, NULL, 10);
4275284582fSBill Yuan } else if (strcmp(**av, "any") == 0) {
42863317b93SBill Yuan (*cmd)->len &= ~F_LEN_MASK;
42963317b93SBill Yuan } else if (strcmp(**av, "me") == 0) {
43063317b93SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn);
43163317b93SBill Yuan (*cmd)->opcode = O_BASIC_IP_SRC_ME;
43263317b93SBill Yuan } else {
43363317b93SBill Yuan char *c = NULL, md = 0;
43463317b93SBill Yuan c = strchr(**av, '/');
435c1bde762SBill Yuan if (!c)
436c1bde762SBill Yuan c = strchr(**av, ':');
43763317b93SBill Yuan if (c) {
43863317b93SBill Yuan md = *c;
43963317b93SBill Yuan *c++ = '\0';
44063317b93SBill Yuan }
44163317b93SBill Yuan if (lookup_host(**av, &p->addr) != 0)
44263317b93SBill Yuan errx(EX_NOHOST, "hostname ``%s'' unknown", **av);
44363317b93SBill Yuan switch (md) {
444c1bde762SBill Yuan case ':':
445c1bde762SBill Yuan port = strtol(c, NULL, 0);
446c1bde762SBill Yuan if (port <= 0 || port >= 65535)
447c1bde762SBill Yuan errx(EX_NOHOST, "port `%s' invalid", c);
448c1bde762SBill Yuan (*cmd)->arg1 = port;
449c1bde762SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn_ip);
450c1bde762SBill Yuan (*cmd)->opcode = O_BASIC_IP_SRC_N_PORT;
451c1bde762SBill Yuan break;
45263317b93SBill Yuan case '/':
45363317b93SBill Yuan i = atoi(c);
45463317b93SBill Yuan if (i == 0)
45563317b93SBill Yuan p->mask.s_addr = htonl(0);
45663317b93SBill Yuan else if (i > 32)
45763317b93SBill Yuan errx(EX_DATAERR, "bad width ``%s''", c);
45863317b93SBill Yuan else
45963317b93SBill Yuan p->mask.s_addr = htonl(~0 << (32 - i));
460c1bde762SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn_ip);
461c1bde762SBill Yuan (*cmd)->opcode = O_BASIC_IP_SRC_MASK;
462c1bde762SBill Yuan p->addr.s_addr &= p->mask.s_addr;
46363317b93SBill Yuan break;
46463317b93SBill Yuan default:
46563317b93SBill Yuan p->mask.s_addr = htonl(~0);
46663317b93SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn_u32);
46763317b93SBill Yuan (*cmd)->opcode = O_BASIC_IP_SRC;
468c1bde762SBill Yuan break;
46963317b93SBill Yuan }
47063317b93SBill Yuan }
4716a03354eSMatthew Dillon NEXT_ARG1;
4726a03354eSMatthew Dillon }
4736a03354eSMatthew Dillon
4746a03354eSMatthew Dillon void
parse_to(ipfw_insn ** cmd,int * ac,char ** av[])4756a03354eSMatthew Dillon parse_to(ipfw_insn **cmd, int *ac, char **av[])
4766a03354eSMatthew Dillon {
47763317b93SBill Yuan ipfw_insn_ip *p = (ipfw_insn_ip *)(*cmd);
478c1bde762SBill Yuan double port;
47963317b93SBill Yuan int i;
48063317b93SBill Yuan
4816a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
4826a03354eSMatthew Dillon NEXT_ARG1;
4835284582fSBill Yuan if (strcmp(**av, "table") == 0) {
4845284582fSBill Yuan NEXT_ARG1;
4855284582fSBill Yuan NEED(*ac, 1, "table id missing");
4865f62bb52SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn);
4875284582fSBill Yuan (*cmd)->opcode = O_BASIC_IP_DST_LOOKUP;
4885284582fSBill Yuan (*cmd)->arg1 = strtoul(**av, NULL, 10);
4895284582fSBill Yuan } else if (strcmp(**av, "any") == 0) {
49063317b93SBill Yuan (*cmd)->len &= ~F_LEN_MASK;
49163317b93SBill Yuan } else if (strcmp(**av, "me") == 0) {
49263317b93SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn);
49363317b93SBill Yuan (*cmd)->opcode = O_BASIC_IP_DST_ME;
49463317b93SBill Yuan } else {
49563317b93SBill Yuan char *c = NULL, md = 0;
49663317b93SBill Yuan c = strchr(**av, '/');
497c1bde762SBill Yuan if (!c)
498c1bde762SBill Yuan c = strchr(**av, ':');
49963317b93SBill Yuan if (c) {
50063317b93SBill Yuan md = *c;
50163317b93SBill Yuan *c++ = '\0';
50263317b93SBill Yuan }
50363317b93SBill Yuan if (lookup_host(**av, &p->addr) != 0)
50463317b93SBill Yuan errx(EX_NOHOST, "hostname ``%s'' unknown", **av);
50563317b93SBill Yuan switch (md) {
506c1bde762SBill Yuan case ':':
507c1bde762SBill Yuan port = strtol(c, NULL, 0);
508c1bde762SBill Yuan if (port <= 0 || port >= 65535)
509c1bde762SBill Yuan errx(EX_NOHOST, "port `%s' invalid", c);
510c1bde762SBill Yuan (*cmd)->arg1 = port;
511c1bde762SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn_ip);
512c1bde762SBill Yuan (*cmd)->opcode = O_BASIC_IP_DST_N_PORT;
513c1bde762SBill Yuan break;
51463317b93SBill Yuan case '/':
51563317b93SBill Yuan i = atoi(c);
51663317b93SBill Yuan if (i == 0)
51763317b93SBill Yuan p->mask.s_addr = htonl(0);
51863317b93SBill Yuan else if (i > 32)
51963317b93SBill Yuan errx(EX_DATAERR, "bad width ``%s''", c);
52063317b93SBill Yuan else
52163317b93SBill Yuan p->mask.s_addr = htonl(~0 << (32 - i));
522c1bde762SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn_ip);
523c1bde762SBill Yuan (*cmd)->opcode = O_BASIC_IP_DST_MASK;
524c1bde762SBill Yuan p->addr.s_addr &= p->mask.s_addr;
52563317b93SBill Yuan break;
52663317b93SBill Yuan default:
52763317b93SBill Yuan p->mask.s_addr = htonl(~0);
52863317b93SBill Yuan (*cmd)->len |= F_INSN_SIZE(ipfw_insn_u32);
52963317b93SBill Yuan (*cmd)->opcode = O_BASIC_IP_DST;
530c1bde762SBill Yuan break;
53163317b93SBill Yuan }
53263317b93SBill Yuan }
5336a03354eSMatthew Dillon NEXT_ARG1;
534c1bde762SBill Yuan
5356a03354eSMatthew Dillon }
5366a03354eSMatthew Dillon
5376a03354eSMatthew Dillon void
parse_proto(ipfw_insn ** cmd,int * ac,char ** av[])5386a03354eSMatthew Dillon parse_proto(ipfw_insn **cmd, int *ac, char **av[])
5396a03354eSMatthew Dillon {
5406a03354eSMatthew Dillon add_proto(*cmd, **av);
5416a03354eSMatthew Dillon NEXT_ARG1;
5426a03354eSMatthew Dillon }
5436a03354eSMatthew Dillon
5446a03354eSMatthew Dillon void
parse_prob(ipfw_insn ** cmd,int * ac,char ** av[])5456a03354eSMatthew Dillon parse_prob(ipfw_insn **cmd, int *ac, char **av[])
5466a03354eSMatthew Dillon {
5476a03354eSMatthew Dillon NEXT_ARG1;
5486a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_PROB;
5496a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
5505f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
5516a03354eSMatthew Dillon (*cmd)->arg1 = strtoul(**av, NULL, 10);
5526a03354eSMatthew Dillon NEXT_ARG1;
5536a03354eSMatthew Dillon }
5546a03354eSMatthew Dillon
5556a03354eSMatthew Dillon void
parse_keep_state(ipfw_insn ** cmd,int * ac,char ** av[])5566a03354eSMatthew Dillon parse_keep_state(ipfw_insn **cmd, int *ac, char **av[])
5576a03354eSMatthew Dillon {
5586a03354eSMatthew Dillon NEXT_ARG1;
5596a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_KEEP_STATE;
5606a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
5615f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
5626a03354eSMatthew Dillon if (strcmp(**av, "limit") == 0) {
5636a03354eSMatthew Dillon NEXT_ARG1;
5646a03354eSMatthew Dillon (*cmd)->arg3 = match_token(limit_types, **av);
5656a03354eSMatthew Dillon if ((*cmd)->arg3 == 0)
5666a03354eSMatthew Dillon errx(EX_DATAERR, "limit `%s' not recognizable", **av);
5676a03354eSMatthew Dillon
5686a03354eSMatthew Dillon NEXT_ARG1;
5696a03354eSMatthew Dillon (*cmd)->arg1 = strtoul(**av, NULL, 10);
5706a03354eSMatthew Dillon if ((*cmd)->arg1 == 0)
5716a03354eSMatthew Dillon errx(EX_DATAERR, "bad limit `%s'", **av);
5726a03354eSMatthew Dillon
5736a03354eSMatthew Dillon NEXT_ARG1;
5746a03354eSMatthew Dillon }
5756a03354eSMatthew Dillon if (strcmp(**av, "live") == 0) {
5766a03354eSMatthew Dillon NEXT_ARG1;
5776a03354eSMatthew Dillon (*cmd)->arg2 = strtoul(**av, NULL, 10);
5786a03354eSMatthew Dillon NEXT_ARG1;
5796a03354eSMatthew Dillon }
5806a03354eSMatthew Dillon }
5816a03354eSMatthew Dillon
5826a03354eSMatthew Dillon void
parse_check_state(ipfw_insn ** cmd,int * ac,char ** av[])5836a03354eSMatthew Dillon parse_check_state(ipfw_insn **cmd, int *ac, char **av[])
5846a03354eSMatthew Dillon {
5856a03354eSMatthew Dillon NEXT_ARG1;
5866a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_CHECK_STATE;
5876a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
5885f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
5896a03354eSMatthew Dillon }
5906a03354eSMatthew Dillon
5916a03354eSMatthew Dillon void
parse_tagged(ipfw_insn ** cmd,int * ac,char ** av[])5926a03354eSMatthew Dillon parse_tagged(ipfw_insn **cmd, int *ac, char **av[])
5936a03354eSMatthew Dillon {
5946a03354eSMatthew Dillon NEXT_ARG1;
5956a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_TAGGED;
5966a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
5975f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
5986a03354eSMatthew Dillon (*cmd)->arg1 = strtoul(**av, NULL, 10);
5996a03354eSMatthew Dillon NEXT_ARG1;
6006a03354eSMatthew Dillon }
6016a03354eSMatthew Dillon
6026a03354eSMatthew Dillon void
parse_comment(ipfw_insn ** cmd,int * ac,char ** av[])6036a03354eSMatthew Dillon parse_comment(ipfw_insn **cmd, int *ac, char **av[])
6046a03354eSMatthew Dillon {
6056a03354eSMatthew Dillon int l = 0;
6066a03354eSMatthew Dillon char *p = (char *)((*cmd) + 1);
6076a03354eSMatthew Dillon
6086a03354eSMatthew Dillon NEXT_ARG1;
6096a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_COMMENT;
6106a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
6116a03354eSMatthew Dillon
6126a03354eSMatthew Dillon while (*ac > 0) {
6136a03354eSMatthew Dillon l += strlen(**av) + 1;
6146a03354eSMatthew Dillon if (l > 84) {
6156a03354eSMatthew Dillon errx(EX_DATAERR, "comment too long (max 80 chars)");
6166a03354eSMatthew Dillon }
6176a03354eSMatthew Dillon strcpy(p, **av);
6186a03354eSMatthew Dillon p += strlen(**av);
6196a03354eSMatthew Dillon *p++ = ' ';
6206a03354eSMatthew Dillon NEXT_ARG1;
6216a03354eSMatthew Dillon }
6226a03354eSMatthew Dillon l = 1 + (l + 3) / 4;
6235f62bb52SBill Yuan (*cmd)->len |= l;
6246a03354eSMatthew Dillon *(--p) = '\0';
6256a03354eSMatthew Dillon }
6266a03354eSMatthew Dillon
6276a03354eSMatthew Dillon void
parse_tag(ipfw_insn ** cmd,int * ac,char ** av[])6286a03354eSMatthew Dillon parse_tag(ipfw_insn **cmd, int *ac, char **av[])
6296a03354eSMatthew Dillon {
6306a03354eSMatthew Dillon NEXT_ARG1;
6316a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_TAG;
6326a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
6335f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
6346a03354eSMatthew Dillon (*cmd)->arg1 = strtoul(**av, NULL, 10);
6356a03354eSMatthew Dillon NEXT_ARG1;
6366a03354eSMatthew Dillon }
6376a03354eSMatthew Dillon
6386a03354eSMatthew Dillon void
parse_untag(ipfw_insn ** cmd,int * ac,char ** av[])6396a03354eSMatthew Dillon parse_untag(ipfw_insn **cmd, int *ac, char **av[])
6406a03354eSMatthew Dillon {
6416a03354eSMatthew Dillon NEXT_ARG1;
6426a03354eSMatthew Dillon (*cmd)->opcode = O_BASIC_UNTAG;
6436a03354eSMatthew Dillon (*cmd)->module = MODULE_BASIC_ID;
6445f62bb52SBill Yuan (*cmd)->len |= LEN_OF_IPFWINSN;
6456a03354eSMatthew Dillon (*cmd)->arg1 = strtoul(**av, NULL, 10);
6466a03354eSMatthew Dillon NEXT_ARG1;
6476a03354eSMatthew Dillon }
6486a03354eSMatthew Dillon
6496a03354eSMatthew Dillon void
show_count(ipfw_insn * cmd,int show_or)6506ce8c93fSBill Yuan show_count(ipfw_insn *cmd, int show_or)
6516a03354eSMatthew Dillon {
6526a03354eSMatthew Dillon printf(" count");
6536a03354eSMatthew Dillon }
6546a03354eSMatthew Dillon
6556a03354eSMatthew Dillon void
show_skipto(ipfw_insn * cmd,int show_or)6566ce8c93fSBill Yuan show_skipto(ipfw_insn *cmd, int show_or)
6576a03354eSMatthew Dillon {
6586a03354eSMatthew Dillon printf(" skipto %u", cmd->arg1);
6596a03354eSMatthew Dillon }
6606a03354eSMatthew Dillon
6616a03354eSMatthew Dillon void
show_forward(ipfw_insn * cmd,int show_or)6626ce8c93fSBill Yuan show_forward(ipfw_insn *cmd, int show_or)
6636a03354eSMatthew Dillon {
6646a03354eSMatthew Dillon struct sockaddr_in *sa;
6656a03354eSMatthew Dillon int i;
6666a03354eSMatthew Dillon
6676a03354eSMatthew Dillon ipfw_insn_sa *s = (ipfw_insn_sa *)cmd;
6686a03354eSMatthew Dillon sa = &s->sa;
6696a03354eSMatthew Dillon printf(" forward");
6706a03354eSMatthew Dillon for (i = 0; i < cmd->arg3; i++){
6716a03354eSMatthew Dillon if (i > 0)
6726a03354eSMatthew Dillon printf(",");
6736a03354eSMatthew Dillon else
6746a03354eSMatthew Dillon printf(" ");
6756a03354eSMatthew Dillon
6766a03354eSMatthew Dillon printf("%s", inet_ntoa(sa->sin_addr));
6776a03354eSMatthew Dillon if (sa->sin_port != 0)
6786a03354eSMatthew Dillon printf(":%d", sa->sin_port);
6796a03354eSMatthew Dillon
6806a03354eSMatthew Dillon sa++;
6816a03354eSMatthew Dillon }
6826a03354eSMatthew Dillon if (cmd->arg1 == 1)
6836a03354eSMatthew Dillon printf(" round-robin");
6846a03354eSMatthew Dillon else if (cmd->arg1 == 2)
6856a03354eSMatthew Dillon printf(" sticky");
6866a03354eSMatthew Dillon
6876a03354eSMatthew Dillon }
6886a03354eSMatthew Dillon
6896a03354eSMatthew Dillon void
show_in(ipfw_insn * cmd,int show_or)6906ce8c93fSBill Yuan show_in(ipfw_insn *cmd, int show_or)
6916a03354eSMatthew Dillon {
6926a03354eSMatthew Dillon printf(" in");
6936a03354eSMatthew Dillon }
6946a03354eSMatthew Dillon
6956a03354eSMatthew Dillon void
show_out(ipfw_insn * cmd,int show_or)6966ce8c93fSBill Yuan show_out(ipfw_insn *cmd, int show_or)
6976a03354eSMatthew Dillon {
6986a03354eSMatthew Dillon printf(" out");
6996a03354eSMatthew Dillon }
7006a03354eSMatthew Dillon
7016a03354eSMatthew Dillon void
show_via(ipfw_insn * cmd,int show_or)7026ce8c93fSBill Yuan show_via(ipfw_insn *cmd, int show_or)
7036a03354eSMatthew Dillon {
7046a03354eSMatthew Dillon char *s;
7056a03354eSMatthew Dillon ipfw_insn_if *cmdif = (ipfw_insn_if *)cmd;
7066a03354eSMatthew Dillon
7076a03354eSMatthew Dillon if ((int)cmd->opcode == O_BASIC_XMIT)
7086a03354eSMatthew Dillon s = "xmit";
7096a03354eSMatthew Dillon else if ((int)cmd->opcode == O_BASIC_RECV)
7106a03354eSMatthew Dillon s = "recv";
7116a03354eSMatthew Dillon else if ((int)cmd->opcode == O_BASIC_VIA)
7126a03354eSMatthew Dillon s = "via";
7136a03354eSMatthew Dillon else
7146a03354eSMatthew Dillon s = "?huh?";
7156ce8c93fSBill Yuan if (show_or)
7166ce8c93fSBill Yuan s = "or";
7176a03354eSMatthew Dillon if (cmdif->name[0] == '\0')
7186a03354eSMatthew Dillon printf(" %s %s", s, inet_ntoa(cmdif->p.ip));
7196a03354eSMatthew Dillon
7206a03354eSMatthew Dillon printf(" %s %s", s, cmdif->name);
7216a03354eSMatthew Dillon }
7226a03354eSMatthew Dillon
7236a03354eSMatthew Dillon void
show_src_port(ipfw_insn * cmd,int show_or)724c1bde762SBill Yuan show_src_port(ipfw_insn *cmd, int show_or)
725c1bde762SBill Yuan {
7265f62bb52SBill Yuan char *word = "src-port";
7275f62bb52SBill Yuan if (show_or)
7285f62bb52SBill Yuan word = "or";
7295f62bb52SBill Yuan printf(" %s %d", word, cmd->arg1);
730c1bde762SBill Yuan }
731c1bde762SBill Yuan
732c1bde762SBill Yuan void
show_dst_port(ipfw_insn * cmd,int show_or)733c1bde762SBill Yuan show_dst_port(ipfw_insn *cmd, int show_or)
734c1bde762SBill Yuan {
7355f62bb52SBill Yuan char *word = "dst-port";
7365f62bb52SBill Yuan if (show_or)
7375f62bb52SBill Yuan word = "or";
7385f62bb52SBill Yuan printf(" %s %d", word, cmd->arg1);
739c1bde762SBill Yuan }
740c1bde762SBill Yuan
741c1bde762SBill Yuan void
show_from(ipfw_insn * cmd,int show_or)7426ce8c93fSBill Yuan show_from(ipfw_insn *cmd, int show_or)
7436a03354eSMatthew Dillon {
7446ce8c93fSBill Yuan char *word = "from";
7456ce8c93fSBill Yuan if (show_or)
7466ce8c93fSBill Yuan word = "or";
7476ce8c93fSBill Yuan printf(" %s %s", word, inet_ntoa(((ipfw_insn_ip *)cmd)->addr));
7486a03354eSMatthew Dillon }
7496a03354eSMatthew Dillon
7506a03354eSMatthew Dillon void
show_from_lookup(ipfw_insn * cmd,int show_or)7515284582fSBill Yuan show_from_lookup(ipfw_insn *cmd, int show_or)
7525284582fSBill Yuan {
7535284582fSBill Yuan char *word = "from";
7545284582fSBill Yuan if (show_or)
7555284582fSBill Yuan word = "or";
7565284582fSBill Yuan printf(" %s table %d", word, cmd->arg1);
7575284582fSBill Yuan }
7585284582fSBill Yuan
7595284582fSBill Yuan void
show_from_me(ipfw_insn * cmd,int show_or)7606ce8c93fSBill Yuan show_from_me(ipfw_insn *cmd, int show_or)
76163317b93SBill Yuan {
7626ce8c93fSBill Yuan char *word = "from";
7636ce8c93fSBill Yuan if (show_or)
7646ce8c93fSBill Yuan word = "or";
7656ce8c93fSBill Yuan printf(" %s me", word);
76663317b93SBill Yuan }
76763317b93SBill Yuan
76863317b93SBill Yuan void
show_from_mask(ipfw_insn * cmd,int show_or)7696ce8c93fSBill Yuan show_from_mask(ipfw_insn *cmd, int show_or)
77063317b93SBill Yuan {
77163317b93SBill Yuan int mask;
7726ce8c93fSBill Yuan char *word = "from";
7736ce8c93fSBill Yuan if (show_or)
7746ce8c93fSBill Yuan word = "or";
77563317b93SBill Yuan ipfw_insn_ip *p = (ipfw_insn_ip *)cmd;
7766ce8c93fSBill Yuan printf(" %s %s", word, inet_ntoa(p->addr));
77763317b93SBill Yuan
77863317b93SBill Yuan mask = contigmask((u_char *)&(p->mask.s_addr), 32);
77963317b93SBill Yuan if (mask < 32)
78063317b93SBill Yuan printf("/%d", mask);
78163317b93SBill Yuan }
78263317b93SBill Yuan
78363317b93SBill Yuan void
show_from_src_n_port(ipfw_insn * cmd,int show_or)784c1bde762SBill Yuan show_from_src_n_port(ipfw_insn *cmd, int show_or)
785c1bde762SBill Yuan {
786c1bde762SBill Yuan char *word = "from";
787c1bde762SBill Yuan if (show_or)
788c1bde762SBill Yuan word = "or";
789c1bde762SBill Yuan ipfw_insn_ip *p = (ipfw_insn_ip *)cmd;
790c1bde762SBill Yuan printf(" %s %s", word, inet_ntoa(p->addr));
791c1bde762SBill Yuan printf(":%d", cmd->arg1);
792c1bde762SBill Yuan }
793c1bde762SBill Yuan
794c1bde762SBill Yuan void
show_to(ipfw_insn * cmd,int show_or)7956ce8c93fSBill Yuan show_to(ipfw_insn *cmd, int show_or)
7966a03354eSMatthew Dillon {
7976ce8c93fSBill Yuan char *word = "to";
7986ce8c93fSBill Yuan if (show_or)
7996ce8c93fSBill Yuan word = "or";
800c1bde762SBill Yuan ipfw_insn_ip *p = (ipfw_insn_ip *)cmd;
801c1bde762SBill Yuan printf(" %s %s", word, inet_ntoa(p->addr));
8026a03354eSMatthew Dillon }
8036a03354eSMatthew Dillon
8046a03354eSMatthew Dillon void
show_to_lookup(ipfw_insn * cmd,int show_or)8055284582fSBill Yuan show_to_lookup(ipfw_insn *cmd, int show_or)
8065284582fSBill Yuan {
8075284582fSBill Yuan char *word = "to";
8085284582fSBill Yuan if (show_or)
8095284582fSBill Yuan word = "or";
8105284582fSBill Yuan printf(" %s table %d", word, cmd->arg1);
8115284582fSBill Yuan }
8125284582fSBill Yuan
8135284582fSBill Yuan void
show_to_me(ipfw_insn * cmd,int show_or)8146ce8c93fSBill Yuan show_to_me(ipfw_insn *cmd, int show_or)
81563317b93SBill Yuan {
8166ce8c93fSBill Yuan char *word = "to";
8176ce8c93fSBill Yuan if (show_or)
8186ce8c93fSBill Yuan word = "or";
8196ce8c93fSBill Yuan printf(" %s me", word);
82063317b93SBill Yuan }
82163317b93SBill Yuan
82263317b93SBill Yuan void
show_to_mask(ipfw_insn * cmd,int show_or)8236ce8c93fSBill Yuan show_to_mask(ipfw_insn *cmd, int show_or)
82463317b93SBill Yuan {
82563317b93SBill Yuan int mask;
8266ce8c93fSBill Yuan char *word = "to";
8276ce8c93fSBill Yuan if (show_or)
8286ce8c93fSBill Yuan word = "or";
82963317b93SBill Yuan ipfw_insn_ip *p = (ipfw_insn_ip *)cmd;
8306ce8c93fSBill Yuan printf(" %s %s", word, inet_ntoa(p->addr));
83163317b93SBill Yuan
83263317b93SBill Yuan mask = contigmask((u_char *)&(p->mask.s_addr), 32);
83363317b93SBill Yuan if (mask < 32)
83463317b93SBill Yuan printf("/%d", mask);
83563317b93SBill Yuan }
83663317b93SBill Yuan
83763317b93SBill Yuan void
show_to_src_n_port(ipfw_insn * cmd,int show_or)838c1bde762SBill Yuan show_to_src_n_port(ipfw_insn *cmd, int show_or)
839c1bde762SBill Yuan {
840c1bde762SBill Yuan char *word = "to";
841c1bde762SBill Yuan if (show_or)
842c1bde762SBill Yuan word = "or";
843c1bde762SBill Yuan printf(" %s %s", word, inet_ntoa(((ipfw_insn_ip *)cmd)->addr));
844c1bde762SBill Yuan printf(":%d", cmd->arg1);
845c1bde762SBill Yuan }
846c1bde762SBill Yuan
847c1bde762SBill Yuan void
show_proto(ipfw_insn * cmd,int show_or)8486ce8c93fSBill Yuan show_proto(ipfw_insn *cmd, int show_or)
8496a03354eSMatthew Dillon {
8506a03354eSMatthew Dillon struct protoent *pe;
8516a03354eSMatthew Dillon u_char proto = 0;
8526a03354eSMatthew Dillon proto = cmd->arg1;
8536a03354eSMatthew Dillon pe = getprotobynumber(cmd->arg1);
8546a03354eSMatthew Dillon printf(" %s", pe->p_name);
8556a03354eSMatthew Dillon }
8566a03354eSMatthew Dillon
8576a03354eSMatthew Dillon void
show_prob(ipfw_insn * cmd,int show_or)8586ce8c93fSBill Yuan show_prob(ipfw_insn *cmd, int show_or)
8596a03354eSMatthew Dillon {
8605f62bb52SBill Yuan char *word = "prob";
8615f62bb52SBill Yuan if (show_or)
8625f62bb52SBill Yuan word = "or";
8635f62bb52SBill Yuan printf(" %s %d%%", word, cmd->arg1);
8646a03354eSMatthew Dillon }
8656a03354eSMatthew Dillon
8666a03354eSMatthew Dillon void
show_keep_state(ipfw_insn * cmd,int show_or)8676ce8c93fSBill Yuan show_keep_state(ipfw_insn *cmd, int show_or)
8686a03354eSMatthew Dillon {
8696a03354eSMatthew Dillon printf(" keep-state");
8706a03354eSMatthew Dillon if (cmd->arg1 != 0) {
8716a03354eSMatthew Dillon char *type=match_token2(limit_types, cmd->arg3);
8726a03354eSMatthew Dillon printf(" limit %s %d", type, cmd->arg1);
8736a03354eSMatthew Dillon }
8746a03354eSMatthew Dillon if (cmd->arg2 != 0) {
8756a03354eSMatthew Dillon printf(" live %d", cmd->arg2);
8766a03354eSMatthew Dillon }
8776a03354eSMatthew Dillon }
8786a03354eSMatthew Dillon
8796a03354eSMatthew Dillon void
show_check_state(ipfw_insn * cmd,int show_or)8806ce8c93fSBill Yuan show_check_state(ipfw_insn *cmd, int show_or)
8816a03354eSMatthew Dillon {
8826a03354eSMatthew Dillon printf(" check-state");
8836a03354eSMatthew Dillon }
8846a03354eSMatthew Dillon
8856a03354eSMatthew Dillon void
show_tagged(ipfw_insn * cmd,int show_or)8866ce8c93fSBill Yuan show_tagged(ipfw_insn *cmd, int show_or)
8876a03354eSMatthew Dillon {
8886a03354eSMatthew Dillon printf(" tagged %d", cmd->arg1);
8896a03354eSMatthew Dillon }
8906a03354eSMatthew Dillon
8916a03354eSMatthew Dillon void
show_comment(ipfw_insn * cmd,int show_or)8926ce8c93fSBill Yuan show_comment(ipfw_insn *cmd, int show_or)
8936a03354eSMatthew Dillon {
8946a03354eSMatthew Dillon printf(" // %s", (char *)(cmd + 1));
8956a03354eSMatthew Dillon }
8966a03354eSMatthew Dillon
8976a03354eSMatthew Dillon void
show_tag(ipfw_insn * cmd,int show_or)8986ce8c93fSBill Yuan show_tag(ipfw_insn *cmd, int show_or)
8996a03354eSMatthew Dillon {
9006a03354eSMatthew Dillon printf(" tag %d", cmd->arg1);
9016a03354eSMatthew Dillon }
9026a03354eSMatthew Dillon
9036a03354eSMatthew Dillon void
show_untag(ipfw_insn * cmd,int show_or)9046ce8c93fSBill Yuan show_untag(ipfw_insn *cmd, int show_or)
9056a03354eSMatthew Dillon {
9066a03354eSMatthew Dillon printf(" untag %d", cmd->arg1);
9076a03354eSMatthew Dillon }
9086a03354eSMatthew Dillon
9096a03354eSMatthew Dillon void
load_module(register_func function,register_keyword keyword)9106a03354eSMatthew Dillon load_module(register_func function, register_keyword keyword)
9116a03354eSMatthew Dillon {
9123b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_COUNT, "count", ACTION);
9136a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_COUNT,
9146a03354eSMatthew Dillon (parser_func)parse_count, (shower_func)show_count);
9156a03354eSMatthew Dillon
9163b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_SKIPTO, "skipto", ACTION);
9176a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_SKIPTO,
9186a03354eSMatthew Dillon (parser_func)parse_skipto, (shower_func)show_skipto);
9196a03354eSMatthew Dillon
9203b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_FORWARD, "forward", ACTION);
9216a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_FORWARD,
9226a03354eSMatthew Dillon (parser_func)parse_forward, (shower_func)show_forward);
9236a03354eSMatthew Dillon
9243b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IN, "in", FILTER);
9256a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_IN,
9266a03354eSMatthew Dillon (parser_func)parse_in, (shower_func)show_in);
9276a03354eSMatthew Dillon
9283b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_OUT, "out", FILTER);
9296a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_OUT,
9306a03354eSMatthew Dillon (parser_func)parse_out, (shower_func)show_out);
9316a03354eSMatthew Dillon
9323b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_VIA, "via", FILTER);
9336a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_VIA,
9346a03354eSMatthew Dillon (parser_func)parse_via, (shower_func)show_via);
9356a03354eSMatthew Dillon
9363b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_XMIT, "xmit", FILTER);
9376a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_XMIT,
9386a03354eSMatthew Dillon (parser_func)parse_via, (shower_func)show_via);
9396a03354eSMatthew Dillon
9403b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_RECV, "recv", FILTER);
9416a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_RECV,
9426a03354eSMatthew Dillon (parser_func)parse_via, (shower_func)show_via);
9436a03354eSMatthew Dillon
944c1bde762SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_SRCPORT, "src-port", FILTER);
945c1bde762SBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_SRCPORT,
946c1bde762SBill Yuan (parser_func)parse_src_port, (shower_func)show_src_port);
947c1bde762SBill Yuan
948c1bde762SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_DSTPORT, "dst-port", FILTER);
949c1bde762SBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_DSTPORT,
950c1bde762SBill Yuan (parser_func)parse_dst_port, (shower_func)show_dst_port);
951c1bde762SBill Yuan
9523b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC, "from", FROM);
9536a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_IP_SRC,
9546a03354eSMatthew Dillon (parser_func)parse_from, (shower_func)show_from);
9555284582fSBill Yuan
95662f8e481SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC_LOOKUP, "from-[table]", FROM);
9575284582fSBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_SRC_LOOKUP,
9585284582fSBill Yuan (parser_func)parse_from, (shower_func)show_from_lookup);
9595284582fSBill Yuan
96062f8e481SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC_ME, "from-[me]", FROM);
96163317b93SBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_SRC_ME,
96263317b93SBill Yuan (parser_func)parse_from, (shower_func)show_from_me);
963c1bde762SBill Yuan
96462f8e481SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC_MASK, "from-[mask]", FROM);
96563317b93SBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_SRC_MASK,
96663317b93SBill Yuan (parser_func)parse_from, (shower_func)show_from_mask);
967c1bde762SBill Yuan
968c1bde762SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_SRC_N_PORT, "from-[ip:port]", FROM);
969c1bde762SBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_SRC_N_PORT,
970c1bde762SBill Yuan (parser_func)parse_from, (shower_func)show_from_src_n_port);
971c1bde762SBill Yuan
9723b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_DST, "to", TO);
9736a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_IP_DST,
9746a03354eSMatthew Dillon (parser_func)parse_to, (shower_func)show_to);
9755284582fSBill Yuan
97662f8e481SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_DST_LOOKUP, "to-[table]", TO);
9775284582fSBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_DST_LOOKUP,
9785284582fSBill Yuan (parser_func)parse_to, (shower_func)show_to_lookup);
9795284582fSBill Yuan
98062f8e481SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_DST_ME, "to-[me]", TO);
98163317b93SBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_DST_ME,
98263317b93SBill Yuan (parser_func)parse_to, (shower_func)show_to_me);
983c1bde762SBill Yuan
98462f8e481SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_DST_MASK, "to-[mask]", TO);
98563317b93SBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_DST_MASK,
98663317b93SBill Yuan (parser_func)parse_to, (shower_func)show_to_mask);
9876a03354eSMatthew Dillon
988c1bde762SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_IP_DST_N_PORT, "to-[ip:port]", FROM);
989c1bde762SBill Yuan function(MODULE_BASIC_ID, O_BASIC_IP_DST_N_PORT,
990c1bde762SBill Yuan (parser_func)parse_to, (shower_func)show_to_src_n_port);
991c1bde762SBill Yuan
9923b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_PROTO, "proto", PROTO);
9936a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_PROTO,
9946a03354eSMatthew Dillon (parser_func)parse_proto, (shower_func)show_proto);
9956a03354eSMatthew Dillon
9963b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_PROB, "prob", FILTER);
9976a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_PROB,
9986a03354eSMatthew Dillon (parser_func)parse_prob, (shower_func)show_prob);
9996a03354eSMatthew Dillon
10003b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_KEEP_STATE, "keep-state", FILTER);
10016a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_KEEP_STATE,
10026a03354eSMatthew Dillon (parser_func)parse_keep_state,
10036a03354eSMatthew Dillon (shower_func)show_keep_state);
10046a03354eSMatthew Dillon
100526a55228SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_CHECK_STATE, "check-state", BEFORE);
10066a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_CHECK_STATE,
10076a03354eSMatthew Dillon (parser_func)parse_check_state,
10086a03354eSMatthew Dillon (shower_func)show_check_state);
10096a03354eSMatthew Dillon
10103b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_TAG, "tag", ACTION);
10116a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_TAG,
10126a03354eSMatthew Dillon (parser_func)parse_tag, (shower_func)show_tag);
10136a03354eSMatthew Dillon
10143b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_UNTAG, "untag", ACTION);
10156a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_UNTAG,
10166a03354eSMatthew Dillon (parser_func)parse_untag, (shower_func)show_untag);
10176a03354eSMatthew Dillon
10183b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_TAGGED, "tagged", FILTER);
10196a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_TAGGED,
10206a03354eSMatthew Dillon (parser_func)parse_tagged, (shower_func)show_tagged);
10216a03354eSMatthew Dillon
10223b6ebdc3SBill Yuan keyword(MODULE_BASIC_ID, O_BASIC_COMMENT, "//", AFTER);
10236a03354eSMatthew Dillon function(MODULE_BASIC_ID, O_BASIC_COMMENT,
10246a03354eSMatthew Dillon (parser_func)parse_comment, (shower_func)show_comment);
10256a03354eSMatthew Dillon }
1026