summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbillf <billf@FreeBSD.org>2000-10-02 03:03:31 +0000
committerbillf <billf@FreeBSD.org>2000-10-02 03:03:31 +0000
commite80d3292ca5091a1d04d9413e27abc3d3f8756eb (patch)
treeb60412997c6df2b5546e06b53f0a4e75d705c5d2
parent18fd693342ac40e9e6164b13dc52bce894ef0e7d (diff)
downloadFreeBSD-src-e80d3292ca5091a1d04d9413e27abc3d3f8756eb.zip
FreeBSD-src-e80d3292ca5091a1d04d9413e27abc3d3f8756eb.tar.gz
Add new fields for more granularity:
IP: version, tos, ttl, len, id TCP: seq#, ack#, window size Reviewed by: silence on freebsd-{net,ipfw}
-rw-r--r--sbin/ipfw/ipfw.c175
-rw-r--r--sys/netinet/ip_fw.h29
2 files changed, 197 insertions, 7 deletions
diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c
index 1caf288..f3b1ea3 100644
--- a/sbin/ipfw/ipfw.c
+++ b/sbin/ipfw/ipfw.c
@@ -412,7 +412,7 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
if (chain->fw_flg & IP_FW_F_FRAG)
printf(" frag");
- if (chain->fw_ipopt || chain->fw_ipnopt) {
+ if (chain->fw_ipflg & IP_FW_IF_IPOPT) {
int _opt_printed = 0;
#define PRINTOPT(x) {if (_opt_printed) printf(",");\
printf(x); _opt_printed = 1;}
@@ -428,12 +428,39 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
if (chain->fw_ipnopt & IP_FW_IPOPT_TS) PRINTOPT("!ts");
}
+ if (chain->fw_ipflg & IP_FW_IF_IPLEN)
+ printf(" iplen %u", chain->fw_iplen);
+ if (chain->fw_ipflg & IP_FW_IF_IPID)
+ printf(" ipid 0x%04x", chain->fw_ipid);
+
+ if (chain->fw_ipflg & IP_FW_IF_IPTOS) {
+ int _opt_printed = 0;
+
+ printf(" iptos ");
+ if (chain->fw_iptos & IPTOS_LOWDELAY) PRINTOPT("lowdelay");
+ if (chain->fw_ipntos & IPTOS_LOWDELAY) PRINTOPT("!lowdelay");
+ if (chain->fw_iptos & IPTOS_THROUGHPUT) PRINTOPT("throughput");
+ if (chain->fw_ipntos & IPTOS_THROUGHPUT) PRINTOPT("!throughput");
+ if (chain->fw_iptos & IPTOS_RELIABILITY) PRINTOPT("reliability");
+ if (chain->fw_ipntos & IPTOS_RELIABILITY) PRINTOPT("!reliability");
+ if (chain->fw_iptos & IPTOS_MINCOST) PRINTOPT("mincost");
+ if (chain->fw_ipntos & IPTOS_MINCOST) PRINTOPT("!mincost");
+ if (chain->fw_iptos & IPTOS_CE) PRINTOPT("congestion");
+ if (chain->fw_ipntos & IPTOS_CE) PRINTOPT("!congestion");
+ }
+
+ if (chain->fw_ipflg & IP_FW_IF_IPTTL)
+ printf(" ipttl %u", chain->fw_ipttl);
+
+ if (chain->fw_ipflg & IP_FW_IF_IPVER)
+ printf(" ipversion %u", chain->fw_ipver);
+
if (chain->fw_tcpf & IP_FW_TCPF_ESTAB)
printf(" established");
else if (chain->fw_tcpf == IP_FW_TCPF_SYN &&
chain->fw_tcpnf == IP_FW_TCPF_ACK)
printf(" setup");
- else if (chain->fw_tcpf || chain->fw_tcpnf) {
+ else if (chain->fw_ipflg & IP_FW_IF_TCPOPT) {
int _flg_printed = 0;
#define PRINTFLG(x) {if (_flg_printed) printf(",");\
printf(x); _flg_printed = 1;}
@@ -452,7 +479,7 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
if (chain->fw_tcpf & IP_FW_TCPF_URG) PRINTFLG("urg");
if (chain->fw_tcpnf & IP_FW_TCPF_URG) PRINTFLG("!urg");
}
- if (chain->fw_tcpopt || chain->fw_tcpnopt) {
+ if (chain->fw_ipflg & IP_FW_IF_TCPOPT) {
int _opt_printed = 0;
#define PRINTTOPT(x) {if (_opt_printed) printf(",");\
printf(x); _opt_printed = 1;}
@@ -470,6 +497,13 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
if (chain->fw_tcpnopt & IP_FW_TCPOPT_CC) PRINTTOPT("!cc");
}
+ if (chain->fw_ipflg & IP_FW_IF_TCPSEQ)
+ printf(" tcpseq %lu", ntohl(chain->fw_tcpseq));
+ if (chain->fw_ipflg & IP_FW_IF_TCPACK)
+ printf(" tcpack %lu", ntohl(chain->fw_tcpack));
+ if (chain->fw_ipflg & IP_FW_IF_TCPWIN)
+ printf(" tcpwin %hu", ntohs(chain->fw_tcpwin));
+
if (chain->fw_flg & IP_FW_F_ICMPBIT) {
int type_index;
int first = 1;
@@ -837,7 +871,15 @@ show_usage(const char *fmt, ...)
" {established|setup}\n"
" tcpflags [!]{syn|fin|rst|ack|psh|urg},...\n"
" ipoptions [!]{ssrr|lsrr|rr|ts},...\n"
+" iplen {length}\n"
+" ipid {identification number (in hex)}\n"
+" iptos [!]{lowdelay|throughput|reliability|mincost|congestion}\n"
+" ipttl {time to live}\n"
+" ipversion {version number}\n"
" tcpoptions [!]{mss|window|sack|ts|cc},...\n"
+" tcpseq {sequence number}\n"
+" tcpack {acknowledgement number}\n"
+" tcpwin {window size}\n"
" icmptypes {type[,type]}...\n"
" pipeconfig:\n"
" {bw|bandwidth} <number>{bit/s|Kbit/s|Mbit/s|Bytes/s|KBytes/s|MBytes/s}\n"
@@ -1148,6 +1190,40 @@ fill_ipopt(u_char *set, u_char *reset, char **vp)
}
static void
+fill_iptos(u_char *set, u_char *reset, char **vp)
+{
+ char *p = *vp,*q;
+ u_char *d;
+
+ while (p && *p) {
+ if (*p == '!') {
+ p++;
+ d = reset;
+ } else {
+ d = set;
+ }
+ q = strchr(p, ',');
+ if (q)
+ *q++ = '\0';
+ if (!strncmp(p,"lowdelay",strlen(p)))
+ *d |= IPTOS_LOWDELAY;
+ if (!strncmp(p,"throughput",strlen(p)))
+ *d |= IPTOS_THROUGHPUT;
+ if (!strncmp(p,"reliability",strlen(p)))
+ *d |= IPTOS_RELIABILITY;
+ if (!strncmp(p,"mincost",strlen(p)))
+ *d |= IPTOS_MINCOST;
+ if (!strncmp(p,"congestion",strlen(p)))
+ *d |= IPTOS_CE;
+#if 0 /* conflicting! */
+ if (!strncmp(p,"ecntransport",strlen(p)))
+ *d |= IPTOS_ECT;
+#endif
+ p = q;
+ }
+}
+
+static void
fill_icmptypes(types, vp, fw_flg)
u_long *types;
char **vp;
@@ -1878,40 +1954,127 @@ badviacombo:
rule.fw_flg |= IP_FW_F_FRAG;
av++; ac--; continue;
}
- if (!strncmp(*av,"ipoptions",strlen(*av))) {
+ if (!strncmp(*av,"ipoptions",strlen(*av)) ||
+ !strncmp(*av,"ipopts",strlen(*av))) {
av++; ac--;
if (!ac)
show_usage("missing argument"
" for ``ipoptions''");
+ rule.fw_ipflg |= IP_FW_IF_IPOPT;
fill_ipopt(&rule.fw_ipopt, &rule.fw_ipnopt, av);
av++; ac--; continue;
}
+ if (!strncmp(*av,"iplen",strlen(*av))) {
+ av++; ac--;
+ if (!ac)
+ show_usage("missing argument"
+ " for ``iplen''");
+ rule.fw_ipflg |= IP_FW_IF_IPLEN;
+ rule.fw_iplen = (u_short)strtoul(*av, NULL, 0);
+ av++; ac--; continue;
+ }
+ if (!strncmp(*av,"ipid",strlen(*av))) {
+ av++; ac--;
+ if (!ac)
+ show_usage("missing argument"
+ " for ``ipid''");
+ rule.fw_ipflg |= IP_FW_IF_IPID;
+ if (strlen(*av) != 6 || (*av)[0] != '0' || (*av)[1] != 'x' ||
+ isxdigit((*av)[2]) == 0 ||
+ isxdigit((*av)[3]) == 0 ||
+ isxdigit((*av)[4]) == 0 ||
+ isxdigit((*av)[5]) == 0)
+ show_usage("argument to ipid must be in hex");
+ rule.fw_ipid = (u_short)strtoul(*av, NULL, 0);
+ av++; ac--; continue;
+ }
+ if (!strncmp(*av,"iptos",strlen(*av))) {
+ av++; ac--;
+ if (!ac)
+ show_usage("missing argument"
+ " for ``iptos''");
+ rule.fw_ipflg |= IP_FW_IF_IPTOS;
+ fill_iptos(&rule.fw_iptos, &rule.fw_ipntos, av);
+ av++; ac--; continue;
+ }
+ if (!strncmp(*av,"ipttl",strlen(*av))) {
+ av++; ac--;
+ if (!ac)
+ show_usage("missing argument"
+ " for ``ipttl''");
+ rule.fw_ipflg |= IP_FW_IF_IPTTL;
+ rule.fw_ipttl = (u_short)strtoul(*av, NULL, 0);
+ av++; ac--; continue;
+ }
+ if (!strncmp(*av,"ipversion",strlen(*av)) ||
+ !strncmp(*av,"ipver",strlen(*av))) {
+ av++; ac--;
+ if (!ac)
+ show_usage("missing argument"
+ " for ``ipversion''");
+ rule.fw_ipflg |= IP_FW_IF_IPVER;
+ rule.fw_ipver = (u_short)strtoul(*av, NULL, 0);
+ av++; ac--; continue;
+ }
if (rule.fw_prot == IPPROTO_TCP) {
if (!strncmp(*av,"established",strlen(*av))) {
rule.fw_tcpf |= IP_FW_TCPF_ESTAB;
+ rule.fw_ipflg |= IP_FW_IF_TCPFLG;
av++; ac--; continue;
}
if (!strncmp(*av,"setup",strlen(*av))) {
rule.fw_tcpf |= IP_FW_TCPF_SYN;
rule.fw_tcpnf |= IP_FW_TCPF_ACK;
+ rule.fw_ipflg |= IP_FW_IF_TCPFLG;
av++; ac--; continue;
}
- if (!strncmp(*av,"tcpflags",strlen(*av)) || !strncmp(*av,"tcpflgs",strlen(*av))) {
+ if (!strncmp(*av,"tcpflags",strlen(*av)) ||
+ !strncmp(*av,"tcpflgs",strlen(*av))) {
av++; ac--;
if (!ac)
show_usage("missing argument"
" for ``tcpflags''");
+ rule.fw_ipflg |= IP_FW_IF_TCPFLG;
fill_tcpflag(&rule.fw_tcpf, &rule.fw_tcpnf, av);
av++; ac--; continue;
}
- if (!strncmp(*av,"tcpoptions",strlen(*av)) || !strncmp(*av, "tcpopts",strlen(*av))) {
+ if (!strncmp(*av,"tcpoptions",strlen(*av)) ||
+ !strncmp(*av, "tcpopts",strlen(*av))) {
av++; ac--;
if (!ac)
show_usage("missing argument"
" for ``tcpoptions''");
+ rule.fw_ipflg |= IP_FW_IF_TCPOPT;
fill_tcpopts(&rule.fw_tcpopt, &rule.fw_tcpnopt, av);
av++; ac--; continue;
}
+ if (!strncmp(*av,"tcpseq",strlen(*av))) {
+ av++; ac--;
+ if (!ac)
+ show_usage("missing argument"
+ " for ``tcpseq''");
+ rule.fw_ipflg |= IP_FW_IF_TCPSEQ;
+ rule.fw_tcpseq = htonl((u_int32_t)strtoul(*av, NULL, 0));
+ av++; ac--; continue;
+ }
+ if (!strncmp(*av,"tcpack",strlen(*av))) {
+ av++; ac--;
+ if (!ac)
+ show_usage("missing argument"
+ " for ``tcpack''");
+ rule.fw_ipflg |= IP_FW_IF_TCPACK;
+ rule.fw_tcpack = htonl((u_int32_t)strtoul(*av, NULL, 0));
+ av++; ac--; continue;
+ }
+ if (!strncmp(*av,"tcpwin",strlen(*av))) {
+ av++; ac--;
+ if (!ac)
+ show_usage("missing argument"
+ " for ``tcpwin''");
+ rule.fw_ipflg |= IP_FW_IF_TCPWIN;
+ rule.fw_tcpwin = htons((u_short)strtoul(*av, NULL, 0));
+ av++; ac--; continue;
+ }
}
if (rule.fw_prot == IPPROTO_ICMP) {
if (!strncmp(*av,"icmptypes",strlen(*av))) {
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 86b2bce..f61abd1 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -54,7 +54,7 @@ struct ip_fw {
struct in_addr fw_src, fw_dst; /* Source and destination IP addr */
struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */
u_short fw_number; /* Rule number */
- u_int fw_flg; /* Flags word */
+ u_int fw_flg; /* Operational Flags word */
#define IP_FW_MAX_PORTS 10 /* A reasonable maximum */
union {
u_short fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */
@@ -62,9 +62,16 @@ struct ip_fw {
#define IP_FW_ICMPTYPES_DIM (IP_FW_ICMPTYPES_MAX / (sizeof(unsigned) * 8))
unsigned fw_icmptypes[IP_FW_ICMPTYPES_DIM]; /* ICMP types bitmap */
} fw_uar;
+ u_int fw_ipflg; /* IP flags word */
u_char fw_ipopt,fw_ipnopt; /* IP options set/unset */
+ u_short fw_iplen, fw_ipid; /* IP length, identification */
+ u_char fw_iptos, fw_ipntos; /* IP type of service set/unset */
+ u_char fw_ipttl; /* IP time to live */
+ u_int fw_ipver:4; /* IP version */
u_char fw_tcpopt,fw_tcpnopt; /* TCP options set/unset */
u_char fw_tcpf,fw_tcpnf; /* TCP flags set/unset */
+ u_int32_t fw_tcpseq, fw_tcpack; /* TCP sequence and acknowledgement */
+ u_short fw_tcpwin; /* TCP window size */
long timestamp; /* timestamp (tv_sec) of last match */
union ip_fw_if fw_in_if, fw_out_if; /* Incoming and outgoing interfaces */
union {
@@ -207,6 +214,26 @@ struct ipfw_dyn_rule {
#define IP_FW_F_MASK 0x1FFFFFFF /* All possible flag bits mask */
+/*
+ * Flags for the 'fw_ipflg' field, for comparing values of ip and its protocols.
+ */
+#define IP_FW_IF_TCPOPT 0x00000001 /* tcp options */
+#define IP_FW_IF_TCPFLG 0x00000002 /* tcp flags */
+#define IP_FW_IF_TCPSEQ 0x00000004 /* tcp sequence number */
+#define IP_FW_IF_TCPACK 0x00000008 /* tcp acknowledgement number */
+#define IP_FW_IF_TCPWIN 0x00000010 /* tcp window size */
+#define IP_FW_IF_TCPMSK 0x0000001f /* mask of all tcp values */
+
+#define IP_FW_IF_IPOPT 0x00000100 /* ip options */
+#define IP_FW_IF_IPLEN 0x00000200 /* ip length */
+#define IP_FW_IF_IPID 0x00000400 /* ip identification */
+#define IP_FW_IF_IPTOS 0x00000800 /* ip type of service */
+#define IP_FW_IF_IPTTL 0x00001000 /* ip time to live */
+#define IP_FW_IF_IPVER 0x00002000 /* ip version */
+#define IP_FW_IF_IPMSK 0x00003f00 /* mask of all ip values */
+
+#define IP_FW_IF_MSK 0x0000ffff /* All possible bits mask */
+
/*
* For backwards compatibility with rules specifying "via iface" but
* not restricted to only "in" or "out" packets, we define this combination
OpenPOWER on IntegriCloud