END_TEST START_TEST(tc_pico_sntp_parse) { /* TODO: test this: static void pico_sntp_parse(char *buf, struct sntp_server_ns_cookie *ck) */ struct sntp_server_ns_cookie *ck; struct pico_socket *sock; struct pico_sntp_header header = { 0 }; ck = PICO_ZALLOC(sizeof(struct sntp_server_ns_cookie)); fail_unless (ck != NULL); ck->hostname = PICO_ZALLOC(sizeof(char) * 5); fail_unless (ck->hostname != NULL); ck->stamp = 0ull; ck->cb_synced = cb_synced; sock = pico_socket_open(0, 0, &pico_sntp_client_wakeup); ck->sock = sock; sock->priv = ck; header.mode = 4; /* server mode */ header.vn = 4; /* sntp version 4 */ header.stratum = 1; /* primary reference */ header.trs_ts.sec = long_be(SNTP_UNIX_OFFSET + 1390000000ul); header.trs_ts.frac = long_be(3865470566ul); /* value: 899msec */ fail_if(pico_sntp_parse((char *) &header, NULL) == 0); fail_if(pico_sntp_parse((char *) &header, ck) != 0); }
static struct pico_eth *pico_ethernet_mcast_translate(struct pico_frame *f, uint8_t *pico_mcast_mac) { struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; /* place 23 lower bits of IP in lower 23 bits of MAC */ pico_mcast_mac[5] = (long_be(hdr->dst.addr) & 0x000000FF); pico_mcast_mac[4] = (uint8_t)((long_be(hdr->dst.addr) & 0x0000FF00) >> 8); pico_mcast_mac[3] = (uint8_t)((long_be(hdr->dst.addr) & 0x007F0000) >> 16); return (struct pico_eth *)pico_mcast_mac; }
static inline int ip_address_is_in_dhcp_range(struct pico_dhcp_server_negotiation *n, uint32_t x) { uint32_t ip_hostendian = long_be(x); if (ip_hostendian < long_be(n->dhcps->pool_start)) return 0; if (ip_hostendian > long_be(n->dhcps->pool_end)) return 0; return 1; }
static inline void dhcp_negotiation_set_ciaddr(struct pico_dhcp_server_negotiation *dhcpn) { struct pico_ip4 *ciaddr = NULL; ciaddr = pico_arp_reverse_lookup(&dhcpn->hwaddr); if (!ciaddr) { dhcpn->ciaddr.addr = dhcpn->dhcps->pool_next; dhcpn->dhcps->pool_next = long_be(long_be(dhcpn->dhcps->pool_next) + 1); pico_arp_create_entry(dhcpn->hwaddr.addr, dhcpn->ciaddr, dhcpn->dhcps->dev); } else { dhcpn->ciaddr = *ciaddr; } }
int pico_ipv4_valid_netmask(uint32_t mask) { int cnt = 0; int end = 0; int i; uint32_t mask_swap = long_be(mask); /* * Swap bytes for convenient parsing * e.g. 0x..f8ff will become 0xfff8.. * Then, we count the consecutive bits * * */ for(i = 0; i < 32; i++) { if ((mask_swap << i) & 0x80000000) { if (end) { pico_err = PICO_ERR_EINVAL; return -1; } cnt++; } else { end = 1; } } return cnt; }
void pico_dns_fill_rr_suffix(struct pico_dns_answer_suffix *suf, uint16_t qtype, uint16_t qclass, uint32_t ttl, uint16_t rdlength) { suf->qtype = short_be(qtype); suf->qclass = short_be(qclass); suf->ttl = long_be(ttl); suf->rdlength = short_be(rdlength); }
static void pico_slaacv4_send_announce_timer(pico_time now, void *arg) { struct slaacv4_cookie *tmp = (struct slaacv4_cookie *)arg; struct pico_ip4 netmask = { 0 }; netmask.addr = long_be(0xFFFF0000); (void)now; if (tmp->announce_nb < ANNOUNCE_NB) { pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_ANNOUNCE); tmp->announce_nb++; tmp->timer = pico_timer_add(ANNOUNCE_INTERVAL * 1000, pico_slaacv4_send_announce_timer, arg); if (!tmp->timer) { slaacv4_dbg("SLAACV4: Failed to start announce timer\n"); tmp->state = SLAACV4_ERROR; if (tmp->cb != NULL) tmp->cb(&tmp->ip, PICO_SLAACV4_ERROR); } } else { tmp->state = SLAACV4_CLAIMED; pico_ipv4_link_add(tmp->device, tmp->ip, netmask); if (tmp->cb != NULL) tmp->cb(&tmp->ip, PICO_SLAACV4_SUCCESS); } }
static struct pico_dhcp_server_negotiation *pico_dhcp_server_add_negotiation(struct pico_device *dev, struct pico_dhcp_hdr *hdr) { struct pico_dhcp_server_negotiation *dhcpn = NULL; struct pico_dhcp_server_setting test = {0}; struct pico_ip4 *ciaddr = NULL; if (pico_dhcp_server_find_negotiation(hdr->xid)) return NULL; dhcpn = pico_zalloc(sizeof(struct pico_dhcp_server_negotiation)); if (!dhcpn) { pico_err = PICO_ERR_ENOMEM; return NULL; } dhcpn->xid = hdr->xid; dhcpn->state = PICO_DHCP_STATE_DISCOVER; memcpy(dhcpn->hwaddr.addr, hdr->hwaddr, PICO_SIZE_ETH); test.dev = dev; dhcpn->dhcps = pico_tree_findKey(&DHCPSettings, &test); if (!dhcpn->dhcps) { dhcps_dbg("DHCP server WARNING: received DHCP message on unconfigured link %s\n", dev->name); pico_free(dhcpn); return NULL; } ciaddr = pico_arp_reverse_lookup(&dhcpn->hwaddr); if (!ciaddr) { dhcpn->ciaddr.addr = dhcpn->dhcps->pool_next; dhcpn->dhcps->pool_next = long_be(long_be(dhcpn->dhcps->pool_next) + 1); pico_arp_create_entry(dhcpn->hwaddr.addr, dhcpn->ciaddr, dhcpn->dhcps->dev); } else { dhcpn->ciaddr = *ciaddr; } pico_tree_insert(&DHCPNegotiations, dhcpn); return dhcpn; }
static int pico_dns_client_check_asuffix(struct pico_dns_answer_suffix *suf, struct pico_dns_query *q) { if (!suf) { pico_err = PICO_ERR_EINVAL; return -1; } if (short_be(suf->qtype) != q->qtype || short_be(suf->qclass) != q->qclass) { dns_dbg("DNS WARNING: received qtype (%u) or qclass (%u) incorrect\n", short_be(suf->qtype), short_be(suf->qclass)); return -1; } if (long_be(suf->ttl) > PICO_DNS_MAX_TTL) { dns_dbg("DNS WARNING: received TTL (%u) > MAX (%u)\n", short_be(suf->ttl), PICO_DNS_MAX_TTL); return -1; } return 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"); }
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; }
void app_mcastsend(char *arg) { char *maddr = NULL, *laddr = NULL, *lport = NULL, *sport = NULL; uint16_t sendto_port = 0; struct pico_ip4 inaddr_link = { 0 }, inaddr_mcast = { 0 }; char *new_arg = NULL, *p = NULL, *nxt = arg; struct pico_ip_mreq mreq = ZERO_MREQ; /* start of parameter parsing */ if (nxt) { nxt = cpy_arg(&laddr, nxt); if (laddr) { pico_string_to_ipv4(laddr, &inaddr_link.addr); } else { goto out; } } else { /* no arguments */ goto out; } if (nxt) { nxt = cpy_arg(&maddr, nxt); if (maddr) { pico_string_to_ipv4(maddr, &inaddr_mcast.addr); } else { goto out; } } else { /* missing multicast address */ goto out; } if (nxt) { nxt = cpy_arg(&sport, nxt); if (sport && atoi(sport)) { sendto_port = short_be(atoi(sport)); } else { /* incorrect send_port */ goto out; } } else { /* missing send_port */ goto out; } if (nxt) { nxt = cpy_arg(&lport, nxt); if (lport && atoi(lport)) { /* unused at this moment */ /* listen_port = short_be(atoi(lport)); */ } else { /* incorrect listen_port */ goto out; } } else { /* missing listen_port */ goto out; } picoapp_dbg("\n%s: mcastsend started. Sending packets to %08X:%u\n\n", __FUNCTION__, long_be(inaddr_mcast.addr), short_be(sendto_port)); /* udpclient:dest_addr:sendto_port[:listen_port:datasize:loops:subloops] */ new_arg = calloc(1, strlen(maddr) + 1 + strlen(sport) + 1 + strlen(lport) + strlen(":64:10:5:") + 1); p = strcat(new_arg, maddr); p = strcat(p + strlen(maddr), ":"); p = strcat(p + 1, sport); p = strcat(p + strlen(sport), ":"); p = strcat(p + 1, lport); p = strcat(p + strlen(lport), ":64:10:5:"); app_udpclient(new_arg); mreq.mcast_group_addr = inaddr_mcast; mreq.mcast_link_addr = inaddr_link; if(pico_socket_setoption(udpclient_pas->s, PICO_IP_ADD_MEMBERSHIP, &mreq) < 0) { picoapp_dbg("%s: socket_setoption PICO_IP_ADD_MEMBERSHIP failed: %s\n", __FUNCTION__, strerror(pico_err)); exit(1); } return; out: picoapp_dbg("mcastsend expects the following format: mcastsend:link_addr:mcast_addr:sendto_port:listen_port\n"); exit(255); }
static void pico_dns_client_callback(uint16_t ev, struct pico_socket *s) { char *q_qname, *q_suf, *a_hdr, *a_qname, *a_suf, *a_rdata; struct dns_message_hdr *hdr; struct dns_query_suffix query_suf; struct dns_answer_suffix answer_suf; struct pico_dns_key test, *key; char *answer; char dns_answer[PICO_DNS_MAX_RESPONSE_LEN] = {0}; uint8_t valid_suffix = 0; uint16_t compression = 0; int i = 0, r = 0; if (ev & PICO_SOCK_EV_RD) { r = pico_socket_read(s, dns_answer, PICO_DNS_MAX_RESPONSE_LEN); pico_socket_close(s); if (r == PICO_DNS_MAX_RESPONSE_LEN || r < (int)sizeof(struct dns_message_hdr)) { dns_dbg("DNS ERROR: received incorrect number(%d) of bytes\n", r); return; } /* Check header validity */ a_hdr = dns_answer; hdr = (struct dns_message_hdr *) a_hdr; pico_dns_client_hdr_ntoh(hdr); if (GET_FLAG_QR(hdr) != PICO_DNS_QR_RESPONSE || GET_FLAG_OPCODE(hdr) != PICO_DNS_OPCODE_QUERY || GET_FLAG_TC(hdr) == PICO_DNS_TC_IS_TRUNCATED || GET_FLAG_RCODE(hdr) != PICO_DNS_RCODE_NO_ERROR) { dns_dbg("DNS ERROR: OPCODE %d | TC %d | RCODE %d\n", GET_FLAG_OPCODE(hdr), GET_FLAG_TC(hdr), GET_FLAG_RCODE(hdr)); return; } if (hdr->ancount < 1 || r < (int)(sizeof(struct dns_message_hdr) + hdr->qdcount * sizeof(struct dns_query_suffix) + hdr->ancount * sizeof(struct dns_answer_suffix))) { dns_dbg("DNS ERROR: ancount < 1 OR received number(%d) of bytes too low\n", r); return; } /* Find DNS key */ test.id = hdr->id; key = pico_tree_findKey(&DNSTable,&test); if (!key) { dns_dbg("DNS WARNING: key with id %u not found\n", hdr->id); return; } key->retrans = 0; /* Check query suffix validity */ q_qname = a_hdr + sizeof(struct dns_message_hdr); q_suf = pico_dns_client_seek(q_qname); query_suf = *(struct dns_query_suffix *) q_suf; if (short_be(query_suf.qtype) != key->qtype || short_be(query_suf.qclass) != key->qclass) { dns_dbg("DNS ERROR: received qtype (%u) or qclass (%u) incorrect\n", short_be(query_suf.qtype), short_be(query_suf.qclass)); return; } /* Seek answer suffix */ a_qname = q_suf + sizeof(struct dns_query_suffix); a_suf = a_qname; while(i++ < hdr->ancount) { uint16_t comp_h = short_from(a_suf); compression = short_be(comp_h); switch (compression >> 14) { case PICO_DNS_POINTER: while (compression >> 14 == PICO_DNS_POINTER) { dns_dbg("DNS: pointer\n"); a_suf += sizeof(uint16_t); comp_h = short_from(a_suf); compression = short_be(comp_h); } break; case PICO_DNS_LABEL: dns_dbg("DNS: label\n"); a_suf = pico_dns_client_seek(a_qname); break; default: dns_dbg("DNS ERROR: incorrect compression (%u) value\n", compression); return; } /* Check answer suffix validity */ answer_suf = *(struct dns_answer_suffix *)a_suf; if (short_be(answer_suf.qtype) != key->qtype || short_be(answer_suf.qclass) != key->qclass) { dns_dbg("DNS WARNING: received qtype (%u) or qclass (%u) incorrect\n", short_be(answer_suf.qtype), short_be(answer_suf.qclass)); a_suf = a_suf + sizeof(struct dns_answer_suffix) + short_be(answer_suf.rdlength); continue; } if (short_be(answer_suf.ttl) > PICO_DNS_MAX_TTL) { dns_dbg("DNS WARNING: received TTL (%u) > MAX (%u)\n", short_be(answer_suf.ttl), PICO_DNS_MAX_TTL); a_suf = a_suf + sizeof(struct dns_answer_suffix) + short_be(answer_suf.rdlength); continue; } valid_suffix = 1; break; } if (!valid_suffix) { dns_dbg("DNS ERROR: invalid dns answer suffix\n"); return; } a_rdata = a_suf + sizeof(struct dns_answer_suffix); if (key->qtype == PICO_DNS_TYPE_A) { uint32_t ip_h = long_from(a_rdata); dns_dbg("DNS: length %u | ip %08X\n", short_be(answer_suf.rdlength), long_be(ip_h)); answer = pico_zalloc(16); pico_ipv4_to_string(answer, ip_h); key->callback(answer, key->arg); } else if (key->qtype == PICO_DNS_TYPE_PTR) { pico_dns_client_reverse_label((char *) a_rdata); dns_dbg("DNS: length %u | name %s\n", short_be(answer_suf.rdlength), (char *)a_rdata + 1); answer = pico_zalloc(answer_suf.rdlength - 1); memcpy(answer, (char *)a_rdata + 1, short_be(answer_suf.rdlength) - 1); key->callback(answer, key->arg); } else { dns_dbg("DNS ERROR: incorrect qtype (%u)\n", key->qtype); return; } }