int main() { uint8_t mac[6]; uint32_t timer = 0; /* Obtain the ethernet MAC address */ eth_mac(mac); const char *ipaddr="192.168.0.150"; uint16_t port_be = 0; interrupt_register(irq_timer, GUEST_TIMER_INT); /* Configure the virtual ethernet driver */ struct pico_device* eth_dev = PICO_ZALLOC(sizeof(struct pico_device)); if(!eth_dev) { return 0; } eth_dev->send = eth_send; eth_dev->poll = eth_poll; eth_dev->link_state = eth_link_state; if( 0 != pico_device_init((struct pico_device *)eth_dev, "virt-eth", mac)) { printf ("\nDevice init failed."); PICO_FREE(eth_dev); return 0; } /* picoTCP initialization */ printf("\nInitializing pico stack\n"); pico_stack_init(); wolfSSL_Debugging_ON(); pico_string_to_ipv4(ipaddr, &my_eth_addr.addr); pico_string_to_ipv4("255.255.255.0", &netmask.addr); pico_ipv4_link_add(eth_dev, my_eth_addr, netmask); port_be = short_be(LISTENING_PORT); /* WolfSSL initialization only, to make sure libwolfssl.a is needed */ pico_https_setCertificate(cert_pem_2048, sizeof(cert_pem_2048)); pico_https_setPrivateKey(privkey_pem_2048, sizeof(privkey_pem_2048)); pico_https_server_start(0, serverWakeup); while (1){ eth_watchdog(&timer, 500); /* pooling picoTCP stack */ pico_stack_tick(); } return 0; }
void init_picotcp() { struct ether_addr mac; struct pico_device *dev = NULL; struct pico_ip4 addr; struct pico_ip4 netm; ether_aton_r(config.if_mac, &mac); pico_stack_init(); dev = pico_netmap_create(config.if_name, "eth_if", (uint8_t *) &mac); pico_string_to_ipv4(config.if_addr, &addr.addr); pico_string_to_ipv4("255.255.255.0", &netm.addr); pico_ipv4_link_add(dev, addr, netm); }
void pre_init(void) { struct pico_ip4 netmask, ipaddr, gw, multicast, zero = {0}; pico_device_eth *pico_driver; memset(&io_ops, 0, sizeof(io_ops)); io_ops.dma_manager = (ps_dma_man_t) { .cookie = NULL, .dma_alloc_fn = malloc_dma_alloc, .dma_free_fn = malloc_dma_free, .dma_pin_fn = malloc_dma_pin, .dma_unpin_fn = malloc_dma_unpin, .dma_cache_op_fn = malloc_dma_cache_op }; /* Initialise the PicoTCP stack */ pico_stack_init(); /* Create a driver. This utilises preallocated buffers, backed up by malloc above */ pico_driver = pico_eth_create_no_malloc("eth0", ethdriver_init, NULL, io_ops, &_picotcp_driver); assert(pico_driver); pico_string_to_ipv4("0.0.0.0", &gw.addr); pico_string_to_ipv4(server_ip_addr, &ipaddr.addr); pico_string_to_ipv4(multicast_addr, &multicast.addr); pico_string_to_ipv4("255.255.255.0", &netmask.addr); pico_ipv4_link_add(pico_driver, ipaddr, netmask); pico_ipv4_route_add(zero, zero, gw, 1, NULL); if (pico_ipv4_is_multicast(multicast.addr)) { ZF_LOGE("Multicast not yet implemented\n"); // PicoTCP usually deals with multicast at the socket layer, using pico_socket_setoption. // It can be done at the igmp level too by using igmp_state_change. See the picoTCP documentation // Eg: pico_igmp_state_change(&ipaddr, &multicast, .... ); } /* Start the timer for tcp */ // TCP runs off a tick for handling events and timeouts. timer_periodic(0, NS_IN_MS * PICO_TICK_MS); start_tcpecho(); }
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(); pico_arp_add_entry(&entry); entry.arp_status = PICO_ARP_STATUS_STALE; eth = pico_arp_lookup(&ip); fail_unless(eth == NULL); }
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"); }
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; }
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 = 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); for (i = 0; i < PICO_ND_MAX_FRAMES_QUEUED; i++) { fail_if(frames_queued[i] != NULL); } 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(0x0A28000A) }; struct pico_ip4 ip2 = { .addr = long_be(0x0A28000B) }; 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); } 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, 0, 0xa, 0xb, 0xf }; struct pico_ip4 netmask = { .addr = long_be(0xffffff00) }; struct pico_ip4 ip = { .addr = long_be(0x0A28000A) }; 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); } END_TEST
int main(int argc, char **argv) { unsigned char macaddr[6] = { 0, 0, 0, 0xa, 0xb, 0x0 }; uint16_t *macaddr_low = (uint16_t *) (macaddr + 2); struct pico_device *dev = NULL; struct option long_options[] = { {"help", 0, 0, 'h'}, {"vde", 1, 0, 'v'}, {"barevde", 1, 0, 'b'}, {"tun", 1, 0, 't'}, {"route", 1, 0, 'r'}, {"app", 1, 0, 'a'}, {"loop", 0, 0, 'l'}, {0, 0, 0, 0} }; int option_idx = 0; int c; *macaddr_low ^= (uint16_t)getpid(); printf("My macaddr base is: %02x %02x\n", macaddr[2], macaddr[3]); pico_stack_init(); /* Parse args */ while(1) { c = getopt_long(argc, argv, "v:b:t:a:r:hl", long_options, &option_idx); if (c < 0) break; switch(c) { case 'v': { char *nxt, *name = NULL, *sock = NULL, *addr = NULL, *nm = NULL, *gw = NULL; struct pico_ip4 ipaddr, netmask, gateway, zero = ZERO_IP4; printf("+++ OPTARG %s\n", optarg); do { nxt = cpy_arg(&name, optarg); if (!nxt) break; nxt = cpy_arg(&sock, nxt); if (!nxt) break; nxt = cpy_arg(&addr, nxt); if (!nxt) break; nxt = cpy_arg(&nm, nxt); if (!nxt) break; nxt = cpy_arg(&gw, nxt); } while(0); if (!nm) { fprintf(stderr, "Vde: bad configuration...\n"); exit(1); } dev = pico_vde_create(sock, name, macaddr); NXT_MAC(macaddr); if (!dev) { perror("Creating vde"); exit(1); } printf("Vde created.\n"); pico_string_to_ipv4(addr, &ipaddr.addr); pico_string_to_ipv4(nm, &netmask.addr); pico_ipv4_link_add(dev, ipaddr, netmask); /* bcastAddr.addr = (ipaddr.addr) | (~netmask.addr); */ if (gw && *gw) { pico_string_to_ipv4(gw, &gateway.addr); pico_ipv4_route_add(zero, zero, gateway, 1, NULL); } } break; } } if( pico_http_server_start(0, serverWakeup) < 0) { fprintf(stderr, "Unable to start the HTTP server on port 80\n"); } else { printf("HTTP server started\n"); } printf("%s: launching PicoTCP loop\n", __FUNCTION__); while(1) { pico_stack_tick(); usleep(2000); } }
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, 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)); uint8_t nullbuf[8] = {}; 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); 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, 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, 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, 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, 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 == 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, len - 20) == 0); #ifdef NOPE /* I don't know what was the intention, but the buffer is shorter than 48 bytes... */ fail_if(memcmp(buffer + 48, nullbuf, 8) == 0); /* there was no data */ #endif } END_TEST int icmp4_socket_unreach_status = 0; void icmp4_unreach_socket_cb(uint16_t ev, struct pico_socket *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
int main(void) { pico_stack_init(); pico_stack_tick(); return 0; }
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; }