Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
RIOT
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
cm-projects
RIOT
Commits
0a9793c4
You need to sign in or sign up before continuing.
Commit
0a9793c4
authored
7 years ago
by
Martine Lenders
Browse files
Options
Downloads
Patches
Plain Diff
gnrc_sixlowpan_iphc: cleanup NHC encoding
parent
2f480efb
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c
+115
-53
115 additions, 53 deletions
...t/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c
with
115 additions
and
53 deletions
sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c
+
115
−
53
View file @
0a9793c4
...
@@ -572,82 +572,124 @@ void gnrc_sixlowpan_iphc_recv(gnrc_pktsnip_t *sixlo, void *rbuf_ptr,
...
@@ -572,82 +572,124 @@ void gnrc_sixlowpan_iphc_recv(gnrc_pktsnip_t *sixlo, void *rbuf_ptr,
}
}
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
static
inline
size_t
iphc_nhc_udp_encode
(
gnrc_pktsnip_t
*
udp
,
ipv6_hdr_t
*
ipv6_hdr
)
static
inline
size_t
iphc_nhc_udp_encode
(
uint8_t
*
nhc_data
,
const
gnrc_pktsnip_t
*
udp
)
{
{
udp_hdr_t
*
udp_hdr
=
udp
->
data
;
const
udp_hdr_t
*
udp_hdr
=
udp
->
data
;
network_
uint16_t
*
src_port
=
&
(
udp_hdr
->
src_port
);
uint16_t
src_port
=
byteorder_ntohs
(
udp_hdr
->
src_port
);
network_
uint16_t
*
dst_port
=
&
(
udp_hdr
->
dst_port
);
uint16_t
dst_port
=
byteorder_ntohs
(
udp_hdr
->
dst_port
);
uint8_t
*
udp_data
=
udp
->
data
;
size_t
nhc_len
=
1
;
/* skip over NHC header */
size_t
nhc_len
=
0
;
/* Set UDP NHC header type
/
*
TODO: Add support for elided checksum
. */
*
(see https://tools.ietf.org/html/rfc6282#section-4.3)
. */
nhc_data
[
0
]
=
NHC_UDP_ID
;
/* Compressing UDP ports, follow the same sequence as the linux kernel (nhc_udp module). */
/* Compressing UDP ports, follow the same sequence as the linux kernel (nhc_udp module). */
if
(((
byteorder_ntohs
(
*
src_port
)
&
NHC_UDP_4BIT_MASK
)
==
NHC_UDP_4BIT_PORT
)
&&
if
(((
src_port
&
NHC_UDP_4BIT_MASK
)
==
NHC_UDP_4BIT_PORT
)
&&
((
byteorder_ntohs
(
*
dst_port
)
&
NHC_UDP_4BIT_MASK
)
==
NHC_UDP_4BIT_PORT
))
{
((
dst_port
&
NHC_UDP_4BIT_MASK
)
==
NHC_UDP_4BIT_PORT
))
{
DEBUG
(
"6lo iphc nhc: elide src and dst
\n
"
);
DEBUG
(
"6lo iphc nhc: elide src and dst
\n
"
);
ipv6_hdr
->
nh
=
NHC_UDP_SD_ELIDED
;
nhc_data
[
0
]
|=
NHC_UDP_SD_ELIDED
;
udp_data
[
nhc_len
++
]
=
byteorder_ntohs
(
*
dst_port
)
-
NHC_UDP_4BIT_PORT
+
nhc_data
[
nhc_len
++
]
=
dst_port
-
NHC_UDP_4BIT_PORT
+
((
byteorder_ntohs
(
*
src_port
)
-
NHC_UDP_4BIT_PORT
)
<<
4
);
((
src_port
-
NHC_UDP_4BIT_PORT
)
<<
4
);
udp_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
0
];
udp_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
1
];
}
}
else
if
((
byteorder_ntohs
(
*
dst_port
)
&
NHC_UDP_8BIT_MASK
)
==
NHC_UDP_8BIT_PORT
)
{
else
if
((
dst_port
&
NHC_UDP_8BIT_MASK
)
==
NHC_UDP_8BIT_PORT
)
{
DEBUG
(
"6lo iphc nhc: elide dst
\n
"
);
DEBUG
(
"6lo iphc nhc: elide dst
\n
"
);
ipv6_hdr
->
nh
=
NHC_UDP_S_INLINE
;
nhc_data
[
0
]
|=
NHC_UDP_S_INLINE
;
nhc_len
+=
2
;
/* keep src_port */
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
src_port
.
u8
[
0
];
udp_data
[
nhc_len
++
]
=
byteorder_ntohs
(
*
dst_port
)
-
NHC_UDP_8BIT_PORT
;
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
src_port
.
u8
[
1
];
udp_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
0
];
nhc_data
[
nhc_len
++
]
=
dst_port
-
NHC_UDP_8BIT_PORT
;
udp_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
1
];
}
}
else
if
((
byteorder_ntohs
(
*
src_port
)
&
NHC_UDP_8BIT_MASK
)
==
NHC_UDP_8BIT_PORT
)
{
else
if
((
src_port
&
NHC_UDP_8BIT_MASK
)
==
NHC_UDP_8BIT_PORT
)
{
DEBUG
(
"6lo iphc nhc: elide src
\n
"
);
DEBUG
(
"6lo iphc nhc: elide src
\n
"
);
ipv6_hdr
->
nh
=
NHC_UDP_D_INLINE
;
nhc_data
[
0
]
|=
NHC_UDP_D_INLINE
;
udp_data
[
nhc_len
++
]
=
byteorder_ntohs
(
*
src_port
)
-
NHC_UDP_8BIT_PORT
;
nhc_data
[
nhc_len
++
]
=
src_port
-
NHC_UDP_8BIT_PORT
;
udp_data
[
nhc_len
++
]
=
udp_hdr
->
dst_port
.
u8
[
0
];
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
dst_port
.
u8
[
0
];
udp_data
[
nhc_len
++
]
=
udp_hdr
->
dst_port
.
u8
[
1
];
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
dst_port
.
u8
[
1
];
udp_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
0
];
udp_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
1
];
}
}
else
{
else
{
DEBUG
(
"6lo iphc nhc: src and dst inline
\n
"
);
DEBUG
(
"6lo iphc nhc: src and dst inline
\n
"
);
ipv6_hdr
->
nh
=
NHC_UDP_SD_INLINE
;
nhc_data
[
0
]
|=
NHC_UDP_SD_INLINE
;
nhc_len
=
sizeof
(
udp_hdr_t
)
-
4
;
/* skip src + dst and elide length */
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
src_port
.
u8
[
0
];
udp_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
0
];
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
src_port
.
u8
[
1
];
udp_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
1
];
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
dst_port
.
u8
[
0
];
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
dst_port
.
u8
[
1
];
}
}
/* Set UDP header ID (rfc6282#section-5). */
/* TODO: Add support for elided checksum. */
ipv6_hdr
->
nh
|=
NHC_UDP_ID
;
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
0
];
nhc_data
[
nhc_len
++
]
=
udp_hdr
->
checksum
.
u8
[
1
];
/* In case payload is in this snip (e.g. a forwarded packet):
* move data to right place */
size_t
diff
=
sizeof
(
udp_hdr_t
)
-
nhc_len
;
for
(
size_t
i
=
nhc_len
;
i
<
(
udp
->
size
-
diff
);
i
++
)
{
udp_data
[
i
]
=
udp_data
[
i
+
diff
];
}
/* NOTE: gnrc_pktbuf_realloc_data overflow if (udp->size - diff) < 4 */
gnrc_pktbuf_realloc_data
(
udp
,
(
udp
->
size
-
diff
));
return
nhc_len
;
return
nhc_len
;
}
}
#endif
#endif
static
inline
bool
_compressible
(
gnrc_pktsnip_t
*
hdr
)
{
switch
(
hdr
->
type
)
{
case
GNRC_NETTYPE_UNDEF
:
/* when forwarded */
case
GNRC_NETTYPE_IPV6
:
#if defined(MODULE_GNRC_SIXLOWPAN_IPHC_NHC) && defined(MODULE_GNRC_UDP)
case
GNRC_NETTYPE_UDP
:
return
true
;
#endif
default:
return
false
;
}
}
void
gnrc_sixlowpan_iphc_send
(
gnrc_pktsnip_t
*
pkt
,
void
*
ctx
,
unsigned
page
)
void
gnrc_sixlowpan_iphc_send
(
gnrc_pktsnip_t
*
pkt
,
void
*
ctx
,
unsigned
page
)
{
{
assert
(
pkt
!=
NULL
);
assert
(
pkt
!=
NULL
);
gnrc_netif_hdr_t
*
netif_hdr
=
pkt
->
data
;
gnrc_netif_hdr_t
*
netif_hdr
=
pkt
->
data
;
ipv6_hdr_t
*
ipv6_hdr
=
pkt
->
next
->
data
;
ipv6_hdr_t
*
ipv6_hdr
;
uint8_t
*
iphc_hdr
;
uint8_t
*
iphc_hdr
;
gnrc_sixlowpan_ctx_t
*
src_ctx
=
NULL
,
*
dst_ctx
=
NULL
;
gnrc_sixlowpan_ctx_t
*
src_ctx
=
NULL
,
*
dst_ctx
=
NULL
;
gnrc_pktsnip_t
*
dispatch
=
gnrc_pktbuf_add
(
NULL
,
NULL
,
pkt
->
next
->
size
,
gnrc_pktsnip_t
*
dispatch
,
*
ptr
=
pkt
->
next
;
GNRC_NETTYPE_SIXLOWPAN
)
;
bool
addr_comp
=
false
;
bool
addr_comp
=
false
,
nhc_comp
=
false
;
size_t
dispatch_size
=
0
;
/* datagram size before compression */
/* datagram size before compression */
size_t
orig_datagram_size
=
gnrc_pkt_len
(
pkt
->
next
);
size_t
orig_datagram_size
=
gnrc_pkt_len
(
pkt
->
next
);
uint16_t
inline_pos
=
SIXLOWPAN_IPHC_HDR_LEN
;
uint16_t
inline_pos
=
SIXLOWPAN_IPHC_HDR_LEN
;
(
void
)
ctx
;
(
void
)
ctx
;
dispatch
=
NULL
;
/* use dispatch as temporary pointer for prev */
/* determine maximum dispatch size and write protect all headers until
* then because they will be removed */
while
(
_compressible
(
ptr
))
{
gnrc_pktsnip_t
*
tmp
=
gnrc_pktbuf_start_write
(
ptr
);
if
(
tmp
==
NULL
)
{
DEBUG
(
"6lo iphc: unable to write protect compressible header
\n
"
);
if
(
addr_comp
)
{
/* addr_comp was used as release indicator */
gnrc_pktbuf_release
(
pkt
);
}
return
;
}
ptr
=
tmp
;
if
(
dispatch
==
NULL
)
{
/* pkt was already write protected in gnrc_sixlowpan.c:_send so
* we shouldn't do it again */
pkt
->
next
=
ptr
;
/* reset original packet */
}
else
{
dispatch
->
next
=
ptr
;
}
if
(
ptr
->
type
==
GNRC_NETTYPE_UNDEF
)
{
/* most likely UDP for now so use that (XXX: extend if extension
* headers make problems) */
dispatch_size
+=
sizeof
(
udp_hdr_t
);
break
;
/* nothing special after UDP so quit even if more UNDEF
* come */
}
else
{
dispatch_size
+=
ptr
->
size
;
}
dispatch
=
ptr
;
/* use dispatch as temporary point for prev */
ptr
=
ptr
->
next
;
}
ipv6_hdr
=
pkt
->
next
->
data
;
dispatch
=
gnrc_pktbuf_add
(
NULL
,
NULL
,
dispatch_size
,
GNRC_NETTYPE_SIXLOWPAN
);
if
(
dispatch
==
NULL
)
{
if
(
dispatch
==
NULL
)
{
DEBUG
(
"6lo iphc: error allocating dispatch space
\n
"
);
DEBUG
(
"6lo iphc: error allocating dispatch space
\n
"
);
gnrc_pktbuf_release
(
pkt
);
gnrc_pktbuf_release
(
pkt
);
...
@@ -724,13 +766,11 @@ void gnrc_sixlowpan_iphc_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
...
@@ -724,13 +766,11 @@ void gnrc_sixlowpan_iphc_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
iphc_hdr
[
inline_pos
++
]
=
(
uint8_t
)((
ipv6_hdr_get_fl
(
ipv6_hdr
)
&
0x000000ff
)
>>
8
);
iphc_hdr
[
inline_pos
++
]
=
(
uint8_t
)((
ipv6_hdr_get_fl
(
ipv6_hdr
)
&
0x000000ff
)
>>
8
);
}
}
/* compress next header */
/*
check for
compress
ible
next header */
switch
(
ipv6_hdr
->
nh
)
{
switch
(
ipv6_hdr
->
nh
)
{
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
case
PROTNUM_UDP
:
case
PROTNUM_UDP
:
iphc_nhc_udp_encode
(
pkt
->
next
->
next
,
ipv6_hdr
);
iphc_hdr
[
IPHC1_IDX
]
|=
SIXLOWPAN_IPHC1_NH
;
iphc_hdr
[
IPHC1_IDX
]
|=
SIXLOWPAN_IPHC1_NH
;
nhc_comp
=
true
;
break
;
break
;
#endif
#endif
...
@@ -934,9 +974,31 @@ void gnrc_sixlowpan_iphc_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
...
@@ -934,9 +974,31 @@ void gnrc_sixlowpan_iphc_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
inline_pos
+=
16
;
inline_pos
+=
16
;
}
}
if
(
nhc_comp
)
{
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
iphc_hdr
[
inline_pos
++
]
=
ipv6_hdr
->
nh
;
switch
(
ipv6_hdr
->
nh
)
{
case
PROTNUM_UDP
:
{
gnrc_pktsnip_t
*
udp
=
pkt
->
next
->
next
;
assert
(
udp
->
size
>=
sizeof
(
udp_hdr_t
));
inline_pos
+=
iphc_nhc_udp_encode
(
&
iphc_hdr
[
inline_pos
],
udp
);
/* remove UDP header */
if
(
udp
->
size
>
sizeof
(
udp_hdr_t
))
{
udp
=
gnrc_pktbuf_mark
(
udp
,
sizeof
(
udp_hdr_t
),
GNRC_NETTYPE_UNDEF
);
if
(
udp
==
NULL
)
{
DEBUG
(
"gnrc_sixlowpan_iphc_encode: unable to mark UDP header
\n
"
);
gnrc_pktbuf_release
(
dispatch
);
return
;
}
}
gnrc_pktbuf_remove_snip
(
pkt
,
udp
);
break
;
}
default:
break
;
}
}
#endif
/* shrink dispatch allocation to final size */
/* shrink dispatch allocation to final size */
/* NOTE: Since this only shrinks the data nothing bad SHOULD happen ;-) */
/* NOTE: Since this only shrinks the data nothing bad SHOULD happen ;-) */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment