Пример #1
0
static void ipvs_mt_parse_addr_and_mask(const char *arg,
					union nf_inet_addr *address,
					union nf_inet_addr *mask,
					unsigned int family)
{
	struct in_addr *addr = NULL;
	struct in6_addr *addr6 = NULL;
	unsigned int naddrs = 0;

	if (family == NFPROTO_IPV4) {
		xtables_ipparse_any(arg, &addr, &mask->in, &naddrs);
		if (naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
				      "multiple IP addresses not allowed");
		if (naddrs == 1)
			memcpy(&address->in, addr, sizeof(*addr));
	} else if (family == NFPROTO_IPV6) {
		xtables_ip6parse_any(arg, &addr6, &mask->in6, &naddrs);
		if (naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
				      "multiple IP addresses not allowed");
		if (naddrs == 1)
			memcpy(&address->in6, addr6, sizeof(*addr6));
	} else {
		/* Hu? */
		assert(false);
	}
}
static int ipaddr_mt4_parse(int c, char **argv, int invert,
		unsigned int *flags, const void *entry,
		struct xt_entry_match **match)
{
	struct xt_ipaddr_mtinfo *info = (void *)(*match)->data;
	struct in_addr *addrs, mask;
	unsigned int naddrs;

	switch (c) {
		case '1': /* --ipsrc */
			if (*flags & XT_IPADDR_SRC)
				xtables_error(PARAMETER_PROBLEM, "xt_ipaddr: "
						"Only use \"--ipsrc\" once!");

			*flags |= XT_IPADDR_SRC;
			info->flags |= XT_IPADDR_SRC;

			if (invert)
				info->flags |= XT_IPADDR_SRC_INV;

			xtables_ipparse_any(optarg, &addrs, &mask, &naddrs);

			if (naddrs != 1)
				xtables_error(PARAMETER_PROBLEM,
						"%s does not resolves to exactly "
						"one address", optarg);

			/* Copy the single address */
			memcpy(&info->src.in, addrs, sizeof(*addrs));
			return true;

		case '2': /* --ipdst */
			if (*flags & XT_IPADDR_DST)
				xtables_error(PARAMETER_PROBLEM, "xt_ipaddr: "
						"Only use \"--ipdst\" once!");

			*flags |= XT_IPADDR_DST;
			info->flags |= XT_IPADDR_DST;

			if (invert)
				info->flags |= XT_IPADDR_DST_INV;

			// addrs = xtables_numeric_to_ipaddr(optarg, &info->dst.in);
			addrs = &info->dst.in;

			if (addrs == NULL)
				xtables_error(PARAMETER_PROBLEM,
						"Parse error at %s\n", optarg);

			memcpy(&info->dst.in, addrs, sizeof(*addrs));
			return true;
	}
	return false;
}
Пример #3
0
static PyObject *
py_ipt_entry_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
{
  static char *kwlist[] = {"source", "destination", "jump",
      "in_interface", "out_interface", NULL};
  PyIPTEntryObject *self = NULL;
  char *source = NULL;
  char *destination = NULL;
  char *jump = NULL;
  char *in_interface = NULL;
  char *out_interface = NULL;
  unsigned int  n_source_addresses = 0;
  unsigned int  n_destination_addresses = 0;

  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|zzzzz", kwlist, &source,
    &destination, &jump, &in_interface, &out_interface))
    goto error;

  self = (PyIPTEntryObject *) type->tp_alloc (type, 0);
  if (self == NULL)
    goto error;

  self->source = NULL;
  self->destination = NULL;
  self->jump = NULL;
  self->in_interface = NULL;
  self->out_interface = NULL;
  self->matches = NULL;
  self->target = NULL;

  if (source == NULL)
    source = "0.0.0.0/0";

  xtables_ipparse_any (source, &self->source, &self->entry.ip.smsk, &n_source_addresses);
  if (n_source_addresses == 0) {
    self->source = NULL;
    PyErr_SetString (PyIPTException,
        "invalid source address.");
    goto error;
  } else if (n_source_addresses > 1) {
    PyErr_SetString (PyIPTException,
        "multiple source addresses are not allowed.");
    goto error;
  }

  if (destination == NULL)
    destination = "0.0.0.0/0";

  xtables_ipparse_any (destination, &self->destination, &self->entry.ip.dmsk, &n_destination_addresses);
  if (n_destination_addresses != 1) {
    self->destination = NULL;
    PyErr_SetString (PyIPTException,
        "invalid destination address.");
    goto error;
  } else if (n_destination_addresses != 1) {
    PyErr_SetString (PyIPTException,
        "multiple destination addresses are not allowed.");
    goto error;
  }
  
  if (in_interface) { 
    xtables_parse_interface(in_interface, self->entry.ip.iniface, self->entry.ip.iniface_mask);
    if (py_ipt_xt_get_error ()) {
      PyErr_SetString (PyIPTException, py_ipt_xt_get_error_message ());
      goto error;
    }
  }
 
  if (out_interface) { 
    xtables_parse_interface(out_interface, self->entry.ip.outiface, self->entry.ip.outiface_mask);
    if (py_ipt_xt_get_error ()) {
      PyErr_SetString (PyIPTException, py_ipt_xt_get_error_message ());
      goto error;
    }
  }

  if (jump)
    self->jump = strdup (jump);

  if (in_interface)
    self->in_interface = strdup (in_interface);

  if (out_interface)
    self->out_interface = strdup (out_interface);

  self->matches = PyList_New (0);

  return (PyObject *) self;

