4 6LoWPAN Header Compression (IPHC)
6LoWPAN’s IPHC (IP Header Compression) algorithm reduces IPv6 headers from 40 bytes down to as few as 2 bytes by intelligently eliding fields that can be derived from link-layer context. The biggest savings come from address compression, where link-local addresses are fully reconstructed from IEEE 802.15.4 MAC addresses, and UDP’s Next Header Compression (NHC) further shrinks transport headers from 8 bytes to 4.
4.1 Learning Objectives
By the end of this chapter, you will be able to:
- Deconstruct IPHC Mechanics: Break down how each IPHC bit flag controls IPv6 header reduction from 40 bytes to 2-7 bytes
- Evaluate Compression Fields: Determine which IPHC fields can be elided in a given network scenario and justify elision decisions
- Calculate Compression Savings: Compute bandwidth and battery savings from header compression across different addressing modes
- Configure Context-Based Compression: Design and deploy shared compression contexts on border routers for optimal global address efficiency
- Diagnose NHC for UDP: Trace how Next Header Compression encodes UDP port ranges and identify when port compression fails
IPv6 headers are normally 40 bytes, but IoT radio frames can only carry about 127 bytes total. Header compression shrinks those 40-byte headers down to as few as 2 bytes by removing redundant information. It is like abbreviating a long address to just a zip code when the mail carrier already knows the street.
“IPv6 headers are 40 bytes long,” said Max the Microcontroller, holding up a long scroll. “But our radio frames only hold 127 bytes total. If we spend 40 bytes just on the address label, there is barely any room left for the actual message!”
Sammy the Sensor looked at his tiny data packet. “My temperature reading is only 4 bytes. It seems silly to wrap it in a 40-byte envelope.” Max pulled out a shrink ray. “That is why 6LoWPAN invented IPHC – IP Header Compression! It shrinks that 40-byte header down to just 2 bytes by being clever about what information it can figure out on its own.”
“How does it do that?” asked Lila the LED curiously. Max explained, “Think of it this way. If I am mailing a letter to my neighbor, I do not need to write the full country, state, and city on the envelope – the mail carrier already knows we are on the same street. IPHC works the same way. It drops address parts that the receiver can reconstruct from the radio link, like deriving the IPv6 address from the 802.15.4 MAC address.”
Bella the Battery cheered. “Smaller headers mean shorter transmissions, which means less energy! IPHC is my best friend!”
4.2 Prerequisites
Before diving into this chapter, you should be familiar with:
- 6LoWPAN Overview: Basic understanding of 6LoWPAN’s purpose
- IPv6 Fundamentals: IPv6 header structure and addressing
- IEEE 802.15.4 Fundamentals: Understanding frame size constraints
IPHC compresses IPv6 headers by analyzing each field and determining if it can be elided (omitted) or shortened. The process starts with a 2-byte IPHC dispatch header that encodes which fields are compressed using bit flags (TF for Traffic Class/Flow, NH for Next Header, HLIM for Hop Limit, SAM/DAM for Source/Destination Address Modes). For link-local addresses (fe80::/10), the entire 128-bit address is derived from the 64-bit IEEE 802.15.4 MAC address via EUI-64 conversion, requiring 0 transmitted bytes. Common values like Hop Limit 64 are encoded as 2-bit flags. UDP Next Header Compression (NHC) further reduces 8-byte UDP headers to 4 bytes by eliding the Length field and compressing ports in the 0xF0B0-0xF0BF range into 4-bit nibbles. The receiver reconstructs the full headers by reversing the process using the IPHC flags, link-layer addresses, and default values.
4.3 The IPHC Compression Algorithm
The IP Header Compression (IPHC) mechanism is the heart of 6LoWPAN efficiency. Here’s how it works at the bit level.
4.3.1 IPHC Base Header Format
The IPHC header is a minimum of 2 bytes that encodes which IPv6 fields are compressed:
4.3.2 IPHC Field Definitions
| Field | Values | Meaning | Bytes Saved |
|---|---|---|---|
| TF (Traffic Class/Flow) | 00=inline, 11=elided | Traffic Class and Flow Label handling | 0-4 bytes |
| NH (Next Header) | 0=inline, 1=compressed | UDP/TCP port compression using NHC | 0-1 byte |
| HLIM (Hop Limit) | 00=inline, 01=1, 10=64, 11=255 | Common hop limit values | 0-1 byte |
| SAM (Source Address Mode) | 00=128-bit inline, 11=fully elided | Source address compression level | 0-16 bytes |
| DAM (Dest Address Mode) | 00=128-bit inline, 11=fully elided | Destination address compression level | 0-16 bytes |
4.3.3 Best-Case Compression Example
Original IPv6 Header (40 bytes):
Version: 6 (4 bits)
Traffic Class: 0 (8 bits) -> ELIDED (TF=11)
Flow Label: 0 (20 bits) -> ELIDED (TF=11)
Payload Length: Derived from 802.15.4 frame -> ELIDED
Next Header: UDP (17) -> COMPRESSED via NHC (NH=1)
Hop Limit: 64 -> COMPRESSED to 2 bits (HLIM=10)
Source: fe80::0200:1234:5678:9abc -> ELIDED (derived from MAC, SAM=11)
Destination: fe80::0200:1234:5678:def0 -> ELIDED (derived from MAC, DAM=11)
IPHC compression ratio for the best-case scenario (link-local addresses, default hop limit, zero traffic class/flow):
\[\text{Compression Ratio} = \frac{\text{Original Size} - \text{Compressed Size}}{\text{Original Size}} \times 100\%\]
Worked example: Original 40-byte IPv6 header compressed to 2 bytes:
\[\frac{40 - 2}{40} \times 100\% = 95\%\]
For an 802.15.4 frame with 102 bytes usable payload, this means:
- Without compression: 40 (IPv6) + 8 (UDP) = 48 bytes overhead → 54 bytes for data (52.9% efficiency)
- With IPHC: 2 (IPHC) + 4 (NHC-UDP) = 6 bytes overhead → 96 bytes for data (94.1% efficiency)
Net gain: \(96 - 54 = 42\) additional bytes per packet for application payload — a 77.8% increase in usable space.
Resulting IPHC Header (2 bytes):
IPHC Dispatch: 01100000 00000000 (TF=11, NH=1, HLIM=10, SAM=11, DAM=11)
Total: 2 bytes instead of 40 bytes = 95% compression!
4.4 Address Compression: The Biggest Win
The majority of compression savings come from address elision:
4.4.1 Link-Local Address Compression
Link-local addresses (fe80::/10) can be fully derived from the IEEE 802.15.4 MAC address:
Full address: fe80::0200:1234:5678:9abc (16 bytes)
With IPHC: 0 bytes elided! (derived from link-layer address)
How it works:
- Prefix fe80::/64 is well-known (link-local)
- Interface ID (IID) is derived from the 802.15.4 extended address using EUI-64 mapping
- Both sender and receiver can reconstruct the full address
4.4.2 Context-Based Compression
For global addresses, networks share compression contexts:
Context 0: 2001:db8:1234:5678::/64 (distributed by border router)
Full Address: 2001:db8:1234:5678::200:1234:5678:9abc
With Context 0:
- Prefix (64 bits) -> ELIDED (context lookup)
- IID (64 bits) -> 2 bytes (if matches MAC pattern)
Total: 2 bytes instead of 16 bytes
Scenario: A smart building has 50 temperature sensors on subnet 2001:db8:building3:floor2::/64. The border router distributes this prefix as Context 0.
Sensor IPv6 Address: 2001:db8:building3:floor2::sensor42
Without Context Compression:
Source: 2001:db8:building3:floor2::sensor42 (full 16 bytes inline)
Destination: 2001:db8:building3::server (full 16 bytes inline)
Total addresses: 32 bytes
With Context Compression:
Context 0 (shared): 2001:db8:building3::/48
Source: Context 0 + floor2::sensor42
- Context ID: 1 byte (index into shared context table)
- Suffix: ::sensor42 = 8 bytes (IID)
- Total: 9 bytes (vs 16 bytes)
Destination: Context 0 + ::server
- Context ID: 1 byte
- Suffix: ::server = 8 bytes
- Total: 9 bytes
Total addresses: 18 bytes (vs 32 bytes)
Savings: 14 bytes per packet (44% reduction on addresses alone)
In a high-traffic scenario (100 sensors, 1 packet/minute, 24 hours):
Packets per day: 100 sensors x 1440 minutes = 144,000 packets
Bytes saved: 144,000 x 14 bytes = 2,016,000 bytes/day = 1.9 MB/day
4.4.3 Knowledge Check: IPHC Address Elision Savings
4.5 Next Header Compression (NHC) for UDP
Standard UDP header (8 bytes):
Source Port: 16 bits
Dest Port: 16 bits
Length: 16 bits -> ELIDED (derived)
Checksum: 16 bits -> ELIDED or inline
NHC UDP (4 bytes typical):
11110CPP (1 byte NHC dispatch)
C=0: Checksum carried inline (16 bits)
C=1: Checksum elided (only allowed with link-layer security)
PP=11: Both ports compressed to 4 bits each (0xF0B0-0xF0BF range)
Source Port: 0xF0B + 4 bits (for ports 61616-61631)
Dest Port: 0xF0B + 4 bits
Checksum: 16 bits (when C=0)
Total: 4 bytes (dispatch + 1-byte ports + 2-byte checksum, with C=0 and PP=11)
4.5.1 Port Compression Modes
| Mode | Source Port | Dest Port | Bytes |
|---|---|---|---|
| PP=00 | 16 bits inline | 16 bits inline | 4 bytes |
| PP=01 | 0xF0 + 8 bits | 16 bits inline | 3 bytes |
| PP=10 | 16 bits inline | 0xF0 + 8 bits | 3 bytes |
| PP=11 | 0xF0B + 4 bits | 0xF0B + 4 bits | 1 byte |
CoAP ports (5683 = 0x1633, 5684 = 0x1634) do NOT fall in the 0xF0Bx range, so they cannot use PP=11 maximum compression. However, they can use PP=01 or PP=10 (0xF000 + 8-bit encoding for ports 61440-61695) when paired with a port in that range. For maximum UDP compression, implementations often use ephemeral ports in the 0xF0B0-0xF0BF range alongside CoAP’s well-known ports.
4.5.2 Knowledge Check: Address Compression Modes
4.5.3 Knowledge Check: NHC UDP Port Compression
4.6 Compression Effectiveness by Traffic Type
| Traffic Type | Typical Compression | Bytes Saved |
|---|---|---|
| Link-local to link-local | 40 -> 2 bytes | 38 bytes (95%) |
| Link-local to global (context) | 40 -> 9 bytes | 31 bytes (78%) |
| Global to global (no context) | 40 -> 18 bytes | 22 bytes (55%) |
| With UDP ports compressed | +8 -> +4 bytes | +4 bytes (50% of UDP header) |
| Best case (LL + UDP) | 48 -> 6 bytes | 42 bytes (88%) |
The Trap: Assuming all 6LoWPAN traffic gets 95% header compression like the best-case examples.
Reality: Compression effectiveness varies dramatically based on addressing:
| Scenario | IPv6 Header Size | IPHC Result | Compression |
|---|---|---|---|
| Link-local to link-local | 40 bytes | 2 bytes | 95% |
| Global with context | 40 bytes | 7-10 bytes | 75-82% |
| Global without context | 40 bytes | 18-20 bytes | 50-55% |
| Multicast destination | 40 bytes | 10-14 bytes | 65-75% |
When Maximum Compression Fails:
- Communicating with external servers (no shared context)
- Using multicast addresses (can’t derive from L2)
- Non-standard hop limits (not 1, 64, or 255)
- Non-zero traffic class or flow labels (QoS marking)
The Fix:
- Design for link-local when possible (sensor-to-gateway)
- Configure compression contexts on border router for external prefixes
- Use short-form addresses (::1, ::2) within the local subnet
- Accept reduced compression for internet-bound traffic
4.7 Interactive Demo: Header Compression
This interactive animation demonstrates IPHC header compression, showing how IPv6+UDP headers can be compressed from 48 bytes down to as few as 2-3 bytes.
Interactive Animation: This animation is under development.
4.8 Knowledge Check: IPHC Compression
4.8.1 Knowledge Check: Context-Based Compression
4.9 Common Misconception: Compression Adds Latency
The Myth: “IPHC compression/decompression adds significant latency because the microcontroller must process each header field.”
The Reality: IPHC overhead is negligible compared to radio transmission time:
| Operation | Time | Comparison |
|---|---|---|
| IPHC compression | ~50-100 us | 0.1 ms |
| IPHC decompression | ~30-80 us | 0.08 ms |
| Radio TX (93 bytes) | 2.98 ms | 30x longer than compression |
| Radio TX (53 bytes) | 1.70 ms | Saves 1.28 ms per packet |
Net Effect: Compression saves 1.28 ms TX time while adding only 0.18 ms processing = 1.1 ms net savings per packet.
Why This Matters:
- Radio TX consumes 27 mA vs 8 mA for CPU processing
- Shorter packets mean less collision probability
- Reduced airtime = more capacity for other nodes
Code Verification (Contiki-NG profiling):
// Measured on CC2538 @ 32 MHz
clock_time_t start = RTIMER_NOW();
sicslowpan_compress(&ipv6_hdr, &compressed_hdr);
clock_time_t elapsed = RTIMER_NOW() - start;
// Result: elapsed = 2-3 RTIMER ticks = 61-92 usConclusion: Always enable IPHC compression. The processing overhead is insignificant; the bandwidth and energy savings are substantial.
4.10 Real-World Deployment: Smart Metering at Scale
4.10.1 Kamstrup Denmark: 1.2 Million Smart Water Meters
Danish utility metering company Kamstrup deployed 1.2 million smart water meters across Scandinavian municipalities using 6LoWPAN over 802.15.4 mesh networks. Each meter sends a 32-byte consumption reading every 15 minutes through a multi-hop mesh to neighborhood gateway concentrators.
Why IPHC was critical to feasibility:
The original prototype used uncompressed IPv6 over 802.15.4. With a 127-byte PHY MTU:
| Configuration | Header overhead | Payload capacity | Fragmentation required |
|---|---|---|---|
| Uncompressed IPv6 + UDP | 48 bytes | 54 bytes (after 25-byte MAC) | No, but barely fits |
| Add RPL routing header | 56 bytes | 46 bytes | Yes – 2 fragments for 32-byte reading + RPL |
| IPHC + NHC (deployed) | 6 bytes | 96 bytes | Never – single frame |
Fragmentation was the dealbreaker. In a 4-hop mesh at 15% per-hop loss, a 2-fragment packet has only (0.854)2 = 27.2% end-to-end delivery probability. A single-frame packet achieves 0.85^4 = 52.2% – nearly double. With IPHC compression eliminating fragmentation entirely, Kamstrup achieved 99.8% daily reading completeness (meters retry hourly until acknowledged).
Compression context design:
Kamstrup configured two compression contexts per gateway cluster:
- Context 0:
2001:db8:kamstrup:region::/64– meters within the same gateway’s subnet. Full IPHC elision reduces source address to 0 bytes. - Context 1:
2001:db8:kamstrup:noc::/64– network operations center. Reduces destination from 16 bytes to 2 bytes.
This meant a typical meter-to-NOC packet compressed to 8 bytes of header (IPHC dispatch + context ID + 2-byte destination suffix + 4-byte NHC-UDP) instead of 48 bytes. The 40-byte savings per packet translated to:
1.2M meters x 96 packets/day x 40 bytes saved = 4.6 GB/day of airtime saved
At 250 kbps radio: 147,456 seconds of airtime saved daily across the network
Battery life impact: Kamstrup measured 11.2-year average battery life with IPHC versus a projected 4.8 years without compression. The difference was not just fewer transmitted bytes but elimination of fragmentation retries, which dominate energy consumption in lossy mesh networks.
4.10.2 Lesson Learned: Context Distribution Matters
During the first 6 months, 3.4% of meters experienced “context staleness” after gateway failovers. When a backup gateway took over, it broadcast new compression contexts, but some meters in deep mesh positions (6+ hops) did not receive the update for up to 45 minutes. During that window, meters sent packets compressed with the old context, which the new gateway could not decompress. Kamstrup’s fix was dual-context caching: gateways maintain both current and previous context tables for a 2-hour overlap window after failover.
4.11 Concept Relationships
| Concept | Depends On | Enables | Conflicts With |
|---|---|---|---|
| IPHC Compression | Link-local addressing, EUI-64 derivation | Battery life extension (2x-3x), single-frame delivery | Global unicast without context (reduces compression ratio) |
| Context-Based Compression | Shared prefix configuration, Context IDs 0-15 | Global address compression (16 bytes → 2 bytes) | Context staleness during failover |
| NHC UDP | Compressible port ranges (0xF0B0-0xF0BF for PP=11, 0xF000-0xF0FF for PP=01/10) | Transport header reduction (8 bytes → 4 bytes) | Arbitrary port numbers outside 0xF0xx range require full inline encoding |
| Address Elision (SAM/DAM=11) | IEEE 802.15.4 MAC addresses, fe80::/10 prefix | Maximum compression (40 bytes → 2 bytes) | Cross-subnet communication (requires explicit addresses) |
Common Pitfalls
If a sender uses context index 3 to compress an address but the receiver’s context table has a different prefix at index 3, the decompressed address will be wrong. Ensure context tables are synchronized across all nodes and refreshed after context updates.
IPHC compression requires the packet to have link-local or known global addresses. Packets with unusual address scopes or multiple extension headers may not compress well, leaving actual on-air sizes close to uncompressed. Measure real frame sizes in your specific protocol stack.
NHC UDP elision only works for ports in specific ranges. Using arbitrary high-numbered ports for application protocols disables UDP header compression, costing 4 extra bytes per packet on a 127-byte link.
4.12 Summary
This chapter explored 6LoWPAN’s IP Header Compression (IPHC) mechanism:
- IPHC reduces IPv6 headers from 40 bytes to as little as 2 bytes by eliding predictable fields
- Address compression provides the biggest savings: link-local addresses can be fully derived from MAC addresses
- Context-based compression enables global address compression using shared prefix information
- NHC for UDP compresses transport headers from 8 bytes to 4 bytes
- Compression effectiveness varies from 95% (link-local) to 55% (global without context)
- Processing overhead is negligible compared to radio transmission time savings
::
::
Key Concepts
- IPHC (Inline IPv6 Header Compression): The 6LoWPAN header compression scheme from RFC 6282 using dispatch bytes and context tables to compress 40-byte IPv6 headers to 2–7 bytes.
- NHC (Next Header Compression): Extension to IPHC that also compresses extension headers and UDP headers, further reducing per-packet overhead.
- Context Table: A table of IPv6 prefixes shared between sender and receiver, allowing addresses matching a known prefix to be compressed to just a context index.
- Dispatch Byte: The first byte of a 6LoWPAN frame indicating the type of data that follows (uncompressed IPv6, IPHC-compressed, mesh addressing, fragmentation header, etc.).
- Stateful vs Stateless Compression: Stateful compression uses context tables (shared prefix knowledge) for higher compression; stateless compression uses link-local address inference for simpler but less efficient compression.
- UDP Header Compression: NHC can compress the 8-byte UDP header to 4 bytes by eliding ports that match well-known values or deriving them from context.
4.13 See Also
- 6LoWPAN Overview - Introduction to 6LoWPAN concepts before diving into compression details
- 6LoWPAN Fragmentation - What happens when compressed packets still exceed 102 bytes
- IPv6 Fundamentals - Understanding the IPv6 header structure being compressed
Scenario: You’re deploying a smart building network with 80 temperature sensors using global IPv6 addresses 2001:db8:building:floor3::sensor<N> reporting to cloud server 2001:db8:cloud:analytics::server1.
Tasks:
- Calculate compressed header size WITHOUT context (inline global addresses)
- Configure Context 0 =
2001:db8:building:floor3::/64and Context 1 =2001:db8:cloud:analytics::/64 - Calculate compressed header size WITH contexts
- Estimate monthly bandwidth savings for 80 sensors × 12 reports/hour
Expected Results:
- Without context: 2-byte IPHC + 9-byte source suffix + 9-byte dest suffix = 20 bytes
- With context: 2-byte IPHC + 1-byte context flags + 2-byte source suffix + 2-byte dest suffix = 7 bytes
- Savings per packet: 13 bytes
- Monthly savings: 80 sensors × 12 × 24 × 30 days × 13 bytes = 8.98 MB/month
- Decision: Context compression is essential for global addressing at scale
4.14 What’s Next
| Chapter | Focus |
|---|---|
| 6LoWPAN Fragmentation | How compressed packets that still exceed the 802.15.4 MTU are split into link-layer fragments |
| 6LoWPAN Routing with RPL | Mesh routing protocol that works alongside IPHC-compressed packets in multi-hop networks |
| 6LoWPAN Deployment | Practical deployment considerations including context configuration and gateway design |
| 6LoWPAN Pitfalls | Common mistakes in 6LoWPAN networks including context staleness and fragmentation traps |
| 6LoWPAN Hands-On and Security | Lab exercises implementing IPHC compression and securing 6LoWPAN links |