Network Protocols Reference

ProRT-IP implements multiple network protocols for scanning including TCP, UDP, ICMP, ICMPv6, and application-layer protocols. This document provides comprehensive technical reference for protocol implementations, packet structures, and RFC compliance.

Protocol Architecture

Layer Model

┌─────────────────────────────────────────┐
│        Application Layer                │
│    (DNS, SNMP, NTP, NetBIOS, etc.)     │
├─────────────────────────────────────────┤
│        Transport Layer                  │
│         (TCP / UDP)                     │
├─────────────────────────────────────────┤
│        Network Layer                    │
│    (IPv4 / IPv6 / ICMP / ICMPv6)       │
├─────────────────────────────────────────┤
│        Data Link Layer                  │
│         (Ethernet)                      │
└─────────────────────────────────────────┘

Implementation Overview

ProtocolModuleRFC ComplianceKey Features
TCPpacket_builder.rsRFC 793, 7323All flags, options (MSS, WScale, SACK, Timestamp)
UDPpacket_builder.rsRFC 768Protocol-specific payloads
IPv4packet_builder.rsRFC 791Fragmentation, TTL control
IPv6ipv6_packet.rsRFC 8200Extension headers, flow labels
ICMPv6icmpv6.rsRFC 4443Echo, NDP, Router Discovery
ICMPpnet crateRFC 792Echo, Unreachable

TCP Protocol Implementation

Header Structure

 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
├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤
│          Source Port          │       Destination Port        │
├─────────────────────────────────────────────────────────────────┤
│                        Sequence Number                          │
├─────────────────────────────────────────────────────────────────┤
│                    Acknowledgment Number                        │
├───────────┬───────┬─┬─┬─┬─┬─┬─┬─────────────────────────────────┤
│  Data     │       │C│E│U│A│P│R│S│F│                               │
│  Offset   │ Res.  │W│C│R│C│S│S│Y│I│           Window              │
│           │       │R│E│G│K│H│T│N│N│                               │
├───────────┴───────┴─┴─┴─┴─┴─┴─┴─┴───────────────────────────────┤
│           Checksum            │         Urgent Pointer          │
├─────────────────────────────────────────────────────────────────┤
│                    Options (if data offset > 5)                 │
├─────────────────────────────────────────────────────────────────┤
│                             Payload                             │
└─────────────────────────────────────────────────────────────────┘

TCP Flags

ProRT-IP implements all 8 TCP flags defined in RFC 793 and RFC 3168:

FlagBitmaskDescriptionScan Usage
FIN0x01Finish - graceful closeFIN scan (stealth)
SYN0x02Synchronize - connection initiationSYN scan (default)
RST0x04Reset - abort connectionResponse detection
PSH0x08Push - immediate delivery-
ACK0x10Acknowledge - data receiptACK scan (firewall mapping)
URG0x20Urgent - priority data-
ECE0x40ECN-Echo (RFC 3168)-
CWR0x80Congestion Window Reduced-

Flag Combinations for Stealth Scans:

Scan TypeFlagsExpected Response (Open)Expected Response (Closed)
SYN0x02SYN+ACKRST
FIN0x01No responseRST
NULL0x00No responseRST
Xmas0x29 (FIN+PSH+URG)No responseRST
ACK0x10RST (unfiltered)RST (unfiltered)

TCP Options

ProRT-IP supports all standard TCP options for fingerprinting and evasion:

#![allow(unused)]
fn main() {
pub enum TcpOption {
    Mss(u16),                    // Maximum Segment Size (kind=2, len=4)
    WindowScale(u8),             // Window Scale factor (kind=3, len=3)
    SackPermitted,               // SACK Permitted (kind=4, len=2)
    Timestamp { tsval, tsecr },  // Timestamps (kind=8, len=10)
    Nop,                         // Padding (kind=1, len=1)
    Eol,                         // End of list (kind=0, len=1)
}
}

Option Details:

OptionKindLengthRFCPurpose
MSS24RFC 879Maximum segment size negotiation
Window Scale33RFC 7323Large window support (up to 1GB)
SACK Permitted42RFC 2018Selective acknowledgment negotiation
Timestamp810RFC 7323RTT measurement, PAWS
NOP11RFC 793Option padding/alignment
EOL01RFC 793End of options list