error:
  Py_XDECREF (self);
  return NULL;
}
Пример #4
0
static int policy_parse(int c, int invert, unsigned int *flags,
                        struct xt_policy_info *info, uint8_t family)
{
	struct xt_policy_elem *e = &info->pol[info->len];
	struct in_addr *addr = NULL, mask;
	struct in6_addr *addr6 = NULL, mask6;
	unsigned int naddr = 0, num;
	int mode;

	xtables_check_inverse(optarg, &invert, &optind, 0);

	switch (c) {
	case '1':
		if (info->flags & (XT_POLICY_MATCH_IN | XT_POLICY_MATCH_OUT))
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --dir option");
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --dir option");

		info->flags |= parse_direction(optarg);
		break;
	case '2':
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --policy option");

		info->flags |= parse_policy(optarg);
		break;
	case '3':
		if (info->flags & XT_POLICY_MATCH_STRICT)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --strict option");

		if (invert)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --strict option");

		info->flags |= XT_POLICY_MATCH_STRICT;
		break;
	case '4':
		if (e->match.reqid)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --reqid option");

		e->match.reqid = 1;
		e->invert.reqid = invert;
		if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg);
		e->reqid = num;
		break;
	case '5':
		if (e->match.spi)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --spi option");

		e->match.spi = 1;
		e->invert.spi = invert;
		if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg);
		e->spi = num;
		break;
	case '6':
		if (e->match.saddr)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --tunnel-src option");

		if (family == NFPROTO_IPV6)
			xtables_ip6parse_any(optarg, &addr6, &mask6, &naddr);
		else
			xtables_ipparse_any(optarg, &addr, &mask, &naddr);
		if (naddr > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: name resolves to multiple IPs");

		e->match.saddr = 1;
		e->invert.saddr = invert;
		if (family == NFPROTO_IPV6) {
			memcpy(&e->saddr.a6, addr6, sizeof(*addr6));
			memcpy(&e->smask.a6, &mask6, sizeof(mask6));
		} else {
			e->saddr.a4 = addr[0];
			e->smask.a4 = mask;
		}
                break;
	case '7':
		if (e->match.daddr)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --tunnel-dst option");

		if (family == NFPROTO_IPV6)
			xtables_ip6parse_any(optarg, &addr6, &mask6, &naddr);
		else
			xtables_ipparse_any(optarg, &addr, &mask, &naddr);
		if (naddr > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: name resolves to multiple IPs");

		e->match.daddr = 1;
		e->invert.daddr = invert;
		if (family == NFPROTO_IPV6) {
			memcpy(&e->daddr.a6, addr6, sizeof(*addr6));
			memcpy(&e->dmask.a6, &mask6, sizeof(mask6));
		} else {
			e->daddr.a4 = addr[0];
			e->dmask.a4 = mask;
		}
		break;
	case '8':
		if (e->match.proto)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --proto option");

		e->proto = xtables_parse_protocol(optarg);
		if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP &&
		    e->proto != IPPROTO_COMP)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: protocol must ah/esp/ipcomp");
		e->match.proto = 1;
		e->invert.proto = invert;
		break;
	case '9':
		if (e->match.mode)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --mode option");

		mode = parse_mode(optarg);
		e->match.mode = 1;
		e->invert.mode = invert;
		e->mode = mode;
		break;
	case 'a':
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --next option");

		if (++info->len == XT_POLICY_MAX_ELEM)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: maximum policy depth reached");
		break;
	default:
		return 0;
	}

	return 1;
}
Пример #5
0
static int
conntrack_mt4_parse(int c, bool invert, unsigned int *flags,
                    struct xt_conntrack_mtinfo2 *info)
{
	struct in_addr *addr = NULL;
	unsigned int naddrs = 0;

