static void pico_slaacv4_send_probe_timer(pico_time now, void *arg)
{
    struct slaacv4_cookie *tmp = (struct slaacv4_cookie *)arg;
    (void)now;

    if (tmp->probe_try_nb < PROBE_NB)
    {
        pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_PROBE);
        tmp->probe_try_nb++;
        tmp->timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, tmp);
        if (!tmp->timer) {
            slaacv4_dbg("SLAACV4: Failed to start probe timer\n");
            tmp->state = SLAACV4_ERROR;
            if (tmp->cb != NULL)
                tmp->cb(&tmp->ip, PICO_SLAACV4_ERROR);
        }
    }
    else
    {
        tmp->state = SLAACV4_ANNOUNCING;
        tmp->timer = pico_timer_add(ANNOUNCE_WAIT * 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);
        }
    }
}
static void pico_slaacv4_receive_ipconflict(int reason)
{
    struct slaacv4_cookie *tmp = &slaacv4_local;

    tmp->conflict_nb++;
    pico_slaacv4_cancel_timers(tmp);

    if(tmp->state == SLAACV4_CLAIMED)
    {
        if(reason == PICO_ARP_CONFLICT_REASON_CONFLICT)
        {
            pico_ipv4_link_del(tmp->device, tmp->ip);
        }
    }

    if (tmp->conflict_nb < MAX_CONFLICTS)
    {
        tmp->state = SLAACV4_CLAIMING;
        tmp->probe_try_nb = 0;
        tmp->announce_nb = 0;
        tmp->ip.addr = pico_slaacv4_getip(tmp->device, (uint8_t)1);
        pico_arp_register_ipconflict(&tmp->ip, &tmp->device->eth->mac, pico_slaacv4_receive_ipconflict);
        pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_PROBE);
        tmp->probe_try_nb++;
        tmp->timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, tmp);
        if (!tmp->timer) {
            slaacv4_dbg("SLAACV4: Failed to start probe timer\n");
            tmp->state = SLAACV4_ERROR;
            if (tmp->cb != NULL)
                tmp->cb(&tmp->ip, PICO_SLAACV4_ERROR);
        }
    }
    else if (tmp->conflict_nb < MAX_CONFLICTS_FAIL)
    {
        tmp->state = SLAACV4_CLAIMING;
        tmp->probe_try_nb = 0;
        tmp->announce_nb = 0;
        tmp->ip.addr = pico_slaacv4_getip(tmp->device, (uint8_t)1);
        pico_arp_register_ipconflict(&tmp->ip, &tmp->device->eth->mac, pico_slaacv4_receive_ipconflict);
        tmp->timer = pico_timer_add(RATE_LIMIT_INTERVAL * 1000, pico_slaacv4_send_probe_timer, tmp);
        if (!tmp->timer) {
            slaacv4_dbg("SLAACV4: Failed to start probe timer\n");
            tmp->state = SLAACV4_ERROR;
            if (tmp->cb != NULL)
                tmp->cb(&tmp->ip, PICO_SLAACV4_ERROR);
        }
    }
    else
    {
        if (tmp->cb != NULL)
        {
            pico_hotplug_deregister(tmp->device, &pico_slaacv4_hotplug_cb);
            tmp->cb(&tmp->ip, PICO_SLAACV4_ERROR);
        }

        tmp->state = SLAACV4_ERROR;
    }

}
Exemple #3
0
static inline void send_ping(struct pico_icmp4_ping_cookie *cookie)
{
  pico_icmp4_send_echo(cookie);
  cookie->timestamp = pico_tick;
  pico_timer_add((uint32_t)cookie->timeout, ping_timeout, cookie);
  if (cookie->seq < cookie->count)
    pico_timer_add((uint32_t)cookie->interval, next_ping, cookie);
}
static void pico_dns_client_retransmission(unsigned long now, void *arg)
{
  struct pico_dns_key *key = (struct pico_dns_key *)arg;
  struct pico_dns_ns *q_ns = NULL;

  if (!key->retrans) {
    dns_dbg("DNS: no retransmission!\n");
    pico_free(key->q_hdr);

    if(pico_tree_delete(&DNSTable,key))
      pico_free(key);
  }
  else if (key->retrans <= PICO_DNS_CLIENT_MAX_RETRANS) {
    key->retrans++;
    dns_dbg("DNS: retransmission! (%u attempts)\n", key->retrans);
        // ugly hack
    q_ns = pico_tree_next(pico_tree_findNode(&NSTable,&key->q_ns))->keyValue;
    if (q_ns)
      key->q_ns = *q_ns; 
    else
        key->q_ns = *((struct pico_dns_ns *)pico_tree_first(&NSTable));
    pico_dns_client_send(key);
    pico_timer_add(PICO_DNS_CLIENT_RETRANS, pico_dns_client_retransmission, key);
  } else {
    dns_dbg("DNS ERROR: no reply from nameservers! (%u attempts)\n", key->retrans);
    pico_socket_close(key->s);
    pico_err = PICO_ERR_EIO;
    key->callback(NULL, key->arg);
    pico_free(key->q_hdr);
    /* RB_REMOVE returns pointer to removed element, NULL to indicate error */

    if(pico_tree_delete(&DNSTable,key))
      pico_free(key);
  }
}
Exemple #5
0
int cb_tftp_rx(struct pico_tftp_session *session, uint16_t event, uint8_t *block, int32_t len, void *arg)
{
    struct note_t *note = (struct note_t *) arg;
    int ret;

    if (event != PICO_TFTP_EV_OK) {
        fprintf(stderr, "TFTP: Error %" PRIu16 ": %s\n", event, block);
        exit(1);
    }

    if (!note)
        return 0;

    note->filesize += len;
    if (write(note->fd, block, len) < 0) {
        perror("write");
        fprintf(stderr, "Filesystem error writing file %s, cancelling current transfer\n", note->filename);
        pico_tftp_abort(session, TFTP_ERR_EACC, "Error on write");
        del_note(note);
    } else {
        if (len != PICO_TFTP_PAYLOAD_SIZE) {
            printf("TFTP: file %s (%" PRId32 " bytes) RX transfer complete!\n", note->filename, note->filesize);
            close(note->fd);
            del_note(note);
        }
    }

    if (!clipboard)
        pico_timer_add(3000, deferred_exit, NULL);

    return len;
}
Exemple #6
0
int cb_tftp_tx(struct pico_tftp_session *session, uint16_t event, uint8_t *block, int32_t len, void *arg)
{
    struct note_t *note = (struct note_t *) arg;

    if (event != PICO_TFTP_EV_OK) {
        fprintf(stderr, "TFTP: Error %" PRIu16 ": %s\n", event, block);
        exit(1);
    }

    len = read(note->fd, tftp_txbuf, PICO_TFTP_PAYLOAD_SIZE);

    if (len >= 0) {
        note->filesize += len;
        pico_tftp_send(session, tftp_txbuf, len);
        if (len < PICO_TFTP_PAYLOAD_SIZE) {
            printf("TFTP: file %s (%" PRId32 " bytes) TX transfer complete!\n", note->filename, note->filesize);
            close(note->fd);
            del_note(note);
        }
    } else {
        perror("read");
        fprintf(stderr, "Filesystem error reading file %s, cancelling current transfer\n", note->filename);
        pico_tftp_abort(session, TFTP_ERR_EACC, "Error on read");
        del_note(note);
    }

    if (!clipboard)
        pico_timer_add(3000, deferred_exit, NULL);

    return len;
}
Exemple #7
0
int cb_tftp(uint16_t err, uint8_t *block, uint32_t len)
{
    static int fd = -1;
    static int count = 1;

    if (fd == -1) {
        fd = open("/tmp/tftp_recv", O_WRONLY | O_CREAT | O_TRUNC, 0666);
        if (fd < 0) {
            perror("open");
            exit(1);
        }
    }

    if (err != PICO_TFTP_ERR_OK) {
        printf("TFTP: Error %d: %s\n", err, block);
        exit(1);
    }

    if (len > 0)
        write(fd, block, len);

    if (len == PICO_TFTP_SIZE) {
        /* printf("Received block %d, size: %d\n", count++, len); */
    } else {
        printf("Received last block, size:%d. Transfer complete.\n", len);
        close(fd);
        pico_timer_add(2000, deferred_exit, NULL);
    }

    return len;

}
Exemple #8
0
int cb_tftp_tx(uint16_t err, uint8_t *block, uint32_t len)
{
    static int fd = -1;
    static int count = 1;
    (void)block;

    if (fd == -1) {
        fd = open("/dev/urandom", O_RDONLY);
        if (fd < 0) {
            perror("open");
            exit(1);
        }
    }

    if (err != PICO_TFTP_ERR_OK) {
        printf("TFTP: Error %d: %s\n", err, block);
        exit(1);
    }

    if (count++ == TFTP_TX_COUNT) {
        len = 0;
        close(fd);
        pico_timer_add(2000, deferred_exit, NULL);
    } else {
        len = read(fd, tftp_txbuf, PICO_TFTP_SIZE);
    }

    if (len >= 0) {
        pico_tftp_send(tftp_txbuf, len);
    }

    return len;
}
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);
    }
}
Exemple #10
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;
}
Exemple #11
0
static void pico_slaacv4_send_probe_timer(pico_time now, void *arg)
{
    struct slaacv4_cookie *tmp = (struct slaacv4_cookie *)arg;
    (void)now;

    if (tmp->probe_try_nb < PROBE_NB)
    {
        pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_PROBE);
        tmp->probe_try_nb++;
        tmp->timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, tmp);
    }
    else
    {
        tmp->state = SLAACV4_ANNOUNCING;
        tmp->timer = pico_timer_add(ANNOUNCE_WAIT * 1000, pico_slaacv4_send_announce_timer, arg);
    }
}
static void pico_ipv6_frag_timer_on(void)
{
    ipv6_fragments_timer = pico_timer_add(PICO_IPV6_FRAG_TIMEOUT, pico_frag_expire, &ipv6_fragments);
    if (!ipv6_fragments_timer) {
        frag_dbg("FRAG: Failed to start IPv6 expiration timer\n");
        pico_fragments_empty_tree(&ipv6_fragments);
    }
}
Exemple #13
0
void cb_tcpecho(uint16_t ev, struct pico_socket *s)
{
    int r = 0;

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

    if (ev & PICO_SOCK_EV_RD) {
        if (flag & PICO_SOCK_EV_CLOSE)
            printf("SOCKET> EV_RD, FIN RECEIVED\n");

        while (len < BSIZE) {
            r = pico_socket_read(s, recvbuf + len, BSIZE - len);
            if (r > 0) {
                len += r;
                flag &= ~(PICO_SOCK_EV_RD);
            } else {
                flag |= PICO_SOCK_EV_RD;
                break;
            }
        }
        if (flag & PICO_SOCK_EV_WR) {
            flag &= ~PICO_SOCK_EV_WR;
            send_tcpecho(s);
        }
    }

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

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

    if (ev & PICO_SOCK_EV_FIN) {
        printf("Socket closed. Exit normally. \n");
        if (!pico_timer_add(2000, deferred_exit, NULL)) {
            printf("Failed to start exit timer, exiting now\n");
            exit(1);
        }
    }

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

    if (ev & PICO_SOCK_EV_CLOSE) {
        printf("Socket received close from peer.\n");
        if (flag & PICO_SOCK_EV_RD) {
            pico_socket_shutdown(s, PICO_SHUT_WR);
            printf("SOCKET> Called shutdown write, ev = %d\n", ev);
        }
    }

    if (ev & PICO_SOCK_EV_WR) {
        r = send_tcpecho(s);
        if (r == 0)
            flag |= PICO_SOCK_EV_WR;
        else
            flag &= (~PICO_SOCK_EV_WR);
    }
}