Exemplo n.º 1
0
/**@brief Creates port as requested in p_port.
 *
 * @details Creates port as requested in p_port.
 *
 * @param[in]   index    Index to the m_port_table where entry of the port created is to be made.
 * @param[in]   p_port   Port information to be created.
 *
 * @retval NRF_SUCCESS   Indicates if port was created successfully, else an an  error code
 *                       indicating reason for failure.
 */
static uint32_t port_create(uint32_t index, coap_port_t  * p_port)
{
    err_t           err = NRF_ERROR_NO_MEM;
    ip6_addr_t      any_addr;
    struct udp_pcb * p_socket = m_port_table[index].p_socket;

    ip6_addr_set_any(&any_addr);

    //Request new socket creation.
    p_socket = udp_new();

    if (NULL != p_socket)
    {
        // Bind the socket to the local port.
        err = udp_bind(p_socket, &any_addr, p_port->port_number);
        if (err == ERR_OK)
        {
            //Register data receive callback.
            udp_recv(p_socket, udp_recv_data_handler, &m_port_table[index]);
            //All procedure with respect to port creation succeeded, make entry in the table.
            m_port_table[index].port_number = p_port->port_number;
            m_port_table[index].p_socket    = p_socket;
        }
        else
        {
            //Not all procedures succeeded with allocated socket, hence free it.
            err = NRF_ERROR_INVALID_PARAM;
            udp_remove(p_socket);
        }
    }

    return err;
}
Exemplo n.º 2
0
/**
 * Conversion from InetAddressIPv6 oid to lwIP ip6_addr
 * @param oid points to u32_t oid[16] input
 * @param ip points to output struct
 */
u8_t
snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip)
{
  if ((oid[0]  > 0xFF) ||
      (oid[1]  > 0xFF) ||
      (oid[2]  > 0xFF) ||
      (oid[3]  > 0xFF) ||
      (oid[4]  > 0xFF) ||
      (oid[5]  > 0xFF) ||
      (oid[6]  > 0xFF) ||
      (oid[7]  > 0xFF) ||
      (oid[8]  > 0xFF) ||
      (oid[9]  > 0xFF) ||
      (oid[10] > 0xFF) ||
      (oid[11] > 0xFF) ||
      (oid[12] > 0xFF) ||
      (oid[13] > 0xFF) ||
      (oid[14] > 0xFF) ||
      (oid[15] > 0xFF)) {
    ip6_addr_set_any(ip);
    return 0;
  }

  ip->addr[0] = (oid[0]  << 24) | (oid[1]  << 16) | (oid[2]  << 8) | (oid[3]  << 0);
  ip->addr[1] = (oid[4]  << 24) | (oid[5]  << 16) | (oid[6]  << 8) | (oid[7]  << 0);
  ip->addr[2] = (oid[8]  << 24) | (oid[9]  << 16) | (oid[10] << 8) | (oid[11] << 0);
  ip->addr[3] = (oid[12] << 24) | (oid[13] << 16) | (oid[14] << 8) | (oid[15] << 0);
  return 1;
}
Exemplo n.º 3
0
/**@brief UDP Port Set-Up.
 *
 * @details Sets up UDP Port to listen on.
 */
static void udp_port_setup(void)
{
    ip6_addr_t any_addr;
    ip6_addr_set_any(&any_addr);

    mp_udp_port = udp_new_ip6();

    if (mp_udp_port != NULL)
    {
        err_t err = udp_bind_ip6(mp_udp_port, &any_addr, UDP_CLIENT_PORT);
        APP_ERROR_CHECK(err);

        udp_recv_ip6(mp_udp_port,udp_recv_data_handler, NULL);
    }
    else
    {
        ASSERT(0);
    }
}
Exemplo n.º 4
0
/**
 * This function is called by the network interface device driver when
 * an IPv6 packet is received. The function does the basic checks of the
 * IP header such as packet size being at least larger than the header
 * size etc. If the packet was not destined for us, the packet is
 * forwarded (using ip6_forward).
 *
 * Finally, the packet is sent to the upper layer protocol input function.
 *
 * @param p the received IPv6 packet (p->payload points to IPv6 header)
 * @param inp the netif on which this packet was received
 * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
 *         processed, but currently always returns ERR_OK)
 */