	switch (c) {
	case '3': /* --ctorigsrc */
		xtables_ipparse_any(optarg, &addr, &info->origsrc_mask.in,
		                        &naddrs);
		if (naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "multiple IP addresses not allowed");
		if (naddrs == 1)
			memcpy(&info->origsrc_addr.in, addr, sizeof(*addr));
		info->match_flags |= XT_CONNTRACK_ORIGSRC;
		if (invert)
			info->invert_flags |= XT_CONNTRACK_ORIGSRC;
		break;

	case '4': /* --ctorigdst */
		xtables_ipparse_any(optarg, &addr, &info->origdst_mask.in,
		                        &naddrs);
		if (naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "multiple IP addresses not allowed");
		if (naddrs == 1)
			memcpy(&info->origdst_addr.in, addr, sizeof(*addr));
		info->match_flags |= XT_CONNTRACK_ORIGDST;
		if (invert)
			info->invert_flags |= XT_CONNTRACK_ORIGDST;
		break;

	case '5': /* --ctreplsrc */
		xtables_ipparse_any(optarg, &addr, &info->replsrc_mask.in,
		                        &naddrs);
		if (naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "multiple IP addresses not allowed");
		if (naddrs == 1)
			memcpy(&info->replsrc_addr.in, addr, sizeof(*addr));
		info->match_flags |= XT_CONNTRACK_REPLSRC;
		if (invert)
			info->invert_flags |= XT_CONNTRACK_REPLSRC;
		break;

	case '6': /* --ctrepldst */
		xtables_ipparse_any(optarg, &addr, &info->repldst_mask.in,
		                        &naddrs);
		if (naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "multiple IP addresses not allowed");
		if (naddrs == 1)
			memcpy(&info->repldst_addr.in, addr, sizeof(*addr));
		info->match_flags |= XT_CONNTRACK_REPLDST;
		if (invert)
			info->invert_flags |= XT_CONNTRACK_REPLDST;
		break;


	default:
		return conntrack_mt_parse(c, invert, flags, info);
	}

	*flags = info->match_flags;
	return true;
}
Пример #6
0
static int conntrack_parse(int c, char **argv, int invert, unsigned int *flags,
                           const void *entry, struct xt_entry_match **match)
{
	struct xt_conntrack_info *sinfo = (void *)(*match)->data;
	char *protocol = NULL;
	unsigned int naddrs = 0;
	struct in_addr *addrs = NULL;


	switch (c) {
	case '1':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		parse_states(argv[optind-1], sinfo);
		if (invert) {
			sinfo->invflags |= XT_CONNTRACK_STATE;
		}
		sinfo->flags |= XT_CONNTRACK_STATE;
		break;

	case '2':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		if(invert)
			sinfo->invflags |= XT_CONNTRACK_PROTO;

		/* Canonicalize into lower case */
		for (protocol = argv[optind-1]; *protocol; protocol++)
			*protocol = tolower(*protocol);

		protocol = argv[optind-1];
		sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum =
			xtables_parse_protocol(protocol);

		if (sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum == 0
		    && (sinfo->invflags & XT_INV_PROTO))
			xtables_error(PARAMETER_PROBLEM,
				   "rule would never match protocol");

		sinfo->flags |= XT_CONNTRACK_PROTO;
		break;

	case '3':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		if (invert)
			sinfo->invflags |= XT_CONNTRACK_ORIGSRC;

		xtables_ipparse_any(argv[optind-1], &addrs,
					&sinfo->sipmsk[IP_CT_DIR_ORIGINAL],
					&naddrs);
		if(naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
				"multiple IP addresses not allowed");

		if(naddrs == 1) {
			sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip = addrs[0].s_addr;
		}

		sinfo->flags |= XT_CONNTRACK_ORIGSRC;
		break;

	case '4':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		if (invert)
			sinfo->invflags |= XT_CONNTRACK_ORIGDST;

		xtables_ipparse_any(argv[optind-1], &addrs,
					&sinfo->dipmsk[IP_CT_DIR_ORIGINAL],
					&naddrs);
		if(naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
				"multiple IP addresses not allowed");

		if(naddrs == 1) {
			sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip = addrs[0].s_addr;
		}

		sinfo->flags |= XT_CONNTRACK_ORIGDST;
		break;

	case '5':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		if (invert)
			sinfo->invflags |= XT_CONNTRACK_REPLSRC;

		xtables_ipparse_any(argv[optind-1], &addrs,
					&sinfo->sipmsk[IP_CT_DIR_REPLY],
					&naddrs);
		if(naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
				"multiple IP addresses not allowed");

		if(naddrs == 1) {
			sinfo->tuple[IP_CT_DIR_REPLY].src.ip = addrs[0].s_addr;
		}

		sinfo->flags |= XT_CONNTRACK_REPLSRC;
		break;

	case '6':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		if (invert)
			sinfo->invflags |= XT_CONNTRACK_REPLDST;

		xtables_ipparse_any(argv[optind-1], &addrs,
					&sinfo->dipmsk[IP_CT_DIR_REPLY],
					&naddrs);
		if(naddrs > 1)
			xtables_error(PARAMETER_PROBLEM,
				"multiple IP addresses not allowed");

		if(naddrs == 1) {
			sinfo->tuple[IP_CT_DIR_REPLY].dst.ip = addrs[0].s_addr;
		}

		sinfo->flags |= XT_CONNTRACK_REPLDST;
		break;

	case '7':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		parse_statuses(argv[optind-1], sinfo);
		if (invert) {
			sinfo->invflags |= XT_CONNTRACK_STATUS;
		}
		sinfo->flags |= XT_CONNTRACK_STATUS;
		break;

	case '8':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		parse_expires(argv[optind-1], sinfo);
		if (invert) {
			sinfo->invflags |= XT_CONNTRACK_EXPIRES;
		}
		sinfo->flags |= XT_CONNTRACK_EXPIRES;
		break;

	default:
		return 0;
	}

	*flags = sinfo->flags;
	return 1;
}
Пример #7
0
 int nat64_tg4_parse(int c, char **argv, int invert,
		unsigned int *flags, const void *entry,
		struct xt_entry_target **target)
{
	struct xt_nat64_tginfo *info = (void *)(*target)->data;
	struct in_addr *addrs, mask;
	char out_dev[IFNAMSIZ];
	unsigned char out_dev_mask[IFNAMSIZ];
	unsigned int naddrs;