TcpPacketBuilder Usage

#![allow(unused)]
fn main() {
use prtip_network::{TcpPacketBuilder, TcpFlags, TcpOption};
use std::net::Ipv4Addr;

// Basic SYN packet
let packet = TcpPacketBuilder::new()
    .source_ip(Ipv4Addr::new(10, 0, 0, 1))
    .dest_ip(Ipv4Addr::new(10, 0, 0, 2))
    .source_port(12345)
    .dest_port(80)
    .flags(TcpFlags::SYN)
    .window(65535)
    .build()
    .expect("Failed to build packet");

// SYN with TCP options (mimics real OS)
let packet = TcpPacketBuilder::new()
    .source_ip(Ipv4Addr::new(10, 0, 0, 1))
    .dest_ip(Ipv4Addr::new(10, 0, 0, 2))
    .source_port(12345)
    .dest_port(443)
    .flags(TcpFlags::SYN)
    .window(65535)
    .add_option(TcpOption::Mss(1460))
    .add_option(TcpOption::WindowScale(7))
    .add_option(TcpOption::SackPermitted)
    .build()
    .expect("Failed to build packet");

// IPv6 TCP packet
let src_v6 = "2001:db8::1".parse().unwrap();
let dst_v6 = "2001:db8::2".parse().unwrap();

let packet = TcpPacketBuilder::new()
    .source_port(12345)
    .dest_port(80)
    .flags(TcpFlags::SYN)
    .build_ipv6_packet(src_v6, dst_v6)
    .expect("Failed to build IPv6 packet");
}

Zero-Copy Packet Building

For high-performance scenarios (>100K pps), use buffer pools:

#![allow(unused)]
fn main() {
use prtip_network::{TcpPacketBuilder, TcpFlags, packet_buffer::with_buffer};

with_buffer(|pool| {
    let packet = TcpPacketBuilder::new()
        .source_ip(Ipv4Addr::new(10, 0, 0, 1))
        .dest_ip(Ipv4Addr::new(10, 0, 0, 2))
        .source_port(12345)
        .dest_port(80)
        .flags(TcpFlags::SYN)
        .build_with_buffer(pool)
        .expect("Failed to build packet");

    // Packet slice is valid within this closure
    send_packet(packet);

    pool.reset();
});
}

Performance Comparison:

MethodAllocationTypical Time
build()1 Vec per packet~2-5µs
build_with_buffer()Zero<1µs

UDP Protocol Implementation

Header Structure

 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
├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤
│          Source Port          │       Destination Port        │
├─────────────────────────────────────────────────────────────────┤
│            Length             │           Checksum            │
├─────────────────────────────────────────────────────────────────┤
│                             Payload                             │
└─────────────────────────────────────────────────────────────────┘

UdpPacketBuilder Usage

#![allow(unused)]
fn main() {
use prtip_network::UdpPacketBuilder;
use std::net::Ipv4Addr;

// Basic UDP packet
let packet = UdpPacketBuilder::new()
    .source_ip(Ipv4Addr::new(10, 0, 0, 1))
    .dest_ip(Ipv4Addr::new(10, 0, 0, 2))
    .source_port(12345)
    .dest_port(53)
    .payload(dns_query.to_vec())
    .build()
    .expect("Failed to build packet");

// IPv6 UDP packet
let packet = UdpPacketBuilder::new()
    .source_port(12345)
    .dest_port(53)
    .payload(dns_query.to_vec())
    .build_ipv6_packet(src_v6, dst_v6)
    .expect("Failed to build packet");
}

Protocol-Specific Payloads

ProRT-IP provides well-formed payloads for common UDP protocols to improve detection rates:

PortProtocolPayload Description
53DNSStandard query for root domain
123NTPVersion 3 client request (48 bytes)
137NetBIOSName Service query for *<00><00>
161SNMPGetRequest for sysDescr.0 with community "public"
111RPCSun RPC NULL call (portmapper query)
500IKEIPSec Main Mode SA payload
1900SSDPM-SEARCH discovery request
5353mDNSQuery for _services._dns-sd._udp.local

