예제 #1
0
파일: ipv6.c 프로젝트: kiibohd/controller
uint32_t ipv6_send(const iot_interface_t * p_interface, iot_pbuffer_t * p_packet)
{
    VERIFY_MODULE_IS_INITIALIZED();

    NULL_PARAM_CHECK(p_packet);
    NULL_PARAM_CHECK(p_interface);

    uint32_t err_code;

    IPV6_MUTEX_LOCK();

    IPV6_ENTRY();

    err_code = ble_6lowpan_interface_send(p_interface,
                                          p_packet->p_payload,
                                          p_packet->length);

    if (err_code != NRF_SUCCESS)
    {
        IPV6_ERR("Cannot send packet!");
    }

    // Free pbuffer, without freeing memory.
    UNUSED_VARIABLE(iot_pbuffer_free(p_packet, false));

    IPV6_EXIT();

    IPV6_MUTEX_UNLOCK();

    return err_code;
}
예제 #2
0
int
connect(int sock, const void * p_addr, socklen_t addrlen)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);
    NULL_PARAM_CHECK(p_addr);

    SOCKET_MUTEX_LOCK();
    socket_entry_t * p_socket_entry = &m_socket_table[sock];
    SOCKET_MUTEX_UNLOCK();

    int ret = -1;
    if (p_socket_entry->state == STATE_OPEN)
    {
        uint32_t err_code = p_socket_entry->handler->connect_handler(&p_socket_entry->handle,
                                                                     p_addr,
                                                                     addrlen);
        if (err_code == NRF_SUCCESS)
        {
            p_socket_entry->state = STATE_CONNECTED;
            ret = 0;
        }
        socket_set_errno(err_code);
    }
    else if (p_socket_entry->state == STATE_CONNECTED)
    {
        set_errno(EISCONN);
    }
    else if (p_socket_entry->state == STATE_CLOSED)
    {
        set_errno(EBADF);
    }
    return ret;
}
예제 #3
0
uint32_t iot_context_manager_get_by_cid(const iot_interface_t * p_interface,
                                        uint8_t           context_id,
                                        iot_context_t  ** pp_context)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(p_interface);
    NULL_PARAM_CHECK(pp_context);
    VERIFY_CID_VALUE(context_id);

    uint32_t err_code;

    CM_ENTRY();

    CM_MUTEX_LOCK();

    const uint32_t table_id = context_table_find(p_interface);

    if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
    {
        err_code = context_find_by_cid(table_id, context_id, pp_context);
    }
    else
    {
        // No free context table found.
        CM_TRC("No context table found.");
        err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
    }

    CM_MUTEX_UNLOCK();

    CM_EXIT();

    return err_code;
}
예제 #4
0
ssize_t recv(int sock, void * p_buf, size_t buf_size, int flags)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);
    NULL_PARAM_CHECK(p_buf);

    SOCKET_MUTEX_LOCK();
    socket_entry_t * p_socket_entry = &m_socket_table[sock];
    SOCKET_MUTEX_UNLOCK();

    ssize_t ret = -1;
    if (p_socket_entry->state == STATE_CONNECTED)
    {
        uint32_t recv_size = 0;
        uint32_t err_code = socket_recv(&p_socket_entry->handle,
                                        p_buf,
                                        buf_size,
                                        &recv_size,
                                        flags);
        if (err_code == NRF_SUCCESS)
        {
            ret = (ssize_t) recv_size;
        }
        socket_set_errno(err_code);
    }
    else
    {
        set_errno(ENOTCONN);
    }
    return ret;
}
예제 #5
0
uint32_t iot_context_manager_get_by_addr(const iot_interface_t * p_interface, 
                                         const ipv6_addr_t     * p_addr, 
                                         iot_context_t        ** pp_context)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(p_interface);
    NULL_PARAM_CHECK(p_addr);
    NULL_PARAM_CHECK(pp_context);
    
    uint32_t err_code;

    CM_TRC("[CONTEXT_MANAGER]: >> iot_context_manager_get_by_addr\r\n");

    CM_MUTEX_LOCK();

    const uint32_t table_id = context_table_find(p_interface);

    if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
    {
        err_code = context_find_by_prefix(table_id, p_addr, pp_context);
    }
    else
    {
        // No free context table found.
        CM_TRC("[CONTEXT_MANAGER]: No context table found.\r\n");
        err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
    }

    CM_MUTEX_UNLOCK();

    CM_TRC("[CONTEXT_MANAGER]: << iot_context_manager_get_by_addr\r\n");

    return err_code;
}
예제 #6
0
uint32_t iot_context_manager_table_alloc(const iot_interface_t * p_interface)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(p_interface);

    uint32_t err_code = NRF_SUCCESS;

    CM_ENTRY();

    CM_MUTEX_LOCK();

    const uint32_t table_id = context_table_find(NULL);

    if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
    {
        // Found a free context table and assign to it.
        CM_TRC("Assigned new context table.");
        m_context_table[table_id].p_interface = (iot_interface_t *)p_interface;
    }
    else
    {
        // No free context table found.
        CM_ERR("No context table found.");
        err_code = (NRF_ERROR_NO_MEM | IOT_CONTEXT_MANAGER_ERR_BASE);
    }

    CM_MUTEX_UNLOCK();

    CM_EXIT();

    return err_code;
}
예제 #7
0
uint32_t iot_context_manager_table_free(const iot_interface_t * p_interface)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(p_interface);

    uint32_t err_code = NRF_SUCCESS;

    CM_ENTRY();

    SDK_MUTEX_INIT(m_iot_context_manager_mutex);

    CM_MUTEX_LOCK();

    const uint32_t table_id = context_table_find(p_interface);

    if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
    {
        // Clear context table.
        CM_TRC("Found context table assigned to interface.");
        context_table_init(table_id);
    }
    else
    {
        // No free context table found.
        CM_ERR("No context table found.");
        err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
    }

    CM_MUTEX_UNLOCK();

    CM_EXIT();

    return err_code;
}
예제 #8
0
파일: ipv6.c 프로젝트: kiibohd/controller
uint32_t ipv6_address_find_best_match(iot_interface_t   ** pp_interface,
                                      ipv6_addr_t       *  p_addr_r,
                                      const ipv6_addr_t *  p_addr_f)
{
    VERIFY_MODULE_IS_INITIALIZED();

    NULL_PARAM_CHECK(p_addr_f);
    NULL_PARAM_CHECK(pp_interface);

    uint32_t      index;
    uint32_t      err_code;
    uint32_t      addr_index;
    uint32_t      match_temp  = 0;
    uint32_t      match_best  = 0;
    ipv6_addr_t * p_best_addr = NULL;

    IPV6_MUTEX_LOCK();

    err_code = interface_find(pp_interface, p_addr_f);

    if (err_code == NRF_SUCCESS && p_addr_r)
    {
        uint32_t interface_id = (uint32_t)(*pp_interface)->p_upper_stack;

        for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++)
        {
            addr_index = m_interfaces[interface_id].addr_range[index];

            if (addr_index != IPV6_INVALID_ADDR_INDEX)
            {
                if (m_address_table[addr_index].state == IPV6_ADDR_STATE_PREFERRED)
                {
                    match_temp = addr_bit_equal(p_addr_f, &m_address_table[addr_index].addr);

                    if (match_temp >= match_best)
                    {
                        match_best  = match_temp;
                        p_best_addr = &m_address_table[addr_index].addr;
                    }
                }
            }
        }

        // No address found.
        if (p_best_addr == NULL)
        {
            // Set undefined :: address.
            IPV6_ADDRESS_INITIALIZE(p_addr_r);
        }
        else
        {
            memcpy(p_addr_r->u8, p_best_addr->u8, IPV6_ADDR_SIZE);
        }
    }

    IPV6_MUTEX_UNLOCK();

    return err_code;
}
예제 #9
0
int listen(int sock, int backlog)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);

    (void) sock;
    (void) backlog;

    return -1;
}
예제 #10
0
int accept(int sock, void * p_cliaddr, socklen_t * p_addrlen)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);
    NULL_PARAM_CHECK(p_cliaddr);

    (void) sock;
    (void) p_cliaddr;
    (void) p_addrlen;

    return -1;
}
예제 #11
0
int bind(int sock, const void * p_myaddr, socklen_t addrlen)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);
    NULL_PARAM_CHECK(p_myaddr);

    (void) sock;
    (void) p_myaddr;
    (void) addrlen;

    return -1;
}
예제 #12
0
int getsockopt(int sock, socket_opt_lvl_t level, int optname, void *optval, socklen_t *optlen)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);

    (void) sock;
    (void) level;
    (void) optname;
    (void) optval;
    (void) optlen;

    return -1;
}
예제 #13
0
int
socket(socket_family_t family, socket_type_t type, socket_protocol_t protocol)
{
    if (m_initialization_state == false)
    {
        (void) socket_init();
    }
    VERIFY_MODULE_IS_INITIALIZED();

    int ret_sock = -1;
    int sock = socket_allocate();
    SOCKET_TRACE("Got value %d from allocate\r\n", (int)sock);
    if (sock >= 0)
    {
        socket_entry_t *p_socket_entry = &m_socket_table[sock];
        p_socket_entry->handle.params.family = family;
        p_socket_entry->handle.params.protocol = protocol;
        p_socket_entry->handle.params.type = type;
        p_socket_entry->handler = NULL;

        if (family == AF_INET6)
        {
#if SOCKET_IPV6_ENABLE == 1 || SOCKET_LWIP_ENABLE == 1
            p_socket_entry->handler = &transport_handler;
#else
            set_errno(EAFNOSUPPORT);
#endif
        // } else if (family == AF_BLE) {
            // TODO: Handle BLE
        }
        else
        {
            set_errno(EAFNOSUPPORT);
        }

        if (p_socket_entry->handler != NULL)
        {
            uint32_t err_code = p_socket_entry->handler->create_handler(&p_socket_entry->handle);
            socket_set_errno(err_code);
            ret_sock = (err_code == NRF_SUCCESS) ? sock : ret_sock;
        }

        if (ret_sock < 0)
        {
            socket_free(sock);
        }
    }
    SOCKET_TRACE("Returning socket value %d\r\n", (int)ret_sock);
    return ret_sock;
}
예제 #14
0
int
close(int sock)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);

    SOCKET_MUTEX_LOCK();
    socket_entry_t * p_socket_entry = &m_socket_table[sock];
    SOCKET_MUTEX_UNLOCK();

    uint32_t err_code = p_socket_entry->handler->close_handler(&p_socket_entry->handle);
    int ret = (err_code == NRF_SUCCESS) ? 0 : -1;
    SOCKET_TRACE("Close socket %d: ret: %d\r\n", (int)sock, ret);
    socket_free(sock);
    return ret;
}
예제 #15
0
파일: ipv6.c 프로젝트: kiibohd/controller
uint32_t ipv6_address_remove(const iot_interface_t * p_interface,
                             const ipv6_addr_t     * p_addr)
{
    VERIFY_MODULE_IS_INITIALIZED();

    NULL_PARAM_CHECK(p_addr);
    NULL_PARAM_CHECK(p_interface);

    uint32_t    index;
    uint32_t    err_code;
    uint32_t    addr_index;

    IPV6_MUTEX_LOCK();

    IPV6_ENTRY();

    uint32_t interface_id = (uint32_t)p_interface->p_upper_stack;

    err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NOT_FOUND);

    for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++)
    {
        addr_index = m_interfaces[interface_id].addr_range[index];

        if (addr_index != IPV6_INVALID_ADDR_INDEX)
        {
            if (0 == IPV6_ADDRESS_CMP(&m_address_table[addr_index].addr, p_addr))
            {
                m_interfaces[interface_id].addr_range[index] = IPV6_INVALID_ADDR_INDEX;

                // Remove address if no reference to interface found.
                addr_free(index, true);

                err_code = NRF_SUCCESS;

                break;
            }
        }
    }

    IPV6_EXIT();

    IPV6_MUTEX_UNLOCK();

    return err_code;
}
예제 #16
0
int
fcntl(int fd, int cmd, int flags)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(fd);

    if (cmd != F_SETFL)
    {
        set_errno(EINVAL);
        return -1;
    }
    SOCKET_MUTEX_LOCK();
    socket_entry_t * p_socket_entry = &m_socket_table[fd];
    SOCKET_MUTEX_UNLOCK();

    p_socket_entry->handle.flags = flags;
    return 0;
}
예제 #17
0
파일: icmp6.c 프로젝트: sische/MasterThesis
uint32_t icmp6_receive_register(icmp6_receive_callback_t cb)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(cb);
    UNUSED_VARIABLE(m_event_handler);

    ICMP6_MUTEX_LOCK();

    ICMP6_TRC("[ICMP6]: >> icmp6_receive_register\r\n");

    // Store application event handler.
    m_event_handler = cb;

    ICMP6_TRC("[ICMP6]: << icmp6_receive_register\r\n");

    ICMP6_MUTEX_UNLOCK();

    return NRF_SUCCESS;
}
예제 #18
0
파일: ipv6.c 프로젝트: kiibohd/controller
uint32_t ipv6_address_set(const iot_interface_t  * p_interface,
                          const ipv6_addr_conf_t * p_addr)
{
    VERIFY_MODULE_IS_INITIALIZED();

    NULL_PARAM_CHECK(p_addr);
    NULL_PARAM_CHECK(p_interface);

    uint32_t err_code;

    IPV6_MUTEX_LOCK();

    IPV6_ENTRY();

    err_code = addr_set(p_interface, p_addr);

    IPV6_EXIT();

    IPV6_MUTEX_UNLOCK();

    return err_code;
}
예제 #19
0
uint32_t iot_context_manager_remove(const iot_interface_t * p_interface,
                                    iot_context_t         * p_context)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(p_interface);
    NULL_PARAM_CHECK(p_context);

    uint32_t err_code  = NRF_SUCCESS;

    CM_ENTRY();

    CM_MUTEX_LOCK();

    const uint32_t table_id = context_table_find(p_interface);

    if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
    {
        if (p_context->context_id != IPV6_CONTEXT_IDENTIFIER_NONE)
        {
            m_context_table[table_id].context_count--;
        }

        // Reinit context entry.
        context_init(p_context);
    }
    else
    {
        // No free context table found.
        CM_ERR("No context table found.");
        err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
    }

    CM_MUTEX_UNLOCK();

    CM_EXIT();

    return err_code;
}
예제 #20
0
파일: ipv6.c 프로젝트: kiibohd/controller
uint32_t ipv6_address_check(const iot_interface_t * p_interface,
                            const ipv6_addr_t     * p_addr)
{
    VERIFY_MODULE_IS_INITIALIZED();

    NULL_PARAM_CHECK(p_addr);
    NULL_PARAM_CHECK(p_interface);

    uint32_t err_code;

    IPV6_MUTEX_LOCK();

    IPV6_ENTRY();

    uint32_t interface_id = (uint32_t)p_interface->p_upper_stack;

    err_code = addr_check(interface_id, p_addr, false);

    IPV6_EXIT();

    IPV6_MUTEX_UNLOCK();

    return err_code;
}
예제 #21
0
uint32_t iot_context_manager_update(const iot_interface_t * p_interface,
                                    iot_context_t         * p_context)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(p_context);
    VERIFY_CID_VALUE(p_context->context_id);
    VERIFY_PREFIX_LEN_VALUE(p_context->prefix_len);

    uint32_t        retval   = NRF_SUCCESS;
    uint32_t        err_code = NRF_SUCCESS;
    iot_context_t * p_internal_context;

    CM_ENTRY();

    CM_MUTEX_LOCK();

    const uint32_t table_id = context_table_find(p_interface);

    if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
    {
          // Try to find context in context table.
          retval = context_find_by_cid(table_id, p_context->context_id, &p_internal_context);

          if (retval != NRF_SUCCESS)
          {
              err_code = context_find_free(table_id, &p_internal_context);

              // Increase context count.
              if (err_code == NRF_SUCCESS)
              {
                  m_context_table[table_id].context_count++;
              }
          }

          if (err_code == NRF_SUCCESS)
          {
               // Update context table, with parameters from application.
               p_internal_context->context_id       = p_context->context_id;
               p_internal_context->prefix_len       = p_context->prefix_len;
               p_internal_context->compression_flag = p_context->compression_flag;
               memset(p_internal_context->prefix.u8, 0, IPV6_ADDR_SIZE);
               IPV6_ADDRESS_PREFIX_SET(p_internal_context->prefix.u8, p_context->prefix.u8, p_context->prefix_len);
           }
           else
           {
               CM_ERR("No place in context table.");
           }
    }
    else
    {
        // No free context table found.
        CM_ERR("No context table found.");
        err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
    }

    CM_MUTEX_UNLOCK();

    CM_EXIT();

    return err_code;
}
예제 #22
0
파일: icmp6.c 프로젝트: sische/MasterThesis
uint32_t icmp6_ns_send(const iot_interface_t  * p_interface,
                       const ipv6_addr_t      * p_src_addr,
                       const ipv6_addr_t      * p_dest_addr,
                       const icmp6_ns_param_t * p_param)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(p_interface);
    NULL_PARAM_CHECK(p_src_addr);
    NULL_PARAM_CHECK(p_dest_addr);
    NULL_PARAM_CHECK(p_param);

    uint32_t                    err_code = NRF_SUCCESS;
    uint16_t                    aro_size = 0;
    uint16_t                    checksum;
    iot_pbuffer_t             * p_pbuffer;
    iot_pbuffer_alloc_param_t   pbuff_param;

    // IPv6 Headers.
    ipv6_header_t             * p_ip_header;
    icmp6_header_t            * p_icmp_header;
    icmp6_ns_header_t         * p_ns_header;
    nd_option_sllao_t         * p_sllao_opt;
    nd_option_aro_t           * p_aro_opt;

    ICMP6_MUTEX_LOCK();

    ICMP6_TRC("[ICMP6]: >> icmp6_ndisc_ns_send\r\n");

    if(p_param->add_aro)
    {
        aro_size = ND_OPT_ARO_SIZE;
    }

    // Requesting buffer for NS message
    pbuff_param.flags  = PBUFFER_FLAG_DEFAULT;
    pbuff_param.type   = ICMP6_PACKET_TYPE;
    pbuff_param.length = ND_NS_HEADER_SIZE + ND_OPT_SLLAO_SIZE + aro_size;

    err_code = iot_pbuffer_allocate(&pbuff_param, &p_pbuffer);

    if(err_code == NRF_SUCCESS)
    {
        p_ip_header   = (ipv6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE -
                                          IPV6_IP_HEADER_SIZE);
        p_icmp_header = (icmp6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE);
        p_ns_header   = (icmp6_ns_header_t *)(p_pbuffer->p_payload);
        p_sllao_opt   = (nd_option_sllao_t *)(p_pbuffer->p_payload + ND_NS_HEADER_SIZE);
        p_aro_opt     = (nd_option_aro_t *)(p_pbuffer->p_payload + ND_NS_HEADER_SIZE +
                                            ND_OPT_SLLAO_SIZE);

        // Change ICMP header.
        p_icmp_header->type     = ICMP6_TYPE_NEIGHBOR_SOLICITATION;
        p_icmp_header->code     = 0;
        p_icmp_header->checksum = 0;

        // IPv6 Header initialization.
        icmp_ip_header(p_ip_header, ND_HOP_LIMIT);

        p_ip_header->srcaddr  = *p_src_addr;
        p_ip_header->destaddr = *p_dest_addr;
        p_ip_header->length   = HTONS(p_pbuffer->length + ICMP6_HEADER_SIZE);

        // Set Neighbour Solicitation parameter.
        p_ns_header->reserved    = 0;
        p_ns_header->target_addr = p_param->target_addr;

        // Add SLLAO option.
        add_sllao_opt(p_interface, p_sllao_opt);

        if(p_param->add_aro)
        {
            add_aro_opt(p_interface, p_aro_opt, p_param->aro_lifetime);
        }

        // Calculate checksum.
        checksum = p_pbuffer->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6;

        ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
        ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
        ipv6_checksum_calculate(p_pbuffer->p_payload - ICMP6_HEADER_SIZE,
                                p_pbuffer->length + ICMP6_HEADER_SIZE,
                                &checksum,
                                false);

        p_icmp_header->checksum = HTONS((~checksum));

        p_pbuffer->p_payload -= ICMP6_OFFSET;
        p_pbuffer->length    += ICMP6_OFFSET;

        // Send IPv6 packet.
        err_code = ipv6_send(p_interface, p_pbuffer);
    }
    else
    {
        ICMP6_ERR("[ICMP6]: Failed to allocate packet buffer!\r\n");
    }

    ICMP6_TRC("[ICMP6]: << icmp6_ndisc_ns_send\r\n");

    ICMP6_MUTEX_UNLOCK();

    return err_code;
}
예제 #23
0
파일: icmp6.c 프로젝트: sische/MasterThesis
uint32_t icmp6_input(iot_interface_t  * p_interface,
                     ipv6_header_t    * p_ip_header,
                     iot_pbuffer_t    * p_packet)
{
    VERIFY_MODULE_IS_INITIALIZED();

    NULL_PARAM_CHECK(p_interface);
    NULL_PARAM_CHECK(p_ip_header);
    NULL_PARAM_CHECK(p_packet);

    uint16_t              checksum;
    uint32_t              process_result = NRF_SUCCESS;
    bool                  is_ndisc       = false;
    icmp6_header_t      * p_icmp_header  = (icmp6_header_t *)p_packet->p_payload;
    icmp6_echo_header_t * p_echo_header  = NULL;
    uint32_t              err_code       = NRF_SUCCESS;

    SDK_MUTEX_LOCK();
      
    ICMP6_TRC("[ICMP6]: >> icmp6_input\r\n");
    
    if(p_packet->length < ICMP6_HEADER_SIZE || p_ip_header->length < ICMP6_HEADER_SIZE)
    {
        ICMP6_ERR("[ICMP6]: Received malformed packet, which has 0x%08lX bytes.\r\n",
                  p_packet->length);
        process_result = ICMP6_MALFORMED_PACKET;
    }
    else
    {
        // Check checksum of packet.
        checksum = p_packet->length + IPV6_NEXT_HEADER_ICMP6;

        ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
        ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
        ipv6_checksum_calculate(p_packet->p_payload, p_packet->length, &checksum, false);
        checksum = (uint16_t)~checksum;

        // Change pbuffer type.
        p_packet->type       = ICMP6_PACKET_TYPE;
        p_packet->p_payload  = p_packet->p_payload + ICMP6_HEADER_SIZE;
        p_packet->length    -= ICMP6_HEADER_SIZE;

        if (checksum != 0)
        {
            ICMP6_ERR("[ICMP6]: Bad checksum detected. Got 0x%08x but expected 0x%08x, 0x%08lX\r\n",
                      NTOHS(p_icmp_header->checksum), checksum, p_packet->length);
            process_result = ICMP6_BAD_CHECKSUM;
        }
        else
        {
            switch(p_icmp_header->type)
            {
                case ICMP6_TYPE_DESTINATION_UNREACHABLE:
                case ICMP6_TYPE_PACKET_TOO_LONG:
                case ICMP6_TYPE_TIME_EXCEED:
                case ICMP6_TYPE_PARAMETER_PROBLEM:
                    ICMP6_TRC("[ICMP6]: Got ICMPv6 error message with type = 0x%08x\r\n",
                              p_icmp_header->type);
                    break;
                case ICMP6_TYPE_ECHO_REQUEST:
                case ICMP6_TYPE_ECHO_REPLY:
                {
                    p_echo_header = (icmp6_echo_header_t *)p_packet->p_payload;

                    ICMP6_TRC("[ICMP6]: Got ICMPv6 Echo message with type = %x.\r\n",
                              p_icmp_header->type);
                    ICMP6_TRC("[ICMP6]: From:");
                    ICMP6_DUMP(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE);
                    ICMP6_TRC("[ICMP6]: Identifier: 0x%04x, Sequence Number: 0x%04x\r\n",
                              NTOHS(p_echo_header->identifier),
                              NTOHS(p_echo_header->sequence_number));
                    break;
                }
                case ICMP6_TYPE_ROUTER_SOLICITATION:
                case ICMP6_TYPE_ROUTER_ADVERTISEMENT:
                case ICMP6_TYPE_NEIGHBOR_SOLICITATION:
                case ICMP6_TYPE_NEIGHBOR_ADVERTISEMENT:
                    process_result = ndisc_input(p_interface,
                                                 p_ip_header,
                                                 p_icmp_header,
                                                 p_packet);
                    is_ndisc = true;
                    break;
                default:
                    process_result = ICMP6_UNHANDLED_PACKET_TYPE;
                    break;
            }
        }
    }

#if (ICMP6_ENABLE_ALL_MESSAGES_TO_APPLICATION == 1)

    err_code = app_notify_icmp_data(p_interface, p_packet, process_result);

#elif (ICMP6_ENABLE_ND6_MESSAGES_TO_APPLICATION == 1)

    if(is_ndisc)
    {
        err_code = app_notify_icmp_data(p_interface, p_packet, process_result);
    }

#endif

#if (ICMP6_ENABLE_HANDLE_ECHO_REQUEST_TO_APPLICATION == 0)
    if(p_icmp_header->type == ICMP6_TYPE_ECHO_REQUEST)
    {
        echo_reply_send(p_interface, p_ip_header, p_icmp_header, p_packet);
    }
#endif

    ICMP6_TRC("[ICMP6]: << icmp6_input\r\n");

    UNUSED_VARIABLE(is_ndisc);
    UNUSED_VARIABLE(p_echo_header);
    UNUSED_VARIABLE(process_result);

    SDK_MUTEX_UNLOCK();

    return err_code;
}
예제 #24
0
파일: icmp6.c 프로젝트: sische/MasterThesis
uint32_t icmp6_echo_request(const iot_interface_t  * p_interface,
                            const ipv6_addr_t      * p_src_addr,
                            const ipv6_addr_t      * p_dest_addr,
                            iot_pbuffer_t          * p_request)
{
    VERIFY_MODULE_IS_INITIALIZED();
    NULL_PARAM_CHECK(p_interface);
    NULL_PARAM_CHECK(p_src_addr);
    NULL_PARAM_CHECK(p_dest_addr);
    NULL_PARAM_CHECK(p_request);
    PACKET_TYPE_CHECK(p_request);

    uint32_t              err_code = NRF_SUCCESS;
    uint16_t              checksum;
    ipv6_header_t       * p_ip_header;
    icmp6_header_t      * p_icmp_header;
    icmp6_echo_header_t * p_echo_header;

    ICMP6_MUTEX_LOCK();

    ICMP6_TRC("[ICMP6]: >> icmp6_echo_request\r\n");

    // Headers of IPv6 packet.
    p_ip_header   = (ipv6_header_t *)(p_request->p_payload - ICMP6_HEADER_SIZE -
                                      IPV6_IP_HEADER_SIZE);
    p_icmp_header = (icmp6_header_t *)(p_request->p_payload - ICMP6_HEADER_SIZE);
    p_echo_header = (icmp6_echo_header_t *)(p_request->p_payload);

    // Change ICMP header.
    p_icmp_header->type     = ICMP6_TYPE_ECHO_REQUEST;
    p_icmp_header->code     = 0;
    p_icmp_header->checksum = 0;

    // IPv6 Header initialization.
    icmp_ip_header(p_ip_header, IPV6_DEFAULT_HOP_LIMIT);

    p_ip_header->srcaddr  = *p_src_addr;
    p_ip_header->destaddr = *p_dest_addr;
    p_ip_header->length   = HTONS(p_request->length + ICMP6_HEADER_SIZE);

    // Set echo reply parameters.
    p_echo_header->identifier      = 0;
    p_echo_header->sequence_number = HTONS(m_sequence_number);

    // Calculate checksum.
    checksum = p_request->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6;

    ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
    ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
    ipv6_checksum_calculate(p_request->p_payload - ICMP6_HEADER_SIZE,
                            p_request->length + ICMP6_HEADER_SIZE,
                            &checksum,
                            false);

    p_icmp_header->checksum = HTONS((~checksum));

    m_sequence_number++;
    p_request->p_payload -= ICMP6_OFFSET;
    p_request->length    += ICMP6_OFFSET;

    // Send IPv6 packet.
    err_code = ipv6_send(p_interface, p_request);

    ICMP6_TRC("[ICMP6]: << icmp6_echo_request\r\n");

    ICMP6_MUTEX_UNLOCK();

    return err_code;
}