示例#1
0
void gnrc_netif_ipv6_addr_remove_internal(gnrc_netif_t *netif,
                                          const ipv6_addr_t *addr)
{
    bool remove_sol_nodes = true;
    ipv6_addr_t sol_nodes;

    assert((netif != NULL) && (addr != NULL));
    ipv6_addr_set_solicited_nodes(&sol_nodes, addr);
    gnrc_netif_acquire(netif);
    for (unsigned i = 0; i < GNRC_NETIF_IPV6_ADDRS_NUMOF; i++) {
        if (ipv6_addr_equal(&netif->ipv6.addrs[i], addr)) {
            netif->ipv6.addrs_flags[i] = 0;
            ipv6_addr_set_unspecified(&netif->ipv6.addrs[i]);
        }
        else {
            ipv6_addr_t tmp;

            ipv6_addr_set_solicited_nodes(&tmp, &netif->ipv6.addrs[i]);
            /* there is still an address on the interface with the same
             * solicited nodes address */
            if (ipv6_addr_equal(&tmp, &sol_nodes)) {
                remove_sol_nodes = false;
            }
        }
    }
    if (remove_sol_nodes) {
        gnrc_netif_ipv6_group_leave_internal(netif, &sol_nodes);
    }
    gnrc_netif_release(netif);
}
示例#2
0
static void _remove_addr_from_entry(gnrc_ipv6_netif_t *entry, ipv6_addr_t *addr)
{
    mutex_lock(&entry->mutex);

    for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
        if (ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
            DEBUG("ipv6 netif: Remove %s to interface %" PRIkernel_pid "\n",
                  ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), entry->pid);
            ipv6_addr_set_unspecified(&(entry->addrs[i].addr));
            entry->addrs[i].flags = 0;
#ifdef MODULE_GNRC_NDP_ROUTER
            /* Removal of prefixes MAY allow the router to retransmit up to
             * GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF unsolicited RA
             * (see https://tools.ietf.org/html/rfc4861#section-6.2.4) */
            if ((entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) &&
                (entry->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV) &&
                (!ipv6_addr_is_multicast(addr) &&
                 !ipv6_addr_is_link_local(addr))) {
                entry->rtr_adv_count = GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF;
                mutex_unlock(&entry->mutex);    /* function below relocks the mutex */
                gnrc_ndp_router_retrans_rtr_adv(entry);
                return;
            }
#endif

            mutex_unlock(&entry->mutex);
            return;
        }
    }

    mutex_unlock(&entry->mutex);
}
示例#3
0
void gnrc_ipv6_nc_remove(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr)
{
    gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get(iface, ipv6_addr);

    if (entry != NULL) {
        DEBUG("ipv6_nc: Remove %s for interface %" PRIkernel_pid "\n",
              ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)),
              iface);

#ifdef MODULE_GNRC_NDP_NODE
        while (entry->pkts != NULL) {
            gnrc_pktbuf_release(entry->pkts->pkt);
            entry->pkts->pkt = NULL;
            gnrc_pktqueue_remove_head(&entry->pkts);
        }
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
        xtimer_remove(&entry->type_timeout);
#endif
#if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER)
        xtimer_remove(&entry->rtr_adv_timer);
