aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovico Cavedon <ludovico.cavedon@gmail.com>2018-01-09 10:26:10 -0800
committerLudovico Cavedon <ludovico.cavedon@gmail.com>2018-01-09 10:26:10 -0800
commit35dc6e27ae11a92553611a9d3d8c1ed963a894d4 (patch)
tree619e67fc56ea614d1121767992488711a6bf1cbf
parent61e297b851af570109e72a93a65b1ac5ccfda0b4 (diff)
Fix MPLS header parsing in ndpiReader.
Reported at https://bugs.debian.org/886133. The current parsing for the MPLS header in examples/ndpi_util.c has multiple issues: - the bitfield order is incorrect for little endian architectures - ntohl() is applied to a 20 bit label, which has unclear purpose - if multiple labels are detected, the while loop parsing labels will never exit due to a missing re-read of the mpls label - the last label is identified by looking inside the label field, while it should be done by looking at the S bit This change fixes the above issues. Notice that bitfield ordering is implementation-dependent, so C bitfields should not be used in the first place to parse network packets.
-rw-r--r--example/ndpi_util.c15
-rw-r--r--src/include/ndpi_typedefs.h8
2 files changed, 17 insertions, 6 deletions
diff --git a/example/ndpi_util.c b/example/ndpi_util.c
index d0a8470dc..af83c6d14 100644
--- a/example/ndpi_util.c
+++ b/example/ndpi_util.c
@@ -689,7 +689,10 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow,
const struct ndpi_wifi_header *wifi;
/* --- MPLS header --- */
- struct ndpi_mpls_header *mpls;
+ union mpls {
+ uint32_t u32;
+ struct ndpi_mpls_header mpls;
+ } mpls;
/** --- IP header --- **/
struct ndpi_iphdr *iph;
@@ -846,15 +849,15 @@ struct ndpi_proto ndpi_workflow_process_packet (struct ndpi_workflow * workflow,
break;
case MPLS_UNI:
case MPLS_MULTI:
- mpls = (struct ndpi_mpls_header *) &packet[ip_offset];
- label = ntohl(mpls->label);
- /* label = ntohl(*((u_int32_t*)&packet[ip_offset])); */
+ mpls.u32 = *((uint32_t *) &packet[ip_offset]);
+ mpls.u32 = ntohl(mpls.u32);
workflow->stats.mpls_count++;
type = ETH_P_IP, ip_offset += 4;
- while((label & 0x100) != 0x100) {
+ while(!mpls.mpls.s) {
ip_offset += 4;
- label = ntohl(mpls->label);
+ mpls.u32 = *((uint32_t *) &packet[ip_offset]);
+ mpls.u32 = ntohl(mpls.u32);
}
break;
case PPPoE:
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index beb6a86f8..d0afcb40c 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -178,7 +178,15 @@ struct ndpi_wifi_header
PACK_ON
struct ndpi_mpls_header
{
+ /* Before using this strcut to parse an MPLS header, you will need to convert
+ * the 4-byte data to the correct endianess with ntohl(). */
+#if defined(__LITTLE_ENDIAN__)
+ u_int32_t ttl:8, s:1, exp:3, label:20;
+#elif defined(__BIG_ENDIAN__)
u_int32_t label:20, exp:3, s:1, ttl:8;
+#else
+# error "Byte order must be defined"
+#endif
} PACK_OFF;
/* ++++++++++++++++++++++++ IP header ++++++++++++++++++++++++ */