Loading net/netfilter/nf_osf.c +111 −96 Original line number Diff line number Diff line Loading @@ -21,15 +21,14 @@ #include <linux/netfilter/nf_osf.h> static inline int nf_osf_ttl(const struct sk_buff *skb, const struct nf_osf_info *info, unsigned char f_ttl) int ttl_check, unsigned char f_ttl) { const struct iphdr *ip = ip_hdr(skb); if (info->flags & NF_OSF_TTL) { if (info->ttl == NF_OSF_TTL_TRUE) if (ttl_check != -1) { if (ttl_check == NF_OSF_TTL_TRUE) return ip->ttl == f_ttl; if (info->ttl == NF_OSF_TTL_NOCHECK) if (ttl_check == NF_OSF_TTL_NOCHECK) return 1; else if (ip->ttl <= f_ttl) return 1; Loading @@ -52,61 +51,25 @@ static inline int nf_osf_ttl(const struct sk_buff *skb, return ip->ttl == f_ttl; } bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, int hooknum, struct net_device *in, struct net_device *out, const struct nf_osf_info *info, struct net *net, const struct list_head *nf_osf_fingers) static bool nf_osf_match_one(const struct sk_buff *skb, const struct nf_osf_user_finger *f, int ttl_check, u16 totlen, u16 window, const unsigned char *optp, unsigned int optsize) { const unsigned char *optp = NULL, *_optp = NULL; unsigned int optsize = 0, check_WSS = 0; int fmatch = FMATCH_WRONG, fcount = 0; const struct iphdr *ip = ip_hdr(skb); const struct nf_osf_user_finger *f; unsigned char opts[MAX_IPOPTLEN]; const struct nf_osf_finger *kf; u16 window, totlen, mss = 0; const struct tcphdr *tcp; struct tcphdr _tcph; bool df; tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph); if (!tcp) return false; if (!tcp->syn) return false; totlen = ntohs(ip->tot_len); df = ntohs(ip->frag_off) & IP_DF; window = ntohs(tcp->window); if (tcp->doff * 4 > sizeof(struct tcphdr)) { optsize = tcp->doff * 4 - sizeof(struct tcphdr); _optp = optp = skb_header_pointer(skb, ip_hdrlen(skb) + sizeof(struct tcphdr), optsize, opts); } list_for_each_entry_rcu(kf, &nf_osf_fingers[df], finger_entry) { unsigned int check_WSS = 0; int fmatch = FMATCH_WRONG; int foptsize, optnum; u16 mss = 0; f = &kf->finger; if (!(info->flags & NF_OSF_LOG) && strcmp(info->genre, f->genre)) continue; optp = _optp; fmatch = FMATCH_WRONG; if (totlen != f->ss || !nf_osf_ttl(skb, info, f->ttl)) continue; if (totlen != f->ss || !nf_osf_ttl(skb, ttl_check, f->ttl)) return false; /* * Should not happen if userspace parser was written correctly. */ if (f->wss.wc >= OSF_WSS_MAX) continue; return false; /* Check options */ Loading @@ -117,7 +80,7 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize) continue; return false; check_WSS = f->wss.wc; Loading Loading @@ -183,9 +146,61 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, } } if (fmatch != FMATCH_OK) return fmatch == FMATCH_OK; } bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, int hooknum, struct net_device *in, struct net_device *out, const struct nf_osf_info *info, struct net *net, const struct list_head *nf_osf_fingers) { const unsigned char *optp = NULL, *_optp = NULL; const struct iphdr *ip = ip_hdr(skb); const struct nf_osf_user_finger *f; unsigned char opts[MAX_IPOPTLEN]; const struct nf_osf_finger *kf; int fcount = 0, ttl_check; int fmatch = FMATCH_WRONG; unsigned int optsize = 0; const struct tcphdr *tcp; struct tcphdr _tcph; u16 window, totlen; bool df; tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph); if (!tcp) return false; if (!tcp->syn) return false; totlen = ntohs(ip->tot_len); df = ntohs(ip->frag_off) & IP_DF; window = ntohs(tcp->window); if (tcp->doff * 4 > sizeof(struct tcphdr)) { optsize = tcp->doff * 4 - sizeof(struct tcphdr); _optp = optp = skb_header_pointer(skb, ip_hdrlen(skb) + sizeof(struct tcphdr), optsize, opts); } ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : -1; list_for_each_entry_rcu(kf, &nf_osf_fingers[df], finger_entry) { f = &kf->finger; if (!(info->flags & NF_OSF_LOG) && strcmp(info->genre, f->genre)) continue; if (!nf_osf_match_one(skb, f, ttl_check, totlen, window, optp, optsize)) continue; fmatch = FMATCH_OK; fcount++; if (info->flags & NF_OSF_LOG) Loading Loading
net/netfilter/nf_osf.c +111 −96 Original line number Diff line number Diff line Loading @@ -21,15 +21,14 @@ #include <linux/netfilter/nf_osf.h> static inline int nf_osf_ttl(const struct sk_buff *skb, const struct nf_osf_info *info, unsigned char f_ttl) int ttl_check, unsigned char f_ttl) { const struct iphdr *ip = ip_hdr(skb); if (info->flags & NF_OSF_TTL) { if (info->ttl == NF_OSF_TTL_TRUE) if (ttl_check != -1) { if (ttl_check == NF_OSF_TTL_TRUE) return ip->ttl == f_ttl; if (info->ttl == NF_OSF_TTL_NOCHECK) if (ttl_check == NF_OSF_TTL_NOCHECK) return 1; else if (ip->ttl <= f_ttl) return 1; Loading @@ -52,61 +51,25 @@ static inline int nf_osf_ttl(const struct sk_buff *skb, return ip->ttl == f_ttl; } bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, int hooknum, struct net_device *in, struct net_device *out, const struct nf_osf_info *info, struct net *net, const struct list_head *nf_osf_fingers) static bool nf_osf_match_one(const struct sk_buff *skb, const struct nf_osf_user_finger *f, int ttl_check, u16 totlen, u16 window, const unsigned char *optp, unsigned int optsize) { const unsigned char *optp = NULL, *_optp = NULL; unsigned int optsize = 0, check_WSS = 0; int fmatch = FMATCH_WRONG, fcount = 0; const struct iphdr *ip = ip_hdr(skb); const struct nf_osf_user_finger *f; unsigned char opts[MAX_IPOPTLEN]; const struct nf_osf_finger *kf; u16 window, totlen, mss = 0; const struct tcphdr *tcp; struct tcphdr _tcph; bool df; tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph); if (!tcp) return false; if (!tcp->syn) return false; totlen = ntohs(ip->tot_len); df = ntohs(ip->frag_off) & IP_DF; window = ntohs(tcp->window); if (tcp->doff * 4 > sizeof(struct tcphdr)) { optsize = tcp->doff * 4 - sizeof(struct tcphdr); _optp = optp = skb_header_pointer(skb, ip_hdrlen(skb) + sizeof(struct tcphdr), optsize, opts); } list_for_each_entry_rcu(kf, &nf_osf_fingers[df], finger_entry) { unsigned int check_WSS = 0; int fmatch = FMATCH_WRONG; int foptsize, optnum; u16 mss = 0; f = &kf->finger; if (!(info->flags & NF_OSF_LOG) && strcmp(info->genre, f->genre)) continue; optp = _optp; fmatch = FMATCH_WRONG; if (totlen != f->ss || !nf_osf_ttl(skb, info, f->ttl)) continue; if (totlen != f->ss || !nf_osf_ttl(skb, ttl_check, f->ttl)) return false; /* * Should not happen if userspace parser was written correctly. */ if (f->wss.wc >= OSF_WSS_MAX) continue; return false; /* Check options */ Loading @@ -117,7 +80,7 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize) continue; return false; check_WSS = f->wss.wc; Loading Loading @@ -183,9 +146,61 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, } } if (fmatch != FMATCH_OK) return fmatch == FMATCH_OK; } bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, int hooknum, struct net_device *in, struct net_device *out, const struct nf_osf_info *info, struct net *net, const struct list_head *nf_osf_fingers) { const unsigned char *optp = NULL, *_optp = NULL; const struct iphdr *ip = ip_hdr(skb); const struct nf_osf_user_finger *f; unsigned char opts[MAX_IPOPTLEN]; const struct nf_osf_finger *kf; int fcount = 0, ttl_check; int fmatch = FMATCH_WRONG; unsigned int optsize = 0; const struct tcphdr *tcp; struct tcphdr _tcph; u16 window, totlen; bool df; tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph); if (!tcp) return false; if (!tcp->syn) return false; totlen = ntohs(ip->tot_len); df = ntohs(ip->frag_off) & IP_DF; window = ntohs(tcp->window); if (tcp->doff * 4 > sizeof(struct tcphdr)) { optsize = tcp->doff * 4 - sizeof(struct tcphdr); _optp = optp = skb_header_pointer(skb, ip_hdrlen(skb) + sizeof(struct tcphdr), optsize, opts); } ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : -1; list_for_each_entry_rcu(kf, &nf_osf_fingers[df], finger_entry) { f = &kf->finger; if (!(info->flags & NF_OSF_LOG) && strcmp(info->genre, f->genre)) continue; if (!nf_osf_match_one(skb, f, ttl_check, totlen, window, optp, optsize)) continue; fmatch = FMATCH_OK; fcount++; if (info->flags & NF_OSF_LOG) Loading