diff options
author | billf <billf@FreeBSD.org> | 2000-10-02 03:33:31 +0000 |
---|---|---|
committer | billf <billf@FreeBSD.org> | 2000-10-02 03:33:31 +0000 |
commit | bdb732a321aa214ae45489b545c22865e5da3d14 (patch) | |
tree | bb9192ebfdf47f010255794267ee37a36d43da93 /sys/netinet | |
parent | a4b042e9d1c54f668ce11e3192e99747882c3e09 (diff) | |
download | FreeBSD-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/netinet')
-rw-r--r-- | sys/netinet/ip_fw.c | 52 |
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; } |