	switch (c) {
		case '1': /* --ipsrc */
			if (*flags & XT_NAT64_IP_SRC)
				xtables_error(PARAMETER_PROBLEM, "xt_nat64: "
						"Only use \"--ipsrc\" once!");

			*flags |= XT_NAT64_IP_SRC;
			info->flags |= XT_NAT64_IP_SRC;

			if (invert)
				xtables_error(PARAMETER_PROBLEM, "xt_nat64: "
						"I'm sorry, the invert flag isn't available yet");

			xtables_ipparse_any(optarg, &addrs, &mask, &naddrs);

			if (naddrs != 1)
				xtables_error(PARAMETER_PROBLEM,
						"%s does not resolves to exactly "
						"one address", optarg);

			/* Copy the single address */
			memcpy(&info->ipsrc.in, addrs, sizeof(*addrs));
			return true;

		case '2': /* --ipdst */
			if (*flags & XT_NAT64_IP_DST)
				xtables_error(PARAMETER_PROBLEM, "xt_nat64: "
						"Only use \"--ipdst\" once!");

			*flags |= XT_NAT64_IP_DST;
			info->flags |= XT_NAT64_IP_DST;

			if (invert)
				xtables_error(PARAMETER_PROBLEM, "xt_nat64: "
						"I'm sorry, the invert flag isn't available yet");

			xtables_ipparse_any(optarg, &addrs, &mask, &naddrs);

			if (naddrs != 1)
				xtables_error(PARAMETER_PROBLEM,
						"%s does not resolves to exactly "
						"one address", optarg);

			if (addrs == NULL)
				xtables_error(PARAMETER_PROBLEM,
						"Parse error at %s\n", optarg);

			memcpy(&info->ipdst.in, addrs, sizeof(*addrs));
			return true;
		case '3': /* --oudev */
			if (*flags & XT_NAT64_OUT_DEV)
				xtables_error(PARAMETER_PROBLEM, "xt_nat64: "
						"Only use \"--outdev\" once!");

			*flags |= XT_NAT64_OUT_DEV;
			info->flags |= XT_NAT64_OUT_DEV;

			if (invert)
				xtables_error(PARAMETER_PROBLEM, "xt_nat64: "
						"I'm sorry, the invert flag isn't available yet");

			xtables_parse_interface(optarg, out_dev, out_dev_mask);

			if (out_dev == NULL)
				xtables_error(PARAMETER_PROBLEM,
						"Parse error at %s\n", optarg);

			memcpy(&info->out_dev, out_dev, sizeof(char) * IFNAMSIZ);
			memcpy(&info->out_dev_mask, out_dev_mask, sizeof(unsigned char) * IFNAMSIZ);
			return true;

	}
	return false;
}