761 lines
39 KiB
C
761 lines
39 KiB
C
|
|
#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
|