Beispiel #1
0
static int
parse_ipv6_net(const char *in, struct rte_acl_field field[4])
{
	int32_t rc;
	const char *mp;
	uint32_t i, m, v[4];
	const uint32_t nbu32 = sizeof(uint32_t) * CHAR_BIT;

	// TODO may be replaced by inet_pton with some refactoring
	/* get address. */
	rc = parse_ipv6_addr(in, &mp, v, '/');
	if (rc != 0)
		return rc;

	/* get mask. */
	GET_CB_FIELD(mp, m, 0, CHAR_BIT * sizeof(v), 0);

	/* put all together. */
	for (i = 0; i != RTE_DIM(v); i++) {
		if (m >= (i + 1) * nbu32)
			field[i].mask_range.u32 = nbu32;
		else
			field[i].mask_range.u32 =
			    m > (i * nbu32) ? m - (i * 32) : 0;

		field[i].value.u32 = v[i];
	}

	return 0;
}
Beispiel #2
0
/**
 * Parses IPv4 and IPv6 addresses. The latter requires IPv6 support to be
 * enabled.
 *
 * For convenience, if the first character is '[' then the address is parsed
 * as an IPv6 one and the trailing ']' is both expected and swallowed.  This
 * allows the routine to be used when parsing "ipv4:port" or "[ipv6]:port"
 * strings.
 *
 * @param s The string to parse.
 * @param endptr This will point to the first character after the parsed
 *        address.
 * @param addr_ptr If not NULL, it is set to the parsed host address or
 *        ``zero_host_addr'' on failure.
 * @return Returns TRUE on success; otherwise FALSE.
 */
