static int 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) { struct ip_auth_hdr *ah, _ah; const struct ip6t_ah *ahinfo = matchinfo; unsigned int ptr; unsigned int hdrlen = 0; int err; err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); if (err < 0) { if (err != -ENOENT) *hotdrop = 1; return 0; } ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); if (ah == NULL) { *hotdrop = 1; return 0; } hdrlen = (ah->hdrlen + 2) << 2; DEBUGP("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen); DEBUGP("RES %04X ", ah->reserved); DEBUGP("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi)); DEBUGP("IPv6 AH spi %02X ", (spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IP6T_AH_INV_SPI)))); DEBUGP("len %02X %04X %02X ", ahinfo->hdrlen, hdrlen, (!ahinfo->hdrlen || (ahinfo->hdrlen == hdrlen) ^ !!(ahinfo->invflags & IP6T_AH_INV_LEN))); DEBUGP("res %02X %04X %02X\n", ahinfo->hdrres, ah->reserved, !(ahinfo->hdrres && ah->reserved)); return (ah != NULL) && (spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IP6T_AH_INV_SPI))) && (!ahinfo->hdrlen || (ahinfo->hdrlen == hdrlen) ^ !!(ahinfo->invflags & IP6T_AH_INV_LEN)) && !(ahinfo->hdrres && ah->reserved); }
static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par) { struct ip_auth_hdr _ah; const struct ip_auth_hdr *ah; const struct ip6t_ah *ahinfo = par->matchinfo; unsigned int ptr; unsigned int hdrlen = 0; int err; err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); if (err < 0) { if (err != -ENOENT) *par->hotdrop = true; return false; } ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); if (ah == NULL) { *par->hotdrop = true; return false; } hdrlen = (ah->hdrlen + 2) << 2; pr_debug("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen); pr_debug("RES %04X ", ah->reserved); pr_debug("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi)); pr_debug("IPv6 AH spi %02X ", spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IP6T_AH_INV_SPI))); pr_debug("len %02X %04X %02X ", ahinfo->hdrlen, hdrlen, (!ahinfo->hdrlen || (ahinfo->hdrlen == hdrlen) ^ !!(ahinfo->invflags & IP6T_AH_INV_LEN))); pr_debug("res %02X %04X %02X\n", ahinfo->hdrres, ah->reserved, !(ahinfo->hdrres && ah->reserved)); return (ah != NULL) && spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IP6T_AH_INV_SPI)) && (!ahinfo->hdrlen || (ahinfo->hdrlen == hdrlen) ^ !!(ahinfo->invflags & IP6T_AH_INV_LEN)) && !(ahinfo->hdrres && ah->reserved); }
static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, int offset, unsigned int protoff, int *hotdrop) { struct ip_esp_hdr _esp, *eh; const struct ip6t_esp *espinfo = matchinfo; unsigned int ptr; /* Make sure this isn't an evil packet */ /*DEBUGP("ipv6_esp entered \n");*/ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP) < 0) return 0; eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp); if (eh == NULL) { *hotdrop = 1; return 0; } DEBUGP("IPv6 ESP SPI %u %08X\n", ntohl(eh->spi), ntohl(eh->spi)); return (eh != NULL) && spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi), !!(espinfo->invflags & IP6T_ESP_INV_SPI)); }
static int 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) { struct ip_auth_hdr _ahdr, *ah; const struct ipt_ah *ahinfo = matchinfo; /* Must not be a fragment. */ if (offset) return 0; ah = skb_header_pointer(skb, protoff, sizeof(_ahdr), &_ahdr); if (ah == NULL) { /* We've been asked to examine this packet, and we * can't. Hence, no choice but to drop. */ duprintf("Dropping evil AH tinygram.\n"); *hotdrop = 1; return 0; } return spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IPT_AH_INV_SPI)); }
static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, int offset, int *hotdrop) { struct ip_auth_hdr ah; const struct ipt_ah *ahinfo = matchinfo; /* Must not be a fragment. */ if (offset) return 0; if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &ah, sizeof(ah)) < 0) { /* We've been asked to examine this packet, and we can't. Hence, no choice but to drop. */ duprintf("Dropping evil AH tinygram.\n"); *hotdrop = 1; return 0; } return spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah.spi), !!(ahinfo->invflags & IPT_AH_INV_SPI)); }
static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, int offset, const void *hdr, u_int16_t datalen, int *hotdrop) { const struct ahhdr *ah = hdr; const struct ipt_ah *ahinfo = matchinfo; if (offset == 0 && datalen < sizeof(struct ahhdr)) { /* We've been asked to examine this packet, and we can't. Hence, no choice but to drop. */ duprintf("Dropping evil AH tinygram.\n"); *hotdrop = 1; return 0; } /* Must not be a fragment. */ return !offset && spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IPT_AH_INV_SPI)); }
static bool esp_mt(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, bool *hotdrop) { const struct ip_esp_hdr *eh; struct ip_esp_hdr _esp; const struct xt_esp *espinfo = matchinfo; /* Must not be a fragment. */ if (offset) return false; eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp); if (eh == NULL) { /* We've been asked to examine this packet, and we * can't. Hence, no choice but to drop. */ duprintf("Dropping evil ESP tinygram.\n"); *hotdrop = true; return false; } return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi), !!(espinfo->invflags & XT_ESP_INV_SPI)); }
static bool match(const struct sk_buff *skb, struct xt_action_param *par) { struct ip_esp_hdr _esp, *eh; const struct xt_esp *espinfo = par->matchinfo; /* Must not be a fragment. */ if (par->fragoff != 0) return false; eh = skb_header_pointer(skb, par->thoff, sizeof(_esp), &_esp); if (eh == NULL) { /* We've been asked to examine this packet, and we * can't. Hence, no choice but to drop. */ duprintf("Dropping evil ESP tinygram.\n"); par->hotdrop = true; return false; } return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi), !!(espinfo->invflags & XT_ESP_INV_SPI)); }
static bool ah_mt(const struct sk_buff *skb, struct xt_action_param *par) { struct ip_auth_hdr _ahdr; const struct ip_auth_hdr *ah; const struct ipt_ah *ahinfo = par->matchinfo; /* Must not be a fragment. */ if (par->fragoff != 0) return false; ah = skb_header_pointer(skb, par->thoff, sizeof(_ahdr), &_ahdr); if (ah == NULL) { /* We've been asked to examine this packet, and we * can't. Hence, no choice but to drop. */ pr_debug("Dropping evil AH tinygram.\n"); par->hotdrop = true; return 0; } return spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IPT_AH_INV_SPI)); }
static bool comp_mt(const struct sk_buff *skb, struct xt_action_param *par) { struct ip_comp_hdr _comphdr; const struct ip_comp_hdr *chdr; const struct xt_ipcomp *compinfo = par->matchinfo; /* Must not be a fragment. */ if (par->fragoff != 0) return false; chdr = skb_header_pointer(skb, par->thoff, sizeof(_comphdr), &_comphdr); if (chdr == NULL) { /* We've been asked to examine this packet, and we * can't. Hence, no choice but to drop. */ pr_debug("Dropping evil IPComp tinygram.\n"); par->hotdrop = true; return 0; } return spi_match(compinfo->spis[0], compinfo->spis[1], ntohl(chdr->cpi << 16), !!(compinfo->invflags & XT_IPCOMP_INV_SPI)); }
static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, int offset, const void *protohdr, u_int16_t datalen, int *hotdrop) { struct ahhdr *ah = NULL; const struct ip6t_ah *ahinfo = matchinfo; unsigned int temp; int len; u8 nexthdr; unsigned int ptr; unsigned int hdrlen = 0; /*DEBUGP("IPv6 AH entered\n");*/ /* if (opt->auth == 0) return 0; * It does not filled on output */ /* type of the 1st exthdr */ nexthdr = skb->nh.ipv6h->nexthdr; /* pointer to the 1st exthdr */ ptr = sizeof(struct ipv6hdr); /* available length */ len = skb->len - ptr; temp = 0; while (ip6t_ext_hdr(nexthdr)) { struct ipv6_opt_hdr *hdr; DEBUGP("ipv6_ah header iteration \n"); /* Is there enough space for the next ext header? */ if (len < (int)sizeof(struct ipv6_opt_hdr)) return 0; /* No more exthdr -> evaluate */ if (nexthdr == NEXTHDR_NONE) { break; } /* ESP -> evaluate */ if (nexthdr == NEXTHDR_ESP) { break; } hdr=skb->data+ptr; /* Calculate the header length */ if (nexthdr == NEXTHDR_FRAGMENT) { hdrlen = 8; } else if (nexthdr == NEXTHDR_AUTH) hdrlen = (hdr->hdrlen+2)<<2; else hdrlen = ipv6_optlen(hdr); /* AH -> evaluate */ if (nexthdr == NEXTHDR_AUTH) { temp |= MASK_AH; break; } /* set the flag */ switch (nexthdr){ case NEXTHDR_HOP: case NEXTHDR_ROUTING: case NEXTHDR_FRAGMENT: case NEXTHDR_AUTH: case NEXTHDR_DEST: break; default: DEBUGP("ipv6_ah match: unknown nextheader %u\n",nexthdr); return 0; break; } nexthdr = hdr->nexthdr; len -= hdrlen; ptr += hdrlen; if ( ptr > skb->len ) { DEBUGP("ipv6_ah: new pointer too large! \n"); break; } } /* AH header not found */ if ( temp != MASK_AH ) return 0; if (len < (int)sizeof(struct ahhdr)){ *hotdrop = 1; return 0; } ah=skb->data+ptr; DEBUGP("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen); DEBUGP("RES %04X ", ah->reserved); DEBUGP("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi)); DEBUGP("IPv6 AH spi %02X ", (spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IP6T_AH_INV_SPI)))); DEBUGP("len %02X %04X %02X ", ahinfo->hdrlen, hdrlen, (!ahinfo->hdrlen || (ahinfo->hdrlen == hdrlen) ^ !!(ahinfo->invflags & IP6T_AH_INV_LEN))); DEBUGP("res %02X %04X %02X\n", ahinfo->hdrres, ah->reserved, !(ahinfo->hdrres && ah->reserved)); return (ah != NULL) && (spi_match(ahinfo->spis[0], ahinfo->spis[1], ntohl(ah->spi), !!(ahinfo->invflags & IP6T_AH_INV_SPI))) && (!ahinfo->hdrlen || (ahinfo->hdrlen == hdrlen) ^ !!(ahinfo->invflags & IP6T_AH_INV_LEN)) && !(ahinfo->hdrres && ah->reserved); }
static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, int offset, const void *protohdr, u_int16_t datalen, int *hotdrop) { struct ip_esp_hdr *esp = NULL; const struct ip6t_esp *espinfo = matchinfo; unsigned int temp; int len; u8 nexthdr; unsigned int ptr; /* Make sure this isn't an evil packet */ /*DEBUGP("ipv6_esp entered \n");*/ /* type of the 1st exthdr */ nexthdr = skb->nh.ipv6h->nexthdr; /* pointer to the 1st exthdr */ ptr = sizeof(struct ipv6hdr); /* available length */ len = skb->len - ptr; temp = 0; while (ip6t_ext_hdr(nexthdr)) { struct ipv6_opt_hdr *hdr; int hdrlen; DEBUGP("ipv6_esp header iteration \n"); /* Is there enough space for the next ext header? */ if (len < (int)sizeof(struct ipv6_opt_hdr)) return 0; /* No more exthdr -> evaluate */ if (nexthdr == NEXTHDR_NONE) { break; } /* ESP -> evaluate */ if (nexthdr == NEXTHDR_ESP) { temp |= MASK_ESP; break; } hdr=(struct ipv6_opt_hdr *)skb->data+ptr; /* Calculate the header length */ if (nexthdr == NEXTHDR_FRAGMENT) { hdrlen = 8; } else if (nexthdr == NEXTHDR_AUTH) hdrlen = (hdr->hdrlen+2)<<2; else hdrlen = ipv6_optlen(hdr); /* set the flag */ switch (nexthdr){ case NEXTHDR_HOP: case NEXTHDR_ROUTING: case NEXTHDR_FRAGMENT: case NEXTHDR_AUTH: case NEXTHDR_DEST: break; default: DEBUGP("ipv6_esp match: unknown nextheader %u\n",nexthdr); return 0; break; } nexthdr = hdr->nexthdr; len -= hdrlen; ptr += hdrlen; if ( ptr > skb->len ) { DEBUGP("ipv6_esp: new pointer too large! \n"); break; } } /* ESP header not found */ if ( temp != MASK_ESP ) return 0; if (len < (int)sizeof(struct ip_esp_hdr)){ *hotdrop = 1; return 0; } esp = (struct ip_esp_hdr *) (skb->data + ptr); DEBUGP("IPv6 ESP SPI %u %08X\n", ntohl(esp->spi), ntohl(esp->spi)); return (esp != NULL) && spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(esp->spi), !!(espinfo->invflags & IP6T_ESP_INV_SPI)); }