Commit 7d202284 authored by Ludo Mondelaers's avatar Ludo Mondelaers

debugged ipv4, not yet created unit tests

parent 04dfc29e
......@@ -64,7 +64,7 @@ struct pico_frame {
uint16_t payload_len;
#ifdef PICO_SUPPORT_IPFRAG
/* Payload fragmentation info (big endian)*/
/* Payload fragmentation info */
uint16_t frag;
#endif
......
This diff is collapsed.
This diff is collapsed.
......@@ -19,6 +19,7 @@
#define PICO_IPV4_MAXPAYLOAD (PICO_IPV4_MTU - PICO_SIZE_IP4HDR)
#define PICO_IPV4_DONTFRAG 0x4000
#define PICO_IPV4_MOREFRAG 0x2000
#define PICO_IPV4_EVIL 0x8000
#define PICO_IPV4_FRAG_MASK 0x1FFF
#define PICO_IPV4_DEFAULT_TTL 64
#ifndef MBED
......
......@@ -20,13 +20,6 @@
#ifdef PICO_SUPPORT_IPV6
#define PICO_IPV6_EXTHDR_HOPBYHOP 0
#define PICO_IPV6_EXTHDR_ROUTING 43
#define PICO_IPV6_EXTHDR_FRAG 44
#define PICO_IPV6_EXTHDR_ESP 50
#define PICO_IPV6_EXTHDR_AUTH 51
#define PICO_IPV6_EXTHDR_NONE 59
#define PICO_IPV6_EXTHDR_DESTOPT 60
#define PICO_IPV6_EXTHDR_OPT_PAD1 0
#define PICO_IPV6_EXTHDR_OPT_PADN 1
......@@ -554,152 +547,6 @@ int pico_ipv6_process_routing(struct pico_ipv6_exthdr *routing, struct pico_fram
}
#define IP6FRAG_MORE(x) ((x & 0x0001))
#if 0
#define IP6FRAG_OFF(x) ((x & 0xFFF8))
static int pico_ipv6_frag_compare(void *ka, void *kb)
{
struct pico_frame *a = ka, *b = kb;
if (IP6FRAG_OFF(a->frag) > IP6FRAG_OFF(b->frag))
return 1;
if (IP6FRAG_OFF(a->frag) < IP6FRAG_OFF(b->frag))
return -1;
return 0;
}
PICO_TREE_DECLARE(ipv6_fragments, pico_ipv6_frag_compare);
struct pico_timer *ipv6_fragments_timer = NULL;
static void pico_ipv6_fragments_complete(unsigned int len, uint8_t proto)
{
struct pico_tree_node *index, *tmp;
struct pico_frame *f;
unsigned int bookmark = 0;
struct pico_frame *full = NULL;
struct pico_frame *first = pico_tree_first(&ipv6_fragments);
full = pico_frame_alloc((uint16_t)(PICO_SIZE_IP6HDR + len));
if (full) {
full->net_hdr = full->buffer;
full->net_len = PICO_SIZE_IP6HDR;
memcpy(full->net_hdr, first->net_hdr, full->net_len);
full->transport_hdr = full->net_hdr + full->net_len;
full->transport_len = (uint16_t)len;
full->dev = first->dev;
pico_tree_foreach_safe(index, &ipv6_fragments, tmp) {
f = index->keyValue;
memcpy(full->transport_hdr + bookmark, f->transport_hdr, f->transport_len);
bookmark += f->transport_len;
pico_tree_delete(&ipv6_fragments, f);
pico_frame_discard(f);
}
pico_transport_receive(full, proto);
if (ipv6_fragments_timer) {
pico_timer_cancel(ipv6_fragments_timer);
ipv6_fragments_timer = NULL;
}
}
}
static void pico_ipv6_fragments_check_complete(uint8_t proto)
{
struct pico_tree_node *index, *temp;
struct pico_frame *cur;
unsigned int bookmark = 0;
pico_tree_foreach_safe(index, &ipv6_fragments, temp) {
cur = index->keyValue;
if (IP6FRAG_OFF(cur->frag) != bookmark)
return;
bookmark += cur->transport_len;
if (!IP6FRAG_MORE(cur->frag)) {
pico_ipv6_fragments_complete(bookmark, proto);
}
}
}
static void pico_ipv6_frag_expire(pico_time now, void *arg)
{
struct pico_tree_node *index, *tmp;
struct pico_frame *f;
struct pico_frame *first = pico_tree_first(&ipv6_fragments);
struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)first->net_hdr;
(void)arg;
(void)now;
if (!first) {
return;
}
/* Empty the tree */
pico_tree_foreach_safe(index, &ipv6_fragments, tmp) {
f = index->keyValue;
pico_tree_delete(&ipv6_fragments, f);
if (f != first)
pico_frame_discard(f); /* Later, after ICMP notification...*/
}
if ((IP6FRAG_OFF(first->frag) == 0) && (!pico_ipv6_is_multicast(hdr->dst.addr)))
pico_icmp6_frag_expired(first);
pico_frame_discard(first);
}
#define PICO_IPV6_FRAG_TIMEOUT 60000
#define FRAG_ID(x) ((uint32_t)((x->ext.frag.id[0] << 24) + (x->ext.frag.id[1] << 16) + \
(x->ext.frag.id[2] << 8) + x->ext.frag.id[3]))
static void pico_ipv6_frag_timer_on(void)
{
ipv6_fragments_timer = pico_timer_add(PICO_IPV6_FRAG_TIMEOUT, pico_ipv6_frag_expire, NULL);
}
static int pico_ipv6_frag_match(struct pico_frame *a, struct pico_frame *b)
{
struct pico_ipv6_hdr *ha, *hb;
if (!a || !b)
return 0;
ha = (struct pico_ipv6_hdr *)a->net_hdr;
hb = (struct pico_ipv6_hdr *)b->net_hdr;
if (!ha || !hb)
return 0;
if (memcmp(ha->src.addr, hb->src.addr, PICO_SIZE_IP6) != 0)
return 0;
if (memcmp(ha->dst.addr, hb->dst.addr, PICO_SIZE_IP6) != 0)
return 0;
return 1;
}
static void pico_ipv6_process_frag(struct pico_ipv6_exthdr *frag, struct pico_frame *f, uint8_t proto)
{
struct pico_frame *first = pico_tree_first(&ipv6_fragments);
static uint32_t ipv6_cur_frag_id = 0u;
if (!first) {
if (ipv6_cur_frag_id && (FRAG_ID(frag) == ipv6_cur_frag_id)) {
/* Discard late arrivals, without firing the timer,
* just to make TAHI happy in-between two consecutive tests
*/
return;
}
pico_ipv6_frag_timer_on();
ipv6_cur_frag_id = FRAG_ID(frag);
}
if (!first || (pico_ipv6_frag_match(f, first) && (FRAG_ID(frag) == ipv6_cur_frag_id))) {
pico_tree_insert(&ipv6_fragments, pico_frame_copy(f));
}
pico_ipv6_fragments_check_complete(proto);
}
#endif
static int pico_ipv6_process_destopt(struct pico_ipv6_exthdr *destopt, struct pico_frame *f, uint32_t opt_ptr)
{
......
......@@ -14,6 +14,18 @@
#define PICO_IPV6_DEFAULT_HOP 64
#define PICO_IPV6_MIN_MTU 1280
#define PICO_IPV6_EXTHDR_HOPBYHOP 0
#define PICO_IPV6_EXTHDR_ROUTING 43
#define PICO_IPV6_EXTHDR_FRAG 44
#define PICO_IPV6_EXTHDR_ESP 50
#define PICO_IPV6_EXTHDR_AUTH 51
#define PICO_IPV6_EXTHDR_NONE 59
#define PICO_IPV6_EXTHDR_DESTOPT 60
extern const uint8_t PICO_IP6_ANY[PICO_SIZE_IP6];
extern struct pico_protocol pico_proto_ipv6;
extern struct pico_tree IPV6Routes;
......
......@@ -189,10 +189,12 @@ int pico_socket_udp_deliver(struct pico_sockport *sp, struct pico_frame *f)
#ifdef PICO_SUPPORT_IPV4
return pico_socket_udp_deliver_ipv4(s, f);
#endif
} else {
} else if IS_IPV6(f){
#ifdef PICO_SUPPORT_IPV6
return pico_socket_udp_deliver_ipv6(s, f);
#endif
} else {
/* something wrong in the packet header*/
}
} /* FOREACH */
pico_frame_discard(f);
......
......@@ -1013,7 +1013,9 @@ static struct pico_remote_endpoint *pico_socket_set_info(struct pico_remote_endp
static void pico_xmit_frame_set_nofrag(struct pico_frame *f)
{
#ifdef PICO_SUPPORT_IPFRAG
f->frag = short_be(PICO_IPV4_DONTFRAG);
//LUM f->frag = short_be(PICO_IPV4_DONTFRAG);
f->frag = PICO_IPV4_DONTFRAG;
printf("[LUM:%s%d] pico_xmit_frame_set_nofrag f->frag:0x%X\n",__FILE__,__LINE__,f->frag);
#else
(void)f;
#endif
......@@ -1076,7 +1078,7 @@ static void pico_socket_xmit_first_fragment_setup(struct pico_frame *f, int spac
frag_dbg("FRAG: first fragmented frame %p | len = %u offset = 0\n", f, f->payload_len);
/* transport header length field contains total length + header length */
f->transport_len = (uint16_t)(space);
f->frag = short_be(PICO_IPV4_MOREFRAG);
f->frag = PICO_IPV4_MOREFRAG;
f->payload += hdr_offset;
f->payload_len = (uint16_t) space;
}
......@@ -1087,13 +1089,13 @@ static void pico_socket_xmit_next_fragment_setup(struct pico_frame *f, int hdr_o
f->payload = f->transport_hdr;
f->payload_len = (uint16_t)(f->payload_len - hdr_offset);
/* set offset in octets */
f->frag = short_be((uint16_t)((uint16_t)(total_payload_written + (uint16_t)hdr_offset) >> 3u));
f->frag = (uint16_t)((total_payload_written + (uint16_t)hdr_offset) >> 3u);
if (total_payload_written + f->payload_len < len) {
frag_dbg("FRAG: intermediate fragmented frame %p | len = %u offset = %u\n", f, f->payload_len, short_be(f->frag));
f->frag |= short_be(PICO_IPV4_MOREFRAG);
f->frag |= PICO_IPV4_MOREFRAG;
} else {
frag_dbg("FRAG: last fragmented frame %p | len = %u offset = %u\n", f, f->payload_len, short_be(f->frag));
f->frag &= short_be(PICO_IPV4_FRAG_MASK);
f->frag &= PICO_IPV4_FRAG_MASK;
}
}
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment