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;
}
Example #2
0
int ipfilter(struct pico_frame *f)
{
    struct filter_node temp;
    struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *) f->net_hdr;
    struct pico_trans *trans;
    struct pico_icmp4_hdr *icmp_hdr;

    memset(&temp, 0u, sizeof(struct filter_node));

    temp.fdev = f->dev;
    temp.out_addr = ipv4_hdr->dst.addr;
    temp.in_addr = ipv4_hdr->src.addr;
    if ((ipv4_hdr->proto == PICO_PROTO_TCP) || (ipv4_hdr->proto == PICO_PROTO_UDP)) {
        trans = (struct pico_trans *) f->transport_hdr;
        temp.out_port = short_be(trans->dport);
        temp.in_port = short_be(trans->sport);
    }
    else if(ipv4_hdr->proto == PICO_PROTO_ICMP4) {
        icmp_hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
        if(icmp_hdr->type == PICO_ICMP_UNREACH && icmp_hdr->type == PICO_ICMP_UNREACH_FILTER_PROHIB)
            return 0;
    }

    temp.proto = ipv4_hdr->proto;
    temp.priority = f->priority;
    temp.tos = ipv4_hdr->tos;
    return ipfilter_apply_filter(f, &temp);
}
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;
}
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
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);
}
Example #6
0
void pico_dns_fill_header(struct pico_dns_header *hdr, uint16_t qdcount, uint16_t ancount)
{

    /* hdr->id should be filled by caller */

    if(qdcount > 0) {
        hdr->qr = PICO_DNS_QR_QUERY;
        hdr->aa = PICO_DNS_AA_NO_AUTHORITY;
    }
    else {
        hdr->qr = PICO_DNS_QR_RESPONSE;
        hdr->aa = PICO_DNS_AA_IS_AUTHORITY;
    }

    hdr->opcode = PICO_DNS_OPCODE_QUERY;
    hdr->tc = PICO_DNS_TC_NO_TRUNCATION;
    hdr->rd = PICO_DNS_RD_NO_DESIRE;
    hdr->ra = PICO_DNS_RA_NO_SUPPORT;
    hdr->z = 0; /* Z, AD, CD are 0 */
    hdr->rcode = PICO_DNS_RCODE_NO_ERROR;
    hdr->qdcount = short_be(qdcount);
    hdr->ancount = short_be(ancount);
    hdr->nscount = short_be(0);
    hdr->arcount = short_be(0);
}
Example #7
0
static int pico_dns_client_query_prefix(struct pico_dns_prefix *pre)
{
    uint16_t id = 0;
    uint8_t retry = 32;

    do {
        id = (uint16_t)(pico_rand() & 0xFFFFU);
        dns_dbg("DNS: generated id %u\n", id);
    } while (retry-- && pico_dns_client_idcheck(id));
    if (!retry)
        return -1;

    pre->id = short_be(id);
    pre->qr = PICO_DNS_QR_QUERY;
    pre->opcode = PICO_DNS_OPCODE_QUERY;
    pre->aa = PICO_DNS_AA_NO_AUTHORITY;
    pre->tc = PICO_DNS_TC_NO_TRUNCATION;
    pre->rd = PICO_DNS_RD_IS_DESIRED;
    pre->ra = PICO_DNS_RA_NO_SUPPORT;
    pre->z = 0;
    pre->rcode = PICO_DNS_RCODE_NO_ERROR;
    pre->qdcount = short_be(1);
    pre->ancount = short_be(0);
    pre->nscount = short_be(0);
    pre->arcount = short_be(0);

    return 0;
}
Example #8
0
static int pico_dns_client_check_qsuffix(struct pico_dns_query_suffix *suf, struct pico_dns_query *q)
{
    if (short_be(suf->qtype) != q->qtype || short_be(suf->qclass) != q->qclass) {
        dns_dbg("DNS ERROR: received qtype (%u) or qclass (%u) incorrect\n", short_be(suf->qtype), short_be(suf->qclass));
        return -1;
    }

    return 0;
}
Example #9
0
void app_tftp(char *arg)
{
    struct command_t *commands;
    struct note_t *note;
    struct pico_tftp_session *session;
    int is_server_enabled = 0;
    int filesize;

    family = IPV6_MODE ? PICO_PROTO_IPV6 : PICO_PROTO_IPV4;

    commands = parse_arguments(arg);
    while (commands) {

        if (toupper(commands->operation) != 'S')
            note = transfer_prepare(&session, commands->operation, commands->filename, &commands->server_address, family);

        switch (commands->operation) {
        case 'S':
        case 's':
            if (!is_server_enabled) {
                pico_tftp_listen(PICO_PROTO_IPV4, (commands->operation == 'S') ? tftp_listen_cb_opt : tftp_listen_cb);
                is_server_enabled = 1;
            }

            break;
        case 'T':
            filesize = get_filesize(commands->filename);
            if (filesize < 0) {
                fprintf(stderr, "TFTP: unable to read size of file %s\n", commands->filename);
                exit(3);
            }

            pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize);
            start_tx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_tx_opt, note);
            break;
        case 't':
            start_tx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_tx, note);
            break;
        case 'R':
            pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, 0);
            start_rx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_rx_opt, note);
            break;
        case 'r':
            start_rx(session, commands->filename, short_be(PICO_TFTP_PORT), cb_tftp_rx, note);
        }
        commands = commands->next;
    }
}
Example #10
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
    };

    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;
    dhcpn->bcast = ((short_be(hdr->flags) & PICO_DHCP_FLAG_BROADCAST) != 0) ? (1) : (0);
    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;
    }

    dhcp_negotiation_set_ciaddr(dhcpn);
    pico_tree_insert(&DHCPNegotiations, dhcpn);
    return dhcpn;
}
Example #11
0
static int pico_dns_client_send(struct pico_dns_query *q)
{
    uint16_t *paramID = PICO_ZALLOC(sizeof(uint16_t));
    if (!paramID) {
        pico_err = PICO_ERR_ENOMEM;
        return -1;
    }

    dns_dbg("DNS: sending query to %08X\n", q->q_ns.ns.addr);
    if (!q->s)
        goto failure;

    if (pico_socket_connect(q->s, &q->q_ns.ns, short_be(PICO_DNS_NS_PORT)) < 0)
        goto failure;

    pico_socket_send(q->s, q->query, q->len);
    *paramID = q->id;
    pico_timer_add(PICO_DNS_CLIENT_RETRANS, pico_dns_client_retransmission, paramID);

    return 0;

failure:
    PICO_FREE(paramID);
    return -1;
}
Example #12
0
static char *pico_dns_client_seek_suffix(char *suf, struct pico_dns_header *pre, struct pico_dns_query *q)
{
    struct pico_dns_answer_suffix *asuffix = NULL;
    uint16_t comp = 0, compression = 0;
    uint16_t i = 0;

    if (!suf)
        return NULL;

    while (i++ < short_be(pre->ancount)) {
        comp = short_from(suf);
        compression = short_be(comp);
        switch (compression >> 14)
        {
        case PICO_DNS_POINTER:
            while (compression >> 14 == PICO_DNS_POINTER) {
                dns_dbg("DNS: pointer\n");
                suf += sizeof(uint16_t);
                comp = short_from(suf);
                compression = short_be(comp);
            }
            break;

        case PICO_DNS_LABEL:
            dns_dbg("DNS: label\n");
            suf = pico_dns_client_seek(suf);
            break;

        default:
            dns_dbg("DNS ERROR: incorrect compression (%u) value\n", compression);
            return NULL;
        }

        asuffix = (struct pico_dns_answer_suffix *)suf;
        if (!asuffix)
            break;

        if (pico_dns_client_check_asuffix(asuffix, q) < 0) {
            suf += (sizeof(struct pico_dns_answer_suffix) + short_be(asuffix->rdlength));
            continue;
        }

        return suf;
    }
    return NULL;
}
Example #13
0
END_TEST
START_TEST(tc_pico_mld_process_in) {
    struct mld_parameters *p;
    struct pico_device *dev = pico_null_create("dummy3");
    struct pico_ipv6_link *link;
    struct pico_tree *filter = PICO_ZALLOC(sizeof(struct pico_tree));
    int i,j, _i,_j,result;
    struct pico_ipv6_mcast_group g; 
    struct mldv2_report *report;
    //Building example frame
    p = PICO_ZALLOC(sizeof(struct mld_parameters));
    pico_string_to_ipv6("AAAA::1", p->mcast_link.addr);
    pico_string_to_ipv6("FF00::e007:707", p->mcast_group.addr);
    //no link
    fail_if(pico_mld_generate_report(p) != -1);
    link = pico_ipv6_link_add(dev, p->mcast_link, p->mcast_link);
    pico_string_to_ipv6("AAAA::1", p->mcast_group.addr);
    fail_if(pico_mld_generate_report(p) != -1);
    pico_string_to_ipv6("FF00::e007:707", p->mcast_group.addr);
    link->mcast_compatibility = PICO_MLDV1;
    g.mcast_addr = p->mcast_group;
    g.MCASTSources.root = &LEAF;
    g.MCASTSources.compare = mcast_sources_cmp_ipv6;
    // No mcastsources tree
    link->mcast_compatibility = PICO_MLDV2;
    fail_if(pico_mld_generate_report(p) != -1);
    pico_tree_insert(link->MCASTGroups, &g);
    pico_tree_insert(&MLDParameters, p);
    
    link->mcast_compatibility = 99;
    fail_if(pico_mld_generate_report(p) != -1);
    link->mcast_compatibility = PICO_MLDV1;
    fail_if(pico_mld_generate_report(p) != 0);
    link->mcast_compatibility = PICO_MLDV2;
    for(_j =0; _j<3; _j++) {   //FILTER
        (_j == 2) ? (result = -1) : (result = 0);
        for(_i=0; _i<3; _i++) {  //FILTER
            if(_i == 2) result = -1;
            for(i = 0; i<3; i++) {  //STATES
                for(j = 0; j<6; j++) { //EVENTS
                    p->MCASTFilter = &_MCASTFilter;
                    p->filter_mode = _i;
                    g.filter_mode = _j;
                    if(p->event == MLD_EVENT_DELETE_GROUP || p->event == MLD_EVENT_QUERY_RECV)
                        p->event++;
                    fail_if(pico_mld_generate_report(p) != result);
                    p->state = i;
                    p->event = j;
                    if(result != -1 && p->f) {//in some combinations, no frame is created
                        report = p->f->transport_hdr + MLD_ROUTER_ALERT_LEN;
                        report->crc = short_be(pico_icmp6_checksum(p->f));
                        fail_if(pico_mld_process_in(p->f) != 0);
                    }
                }
            }
        }
    }
}
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;
}
Example #15
0
uint8_t pico_dhcp_opt_maxmsgsize(void *ptr, uint16_t size)
{
    struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;

    /* option: maximum message size */
    opt->code = PICO_DHCP_OPT_MAXMSGSIZE;
    opt->len = PICO_DHCP_OPTLEN_MAXMSGSIZE - PICO_DHCP_OPTLEN_HDR;
    opt->ext.max_msg_size.size = short_be(size);
    return PICO_DHCP_OPTLEN_MAXMSGSIZE;
}
Example #16
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;
}
Example #17
0
static int pico_ipv4_checksum(struct pico_frame *f)
{
    struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
    if (!hdr)
        return -1;

    hdr->crc = 0;
    hdr->crc = short_be(pico_checksum(hdr, f->net_len));
    return 0;
}
Example #18
0
static uint8_t pico_icmp4_send_echo(struct pico_icmp4_ping_cookie *cookie)
{
  struct pico_frame *echo = pico_proto_ipv4.alloc(&pico_proto_ipv4, (uint16_t)(PICO_ICMPHDR_UN_SIZE + cookie->size));
  struct pico_icmp4_hdr *hdr;

  hdr = (struct pico_icmp4_hdr *) echo->transport_hdr;

  hdr->type = PICO_ICMP_ECHO;
  hdr->code = 0;
  hdr->hun.ih_idseq.idseq_id = short_be(cookie->id);
  hdr->hun.ih_idseq.idseq_seq = short_be(cookie->seq);
  echo->transport_len = (uint16_t)(PICO_ICMPHDR_UN_SIZE + cookie->size);
  echo->payload = echo->transport_hdr + PICO_ICMPHDR_UN_SIZE;
  echo->payload_len = cookie->size;
  /* XXX: Fill payload */
  pico_icmp4_checksum(echo);
  pico_ipv4_frame_push(echo, &cookie->dst, PICO_PROTO_ICMP4);
  return 0;
}
Example #19
0
static int pico_icmp4_checksum(struct pico_frame *f)
{
  struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
  if (!hdr) {
    pico_err = PICO_ERR_EINVAL;
    return -1;
  }
  hdr->crc = 0;
  hdr->crc = short_be(pico_checksum(hdr, f->transport_len));
  return 0;
}
Example #20
0
int pico_socket_sendto(struct pico_socket *s, const void *buf, const int len, void *dst, uint16_t remote_port)
{
    const struct pico_tftp_hdr *h = (const struct pico_tftp_hdr *)buf;
    fail_if(s != &example_socket);
    fail_if(short_be(h->opcode) != expected_opcode);
    fail_if(len <= 0);
    (void)dst;
    (void)remote_port;
    called_sendto++;
    return 0;
}
Example #21
0
static int pico_dns_client_check_header(struct pico_dns_header *pre)
{
    if (pre->qr != PICO_DNS_QR_RESPONSE || pre->opcode != PICO_DNS_OPCODE_QUERY || pre->rcode != PICO_DNS_RCODE_NO_ERROR) {
        dns_dbg("DNS ERROR: OPCODE %d | TC %d | RCODE %d\n", pre->opcode, pre->tc, pre->rcode);
        return -1;
    }

    if (short_be(pre->ancount) < 1) {
        dns_dbg("DNS ERROR: ancount < 1\n");
        return -1;
    }

    return 0;
}
Example #22
0
static inline int pico_ipv4_crc_check(struct pico_frame *f)
{
    uint16_t checksum_invalid = 1;
    struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;

    checksum_invalid = short_be(pico_checksum(hdr, f->net_len));
    if (checksum_invalid) {
        dbg("IP: checksum failed!\n");
        pico_frame_discard(f);
        return 0;
    }

    return 1;
}
Example #23
0
/*
 * TCP code. For TCP, a socket is created and listens.
 * A callback occurs when the packet is received. The callback handles the different types of TCP events,
 * including the handshake protocol.
 * Based off the sample tcpecho app provided in the picotcp library.
 */
void cb_tcpecho(uint16_t ev, struct pico_socket *s)
{
    int r = 0;

    ZF_LOGD("tcpecho> wakeup ev=%u\n", ev);

    if (ev & PICO_SOCK_EV_RD) {
        char buf[100];
        r = pico_socket_read(s, buf, 100);
        pico_socket_write(s, buf, r); // Immediately echo back a response
    }

    if (ev & PICO_SOCK_EV_CONN) {
        uint32_t ka_val = 0;
        struct pico_socket *sock_peer;
        struct pico_ip4 orig = {0};
        uint16_t port = 0;
        char peer[30] = {0};
        int yes = 1;

        sock_peer = pico_socket_accept(s, &orig, &port);
        pico_ipv4_to_string(peer, orig.addr);
        ZF_LOGD("Connection established with %s:%d.\n", peer, short_be(port));
        pico_socket_setoption(sock_peer, PICO_TCP_NODELAY, &yes);
        /* Set keepalive options - from picoTCP documentation */
        ka_val = 5;
        pico_socket_setoption(sock_peer, PICO_SOCKET_OPT_KEEPCNT, &ka_val);
        ka_val = 30000;
        pico_socket_setoption(sock_peer, PICO_SOCKET_OPT_KEEPIDLE, &ka_val);
        ka_val = 5000;
        pico_socket_setoption(sock_peer, PICO_SOCKET_OPT_KEEPINTVL, &ka_val);
    }

    if (ev & PICO_SOCK_EV_FIN) {
        ZF_LOGD("Socket closed. Exit normally. \n");
    }

    if (ev & PICO_SOCK_EV_ERR) {
        ZF_LOGD("Socket error received: %s. Bailing out.\n", strerror(pico_err));
    }

    if (ev & PICO_SOCK_EV_CLOSE) {
        ZF_LOGD("Socket received close from peer.\n");
        pico_socket_shutdown(s, PICO_SHUT_WR);
    }

    if (ev & PICO_SOCK_EV_WR) {
        ZF_LOGD("TCP Write ack\n");
    }
}
Example #24
0
static void ping_recv_reply(struct pico_frame *f)
{
  struct pico_icmp4_ping_cookie test, *cookie;
  struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
  test.id  = short_be(hdr->hun.ih_idseq.idseq_id );
  test.seq = short_be(hdr->hun.ih_idseq.idseq_seq);

  cookie = pico_tree_findKey(&Pings, &test);
  if (cookie) {
    struct pico_icmp4_stats stats;
    cookie->err = PICO_PING_ERR_REPLIED;
    stats.dst = cookie->dst;
    stats.seq = cookie->seq;
    stats.size = cookie->size;
    stats.time = pico_tick - cookie->timestamp;
    stats.err = cookie->err;
    stats.ttl = ((struct pico_ipv4_hdr *)f->net_hdr)->ttl;
		if(cookie->cb != NULL)
    	cookie->cb(&stats);
  } else {
    dbg("Reply for seq=%d, not found.\n", test.seq);
  }
}
static inline void pico_dns_client_hdr_ntoh(struct dns_message_hdr *hdr)
{
  hdr->id = short_be(hdr->id);
  hdr->flags = short_be(hdr->flags);
  hdr->qdcount = short_be(hdr->qdcount);
  hdr->ancount = short_be(hdr->ancount);
  hdr->nscount = short_be(hdr->nscount);
  hdr->arcount = short_be(hdr->arcount);
}
Example #26
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 #27
0
static int pico_dns_client_user_callback(struct pico_dns_answer_suffix *asuffix, struct pico_dns_query *q)
{
    uint32_t ip = 0;
    char *str = NULL;
    char *rdata = (char *) asuffix + sizeof(struct pico_dns_answer_suffix);

    switch (q->qtype)
    {
    case PICO_DNS_TYPE_A:
        ip = long_from(rdata);
        str = PICO_ZALLOC(PICO_DNS_IPV4_ADDR_LEN);
        pico_ipv4_to_string(str, ip);
        break;
#ifdef PICO_SUPPORT_IPV6
    case PICO_DNS_TYPE_AAAA:
    {
        struct pico_ip6 ip6;
        memcpy(&ip6.addr, rdata, sizeof(struct pico_ip6));
        str = PICO_ZALLOC(PICO_DNS_IPV6_ADDR_LEN);
        pico_ipv6_to_string(str, ip6.addr);
        break;
    }
#endif
    case PICO_DNS_TYPE_PTR:
        pico_dns_client_answer_domain(rdata);
        str = PICO_ZALLOC((size_t)(asuffix->rdlength - PICO_DNS_LABEL_INITIAL));
        if (!str) {
            pico_err = PICO_ERR_ENOMEM;
            return -1;
        }

        memcpy(str, rdata + PICO_DNS_LABEL_INITIAL, short_be(asuffix->rdlength) - PICO_DNS_LABEL_INITIAL);
        break;

    default:
        dns_dbg("DNS ERROR: incorrect qtype (%u)\n", q->qtype);
        break;
    }

    if (q->retrans) {
        q->callback(str, q->arg);
        q->retrans = 0;
        PICO_FREE(str);
        pico_dns_client_del_query(q->id);
    }

    return 0;
}
Example #28
0
void tftp_listen_cb(union pico_address *addr, uint16_t port, uint16_t opcode, char *filename, int32_t len)
{
    struct note_t *note;
    struct pico_tftp_session *session;

    printf("TFTP listen callback (BASIC) from remote port %" PRIu16 ".\n", short_be(port));
    if (opcode == PICO_TFTP_RRQ) {
        printf("Received TFTP get request for %s\n", filename);
        note = transfer_prepare(&session, 't', filename, addr, family);
        start_tx(session, filename, port, cb_tftp_tx, note);
    } else if (opcode == PICO_TFTP_WRQ) {
        printf("Received TFTP put request for %s\n", filename);
        note = transfer_prepare(&session, 'r', filename, addr, family);
        start_rx(session, filename, port, cb_tftp_rx, note);
    }
}
Example #29
0
static void pico_dns_client_callback(uint16_t ev, struct pico_socket *s)
{
    struct pico_dns_header *header = NULL;
    char *domain;
    struct pico_dns_query_suffix *qsuffix = NULL;
    struct pico_dns_answer_suffix *asuffix = NULL;
    struct pico_dns_query *q = NULL;
    char *p_asuffix = NULL;
    char msg[PICO_DNS_MAX_RESPONSE_LEN] = {
        0
    };

    if (ev == PICO_SOCK_EV_ERR) {
        dns_dbg("DNS: socket error received\n");
        return;
    }

    if (ev & PICO_SOCK_EV_RD) {
        if (pico_socket_read(s, msg, PICO_DNS_MAX_RESPONSE_LEN) <= 0)
            return;
    }

    header = (struct pico_dns_header *)msg;
    domain = (char *)header + sizeof(struct pico_dns_header);
    qsuffix = (struct pico_dns_query_suffix *)pico_dns_client_seek(domain);
    /* valid asuffix is determined dynamically later on */

    if (pico_dns_client_check_header(header) < 0)
        return;

    q = pico_dns_client_find_query(short_be(header->id));
    if (!q)
        return;

    if (pico_dns_client_check_qsuffix(qsuffix, q) < 0)
        return;

    p_asuffix = (char *)qsuffix + sizeof(struct pico_dns_query_suffix);
    p_asuffix = pico_dns_client_seek_suffix(p_asuffix, header, q);
    if (!p_asuffix)
        return;

    asuffix = (struct pico_dns_answer_suffix *)p_asuffix;
    pico_dns_client_user_callback(asuffix, q);

    return;
}
Example #30
0
void tftp_listen_cb_opt(union pico_address *addr, uint16_t port, uint16_t opcode, char *filename, int32_t len)
{
    struct note_t *note;
    struct pico_tftp_session *session;
    int options;
    uint8_t timeout;
    int32_t filesize;
    int ret;

    printf("TFTP listen callback (OPTIONS) from remote port %" PRIu16 ".\n", short_be(port));
    /* declare the options we want to support */
    ret = pico_tftp_parse_request_args(filename, len, &options, &timeout, &filesize);
    if (ret)
        pico_tftp_reject_request(addr, port, TFTP_ERR_EOPT, "Malformed request");

    if (opcode == PICO_TFTP_RRQ) {
        printf("Received TFTP get request for %s\n", filename);
        note = transfer_prepare(&session, 'T', filename, addr, family);

        if (options & PICO_TFTP_OPTION_TIME)
            pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout);

        if (options & PICO_TFTP_OPTION_FILE) {
            ret = get_filesize(filename);
            if (ret < 0) {
                pico_tftp_reject_request(addr, port, TFTP_ERR_ENOENT, "File not found");
                return;
            }

            pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, ret);
        }

        start_tx(session, filename, port, cb_tftp_tx_opt, note);
    } else { /* opcode == PICO_TFTP_WRQ */
        printf("Received TFTP put request for %s\n", filename);

        note = transfer_prepare(&session, 'R', filename, addr, family);
        if (options & PICO_TFTP_OPTION_TIME)
            pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout);

        if (options & PICO_TFTP_OPTION_FILE)
            pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize);

        start_rx(session, filename, port, cb_tftp_rx_opt, note);
    }
}