6loWPAN: Fix last checksum issues. Contiki 6loWPAN port is now complete (but completely untested)

This commit is contained in:
Gregory Nutt
2017-04-02 14:30:01 -06:00
parent 6e2f8f3aa3
commit 392c90b020
5 changed files with 262 additions and 313 deletions
+65 -7
View File
@@ -50,10 +50,73 @@
#include "netdev/netdev.h"
#include "socket/socket.h"
#include "tcp/tcp.h"
#include "utils/utils.h"
#include "sixlowpan/sixlowpan_internal.h"
#if defined(CONFIG_NET_6LOWPAN) && defined(CONFIG_NET_TCP)
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: sixlowpan_tcp_chksum
*
* Description:
* Perform the checksum calcaultion over the IPv6, protocol headers, and
* data payload as necessary.
*
* Input Parameters:
* ipv6tcp - A reference to a structure containing the IPv6 and TCP headers.
* buf - The beginning of the payload data
* buflen - The length of the payload data.
*
* Returned Value:
* The calculated checksum
*
****************************************************************************/
static uint16_t sixlowpan_tcp_chksum(FAR struct ipv6tcp_hdr_s *ipv6tcp,
FAR const uint8_t *buf, uint16_t buflen)
{
uint16_t upperlen;
uint16_t sum;
/* The length reported in the IPv6 header is the length of the payload
* that follows the header.
*/
upperlen = ((uint16_t)ipv6tcp->ipv6.len[0] << 8) + ipv6tcp->ipv6.len[1];
/* Verify some minimal assumptions */
if (upperlen > CONFIG_NET_6LOWPAN_MTU)
{
return 0;
}
/* The checksum is calculated starting with a pseudo-header of IPv6 header
* fields according to the IPv6 standard, which consists of the source
* and destination addresses, the packet length and the next header field.
*/
sum = upperlen + ipv6tcp->ipv6.proto;
/* Sum IP source and destination addresses. */
sum = chksum(sum, (FAR uint8_t *)ipv6tcp->ipv6.srcipaddr,
2 * sizeof(net_ipv6addr_t));
/* Sum the TCP header */
sum = chksum(sum, (FAR uint8_t *)&ipv6tcp->tcp, TCP_HDRLEN);
/* Sum payload data. */
sum = chksum(sum, buf, buflen);
return (sum == 0) ? 0xffff : htons(sum);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -224,19 +287,14 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
/* Calculate TCP checksum. */
ipv6tcp.tcp.tcpchksum = 0;
#if 0
/* REVISIT: Current checksum logic expects the IPv6 header, the UDP header, and
* the payload data to be in contiguous memory.
*/
ipv6tcp.tcp.tcpchksum = ~tcp_ipv6_chksum(dev);
#endif
ipv6tcp.tcp.tcpchksum = ~sixlowpan_tcp_chksum(&ipv6tcp, buf, buflen);
ninfo("Outgoing TCP packet length: %d bytes\n", iplen + IOPv6_HDRLEN);
#ifdef CONFIG_NET_STATISTICS
g_netstats.tcp.sent++;
#endif
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
+66 -11
View File
@@ -51,10 +51,75 @@
#include "netdev/netdev.h"
#include "socket/socket.h"
#include "udp/udp.h"
#include "utils/utils.h"
#include "sixlowpan/sixlowpan_internal.h"
#if defined(CONFIG_NET_6LOWPAN) && defined(CONFIG_NET_UDP)
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: sixlowpan_udp_chksum
*
* Description:
* Perform the checksum calcaultion over the IPv6, protocol headers, and
* data payload as necessary.
*
* Input Parameters:
* ipv6udp - A reference to a structure containing the IPv6 and UDP headers.
* buf - The beginning of the payload data
* buflen - The length of the payload data.
*
* Returned Value:
* The calculated checksum
*
****************************************************************************/
#ifdef CONFIG_NET_UDP_CHECKSUMS
static uint16_t sixlowpan_udp_chksum(FAR struct ipv6udp_hdr_s *ipv6udp,
FAR const uint8_t *buf, uint16_t buflen)
{
uint16_t upperlen;
uint16_t sum;
/* The length reported in the IPv6 header is the length of the payload
* that follows the header.
*/
upperlen = ((uint16_t)ipv6udp->ipv6.len[0] << 8) + ipv6udp->ipv6.len[1];
/* Verify some minimal assumptions */
if (upperlen > CONFIG_NET_6LOWPAN_MTU)
{
return 0;
}
/* The checksum is calculated starting with a pseudo-header of IPv6 header
* fields according to the IPv6 standard, which consists of the source
* and destination addresses, the packet length and the next header field.
*/
sum = upperlen + ipv6udp->ipv6.proto;
/* Sum IP source and destination addresses. */
sum = chksum(sum, (FAR uint8_t *)ipv6udp->ipv6.srcipaddr,
2 * sizeof(net_ipv6addr_t));
/* Sum the UDP header */
sum = chksum(sum, (FAR uint8_t *)&ipv6udp->udp, UDP_HDRLEN);
/* Sum payload data. */
sum = chksum(sum, buf, buflen);
return (sum == 0) ? 0xffff : htons(sum);
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -211,23 +276,13 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
ipv6udp.udp.udplen = htons(iplen);
ipv6udp.udp.udpchksum = 0;
ipv6udp.udp.udpchksum = 0;
#warning Missing logic
#if 0 /* REVISIT */
#ifdef CONFIG_NET_UDP_CHECKSUMS
/* Calculate UDP checksum. */
/* REVISIT: Current checksum logic expects the IPv6 header, the UDP header, and
* the payload data to be in contiguous memory.
*/
ipv6udp.udp.udpchksum = ~udp_ipv6_chksum(dev);
ipv6udp.udp.udpchksum = ~sixlowpan_udp_chksum(ipv6udp, buf, buflen);
if (ipv6udp.udp.udpchksum == 0)
{
ipv6udp.udp.udpchksum = 0xffff;
}
#endif /* CONFIG_NET_UDP_CHECKSUMS */
#endif /* REVISIT */
ninfo("Outgoing UDP packet length: %d\n", iplen + IPv6_HDRLEN);