Ejemplo n.º 1
0
Archivo: pool4.c Proyecto: NICMx/Jool
int handle_pool4_config(struct xlator *jool, struct genl_info *info)
{
	struct request_hdr *hdr = get_jool_hdr(info);
	union request_pool4 *request = (union request_pool4 *)(hdr + 1);
	int error;

	if (xlat_is_siit()) {
		log_err("SIIT doesn't have pool4.");
		return nlcore_respond(info, -EINVAL);
	}

	error = validate_request_size(info, sizeof(*request));
	if (error)
		return nlcore_respond(info, error);

	switch (hdr->operation) {
	case OP_FOREACH:
		return handle_pool4_display(jool->nat64.pool4, info, request);
	case OP_ADD:
		return handle_pool4_add(jool->nat64.pool4, info, request);
	case OP_UPDATE:
		return handle_pool4_update(jool->nat64.pool4, info, request);
	case OP_REMOVE:
		return handle_pool4_rm(jool, info, request);
	case OP_FLUSH:
		return handle_pool4_flush(jool, info, request);
	}

	log_err("Unknown operation: %u", hdr->operation);
	return nlcore_respond(info, -EINVAL);
}
Ejemplo n.º 2
0
Archivo: packet.c Proyecto: NICMx/Jool
static verdict handle_icmp6(struct xlation *state, struct pkt_metadata const *meta)
{
	union {
		struct icmp6hdr icmp;
		struct frag_hdr frag;
	} buffer;
	union {
		struct icmp6hdr *icmp;
		struct frag_hdr *frag;
	} ptr;
	verdict result;

	ptr.icmp = skb_hdr_ptr(state->in.skb, meta->l4_offset, buffer.icmp);
	if (!ptr.icmp)
		return truncated(state, "ICMPv6 header");

	if (has_inner_pkt6(ptr.icmp->icmp6_type)) {
		result = validate_inner6(state, meta);
		if (result != VERDICT_CONTINUE)
			return result;
	}

	if (xlat_is_siit() && meta->has_frag_hdr && is_icmp6_info(ptr.icmp->icmp6_type)) {
		ptr.frag = skb_hdr_ptr(state->in.skb, meta->frag_offset, buffer.frag);
		if (!ptr.frag)
			return truncated(state, "fragment header");
		if (is_fragmented_ipv6(ptr.frag)) {
			log_debug("Packet is a fragmented ping; its checksum cannot be translated.");
			return drop(state, JSTAT_FRAGMENTED_PING);
		}
	}

	return VERDICT_CONTINUE;
}
Ejemplo n.º 3
0
int handle_session_config(struct xlator *jool, struct genl_info *info)
{
	struct request_hdr *hdr;
	struct request_session *request;
	int error;

	if (xlat_is_siit()) {
		log_err("SIIT doesn't have session tables.");
		return nlcore_respond(info, -EINVAL);
	}

	hdr = get_jool_hdr(info);
	request = (struct request_session *)(hdr + 1);

	error = validate_request_size(info, sizeof(*request));
	if (error)
		return nlcore_respond(info, error);

	switch (be16_to_cpu(hdr->operation)) {
	case OP_DISPLAY:
		return handle_session_display(jool->nat64.bib, info, request);
	case OP_COUNT:
		return handle_session_count(jool->nat64.bib, info, request);
	}

	log_err("Unknown operation: %u", be16_to_cpu(hdr->operation));
	return nlcore_respond(info, -EINVAL);
}
Ejemplo n.º 4
0
static int handle_session_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		struct request_session *request)
{
	__u64 count;
	int error;

	if (xlat_is_siit()) {
		log_err("SIIT doesn't have session tables.");
		return -EINVAL;
	}

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		return handle_session_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning session count.");
		error = sessiondb_count(request->l4_proto, &count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Ejemplo n.º 5
0
static int handle_pool4_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_pool4 *request)
{
	struct response_pool4_count counters;

	if (xlat_is_siit()) {
		log_err("SIIT doesn't have pool4.");
		return -EINVAL;
	}

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		return handle_pool4_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning IPv4 pool counters.");
		pool4db_count(&counters.tables, &counters.samples,
				&counters.taddrs);
		return respond_setcfg(nl_hdr, &counters, sizeof(counters));

	case OP_ADD:
		return handle_pool4_add(nl_hdr, request);

	case OP_REMOVE:
		return handle_pool4_rm(nl_hdr, request);

	case OP_FLUSH:
		return handle_pool4_flush(nl_hdr, request);

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Ejemplo n.º 6
0
static int validate_version(struct request_hdr *hdr)
{
	if (hdr->magic[0] != 'j' || hdr->magic[1] != 'o')
		goto magic_fail;
	if (hdr->magic[2] != 'o' || hdr->magic[3] != 'l')
		goto magic_fail;

	switch (hdr->type) {
	case 's':
		if (xlat_is_nat64()) {
			log_err("You're speaking to NAT64 Jool using "
					"the SIIT Jool application.");
			return -EINVAL;
		}
		break;
	case 'n':
		if (xlat_is_siit()) {
			log_err("You're speaking to SIIT Jool using "
					"the NAT64 Jool application.");
			return -EINVAL;
		}
		break;
	default:
		goto magic_fail;
	}

	if (xlat_version() == hdr->version)
		return 0;

	log_err("Version mismatch. The kernel module is %u.%u.%u.%u, "
			"but the userspace application is %u.%u.%u.%u. "
			"Please update Jool's %s.",
			JOOL_VERSION_MAJOR, JOOL_VERSION_MINOR,
			JOOL_VERSION_REV, JOOL_VERSION_DEV,
			hdr->version >> 24, (hdr->version >> 16) & 0xFFU,
			(hdr->version >> 8) & 0xFFU, hdr->version & 0xFFU,
			(xlat_version() > hdr->version)
				? "userspace application"
				: "kernel module");
	return -EINVAL;

magic_fail:
	log_err("It appears you're trying to speak to Jool using some other "
			"Netlink client or an older userspace application. "
			"If the latter is true, please update your userspace "
			"application.");
	return -EINVAL;
}
Ejemplo n.º 7
0
static int do_parsing(char *buffer)
{
	int error;

	cJSON *json = cJSON_Parse(buffer);
	if (!json) {
		log_err("The JSON parser got confused around about here:");
		log_err("%s", cJSON_GetErrorPtr());
		return -EINVAL;
	}

	error = validate_file_type(json);
	if (error)
		return error;

	return xlat_is_siit() ? parse_siit_json(json) : parse_nat64_json(json);
}
Ejemplo n.º 8
0
static int validate_file_type(cJSON *json_structure)
{
	char *siit = "SIIT";
	char *nat64 = "NAT64";
	char *expected;

	cJSON *file_type = cJSON_GetObjectItem(json_structure, "File_Type");
	if (!file_type)
		return 0; /* The user doesn't care. */

	expected = xlat_is_siit() ? siit : nat64;

	if (strcasecmp(file_type->valuestring, expected) != 0) {
		log_err("File_Type is supposed to be '%s' (got '%s').",
				expected, file_type->valuestring);
		return -EINVAL;
	}

	return 0;
}
Ejemplo n.º 9
0
static int handle_bib_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		struct request_bib *request)
{
	__u64 count;
	int error;

	if (xlat_is_siit()) {
		log_err("SIIT doesn't have BIBs.");
		return -EINVAL;
	}

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		return handle_bib_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning BIB count.");
		error = bibdb_count(request->l4_proto, &count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

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

		log_debug("Adding BIB entry.");
		return respond_error(nl_hdr, add_static_route(request));

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

		log_debug("Removing BIB entry.");
		return respond_error(nl_hdr, delete_static_route(request));

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Ejemplo n.º 10
0
Archivo: packet.c Proyecto: NICMx/Jool
static verdict handle_icmp4(struct xlation *state, struct pkt_metadata *meta)
{
	struct icmphdr buffer, *ptr;
	verdict result;

	ptr = skb_hdr_ptr(state->in.skb, meta->l4_offset, buffer);
	if (!ptr)
		return truncated(state, "ICMP header");

	if (has_inner_pkt4(ptr->type)) {
		result = validate_inner4(state, meta);
		if (result != VERDICT_CONTINUE)
			return result;
	}

	if (xlat_is_siit() && is_icmp4_info(ptr->type) && is_fragmented_ipv4(ip_hdr(state->in.skb))) {
		log_debug("Packet is a fragmented ping; its checksum cannot be translated.");
		return drop(state, JSTAT_FRAGMENTED_PING);
	}

	return VERDICT_CONTINUE;
}