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:
parent
0281e449f4
commit
98b829924f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=66521
175
sbin/ipfw/ipfw.c
175
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"
|
||||
@ -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))) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user