Example #1
0
static struct pico_dns_query *pico_dns_client_add_query(struct pico_dns_prefix *hdr, uint16_t len, struct pico_dns_query_suffix *suffix,
                                                        void (*callback)(char *, void *), void *arg)
{
    struct pico_dns_query *q = NULL, *found = NULL;

    q = pico_zalloc(sizeof(struct pico_dns_query));
    if (!q)
        return NULL;

    q->query = (char *)hdr;
    q->len = len;
    q->id = short_be(hdr->id);
    q->qtype = short_be(suffix->qtype);
    q->qclass = short_be(suffix->qclass);
    q->retrans = 1;
    q->q_ns = *((struct pico_dns_ns *)pico_tree_first(&NSTable));
    q->callback = callback;
    q->arg = arg;
    q->s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dns_client_callback);
    if (!q->s) {
        pico_free(q);
        return NULL;
    }

    found = pico_tree_insert(&DNSTable, q);
    if (found) {
        pico_err = PICO_ERR_EAGAIN;
        pico_socket_close(q->s);
        pico_free(q);
        return NULL;
    }

    return q;
}
void
setup_udp_app() {
	struct pico_socket *listen_socket;
	struct pico_ip4 address;
	uint16_t port;
	int ret;

	port = short_be(atoi(config.port));
	bzero(&address, sizeof(address));

	listen_socket = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &cb_udpconnect);
	if (!listen_socket) {
		printf("cannot open socket: %s", strerror(pico_err));
		exit(1);
	}

	ret = pico_socket_bind(listen_socket, &address, &port);
	if (ret < 0) {
		printf("cannot bind socket to port %u: %s", short_be(port), strerror(pico_err));
		exit(1);
	}


	return;
}
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);
}
Example #4
0
void start_tcpecho()
{
    uint16_t listen_port = short_be(8777);
    int ret = 0, yes = 1;
    struct pico_socket *s = NULL;
    struct pico_ip4 ip4 = {0};

    s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpecho);

    if (!s) {
        ZF_LOGE("%s: error opening socket: %s\n", __FUNCTION__, strerror(pico_err));
    }

    pico_socket_setoption(s, PICO_TCP_NODELAY, &yes);

    ret = pico_socket_bind(s, &ip4, &listen_port);

    if (ret < 0) {
        ZF_LOGE("%s: error binding socket to port %u: %s\n", __FUNCTION__, short_be(listen_port), strerror(pico_err));
    }

    if (pico_socket_listen(s, 40) != 0) {
        ZF_LOGE("%s: error listening on port %u\n", __FUNCTION__, short_be(listen_port));
    }

    ZF_LOGD("Launching PicoTCP echo server\n");
}
Example #5
0
static struct pico_dhcp_server_setting *pico_dhcp_server_add_setting(struct pico_dhcp_server_setting *setting)
{
  uint16_t port = PICO_DHCPD_PORT;
  struct pico_dhcp_server_setting *dhcps = NULL, *found = NULL, test = {0};
  struct pico_ipv4_link *link = NULL;
  
  link = pico_ipv4_link_get(&setting->server_ip);
  if (!link) {
    pico_err = PICO_ERR_EINVAL;
    return NULL;
  }
  test.dev = setting->dev;
  found = pico_tree_findKey(&DHCPSettings, &test);
  if (found) {
    pico_err = PICO_ERR_EINVAL;
    return NULL;
  }
  dhcps = pico_zalloc(sizeof(struct pico_dhcp_server_setting));
  if (!dhcps) {
    pico_err = PICO_ERR_ENOMEM;
    return NULL;
  }

  dhcps->lease_time = setting->lease_time;
  dhcps->pool_start = setting->pool_start;
  dhcps->pool_next = setting->pool_next;
  dhcps->pool_end = setting->pool_end;
  dhcps->dev = link->dev;
  dhcps->server_ip = link->address;
  dhcps->netmask = link->netmask;

  /* default values if not provided */
  if (!dhcps->pool_start)
    dhcps->pool_start = (dhcps->server_ip.addr & dhcps->netmask.addr) | DHCP_SERVER_POOL_START;
  if (!dhcps->pool_end)
    dhcps->pool_end = (dhcps->server_ip.addr & dhcps->netmask.addr) | DHCP_SERVER_POOL_END;
  if (!dhcps->lease_time)
    dhcps->lease_time = DHCP_SERVER_LEASE_TIME;
  dhcps->pool_next = dhcps->pool_start;

