X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fipv6%2Fnetfilter%2Fip6t_frag.c;h=bb1cfa82b47c779b1d67f80b30f6a572f864764a;hb=9f15c5302de4e8b0aac7ca24c36bf26a7fe1a513;hp=a9964b946ed503409eeaa750d044ac82fa654bc3;hpb=2e4e6a17af35be359cc8f1c924f8f198fbd478cc;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index a9964b9..bb1cfa8 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -28,130 +29,132 @@ MODULE_AUTHOR("Andras Kis-Szabo "); #endif /* Returns 1 if the id is matched by the range, 0 otherwise */ -static inline int -id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert) +static inline bool +id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert) { - int r=0; - DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', - min,id,max); - r=(id >= min && id <= max) ^ invert; - DEBUGP(" result %s\n",r? "PASS" : "FAILED"); - return r; + bool r; + DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ', + min, id, max); + r = (id >= min && id <= max) ^ invert; + DEBUGP(" result %s\n", r ? "PASS" : "FAILED"); + return r; } -static int +static bool match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, + const struct xt_match *match, const void *matchinfo, int offset, unsigned int protoff, - int *hotdrop) + bool *hotdrop) { - struct frag_hdr _frag, *fh; - const struct ip6t_frag *fraginfo = matchinfo; - unsigned int ptr; - - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0) - return 0; + struct frag_hdr _frag; + const struct frag_hdr *fh; + const struct ip6t_frag *fraginfo = matchinfo; + unsigned int ptr; + int err; + + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); + if (err < 0) { + if (err != -ENOENT) + *hotdrop = true; + return false; + } fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); - if (fh == NULL){ - *hotdrop = 1; - return 0; + if (fh == NULL) { + *hotdrop = true; + return false; } - DEBUGP("INFO %04X ", fh->frag_off); - DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7); - DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6); - DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF)); - DEBUGP("ID %u %08X\n", ntohl(fh->identification), - ntohl(fh->identification)); - - DEBUGP("IPv6 FRAG id %02X ", - (id_match(fraginfo->ids[0], fraginfo->ids[1], - ntohl(fh->identification), - !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))); - DEBUGP("res %02X %02X%04X %02X ", - (fraginfo->flags & IP6T_FRAG_RES), fh->reserved, - ntohs(fh->frag_off) & 0x6, - !((fraginfo->flags & IP6T_FRAG_RES) - && (fh->reserved || (ntohs(fh->frag_off) & 0x06)))); - DEBUGP("first %02X %02X %02X ", - (fraginfo->flags & IP6T_FRAG_FST), - ntohs(fh->frag_off) & ~0x7, - !((fraginfo->flags & IP6T_FRAG_FST) - && (ntohs(fh->frag_off) & ~0x7))); - DEBUGP("mf %02X %02X %02X ", - (fraginfo->flags & IP6T_FRAG_MF), - ntohs(fh->frag_off) & IP6_MF, - !((fraginfo->flags & IP6T_FRAG_MF) - && !((ntohs(fh->frag_off) & IP6_MF)))); - DEBUGP("last %02X %02X %02X\n", - (fraginfo->flags & IP6T_FRAG_NMF), - ntohs(fh->frag_off) & IP6_MF, - !((fraginfo->flags & IP6T_FRAG_NMF) - && (ntohs(fh->frag_off) & IP6_MF))); - - return (fh != NULL) - && - (id_match(fraginfo->ids[0], fraginfo->ids[1], - ntohl(fh->identification), - !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))) - && - !((fraginfo->flags & IP6T_FRAG_RES) - && (fh->reserved || (ntohs(fh->frag_off) & 0x6))) - && - !((fraginfo->flags & IP6T_FRAG_FST) - && (ntohs(fh->frag_off) & ~0x7)) - && - !((fraginfo->flags & IP6T_FRAG_MF) - && !(ntohs(fh->frag_off) & IP6_MF)) - && - !((fraginfo->flags & IP6T_FRAG_NMF) - && (ntohs(fh->frag_off) & IP6_MF)); + DEBUGP("INFO %04X ", fh->frag_off); + DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7); + DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6); + DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF)); + DEBUGP("ID %u %08X\n", ntohl(fh->identification), + ntohl(fh->identification)); + + DEBUGP("IPv6 FRAG id %02X ", + id_match(fraginfo->ids[0], fraginfo->ids[1], + ntohl(fh->identification), + !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))); + DEBUGP("res %02X %02X%04X %02X ", + fraginfo->flags & IP6T_FRAG_RES, fh->reserved, + ntohs(fh->frag_off) & 0x6, + !((fraginfo->flags & IP6T_FRAG_RES) + && (fh->reserved || (ntohs(fh->frag_off) & 0x06)))); + DEBUGP("first %02X %02X %02X ", + fraginfo->flags & IP6T_FRAG_FST, + ntohs(fh->frag_off) & ~0x7, + !((fraginfo->flags & IP6T_FRAG_FST) + && (ntohs(fh->frag_off) & ~0x7))); + DEBUGP("mf %02X %02X %02X ", + fraginfo->flags & IP6T_FRAG_MF, + ntohs(fh->frag_off) & IP6_MF, + !((fraginfo->flags & IP6T_FRAG_MF) + && !((ntohs(fh->frag_off) & IP6_MF)))); + DEBUGP("last %02X %02X %02X\n", + fraginfo->flags & IP6T_FRAG_NMF, + ntohs(fh->frag_off) & IP6_MF, + !((fraginfo->flags & IP6T_FRAG_NMF) + && (ntohs(fh->frag_off) & IP6_MF))); + + return (fh != NULL) + && + id_match(fraginfo->ids[0], fraginfo->ids[1], + ntohl(fh->identification), + !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)) + && + !((fraginfo->flags & IP6T_FRAG_RES) + && (fh->reserved || (ntohs(fh->frag_off) & 0x6))) + && + !((fraginfo->flags & IP6T_FRAG_FST) + && (ntohs(fh->frag_off) & ~0x7)) + && + !((fraginfo->flags & IP6T_FRAG_MF) + && !(ntohs(fh->frag_off) & IP6_MF)) + && + !((fraginfo->flags & IP6T_FRAG_NMF) + && (ntohs(fh->frag_off) & IP6_MF)); } /* Called when user tries to insert an entry of this type. */ -static int +static bool checkentry(const char *tablename, - const void *ip, - void *matchinfo, - unsigned int matchinfosize, - unsigned int hook_mask) + const void *ip, + const struct xt_match *match, + void *matchinfo, + unsigned int hook_mask) { - const struct ip6t_frag *fraginfo = matchinfo; - - if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_frag))) { - DEBUGP("ip6t_frag: matchsize %u != %u\n", - matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_frag))); - return 0; - } - if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { - DEBUGP("ip6t_frag: unknown flags %X\n", - fraginfo->invflags); - return 0; - } - - return 1; + const struct ip6t_frag *fraginfo = matchinfo; + + if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { + DEBUGP("ip6t_frag: unknown flags %X\n", fraginfo->invflags); + return false; + } + return true; } -static struct ip6t_match frag_match = { +static struct xt_match frag_match __read_mostly = { .name = "frag", - .match = &match, - .checkentry = &checkentry, + .family = AF_INET6, + .match = match, + .matchsize = sizeof(struct ip6t_frag), + .checkentry = checkentry, .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_frag_init(void) { - return ip6t_register_match(&frag_match); + return xt_register_match(&frag_match); } -static void __exit cleanup(void) +static void __exit ip6t_frag_fini(void) { - ip6t_unregister_match(&frag_match); + xt_unregister_match(&frag_match); } -module_init(init); -module_exit(cleanup); +module_init(ip6t_frag_init); +module_exit(ip6t_frag_fini);