#endif

        ipv6_addr_set_unspecified(&(entry->ipv6_addr));
        entry->iface = KERNEL_PID_UNDEF;
        entry->flags = 0;
    }
}
示例#4
0
void gnrc_netif_ipv6_group_leave_internal(gnrc_netif_t *netif,
                                          const ipv6_addr_t *addr)
{
    int idx;

    assert((netif != NULL) && (addr != NULL));
    gnrc_netif_acquire(netif);
    idx = _group_idx(netif, addr);
    if (idx >= 0) {
        ipv6_addr_set_unspecified(&netif->ipv6.groups[idx]);
        /* TODO:
         *  - MLD action */
    }
    gnrc_netif_release(netif);
}
示例#5
0
文件: gnrc_conn.c 项目: herrfz/RIOT
bool gnrc_conn6_set_local_addr(uint8_t *conn_addr, const ipv6_addr_t *addr)
{
    ipv6_addr_t *tmp;
    if (!ipv6_addr_is_unspecified(addr) &&
        !ipv6_addr_is_loopback(addr) &&
        gnrc_ipv6_netif_find_by_addr(&tmp, addr) == KERNEL_PID_UNDEF) {
        return false;
    }
    else if (ipv6_addr_is_loopback(addr) || ipv6_addr_is_unspecified(addr)) {
        ipv6_addr_set_unspecified((ipv6_addr_t *)conn_addr);
    }
    else {
        memcpy(conn_addr, addr, sizeof(ipv6_addr_t));
    }
    return true;
}
示例#6
0
static void _remove_addr_from_entry(gnrc_ipv6_netif_t *entry, ipv6_addr_t *addr)
{
    mutex_lock(&entry->mutex);

    for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
        if (ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
            DEBUG("ipv6 netif: Remove %s to interface %" PRIkernel_pid "\n",
                  ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), entry->pid);
            ipv6_addr_set_unspecified(&(entry->addrs[i].addr));
            entry->addrs[i].flags = 0;

            mutex_unlock(&entry->mutex);
            return;
        }
    }

    mutex_unlock(&entry->mutex);
}
示例#7
0
void gnrc_sixlowpan_nd_router_abr_remove(gnrc_sixlowpan_nd_router_abr_t *abr)
{
    for (int i = 0; i < GNRC_SIXLOWPAN_CTX_SIZE; i++) {
        if (bf_isset(abr->ctxs, i)) {
            gnrc_sixlowpan_ctx_remove(i);
            bf_unset(abr->ctxs, i);
        }
    }

    while (abr->prfs != NULL) {
        gnrc_sixlowpan_nd_router_prf_t *prefix = abr->prfs;
        LL_DELETE(abr->prfs, prefix);
        gnrc_ipv6_netif_remove_addr(prefix->iface->pid, &prefix->prefix->addr);
        prefix->next = NULL;
        prefix->iface = NULL;
        prefix->prefix = NULL;
    }
    ipv6_addr_set_unspecified(&abr->addr);
    abr->version = 0;
}
示例#8
0
static void _nc_remove(kernel_pid_t iface, gnrc_ipv6_nc_t *entry)
{
    (void) iface;
    if (entry == NULL) {
        return;
    }

    DEBUG("ipv6_nc: Remove %s for interface %" PRIkernel_pid "\n",
          ipv6_addr_to_str(addr_str, &(entry->ipv6_addr), sizeof(addr_str)),
          iface);

#ifdef MODULE_GNRC_NDP_NODE
    while (entry->pkts != NULL) {
        gnrc_pktbuf_release(entry->pkts->pkt);
        entry->pkts->pkt = NULL;
        gnrc_pktqueue_remove_head(&entry->pkts);
    }
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
    xtimer_remove(&entry->type_timeout);

    gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface);

    if ((if_entry != NULL) && (if_entry->rtr_adv_msg.content.ptr == (char *) entry)) {
        /* cancel timer set by gnrc_ndp_rtr_sol_handle */
        xtimer_remove(&if_entry->rtr_adv_timer);
    }
#endif
#if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER)
    xtimer_remove(&entry->rtr_adv_timer);
#endif

    xtimer_remove(&entry->rtr_timeout);
    xtimer_remove(&entry->nbr_sol_timer);
    xtimer_remove(&entry->nbr_adv_timer);

    ipv6_addr_set_unspecified(&(entry->ipv6_addr));
    entry->iface = KERNEL_PID_UNDEF;
    entry->flags = 0;
}
示例#9
0
static int _implicit_bind(socket_t *s, void *addr)
{
    ipv6_addr_t unspec;
    ipv6_addr_t *best_match;
    int res;

    /* TODO: ensure that this port hasn't been used yet */
    s->src_port = (uint16_t)genrand_uint32_range(1LU << 10U, 1LU << 16U);

    /* find the best matching source address */
    if ((best_match = conn_find_best_source(addr)) == NULL) {
        ipv6_addr_set_unspecified(&unspec);
        best_match = &unspec;
    }
    switch (s->type) {
#ifdef MODULE_CONN_TCP
        case SOCK_STREAM:
            res = conn_tcp_create(&s->conn.udp, best_match, sizeof(unspec),
                                  s->domain, s->src_port);
            break;
#endif
#ifdef MODULE_CONN_UDP
        case SOCK_DGRAM:
            res = conn_udp_create(&s->conn.udp, best_match, sizeof(unspec),
                                  s->domain, s->src_port);
            break;
#endif
        default:
            res = -1;
            break;
    }
    if (res < 0) {
        errno = -res;
    }
    else {
        s->bound = true;
    }
    return res;
}
示例#10
0
gnrc_sixlowpan_ctx_t *gnrc_sixlowpan_ctx_update(uint8_t id, const ipv6_addr_t *prefix,
                                                uint8_t prefix_len, uint16_t ltime,
                                                bool comp)
{
    if ((id >= GNRC_SIXLOWPAN_CTX_SIZE) || (prefix_len == 0)) {
        return NULL;
    }

    mutex_lock(&_ctx_mutex);

    _ctxs[id].ltime = ltime;

    if (ltime == 0) {
        comp = false;
    }

    if (prefix_len > IPV6_ADDR_BIT_LEN) {
        _ctxs[id].prefix_len = IPV6_ADDR_BIT_LEN;
    }
    else {
        _ctxs[id].prefix_len = prefix_len;
    }

    _ctxs[id].flags_id = (comp) ? (GNRC_SIXLOWPAN_CTX_FLAGS_COMP | id) : id;

    if (!ipv6_addr_equal(&(_ctxs[id].prefix), prefix)) {
        ipv6_addr_set_unspecified(&(_ctxs[id].prefix));
        ipv6_addr_init_prefix(&(_ctxs[id].prefix), prefix, _ctxs[id].prefix_len);
    }
    DEBUG("6lo ctx: update context (%u, %s/%" PRIu8 "), lifetime: %" PRIu16 " min\n",
          id, ipv6_addr_to_str(ipv6str, &_ctxs[id].prefix, sizeof(ipv6str)),
          _ctxs[id].prefix_len, _ctxs[id].ltime);
    _ctx_inval_times[id] = ltime + _current_minute();

    mutex_unlock(&_ctx_mutex);
    return &(_ctxs[id]);
}
示例#11
0
/**
 * @brief Transition from current FSM state into another state.
 *
 * @param[in,out] tcb     TCB holding the FSM state.
 * @param[in]     state   State to transition in.
 *
 * @return   Zero on success.
 */
