Exemple #1
0
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);
}
Exemple #2
0
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));
}
Exemple #4
0
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));
}
Exemple #6
0
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));
}
Exemple #7
0
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));
}
Exemple #8
0
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));
}
Exemple #9
0
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));
}
Exemple #10
0
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);
}
Exemple #12
0
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));
}