bool test_addr_6to4(struct in6_addr *src, struct ipv6_prefix *prefix, struct in_addr *expected) { struct in_addr actual; bool success = true; success &= assert_true(addr_6to4(src, prefix, &actual), "Extract IPv4-result"); success &= assert_equals_ipv4(expected, &actual, "Extract IPv4-out"); return success; }
/** * Assumes that "tuple" and "bib"'s session doesn't exist, and creates it. Returns the resulting * entry in "session". * Assumes that "tuple" represents a IPv6 packet. */ static int create_session_ipv6(struct tuple *tuple6, struct bib_entry *bib, struct session_entry **session, enum session_timer_type timer_type, enum tcp_state state) { struct ipv6_prefix prefix; struct in_addr ipv4_dst; struct ipv4_transport_addr addr4; int error; /* Translate address from IPv6 to IPv4 */ error = pool6_get(&tuple6->dst.addr6.l3, &prefix); if (error) { log_debug("Errcode %d while obtaining %pI6c's prefix.", error, &tuple6->dst.addr6.l3); return error; } error = addr_6to4(&tuple6->dst.addr6.l3, &prefix, &ipv4_dst); if (error) { log_debug("Error code %d while translating the packet's address.", error); return error; } /* * Create the session entry. * * Fortunately, ICMP errors cannot reach this code because of the requirements in the header * of section 3.5, so we can use the tuple as shortcuts for the packet's fields. */ addr4.l3 = ipv4_dst; addr4.l4 = (tuple6->l4_proto != L4PROTO_ICMP) ? tuple6->dst.addr6.l4 : bib->ipv4.l4; *session = session_create(&tuple6->src.addr6, &tuple6->dst.addr6, &bib->ipv4, &addr4, tuple6->l4_proto, bib); if (!(*session)) { log_debug("Failed to allocate a session entry."); return -ENOMEM; } (*session)->state = state; apply_policies(); /* Add it to the table. */ error = sessiondb_add(*session, timer_type); if (error) { session_return(*session); log_debug("Error code %d while adding the session to the DB.", error); return error; } return 0; }
int rfc6052_6to4(struct pool6 *pool, const struct in6_addr *addr6, struct in_addr *result) { struct ipv6_prefix prefix; int error; error = pool6_find(pool, addr6, &prefix); if (error) { log_debug("Could not find a prefix that matches %pI6c.", addr6); return error; } return addr_6to4(addr6, &prefix, result); }