static int _transition_to(gnrc_tcp_tcb_t *tcb, fsm_state_t state)
{
    DEBUG("_transition_to: %d\n", state);

    gnrc_tcp_tcb_t *iter = NULL;

    switch (state) {
        case FSM_STATE_CLOSED:
            /* Clear retransmit queue */
            _clear_retransmit(tcb);

            /* Remove connection from active connections */
            mutex_lock(&_list_tcb_lock);
            LL_DELETE(_list_tcb_head, tcb);
            mutex_unlock(&_list_tcb_lock);

            /* Free potencially allocated receive buffer */
            _rcvbuf_release_buffer(tcb);
            tcb->status |= STATUS_NOTIFY_USER;
            break;

        case FSM_STATE_LISTEN:
            /* Clear address info */
#ifdef MODULE_GNRC_IPV6
            if (tcb->address_family == AF_INET6) {
                if (tcb->status & STATUS_ALLOW_ANY_ADDR) {
                    ipv6_addr_set_unspecified((ipv6_addr_t *) tcb->local_addr);
                }
                ipv6_addr_set_unspecified((ipv6_addr_t *) tcb->peer_addr);
            }
#endif
            tcb->peer_port = PORT_UNSPEC;

            /* Allocate receive buffer */
            if (_rcvbuf_get_buffer(tcb) == -ENOMEM) {
                return -ENOMEM;
            }

            /* Add connection to active connections (if not already active) */
            mutex_lock(&_list_tcb_lock);
            LL_SEARCH(_list_tcb_head, iter, tcb, TCB_EQUAL);
            if (iter == NULL) {
                LL_PREPEND(_list_tcb_head, tcb);
            }
            mutex_unlock(&_list_tcb_lock);
            break;

        case FSM_STATE_SYN_SENT:
            /* Allocate rceveive buffer */
            if (_rcvbuf_get_buffer(tcb) == -ENOMEM) {
                return -ENOMEM;
            }

            /* Add connection to active connections (if not already active) */
            mutex_lock(&_list_tcb_lock);
            LL_SEARCH(_list_tcb_head, iter, tcb, TCB_EQUAL);
            /* If connection is not already active: Check port number, append TCB */
            if (iter == NULL) {
                /* Check if port number was specified */
                if (tcb->local_port != PORT_UNSPEC) {
                    /* Check if given port number is use: return error and release buffer */
                    if (_is_local_port_in_use(tcb->local_port)) {
                        mutex_unlock(&_list_tcb_lock);
                        _rcvbuf_release_buffer(tcb);
                        return -EADDRINUSE;
                    }
                }
                /* Pick random port */
                else {
                    tcb->local_port = _get_random_local_port();
                }
                LL_PREPEND(_list_tcb_head, tcb);
            }
            mutex_unlock(&_list_tcb_lock);
            break;

        case FSM_STATE_SYN_RCVD:
        case FSM_STATE_ESTABLISHED:
        case FSM_STATE_CLOSE_WAIT:
            tcb->status |= STATUS_NOTIFY_USER;
            break;

        case FSM_STATE_TIME_WAIT:
            _restart_timewait_timer(tcb);
            break;

        default:
            break;
    }
    tcb->state = state;
    return 0;
}