Created
April 12, 2026 09:50
-
-
Save cb341/8819e5b5d5449caa6e245beab3f8a57c to your computer and use it in GitHub Desktop.
IP Frame Schema Reference
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # IPv4 Header Frame Schema - ANSI box drawing | |
| # Grid: 32 bits per row, each bit = 3 chars wide (2 content + 1 separator) | |
| # Total inner width = 32*3 - 1 = 95 chars | |
| R='\033[0m' | |
| B='\033[1;34m' | |
| W='\033[1;37m' | |
| G='\033[1;32m' | |
| Y='\033[1;33m' | |
| C='\033[1;36m' | |
| # Build a horizontal border between two rows. | |
| # For each bit boundary (positions 1..31), decide the junction character: | |
| # - above_split AND below_split: ┼ | |
| # - above_split only: ┴ | |
| # - below_split only: ┬ | |
| # - neither: ─ | |
| # left/right are the edge chars (┌├└ / ┐┤┘) | |
| border() { | |
| local left="$1" right="$2" | |
| shift 2 | |
| local -a above=() below=() | |
| local mode="above" | |
| for arg in "$@"; do | |
| if [ "$arg" = "|" ]; then | |
| mode="below" | |
| continue | |
| fi | |
| if [ "$mode" = "above" ]; then | |
| above+=("$arg") | |
| else | |
| below+=("$arg") | |
| fi | |
| done | |
| printf " ${B}${left}" | |
| for bit in $(seq 0 31); do | |
| # print 2 dash chars for this bit | |
| printf "──" | |
| # after each bit except last, print junction or dash | |
| if [ $bit -lt 31 ]; then | |
| local in_above=0 in_below=0 | |
| local boundary=$((bit + 1)) | |
| for a in "${above[@]}"; do [ "$a" -eq "$boundary" ] && in_above=1 && break; done | |
| for b in "${below[@]}"; do [ "$b" -eq "$boundary" ] && in_below=1 && break; done | |
| if [ $in_above -eq 1 ] && [ $in_below -eq 1 ]; then | |
| printf "┼" | |
| elif [ $in_above -eq 1 ]; then | |
| printf "┴" | |
| elif [ $in_below -eq 1 ]; then | |
| printf "┬" | |
| else | |
| printf "─" | |
| fi | |
| fi | |
| done | |
| printf "${right}${R}\n" | |
| } | |
| # Print a content row. Args: pairs of (num_bits label) | |
| row() { | |
| printf " " | |
| while [ $# -ge 2 ]; do | |
| local nbits=$1 label="$2" | |
| shift 2 | |
| local width=$(( nbits * 3 - 1 )) | |
| local lbl_len=${#label} | |
| if (( lbl_len > width )); then | |
| label="${label:0:$width}" | |
| lbl_len=$width | |
| fi | |
| local pad=$(( (width - lbl_len) / 2 )) | |
| local rpad=$(( width - lbl_len - pad )) | |
| printf "${B}│${Y}%*s%s%*s${R}" $pad "" "$label" $rpad "" | |
| done | |
| printf "${B}│${R}\n" | |
| } | |
| printf "\n${W} IPv4 Header Format${R}\n" | |
| printf "${C} (each column = 1 bit, 32 bits/row)${R}\n\n" | |
| # Bit ruler - each number takes 3 chars (right-aligned in its cell) except last | |
| printf " ${G}" | |
| for i in $(seq 0 31); do | |
| if [ $i -eq 0 ]; then | |
| printf " %d" $i | |
| else | |
| printf " %2d" $((i)) | |
| fi | |
| done | |
| printf "${R}\n" | |
| # Define splits per row (bit positions where fields start, excluding 0) | |
| # Row 1: Ver(0-3) IHL(4-7) DSCP(8-13) ECN(14-15) TotalLen(16-31) -> splits: 4,8,14,16 | |
| # Row 2: ID(0-15) Flags(16-18) FragOff(19-31) -> splits: 16,19 | |
| # Row 3: TTL(0-7) Proto(8-15) Checksum(16-31) -> splits: 8,16 | |
| # Row 4: SrcAddr(0-31) -> splits: none | |
| # Row 5: DstAddr(0-31) -> splits: none | |
| # Row 6: Options(0-23) Padding(24-31) -> splits: 24 | |
| # Top border (nothing above, row1 below) | |
| border "┌" "┐" "|" 4 8 14 16 | |
| # Row 1 | |
| row 4 "Ver" 4 "IHL" 6 "DSCP" 2 "EC" 16 "Total Length" | |
| # Border between row1 and row2 | |
| border "├" "┤" 4 8 14 16 "|" 16 19 | |
| # Row 2 | |
| row 16 "Identification" 3 "Flg" 13 "Fragment Offset" | |
| # Border between row2 and row3 | |
| border "├" "┤" 16 19 "|" 8 16 | |
| # Row 3 | |
| row 8 "TTL" 8 "Protocol" 16 "Header Checksum" | |
| # Border between row3 and row4 | |
| border "├" "┤" 8 16 "|" | |
| # Row 4 | |
| row 32 "Source Address" | |
| # Border between row4 and row5 | |
| border "├" "┤" "|" | |
| # Row 5 | |
| row 32 "Destination Address" | |
| # Border between row5 and row6 | |
| border "├" "┤" "|" 24 | |
| # Row 6 | |
| row 24 "Options (variable)" 8 "Padding" | |
| # Bottom border (row6 above, nothing below) | |
| border "└" "┘" 24 "|" | |
| # Legend box - same inner width as header (95 chars) | |
| LW=95 | |
| lbox_border() { | |
| local left="$1" right="$2" | |
| printf " ${B}${left}" | |
| printf '%0.s─' $(seq 1 $LW) | |
| printf "${right}${R}\n" | |
| } | |
| lbox_line() { | |
| local color="$1" text="$2" | |
| local len=${#text} | |
| local pad=$(( LW - len )) | |
| printf " ${B}│${color}%s%*s${R}${B}│${R}\n" "$text" $pad "" | |
| } | |
| lh() { lbox_line "$Y" " $1"; } # header (yellow) | |
| lv() { lbox_line "$R" " $1"; } # value line | |
| le() { lbox_line "$R" ""; } # empty line | |
| printf "\n" | |
| lbox_border "┌" "┐" | |
| lbox_line "$W" " FIELD REFERENCE" | |
| lbox_border "├" "┤" | |
| le | |
| lh "Version (4 bits)" | |
| lv "4 = IPv4" | |
| lv "6 = IPv6 (not used in IPv4 headers, but reserved)" | |
| le | |
| lh "IHL - Internet Header Length (4 bits)" | |
| lv "5 = 20 bytes (no options, minimum)" | |
| lv "6-15 = 24-60 bytes (with options)" | |
| le | |
| lh "DSCP - Differentiated Services Code Point (6 bits)" | |
| lv "000000 = CS0 (Best Effort / Default)" | |
| lv "001000 = CS1 (Scavenger)" | |
| lv "001010 = AF11 (Assured Forwarding 11)" | |
| lv "001100 = AF12 (Assured Forwarding 12)" | |
| lv "001110 = AF13 (Assured Forwarding 13)" | |
| lv "010000 = CS2 (OAM)" | |
| lv "010010 = AF21 (Assured Forwarding 21)" | |
| lv "010100 = AF22 (Assured Forwarding 22)" | |
| lv "010110 = AF23 (Assured Forwarding 23)" | |
| lv "011000 = CS3 (Signaling)" | |
| lv "011010 = AF31 (Assured Forwarding 31)" | |
| lv "011100 = AF32 (Assured Forwarding 32)" | |
| lv "011110 = AF33 (Assured Forwarding 33)" | |
| lv "100000 = CS4 (Real-Time Interactive)" | |
| lv "100010 = AF41 (Assured Forwarding 41)" | |
| lv "100100 = AF42 (Assured Forwarding 42)" | |
| lv "100110 = AF43 (Assured Forwarding 43)" | |
| lv "101000 = CS5 (Broadcast Video)" | |
| lv "101110 = EF (Expedited Forwarding - low latency)" | |
| lv "110000 = CS6 (Network Control)" | |
| lv "111000 = CS7 (Reserved)" | |
| le | |
| lh "ECN - Explicit Congestion Notification (2 bits)" | |
| lv "00 = Not-ECT (Not ECN-Capable Transport)" | |
| lv "01 = ECT(1) (ECN-Capable Transport)" | |
| lv "10 = ECT(0) (ECN-Capable Transport)" | |
| lv "11 = CE (Congestion Experienced)" | |
| le | |
| lh "Flags (3 bits)" | |
| lv "Bit 0: Reserved (must be 0)" | |
| lv "Bit 1: DF (Don't Fragment)" | |
| lv " 0 = May fragment" | |
| lv " 1 = Don't fragment" | |
| lv "Bit 2: MF (More Fragments)" | |
| lv " 0 = Last fragment" | |
| lv " 1 = More fragments follow" | |
| le | |
| lh "Protocol (8 bits) - common values" | |
| lv "1 = ICMP (Internet Control Message Protocol)" | |
| lv "2 = IGMP (Internet Group Management Protocol)" | |
| lv "6 = TCP (Transmission Control Protocol)" | |
| lv "17 = UDP (User Datagram Protocol)" | |
| lv "41 = IPv6 (IPv6 Encapsulation)" | |
| lv "47 = GRE (Generic Routing Encapsulation)" | |
| lv "50 = ESP (Encapsulating Security Payload)" | |
| lv "51 = AH (Authentication Header)" | |
| lv "89 = OSPF (Open Shortest Path First)" | |
| lv "132 = SCTP (Stream Control Transmission Protocol)" | |
| le | |
| lh "TTL - Time To Live (8 bits)" | |
| lv "Common defaults: 64 (Linux), 128 (Windows), 255 (Cisco)" | |
| lv "Decremented by 1 at each hop; packet discarded at 0" | |
| le | |
| lh "Fragment Offset (13 bits)" | |
| lv "Measured in 8-byte units. Max offset = 8191 x 8 = 65528 bytes" | |
| le | |
| lh "Total Length (16 bits)" | |
| lv "Min = 20 (header only), Max = 65535 bytes" | |
| lv "Includes header + payload" | |
| le | |
| lbox_border "└" "┘" | |
| printf "\n" |
cb341
commented
Apr 12, 2026
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment