summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbillf <billf@FreeBSD.org>2000-10-02 03:33:31 +0000
committerbillf <billf@FreeBSD.org>2000-10-02 03:33:31 +0000
commitbdb732a321aa214ae45489b545c22865e5da3d14 (patch)
treebb9192ebfdf47f010255794267ee37a36d43da93 /sys
parenta4b042e9d1c54f668ce11e3192e99747882c3e09 (diff)
downloadFreeBSD-src-bdb732a321aa214ae45489b545c22865e5da3d14.zip
FreeBSD-src-bdb732a321aa214ae45489b545c22865e5da3d14.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}
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip_fw.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 4c73a89..a1e9eb9 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -193,6 +193,7 @@ static __inline int
iface_match __P((struct ifnet *ifp, union ip_fw_if *ifu,
int byname));
static int ipopts_match __P((struct ip *ip, struct ip_fw *f));
+static int iptos_match __P((struct ip *ip, struct ip_fw *f));
static __inline int
port_match __P((u_short *portptr, int nports, u_short port,
int range_flag, int mask));
@@ -354,6 +355,33 @@ ipopts_match(struct ip *ip, struct ip_fw *f)
}
static int
+iptos_match(struct ip *ip, struct ip_fw *f)
+{
+
+ u_int flags = (ip->ip_tos & 0x1f);
+ u_char opts, nopts, nopts_sve;
+
+ opts = f->fw_iptos;
+ nopts = nopts_sve = f->fw_ipntos;
+
+ while (flags != 0) {
+ u_int flag;
+
+ flag = 1 << (ffs(flags) -1);
+ opts &= ~flag;
+ nopts &= ~flag;
+ flags &= ~flag;
+ }
+
+ if (opts == 0 && nopts == nopts_sve)
+ return 1;
+ else
+ return 0;
+
+}
+
+
+static int
tcpopts_match(struct tcphdr *tcp, struct ip_fw *f)
{
register u_char *cp;
@@ -1108,8 +1136,18 @@ again:
continue;
}
- /* Check IP options */
- if (f->fw_ipopt != f->fw_ipnopt && !ipopts_match(ip, f))
+ /* Check IP header values */
+ if (f->fw_ipflg & IP_FW_IF_IPOPT && !ipopts_match(ip, f))
+ continue;
+ if (f->fw_ipflg & IP_FW_IF_IPLEN && f->fw_iplen != ip->ip_len)
+ continue;
+ if (f->fw_ipflg & IP_FW_IF_IPID && f->fw_ipid != ip->ip_id)
+ continue;
+ if (f->fw_ipflg & IP_FW_IF_IPTOS && !iptos_match(ip, f))
+ continue;
+ if (f->fw_ipflg & IP_FW_IF_IPTTL && f->fw_ipttl != ip->ip_ttl)
+ continue;
+ if (f->fw_ipflg & IP_FW_IF_IPVER && f->fw_ipver != ip->ip_v)
continue;
/* Check protocol; if wildcard, and no [ug]id, match */
@@ -1211,9 +1249,15 @@ again:
}
tcp = (struct tcphdr *) ((u_int32_t *)ip + ip->ip_hl);
- if (f->fw_tcpopt != f->fw_tcpnopt && !tcpopts_match(tcp, f))
+ if (f->fw_ipflg & IP_FW_IF_TCPOPT && !tcpopts_match(tcp, f))
+ continue;
+ if (f->fw_ipflg & IP_FW_IF_TCPFLG && !tcpflg_match(tcp, f))
+ continue;
+ if (f->fw_ipflg & IP_FW_IF_TCPSEQ && tcp->th_seq != f->fw_tcpseq)
+ continue;
+ if (f->fw_ipflg & IP_FW_IF_TCPACK && tcp->th_ack != f->fw_tcpack)
continue;
- if (f->fw_tcpf != f->fw_tcpnf && !tcpflg_match(tcp, f))
+ if (f->fw_ipflg & IP_FW_IF_TCPWIN && tcp->th_win != f->fw_tcpwin)
continue;
goto check_ports;
}
OpenPOWER on IntegriCloud