Beispiel #1
0
void udp_packet_handler(void)
{
    msg_t m_recv_ip, m_send_ip, m_recv_udp, m_send_udp;
    ipv6_hdr_t *ipv6_header;
    udp_hdr_t *udp_header;
    socket_internal_t *udp_socket = NULL;
    uint16_t chksum;

    while (1) {
        msg_receive(&m_recv_ip);
        ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr);
        udp_header = ((udp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN));

        chksum = ipv6_csum(ipv6_header, (uint8_t*) udp_header, NTOHS(udp_header->length), IPPROTO_UDP);

        if (chksum == 0xffff) {
            udp_socket = get_udp_socket(udp_header);

            if (udp_socket != NULL) {
                m_send_udp.content.ptr = (char *)ipv6_header;
                msg_send_receive(&m_send_udp, &m_recv_udp, udp_socket->recv_pid);
            }
            else {
                printf("Dropped UDP Message because no thread ID was found for delivery!\n");
            }
        }
        else {
            printf("Wrong checksum (%x)!\n", chksum);
        }

        msg_reply(&m_recv_ip, &m_send_ip);
    }
}
Beispiel #2
0
Datei: ip.c Projekt: A-L-E-X/RIOT
void *ipv6_process(void *arg)
{
    (void) arg;

    msg_t m_recv_lowpan, m_send_lowpan;
    msg_t m_recv, m_send;
    uint8_t i;
    uint16_t packet_length;

    msg_init_queue(ip_msg_queue, IP_PKT_RECV_BUF_SIZE);

    while (1) {
        msg_receive(&m_recv_lowpan);

        ipv6_buf = (ipv6_hdr_t *)m_recv_lowpan.content.ptr;

        /* identifiy packet */
        nextheader = &ipv6_buf->nextheader;

        for (i = 0; i < SIXLOWIP_MAX_REGISTERED; i++) {
            if (sixlowip_reg[i]) {
                msg_t m_send;
                m_send.type = IPV6_PACKET_RECEIVED;
                m_send.content.ptr = (char *) ipv6_buf;
                msg_send(&m_send, sixlowip_reg[i], 1);
            }
        }

        /* destination is our address */
        if (is_our_address(&ipv6_buf->destaddr)) {
            switch (*nextheader) {
                case (IPV6_PROTO_NUM_ICMPV6): {
                    icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);

                    /* checksum test*/
                    if (ipv6_csum(ipv6_buf, (uint8_t *) icmp_buf, NTOHS(ipv6_buf->length),
                                  IPV6_PROTO_NUM_ICMPV6) != 0xffff) {
                        DEBUG("ERROR: wrong checksum\n");
                    }

                    icmpv6_demultiplex(icmp_buf);
                    break;
                }

                case (IPV6_PROTO_NUM_TCP): {
                    if (tcp_packet_handler_pid != KERNEL_PID_UNDEF) {
                        m_send.content.ptr = (char *) ipv6_buf;
                        msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
                    }
                    else {
                        DEBUG("INFO: No TCP handler registered.\n");
                    }

                    break;
                }

                case (IPV6_PROTO_NUM_UDP): {
                    if (udp_packet_handler_pid != KERNEL_PID_UNDEF) {
                        m_send.content.ptr = (char *) ipv6_buf;
                        msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
                    }
                    else {
                        DEBUG("INFO: No UDP handler registered.\n");
                    }

                    break;
                }

                case (IPV6_PROTO_NUM_NONE): {
                    DEBUG("INFO: Packet with no Header following the IPv6 Header received.\n");
                    break;
                }

                default:
                    DEBUG("INFO: Unknown next header\n");
                    break;
            }
        }
        /* destination is foreign address */
        else {
            DEBUG("That's not for me, destination is %s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &ipv6_buf->destaddr));
            packet_length = IPV6_HDR_LEN + NTOHS(ipv6_buf->length);
            ndp_neighbor_cache_t *nce;

            ipv6_addr_t *dest;

            if (ip_get_next_hop == NULL) {
                dest = &ipv6_buf->destaddr;
            }
            else {
                dest = ip_get_next_hop(&ipv6_buf->destaddr);
            }

            if ((dest == NULL) || ((--ipv6_buf->hoplimit) == 0)) {
                DEBUG("!!! Packet not for me, routing handler is set, but I "\
                      " have no idea where to send or the hop limit is exceeded.\n");
                msg_reply(&m_recv_lowpan, &m_send_lowpan);
                continue;
            }

            nce = ndp_get_ll_address(dest);

            /* copy received packet to send buffer */
            memcpy(ipv6_get_buf_send(), ipv6_get_buf(), packet_length);

            /* send packet to node ID derived from dest IP */
            if (nce != NULL) {
                sixlowpan_lowpan_sendto(nce->if_id, &nce->lladdr,
                                        nce->lladdr_len,
                                        (uint8_t *)ipv6_get_buf_send(),
                                        packet_length);
            } else {
                /* XXX: this is wrong, but until ND does work correctly,
                 *      this is the only way (aka the old way)*/
                uint16_t raddr = dest->uint16[7];
                sixlowpan_lowpan_sendto(0, &raddr, 2, (uint8_t *)ipv6_get_buf_send(), packet_length);
            }
        }

        msg_reply(&m_recv_lowpan, &m_send_lowpan);
    }
}