err_t
ip6_input(struct pbuf *p, struct netif *inp)
{
    struct ip6_hdr *ip6hdr;
    struct netif *netif;
    u8_t nexth;
    u16_t hlen; /* the current header length */
    u8_t i;
#if IP_ACCEPT_LINK_LAYER_ADDRESSING
    int check_ip_src=1;
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */

    IP6_STATS_INC(ip6.recv);

    /* identify the IP header */
    ip6hdr = (struct ip6_hdr *)p->payload;
    if (IP6H_V(ip6hdr) != 6) {
        LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U16_F"\n",
                    IP6H_V(ip6hdr)));
        pbuf_free(p);
        IP6_STATS_INC(ip6.err);
        IP6_STATS_INC(ip6.drop);
        return ERR_OK;
    }

    /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
    if ((IP6_HLEN > p->len) || ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len)) {
        if (IP6_HLEN > p->len) {
            LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                        ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
                         IP6_HLEN, p->len));
        }
        if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) {
            LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                        ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
                         IP6H_PLEN(ip6hdr) + IP6_HLEN, p->tot_len));
        }
        /* free (drop) packet pbufs */
        pbuf_free(p);
        IP6_STATS_INC(ip6.lenerr);
        IP6_STATS_INC(ip6.drop);
        return ERR_OK;
    }

    /* Trim pbuf. This should have been done at the netif layer,
     * but we'll do it anyway just to be sure that its done. */
    pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr));

    /* copy IP addresses to aligned ip6_addr_t */
    ip6_addr_copy(ip_data.current_iphdr_dest.ip6, ip6hdr->dest);
    ip6_addr_copy(ip_data.current_iphdr_src.ip6, ip6hdr->src);

    /* current header pointer. */
    ip_data.current_ip6_header = ip6hdr;

    /* match packet against an interface, i.e. is this packet for us? */
    if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
        /* Always joined to multicast if-local and link-local all-nodes group. */
        if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) ||
                ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) {
            netif = inp;
        }
#if LWIP_IPV6_MLD
        else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) {
            netif = inp;
        }
#else /* LWIP_IPV6_MLD */
        else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) {
            /* Accept all solicited node packets when MLD is not enabled
             * (for Neighbor discovery). */
            netif = inp;
        }
#endif /* LWIP_IPV6_MLD */
        else {
            netif = NULL;
        }
    }
    else {
        /* start trying with inp. if that's not acceptable, start walking the
           list of configured netifs.
           'first' is used as a boolean to mark whether we started walking the list */
        int first = 1;
        netif = inp;
        do {
            /* interface is up? */
            if (netif_is_up(netif)) {
                /* unicast to this interface address? address configured? */
                for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
                    if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
                            ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))) {
                        /* exit outer loop */
                        goto netif_found;
                    }
                }
            }
            if (first) {
                first = 0;
                netif = netif_list;
            } else {
                netif = netif->next;
            }
            if (netif == inp) {
                netif = netif->next;
            }
        } while(netif != NULL);
