示例#1
0
文件: nat.c 项目: xHire/wrapsix
/**
 * Retrieve or create data structure via fragment identification.
 *
 * @param	nat_proto4	Radix tree of fragments
 * @param	nat_timeout	Linked list in which to watch for timeout
 * @param	ipv4_src	Source IPv4 address
 * @param	id		Fragment identification
 *
 * @return	Structure for fragments (either retrieved or created)
 * @return	NULL when structure for fragments couldn't be created
 */
struct s_nat_fragments *nat_in_fragments(radixtree_t *nat_proto4,
					 linkedlist_t *nat_timeout,
					 struct s_ipv4_addr ipv4_src,
					 unsigned short id)
{
	struct s_nat_fragments *result;

	/* create structure to search in the tree */
	struct s_radixtree_fragments4 radixsearch4;
	radixsearch4.addr = ipv4_src;
	radixsearch4.id = id;

	if ((result = radixtree_lookup(nat_proto4, radixtree_chunker,
	     &radixsearch4, sizeof(radixsearch4))) != NULL) {
		return result;
	} else {
		/* when fragmentation is not found, add one */
		if ((result = (struct s_nat_fragments *)
		     malloc(sizeof(struct s_nat_fragments))) == NULL) {
			log_error("Lack of free memory");
			return NULL;
		}

		result->id = id;
		result->connection = NULL;
		result->queue = NULL;

		radixtree_insert(nat_proto4, radixtree_chunker,
				 &radixsearch4, sizeof(radixsearch4),
				 result);
		linkedlist_append(nat_timeout, result);

		return result;
	}
}
示例#2
0
uint32_t string_pool_append(char *pool, uint32_t *n_pool, radixtree_t *r, const char *str) {
    uint32_t location = radixtree_find_exact (r, str);

    if (location == RADIXTREE_NONE) {
        size_t n = strlen(str);

        /* TODO: check if n_pool + n < max */
        strncpy (&pool[*n_pool], str, n);
        location = *n_pool;
        *n_pool += n;

        radixtree_insert(r, str, location);
    }

    return location;
}
示例#3
0
文件: nat.c 项目: xHire/wrapsix
/**
 * Lookup or create NAT connection for outgoing IPv6 packet.
 *
 * @param	nat_proto6	IPv6 NAT table
 * @param	nat_proto4	IPv4 NAT table
 * @param	eth_src		Source MAC address
 * @param	ipv6_src	Source IPv6 address
 * @param	ipv6_dst	Destination IPv6 address
 * @param	port_src	Source port
 * @param	port_dst	Destination port
 * @param	create		Whether or not to create new NAT entry
 *
 * @return	NULL when it wasn't possible to create connection
 * @return	pointer to connection structure otherwise
 */
struct s_nat *nat_out(radixtree_t *nat_proto6, radixtree_t *nat_proto4,
		      struct s_mac_addr eth_src,
		      struct s_ipv6_addr ipv6_src, struct s_ipv6_addr ipv6_dst,
		      unsigned short	 port_src, unsigned short     port_dst,
		      unsigned char create)
{
	struct s_nat *result, *connection;

	struct s_radixtree_nat4 radixsearch4;
	struct s_radixtree_nat6 radixsearch6;

	/* create structure to search in the tree */
	radixsearch6.ipv6 = ipv6_src;
	ipv6_to_ipv4(&ipv6_dst, &radixsearch6.ipv4);
	radixsearch6.port_src = port_src;
	radixsearch6.port_dst = port_dst;

	if ((result = (struct s_nat *) radixtree_lookup(nat_proto6,
	    radixtree_chunker, &radixsearch6, sizeof(radixsearch6))) == NULL) {
		if (create > 0) {
			/* if no connection is found, let's create one */
			if ((connection =
			     (struct s_nat *) malloc(sizeof(struct s_nat))) ==
			    NULL) {
				log_error("Lack of free memory");
				return NULL;
			}

			connection->mac = eth_src;
			connection->ipv6 = ipv6_src;
			connection->ipv4 = radixsearch6.ipv4;
			connection->ipv6_port_src = port_src;
			connection->ipv4_port_dst = port_dst;
			connection->state = 1;
			connection->llnode = NULL;

			radixsearch4.addr = radixsearch6.ipv4;
			radixsearch4.port_src = port_dst;
			radixsearch4.zeros = 0x0;

			/* generate some outgoing port */
			do {
				/* returns port from range 1024 - 65535 */
				radixsearch4.port_dst = (rand() % 64511) + 1024;

				result = radixtree_lookup(nat_proto4,
							  radixtree_chunker,
							  &radixsearch4,
							  sizeof(radixsearch4));
			} while (result != NULL);

			connection->ipv4_port_src = radixsearch4.port_dst;

			/* save this connection to the NAT table (to *both* of
			 * them) */
			radixtree_insert(nat_proto6, radixtree_chunker,
					 &radixsearch6, sizeof(radixsearch6),
					 connection);
			radixtree_insert(nat_proto4, radixtree_chunker,
					 &radixsearch4, sizeof(radixsearch4),
					 connection);

			return connection;
		} else {
			return NULL;
		}
	} else {
		/* when connection is found, return it */
		return result;
	}
}