  dhcps->s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dhcpd_wakeup);
  if (!dhcps->s) {
    dhcps_dbg("DHCP server ERROR: failure opening socket (%s)\n", strerror(pico_err));
    pico_free(dhcps);
    return NULL;
  }
  if (pico_socket_bind(dhcps->s, &dhcps->server_ip, &port) < 0) {
    dhcps_dbg("DHCP server ERROR: failure binding socket (%s)\n", strerror(pico_err));
    pico_free(dhcps);
    return NULL;
  }
  
  pico_tree_insert(&DHCPSettings, dhcps);
  return dhcps;
}
static int pico_dns_client_send(struct pico_dns_key *key)
{
  struct pico_socket *s;
  int w = 0;

  dns_dbg("DNS: sending query to %08X\n", key->q_ns.ns.addr);
  s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dns_client_callback);
  if (!s)
    return -1; 
  key->s = s;
  if (pico_socket_connect(s, &key->q_ns.ns, short_be(PICO_DNS_NS_PORT)) != 0)
    return -1;
  w = pico_socket_send(s, key->q_hdr, key->len);
  if (w <= 0)
    return -1;

  return 0;
}
END_TEST
START_TEST(tc_sntp_receive_timeout)
{
    struct sntp_server_ns_cookie *ck;
    struct pico_socket *sock;
    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;
    sntp_receive_timeout(0ull, ck);

}
Example #8
0
static inline struct pico_dhcp_server_setting *dhcps_try_open_socket(struct pico_dhcp_server_setting *dhcps)
{
    uint16_t port = PICO_DHCPD_PORT;
    dhcps->s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dhcpd_wakeup);
    if (!dhcps->s) {
        dhcps_dbg("DHCP server ERROR: failure opening socket (%s)\n", strerror(pico_err));
        PICO_FREE(dhcps);
        return NULL;
    }

    if (pico_socket_bind(dhcps->s, &dhcps->server_ip, &port) < 0) {
        dhcps_dbg("DHCP server ERROR: failure binding socket (%s)\n", strerror(pico_err));
        PICO_FREE(dhcps);
        return NULL;
    }

    pico_tree_insert(&DHCPSettings, dhcps);
    return dhcps;
}
END_TEST
START_TEST(tc_pico_sntp_cleanup)
{
    struct sntp_server_ns_cookie *ck;
    struct pico_socket *sock;
    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;


    pico_sntp_cleanup(ck, PICO_ERR_NOERR);
}
END_TEST
START_TEST(tc_pico_sntp_client_wakeup)
{
    /* TODO: test this: static void pico_sntp_client_wakeup(uint16_t ev, struct pico_socket *s) */
    uint16_t event = PICO_SOCK_EV_ERR;
    struct sntp_server_ns_cookie *ck;
    struct pico_socket *sock;
    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;

    ck->cb_synced = cb_synced;
    printf("Started wakeup unit test\n");

    pico_sntp_client_wakeup(event, sock);
}
Example #11
0
void app_tcpclient()
{
    char *daddr = NULL, *dport = NULL;
    uint16_t send_port = 0, listen_port = short_be(5555);
    int i = 0, ret = 0, yes = 1;
    struct pico_socket *s = NULL;
    struct pico_ip4 dst = {0};
    struct pico_ip4 inaddr = {0};

    ZF_LOGD("Connecting to: %s:%d\n", daddr, short_be(send_port));

    s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpclient);

    if (!s) {
        ZF_LOGE("%s: error opening socket: %s\n", __FUNCTION__, strerror(pico_err));
    }

    pico_socket_setoption(s, PICO_TCP_NODELAY, &yes);

    ret = pico_socket_bind(s, &inaddr, &listen_port);

    if (ret < 0) {
        ZF_LOGE("%s: error binding socket to port %u: %s\n", __FUNCTION__, short_be(listen_port), strerror(pico_err));
    }

    // Set the destination address (string) above in the usual xxx.xxx.xxx.xxx ip4 way.
    pico_string_to_ipv4(daddr, &dst.addr);

    ret = pico_socket_connect(s, &dst, send_port);

    if (ret < 0) {
        ZF_LOGE("%s: error connecting to %s:%u: %s\n", __FUNCTION__, daddr, short_be(send_port), strerror(pico_err));
    }

    ZF_LOGD("TCP client connected\n");

}
Example #12
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