swift-ietf/swift-rfc-791
Swift implementation of RFC 791: Internet Protocol (IPv4).
Overview
This package provides type-safe Swift representations of all Internet Protocol version 4 header fields as defined in RFC 791. Each field is modeled as a distinct type with validation, serialization, and parsing capabilities.
The implementation follows RFC 791 (September 1981), the foundational specification for IPv4 that remains the basis of Internet routing today.
Features
- Complete IPv4 header field coverage (Version, IHL, TOS, Total Length, Identification, Flags, Fragment Offset, TTL, Protocol, Header Checksum, Source/Destination Address)
- Type-safe IPv4 address representation with dotted-decimal parsing and serialization
- Address classification (Class A, B, C, D, E) per RFC 791 Section 3.2
- Type of Service with Precedence levels and D/T/R flags
- Fragment handling with offset calculations (8-octet units)
- Header checksum computation and verification (one's complement algorithm)
- Binary serialization via
Binary.Serializableprotocol - ASCII serialization for addresses via
Binary.ASCII.Serializableprotocol - 202 tests covering parsing, serialization, validation, and edge cases
Installation
Add to your Package.swift:
dependencies: [
.package(url: "https://github.com/swift-standards/swift-rfc-791.git", from: "0.1.0")
]Then add the dependency to your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "RFC 791", package: "swift-rfc-791")
]
)Quick Start
import RFC_791
// Create an IPv4 address from dotted-decimal notation
let address: RFC_791.IPv4.Address = "192.168.1.1"
print(address.octets) // (192, 168, 1, 1)
print(address.addressClass) // .classC
// Create header fields
let ttl = RFC_791.TTL.default64 // 64 hops (Linux/macOS default)
let proto = RFC_791.`Protocol`.tcp // Protocol number 6
let flags = RFC_791.Flags(dontFragment: true, moreFragments: false)
// Serialize address to ASCII bytes (dotted-decimal)
let bytes = [UInt8](address) // "192.168.1.1" as ASCIIUsage Examples
IPv4 Addresses
Create and manipulate IPv4 addresses:
import RFC_791
// From string literal
let addr1: RFC_791.IPv4.Address = "10.0.0.1"
// From raw 32-bit value
let addr2 = RFC_791.IPv4.Address(rawValue: 0xC0A80001) // 192.168.0.1
// From individual octets
let addr3 = RFC_791.IPv4.Address(127, 0, 0, 1)
// Access octets
let (a, b, c, d) = addr1.octets
print("\(a).\(b).\(c).\(d)") // "10.0.0.1"
// Address classification (RFC 791 Section 3.2)
addr1.addressClass // .classA (10.x.x.x)
addr1.isMulticast // false
addr1.isReserved // false
// Special addresses
RFC_791.IPv4.Address.any // 0.0.0.0
RFC_791.IPv4.Address.broadcast // 255.255.255.255
RFC_791.IPv4.Address.loopback // 127.0.0.1IP Header Fields
Work with individual header fields:
import RFC_791
// Version (4-bit)
let version = RFC_791.Version.v4
version.isIPv4 // true
// Internet Header Length (4-bit, in 32-bit words)
let ihl = RFC_791.IHL.minimum // 5 (20 bytes, no options)
ihl.byteLength // 20
ihl.hasOptions // false
// Time to Live (8-bit)
let ttl = RFC_791.TTL(rawValue: 64)
ttl.isExpired // false
ttl.decremented?.rawValue // 63
// Protocol (8-bit) - use backticks for reserved keyword
RFC_791.`Protocol`.icmp.rawValue // 1
RFC_791.`Protocol`.tcp.rawValue // 6
RFC_791.`Protocol`.udp.rawValue // 17
// Identification (16-bit)
let id = RFC_791.Identification(rawValue: 0x1234)
// Total Length (16-bit)
let length = RFC_791.TotalLength(rawValue: 1500)!
length.maximumDataLength // 1480 (minus minimum header)Type of Service
Configure QoS parameters:
import RFC_791
// Create with precedence and flags
let tos = RFC_791.TypeOfService(
precedence: .immediate,
lowDelay: true,
highThroughput: false,
highReliability: true
)
// Extract components
tos.precedence // .immediate
tos.lowDelay // true
tos.highThroughput // false
tos.highReliability // true
// Precedence levels (RFC 791 Section 3.1)
RFC_791.Precedence.routine // 0
RFC_791.Precedence.priority // 1
RFC_791.Precedence.immediate // 2
RFC_791.Precedence.flash // 3
RFC_791.Precedence.flashOverride // 4
RFC_791.Precedence.criticEcp // 5
RFC_791.Precedence.internetworkControl // 6
RFC_791.Precedence.networkControl // 7Fragmentation
Handle IP fragmentation:
import RFC_791
// Fragment flags
let flags = RFC_791.Flags(dontFragment: false, moreFragments: true)
flags.dontFragment // false
flags.moreFragments // true
// Fragment offset (13-bit, in 8-octet units)
let offset = RFC_791.FragmentOffset(rawValue: 185)!
offset.byteOffset // 1480 (typical MTU boundary)
offset.isFirstFragment // false
// Create from byte offset
let firstFrag = RFC_791.FragmentOffset.fromByteOffset(0)!
firstFrag.isFirstFragment // trueHeader Checksum
Compute and verify checksums:
import RFC_791
// Compute checksum for a header (with checksum field zeroed)
let header: [UInt8] = [
0x45, 0x00, // Version, IHL, TOS
0x00, 0x73, // Total Length
0x00, 0x00, // Identification
0x40, 0x00, // Flags, Fragment Offset
0x40, 0x11, // TTL, Protocol
0x00, 0x00, // Checksum (zero for computation)
0xC0, 0xA8, 0x00, 0x01, // Source: 192.168.0.1
0xC0, 0xA8, 0x00, 0xC7, // Destination: 192.168.0.199
]
let checksum = RFC_791.HeaderChecksum.compute(over: header)
print(checksum.rawValue) // 0xB861
// Verify a header with checksum included
let completeHeader: [UInt8] = [
0x45, 0x00, 0x00, 0x73, 0x00, 0x00, 0x40, 0x00,
0x40, 0x11, 0xB8, 0x61, // Checksum at bytes 10-11
0xC0, 0xA8, 0x00, 0x01, 0xC0, 0xA8, 0x00, 0xC7,
]
RFC_791.HeaderChecksum.verify(header: completeHeader) // trueBinary Serialization
Serialize fields to bytes:
import RFC_791
var buffer: [UInt8] = []
// 16-bit fields (2 bytes each, big-endian)
RFC_791.TotalLength(rawValue: 1500)!.serialize(into: &buffer)
RFC_791.Identification(rawValue: 0x1234).serialize(into: &buffer)
RFC_791.HeaderChecksum(rawValue: 0xABCD).serialize(into: &buffer)
// 8-bit fields (1 byte each)
RFC_791.TTL(rawValue: 64).serialize(into: &buffer)
RFC_791.`Protocol`.tcp.serialize(into: &buffer)
// Address serializes to ASCII dotted-decimal (variable length)
let address: RFC_791.IPv4.Address = "192.168.1.1"
let addressBytes = [UInt8](address) // "192.168.1.1" as ASCIIBinary Parsing
Parse fields from bytes:
import RFC_791
// Parse address from ASCII dotted-decimal bytes
let addrBytes: [UInt8] = Array("192.168.1.1".utf8)
let address = try RFC_791.IPv4.Address(ascii: addrBytes, in: ())
// Parse 16-bit fields from binary
let lengthBytes: [UInt8] = [0x05, 0xDC] // 1500
let length = try RFC_791.TotalLength(bytes: lengthBytes)
// Parse with error handling
do {
let ttl = try RFC_791.TTL(bytes: [])
} catch RFC_791.TTL.Error.empty {
print("No data")
}Standards Compliance
Conforms to RFC 791 (September 1981): Internet Protocol - DARPA Internet Program Protocol Specification.
Header Format
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Type Coverage
| Field | Bits | Type | |-------|------|------| | Version | 4 | RFC_791.Version | | IHL | 4 | RFC_791.IHL | | Type of Service | 8 | RFC_791.TypeOfService | | Total Length | 16 | RFC_791.TotalLength | | Identification | 16 | RFC_791.Identification | | Flags | 3 | RFC_791.Flags | | Fragment Offset | 13 | RFC_791.FragmentOffset | | Time to Live | 8 | RFC_791.TTL | | Protocol | 8 | RFC_791.Protocol | | Header Checksum | 16 | RFC_791.HeaderChecksum | | Source Address | 32 | RFC_791.IPv4.Address | | Destination Address | 32 | RFC_791.IPv4.Address |
Testing
Test suite: 202 tests covering all types.
Run tests:
swift testRequirements
- Swift 6.0 or later
- macOS 15.0+ / iOS 18.0+ / tvOS 18.0+ / watchOS 11.0+
License
This package is licensed under the Apache License 2.0. See LICENSE.md for details.
Contributing
Contributions are welcome. Please ensure all tests pass and new features include test coverage.
Package Metadata
Repository: swift-ietf/swift-rfc-791
Default branch: main
README: README.md