6loWPAN: Add calculation of TCP header size. It is not a constant.
This commit is contained in:
parent
e3b4d77ee2
commit
60f0186258
@ -154,29 +154,37 @@ static void sixlowpan_copy_protohdr(FAR const struct ipv6_hdr_s *ipv6hdr,
|
||||
{
|
||||
#ifdef CONFIG_NET_TCP
|
||||
case IP_PROTO_TCP:
|
||||
combined = sizeof(struct ipv6tcp_hdr_s);
|
||||
protosize = sizeof(struct tcp_hdr_s);
|
||||
{
|
||||
FAR struct tcp_hdr_s *tcp = &((FAR struct ipv6tcp_hdr_s *)ipv6hdr)->tcp;
|
||||
|
||||
/* The TCP header length is encoded in the top 4 bits of the
|
||||
* tcpoffset field (in units of 32-bit words).
|
||||
*/
|
||||
|
||||
protosize = ((uint16_t)tcp->tcpoffset >> 4) << 2;
|
||||
combined = sizeof(struct ipv6_hdr_s) + protosize;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
case IP_PROTO_UDP:
|
||||
combined = sizeof(struct ipv6udp_hdr_s);
|
||||
protosize = sizeof(struct udp_hdr_s);
|
||||
combined = sizeof(struct ipv6udp_hdr_s);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
case IP_PROTO_ICMP6:
|
||||
combined = sizeof(struct ipv6icmp_hdr_s);
|
||||
protosize = sizeof(struct icmpv6_hdr_s);
|
||||
combined = sizeof(struct ipv6icmp_hdr_s);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
nwarn("WARNING: Unrecognized proto: %u\n", ipv6hdr->proto);
|
||||
combined = sizeof(struct ipv6_hdr_s);
|
||||
protosize = 0;
|
||||
combined = sizeof(struct ipv6_hdr_s);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,7 @@
|
||||
/* Buffer access helpers */
|
||||
|
||||
#define IPv6BUF(dev) ((FAR struct ipv6_hdr_s *)((dev)->d_buf))
|
||||
#define TCPBUF(dev) ((FAR struct tcp_hdr_s *)&(dev)->d_buf[IPv6_HDRLEN])
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@ -728,7 +729,7 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
||||
* layer protocol header.
|
||||
*/
|
||||
|
||||
ipv6hdr = (FAR struct ipv6_hdr_s *)(ieee->i_dev.d_buf);
|
||||
ipv6hdr = IPv6BUF(&ieee->i_dev);
|
||||
|
||||
/* Get the Rime MAC address of the destination. This
|
||||
* assumes an encoding of the MAC address in the IPv6
|
||||
@ -743,7 +744,15 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
||||
|
||||
if (ipv6hdr->proto != IP_PROTO_TCP)
|
||||
{
|
||||
hdrlen = IPv6_HDRLEN + TCP_HDRLEN;
|
||||
FAR struct tcp_hdr_s *tcp = TCPBUF(&ieee->i_dev);
|
||||
uint16_t tcplen;
|
||||
|
||||
/* The TCP header length is encoded in the top 4 bits
|
||||
* of the tcpoffset field (in units of 32-bit words).
|
||||
*/
|
||||
|
||||
tcplen = ((uint16_t)tcp->tcpoffset >> 4) << 2;
|
||||
hdrlen = IPv6_HDRLEN + tcplen;
|
||||
}
|
||||
else if (ipv6hdr->proto != IP_PROTO_UDP)
|
||||
{
|
||||
|
@ -88,6 +88,7 @@ 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 tcplen;
|
||||
uint16_t sum;
|
||||
|
||||
/* The length reported in the IPv6 header is the length of the payload
|
||||
@ -115,9 +116,14 @@ static uint16_t sixlowpan_tcp_chksum(FAR struct ipv6tcp_hdr_s *ipv6tcp,
|
||||
sum = chksum(sum, (FAR uint8_t *)ipv6tcp->ipv6.srcipaddr,
|
||||
2 * sizeof(net_ipv6addr_t));
|
||||
|
||||
/* Sum the TCP header */
|
||||
/* Sum the TCP header
|
||||
*
|
||||
* The TCP header length is encoded in the top 4 bits of the tcpoffset
|
||||
* field (in units of 32-bit words).
|
||||
*/
|
||||
|
||||
sum = chksum(sum, (FAR uint8_t *)&ipv6tcp->tcp, TCP_HDRLEN);
|
||||
tcplen = ((uint16_t)ipv6tcp->tcp.tcpoffset >> 4) << 2;
|
||||
sum = chksum(sum, (FAR uint8_t *)&ipv6tcp->tcp, tcplen);
|
||||
|
||||
/* Sum payload data. */
|
||||
|
||||
@ -383,43 +389,62 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
|
||||
|
||||
if (dev != NULL && dev->d_len > 0)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6hdr;
|
||||
FAR struct ipv6tcp_hdr_s *ipv6hdr;
|
||||
|
||||
/* The IPv6 header followed by a TCP headers should lie at the
|
||||
* beginning of d_buf since there is no link layer protocol header
|
||||
* and the TCP state machine should only response with TCP packets.
|
||||
*/
|
||||
|
||||
ipv6hdr = (FAR struct ipv6_hdr_s *)(dev->d_buf);
|
||||
ipv6hdr = (FAR struct ipv6tcp_hdr_s *)(dev->d_buf);
|
||||
|
||||
/* The TCP data payload should follow the IPv6 header plus the
|
||||
* protocol header.
|
||||
*/
|
||||
|
||||
if (ipv6hdr->proto != IP_PROTO_TCP)
|
||||
if (ipv6hdr->ipv6.proto != IP_PROTO_TCP)
|
||||
{
|
||||
nwarn("WARNING: Expected TCP protoype: %u\n", ipv6hdr->proto);
|
||||
nwarn("WARNING: Expected TCP protoype: %u vs %s\n",
|
||||
ipv6hdr->ipv6.proto, IP_PROTO_TCP);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct rimeaddr_s destmac;
|
||||
FAR uint8_t *buf;
|
||||
size_t buflen;
|
||||
uint16_t hdrlen;
|
||||
uint16_t buflen;
|
||||
|
||||
/* Get the Rime MAC address of the destination. This assumes an
|
||||
* encoding of the MAC address in the IPv6 address.
|
||||
*/
|
||||
|
||||
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
|
||||
sixlowpan_rimefromip(ipv6hdr->ipv6.destipaddr, &destmac);
|
||||
|
||||
/* Convert the outgoing packet into a frame list. */
|
||||
/* Get the IPv6 + TCP combined header length. The size of the TCP
|
||||
* header is encoded in the top 4 bits of the tcpoffset field (in
|
||||
* units of 32-bit words).
|
||||
*/
|
||||
|
||||
buf = dev->d_buf + sizeof(struct ipv6_hdr_s);
|
||||
buflen = dev->d_len - sizeof(struct ipv6_hdr_s);
|
||||
hdrlen = IPv6_HDRLEN + (((uint16_t)ipv6hdr->tcp.tcpoffset >> 4) << 2);
|
||||
|
||||
(void)sixlowpan_queue_frames(
|
||||
(FAR struct ieee802154_driver_s *)dev, ipv6hdr,
|
||||
buf, buflen, &destmac);
|
||||
/* Drop the packet if the buffer length is less than this. */
|
||||
|
||||
if (hdrlen > dev->d_len)
|
||||
{
|
||||
nwarn("WARNING: Dropping small TCP packet: %u < %u\n",
|
||||
buflen, hdrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert the outgoing packet into a frame list. */
|
||||
|
||||
buf = dev->d_buf + hdrlen;
|
||||
buflen = dev->d_len - hdrlen;
|
||||
|
||||
(void)sixlowpan_queue_frames(
|
||||
(FAR struct ieee802154_driver_s *)dev, &ipv6hdr->ipv6,
|
||||
buf, buflen, &destmac);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user