-
Notifications
You must be signed in to change notification settings - Fork 0
IPv4 Protocol
IPv4 packet processing with fragment reassembly, forming the foundation of JNode's network stack.
JNode's IPv4 implementation is the network layer at the heart of the custom network stack. The IPv4NetworkLayer class acts as the NetworkLayer interface implementation, receiving packets from the link layer via NetworkLayerManager, routing them to the appropriate transport layer (TCP, UDP, ICMP, RAW), and handling outbound packet transmission with routing decisions. The layer maintains a HashMap<Integer, IPv4Protocol> mapping IP protocol numbers to handler instances, and a separate fragment table for reassembly.
IPv4Constants defines all standard IP protocol numbers (TCP=6, UDP=17, ICMP=1, etc.), fragmentation flags (IP_MF, IP_DF, IP_FRAGOFS_MASK), route flags (RTF_UP, RTF_GATEWAY, etc.), and network class limits.
| Class / File | Role |
|---|---|
net/src/net/org/jnode/net/ipv4/layer/IPv4NetworkLayer.java |
Central IPv4 network layer: packet receive, checksum validation, fragment reassembly, protocol routing, ARP cache update, statistics |
net/src/net/org/jnode/net/ipv4/IPv4Header.java |
IPv4 header: 20-byte header parsing/construction, fragment flags, checksum validation, address swapping |
net/src/net/org/jnode/net/ipv4/IPv4Constants.java |
Protocol numbers (TCP=6, UDP=17, ICMP=1, etc.), fragmentation bits, route flags, network class limits |
net/src/net/org/jnode/net/ipv4/IPv4FragmentList.java |
Fragment reassembly tracker: ordered fragment assembly, timeout-based lifecycle, completeness check |
net/src/net/org/jnode/net/ipv4/IPv4RoutingTable.java |
Route table: host-route lookup, network-route lookup with subnet matching, default gateway fallback |
net/src/net/org/jnode/net/ipv4/IPv4Route.java |
Individual route entry with destination, gateway, subnet mask, flags, and MTU |
net/src/net/org/jnode/net/ipv4/IPv4Address.java |
32-bit IPv4 address representation and manipulation |
net/src/net/org/jnode/net/ipv4/IPv4Service.java |
Interface for transmit(), getRoutingTable(), and protocol lookup |
net/src/net/org/jnode/net/ipv4/IPv4Utils.java |
Internet checksum calculation (ones-complement, header validation) |
net/src/net/org/jnode/net/ipv4/IPv4Protocol.java |
Interface for transport protocols that can receive ICMP error notifications |
Network Device
→ NetDeviceAPI.receive(SocketBuffer)
→ NetworkLayerManager.receive(skbuf)
→ IPv4NetworkLayer.receive(skbuf, deviceAPI)
1. Create IPv4Header from skbuf
2. Validate checksum (drop if bad)
3. Pull header bytes, trim to dataLength
4. Update ARP cache (src MAC + src IP)
5. Check destination address (process if for me)
6. If fragment → deliverFragment() → IPv4FragmentList
Else → deliver() → IPv4Protocol.receive(hdr, skbuf)
7. Periodic cleanup of dead fragments (every 2 * IP_FRAGTIMEOUT)
The header is 20 bytes minimum (IHL * 4). Fields parsed on receive:
- Version (4 bits): extracted from upper nibble of byte 0
- IHL (4 bits): header length multiplier
- TOS (1 byte): type of service
- Total Length (2 bytes): full packet length minus any link layer headers
- Identification (2 bytes): fragmentation reassembly key component
-
Flags + Fragment Offset (2 bytes):
IP_DF(0x4000),IP_MF(0x2000), offset masked withIP_FRAGOFS_MASK(0x1FFF), shifted left by 3 - TTL (1 byte): time-to-live, decremented per hop
- Protocol (1 byte): next-layer protocol ID (1=ICMP, 6=TCP, 17=UDP)
-
Source Address (4 bytes): parsed into
IPv4Address -
Destination Address (4 bytes): parsed into
IPv4Address -
Checksum (2 bytes): validated via
IPv4Utils.calcChecksum
Checksum is set to 0xFFFF if the computed value is zero (RFC 1122 compliance). Source address is inserted by the sender.
Fragments are tracked via IPv4FragmentList, keyed by identification-protocol-srcIP-dstIP. When a fragment arrives:
- Look up fragment list by key
- If not found, create a new
IPv4FragmentList - Insert at correct offset position (checking for overlaps)
- Track
haveFirstFragmentandhaveLastFragmentflags - If
isComplete()(first+last fragment, single list entry), deliver to protocol - Periodically remove lists where
isAlive()returns false (timeout:IP_FRAGTIMEOUT = 120000ms)
IPv4NetworkLayer delegates to IPv4Sender. The sender:
- Looks up route via
IPv4RoutingTable.search(dst) - Gets destination MAC via ARP resolution
- Sets source/destination IP in header
- Increments TTL, sets identification
- Computes and writes checksum
- Sends via the route's device
Three-tier lookup in IPv4RoutingTable.search():
-
Host routes — exact destination match (
r.isHost() && r.isUp()) -
Network routes — subnet mask match (
r.matches(destination, subnetMask)) -
Default gateway — any gateway route (
r.isGateway() && r.isUp())
ConcurrentModificationException is caught and retried (the list can be modified by another thread during traversal).
-
Checksum corner case:
IPv4Utils.calcChecksumreturns~chsum. For a zero-checksum (all zeros), this produces0xFFFF. On write,prefixTo()converts 0 to0xFFFFto represent zero (RFC 1122). A true zero checksum is computed as0x0000only when the checksum field itself is zeroed and the computed value is 0, which should not happen in normal packets. -
Fragment reassembly buffering: Fragments are held in
IPv4FragmentListuntil complete or timed out. There is no limit on the number of concurrent fragment lists — a DoS attack could exhaust memory. - TTL decrement is not performed: The stack reads TTL but does not decrement it during forwarding. This means packets never expire in the stack; TTL is purely informational unless the stack implements forwarding.
- No fragmentation on send: The outbound path does not check MTU before sending. If the packet exceeds the device MTU, it may be silently dropped or cause hardware issues.
- ARP cache update on every packet: Every inbound IPv4 packet updates the ARP cache with the source IP-to-MAC mapping. This is a passive ARP table update mechanism.
- Fragment key includes source address: This prevents fragments from different sources being mixed (which is correct per RFC 791).
-
Minimum fragment size:
IP_MIN_FRAG_SIZE = 8bytes. Fragments smaller than this are still tracked — the check is informational. -
ChecksumOk flag: When constructing a header from a buffer, the checksum is validated and stored. When creating a header programmatically,
checksumOk = trueunconditionally — the caller is responsible for ensuring correctness.
- Network-Stack — Hub page for the complete network stack
- Network-Layers — Three-layer architecture including IPv4's role as NetworkLayer
- TCP-Protocol — TCP over IPv4
- UDP-Protocol — UDP over IPv4
- ARP — IPv4-to-MAC resolution (used by IPv4 layer)