Usage:

#![allow(unused)]
fn main() {
use prtip_network::protocol_payloads::get_udp_payload;

if let Some(payload) = get_udp_payload(53) {
    // Use DNS-specific payload for better detection
    let packet = UdpPacketBuilder::new()
        .source_port(12345)
        .dest_port(53)
        .payload(payload)
        .build();
}
}

UDP Scan Behavior

UDP scanning is fundamentally different from TCP:

ResponseInterpretation
UDP responsePort is open
ICMP Port UnreachablePort is closed
ICMP Other UnreachablePort is filtered
No responseOpen or filtered

Timing Considerations:

  • UDP scans are 10-100x slower than TCP scans
  • ICMP rate limiting affects response timing
  • Retransmissions required for reliability
  • Protocol-specific payloads improve response rates

IPv4 Protocol Implementation

Header Fields

ProRT-IP provides full control over IPv4 header fields:

FieldSizeDefaultConfigurable
Version4 bits4No
IHL4 bits5 (20 bytes)Auto-calculated
DSCP/ECN8 bits0No
Total Length16 bitsAutoAuto-calculated
Identification16 bitsRandomYes (ip_id())
Flags3 bitsDon't FragmentVia fragmentation
Fragment Offset13 bits0Via fragmentation
TTL8 bits64Yes (ttl())
Protocol8 bits6 (TCP) or 17 (UDP)Auto
Checksum16 bitsAutoAuto-calculated
Source IP32 bitsRequiredYes
Destination IP32 bitsRequiredYes

Checksum Algorithm

IPv4 and TCP/UDP checksums use the Internet checksum algorithm (RFC 1071):

1. Sum all 16-bit words with carry
2. Add any carry overflow
3. Take one's complement

Implementation:

  • IPv4 header checksum: Covers only IP header
  • TCP/UDP checksum: Includes pseudo-header (src IP, dst IP, protocol, length)
  • ICMPv6 checksum: Includes 40-byte IPv6 pseudo-header

IPv6 Protocol Implementation

Header Structure

 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│  Traffic Class  │             Flow Label              │
├───────┴─────────────────┴─────────────────────────────────────┤
│         Payload Length        │  Next Header  │   Hop Limit   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│                         Source Address                          │
│                          (128 bits)                             │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│                      Destination Address                        │
│                          (128 bits)                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Ipv6PacketBuilder Usage

#![allow(unused)]
fn main() {
use prtip_network::ipv6_packet::Ipv6PacketBuilder;
use std::net::Ipv6Addr;

let src = "2001:db8::1".parse::<Ipv6Addr>().unwrap();
let dst = "2001:db8::2".parse::<Ipv6Addr>().unwrap();

let packet = Ipv6PacketBuilder::new(src, dst)
    .hop_limit(64)
    .next_header(6)  // TCP
    .payload(tcp_data)
    .build()
    .expect("Failed to build IPv6 packet");
}

IPv6 vs IPv4 Size Comparison

ComponentIPv4IPv6Difference
IP Header20 bytes40 bytes+20 bytes
TCP Header20 bytes20 bytes0
Minimum Packet40 bytes60 bytes+20 bytes

ICMPv6 Protocol Implementation

Supported Message Types

TypeNameUsage
128Echo RequestHost discovery (ping)
129Echo ReplyResponse to ping
133Router SolicitationRouter discovery
134Router AdvertisementRouter announcement
135Neighbor SolicitationAddress resolution (replaces ARP)
136Neighbor AdvertisementAddress resolution response
1Destination UnreachableError reporting

Icmpv6PacketBuilder Usage

#![allow(unused)]
fn main() {
use prtip_network::icmpv6::Icmpv6PacketBuilder;
use std::net::Ipv6Addr;

let src = "2001:db8::1".parse().unwrap();
let dst = "2001:db8::2".parse().unwrap();

// Echo Request (ping)
let packet = Icmpv6PacketBuilder::echo_request(1234, 1, vec![0xDE, 0xAD])
    .build(src, dst)
    .unwrap();

// Neighbor Solicitation (address resolution)
let target = "fe80::2".parse().unwrap();
let mac = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55];
let packet = Icmpv6PacketBuilder::neighbor_solicitation(target, Some(mac))
    .build(src, "ff02::1:ff00:2".parse().unwrap())
    .unwrap();

