Files
my-os-project2/kernel/picotcp/test/unit/unit_ipv4.c
2025-10-29 14:29:06 +01:00

853 lines
38 KiB
C

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