Example #1
0
/*
 * Print the ip address contained in a command.
 */
void
print_ip6(struct buf_pr *bp, ipfw_insn_ip6 *cmd, char const *s)
{
       struct hostent *he = NULL;
       int len = F_LEN((ipfw_insn *) cmd) - 1;
       struct in6_addr *a = &(cmd->addr6);
       char trad[255];

       bprintf(bp, "%s%s ", cmd->o.len & F_NOT ? " not": "", s);

       if (cmd->o.opcode == O_IP6_SRC_ME || cmd->o.opcode == O_IP6_DST_ME) {
	       bprintf(bp, "me6");
	       return;
       }
       if (cmd->o.opcode == O_IP6) {
	       bprintf(bp, " ip6");
	       return;
       }

       /*
	* len == 4 indicates a single IP, whereas lists of 1 or more
	* addr/mask pairs have len = (2n+1). We convert len to n so we
	* use that to count the number of entries.
	*/

       for (len = len / 4; len > 0; len -= 2, a += 2) {
	   int mb =	/* mask length */
	       (cmd->o.opcode == O_IP6_SRC || cmd->o.opcode == O_IP6_DST) ?
	       128 : contigmask((uint8_t *)&(a[1]), 128);

	   if (mb == 128 && co.do_resolv)
	       he = gethostbyaddr((char *)a, sizeof(*a), AF_INET6);
	   if (he != NULL)	     /* resolved to name */
	       bprintf(bp, "%s", he->h_name);
	   else if (mb == 0)	   /* any */
	       bprintf(bp, "any");
	   else {	  /* numeric IP followed by some kind of mask */
	       if (inet_ntop(AF_INET6,  a, trad, sizeof( trad ) ) == NULL)
		   bprintf(bp, "Error ntop in print_ip6\n");
	       bprintf(bp, "%s",  trad );
	       if (mb < 0) /* mask not contiguous */
		   bprintf(bp, "/%s",
		       inet_ntop(AF_INET6, &a[1], trad, sizeof(trad)));
	       else if (mb < 128)
		   bprintf(bp, "/%d", mb);
	   }
	   if (len > 2)
	       bprintf(bp, ",");
       }
}
Example #2
0
void
show_to_mask(ipfw_insn *cmd, int show_or)
{
	int mask;
	char *word = "to";
	if (show_or)
		word = "or";
	ipfw_insn_ip *p = (ipfw_insn_ip *)cmd;
	printf(" %s %s", word, inet_ntoa(p->addr));

	mask = contigmask((u_char *)&(p->mask.s_addr), 32);
	if (mask < 32)
		printf("/%d", mask);
}
Example #3
0
/*
 * fill the addr and mask fields in the instruction as appropriate from av.
 * Update length as appropriate.
 * The following formats are allowed:
 *     any     matches any IP6. Actually returns an empty instruction.
 *     me      returns O_IP6_*_ME
 *
 *     03f1::234:123:0342			single IP6 address
 *     03f1::234:123:0342/24			address/masklen
 *     03f1::234:123:0342/ffff::ffff:ffff	address/mask
 *     03f1::234:123:0342/24,03f1::234:123:0343/	List of address
 *
 * Set of address (as in ipv6) not supported because ipv6 address
 * are typically random past the initial prefix.
 * Return 1 on success, 0 on failure.
 */
static int
fill_ip6(ipfw_insn_ip6 *cmd, char *av, int cblen, struct tidx *tstate)
{
	int len = 0;
	struct in6_addr *d = &(cmd->addr6);
	/*
	 * Needed for multiple address.
	 * Note d[1] points to struct in6_add r mask6 of cmd
	 */

	cmd->o.len &= ~F_LEN_MASK;	/* zero len */

	if (strcmp(av, "any") == 0)
		return (1);


	if (strcmp(av, "me") == 0) {	/* Set the data for "me" opt*/
		cmd->o.len |= F_INSN_SIZE(ipfw_insn);
		return (1);
	}

	if (strcmp(av, "me6") == 0) {	/* Set the data for "me" opt*/
		cmd->o.len |= F_INSN_SIZE(ipfw_insn);
		return (1);
	}

	if (strncmp(av, "table(", 6) == 0) {
		fill_table(&cmd->o, av, O_IP_DST_LOOKUP, tstate);
		return (1);
	}

	av = strdup(av);
	while (av) {
		/*
		 * After the address we can have '/' indicating a mask,
		 * or ',' indicating another address follows.
		 */

		char *p, *q;
		int masklen;
		char md = '\0';

		CHECK_LENGTH(cblen, 1 + len + 2 * F_INSN_SIZE(struct in6_addr));

		if ((q = strchr(av, ',')) ) {
			*q = '\0';
			q++;
		}

		if ((p = strchr(av, '/')) ) {
			md = *p;	/* save the separator */
			*p = '\0';	/* terminate address string */
			p++;		/* and skip past it */
		}
		/* now p points to NULL, mask or next entry */

		/* lookup stores address in *d as a side effect */
		if (lookup_host6(av, d) != 0) {
			/* XXX: failed. Free memory and go */
			errx(EX_DATAERR, "bad address \"%s\"", av);
		}
		/* next, look at the mask, if any */
		if (md == '/' && strchr(p, ':')) {
			if (!inet_pton(AF_INET6, p, &d[1]))
				errx(EX_DATAERR, "bad mask \"%s\"", p);

			masklen = contigmask((uint8_t *)&(d[1]), 128);
		} else {
			masklen = (md == '/') ? atoi(p) : 128;
			if (masklen > 128 || masklen < 0)
				errx(EX_DATAERR, "bad width \"%s\''", p);
			else
				n2mask(&d[1], masklen);
		}

		APPLY_MASK(d, &d[1])   /* mask base address with mask */

		av = q;

		/* Check this entry */
		if (masklen == 0) {
			/*
			 * 'any' turns the entire list into a NOP.
			 * 'not any' never matches, so it is removed from the
			 * list unless it is the only item, in which case we
			 * report an error.
			 */
			if (cmd->o.len & F_NOT && av == NULL && len == 0)
				errx(EX_DATAERR, "not any never matches");
			continue;
		}

		/*
		 * A single IP can be stored alone
		 */
		if (masklen == 128 && av == NULL && len == 0) {
			len = F_INSN_SIZE(struct in6_addr);
			break;
		}

		/* Update length and pointer to arguments */
		len += F_INSN_SIZE(struct in6_addr)*2;
		d += 2;
	} /* end while */