예제 #1
0
static int handle_global_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_global *request)
{
	struct global_config response = { .mtu_plateaus = NULL };
	unsigned char *buffer;
	size_t buffer_len;
	bool disabled;
	int error;

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		log_debug("Returning 'Global' options.");

		error = config_clone(&response);
		if (error)
			goto end;

		disabled = xlat_is_nat64()
				? pool6_is_empty()
				: (pool6_is_empty() && eamt_is_empty());
		error = serialize_global_config(&response, disabled, &buffer, &buffer_len);
		if (error)
			goto end;

		error = respond_setcfg(nl_hdr, buffer, buffer_len);
		kfree(buffer);
		break;

	case OP_UPDATE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Updating 'Global' options.");

		buffer = (unsigned char *) (request + 1);
		buffer_len = jool_hdr->length - sizeof(*jool_hdr) - sizeof(*request);

		error = handle_global_update(request->update.type, buffer_len, buffer);
		break;

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		error = -EINVAL;
	}

end:
	return respond_error(nl_hdr, error);
}
예제 #2
0
파일: core.c 프로젝트: patybarron/NAT64
unsigned int core_4to6(struct sk_buff *skb)
{
	struct packet pkt;
	struct iphdr *hdr = ip_hdr(skb);
	int error;

	if (config_get_is_disable())
		return NF_ACCEPT; /* Translation is disabled; let the packet pass. */

	if (is_blacklisted4(hdr->saddr) || is_blacklisted4(hdr->daddr))
		return NF_ACCEPT;

	if (nat64_is_stateful()) {
		if (!pool4_contains(hdr->daddr) || pool6_is_empty())
			return NF_ACCEPT; /* Not meant for translation; let the kernel handle it. */
	}

	log_debug("===============================================");
	log_debug("Catching IPv4 packet: %pI4->%pI4", &hdr->saddr, &hdr->daddr);

	error = pkt_init_ipv4(&pkt, skb); /* Reminder: This function might change pointers. */
	if (error)
		return NF_DROP;

	error = validate_icmp4_csum(&pkt);
	if (error) {
		inc_stats(&pkt, IPSTATS_MIB_INHDRERRORS);
		return NF_DROP;
	}

	return core_common(&pkt);
}
예제 #3
0
int serialize_global_config(struct global_config *config, unsigned char **buffer_out,
		size_t *buffer_len_out)
{
	unsigned char *buffer;
	struct global_config *tmp;
	size_t mtus_len;
	bool disabled;

	mtus_len = config->mtu_plateau_count * sizeof(*config->mtu_plateaus);

	buffer = kmalloc(sizeof(*config) + mtus_len, GFP_KERNEL);
	if (!buffer) {
		log_debug("Could not allocate the configuration structure.");
		return -ENOMEM;
	}

	memcpy(buffer, config, sizeof(*config));
	memcpy(buffer + sizeof(*config), config->mtu_plateaus, mtus_len);
	tmp = (struct global_config *) buffer;

#ifdef STATEFUL
	tmp->ttl.udp = jiffies_to_msecs(config->ttl.udp);
	tmp->ttl.tcp_est = jiffies_to_msecs(config->ttl.tcp_est);
	tmp->ttl.tcp_trans = jiffies_to_msecs(config->ttl.tcp_trans);
	tmp->ttl.icmp = jiffies_to_msecs(config->ttl.icmp);
	tmp->ttl.frag = jiffies_to_msecs(config->ttl.frag);
	disabled = config->is_disable || pool6_is_empty() || pool4_is_empty();
#else
	disabled = config->is_disable || (pool6_is_empty() && eamt_is_empty());
#endif
	tmp->jool_status = !disabled;

	*buffer_out = buffer;
	*buffer_len_out = sizeof(*config) + mtus_len;
	return 0;
}