netif_found:
        LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n",
                                netif->name[0], netif->name[1]));
    }

    /* "::" packet source address? (used in duplicate address detection) */
    if (ip6_addr_isany(ip6_current_src_addr()) &&
            (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) {
        /* packet source is not valid */
        /* free (drop) packet pbufs */
        LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n"));
        pbuf_free(p);
        IP6_STATS_INC(ip6.drop);
        goto ip6_input_cleanup;
    }

    /* packet not for us? */
    if (netif == NULL) {
        /* packet not for us, route or discard */
        LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n"));
#if LWIP_IPV6_FORWARD
        /* non-multicast packet? */
        if (!ip6_addr_ismulticast(ip6_current_dest_addr())) {
            /* try to forward IP packet on (other) interfaces */
            ip6_forward(p, ip6hdr, inp);
        }
#endif /* LWIP_IPV6_FORWARD */
        pbuf_free(p);
        goto ip6_input_cleanup;
    }

    /* current netif pointer. */
    ip_data.current_netif = inp;

    /* Save next header type. */
    nexth = IP6H_NEXTH(ip6hdr);

    /* Init header length. */
    hlen = ip_data.current_ip_header_tot_len = IP6_HLEN;

    /* Move to payload. */
    pbuf_header(p, -IP6_HLEN);

    /* Process known option extension headers, if present. */
    while (nexth != IP6_NEXTH_NONE)
    {
        switch (nexth) {
        case IP6_NEXTH_HOPBYHOP:
            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n"));
            /* Get next header type. */
            nexth = *((u8_t *)p->payload);

            /* Get the header length. */
            hlen = 8 * (1 + *((u8_t *)p->payload) + 1);
            ip_data.current_ip_header_tot_len += hlen;

            /* Skip over this header. */
            if (hlen > p->len) {
                LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                            ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
                             hlen, p->len));
                /* free (drop) packet pbufs */
                pbuf_free(p);
                IP6_STATS_INC(ip6.lenerr);
                IP6_STATS_INC(ip6.drop);
                goto ip6_input_cleanup;
            }

            pbuf_header(p, -hlen);
            break;
        case IP6_NEXTH_DESTOPTS:
            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n"));
            /* Get next header type. */
            nexth = *((u8_t *)p->payload);

            /* Get the header length. */
            hlen = 8 * (1 + *((u8_t *)p->payload) + 1);
            ip_data.current_ip_header_tot_len += hlen;

            /* Skip over this header. */
            if (hlen > p->len) {
                LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                            ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
                             hlen, p->len));
                /* free (drop) packet pbufs */
                pbuf_free(p);
                IP6_STATS_INC(ip6.lenerr);
                IP6_STATS_INC(ip6.drop);
                goto ip6_input_cleanup;
            }

            pbuf_header(p, -hlen);
            break;
        case IP6_NEXTH_ROUTING:
            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n"));
            /* Get next header type. */
            nexth = *((u8_t *)p->payload);

            /* Get the header length. */
            hlen = 8 * (1 + *((u8_t *)p->payload) + 1);
            ip_data.current_ip_header_tot_len += hlen;

            /* Skip over this header. */
            if (hlen > p->len) {
                LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                            ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
                             hlen, p->len));
                /* free (drop) packet pbufs */
                pbuf_free(p);
                IP6_STATS_INC(ip6.lenerr);
                IP6_STATS_INC(ip6.drop);
                goto ip6_input_cleanup;
            }

            pbuf_header(p, -hlen);
            break;

        case IP6_NEXTH_FRAGMENT:
        {
            struct ip6_frag_hdr * frag_hdr;
            LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n"));

            frag_hdr = (struct ip6_frag_hdr *)p->payload;

            /* Get next header type. */
            nexth = frag_hdr->_nexth;

            /* Fragment Header length. */
            hlen = 8;
            ip_data.current_ip_header_tot_len += hlen;

            /* Make sure this header fits in current pbuf. */
            if (hlen > p->len) {
                LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                            ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n",
                             hlen, p->len));
                /* free (drop) packet pbufs */
                pbuf_free(p);
                IP6_FRAG_STATS_INC(ip6_frag.lenerr);
                IP6_FRAG_STATS_INC(ip6_frag.drop);
                goto ip6_input_cleanup;
            }

            /* Offset == 0 and more_fragments == 0? */
            if (((frag_hdr->_fragment_offset & IP6_FRAG_OFFSET_MASK) == 0) &&
                    ((frag_hdr->_fragment_offset & IP6_FRAG_MORE_FLAG) == 0)) {

                /* This is a 1-fragment packet, usually a packet that we have
                 * already reassembled. Skip this header anc continue. */
                pbuf_header(p, -hlen);
            }
            else {
#if LWIP_IPV6_REASS

                /* reassemble the packet */
                p = ip6_reass(p);
                /* packet not fully reassembled yet? */
                if (p == NULL) {
                    goto ip6_input_cleanup;
                }

                /* Returned p point to IPv6 header.
                 * Update all our variables and pointers and continue. */
                ip6hdr = (struct ip6_hdr *)p->payload;
                nexth = IP6H_NEXTH(ip6hdr);
                hlen = ip_data.current_ip_header_tot_len = IP6_HLEN;
                pbuf_header(p, -IP6_HLEN);

#else /* LWIP_IPV6_REASS */
                /* free (drop) packet pbufs */
                LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n"));
                pbuf_free(p);
                IP6_STATS_INC(ip6.opterr);
                IP6_STATS_INC(ip6.drop);
                goto ip6_input_cleanup;
#endif /* LWIP_IPV6_REASS */
            }
            break;
        }
        default:
            goto options_done;
            break;
        }
    }
options_done:

    /* p points to IPv6 header again. */
    pbuf_header(p, ip_data.current_ip_header_tot_len);

    /* send to upper layers */
    LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
    ip6_debug_print(p);
    LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));

#if LWIP_RAW
    /* raw input did not eat the packet? */
    if (raw_input(p, inp) == 0)
#endif /* LWIP_RAW */
    {
        switch (nexth) {
        case IP6_NEXTH_NONE:
            pbuf_free(p);
            break;
#if LWIP_UDP
        case IP6_NEXTH_UDP:
#if LWIP_UDPLITE
        case IP6_NEXTH_UDPLITE:
#endif /* LWIP_UDPLITE */
            /* Point to payload. */
            pbuf_header(p, -ip_data.current_ip_header_tot_len);
            udp_input(p, inp);
            break;
#endif /* LWIP_UDP */
#if LWIP_TCP
        case IP6_NEXTH_TCP:
            /* Point to payload. */
            pbuf_header(p, -ip_data.current_ip_header_tot_len);
            tcp_input(p, inp);
            break;
#endif /* LWIP_TCP */
#if LWIP_ICMP6
        case IP6_NEXTH_ICMP6:
            /* Point to payload. */
            pbuf_header(p, -ip_data.current_ip_header_tot_len);
            icmp6_input(p, inp);
            break;
#endif /* LWIP_ICMP */
        default:
#if LWIP_ICMP6
            /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
            if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
                    (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
                icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen);
            }
#endif /* LWIP_ICMP */
            LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", IP6H_NEXTH(ip6hdr)));
            pbuf_free(p);
            IP6_STATS_INC(ip6.proterr);
            IP6_STATS_INC(ip6.drop);
            break;
        }
    }

ip6_input_cleanup:
    ip_data.current_netif = NULL;
    ip_data.current_ip6_header = NULL;
    ip_data.current_ip_header_tot_len = 0;
    ip6_addr_set_any(&ip_data.current_iphdr_src.ip6);
    ip6_addr_set_any(&ip_data.current_iphdr_dest.ip6);

    return ERR_OK;
}