Пример #1
0
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);
}
Пример #2
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
    }
}
Пример #5
0
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;
}
Пример #6
0
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);
}
Пример #7
0
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);
    }
}
Пример #8
0
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; 
}
Пример #9
0
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;
}
Пример #10
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");
}
Пример #11
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;
}
Пример #12
0
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;
    }
  }