Skip to content

Commit

Permalink
Unitary tests for IPv6 in packet_db
Browse files Browse the repository at this point in the history
  • Loading branch information
robertoaceves committed Sep 17, 2013
1 parent 353c548 commit 14d0b4c
Show file tree
Hide file tree
Showing 17 changed files with 662 additions and 151 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ Thumbs.db
.cproject
.project

/Debug
1 change: 1 addition & 0 deletions include/nat64/comm/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ enum error_code {

/* IPv6 header iterator */
ERR_INVALID_ITERATOR = 2000,
ERR_MISSING_FRAG_HEADER = 2001,

/* Pool6 */
ERR_POOL6_EMPTY = 2200,
Expand Down
4 changes: 2 additions & 2 deletions include/nat64/mod/out_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

#include "linux/netlink.h"

#define BUFFER_SIZE NLMSG_DEFAULT_SIZE
#define OUT_STREAM_BUFFER_SIZE NLMSG_DEFAULT_SIZE


struct out_stream {
struct sock *socket;
struct nlmsghdr *request_hdr;

unsigned char buffer[BUFFER_SIZE];
unsigned char buffer[OUT_STREAM_BUFFER_SIZE];
int buffer_len;
};

Expand Down
1 change: 1 addition & 0 deletions include/nat64/mod/packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void pkt_destroy(void);

__u16 is_more_fragments_set_ipv6(struct frag_hdr *hdr);
__u16 is_more_fragments_set_ipv4(struct iphdr *hdr);
__u16 is_dont_fragment_set(struct iphdr *hdr);
__u16 get_fragment_offset_ipv6(struct frag_hdr *hdr);
__u16 get_fragment_offset_ipv4(struct iphdr *hdr);
__be16 build_ipv6_frag_off_field(__u16 more_fragments, __u16 fragment_offset);
Expand Down
22 changes: 18 additions & 4 deletions include/nat64/unit/skb_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,23 @@ int init_payload_normal(void *l4_hdr, u16 payload_len);

int create_skb_ipv6_udp(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_tcp(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_icmp(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_icmp_info(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_icmp_error(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);

int create_skb_ipv4_udp(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);
int create_skb_ipv4_tcp(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);
int create_skb_ipv4_icmp(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);
int create_skb_ipv4_empty(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_empty(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv4_icmp_info(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);
int create_skb_ipv4_icmp_error(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);

int create_skb_ipv4_udp_fragment(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);
int create_skb_ipv4_tcp_fragment(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);
int create_skb_ipv4_icmp_info_fragment(struct ipv4_pair *pair4, struct sk_buff **result, u16 payload_len);
/* fragmented ICMPv4 errors do not exist. */

int create_skb_ipv6_udp_fragment_1(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_udp_fragment_n(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_tcp_fragment_1(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_tcp_fragment_n(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_icmp_info_fragment_1(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
int create_skb_ipv6_icmp_info_fragment_n(struct ipv6_pair *pair6, struct sk_buff **result, u16 payload_len);
/* fragmented ICMPv6 errors do not exist. */
48 changes: 24 additions & 24 deletions mod/Kbuild
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
ccflags-y := -I$(src)/../include
#EXTRA_CFLAGS += -DDEBUG
EXTRA_CFLAGS += -DDEBUG

obj-m += jool.o

#jool-objs += types.o
#jool-objs += str_utils.o
#jool-objs += packet.o
#jool-objs += ipv6_hdr_iterator.o
#jool-objs += rfc6052.o
#jool-objs += out_stream.o
#jool-objs += random.o
#jool-objs += poolnum.o
#jool-objs += pool6.o
#jool-objs += pool4.o
#jool-objs += bib.o
#jool-objs += session.o
#jool-objs += static_routes.o
#jool-objs += config.o
#jool-objs += config_validation.o
#jool-objs += config_proto.o
#jool-objs += determine_incoming_tuple.o
#jool-objs += filtering_and_updating.o
#jool-objs += compute_outgoing_tuple.o
jool-objs += types.o
jool-objs += str_utils.o
jool-objs += packet.o
jool-objs += ipv6_hdr_iterator.o
jool-objs += rfc6052.o
jool-objs += out_stream.o
jool-objs += random.o
jool-objs += poolnum.o
jool-objs += pool6.o
jool-objs += pool4.o
jool-objs += bib.o
jool-objs += session.o
jool-objs += static_routes.o
jool-objs += config.o
jool-objs += config_validation.o
jool-objs += config_proto.o
jool-objs += determine_incoming_tuple.o
jool-objs += filtering_and_updating.o
jool-objs += compute_outgoing_tuple.o
jool-objs += translate_packet.o
#jool-objs += handling_hairpinning.o
#jool-objs += send_packet.o
#jool-objs += nf_hook.o
#jool-objs += core.o
jool-objs += handling_hairpinning.o
jool-objs += send_packet.o
jool-objs += nf_hook.o
jool-objs += core.o
4 changes: 2 additions & 2 deletions mod/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ unsigned int core_4to6(struct sk_buff *skb)

return nat64_core(skb,
compute_out_tuple_4to6,
translating_the_packet_4to6,
translating_the_packet,
send_packet_ipv6);
}

Expand All @@ -99,6 +99,6 @@ unsigned int core_6to4(struct sk_buff *skb)

return nat64_core(skb,
compute_out_tuple_6to4,
translating_the_packet_6to4,
translating_the_packet,
send_packet_ipv4);
}
1 change: 1 addition & 0 deletions mod/filtering_and_updating.c
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,7 @@ bool session_expired(struct session_entry *session_entry_p)
log_err(ERR_INVALID_STATE, "Invalid state found; removing session entry.");
return false;
}
return false;
default:
log_err(ERR_L4PROTO, "Unsupported transport protocol: %u.", session_entry_p->l4_proto);
return false;
Expand Down
2 changes: 1 addition & 1 deletion mod/out_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void stream_write(struct out_stream *stream, void *payload, int payload_len)
* TODO (fine) if payload_len > BUFFER_SIZE, this will go downhill.
* Will never happen in this project, hence the low priority.
*/
if (stream->buffer_len + payload_len > BUFFER_SIZE)
if (stream->buffer_len + payload_len > OUT_STREAM_BUFFER_SIZE)
flush(stream, 0);

memcpy(stream->buffer + stream->buffer_len, payload, payload_len);
Expand Down
47 changes: 27 additions & 20 deletions mod/packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,19 @@ void pkt_destroy(void)
/* No code. */
}

/**
* Returns 1 if the Don't Fragments flag from the "header" header is set, 0 otherwise.
*/
__u16 is_dont_fragment_set(struct iphdr *hdr)
{
__u16 frag_off = be16_to_cpu(hdr->frag_off);
return (frag_off & IP_DF) >> 14;
}

__u16 is_more_fragments_set_ipv6(struct frag_hdr *hdr)
{
__u16 frag_off = be16_to_cpu(hdr->frag_off);
return (frag_off & 0x1);
return (frag_off & IP6_MF);
}

/**
Expand All @@ -63,7 +72,7 @@ __u16 get_fragment_offset_ipv6(struct frag_hdr *hdr)
__u16 get_fragment_offset_ipv4(struct iphdr *hdr)
{
__u16 frag_off = be16_to_cpu(hdr->frag_off);
return frag_off & 0x1FFF;
return frag_off & IP_OFFSET;
}

__be16 build_ipv6_frag_off_field(__u16 fragment_offset, __u16 more_fragments)
Expand Down Expand Up @@ -279,7 +288,7 @@ static enum verdict init_ipv6_l4_fields(struct fragment *frag, struct hdr_iterat
ip6_header = ipv6_hdr(frag->skb);
frag_header = get_extension_header(ip6_header, NEXTHDR_FRAGMENT);

if (frag_header == NULL || be16_to_cpu(frag_header->frag_off) == 0) {
if (frag_header == NULL || get_fragment_offset_ipv6(frag_header) == 0) {
u16 datagram_len = frag->skb->len - frag->l3_hdr.len;
enum verdict result;

Expand Down Expand Up @@ -321,12 +330,13 @@ static enum verdict init_ipv6_l4_fields(struct fragment *frag, struct hdr_iterat
return VER_DROP;
}

frag->l4_hdr.ptr = iterator->data;
} else {
frag->l4_hdr.proto = L4PROTO_NONE;
frag->l4_hdr.len = 0;
frag->l4_hdr.ptr = NULL;
}

frag->l4_hdr.ptr = iterator->data;
frag->l4_hdr.ptr_needs_kfree = false;

return VER_CONTINUE;
Expand Down Expand Up @@ -360,8 +370,13 @@ enum verdict frag_create_ipv6(struct sk_buff *skb, struct fragment **frag_out)
goto error;

// Payload
frag->payload.len = skb->len - frag->l3_hdr.len - frag->l4_hdr.len;
frag->payload.ptr = frag->l4_hdr.ptr + frag->l4_hdr.len;
if ( frag->l4_hdr.proto == L4PROTO_NONE ){
frag->payload.len = iterator.limit - iterator.data;
frag->payload.ptr = iterator.data;
} else {
frag->payload.len = skb->len - frag->l3_hdr.len - frag->l4_hdr.len;
frag->payload.ptr = frag->l4_hdr.ptr + frag->l4_hdr.len;
}
frag->payload.ptr_needs_kfree = false;

// List
Expand Down Expand Up @@ -427,7 +442,7 @@ static enum verdict init_ipv4_l3_payload(struct fragment *frag)
u16 fragment_offset;
enum verdict result;

fragment_offset = be16_to_cpu(ipv4_header->frag_off) & 0x1FFF;
fragment_offset = get_fragment_offset_ipv4(ipv4_header);
if (fragment_offset == 0) {
u16 datagram_len = frag->skb->len - frag->l3_hdr.len;

Expand Down Expand Up @@ -561,9 +576,6 @@ enum verdict frag_create_skb(struct fragment *frag)
if (has_l4_hdr)
skb_set_transport_header(new_skb, frag->l3_hdr.len);

//log_debug("payload[6] = %d", ((unsigned char *)frag->payload.ptr)[6]);
//log_debug("PAYLOAD LENGTH: %d", frag->payload.len);

memcpy(skb_network_header(new_skb), frag->l3_hdr.ptr, frag->l3_hdr.len);
if (has_l4_hdr) {
memcpy(skb_transport_header(new_skb), frag->l4_hdr.ptr, frag->l4_hdr.len);
Expand All @@ -579,8 +591,6 @@ enum verdict frag_create_skb(struct fragment *frag)
if (frag->payload.ptr_needs_kfree)
kfree(frag->payload.ptr);

//log_debug("bools: %d %d %d", frag->l3_hdr.ptr_needs_kfree, frag->l4_hdr.ptr_needs_kfree, frag->payload.ptr_needs_kfree);

frag->l3_hdr.ptr = skb_network_header(new_skb);
if (has_l4_hdr) {
frag->l4_hdr.ptr = skb_transport_header(new_skb);
Expand Down Expand Up @@ -663,7 +673,6 @@ void frag_print(struct fragment *frag)
struct tcphdr *tcp_header;
struct udphdr *udp_header;
struct in_addr addr4;
u16 frag_off;

if (!frag) {
log_info("(null)");
Expand All @@ -686,27 +695,25 @@ void frag_print(struct fragment *frag)

if (hdr6->nexthdr == NEXTHDR_FRAGMENT) {
frag_header = (struct frag_hdr *) (hdr6 + 1);
frag_off = be16_to_cpu(frag_header->frag_off);
log_info("Fragment header:");
log_info(" next header: %s", nexthdr_to_string(frag_header->nexthdr));
log_info(" reserved: %u", frag_header->reserved);
log_info(" fragment offset: %u", frag_off >> 3);
log_info(" more fragments: %u", frag_off & 0x1);
log_info(" fragment offset: %u", get_fragment_offset_ipv6(frag_header));
log_info(" more fragments: %u", is_more_fragments_set_ipv6(frag_header));
log_info(" identification: %u", be32_to_cpu(frag_header->identification));
}
break;

case L3PROTO_IPV4:
hdr4 = frag_get_ipv4_hdr(frag);
frag_off = be16_to_cpu(hdr4->frag_off);
log_info(" version: %u", hdr4->version);
log_info(" header length: %u", hdr4->ihl);
log_info(" type of service: %u", hdr4->tos);
log_info(" total length: %u", be16_to_cpu(hdr4->tot_len));
log_info(" identification: %u", be16_to_cpu(hdr4->id));
log_info(" more fragments: %u", (frag_off & IP_MF) >> 13);
log_info(" don't fragment: %u", (frag_off & IP_DF) >> 14);
log_info(" fragment offset: %u", frag_off & 0x1fff);
log_info(" more fragments: %u", is_more_fragments_set_ipv4(hdr4));
log_info(" don't fragment: %u", is_dont_fragment_set(hdr4));
log_info(" fragment offset: %u", get_fragment_offset_ipv4(hdr4));
log_info(" time to live: %u", hdr4->ttl);
log_info(" protocol: %s", protocol_to_string(hdr4->protocol));
log_info(" checksum: %u", hdr4->check);
Expand Down
26 changes: 22 additions & 4 deletions mod/packet_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ static __u16 hash_function(struct pktdb_key *key)
return key->identifier;
}

static int pkt_fragment_count(struct packet *pkt)
{
struct fragment *frag;
int i = 0;

list_for_each_entry(frag, &pkt->fragments, next) {
i++;
}

return i;
}

static int frag_to_key(struct fragment *frag, struct pktdb_key *key)
{
struct ipv6hdr *hdr6;
Expand All @@ -74,17 +86,22 @@ static int frag_to_key(struct fragment *frag, struct pktdb_key *key)
case L3PROTO_IPV6:
hdr6 = frag_get_ipv6_hdr(frag);
hdr_frag = frag_get_fragment_hdr(frag);
if (!hdr_frag)
return -EINVAL; // Unfragmented packet
key->identifier = hdr_frag->identification;
key->is_ipv6 = true;
key->ipv6.src = hdr6->saddr;
key->ipv6.dst = hdr6->daddr;
key->identifier = hdr_frag->identification;
break;

case L3PROTO_IPV4:
hdr4 = frag_get_ipv4_hdr(frag);
key->is_ipv6 = false;
key->ipv4.src.s_addr = hdr4->saddr;
key->ipv4.dst.s_addr = hdr4->daddr;
if ( !is_more_fragments_set_ipv4(hdr4)
&& get_fragment_offset_ipv4(hdr4) == 0 )
return -EINVAL; // Unfragmented packet
key->identifier = be16_to_cpu(hdr4->id);
break;

Expand Down Expand Up @@ -212,7 +229,7 @@ enum verdict pkt_from_skb(struct sk_buff *skb, struct packet **pkt)
struct fragment *frag;
enum verdict result;

result = (skb->protocol == IPPROTO_IPV6)
result = (skb->protocol == htons(ETH_P_IPV6))
? frag_create_ipv6(skb, &frag)
: frag_create_ipv4(skb, &frag);
if (result != VER_CONTINUE)
Expand All @@ -222,7 +239,7 @@ enum verdict pkt_from_skb(struct sk_buff *skb, struct packet **pkt)

pkt_from_db = pktdb_get(frag);
if (pkt_from_db) {
if (skb->protocol == IPPROTO_IPV6)
if (skb->protocol == htons(ETH_P_IPV6))
pkt_add_frag_ipv6(pkt_from_db, frag);
else
pkt_add_frag_ipv4(pkt_from_db, frag);
Expand All @@ -240,10 +257,11 @@ enum verdict pkt_from_skb(struct sk_buff *skb, struct packet **pkt)
}

} else {
*pkt = (skb->protocol == IPPROTO_IPV6)
*pkt = (skb->protocol == htons(ETH_P_IPV6))
? pkt_create_ipv6(frag)
: pkt_create_ipv4(frag);


if (pkt_is_complete(*pkt))
/* No fragmentation; no need to reassemble. pkt is already set so just state success. */
result = VER_CONTINUE;
Expand Down
3 changes: 0 additions & 3 deletions mod/translate_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,6 @@ static enum verdict translate_fragment(struct fragment *in, struct tuple *tuple,
__u16 min_ipv6_mtu;

// Translate this single fragment.
//log_debug("Van los protos: %d %d", in->l3_hdr.proto, in->l4_hdr.proto);
//log_debug("L4-header: %p", in->l4_hdr.ptr);

result = translate(tuple, in, &out, &steps[in->l3_hdr.proto][in->l4_hdr.proto]);
if (result != VER_CONTINUE)
return result;
Expand Down
2 changes: 1 addition & 1 deletion mod/translate_packet_6to4.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ static int l4_hdr_len(void *hdr, enum l3_proto l3proto, enum l4_proto l4proto)
case L3PROTO_IPV4:
return sizeof(struct icmphdr);
}

return -1;
case L4PROTO_NONE:
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion unit/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@ modules:
make -C ${KERNEL_DIR} M=$$PWD $@;
clean:
make -C ${KERNEL_DIR} M=$$PWD $@;
rm -f ../mod/*.o
rm -f ../mod/*.o *.ko *.o
Loading

0 comments on commit 14d0b4c

Please sign in to comment.