bool
string_to_host_addr(const char *s, const char **endptr, host_addr_t *addr_ptr)
{
	uint32 ip;
	bool brackets = FALSE;

	g_assert(s);

	if ('[' == *s) {
		brackets = TRUE;
		s++;
	}

	if (!brackets && string_to_ip_strict(s, &ip, endptr)) {
		if (addr_ptr) {
			*addr_ptr = host_addr_get_ipv4(ip);
		}
		return TRUE;
	} else {
		uint8 ipv6[16];
		const char *end;
		bool ok;

		ok = parse_ipv6_addr(s, ipv6, &end);
		if (ok) {
			if (addr_ptr) {
				*addr_ptr = host_addr_peek_ipv6(ipv6);
			}
			if (brackets) {
				if (']' == *end) {
					end++;
				} else {
					ok = FALSE;		/* Trailing ']' required if we had '[' */
				}
			}
		}

		if (endptr != NULL)
			*endptr = end;
		if (ok)
			return TRUE;

		/* FALL THROUGH */
	}

	if (addr_ptr)
		*addr_ptr = zero_host_addr;
	return FALSE;
}
void Alpha::functionTaskTask0() {
    ipstack::Interface* interface = setupEthernet();

    if (interface==0) {
        // ethernet setup failed
        System::haltsystem();
    }

    // You can ping CiAO IP now by using
    // * ping 10.0.3.2 (for icmp ping)
    // * ping6 fe80::6655:44ff:fe33:2211%tap0 (for icmp ping with ipv6 on tap0 device)
    // * echoping -u 10.0.3.2 (for udp ping; use ipv4 addresses, ipv6 is not supported by echoping for udp)
    // * sendip -p ipv6 -p udp -us 5070 -ud 8 -d "Hello" -v fe80::6655:44ff:fe33:2211 (for ipv6 udp ping)
    // * telnet 10.0.3.2 (for testing the tcp reset capability; use ipv4 or ipv6 address)
    // * Send udp to port 88 to get it printed out

    // Setup test ipv6 address: we will ping that address (and test the ndp address resolution)
    ipstack::ipv6addr testipv6;
    if (!parse_ipv6_addr("fe80:0:0:0:a81a:54ff:fef0:3f", testipv6)) {
        System::haltsystem();
    }
    ICMPv6_Socket &icmpv6instance = ICMPv6_Socket::instance();
    icmpv6instance.ipv6.set_dst_addr(testipv6); // src address is determined automatically

    // Setup test ipv4 address: we will ping that address (and test the arp address resolution)
    UInt32 testipv4 = IPv4_Packet::convert_ipv4_addr(10,0,3,1);

    ICMPv4_Socket &icmpv4instance = ICMPv4_Socket::instance();
    icmpv4instance.ipv4.set_dst_addr(testipv4); // src address has been set above

    SendBuffer* sbi;
    const char teststring[] = "HELLO";


    IP::UDP_Socket<1514,1,128,2> socket;
    socket.set_sport(88);
    socket.bind(); // listen

    printf("Send IPv4 ping\n");
    sbi = icmpv4instance.requestSendBuffer(ICMP_Packet::ICMP_HEADER_SIZE+sizeof(teststring));
    if (sbi) {
        sbi->mark("IPv4 ping");
        ICMP_Packet* icmp = (ICMP_Packet*)sbi->getDataPointer();

        icmp->set_type(ICMP_Packet::ICMP_TYPE_ECHO_REQUEST);
        icmp->set_code(ICMP_Packet::ICMP_CODE_ECHO);

        sbi->writtenToDataPointer(ICMP_Packet::ICMP_HEADER_SIZE);
        sbi->write(teststring, sizeof(teststring));

        icmpv4instance.send(sbi);
    }

    printf("Send IPv6 ping\n");
    sbi = icmpv6instance.requestSendBuffer(ICMPv6_Packet::ICMP_HEADER_SIZE+sizeof(teststring)+sizeof(UInt32));
    if (sbi) {
        sbi->mark("IPv6 ping");
        ICMPv6_Packet* icmp = (ICMPv6_Packet*)sbi->getDataPointer();

        icmp->set_type(ICMPv6_Packet::ICMP_TYPE_ECHO_REQUEST);
        icmp->set_code(ICMPv6_Packet::ICMP_CODE_ECHO_REQUEST);

        sbi->writtenToDataPointer(ICMPv6_Packet::ICMP_HEADER_SIZE);
        // write seq and id
        UInt32 idAndSeq = 0xcaffee;
        sbi->write(&idAndSeq, sizeof(idAndSeq));
        // write payload
        sbi->write(teststring, sizeof(teststring));

        icmpv6instance.send(sbi);
    }

    printf("Start udp listen on port %u\n", socket.get_sport());
    while(1) {
        ReceiveBuffer* rbuffer = socket.receiveBlock();

        ReceiveBufferUDPIPv6* ipv6udp = ReceiveBufferUDPIPv6::cast(rbuffer);
        ReceiveBufferUDPIPv4* ipv4udp = ReceiveBufferUDPIPv4::cast(rbuffer);
        if (ipv6udp) {
            printf("Received IPv6/UDP. Bytes: %u\n", rbuffer->getSize());
            char ipstrbuffer[50] = {0};
            ipstack::ipv6_addr_toString(ipv6udp->getRemoteInfo()->ipv6, ipstrbuffer);
            printf("  Remote IPv6-Address: %s, Port: %u\n", ipstrbuffer, ipv4udp->getRemoteInfo()->remoteport);
        } else if (ipv4udp) {
            printf("Received IPv4/UDP. Bytes: %u\n", rbuffer->getSize());
            UInt8 a,b,c,d;
            IPv4_Packet::convert_ipv4_addr(ipv4udp->getRemoteInfo()->ipv4, a, b, c, d);
            printf("  Remote IPv4-Address: %u.%u.%u.%u, Port: %u\n", a,b,c,d, ipv4udp->getRemoteInfo()->remoteport);
        } else {
            printf("error, udp ip version unknown. Bytes: %u\n", rbuffer->getSize());
        }
        ReceiveBuffer::free(rbuffer);
    }
}
Beispiel #4
0
void
parse_sp6_tokens(char **tokens, uint32_t n_tokens,
	struct parse_status *status)
{
	struct acl6_rules *rule_ipv6 = NULL;