// Router Solicitation
let packet = Icmpv6PacketBuilder::router_solicitation(Some(mac))
    .build(src, "ff02::2".parse().unwrap())
    .unwrap();
}

ICMPv6 Checksum

ICMPv6 checksums include a 40-byte pseudo-header (unlike IPv4 ICMP):

Pseudo-header format:
├─ Source Address (16 bytes)
├─ Destination Address (16 bytes)
├─ Upper-Layer Packet Length (4 bytes)
├─ Zero padding (3 bytes)
└─ Next Header: 58 (1 byte)

ICMPv6 Response Parsing

#![allow(unused)]
fn main() {
use prtip_network::icmpv6::Icmpv6ResponseParser;

// Parse Echo Reply
if let Some((identifier, sequence)) = Icmpv6ResponseParser::parse_echo_reply(&packet) {
    println!("Reply from id={} seq={}", identifier, sequence);
}

// Parse Port Unreachable (for UDP scanning)
if let Some((dest_addr, port)) = Icmpv6ResponseParser::parse_port_unreachable(&packet) {
    println!("Port {} on {} is closed", port, dest_addr);
}

// Quick type check
if Icmpv6ResponseParser::is_icmpv6(&packet) {
    let (typ, code) = Icmpv6ResponseParser::get_type_code(&packet).unwrap();
    println!("ICMPv6 type={} code={}", typ, code);
}
}

Evasion Techniques

Bad Checksum

Test firewall/IDS checksum validation:

#![allow(unused)]
fn main() {
// TCP with invalid checksum
let packet = TcpPacketBuilder::new()
    .source_ip(src)
    .dest_ip(dst)
    .source_port(12345)
    .dest_port(80)
    .flags(TcpFlags::SYN)
    .bad_checksum(true)  // Sets checksum to 0x0000
    .build();

// UDP with invalid checksum
let packet = UdpPacketBuilder::new()
    .source_ip(src)
    .dest_ip(dst)
    .source_port(12345)
    .dest_port(53)
    .bad_checksum(true)
    .build();
}

TTL Control

Control packet hop limit for traceroute-style probes:

#![allow(unused)]
fn main() {
let packet = TcpPacketBuilder::new()
    .source_ip(src)
    .dest_ip(dst)
    .source_port(12345)
    .dest_port(80)
    .ttl(10)  // Only traverse 10 hops
    .flags(TcpFlags::SYN)
    .build();
}

RFC Compliance Matrix

RFCTitleImplementation Status
RFC 768UDP✅ Full
RFC 791IPv4✅ Full
RFC 792ICMP✅ Via pnet
RFC 793TCP✅ Full
RFC 879TCP MSS✅ Full
RFC 1071Internet Checksum✅ Full
RFC 2018TCP SACK✅ Full
RFC 3168ECN✅ Flags only
RFC 4443ICMPv6✅ Full
RFC 4861NDP✅ NS/NA/RS
RFC 5681TCP Congestion⚠️ Partial (timing)
RFC 6298TCP RTO✅ Via timing
RFC 7323TCP Extensions✅ Full
RFC 8200IPv6✅ Full

Performance Characteristics

Packet Building Performance

OperationTimeAllocations
TCP SYN (basic)~2µs1
TCP SYN (with options)~3µs1
TCP SYN (zero-copy)<1µs0
UDP (basic)~1.5µs1
UDP (with payload)~2µs1
ICMPv6 Echo~2µs1

Throughput Limits

ScenarioMax Packets/secNotes
SYN scan (standard)~500KSingle-threaded
SYN scan (zero-copy)~1MBuffer pool
UDP scan~100KICMP rate limiting
ICMPv6 scan~200KHost discovery

See Also


Last Updated: 2025-11-21 ProRT-IP Version: v0.5.4