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); } }
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); } }