	uint32_t *ri = NULL; /* rule index */
	uint32_t ti = 0; /* token index */

	uint32_t esp_p = 0;
	uint32_t protect_p = 0;
	uint32_t bypass_p = 0;
	uint32_t discard_p = 0;
	uint32_t pri_p = 0;
	uint32_t src_p = 0;
	uint32_t dst_p = 0;
	uint32_t proto_p = 0;
	uint32_t sport_p = 0;
	uint32_t dport_p = 0;

	if (strcmp(tokens[1], "in") == 0) {
		ri = &nb_acl6_rules_in;

		APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, "too "
			"many sp rules, abort insertion\n");
		if (status->status < 0)
			return;

		rule_ipv6 = &acl6_rules_in[*ri];

	} else if (strcmp(tokens[1], "out") == 0) {
		ri = &nb_acl6_rules_out;

		APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, "too "
			"many sp rules, abort insertion\n");
		if (status->status < 0)
			return;

		rule_ipv6 = &acl6_rules_out[*ri];

	} else {
		APP_CHECK(0, status, "unrecognized input \"%s\", expect"
			" \"in\" or \"out\"\n", tokens[ti]);
		return;
	}

	rule_ipv6->data.category_mask = 1;


	for (ti = 2; ti < n_tokens; ti++) {
		if (strcmp(tokens[ti], "esp") == 0) {
			/* currently do nothing */
			APP_CHECK_PRESENCE(esp_p, tokens[ti], status);
			if (status->status < 0)
				return;
			esp_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "protect") == 0) {
			APP_CHECK_PRESENCE(protect_p, tokens[ti], status);
			if (status->status < 0)
				return;
			APP_CHECK(bypass_p == 0, status, "conflict item "
				"between \"%s\" and \"%s\"", tokens[ti],
				"bypass");
			if (status->status < 0)
				return;
			APP_CHECK(discard_p == 0, status, "conflict item "
				"between \"%s\" and \"%s\"", tokens[ti],
				"discard");
			if (status->status < 0)
				return;
			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
			if (status->status < 0)
				return;
			APP_CHECK_TOKEN_IS_NUM(tokens, ti, status);
			if (status->status < 0)
				return;

			rule_ipv6->data.userdata =
				PROTECT(atoi(tokens[ti]));

			protect_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "bypass") == 0) {
			APP_CHECK_PRESENCE(bypass_p, tokens[ti], status);
			if (status->status < 0)
				return;
			APP_CHECK(protect_p == 0, status, "conflict item "
				"between \"%s\" and \"%s\"", tokens[ti],
				"protect");
			if (status->status < 0)
				return;
			APP_CHECK(discard_p == 0, status, "conflict item "
				"between \"%s\" and \"%s\"", tokens[ti],
				"discard");
			if (status->status < 0)
				return;

			rule_ipv6->data.userdata = BYPASS;

			bypass_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "discard") == 0) {
			APP_CHECK_PRESENCE(discard_p, tokens[ti], status);
			if (status->status < 0)
				return;
			APP_CHECK(protect_p == 0, status, "conflict item "
				"between \"%s\" and \"%s\"", tokens[ti],
				"protect");
			if (status->status < 0)
				return;
			APP_CHECK(bypass_p == 0, status, "conflict item "
				"between \"%s\" and \"%s\"", tokens[ti],
				"discard");
			if (status->status < 0)
				return;

			rule_ipv6->data.userdata = DISCARD;

			discard_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "pri") == 0) {
			APP_CHECK_PRESENCE(pri_p, tokens[ti], status);
			if (status->status < 0)
				return;
			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
			if (status->status < 0)
				return;
			APP_CHECK_TOKEN_IS_NUM(tokens, ti, status);
			if (status->status < 0)
				return;

			rule_ipv6->data.priority = atoi(tokens[ti]);

			pri_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "src") == 0) {
			struct in6_addr ip;
			uint32_t depth;

			APP_CHECK_PRESENCE(src_p, tokens[ti], status);
			if (status->status < 0)
				return;
			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
			if (status->status < 0)
				return;

			APP_CHECK(parse_ipv6_addr(tokens[ti], &ip,
				&depth) == 0, status, "unrecognized "
				"input \"%s\", expect valid ipv6 "
				"addr", tokens[ti]);
			if (status->status < 0)
				return;

			rule_ipv6->field[1].value.u32 =
				(uint32_t)ip.s6_addr[0] << 24 |
				(uint32_t)ip.s6_addr[1] << 16 |
				(uint32_t)ip.s6_addr[2] << 8 |
				(uint32_t)ip.s6_addr[3];
			rule_ipv6->field[1].mask_range.u32 =
				(depth > 32) ? 32 : depth;
			depth = (depth > 32) ? (depth - 32) : 0;
			rule_ipv6->field[2].value.u32 =
				(uint32_t)ip.s6_addr[4] << 24 |
				(uint32_t)ip.s6_addr[5] << 16 |
				(uint32_t)ip.s6_addr[6] << 8 |
				(uint32_t)ip.s6_addr[7];
			rule_ipv6->field[2].mask_range.u32 =
				(depth > 32) ? 32 : depth;
			depth = (depth > 32) ? (depth - 32) : 0;
			rule_ipv6->field[3].value.u32 =
				(uint32_t)ip.s6_addr[8] << 24 |
				(uint32_t)ip.s6_addr[9] << 16 |
				(uint32_t)ip.s6_addr[10] << 8 |
				(uint32_t)ip.s6_addr[11];
			rule_ipv6->field[3].mask_range.u32 =
				(depth > 32) ? 32 : depth;
			depth = (depth > 32) ? (depth - 32) : 0;
			rule_ipv6->field[4].value.u32 =
				(uint32_t)ip.s6_addr[12] << 24 |
				(uint32_t)ip.s6_addr[13] << 16 |
				(uint32_t)ip.s6_addr[14] << 8 |
				(uint32_t)ip.s6_addr[15];
			rule_ipv6->field[4].mask_range.u32 =
				(depth > 32) ? 32 : depth;

			src_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "dst") == 0) {
			struct in6_addr ip;
			uint32_t depth;

			APP_CHECK_PRESENCE(dst_p, tokens[ti], status);
			if (status->status < 0)
				return;
			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
			if (status->status < 0)
				return;

			APP_CHECK(parse_ipv6_addr(tokens[ti], &ip,
				&depth) == 0, status, "unrecognized "
				"input \"%s\", expect valid ipv6 "
				"addr", tokens[ti]);
			if (status->status < 0)
				return;

			rule_ipv6->field[5].value.u32 =
				(uint32_t)ip.s6_addr[0] << 24 |
				(uint32_t)ip.s6_addr[1] << 16 |
				(uint32_t)ip.s6_addr[2] << 8 |
				(uint32_t)ip.s6_addr[3];
			rule_ipv6->field[5].mask_range.u32 =
				(depth > 32) ? 32 : depth;
			depth = (depth > 32) ? (depth - 32) : 0;
			rule_ipv6->field[6].value.u32 =
				(uint32_t)ip.s6_addr[4] << 24 |
				(uint32_t)ip.s6_addr[5] << 16 |
				(uint32_t)ip.s6_addr[6] << 8 |
				(uint32_t)ip.s6_addr[7];
			rule_ipv6->field[6].mask_range.u32 =
				(depth > 32) ? 32 : depth;
			depth = (depth > 32) ? (depth - 32) : 0;
			rule_ipv6->field[7].value.u32 =
				(uint32_t)ip.s6_addr[8] << 24 |
				(uint32_t)ip.s6_addr[9] << 16 |
				(uint32_t)ip.s6_addr[10] << 8 |
				(uint32_t)ip.s6_addr[11];
			rule_ipv6->field[7].mask_range.u32 =
				(depth > 32) ? 32 : depth;
			depth = (depth > 32) ? (depth - 32) : 0;
			rule_ipv6->field[8].value.u32 =
				(uint32_t)ip.s6_addr[12] << 24 |
				(uint32_t)ip.s6_addr[13] << 16 |
				(uint32_t)ip.s6_addr[14] << 8 |
				(uint32_t)ip.s6_addr[15];
			rule_ipv6->field[8].mask_range.u32 =
				(depth > 32) ? 32 : depth;

			dst_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "proto") == 0) {
			uint16_t low, high;

			APP_CHECK_PRESENCE(proto_p, tokens[ti], status);
			if (status->status < 0)
				return;
			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
			if (status->status < 0)
				return;

			APP_CHECK(parse_range(tokens[ti], &low, &high)
				== 0, status, "unrecognized input \"%s\""
				", expect \"from:to\"", tokens[ti]);
			if (status->status < 0)
				return;
			APP_CHECK(low <= 0xff, status, "proto low "
				"over-limit");
			if (status->status < 0)
				return;
			APP_CHECK(high <= 0xff, status, "proto high "
				"over-limit");
			if (status->status < 0)
				return;

			rule_ipv6->field[0].value.u8 = (uint8_t)low;
			rule_ipv6->field[0].mask_range.u8 = (uint8_t)high;

			proto_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "sport") == 0) {
			uint16_t port_low, port_high;

			APP_CHECK_PRESENCE(sport_p, tokens[ti], status);
			if (status->status < 0)
				return;
			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
			if (status->status < 0)
				return;

			APP_CHECK(parse_range(tokens[ti], &port_low,
				&port_high) == 0, status, "unrecognized "
				"input \"%s\", expect \"port_from:"
				"port_to\"", tokens[ti]);
			if (status->status < 0)
				return;

			rule_ipv6->field[9].value.u16 = port_low;
			rule_ipv6->field[9].mask_range.u16 = port_high;

			sport_p = 1;
			continue;
		}

		if (strcmp(tokens[ti], "dport") == 0) {
			uint16_t port_low, port_high;

			APP_CHECK_PRESENCE(dport_p, tokens[ti], status);
			if (status->status < 0)
				return;
			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
			if (status->status < 0)
				return;

			APP_CHECK(parse_range(tokens[ti], &port_low,
				&port_high) == 0, status, "unrecognized "
				"input \"%s\", expect \"port_from:"
				"port_to\"", tokens[ti]);
			if (status->status < 0)
				return;

			rule_ipv6->field[10].value.u16 = port_low;
			rule_ipv6->field[10].mask_range.u16 = port_high;

			dport_p = 1;
			continue;
		}

		/* unrecognizeable input */
		APP_CHECK(0, status, "unrecognized input \"%s\"",
			tokens[ti]);
		return;
	}

	/* check if argument(s) are missing */
	APP_CHECK(esp_p == 1, status, "missing argument \"esp\"");
	if (status->status < 0)
		return;

	APP_CHECK(protect_p | bypass_p | discard_p, status, "missing "
		"argument \"protect\", \"bypass\", or \"discard\"");
	if (status->status < 0)
		return;

	*ri = *ri + 1;
}
Beispiel #5
0
/**
 * Parse an IPv6 Geo IP line and record the range in the database.
 */
