Porting PicoTCP WIP
This commit is contained in:
1634
kernel/picotcp/test/unit/modunit_pico_6lowpan.c
Normal file
1634
kernel/picotcp/test/unit/modunit_pico_6lowpan.c
Normal file
File diff suppressed because it is too large
Load Diff
556
kernel/picotcp/test/unit/modunit_pico_802154.c
Normal file
556
kernel/picotcp/test/unit/modunit_pico_802154.c
Normal file
@ -0,0 +1,556 @@
|
||||
#include "pico_addressing.h"
|
||||
#include "pico_ipv6_nd.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_frame.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_6lowpan.h"
|
||||
#include "modules/pico_802154.c"
|
||||
#include "check.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* MACROS
|
||||
******************************************************************************/
|
||||
|
||||
#define STARTING() \
|
||||
printf("*********************** STARTING %s ***\n", __func__); \
|
||||
fflush(stdout)
|
||||
#define TRYING(s, ...) \
|
||||
printf("Trying %s: " s, __func__, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
#define CHECKING(i) \
|
||||
printf("Checking the results of test %2d in %s...", (i)++, \
|
||||
__func__); \
|
||||
fflush(stdout)
|
||||
#define FAIL_UNLESS(cond, s, ...) \
|
||||
if ((cond)) { \
|
||||
printf(" SUCCESS\n"); \
|
||||
} else { \
|
||||
printf(" FAILED\n"); \
|
||||
} \
|
||||
fail_unless((cond), s, ##__VA_ARGS__)
|
||||
#define FAIL_IF(cond, s, ...) \
|
||||
if (!(cond)) { \
|
||||
printf(" SUCCESS\n"); \
|
||||
} else { \
|
||||
printf(" FAILED\n"); \
|
||||
} \
|
||||
fail_if((cond), s, ##__VA_ARGS__)
|
||||
#define ENDING(i) \
|
||||
printf("*********************** ENDING %s *** NUMBER OF TESTS: %d\n",\
|
||||
__func__, ((i)-1)); \
|
||||
fflush(stdout)
|
||||
#define DBG(s, ...) \
|
||||
printf(s, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
|
||||
/*******************************************************************************
|
||||
* HELPER FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
static void dbg_addr_ext(const char *msg, uint8_t a[SIZE_6LOWPAN_EXT])
|
||||
{
|
||||
DBG("%s: (64-bit extended address): ", msg);
|
||||
DBG("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* ADDRESSES
|
||||
******************************************************************************/
|
||||
|
||||
START_TEST(tc_swap)
|
||||
{
|
||||
int test = 1;
|
||||
uint8_t a = 5;
|
||||
uint8_t b = 1;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("With a = %d and b = %d\n", a, b);
|
||||
pico_swap(&a, &b);
|
||||
CHECKING(test);
|
||||
FAIL_IF(1 != a && b != 5, "Failed swapping numbers\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_to_ietf)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_802154 a = {
|
||||
.addr.data = { 1,2,3,4,5,6,7,8 },
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
uint8_t buf[] = {8,7,6,5,4,3,2,1};
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Extended address mode\n");
|
||||
addr_802154_to_ietf(&a);
|
||||
dbg_addr_ext("After", a.addr.data);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(a.addr.data, buf, SIZE_6LOWPAN_EXT),
|
||||
"Failed converting to IETF endianness\n");
|
||||
|
||||
// TEST 2
|
||||
TRYING("Short address mode\n");
|
||||
a.mode = AM_6LOWPAN_SHORT;
|
||||
addr_802154_to_ietf(&a);
|
||||
dbg_addr_ext("After", a.addr.data);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(a.addr._short.addr == short_be(0x0708),
|
||||
"Failed converting short to IETF endianness\n");
|
||||
|
||||
// TEST 3
|
||||
TRYING("Wrong address mode\n");
|
||||
a.mode = AM_6LOWPAN_NONE;
|
||||
addr_802154_to_ietf(&a);
|
||||
dbg_addr_ext("After", a.addr.data);
|
||||
buf[0] = 7;
|
||||
buf[1] = 8;
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(a.addr.data, buf, SIZE_6LOWPAN_EXT),
|
||||
"Should've done nothing\n");
|
||||
|
||||
ENDING(test);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_ll_src)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_ip6 ip = {
|
||||
.addr = {0,0,0,0,0,0,0,0, 3,2,3,4,5,6,7,8}
|
||||
};
|
||||
struct pico_ip6 ip2 = {
|
||||
.addr = {0,0,0,0,0,0,0,0, 0,0,0,0xff,0xfe,0,0x12,0x34}
|
||||
};
|
||||
struct pico_6lowpan_info info = {
|
||||
.addr_short.addr = short_be(0x1234),
|
||||
.addr_ext.addr = {3,2,3,4,5,6,7,8}
|
||||
};
|
||||
struct pico_device dev;
|
||||
struct pico_802154 addr;
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->buffer;
|
||||
|
||||
STARTING();
|
||||
|
||||
dev.eth = (struct pico_ethdev *)&info;
|
||||
f->net_hdr = f->buffer;
|
||||
f->dev = &dev;
|
||||
dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;
|
||||
|
||||
// TEST 3
|
||||
TRYING("With an IPv6 address that is derived from MAC short address\n");
|
||||
info.addr_short.addr = short_be(0x1234);
|
||||
hdr->src = ip2;
|
||||
addr = addr_802154_ll_src(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
|
||||
"Should've returned device's short address \n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(short_be(0x1234) == addr.addr._short.addr,
|
||||
"Should've copied the short address from the device\n");
|
||||
|
||||
// TEST 4
|
||||
TRYING("With an IPv6 address that is derived from MAC extended address\n");
|
||||
ip.addr[8] = 1;
|
||||
hdr->src = ip;
|
||||
addr = addr_802154_ll_src(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
|
||||
"Should've returned device's extended address\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(info.addr_ext.addr, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
|
||||
"Should've copied device's extended address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_ll_dst)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_ip6 ip;
|
||||
struct pico_ip6 local;
|
||||
struct pico_ip6 local2;
|
||||
struct pico_802154 addr;
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->buffer;
|
||||
struct pico_device dev;
|
||||
uint8_t buf[] = {3,2,3,4,5,6,7,8};
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e801:100", ip.addr);
|
||||
pico_string_to_ipv6("fe80:0:0:0:0102:0304:0506:0708", local.addr);
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0ff:fe00:1234", local2.addr);
|
||||
|
||||
STARTING();
|
||||
|
||||
f->net_hdr = f->buffer;
|
||||
f->dev = &dev;
|
||||
dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;
|
||||
|
||||
// TEST 1
|
||||
TRYING("With a MCAST IPv6 address, should return 0xFFFF\n");
|
||||
hdr->dst = ip;
|
||||
addr = addr_802154_ll_dst(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
|
||||
"Should've set address mode to SHORT\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(short_be(ADDR_802154_BCAST) == addr.addr._short.addr,
|
||||
"Should've set address to BCAST\n");
|
||||
|
||||
// TEST 2
|
||||
TRYING("With a link local IPv6 address derived from an extended L2 address\n");
|
||||
hdr->dst = local;
|
||||
addr = addr_802154_ll_dst(f);
|
||||
dbg_addr_ext("After:", addr.addr._ext.addr);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
|
||||
"Should've set address mode to EXTENDED\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(buf, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
|
||||
"Should've copied the extended address from the IP address\n");
|
||||
|
||||
// TEST 3
|
||||
TRYING("With a link local IPv6 address derived from a short L2 address\n");
|
||||
hdr->dst = local2;
|
||||
addr = addr_802154_ll_dst(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_SHORT == addr.mode,
|
||||
"Should've set address mode to SHORT\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(short_be(0x1234) == addr.addr._short.addr,
|
||||
"Should've copied the short address from the IP address\n");
|
||||
|
||||
/* TODO: Test getting address from neighbour table */
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* FRAME
|
||||
******************************************************************************/
|
||||
|
||||
/* Frame (123 bytes) */
|
||||
static uint8_t pkt[] = {
|
||||
0x41, 0xcc, 0xa6, 0xff, 0xff, 0x8a, /* A..... */
|
||||
0x18, 0x00, 0xff, 0xff, 0xda, 0x1c, 0x00, 0x88, /* ........ */
|
||||
0x18, 0x00, 0xff, 0xff, 0xda, 0x1c, 0x00, 0xc1, /* ........ */
|
||||
0x09, 0x00, 0x02, 0x42, 0xfa, 0x40, 0x04, 0x01, /* ...B.@.. */
|
||||
0xf0, 0xb1, 0x01, 0x06, 0x6f, 0xaf, 0x48, 0x65, /* ....o.He */
|
||||
0x6c, 0x6c, 0x6f, 0x20, 0x30, 0x30, 0x36, 0x20, /* llo 006 */
|
||||
0x30, 0x78, 0x46, 0x46, 0x33, 0x43, 0x0a, 0x00, /* 0xFF3C.. */
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, /* ........ */
|
||||
0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, /* ...... ! */
|
||||
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, /* "#$%&'() */
|
||||
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, /* *+,-./01 */
|
||||
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, /* 23456789 */
|
||||
0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, /* :;<=>?@A */
|
||||
0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, /* BCDEFGHI */
|
||||
0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, /* JKLMNOPQ */
|
||||
0x52, 0x53, 0x54, 0x68, 0x79 /* RSThy */
|
||||
};
|
||||
|
||||
START_TEST(tc_dst_am)
|
||||
{
|
||||
int test = 1;
|
||||
int ret = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Trying to determine AM of destination addr from buffer \n");
|
||||
ret = dst_am((struct pico_802154_hdr *)pkt);
|
||||
DBG("ret = %d\n", ret);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == ret,
|
||||
"Should've returned the AM of an extended address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_src_am)
|
||||
{
|
||||
int test = 1;
|
||||
int ret = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Trying to determine AM of source addr from buffer \n");
|
||||
ret = src_am((struct pico_802154_hdr *)pkt);
|
||||
DBG("ret = %d\n", ret);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == ret,
|
||||
"Should've returned the AM of an extended address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_hdr_len)
|
||||
{
|
||||
int test = 1;
|
||||
int ret = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Trying to determine length of the header from buffer\n");
|
||||
ret = frame_802154_hdr_len((struct pico_802154_hdr *)pkt);
|
||||
DBG("ret = %d\n", ret);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(21 == ret,
|
||||
"Should've returned the correct length of the header\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_src)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_802154_hdr *hdr;
|
||||
struct pico_802154 addr;
|
||||
uint8_t src[] = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x88};
|
||||
STARTING();
|
||||
|
||||
hdr = (struct pico_802154_hdr *)pkt;
|
||||
|
||||
// TEST 1
|
||||
TRYING("To receive the source address from a mapped buffer\n");
|
||||
addr = frame_802154_src(hdr);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
|
||||
"Should've returned an extended address\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(src, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
|
||||
"Should've copied the extended source address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_dst)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_802154_hdr *hdr;
|
||||
struct pico_802154 addr;
|
||||
uint8_t dst[] = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a};
|
||||
|
||||
STARTING();
|
||||
hdr = (struct pico_802154_hdr *)pkt;
|
||||
|
||||
// TEST 1
|
||||
TRYING("To receive the source address from a mapped buffer\n");
|
||||
addr = frame_802154_dst(hdr);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(AM_6LOWPAN_EXT == addr.mode,
|
||||
"Should've returned an extended address\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(dst, addr.addr._ext.addr, SIZE_6LOWPAN_EXT),
|
||||
"Should've copied the extended source address\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_802154_format)
|
||||
{
|
||||
int test = 1;
|
||||
struct pico_802154 src = {
|
||||
.addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x88},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_802154 dst = {
|
||||
.addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_6lowpan_short pan = { .addr = short_be(0xffff) };
|
||||
uint8_t buf[127] = {0};
|
||||
int i = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
// TEST 1
|
||||
TRYING("To format a frame like sample capture\n");
|
||||
frame_802154_format(buf, 166, FCF_INTRA_PAN, FCF_NO_ACK_REQ,
|
||||
FCF_NO_SEC, pan, src, dst);
|
||||
printf("Buffer:");
|
||||
for (i = 0; i < 21; i++) {
|
||||
if (i % 8 != 0)
|
||||
printf("%02x ", buf[i]);
|
||||
else {
|
||||
printf("\n%02x ", buf[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(21 == frame_802154_hdr_len((struct pico_802154_hdr *)buf),
|
||||
"Failed to correctly set the frame header, the length isn't right\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(pkt, buf, 21),
|
||||
"Failed to correctly format IEEE802.15.4 frame\n");
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_802154_process_out)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int test = 1;
|
||||
struct pico_802154 src = {
|
||||
.addr.data = {3,2,3,4,5,6,7,8},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_802154 dst = {
|
||||
.addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_frame *f = pico_frame_alloc(0);
|
||||
struct pico_6lowpan_info info = {
|
||||
.addr_short.addr = short_be(0x1234),
|
||||
.addr_ext.addr = {3,2,3,4,5,6,7,8},
|
||||
.pan_id.addr = short_be(0x1234)
|
||||
};
|
||||
struct pico_device dev;
|
||||
uint8_t buf[] = {0x41,0xcc,0x00,0x34,0x12,0x8a,0x18,0x00,
|
||||
0xff,0xff,0xda,0x1c,0x00,0x08,0x07,0x06,
|
||||
0x05,0x04,0x03,0x02,0x03};
|
||||
dev.eth = (struct pico_ethdev *)&info;
|
||||
dev.q_out = PICO_ZALLOC(sizeof(struct pico_queue));
|
||||
f->dev = &dev;
|
||||
dev.hostvars.lowpan_flags = PICO_6LP_FLAG_LOWPAN;
|
||||
|
||||
STARTING();
|
||||
pico_stack_init();
|
||||
|
||||
// TEST 1
|
||||
TRYING("Trying with bare frame\n");
|
||||
f->src.pan = src;
|
||||
f->dst.pan = dst;
|
||||
ret = pico_802154_process_out(f);
|
||||
printf("Buffer:");
|
||||
for (i = 0; i < 21; i++) {
|
||||
if (i % 8 != 0)
|
||||
printf("%02x ", f->datalink_hdr[i]);
|
||||
else {
|
||||
printf("\n%02x ", f->datalink_hdr[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 < ret, "Shouldn't have returned an error\n");
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 == memcmp(buf, f->datalink_hdr, 21),
|
||||
"Frame isn't correctly formatted\n");
|
||||
|
||||
pico_frame_discard(f);
|
||||
|
||||
ENDING(test);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_802154_process_in)
|
||||
{
|
||||
int ret = 0;
|
||||
int test = 1;
|
||||
struct pico_802154 src = {
|
||||
.addr.data = {3,2,3,4,5,6,7,8},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_802154 dst = {
|
||||
.addr.data = {0x00, 0x1C, 0xDA, 0xFF, 0xFF, 0x00, 0x18, 0x8a},
|
||||
.mode = AM_6LOWPAN_EXT
|
||||
};
|
||||
struct pico_frame *f = pico_frame_alloc(22);
|
||||
uint8_t buf[] = {0x41,0xcc,0x00,0x34,0x12,0x8a,0x18,0x00,
|
||||
0xff,0xff,0xda,0x1c,0x00,0x08,0x07,0x06,
|
||||
0x05,0x04,0x03,0x02,0x03,0x60};
|
||||
memcpy(f->buffer, buf, 22);
|
||||
f->src.pan = src;
|
||||
f->dst.pan = dst;
|
||||
|
||||
STARTING();
|
||||
pico_stack_init();
|
||||
|
||||
TRYING("Apply processing function on predefined buffer\n");
|
||||
ret = pico_802154_process_in(f);
|
||||
CHECKING(test);
|
||||
FAIL_UNLESS(0 < ret, "Should not return failure\n");
|
||||
}
|
||||
END_TEST
|
||||
static Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_swap = tcase_create("Unit test for pico_swap");
|
||||
TCase *TCase_802154_to_ietf = tcase_create("Unit test for 802154_to_ietf");
|
||||
TCase *TCase_802154_ll_src = tcase_create("Unit test for 802154_ll_src");
|
||||
TCase *TCase_802154_ll_dst = tcase_create("Unit test for 802154_ll_dst");
|
||||
TCase *TCase_802154_hdr_len = tcase_create("Unit test for 802154_hdr_len");
|
||||
TCase *TCase_src_am = tcase_create("Unit test for src_am");
|
||||
TCase *TCase_dst_am = tcase_create("Unit test for dst_am");
|
||||
TCase *TCase_802154_src = tcase_create("Unit test for 802154_src");
|
||||
TCase *TCase_802154_dst = tcase_create("Unit test for 802154_dst");
|
||||
TCase *TCase_802154_format = tcase_create("Unit test for 802154_format");
|
||||
TCase *TCase_802154_process_out = tcase_create("Unit test for 802154_process_out");
|
||||
TCase *TCase_802154_process_in = tcase_create("Unit test for 802154_process_in");
|
||||
|
||||
/*******************************************************************************
|
||||
* ADDRESSES
|
||||
******************************************************************************/
|
||||
tcase_add_test(TCase_swap, tc_swap);
|
||||
suite_add_tcase(s, TCase_swap);
|
||||
tcase_add_test(TCase_802154_to_ietf, tc_802154_to_ietf);
|
||||
suite_add_tcase(s, TCase_802154_to_ietf);
|
||||
tcase_add_test(TCase_802154_ll_src, tc_802154_ll_src);
|
||||
suite_add_tcase(s, TCase_802154_ll_src);
|
||||
tcase_add_test(TCase_802154_ll_dst, tc_802154_ll_dst);
|
||||
suite_add_tcase(s, TCase_802154_ll_dst);
|
||||
|
||||
/*******************************************************************************
|
||||
* FRAME
|
||||
******************************************************************************/
|
||||
tcase_add_test(TCase_802154_hdr_len, tc_802154_hdr_len);
|
||||
suite_add_tcase(s, TCase_802154_hdr_len);
|
||||
tcase_add_test(TCase_src_am, tc_src_am);
|
||||
suite_add_tcase(s, TCase_src_am);
|
||||
tcase_add_test(TCase_dst_am, tc_dst_am);
|
||||
suite_add_tcase(s, TCase_dst_am);
|
||||
tcase_add_test(TCase_802154_src, tc_802154_src);
|
||||
suite_add_tcase(s, TCase_802154_src);
|
||||
tcase_add_test(TCase_802154_dst, tc_802154_dst);
|
||||
suite_add_tcase(s, TCase_802154_dst);
|
||||
tcase_add_test(TCase_802154_format, tc_802154_format);
|
||||
suite_add_tcase(s, TCase_802154_format);
|
||||
tcase_add_test(TCase_802154_process_out, tc_802154_process_out);
|
||||
suite_add_tcase(s, TCase_802154_process_out);
|
||||
tcase_add_test(TCase_802154_process_in, tc_802154_process_in);
|
||||
suite_add_tcase(s, TCase_802154_process_in);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
545
kernel/picotcp/test/unit/modunit_pico_aodv.c
Normal file
545
kernel/picotcp/test/unit/modunit_pico_aodv.c
Normal file
@ -0,0 +1,545 @@
|
||||
#include <pico_stack.h>
|
||||
#include <pico_tree.h>
|
||||
#include <pico_socket.h>
|
||||
#include <pico_aodv.h>
|
||||
#include <pico_device.h>
|
||||
#include <pico_ipv4.h>
|
||||
#include "modules/pico_aodv.c"
|
||||
#include "check.h"
|
||||
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_aodv_node_compare)
|
||||
{
|
||||
struct pico_aodv_node a, b;
|
||||
a.dest.ip4.addr = long_be(1);
|
||||
b.dest.ip4.addr = long_be(2);
|
||||
|
||||
fail_if(aodv_node_compare(&a, &b) >= 0);
|
||||
a.dest.ip4.addr = long_be(3);
|
||||
fail_if(aodv_node_compare(&a, &b) <= 0);
|
||||
b.dest.ip4.addr = long_be(3);
|
||||
fail_if(aodv_node_compare(&a, &b) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_dev_cmp)
|
||||
{
|
||||
struct pico_device a, b;
|
||||
a.hash = 1;
|
||||
b.hash = 2;
|
||||
fail_if(aodv_dev_cmp(&a, &b) >= 0);
|
||||
a.hash = 3;
|
||||
fail_if(aodv_dev_cmp(&a, &b) <= 0);
|
||||
b.hash = 3;
|
||||
fail_if(aodv_dev_cmp(&a, &b) != 0);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_get_node_by_addr)
|
||||
{
|
||||
struct pico_aodv_node a;
|
||||
union pico_address test;
|
||||
a.dest.ip4.addr = long_be(10);
|
||||
test.ip4.addr = long_be(10);
|
||||
|
||||
pico_tree_insert(&aodv_nodes, &a);
|
||||
|
||||
fail_if(get_node_by_addr(&test) != &a);
|
||||
pico_tree_delete(&aodv_nodes, &a);
|
||||
fail_if(get_node_by_addr(&test) != NULL);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static int set_bcast_link_called = 0;
|
||||
void pico_ipv4_route_set_bcast_link(struct pico_ipv4_link *link)
|
||||
{
|
||||
IGNORE_PARAMETER(link);
|
||||
set_bcast_link_called++;
|
||||
}
|
||||
|
||||
START_TEST(tc_pico_aodv_set_dev)
|
||||
{
|
||||
struct pico_device *dev = NULL;
|
||||
pico_aodv_set_dev(dev);
|
||||
fail_if(set_bcast_link_called != 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_peer_refresh)
|
||||
{
|
||||
/* TODO: test this: static int aodv_peer_refresh(struct pico_aodv_node *node, uint32_t seq) */
|
||||
struct pico_aodv_node node;
|
||||
memset(&node, 0, sizeof(node));
|
||||
node.dseq = 0xFFFF;
|
||||
fail_if(aodv_peer_refresh(&node, 10) != 0); /* should succeed, because SYNC flag is not yet set... */
|
||||
fail_if((node.flags & PICO_AODV_NODE_SYNC) == 0); /* Flag should be set after last call... */
|
||||
fail_if(aodv_peer_refresh(&node, 5) == 0); /* should FAIL, because seq number is lower... */
|
||||
fail_if(aodv_peer_refresh(&node, 10) == 0); /* should FAIL, because seq number is still the same... */
|
||||
fail_if(aodv_peer_refresh(&node, 15) != 0); /* should succeed, because seq number is now bigger... */
|
||||
fail_if(node.dseq != 15);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static int called_route_add = 0;
|
||||
static uint32_t route_add_gw = 0u;
|
||||
static int route_add_metric = 0;
|
||||
int pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link)
|
||||
{
|
||||
IGNORE_PARAMETER(link);
|
||||
IGNORE_PARAMETER(netmask);
|
||||
IGNORE_PARAMETER(address);
|
||||
called_route_add++;
|
||||
route_add_gw = gateway.addr;
|
||||
route_add_metric = metric;
|
||||
return 0;
|
||||
}
|
||||
|
||||
START_TEST(tc_aodv_elect_route)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
union pico_address gateway;
|
||||
memset(&node, 0, sizeof(node));
|
||||
gateway.ip4.addr = 0x55555555;
|
||||
|
||||
called_route_add = 0;
|
||||
aodv_elect_route(&node, NULL, 150, NULL);
|
||||
fail_if(called_route_add != 1); /* Not active, should succeed */
|
||||
fail_if(route_add_gw != 0u);
|
||||
fail_if(route_add_metric != 1);
|
||||
|
||||
called_route_add = 0;
|
||||
route_add_metric = 0;
|
||||
route_add_gw = 0u;
|
||||
node.flags = PICO_AODV_NODE_ROUTE_DOWN | PICO_AODV_NODE_ROUTE_UP;
|
||||
aodv_elect_route(&node, &gateway, 150, NULL);
|
||||
fail_if(called_route_add != 0); /* Already active, existing metric is lower */
|
||||
|
||||
called_route_add = 0;
|
||||
route_add_metric = 0;
|
||||
route_add_gw = 0u;
|
||||
node.metric = 22;
|
||||
aodv_elect_route(&node, &gateway, 15, NULL);
|
||||
fail_if(called_route_add != 1); /* Already active, existing metric is higher */
|
||||
fail_if(route_add_metric != 16);
|
||||
fail_if(route_add_gw != 0x55555555);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_peer_new)
|
||||
{
|
||||
union pico_address addr;
|
||||
struct pico_aodv_node *new;
|
||||
addr.ip4.addr = 0x44444444;
|
||||
new = aodv_peer_new(&addr);
|
||||
fail_if(!new);
|
||||
fail_if(!get_node_by_addr(&addr));
|
||||
pico_set_mm_failure(1);
|
||||
new = aodv_peer_new(&addr);
|
||||
fail_if(new);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_aodv_peer_eval)
|
||||
{
|
||||
union pico_address addr;
|
||||
struct pico_aodv_node *node = NULL;
|
||||
/* Case 0: Creation */
|
||||
addr.ip4.addr = 0x11224433;
|
||||
node = aodv_peer_eval(&addr, 0, 0);
|
||||
fail_if(!node);
|
||||
fail_if((node->flags & PICO_AODV_NODE_SYNC) != 0); /* Not synced! */
|
||||
|
||||
/* Case 1: retrieve, unsynced */
|
||||
node->metric = 42;
|
||||
node = aodv_peer_eval(&addr, 0, 0); /* Should get existing node! */
|
||||
fail_if(!node);
|
||||
fail_if(node->metric != 42);
|
||||
fail_if((node->flags & PICO_AODV_NODE_SYNC) != 0); /* Not synced! */
|
||||
|
||||
|
||||
/* Case 2: new node, invalid allocation */
|
||||
addr.ip4.addr = 0x11224455;
|
||||
pico_set_mm_failure(1);
|
||||
node = aodv_peer_eval(&addr, long_be(10), 1);
|
||||
fail_if(node);
|
||||
|
||||
/* Case 3: existing node, setting the new sequence */
|
||||
addr.ip4.addr = 0x11224433;
|
||||
node = aodv_peer_eval(&addr, long_be(10), 1); /* Should get existing node! */
|
||||
fail_if(node->metric != 42);
|
||||
fail_if((node->flags & PICO_AODV_NODE_SYNC) == 0);
|
||||
fail_if(node->dseq != 10);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_lifetime)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
pico_time now = PICO_TIME_MS();
|
||||
memset(&node, 0, sizeof(node));
|
||||
fail_if(aodv_lifetime(&node) == 0);
|
||||
fail_if(node.last_seen < now);
|
||||
node.last_seen = now - AODV_ACTIVE_ROUTE_TIMEOUT;
|
||||
fail_if(aodv_lifetime(&node) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static uint8_t sent_pkt_type = 0xFF;
|
||||
static uint32_t dest_addr = 0;
|
||||
static int pico_socket_sendto_called = 0;
|
||||
static int pico_socket_sendto_extended_called = 0;
|
||||
uint32_t expected_dseq = 0;
|
||||
int pico_socket_sendto(struct pico_socket *s, const void *buf, const int len, void *dst, uint16_t remote_port)
|
||||
{
|
||||
uint8_t *pkt = (uint8_t *)(uintptr_t)buf;
|
||||
printf("Sendto called!\n");
|
||||
pico_socket_sendto_called++;
|
||||
fail_if(remote_port != short_be(PICO_AODV_PORT));
|
||||
fail_if (s != aodv_socket);
|
||||
fail_if(pkt[0] > 4);
|
||||
fail_if(pkt[0] < 1);
|
||||
sent_pkt_type = pkt[0];
|
||||
dest_addr = ((union pico_address *)dst)->ip4.addr;
|
||||
if (sent_pkt_type == AODV_TYPE_RREQ) {
|
||||
/* struct pico_aodv_rreq *req = (struct pico_aodv_rreq *)(uintptr_t)buf; */
|
||||
fail_if(len != sizeof(struct pico_aodv_rreq));
|
||||
}
|
||||
else if (sent_pkt_type == AODV_TYPE_RREP) {
|
||||
struct pico_aodv_rrep *rep = (struct pico_aodv_rrep *)(uintptr_t)buf;
|
||||
fail_if(len != sizeof(struct pico_aodv_rrep));
|
||||
fail_if(rep->dest != 0x11111111);
|
||||
fail_if(rep->orig != 0x22222222);
|
||||
printf("rep->dseq= %08x, exp: %08x\n", rep->dseq, expected_dseq);
|
||||
fail_if(rep->dseq != expected_dseq);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int pico_socket_sendto_extended(struct pico_socket *s, const void *buf, const int len,
|
||||
void *dst, uint16_t remote_port, struct pico_msginfo *msginfo)
|
||||
{
|
||||
IGNORE_PARAMETER(msginfo);
|
||||
pico_socket_sendto_extended_called++;
|
||||
return pico_socket_sendto(s, buf, len, dst, remote_port);
|
||||
}
|
||||
|
||||
START_TEST(tc_aodv_send_reply)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
struct pico_aodv_rreq req;
|
||||
struct pico_msginfo info;
|
||||
union pico_address addr;
|
||||
addr.ip4.addr = 0x22222222;
|
||||
memset(&node, 0, sizeof(node));
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
req.dest = 0x11111111;
|
||||
req.orig = addr.ip4.addr;
|
||||
req.dseq = 99;
|
||||
|
||||
aodv_send_reply(&node, &req, 1, &info);
|
||||
fail_if(pico_socket_sendto_called != 0); /* Call should have no effect, due to non-existing origin node */
|
||||
|
||||
/* Creating origin... */
|
||||
fail_if(aodv_peer_new(&addr) == NULL);
|
||||
aodv_send_reply(&node, &req, 0, &info);
|
||||
fail_if(pico_socket_sendto_called != 0); /* Call should have no effect, node non-local, non sync'd */
|
||||
|
||||
expected_dseq = long_be(pico_aodv_local_id + 1);
|
||||
aodv_send_reply(&node, &req, 1, &info);
|
||||
fail_if(pico_socket_sendto_called != 1); /* Call should succeed */
|
||||
pico_socket_sendto_called = 0;
|
||||
|
||||
node.flags = PICO_AODV_NODE_SYNC;
|
||||
node.dseq = 42;
|
||||
expected_dseq = long_be(42);
|
||||
aodv_send_reply(&node, &req, 0, &info);
|
||||
fail_if(pico_socket_sendto_called != 1); /* Call should succeed */
|
||||
pico_socket_sendto_called = 0;
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static struct pico_ipv4_link global_link;
|
||||
struct pico_ipv4_link *pico_ipv4_link_by_dev(struct pico_device *dev)
|
||||
{
|
||||
IGNORE_PARAMETER(dev);
|
||||
if (!global_link.address.addr)
|
||||
return NULL;
|
||||
|
||||
printf("Setting link!\n");
|
||||
return &global_link;
|
||||
}
|
||||
|
||||
static struct pico_device global_dev;
|
||||
static int link_find_success = 0;
|
||||
struct pico_device *pico_ipv4_link_find(struct pico_ip4 *ip4)
|
||||
{
|
||||
IGNORE_PARAMETER(ip4);
|
||||
if (link_find_success)
|
||||
return &global_dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int timer_set = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(arg);
|
||||
IGNORE_PARAMETER(timer);
|
||||
IGNORE_PARAMETER(expire);
|
||||
printf("Timer set!\n");
|
||||
timer_set++;
|
||||
return (uint32_t ) 0x99999999;
|
||||
|
||||
}
|
||||
|
||||
START_TEST(tc_aodv_send_req)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
struct pico_device d;
|
||||
aodv_socket = NULL;
|
||||
|
||||
memset(&node, 0, sizeof(node));
|
||||
node.flags = PICO_AODV_NODE_ROUTE_DOWN | PICO_AODV_NODE_ROUTE_UP;
|
||||
fail_if(aodv_send_req(&node) != 0); /* Should fail: node already active */
|
||||
fail_if(pico_socket_sendto_called != 0);
|
||||
fail_if(pico_socket_sendto_extended_called != 0);
|
||||
|
||||
node.flags = 0;
|
||||
fail_if(aodv_send_req(&node) != 0); /* Should fail: no devices in tree */
|
||||
fail_if(pico_socket_sendto_called != 0);
|
||||
fail_if(pico_socket_sendto_extended_called != 0);
|
||||
|
||||
pico_tree_insert(&aodv_devices, &d);
|
||||
fail_if(aodv_send_req(&node) != -1); /* Should fail: aodv_socket == NULL */
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
fail_if(pico_socket_sendto_called != 0);
|
||||
fail_if(pico_socket_sendto_extended_called != 0);
|
||||
|
||||
|
||||
/* No valid link, timer is set, call does not send packets */
|
||||
aodv_socket = (struct pico_socket*) 1;
|
||||
global_link.address.addr = 0;
|
||||
fail_if(aodv_send_req(&node) != 0);
|
||||
fail_if(pico_socket_sendto_called != 0);
|
||||
fail_if(pico_socket_sendto_extended_called != 0);
|
||||
fail_if(timer_set != 1);
|
||||
timer_set = 0;
|
||||
|
||||
|
||||
/* One valid link, timer is set, one packet is sent */
|
||||
global_link.address.addr = 0xFEFEFEFE;
|
||||
fail_if(aodv_send_req(&node) != 1);
|
||||
fail_if(pico_socket_sendto_called != 1);
|
||||
fail_if(pico_socket_sendto_extended_called != 1);
|
||||
fail_if(timer_set != 1);
|
||||
pico_socket_sendto_called = 0;
|
||||
pico_socket_sendto_extended_called = 0;
|
||||
timer_set = 0;
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_reverse_path_discover)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
memset(&node, 0, sizeof(node));
|
||||
aodv_reverse_path_discover(0, &node);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_recv_valid_rreq)
|
||||
{
|
||||
struct pico_aodv_node node;
|
||||
struct pico_aodv_rreq req;
|
||||
struct pico_msginfo info;
|
||||
union pico_address addr;
|
||||
memset(&node, 0, sizeof(node));
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
addr.ip4.addr = 0x22222222;
|
||||
|
||||
link_find_success = 0;
|
||||
aodv_recv_valid_rreq(&node, &req, &info);
|
||||
fail_if(pico_socket_sendto_called > 0);
|
||||
|
||||
/* link not local, but active node, set to send reply, no timer */
|
||||
link_find_success = 0;
|
||||
fail_if(aodv_peer_new(&addr) == NULL);
|
||||
global_link.address.addr = 0x44444444;
|
||||
req.orig = addr.ip4.addr;
|
||||
req.dest = 0x11111111;
|
||||
node.flags = PICO_AODV_NODE_SYNC | PICO_AODV_NODE_ROUTE_UP | PICO_AODV_NODE_ROUTE_DOWN;
|
||||
node.dseq = 42;
|
||||
expected_dseq = long_be(42);
|
||||
aodv_recv_valid_rreq(&node, &req, &info);
|
||||
fail_if(pico_socket_sendto_called < 1);
|
||||
fail_if(timer_set > 0);
|
||||
pico_socket_sendto_called = 0;
|
||||
|
||||
/* link local, active node. Full send + set timer. */
|
||||
link_find_success = 1;
|
||||
expected_dseq = long_be(pico_aodv_local_id + 1);
|
||||
aodv_peer_new(&addr);
|
||||
aodv_recv_valid_rreq(&node, &req, &info);
|
||||
fail_if(pico_socket_sendto_called < 1);
|
||||
fail_if(timer_set < 1);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_parse_rreq)
|
||||
{
|
||||
/* TODO: test this: static void aodv_parse_rreq(union pico_address *from, uint8_t *buf, int len, struct pico_msginfo *msginfo) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_parse_rrep)
|
||||
{
|
||||
/* TODO: test this: static void aodv_parse_rrep(union pico_address *from, uint8_t *buf, int len, struct pico_msginfo *msginfo) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_parse_rerr)
|
||||
{
|
||||
/* TODO: test this: static void aodv_parse_rerr(union pico_address *from, uint8_t *buf, int len, struct pico_msginfo *msginfo) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_parse_rack)
|
||||
{
|
||||
aodv_parse_rack(NULL, NULL, 0, NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_aodv_parse)
|
||||
{
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_aodv_socket_callback)
|
||||
{
|
||||
/* TODO: test this: static void pico_aodv_socket_callback(uint16_t ev, struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_make_rreq)
|
||||
{
|
||||
/* TODO: test this: static void aodv_make_rreq(struct pico_aodv_node *node, struct pico_aodv_rreq *req) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_aodv_retrans_rreq)
|
||||
{
|
||||
/* TODO: test this: static void aodv_retrans_rreq(pico_time now, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_aodv_expired)
|
||||
{
|
||||
/* TODO: test this: static void pico_aodv_expired(struct pico_aodv_node *node) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_aodv_collector)
|
||||
{
|
||||
/* TODO: test this: static void pico_aodv_collector(pico_time now, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_aodv_node_compare = tcase_create("Unit test for aodv_node_compare");
|
||||
TCase *TCase_aodv_dev_cmp = tcase_create("Unit test for aodv_dev_cmp");
|
||||
TCase *TCase_get_node_by_addr = tcase_create("Unit test for get_node_by_addr");
|
||||
TCase *TCase_pico_aodv_set_dev = tcase_create("Unit test for pico_aodv_set_dev");
|
||||
TCase *TCase_aodv_peer_refresh = tcase_create("Unit test for aodv_peer_refresh");
|
||||
TCase *TCase_aodv_elect_route = tcase_create("Unit test for aodv_elect_route");
|
||||
TCase *TCase_aodv_peer_new = tcase_create("Unit test for aodv_peer_new");
|
||||
TCase *TCase_aodv_peer_eval = tcase_create("Unit test for aodv_peer_eval");
|
||||
TCase *TCase_aodv_lifetime = tcase_create("Unit test for aodv_lifetime");
|
||||
TCase *TCase_aodv_send_reply = tcase_create("Unit test for aodv_send_reply");
|
||||
TCase *TCase_aodv_send_req = tcase_create("Unit test for aodv_send_req");
|
||||
TCase *TCase_aodv_reverse_path_discover = tcase_create("Unit test for aodv_reverse_path_discover");
|
||||
TCase *TCase_aodv_recv_valid_rreq = tcase_create("Unit test for aodv_recv_valid_rreq");
|
||||
TCase *TCase_aodv_parse_rreq = tcase_create("Unit test for aodv_parse_rreq");
|
||||
TCase *TCase_aodv_parse_rrep = tcase_create("Unit test for aodv_parse_rrep");
|
||||
TCase *TCase_aodv_parse_rerr = tcase_create("Unit test for aodv_parse_rerr");
|
||||
TCase *TCase_aodv_parse_rack = tcase_create("Unit test for aodv_parse_rack");
|
||||
TCase *TCase_pico_aodv_parse = tcase_create("Unit test for pico_aodv_parse");
|
||||
TCase *TCase_pico_aodv_socket_callback = tcase_create("Unit test for pico_aodv_socket_callback");
|
||||
TCase *TCase_aodv_make_rreq = tcase_create("Unit test for aodv_make_rreq");
|
||||
TCase *TCase_aodv_retrans_rreq = tcase_create("Unit test for aodv_retrans_rreq");
|
||||
TCase *TCase_pico_aodv_expired = tcase_create("Unit test for pico_aodv_expired");
|
||||
TCase *TCase_pico_aodv_collector = tcase_create("Unit test for pico_aodv_collector");
|
||||
|
||||
|
||||
tcase_add_test(TCase_aodv_node_compare, tc_aodv_node_compare);
|
||||
suite_add_tcase(s, TCase_aodv_node_compare);
|
||||
tcase_add_test(TCase_aodv_dev_cmp, tc_aodv_dev_cmp);
|
||||
suite_add_tcase(s, TCase_aodv_dev_cmp);
|
||||
tcase_add_test(TCase_get_node_by_addr, tc_get_node_by_addr);
|
||||
suite_add_tcase(s, TCase_get_node_by_addr);
|
||||
tcase_add_test(TCase_pico_aodv_set_dev, tc_pico_aodv_set_dev);
|
||||
suite_add_tcase(s, TCase_pico_aodv_set_dev);
|
||||
tcase_add_test(TCase_aodv_peer_refresh, tc_aodv_peer_refresh);
|
||||
suite_add_tcase(s, TCase_aodv_peer_refresh);
|
||||
tcase_add_test(TCase_aodv_elect_route, tc_aodv_elect_route);
|
||||
suite_add_tcase(s, TCase_aodv_elect_route);
|
||||
tcase_add_test(TCase_aodv_peer_new, tc_aodv_peer_new);
|
||||
suite_add_tcase(s, TCase_aodv_peer_new);
|
||||
tcase_add_test(TCase_aodv_peer_eval, tc_aodv_peer_eval);
|
||||
suite_add_tcase(s, TCase_aodv_peer_eval);
|
||||
tcase_add_test(TCase_aodv_lifetime, tc_aodv_lifetime);
|
||||
suite_add_tcase(s, TCase_aodv_lifetime);
|
||||
tcase_add_test(TCase_aodv_send_reply, tc_aodv_send_reply);
|
||||
suite_add_tcase(s, TCase_aodv_send_reply);
|
||||
tcase_add_test(TCase_aodv_send_req, tc_aodv_send_req);
|
||||
suite_add_tcase(s, TCase_aodv_send_req);
|
||||
tcase_add_test(TCase_aodv_reverse_path_discover, tc_aodv_reverse_path_discover);
|
||||
suite_add_tcase(s, TCase_aodv_reverse_path_discover);
|
||||
tcase_add_test(TCase_aodv_recv_valid_rreq, tc_aodv_recv_valid_rreq);
|
||||
suite_add_tcase(s, TCase_aodv_recv_valid_rreq);
|
||||
tcase_add_test(TCase_aodv_parse_rreq, tc_aodv_parse_rreq);
|
||||
suite_add_tcase(s, TCase_aodv_parse_rreq);
|
||||
tcase_add_test(TCase_aodv_parse_rrep, tc_aodv_parse_rrep);
|
||||
suite_add_tcase(s, TCase_aodv_parse_rrep);
|
||||
tcase_add_test(TCase_aodv_parse_rerr, tc_aodv_parse_rerr);
|
||||
suite_add_tcase(s, TCase_aodv_parse_rerr);
|
||||
tcase_add_test(TCase_aodv_parse_rack, tc_aodv_parse_rack);
|
||||
suite_add_tcase(s, TCase_aodv_parse_rack);
|
||||
tcase_add_test(TCase_pico_aodv_parse, tc_pico_aodv_parse);
|
||||
suite_add_tcase(s, TCase_pico_aodv_parse);
|
||||
tcase_add_test(TCase_pico_aodv_socket_callback, tc_pico_aodv_socket_callback);
|
||||
suite_add_tcase(s, TCase_pico_aodv_socket_callback);
|
||||
tcase_add_test(TCase_aodv_make_rreq, tc_aodv_make_rreq);
|
||||
suite_add_tcase(s, TCase_aodv_make_rreq);
|
||||
tcase_add_test(TCase_aodv_retrans_rreq, tc_aodv_retrans_rreq);
|
||||
suite_add_tcase(s, TCase_aodv_retrans_rreq);
|
||||
tcase_add_test(TCase_pico_aodv_expired, tc_pico_aodv_expired);
|
||||
suite_add_tcase(s, TCase_pico_aodv_expired);
|
||||
tcase_add_test(TCase_pico_aodv_collector, tc_pico_aodv_collector);
|
||||
suite_add_tcase(s, TCase_pico_aodv_collector);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
97
kernel/picotcp/test/unit/modunit_pico_dev_loop.c
Normal file
97
kernel/picotcp/test/unit/modunit_pico_dev_loop.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include "modules/pico_dev_loop.c"
|
||||
#include "check.h"
|
||||
static int called = 0;
|
||||
static int fail = 0;
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
int pico_device_init(struct pico_device __attribute__((unused)) *dev, const char __attribute__((unused)) *name, const uint8_t __attribute__((unused)) *mac)
|
||||
{
|
||||
if (fail)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pico_device_destroy(struct pico_device *dev)
|
||||
{
|
||||
dev = dev;
|
||||
}
|
||||
|
||||
int32_t pico_stack_recv(struct pico_device __attribute__((unused)) *dev, uint8_t __attribute__((unused)) *buffer, uint32_t __attribute__((unused)) len)
|
||||
{
|
||||
called = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
START_TEST(tc_pico_loop_send)
|
||||
{
|
||||
uint8_t buf[LOOP_MTU + 1] = {};
|
||||
fail_if(pico_loop_send(NULL, buf, LOOP_MTU + 1) != 0);
|
||||
|
||||
/* First send: OK */
|
||||
fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != LOOP_MTU);
|
||||
|
||||
/* Second: buffer busy */
|
||||
fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != 0);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_loop_poll)
|
||||
{
|
||||
uint8_t buf[LOOP_MTU + 1] = {};
|
||||
fail_if(pico_loop_poll(NULL, 0) != 0);
|
||||
called = 0;
|
||||
/* First send: OK */
|
||||
fail_if(pico_loop_send(NULL, buf, LOOP_MTU) != LOOP_MTU);
|
||||
fail_if(pico_loop_poll(NULL, 1) != 0);
|
||||
fail_if(called == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_loop_create)
|
||||
{
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in pico_loop_create (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_loop_create() != NULL);
|
||||
#endif
|
||||
fail = 1;
|
||||
fail_if(pico_loop_create() != NULL);
|
||||
fail = 0;
|
||||
fail_if(pico_loop_create() == NULL);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_loop_send = tcase_create("Unit test for pico_loop_send");
|
||||
TCase *TCase_pico_loop_poll = tcase_create("Unit test for pico_loop_poll");
|
||||
TCase *TCase_pico_loop_create = tcase_create("Unit test for pico_loop_create");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_loop_send, tc_pico_loop_send);
|
||||
suite_add_tcase(s, TCase_pico_loop_send);
|
||||
tcase_add_test(TCase_pico_loop_poll, tc_pico_loop_poll);
|
||||
suite_add_tcase(s, TCase_pico_loop_poll);
|
||||
tcase_add_test(TCase_pico_loop_create, tc_pico_loop_create);
|
||||
suite_add_tcase(s, TCase_pico_loop_create);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
1387
kernel/picotcp/test/unit/modunit_pico_dev_ppp.c
Normal file
1387
kernel/picotcp/test/unit/modunit_pico_dev_ppp.c
Normal file
File diff suppressed because it is too large
Load Diff
229
kernel/picotcp/test/unit/modunit_pico_dns_client.c
Normal file
229
kernel/picotcp/test/unit/modunit_pico_dns_client.c
Normal file
@ -0,0 +1,229 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_addressing.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_dns_client.h"
|
||||
#include "pico_tree.h"
|
||||
#include "pico_udp.h"
|
||||
#include "modules/pico_dns_client.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_pico_dns_client_callback)
|
||||
{
|
||||
struct pico_socket *s = pico_udp_open();
|
||||
s->proto = &pico_proto_udp;
|
||||
|
||||
fail_if(!s);
|
||||
|
||||
/* Test with ERR */
|
||||
pico_dns_client_callback(PICO_SOCK_EV_ERR, s);
|
||||
|
||||
/* Test with failing RD */
|
||||
pico_dns_client_callback(PICO_SOCK_EV_RD, s);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_retransmission)
|
||||
{
|
||||
/* TODO: test this: static void pico_dns_client_retransmission(pico_time now, void *arg); */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_ns_cmp)
|
||||
{
|
||||
/* TODO: test this: static int dns_ns_cmp(void *ka, void *kb) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_query_cmp)
|
||||
{
|
||||
/* TODO: test this: static int dns_query_cmp(void *ka, void *kb) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_del_ns)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_del_ns(struct pico_ip4 *ns_addr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_ns)
|
||||
{
|
||||
/* TODO: test this: static struct pico_dns_ns *pico_dns_client_add_ns(struct pico_ip4 *ns_addr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_del_query)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_del_query(uint16_t id) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_query)
|
||||
{
|
||||
/* TODO: test this: static struct pico_dns_query *pico_dns_client_find_query(uint16_t id) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_strlen)
|
||||
{
|
||||
/* TODO: test this: static uint16_t pico_dns_client_strlen(const char *url) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_seek)
|
||||
{
|
||||
/* TODO: test this: static char *pico_dns_client_seek(char *ptr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_mirror)
|
||||
{
|
||||
/* TODO: test this: static int8_t pico_dns_client_mirror(char *ptr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_query_prefix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_query_prefix(struct pico_dns_prefix *pre) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_query_suffix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_query_suffix(struct pico_dns_query_suffix *suf, uint16_t type, uint16_t class) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_query_domain)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_query_domain(char *ptr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_answer_domain)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_answer_domain(char *ptr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_check_prefix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_check_prefix(struct pico_dns_prefix *pre) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_check_qsuffix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_check_qsuffix(struct pico_dns_query_suffix *suf, struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_check_asuffix)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_check_asuffix(struct pico_dns_answer_suffix *suf, struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_seek_suffix)
|
||||
{
|
||||
/* TODO: test this: static char *pico_dns_client_seek_suffix(char *suf, struct pico_dns_prefix *pre, struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_send)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_send(struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_user_callback)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_user_callback(struct pico_dns_answer_suffix *asuffix, struct pico_dns_query *q) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_client_getaddr_init)
|
||||
{
|
||||
/* TODO: test this: static int pico_dns_client_getaddr_init(const char *url, uint16_t proto, void (*callback)(char *, void *), void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_dns_ipv6_set_ptr)
|
||||
{
|
||||
/* TODO: test this: static void pico_dns_ipv6_set_ptr(const char *ip, char *dst) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_dns_client_callback = tcase_create("Unit test for pico_dns_client_callback");
|
||||
TCase *TCase_pico_dns_client_retransmission = tcase_create("Unit test for pico_dns_client_retransmission");
|
||||
TCase *TCase_dns_ns_cmp = tcase_create("Unit test for dns_ns_cmp");
|
||||
TCase *TCase_dns_query_cmp = tcase_create("Unit test for dns_query_cmp");
|
||||
TCase *TCase_pico_dns_client_del_ns = tcase_create("Unit test for pico_dns_client_del_ns");
|
||||
TCase *TCase_pico_dns_ns = tcase_create("Unit test for pico_dns_ns");
|
||||
TCase *TCase_pico_dns_client_del_query = tcase_create("Unit test for pico_dns_client_del_query");
|
||||
TCase *TCase_pico_dns_query = tcase_create("Unit test for pico_dns_query");
|
||||
TCase *TCase_pico_dns_client_strlen = tcase_create("Unit test for pico_dns_client_strlen");
|
||||
TCase *TCase_pico_dns_client_seek = tcase_create("Unit test for pico_dns_client_seek");
|
||||
TCase *TCase_pico_dns_client_mirror = tcase_create("Unit test for pico_dns_client_mirror");
|
||||
TCase *TCase_pico_dns_client_query_prefix = tcase_create("Unit test for pico_dns_client_query_prefix");
|
||||
TCase *TCase_pico_dns_client_query_suffix = tcase_create("Unit test for pico_dns_client_query_suffix");
|
||||
TCase *TCase_pico_dns_client_query_domain = tcase_create("Unit test for pico_dns_client_query_domain");
|
||||
TCase *TCase_pico_dns_client_answer_domain = tcase_create("Unit test for pico_dns_client_answer_domain");
|
||||
TCase *TCase_pico_dns_client_check_prefix = tcase_create("Unit test for pico_dns_client_check_prefix");
|
||||
TCase *TCase_pico_dns_client_check_qsuffix = tcase_create("Unit test for pico_dns_client_check_qsuffix");
|
||||
TCase *TCase_pico_dns_client_check_asuffix = tcase_create("Unit test for pico_dns_client_check_asuffix");
|
||||
TCase *TCase_pico_dns_client_seek_suffix = tcase_create("Unit test for pico_dns_client_seek_suffix");
|
||||
TCase *TCase_pico_dns_client_send = tcase_create("Unit test for pico_dns_client_send");
|
||||
TCase *TCase_pico_dns_client_user_callback = tcase_create("Unit test for pico_dns_client_user_callback");
|
||||
TCase *TCase_pico_dns_client_getaddr_init = tcase_create("Unit test for pico_dns_client_getaddr_init");
|
||||
TCase *TCase_pico_dns_ipv6_set_ptr = tcase_create("Unit test for pico_dns_ipv6_set_ptr");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_dns_client_callback, tc_pico_dns_client_callback);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_callback);
|
||||
tcase_add_test(TCase_pico_dns_client_retransmission, tc_pico_dns_client_retransmission);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_retransmission);
|
||||
tcase_add_test(TCase_dns_ns_cmp, tc_dns_ns_cmp);
|
||||
suite_add_tcase(s, TCase_dns_ns_cmp);
|
||||
tcase_add_test(TCase_dns_query_cmp, tc_dns_query_cmp);
|
||||
suite_add_tcase(s, TCase_dns_query_cmp);
|
||||
tcase_add_test(TCase_pico_dns_client_del_ns, tc_pico_dns_client_del_ns);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_del_ns);
|
||||
tcase_add_test(TCase_pico_dns_ns, tc_pico_dns_ns);
|
||||
suite_add_tcase(s, TCase_pico_dns_ns);
|
||||
tcase_add_test(TCase_pico_dns_client_del_query, tc_pico_dns_client_del_query);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_del_query);
|
||||
tcase_add_test(TCase_pico_dns_query, tc_pico_dns_query);
|
||||
suite_add_tcase(s, TCase_pico_dns_query);
|
||||
tcase_add_test(TCase_pico_dns_client_strlen, tc_pico_dns_client_strlen);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_strlen);
|
||||
tcase_add_test(TCase_pico_dns_client_seek, tc_pico_dns_client_seek);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_seek);
|
||||
tcase_add_test(TCase_pico_dns_client_mirror, tc_pico_dns_client_mirror);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_mirror);
|
||||
tcase_add_test(TCase_pico_dns_client_query_prefix, tc_pico_dns_client_query_prefix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_query_prefix);
|
||||
tcase_add_test(TCase_pico_dns_client_query_suffix, tc_pico_dns_client_query_suffix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_query_suffix);
|
||||
tcase_add_test(TCase_pico_dns_client_query_domain, tc_pico_dns_client_query_domain);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_query_domain);
|
||||
tcase_add_test(TCase_pico_dns_client_answer_domain, tc_pico_dns_client_answer_domain);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_answer_domain);
|
||||
tcase_add_test(TCase_pico_dns_client_check_prefix, tc_pico_dns_client_check_prefix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_check_prefix);
|
||||
tcase_add_test(TCase_pico_dns_client_check_qsuffix, tc_pico_dns_client_check_qsuffix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_check_qsuffix);
|
||||
tcase_add_test(TCase_pico_dns_client_check_asuffix, tc_pico_dns_client_check_asuffix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_check_asuffix);
|
||||
tcase_add_test(TCase_pico_dns_client_seek_suffix, tc_pico_dns_client_seek_suffix);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_seek_suffix);
|
||||
tcase_add_test(TCase_pico_dns_client_send, tc_pico_dns_client_send);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_send);
|
||||
tcase_add_test(TCase_pico_dns_client_user_callback, tc_pico_dns_client_user_callback);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_user_callback);
|
||||
tcase_add_test(TCase_pico_dns_client_getaddr_init, tc_pico_dns_client_getaddr_init);
|
||||
suite_add_tcase(s, TCase_pico_dns_client_getaddr_init);
|
||||
tcase_add_test(TCase_pico_dns_ipv6_set_ptr, tc_pico_dns_ipv6_set_ptr);
|
||||
suite_add_tcase(s, TCase_pico_dns_ipv6_set_ptr);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
1446
kernel/picotcp/test/unit/modunit_pico_dns_common.c
Normal file
1446
kernel/picotcp/test/unit/modunit_pico_dns_common.c
Normal file
File diff suppressed because it is too large
Load Diff
403
kernel/picotcp/test/unit/modunit_pico_dns_sd.c
Normal file
403
kernel/picotcp/test/unit/modunit_pico_dns_sd.c
Normal file
@ -0,0 +1,403 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_addressing.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_dns_common.h"
|
||||
#include "pico_tree.h"
|
||||
#include "pico_dev_mock.c"
|
||||
#include "modules/pico_dns_sd.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void callback( pico_mdns_rtree *tree, char *str, void *arg);
|
||||
int dns_sd_init(void);
|
||||
char text[] = "textvers";
|
||||
char text2[] = "pass";
|
||||
char text3[] = "color";
|
||||
char value[] = "1";
|
||||
char value3[] = "";
|
||||
void callback( pico_mdns_rtree *tree,
|
||||
char *str,
|
||||
void *arg )
|
||||
{
|
||||
kv_vector vector = {
|
||||
0
|
||||
};
|
||||
|
||||
/* This doesn't even gets called, tests exit before possible callback */
|
||||
IGNORE_PARAMETER(str);
|
||||
IGNORE_PARAMETER(arg);
|
||||
IGNORE_PARAMETER(tree);
|
||||
fail_unless(pico_dns_sd_register_service("Hello World!",
|
||||
"_kerberos._udp",
|
||||
88, &vector, 120,
|
||||
callback, NULL) == 0,
|
||||
"dns_sd_register_service failed!\n");
|
||||
}
|
||||
|
||||
int dns_sd_init()
|
||||
{
|
||||
struct mock_device *mock = NULL;
|
||||
|
||||
struct pico_ip4 local = {
|
||||
.addr = long_be(0x0a280064)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
if (!mock)
|
||||
return -1;
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
/* Try to initialise the mDNS module right */
|
||||
return pico_dns_sd_init("host.local", local, callback, NULL);
|
||||
}
|
||||
|
||||
START_TEST(tc_dns_sd_kv_vector_strlen)
|
||||
{
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
fail_unless(pico_dns_sd_kv_vector_strlen(&pairs) == 23,
|
||||
"dns_sd_kv_vector_strlen returned wrong length!\n");
|
||||
|
||||
pico_dns_sd_kv_vector_erase(&pairs);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_srv_record_create)
|
||||
{
|
||||
struct pico_mdns_record *record = NULL;
|
||||
|
||||
uint8_t buf[19] = {
|
||||
0, 0, 0, 0, 0, 80,
|
||||
5, 'h', 'i', 't', 'e', 'x',
|
||||
5, 'l', 'o', 'c', 'a', 'l',
|
||||
0
|
||||
};
|
||||
|
||||
record = pico_dns_sd_srv_record_create("test.local", 0, 0, 80,
|
||||
"hitex.local", 10,
|
||||
PICO_MDNS_RECORD_UNIQUE);
|
||||
|
||||
fail_unless(strcmp(record->record->rname, "\4test\5local") == 0,
|
||||
"Name of SRV record not correct!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rtype) == 33,
|
||||
"Type of SRV record not correctly set!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rclass) == 0x8001,
|
||||
"Class of SRV record not correctly set!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rdlength) == 19,
|
||||
"rdlength of SRV record not correctly set!\n");
|
||||
fail_unless(long_be(record->record->rsuffix->rttl) == 10,
|
||||
"TTL of SRV record not correctly set!\n");
|
||||
fail_unless(memcmp(record->record->rdata, buf, 19) == 0,
|
||||
"Rdata of TXT record not correctly set!\n");
|
||||
pico_mdns_record_delete((void **)&record);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_txt_record_create)
|
||||
{
|
||||
struct pico_mdns_record *record = NULL;
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
|
||||
uint8_t buf[23] = {
|
||||
10, 't', 'e', 'x', 't', 'v', 'e', 'r', 's', '=', '1',
|
||||
4, 'p', 'a', 's', 's',
|
||||
6, 'c', 'o', 'l', 'o', 'r', '='
|
||||
};
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
record = pico_dns_sd_txt_record_create("test.local", pairs, 10,
|
||||
PICO_MDNS_RECORD_UNIQUE);
|
||||
|
||||
fail_unless(strcmp(record->record->rname, "\4test\5local") == 0,
|
||||
"Name of TXT record not correct!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rtype) == 16,
|
||||
"Type of TXT record not correctly set!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rclass) == 0x8001,
|
||||
"Class of TXT record not correctly set!\n");
|
||||
fail_unless(short_be(record->record->rsuffix->rdlength) == 23,
|
||||
"rdlength of TXT record not correctly set!\n");
|
||||
fail_unless(long_be(record->record->rsuffix->rttl) == 10,
|
||||
"TTL of TXT record not correctly set!\n");
|
||||
fail_unless(memcmp(record->record->rdata, buf, 23) == 0,
|
||||
"Rdata of TXT record not correctly set!\n");
|
||||
pico_mdns_record_delete((void **)&record);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_kv_create)
|
||||
{
|
||||
key_value_pair_t *pair = NULL;
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", "1");
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(strcmp(pair->value, "1") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
PICO_FREE(pair->key);
|
||||
PICO_FREE(pair->value);
|
||||
PICO_FREE(pair);
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", NULL);
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(pair->value == NULL,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
PICO_FREE(pair->key);
|
||||
PICO_FREE(pair);
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", "");
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(strcmp(pair->value, "") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
PICO_FREE(pair->key);
|
||||
PICO_FREE(pair->value);
|
||||
PICO_FREE(pair);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_kv_delete)
|
||||
{
|
||||
key_value_pair_t *pair = NULL;
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", "1");
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(strcmp(pair->value, "1") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
pico_dns_sd_kv_delete(&pair);
|
||||
fail_unless(pair == NULL,
|
||||
"dns_sd_kv_delete failed!\n");
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", NULL);
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(pair->value == NULL,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
pico_dns_sd_kv_delete(&pair);
|
||||
fail_unless(pair == NULL,
|
||||
"dns_sd_kv_delete failed!\n");
|
||||
|
||||
pair = pico_dns_sd_kv_create("textvers", "");
|
||||
fail_unless(strcmp(pair->key, "textvers") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
fail_unless(strcmp(pair->value, "") == 0,
|
||||
"dns_sd_kv_create failed!\n");
|
||||
pico_dns_sd_kv_delete(&pair);
|
||||
fail_unless(pair == NULL,
|
||||
"dns_sd_kv_delete failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_check_type_format)
|
||||
{
|
||||
fail_unless(pico_dns_sd_check_type_format("_http._tcp") == 0,
|
||||
"dns_sd_check_type_format failed with correct format!\n");
|
||||
fail_unless(pico_dns_sd_check_type_format("_printer._sub._http._tcp")
|
||||
== 0,
|
||||
"dns_sd_check_type_format failed with subtype!\n");
|
||||
|
||||
/* Test too long subtype */
|
||||
fail_unless(pico_dns_sd_check_type_format(
|
||||
"1234567891123456789212345678931234567894123456789512345678961234._sub._http._tcp"), "dns_sd_check_type_format failed with too big subtype!\n");
|
||||
|
||||
/* Test too long service type with subtype */
|
||||
fail_unless(pico_dns_sd_check_type_format(
|
||||
"printer._sub.0123456789112345678._tcp"),
|
||||
"dns_sd_check_type_format failed with too big sn w/ sub!\n");
|
||||
|
||||
/* Test too long service type with subtype */
|
||||
fail_unless(pico_dns_sd_check_type_format("0123456789112345678._tcp"),
|
||||
"dns_sd_check_type_format failed with too big sn!\n");
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_check_instance_name_format)
|
||||
{
|
||||
/* Test too long name */
|
||||
fail_unless(pico_dns_sd_check_instance_name_format(
|
||||
"1234567891123456789212345678931234567894123456789512345678961234"),
|
||||
"dns_sd_check_instance_name_format failed with too big name!\n");
|
||||
|
||||
fail_unless(pico_dns_sd_check_instance_name_format("Hello World!") == 0,
|
||||
"dns_sd_check_instance_name_format failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_create_service_url)
|
||||
{
|
||||
char *service_url = NULL;
|
||||
|
||||
service_url = pico_dns_sd_create_service_url("Hello World!", "_http._tcp");
|
||||
|
||||
fail_unless(strcmp(service_url, "Hello World!._http._tcp.local") == 0,
|
||||
"dns_sd_create_service_url failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_init)
|
||||
{
|
||||
pico_stack_init();
|
||||
fail_unless(dns_sd_init() == 0,
|
||||
"dns_sd_init failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_register_service)
|
||||
{
|
||||
pico_stack_init();
|
||||
dns_sd_init();
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_browse_service)
|
||||
{
|
||||
/* Not implemented in code */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_dns_sd_kv_vector_add)
|
||||
{
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
char *key = NULL;
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
key = pico_dns_sd_kv_vector_get(&pairs, 2)->key;
|
||||
fail_unless(strcmp("color", key) == 0,
|
||||
"dns_sd_kv_vector_add failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_kv_vector_get)
|
||||
{
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
char *key = NULL;
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
key = pico_dns_sd_kv_vector_get(&pairs, 2)->key;
|
||||
fail_unless(strcmp("color", key) == 0,
|
||||
"dns_sd_kv_vector_get failed!\n");
|
||||
|
||||
fail_unless(pico_dns_sd_kv_vector_get(&pairs, 3) == NULL,
|
||||
"dns_sd_kv_vector_get failed @ OOB!\n");
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dns_sd_kv_vector_erase)
|
||||
{
|
||||
kv_vector pairs = {
|
||||
0
|
||||
};
|
||||
|
||||
pico_dns_sd_kv_vector_add(&pairs, text, value);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text2, NULL);
|
||||
pico_dns_sd_kv_vector_add(&pairs, text3, value3);
|
||||
|
||||
pico_dns_sd_kv_vector_erase(&pairs);
|
||||
|
||||
fail_unless(pairs.pairs == NULL,
|
||||
"dns_sd_kv_vector_erase failed!\n");
|
||||
fail_unless(pairs.count == 0,
|
||||
"dns_sd_kv_vector_erase failed!\n");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
/* Key-Value pair vector plain creation function */
|
||||
TCase *TCase_dns_sd_kv_vector_strlen = tcase_create("Unit test for dns_sd_kv_vector_strlen");
|
||||
|
||||
/* DNS utility functions */
|
||||
TCase *TCase_dns_sd_srv_record_create = tcase_create("Unit test for dns_sd_srv_record_create");
|
||||
TCase *TCase_dns_sd_txt_record_create = tcase_create("Unit test for dns_sd_txt_record_create");
|
||||
|
||||
/* Key-Value pair creation */
|
||||
TCase *TCase_dns_sd_kv_create = tcase_create("Unit test for dns_sd_kv_create");
|
||||
TCase *TCase_dns_sd_kv_delete = tcase_create("Unit test for dns_sd_kv_delete");
|
||||
|
||||
/* Utility functions */
|
||||
TCase *TCase_dns_sd_check_type_format = tcase_create("Unit test for dns_sd_check_type_format");
|
||||
TCase *TCase_dns_sd_check_instance_name_format = tcase_create("Unit test for dns_sd_check_instance_name_format");
|
||||
TCase *TCase_dns_sd_create_service_url = tcase_create("Unit test for dns_sd_create_service_url");
|
||||
/* DNS SD API functions */
|
||||
TCase *TCase_dns_sd_init = tcase_create("Unit test for dns_sd_init");
|
||||
TCase *TCase_dns_sd_register_service = tcase_create("Unit test for dns_sd_register_service");
|
||||
TCase *TCase_dns_sd_browse_service = tcase_create("Unit test for dns_sd_browse_service");
|
||||
|
||||
/* Key-Value vector functions */
|
||||
TCase *TCase_dns_sd_kv_vector_add = tcase_create("Unit test for dns_sd_kv_vector_add");
|
||||
TCase *TCase_dns_sd_kv_vector_get = tcase_create("Unit test for dns_sd_kv_vector_get");
|
||||
TCase *TCase_dns_sd_kv_vector_erase = tcase_create("Unit test for dns_sd_kv_vector_erase");
|
||||
|
||||
/* Key-Value pair vector plain creation function */
|
||||
tcase_add_test(TCase_dns_sd_kv_vector_strlen, tc_dns_sd_kv_vector_strlen);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_vector_strlen);
|
||||
|
||||
/* DNS utility functions */
|
||||
tcase_add_test(TCase_dns_sd_srv_record_create, tc_dns_sd_srv_record_create);
|
||||
suite_add_tcase(s, TCase_dns_sd_srv_record_create);
|
||||
tcase_add_test(TCase_dns_sd_txt_record_create, tc_dns_sd_txt_record_create);
|
||||
suite_add_tcase(s, TCase_dns_sd_txt_record_create);
|
||||
|
||||
/* Key-Value pair creation */
|
||||
tcase_add_test(TCase_dns_sd_kv_create, tc_dns_sd_kv_create);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_create);
|
||||
tcase_add_test(TCase_dns_sd_kv_delete, tc_dns_sd_kv_delete);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_delete);
|
||||
|
||||
/* Utility functions */
|
||||
tcase_add_test(TCase_dns_sd_check_type_format, tc_dns_sd_check_type_format);
|
||||
suite_add_tcase(s, TCase_dns_sd_check_type_format);
|
||||
tcase_add_test(TCase_dns_sd_check_instance_name_format, tc_dns_sd_check_instance_name_format);
|
||||
suite_add_tcase(s, TCase_dns_sd_check_instance_name_format);
|
||||
tcase_add_test(TCase_dns_sd_create_service_url, tc_dns_sd_create_service_url);
|
||||
suite_add_tcase(s, TCase_dns_sd_create_service_url);
|
||||
|
||||
/* DNS SD API functions */
|
||||
tcase_add_test(TCase_dns_sd_init, tc_dns_sd_init);
|
||||
suite_add_tcase(s, TCase_dns_sd_init);
|
||||
tcase_add_test(TCase_dns_sd_register_service, tc_dns_sd_register_service);
|
||||
suite_add_tcase(s, TCase_dns_sd_register_service);
|
||||
tcase_add_test(TCase_dns_sd_browse_service, tc_dns_sd_browse_service);
|
||||
suite_add_tcase(s, TCase_dns_sd_browse_service);
|
||||
|
||||
/* Key-Value vector functions */
|
||||
tcase_add_test(TCase_dns_sd_kv_vector_add, tc_dns_sd_kv_vector_add);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_vector_add);
|
||||
tcase_add_test(TCase_dns_sd_kv_vector_get, tc_dns_sd_kv_vector_get);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_vector_get);
|
||||
tcase_add_test(TCase_dns_sd_kv_vector_erase, tc_dns_sd_kv_vector_erase);
|
||||
suite_add_tcase(s, TCase_dns_sd_kv_vector_erase);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
315
kernel/picotcp/test/unit/modunit_pico_ethernet.c
Normal file
315
kernel/picotcp/test/unit/modunit_pico_ethernet.c
Normal file
@ -0,0 +1,315 @@
|
||||
//#include "pico_config.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_icmp4.h"
|
||||
#include "pico_icmp6.h"
|
||||
#include "pico_arp.h"
|
||||
#include "pico_ethernet.h"
|
||||
#include "modules/pico_ethernet.c"
|
||||
#include "check.h"
|
||||
|
||||
#define STARTING() \
|
||||
printf("*********************** STARTING %s ***\n", __func__); \
|
||||
fflush(stdout)
|
||||
#define TRYING(s, ...) \
|
||||
printf("Trying %s: " s, __func__, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
#define CHECKING(i) \
|
||||
printf("Checking the results of test %2d in %s...", (i)++, \
|
||||
__func__); \
|
||||
fflush(stdout)
|
||||
#define SUCCESS() \
|
||||
printf(" SUCCES\n"); \
|
||||
fflush(stdout)
|
||||
#define BREAKING(s, ...) \
|
||||
printf("Breaking %s: " s, __func__, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
#define ENDING(i) \
|
||||
printf("*********************** ENDING %s *** N TESTS: %d\n", \
|
||||
__func__, ((i)-1)); \
|
||||
fflush(stdout)
|
||||
#define DBG(s, ...) \
|
||||
printf(s, ##__VA_ARGS__); \
|
||||
fflush(stdout)
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_destination_is_bcast)
|
||||
{
|
||||
/* test this: static int destination_is_bcast(struct pico_frame *f) */
|
||||
struct pico_ip6 addr = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *h = (struct pico_ipv6_hdr *)f->buffer;
|
||||
struct pico_ipv4_hdr *h4 = NULL;
|
||||
|
||||
/* Test parameters */
|
||||
int ret = 0, count = 0;
|
||||
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x60; /* Ipv6 */
|
||||
|
||||
STARTING();
|
||||
|
||||
TRYING("With wrong protocol -> IPv6\n");
|
||||
memcpy(h->dst.addr, addr.addr, PICO_SIZE_IP6);
|
||||
ret = destination_is_bcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since IPv6 frame\n");
|
||||
SUCCESS();
|
||||
pico_frame_discard(f);
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
|
||||
h4 = (struct pico_ipv4_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t *)h4;
|
||||
f->buffer[0] = 0x40; /* IPv4 */
|
||||
TRYING("With right protocol -> IPv4\n");
|
||||
ret = destination_is_bcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since not a mcast address\n");
|
||||
SUCCESS();
|
||||
|
||||
BREAKING();
|
||||
ret = destination_is_bcast(NULL);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since NULL-pointer\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_destination_is_mcast)
|
||||
{
|
||||
struct pico_ip6 addr = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
|
||||
struct pico_ip6 mcast = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
|
||||
struct pico_ip4 addr4 = {0};
|
||||
struct pico_ip4 mcast4 = {0};
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *h = (struct pico_ipv6_hdr *)f->buffer;
|
||||
struct pico_ipv4_hdr *h4 = (struct pico_ipv4_hdr *)f->buffer;
|
||||
/* Test parameters */
|
||||
int ret = 0, count = 0;
|
||||
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x60; /* Ipv6 */
|
||||
|
||||
STARTING();
|
||||
|
||||
pico_string_to_ipv4("232.1.1.0", &(mcast4.addr)); /* 0 */
|
||||
pico_string_to_ipv4("10.20.0.1", &(addr4.addr));
|
||||
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e801:100", (mcast.addr)); /* 0 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:100", (addr.addr)); /* 0 */
|
||||
|
||||
TRYING("With IPv6 unicast addr\n");
|
||||
memcpy(h->dst.addr, addr.addr, PICO_SIZE_IP6);
|
||||
ret = destination_is_mcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since not an IPv6 multicast\n");
|
||||
SUCCESS();
|
||||
|
||||
TRYING("With IPv6 multicast addr\n");
|
||||
memcpy(h->dst.addr, mcast.addr, PICO_SIZE_IP6);
|
||||
ret = destination_is_mcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(1 == ret, "Should've returned 1 since an IPv6 multicast\n");
|
||||
SUCCESS();
|
||||
|
||||
pico_frame_discard(f);
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
|
||||
h4 = (struct pico_ipv4_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t *)h4;
|
||||
f->buffer[0] = 0x40; /* IPv4 */
|
||||
|
||||
TRYING("With IPv4 unicast addr\n");
|
||||
h4->dst = addr4;
|
||||
ret = destination_is_bcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since not an IPv4 mcast address\n");
|
||||
SUCCESS();
|
||||
|
||||
TRYING("With IPv4 multicast addr\n");
|
||||
h4->dst = mcast4;
|
||||
ret = destination_is_mcast(f);
|
||||
CHECKING(count);
|
||||
fail_unless(1 == ret, "Should've returned 1 since an IPv4 multicast\n");
|
||||
SUCCESS();
|
||||
|
||||
BREAKING();
|
||||
ret = destination_is_bcast(NULL);
|
||||
CHECKING(count);
|
||||
fail_unless(0 == ret, "Should've returned 0 since NULL-pointer\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ipv4_ethernet_receive)
|
||||
{
|
||||
/* test this: static int32_t pico_ipv4_ethernet_receive(struct pico_frame *f) */
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_ipv4_hdr *h4 = NULL;
|
||||
int ret = 0, count = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
|
||||
h4 = (struct pico_ipv4_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t *)h4;
|
||||
f->buffer[0] = 0x40; /* IPv4 */
|
||||
|
||||
TRYING("With IPv4 frame\n");
|
||||
ret = pico_ipv4_ethernet_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret > 0, "Was correct frame should've returned size of frame\n");
|
||||
SUCCESS();
|
||||
CHECKING(count);
|
||||
fail_unless(pico_proto_ipv4.q_in->size == f->buffer_len, "Frame not enqueued\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ipv6_ethernet_receive)
|
||||
{
|
||||
/* test this: static int32_t pico_ipv6_ethernet_receive(struct pico_frame *f) */
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_ipv6_hdr *h = NULL;
|
||||
|
||||
int ret = 0, count = 0;
|
||||
|
||||
STARTING();
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
h = (struct pico_ipv6_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x40; /* Ipv6 */
|
||||
|
||||
TRYING("With wrong network type\n");
|
||||
ret = pico_ipv6_ethernet_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == -1, "Wrong type should've returned an error\n");
|
||||
SUCCESS();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
h = (struct pico_ipv6_hdr *)f->buffer;
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x60;
|
||||
TRYING("With correct network type\n");
|
||||
ret = pico_ipv6_ethernet_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == (int32_t)f->buffer_len, "Was correct frame, should've returned success\n");
|
||||
SUCCESS();
|
||||
CHECKING(count);
|
||||
fail_unless(pico_proto_ipv6.q_in->size == f->buffer_len, "Frame not enqueued\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_eth_receive)
|
||||
{
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_eth_hdr *eth = NULL;
|
||||
int ret = 0, count = 0;
|
||||
|
||||
STARTING();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr) + sizeof(struct pico_eth_hdr));
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
|
||||
eth = (struct pico_eth_hdr *)f->datalink_hdr;
|
||||
((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */
|
||||
|
||||
/* ETHERNET PROTOCOL : IPV6 */
|
||||
eth->proto = PICO_IDETH_IPV6;
|
||||
|
||||
TRYING("With wrong network type\n");
|
||||
ret = pico_eth_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == -1, "Wrong type should've returned an error\n");
|
||||
SUCCESS();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr) + sizeof(struct pico_eth_hdr));
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
|
||||
eth = (struct pico_eth_hdr *)f->datalink_hdr;
|
||||
((uint8_t *)(f->net_hdr))[0] = 0x60; /* Ipv6 */
|
||||
|
||||
/* ETHERNET PROTOCOL : IPV6 */
|
||||
eth->proto = PICO_IDETH_IPV6;
|
||||
TRYING("With correct network type\n");
|
||||
ret = pico_eth_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == (int32_t)f->buffer_len, "Was correct frame, should've returned success\n");
|
||||
SUCCESS();
|
||||
CHECKING(count);
|
||||
fail_unless(pico_proto_ipv6.q_in->size == f->buffer_len, "Frame not enqueued\n");
|
||||
SUCCESS();
|
||||
|
||||
pico_frame_discard(f);
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr) + sizeof(struct pico_eth_hdr));
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
|
||||
eth = (struct pico_eth_hdr *)f->datalink_hdr;
|
||||
((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */
|
||||
|
||||
TRYING("With wrong frame type\n");
|
||||
ret = pico_eth_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret == -1, "should've returned -1 wrong ethernet protocol\n");
|
||||
SUCCESS();
|
||||
|
||||
f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr) + sizeof(struct pico_eth_hdr));
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
|
||||
eth = (struct pico_eth_hdr *)f->datalink_hdr;
|
||||
((uint8_t *)(f->net_hdr))[0] = 0x40; /* Ipv4 */
|
||||
eth->proto = PICO_IDETH_IPV4;
|
||||
|
||||
TRYING("With IPv4 frame\n");
|
||||
ret = pico_eth_receive(f);
|
||||
CHECKING(count);
|
||||
fail_unless(ret > 0, "Was correct frame should've returned size of frame\n");
|
||||
SUCCESS();
|
||||
CHECKING(count);
|
||||
fail_unless(pico_proto_ipv4.q_in->size == f->buffer_len, "Frame not enqueued\n");
|
||||
SUCCESS();
|
||||
|
||||
ENDING(count);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_destination_is_bcast = tcase_create("Unit test for destination_is_bcast");
|
||||
TCase *TCase_destination_is_mcast = tcase_create("Unit test for destination_is_mcast");
|
||||
TCase *TCase_pico_ipv4_ethernet_receive = tcase_create("Unit test for pico_ipv4_ethernet_receive");
|
||||
TCase *TCase_pico_ipv6_ethernet_receive = tcase_create("Unit test for pico_ipv6_ethernet_receive");
|
||||
TCase *TCase_pico_eth_receive = tcase_create("Unit test for pico_eth_receive");
|
||||
|
||||
tcase_add_test(TCase_destination_is_bcast, tc_destination_is_bcast);
|
||||
suite_add_tcase(s, TCase_destination_is_bcast);
|
||||
tcase_add_test(TCase_destination_is_mcast, tc_destination_is_mcast);
|
||||
suite_add_tcase(s, TCase_destination_is_mcast);
|
||||
tcase_add_test(TCase_pico_ipv4_ethernet_receive, tc_pico_ipv4_ethernet_receive);
|
||||
suite_add_tcase(s, TCase_pico_ipv4_ethernet_receive);
|
||||
tcase_add_test(TCase_pico_ipv6_ethernet_receive, tc_pico_ipv6_ethernet_receive);
|
||||
suite_add_tcase(s, TCase_pico_ipv6_ethernet_receive);
|
||||
tcase_add_test(TCase_pico_eth_receive, tc_pico_eth_receive);
|
||||
suite_add_tcase(s, TCase_pico_eth_receive);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
1234
kernel/picotcp/test/unit/modunit_pico_fragments.c
Normal file
1234
kernel/picotcp/test/unit/modunit_pico_fragments.c
Normal file
File diff suppressed because it is too large
Load Diff
274
kernel/picotcp/test/unit/modunit_pico_frame.c
Normal file
274
kernel/picotcp/test/unit/modunit_pico_frame.c
Normal file
@ -0,0 +1,274 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_protocol.h"
|
||||
#include "pico_frame.h"
|
||||
#include "stack/pico_frame.c"
|
||||
#include "check.h"
|
||||
|
||||
volatile pico_err_t pico_err;
|
||||
|
||||
#define FRAME_SIZE 1000
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_pico_frame_alloc_discard)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(FRAME_SIZE);
|
||||
|
||||
/* Test consistency */
|
||||
fail_if(!f);
|
||||
fail_if(!f->buffer);
|
||||
fail_if(!f->usage_count);
|
||||
fail_if(*f->usage_count != 1);
|
||||
fail_if(f->start != f->buffer);
|
||||
fail_if(f->len != f->buffer_len);
|
||||
fail_if(f->len != FRAME_SIZE);
|
||||
pico_frame_discard(f);
|
||||
|
||||
/* Test empty discard */
|
||||
pico_frame_discard(NULL);
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in frame_alloc (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
f = pico_frame_alloc(FRAME_SIZE);
|
||||
fail_if(f);
|
||||
|
||||
printf("Testing with faulty memory in frame_alloc (2)\n");
|
||||
pico_set_mm_failure(2);
|
||||
f = pico_frame_alloc(FRAME_SIZE);
|
||||
fail_if(f);
|
||||
|
||||
printf("Testing with faulty memory in frame_do_alloc, with external buffer, failing to allocate usage_count \n");
|
||||
pico_set_mm_failure(2);
|
||||
f = pico_frame_do_alloc(FRAME_SIZE, 1, 1);
|
||||
fail_if(f);
|
||||
#endif
|
||||
printf("Testing frame_do_alloc, with invalid flags combination\n");
|
||||
f = pico_frame_do_alloc(FRAME_SIZE, 0, 1);
|
||||
fail_if(f);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_frame_grow_head)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(3);
|
||||
struct pico_frame *f2 = pico_frame_alloc(0);
|
||||
int ret = 0;
|
||||
uint8_t buf[6] = { 0, 0, 0, 'a', 'b', 'c'};
|
||||
|
||||
/* I don't care about usage_count, it's tested 'pico_frame_grow' */
|
||||
fail_if(pico_frame_grow_head(f, 2) == 0);
|
||||
|
||||
/* Check for dereferencing OOB */
|
||||
fail_if(pico_frame_grow_head(f2, 2) == -1);
|
||||
f2->net_hdr[0] = 1;
|
||||
|
||||
f->net_hdr = f->buffer;
|
||||
f->net_len = 3;
|
||||
f->net_hdr[0] = 'a';
|
||||
f->net_hdr[1] = 'b';
|
||||
f->net_hdr[2] = 'c';
|
||||
|
||||
/* Try to grow head */
|
||||
ret = pico_frame_grow_head(f, 6);
|
||||
fail_if(ret != 0);
|
||||
fail_unless(0 == memcmp(f->buffer, buf, f->buffer_len));
|
||||
fail_unless(3 == f->net_hdr - f->buffer);
|
||||
|
||||
f->datalink_hdr = f->net_hdr - 3;
|
||||
f->datalink_hdr[0] = 1;
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_frame_grow)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(3);
|
||||
struct pico_frame *f2 = pico_frame_alloc(0);
|
||||
fail_if(f->buffer_len != 3);
|
||||
/* Ensure that the usage_count starts at byte 4, for good alignment */
|
||||
fail_if(((void*)f->usage_count - (void *)f->buffer) != 4);
|
||||
|
||||
((uint8_t *)f->buffer)[0] = 'a';
|
||||
((uint8_t *)f->buffer)[1] = 'b';
|
||||
((uint8_t *)f->buffer)[2] = 'c';
|
||||
*f->usage_count = 12;
|
||||
|
||||
|
||||
/* First, the failing cases. */
|
||||
fail_if(pico_frame_grow(NULL, 30) == 0);
|
||||
fail_if(pico_frame_grow(f, 2) == 0);
|
||||
f->flags = 0;
|
||||
|
||||
/* Check for dereferencing OOB */
|
||||
fail_if(pico_frame_grow(f2, 3) != 0);
|
||||
f2->net_hdr[0] = 1;
|
||||
f2->net_hdr[1] = 2;
|
||||
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_frame_grow(f, 21) == 0);
|
||||
|
||||
/* Now, the good one. */
|
||||
fail_if(pico_frame_grow(f, 21) != 0);
|
||||
fail_if(f->buffer_len != 21);
|
||||
fail_if(((void *)f->usage_count - (void *)f->buffer) != 24);
|
||||
|
||||
|
||||
fail_if(((uint8_t *)f->buffer)[0] != 'a');
|
||||
fail_if(((uint8_t *)f->buffer)[1] != 'b');
|
||||
fail_if(((uint8_t *)f->buffer)[2] != 'c');
|
||||
fail_if(*f->usage_count != 12);
|
||||
|
||||
*f->usage_count = 1;
|
||||
pico_frame_discard(f);
|
||||
|
||||
f = pico_frame_alloc_skeleton(10, 1);
|
||||
fail_if(!f);
|
||||
fail_if(f->buffer);
|
||||
fail_if(!f->flags);
|
||||
f->buffer = PICO_ZALLOC(10);
|
||||
|
||||
fail_if(pico_frame_grow(f, 22) != 0);
|
||||
fail_if (f->flags);
|
||||
pico_frame_discard(f);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_frame_copy)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(FRAME_SIZE);
|
||||
struct pico_frame *c1, *c2, *c3;
|
||||
(void)c3;
|
||||
fail_if(!f);
|
||||
fail_if(!f->buffer);
|
||||
fail_if(*f->usage_count != 1);
|
||||
|
||||
/* First copy */
|
||||
c1 = pico_frame_copy(f);
|
||||
fail_if(!c1);
|
||||
fail_if(!c1->buffer);
|
||||
fail_if(!c1->usage_count);
|
||||
|
||||
fail_if (c1->buffer != f->buffer);
|
||||
fail_if(c1->usage_count != f->usage_count);
|
||||
fail_if(*c1->usage_count != 2);
|
||||
fail_if(*f->usage_count != 2);
|
||||
fail_if(c1->start != c1->buffer);
|
||||
fail_if(c1->len != c1->buffer_len);
|
||||
fail_if(c1->len != FRAME_SIZE);
|
||||
|
||||
/* Second copy */
|
||||
c2 = pico_frame_copy(f);
|
||||
fail_if (c2->buffer != f->buffer);
|
||||
fail_if(c2->usage_count != f->usage_count);
|
||||
fail_if(*c2->usage_count != 3);
|
||||
fail_if(*f->usage_count != 3);
|
||||
fail_if(c2->start != c2->buffer);
|
||||
fail_if(c2->len != c2->buffer_len);
|
||||
fail_if(c2->len != FRAME_SIZE);
|
||||
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in frame_copy (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
c3 = pico_frame_copy(f);
|
||||
fail_if(c3);
|
||||
fail_if(!f);
|
||||
#endif
|
||||
|
||||
/* Discard 1 */
|
||||
pico_frame_discard(c1);
|
||||
fail_if(*f->usage_count != 2);
|
||||
|
||||
/* Discard 2 */
|
||||
pico_frame_discard(c2);
|
||||
fail_if(*f->usage_count != 1);
|
||||
|
||||
pico_frame_discard(f);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_frame_deepcopy)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(FRAME_SIZE);
|
||||
struct pico_frame *dc = pico_frame_deepcopy(f);
|
||||
fail_if(*f->usage_count != 1);
|
||||
fail_if(*dc->usage_count != 1);
|
||||
fail_if(dc->buffer == f->buffer);
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in frame_deepcopy (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
dc = pico_frame_deepcopy(f);
|
||||
fail_if(dc);
|
||||
fail_if(!f);
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_is_digit)
|
||||
{
|
||||
fail_if(pico_is_digit('a'));
|
||||
fail_if(pico_is_digit('Z'));
|
||||
fail_if(pico_is_digit('\0'));
|
||||
fail_if(pico_is_digit('\n'));
|
||||
fail_if(pico_is_digit('0' - 1));
|
||||
fail_if(pico_is_digit('9' + 1));
|
||||
fail_unless(pico_is_digit('0'));
|
||||
fail_unless(pico_is_digit('9'));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(tc_pico_is_hex)
|
||||
{
|
||||
fail_if(pico_is_hex('g'));
|
||||
fail_if(pico_is_hex('Z'));
|
||||
fail_if(pico_is_hex('\0'));
|
||||
fail_if(pico_is_hex('\n'));
|
||||
fail_if(pico_is_hex('0' - 1));
|
||||
fail_if(pico_is_hex('f' + 1));
|
||||
fail_if(pico_is_hex('F' + 1));
|
||||
fail_unless(pico_is_hex('0'));
|
||||
fail_unless(pico_is_hex('f'));
|
||||
fail_unless(pico_is_hex('A'));
|
||||
fail_unless(pico_is_hex('F'));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("pico_frame.c");
|
||||
TCase *TCase_pico_frame_alloc_discard = tcase_create("Unit test for pico_frame_alloc_discard");
|
||||
TCase *TCase_pico_frame_copy = tcase_create("Unit test for pico_frame_copy");
|
||||
TCase *TCase_pico_frame_grow = tcase_create("Unit test for pico_frame_grow");
|
||||
TCase *TCase_pico_frame_grow_head = tcase_create("Unit test for pico_frame_grow_head");
|
||||
TCase *TCase_pico_frame_deepcopy = tcase_create("Unit test for pico_frame_deepcopy");
|
||||
TCase *TCase_pico_is_digit = tcase_create("Unit test for pico_is_digit");
|
||||
TCase *TCase_pico_is_hex = tcase_create("Unit test for pico_is_hex");
|
||||
tcase_add_test(TCase_pico_frame_alloc_discard, tc_pico_frame_alloc_discard);
|
||||
tcase_add_test(TCase_pico_frame_copy, tc_pico_frame_copy);
|
||||
tcase_add_test(TCase_pico_frame_grow, tc_pico_frame_grow);
|
||||
tcase_add_test(TCase_pico_frame_grow_head, tc_pico_frame_grow_head);
|
||||
tcase_add_test(TCase_pico_frame_deepcopy, tc_pico_frame_deepcopy);
|
||||
tcase_add_test(TCase_pico_is_digit, tc_pico_is_digit);
|
||||
tcase_add_test(TCase_pico_is_hex, tc_pico_is_hex);
|
||||
suite_add_tcase(s, TCase_pico_frame_alloc_discard);
|
||||
suite_add_tcase(s, TCase_pico_frame_copy);
|
||||
suite_add_tcase(s, TCase_pico_frame_grow);
|
||||
suite_add_tcase(s, TCase_pico_frame_grow_head);
|
||||
suite_add_tcase(s, TCase_pico_frame_deepcopy);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
192
kernel/picotcp/test/unit/modunit_pico_hotplug_detection.c
Normal file
192
kernel/picotcp/test/unit/modunit_pico_hotplug_detection.c
Normal file
@ -0,0 +1,192 @@
|
||||
#include "pico_hotplug_detection.h"
|
||||
#include "pico_tree.h"
|
||||
#include "pico_device.h"
|
||||
#include "modules/pico_hotplug_detection.c"
|
||||
#include "check.h"
|
||||
#include "pico_dev_null.c"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void cb_one(struct pico_device *dev, int event);
|
||||
void cb_two(struct pico_device *dev, int event);
|
||||
int link_state_a(struct pico_device *self);
|
||||
int link_state_b(struct pico_device *self);
|
||||
|
||||
/* stubs for timer */
|
||||
static int8_t timer_active = 0;
|
||||
void (*timer_cb_function)(pico_time, void *);
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(expire);
|
||||
IGNORE_PARAMETER(arg);
|
||||
|
||||
timer_active++;
|
||||
timer_cb_function = timer;
|
||||
|
||||
return 123;
|
||||
}
|
||||
|
||||
void pico_timer_cancel(uint32_t id)
|
||||
{
|
||||
timer_active--;
|
||||
fail_if(id != 123);
|
||||
}
|
||||
|
||||
/* callbacks for testing */
|
||||
uint32_t cb_one_cntr = 0;
|
||||
int cb_one_last_event = 0;
|
||||
void cb_one(struct pico_device *dev, int event)
|
||||
{
|
||||
IGNORE_PARAMETER(dev);
|
||||
|
||||
cb_one_cntr++;
|
||||
cb_one_last_event = event;
|
||||
}
|
||||
uint32_t cb_two_cntr = 0;
|
||||
int cb_two_last_event = 0;
|
||||
void cb_two(struct pico_device *dev, int event)
|
||||
{
|
||||
IGNORE_PARAMETER(dev);
|
||||
|
||||
cb_two_cntr++;
|
||||
cb_two_last_event = event;
|
||||
}
|
||||
|
||||
/* link state functions for the testing devices */
|
||||
int state_a = 0;
|
||||
int link_state_a(struct pico_device *self)
|
||||
{
|
||||
IGNORE_PARAMETER(self);
|
||||
return state_a;
|
||||
}
|
||||
|
||||
int state_b = 0;
|
||||
int link_state_b(struct pico_device *self)
|
||||
{
|
||||
IGNORE_PARAMETER(self);
|
||||
return state_b;
|
||||
}
|
||||
|
||||
|
||||
START_TEST(tc_pico_hotplug_reg_dereg)
|
||||
{
|
||||
/* create some devices */
|
||||
struct pico_device *dev_a, *dev_b;
|
||||
dev_a = pico_null_create("dummy1");
|
||||
dev_b = pico_null_create("dummy2");
|
||||
|
||||
dev_a->link_state = &link_state_a;
|
||||
dev_b->link_state = &link_state_b;
|
||||
|
||||
/* add some function pointers to be called */
|
||||
pico_hotplug_register(dev_a, &cb_one);
|
||||
fail_unless(timer_active == 1);
|
||||
pico_hotplug_register(dev_a, &cb_two);
|
||||
pico_hotplug_register(dev_b, &cb_two);
|
||||
fail_unless(timer_active == 1);
|
||||
|
||||
/* remove function pointers */
|
||||
pico_hotplug_deregister(dev_a, &cb_one);
|
||||
pico_hotplug_deregister(dev_a, &cb_two);
|
||||
pico_hotplug_deregister(dev_b, &cb_two);
|
||||
|
||||
/* check that our tree is empty at the end */
|
||||
fail_unless(pico_tree_empty(&Hotplug_device_tree));
|
||||
|
||||
/* register functions multiple times */
|
||||
pico_hotplug_register(dev_a, &cb_one);
|
||||
pico_hotplug_register(dev_a, &cb_one);
|
||||
pico_hotplug_register(dev_a, &cb_two);
|
||||
pico_hotplug_register(dev_a, &cb_two);
|
||||
pico_hotplug_register(dev_b, &cb_two);
|
||||
pico_hotplug_register(dev_b, &cb_two);
|
||||
|
||||
/* remove function pointers once */
|
||||
pico_hotplug_deregister(dev_a, &cb_one);
|
||||
pico_hotplug_deregister(dev_a, &cb_two);
|
||||
fail_unless(timer_active == 1);
|
||||
pico_hotplug_deregister(dev_b, &cb_two);
|
||||
fail_unless(timer_active == 0);
|
||||
|
||||
/* check that our tree is empty at the end */
|
||||
fail_unless(pico_tree_empty(&Hotplug_device_tree));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_hotplug_callbacks)
|
||||
{
|
||||
/* create some devices */
|
||||
struct pico_device *dev_a, *dev_b;
|
||||
|
||||
dev_a = pico_null_create("dummy1");
|
||||
dev_b = pico_null_create("dummy2");
|
||||
|
||||
dev_a->link_state = &link_state_a;
|
||||
dev_b->link_state = &link_state_b;
|
||||
|
||||
/* add some function pointers to be called */
|
||||
pico_hotplug_register(dev_a, &cb_one);
|
||||
pico_hotplug_register(dev_a, &cb_two);
|
||||
pico_hotplug_register(dev_b, &cb_two);
|
||||
|
||||
fail_unless(timer_active == 1);
|
||||
|
||||
timer_active = 0;
|
||||
timer_cb_function(0, NULL);
|
||||
fail_unless(timer_active == 1);
|
||||
fail_unless(cb_one_cntr == 1);
|
||||
fail_unless(cb_two_cntr == 2);
|
||||
|
||||
state_a = 1;
|
||||
timer_active = 0;
|
||||
timer_cb_function(0, NULL);
|
||||
fail_unless(timer_active == 1);
|
||||
fail_unless(cb_one_cntr == 2);
|
||||
fail_unless(cb_one_last_event == PICO_HOTPLUG_EVENT_UP );
|
||||
fail_unless(cb_two_cntr == 3);
|
||||
fail_unless(cb_two_last_event == PICO_HOTPLUG_EVENT_UP );
|
||||
|
||||
state_b = 1;
|
||||
timer_active = 0;
|
||||
timer_cb_function(0, NULL);
|
||||
fail_unless(timer_active == 1);
|
||||
fail_unless(cb_one_cntr == 2);
|
||||
fail_unless(cb_one_last_event == PICO_HOTPLUG_EVENT_UP );
|
||||
fail_unless(cb_two_cntr == 4);
|
||||
fail_unless(cb_two_last_event == PICO_HOTPLUG_EVENT_UP );
|
||||
|
||||
state_a = 0;
|
||||
state_b = 0;
|
||||
timer_active = 0;
|
||||
timer_cb_function(0, NULL);
|
||||
fail_unless(timer_active == 1);
|
||||
fail_unless(cb_one_cntr == 3);
|
||||
fail_unless(cb_one_last_event == PICO_HOTPLUG_EVENT_DOWN );
|
||||
fail_unless(cb_two_cntr == 6);
|
||||
fail_unless(cb_two_last_event == PICO_HOTPLUG_EVENT_DOWN );
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_hotplug_reg_dereg = tcase_create("Unit test for pico_hotplug_reg_dereg");
|
||||
TCase *TCase_pico_hotplug_callbacks = tcase_create("Unit test for pico_hotplug_callbacks");
|
||||
|
||||
tcase_add_test(TCase_pico_hotplug_reg_dereg, tc_pico_hotplug_reg_dereg);
|
||||
suite_add_tcase(s, TCase_pico_hotplug_reg_dereg);
|
||||
tcase_add_test(TCase_pico_hotplug_callbacks, tc_pico_hotplug_callbacks);
|
||||
suite_add_tcase(s, TCase_pico_hotplug_callbacks);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
359
kernel/picotcp/test/unit/modunit_pico_igmp.c
Normal file
359
kernel/picotcp/test/unit/modunit_pico_igmp.c
Normal file
@ -0,0 +1,359 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_queue.h"
|
||||
#include "pico_tree.h"
|
||||
#include "modules/pico_igmp.c"
|
||||
#include "check.h"
|
||||
#include "pico_dev_null.c"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void mock_callback(struct igmp_timer *t);
|
||||
|
||||
static uint32_t timers_added = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(expire);
|
||||
IGNORE_PARAMETER(timer);
|
||||
IGNORE_PARAMETER(arg);
|
||||
return ++timers_added;
|
||||
}
|
||||
|
||||
void mock_callback(struct igmp_timer *t)
|
||||
{
|
||||
IGNORE_PARAMETER(t);
|
||||
}
|
||||
static int mcast_filter_cmp(void *ka, void *kb)
|
||||
{
|
||||
union pico_address *a = ka, *b = kb;
|
||||
if (a->ip4.addr < b->ip4.addr)
|
||||
return -1;
|
||||
|
||||
if (a->ip4.addr > b->ip4.addr)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int mcast_sources_cmp(void *ka, void *kb)
|
||||
{
|
||||
union pico_address *a = ka, *b = kb;
|
||||
if (a->ip4.addr < b->ip4.addr)
|
||||
return -1;
|
||||
|
||||
if (a->ip4.addr > b->ip4.addr)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static PICO_TREE_DECLARE(_MCASTFilter, mcast_filter_cmp);
|
||||
START_TEST(tc_pico_igmp_report_expired)
|
||||
{
|
||||
struct igmp_timer *t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
struct pico_ip4 zero = {0};
|
||||
t->mcast_link = zero;
|
||||
t->mcast_group = zero;
|
||||
/* void function, just check for side effects */
|
||||
pico_igmp_report_expired(t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_igmpt_type_compare)
|
||||
{
|
||||
struct igmp_timer a;
|
||||
struct igmp_timer b;
|
||||
a.type = 1;
|
||||
b.type = 2;
|
||||
fail_if(igmpt_type_compare(&a, &b) != -1);
|
||||
fail_if(igmpt_type_compare(&b, &a) != 1);
|
||||
fail_if(igmp_timer_cmp(&b, &a) != 1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_state_change)
|
||||
{
|
||||
struct pico_ip4 mcast_link, mcast_group;
|
||||
pico_string_to_ipv4("192.168.1.1", &mcast_link.addr);
|
||||
pico_string_to_ipv4("224.7.7.7", &mcast_group.addr);
|
||||
fail_if(pico_igmp_state_change(&mcast_link, &mcast_group, 0, NULL, 99) != -1);
|
||||
fail_if(pico_igmp_state_change(&mcast_link, &mcast_group, 0, NULL, PICO_IGMP_STATE_CREATE) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_timer_expired)
|
||||
{
|
||||
struct igmp_timer *t, *s;
|
||||
t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
t->stopped = IGMP_TIMER_STOPPED;
|
||||
t->type = 0;
|
||||
pico_string_to_ipv4("192.168.1.1", &t->mcast_link.addr);
|
||||
pico_string_to_ipv4("244.7.7.7", &t->mcast_group.addr);
|
||||
/* void function, just check for side effects */
|
||||
pico_igmp_timer_expired(0, (void *)t);
|
||||
pico_tree_insert(&IGMPTimers, t);
|
||||
s = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
memcpy(s,t,sizeof(struct igmp_timer)); // t will be freed next test
|
||||
pico_igmp_timer_expired(0, (void *)t); /* t is freed here */
|
||||
s->stopped++;
|
||||
s->start = PICO_TIME_MS()*2;
|
||||
s->type++;
|
||||
pico_tree_insert(&IGMPTimers, s);
|
||||
t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
memcpy(t,s,sizeof(struct igmp_timer)); // s will be freed next test
|
||||
pico_igmp_timer_expired(0, (void *)s); /* s is freed here */
|
||||
t->callback = mock_callback;
|
||||
pico_igmp_timer_expired(0, (void *)t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_v2querier_expired)
|
||||
{
|
||||
struct igmp_timer *t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
struct pico_ip4 addr = {0};
|
||||
struct pico_device *dev = pico_null_create("dummy2");
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_frame));
|
||||
t->f = f;
|
||||
pico_string_to_ipv4("192.168.1.1", &(addr.addr));
|
||||
/* void function, just check for side effects */
|
||||
/* No link */
|
||||
pico_igmp_v2querier_expired(t);
|
||||
f->dev = dev;
|
||||
pico_ipv4_link_add(dev, addr, addr);
|
||||
pico_igmp_v2querier_expired(t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_delete_parameter)
|
||||
{
|
||||
struct mcast_parameters p;
|
||||
fail_if(pico_igmp_delete_parameter(&p) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_process_in)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv4_link *link;
|
||||
uint8_t i, j, _i, _j;
|
||||
int result;
|
||||
struct pico_mcast_group g;
|
||||
/* Building example frame */
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv4("192.168.1.1", &p->mcast_link.ip4.addr);
|
||||
pico_string_to_ipv4("244.7.7.7", &p->mcast_group.ip4.addr);
|
||||
/* no link */
|
||||
fail_if(pico_igmp_generate_report(p) != -1);
|
||||
|
||||
pico_ipv4_link_add(dev, p->mcast_link.ip4, p->mcast_link.ip4);
|
||||
link = pico_ipv4_link_get(&p->mcast_link.ip4);
|
||||
link->mcast_compatibility = PICO_IGMPV2;
|
||||
g.mcast_addr.ip4 = p->mcast_group.ip4;
|
||||
g.MCASTSources.root = &LEAF;
|
||||
g.MCASTSources.compare = mcast_sources_cmp;
|
||||
/* No mcastsources tree */
|
||||
link->mcast_compatibility = PICO_IGMPV3;
|
||||
fail_if(pico_igmp_generate_report(p) != -1);
|
||||
pico_tree_insert(link->MCASTGroups, &g);
|
||||
pico_tree_insert(&IGMPParameters, p);
|
||||
|
||||
link->mcast_compatibility = 99;
|
||||
fail_if(pico_igmp_generate_report(p) != -1);
|
||||
link->mcast_compatibility = PICO_IGMPV2;
|
||||
fail_if(pico_igmp_generate_report(p) != 0);
|
||||
link->mcast_compatibility = PICO_IGMPV3;
|
||||
for(_j = 0; _j < 3; _j++) { /* FILTER */
|
||||
(_j == 2) ? (result = -1) : (result = 0);
|
||||
for(_i = 0; _i < 3; _i++) { /* FILTER */
|
||||
if(_i == 2) result = -1;
|
||||
|
||||
for(i = 0; i < 3; i++) { /* STATES */
|
||||
for(j = 0; j < 6; j++) { /* EVENTS */
|
||||
p->MCASTFilter = &_MCASTFilter;
|
||||
p->filter_mode = _i;
|
||||
g.filter_mode = _j;
|
||||
if(p->event == IGMP_EVENT_DELETE_GROUP || p->event == IGMP_EVENT_QUERY_RECV)
|
||||
p->event++;
|
||||
|
||||
fail_if(pico_igmp_generate_report(p) != result);
|
||||
p->state = i;
|
||||
p->event = j;
|
||||
if(result != -1 && p->f) /* in some combinations, no frame is created */
|
||||
fail_if(pico_igmp_process_in(NULL, p->f) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_find_parameter)
|
||||
{
|
||||
struct pico_ip4 mcast_link, mcast_group;
|
||||
struct mcast_parameters test = {
|
||||
0
|
||||
};
|
||||
fail_if(pico_igmp_find_parameter(NULL, NULL) != NULL);
|
||||
pico_string_to_ipv4("192.168.1.1", &mcast_link.addr);
|
||||
fail_if(pico_igmp_find_parameter(&mcast_link, NULL) != NULL);
|
||||
pico_string_to_ipv4("192.168.1.2", &mcast_group.addr);
|
||||
fail_if(pico_igmp_find_parameter(&mcast_link, &mcast_group) != NULL);
|
||||
test.mcast_link.ip4 = mcast_link;
|
||||
test.mcast_group.ip4 = mcast_group;
|
||||
pico_tree_insert(&IGMPParameters, &test);
|
||||
|
||||
fail_if(pico_igmp_find_parameter(&mcast_link, &mcast_group) == NULL);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_compatibility_mode)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy1");
|
||||
struct pico_ip4 addr;
|
||||
struct pico_ipv4_hdr *hdr;
|
||||
struct igmp_message *query;
|
||||
uint8_t ihl = 24;
|
||||
f = pico_proto_ipv4.alloc(&pico_proto_ipv4, dev, sizeof(struct igmpv3_report) + sizeof(struct igmpv3_group_record) + (0 * sizeof(struct pico_ip4)));
|
||||
pico_string_to_ipv4("192.168.1.2", &addr.addr);
|
||||
hdr = (struct pico_ipv4_hdr *) f->net_hdr;
|
||||
ihl = (uint8_t)((hdr->vhl & 0x0F) * 4); /* IHL is in 32bit words */
|
||||
query = (struct igmp_message *) f->transport_hdr;
|
||||
/* No link */
|
||||
fail_if(pico_igmp_compatibility_mode(f) != -1);
|
||||
pico_ipv4_link_add(dev, addr, addr);
|
||||
f->dev = dev;
|
||||
/* Igmpv3 query */
|
||||
hdr->len = short_be((uint16_t)(12 + ihl));
|
||||
fail_if(pico_igmp_compatibility_mode(f) != 0);
|
||||
/* Igmpv2 query */
|
||||
hdr->len = short_be((uint16_t)(8 + ihl));
|
||||
query->max_resp_time = 0;
|
||||
fail_if(pico_igmp_compatibility_mode(f) == 0);
|
||||
query->max_resp_time = 1;
|
||||
fail_if(pico_igmp_compatibility_mode(f) != 0);
|
||||
/* Invalid Query */
|
||||
hdr->len = short_be((uint16_t)(9 + ihl));
|
||||
fail_if(pico_igmp_compatibility_mode(f) == 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_analyse_packet)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy0");
|
||||
struct pico_ip4 addr;
|
||||
struct igmp_message *igmp;
|
||||
f = pico_proto_ipv4.alloc(&pico_proto_ipv4, dev, sizeof(struct igmp_message));
|
||||
pico_string_to_ipv4("192.168.1.1", &addr.addr);
|
||||
/* No link */
|
||||
fail_if(pico_igmp_analyse_packet(f) != NULL);
|
||||
pico_ipv4_link_add(dev, addr, addr);
|
||||
f->dev = dev;
|
||||
|
||||
igmp = (struct igmp_message *) (f->transport_hdr);
|
||||
igmp->type = 0;
|
||||
/* wrong type */
|
||||
fail_if(pico_igmp_analyse_packet(f) != NULL);
|
||||
|
||||
/* all correct */
|
||||
igmp->type = IGMP_TYPE_MEM_QUERY;
|
||||
fail_if(pico_igmp_analyse_packet(f) == NULL);
|
||||
igmp->type = IGMP_TYPE_MEM_REPORT_V1;
|
||||
fail_if(pico_igmp_analyse_packet(f) == NULL);
|
||||
igmp->type = IGMP_TYPE_MEM_REPORT_V2;
|
||||
fail_if(pico_igmp_analyse_packet(f) == NULL);
|
||||
igmp->type = IGMP_TYPE_MEM_REPORT_V3;
|
||||
fail_if(pico_igmp_analyse_packet(f) == NULL);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_igmp_discard)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_srst)
|
||||
{
|
||||
struct mcast_parameters p;
|
||||
struct pico_device *dev = pico_null_create("dummy0");
|
||||
struct pico_ipv4_link *link;
|
||||
|
||||
pico_string_to_ipv4("192.168.1.1", &p.mcast_link.ip4.addr);
|
||||
/* no link */
|
||||
fail_if(srst(&p) != -1);
|
||||
pico_ipv4_link_add(dev, p.mcast_link.ip4, p.mcast_link.ip4);
|
||||
link = pico_ipv4_link_get(&p.mcast_link.ip4);
|
||||
/* Not supported protocol for this call */
|
||||
link->mcast_compatibility = PICO_IGMPV2;
|
||||
fail_if(srst(&p) != -1);
|
||||
link->mcast_compatibility = PICO_IGMPV3;
|
||||
fail_if(srst(&p) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_stcl)
|
||||
{
|
||||
struct igmp_timer *t = PICO_ZALLOC(sizeof(struct igmp_timer));
|
||||
struct mcast_parameters p;
|
||||
|
||||
pico_string_to_ipv4("192.168.1.10", &t->mcast_link.addr);
|
||||
pico_string_to_ipv4("244.7.7.7", &t->mcast_group.addr);
|
||||
p.mcast_link.ip4 = t->mcast_link;
|
||||
p.mcast_group.ip4 = t->mcast_group;
|
||||
t->type = IGMP_TIMER_GROUP_REPORT;
|
||||
/* not in tree */
|
||||
fail_if(stcl(&p) != -1);
|
||||
pico_igmp_timer_start(t);
|
||||
fail_if(stcl(&p) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_igmp_report_expired = tcase_create("Unit test for pico_igmp_report_expired");
|
||||
TCase *TCase_igmpt_type_compare = tcase_create("Unit test for igmpt_type_compare");
|
||||
TCase *TCase_pico_igmp_analyse_packet = tcase_create("Unit test for pico_igmp_analyse_packet");
|
||||
TCase *TCase_pico_igmp_discard = tcase_create("Unit test for pico_igmp_discard");
|
||||
TCase *TCase_pico_igmp_compatibility_mode = tcase_create("Unit test for pico_igmp_compatibility");
|
||||
TCase *TCase_pico_igmp_state_change = tcase_create("Unit test for pico_igmp_state_change");
|
||||
TCase *TCase_pico_igmp_process_in = tcase_create("Unit test for pico_igmp_process_in");
|
||||
TCase *TCase_pico_igmp_timer_expired = tcase_create("Unit test for pico_igmp_timer_expired");
|
||||
TCase *TCase_pico_igmp_delete_parameter = tcase_create("Unit test for pico_igmp_delete_parameter");
|
||||
TCase *TCase_pico_igmp_find_parameter = tcase_create("Unit test for pico_igmp_find_parameter");
|
||||
TCase *TCase_stcl = tcase_create("Unit test for stcl");
|
||||
TCase *TCase_srst = tcase_create("Unit test for srst");
|
||||
TCase *TCase_pico_igmp_v2querier_expired = tcase_create("Unit test for pico_igmp_v2_querier_expired");
|
||||
|
||||
tcase_add_test(TCase_pico_igmp_report_expired, tc_pico_igmp_report_expired);
|
||||
suite_add_tcase(s, TCase_pico_igmp_report_expired);
|
||||
tcase_add_test(TCase_igmpt_type_compare, tc_igmpt_type_compare);
|
||||
suite_add_tcase(s, TCase_igmpt_type_compare);
|
||||
tcase_add_test(TCase_pico_igmp_analyse_packet, tc_pico_igmp_analyse_packet);
|
||||
suite_add_tcase(s, TCase_pico_igmp_analyse_packet);
|
||||
tcase_add_test(TCase_pico_igmp_discard, tc_pico_igmp_discard);
|
||||
suite_add_tcase(s, TCase_pico_igmp_discard);
|
||||
tcase_add_test(TCase_pico_igmp_compatibility_mode, tc_pico_igmp_compatibility_mode);
|
||||
suite_add_tcase(s, TCase_pico_igmp_compatibility_mode);
|
||||
suite_add_tcase(s, TCase_pico_igmp_state_change);
|
||||
tcase_add_test(TCase_pico_igmp_state_change, tc_pico_igmp_state_change);
|
||||
suite_add_tcase(s, TCase_pico_igmp_process_in);
|
||||
tcase_add_test(TCase_pico_igmp_process_in, tc_pico_igmp_process_in);
|
||||
suite_add_tcase(s, TCase_pico_igmp_timer_expired);
|
||||
tcase_add_test(TCase_pico_igmp_timer_expired, tc_pico_igmp_timer_expired);
|
||||
suite_add_tcase(s, TCase_pico_igmp_delete_parameter);
|
||||
tcase_add_test(TCase_pico_igmp_delete_parameter, tc_pico_igmp_delete_parameter);
|
||||
suite_add_tcase(s, TCase_pico_igmp_find_parameter);
|
||||
tcase_add_test(TCase_pico_igmp_find_parameter, tc_pico_igmp_find_parameter);
|
||||
suite_add_tcase(s, TCase_stcl);
|
||||
tcase_add_test(TCase_stcl, tc_stcl);
|
||||
suite_add_tcase(s, TCase_srst);
|
||||
tcase_add_test(TCase_srst, tc_srst);
|
||||
suite_add_tcase(s, TCase_pico_igmp_v2querier_expired);
|
||||
tcase_add_test(TCase_pico_igmp_v2querier_expired, tc_pico_igmp_v2querier_expired);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
321
kernel/picotcp/test/unit/modunit_pico_ipfilter.c
Normal file
321
kernel/picotcp/test/unit/modunit_pico_ipfilter.c
Normal file
@ -0,0 +1,321 @@
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_config.h"
|
||||
#include "pico_icmp4.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_device.h"
|
||||
#include "pico_ipfilter.h"
|
||||
#include "pico_tcp.h"
|
||||
#include "pico_udp.h"
|
||||
#include "pico_tree.h"
|
||||
#include "modules/pico_ipfilter.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
int pico_icmp4_packet_filtered(struct pico_frame *f)
|
||||
{
|
||||
(void)f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pico_frame_discard(struct pico_frame *f)
|
||||
{
|
||||
(void)f;
|
||||
}
|
||||
|
||||
volatile pico_err_t pico_err;
|
||||
|
||||
|
||||
|
||||
START_TEST(tc_ipfilter)
|
||||
{
|
||||
uint32_t r;
|
||||
struct filter_node a = {
|
||||
0
|
||||
}, b = {
|
||||
0
|
||||
};
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
|
||||
/* a is rule, matching packet b */
|
||||
a.filter_id = 1;
|
||||
|
||||
/* check that rule is matched properly */
|
||||
fail_if(filter_match_packet_find_rule(&a, &b) != &a);
|
||||
|
||||
/* a has a out port that does not match packet */
|
||||
b.out_port = 8;
|
||||
a.out_port = 7;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches all ports */
|
||||
a.out_port = 0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
|
||||
/* a has a in port that does not match packet */
|
||||
b.in_port = 8;
|
||||
a.in_port = 7;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches all ports */
|
||||
a.in_port = 0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a matches port exactly */
|
||||
a.in_port = 0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all out addresses */
|
||||
b.out_addr = 0x010000a0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a does not match b via 8-bit netmask */
|
||||
a.out_addr = 0x000000c0;
|
||||
a.out_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a does not match b at all*/
|
||||
a.out_addr = 0x020000b0;
|
||||
a.out_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches b via 8-bit netmask */
|
||||
a.out_addr = 0x000000a0;
|
||||
a.out_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a matches b exactly */
|
||||
a.out_addr = 0x010000a0;
|
||||
a.out_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all in addresses */
|
||||
b.in_addr = 0x010000a0;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a does not match b via 8-bit netmask */
|
||||
a.in_addr = 0x000000c0;
|
||||
a.in_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a does not match b at all*/
|
||||
a.in_addr = 0x020000b0;
|
||||
a.in_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches b via 8-bit netmask */
|
||||
a.in_addr = 0x000000a0;
|
||||
a.in_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a matches b exactly */
|
||||
a.in_addr = 0x010000a0;
|
||||
a.in_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all protocols */
|
||||
b.proto = 4u;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a does not match protocol */
|
||||
a.proto = 5u;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches b's protocol */
|
||||
a.proto = b.proto;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all devices */
|
||||
b.fdev = (struct pico_device *) &b;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
/* a does not match device */
|
||||
a.fdev = (struct pico_device *)&a;
|
||||
fail_if(filter_compare(&a, &b) == 0);
|
||||
|
||||
/* a matches b's device */
|
||||
a.fdev = b.fdev;
|
||||
fail_if(filter_compare(&a, &b) != 0);
|
||||
|
||||
|
||||
/*** SAME TEST DUPLICATED WITH INVERTED ORDER OF PARAMETERS ***/
|
||||
|
||||
memset(&a, 0, sizeof(struct filter_node));
|
||||
memset(&b, 0, sizeof(struct filter_node));
|
||||
|
||||
a.filter_id = 2;
|
||||
|
||||
|
||||
/* check that rule is matched properly */
|
||||
fail_if(filter_match_packet_find_rule(&b, &a) != &a);
|
||||
|
||||
/* a has a out port that does not match packet */
|
||||
b.out_port = 8;
|
||||
a.out_port = 7;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches all ports */
|
||||
a.out_port = 0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
|
||||
/* a has a in port that does not match packet */
|
||||
b.in_port = 8;
|
||||
a.in_port = 7;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches all ports */
|
||||
a.in_port = 0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a matches port exactly */
|
||||
a.in_port = 0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all out addresses */
|
||||
b.out_addr = 0x010000a0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a does not match b via 8-bit netmask */
|
||||
a.out_addr = 0x000000c0;
|
||||
a.out_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a does not match b at all*/
|
||||
a.out_addr = 0x020000b0;
|
||||
a.out_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches b via 8-bit netmask */
|
||||
a.out_addr = 0x000000a0;
|
||||
a.out_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a matches b exactly */
|
||||
a.out_addr = 0x010000a0;
|
||||
a.out_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all in addresses */
|
||||
b.in_addr = 0x010000a0;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a does not match b via 8-bit netmask */
|
||||
a.in_addr = 0x000000c0;
|
||||
a.in_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a does not match b at all*/
|
||||
a.in_addr = 0x020000b0;
|
||||
a.in_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches b via 8-bit netmask */
|
||||
a.in_addr = 0x000000a0;
|
||||
a.in_addr_netmask = 0x000000ff;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a matches b exactly */
|
||||
a.in_addr = 0x010000a0;
|
||||
a.in_addr_netmask = 0xffffffff;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all protocols */
|
||||
b.proto = 4u;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a does not match protocol */
|
||||
a.proto = 5u;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches b's protocol */
|
||||
a.proto = b.proto;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/*** NEXT TEST ***/
|
||||
|
||||
/* a matches all devices */
|
||||
b.fdev = (struct pico_device *)&b;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
/* a does not match device */
|
||||
a.fdev = (struct pico_device *)&a;
|
||||
fail_if(filter_compare(&b, &a) == 0);
|
||||
|
||||
/* a matches b's device */
|
||||
a.fdev = b.fdev;
|
||||
fail_if(filter_compare(&b, &a) != 0);
|
||||
|
||||
|
||||
|
||||
/*********** TEST ADD FILTER **************/
|
||||
|
||||
/*
|
||||
uint32_t pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto,
|
||||
struct pico_ip4 *out_addr, struct pico_ip4 *out_addr_netmask,
|
||||
struct pico_ip4 *in_addr, struct pico_ip4 *in_addr_netmask,
|
||||
uint16_t out_port, uint16_t in_port, int8_t priority,
|
||||
uint8_t tos, enum filter_action action)
|
||||
*/
|
||||
|
||||
|
||||
r = pico_ipv4_filter_add(NULL, 0, NULL, NULL, NULL, NULL, 0, 0, MAX_PRIORITY + 1, 0, FILTER_DROP);
|
||||
fail_if(r > 0);
|
||||
|
||||
r = pico_ipv4_filter_add(NULL, 0, NULL, NULL, NULL, NULL, 0, 0, MIN_PRIORITY - 1, 0, FILTER_PRIORITY);
|
||||
fail_if(r > 0);
|
||||
|
||||
r = pico_ipv4_filter_add(NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, FILTER_COUNT);
|
||||
fail_if(r > 0);
|
||||
|
||||
#ifdef FAULTY
|
||||
pico_set_mm_failure(1);
|
||||
r = pico_ipv4_filter_add(NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, FILTER_DROP);
|
||||
fail_if(r > 0);
|
||||
fail_if(pico_err != PICO_ERR_ENOMEM);
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("IPfilter module");
|
||||
|
||||
TCase *TCase_ipfilter = tcase_create("Unit test for ipfilter");
|
||||
tcase_add_test(TCase_ipfilter, tc_ipfilter);
|
||||
suite_add_tcase(s, TCase_ipfilter);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
289
kernel/picotcp/test/unit/modunit_pico_ipv6_nd.c
Normal file
289
kernel/picotcp/test/unit/modunit_pico_ipv6_nd.c
Normal file
@ -0,0 +1,289 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_tree.h"
|
||||
#include "pico_ipv6_nd.h"
|
||||
#include "pico_icmp6.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_device.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_addressing.h"
|
||||
#include "modules/pico_ipv6_nd.c"
|
||||
#include "check.h"
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
|
||||
#undef PICO_TIME
|
||||
#undef PICO_TIME_MS
|
||||
|
||||
#define PICO_TIME_MS (0)
|
||||
#define PICO_TIME (0)
|
||||
|
||||
Suite *pico_suite(void);
|
||||
START_TEST(tc_pico_nd_new_expire_time)
|
||||
{
|
||||
struct pico_ipv6_neighbor n = {
|
||||
0
|
||||
};
|
||||
struct pico_device d = { {0} };
|
||||
|
||||
/* TODO: how to test these time values */
|
||||
|
||||
n.dev = &d;
|
||||
|
||||
d.hostvars.retranstime = 666;
|
||||
|
||||
n.state = PICO_ND_STATE_INCOMPLETE;
|
||||
pico_nd_new_expire_time(&n);
|
||||
|
||||
n.state = PICO_ND_STATE_REACHABLE;
|
||||
pico_nd_new_expire_time(&n);
|
||||
|
||||
|
||||
n.state = PICO_ND_STATE_STALE;
|
||||
pico_nd_new_expire_time(&n);
|
||||
|
||||
|
||||
n.state = PICO_ND_STATE_PROBE;
|
||||
pico_nd_new_expire_time(&n);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_queue)
|
||||
{
|
||||
struct pico_ip6 addr = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }};
|
||||
int i;
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv6_hdr));
|
||||
struct pico_ipv6_hdr *h = (struct pico_ipv6_hdr *) f->buffer;
|
||||
f->net_hdr = (uint8_t*) h;
|
||||
f->buffer[0] = 0x60; /* Ipv6 */
|
||||
memcpy(h->dst.addr, addr.addr, PICO_SIZE_IP6);
|
||||
|
||||
fail_if(!f);
|
||||
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued_v6[i] != NULL);
|
||||
}
|
||||
pico_ipv6_nd_unreachable(&addr);
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued_v6[i] != NULL);
|
||||
}
|
||||
pico_ipv6_nd_postpone(f);
|
||||
fail_if(frames_queued_v6[0]->buffer != f->buffer);
|
||||
|
||||
pico_ipv6_nd_unreachable(&addr);
|
||||
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued_v6[i] != NULL);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_nd_discover)
|
||||
{
|
||||
/* TODO: test this: static void pico_nd_discover(struct pico_ipv6_neighbor *n) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_options)
|
||||
{
|
||||
/* TODO: test this: static int neigh_options(struct pico_frame *f, struct pico_icmp6_opt_lladdr *opt, uint8_t expected_opt) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_complete)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_complete(struct pico_ipv6_neighbor *n, struct pico_icmp6_opt_lladdr *opt) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_reconfirm_router_option)
|
||||
{
|
||||
/* TODO: test this: static void neigh_adv_reconfirm_router_option(struct pico_ipv6_neighbor *n, unsigned int isRouter) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_reconfirm)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_reconfirm(struct pico_ipv6_neighbor *n, struct pico_icmp6_opt_lladdr *opt, struct pico_icmp6_hdr *hdr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_check_solicited)
|
||||
{
|
||||
/* TODO: test this: static void neigh_adv_check_solicited(struct pico_icmp6_hdr *ic6, struct pico_ipv6_neighbor *n) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_process)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_process(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ipv6_neighbor)
|
||||
{
|
||||
/* TODO: test this: static struct pico_ipv6_neighbor *neighbor_from_sol_new(struct pico_ip6 *ip, struct pico_icmp6_opt_lladdr *opt, struct pico_device *dev) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neighbor_from_sol)
|
||||
{
|
||||
/* TODO: test this: static void neighbor_from_sol(struct pico_ip6 *ip, struct pico_icmp6_opt_lladdr *opt, struct pico_device *dev) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_sol_process)
|
||||
{
|
||||
/* TODO: test this: static int neigh_sol_process(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_icmp6_initial_checks)
|
||||
{
|
||||
/* TODO: test this: static int icmp6_initial_checks(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_mcast_validity_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_mcast_validity_check(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_sol_mcast_validity_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_sol_mcast_validity_check(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_validity_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_validity_checks(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_sol_validity_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_sol_validity_checks(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_neigh_adv_checks)
|
||||
{
|
||||
/* TODO: test this: static int neigh_adv_checks(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_router_sol_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_router_sol_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_router_adv_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_router_adv_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_neigh_sol_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_neigh_sol_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_neigh_adv_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_neigh_adv_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_nd_redirect_recv)
|
||||
{
|
||||
/* TODO: test this: static int pico_nd_redirect_recv(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ipv6_nd_timer_callback)
|
||||
{
|
||||
/* TODO: test this: static void pico_ipv6_nd_timer_callback(pico_time now, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_nd_new_expire_time = tcase_create("Unit test for pico_nd_new_expire_time");
|
||||
TCase *TCase_pico_nd_discover = tcase_create("Unit test for pico_nd_discover");
|
||||
TCase *TCase_neigh_options = tcase_create("Unit test for neigh_options");
|
||||
TCase *TCase_neigh_adv_complete = tcase_create("Unit test for neigh_adv_complete");
|
||||
TCase *TCase_neigh_adv_reconfirm_router_option = tcase_create("Unit test for neigh_adv_reconfirm_router_option");
|
||||
TCase *TCase_neigh_adv_reconfirm = tcase_create("Unit test for neigh_adv_reconfirm");
|
||||
TCase *TCase_neigh_adv_check_solicited = tcase_create("Unit test for neigh_adv_check_solicited");
|
||||
TCase *TCase_neigh_adv_process = tcase_create("Unit test for neigh_adv_process");
|
||||
TCase *TCase_pico_ipv6_neighbor = tcase_create("Unit test for pico_ipv6_neighbor");
|
||||
TCase *TCase_neighbor_from_sol = tcase_create("Unit test for neighbor_from_sol");
|
||||
TCase *TCase_neigh_sol_process = tcase_create("Unit test for neigh_sol_process");
|
||||
TCase *TCase_icmp6_initial_checks = tcase_create("Unit test for icmp6_initial_checks");
|
||||
TCase *TCase_neigh_sol_mcast_validity_checks = tcase_create("Unit test for neigh_sol_mcast_validity_checks");
|
||||
TCase *TCase_neigh_sol_validity_checks = tcase_create("Unit test for neigh_sol_validity_checks");
|
||||
TCase *TCase_neigh_adv_checks = tcase_create("Unit test for neigh_adv_checks");
|
||||
TCase *TCase_neigh_adv_validity_checks = tcase_create("Unit test for neigh_adv_validity_checks");
|
||||
TCase *TCase_neigh_adv_mcast_validity_checks = tcase_create("Unit test for neigh_adv_mcast_validity_checks");
|
||||
TCase *TCase_pico_nd_router_sol_recv = tcase_create("Unit test for pico_nd_router_sol_recv");
|
||||
TCase *TCase_pico_nd_router_adv_recv = tcase_create("Unit test for pico_nd_router_adv_recv");
|
||||
TCase *TCase_pico_nd_neigh_sol_recv = tcase_create("Unit test for pico_nd_neigh_sol_recv");
|
||||
TCase *TCase_pico_nd_neigh_adv_recv = tcase_create("Unit test for pico_nd_neigh_adv_recv");
|
||||
TCase *TCase_pico_nd_redirect_recv = tcase_create("Unit test for pico_nd_redirect_recv");
|
||||
TCase *TCase_pico_ipv6_nd_timer_callback = tcase_create("Unit test for pico_ipv6_nd_timer_callback");
|
||||
TCase *TCase_pico_nd_queue = tcase_create("Unit test for pico_ipv6_nd: queue for pending frames");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_nd_new_expire_time, tc_pico_nd_new_expire_time);
|
||||
suite_add_tcase(s, TCase_pico_nd_new_expire_time);
|
||||
tcase_add_test(TCase_pico_nd_discover, tc_pico_nd_discover);
|
||||
suite_add_tcase(s, TCase_pico_nd_discover);
|
||||
tcase_add_test(TCase_neigh_options, tc_neigh_options);
|
||||
suite_add_tcase(s, TCase_neigh_options);
|
||||
tcase_add_test(TCase_neigh_adv_complete, tc_neigh_adv_complete);
|
||||
suite_add_tcase(s, TCase_neigh_adv_complete);
|
||||
tcase_add_test(TCase_neigh_adv_reconfirm_router_option, tc_neigh_adv_reconfirm_router_option);
|
||||
suite_add_tcase(s, TCase_neigh_adv_reconfirm_router_option);
|
||||
tcase_add_test(TCase_neigh_adv_reconfirm, tc_neigh_adv_reconfirm);
|
||||
suite_add_tcase(s, TCase_neigh_adv_reconfirm);
|
||||
tcase_add_test(TCase_neigh_adv_check_solicited, tc_neigh_adv_check_solicited);
|
||||
suite_add_tcase(s, TCase_neigh_adv_check_solicited);
|
||||
tcase_add_test(TCase_neigh_adv_process, tc_neigh_adv_process);
|
||||
suite_add_tcase(s, TCase_neigh_adv_process);
|
||||
tcase_add_test(TCase_pico_ipv6_neighbor, tc_pico_ipv6_neighbor);
|
||||
suite_add_tcase(s, TCase_pico_ipv6_neighbor);
|
||||
tcase_add_test(TCase_neighbor_from_sol, tc_neighbor_from_sol);
|
||||
suite_add_tcase(s, TCase_neighbor_from_sol);
|
||||
tcase_add_test(TCase_neigh_sol_process, tc_neigh_sol_process);
|
||||
suite_add_tcase(s, TCase_neigh_sol_process);
|
||||
tcase_add_test(TCase_icmp6_initial_checks, tc_icmp6_initial_checks);
|
||||
suite_add_tcase(s, TCase_icmp6_initial_checks);
|
||||
tcase_add_test(TCase_neigh_adv_mcast_validity_checks, tc_neigh_adv_mcast_validity_checks);
|
||||
suite_add_tcase(s, TCase_neigh_adv_mcast_validity_checks);
|
||||
tcase_add_test(TCase_neigh_sol_mcast_validity_checks, tc_neigh_sol_mcast_validity_checks);
|
||||
suite_add_tcase(s, TCase_neigh_sol_mcast_validity_checks);
|
||||
tcase_add_test(TCase_neigh_adv_validity_checks, tc_neigh_adv_validity_checks);
|
||||
suite_add_tcase(s, TCase_neigh_adv_validity_checks);
|
||||
tcase_add_test(TCase_neigh_sol_validity_checks, tc_neigh_sol_validity_checks);
|
||||
suite_add_tcase(s, TCase_neigh_sol_validity_checks);
|
||||
tcase_add_test(TCase_neigh_adv_checks, tc_neigh_adv_checks);
|
||||
suite_add_tcase(s, TCase_neigh_adv_checks);
|
||||
tcase_add_test(TCase_pico_nd_router_sol_recv, tc_pico_nd_router_sol_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_router_sol_recv);
|
||||
tcase_add_test(TCase_pico_nd_router_adv_recv, tc_pico_nd_router_adv_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_router_adv_recv);
|
||||
tcase_add_test(TCase_pico_nd_neigh_sol_recv, tc_pico_nd_neigh_sol_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_neigh_sol_recv);
|
||||
tcase_add_test(TCase_pico_nd_neigh_adv_recv, tc_pico_nd_neigh_adv_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_neigh_adv_recv);
|
||||
tcase_add_test(TCase_pico_nd_redirect_recv, tc_pico_nd_redirect_recv);
|
||||
suite_add_tcase(s, TCase_pico_nd_redirect_recv);
|
||||
tcase_add_test(TCase_pico_ipv6_nd_timer_callback, tc_pico_ipv6_nd_timer_callback);
|
||||
suite_add_tcase(s, TCase_pico_ipv6_nd_timer_callback);
|
||||
tcase_add_test(TCase_pico_nd_queue, tc_pico_nd_queue);
|
||||
suite_add_tcase(s, TCase_pico_nd_queue);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
#else
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
2227
kernel/picotcp/test/unit/modunit_pico_mdns.c
Normal file
2227
kernel/picotcp/test/unit/modunit_pico_mdns.c
Normal file
File diff suppressed because it is too large
Load Diff
584
kernel/picotcp/test/unit/modunit_pico_mld.c
Normal file
584
kernel/picotcp/test/unit/modunit_pico_mld.c
Normal file
@ -0,0 +1,584 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_queue.h"
|
||||
#include "pico_tree.h"
|
||||
#include "modules/pico_mld.c"
|
||||
#include "check.h"
|
||||
#include "pico_dev_null.c"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void mock_callback(struct mld_timer *t);
|
||||
|
||||
static uint32_t timers_added = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(expire);
|
||||
IGNORE_PARAMETER(timer);
|
||||
IGNORE_PARAMETER(arg);
|
||||
return ++timers_added;
|
||||
}
|
||||
void mock_callback(struct mld_timer *t)
|
||||
{
|
||||
IGNORE_PARAMETER(t);
|
||||
}
|
||||
static int mcast_filter_cmp_ipv6(void *ka, void *kb)
|
||||
{
|
||||
union pico_address *a = ka, *b = kb;
|
||||
return memcmp(&a->ip6, &b->ip6, sizeof(struct pico_ip6));
|
||||
}
|
||||
static int mcast_sources_cmp_ipv6(void *ka, void *kb)
|
||||
{
|
||||
union pico_address *a = ka, *b = kb;
|
||||
return memcmp(&a->ip6, &b->ip6, sizeof(struct pico_ip6));
|
||||
}
|
||||
static PICO_TREE_DECLARE(_MCASTFilter, mcast_filter_cmp_ipv6);
|
||||
|
||||
START_TEST(tc_pico_mld_fill_hopbyhop)
|
||||
{
|
||||
struct pico_ipv6_hbhoption *hbh = NULL;
|
||||
/* Not-null case tested by unit_ipv6.c */
|
||||
fail_if(pico_mld_fill_hopbyhop(hbh) != NULL);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_check_hopbyhop)
|
||||
{
|
||||
struct pico_ipv6_hbhoption *hbh = NULL;
|
||||
struct pico_ipv6_hbhoption _hbh;
|
||||
uint8_t *p;
|
||||
uint8_t options[8] = {
|
||||
PICO_PROTO_ICMP6, 0, PICO_IPV6_EXTHDR_OPT_ROUTER_ALERT, \
|
||||
PICO_IPV6_EXTHDR_OPT_ROUTER_ALERT_DATALEN, 0, 0, 1, 0
|
||||
};
|
||||
int i = 0;
|
||||
int test = 0;
|
||||
fail_if(pico_mld_check_hopbyhop(hbh) != -1);
|
||||
_hbh.type = 1;
|
||||
_hbh.len = 0;
|
||||
fail_if(pico_mld_check_hopbyhop(&_hbh) != -1);
|
||||
_hbh.type = PICO_PROTO_ICMP6;
|
||||
_hbh.len = 1;
|
||||
fail_if(pico_mld_check_hopbyhop(&_hbh) != -1);
|
||||
|
||||
hbh = (struct pico_ipv6_hbhoption *) PICO_ZALLOC(sizeof(struct pico_ipv6_hbhoption) + 7);
|
||||
hbh->type = PICO_PROTO_ICMP6;
|
||||
hbh->len = 0;
|
||||
for(test = 0; test < 7; test++) {
|
||||
p = (uint8_t *)hbh + sizeof(struct pico_ipv6_hbhoption);
|
||||
for(i = 0; i < 6; i++ ) {
|
||||
if(i != test)
|
||||
*(p++) = options[i + 2];
|
||||
else
|
||||
*(p++) = 9;
|
||||
}
|
||||
if(test != 6)
|
||||
fail_if(pico_mld_check_hopbyhop(hbh) != -1);
|
||||
else
|
||||
fail_if(pico_mld_check_hopbyhop(hbh) != 0);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_v1querier_expired)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
struct pico_ip6 addr = {{0}};
|
||||
struct pico_device *dev = pico_null_create("dummy2");
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_frame));
|
||||
t->f = f;
|
||||
pico_string_to_ipv6("AAAA::109", addr.addr);
|
||||
/* void function, just check for side effects */
|
||||
/* No link */
|
||||
pico_mld_v1querier_expired(t);
|
||||
f->dev = dev;
|
||||
pico_ipv6_link_add(dev, addr, addr);
|
||||
pico_mld_v1querier_expired(t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_send_report)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy1");
|
||||
struct pico_ip6 addr;
|
||||
struct pico_ipv6_link *link;
|
||||
struct mcast_parameters p;
|
||||
f = pico_proto_ipv6.alloc(&pico_proto_ipv6, dev, sizeof(struct mldv2_report) + MLD_ROUTER_ALERT_LEN + sizeof(struct mldv2_group_record) + (0 * sizeof(struct pico_ip6)));
|
||||
pico_string_to_ipv6("AAAA::110", addr.addr);
|
||||
p.mcast_link.ip6 = addr;
|
||||
/* No link */
|
||||
fail_if(pico_mld_send_report(&p, f) != -1);
|
||||
link = pico_ipv6_link_add(dev, addr, addr);
|
||||
p.event = 0;
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
fail_if(pico_mld_send_report(&p, f) != 0);
|
||||
link->mcast_compatibility = 99;
|
||||
fail_if(pico_mld_send_report(&p, f) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_report_expired)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
struct pico_ip6 zero = {0};
|
||||
|
||||
t->mcast_link = zero;
|
||||
t->mcast_group = zero;
|
||||
/* void function, just check for side effects */
|
||||
pico_mld_report_expired(t);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_delete_parameter)
|
||||
{
|
||||
struct mcast_parameters p;
|
||||
fail_if(pico_mld_delete_parameter(&p) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mldt_type_compare)
|
||||
{
|
||||
struct mld_timer a;
|
||||
struct mld_timer b;
|
||||
a.type = 1;
|
||||
b.type = 2;
|
||||
fail_if(mldt_type_compare(&a, &b) != -1);
|
||||
fail_if(mldt_type_compare(&b, &a) != 1);
|
||||
fail_if(mld_timer_cmp(&b, &a) != 1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_is_checksum_valid)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
f = pico_proto_ipv6.alloc(&pico_proto_ipv6, NULL, sizeof(struct mldv2_report) + MLD_ROUTER_ALERT_LEN + sizeof(struct mldv2_group_record) + (0 * sizeof(struct pico_ip6)));
|
||||
fail_if(pico_mld_is_checksum_valid(f) == 1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_find_parameter)
|
||||
{
|
||||
struct pico_ip6 mcast_link, mcast_group;
|
||||
struct mcast_parameters test = {
|
||||
0
|
||||
};
|
||||
fail_if(pico_mld_find_parameter(NULL, NULL) != NULL);
|
||||
pico_string_to_ipv6("AAAA::111", mcast_link.addr);
|
||||
fail_if(pico_mld_find_parameter(&mcast_link, NULL) != NULL);
|
||||
pico_string_to_ipv6("AAAA::211", mcast_group.addr);
|
||||
fail_if(pico_mld_find_parameter(&mcast_link, &mcast_group) != NULL);
|
||||
test.mcast_link.ip6 = mcast_link;
|
||||
test.mcast_group.ip6 = mcast_group;
|
||||
pico_tree_insert(&MLDParameters, &test);
|
||||
|
||||
fail_if(pico_mld_find_parameter(&mcast_link, &mcast_group) == NULL);
|
||||
pico_tree_delete(&MLDParameters, &test);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_timer_expired)
|
||||
{
|
||||
struct mld_timer *t, *s;
|
||||
t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
t->stopped = MLD_TIMER_STOPPED;
|
||||
t->type = 0;
|
||||
pico_string_to_ipv6("AAAA::112", t->mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::112", t->mcast_group.addr);
|
||||
/* void function, just check for side effects */
|
||||
pico_mld_timer_expired(0, (void *)t);
|
||||
pico_tree_insert(&MLDTimers, t);
|
||||
s = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
memcpy(s, t, sizeof(struct mld_timer)); /* t will be freed next test */
|
||||
pico_mld_timer_expired(0, (void *)t); /* will be freed */
|
||||
s->stopped++;
|
||||
s->start = PICO_TIME_MS() * 2;
|
||||
s->type++;
|
||||
pico_tree_insert(&MLDTimers, s);
|
||||
t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
memcpy(t, s, sizeof(struct mld_timer)); /* s will be freed next test */
|
||||
pico_mld_timer_expired(0, (void *)s); /* s will be freed */
|
||||
t->mld_callback = mock_callback;
|
||||
pico_mld_timer_expired(0, (void *)t); /* t will be freed */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_send_done)
|
||||
{
|
||||
struct mcast_parameters p;
|
||||
fail_if(pico_mld_send_done(&p, NULL) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mld_stsdifs)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv6_link *link;
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
/* Building example frame */
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::113", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
/* no link */
|
||||
fail_if(mld_stsdifs(p) != -1);
|
||||
link = pico_ipv6_link_add(dev, p->mcast_link.ip6, p->mcast_link.ip6);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
/* no timer */
|
||||
fail_if(mld_stsdifs(p) != -1);
|
||||
t->type = MLD_TIMER_GROUP_REPORT;
|
||||
t->mcast_link = p->mcast_link.ip6;
|
||||
t->mcast_group = p->mcast_group.ip6;
|
||||
pico_tree_insert(&MLDTimers, t);
|
||||
fail_if(mld_stsdifs(p) != 0);
|
||||
/* set flag */
|
||||
pico_mld_flag = 1;
|
||||
fail_if(mld_stsdifs(p) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mld_srsf)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
/* Building example frame */
|
||||
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::114", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
fail_if(mld_srsf(p) != -1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_mld_srst)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv6_link *link;
|
||||
struct pico_mcast_group g;
|
||||
/* Building example frame */
|
||||
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::99", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
p->MCASTFilter = &_MCASTFilter;
|
||||
p->filter_mode = 0;
|
||||
g.filter_mode = 0;
|
||||
g.mcast_addr = p->mcast_group;
|
||||
g.MCASTSources.root = &LEAF;
|
||||
g.MCASTSources.compare = mcast_sources_cmp_ipv6;
|
||||
|
||||
pico_tree_insert(&MLDParameters, p);
|
||||
/* no link */
|
||||
fail_if(mld_srst(p) != -1);
|
||||
link = pico_ipv6_link_add(dev, p->mcast_link.ip6, p->mcast_link.ip6);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
/* invalid proto */
|
||||
fail_if(mld_srst(p) != -1);
|
||||
link->mcast_compatibility = PICO_MLDV2;
|
||||
pico_tree_insert(link->MCASTGroups, &g);
|
||||
|
||||
fail_if(mld_srst(p) != 0);
|
||||
pico_tree_delete(&MLDParameters, p);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mld_mrsrrt)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv6_link *link;
|
||||
/* Building example frame */
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::115", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
/* no link */
|
||||
fail_if(mld_mrsrrt(p) != -1);
|
||||
link = pico_ipv6_link_add(dev, p->mcast_link.ip6, p->mcast_link.ip6);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
/* wrong proto */
|
||||
fail_if(mld_mrsrrt(p) != -1);
|
||||
link->mcast_compatibility = PICO_MLDV2;
|
||||
p->f = pico_proto_ipv6.alloc(&pico_proto_ipv6, dev, sizeof(struct mldv2_report) + MLD_ROUTER_ALERT_LEN + sizeof(struct mldv2_group_record) + (0 * sizeof(struct pico_ip6)));
|
||||
fail_if(mld_mrsrrt(p) != -1);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_process_in)
|
||||
{
|
||||
struct mcast_parameters *p;
|
||||
struct pico_device *dev = pico_null_create("dummy3");
|
||||
struct pico_ipv6_link *link;
|
||||
uint8_t i, j, _i, _j;
|
||||
int result = 0;
|
||||
struct pico_mcast_group g;
|
||||
struct mldv2_report *report;
|
||||
/* Building example frame */
|
||||
p = PICO_ZALLOC(sizeof(struct mcast_parameters));
|
||||
pico_string_to_ipv6("AAAA::101", p->mcast_link.ip6.addr);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
/* no link */
|
||||
fail_if(pico_mld_generate_report(p) != -1);
|
||||
link = pico_ipv6_link_add(dev, p->mcast_link.ip6, p->mcast_link.ip6);
|
||||
pico_string_to_ipv6("AAAA::100", p->mcast_group.ip6.addr);
|
||||
fail_if(pico_mld_generate_report(p) != -1);
|
||||
pico_string_to_ipv6("FF00::e007:707", p->mcast_group.ip6.addr);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
g.mcast_addr = p->mcast_group;
|
||||
g.MCASTSources.root = &LEAF;
|
||||
g.MCASTSources.compare = mcast_sources_cmp_ipv6;
|
||||
/* No mcastsources tree */
|
||||
link->mcast_compatibility = PICO_MLDV2;
|
||||
fail_if(pico_mld_generate_report(p) != -1);
|
||||
pico_tree_insert(link->MCASTGroups, &g);
|
||||
pico_tree_insert(&MLDParameters, p);
|
||||
|
||||
link->mcast_compatibility = 99;
|
||||
fail_if(pico_mld_generate_report(p) != -1);
|
||||
link->mcast_compatibility = PICO_MLDV1;
|
||||
fail_if(pico_mld_generate_report(p) != 0);
|
||||
link->mcast_compatibility = PICO_MLDV2;
|
||||
for(_j = 0; _j < 3; _j++) { /* FILTER */
|
||||
(_j == 2) ? (result = -1) : (result = 0);
|
||||
for(_i = 0; _i < 3; _i++) { /* FILTER */
|
||||
if(_i == 2) result = -1;
|
||||
|
||||
for(i = 0; i < 3; i++) { /* STATES */
|
||||
for(j = 0; j < 6; j++) { /* EVENTS */
|
||||
p->MCASTFilter = &_MCASTFilter;
|
||||
p->filter_mode = _i;
|
||||
g.filter_mode = _j;
|
||||
if(p->event == MLD_EVENT_DELETE_GROUP || p->event == MLD_EVENT_QUERY_RECV)
|
||||
p->event++;
|
||||
|
||||
fail_if(pico_mld_generate_report(p) != result);
|
||||
p->state = i;
|
||||
p->event = j;
|
||||
if(result != -1 && p->f) { /* in some combinations, no frame is created */
|
||||
report = (struct mldv2_report *)(p->f->transport_hdr + MLD_ROUTER_ALERT_LEN);
|
||||
report->crc = short_be(pico_icmp6_checksum(p->f));
|
||||
fail_if(pico_mld_process_in(p->f) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pico_tree_delete(&MLDParameters, p);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_mld_rtimrtct)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
struct mcast_parameters p;
|
||||
pico_string_to_ipv6("AAAA::102", t->mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::102", t->mcast_group.addr);
|
||||
p.mcast_link.ip6 = t->mcast_link;
|
||||
p.mcast_group.ip6 = t->mcast_group;
|
||||
t->type = MLD_TIMER_GROUP_REPORT;
|
||||
/* not in tree */
|
||||
fail_if(mld_rtimrtct(&p) != -1);
|
||||
pico_mld_timer_start(t);
|
||||
fail_if(mld_rtimrtct(&p) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_mld_stcl)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
struct mcast_parameters p;
|
||||
pico_string_to_ipv6("AAAA::103", t->mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::103", t->mcast_group.addr);
|
||||
p.mcast_link.ip6 = t->mcast_link;
|
||||
p.mcast_group.ip6 = t->mcast_group;
|
||||
t->type = MLD_TIMER_GROUP_REPORT;
|
||||
/* not in tree */
|
||||
fail_if(mld_stcl(&p) != -1);
|
||||
pico_mld_timer_start(t);
|
||||
fail_if(mld_stcl(&p) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_compatibility_mode)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy1");
|
||||
struct pico_ip6 addr;
|
||||
|
||||
f = pico_proto_ipv6.alloc(&pico_proto_ipv6, NULL, sizeof(struct mldv2_report) + MLD_ROUTER_ALERT_LEN + sizeof(struct mldv2_group_record) + (0 * sizeof(struct pico_ip6)));
|
||||
pico_string_to_ipv6("AAAA::104", addr.addr);
|
||||
/* No link */
|
||||
fail_if(pico_mld_compatibility_mode(f) != -1);
|
||||
pico_ipv6_link_add(dev, addr, addr);
|
||||
f->dev = dev;
|
||||
/* MLDv2 query */
|
||||
f->buffer_len = 28 + PICO_SIZE_IP6HDR + MLD_ROUTER_ALERT_LEN;
|
||||
fail_if(pico_mld_compatibility_mode(f) != 0);
|
||||
/* MLDv1 query */
|
||||
f->buffer_len = 24 + PICO_SIZE_IP6HDR + MLD_ROUTER_ALERT_LEN;
|
||||
fail_if(pico_mld_compatibility_mode(f) != 0);
|
||||
/* Invalid Query */
|
||||
f->buffer_len = 25 + PICO_SIZE_IP6HDR + MLD_ROUTER_ALERT_LEN;
|
||||
fail_if(pico_mld_compatibility_mode(f) == 0);
|
||||
/* MLDv2 query + timer amready running */
|
||||
f->dev = dev;
|
||||
f->buffer_len = 28 + PICO_SIZE_IP6HDR + MLD_ROUTER_ALERT_LEN + PICO_SIZE_ETHHDR;
|
||||
fail_if(pico_mld_compatibility_mode(f) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_timer_reset)
|
||||
{
|
||||
struct mld_timer *t = PICO_ZALLOC(sizeof(struct mld_timer));
|
||||
pico_string_to_ipv6("AAAA::105", t->mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::105", t->mcast_group.addr);
|
||||
t->type = 0;
|
||||
fail_if(pico_mld_timer_reset(t) != -1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_state_change)
|
||||
{
|
||||
struct pico_ip6 mcast_link, mcast_group;
|
||||
struct mcast_parameters p;
|
||||
pico_string_to_ipv6("AAAA::106", mcast_link.addr);
|
||||
pico_string_to_ipv6("AAAA::106", mcast_group.addr);
|
||||
p.mcast_link.ip6 = mcast_link;
|
||||
p.mcast_group.ip6 = mcast_group;
|
||||
|
||||
fail_if(pico_mld_state_change(NULL, &mcast_group, 0, NULL, PICO_MLD_STATE_CREATE) != -1);
|
||||
/* All host group */
|
||||
pico_string_to_ipv6("FF01:0:0:0:0:0:0:1", mcast_group.addr);
|
||||
fail_if(pico_mld_state_change(&mcast_link, &mcast_group, 0, NULL, PICO_MLD_STATE_CREATE) != 0);
|
||||
pico_string_to_ipv6("AAAA::107", mcast_group.addr);
|
||||
fail_if(pico_mld_state_change(&mcast_link, &mcast_group, 0, NULL, 99) != -1);
|
||||
pico_tree_insert(&MLDParameters, &p);
|
||||
fail_if(pico_mld_state_change(&mcast_link, &mcast_group, 0, NULL, 99) != -1);
|
||||
pico_tree_delete(&MLDParameters, &p);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_analyse_packet)
|
||||
{
|
||||
struct pico_frame *f;
|
||||
struct pico_device *dev = pico_null_create("dummy0");
|
||||
struct pico_ip6 addr;
|
||||
struct pico_ip6 local;
|
||||
struct pico_ipv6_hdr *ip6;
|
||||
struct pico_ipv6_hbhoption *hbh;
|
||||
struct pico_icmp6_hdr *mld;
|
||||
f = pico_proto_ipv6.alloc(&pico_proto_ipv6, dev, sizeof(struct mld_message) + MLD_ROUTER_ALERT_LEN);
|
||||
pico_string_to_ipv6("AAAA::108", addr.addr);
|
||||
pico_string_to_ipv6("FE80::1", local.addr);
|
||||
/* No link */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
pico_ipv6_link_add(dev, addr, addr);
|
||||
ip6 = (struct pico_ipv6_hdr *) f->net_hdr;
|
||||
ip6->hop = 99;
|
||||
/* Incorrect hop */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
ip6->hop = 1;
|
||||
hbh = (struct pico_ipv6_hbhoption *) f->transport_hdr;
|
||||
pico_mld_fill_hopbyhop(hbh);
|
||||
hbh->type = 99;
|
||||
/* incorrect hop by hop */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
pico_mld_fill_hopbyhop(hbh);
|
||||
ip6->src = addr;
|
||||
/* Not link local */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
memcpy(&ip6->src, PICO_IP6_ANY, sizeof(struct pico_ip6));
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
ip6->src = local;
|
||||
mld = (struct pico_icmp6_hdr *) (f->transport_hdr + MLD_ROUTER_ALERT_LEN);
|
||||
mld->type = 0;
|
||||
|
||||
/* wrong type */
|
||||
fail_if(pico_mld_analyse_packet(f) != NULL);
|
||||
/* all correct */
|
||||
mld->type = PICO_MLD_QUERY;
|
||||
fail_if(pico_mld_analyse_packet(f) == NULL);
|
||||
mld->type = PICO_MLD_REPORT;
|
||||
fail_if(pico_mld_analyse_packet(f) == NULL);
|
||||
mld->type = PICO_MLD_DONE;
|
||||
fail_if(pico_mld_analyse_packet(f) == NULL);
|
||||
mld->type = PICO_MLD_REPORTV2;
|
||||
fail_if(pico_mld_analyse_packet(f) == NULL);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_mld_discard)
|
||||
{
|
||||
mld_discard(NULL);
|
||||
}
|
||||
END_TEST
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_mld_fill_hopbyhop = tcase_create("Unit test for pico_mld_fill_hopbyhop");
|
||||
TCase *TCase_pico_mld_check_hopbyhop = tcase_create("Unit test for pico_mld_check_hopbyhop");
|
||||
TCase *TCase_pico_mld_report_expired = tcase_create("Unit test for pico_mld_report_expired");
|
||||
TCase *TCase_mldt_type_compare = tcase_create("Unit test for mldt_type_compare");
|
||||
TCase *TCase_pico_mld_analyse_packet = tcase_create("Unit test for pico_mld_analyse_packet");
|
||||
TCase *TCase_pico_mld_discard = tcase_create("Unit test for pico_mld_discard");
|
||||
TCase *TCase_pico_mld_compatibility_mode = tcase_create("Unit test for pico_mld_compatibility");
|
||||
TCase *TCase_pico_mld_v1querier_expired = tcase_create("Unit test for pico_mld_v1querier_expired");
|
||||
TCase *TCase_pico_mld_delete_parameter = tcase_create("Unit test for pico_mld_delete_parameter");
|
||||
TCase *TCase_pico_mld_timer_expired = tcase_create("Unit test for pico_mld_timer_expired");
|
||||
TCase *TCase_pico_mld_timer_reset = tcase_create("Unit test for pico_mld_timer_reset");
|
||||
TCase *TCase_pico_mld_send_done = tcase_create("Unit test for pico_mld_send_done");
|
||||
TCase *TCase_pico_mld_is_checksum_valid = tcase_create("Unit test for pico_mld_is_checksum");
|
||||
TCase *TCase_pico_mld_find_parameter = tcase_create("Unit test for pico_mld_find_parameter");
|
||||
TCase *TCase_pico_mld_state_change = tcase_create("Unit test for pico_mld_state_change");
|
||||
TCase *TCase_mld_srst = tcase_create("Unit test for pico_mld_srst");
|
||||
TCase *TCase_mld_stcl = tcase_create("Unit test for pico_mld_stcl");
|
||||
TCase *TCase_pico_mld_process_in = tcase_create("Unit test for pico_mld_process_in");
|
||||
TCase *TCase_pico_mld_send_report = tcase_create("Unit test for pico_mld_send_report");
|
||||
TCase *TCase_mld_stsdifs = tcase_create("Unit test for mld_stsdifs");
|
||||
TCase *TCase_mld_srsf = tcase_create("Unit test for mld_srsf");
|
||||
TCase *TCase_mld_rtimrtct = tcase_create("Unit test for mld_rtimrtct");
|
||||
TCase *TCase_mld_mrsrrt = tcase_create("Unit test for mld_mrsrrt");
|
||||
|
||||
tcase_add_test(TCase_pico_mld_fill_hopbyhop, tc_pico_mld_fill_hopbyhop);
|
||||
suite_add_tcase(s, TCase_pico_mld_fill_hopbyhop);
|
||||
tcase_add_test(TCase_pico_mld_check_hopbyhop, tc_pico_mld_check_hopbyhop);
|
||||
suite_add_tcase(s, TCase_pico_mld_check_hopbyhop);
|
||||
tcase_add_test(TCase_pico_mld_report_expired, tc_pico_mld_report_expired);
|
||||
suite_add_tcase(s, TCase_pico_mld_report_expired);
|
||||
tcase_add_test(TCase_mldt_type_compare, tc_mldt_type_compare);
|
||||
suite_add_tcase(s, TCase_mldt_type_compare);
|
||||
tcase_add_test(TCase_pico_mld_analyse_packet, tc_pico_mld_analyse_packet);
|
||||
suite_add_tcase(s, TCase_pico_mld_analyse_packet);
|
||||
tcase_add_test(TCase_pico_mld_discard, tc_pico_mld_discard);
|
||||
suite_add_tcase(s, TCase_pico_mld_discard);
|
||||
tcase_add_test(TCase_pico_mld_compatibility_mode, tc_pico_mld_compatibility_mode);
|
||||
suite_add_tcase(s, TCase_pico_mld_compatibility_mode);
|
||||
tcase_add_test(TCase_pico_mld_v1querier_expired, tc_pico_mld_v1querier_expired);
|
||||
suite_add_tcase(s, TCase_pico_mld_v1querier_expired);
|
||||
tcase_add_test(TCase_pico_mld_delete_parameter, tc_pico_mld_delete_parameter);
|
||||
suite_add_tcase(s, TCase_pico_mld_delete_parameter);
|
||||
tcase_add_test(TCase_pico_mld_timer_expired, tc_pico_mld_timer_expired);
|
||||
suite_add_tcase(s, TCase_pico_mld_timer_expired);
|
||||
tcase_add_test(TCase_pico_mld_timer_reset, tc_pico_mld_timer_reset);
|
||||
suite_add_tcase(s, TCase_pico_mld_timer_reset);
|
||||
tcase_add_test(TCase_pico_mld_send_done, tc_pico_mld_send_done);
|
||||
suite_add_tcase(s, TCase_pico_mld_send_done);
|
||||
tcase_add_test(TCase_pico_mld_is_checksum_valid, tc_pico_mld_is_checksum_valid);
|
||||
suite_add_tcase(s, TCase_pico_mld_is_checksum_valid);
|
||||
tcase_add_test(TCase_pico_mld_find_parameter, tc_pico_mld_find_parameter);
|
||||
suite_add_tcase(s, TCase_pico_mld_find_parameter);
|
||||
tcase_add_test(TCase_pico_mld_state_change, tc_pico_mld_state_change);
|
||||
suite_add_tcase(s, TCase_pico_mld_state_change);
|
||||
tcase_add_test(TCase_mld_srst, tc_mld_srst);
|
||||
suite_add_tcase(s, TCase_mld_srst);
|
||||
tcase_add_test(TCase_mld_stcl, tc_mld_stcl);
|
||||
suite_add_tcase(s, TCase_mld_stcl);
|
||||
tcase_add_test(TCase_pico_mld_process_in, tc_pico_mld_process_in);
|
||||
suite_add_tcase(s, TCase_pico_mld_process_in);
|
||||
tcase_add_test(TCase_pico_mld_send_report, tc_pico_mld_send_report);
|
||||
suite_add_tcase(s, TCase_pico_mld_send_report);
|
||||
tcase_add_test(TCase_mld_stsdifs, tc_mld_stsdifs);
|
||||
suite_add_tcase(s, TCase_mld_stsdifs);
|
||||
tcase_add_test(TCase_mld_srsf, tc_mld_srsf);
|
||||
suite_add_tcase(s, TCase_mld_srsf);
|
||||
tcase_add_test(TCase_mld_rtimrtct, tc_mld_rtimrtct);
|
||||
suite_add_tcase(s, TCase_mld_rtimrtct);
|
||||
tcase_add_test(TCase_mld_mrsrrt, tc_mld_mrsrrt);
|
||||
suite_add_tcase(s, TCase_mld_mrsrrt);
|
||||
return s;
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
229
kernel/picotcp/test/unit/modunit_pico_protocol.c
Normal file
229
kernel/picotcp/test/unit/modunit_pico_protocol.c
Normal file
@ -0,0 +1,229 @@
|
||||
#include "pico_protocol.h"
|
||||
#include "pico_tree.h"
|
||||
#include "stack/pico_protocol.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
volatile pico_err_t pico_err = 0;
|
||||
|
||||
static int protocol_passby = 0;
|
||||
|
||||
static struct pico_frame f = {
|
||||
.next = NULL
|
||||
};
|
||||
|
||||
static struct pico_queue q = {
|
||||
0
|
||||
};
|
||||
|
||||
static struct pico_tree_node NODE_IN = {
|
||||
0
|
||||
};
|
||||
static struct pico_tree_node NODE_OUT = {
|
||||
0
|
||||
};
|
||||
|
||||
#define KEY_IN 0x0D01
|
||||
#define KEY_OUT 0x0D00
|
||||
|
||||
|
||||
START_TEST(tc_pico_proto_cmp)
|
||||
{
|
||||
struct pico_protocol a = {
|
||||
.hash = 0
|
||||
};
|
||||
struct pico_protocol b = {
|
||||
.hash = 1
|
||||
};
|
||||
fail_if(pico_proto_cmp(&a, &b) >= 0);
|
||||
a.hash = 1;
|
||||
fail_if(pico_proto_cmp(&a, &b) != 0);
|
||||
a.hash = 2;
|
||||
fail_if(pico_proto_cmp(&a, &b) <= 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static int modunit_proto_loop_cb_in(struct pico_protocol *self, struct pico_frame *p)
|
||||
{
|
||||
if (!p)
|
||||
protocol_passby = -1; /* Error! */
|
||||
|
||||
if (!self)
|
||||
protocol_passby = -1; /* Error! */
|
||||
|
||||
if (protocol_passby != 0) /* Ensure that we are called only once. */
|
||||
protocol_passby = -1;
|
||||
|
||||
protocol_passby = KEY_IN;
|
||||
|
||||
return 1; /* One frame processed! */
|
||||
}
|
||||
|
||||
static int modunit_proto_loop_cb_out(struct pico_protocol *self, struct pico_frame *p)
|
||||
{
|
||||
if (!p)
|
||||
protocol_passby = -1; /* Error! */
|
||||
|
||||
if (!self)
|
||||
protocol_passby = -1; /* Error! */
|
||||
|
||||
if (protocol_passby != 0) /* Ensure that we are called only once. */
|
||||
protocol_passby = -1;
|
||||
|
||||
protocol_passby = KEY_OUT;
|
||||
|
||||
return 1; /* One frame processed! */
|
||||
}
|
||||
|
||||
START_TEST(tc_proto_loop_in)
|
||||
{
|
||||
struct pico_protocol p = {
|
||||
.process_in = modunit_proto_loop_cb_in, .q_in = &q
|
||||
};
|
||||
protocol_passby = 0;
|
||||
pico_enqueue(p.q_in, &f);
|
||||
fail_if(proto_loop_in(&p, 1) != 0);
|
||||
fail_if(protocol_passby != KEY_IN);
|
||||
|
||||
/* Try to dequeue from empty queue, get same loop_score */
|
||||
protocol_passby = 0;
|
||||
fail_if(proto_loop_in(&p, 1) != 1);
|
||||
fail_if(protocol_passby != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(tc_proto_loop_out)
|
||||
{
|
||||
struct pico_protocol p = {
|
||||
.process_out = modunit_proto_loop_cb_out, .q_out = &q
|
||||
};
|
||||
protocol_passby = 0;
|
||||
pico_enqueue(p.q_out, &f);
|
||||
fail_if(proto_loop_out(&p, 1) != 0);
|
||||
fail_if(protocol_passby != KEY_OUT);
|
||||
|
||||
/* Try to dequeue from empty queue, get same loop_score */
|
||||
protocol_passby = 0;
|
||||
fail_if(proto_loop_out(&p, 1) != 1);
|
||||
fail_if(protocol_passby != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_proto_loop)
|
||||
{
|
||||
struct pico_protocol p = {
|
||||
.process_in = modunit_proto_loop_cb_in,
|
||||
.process_out = modunit_proto_loop_cb_out,
|
||||
.q_in = &q,
|
||||
.q_out = &q
|
||||
};
|
||||
protocol_passby = 0;
|
||||
pico_enqueue(p.q_in, &f);
|
||||
fail_if(proto_loop(&p, 1, PICO_LOOP_DIR_IN) != 0);
|
||||
fail_if(protocol_passby != KEY_IN);
|
||||
|
||||
protocol_passby = 0;
|
||||
pico_enqueue(p.q_out, &f);
|
||||
fail_if(proto_loop(&p, 1, PICO_LOOP_DIR_OUT) != 0);
|
||||
fail_if(protocol_passby != KEY_OUT);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_tree_node)
|
||||
{
|
||||
struct pico_proto_rr rr = {
|
||||
0
|
||||
};
|
||||
rr.node_in = &NODE_IN;
|
||||
rr.node_out = &NODE_OUT;
|
||||
fail_unless(roundrobin_init(&rr, PICO_LOOP_DIR_IN) == &NODE_IN);
|
||||
fail_unless(roundrobin_init(&rr, PICO_LOOP_DIR_OUT) == &NODE_OUT);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_roundrobin_end)
|
||||
{
|
||||
struct pico_proto_rr rr;
|
||||
roundrobin_end(&rr, PICO_LOOP_DIR_IN, &NODE_IN);
|
||||
fail_if(rr.node_in != &NODE_IN);
|
||||
roundrobin_end(&rr, PICO_LOOP_DIR_OUT, &NODE_OUT);
|
||||
fail_if(rr.node_out != &NODE_OUT);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_protocol_generic_loop)
|
||||
{
|
||||
struct pico_proto_rr rr = {
|
||||
0
|
||||
};
|
||||
int ret = 0;
|
||||
|
||||
rr.node_in = &NODE_IN;
|
||||
rr.node_out = &NODE_OUT;
|
||||
ret = pico_protocol_generic_loop(&rr, 0, PICO_LOOP_DIR_IN);
|
||||
|
||||
fail_if(ret != 0);
|
||||
|
||||
pico_protocols_loop(0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(tc_proto_layer_rr_reset)
|
||||
{
|
||||
struct pico_proto_rr rr;
|
||||
rr.node_in = &NODE_IN;
|
||||
rr.node_out = &NODE_OUT;
|
||||
proto_layer_rr_reset(&rr);
|
||||
fail_if(rr.node_in != NULL);
|
||||
fail_if(rr.node_out != NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("pico_protocol.c");
|
||||
|
||||
TCase *TCase_pico_proto_cmp = tcase_create("Unit test for pico_proto_cmp");
|
||||
TCase *TCase_proto_loop_in = tcase_create("Unit test for proto_loop_in");
|
||||
TCase *TCase_proto_loop_out = tcase_create("Unit test for proto_loop_out");
|
||||
TCase *TCase_proto_loop = tcase_create("Unit test for proto_loop");
|
||||
TCase *TCase_pico_tree_node = tcase_create("Unit test for pico_tree_node");
|
||||
TCase *TCase_roundrobin_end = tcase_create("Unit test for roundrobin_end");
|
||||
TCase *TCase_pico_protocol_generic_loop = tcase_create("Unit test for pico_protocol_generic_loop");
|
||||
TCase *TCase_proto_layer_rr_reset = tcase_create("Unit test for proto_layer_rr_reset");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_proto_cmp, tc_pico_proto_cmp);
|
||||
suite_add_tcase(s, TCase_pico_proto_cmp);
|
||||
tcase_add_test(TCase_proto_loop_in, tc_proto_loop_in);
|
||||
suite_add_tcase(s, TCase_proto_loop_in);
|
||||
tcase_add_test(TCase_proto_loop_out, tc_proto_loop_out);
|
||||
suite_add_tcase(s, TCase_proto_loop_out);
|
||||
tcase_add_test(TCase_proto_loop, tc_proto_loop);
|
||||
suite_add_tcase(s, TCase_proto_loop);
|
||||
tcase_add_test(TCase_pico_tree_node, tc_pico_tree_node);
|
||||
suite_add_tcase(s, TCase_pico_tree_node);
|
||||
tcase_add_test(TCase_roundrobin_end, tc_roundrobin_end);
|
||||
suite_add_tcase(s, TCase_roundrobin_end);
|
||||
tcase_add_test(TCase_pico_protocol_generic_loop, tc_pico_protocol_generic_loop);
|
||||
suite_add_tcase(s, TCase_pico_protocol_generic_loop);
|
||||
tcase_add_test(TCase_proto_layer_rr_reset, tc_proto_layer_rr_reset);
|
||||
suite_add_tcase(s, TCase_proto_layer_rr_reset);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
428
kernel/picotcp/test/unit/modunit_pico_sntp_client.c
Normal file
428
kernel/picotcp/test/unit/modunit_pico_sntp_client.c
Normal file
@ -0,0 +1,428 @@
|
||||
#include "pico_sntp_client.h"
|
||||
#include "modules/pico_sntp_client.c"
|
||||
#include "check.h"
|
||||
#include "pico_socket.h"
|
||||
/* Mocking functions, variables, ... */
|
||||
volatile pico_time pico_tick = 0ull;
|
||||
volatile pico_err_t pico_err = 0;
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void cb_synced(pico_err_t status);
|
||||
|
||||
/* Used in pico_sntp_sync_start */
|
||||
struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s))
|
||||
{
|
||||
struct pico_socket *sock = PICO_ZALLOC(sizeof(struct pico_socket));
|
||||
(void) net;
|
||||
(void) proto;
|
||||
(void) wakeup;
|
||||
fail_unless (sock != NULL);
|
||||
return sock;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start */
|
||||
int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port)
|
||||
{
|
||||
(void) s;
|
||||
(void) local_addr;
|
||||
(void) port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start */
|
||||
int pico_socket_close(struct pico_socket *s)
|
||||
{
|
||||
(void) s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_send */
|
||||
int8_t pico_socket_del(struct pico_socket *s)
|
||||
{
|
||||
(void) s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in dnsCallback */
|
||||
int pico_string_to_ipv4(const char *ipstr, uint32_t *ip)
|
||||
{
|
||||
(void) ipstr;
|
||||
(void) ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in dnsCallback */
|
||||
int pico_string_to_ipv6(const char *ipstr, uint8_t *ip)
|
||||
{
|
||||
(void) ipstr;
|
||||
(void) ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start_ipv4 */
|
||||
int pico_ipv4_to_string(char* ipbuf, const uint32_t ip)
|
||||
{
|
||||
(void) ipbuf;
|
||||
(void) ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start_ipv6 */
|
||||
int pico_ipv6_to_string(char* ipbuf, const uint8_t ip[PICO_SIZE_IP6])
|
||||
{
|
||||
(void) ipbuf;
|
||||
(void) ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_client_wakeup */
|
||||
int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, void *orig, uint16_t *remote_port)
|
||||
{
|
||||
(void) s;
|
||||
(void) buf;
|
||||
(void) len;
|
||||
(void) orig;
|
||||
(void) remote_port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_send */
|
||||
int pico_socket_sendto(struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port)
|
||||
{
|
||||
(void) s;
|
||||
(void) buf;
|
||||
(void) len;
|
||||
(void) dst;
|
||||
(void) remote_port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start_dns_ipv4, not tested */
|
||||
int pico_dns_client_getaddr(const char *url, void (*callback)(char *ip, void *arg), void *arg)
|
||||
{
|
||||
(void) url;
|
||||
(void) callback;
|
||||
(void) arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_sync_start_dns_ipv6, not tested */
|
||||
int pico_dns_client_getaddr6(const char *url, void (*callback)(char *, void *), void *arg)
|
||||
{
|
||||
(void) url;
|
||||
(void) callback;
|
||||
(void) arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_parse */
|
||||
void cb_synced(pico_err_t status)
|
||||
{
|
||||
(void) status;
|
||||
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_send */
|
||||
static uint32_t timers_added = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
(void) expire;
|
||||
(void) timer;
|
||||
(void) arg;
|
||||
return ++timers_added;
|
||||
}
|
||||
|
||||
/* Used in pico_sntp_cleanup */
|
||||
void pico_timer_cancel(uint32_t t)
|
||||
{
|
||||
IGNORE_PARAMETER(t);
|
||||
}
|
||||
|
||||
START_TEST(tc_timestamp_convert)
|
||||
{
|
||||
struct pico_sntp_ts ts;
|
||||
struct pico_timeval tv;
|
||||
pico_time delay = 0ull;
|
||||
int ret = 0;
|
||||
|
||||
/* Input is all zero */
|
||||
ts.sec = long_be(0ul);
|
||||
ts.frac = long_be(0ul);
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == -1);
|
||||
ck_assert(tv.tv_sec == 0);
|
||||
ck_assert(tv.tv_msec == 0);
|
||||
|
||||
/* Minimum input*/
|
||||
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
ts.frac = long_be(4310344ul); /* MIN value: 1msec */
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == 0);
|
||||
fail_unless(tv.tv_sec == 1390000000);
|
||||
fail_unless(tv.tv_msec == 1);
|
||||
|
||||
/* Intermediate input */
|
||||
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
ts.frac = long_be(3865470566ul); /* value: 899msec */
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == 0);
|
||||
fail_unless(tv.tv_sec == 1390000000);
|
||||
fail_unless(tv.tv_msec == 900);
|
||||
|
||||
/* Maximum input */
|
||||
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
ts.frac = long_be(4294967295ul); /* MAX value: 999msec */
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == 0);
|
||||
fail_unless(tv.tv_sec == 1390000001);
|
||||
fail_unless(tv.tv_msec == 0);
|
||||
|
||||
/* Intermediate input with delay */
|
||||
ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
ts.frac = long_be(3865470566ul); /* value: 899msec */
|
||||
delay = 200ull;
|
||||
ret = timestamp_convert(&ts, &tv, delay);
|
||||
ck_assert(ret == 0);
|
||||
fail_unless(tv.tv_sec == 1390000001);
|
||||
fail_unless(tv.tv_msec == 100);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_cleanup)
|
||||
{
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
struct pico_socket *sock;
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
fail_unless (ck != NULL);
|
||||
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
|
||||
fail_unless (ck->hostname != NULL);
|
||||
ck->stamp = 0ull;
|
||||
ck->cb_synced = cb_synced;
|
||||
|
||||
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
|
||||
ck->sock = sock;
|
||||
sock->priv = ck;
|
||||
|
||||
|
||||
pico_sntp_cleanup(ck, PICO_ERR_NOERR);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_parse)
|
||||
{
|
||||
/* TODO: test this: static void pico_sntp_parse(char *buf, struct sntp_server_ns_cookie *ck) */
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
struct pico_socket *sock;
|
||||
struct pico_sntp_header header = {
|
||||
0
|
||||
};
|
||||
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
fail_unless (ck != NULL);
|
||||
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
|
||||
fail_unless (ck->hostname != NULL);
|
||||
ck->stamp = 0ull;
|
||||
ck->cb_synced = cb_synced;
|
||||
|
||||
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
|
||||
ck->sock = sock;
|
||||
sock->priv = ck;
|
||||
|
||||
header.mode = 4; /* server mode */
|
||||
header.vn = 4; /* sntp version 4 */
|
||||
header.stratum = 1; /* primary reference */
|
||||
header.trs_ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul);
|
||||
header.trs_ts.frac = long_be(3865470566ul); /* value: 899msec */
|
||||
|
||||
fail_if(pico_sntp_parse((char *) &header, NULL) == 0);
|
||||
fail_if(pico_sntp_parse((char *) &header, ck) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_client_wakeup)
|
||||
{
|
||||
/* TODO: test this: static void pico_sntp_client_wakeup(uint16_t ev, struct pico_socket *s) */
|
||||
uint16_t event = PICO_SOCK_EV_ERR;
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
struct pico_socket *sock;
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
fail_unless (ck != NULL);
|
||||
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
|
||||
fail_unless (ck->hostname != NULL);
|
||||
ck->stamp = 0ull;
|
||||
ck->cb_synced = cb_synced;
|
||||
|
||||
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
|
||||
ck->sock = sock;
|
||||
sock->priv = ck;
|
||||
|
||||
ck->cb_synced = cb_synced;
|
||||
printf("Started wakeup unit test\n");
|
||||
|
||||
pico_sntp_client_wakeup(event, sock);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_sntp_receive_timeout)
|
||||
{
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
struct pico_socket *sock;
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
fail_unless (ck != NULL);
|
||||
ck->hostname = PICO_ZALLOC(sizeof(char) * 5);
|
||||
fail_unless (ck->hostname != NULL);
|
||||
ck->stamp = 0ull;
|
||||
ck->cb_synced = cb_synced;
|
||||
|
||||
sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup);
|
||||
ck->sock = sock;
|
||||
sock->priv = ck;
|
||||
sntp_receive_timeout(0ull, ck);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_send)
|
||||
{
|
||||
/* TODO: test this: static void pico_sntp_send(struct pico_socket *sock, union pico_address *dst) */
|
||||
struct pico_socket sock = {
|
||||
0
|
||||
};
|
||||
union pico_address dst;
|
||||
struct sntp_server_ns_cookie ck = {
|
||||
0
|
||||
};
|
||||
sock.priv = &ck;
|
||||
|
||||
pico_sntp_send(&sock, &dst);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_dnsCallback)
|
||||
{
|
||||
/* TODO: test this: static void dnsCallback(char *ip, void *arg) */
|
||||
char ip[] = "198.123.30.132";
|
||||
struct sntp_server_ns_cookie *ck;
|
||||
ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie));
|
||||
|
||||
dnsCallback(ip, ck);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync)
|
||||
{
|
||||
const char *sntp_server= "ntp.nasa.gov";
|
||||
|
||||
fail_if(pico_sntp_sync(NULL, cb_synced) == 0);
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
|
||||
fail_if(pico_sntp_sync(sntp_server, NULL) == 0);
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
|
||||
fail_if(pico_sntp_sync(sntp_server, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_ip)
|
||||
{
|
||||
union pico_address sntp_addr = { .ip4.addr = 0ul };
|
||||
|
||||
fail_if(pico_sntp_sync_ip(NULL, cb_synced) == 0);
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
|
||||
fail_if(pico_sntp_sync_ip(&sntp_addr, NULL) == 0);
|
||||
fail_if(pico_err != PICO_ERR_EINVAL);
|
||||
|
||||
fail_if(pico_sntp_sync_ip(&sntp_addr, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start)
|
||||
{
|
||||
struct sntp_server_ns_cookie ck = { 0 };
|
||||
union pico_address sntp_addr = { .ip4.addr= 0ul };
|
||||
|
||||
fail_if(pico_sntp_sync_start(&ck, &sntp_addr) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start_dns_ipv4)
|
||||
{
|
||||
const char *sntp_server = "ntp.nasa.gov";
|
||||
|
||||
fail_if(pico_sntp_sync_start_dns_ipv4(sntp_server, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start_dns_ipv6)
|
||||
{
|
||||
const char *sntp_server = "ntp.nasa.gov";
|
||||
|
||||
fail_if(pico_sntp_sync_start_dns_ipv6(sntp_server, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start_ipv4)
|
||||
{
|
||||
union pico_address sntp_addr = { .ip4.addr = 0};
|
||||
|
||||
fail_if(pico_sntp_sync_start_ipv4(&sntp_addr, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_sntp_sync_start_ipv6)
|
||||
{
|
||||
union pico_address sntp_addr = { .ip6.addr = { 0 } };
|
||||
|
||||
fail_if(pico_sntp_sync_start_ipv6(&sntp_addr, cb_synced) != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_timestamp_convert = tcase_create("Unit test for pico_timeval");
|
||||
TCase *TCase_pico_sntp_cleanup = tcase_create("Unit test for pico_sntp_cleanup");
|
||||
TCase *TCase_pico_sntp_send = tcase_create("Unit test for pico_sntp_send");
|
||||
TCase *TCase_pico_sntp_parse = tcase_create("Unit test for pico_sntp_parse");
|
||||
TCase *TCase_pico_sntp_client_wakeup = tcase_create("Unit test for pico_sntp_client_wakeup");
|
||||
TCase *TCase_sntp_receive_timeout = tcase_create("Unit test for sntp_receive_timeout");
|
||||
TCase *TCase_dnsCallback = tcase_create("Unit test for dnsCallback");
|
||||
TCase *TCase_pico_sntp_sync = tcase_create("Unit test for pico_sntp_sync");
|
||||
TCase *TCase_pico_sntp_sync_ip = tcase_create("Unit test for pico_sntp_sync_ip");
|
||||
TCase *TCase_pico_sntp_sync_start = tcase_create("Unit test for pico_sntp_sync_start");
|
||||
TCase *TCase_pico_sntp_sync_start_dns_ipv4 = tcase_create("Unit test for pico_sntp_sync_start_dns_ipv4");
|
||||
TCase *TCase_pico_sntp_sync_start_dns_ipv6 = tcase_create("Unit test for pico_sntp_sync_start_dns_ipv6");
|
||||
TCase *TCase_pico_sntp_sync_start_ipv4 = tcase_create("Unit test for pico_sntp_sync_start_ipv4");
|
||||
TCase *TCase_pico_sntp_sync_start_ipv6 = tcase_create("Unit test for pico_sntp_sync_start_ipv6");
|
||||
|
||||
|
||||
tcase_add_test(TCase_timestamp_convert, tc_timestamp_convert);
|
||||
suite_add_tcase(s, TCase_timestamp_convert);
|
||||
tcase_add_test(TCase_pico_sntp_cleanup, tc_pico_sntp_cleanup);
|
||||
suite_add_tcase(s, TCase_pico_sntp_cleanup);
|
||||
tcase_add_test(TCase_pico_sntp_parse, tc_pico_sntp_parse);
|
||||
suite_add_tcase(s, TCase_pico_sntp_parse);
|
||||
tcase_add_test(TCase_pico_sntp_client_wakeup, tc_pico_sntp_client_wakeup);
|
||||
suite_add_tcase(s, TCase_pico_sntp_client_wakeup);
|
||||
tcase_add_test(TCase_sntp_receive_timeout, tc_sntp_receive_timeout);
|
||||
suite_add_tcase(s, TCase_sntp_receive_timeout);
|
||||
tcase_add_test(TCase_pico_sntp_send, tc_pico_sntp_send);
|
||||
suite_add_tcase(s, TCase_pico_sntp_send);
|
||||
tcase_add_test(TCase_dnsCallback, tc_dnsCallback);
|
||||
suite_add_tcase(s, TCase_dnsCallback);
|
||||
tcase_add_test(TCase_pico_sntp_sync, tc_pico_sntp_sync);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync);
|
||||
tcase_add_test(TCase_pico_sntp_sync_ip, tc_pico_sntp_sync_ip);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_ip);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start, tc_pico_sntp_sync_start);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start_dns_ipv4, tc_pico_sntp_sync_start_dns_ipv4);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start_dns_ipv4);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start_dns_ipv6, tc_pico_sntp_sync_start_dns_ipv6);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start_dns_ipv6);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start_ipv4, tc_pico_sntp_sync_start_ipv4);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start_ipv4);
|
||||
tcase_add_test(TCase_pico_sntp_sync_start_ipv6, tc_pico_sntp_sync_start_ipv6);
|
||||
suite_add_tcase(s, TCase_pico_sntp_sync_start_ipv6);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
145
kernel/picotcp/test/unit/modunit_pico_stack.c
Normal file
145
kernel/picotcp/test/unit/modunit_pico_stack.c
Normal file
@ -0,0 +1,145 @@
|
||||
#include "pico_config.h"
|
||||
#include "pico_frame.h"
|
||||
#include "pico_device.h"
|
||||
#include "pico_protocol.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_addressing.h"
|
||||
#include "pico_dns_client.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_arp.h"
|
||||
#include "pico_ipv4.h"
|
||||
#include "pico_ipv6.h"
|
||||
#include "pico_icmp4.h"
|
||||
#include "pico_igmp.h"
|
||||
#include "pico_udp.h"
|
||||
#include "pico_tcp.h"
|
||||
#include "pico_socket.h"
|
||||
#include "heap.h"
|
||||
#include "stack/pico_stack.c"
|
||||
#include "check.h"
|
||||
|
||||
|
||||
Suite *pico_suite(void);
|
||||
void fake_timer(pico_time __attribute__((unused)) now, void __attribute__((unused)) *n);
|
||||
|
||||
START_TEST(tc_pico_ll_receive)
|
||||
{
|
||||
/* TODO: test this: static int32_t pico_ll_receive(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ll_check_bcast)
|
||||
{
|
||||
/* TODO: test this: static void pico_ll_check_bcast(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_destination_is_bcast)
|
||||
{
|
||||
/* TODO: test this: static int destination_is_bcast(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_destination_is_mcast)
|
||||
{
|
||||
/* TODO: test this: static int destination_is_mcast(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_eth)
|
||||
{
|
||||
/* TODO: test this: static struct pico_eth *pico_ethernet_mcast_translate(struct pico_frame *f, uint8_t *pico_mcast_mac) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ethsend_local)
|
||||
{
|
||||
/* TODO: test this: static int32_t pico_ethsend_local(struct pico_frame *f, struct pico_eth_hdr *hdr, int *ret) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ethsend_bcast)
|
||||
{
|
||||
/* TODO: test this: static int32_t pico_ethsend_bcast(struct pico_frame *f, int *ret) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_ethsend_dispatch)
|
||||
{
|
||||
/* TODO: test this: static int32_t pico_ethsend_dispatch(struct pico_frame *f, int *ret) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_calc_score)
|
||||
{
|
||||
/* TODO: test this: static int calc_score(int *score, int *index, int avg[][PROTO_DEF_AVG_NR], int *ret) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
void fake_timer(pico_time __attribute__((unused)) now, void __attribute__((unused)) *n)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
START_TEST(tc_stack_generic)
|
||||
{
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in pico_stack_init (11)\n");
|
||||
pico_set_mm_failure(13);
|
||||
fail_if(pico_stack_init() != -1);
|
||||
#endif
|
||||
pico_stack_init();
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in pico_timer_add (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_timer_add(0, fake_timer, NULL) != 0);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_pico_ll_receive = tcase_create("Unit test for pico_ll_receive");
|
||||
TCase *TCase_pico_ll_check_bcast = tcase_create("Unit test for pico_ll_check_bcast");
|
||||
TCase *TCase_destination_is_bcast = tcase_create("Unit test for destination_is_bcast");
|
||||
TCase *TCase_destination_is_mcast = tcase_create("Unit test for destination_is_mcast");
|
||||
TCase *TCase_pico_eth = tcase_create("Unit test for pico_eth");
|
||||
TCase *TCase_pico_ethsend_local = tcase_create("Unit test for pico_ethsend_local");
|
||||
TCase *TCase_pico_ethsend_bcast = tcase_create("Unit test for pico_ethsend_bcast");
|
||||
TCase *TCase_pico_ethsend_dispatch = tcase_create("Unit test for pico_ethsend_dispatch");
|
||||
TCase *TCase_calc_score = tcase_create("Unit test for calc_score");
|
||||
TCase *TCase_stack_generic = tcase_create("GENERIC stack initialization unit test");
|
||||
|
||||
|
||||
tcase_add_test(TCase_pico_ll_receive, tc_pico_ll_receive);
|
||||
suite_add_tcase(s, TCase_pico_ll_receive);
|
||||
tcase_add_test(TCase_pico_ll_check_bcast, tc_pico_ll_check_bcast);
|
||||
suite_add_tcase(s, TCase_pico_ll_check_bcast);
|
||||
tcase_add_test(TCase_destination_is_bcast, tc_destination_is_bcast);
|
||||
suite_add_tcase(s, TCase_destination_is_bcast);
|
||||
tcase_add_test(TCase_destination_is_mcast, tc_destination_is_mcast);
|
||||
suite_add_tcase(s, TCase_destination_is_mcast);
|
||||
tcase_add_test(TCase_pico_eth, tc_pico_eth);
|
||||
suite_add_tcase(s, TCase_pico_eth);
|
||||
tcase_add_test(TCase_pico_ethsend_local, tc_pico_ethsend_local);
|
||||
suite_add_tcase(s, TCase_pico_ethsend_local);
|
||||
tcase_add_test(TCase_pico_ethsend_bcast, tc_pico_ethsend_bcast);
|
||||
suite_add_tcase(s, TCase_pico_ethsend_bcast);
|
||||
tcase_add_test(TCase_pico_ethsend_dispatch, tc_pico_ethsend_dispatch);
|
||||
suite_add_tcase(s, TCase_pico_ethsend_dispatch);
|
||||
tcase_add_test(TCase_calc_score, tc_calc_score);
|
||||
suite_add_tcase(s, TCase_calc_score);
|
||||
tcase_add_test(TCase_stack_generic, tc_stack_generic);
|
||||
suite_add_tcase(s, TCase_stack_generic);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
59
kernel/picotcp/test/unit/modunit_pico_strings.c
Normal file
59
kernel/picotcp/test/unit/modunit_pico_strings.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include "modules/pico_strings.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_get_string_terminator_position)
|
||||
{
|
||||
char buf[6] = "unit";
|
||||
get_string_terminator_position(NULL,0);
|
||||
fail_if(get_string_terminator_position(buf,2) != 0);
|
||||
fail_if(get_string_terminator_position(buf,6) != &buf[4]);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_strncasecmp)
|
||||
{
|
||||
fail_if(pico_strncasecmp("unit","UNIT",4) != 0);
|
||||
fail_if(pico_strncasecmp("unit1","UNIT2",5) != -1);
|
||||
fail_if(pico_strncasecmp("unit2","UNIT1",5) != 1);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_num2string)
|
||||
{
|
||||
char buf[20];
|
||||
fail_if(num2string(-1,NULL,1) != -1);
|
||||
fail_if(num2string(1,NULL,1) != -1);
|
||||
fail_if(num2string(1,buf,1) != -1);
|
||||
fail_if(num2string(1,buf,3) != 2);
|
||||
fail_if(num2string(11,buf,3) != 3);
|
||||
fail_if(num2string(112,buf,4) != 4);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_get_string_terminator_position = tcase_create("Unit test for get_string_terminator_position");
|
||||
TCase *TCase_num2string = tcase_create("Unit test for num2string");
|
||||
TCase *TCase_pico_strncasecmp = tcase_create("Unit test for pico_strncasecmp");
|
||||
|
||||
tcase_add_test(TCase_get_string_terminator_position, tc_get_string_terminator_position);
|
||||
suite_add_tcase(s, TCase_get_string_terminator_position);
|
||||
tcase_add_test(TCase_num2string,tc_num2string);
|
||||
suite_add_tcase(s, TCase_num2string);
|
||||
tcase_add_test(TCase_pico_strncasecmp,tc_pico_strncasecmp);
|
||||
suite_add_tcase(s, TCase_pico_strncasecmp);
|
||||
|
||||
return s;
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
863
kernel/picotcp/test/unit/modunit_pico_tcp.c
Normal file
863
kernel/picotcp/test/unit/modunit_pico_tcp.c
Normal file
@ -0,0 +1,863 @@
|
||||
#include "pico_tcp.h"
|
||||
#include "pico_config.h"
|
||||
#include "pico_eth.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_stack.h"
|
||||
#include "pico_socket.h"
|
||||
#include "pico_queue.h"
|
||||
#include "pico_tree.h"
|
||||
#include "modules/pico_tcp.c"
|
||||
#include "check.h"
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
static uint32_t timers_added = 0;
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
IGNORE_PARAMETER(expire);
|
||||
IGNORE_PARAMETER(timer);
|
||||
IGNORE_PARAMETER(arg);
|
||||
return ++timers_added;
|
||||
}
|
||||
|
||||
START_TEST(tc_input_segment_compare)
|
||||
{
|
||||
struct tcp_input_segment A = {
|
||||
.seq = 0xFFFFFFFF
|
||||
};
|
||||
struct tcp_input_segment B = {
|
||||
.seq = 0xFFFFFFFe
|
||||
};
|
||||
struct tcp_input_segment a = {
|
||||
.seq = 0x01
|
||||
};
|
||||
struct tcp_input_segment b = {
|
||||
.seq = 0x02
|
||||
};
|
||||
|
||||
fail_if(input_segment_compare(&A, &B) <= 0);
|
||||
fail_if(input_segment_compare(&a, &b) >= 0);
|
||||
fail_if(input_segment_compare(&A, &b) >= 0);
|
||||
fail_if(input_segment_compare(&A, &A) != 0);
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_input_segment)
|
||||
{
|
||||
/* TODO: test this: static struct tcp_input_segment *segment_from_frame(struct pico_frame *f) */
|
||||
struct pico_frame *f = pico_frame_alloc(60);
|
||||
struct tcp_input_segment *seg;
|
||||
|
||||
fail_if(!f);
|
||||
f->payload = f->start;
|
||||
f->payload_len = 60;
|
||||
f->transport_hdr = f->payload;
|
||||
f->transport_len = (uint16_t)(f->payload_len - 40);
|
||||
memset(f->payload, 'c', f->payload_len);
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xdeadbeef);
|
||||
|
||||
seg = segment_from_frame(f);
|
||||
fail_if(!seg);
|
||||
fail_if(seg->seq != 0xdeadbeef);
|
||||
fail_if(seg->payload_len != f->payload_len);
|
||||
fail_if(memcmp(seg->payload, f->payload, f->payload_len) != 0);
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
printf("Testing with faulty memory in segment_from_frame (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
seg = segment_from_frame(f);
|
||||
fail_if(seg);
|
||||
|
||||
printf("Testing with faulty memory in segment_from_frame (2)\n");
|
||||
pico_set_mm_failure(2);
|
||||
seg = segment_from_frame(f);
|
||||
fail_if(seg);
|
||||
#endif
|
||||
printf("Testing segment_from_frame with empty payload\n");
|
||||
f->payload_len = 0;
|
||||
seg = segment_from_frame(f);
|
||||
fail_if(seg);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_segment_compare)
|
||||
{
|
||||
/* TODO: test this: static int segment_compare(void *ka, void *kb) */
|
||||
struct pico_frame *a = pico_frame_alloc(40);
|
||||
struct pico_frame *b = pico_frame_alloc(60);
|
||||
a->transport_hdr = a->start;
|
||||
b->transport_hdr = b->start;
|
||||
|
||||
((struct pico_tcp_hdr *)((b)->transport_hdr))->seq = long_be(0xaa00);
|
||||
((struct pico_tcp_hdr *)((a)->transport_hdr))->seq = long_be(0xffffaa00);
|
||||
fail_if(segment_compare(a, b) >= 0);
|
||||
fail_if(segment_compare(a, a) != 0);
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_discard_all_segments)
|
||||
{
|
||||
struct pico_socket_tcp *t = (struct pico_socket_tcp *)pico_tcp_open(PICO_PROTO_IPV4);
|
||||
struct pico_frame *f = pico_frame_alloc(80);
|
||||
struct tcp_input_segment *is;
|
||||
fail_if(!t);
|
||||
fail_if(!f);
|
||||
|
||||
printf("Testing enqueuing bogus frame\n");
|
||||
f->buffer_len = 0;
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) >= 0);
|
||||
f->buffer_len = 80;
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)(f->buffer_len - 40);
|
||||
f->payload = f->start + 40;
|
||||
f->payload_len = 40;
|
||||
memset(f->payload, 'c', f->payload_len);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(!is);
|
||||
is->payload_len = 0;
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) >= 0);
|
||||
is->payload_len = 40;
|
||||
|
||||
/* Successfull cases */
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) <= 0);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) <= 0);
|
||||
|
||||
/* Fail because size exceeded. Must return 0. */
|
||||
t->tcpq_out.max_size = 50;
|
||||
t->tcpq_in.max_size = 50;
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) != 0);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) != 0);
|
||||
|
||||
|
||||
#ifdef PICO_FAULTY
|
||||
/* Fail because the tree cannot allocate a new node. Should return 0 */
|
||||
printf("Testing with faulty memory (1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) > 0);
|
||||
pico_set_mm_failure(1);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) > 0);
|
||||
|
||||
printf("Testing input segment conversion with faulty mm(1)\n");
|
||||
pico_set_mm_failure(1);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(is);
|
||||
printf("Testing input segment conversion with faulty mm(2)\n");
|
||||
pico_set_mm_failure(2);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(is);
|
||||
#endif
|
||||
|
||||
/* Discard all segments */
|
||||
fail_if(t->tcpq_out.size == 0);
|
||||
fail_if(t->tcpq_out.frames == 0);
|
||||
tcp_discard_all_segments(&t->tcpq_out);
|
||||
fail_if(t->tcpq_out.size != 0);
|
||||
fail_if(t->tcpq_out.frames != 0);
|
||||
|
||||
fail_if(t->tcpq_in.size == 0);
|
||||
fail_if(t->tcpq_in.frames == 0);
|
||||
fail_if(pico_tcp_queue_in_is_empty(&t->sock));
|
||||
|
||||
tcp_discard_all_segments(&t->tcpq_in);
|
||||
fail_if(t->tcpq_in.size != 0);
|
||||
fail_if(t->tcpq_in.frames != 0);
|
||||
fail_unless(pico_tcp_queue_in_is_empty(&t->sock));
|
||||
|
||||
|
||||
/* Testing next_segment with NULLS */
|
||||
fail_if(next_segment(NULL, NULL) != NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_release_until)
|
||||
{
|
||||
struct pico_socket_tcp *t = (struct pico_socket_tcp *)pico_tcp_open(PICO_PROTO_IPV6);
|
||||
struct pico_frame *f;
|
||||
uint32_t i = 0;
|
||||
int ret = 0;
|
||||
struct tcp_input_segment *is;
|
||||
fail_if(!t);
|
||||
ret = release_until(&t->tcpq_out, 0);
|
||||
fail_unless(ret == 0);
|
||||
|
||||
/* Test with output queue */
|
||||
for (i = 0; i < 32; i++) {
|
||||
f = pico_frame_alloc(84);
|
||||
fail_if(!f);
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xaa00 + f->buffer_len * i);
|
||||
printf("inserting frame seq = %08x len = %d\n", 0xaa00 + f->buffer_len * i, f->buffer_len);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) <= 0);
|
||||
}
|
||||
ret = release_until(&t->tcpq_out, 0xaa00 + f->buffer_len * 30);
|
||||
printf("Release until %08x\n", 0xaa00 + f->buffer_len * 30);
|
||||
fail_if(ret != 30);
|
||||
printf("Ret is %d\n", ret);
|
||||
printf("Remaining is %d\n", t->tcpq_out.frames);
|
||||
fail_if(t->tcpq_out.frames != 2);
|
||||
|
||||
/* Test with input queue */
|
||||
for (i = 0; i < 32; i++) {
|
||||
f = pico_frame_alloc(84);
|
||||
fail_if(!f);
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
f->payload = f->start;
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xaa00 + f->buffer_len * i);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(!is);
|
||||
printf("inserting Input frame seq = %08x len = %d\n", long_be(is->seq), is->payload_len);
|
||||
fail_if(!is);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) <= 0);
|
||||
}
|
||||
ret = release_until(&t->tcpq_in, 0xaa00 + f->buffer_len * 30);
|
||||
printf("Release until %08x\n", 0xaa00 + f->buffer_len * 30);
|
||||
fail_if(ret != 30);
|
||||
printf("Ret is %d\n", ret);
|
||||
printf("Remaining is %d\n", t->tcpq_out.frames);
|
||||
fail_if(t->tcpq_out.frames != 2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_release_all_until)
|
||||
{
|
||||
struct pico_socket_tcp *t = (struct pico_socket_tcp *)pico_tcp_open(PICO_PROTO_IPV4);
|
||||
struct pico_frame *f;
|
||||
uint32_t i = 0;
|
||||
int ret = 0;
|
||||
struct tcp_input_segment *is;
|
||||
pico_time tm;
|
||||
fail_if(!t);
|
||||
ret = release_all_until(&t->tcpq_out, 0, &tm);
|
||||
fail_unless(ret == 0);
|
||||
|
||||
/* Test with output queue */
|
||||
for (i = 0; i < 32; i++) {
|
||||
f = pico_frame_alloc(84);
|
||||
fail_if(!f);
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xaa00 + f->buffer_len * i);
|
||||
printf("inserting frame seq = %08x len = %d\n", 0xaa00 + f->buffer_len * i, f->buffer_len);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_out, f) <= 0);
|
||||
}
|
||||
ret = release_all_until(&t->tcpq_out, 0xaa00 + f->buffer_len * 30, &tm);
|
||||
printf("Release until %08x\n", 0xaa00 + f->buffer_len * 30);
|
||||
fail_if(ret != 30);
|
||||
printf("Ret is %d\n", ret);
|
||||
printf("Remaining is %d\n", t->tcpq_out.frames);
|
||||
fail_if(t->tcpq_out.frames != 2);
|
||||
|
||||
/* Test with input queue */
|
||||
for (i = 0; i < 32; i++) {
|
||||
f = pico_frame_alloc(84);
|
||||
fail_if(!f);
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
f->payload = f->start;
|
||||
((struct pico_tcp_hdr *)((f)->transport_hdr))->seq = long_be(0xaa00 + f->buffer_len * i);
|
||||
is = segment_from_frame(f);
|
||||
fail_if(!is);
|
||||
printf("inserting Input frame seq = %08x len = %d\n", long_be(is->seq), is->payload_len);
|
||||
fail_if(!is);
|
||||
fail_if(pico_enqueue_segment(&t->tcpq_in, is) <= 0);
|
||||
}
|
||||
ret = release_all_until(&t->tcpq_in, 0xaa00 + f->buffer_len * 30, &tm);
|
||||
printf("Release until %08x\n", 0xaa00 + f->buffer_len * 30);
|
||||
fail_if(ret != 30);
|
||||
printf("Ret is %d\n", ret);
|
||||
printf("Remaining is %d\n", t->tcpq_out.frames);
|
||||
fail_if(t->tcpq_out.frames != 2);
|
||||
|
||||
/* Test enqueue_segment with NULL segment */
|
||||
fail_if(pico_enqueue_segment(NULL, NULL) != -1);
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_fin)
|
||||
{
|
||||
/* TODO: test this: static void tcp_send_fin(struct pico_socket_tcp *t); */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_tcp_process_out)
|
||||
{
|
||||
/* TODO: test this: static int pico_tcp_process_out(struct pico_protocol *self, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_pico_paws)
|
||||
{
|
||||
pico_paws();
|
||||
/* Nothing to test for a random function...*/
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(tc_tcp_add_options)
|
||||
{
|
||||
/* TODO: test this: static void tcp_add_options(struct pico_socket_tcp *ts, struct pico_frame *f, uint16_t flags, uint16_t optsiz) */
|
||||
struct pico_socket_tcp ts = { };
|
||||
struct pico_frame *f = pico_frame_alloc(100);
|
||||
uint16_t flags = 0;
|
||||
uint16_t optsiz = 50;
|
||||
uint8_t *frame_opt_buff;
|
||||
int i;
|
||||
struct tcp_sack_block *a, *b, *c;
|
||||
uint32_t al = 0xa0,
|
||||
ar = 0xaf,
|
||||
bl = 0xb0,
|
||||
br = 0xbf,
|
||||
cl = 0xc0,
|
||||
cr = 0xcf;
|
||||
f->transport_hdr = f->start;
|
||||
f->transport_len = (uint16_t)f->buffer_len;
|
||||
f->payload_len = f->transport_len;
|
||||
frame_opt_buff = f->transport_hdr + PICO_SIZE_TCPHDR;
|
||||
|
||||
/* Window scale only */
|
||||
printf("Testing window scale option\n");
|
||||
ts.wnd_scale = 66;
|
||||
tcp_add_options(&ts, f, flags, optsiz);
|
||||
fail_if(frame_opt_buff[0] != PICO_TCP_OPTION_WS);
|
||||
fail_if(frame_opt_buff[1] != PICO_TCPOPTLEN_WS);
|
||||
fail_if(frame_opt_buff[2] != 66);
|
||||
for (i = 3; i < optsiz - 1; i++)
|
||||
fail_if(frame_opt_buff[i] != PICO_TCP_OPTION_NOOP);
|
||||
fail_if(frame_opt_buff[optsiz - 1] != PICO_TCP_OPTION_END);
|
||||
|
||||
/* MSS + SACK_OK + WS + TIMESTAMPS */
|
||||
printf("Testing full SYN options\n");
|
||||
flags = PICO_TCP_SYN;
|
||||
ts.wnd_scale = 66;
|
||||
ts.mss = 0xAA88;
|
||||
tcp_add_options(&ts, f, flags, optsiz);
|
||||
fail_if(frame_opt_buff[0] != PICO_TCP_OPTION_MSS);
|
||||
fail_if(frame_opt_buff[1] != PICO_TCPOPTLEN_MSS);
|
||||
fail_if(frame_opt_buff[2] != 0xAA);
|
||||
fail_if(frame_opt_buff[3] != 0x88);
|
||||
fail_if(frame_opt_buff[4] != PICO_TCP_OPTION_SACK_OK);
|
||||
fail_if(frame_opt_buff[5] != PICO_TCPOPTLEN_SACK_OK);
|
||||
fail_if(frame_opt_buff[6] != PICO_TCP_OPTION_WS);
|
||||
fail_if(frame_opt_buff[7] != PICO_TCPOPTLEN_WS);
|
||||
fail_if(frame_opt_buff[8] != 66);
|
||||
fail_if(frame_opt_buff[9] != PICO_TCP_OPTION_TIMESTAMP);
|
||||
fail_if(frame_opt_buff[10] != PICO_TCPOPTLEN_TIMESTAMP);
|
||||
/* Timestamps: up to byte 18 */
|
||||
for (i = 19; i < optsiz - 1; i++)
|
||||
fail_if(frame_opt_buff[i] != PICO_TCP_OPTION_NOOP);
|
||||
fail_if(frame_opt_buff[optsiz - 1] != PICO_TCP_OPTION_END);
|
||||
|
||||
/* Testing SACKs */
|
||||
printf("Testing full SACK options\n");
|
||||
a = PICO_ZALLOC(sizeof (struct tcp_sack_block));
|
||||
b = PICO_ZALLOC(sizeof (struct tcp_sack_block));
|
||||
c = PICO_ZALLOC(sizeof (struct tcp_sack_block));
|
||||
a->left = al;
|
||||
a->right = ar;
|
||||
a->next = b;
|
||||
b->left = bl;
|
||||
b->right = br;
|
||||
b->next = c;
|
||||
c->left = cl;
|
||||
c->right = cr;
|
||||
c->next = NULL;
|
||||
|
||||
ts.sack_ok = 1;
|
||||
ts.sacks = a;
|
||||
flags = PICO_TCP_ACK;
|
||||
tcp_add_options(&ts, f, flags, optsiz);
|
||||
fail_if(frame_opt_buff[0] != PICO_TCP_OPTION_WS);
|
||||
fail_if(frame_opt_buff[1] != PICO_TCPOPTLEN_WS);
|
||||
fail_if(frame_opt_buff[2] != 66);
|
||||
fail_if(frame_opt_buff[3] != PICO_TCP_OPTION_SACK);
|
||||
fail_if(frame_opt_buff[4] != PICO_TCPOPTLEN_SACK + 6 * (sizeof(uint32_t)));
|
||||
fail_if(memcmp(frame_opt_buff + 5, &al, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 9, &ar, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 13, &bl, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 17, &br, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 21, &cl, 4) != 0);
|
||||
fail_if(memcmp(frame_opt_buff + 25, &cr, 4) != 0);
|
||||
fail_if(ts.sacks != NULL);
|
||||
for (i = 29; i < optsiz - 1; i++)
|
||||
fail_if(frame_opt_buff[i] != PICO_TCP_OPTION_NOOP);
|
||||
fail_if(frame_opt_buff[optsiz - 1] != PICO_TCP_OPTION_END);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_options_size_frame)
|
||||
{
|
||||
/* TODO: test this: static uint16_t tcp_options_size_frame(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_add_options_frame)
|
||||
{
|
||||
/* TODO: test this: static void tcp_add_options_frame(struct pico_socket_tcp *ts, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_ack)
|
||||
{
|
||||
/* TODO: test this: static void tcp_send_ack(struct pico_socket_tcp *t); */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_set_space)
|
||||
{
|
||||
/* TODO: test this: static void tcp_set_space(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_options_size)
|
||||
{
|
||||
/* TODO: test this: static uint16_t tcp_options_size(struct pico_socket_tcp *t, uint16_t flags) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_process_sack)
|
||||
{
|
||||
/* TODO: test this: static void tcp_process_sack(struct pico_socket_tcp *t, uint32_t start, uint32_t end) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rcv_sack)
|
||||
{
|
||||
/* TODO: test this: static void tcp_rcv_sack(struct pico_socket_tcp *t, uint8_t *opt, int len) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_parse_options)
|
||||
{
|
||||
/* TODO: test this: static void tcp_parse_options(struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send)
|
||||
{
|
||||
/* TODO: test this: static int tcp_send(struct pico_socket_tcp *ts, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_sock_stats)
|
||||
{
|
||||
/* TODO: test this: static void sock_stats(uint32_t when, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_initconn_retry)
|
||||
{
|
||||
/* TODO: test this: static void initconn_retry(pico_time when, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_synack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_send_synack(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_empty)
|
||||
{
|
||||
/* TODO: test this: static void tcp_send_empty(struct pico_socket_tcp *t, uint16_t flags, int is_keepalive) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_probe)
|
||||
{
|
||||
/* TODO: test this: static void tcp_send_probe(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_send_rst)
|
||||
{
|
||||
/* TODO: test this: static int tcp_send_rst(struct pico_socket *s, struct pico_frame *fr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_nosync_rst)
|
||||
{
|
||||
/* TODO: test this: static int tcp_nosync_rst(struct pico_socket *s, struct pico_frame *fr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_sack_prepare)
|
||||
{
|
||||
/* TODO: test this: static void tcp_sack_prepare(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_data_in)
|
||||
{
|
||||
/* TODO: test this: static int tcp_data_in(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_ack_advance_una)
|
||||
{
|
||||
/* TODO: test this: static int tcp_ack_advance_una(struct pico_socket_tcp *t, struct pico_frame *f, pico_time *timestamp) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_time_diff)
|
||||
{
|
||||
/* TODO: test this: static uint16_t time_diff(pico_time a, pico_time b) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rtt)
|
||||
{
|
||||
/* TODO: test this: static void tcp_rtt(struct pico_socket_tcp *t, uint32_t rtt) */
|
||||
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_congestion_control)
|
||||
{
|
||||
/* TODO: test this: static void tcp_congestion_control(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_add_retransmission_timer)
|
||||
{
|
||||
/* TODO: test this: static void add_retransmission_timer(struct pico_socket_tcp *t, pico_time next_ts); */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_first_timeout)
|
||||
{
|
||||
/* TODO: test this: static void tcp_first_timeout(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rto_xmit)
|
||||
{
|
||||
/* TODO: test this: static int tcp_rto_xmit(struct pico_socket_tcp *t, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_next_zerowindow_probe)
|
||||
{
|
||||
/* TODO: test this: static void tcp_next_zerowindow_probe(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_is_allowed_to_send)
|
||||
{
|
||||
/* TODO: test this: static int tcp_is_allowed_to_send(struct pico_socket_tcp *t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_retrans_timeout)
|
||||
{
|
||||
/* TODO: test this: static void tcp_retrans_timeout(pico_time val, void *sock) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_retrans)
|
||||
{
|
||||
/* TODO: test this: static int tcp_retrans(struct pico_socket_tcp *t, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_ack_dbg)
|
||||
{
|
||||
/* TODO: test this: static void tcp_ack_dbg(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_ack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_ack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_finwaitack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_finwaitack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_deltcb)
|
||||
{
|
||||
/* TODO: test this: static void tcp_deltcb(pico_time when, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_finwaitfin)
|
||||
{
|
||||
/* TODO: test this: static int tcp_finwaitfin(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_closewaitack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_closewaitack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_lastackwait)
|
||||
{
|
||||
/* TODO: test this: static int tcp_lastackwait(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_syn)
|
||||
{
|
||||
/* TODO: test this: static int tcp_syn(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_set_init_point)
|
||||
{
|
||||
/* TODO: test this: static void tcp_set_init_point(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_synack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_synack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_first_ack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_first_ack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_closewait)
|
||||
{
|
||||
/* TODO: test this: static int tcp_closewait(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_fin)
|
||||
{
|
||||
/* TODO: test this: static int tcp_fin(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rcvfin)
|
||||
{
|
||||
/* TODO: test this: static int tcp_rcvfin(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_finack)
|
||||
{
|
||||
/* TODO: test this: static int tcp_finack(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_force_closed)
|
||||
{
|
||||
/* TODO: test this: static void tcp_force_closed(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_wakeup_pending)
|
||||
{
|
||||
/* TODO: test this: static void tcp_wakeup_pending(struct pico_socket *s, uint16_t ev) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_rst)
|
||||
{
|
||||
/* TODO: test this: static int tcp_rst(struct pico_socket *s, struct pico_frame *f) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_halfopencon)
|
||||
{
|
||||
/* TODO: test this: static int tcp_halfopencon(struct pico_socket *s, struct pico_frame *fr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tcp_closeconn)
|
||||
{
|
||||
/* TODO: test this: static int tcp_closeconn(struct pico_socket *s, struct pico_frame *fr) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_invalid_flags)
|
||||
{
|
||||
/* TODO: test this: static uint8_t invalid_flags(struct pico_socket *s, uint8_t flags) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_checkLocalClosing)
|
||||
{
|
||||
/* TODO: test this: static int checkLocalClosing(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_checkRemoteClosing)
|
||||
{
|
||||
/* TODO: test this: static int checkRemoteClosing(struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
TCase *TCase_input_segment_compare = tcase_create("Unit test for input_segment_compare");
|
||||
TCase *TCase_tcp_input_segment = tcase_create("Unit test for tcp_input_segment");
|
||||
TCase *TCase_segment_compare = tcase_create("Unit test for segment_compare");
|
||||
TCase *TCase_tcp_discard_all_segments = tcase_create("Unit test for tcp_discard_all_segments");
|
||||
TCase *TCase_release_until = tcase_create("Unit test for release_until");
|
||||
TCase *TCase_release_all_until = tcase_create("Unit test for release_all_until");
|
||||
TCase *TCase_tcp_send_fin = tcase_create("Unit test for tcp_send_fin");
|
||||
TCase *TCase_pico_tcp_process_out = tcase_create("Unit test for pico_tcp_process_out");
|
||||
TCase *TCase_pico_paws = tcase_create("Unit test for pico_paws");
|
||||
TCase *TCase_tcp_add_options = tcase_create("Unit test for tcp_add_options");
|
||||
TCase *TCase_tcp_options_size_frame = tcase_create("Unit test for tcp_options_size_frame");
|
||||
TCase *TCase_tcp_add_options_frame = tcase_create("Unit test for tcp_add_options_frame");
|
||||
TCase *TCase_tcp_send_ack = tcase_create("Unit test for tcp_send_ack");
|
||||
TCase *TCase_tcp_set_space = tcase_create("Unit test for tcp_set_space");
|
||||
TCase *TCase_tcp_options_size = tcase_create("Unit test for tcp_options_size");
|
||||
TCase *TCase_tcp_process_sack = tcase_create("Unit test for tcp_process_sack");
|
||||
TCase *TCase_tcp_rcv_sack = tcase_create("Unit test for tcp_rcv_sack");
|
||||
TCase *TCase_tcp_parse_options = tcase_create("Unit test for tcp_parse_options");
|
||||
TCase *TCase_tcp_send = tcase_create("Unit test for tcp_send");
|
||||
TCase *TCase_sock_stats = tcase_create("Unit test for sock_stats");
|
||||
TCase *TCase_initconn_retry = tcase_create("Unit test for initconn_retry");
|
||||
TCase *TCase_tcp_send_synack = tcase_create("Unit test for tcp_send_synack");
|
||||
TCase *TCase_tcp_send_empty = tcase_create("Unit test for tcp_send_empty");
|
||||
TCase *TCase_tcp_send_probe = tcase_create("Unit test for tcp_send_probe");
|
||||
TCase *TCase_tcp_send_rst = tcase_create("Unit test for tcp_send_rst");
|
||||
TCase *TCase_tcp_nosync_rst = tcase_create("Unit test for tcp_nosync_rst");
|
||||
TCase *TCase_tcp_sack_prepare = tcase_create("Unit test for tcp_sack_prepare");
|
||||
TCase *TCase_tcp_data_in = tcase_create("Unit test for tcp_data_in");
|
||||
TCase *TCase_tcp_ack_advance_una = tcase_create("Unit test for tcp_ack_advance_una");
|
||||
TCase *TCase_time_diff = tcase_create("Unit test for time_diff");
|
||||
TCase *TCase_tcp_rtt = tcase_create("Unit test for tcp_rtt");
|
||||
TCase *TCase_tcp_congestion_control = tcase_create("Unit test for tcp_congestion_control");
|
||||
TCase *TCase_add_retransmission_timer = tcase_create("Unit test for add_retransmission_timer");
|
||||
TCase *TCase_tcp_first_timeout = tcase_create("Unit test for tcp_first_timeout");
|
||||
TCase *TCase_tcp_rto_xmit = tcase_create("Unit test for tcp_rto_xmit");
|
||||
TCase *TCase_tcp_next_zerowindow_probe = tcase_create("Unit test for tcp_next_zerowindow_probe");
|
||||
TCase *TCase_tcp_is_allowed_to_send = tcase_create("Unit test for tcp_is_allowed_to_send");
|
||||
TCase *TCase_tcp_retrans_timeout = tcase_create("Unit test for tcp_retrans_timeout");
|
||||
TCase *TCase_tcp_retrans = tcase_create("Unit test for tcp_retrans");
|
||||
TCase *TCase_tcp_ack_dbg = tcase_create("Unit test for tcp_ack_dbg");
|
||||
TCase *TCase_tcp_ack = tcase_create("Unit test for tcp_ack");
|
||||
TCase *TCase_tcp_finwaitack = tcase_create("Unit test for tcp_finwaitack");
|
||||
TCase *TCase_tcp_deltcb = tcase_create("Unit test for tcp_deltcb");
|
||||
TCase *TCase_tcp_finwaitfin = tcase_create("Unit test for tcp_finwaitfin");
|
||||
TCase *TCase_tcp_closewaitack = tcase_create("Unit test for tcp_closewaitack");
|
||||
TCase *TCase_tcp_lastackwait = tcase_create("Unit test for tcp_lastackwait");
|
||||
TCase *TCase_tcp_syn = tcase_create("Unit test for tcp_syn");
|
||||
TCase *TCase_tcp_set_init_point = tcase_create("Unit test for tcp_set_init_point");
|
||||
TCase *TCase_tcp_synack = tcase_create("Unit test for tcp_synack");
|
||||
TCase *TCase_tcp_first_ack = tcase_create("Unit test for tcp_first_ack");
|
||||
TCase *TCase_tcp_closewait = tcase_create("Unit test for tcp_closewait");
|
||||
TCase *TCase_tcp_fin = tcase_create("Unit test for tcp_fin");
|
||||
TCase *TCase_tcp_rcvfin = tcase_create("Unit test for tcp_rcvfin");
|
||||
TCase *TCase_tcp_finack = tcase_create("Unit test for tcp_finack");
|
||||
TCase *TCase_tcp_force_closed = tcase_create("Unit test for tcp_force_closed");
|
||||
TCase *TCase_tcp_wakeup_pending = tcase_create("Unit test for tcp_wakeup_pending");
|
||||
TCase *TCase_tcp_rst = tcase_create("Unit test for tcp_rst");
|
||||
TCase *TCase_tcp_halfopencon = tcase_create("Unit test for tcp_halfopencon");
|
||||
TCase *TCase_tcp_closeconn = tcase_create("Unit test for tcp_closeconn");
|
||||
TCase *TCase_invalid_flags = tcase_create("Unit test for invalid_flags");
|
||||
TCase *TCase_checkLocalClosing = tcase_create("Unit test for checkLocalClosing");
|
||||
TCase *TCase_checkRemoteClosing = tcase_create("Unit test for checkRemoteClosing");
|
||||
|
||||
|
||||
tcase_add_test(TCase_input_segment_compare, tc_input_segment_compare);
|
||||
suite_add_tcase(s, TCase_input_segment_compare);
|
||||
tcase_add_test(TCase_tcp_input_segment, tc_tcp_input_segment);
|
||||
suite_add_tcase(s, TCase_tcp_input_segment);
|
||||
tcase_add_test(TCase_segment_compare, tc_segment_compare);
|
||||
suite_add_tcase(s, TCase_segment_compare);
|
||||
tcase_add_test(TCase_tcp_discard_all_segments, tc_tcp_discard_all_segments);
|
||||
suite_add_tcase(s, TCase_tcp_discard_all_segments);
|
||||
tcase_add_test(TCase_release_until, tc_release_until);
|
||||
suite_add_tcase(s, TCase_release_until);
|
||||
tcase_add_test(TCase_release_all_until, tc_release_all_until);
|
||||
suite_add_tcase(s, TCase_release_all_until);
|
||||
tcase_add_test(TCase_tcp_send_fin, tc_tcp_send_fin);
|
||||
suite_add_tcase(s, TCase_tcp_send_fin);
|
||||
tcase_add_test(TCase_pico_tcp_process_out, tc_pico_tcp_process_out);
|
||||
suite_add_tcase(s, TCase_pico_tcp_process_out);
|
||||
tcase_add_test(TCase_pico_paws, tc_pico_paws);
|
||||
suite_add_tcase(s, TCase_pico_paws);
|
||||
tcase_add_test(TCase_tcp_add_options, tc_tcp_add_options);
|
||||
suite_add_tcase(s, TCase_tcp_add_options);
|
||||
tcase_add_test(TCase_tcp_options_size_frame, tc_tcp_options_size_frame);
|
||||
suite_add_tcase(s, TCase_tcp_options_size_frame);
|
||||
tcase_add_test(TCase_tcp_add_options_frame, tc_tcp_add_options_frame);
|
||||
suite_add_tcase(s, TCase_tcp_add_options_frame);
|
||||
tcase_add_test(TCase_tcp_send_ack, tc_tcp_send_ack);
|
||||
suite_add_tcase(s, TCase_tcp_send_ack);
|
||||
tcase_add_test(TCase_tcp_set_space, tc_tcp_set_space);
|
||||
suite_add_tcase(s, TCase_tcp_set_space);
|
||||
tcase_add_test(TCase_tcp_options_size, tc_tcp_options_size);
|
||||
suite_add_tcase(s, TCase_tcp_options_size);
|
||||
tcase_add_test(TCase_tcp_process_sack, tc_tcp_process_sack);
|
||||
suite_add_tcase(s, TCase_tcp_process_sack);
|
||||
tcase_add_test(TCase_tcp_rcv_sack, tc_tcp_rcv_sack);
|
||||
suite_add_tcase(s, TCase_tcp_rcv_sack);
|
||||
tcase_add_test(TCase_tcp_parse_options, tc_tcp_parse_options);
|
||||
suite_add_tcase(s, TCase_tcp_parse_options);
|
||||
tcase_add_test(TCase_tcp_send, tc_tcp_send);
|
||||
suite_add_tcase(s, TCase_tcp_send);
|
||||
tcase_add_test(TCase_sock_stats, tc_sock_stats);
|
||||
suite_add_tcase(s, TCase_sock_stats);
|
||||
tcase_add_test(TCase_initconn_retry, tc_initconn_retry);
|
||||
suite_add_tcase(s, TCase_initconn_retry);
|
||||
tcase_add_test(TCase_tcp_send_synack, tc_tcp_send_synack);
|
||||
suite_add_tcase(s, TCase_tcp_send_synack);
|
||||
tcase_add_test(TCase_tcp_send_empty, tc_tcp_send_empty);
|
||||
suite_add_tcase(s, TCase_tcp_send_empty);
|
||||
tcase_add_test(TCase_tcp_send_probe, tc_tcp_send_probe);
|
||||
suite_add_tcase(s, TCase_tcp_send_probe);
|
||||
tcase_add_test(TCase_tcp_send_rst, tc_tcp_send_rst);
|
||||
suite_add_tcase(s, TCase_tcp_send_rst);
|
||||
tcase_add_test(TCase_tcp_nosync_rst, tc_tcp_nosync_rst);
|
||||
suite_add_tcase(s, TCase_tcp_nosync_rst);
|
||||
tcase_add_test(TCase_tcp_sack_prepare, tc_tcp_sack_prepare);
|
||||
suite_add_tcase(s, TCase_tcp_sack_prepare);
|
||||
tcase_add_test(TCase_tcp_data_in, tc_tcp_data_in);
|
||||
suite_add_tcase(s, TCase_tcp_data_in);
|
||||
tcase_add_test(TCase_tcp_ack_advance_una, tc_tcp_ack_advance_una);
|
||||
suite_add_tcase(s, TCase_tcp_ack_advance_una);
|
||||
tcase_add_test(TCase_time_diff, tc_time_diff);
|
||||
suite_add_tcase(s, TCase_time_diff);
|
||||
tcase_add_test(TCase_tcp_rtt, tc_tcp_rtt);
|
||||
suite_add_tcase(s, TCase_tcp_rtt);
|
||||
tcase_add_test(TCase_tcp_congestion_control, tc_tcp_congestion_control);
|
||||
suite_add_tcase(s, TCase_tcp_congestion_control);
|
||||
tcase_add_test(TCase_add_retransmission_timer, tc_add_retransmission_timer);
|
||||
suite_add_tcase(s, TCase_add_retransmission_timer);
|
||||
tcase_add_test(TCase_tcp_first_timeout, tc_tcp_first_timeout);
|
||||
suite_add_tcase(s, TCase_tcp_first_timeout);
|
||||
tcase_add_test(TCase_tcp_rto_xmit, tc_tcp_rto_xmit);
|
||||
suite_add_tcase(s, TCase_tcp_rto_xmit);
|
||||
tcase_add_test(TCase_tcp_next_zerowindow_probe, tc_tcp_next_zerowindow_probe);
|
||||
suite_add_tcase(s, TCase_tcp_next_zerowindow_probe);
|
||||
tcase_add_test(TCase_tcp_is_allowed_to_send, tc_tcp_is_allowed_to_send);
|
||||
suite_add_tcase(s, TCase_tcp_is_allowed_to_send);
|
||||
tcase_add_test(TCase_tcp_retrans_timeout, tc_tcp_retrans_timeout);
|
||||
suite_add_tcase(s, TCase_tcp_retrans_timeout);
|
||||
tcase_add_test(TCase_tcp_retrans, tc_tcp_retrans);
|
||||
suite_add_tcase(s, TCase_tcp_retrans);
|
||||
tcase_add_test(TCase_tcp_ack_dbg, tc_tcp_ack_dbg);
|
||||
suite_add_tcase(s, TCase_tcp_ack_dbg);
|
||||
tcase_add_test(TCase_tcp_ack, tc_tcp_ack);
|
||||
suite_add_tcase(s, TCase_tcp_ack);
|
||||
tcase_add_test(TCase_tcp_finwaitack, tc_tcp_finwaitack);
|
||||
suite_add_tcase(s, TCase_tcp_finwaitack);
|
||||
tcase_add_test(TCase_tcp_deltcb, tc_tcp_deltcb);
|
||||
suite_add_tcase(s, TCase_tcp_deltcb);
|
||||
tcase_add_test(TCase_tcp_finwaitfin, tc_tcp_finwaitfin);
|
||||
suite_add_tcase(s, TCase_tcp_finwaitfin);
|
||||
tcase_add_test(TCase_tcp_closewaitack, tc_tcp_closewaitack);
|
||||
suite_add_tcase(s, TCase_tcp_closewaitack);
|
||||
tcase_add_test(TCase_tcp_lastackwait, tc_tcp_lastackwait);
|
||||
suite_add_tcase(s, TCase_tcp_lastackwait);
|
||||
tcase_add_test(TCase_tcp_syn, tc_tcp_syn);
|
||||
suite_add_tcase(s, TCase_tcp_syn);
|
||||
tcase_add_test(TCase_tcp_set_init_point, tc_tcp_set_init_point);
|
||||
suite_add_tcase(s, TCase_tcp_set_init_point);
|
||||
tcase_add_test(TCase_tcp_synack, tc_tcp_synack);
|
||||
suite_add_tcase(s, TCase_tcp_synack);
|
||||
tcase_add_test(TCase_tcp_first_ack, tc_tcp_first_ack);
|
||||
suite_add_tcase(s, TCase_tcp_first_ack);
|
||||
tcase_add_test(TCase_tcp_closewait, tc_tcp_closewait);
|
||||
suite_add_tcase(s, TCase_tcp_closewait);
|
||||
tcase_add_test(TCase_tcp_fin, tc_tcp_fin);
|
||||
suite_add_tcase(s, TCase_tcp_fin);
|
||||
tcase_add_test(TCase_tcp_rcvfin, tc_tcp_rcvfin);
|
||||
suite_add_tcase(s, TCase_tcp_rcvfin);
|
||||
tcase_add_test(TCase_tcp_finack, tc_tcp_finack);
|
||||
suite_add_tcase(s, TCase_tcp_finack);
|
||||
tcase_add_test(TCase_tcp_force_closed, tc_tcp_force_closed);
|
||||
suite_add_tcase(s, TCase_tcp_force_closed);
|
||||
tcase_add_test(TCase_tcp_wakeup_pending, tc_tcp_wakeup_pending);
|
||||
suite_add_tcase(s, TCase_tcp_wakeup_pending);
|
||||
tcase_add_test(TCase_tcp_rst, tc_tcp_rst);
|
||||
suite_add_tcase(s, TCase_tcp_rst);
|
||||
tcase_add_test(TCase_tcp_halfopencon, tc_tcp_halfopencon);
|
||||
suite_add_tcase(s, TCase_tcp_halfopencon);
|
||||
tcase_add_test(TCase_tcp_closeconn, tc_tcp_closeconn);
|
||||
suite_add_tcase(s, TCase_tcp_closeconn);
|
||||
tcase_add_test(TCase_invalid_flags, tc_invalid_flags);
|
||||
suite_add_tcase(s, TCase_invalid_flags);
|
||||
tcase_add_test(TCase_checkLocalClosing, tc_checkLocalClosing);
|
||||
suite_add_tcase(s, TCase_checkLocalClosing);
|
||||
tcase_add_test(TCase_checkRemoteClosing, tc_checkRemoteClosing);
|
||||
suite_add_tcase(s, TCase_checkRemoteClosing);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
375
kernel/picotcp/test/unit/modunit_pico_tftp.c
Normal file
375
kernel/picotcp/test/unit/modunit_pico_tftp.c
Normal file
@ -0,0 +1,375 @@
|
||||
#include <pico_defines.h>
|
||||
#include <pico_stack.h>
|
||||
#include <pico_socket.h>
|
||||
#include <pico_tftp.h>
|
||||
#include "modules/pico_tftp.c"
|
||||
#include "check.h"
|
||||
|
||||
|
||||
Suite *pico_suite(void);
|
||||
int tftp_user_cb(struct pico_tftp_session *session, uint16_t err, uint8_t *block, int32_t len, void *arg);
|
||||
/* MOCKS */
|
||||
static int called_pico_socket_close = 0;
|
||||
static uint16_t expected_opcode = 0;
|
||||
static int called_user_cb = 0;
|
||||
static int called_sendto = 0;
|
||||
static uint32_t called_pico_timer_add = 0;
|
||||
static int called_pico_timer_cancel = 0;
|
||||
static struct pico_socket example_socket;
|
||||
static struct pico_tftp_session example_session;
|
||||
|
||||
int pico_socket_close(struct pico_socket *s)
|
||||
{
|
||||
fail_if(s != example_session.socket);
|
||||
called_pico_socket_close++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pico_socket_sendto(struct pico_socket *s, const void *buf, const int len, void *dst, uint16_t remote_port)
|
||||
{
|
||||
const struct pico_tftp_hdr *h = (const struct pico_tftp_hdr *)buf;
|
||||
fail_if(s != &example_socket);
|
||||
fail_if(short_be(h->opcode) != expected_opcode);
|
||||
fail_if(len <= 0);
|
||||
(void)dst;
|
||||
(void)remote_port;
|
||||
called_sendto++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tftp_user_cb(struct pico_tftp_session *session, uint16_t err, uint8_t *block, int32_t len, void *arg)
|
||||
{
|
||||
(void)session;
|
||||
(void)err;
|
||||
(void)block;
|
||||
(void)len;
|
||||
(void)arg;
|
||||
called_user_cb++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
|
||||
{
|
||||
(void)expire;
|
||||
(void)timer;
|
||||
(void)arg;
|
||||
|
||||
return ++called_pico_timer_add;
|
||||
}
|
||||
|
||||
void pico_timer_cancel(uint32_t t)
|
||||
{
|
||||
(void)t;
|
||||
called_pico_timer_cancel++;
|
||||
}
|
||||
|
||||
/* TESTS */
|
||||
|
||||
/* START_TEST(tc_check_opcode) */
|
||||
/* { */
|
||||
/* / * TODO: test this: static int check_opcode(struct pico_tftp_hdr *th) * / */
|
||||
/* struct pico_tftp_hdr th; */
|
||||
/* th.opcode = 0; */
|
||||
/* fail_unless(check_opcode(&th) == -1); */
|
||||
/* th.opcode = short_be(PICO_TFTP_RRQ); */
|
||||
/* fail_unless(check_opcode(&th) == 0); */
|
||||
/* th.opcode = short_be(0xFF); */
|
||||
/* fail_unless(check_opcode(&th) == -1); */
|
||||
/* } */
|
||||
/* END_TEST */
|
||||
|
||||
|
||||
START_TEST(tc_find_session_by_socket)
|
||||
{
|
||||
tftp_sessions = (struct pico_tftp_session *)PICO_ZALLOC(sizeof(struct pico_tftp_session));
|
||||
tftp_sessions->socket = &example_socket;
|
||||
tftp_sessions->next = (struct pico_tftp_session *)PICO_ZALLOC(sizeof(struct pico_tftp_session));
|
||||
tftp_sessions->socket = NULL;
|
||||
tftp_sessions->next = NULL;
|
||||
fail_if(find_session_by_socket(&example_socket) != tftp_sessions->next);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_finish)
|
||||
{
|
||||
tftp_sessions = 0;
|
||||
|
||||
/* Test case: client */
|
||||
example_session.socket = &example_socket;
|
||||
called_pico_socket_close = 0;
|
||||
tftp_finish(&example_session);
|
||||
fail_if(!called_pico_socket_close);
|
||||
|
||||
/* Test eval_finish() len is 5*/
|
||||
example_session.socket = &example_socket;
|
||||
called_pico_socket_close = 0;
|
||||
tftp_eval_finish(&example_session, 5);
|
||||
fail_if(example_session.state != TFTP_STATE_CLOSING);
|
||||
fail_if(!called_pico_socket_close);
|
||||
|
||||
/* Test eval_finish() len is PICO_TFTP_TOTAL_BLOCK_SIZE */
|
||||
example_session.socket = &example_socket;
|
||||
called_pico_socket_close = 0;
|
||||
tftp_eval_finish(&example_session, PICO_TFTP_TOTAL_BLOCK_SIZE);
|
||||
fail_if(called_pico_socket_close);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_ack)
|
||||
{
|
||||
example_session.socket = &example_socket;
|
||||
#ifdef PICO_FAULTY
|
||||
/* send_ack must not segfault when out of memory */
|
||||
pico_set_mm_failure(1);
|
||||
tftp_send_ack(&example_session);
|
||||
fail_if(called_sendto > 0);
|
||||
#endif
|
||||
expected_opcode = PICO_TFTP_ACK;
|
||||
tftp_send_ack(&example_session);
|
||||
fail_if(called_sendto < 1);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_req)
|
||||
{
|
||||
/* Not needed. The tftp_send_rx_req and tftp_send_tx_req cover this. */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_rx_req)
|
||||
{
|
||||
char filename[14] = "some filename";
|
||||
|
||||
example_session.socket = &example_socket;
|
||||
called_user_cb = 0;
|
||||
called_pico_socket_close = 0;
|
||||
called_sendto = 0;
|
||||
#ifdef PICO_FAULTY
|
||||
example_session.callback = tftp_user_cb;
|
||||
|
||||
/* send_req must call error cb when out of memory */
|
||||
pico_set_mm_failure(1);
|
||||
tftp_send_rx_req(&example_session, NULL, 0, filename);
|
||||
fail_if(called_user_cb < 1);
|
||||
fail_if(called_sendto > 0);
|
||||
#endif
|
||||
expected_opcode = PICO_TFTP_RRQ;
|
||||
tftp_send_rx_req(&example_session, NULL, 0, NULL);
|
||||
fail_if(called_sendto > 0); /* Calling with filename = NULL: not good */
|
||||
|
||||
tftp_send_rx_req(&example_session, NULL, 0, filename);
|
||||
fail_if(called_sendto < 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_tx_req)
|
||||
{
|
||||
char filename[14] = "some filename";
|
||||
|
||||
example_session.socket = &example_socket;
|
||||
called_user_cb = 0;
|
||||
called_pico_socket_close = 0;
|
||||
called_sendto = 0;
|
||||
#ifdef PICO_FAULTY
|
||||
example_session.callback = tftp_user_cb;
|
||||
|
||||
/* send_req must call error cb when out of memory */
|
||||
pico_set_mm_failure(1);
|
||||
tftp_send_tx_req(&example_session, NULL, 0, filename);
|
||||
fail_if(called_user_cb < 1);
|
||||
fail_if(called_sendto > 0);
|
||||
#endif
|
||||
expected_opcode = PICO_TFTP_WRQ;
|
||||
tftp_send_tx_req(&example_session, NULL, 0, NULL);
|
||||
fail_if(called_sendto > 0); /* Calling with filename = NULL: not good */
|
||||
|
||||
tftp_send_tx_req(&example_session, NULL, 0, filename);
|
||||
fail_if(called_sendto < 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_error)
|
||||
{
|
||||
char longtext[1024];
|
||||
example_session.socket = &example_socket;
|
||||
called_user_cb = 0;
|
||||
called_pico_socket_close = 0;
|
||||
|
||||
/* Sending empty msg */
|
||||
called_sendto = 0;
|
||||
expected_opcode = PICO_TFTP_ERROR;
|
||||
tftp_send_error(&example_session, NULL, 0, 0, NULL);
|
||||
fail_if(called_sendto < 1);
|
||||
/* Sending some msg */
|
||||
called_sendto = 0;
|
||||
expected_opcode = PICO_TFTP_ERROR;
|
||||
tftp_send_error(&example_session, NULL, 0, 0, "some text here");
|
||||
fail_if(called_sendto < 1);
|
||||
|
||||
/* sending some very long msg */
|
||||
memset(longtext, 'a', 1023);
|
||||
longtext[1023] = (char)0;
|
||||
called_sendto = 0;
|
||||
expected_opcode = PICO_TFTP_ERROR;
|
||||
tftp_send_error(&example_session, NULL, 0, 0, longtext);
|
||||
fail_if(called_sendto < 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_tftp_send_data)
|
||||
{
|
||||
example_session.state = 0;
|
||||
example_session.socket = &example_socket;
|
||||
called_sendto = 0;
|
||||
expected_opcode = PICO_TFTP_DATA;
|
||||
tftp_send_data(&example_session, (const uint8_t*)"buffer", strlen("buffer"));
|
||||
fail_if(called_sendto < 1);
|
||||
fail_if(example_session.state != TFTP_STATE_WAIT_LAST_ACK);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_tftp_abort)
|
||||
{
|
||||
int ret;
|
||||
server.listen_socket = NULL;
|
||||
|
||||
/*first case: no session and no listening socket*/
|
||||
ret = pico_tftp_abort(NULL, TFTP_ERR_EUSR, "test");
|
||||
fail_if(ret != -1);
|
||||
/*second case: no session but listening socket*/
|
||||
server.listen_socket = example_session.socket = &example_socket;
|
||||
pico_tftp_abort(NULL, TFTP_ERR_EUSR, "test");
|
||||
fail_if(ret != -1);
|
||||
/*tirdh case: session non into list*/
|
||||
ret = pico_tftp_abort(&example_session, TFTP_ERR_EUSR, "test");
|
||||
fail_if(ret != -1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Receiving functions */
|
||||
|
||||
START_TEST(tc_tftp_data)
|
||||
{
|
||||
/* TODO: test this: static void tftp_data(uint8_t *block, uint32_t len, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_ack)
|
||||
{
|
||||
/* TODO: test this: static void tftp_ack(uint8_t *block, uint32_t len, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_timeout)
|
||||
{
|
||||
/* TODO: test this: static void tftp_timeout(pico_time t) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_req)
|
||||
{
|
||||
/* TODO: test this: static void tftp_req(uint8_t *block, uint32_t len, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_data_err)
|
||||
{
|
||||
/* TODO: test this: static void tftp_data_err(uint8_t *block, uint32_t len, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_fsm_timeout)
|
||||
{
|
||||
/* TODO: test this: static void tftp_fsm_timeout(pico_time now, void *arg) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_receive)
|
||||
{
|
||||
/* TODO: test this: static void tftp_receive(uint8_t *block, uint32_t r, union pico_address *a, uint16_t port) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_cb)
|
||||
{
|
||||
/* TODO: test this: static void tftp_cb(uint16_t ev, struct pico_socket *s) */
|
||||
}
|
||||
END_TEST
|
||||
START_TEST(tc_tftp_socket_open)
|
||||
{
|
||||
/* TODO: test this: static int tftp_socket_open(uint16_t family, union pico_address *a, uint16_t port) */
|
||||
fail_if(tftp_socket_open(0xFFFF, 21) != NULL);
|
||||
fail_if(tftp_socket_open(0xFFFF, 0xFFFF) != NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("PicoTCP");
|
||||
|
||||
/* TCase *TCase_check_opcode = tcase_create("Unit test for check_opcode"); */
|
||||
TCase *TCase_find_session_by_socket = tcase_create("Unit test for find_session_by_socket");
|
||||
TCase *TCase_tftp_finish = tcase_create("Unit test for tftp_finish");
|
||||
TCase *TCase_tftp_send_ack = tcase_create("Unit test for tftp_send_ack");
|
||||
TCase *TCase_tftp_send_req = tcase_create("Unit test for tftp_send_req");
|
||||
TCase *TCase_tftp_send_rx_req = tcase_create("Unit test for tftp_send_rx_req");
|
||||
TCase *TCase_tftp_send_tx_req = tcase_create("Unit test for tftp_send_tx_req");
|
||||
TCase *TCase_tftp_send_error = tcase_create("Unit test for tftp_send_error");
|
||||
TCase *TCase_tftp_send_data = tcase_create("Unit test for tftp_send_data");
|
||||
TCase *Tcase_pico_tftp_abort = tcase_create("Unit test for pico_tftp_abort");
|
||||
TCase *TCase_tftp_data = tcase_create("Unit test for tftp_data");
|
||||
TCase *TCase_tftp_ack = tcase_create("Unit test for tftp_ack");
|
||||
TCase *TCase_tftp_timeout = tcase_create("Unit test for tftp_timeout");
|
||||
TCase *TCase_tftp_req = tcase_create("Unit test for tftp_req");
|
||||
TCase *TCase_tftp_data_err = tcase_create("Unit test for tftp_data_err");
|
||||
TCase *TCase_tftp_fsm_timeout = tcase_create("Unit test for tftp_fsm_timeout");
|
||||
TCase *TCase_tftp_receive = tcase_create("Unit test for tftp_receive");
|
||||
TCase *TCase_tftp_cb = tcase_create("Unit test for tftp_cb");
|
||||
TCase *TCase_tftp_socket_open = tcase_create("Unit test for tftp_socket_open");
|
||||
|
||||
|
||||
/* tcase_add_test(TCase_check_opcode, tc_check_opcode); */
|
||||
/* suite_add_tcase(s, TCase_check_opcode); */
|
||||
tcase_add_test(TCase_find_session_by_socket, tc_find_session_by_socket);
|
||||
suite_add_tcase(s, TCase_find_session_by_socket);
|
||||
tcase_add_test(TCase_tftp_finish, tc_tftp_finish);
|
||||
suite_add_tcase(s, TCase_tftp_finish);
|
||||
tcase_add_test(TCase_tftp_send_ack, tc_tftp_send_ack);
|
||||
suite_add_tcase(s, TCase_tftp_send_ack);
|
||||
tcase_add_test(TCase_tftp_send_req, tc_tftp_send_req);
|
||||
suite_add_tcase(s, TCase_tftp_send_req);
|
||||
tcase_add_test(TCase_tftp_send_rx_req, tc_tftp_send_rx_req);
|
||||
suite_add_tcase(s, TCase_tftp_send_rx_req);
|
||||
tcase_add_test(TCase_tftp_send_tx_req, tc_tftp_send_tx_req);
|
||||
suite_add_tcase(s, TCase_tftp_send_tx_req);
|
||||
tcase_add_test(TCase_tftp_send_error, tc_tftp_send_error);
|
||||
suite_add_tcase(s, TCase_tftp_send_error);
|
||||
tcase_add_test(TCase_tftp_send_data, tc_tftp_send_data);
|
||||
suite_add_tcase(s, TCase_tftp_send_data);
|
||||
tcase_add_test(TCase_tftp_data, tc_tftp_data);
|
||||
suite_add_tcase(s, Tcase_pico_tftp_abort);
|
||||
tcase_add_test(Tcase_pico_tftp_abort, tc_pico_tftp_abort);
|
||||
suite_add_tcase(s, TCase_tftp_data);
|
||||
tcase_add_test(TCase_tftp_ack, tc_tftp_ack);
|
||||
suite_add_tcase(s, TCase_tftp_ack);
|
||||
tcase_add_test(TCase_tftp_timeout, tc_tftp_timeout);
|
||||
suite_add_tcase(s, TCase_tftp_timeout);
|
||||
tcase_add_test(TCase_tftp_req, tc_tftp_req);
|
||||
suite_add_tcase(s, TCase_tftp_req);
|
||||
tcase_add_test(TCase_tftp_data_err, tc_tftp_data_err);
|
||||
suite_add_tcase(s, TCase_tftp_data_err);
|
||||
tcase_add_test(TCase_tftp_fsm_timeout, tc_tftp_fsm_timeout);
|
||||
suite_add_tcase(s, TCase_tftp_fsm_timeout);
|
||||
tcase_add_test(TCase_tftp_receive, tc_tftp_receive);
|
||||
suite_add_tcase(s, TCase_tftp_receive);
|
||||
tcase_add_test(TCase_tftp_cb, tc_tftp_cb);
|
||||
suite_add_tcase(s, TCase_tftp_cb);
|
||||
tcase_add_test(TCase_tftp_socket_open, tc_tftp_socket_open);
|
||||
suite_add_tcase(s, TCase_tftp_socket_open);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
84
kernel/picotcp/test/unit/modunit_queue.c
Normal file
84
kernel/picotcp/test/unit/modunit_queue.c
Normal file
@ -0,0 +1,84 @@
|
||||
#include "pico_frame.h"
|
||||
#include "pico_queue.h"
|
||||
#include "stack/pico_frame.c"
|
||||
#include "pico_stack.h"
|
||||
#include "check.h"
|
||||
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
struct pico_queue q1 = {
|
||||
0
|
||||
}, q2 = {
|
||||
0
|
||||
};
|
||||
|
||||
START_TEST(tc_q)
|
||||
{
|
||||
struct pico_frame *f0 = pico_frame_alloc(100);
|
||||
struct pico_frame *f1 = pico_frame_alloc(100);
|
||||
struct pico_frame *f2 = pico_frame_alloc(100);
|
||||
struct pico_frame *f3 = pico_frame_alloc(100);
|
||||
struct pico_frame *f4 = pico_frame_alloc(100);
|
||||
|
||||
pico_queue_protect(&q1);
|
||||
|
||||
q1.max_frames = 4;
|
||||
q2.max_size = 4 * 100;
|
||||
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f0)) < 0);
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f1)) < 0);
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f2)) < 0);
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f3)) < 0);
|
||||
fail_if (pico_enqueue(&q1, pico_frame_copy(f4)) >= 0);
|
||||
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f0)) < 0);
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f1)) < 0);
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f2)) < 0);
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f3)) < 0);
|
||||
fail_if (pico_enqueue(&q2, pico_frame_copy(f4)) >= 0);
|
||||
|
||||
fail_if((pico_dequeue(&q1))->buffer != f0->buffer);
|
||||
fail_if((pico_dequeue(&q1))->buffer != f1->buffer);
|
||||
fail_if((pico_dequeue(&q1))->buffer != f2->buffer);
|
||||
fail_if((pico_dequeue(&q1))->buffer != f3->buffer);
|
||||
fail_if(pico_queue_peek(&q1) != NULL);
|
||||
fail_if(pico_dequeue(&q1) != NULL);
|
||||
fail_if(q1.size != 0);
|
||||
fail_if(q1.frames != 0);
|
||||
|
||||
|
||||
pico_queue_empty(&q2);
|
||||
fail_if(q2.size != 0);
|
||||
fail_if(q2.frames != 0);
|
||||
fail_if(pico_queue_peek(&q2) != NULL);
|
||||
fail_if(pico_dequeue(&q2) != NULL);
|
||||
|
||||
pico_queue_deinit(&q1);
|
||||
pico_queue_deinit(&q2);
|
||||
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("Packet Queues");
|
||||
|
||||
TCase *TCase_q = tcase_create("Unit test for pico_queue.c");
|
||||
tcase_add_test(TCase_q, tc_q);
|
||||
suite_add_tcase(s, TCase_q);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
59
kernel/picotcp/test/unit/modunit_seq.c
Normal file
59
kernel/picotcp/test/unit/modunit_seq.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include "pico_tcp.c"
|
||||
#include <check.h>
|
||||
|
||||
Suite *pico_suite(void);
|
||||
|
||||
START_TEST(tc_seq_compare)
|
||||
{
|
||||
uint32_t big_a = 0xFFFFFF0alu;
|
||||
uint32_t big_b = 0xFFFFFF0blu;
|
||||
uint32_t small_a = 0xalu;
|
||||
uint32_t small_b = 0xblu;
|
||||
uint32_t under_thresh = 0x7ffffffflu;
|
||||
uint32_t over_thresh = 0x80000000lu;
|
||||
uint32_t zero = 0lu;
|
||||
|
||||
fail_if(pico_seq_compare(small_a, small_b) >= 0);
|
||||
fail_if(pico_seq_compare(small_b, small_a) <= 0);
|
||||
|
||||
fail_if(pico_seq_compare(over_thresh, under_thresh) <= 0);
|
||||
fail_if(pico_seq_compare(under_thresh, over_thresh) >= 0);
|
||||
|
||||
fail_if(pico_seq_compare(small_a, big_b) <= 0);
|
||||
fail_if(pico_seq_compare(big_b, small_a) >= 0);
|
||||
|
||||
fail_if(pico_seq_compare(small_a, zero) <= 0);
|
||||
fail_if(pico_seq_compare(zero, small_a) >= 0);
|
||||
|
||||
fail_if(pico_seq_compare(big_a, zero) >= 0);
|
||||
fail_if(pico_seq_compare(zero, big_a) <= 0);
|
||||
|
||||
fail_if(pico_seq_compare(big_a, big_b) >= 0);
|
||||
fail_if(pico_seq_compare(big_b, big_a) <= 0);
|
||||
|
||||
fail_if(pico_seq_compare(big_a, big_a) != 0);
|
||||
fail_if(pico_seq_compare(zero, zero) != 0);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *pico_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("pico tcp sequence numbers");
|
||||
TCase *TCase_seq_compare = tcase_create("Unit test for pico_seq_compare");
|
||||
tcase_add_test(TCase_seq_compare, tc_seq_compare);
|
||||
suite_add_tcase(s, TCase_seq_compare);
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fails;
|
||||
Suite *s = pico_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
fails = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
return fails;
|
||||
}
|
||||
|
||||
213
kernel/picotcp/test/unit/unit_arp.c
Normal file
213
kernel/picotcp/test/unit/unit_arp.c
Normal file
@ -0,0 +1,213 @@
|
||||
#include "pico_ethernet.c"
|
||||
|
||||
static struct pico_frame *init_frame(struct pico_device *dev)
|
||||
{
|
||||
struct pico_frame *f = pico_frame_alloc(PICO_SIZE_ETHHDR + PICO_SIZE_ARPHDR);
|
||||
f->net_hdr = f->buffer + PICO_SIZE_ETHHDR;
|
||||
f->datalink_hdr = f->buffer;
|
||||
f->dev = dev;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
START_TEST (arp_update_max_arp_reqs_test)
|
||||
{
|
||||
pico_stack_init();
|
||||
max_arp_reqs = 0;
|
||||
usleep((PICO_ARP_INTERVAL + 1) * 1000);
|
||||
pico_stack_tick();
|
||||
fail_unless(max_arp_reqs > 0);
|
||||
|
||||
max_arp_reqs = PICO_ARP_MAX_RATE;
|
||||
usleep((PICO_ARP_INTERVAL + 1) * 1000);
|
||||
pico_stack_tick();
|
||||
fail_unless(max_arp_reqs == PICO_ARP_MAX_RATE);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (arp_compare_test)
|
||||
{
|
||||
struct pico_arp a, b;
|
||||
char ipstr[] = "192.168.1.1";
|
||||
|
||||
memset(&a, 0, sizeof(a));
|
||||
pico_string_to_ipv4(ipstr, &b.ipv4.addr);
|
||||
|
||||
fail_unless(arp_compare(&a, &b) == -1);
|
||||
fail_unless(arp_compare(&b, &a) == 1);
|
||||
fail_unless(arp_compare(&a, &a) == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (arp_lookup_test)
|
||||
{
|
||||
struct pico_ip4 ip;
|
||||
struct pico_eth *eth = NULL;
|
||||
char ipstr[] = "192.168.1.1";
|
||||
struct pico_arp entry;
|
||||
|
||||
eth = pico_arp_lookup(&ip);
|
||||
fail_unless(eth == NULL);
|
||||
|
||||
pico_string_to_ipv4(ipstr, &ip.addr);
|
||||
entry.ipv4 = ip;
|
||||
|
||||
pico_stack_init();
|
||||
fail_unless(pico_arp_add_entry(&entry) == 0);
|
||||
entry.arp_status = PICO_ARP_STATUS_STALE;
|
||||
eth = pico_arp_lookup(&ip);
|
||||
fail_unless(eth == NULL);
|
||||
pico_tree_delete(&arp_tree, &entry);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (arp_expire_test)
|
||||
{
|
||||
struct pico_arp entry;
|
||||
entry.arp_status = PICO_ARP_STATUS_REACHABLE;
|
||||
entry.timestamp = 0;
|
||||
|
||||
arp_expire(PICO_ARP_TIMEOUT, &entry);
|
||||
fail_unless(entry.arp_status == PICO_ARP_STATUS_STALE);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tc_pico_arp_queue)
|
||||
{
|
||||
struct pico_ip4 addr = {
|
||||
.addr = 0xaabbccdd
|
||||
};
|
||||
int i;
|
||||
struct pico_frame *f = pico_frame_alloc(sizeof(struct pico_ipv4_hdr));
|
||||
struct pico_ipv4_hdr *h = (struct pico_ipv4_hdr *) f->buffer;
|
||||
fail_if(!f);
|
||||
f->net_hdr = (uint8_t *)h;
|
||||
h->dst.addr = addr.addr;
|
||||
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued[i] != NULL);
|
||||
}
|
||||
pico_arp_unreachable(&addr);
|
||||
for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) {
|
||||
fail_if(frames_queued[i] != NULL);
|
||||
}
|
||||
pico_arp_postpone(f);
|
||||
fail_if(frames_queued[0]->buffer != f->buffer);
|
||||
pico_arp_unreachable(&addr);
|
||||
PICO_FREE(f);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
|
||||
START_TEST (arp_receive_test)
|
||||
{
|
||||
struct mock_device *mock;
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_arp_hdr *ah = NULL;
|
||||
struct pico_eth_hdr *eh = NULL;
|
||||
uint8_t macaddr1[6] = {
|
||||
0, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
uint8_t macaddr2[6] = {
|
||||
0, 0, 0, 0xc, 0xd, 0xf
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 ip1 = {
|
||||
.addr = long_be(0x0A2800AA)
|
||||
};
|
||||
struct pico_ip4 ip2 = {
|
||||
.addr = long_be(0x0A2800AB)
|
||||
};
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, ip1, netmask), "add link to mock device failed");
|
||||
|
||||
/* Normal ARP request */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
eh = (struct pico_eth_hdr *) f->datalink_hdr;
|
||||
ah = (struct pico_arp_hdr *) f->net_hdr;
|
||||
|
||||
memcpy(eh->saddr, macaddr2, PICO_SIZE_ETH);
|
||||
memcpy(eh->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH);
|
||||
eh->proto = PICO_IDETH_ARP;
|
||||
|
||||
ah->htype = PICO_ARP_HTYPE_ETH;
|
||||
ah->ptype = PICO_IDETH_IPV4;
|
||||
ah->hsize = PICO_SIZE_ETH;
|
||||
ah->psize = PICO_SIZE_IP4;
|
||||
ah->opcode = PICO_ARP_REQUEST;
|
||||
memcpy(ah->s_mac, macaddr2, PICO_SIZE_ETH);
|
||||
ah->src.addr = ip2.addr;
|
||||
ah->dst.addr = ip1.addr;
|
||||
fail_unless(pico_arp_receive(f) == 0);
|
||||
|
||||
/* net_hdr is a nullpointer */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
f->net_hdr = NULL;
|
||||
fail_unless(pico_arp_receive(f) == -1);
|
||||
|
||||
/* wrong hardware type */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
ah = (struct pico_arp_hdr *) f->net_hdr;
|
||||
ah->htype = 0;
|
||||
fail_unless(pico_arp_receive(f) == -1);
|
||||
|
||||
/* wrong protocol type */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
ah = (struct pico_arp_hdr *) f->net_hdr;
|
||||
ah->ptype = 0;
|
||||
fail_unless(pico_arp_receive(f) == -1);
|
||||
|
||||
/* source mac address is multicast */
|
||||
f = init_frame(mock->dev);
|
||||
fail_if(!f, "FRAME INIT failed");
|
||||
ah = (struct pico_arp_hdr *) f->net_hdr;
|
||||
ah->s_mac[0] = 0x01;
|
||||
fail_unless(pico_arp_receive(f) == -1);
|
||||
pico_ipv4_link_del(mock->dev, ip1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (arp_get_test)
|
||||
{
|
||||
struct pico_frame *f = NULL;
|
||||
struct mock_device *mock;
|
||||
struct pico_ipv4_hdr *hdr = NULL;
|
||||
struct pico_eth *eth = NULL;
|
||||
uint8_t macaddr[6] = {
|
||||
0, 0, 0xa, 0xa, 0xb, 0xf
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 ip = {
|
||||
.addr = long_be(0x0A28000B)
|
||||
};
|
||||
|
||||
mock = pico_mock_create(macaddr);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, ip, netmask), "add link to mock device failed");
|
||||
|
||||
f = pico_frame_alloc(PICO_SIZE_ETHHDR + sizeof(struct pico_ipv4_hdr));
|
||||
f->net_hdr = f->start + PICO_SIZE_ETHHDR;
|
||||
f->datalink_hdr = f->start;
|
||||
f->dev = mock->dev;
|
||||
|
||||
hdr = (struct pico_ipv4_hdr *) f->net_hdr;
|
||||
hdr->dst.addr = ip.addr;
|
||||
eth = pico_arp_get(f);
|
||||
fail_unless(eth == &mock->dev->eth->mac);
|
||||
pico_ipv4_link_del(mock->dev, ip);
|
||||
}
|
||||
END_TEST
|
||||
554
kernel/picotcp/test/unit/unit_dhcp.c
Normal file
554
kernel/picotcp/test/unit/unit_dhcp.c
Normal file
@ -0,0 +1,554 @@
|
||||
|
||||
static struct pico_dhcp_client_cookie*dhcp_client_ptr;
|
||||
|
||||
void callback_dhcpclient(void*cli, int code);
|
||||
int generate_dhcp_msg(uint8_t *buf, uint32_t *len, uint8_t type);
|
||||
|
||||
void callback_dhcpclient(void*cli, int code)
|
||||
{
|
||||
struct pico_ip4 gateway;
|
||||
char gw_txt_addr[30];
|
||||
IGNORE_PARAMETER(cli);
|
||||
|
||||
if(code == PICO_DHCP_SUCCESS) {
|
||||
gateway = pico_dhcp_get_gateway(&dhcp_client_ptr);
|
||||
pico_ipv4_to_string(gw_txt_addr, gateway.addr);
|
||||
}
|
||||
|
||||
printf("callback happened with code %d!\n", code);
|
||||
}
|
||||
|
||||
int generate_dhcp_msg(uint8_t *buf, uint32_t *len, uint8_t type)
|
||||
{
|
||||
if(type == DHCP_MSG_TYPE_DISCOVER) {
|
||||
uint8_t buffer[] = {
|
||||
0x01, 0x01, 0x06, 0x00, 0x0c, 0x10,
|
||||
0x53, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x0a, 0x0b, 0x0f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x01, 0x37, 0x07, 0x01,
|
||||
0x1c, 0x02, 0x03, 0x0c, 0x3a, 0x3b, 0x39, 0x02, 0x02, 0x40, 0xff, 0x00
|
||||
};
|
||||
*len = sizeof(buffer);
|
||||
memcpy(&(buf[0]), buffer, *len);
|
||||
}else if(type == DHCP_MSG_TYPE_OFFER) {
|
||||
return 1;
|
||||
}else if(type == DHCP_MSG_TYPE_REQUEST) {
|
||||
uint32_t i = 0;
|
||||
uint8_t buffer1[] = {
|
||||
/* 0x63,0x82,0x53,0x63,// MAGIC COOCKIE */
|
||||
/* 0x35,0x01,0x03, // DHCP REQUEST */
|
||||
/* 0x36,0x04,0x00,0x00,0x00,0x00 // SERVER ID */
|
||||
0x32, 0x04, buf[0x3a], buf[0x3b], buf[0x3c], buf[0x3e], /* requested ip */
|
||||
0x37, 0x04, 0x01, 0x03, 0x06, 0x2a, /* Parameter list */
|
||||
0x3d, 0x07, 0x01, buf[0x06], buf[0x07], buf[0x08], buf[0x09], buf[0x0a], buf[0x0b], /* Client id */
|
||||
0xff
|
||||
};
|
||||
|
||||
buf[0x02a] = 0x01; /* change to boot request */
|
||||
buf[0x11c] = 0x03; /* request */
|
||||
|
||||
memcpy(&(buf[0x123]), &(buffer1[0]), sizeof(buffer1));
|
||||
*len = sizeof(buffer1) + 0x123;
|
||||
for(i = *len; i < 0x150; i++) {
|
||||
buf[i + 10] = 0x00;
|
||||
}
|
||||
return 0;
|
||||
}else if(type == DHCP_MSG_TYPE_ACK) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
START_TEST (test_dhcp_server_api)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check if dhcp recv works correctly if
|
||||
* MAC address of client is not in arp table yet
|
||||
* Status : Done
|
||||
************************************************************************/
|
||||
|
||||
struct mock_device *mock;
|
||||
uint8_t macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 serverip = {
|
||||
.addr = long_be(0x0A28000A)
|
||||
};
|
||||
uint8_t buf[600] = {
|
||||
0
|
||||
};
|
||||
/* Declaration test 1 */
|
||||
struct pico_dhcp_server_setting s1 = {
|
||||
0
|
||||
};
|
||||
/* Declaration test 2 */
|
||||
struct pico_dhcp_server_setting s2 = {
|
||||
0
|
||||
};
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, serverip, netmask), "add link to mock device failed");
|
||||
|
||||
/* test 0 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Test 0 statements */
|
||||
fail_unless(pico_dhcp_server_initiate(NULL), "DHCP_SERVER> initiate succeeded after pointer to dev == NULL");
|
||||
fail_unless(pico_err == PICO_ERR_EINVAL, "DHCP_SERVER> initiate succeeded without PICO_ERR_EINVAL after wrong parameter");
|
||||
|
||||
/* test 1 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Store data in settings */
|
||||
s1.server_ip.addr = long_be(0x0A28000F); /* make sure this IP is not assigned */
|
||||
/* Test 1 statements */
|
||||
fail_unless(pico_dhcp_server_initiate(&s1), "DHCP_SERVER> initiate succeeded after pointer to dev == NULL");
|
||||
fail_unless(pico_err == PICO_ERR_EINVAL, "DHCP_SERVER> initiate succeeded without PICO_ERR_EINVAL after wrong parameter");
|
||||
|
||||
/* test 2 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Store data in settings */
|
||||
s2.server_ip = serverip;
|
||||
/* Test 2 statements */
|
||||
fail_if(pico_dhcp_server_initiate(&s2), "DHCP_SERVER> failed after correct parameter");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_dhcp)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check if all states (offer, bound) are changed correctly
|
||||
* and if response messages are replied correctly
|
||||
* Status : Done
|
||||
*************************************************************************/
|
||||
struct mock_device*mock;
|
||||
struct pico_dhcp_server_setting s = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 xid = {
|
||||
.addr = long_be(0x00003d1d)
|
||||
};
|
||||
uint8_t macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
uint8_t macaddr2[6] = {
|
||||
0xc6, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 serverip = {
|
||||
.addr = long_be(0x0A28000A)
|
||||
};
|
||||
struct pico_socket sock = { };
|
||||
struct pico_dhcp_server_negotiation *dn = NULL;
|
||||
struct pico_ip4 *stored_ipv4 = NULL;
|
||||
uint32_t len = 0;
|
||||
int network_read = 0;
|
||||
uint8_t *buf;
|
||||
uint8_t printbufactive = 0;
|
||||
|
||||
buf = PICO_ZALLOC(600);
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/*Insert custom values in buffer*/
|
||||
fail_if(generate_dhcp_msg(buf, &len, DHCP_MSG_TYPE_DISCOVER), "DHCP_SERVER->failed to generate buffer");
|
||||
memcpy(&(buf[4]), &(xid.addr), sizeof(struct pico_ip4));
|
||||
memcpy(&(buf[28]), &(macaddr1[0]), sizeof(struct pico_ip4));
|
||||
printbuf(&(buf[0]), len, "DHCP-DISCOVER packet", printbufactive);
|
||||
|
||||
/*Initiate test setup*/
|
||||
pico_stack_init();
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr2);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, serverip, netmask), "add link to mock device failed");
|
||||
|
||||
s.server_ip = serverip;
|
||||
|
||||
fail_if(pico_dhcp_server_initiate(&s), "DHCP_SERVER> server initiation failed");
|
||||
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_unless(dn == NULL, "DCHP SERVER -> negotiation data available befor discover msg recvd");
|
||||
|
||||
/* simulate reception of a DISCOVER packet */
|
||||
sock.local_addr.ip4 = serverip;
|
||||
pico_dhcp_server_recv(&sock, buf, len);
|
||||
|
||||
tick_it(3);
|
||||
|
||||
/* check if negotiation data is stored */
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_if(dn == NULL, "DCHP SERVER -> no negotiation stored after discover msg recvd");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
stored_ipv4 = pico_arp_reverse_lookup(&dn->hwaddr);
|
||||
fail_if(stored_ipv4 == NULL, "DCHP SERVER -> new address is not inserted in ARP");
|
||||
fail_unless(stored_ipv4->addr == dn->ciaddr.addr, "DCHP SERVER -> new ip not stored in negotiation data");
|
||||
|
||||
/* check if state is changed and reply is received */
|
||||
network_read = pico_mock_network_read(mock, buf, BUFLEN);
|
||||
fail_unless(network_read > 0, "received msg on network of %u bytes", network_read);
|
||||
printbuf(&(buf[0]), (uint32_t)network_read, "DHCP-OFFER msg", printbufactive);
|
||||
fail_unless(buf[0x011c] == 0x02, "No DHCP offer received after discovery");
|
||||
fail_unless(dn->state == PICO_DHCP_STATE_OFFER, "DCHP SERVER -> negotiation state not changed to OFFER");
|
||||
|
||||
/*change offer to request*/
|
||||
fail_if(generate_dhcp_msg(buf, &len, DHCP_MSG_TYPE_REQUEST), "DHCP_SERVER->failed to generate buffer");
|
||||
printbuf(&(buf[0x2a]), len - 0x2a, "request buffer", printbufactive);
|
||||
|
||||
/* simulate reception of a offer packet */
|
||||
pico_dhcp_server_recv(&sock, &(buf[0x2a]), len - 0x2a);
|
||||
fail_unless(dn->state == PICO_DHCP_STATE_BOUND, "DCHP SERVER -> negotiation state not changed to BOUND");
|
||||
|
||||
tick_it(3);
|
||||
|
||||
/* check if state is changed and reply is received */
|
||||
do {
|
||||
network_read = pico_mock_network_read(mock, buf, BUFLEN);
|
||||
} while (buf[0] == 0x33);
|
||||
printf("Received message: %d bytes\n", network_read);
|
||||
fail_unless(network_read > 0, "received msg on network of %d bytes", network_read);
|
||||
printbuf(&(buf[0]), (uint32_t)network_read, "DHCP-ACK msg", printbufactive);
|
||||
fail_unless(buf[0x11c] == 0x05, "No DHCP ACK received after discovery");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST (test_dhcp_server_ipninarp)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check if dhcp recv works correctly if
|
||||
* MAC address of client is not in arp table yet
|
||||
* Status : Done
|
||||
*************************************************************************/
|
||||
struct mock_device*mock;
|
||||
struct pico_dhcp_server_setting s = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 xid = {
|
||||
.addr = long_be(0x00003d1d)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 serverip = {
|
||||
.addr = long_be(0x0A28000A)
|
||||
};
|
||||
struct pico_socket sock = { };
|
||||
struct pico_dhcp_server_negotiation *dn = NULL;
|
||||
struct pico_ip4 *stored_ipv4 = NULL;
|
||||
unsigned char macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
uint32_t len = 0;
|
||||
uint8_t buf[600] = {
|
||||
0
|
||||
};
|
||||
uint8_t printbufactive = 0;
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/*Insert custom values in buffer*/
|
||||
fail_if(generate_dhcp_msg(buf, &len, DHCP_MSG_TYPE_DISCOVER), "DHCP_SERVER->failed to generate buffer");
|
||||
memcpy(&(buf[4]), &(xid.addr), sizeof(struct pico_ip4));
|
||||
memcpy(&(buf[28]), &(macaddr1[0]), sizeof(struct pico_ip4));
|
||||
printbuf(&(buf[0]), len, "DHCP-DISCOVER packet", printbufactive);
|
||||
|
||||
/*Initiate test setup*/
|
||||
pico_stack_init();
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, serverip, netmask), "add link to mock device failed");
|
||||
s.server_ip = serverip;
|
||||
|
||||
fail_if(pico_dhcp_server_initiate(&s), "DHCP_SERVER> server initiation failed");
|
||||
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_unless(dn == NULL, "DCHP SERVER -> negotiation data available before discover msg recvd");
|
||||
|
||||
/* simulate reception of a DISCOVER packet */
|
||||
sock.local_addr.ip4 = serverip;
|
||||
pico_dhcp_server_recv(&sock, buf, len);
|
||||
|
||||
/* check if negotiation data is stored */
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_if(dn == NULL, "DCHP SERVER -> no negotiation stored after discover msg recvd");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
stored_ipv4 = pico_arp_reverse_lookup(&dn->hwaddr);
|
||||
fail_if(stored_ipv4 == NULL, "DCHP SERVER -> new address is not inserted in ARP");
|
||||
fail_unless(stored_ipv4->addr == dn->ciaddr.addr, "DCHP SERVER -> new ip not stored in negotiation data");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
fail_if(pico_arp_reverse_lookup(&dn->hwaddr) == NULL, "DCHP SERVER -> new address is not inserted in ARP");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_dhcp_server_ipinarp)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check if dhcp recv works correctly if
|
||||
* MAC address of client is allready in arp table
|
||||
* Status : Done
|
||||
*************************************************************************/
|
||||
struct mock_device*mock;
|
||||
struct pico_dhcp_server_setting s = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 ipv4address = {
|
||||
.addr = long_be(0x0a280067)
|
||||
};
|
||||
struct pico_ip4 xid = {
|
||||
.addr = long_be(0x00003d1d)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct pico_ip4 serverip = {
|
||||
.addr = long_be(0x0A28000A)
|
||||
};
|
||||
struct pico_socket sock = { };
|
||||
struct pico_ip4 *stored_ipv4 = NULL;
|
||||
struct pico_dhcp_server_negotiation *dn = NULL;
|
||||
struct pico_eth *arp_resp = NULL;
|
||||
unsigned char macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
uint32_t len = 0;
|
||||
uint8_t buf[600] = {
|
||||
0
|
||||
};
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/*Insert custom values in buffer*/
|
||||
fail_if(generate_dhcp_msg(buf, &len, DHCP_MSG_TYPE_DISCOVER), "DHCP_SERVER->failed to generate buffer");
|
||||
memcpy(&(buf[28]), &(macaddr1[0]), sizeof(struct pico_ip4));
|
||||
memcpy(&(buf[4]), &(xid.addr), sizeof(struct pico_ip4));
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_ipv4_link_add(mock->dev, serverip, netmask), "add link to mock device failed");
|
||||
s.server_ip = serverip;
|
||||
|
||||
/*Initiate test setup*/
|
||||
pico_stack_init();
|
||||
pico_arp_create_entry(&(macaddr1[0]), ipv4address, s.dev);
|
||||
|
||||
fail_if(pico_dhcp_server_initiate(&s), "DHCP_SERVER> server initiation failed");
|
||||
|
||||
/* simulate reception of a DISCOVER packet */
|
||||
sock.local_addr.ip4 = serverip;
|
||||
pico_dhcp_server_recv(&sock, buf, len);
|
||||
|
||||
/* check if negotiation data is stored */
|
||||
dn = pico_dhcp_server_find_negotiation(xid.addr);
|
||||
fail_if(dn == NULL, "DCHP SERVER -> no negotiation stored after discover msg recvd");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
stored_ipv4 = pico_arp_reverse_lookup(&dn->hwaddr);
|
||||
fail_if(stored_ipv4 == NULL, "DCHP SERVER -> new address is not inserted in ARP");
|
||||
fail_unless(stored_ipv4->addr == dn->ciaddr.addr, "DCHP SERVER -> new ip not stored in negotiation data");
|
||||
|
||||
/* check if new ip is in ARP cache */
|
||||
arp_resp = pico_arp_lookup(&ipv4address);
|
||||
fail_if(arp_resp == NULL, "DCHP SERVER -> address unavailable in arp cache");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#if 0
|
||||
START_TEST (test_dhcp_client)
|
||||
{
|
||||
struct mock_device*mock;
|
||||
uint32_t dhcp_hdr_offset = PICO_SIZE_ETHHDR + PICO_SIZE_IP4HDR + PICO_UDPHDR_SIZE;
|
||||
unsigned char macaddr1[6] = {
|
||||
0xc1, 0, 0, 0xa, 0xb, 0xf
|
||||
};
|
||||
struct pico_ip4 address = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 yiaddr = {
|
||||
.addr = long_be(0xC0A8000A)
|
||||
};
|
||||
struct pico_ip4 gateway = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 router = {
|
||||
.addr = long_be(0xC0A800FE)
|
||||
};
|
||||
uint8_t buf[BUFLEN] = {
|
||||
0
|
||||
};
|
||||
uint8_t offer_buf1[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x00, 0x01
|
||||
};
|
||||
uint8_t offer_buf2[] = {
|
||||
0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x00, 0x07, 0x08, 0x3b, 0x04, 0x00, 0x00, 0x0c, 0x4e, 0x33, 0x04, 0x00, 0x00, 0x0e, 0x10, 0x36, 0x04, 0xc0, 0xa8, 0x00, 0x01, 0xff
|
||||
};
|
||||
uint8_t routeropt_buf[] = {
|
||||
PICO_DHCPOPT_ROUTER, 0x04, 0xC0, 0xA8, 0x00, 0xFE, 0xFF
|
||||
};
|
||||
int type = 0;
|
||||
uint8_t printbufactive = 0;
|
||||
uint32_t len = 0;
|
||||
uint32_t xid = 0;
|
||||
struct pico_dhcp_client_cookie *cli = NULL;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
/* Create mock device */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
fail_if(!mock, "MOCK DEVICE creation failed");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
|
||||
/* initiate negotiation -> change state to */
|
||||
pico_dhcp_initiate_negotiation(mock->dev, &callback_dhcpclient, &xid);
|
||||
cli = get_cookie_by_xid(xid);
|
||||
dhcp_client_ptr = cli;
|
||||
fail_if(cli == NULL, "initiate fail");
|
||||
fail_unless(cli->state == DHCPSTATE_DISCOVER, "Not in discover state after init negotiate");
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
|
||||
/* push discover msg on network */
|
||||
tick_it(3);
|
||||
|
||||
/* read discover message from network */
|
||||
len = pico_mock_network_read(mock, buf, BUFLEN );
|
||||
fail_unless(len, "No msg received on network!");
|
||||
printbuf(&(buf[0]), len, "DHCP-DISCOVER packet", printbufactive);
|
||||
fail_unless(buf[0x011c] == 0x01, "No DHCP Discover received after initiate negotiation");
|
||||
mock_print_protocol(buf);
|
||||
fail_if(pico_mock_network_read(mock, buf, BUFLEN), "data on network that shouldn't be there");
|
||||
|
||||
/* check API access functions */
|
||||
address = pico_dhcp_get_address(cli);
|
||||
fail_unless(address.addr == 0, "Client address gets value at init -> should get it from dhcp server");
|
||||
|
||||
gateway = pico_dhcp_get_gateway(cli);
|
||||
fail_unless(gateway.addr == 0, "Gateway gets value at init -> should get it from dhcp server ");
|
||||
|
||||
/* Change received discovery msg to offer offer msg */
|
||||
buf[0x2a] = 0x02;
|
||||
memcpy(&(buf[0x3a]), &(offer_buf1[0]), sizeof(offer_buf1));
|
||||
memcpy(&(buf[0x3a]), &(yiaddr.addr), sizeof(struct pico_ip4));
|
||||
memcpy(&(buf[0x116]), &(offer_buf2[0]), sizeof(offer_buf2));
|
||||
memcpy(&(buf[0x13b]), &(routeropt_buf[0]), sizeof(routeropt_buf));
|
||||
memcpy(&(buf[0x13d]), &(router.addr), sizeof(struct pico_ip4));
|
||||
printbuf(&(buf[dhcp_hdr_offset]), len - dhcp_hdr_offset, "DHCP-OFFER message", printbufactive);
|
||||
|
||||
/* generate dhcp type from msg */
|
||||
type = pico_dhcp_verify_and_identify_type(&(buf[dhcp_hdr_offset]), len - dhcp_hdr_offset, cli);
|
||||
fail_if(type == 0, "unkown DHCP type");
|
||||
|
||||
/* simulate reception of a DHCP server offer */
|
||||
pico_dhcp_state_machine(type, cli, &(buf[dhcp_hdr_offset]), len - dhcp_hdr_offset);
|
||||
fail_if(cli->state == DHCPSTATE_DISCOVER, "still in discover state after dhcp server offer");
|
||||
fail_unless(cli->state == DHCPSTATE_REQUEST, "not in REQUEST state after dhcp server offer");
|
||||
|
||||
address = pico_dhcp_get_address(cli);
|
||||
fail_unless(address.addr == yiaddr.addr, "Client address incorrect => yiaddr or pico_dhcp_get_address incorrect");
|
||||
gateway = pico_dhcp_get_gateway(cli);
|
||||
fail_unless(gateway.addr == router.addr, "Gateway incorrect! => routeroption or pico_dhcp_get_gateway incorrect");
|
||||
tick_it(3);
|
||||
|
||||
len = pico_mock_network_read(mock, buf, BUFLEN);
|
||||
fail_unless(len, "received msg on network of %d bytes", len);
|
||||
printbuf(&(buf[0]), len, "DHCP-REQUEST packet", printbufactive);
|
||||
fail_unless(buf[0x011c] == 0x03, "No DHCP request received after offer");
|
||||
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
|
||||
START_TEST (test_dhcp_client_api)
|
||||
{
|
||||
/************************************************************************
|
||||
* Check API of pico_dhcp_initiate_negotiation
|
||||
* Status : Done
|
||||
************************************************************************/
|
||||
|
||||
/* Declaration test 0 */
|
||||
uint32_t xid0 = 0;
|
||||
struct pico_dhcp_client_cookie *cli0 = NULL;
|
||||
/* Declaration test 1 */
|
||||
uint32_t xid1 = 0;
|
||||
struct pico_dhcp_client_cookie *cli1 = NULL;
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
/* test 0 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Test 0 statements */
|
||||
pico_dhcp_initiate_negotiation(NULL, NULL, &xid0);
|
||||
cli0 = pico_dhcp_client_find_cookie(xid0);
|
||||
fail_unless(cli0 == NULL, "DHCP_CLIENT> initiate succeeded after pointer to dev == NULL");
|
||||
fail_unless(pico_err == PICO_ERR_EINVAL, "DHCP_SERVER> initiate succeeded without PICO_ERR_EINVAL after wrong parameter");
|
||||
|
||||
/* test 1 */
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Test 1 statements */
|
||||
pico_dhcp_initiate_negotiation(NULL, &callback_dhcpclient, &xid1);
|
||||
cli1 = pico_dhcp_client_find_cookie(xid1);
|
||||
fail_unless(cli1 == NULL, "DHCP_CLIENT> initiate succeeded after pointer to dev == NULL");
|
||||
fail_unless(pico_err == PICO_ERR_EINVAL, "DHCP_SERVER> initiate succeeded without PICO_ERR_EINVAL after wrong parameter");
|
||||
|
||||
#if 0
|
||||
/* not testable since we do not have a stub for the pico_socket_sendto */
|
||||
/* Declaration test 2 */
|
||||
uint32_t xid2 = 0;
|
||||
struct pico_dhcp_client_cookie *cli2 = NULL;
|
||||
struct pico_device *dev2;
|
||||
struct mock_device *mock2 = NULL;
|
||||
|
||||
/* test 2 */
|
||||
/* Create device */
|
||||
dev2 = pico_null_create("dummy");
|
||||
mock2 = pico_mock_create(NULL);
|
||||
fail_if(mock2 == NULL, "No device created");
|
||||
/* Clear error code */
|
||||
pico_err = PICO_ERR_NOERR;
|
||||
/* Test 2 statements */
|
||||
xid2 = pico_dhcp_initiate_negotiation(dev2, &callback_dhcpclient);
|
||||
cli2 = get_cookie_by_xid(xid2);
|
||||
fail_if(cli2 == NULL, "DHCP_CLIENT: error initiating: %s", strerror(pico_err));
|
||||
xid2 = pico_dhcp_initiate_negotiation(mock2->dev, &callback_dhcpclient);
|
||||
cli2 = get_cookie_by_xid(xid2);
|
||||
fail_if(cli2 == NULL, "DHCP_CLIENT: error initiating: %s", strerror(pico_err));
|
||||
xid2 = pico_dhcp_initiate_negotiation(dev2, &callback_dhcpclient);
|
||||
cli2 = get_cookie_by_xid(xid2);
|
||||
fail_if(cli2 == NULL, "DHCP_CLIENT: error initiating: %s", strerror(pico_err));
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
88
kernel/picotcp/test/unit/unit_dns.c
Normal file
88
kernel/picotcp/test/unit/unit_dns.c
Normal file
@ -0,0 +1,88 @@
|
||||
void cb_dns(char *ip, void *arg);
|
||||
|
||||
void cb_dns(char *ip, void *arg)
|
||||
{
|
||||
if (!ip) {
|
||||
/* Error occured */
|
||||
printf("DNS error getaddr\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do something */
|
||||
printf("DNS -> %s\n", ip);
|
||||
PICO_FREE(ip);
|
||||
if (arg)
|
||||
PICO_FREE(arg);
|
||||
}
|
||||
|
||||
|
||||
START_TEST (test_dns)
|
||||
{
|
||||
int ret;
|
||||
char url[] = "www.google.com";
|
||||
char ip[] = "8.8.4.4";
|
||||
struct pico_ip4 ns;
|
||||
|
||||
ns.addr = long_be(0x0a00280a); /* 10.40.0.10 */
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
printf("START DNS TEST\n");
|
||||
|
||||
/* testing nameserver API */
|
||||
ret = pico_dns_client_nameserver(NULL, PICO_DNS_NS_ADD);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver add error");
|
||||
|
||||
ret = pico_dns_client_nameserver(NULL, PICO_DNS_NS_DEL);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver del error");
|
||||
|
||||
ret = pico_dns_client_nameserver(NULL, 99);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver wrong code");
|
||||
|
||||
ret = pico_dns_client_nameserver(NULL, 0xFF);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver wrong code");
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_DEL); /* delete non added ns */
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver del error");
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, 99);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver wrong code");
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one */
|
||||
fail_if(ret < 0, "dns> dns_client_nameserver add error: %s", strerror(pico_err));
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, 99);
|
||||
fail_if(ret == 0, "dns> dns_client_nameserver wrong code");
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_DEL);
|
||||
fail_if(ret < 0, "dns> dns_client_nameserver del error: %s", strerror(pico_err));
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one */
|
||||
fail_if(ret < 0, "dns> dns_client_nameserver add error: %s", strerror(pico_err));
|
||||
|
||||
ret = pico_dns_client_nameserver(&ns, PICO_DNS_NS_ADD); /* add correct one again */
|
||||
fail_if(ret < 0, "dns> dns_client_nameserver add double failed");
|
||||
|
||||
/* testing getaddr API */
|
||||
/* not testable since we do not have a stub for the pico_socket_send */
|
||||
/* ret = pico_dns_client_getaddr(url, cb_dns, NULL); / * ask correct one * / */
|
||||
/* fail_if(ret < 0, "dns> dns_client_getaddr: %s",strerror(pico_err)); */
|
||||
|
||||
ret = pico_dns_client_getaddr(NULL, cb_dns, NULL);
|
||||
fail_if(ret == 0, "dns> dns_client_getaddr: no url");
|
||||
|
||||
ret = pico_dns_client_getaddr(url, NULL, NULL);
|
||||
fail_if(ret == 0, "dns> dns_client_getaddr: no cb");
|
||||
|
||||
/* testing getname API */
|
||||
/* not testable since we do not have a stub for the pico_socket_send */
|
||||
/* ret = pico_dns_client_getname(ip, cb_dns, NULL); / * ask correct one * / */
|
||||
/* fail_if(ret < 0, "dns> dns_client_getname: %s",strerror(pico_err)); */
|
||||
|
||||
ret = pico_dns_client_getname(NULL, cb_dns, NULL);
|
||||
fail_if(ret == 0, "dns> dns_client_getname: no ip");
|
||||
|
||||
ret = pico_dns_client_getname(ip, NULL, NULL);
|
||||
fail_if(ret == 0, "dns> dns_client_getname: no cb");
|
||||
}
|
||||
END_TEST
|
||||
401
kernel/picotcp/test/unit/unit_icmp4.c
Normal file
401
kernel/picotcp/test/unit/unit_icmp4.c
Normal file
@ -0,0 +1,401 @@
|
||||
|
||||
#include "pico_icmp4.h"
|
||||
#define NUM_PING 1
|
||||
int ping_test_var = 0;
|
||||
|
||||
void cb_ping(struct pico_icmp4_stats *s);
|
||||
void icmp4_unreach_socket_cb(uint16_t ev, struct pico_socket *s);
|
||||
|
||||
void cb_ping(struct pico_icmp4_stats *s)
|
||||
{
|
||||
char host[30];
|
||||
pico_ipv4_to_string(host, s->dst.addr);
|
||||
if (s->err == 0) {
|
||||
dbg("%lu bytes from %s: icmp_req=%lu ttl=64 time=%lu ms\n", s->size, host, s->seq, s->time);
|
||||
if (s->seq == NUM_PING) {
|
||||
ping_test_var++;
|
||||
}
|
||||
|
||||
fail_if (s->seq > NUM_PING);
|
||||
} else {
|
||||
dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST (test_icmp4_ping)
|
||||
{
|
||||
struct pico_ip4 local = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 remote = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
0
|
||||
};
|
||||
struct mock_device *mock = NULL;
|
||||
char local_address[] = {
|
||||
"192.168.1.102"
|
||||
};
|
||||
char remote_address[] = {
|
||||
"192.168.1.103"
|
||||
};
|
||||
uint16_t interval = 1000;
|
||||
uint16_t timeout = 5000;
|
||||
uint8_t size = 48;
|
||||
|
||||
int bufferlen = 80;
|
||||
uint8_t buffer[bufferlen];
|
||||
int len;
|
||||
uint8_t temp_buf[4];
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
pico_string_to_ipv4(local_address, &(local.addr));
|
||||
pico_string_to_ipv4("255.255.255.0", &(netmask.addr));
|
||||
|
||||
pico_string_to_ipv4(remote_address, &(remote.addr));
|
||||
pico_string_to_ipv4("255.255.255.0", &(netmask.addr));
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
fail_if(mock == NULL, "No device created");
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
fail_if(pico_icmp4_ping(local_address, NUM_PING, interval, timeout, size, cb_ping) < 0);
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
fail_if(ping_test_var != 1);
|
||||
|
||||
pico_icmp4_ping(remote_address, NUM_PING, interval, timeout, size, cb_ping);
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
/* get the packet from the mock_device */
|
||||
memset(buffer, 0, (size_t)bufferlen);
|
||||
len = pico_mock_network_read(mock, buffer, bufferlen);
|
||||
fail_if(len < 20);
|
||||
/* inspect it */
|
||||
fail_unless(mock_ip_protocol(mock, buffer, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer, len) == 8);
|
||||
fail_unless(mock_icmp_code(mock, buffer, len) == 0);
|
||||
fail_unless(pico_checksum(buffer + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
/* cobble up a reply */
|
||||
buffer[20] = 0; /* type 0 : reply */
|
||||
memcpy(temp_buf, buffer + 12, 4);
|
||||
memcpy(buffer + 12, buffer + 16, 4);
|
||||
memcpy(buffer + 16, temp_buf, 4);
|
||||
|
||||
/* using the mock-device because otherwise I have to put everything in a pico_frame correctly myself. */
|
||||
pico_mock_network_write(mock, buffer, len);
|
||||
/* check if it is received */
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
fail_unless(ping_test_var == 2);
|
||||
|
||||
/* repeat but make it an invalid reply... */
|
||||
|
||||
pico_icmp4_ping(remote_address, NUM_PING, interval, timeout, size, cb_ping);
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
/* get the packet from the mock_device */
|
||||
memset(buffer, 0, (size_t)bufferlen);
|
||||
len = pico_mock_network_read(mock, buffer, bufferlen);
|
||||
/* inspect it */
|
||||
fail_unless(mock_ip_protocol(mock, buffer, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer, len) == 8);
|
||||
fail_unless(mock_icmp_code(mock, buffer, len) == 0);
|
||||
fail_unless(pico_checksum(buffer + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
/* cobble up a reply */
|
||||
buffer[20] = 0; /* type 0 : reply */
|
||||
memcpy(temp_buf, buffer + 12, 4);
|
||||
memcpy(buffer + 12, buffer + 16, 4);
|
||||
memcpy(buffer + 16, temp_buf, 4);
|
||||
buffer[26] = (uint8_t)~buffer[26]; /* flip some bits in the sequence number, to see if the packet gets ignored properly */
|
||||
|
||||
/* using the mock-device because otherwise I have to put everything in a pico_frame correctly myself. */
|
||||
pico_mock_network_write(mock, buffer, len);
|
||||
/* check if it is received */
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
fail_unless(ping_test_var == 2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST (test_icmp4_incoming_ping)
|
||||
{
|
||||
int bufferlen = 76;
|
||||
uint8_t buffer[76] = {
|
||||
0x45, 0x00, 0x00, 0x4c,
|
||||
0x91, 0xc3, 0x40, 0x00,
|
||||
0x40, 0x01, 0x24, 0xd0,
|
||||
0xc0, 0xa8, 0x01, 0x66,
|
||||
0xc0, 0xa8, 0x01, 0x64,
|
||||
0x08, 0x00, 0x66, 0x3c,
|
||||
0x91, 0xc2, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
int buffer2len = 76;
|
||||
int len;
|
||||
int cntr = 0;
|
||||
uint8_t buffer2[bufferlen];
|
||||
struct pico_ip4 local = {
|
||||
.addr = long_be(0xc0a80164)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct mock_device*mock;
|
||||
struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) buffer;
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
fail_if(mock == NULL, "No device created");
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
hdr->crc = 0;
|
||||
hdr->crc = short_be(pico_checksum(hdr, PICO_SIZE_IP4HDR));
|
||||
pico_mock_network_write(mock, buffer, bufferlen);
|
||||
/* check if it is received */
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, buffer2len);
|
||||
/* inspect it */
|
||||
|
||||
while(cntr < len) {
|
||||
printf("0x%02x ", buffer2[cntr]);
|
||||
cntr++;
|
||||
if(cntr % 4 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
fail_unless(len == buffer2len, "ping reply lenght does not match, expected len: %d, got: %d", buffer2len, len);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 0);
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 0);
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_icmp4_unreachable_send)
|
||||
{
|
||||
struct pico_ip4 local = {
|
||||
.addr = long_be(0x0a280064)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct mock_device*mock;
|
||||
int len = 0;
|
||||
int bufferlen = 80;
|
||||
uint8_t buffer2[bufferlen];
|
||||
|
||||
uint8_t buffer[32] = {
|
||||
0x45, 0x00, 0x00, 0x20, 0x91, 0xc0, 0x40, 0x00,
|
||||
0x40, 0x11, 0x94, 0xb4, 0x0a, 0x28, 0x00, 0x05,
|
||||
0x0a, 0x28, 0x00, 0x04, 0x15, 0xb3, 0x15, 0xb3,
|
||||
0x00, 0x0c, 0x00, 0x00, 'e', 'l', 'l', 'o'
|
||||
};
|
||||
|
||||
/* fake packet with bad upper-layer-protocol */
|
||||
uint8_t buffer3[20] = {
|
||||
0x45, 0x00, 0x00, 0x14, 0x91, 0xc0, 0x40, 0x00,
|
||||
0x40, 0xff, 0x94, 0xb4, 0x0a, 0x28, 0x00, 0x05,
|
||||
0x0a, 0x28, 0x00, 0x04
|
||||
};
|
||||
|
||||
struct pico_frame*f = PICO_ZALLOC(sizeof(struct pico_frame));
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
|
||||
f->net_hdr = buffer;
|
||||
f->buffer = buffer;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
fail_if(mock == NULL, "No device created");
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
|
||||
fail_if(pico_icmp4_dest_unreachable(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 56, "len is indeed %d\n", len);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 3); /* destination unreachable */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 1); /* host unreachable */
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
|
||||
fail_if(pico_icmp4_port_unreachable(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 56);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 3); /* destination unreachable */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 3); /* port unreachable */
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
|
||||
fail_if(pico_icmp4_proto_unreachable(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 56);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 3); /* destination unreachable */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 2); /* proto unreachable */
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
|
||||
fail_if(pico_icmp4_ttl_expired(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 56);
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 11); /* ttl expired */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 0);
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
|
||||
f->net_hdr = buffer3;
|
||||
f->buffer = buffer3;
|
||||
|
||||
fail_if(pico_icmp4_proto_unreachable(f));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
|
||||
len = pico_mock_network_read(mock, buffer2, bufferlen);
|
||||
|
||||
fail_unless(len == 48); /* Buffer 3 is shorter, reply is shorter too... */
|
||||
fail_unless(mock_ip_protocol(mock, buffer2, len) == 1);
|
||||
fail_unless(mock_icmp_type(mock, buffer2, len) == 3); /* destination unreachable */
|
||||
fail_unless(mock_icmp_code(mock, buffer2, len) == 2); /* proto unreachable */
|
||||
fail_unless(pico_checksum(buffer2 + 20, (uint32_t)(len - 20)) == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int icmp4_socket_unreach_status = 0;
|
||||
void icmp4_unreach_socket_cb(uint16_t ev, struct pico_socket *s)
|
||||
{
|
||||
IGNORE_PARAMETER(s);
|
||||
|
||||
if (ev == PICO_SOCK_EV_ERR) {
|
||||
icmp4_socket_unreach_status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST (test_icmp4_unreachable_recv)
|
||||
{
|
||||
struct pico_ip4 local = {
|
||||
.addr = long_be(0x0a280064)
|
||||
};
|
||||
struct pico_ip4 remote = {
|
||||
.addr = long_be(0x0a280065)
|
||||
};
|
||||
struct pico_ip4 netmask = {
|
||||
.addr = long_be(0xffffff00)
|
||||
};
|
||||
struct mock_device*mock;
|
||||
struct pico_socket*sock;
|
||||
uint16_t port = short_be(7777);
|
||||
|
||||
/* put a host unreachable in the queue, run a few stack ticks */
|
||||
uint8_t buffer[] = {
|
||||
0x45, 0x00, 0x00, 0x20,
|
||||
0x91, 0xc0, 0x40, 0x00,
|
||||
0x40, 0x01, 0x94, 0xb4,
|
||||
0x0a, 0x28, 0x00, 0x65,
|
||||
0x0a, 0x28, 0x00, 0x64,
|
||||
0x03, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) buffer;
|
||||
|
||||
printf("*********************** starting %s * \n", __func__);
|
||||
pico_stack_init();
|
||||
|
||||
mock = pico_mock_create(NULL);
|
||||
fail_if(mock == NULL, "No device created");
|
||||
|
||||
pico_ipv4_link_add(mock->dev, local, netmask);
|
||||
|
||||
/* open a socket */
|
||||
sock = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &icmp4_unreach_socket_cb);
|
||||
fail_if(sock == NULL);
|
||||
fail_if(pico_socket_bind(sock, &local, &port));
|
||||
pico_socket_connect(sock, &remote, port);
|
||||
pico_socket_write(sock, "fooo", 4);
|
||||
/* see if my callback was called with the proper code */
|
||||
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
/* filling in the IP header and first 8 bytes */
|
||||
hdr->crc = 0;
|
||||
hdr->crc = short_be(pico_checksum(hdr, PICO_SIZE_IP4HDR));
|
||||
printf("read %d bytes\n", pico_mock_network_read(mock, buffer + 28, 28));
|
||||
|
||||
printf("wrote %d bytes\n", pico_mock_network_write(mock, buffer, 56));
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
fail_unless(icmp4_socket_unreach_status == 1);
|
||||
}
|
||||
END_TEST
|
||||
852
kernel/picotcp/test/unit/unit_ipv4.c
Normal file
852
kernel/picotcp/test/unit/unit_ipv4.c
Normal file
@ -0,0 +1,852 @@
|
||||
|
||||
START_TEST (test_ipv4)
|
||||
{
|
||||
#define IP_TST_SIZ 256
|
||||
uint32_t i;
|
||||
|
||||
struct pico_device *dev[IP_TST_SIZ];
|
||||
char devname[8];
|
||||
struct pico_ip4 a[IP_TST_SIZ], d[IP_TST_SIZ], *source[IP_TST_SIZ], nm16, nm32, gw[IP_TST_SIZ], r[IP_TST_SIZ], ret;
|
||||
struct pico_ipv4_link *l[IP_TST_SIZ];
|
||||
|
||||
char ipstr[] = "192.168.1.1";
|
||||
struct pico_ip4 ipaddr;
|
||||
|
||||
struct pico_frame *f_NULL = NULL;
|
||||
struct pico_ip4 *dst_NULL = NULL;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
nm16.addr = long_be(0xFFFF0000);
|
||||
nm32.addr = long_be(0xFFFFFFFF);
|
||||
|
||||
/*link_add*/
|
||||
for (i = 0; i < IP_TST_SIZ; i++) {
|
||||
snprintf(devname, 8, "nul%d", i);
|
||||
dev[i] = pico_null_create(devname);
|
||||
a[i].addr = long_be(0x0a000001u + (i << 16));
|
||||
d[i].addr = long_be(0x0a000002u + (i << 16));
|
||||
fail_if(pico_ipv4_link_add(dev[i], a[i], nm16) != 0, "Error adding link");
|
||||
}
|
||||
/*link_find + link_get + route_add*/
|
||||
for (i = 0; i < IP_TST_SIZ; i++) {
|
||||
gw[i].addr = long_be(0x0a0000f0u + (i << 16));
|
||||
r[i].addr = long_be(0x0c00001u + (i << 16));
|
||||
fail_unless(pico_ipv4_link_find(&a[i]) == dev[i], "Error finding link");
|
||||
l[i] = pico_ipv4_link_get(&a[i]);
|
||||
fail_if(l[i] == NULL, "Error getting link");
|
||||
fail_if(pico_ipv4_route_add(r[i], nm32, gw[i], 1, l[i]) != 0, "Error adding route");
|
||||
fail_if(pico_ipv4_route_add(d[i], nm32, gw[i], 1, l[i]) != 0, "Error adding route");
|
||||
}
|
||||
/*get_gateway + source_find*/
|
||||
for (i = 0; i < IP_TST_SIZ; i++) {
|
||||
ret = pico_ipv4_route_get_gateway(&r[i]);
|
||||
fail_if(ret.addr != gw[i].addr, "Error get gateway: returned wrong route");
|
||||
source[i] = pico_ipv4_source_find(&d[i]);
|
||||
fail_if(source[i]->addr != a[i].addr, "Error find source: returned wrong route");
|
||||
}
|
||||
/*route_del + link_del*/
|
||||
for (i = 0; i < IP_TST_SIZ; i++) {
|
||||
fail_if(pico_ipv4_route_del(r[i], nm32, 1) != 0, "Error deleting route");
|
||||
fail_if(pico_ipv4_link_del(dev[i], a[i]) != 0, "Error deleting link");
|
||||
}
|
||||
/*string_to_ipv4 + ipv4_to_string*/
|
||||
pico_string_to_ipv4(ipstr, &(ipaddr.addr));
|
||||
fail_if(ipaddr.addr != long_be(0xc0a80101), "Error string to ipv4");
|
||||
memset(ipstr, 0, 12);
|
||||
pico_ipv4_to_string(ipstr, ipaddr.addr);
|
||||
fail_if(strncmp(ipstr, "192.168.1.1", 11) != 0, "Error ipv4 to string");
|
||||
|
||||
/*valid_netmask*/
|
||||
fail_if(pico_ipv4_valid_netmask(long_be(nm32.addr)) != 32, "Error checking netmask");
|
||||
|
||||
/*is_unicast*/
|
||||
fail_if((pico_ipv4_is_unicast(long_be(0xc0a80101))) != 1, "Error checking unicast");
|
||||
fail_if((pico_ipv4_is_unicast(long_be(0xe0000001))) != 0, "Error checking unicast");
|
||||
|
||||
/*rebound*/
|
||||
fail_if(pico_ipv4_rebound(f_NULL) != -1, "Error rebound frame");
|
||||
|
||||
/*frame_push*/
|
||||
fail_if(pico_ipv4_frame_push(f_NULL, dst_NULL, PICO_PROTO_TCP) != -1, "Error push frame");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_nat_enable_disable)
|
||||
{
|
||||
struct pico_ipv4_link link = {
|
||||
.address = {.addr = long_be(0x0a320001)}
|
||||
}; /* 10.50.0.1 */
|
||||
struct pico_frame *f = pico_ipv4_alloc(&pico_proto_ipv4, NULL, PICO_UDPHDR_SIZE);
|
||||
struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr;
|
||||
struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr;
|
||||
const char *raw_data = "ello";
|
||||
|
||||
net->vhl = 0x45; /* version = 4, hdr len = 5 (32-bit words) */
|
||||
net->tos = 0;
|
||||
net->len = short_be(32); /* hdr + data (bytes) */
|
||||
net->id = short_be(0x91c0);
|
||||
net->frag = short_be(0x4000); /* don't fragment flag, offset = 0 */
|
||||
net->ttl = 64;
|
||||
net->proto = 17; /* UDP */
|
||||
net->crc = 0;
|
||||
net->src.addr = long_be(0x0a280008); /* 10.40.0.8 */
|
||||
net->dst.addr = long_be(0x0a320001); /* 10.50.0.1 */
|
||||
|
||||
udp->trans.sport = short_be(5555);
|
||||
udp->trans.dport = short_be(6667);
|
||||
udp->len = 12;
|
||||
udp->crc = 0;
|
||||
|
||||
f->payload = f->transport_hdr + PICO_UDPHDR_SIZE;
|
||||
memcpy(f->payload, raw_data, 4);
|
||||
|
||||
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NAT ENABLE/DISABLE TEST\n");
|
||||
pico_stack_init();
|
||||
|
||||
fail_if(pico_ipv4_nat_enable(&link));
|
||||
fail_unless(nat_link->address.addr == link.address.addr);
|
||||
fail_unless(pico_ipv4_nat_is_enabled(&link.address));
|
||||
|
||||
fail_if(pico_ipv4_nat_outbound(f, &net->dst));
|
||||
pico_ipv4_nat_table_cleanup(pico_tick, NULL);
|
||||
|
||||
fail_if(pico_ipv4_nat_disable());
|
||||
fail_if(pico_ipv4_nat_is_enabled(&link.address));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_nat_translation)
|
||||
{
|
||||
struct pico_ipv4_link link = {
|
||||
.address = {.addr = long_be(0x0a320001)}
|
||||
}; /* 10.50.0.1 */
|
||||
struct pico_frame *f = pico_ipv4_alloc(&pico_proto_ipv4, NULL, PICO_UDPHDR_SIZE);
|
||||
struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr;
|
||||
struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr;
|
||||
struct pico_ip4 src_ori = {
|
||||
.addr = long_be(0x0a280008)
|
||||
}; /* 10.40.0.8 */
|
||||
struct pico_ip4 dst_ori = {
|
||||
.addr = long_be(0x0a320009)
|
||||
}; /* 10.50.0.9 */
|
||||
struct pico_ip4 nat = {
|
||||
.addr = long_be(0x0a320001)
|
||||
}; /* 10.50.0.9 */
|
||||
const char *raw_data = "ello";
|
||||
uint16_t sport_ori = short_be(5555);
|
||||
uint16_t dport_ori = short_be(6667);
|
||||
uint16_t nat_port = 0;
|
||||
|
||||
net->vhl = 0x45; /* version = 4, hdr len = 5 (32-bit words) */
|
||||
net->tos = 0;
|
||||
net->len = short_be(32); /* hdr + data (bytes) */
|
||||
net->id = short_be(0x91c0);
|
||||
net->frag = short_be(0x4000); /* don't fragment flag, offset = 0 */
|
||||
net->ttl = 64;
|
||||
net->proto = 17; /* UDP */
|
||||
net->crc = 0;
|
||||
net->src = src_ori;
|
||||
net->dst = dst_ori;
|
||||
|
||||
udp->trans.sport = sport_ori;
|
||||
udp->trans.dport = dport_ori;
|
||||
udp->len = 12;
|
||||
udp->crc = 0;
|
||||
|
||||
f->payload = f->transport_hdr + PICO_UDPHDR_SIZE;
|
||||
memcpy(f->payload, raw_data, 4);
|
||||
|
||||
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NAT TRANSLATION TEST\n");
|
||||
pico_stack_init();
|
||||
fail_if(pico_ipv4_nat_enable(&link));
|
||||
|
||||
/* perform outbound translation, check if source IP got translated */
|
||||
fail_if(pico_ipv4_nat_outbound(f, &nat_link->address));
|
||||
fail_if(net->src.addr != link.address.addr, "source address not translated");
|
||||
|
||||
/* perform outbound translation of same packet, check if source IP and PORT got translated the same as previous packet */
|
||||
nat_port = udp->trans.sport;
|
||||
net->src = src_ori; /* restore original src */
|
||||
udp->trans.sport = sport_ori; /* restore original sport */
|
||||
fail_if(pico_ipv4_nat_outbound(f, &nat_link->address));
|
||||
fail_if(net->src.addr != link.address.addr, "source address not translated");
|
||||
fail_if(udp->trans.sport != nat_port, "frames with the same source IP, source PORT and PROTO did not get translated the same");
|
||||
|
||||
/* perform outbound translation of packet with changed source PORT, check if source PORT got translated differently as previous packet */
|
||||
nat_port = udp->trans.sport;
|
||||
net->src = src_ori; /* restore original src */
|
||||
udp->trans.sport = short_be(5556); /* change sport */
|
||||
fail_if(pico_ipv4_nat_outbound(f, &nat_link->address));
|
||||
fail_if(net->src.addr != link.address.addr, "source address not translated");
|
||||
fail_if(udp->trans.sport == short_be(sport_ori), "two frames with different sport get translated the same");
|
||||
|
||||
/* perform inbound translation of previous packet, check if destination IP and PORT got translated to the original source IP and PORT */
|
||||
nat_port = udp->trans.sport;
|
||||
net->src = dst_ori;
|
||||
net->dst = nat;
|
||||
udp->trans.sport = sport_ori;
|
||||
udp->trans.dport = nat_port;
|
||||
fail_if(pico_ipv4_nat_inbound(f, &nat_link->address));
|
||||
fail_if(net->dst.addr != src_ori.addr, "destination address not translated correctly");
|
||||
fail_if(udp->trans.dport != short_be(5556), "ports not translated correctly");
|
||||
pico_ipv4_nat_table_cleanup(pico_tick, NULL);
|
||||
|
||||
fail_if(pico_ipv4_nat_disable());
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_nat_port_forwarding)
|
||||
{
|
||||
struct pico_ipv4_link link = {
|
||||
.address = {.addr = long_be(0x0a320001)}
|
||||
}; /* 10.50.0.1 */
|
||||
struct pico_frame *f = pico_ipv4_alloc(&pico_proto_ipv4, NULL, PICO_UDPHDR_SIZE);
|
||||
struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr;
|
||||
struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr;
|
||||
struct pico_ip4 src_addr = {
|
||||
.addr = long_be(0x0a280008)
|
||||
}; /* 10.40.0.8 */
|
||||
struct pico_ip4 dst_addr = {
|
||||
.addr = long_be(0x0a320009)
|
||||
}; /* 10.50.0.9 */
|
||||
struct pico_ip4 nat_addr = {
|
||||
.addr = long_be(0x0a320001)
|
||||
}; /* 10.50.0.9 */
|
||||
const char *raw_data = "ello";
|
||||
uint16_t sport_ori = short_be(5555);
|
||||
uint16_t fport_pub = short_be(80);
|
||||
uint16_t fport_priv = short_be(8080);
|
||||
|
||||
net->vhl = 0x45; /* version = 4, hdr len = 5 (32-bit words) */
|
||||
net->tos = 0;
|
||||
net->len = short_be(32); /* hdr + data (bytes) */
|
||||
net->id = short_be(0x91c0);
|
||||
net->frag = short_be(0x4000); /* don't fragment flag, offset = 0 */
|
||||
net->ttl = 64;
|
||||
net->proto = 17; /* UDP */
|
||||
net->crc = 0;
|
||||
net->src = dst_addr;
|
||||
net->dst = nat_addr;
|
||||
|
||||
udp->trans.sport = sport_ori;
|
||||
udp->trans.dport = fport_pub;
|
||||
udp->len = 12;
|
||||
udp->crc = 0;
|
||||
|
||||
f->payload = f->transport_hdr + PICO_UDPHDR_SIZE;
|
||||
memcpy(f->payload, raw_data, 4);
|
||||
|
||||
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NAT PORT FORWARD TEST\n");
|
||||
pico_stack_init();
|
||||
fail_if(pico_ipv4_nat_enable(&link));
|
||||
|
||||
fail_if(pico_ipv4_port_forward(nat_addr, fport_pub, src_addr, fport_priv, 17, PICO_NAT_PORT_FORWARD_ADD));
|
||||
|
||||
fail_if(pico_ipv4_nat_inbound(f, &nat_link->address));
|
||||
fail_if(net->dst.addr != src_addr.addr, "destination address not translated correctly");
|
||||
fail_if(udp->trans.dport != fport_priv, "destination port not translated correctly");
|
||||
|
||||
fail_if(pico_ipv4_port_forward(nat_addr, fport_pub, src_addr, fport_priv, 17, PICO_NAT_PORT_FORWARD_DEL));
|
||||
pico_ipv4_nat_table_cleanup(pico_tick, NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_ipfilter)
|
||||
{
|
||||
struct pico_device *dev = NULL;
|
||||
uint8_t proto = 0, tos = 0;
|
||||
uint16_t sport = 0, dport = 0;
|
||||
int8_t priority = 0;
|
||||
int ret = 0;
|
||||
|
||||
struct pico_ip4 src_addr = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 saddr_netmask = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 dst_addr = {
|
||||
0
|
||||
};
|
||||
struct pico_ip4 daddr_netmask = {
|
||||
0
|
||||
};
|
||||
|
||||
enum filter_action action = 1;
|
||||
|
||||
uint32_t filter_id1;
|
||||
|
||||
/* 192.168.1.2:16415 -> 192.168.1.109:1222 [sending a TCP syn] */
|
||||
uint8_t ipv4_buf[] = {
|
||||
0x00, 0x02, 0xf7, 0xf1, 0x79, 0x33, 0xe0, 0xdb, 0x55,
|
||||
0xd4, 0xb6, 0x27, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28,
|
||||
0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf7, 0x0f, 0xc0,
|
||||
0xa8, 0x01, 0x02, 0xc0, 0xa8, 0x01, 0x6d, 0x40, 0x1f,
|
||||
0x04, 0xc6, 0x00, 0xb1, 0x56, 0x5a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x50, 0x02, 0x20, 0x00, 0x70, 0x32, 0x00, 0x00
|
||||
};
|
||||
|
||||
struct pico_frame *f;
|
||||
|
||||
printf("IP Filter> Adding a new filter...\n");
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, action);
|
||||
fail_if(filter_id1 <= 0, "Error adding filter\n");
|
||||
printf("filter_id1 = %d\n", filter_id1);
|
||||
|
||||
printf("IP Filter> Trying to add the same filter...\n");
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, action);
|
||||
fail_if(ret > 0, "Error adding filter\n");
|
||||
|
||||
printf("IP Filter> Deleting added filter...\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != 0, "Error deleting the filter\n");
|
||||
|
||||
printf("IP Filter> Trying to delete the same filter\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != -1, "Deleting non existing filter failed\n");
|
||||
|
||||
f = (struct pico_frame *)PICO_ZALLOC(200);
|
||||
f->buffer = PICO_ZALLOC(20);
|
||||
f->usage_count = PICO_ZALLOC(sizeof(uint32_t));
|
||||
f->buffer = ipv4_buf;
|
||||
f->net_hdr = ipv4_buf + 14u; /* shifting to IP layer */
|
||||
f->transport_hdr = ipv4_buf + 34u; /* shifting to Transport layer */
|
||||
|
||||
/* adding exact filter */
|
||||
pico_string_to_ipv4("192.168.1.109", &src_addr.addr);
|
||||
pico_string_to_ipv4("255.255.255.255", &saddr_netmask.addr);
|
||||
sport = 1222u;
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, FILTER_REJECT);
|
||||
fail_if(filter_id1 <= 0, "Error adding exact filter\n");
|
||||
printf("Filter is added\n");
|
||||
sync();
|
||||
sleep(1);
|
||||
|
||||
ret = ipfilter(f);
|
||||
fail_if(ret != 1, "Frame wasn't filtered\n");
|
||||
|
||||
printf("IP Filter> Deleting added filter...\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != 0, "Error deleting the filter\n");
|
||||
|
||||
printf("IP Filter> Adding masked filter...\n");
|
||||
pico_string_to_ipv4("192.168.1.7", &src_addr.addr);
|
||||
pico_string_to_ipv4("255.255.255.0", &saddr_netmask.addr);
|
||||
sport = 1222u;
|
||||
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, FILTER_DROP);
|
||||
fail_if(filter_id1 <= 0, "Error adding masked filter\n");
|
||||
|
||||
f = (struct pico_frame *)PICO_ZALLOC(200);
|
||||
f->buffer = PICO_ZALLOC(20);
|
||||
f->usage_count = PICO_ZALLOC(sizeof(uint32_t));
|
||||
f->buffer = ipv4_buf;
|
||||
f->net_hdr = ipv4_buf + 14u; /* shifting to IP layer */
|
||||
f->transport_hdr = ipv4_buf + 34u; /* shifting to Transport layer */
|
||||
ret = ipfilter(f);
|
||||
fail_if(ret != 1, "Mask filter failed to filter\n");
|
||||
|
||||
printf("IP Filter> Deleting added filter...\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != 0, "Error deleting the filter\n");
|
||||
|
||||
printf("IP Filter> Adding bad filter..\n");
|
||||
pico_string_to_ipv4("191.1.1.7", &src_addr.addr);
|
||||
pico_string_to_ipv4("255.255.255.0", &saddr_netmask.addr);
|
||||
sport = 1991u;
|
||||
filter_id1 = pico_ipv4_filter_add(dev, proto, &src_addr, &saddr_netmask, &dst_addr, &daddr_netmask, sport, dport, priority, tos, FILTER_DROP);
|
||||
fail_if(filter_id1 <= 0, "Error adding bad filter\n");
|
||||
|
||||
f = (struct pico_frame *)PICO_ZALLOC(200);
|
||||
f->buffer = PICO_ZALLOC(20);
|
||||
f->usage_count = PICO_ZALLOC(sizeof(uint32_t));
|
||||
f->buffer = ipv4_buf;
|
||||
f->net_hdr = ipv4_buf + 14u; /* shifting to IP layer */
|
||||
f->transport_hdr = ipv4_buf + 34u; /* shifting to Transport layer */
|
||||
ret = ipfilter(f);
|
||||
fail_if(ret != 0, "Filter shouldn't have filtered this frame\n");
|
||||
|
||||
printf("IP Filter> Deleting added filter...\n");
|
||||
ret = pico_ipv4_filter_del(filter_id1);
|
||||
fail_if(ret != 0, "Error deleting the filter\n");
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef PICO_SUPPORT_MCAST
|
||||
START_TEST (test_igmp_sockopts)
|
||||
{
|
||||
int i = 0, j = 0, k = 0, ret = 0;
|
||||
struct pico_socket *s, *s1 = NULL;
|
||||
struct pico_device *dev = NULL;
|
||||
union pico_address *source = NULL;
|
||||
union pico_address inaddr_dst = {
|
||||
0
|
||||
}, inaddr_incorrect = {
|
||||
0
|
||||
}, inaddr_uni = {
|
||||
0
|
||||
}, inaddr_null = {
|
||||
0
|
||||
}, netmask = {
|
||||
0
|
||||
};
|
||||
union pico_address inaddr_link[2] = {0};
|
||||
union pico_address inaddr_mcast[8] = {0};
|
||||
union pico_address inaddr_source[8] = {0};
|
||||
struct pico_ip_mreq _mreq = {0}, mreq[16] = {0};
|
||||
struct pico_ip_mreq_source mreq_source[128] = {0};
|
||||
struct pico_tree_node *index = NULL;
|
||||
|
||||
int ttl = 64;
|
||||
int getttl = 0;
|
||||
int loop = 9;
|
||||
int getloop = 0;
|
||||
union pico_address mcast_def_link = {
|
||||
0
|
||||
};
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
printf("START IGMP SOCKOPTS TEST\n");
|
||||
|
||||
pico_string_to_ipv4("224.7.7.7", &inaddr_dst.ip4.addr);
|
||||
pico_string_to_ipv4("10.40.0.2", &inaddr_uni.ip4.addr);
|
||||
pico_string_to_ipv4("224.8.8.8", &inaddr_incorrect.ip4.addr);
|
||||
pico_string_to_ipv4("0.0.0.0", &inaddr_null.ip4.addr);
|
||||
|
||||
pico_string_to_ipv4("10.40.0.1", &inaddr_link[0].ip4.addr); /* 0 */
|
||||
pico_string_to_ipv4("10.50.0.1", &inaddr_link[1].ip4.addr); /* 1 */
|
||||
|
||||
pico_string_to_ipv4("232.1.1.0", &inaddr_mcast[0].ip4.addr); /* 0 */
|
||||
pico_string_to_ipv4("232.2.2.1", &inaddr_mcast[1].ip4.addr); /* 1 */
|
||||
pico_string_to_ipv4("232.3.3.2", &inaddr_mcast[2].ip4.addr); /* 2 */
|
||||
pico_string_to_ipv4("232.4.4.3", &inaddr_mcast[3].ip4.addr); /* 3 */
|
||||
pico_string_to_ipv4("232.5.5.4", &inaddr_mcast[4].ip4.addr); /* 4 */
|
||||
pico_string_to_ipv4("232.6.6.5", &inaddr_mcast[5].ip4.addr); /* 5 */
|
||||
pico_string_to_ipv4("232.7.7.6", &inaddr_mcast[6].ip4.addr); /* 6 */
|
||||
pico_string_to_ipv4("232.8.8.7", &inaddr_mcast[7].ip4.addr); /* 7 */
|
||||
|
||||
pico_string_to_ipv4("10.40.1.0", &inaddr_source[0].ip4.addr); /* 0 */
|
||||
pico_string_to_ipv4("10.40.1.1", &inaddr_source[1].ip4.addr); /* 1 */
|
||||
pico_string_to_ipv4("10.40.1.2", &inaddr_source[2].ip4.addr); /* 2 */
|
||||
pico_string_to_ipv4("10.40.1.3", &inaddr_source[3].ip4.addr); /* 3 */
|
||||
pico_string_to_ipv4("10.40.1.4", &inaddr_source[4].ip4.addr); /* 4 */
|
||||
pico_string_to_ipv4("10.40.1.5", &inaddr_source[5].ip4.addr); /* 5 */
|
||||
pico_string_to_ipv4("10.40.1.6", &inaddr_source[6].ip4.addr); /* 6 */
|
||||
pico_string_to_ipv4("10.40.1.7", &inaddr_source[7].ip4.addr); /* 7 */
|
||||
|
||||
/* 00 01 02 03 04 05 06 07 | 10 11 12 13 14 15 16 17 */
|
||||
for (i = 0; i < 16; i++) {
|
||||
mreq[i].mcast_link_addr = inaddr_link[i / 8];
|
||||
mreq[i].mcast_group_addr = inaddr_mcast[i % 8];
|
||||
}
|
||||
/* 000 001 002 003 004 005 006 007 | 010 011 012 013 014 015 016 017 */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
/* printf(">>>>> mreq_source[%d]: link[%d] mcast[%d] source[%d]\n", (i*8)+j, i/8, i%8, j); */
|
||||
mreq_source[(i * 8) + j].mcast_link_addr = inaddr_link[i / 8];
|
||||
mreq_source[(i * 8) + j].mcast_group_addr = inaddr_mcast[i % 8];
|
||||
mreq_source[(i * 8) + j].mcast_source_addr = inaddr_source[j];
|
||||
}
|
||||
}
|
||||
dev = pico_null_create("dummy0");
|
||||
netmask.ip4.addr = long_be(0xFFFF0000);
|
||||
ret = pico_ipv4_link_add(dev, inaddr_link[0].ip4, netmask.ip4);
|
||||
fail_if(ret < 0, "link add failed");
|
||||
|
||||
dev = pico_null_create("dummy1");
|
||||
netmask.ip4.addr = long_be(0xFFFF0000);
|
||||
ret = pico_ipv4_link_add(dev, inaddr_link[1].ip4, netmask.ip4);
|
||||
fail_if(ret < 0, "link add failed");
|
||||
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s == NULL, "UDP socket open failed");
|
||||
s1 = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s1 == NULL, "UDP socket open failed");
|
||||
|
||||
/* argument validation tests */
|
||||
printf("IGMP SETOPTION ARGUMENT VALIDATION TEST\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_IF, &mcast_def_link);
|
||||
fail_if(ret == 0, "unsupported PICO_IP_MULTICAST_IF succeeded\n");
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_IF, &mcast_def_link);
|
||||
fail_if(ret == 0, "unsupported PICO_IP_MULTICAST_IF succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_TTL, &ttl);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_TTL failed\n");
|
||||
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_TTL, &getttl);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_TTL failed\n");
|
||||
fail_if(getttl != ttl, "setoption ttl != getoption ttl\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_LOOP, &loop);
|
||||
fail_if(ret == 0, "PICO_IP_MULTICAST_LOOP succeeded with invalid (not 0 or 1) loop value\n");
|
||||
loop = 0;
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_LOOP, &loop);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_LOOP failed disabling\n");
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_LOOP, &getloop);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_LOOP failed getting value\n");
|
||||
fail_if(getloop != loop, "setoption loop != getoption loop\n");
|
||||
_mreq.mcast_group_addr = inaddr_dst;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "supported PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "supported PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
_mreq.mcast_group_addr = inaddr_dst;
|
||||
_mreq.mcast_link_addr = inaddr_null;
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed with valid NULL (use default) link address\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed with valid NULL (use default) link address\n");
|
||||
_mreq.mcast_group_addr = inaddr_uni;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid (unicast) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_null;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid (NULL) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_dst;
|
||||
_mreq.mcast_link_addr = inaddr_uni;
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid link address\n");
|
||||
_mreq.mcast_group_addr = inaddr_incorrect;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (not added) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_uni;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (unicast) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_null;
|
||||
_mreq.mcast_link_addr = inaddr_link[0];
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (NULL) group address\n");
|
||||
_mreq.mcast_group_addr = inaddr_dst;
|
||||
_mreq.mcast_link_addr = inaddr_uni;
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (unicast) link address\n");
|
||||
|
||||
/* flow validation tests */
|
||||
printf("IGMP SETOPTION FLOW VALIDATION TEST\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed with err %s\n", strerror(pico_err));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_UNBLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* stress tests */
|
||||
printf("IGMP SETOPTION STRESS TEST\n");
|
||||
for (k = 0; k < 2; k++) {
|
||||
/* ADD for even combinations of group and link, ADD_SOURCE for uneven */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 2) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[i]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* UNBLOCK and DROP for even combinations, DROP_SOURCE for uneven */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 2) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_UNBLOCK_SOURCE failed\n");
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[i]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* everything should be cleanup up, next iteration will fail if not */
|
||||
}
|
||||
/* filter validation tests */
|
||||
printf("IGMP SETOPTION FILTER VALIDATION TEST\n");
|
||||
/* INCLUDE + INCLUDE expected filter: source of 0 and 1*/
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (INCLUDE + INCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (source->ip4.addr == mreq_source[0].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else if (source->ip4.addr == mreq_source[1].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (INCLUDE + INCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* INCLUDE + EXCLUDE expected filter: source of 2 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[2]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 1)
|
||||
fail("MCASTFilter (INCLUDE + EXCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (source->ip4.addr == mreq_source[2].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (INCLUDE + EXCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* EXCLUDE + INCLUDE expected filter: source of 0 and 1 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (EXCLUDE + INCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (source->ip4.addr == mreq_source[0].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else if (source->ip4.addr == mreq_source[1].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (EXCLUDE + INCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* EXCLUDE + EXCLUDE expected filter: source of 3 and 4 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[5]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[6]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (EXCLUDE + EXCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (source->ip4.addr == mreq_source[3].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else if (source->ip4.addr == mreq_source[4].mcast_source_addr.ip4.addr) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (EXCLUDE + EXCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
|
||||
ret = pico_socket_close(s);
|
||||
fail_if(ret < 0, "socket close failed: %s\n", strerror(pico_err));
|
||||
ret = pico_socket_close(s1);
|
||||
fail_if(ret < 0, "socket close failed: %s\n", strerror(pico_err));
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
|
||||
START_TEST (test_slaacv4)
|
||||
{
|
||||
uint32_t tmp;
|
||||
struct pico_device *dev;
|
||||
struct mock_device *mock;
|
||||
char ip_addr[20];
|
||||
uint8_t macaddr1[6] = {
|
||||
0xc3, 0, 0, 0xa, 0xc, 0xf
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* verify min boundary*/
|
||||
tmp = SLAACV4_CREATE_IPV4(0);
|
||||
pico_ipv4_to_string(ip_addr, tmp);
|
||||
printf("IP address generated by slaac: %s\n", ip_addr);
|
||||
|
||||
fail_if(long_be(tmp) < (long_be(SLAACV4_NETWORK) | SLAACV4_MINRANGE));
|
||||
|
||||
/* verify max boundary*/
|
||||
tmp = SLAACV4_CREATE_IPV4(0x00FD);
|
||||
fail_if(long_be(tmp) > (long_be(SLAACV4_NETWORK) | 0x0000FEFF));
|
||||
|
||||
/* verify case where dev->eth is NULL */
|
||||
dev = pico_null_create("dummy");
|
||||
tmp = pico_slaacv4_getip(dev, 0);
|
||||
fail_if(long_be(tmp) != (long_be(SLAACV4_NETWORK) | SLAACV4_MINRANGE));
|
||||
/* verify nominal case; two runs of slaacv4_get_ip need to return same value */
|
||||
mock = pico_mock_create(macaddr1);
|
||||
tmp = pico_slaacv4_getip(mock->dev, 0);
|
||||
fail_if(tmp != pico_slaacv4_getip(mock->dev, 0));
|
||||
|
||||
}
|
||||
END_TEST
|
||||
760
kernel/picotcp/test/unit/unit_ipv6.c
Normal file
760
kernel/picotcp/test/unit/unit_ipv6.c
Normal file
@ -0,0 +1,760 @@
|
||||
|
||||
#ifdef PICO_SUPPORT_IPV6
|
||||
START_TEST (test_ipv6)
|
||||
{
|
||||
char ipstr[40] = {
|
||||
0
|
||||
};
|
||||
char ipstr0[] = "2001:0db8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr0_t[] = "2001:0db8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr1[] = "2001:db8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr1_t[] = "2001:0db8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr2[] = "2001:b8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr2_t[] = "2001:00b8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr3[] = "2001:8:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr3_t[] = "2001:0008:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr4[] = "2001:8:130f:0:0:09c0:876a:130b";
|
||||
char ipstr4_t[] = "2001:0008:130f:0000:0000:09c0:876a:130b";
|
||||
char ipstr5[] = "2001::8:130f:09c0:876a:130b";
|
||||
char ipstr5_t[] = "2001:0000:0000:0008:130f:09c0:876a:130b";
|
||||
char ipstr6[] = "2001::8:09c0:876a:130b";
|
||||
char ipstr6_t[] = "2001:0000:0000:0000:0008:09c0:876a:130b";
|
||||
char ipstr7[] = "2001::8:876a:130b";
|
||||
char ipstr7_t[] = "2001:0000:0000:0000:0000:0008:876a:130b";
|
||||
char ipstr8[] = "2001::876a:130b";
|
||||
char ipstr8_t[] = "2001:0000:0000:0000:0000:0000:876a:130b";
|
||||
char ipstr9[] = "ff01::1";
|
||||
char ipstr9_t[] = "ff01:0000:0000:0000:0000:0000:0000:0001";
|
||||
char ipstr10[] = "::1";
|
||||
char ipstr10_t[] = "0000:0000:0000:0000:0000:0000:0000:0001";
|
||||
char ipstr11[] = "fe80::";
|
||||
char ipstr11_t[] = "fe80:0000:0000:0000:0000:0000:0000:0000";
|
||||
char ipstr12[] = "::";
|
||||
char ipstr12_t[] = "0000:0000:0000:0000:0000:0000:0000:0000";
|
||||
char ipstr13[] = "2001:8:130f::09c0::130b"; /* invalid */
|
||||
char ipstr14[] = "2001:8:xxxx::09c0:130b"; /* invalid */
|
||||
char ipstr15[] = "2001:8:$$$$::09c0:130b"; /* invalid */
|
||||
char ipstr16[] = "2001:8:!@#$::%^&*:()0b"; /* invalid */
|
||||
char ipstr17[] = "2001:1"; /* invalid */
|
||||
char ipstr18[] = "20010db8:130f:0000:0000:09c0:876a:130b"; /* invalid */
|
||||
char ipstr19[] = "20010db8130f0000000009c0876a130b"; /* invalid */
|
||||
char ipstr20[] = "2001;0db8;130f;0000;0000;09c0;876a;130b"; /* invalid */
|
||||
uint8_t iphex0[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex1[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex2[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex3[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x08, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex4[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x08, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex5[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x13, 0x0f, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex6[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0xc0, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex7[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex8[PICO_SIZE_IP6] = {
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x6a, 0x13, 0x0b
|
||||
};
|
||||
uint8_t iphex9[PICO_SIZE_IP6] = {
|
||||
0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
|
||||
};
|
||||
uint8_t iphex10[PICO_SIZE_IP6] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
|
||||
};
|
||||
uint8_t iphex11[PICO_SIZE_IP6] = {
|
||||
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
uint8_t iphex12[PICO_SIZE_IP6] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
struct pico_ip6 iphex_a = {{ 0x20, 0x01, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }};
|
||||
struct pico_ip6 iphex_r = {{ 0x40, 0x02, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }};
|
||||
struct pico_ip6 iphex_gw = {{ 0x20, 0x01, 0x0d, 0xb8, 0x13, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f }};
|
||||
struct pico_ip6 nm64 = {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }};
|
||||
struct pico_ip6 nm128 = {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }};
|
||||
struct pico_ip6 ipaddr = {{0}};
|
||||
|
||||
struct pico_ip6 _gw, r[IP_TST_SIZ], a[IP_TST_SIZ], gw[IP_TST_SIZ], *source[IP_TST_SIZ];
|
||||
struct pico_device *dev[IP_TST_SIZ];
|
||||
struct pico_ipv6_link *l[IP_TST_SIZ];
|
||||
struct pico_ipv6_link *_link = NULL;
|
||||
struct pico_ipv6_route *_route = NULL;
|
||||
char devname[8];
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
/* pico_string_to_ipv6 and pico_ipv6_to_string */
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr0);
|
||||
pico_string_to_ipv6(ipstr0, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex0, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr0_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr1);
|
||||
pico_string_to_ipv6(ipstr1, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex1, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr1_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr2);
|
||||
pico_string_to_ipv6(ipstr2, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex2, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr2_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr3);
|
||||
pico_string_to_ipv6(ipstr3, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex3, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr3_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr4);
|
||||
pico_string_to_ipv6(ipstr4, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex4, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr4_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr5);
|
||||
pico_string_to_ipv6(ipstr5, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex5, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr5_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr6);
|
||||
pico_string_to_ipv6(ipstr6, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex6, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr6_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr7);
|
||||
pico_string_to_ipv6(ipstr7, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex7, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr7_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr8);
|
||||
pico_string_to_ipv6(ipstr8, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex8, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr8_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr9);
|
||||
pico_string_to_ipv6(ipstr9, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex9, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr9_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr10);
|
||||
pico_string_to_ipv6(ipstr10, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex10, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr10_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr11);
|
||||
pico_string_to_ipv6(ipstr11, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex11, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr11_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 valid conversion of %s\n", ipstr12);
|
||||
pico_string_to_ipv6(ipstr12, ipaddr.addr);
|
||||
fail_if(memcmp(ipaddr.addr, iphex12, PICO_SIZE_IP6), "Error string to ipv6");
|
||||
pico_ipv6_to_string(ipstr, ipaddr.addr);
|
||||
printf("pico_ipv6_to_string valid conversion to %s\n", ipstr);
|
||||
fail_if(strncmp(ipstr, ipstr12_t, 40) != 0, "Error ipv6 to string");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr13);
|
||||
ret = pico_string_to_ipv6(ipstr13, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr14);
|
||||
ret = pico_string_to_ipv6(ipstr14, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr15);
|
||||
ret = pico_string_to_ipv6(ipstr15, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr16);
|
||||
ret = pico_string_to_ipv6(ipstr16, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr17);
|
||||
ret = pico_string_to_ipv6(ipstr17, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr18);
|
||||
ret = pico_string_to_ipv6(ipstr18, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr19);
|
||||
ret = pico_string_to_ipv6(ipstr19, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
printf("pico_string_to_ipv6 invalid conversion of %s\n", ipstr20);
|
||||
ret = pico_string_to_ipv6(ipstr20, ipaddr.addr);
|
||||
fail_if(ret == 0, "Error string to ipv6");
|
||||
|
||||
/*link_add*/
|
||||
for (i = 0; i < 10; ++i) {
|
||||
snprintf(devname, 8, "nul%d", i);
|
||||
dev[i] = pico_null_create(devname);
|
||||
a[i] = iphex_a;
|
||||
a[i].addr[4] = (uint8_t)(a[i].addr[4] + i);
|
||||
fail_if(pico_ipv6_link_add(dev[i], a[i], nm64) == NULL, "Error adding link");
|
||||
}
|
||||
/*link_find + link_get + route_add*/
|
||||
for (i = 0; i < 10; ++i) {
|
||||
gw[i] = iphex_gw;
|
||||
gw[i].addr[4] = (uint8_t)(gw[i].addr[4] + i);
|
||||
fail_unless(pico_ipv6_link_find(&a[i]) == dev[i], "Error finding link");
|
||||
l[i] = pico_ipv6_link_get(&a[i]);
|
||||
fail_if(l[i] == NULL, "Error getting link");
|
||||
r[i] = iphex_r;
|
||||
r[i].addr[4] = (uint8_t)(r[i].addr[4] + i);
|
||||
fail_if(pico_ipv6_route_add(r[i], nm128, a[i], 1, l[i]) != 0, "Error adding route");
|
||||
}
|
||||
/*get_gateway*/
|
||||
for (i = 0; i < 10; i++) {
|
||||
_gw = pico_ipv6_route_get_gateway(&r[i]);
|
||||
fail_if(memcmp(_gw.addr, a[i].addr, PICO_SIZE_IP6) != 0, "Error get gateway: returned wrong route");
|
||||
source[i] = pico_ipv6_source_find(&r[i]);
|
||||
fail_if(memcmp(source[i]->addr, a[i].addr, PICO_SIZE_IP6) != 0, "Error find source: returned wrong route");
|
||||
}
|
||||
/*route_del + link_del*/
|
||||
for (i = 0; i < 10; i++) {
|
||||
fail_if(pico_ipv6_route_del(r[i], nm128, a[i], 1, l[i]) != 0, "Error deleting route");
|
||||
fail_if(pico_ipv6_link_del(dev[i], a[i]) != 0, "Error deleting link");
|
||||
}
|
||||
/* add 2 links to dev[0] */
|
||||
_link = pico_ipv6_link_add(dev[0], a[0], nm64);
|
||||
fail_if (!_link, "Error adding link");
|
||||
_link = pico_ipv6_link_add(dev[0], a[1], nm64);
|
||||
fail_if (!_link, "Error adding link");
|
||||
/* add 2 routes to each of the links */
|
||||
ret = pico_ipv6_route_add(r[0], nm128, a[0], 1, l[0]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[1], nm128, a[0], 1, l[0]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[2], nm128, a[1], 1, l[1]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[3], nm128, a[1], 1, l[1]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
|
||||
/* add 2 links to dev[1] */
|
||||
_link = pico_ipv6_link_add(dev[1], a[8], nm64);
|
||||
fail_if (!_link, "Error adding link");
|
||||
_link = pico_ipv6_link_add(dev[1], a[9], nm64);
|
||||
fail_if (!_link, "Error adding link");
|
||||
/* add 2 routes to each of the links */
|
||||
ret = pico_ipv6_route_add(r[6], nm128, a[8], 1, l[8]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[7], nm128, a[8], 1, l[8]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[8], nm128, a[9], 1, l[9]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
ret = pico_ipv6_route_add(r[9], nm128, a[9], 1, l[9]);
|
||||
fail_if(ret != 0, "Error adding route");
|
||||
|
||||
/* destroy device, should clean up all links and routes */
|
||||
pico_device_destroy(dev[0]);
|
||||
_link = pico_ipv6_link_get(&a[0]);
|
||||
fail_if(_link != NULL, "Error destroying device");
|
||||
_link = pico_ipv6_link_get(&a[1]);
|
||||
fail_if(_link != NULL, "Error destroying device");
|
||||
_link = pico_ipv6_link_get(&a[8]);
|
||||
fail_if(_link == NULL, "Error destroying device");
|
||||
_link = pico_ipv6_link_get(&a[9]);
|
||||
fail_if(_link == NULL, "Error destroying device");
|
||||
|
||||
_route = pico_ipv6_route_find(&r[0]);
|
||||
fail_if(_route != NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[1]);
|
||||
fail_if(_route != NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[2]);
|
||||
fail_if(_route != NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[3]);
|
||||
fail_if(_route != NULL, "Error destroying device");
|
||||
|
||||
_route = pico_ipv6_route_find(&r[6]);
|
||||
fail_if(_route == NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[7]);
|
||||
fail_if(_route == NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[8]);
|
||||
fail_if(_route == NULL, "Error destroying device");
|
||||
_route = pico_ipv6_route_find(&r[9]);
|
||||
fail_if(_route == NULL, "Error destroying device");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef PICO_SUPPORT_MCAST
|
||||
START_TEST (test_mld_sockopts)
|
||||
{
|
||||
int i = 0, j = 0, k = 0, ret = 0;
|
||||
struct pico_socket *s, *s1 = NULL;
|
||||
struct pico_device *dev = NULL;
|
||||
union pico_address *source = NULL;
|
||||
union pico_address inaddr_dst = {
|
||||
0
|
||||
}, inaddr_incorrect = {
|
||||
0
|
||||
}, inaddr_uni = {
|
||||
0
|
||||
}, inaddr_null = {
|
||||
0
|
||||
};
|
||||
struct pico_ip6 netmask = {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }};
|
||||
|
||||
union pico_address inaddr_link[2] = {0};
|
||||
union pico_address inaddr_mcast[8] = {0};
|
||||
union pico_address inaddr_source[8] = {0};
|
||||
struct pico_ip_mreq _mreq = {0}, mreq[16] = {0};
|
||||
struct pico_ip_mreq_source mreq_source[128] = {0};
|
||||
struct pico_tree_node *index = NULL;
|
||||
struct pico_ipv6_link *ret_link = NULL;
|
||||
int ttl = 64;
|
||||
int getttl = 0;
|
||||
int loop = 9;
|
||||
int getloop = 0;
|
||||
struct pico_ip6 mcast_def_link = {
|
||||
0
|
||||
};
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
printf("START MLD SOCKOPTS TEST\n");
|
||||
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e007:707", inaddr_dst.ip6.addr);
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:2", inaddr_uni.ip6.addr);
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e008:808", inaddr_incorrect.ip6.addr);
|
||||
pico_string_to_ipv6("::", inaddr_null.ip6.addr);
|
||||
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:0001", inaddr_link[0].ip6.addr); /* 0 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a32:0001", inaddr_link[1].ip6.addr); /* 1 */
|
||||
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e801:100", inaddr_mcast[0].ip6.addr); /* 0 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e802:201", inaddr_mcast[1].ip6.addr); /* 1 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:302", inaddr_mcast[2].ip6.addr); /* 2 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:403", inaddr_mcast[3].ip6.addr); /* 3 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:504", inaddr_mcast[4].ip6.addr); /* 4 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:605", inaddr_mcast[5].ip6.addr); /* 5 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:706", inaddr_mcast[6].ip6.addr); /* 6 */
|
||||
pico_string_to_ipv6("ff00:0:0:0:0:0:e803:807", inaddr_mcast[7].ip6.addr); /* 7 */
|
||||
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:100", inaddr_source[0].ip6.addr); /* 0 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:101", inaddr_source[1].ip6.addr); /* 1 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:102", inaddr_source[2].ip6.addr); /* 2 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:103", inaddr_source[3].ip6.addr); /* 3 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:104", inaddr_source[4].ip6.addr); /* 4 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:105", inaddr_source[5].ip6.addr); /* 5 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:106", inaddr_source[6].ip6.addr); /* 6 */
|
||||
pico_string_to_ipv6("fe80:0:0:0:0:0:a28:107", inaddr_source[7].ip6.addr); /* 7 */
|
||||
|
||||
/* 00 01 02 03 04 05 06 07 | 10 11 12 13 14 15 16 17 */
|
||||
for (i = 0; i < 16; i++) {
|
||||
mreq[i].mcast_link_addr = inaddr_link[i / 8];
|
||||
mreq[i].mcast_group_addr = inaddr_mcast[i % 8];
|
||||
}
|
||||
/* 000 001 002 003 004 005 006 007 | 010 011 012 013 014 015 016 017 */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
/* printf(">>>>> mreq_source[%d]: link[%d] mcast[%d] source[%d]\n", (i*8)+j, i/8, i%8, j); */
|
||||
mreq_source[(i * 8) + j].mcast_link_addr = inaddr_link[i / 8];
|
||||
mreq_source[(i * 8) + j].mcast_group_addr = inaddr_mcast[i % 8];
|
||||
mreq_source[(i * 8) + j].mcast_source_addr = inaddr_source[j];
|
||||
}
|
||||
}
|
||||
dev = pico_null_create("dummy0");
|
||||
ret_link = pico_ipv6_link_add(dev, inaddr_link[0].ip6, netmask);
|
||||
fail_if(ret_link == NULL, "link add failed");
|
||||
dev = pico_null_create("dummy1");
|
||||
ret_link = pico_ipv6_link_add(dev, inaddr_link[1].ip6, netmask);
|
||||
fail_if(ret_link == NULL, "link add failed");
|
||||
|
||||
|
||||
s = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s == NULL, "UDP socket open failed");
|
||||
s1 = pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s1 == NULL, "UDP socket open failed");
|
||||
|
||||
|
||||
/* argument validation tests */
|
||||
printf("MLD SETOPTION ARGUMENT VALIDATION TEST\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_IF, &mcast_def_link);
|
||||
fail_if(ret == 0, "unsupported PICO_IP_MULTICAST_IF succeeded\n");
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_IF, &mcast_def_link);
|
||||
fail_if(ret == 0, "unsupported PICO_IP_MULTICAST_IF succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_TTL, &ttl);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_TTL failed\n");
|
||||
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_TTL, &getttl);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_TTL failed\n");
|
||||
fail_if(getttl != ttl, "setoption ttl != getoption ttl\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_LOOP, &loop);
|
||||
fail_if(ret == 0, "PICO_IP_MULTICAST_LOOP succeeded with invalid (not 0 or 1) loop value\n");
|
||||
loop = 0;
|
||||
ret = pico_socket_setoption(s, PICO_IP_MULTICAST_LOOP, &loop);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_LOOP failed disabling\n");
|
||||
ret = pico_socket_getoption(s, PICO_IP_MULTICAST_LOOP, &getloop);
|
||||
fail_if(ret < 0, "supported PICO_IP_MULTICAST_LOOP failed getting value\n");
|
||||
fail_if(getloop != loop, "setoption loop != getoption loop\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_dst.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "supported PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "supported PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_dst.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_null.ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed with valid NULL (use default) link address\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed with valid NULL (use default) link address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_uni.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid (unicast) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_null.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid (NULL) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_dst.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_uni.ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded with invalid link address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_incorrect.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (not added) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_uni.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (unicast) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_null.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_link[0].ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (NULL) group address\n");
|
||||
memcpy(&_mreq.mcast_group_addr, &inaddr_dst.ip6, sizeof(struct pico_ip6));
|
||||
memcpy(&_mreq.mcast_link_addr, &inaddr_uni.ip6, sizeof(struct pico_ip6));
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &_mreq);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded with invalid (unicast) link address\n");
|
||||
/* flow validation tests */
|
||||
printf("MLD SETOPTION FLOW VALIDATION TEST\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed with err %s\n", strerror(pico_err));
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_UNBLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_BLOCK_SOURCE succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_UNBLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret == 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP succeeded\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
/* stress tests */
|
||||
|
||||
printf("MLD SETOPTION STRESS TEST\n");
|
||||
for (k = 0; k < 2; k++) {
|
||||
/* ADD for even combinations of group and link, ADD_SOURCE for uneven */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 2) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[i]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* UNBLOCK and DROP for even combinations, DROP_SOURCE for uneven */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 2) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_UNBLOCK_SOURCE, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_UNBLOCK_SOURCE failed\n");
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[i]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_SOURCE_MEMBERSHIP, &mreq_source[(i * 8) + j]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_SOURCE_MEMBERSHIP failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* everything should be cleanup up, next iteration will fail if not */
|
||||
}
|
||||
/* filter validation tests */
|
||||
printf("MLD SETOPTION FILTER VALIDATION TEST\n");
|
||||
/* INCLUDE + INCLUDE expected filter: source of 0 and 1*/
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
i = 0;
|
||||
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (INCLUDE + INCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (memcmp(&source->ip6, &mreq_source[0].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else if (memcmp(&source->ip6, &mreq_source[1].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (INCLUDE + INCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* INCLUDE + EXCLUDE expected filter: source of 2 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[2]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 1)
|
||||
fail("MCASTFilter (INCLUDE + EXCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (memcmp(&source->ip6, &mreq_source[2].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (INCLUDE + EXCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* EXCLUDE + INCLUDE expected filter: source of 0 and 1 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_SOURCE_MEMBERSHIP, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_SOURCE_MEMBERSHIP failed\n");
|
||||
i = 0;
|
||||
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (EXCLUDE + INCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (memcmp(&source->ip6, &mreq_source[0].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else if (memcmp(&source->ip6, &mreq_source[1].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (EXCLUDE + INCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
/* EXCLUDE + EXCLUDE expected filter: source of 3 and 4 */
|
||||
ret = pico_socket_setoption(s, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[0]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[1]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_ADD_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_ADD_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[3]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[4]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[5]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_BLOCK_SOURCE, &mreq_source[6]);
|
||||
fail_if(ret < 0, "PICO_IP_BLOCK_SOURCE failed\n");
|
||||
i = 0;
|
||||
pico_tree_foreach(index, &MCASTFilter)
|
||||
{
|
||||
if (++i > 2)
|
||||
fail("MCASTFilter (EXCLUDE + EXCLUDE) too many elements\n");
|
||||
|
||||
source = index->keyValue;
|
||||
if (memcmp(&source->ip6, &mreq_source[3].mcast_source_addr, sizeof(struct pico_ip6) == 0)) { /* OK */
|
||||
}
|
||||
else if (memcmp(&source->ip6, &mreq_source[4].mcast_source_addr, sizeof(struct pico_ip6)) == 0) { /* OK */
|
||||
}
|
||||
else {
|
||||
fail("MCASTFilter (EXCLUDE + EXCLUDE) incorrect\n");
|
||||
}
|
||||
}
|
||||
ret = pico_socket_setoption(s, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
ret = pico_socket_setoption(s1, PICO_IP_DROP_MEMBERSHIP, &mreq[0]);
|
||||
fail_if(ret < 0, "PICO_IP_DROP_MEMBERSHIP failed\n");
|
||||
|
||||
|
||||
ret = pico_socket_close(s);
|
||||
fail_if(ret < 0, "socket close failed: %s\n", strerror(pico_err));
|
||||
ret = pico_socket_close(s1);
|
||||
fail_if(ret < 0, "socket close failed: %s\n", strerror(pico_err));
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
2158
kernel/picotcp/test/unit/unit_mem_manager.c
Normal file
2158
kernel/picotcp/test/unit/unit_mem_manager.c
Normal file
File diff suppressed because it is too large
Load Diff
71
kernel/picotcp/test/unit/unit_mocks.c
Normal file
71
kernel/picotcp/test/unit/unit_mocks.c
Normal file
@ -0,0 +1,71 @@
|
||||
#define BUFLEN (576 + 14 + 20 + 8)
|
||||
|
||||
int mock_print_protocol(uint8_t *buf);
|
||||
int printbuf(uint8_t *buf, uint32_t len, const char *str, uint8_t printbufactive);
|
||||
int tick_it(uint32_t nticks);
|
||||
|
||||
int mock_print_protocol(uint8_t *buf)
|
||||
{
|
||||
uint8_t pnr = buf[0x17]; /* protocol number */
|
||||
|
||||
printf("transport protocol: %s\n",
|
||||
(pnr == PICO_PROTO_ICMP4 ? "icmp4" :
|
||||
(pnr == PICO_PROTO_IGMP ? "igmp" :
|
||||
(pnr == PICO_PROTO_TCP ? "tcp" :
|
||||
(pnr == PICO_PROTO_UDP ? "udp" :
|
||||
(pnr == PICO_PROTO_ICMP6 ? "icmp6" :
|
||||
"unknown proto"))))));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printbuf(uint8_t *buf, uint32_t len, const char *str, uint8_t printbufactive)
|
||||
{
|
||||
uint8_t printMethod = 0;
|
||||
uint32_t cntr = 0;
|
||||
uint32_t cntr2 = 0;
|
||||
if((printbufactive) && (printMethod == 0)) {
|
||||
printf("\n%s:\n", str);
|
||||
for(cntr = 0; cntr < len; cntr++) {
|
||||
if((cntr % 8) == 0 && cntr != 0)
|
||||
printf(" ");
|
||||
|
||||
if((cntr % 16) == 0 && cntr != 0)
|
||||
printf("\n");
|
||||
|
||||
if((cntr % 16) == 0)
|
||||
printf("%03x0 ", cntr2++);
|
||||
|
||||
printf("%02x ", buf[cntr]);
|
||||
}
|
||||
printf("\n");
|
||||
}else if((printbufactive) && (printMethod == 1)) {
|
||||
printf("\n%s:\n", str);
|
||||
printf("Buf = {");
|
||||
for(cntr = 0; cntr < len; cntr++) {
|
||||
if(cntr != 0)
|
||||
printf(",");
|
||||
|
||||
if((cntr % 16 == 0) && (cntr != 0))
|
||||
printf("\n");
|
||||
|
||||
printf("0x%02x", buf[cntr]);
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BUFLEN (576 + 14 + 20 + 8)
|
||||
#define DHCP_MSG_TYPE_DISCOVER (1)
|
||||
#define DHCP_MSG_TYPE_OFFER (2)
|
||||
#define DHCP_MSG_TYPE_REQUEST (3)
|
||||
#define DHCP_MSG_TYPE_ACK (4)
|
||||
int tick_it(uint32_t nticks)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < nticks; i++) {
|
||||
pico_stack_tick();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
93
kernel/picotcp/test/unit/unit_rbtree.c
Normal file
93
kernel/picotcp/test/unit/unit_rbtree.c
Normal file
@ -0,0 +1,93 @@
|
||||
/* RB tree unit test */
|
||||
typedef struct
|
||||
{
|
||||
int value;
|
||||
}elem;
|
||||
|
||||
int compare(void *a, void *b);
|
||||
|
||||
int compare(void *a, void *b)
|
||||
{
|
||||
return ((elem *)a)->value - ((elem *)b)->value;
|
||||
}
|
||||
|
||||
static PICO_TREE_DECLARE(test_tree, compare);
|
||||
static PICO_TREE_DECLARE(test_tree2, compare);
|
||||
#define RBTEST_SIZE 20000
|
||||
|
||||
START_TEST (test_rbtree2)
|
||||
{
|
||||
struct pico_tree_node *s;
|
||||
elem *e;
|
||||
int i, last;
|
||||
struct timeval start, end;
|
||||
gettimeofday(&start, 0);
|
||||
|
||||
srand48(RBTEST_SIZE); /* use test-size as salt */
|
||||
for (i = 0; i < (RBTEST_SIZE >> 1); i++)
|
||||
{
|
||||
e = malloc(sizeof(elem));
|
||||
e->value = (int)lrand48() % RBTEST_SIZE;
|
||||
if (pico_tree_findKey(&test_tree2, e)) {
|
||||
free(e);
|
||||
} else {
|
||||
pico_tree_insert(&test_tree2, e);
|
||||
}
|
||||
}
|
||||
gettimeofday(&end, 0);
|
||||
printf("Rbtree test 2 inserted %d entries in %d milliseconds\n", RBTEST_SIZE,
|
||||
(int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000));
|
||||
last = 0;
|
||||
pico_tree_foreach(s, &test_tree2){
|
||||
fail_if (last > ((elem *)(s->keyValue))->value, "error");
|
||||
last = ((elem *)(s->keyValue))->value;
|
||||
}
|
||||
|
||||
gettimeofday(&end, 0);
|
||||
printf("Rbtree test 2 duration with %d entries: %d milliseconds\n", RBTEST_SIZE,
|
||||
(int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000));
|
||||
printf("Test finished.\n");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_rbtree)
|
||||
{
|
||||
struct pico_tree_node *s, *tmp;
|
||||
elem t, *e;
|
||||
int i;
|
||||
struct timeval start, end;
|
||||
printf("Started test...\n");
|
||||
gettimeofday(&start, 0);
|
||||
|
||||
for (i = 0; i < (RBTEST_SIZE >> 1); i++) {
|
||||
e = malloc(sizeof(elem));
|
||||
e->value = i;
|
||||
pico_tree_insert(&test_tree, e);
|
||||
/* RB_INSERT(rbtree, &RBTREE, e); */
|
||||
e = malloc(sizeof(elem));
|
||||
e->value = (RBTEST_SIZE - 1) - i;
|
||||
pico_tree_insert(&test_tree, e);
|
||||
}
|
||||
i = 0;
|
||||
pico_tree_foreach(s, &test_tree){
|
||||
fail_if (i++ != ((elem *)(s->keyValue))->value, "error");
|
||||
}
|
||||
t.value = RBTEST_SIZE >> 2;
|
||||
|
||||
e = pico_tree_findKey(&test_tree, &t);
|
||||
fail_if(!e, "Search failed...");
|
||||
fail_if(e->value != t.value, "Wrong element returned...");
|
||||
|
||||
pico_tree_foreach_reverse_safe(s, &test_tree, tmp){
|
||||
fail_if(!s, "Reverse safe returned null");
|
||||
e = (elem *)pico_tree_delete(&test_tree, s->keyValue);
|
||||
free(e);
|
||||
}
|
||||
|
||||
fail_if(!pico_tree_empty(&test_tree), "Not empty");
|
||||
gettimeofday(&end, 0);
|
||||
printf("Rbtree test duration with %d entries: %d milliseconds\n", RBTEST_SIZE,
|
||||
(int)((end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000));
|
||||
printf("Test finished...\n");
|
||||
}
|
||||
END_TEST
|
||||
521
kernel/picotcp/test/unit/unit_socket.c
Normal file
521
kernel/picotcp/test/unit/unit_socket.c
Normal file
@ -0,0 +1,521 @@
|
||||
|
||||
int pico_aodv_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
START_TEST (test_socket)
|
||||
{
|
||||
int ret = 0;
|
||||
uint16_t port_be = 0, porta, proto, port_got;
|
||||
char buf[] = "test";
|
||||
struct pico_socket *sk_tcp, *sk_udp, *s, *sl, *sa;
|
||||
struct pico_device *dev;
|
||||
struct pico_ip4 inaddr_dst, inaddr_link, inaddr_incorrect, inaddr_uni, inaddr_null, netmask, orig, inaddr_got;
|
||||
|
||||
int getnodelay = -1;
|
||||
int nodelay = -1;
|
||||
int count = 0;
|
||||
|
||||
uint32_t getsocket_buffer = 0;
|
||||
uint32_t socket_buffer = 0;
|
||||
|
||||
pico_stack_init();
|
||||
|
||||
printf("START SOCKET TEST\n");
|
||||
|
||||
pico_string_to_ipv4("224.7.7.7", &inaddr_dst.addr);
|
||||
pico_string_to_ipv4("10.40.0.2", &inaddr_link.addr);
|
||||
pico_string_to_ipv4("224.8.8.8", &inaddr_incorrect.addr);
|
||||
pico_string_to_ipv4("0.0.0.0", &inaddr_null.addr);
|
||||
pico_string_to_ipv4("10.40.0.3", &inaddr_uni.addr);
|
||||
|
||||
dev = pico_null_create("dummy");
|
||||
netmask.addr = long_be(0xFFFF0000);
|
||||
ret = pico_ipv4_link_add(dev, inaddr_link, netmask);
|
||||
fail_if(ret < 0, "socket> error adding link");
|
||||
|
||||
|
||||
/* socket_open passing wrong parameters */
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, 99, NULL);
|
||||
fail_if(s != NULL, "Error got socket wrong parameters");
|
||||
|
||||
s = pico_socket_open(PICO_PROTO_IPV4, 0xFFFF, NULL);
|
||||
fail_if(s != NULL, "Error got socket");
|
||||
|
||||
s = pico_socket_open(99, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s != NULL, "Error got socket");
|
||||
|
||||
s = pico_socket_open(0xFFFF, PICO_PROTO_UDP, NULL);
|
||||
fail_if(s != NULL, "Error got socket");
|
||||
|
||||
|
||||
sk_tcp = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, NULL);
|
||||
fail_if(sk_tcp == NULL, "socket> tcp socket open failed");
|
||||
|
||||
|
||||
port_be = short_be(5555);
|
||||
/* socket_bind passing wrong parameters */
|
||||
ret = pico_socket_bind(NULL, &inaddr_link, &port_be);
|
||||
fail_if(ret == 0, "socket> tcp socket bound wrong parameter");
|
||||
ret = pico_socket_bind(sk_tcp, NULL, &port_be);
|
||||
fail_if(ret == 0, "socket> tcp socket bound wrong parameter");
|
||||
ret = pico_socket_bind(sk_tcp, &inaddr_link, NULL);
|
||||
fail_if(ret == 0, "socket> tcp socket bound wrong parameter");
|
||||
/* socket_getname passing wrong parameters */
|
||||
ret = pico_socket_getname(NULL, &inaddr_link, &port_be, &proto);
|
||||
fail_if(ret == 0, "socket> tcp socket getname with wrong parameter");
|
||||
ret = pico_socket_getname(sk_tcp, NULL, &port_be, &proto);
|
||||
fail_if(ret == 0, "socket> tcp socket getname with wrong parameter");
|
||||
ret = pico_socket_getname(sk_tcp, &inaddr_link, NULL, &proto);
|
||||
fail_if(ret == 0, "socket> tcp socket getname with wrong parameter");
|
||||
ret = pico_socket_getname(sk_tcp, &inaddr_link, &port_be, NULL);
|
||||
fail_if(ret == 0, "socket> tcp socket getname with wrong parameter");
|
||||
/* socket_bind passing correct parameters */
|
||||
ret = pico_socket_bind(sk_tcp, &inaddr_link, &port_be);
|
||||
fail_if(ret < 0, "socket> tcp socket bind failed");
|
||||
count = pico_count_sockets(PICO_PROTO_TCP);
|
||||
printf("Count: %d\n", count);
|
||||
fail_unless(count == 1);
|
||||
count = pico_count_sockets(0);
|
||||
printf("Count: %d\n", count);
|
||||
fail_unless(count == 1);
|
||||
|
||||
sk_udp = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, NULL);
|
||||
fail_if(sk_udp == NULL, "socket> udp socket open failed");
|
||||
|
||||
port_be = short_be(5555);
|
||||
ret = pico_socket_bind(sk_udp, &inaddr_link, &port_be);
|
||||
fail_if(ret < 0, "socket> udp socket bind failed");
|
||||
|
||||
fail_if (pico_count_sockets(PICO_PROTO_UDP) != 1);
|
||||
fail_if (pico_count_sockets(0) != 2);
|
||||
|
||||
|
||||
ret = pico_socket_getname(sk_udp, &inaddr_got, &port_got, &proto);
|
||||
fail_if(ret < 0, "socket> udp socket getname failed");
|
||||
fail_if(inaddr_got.addr != inaddr_link.addr, "Getname: Address is different");
|
||||
fail_if(port_be != port_got, "Getname: Port is different");
|
||||
fail_if(proto != PICO_PROTO_IPV4, "Getname: proto is wrong");
|
||||
|
||||
/* socket_close passing wrong parameter */
|
||||
ret = pico_socket_close(NULL);
|
||||
fail_if(ret == 0, "Error socket close with wrong parameters");
|
||||
|
||||
|
||||
/* socket_connect passing wrong parameters */
|
||||
ret = pico_socket_connect(sk_udp, NULL, port_be);
|
||||
fail_if(ret == 0, "Error socket connect with wrong parameters");
|
||||
ret = pico_socket_connect(NULL, &inaddr_dst, port_be);
|
||||
fail_if(ret == 0, "Error socket connect with wrong parameters");
|
||||
|
||||
/* socket_connect passing correct parameters */
|
||||
ret = pico_socket_connect(sk_udp, &inaddr_dst, port_be);
|
||||
fail_if(ret < 0, "Error socket connect");
|
||||
ret = pico_socket_connect(sk_tcp, &inaddr_dst, port_be);
|
||||
fail_if(ret < 0, "Error socket connect");
|
||||
|
||||
|
||||
/* testing listening socket */
|
||||
sl = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, NULL);
|
||||
fail_if(sl == NULL, "socket> tcp socket open failed");
|
||||
port_be = short_be(6666);
|
||||
ret = pico_socket_bind(sl, &inaddr_link, &port_be);
|
||||
fail_if(ret < 0, "socket> tcp socket bind failed");
|
||||
/* socket_listen passing wrong parameters */
|
||||
ret = pico_socket_listen(sl, 0);
|
||||
fail_if(ret == 0, "Error socket tcp socket listen done, wrong parameter");
|
||||
ret = pico_socket_listen(NULL, 10);
|
||||
fail_if(ret == 0, "Error socket tcp socket listen done, wrong parameter");
|
||||
/* socket_listen passing correct parameters */
|
||||
ret = pico_socket_listen(sl, 10);
|
||||
fail_if(ret < 0, "socket> tcp socket listen failed: %s", strerror(pico_err));
|
||||
|
||||
/* socket_accept passing wrong parameters */
|
||||
sa = pico_socket_accept(sl, &orig, NULL);
|
||||
fail_if(sa != NULL, "Error socket tcp socket accept wrong argument");
|
||||
sa = pico_socket_accept(sl, NULL, &porta);
|
||||
fail_if(sa != NULL, "Error socket tcp socket accept wrong argument");
|
||||
/* socket_accept passing correct parameters */
|
||||
sa = pico_socket_accept(sl, &orig, &porta);
|
||||
fail_if(sa == NULL && pico_err != PICO_ERR_EAGAIN, "socket> tcp socket accept failed: %s", strerror(pico_err));
|
||||
|
||||
ret = pico_socket_close(sl);
|
||||
fail_if(ret < 0, "socket> tcp socket close failed: %s\n", strerror(pico_err));
|
||||
|
||||
|
||||
/* testing socket read/write */
|
||||
/* socket_write passing wrong parameters */
|
||||
ret = pico_socket_write(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket write succeeded, wrong argument\n");
|
||||
ret = pico_socket_write(sk_tcp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket write succeeded, wrong argument\n");
|
||||
ret = pico_socket_write(sk_tcp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket write succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_write(sk_tcp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret < 0, "socket> tcp socket write failed: %s\n", strerror(pico_err));
|
||||
/* socket_read passing wrong parameters */
|
||||
ret = pico_socket_read(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_tcp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_tcp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket read succeeded, wrong argument\n");
|
||||
/* socket_read passing correct parameters */
|
||||
ret = pico_socket_read(sk_tcp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret < 0, "socket> tcp socket read failed, ret = %d: %s\n", ret, strerror(pico_err)); /* tcp_recv returns 0 when no frame !? */
|
||||
|
||||
|
||||
/* send/recv */
|
||||
/* socket_send passing wrong parameters */
|
||||
ret = pico_socket_send(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket send succeeded, wrong argument\n");
|
||||
ret = pico_socket_send(sk_tcp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket send succeeded, wrong argument\n");
|
||||
ret = pico_socket_send(sk_tcp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket send succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_send(sk_tcp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret <= 0, "socket> tcp socket send failed: %s\n", strerror(pico_err));
|
||||
/* socket_recv passing wrong parameters */
|
||||
ret = pico_socket_recv(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_tcp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_tcp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket recv succeeded, wrong argument\n");
|
||||
/* socket_recv passing correct parameters */
|
||||
ret = pico_socket_recv(sk_tcp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret < 0, "socket> tcp socket recv failed, ret = %d: %s\n", ret, strerror(pico_err)); /* tcp_recv returns 0 when no frame !? */
|
||||
|
||||
|
||||
/* sendto/recvfrom */
|
||||
/* socket_sendto passing wrong parameters */
|
||||
ret = pico_socket_sendto(NULL, (void *)buf, sizeof(buf), &inaddr_dst, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_tcp, NULL, sizeof(buf), &inaddr_dst, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_tcp, (void *)buf, 0, &inaddr_dst, port_be);
|
||||
fail_if(ret > 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_tcp, (void *)buf, sizeof(buf), NULL, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_tcp, (void *)buf, sizeof(buf), &inaddr_dst, 0xFFFF);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_sendto(sk_tcp, (void *)buf, sizeof(buf), &inaddr_dst, short_be(5555));
|
||||
fail_if(ret <= 0, "socket> udp socket sendto failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
/* socket_recvfrom passing wrong parameters */
|
||||
ret = pico_socket_recvfrom(NULL, (void *)buf, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_tcp, NULL, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_tcp, (void *)buf, 0, &orig, &porta);
|
||||
fail_if(ret > 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_tcp, (void *)buf, sizeof(buf), NULL, &porta);
|
||||
fail_if(ret > 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_tcp, (void *)buf, sizeof(buf), &orig, NULL);
|
||||
fail_if(ret > 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
/* socket_recvfrom passing correct parameters */
|
||||
ret = pico_socket_recvfrom(sk_tcp, (void *)buf, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret != 0, "socket> tcp socket recvfrom failed, ret = %d: %s\n", ret, strerror(pico_err)); /* tcp_recv returns -1 when no frame !? */
|
||||
|
||||
|
||||
/* testing socket read/write */
|
||||
/* socket_write passing wrong parameters */
|
||||
ret = pico_socket_write(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket write succeeded, wrong argument\n");
|
||||
ret = pico_socket_write(sk_udp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket write succeeded, wrong argument\n");
|
||||
ret = pico_socket_write(sk_udp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket write succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_write(sk_udp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret < 0, "socket> tcp socket write failed: %s\n", strerror(pico_err));
|
||||
/* socket_read passing wrong parameters */
|
||||
ret = pico_socket_read(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_udp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_udp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket read succeeded, wrong argument\n");
|
||||
ret = pico_socket_read(sk_udp, (void *)buf, 0xFFFF + 1);
|
||||
fail_if(ret >= 0, "Error socket read succeeded while len was > 0xFFFF");
|
||||
/* socket_read passing correct parameters */
|
||||
ret = pico_socket_read(sk_udp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret != 0, "socket> udp socket read failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
|
||||
|
||||
/* send/recv */
|
||||
/* socket_send passing wrong parameters */
|
||||
ret = pico_socket_send(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket send succeeded, wrong argument\n");
|
||||
ret = pico_socket_send(sk_udp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket send succeeded, wrong argument\n");
|
||||
ret = pico_socket_send(sk_udp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket send succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_send(sk_udp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret <= 0, "socket> tcp socket send failed: %s\n", strerror(pico_err));
|
||||
/* socket_recv passing wrong parameters */
|
||||
ret = pico_socket_recv(NULL, (void *)buf, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_udp, NULL, sizeof(buf));
|
||||
fail_if(ret == 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_udp, (void *)buf, 0);
|
||||
fail_if(ret > 0, "Error socket recv succeeded, wrong argument\n");
|
||||
ret = pico_socket_recv(sk_udp, (void *)buf, 0xFFFF + 1);
|
||||
fail_if(ret >= 0, "Error socket recv succeeded while len was > 0xFFFF");
|
||||
/* socket_recv passing correct parameters */
|
||||
ret = pico_socket_recv(sk_udp, (void *)buf, sizeof(buf));
|
||||
fail_if(ret != 0, "socket> udp socket recv failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
|
||||
|
||||
/* sendto/recvfrom */
|
||||
/* socket_sendto passing wrong parameters */
|
||||
ret = pico_socket_sendto(NULL, (void *)buf, sizeof(buf), &inaddr_dst, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_udp, NULL, sizeof(buf), &inaddr_dst, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_udp, (void *)buf, 0, &inaddr_dst, port_be);
|
||||
fail_if(ret > 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_udp, (void *)buf, sizeof(buf), NULL, port_be);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
ret = pico_socket_sendto(sk_udp, (void *)buf, sizeof(buf), &inaddr_dst, 0xFFFF);
|
||||
fail_if(ret >= 0, "Error socket sendto succeeded, wrong argument\n");
|
||||
/* socket_write passing correct parameters */
|
||||
ret = pico_socket_sendto(sk_udp, (void *)buf, sizeof(buf), &inaddr_dst, short_be(5555));
|
||||
fail_if(ret <= 0, "socket> udp socket sendto failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
/* socket_recvfrom passing wrong parameters */
|
||||
ret = pico_socket_recvfrom(NULL, (void *)buf, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_udp, NULL, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded, wrong argument\n");
|
||||
ret = pico_socket_recvfrom(sk_udp, (void *)buf, 0xFFFF + 1, &orig, &porta);
|
||||
fail_if(ret >= 0, "Error socket recvfrom succeeded while len was > 0xFFFF");
|
||||
/* socket_recvfrom passing correct parameters */
|
||||
ret = pico_socket_recvfrom(sk_udp, (void *)buf, 0, &orig, &porta);
|
||||
fail_if(ret != 0, "socket> udp socket recvfrom failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
ret = pico_socket_recvfrom(sk_udp, (void *)buf, sizeof(buf), &orig, &porta);
|
||||
fail_if(ret != 0, "socket> udp socket recvfrom failed, ret = %d: %s\n", ret, strerror(pico_err));
|
||||
|
||||
/* temporary fix, until Nagle problems are analyzed and fixed */
|
||||
{
|
||||
nodelay = 0;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_TCP_NODELAY, &nodelay);
|
||||
}
|
||||
|
||||
/* setoption/getoption */
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_TCP_NODELAY, &getnodelay);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_TCP_NODELAY failed (err = %s)\n", strerror(pico_err));
|
||||
fail_if(getnodelay != 0, "socket> socket_setoption: default PICO_TCP_NODELAY != 0 (nagle disabled by default)\n");
|
||||
|
||||
nodelay = 1;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_TCP_NODELAY, &nodelay);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_TCP_NODELAY failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_TCP_NODELAY, &getnodelay);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_TCP_NODELAY failed\n");
|
||||
fail_if(getnodelay == 0, "socket> socket_setoption: PICO_TCP_NODELAY is off (expected: on!)\n");
|
||||
|
||||
nodelay = 0;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_TCP_NODELAY, &nodelay);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_TCP_NODELAY failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_TCP_NODELAY, &getnodelay);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_TCP_NODELAY failed\n");
|
||||
fail_if(getnodelay != 0, "socket> socket_setoption: PICO_TCP_NODELAY is on (expected: off!)\n");
|
||||
|
||||
|
||||
/* Set/get recv buffer (TCP) */
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != PICO_DEFAULT_SOCKETQ,
|
||||
"socket> socket_setoption: default PICO_SOCKET_OPT_SNDBUF != DEFAULT\n");
|
||||
|
||||
socket_buffer = PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_RCVBUF is != than expected\n");
|
||||
|
||||
socket_buffer = 2 * PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_RCVBUF is != than expected\n");
|
||||
|
||||
/* Set/get send buffer (TCP) */
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != PICO_DEFAULT_SOCKETQ,
|
||||
"socket> socket_setoption: default PICO_SOCKET_OPT_SNDBUF != DEFAULT got: %d exp: %d\n", getsocket_buffer, PICO_DEFAULT_SOCKETQ);
|
||||
|
||||
socket_buffer = PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_SNDBUF is != than expected\n");
|
||||
|
||||
socket_buffer = 2 * PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_tcp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_SNDBUF is != than expected\n");
|
||||
|
||||
/* Set/get recv buffer (UDP) */
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != PICO_DEFAULT_SOCKETQ,
|
||||
"socket> socket_setoption: default PICO_SOCKET_OPT_SNDBUF != DEFAULT\n");
|
||||
|
||||
socket_buffer = PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_RCVBUF is != than expected\n");
|
||||
|
||||
socket_buffer = 2 * PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_RCVBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_RCVBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_RCVBUF is != than expected\n");
|
||||
|
||||
/* Set/get send buffer (UDP) */
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != PICO_DEFAULT_SOCKETQ,
|
||||
"socket> socket_setoption: default PICO_SOCKET_OPT_SNDBUF != DEFAULT\n");
|
||||
|
||||
socket_buffer = PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_SNDBUF is != than expected\n");
|
||||
|
||||
socket_buffer = 2 * PICO_DEFAULT_SOCKETQ;
|
||||
ret = pico_socket_setoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &socket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_setoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
ret = pico_socket_getoption(sk_udp, PICO_SOCKET_OPT_SNDBUF, &getsocket_buffer);
|
||||
fail_if(ret < 0, "socket> socket_getoption: supported PICO_SOCKET_OPT_SNDBUF failed\n");
|
||||
fail_if(getsocket_buffer != socket_buffer, "UDP socket> socket_setoption: PICO_SOCKET_OPT_SNDBUF is != than expected\n");
|
||||
|
||||
/* Close sockets, eventually. */
|
||||
ret = pico_socket_close(sk_tcp);
|
||||
fail_if(ret < 0, "socket> tcp socket close failed: %s\n", strerror(pico_err));
|
||||
ret = pico_socket_close(sk_udp);
|
||||
fail_if(ret < 0, "socket> udp socket close failed: %s\n", strerror(pico_err));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef PICO_SUPPORT_CRC_FAULTY_UNIT_TEST
|
||||
START_TEST (test_crc_check)
|
||||
{
|
||||
uint8_t buffer[64] = {
|
||||
0x45, 0x00, 0x00, 0x40, /* start of IP hdr */
|
||||
0x91, 0xc3, 0x40, 0x00,
|
||||
0x40, 0x11, 0x24, 0xcf, /* last 2 bytes are CRC */
|
||||
0xc0, 0xa8, 0x01, 0x66,
|
||||
0xc0, 0xa8, 0x01, 0x64, /* end of IP hdr */
|
||||
0x15, 0xb3, 0x1F, 0x90, /* start of UDP/TCP hdr */
|
||||
0x00, 0x2c, 0x27, 0x22, /* end of UDP hdr */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0b, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, /* end of TCP hdr */
|
||||
0x01, 0x23, 0x45, 0x67, /* start of data */
|
||||
0x89, 0xab, 0xcd, 0xef,
|
||||
0xc0, 0xca, 0xc0, 0x1a
|
||||
};
|
||||
struct pico_frame *f = NULL;
|
||||
struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) buffer;
|
||||
struct pico_udp_hdr *udp_hdr = NULL;
|
||||
struct pico_tcp_hdr *tcp_hdr = NULL;
|
||||
uint32_t *f_usage_count = NULL;
|
||||
uint8_t *f_buffer = NULL;
|
||||
int ret = -1;
|
||||
|
||||
printf("START CRC TEST\n");
|
||||
pico_stack_init();
|
||||
|
||||
/* IPv4 CRC unit tests */
|
||||
/* Allocated memory will not be freed when pico_ipv4_crc_check fails */
|
||||
f = calloc(1, sizeof(struct pico_frame));
|
||||
f_usage_count = calloc(1, sizeof(uint32_t));
|
||||
f_buffer = calloc(1, sizeof(uint8_t));
|
||||
f->net_hdr = buffer;
|
||||
f->net_len = PICO_SIZE_IP4HDR;
|
||||
f->transport_hdr = buffer + PICO_SIZE_IP4HDR;
|
||||
f->transport_len = sizeof(buffer) - PICO_SIZE_IP4HDR;
|
||||
f->usage_count = f_usage_count;
|
||||
f->buffer = f_buffer;
|
||||
*(f->usage_count) = 512;
|
||||
|
||||
hdr->crc = 0;
|
||||
printf(">>>>>>>>>>>>>>>>>>>>> CRC VALUE = %X\n", pico_checksum(hdr, PICO_SIZE_IP4HDR));
|
||||
hdr->crc = short_be(0x24CF); /* Make check pass */
|
||||
ret = pico_ipv4_crc_check(f);
|
||||
fail_if(ret == 0, "correct IPv4 checksum got rejected\n");
|
||||
hdr->crc = short_be(0x8899); /* Make check fail */
|
||||
ret = pico_ipv4_crc_check(f);
|
||||
fail_if(ret == 1, "incorrect IPv4 checksum got accepted\n");
|
||||
|
||||
/* UDP CRC unit tests */
|
||||
/* Allocated memory will be freed when pico_transport_crc_check fails */
|
||||
f = calloc(1, sizeof(struct pico_frame));
|
||||
f_usage_count = calloc(1, sizeof(uint32_t));
|
||||
f_buffer = calloc(1, sizeof(uint8_t));
|
||||
f->net_hdr = buffer;
|
||||
f->transport_hdr = buffer + PICO_SIZE_IP4HDR;
|
||||
f->transport_len = sizeof(buffer) - PICO_SIZE_IP4HDR;
|
||||
f->usage_count = f_usage_count;
|
||||
f->buffer = f_buffer;
|
||||
*(f->usage_count) = 1;
|
||||
hdr->proto = 0x11; /* UDP */
|
||||
hdr->crc = short_be(0x24cf); /* Set IPv4 CRC correct */
|
||||
udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
|
||||
|
||||
/* udp_hdr->crc = 0; */
|
||||
/* printf(">>>>>>>>>>>>>>>>>>>>> UDP CRC VALUE = %X\n", pico_udp_checksum_ipv4(f)); */
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 0, "correct UDP checksum got rejected\n");
|
||||
udp_hdr->crc = 0;
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 0, "UDP checksum of 0 did not get ignored\n");
|
||||
udp_hdr->crc = short_be(0x8899); /* Make check fail */
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 1, "incorrect UDP checksum got accepted\n");
|
||||
|
||||
/* TCP CRC unit tests */
|
||||
/* Allocated memory will be freed when pico_transport_crc_check fails */
|
||||
f = calloc(1, sizeof(struct pico_frame));
|
||||
f_usage_count = calloc(1, sizeof(uint32_t));
|
||||
f_buffer = calloc(1, sizeof(uint8_t));
|
||||
f->net_hdr = buffer;
|
||||
f->transport_hdr = buffer + PICO_SIZE_IP4HDR;
|
||||
f->transport_len = sizeof(buffer) - PICO_SIZE_IP4HDR;
|
||||
f->usage_count = f_usage_count;
|
||||
f->buffer = f_buffer;
|
||||
*(f->usage_count) = 1;
|
||||
hdr->proto = 0x06; /* TCP */
|
||||
hdr->crc = short_be(0x24cf); /* Set IPv4 CRC correct */
|
||||
tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
|
||||
tcp_hdr->seq = long_be(0x002c2722); /* Set sequence number correct */
|
||||
|
||||
/* tcp_hdr = 0; */
|
||||
/* printf(">>>>>>>>>>>>>>>>>>>>> TCP CRC VALUE = %X\n", pico_tcp_checksum_ipv4(f)); */
|
||||
tcp_hdr->crc = short_be(0x0016); /* Set correct TCP CRC */
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 0, "correct TCP checksum got rejected\n");
|
||||
tcp_hdr->crc = short_be(0x8899); /* Make check fail */
|
||||
ret = pico_transport_crc_check(f);
|
||||
fail_if(ret == 1, "incorrect TCP checksum got accepted\n");
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
40
kernel/picotcp/test/unit/unit_timer.c
Normal file
40
kernel/picotcp/test/unit/unit_timer.c
Normal file
@ -0,0 +1,40 @@
|
||||
#define EXISTING_TIMERS 7
|
||||
|
||||
|
||||
START_TEST (test_timers)
|
||||
{
|
||||
uint32_t T[128];
|
||||
int i;
|
||||
struct pico_timer_ref *tref;
|
||||
pico_stack_init();
|
||||
for (i = 0; i < 128; i++) {
|
||||
pico_time expire = (pico_time)(999999 + i);
|
||||
void (*timer)(pico_time, void *) =(void (*)(pico_time, void *))0xff00 + i;
|
||||
void *arg = ((void*)0xaa00 + i);
|
||||
|
||||
T[i] = pico_timer_add(expire, timer, arg);
|
||||
printf("New timer %u\n", T[i]);
|
||||
}
|
||||
for (i = 0; i < 128; i++) {
|
||||
void (*timer)(pico_time, void *) =(void (*)(pico_time, void *))0xff00 + i;
|
||||
void *arg = ((void*)0xaa00 + i);
|
||||
|
||||
fail_if((uint32_t)(i + 1) > Timers->n);
|
||||
tref = heap_get_element(Timers, (uint32_t)i + EXISTING_TIMERS);
|
||||
fail_unless(tref->id == T[i]);
|
||||
fail_unless(tref->tmr->timer == timer);
|
||||
fail_unless(tref->tmr->arg == arg);
|
||||
}
|
||||
for (i = 127; i >= 0; i--) {
|
||||
printf("Deleting timer %d \n", i );
|
||||
pico_timer_cancel(T[i]);
|
||||
printf("Deleted timer %d \n", i );
|
||||
tref = heap_get_element(Timers, (uint32_t)i + EXISTING_TIMERS);
|
||||
fail_unless(tref->tmr == NULL);
|
||||
}
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
pico_stack_tick();
|
||||
}
|
||||
END_TEST
|
||||
Reference in New Issue
Block a user