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);
}
Ejemplo n.º 3
0
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();

}
Ejemplo n.º 4
0
END_TEST

START_TEST (arp_lookup_test)
{
    struct pico_ip4 ip;
    struct pico_eth *eth = NULL;
    char ipstr[] = "192.168.1.1";
    struct pico_arp entry;

    eth = pico_arp_lookup(&ip);
    fail_unless(eth == NULL);

    pico_string_to_ipv4(ipstr, &ip.addr);
    entry.ipv4 = ip;

    pico_stack_init();
    pico_arp_add_entry(&entry);
    entry.arp_status = PICO_ARP_STATUS_STALE;
    eth = pico_arp_lookup(&ip);
    fail_unless(eth == NULL);
}
Ejemplo n.º 5
0
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");
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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);
    }
}
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
int main(void)
{
    pico_stack_init();
    pico_stack_tick();
    return 0;
}
Ejemplo n.º 11
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;
}