static void
gip_parse_ipv6(const char *line, int linenum)
{
	const char *end;
	uint16 code;
	int error;
	uint8 ip[16];
	unsigned bits;

	/*
	 * Each line looks like:
	 *
	 *    2a03:be00::/32 nl
	 *
	 * The leading part up to the space is the IPv6 network in CIDR format.
	 * The trailing word is the 2-letter ISO country code.
	 */

	if (!parse_ipv6_addr(line, ip, &end)) {
		g_warning("%s, line %d: bad IPv6 network address \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	if ('/' != *end) {
		g_warning("%s, line %d: missing network separator in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	bits = parse_uint(end + 1, &end, 10, &error);

	if (error) {
		g_warning("%s, line %d: cannot parse network bit amount in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	if (bits > 128) {
		g_warning("%s, line %d: invalid bit amount %u in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, bits, line);
		return;
	}

	if (!is_ascii_space(*end)) {
		g_warning("%s, line %d: missing spaces after network in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	while (is_ascii_space(*end))
		end++;

	if ('\0' == *end) {
		g_warning("%s, line %d: missing country code in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	code = iso3166_encode_cc(end);
	if (ISO3166_INVALID == code) {
		g_warning("%s, line %d: bad country code in \"%s\"",
			gip_source[GIP_IPV6].file, linenum, line);
		return;
	}

	error = iprange_add_cidr6(geo_db, ip, bits, (code + 1) << 1);

	if (IPR_ERR_OK != error) {
		g_warning("%s, line %d: cannot insert %s/%u: %s",
			gip_source[GIP_IPV6].file, linenum, ipv6_to_string(ip),
			bits, iprange_strerror(error));
	}
}
int
app_pipeline_fc_load_file_ipv6(char *filename,
	struct pipeline_fc_key *keys,
	uint32_t *port_ids,
	uint32_t *flow_ids,
	uint32_t *n_keys,
	uint32_t *line)
{
	FILE *f = NULL;
	char file_buf[1024];
	uint32_t i, l;

	/* Check input arguments */
	if ((filename == NULL) ||
		(keys == NULL) ||
		(port_ids == NULL) ||
		(flow_ids == NULL) ||
		(n_keys == NULL) ||
		(*n_keys == 0) ||
		(line == NULL)) {
		if (line)
			*line = 0;
		return -1;
		}

	/* Open input file */
	f = fopen(filename, "r");
	if (f == NULL) {
		*line = 0;
		return -1;
	}

	/* Read file */
	for (i = 0, l = 1; i < *n_keys; l++) {
		char *tokens[32];
		uint32_t n_tokens = RTE_DIM(tokens);

		struct in6_addr sipaddr, dipaddr;
		uint16_t sport, dport;
		uint8_t proto;
		uint32_t portid, flowid;
		int status;

		if (fgets(file_buf, sizeof(file_buf), f) == NULL)
			break;

		status = parse_tokenize_string(file_buf, tokens, &n_tokens);
		if (status)
			goto error3;

		if ((n_tokens == 0) || (tokens[0][0] == '#'))
			continue;

		if ((n_tokens != 10) ||
			strcmp(tokens[0], "ipv6") ||
			parse_ipv6_addr(tokens[1], &sipaddr) ||
			parse_ipv6_addr(tokens[2], &dipaddr) ||
			parser_read_uint16(&sport, tokens[3]) ||
			parser_read_uint16(&dport, tokens[4]) ||
			parser_read_uint8(&proto, tokens[5]) ||
			strcmp(tokens[6], "port") ||
			parser_read_uint32(&portid, tokens[7]) ||
			strcmp(tokens[8], "id") ||
			parser_read_uint32(&flowid, tokens[9]))
			goto error3;

		keys[i].type = FLOW_KEY_IPV6_5TUPLE;
		memcpy(keys[i].key.ipv6_5tuple.ip_src,
			sipaddr.s6_addr,
			sizeof(sipaddr.s6_addr));
		memcpy(keys[i].key.ipv6_5tuple.ip_dst,
			dipaddr.s6_addr,
			sizeof(dipaddr.s6_addr));
		keys[i].key.ipv6_5tuple.port_src = sport;
		keys[i].key.ipv6_5tuple.port_dst = dport;
		keys[i].key.ipv6_5tuple.proto = proto;

		port_ids[i] = portid;
		flow_ids[i] = flowid;

		if (app_pipeline_fc_key_check(&keys[i]))
			goto error3;

		i++;
	}

	/* Close file */
	*n_keys = i;
	fclose(f);
	return 0;

error3:
	*line = l;
	fclose(f);
	return -1;
}