Loading learning content...
The Internet carries vastly different types of traffic—real-time video conferencing, large file downloads, latency-sensitive online gaming, and best-effort web browsing—all sharing the same physical infrastructure. How does network equipment know which packets deserve priority treatment? The answer lies in the second byte of the IPv4 header: the Type of Service (ToS) field.
This single byte has undergone one of the most significant evolutionary journeys in Internet protocol history. What began in 1981 as a simple quality-of-service hint has transformed into a sophisticated traffic classification system that enables modern enterprise networks, ISP service tiers, and real-time application delivery. Understanding this evolution is essential for anyone working with network QoS, traffic engineering, or application performance optimization.
By the end of this page, you will master the complete evolution of the ToS field: its original RFC 791 structure, the Differentiated Services (DiffServ) architecture that replaced it, DSCP code points and their meanings, Explicit Congestion Notification (ECN) bits, and how modern networks use these 8 bits to implement quality-of-service policies.
The Type of Service field occupies the second byte (byte 1) of the IPv4 header, immediately following the Version/IHL byte. It consists of exactly 8 bits, occupying bit positions 8-15 of the header.
| Byte | Bit Positions | Field Name | Size |
|---|---|---|---|
| 0 | 0-7 | Version + IHL | 8 bits |
| 1 | 8-15 | Type of Service | 8 bits |
| 2-3 | 16-31 | Total Length | 16 bits |
| 4-5 | 32-47 | Identification | 16 bits |
Two Interpretations of the Same Byte:
The ToS byte has two valid interpretations depending on which RFC you follow:
Original ToS (RFC 791, 1981): The byte is divided into precedence, delay, throughput, reliability, and reserved bits.
DiffServ/ECN (RFC 2474/3168): The byte is divided into a 6-bit DSCP (Differentiated Services Code Point) and a 2-bit ECN (Explicit Congestion Notification) field.
The DiffServ interpretation is the modern standard and is used by virtually all current network equipment. However, understanding the original format is important for historical context and for interpreting legacy documentation.
The DiffServ redesign was engineered for backward compatibility. The three precedence bits (bits 0-2 of the original ToS) align with the three most significant bits of DSCP. This means certain legacy configurations continue to work, though with reduced functionality.
RFC 791 defined the Type of Service field with the following structure:
| Bits | Field Name | Size | Purpose |
|---|---|---|---|
| 0-2 | Precedence | 3 bits | Packet importance level (0-7) |
| 3 | Delay (D) | 1 bit | 0=Normal, 1=Low delay requested |
| 4 | Throughput (T) | 1 bit | 0=Normal, 1=High throughput requested |
| 5 | Reliability (R) | 1 bit | 0=Normal, 1=High reliability requested |
| 6-7 | Reserved | 2 bits | Must be zero (later became ECN) |
Precedence Values:
The 3-bit Precedence field defined eight priority levels for network traffic:
| Value | Binary | Name | Intended Use |
|---|---|---|---|
| 7 | 111 | Network Control | Reserved for network routing protocols |
| 6 | 110 | Internetwork Control | Reserved for internetwork control traffic |
| 5 | 101 | CRITIC/ECP | Critical and experimental traffic |
| 4 | 100 | Flash Override | Military: Emergency override |
| 3 | 011 | Flash | Military: Emergency traffic |
| 2 | 010 | Immediate | Priority traffic requiring fast handling |
| 1 | 001 | Priority | Priority traffic |
| 0 | 000 | Routine | Normal, best-effort traffic |
The D-T-R Bits:
The Delay, Throughput, and Reliability bits were designed to express application requirements:
Why Original ToS Failed:
Despite its logical structure, the original ToS system was never widely implemented:
Router burden: Maintaining multiple routing tables for different ToS combinations was impractical.
No policing: There was no mechanism to prevent every application from claiming maximum precedence.
Conflicting requests: Paths with low delay often had low bandwidth, making D+T requests impossible to satisfy.
Commercial reality: ISPs had no business model for ToS-based differentiation.
The bits remained in the header but were typically ignored—set to zero and passed through unchanged.
Some older network equipment and documentation still reference IP Precedence. When troubleshooting such systems, remember that IP Precedence values 0-7 map to DSCP values 0, 8, 16, 24, 32, 40, 48, and 56 respectively (multiply precedence by 8 to get equivalent DSCP).
Recognizing the limitations of original ToS, the IETF developed the Differentiated Services (DiffServ) architecture, documented in RFCs 2474 and 2475 (1998). DiffServ redefined the ToS byte with a practical, scalable approach to quality of service.
| Bits | Field Name | Size | Description |
|---|---|---|---|
| 0-5 | DSCP | 6 bits | Differentiated Services Code Point (0-63) |
| 6-7 | ECN | 2 bits | Explicit Congestion Notification |
Key DiffServ Concepts:
1. Per-Hop Behavior (PHB): DiffServ operates on a "per-hop" basis. Each router examines the DSCP value and applies a locally-defined forwarding treatment. This is simpler than end-to-end signaling and scales to Internet-size networks.
2. Traffic Classification at the Edge: Packets are classified and marked at network edges (ingress points). Core routers simply forward based on the DSCP value without complex classification. This "dumb core, smart edge" design enables high-speed forwarding.
3. Service Level Agreements (SLAs): ISPs can offer different service tiers by honoring or modifying DSCP values. Premium customers might have their traffic marked for priority handling.
4. Trust Boundaries: Networks typically don't trust DSCP markings from external sources. Traffic crossing trust boundaries is often remarked according to local policy.
All modern routers, switches, and operating systems use the DiffServ interpretation. When working with QoS, always think in terms of DSCP code points, not the original ToS Precedence/D/T/R structure.
The Differentiated Services Code Point (DSCP) is a 6-bit field allowing 64 possible values (0-63). While organizations can use these values freely within their networks, IANA has defined standard code points for interoperability.
DSCP Pools:
The 64 DSCP values are organized into pools:
Pool 1 (Standard): DSCP values xxxxx0 (even values, lower bit = 0) — 32 values standardized by IETF
Pool 2 (Experimental/LU): DSCP values xxxx11 — Experimental or Local Use
Pool 3 (Experimental/LU): DSCP values xxxx01 — Experimental or Local Use
| DSCP | Decimal | Binary | PHB | Typical Use |
|---|---|---|---|---|
| EF | 46 | 101110 | Expedited Forwarding | VoIP, real-time video, low-latency apps |
| AF41 | 34 | 100010 | Assured Forwarding 4, Low Drop | Video conferencing |
| AF42 | 36 | 100100 | Assured Forwarding 4, Med Drop | Video streaming |
| AF43 | 38 | 100110 | Assured Forwarding 4, High Drop | Video excess traffic |
| AF31 | 26 | 011010 | Assured Forwarding 3, Low Drop | Streaming media |
| AF21 | 18 | 010010 | Assured Forwarding 2, Low Drop | Transactional data |
| AF11 | 10 | 001010 | Assured Forwarding 1, Low Drop | Bulk data |
| CS6 | 48 | 110000 | Class Selector 6 | Network control (OSPF, BGP) |
| CS5 | 40 | 101000 | Class Selector 5 | Voice signaling (SIP) |
| CS0/BE | 0 | 000000 | Best Effort | Default, unclassified traffic |
Expedited Forwarding (EF) — DSCP 46:
EF (RFC 3246) provides the highest priority per-hop behavior. Characteristics include:
EF is designed for voice over IP (VoIP) and other real-time applications. Networks implementing EF must police incoming EF traffic to prevent abuse—otherwise, every application would mark itself as EF.
Assured Forwarding (AF) — Classes 1-4, Drop Precedence 1-3:
AF (RFC 2597) provides differentiated dropping behavior. Each AF class has three drop precedence levels:
During congestion, packets with higher drop precedence (AFx3) are dropped before those with lower precedence (AFx1). This enables traffic shaping where important packets are marked AFx1 and excess traffic is marked AFx3.
123456789101112131415161718192021222324252627282930313233343536373839
# DSCP is stored in the upper 6 bits of the ToS byte# ECN is stored in the lower 2 bits def decode_dscp_ecn(tos_byte: int) -> tuple[int, int]: """Extract DSCP and ECN from ToS byte.""" dscp = (tos_byte >> 2) & 0x3F # Upper 6 bits ecn = tos_byte & 0x03 # Lower 2 bits return dscp, ecn def encode_dscp_ecn(dscp: int, ecn: int) -> int: """Encode DSCP and ECN into ToS byte.""" if not 0 <= dscp <= 63: raise ValueError("DSCP must be 0-63") if not 0 <= ecn <= 3: raise ValueError("ECN must be 0-3") return (dscp << 2) | ecn # Common DSCP valuesDSCP_VALUES = { 'EF': 46, # Expedited Forwarding 'AF41': 34, 'AF42': 36, 'AF43': 38, 'AF31': 26, 'AF32': 28, 'AF33': 30, 'AF21': 18, 'AF22': 20, 'AF23': 22, 'AF11': 10, 'AF12': 12, 'AF13': 14, 'CS7': 56, 'CS6': 48, 'CS5': 40, 'CS4': 32, 'CS3': 24, 'CS2': 16, 'CS1': 8, 'CS0': 0, 'BE': 0, # Best Effort (same as CS0)} # Examplestos_byte = 0xB8 # 0b10111000dscp, ecn = decode_dscp_ecn(tos_byte)print(f"DSCP: {dscp} (EF={dscp==46}), ECN: {ecn}")# Output: DSCP: 46 (EF=True), ECN: 0 # Create a ToS byte for AF41 traffictos = encode_dscp_ecn(DSCP_VALUES['AF41'], 0)print(f"AF41 ToS byte: 0x{tos:02X}")# Output: AF41 ToS byte: 0x88Class Selector (CS) values CS0-CS7 correspond to the original IP Precedence values 0-7. They exist for backward compatibility. CS = Precedence × 8. For example, IP Precedence 5 = CS5 = DSCP 40.
The Explicit Congestion Notification (ECN) field occupies the two least significant bits of the ToS byte (bits 6-7 in DiffServ notation). ECN enables routers to signal congestion to endpoints without dropping packets, improving performance for both TCP and UDP traffic.
| ECN Value | Binary | Meaning | Description |
|---|---|---|---|
| Not-ECT | 00 | Not ECN-Capable Transport | Endpoint does not support ECN |
| ECT(0) | 10 | ECN-Capable Transport | Endpoint supports ECN (variant 0) |
| ECT(1) | 01 | ECN-Capable Transport | Endpoint supports ECN (variant 1) |
| CE | 11 | Congestion Experienced | Router marked packet as experiencing congestion |
How ECN Works:
Endpoint negotiation: During TCP three-way handshake, endpoints negotiate ECN support using TCP flags (ECE and CWR).
Packet marking: If ECN is negotiated, the sender marks packets with ECT(0) or ECT(1).
Congestion detection: When a router's queue starts filling, instead of dropping the packet, it sets the ECN field to CE (Congestion Experienced).
Receiver notification: The receiver sees the CE marking and sets the ECE flag in its TCP ACK.
Sender response: The sender receives the ECE, reduces its congestion window (just like a packet loss), and sets CWR to acknowledge.
Benefits over packet dropping:
Low Latency Low Loss Scalable throughput (L4S) is an advanced ECN-based architecture that uses the ECT(1) codepoint to signal traffic that responds to very fine-grained congestion signals. L4S promises sub-millisecond queuing latency while maintaining high throughput—a major advancement for interactive applications.
Understanding DSCP is only useful if you can apply it in real networks. Let's examine how QoS is configured on actual network equipment and operating systems.
Enterprise Network QoS Model (RFC 4594):
RFC 4594 provides guidelines for a standardized QoS model across enterprises:
| Service Class | DSCP | Applications | Characteristics |
|---|---|---|---|
| Network Control | CS6 | OSPF, BGP, HSRP | Network-critical, never drop |
| Telephony | EF | VoIP bearer | <150ms latency, <30ms jitter |
| Signaling | CS5 | SIP, H.323 signaling | Call setup/teardown |
| Multimedia Conferencing | AF4x | Video conferencing | Low latency, variable rate |
| Real-Time Interactive | CS4 | Gaming, remote desktop | Low latency required |
| Multimedia Streaming | AF3x | Video on demand | High bandwidth, tolerant of latency |
| Broadcast Video | CS3 | IPTV | One-way video distribution |
| Low-Latency Data | AF2x | Client/server transactions | Response time sensitive |
| OAM | CS2 | SNMP, SSH management | Operations and management |
| High-Throughput Data | AF1x | Backup, replication | High volume, tolerant of delay |
| Standard | CS0 (BE) | Email, web browsing | Default best-effort |
| Low-Priority Data | CS1 | Software updates | Scavenger class |
123456789101112131415161718192021222324252627282930
! Cisco IOS: Classify and mark VoIP traffic!! Define class to match voice RTP trafficclass-map match-any VOICE-RTP match protocol rtp audio match dscp ef!! Define class for videoclass-map match-any VIDEO match dscp af41 af42 af43!! Define policy map with queuingpolicy-map WAN-QOS class VOICE-RTP priority percent 10 ! Strict priority queue set dscp ef ! Ensure EF marking class VIDEO bandwidth percent 30 ! Guaranteed bandwidth set dscp af41 random-detect dscp-based ! WRED for congestion mgmt class class-default bandwidth percent 60 ! Best effort fair-queue ! WFQ within class!! Apply policy to interfaceinterface GigabitEthernet0/0 service-policy output WAN-QOS ! Verify configurationshow policy-map interface GigabitEthernet0/01234567891011121314151617181920212223242526272829303132333435
#!/bin/bash# Linux Traffic Control: Mark and prioritize packets by DSCP # Create HTB qdisc with handle 1:0tc qdisc add dev eth0 root handle 1: htb default 30 # Root class (total bandwidth)tc class add dev eth0 parent 1: classid 1:1 htb rate 1gbit # VoIP class (EF, DSCP 46) - strict prioritytc class add dev eth0 parent 1:1 classid 1:10 htb rate 100mbit ceil 100mbit prio 0 # Video class (AF41, DSCP 34) - guaranteed bandwidthtc class add dev eth0 parent 1:1 classid 1:20 htb rate 300mbit ceil 500mbit prio 1 # Best effort (DSCP 0)tc class add dev eth0 parent 1:1 classid 1:30 htb rate 600mbit ceil 1gbit prio 2 # Classify packets by DSCP# DSCP 46 (EF) = ToS byte 0xB8 (46 << 2 = 184 = 0xB8)tc filter add dev eth0 parent 1: protocol ip prio 1 \ u32 match ip tos 0xb8 0xfc flowid 1:10 # DSCP 34 (AF41) = ToS byte 0x88 (34 << 2 = 136 = 0x88)tc filter add dev eth0 parent 1: protocol ip prio 2 \ u32 match ip tos 0x88 0xfc flowid 1:20 # Add SFQ to leaf classes for fairnesstc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10 # Verify configurationtc -s qdisc show dev eth0tc -s class show dev eth0Never trust DSCP markings from untrusted sources. At network ingress points (Internet-facing interfaces, guest networks), either remark all traffic to BE (DSCP 0) or remark according to a verified policy. Otherwise, attackers can mark their traffic as EF to gain unfair priority.
Analyzing DSCP values in packet captures is essential for QoS troubleshooting. Let's examine how different tools display this information.
1234567891011121314151617181920212223242526
# Wireshark displays the ToS byte with full DiffServ interpretation Internet Protocol Version 4, Src: 192.168.1.100, Dst: 10.0.0.1 0100 .... = Version: 4 .... 0101 = Header Length: 20 bytes (5) Differentiated Services Field: 0xb8 (DSCP: EF, ECN: Not-ECT) 1011 10.. = Differentiated Services Codepoint: Expedited Forwarding (46) .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0) Total Length: 200 ... # Common Wireshark display filters for DSCP:ip.dsfield.dscp == 46 # Match EF trafficip.dsfield.dscp == 34 # Match AF41 trafficip.dsfield.dscp >= 32 # Match high-priority (AF4x/CS4+)ip.dsfield.ecn == 3 # Match CE (congestion) markedip.dsfield.dscp == 0 # Match best-effortip.dsfield != 0 # Any non-default ToS # ToS byte filter (alternative syntax):ip.tos == 0xb8 # EF with no ECN (ToS = DSCP<<2 | ECN)ip.tos & 0xFC == 0xb8 # EF regardless of ECN bits # Wireshark column customization:# Add column with: ip.dsfield.dscp# This shows DSCP value for each packet in packet listCommon Troubleshooting Scenarios:
Applications set DSCP via socket options. In Python: sock.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, dscp << 2). In C: setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)). Note that the ToS value is DSCP << 2, not raw DSCP.
We've conducted a comprehensive analysis of the Type of Service byte and its modern DiffServ interpretation. Let's consolidate the essential knowledge:
What's Next:
With Type of Service mastered, we proceed to the Total Length field—a 16-bit value specifying the entire IPv4 packet size in bytes. This seemingly simple field has important implications for fragmentation, MTU discovery, and packet validation.
You now possess comprehensive understanding of the Type of Service byte—its historical evolution, DSCP code points, ECN mechanism, practical QoS configuration, and troubleshooting techniques. This knowledge is essential for designing and managing quality-of-service in modern networks.