Add new fields for more granularity:

IP: version, tos, ttl, len, id
	TCP: seq#, ack#, window size

Reviewed by:	silence on freebsd-{net,ipfw}
This commit is contained in:
Bill Fumerola 2000-10-02 03:03:31 +00:00
parent 0281e449f4
commit 98b829924f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=66521
2 changed files with 197 additions and 7 deletions

View File

@ -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"
@ -1147,6 +1189,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;
@ -1878,40 +1954,127 @@ add(ac,av)
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))) {

View File

@ -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