2013-08-15 10:17:15 +02:00
|
|
|
/**
|
2013-09-30 13:28:19 +02:00
|
|
|
* Destiny UDP implementation
|
2013-08-15 10:17:15 +02:00
|
|
|
*
|
|
|
|
* Copyright (C) 2013 INRIA.
|
|
|
|
*
|
2013-11-22 20:47:05 +01:00
|
|
|
* This file is subject to the terms and conditions of the GNU Lesser General
|
2013-08-15 10:17:15 +02:00
|
|
|
* Public License. See the file LICENSE in the top level directory for more
|
|
|
|
* details.
|
|
|
|
*
|
2013-09-30 13:28:19 +02:00
|
|
|
* @ingroup destiny
|
2013-08-15 10:17:15 +02:00
|
|
|
* @{
|
|
|
|
* @file udp.c
|
2013-09-30 13:28:19 +02:00
|
|
|
* @brief UDP implementation
|
2013-08-15 10:17:15 +02:00
|
|
|
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2013-08-05 16:10:54 +02:00
|
|
|
#include "ipv6.h"
|
2013-09-30 13:19:19 +02:00
|
|
|
#include "msg.h"
|
2013-08-05 16:10:54 +02:00
|
|
|
#include "sixlowpan.h"
|
2013-09-30 13:19:19 +02:00
|
|
|
#include "thread.h"
|
|
|
|
|
2013-09-20 15:13:18 +02:00
|
|
|
#include "destiny/in.h"
|
2013-09-30 13:19:19 +02:00
|
|
|
|
2013-10-28 16:14:52 +01:00
|
|
|
#include "net_help.h"
|
2013-08-15 10:17:15 +02:00
|
|
|
|
2013-09-30 13:19:19 +02:00
|
|
|
#include "msg_help.h"
|
2013-09-23 12:40:16 +02:00
|
|
|
#include "socket.h"
|
|
|
|
|
2013-09-30 13:19:19 +02:00
|
|
|
#include "udp.h"
|
|
|
|
|
2013-08-15 10:17:15 +02:00
|
|
|
uint16_t udp_csum(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header)
|
|
|
|
{
|
|
|
|
uint16_t sum;
|
2013-11-20 02:20:24 +01:00
|
|
|
uint16_t len = NTOHS(udp_header->length);
|
2013-08-15 10:17:15 +02:00
|
|
|
|
|
|
|
sum = len + IPPROTO_UDP;
|
|
|
|
sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t));
|
|
|
|
sum = csum(sum, (uint8_t *)udp_header, len);
|
|
|
|
return (sum == 0) ? 0xffff : HTONS(sum);
|
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
2013-11-20 23:46:37 +01:00
|
|
|
chksum = ipv6_csum(ipv6_header, (uint8_t*) udp_header, NTOHS(udp_header->length), IPPROTO_UDP);
|
2013-08-15 10:17:15 +02:00
|
|
|
|
|
|
|
if (chksum == 0xffff) {
|
2013-11-21 14:21:38 +01:00
|
|
|
udp_socket = get_udp_socket(udp_header);
|
2013-08-15 10:17:15 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|