6LoWPAN: Fix a whole in the logic of the previous commit. It turns out that g_uncomp_hdrlen has other usages so it cannot be modified as I was doing. Instead, I needed to add a separate localt variable, protosize, to keep track of the two usages of g_uncomp_hdrlen.
This commit is contained in:
parent
53c0938b53
commit
2dab490cee
@ -151,10 +151,9 @@ static uint8_t g_bitbucket[UNCOMP_MAXHDR];
|
||||
****************************************************************************/
|
||||
|
||||
static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr,
|
||||
FAR uint8_t *bptr, bool proto)
|
||||
FAR uint8_t *bptr)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
|
||||
uint16_t protosize;
|
||||
|
||||
/* Put uncompressed IPv6 header in d_buf. */
|
||||
|
||||
@ -165,54 +164,75 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr,
|
||||
|
||||
g_frame_hdrlen += IPv6_HDRLEN;
|
||||
g_uncomp_hdrlen += IPv6_HDRLEN;
|
||||
}
|
||||
|
||||
/* Does a protocol header follow the IPv6 header? */
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_uncompress_ipv6proto
|
||||
*
|
||||
* Description:
|
||||
* Copy the protocol header following the IPv4 header
|
||||
*
|
||||
* Input Parameters:
|
||||
* fptr - Pointer to the beginning of the frame under construction
|
||||
* bptr - Output goes here. Normally this is a known offset into d_buf,
|
||||
* may be redirected to g_bitbucket on the case of FRAGN frames.
|
||||
* proto - True: Copy the protocol header following the IPv6 header too.
|
||||
*
|
||||
* Returned Value:
|
||||
* The size of the protocol header that was copied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
if (proto)
|
||||
static uint16_t sixlowpan_uncompress_ipv6proto(FAR uint8_t *fptr,
|
||||
FAR uint8_t *bptr)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
|
||||
uint16_t protosize = 0;
|
||||
|
||||
/* Copy the following protocol header. */
|
||||
|
||||
switch (ipv6->proto)
|
||||
{
|
||||
/* Yes.. Copy the following protocol header. */
|
||||
|
||||
switch (ipv6->proto)
|
||||
{
|
||||
#ifdef CONFIG_NET_TCP
|
||||
case IP_PROTO_TCP:
|
||||
{
|
||||
FAR struct tcp_hdr_s *tcp =
|
||||
(FAR struct tcp_hdr_s *)(fptr + g_frame_hdrlen);
|
||||
case IP_PROTO_TCP:
|
||||
{
|
||||
FAR struct tcp_hdr_s *tcp =
|
||||
(FAR struct tcp_hdr_s *)(fptr + g_frame_hdrlen);
|
||||
|
||||
/* The TCP header length is encoded in the top 4 bits of the
|
||||
* tcpoffset field (in units of 32-bit words).
|
||||
*/
|
||||
/* 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;
|
||||
}
|
||||
break;
|
||||
protosize = ((uint16_t)tcp->tcpoffset >> 4) << 2;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
case IP_PROTO_UDP:
|
||||
protosize = sizeof(struct udp_hdr_s);
|
||||
break;
|
||||
case IP_PROTO_UDP:
|
||||
protosize = sizeof(struct udp_hdr_s);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
case IP_PROTO_ICMP6:
|
||||
protosize = sizeof(struct icmpv6_hdr_s);
|
||||
break;
|
||||
case IP_PROTO_ICMP6:
|
||||
protosize = sizeof(struct icmpv6_hdr_s);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
nwarn("WARNING: Unrecognized proto: %u\n", ipv6->proto);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the protocol header. */
|
||||
|
||||
memcpy((FAR uint8_t *)ipv6 + g_uncomp_hdrlen, fptr + g_frame_hdrlen,
|
||||
protosize);
|
||||
|
||||
g_frame_hdrlen += protosize;
|
||||
default:
|
||||
nwarn("WARNING: Unrecognized proto: %u\n", ipv6->proto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy the protocol header. */
|
||||
|
||||
memcpy((FAR uint8_t *)ipv6 + g_uncomp_hdrlen, fptr + g_frame_hdrlen,
|
||||
protosize);
|
||||
|
||||
g_frame_hdrlen += protosize;
|
||||
g_uncomp_hdrlen += protosize;
|
||||
return protosize;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -266,6 +286,7 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
||||
uint16_t paysize; /* Size of the data payload */
|
||||
uint16_t fragtag = 0; /* Tag of the fragment */
|
||||
uint8_t fragoffset = 0; /* Offset of the fragment in the IP packet */
|
||||
uint8_t protosize = 0; /* Length of the protocal header (treated like payload) */
|
||||
bool isfrag = false; /* true: Frame is a fragment */
|
||||
bool isfrag1 = false; /* true: Frame is the first fragement of the series */
|
||||
int reqsize; /* Required buffer size */
|
||||
@ -447,11 +468,19 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
||||
{
|
||||
ninfo("IPv6 Dispatch\n");
|
||||
|
||||
/* NOTE: A protocol header will follow only on a non-fragmented
|
||||
* packet or on the first fragment of a fragmented packet.
|
||||
/* Uncompress the IPv6 header */
|
||||
|
||||
sixlowpan_uncompress_ipv6hdr(fptr, bptr);
|
||||
|
||||
/* A protocol header will follow the IPv6 header only on a non-
|
||||
* fragmented packet or on the first fragment of a fragmented
|
||||
* packet.
|
||||
*/
|
||||
|
||||
sixlowpan_uncompress_ipv6hdr(fptr, bptr, !isfrag || isfrag1);
|
||||
if (!isfrag || isfrag1)
|
||||
{
|
||||
protosize = sixlowpan_uncompress_ipv6proto(fptr, bptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -470,7 +499,7 @@ static int sixlowpan_frame_process(FAR struct radio_driver_s *radio,
|
||||
* begin placing the data payload.
|
||||
*/
|
||||
|
||||
reass->rb_boffset = g_uncomp_hdrlen;
|
||||
reass->rb_boffset = g_uncomp_hdrlen - protosize;
|
||||
}
|
||||
|
||||
/* No.. is this a subsequent fragment in the same sequence? */
|
||||
|
Loading…
Reference in New Issue
Block a user