Packet Capture — tcpdump আর Wireshark দিয়ে সত্য দেখা
Packet Capture with tcpdump and Wireshark
Theory-র চূড়ান্ত পরীক্ষা wire-এর কাছে — kernel tap থেকে BPF VM, capture-vs-display filter grammar, retransmission-coloring, আর pcap parser from scratch; packets don't lie।
আগে এটা বুঝি
Module জুড়ে আমরা protocol-গুলোর গল্প শুনেছি — DORA চার ধাপ, TLS এক round-trip, QUIC stream-multiplexing। কিন্তু গল্প আর সত্য মিলে যায় কি? Documentation bug-হতে পারে, implementation deviate হতে পারে, middlebox চুপচাপ ভাঙতে পারে।
Networking-এ সত্যের একটাই উৎস: wire-এ আসলে যা গেল। আর wire পড়ার tool — tcpdump command-line-এ, Wireshark GUI-তে। দুজনেই একই ফাউন্ডেশনে (libpcap), একই file-format (pcap), কিন্তু philosophy ভিন্ন: tcpdump scalpel, Wireshark microscope।
আজ তিনটা কাজ: (১) capture-র architecture — kernel tap থেকে BPF virtual-machine; (২) দুই filter-language; (৩) সবচেয়ে satisfying — pcap-format নিজের হাতে parse করা, struct দিয়ে, endianness-পাঠ সরাসরি কাজে লাগবে।
মূল ধারণা
libpcap architecture — packet-এর user-space যাত্রা
NIC (interface)
│ frame arrives
▼
kernel driver ──▶ normal path ──▶ TCP/IP stack ──▶ app socket
│ (app-দেখা traffic)
├─ kernel TAP: প্রতিটা inbound/outbound frame-এর copy
▼
BPF filter VM ◀── compiled filter-program (tcpdump expression)
│ pass?
▼
ring buffer (shared memory)
▼
libpcap reader ──▶ tcpdump / Wireshark / আপনার scriptতিনটা design-decision:
(১) Tap = observer, interceptor না। Original packet normal-path-এই যায়; tap duplicate নেয়। Capture চালু থাকলেও traffic slow হয় না (buffer-overrun ছাড়া)।
(২) Filter compile হয় kernel-এ। tcpdump port 443 expression আগে
BPF bytecode-এ compile (tcpdump -d দিয়ে দেখুন!), kernel-এ load;
প্রতিটা frame-এ VM-চালানো match-test — fail মানে copy-ই নেই। McCanne-
Jacobson (1993)-এর contribution: filter-as-program, filter-as-parameter
নয়:
tcpdump -d 'tcp port 80'
# (000) ldh [12] ← ethertype field পড়ো
# (001) jeq #0x0800 jt 2 jf 10 ← IPv4?
# (009) jeq #0x0050 jt 12 jf 13 ← port 80?
# ... register-machine code!(৩) Ring buffer। Tool ধীর হলে frames জমে; overflow = dropped-counter
(tcpdump শেষে বলে)। High-rate-এ -B buffer-size আর -s snapshot-length
ছোট-রাখা survival-skill।
Promiscuous vs monitor
| Mode | কী দেখে | কখন |
|---|---|---|
| Normal | নিজের MAC + broadcast | default |
| Promiscuous | segment-এর সব frame | hub-era legacy; switched LAN-এ broadcast/multicast + নিজের port |
| Monitor (wifi-only) | 802.11 mgmt/ctrl frames raw | wifi-analysis, channel-hopping |
Switched-network reality: switch MAC-learning করে unicast শুধু destination-port-এ পাঠায় — promiscuous-ও প্রতিবেশীর unicast দেখে না। Full-LAN visibility = admin-এর SPAN/mirror-port (authorized path)। Wifi-monitor আলাদা universe — frame-format-ই ভিন্ন (radiotap + 802.11), Ethernet-assumption ভাঙে।
Capture filter vs display filter — দুই ভাষা
CAPTURE (BPF — kernel-এ, সরল):
host 192.168.1.50 net 10.4.0.0/24 port 443
src 10.0.0.5 and udp not port 22 icmp or arp
tcp[13] & 2 != 0 ← SYN-bit byte-test!
DISPLAY (Wireshark — captured-file-এ, সমৃদ্ধ):
http.request.method == POST
ip.addr == 192.168.1.50 and tcp.port == 443
tcp.analysis.retransmission
http.response.code == 304পার্থক্য syntax-ও, timing-ও: capture-filter ঠিক করে কী record হবে (miss = চিরতরে হারাল); display-filter record-sea-তে কী দেখবেন (যত খুশি বদলান)। Strategy: capture চওড়া, display সরু — over-aggressive kernel-filter evidence চিরতরে মুছে দেয়। তবু high-volume-এ kernel-filter অপরিহার্য (disk/buffer-save)।
Wire-এ TCP conversation পড়ার toolkit
- Follow Stream — bidirectional bytestream → chat-transcript (client-red/server-blue); plaintext-HTTP পুরো পড়া যায়
- Expert Info — out-of-order, dup-ack, retransmission, zero-window, reset classification
- Coloring rules — black/red = bad (retransmit/RST), gray = checksum-warn
- iRTT — SYN→SYN-ACK delta = measured initial RTT — geo-distance proxy!
- Time column delta-mode — প্রতি packet-এর gap — latency-hunting lens
ভেতরে কী ঘটছে
Latency forensics — timestamps-এ অনুসন্ধান
Slow page-load-এর annotated trace:
No. time(s) delta summary
1 0.000000 SYN → client
2 0.043112 43.1ms ← SYN-ACK iRTT=43ms!
3 0.043190 0.08ms ACK → client
4 0.044100 0.91ms ClientHello → TLS
5 0.086900 42.8ms ← ServerHello+cert server
9 0.131500 44.6ms ← HTTP 200 OK server
10 0.132000 0.50ms → GET /style.css client
12 ... [tcp.analysis.retransmission]
13 0.520400 344.6ms! ← retransmitted segment serverReading-rule: delta বড় হলে জিজ্ঞেস করো কার ঘুম ভাঙছে।
- ~RTT-sized deltas (৪০+ms) প্রতি exchange-এ = physical-distance RTT — normal, unavoidable (CDN-lesson মনে করুন!)
- sub-ms = local processing — fine
- 300ms+ spike + retransmission-flag = loss+recovery — HOL-family pain-এর বাস্তব খরচ
- asymmetric pattern (tiny-fast request, huge-slow response) = download-heavy — bandwidth-story, RTT-story নয়
iRTT magic: same-site two-connection-এ 40ms vs 250ms — প্রথমটা CDN-edge, দ্বিতীয়টা origin-direct; এক field-এ CDN-effectiveness audit!
Rotating captures — দীর্ঘ hunt
sudo tcpdump -i en0 -w /tmp/cap.pcap -C 50 -W 8 'port 443'
# -C 50: প্রতি ফাইল 50MB; -W 8: max ৮ ফাইল — পুরনো overwriteProduction incident-response standard: rotating-capture background-এ,
incident-ঘটলে শেষ N-minute window already preserved। -G 3600 time-based
hourly variant।
উদাহরণ
পূর্ণ conversation decode — handshake থেকে close
Local HTTP-request-এর tcpdump-view:
1 IP 127.0.0.1.51234 > 127.0.0.1.8000: Flags [S], seq 1000
2 IP 127.0.0.1.8000 > 127.0.0.1.51234: Flags [S.], seq 5000, ack 1001
3 IP 127.0.0.1.51234 > 127.0.0.1.8000: Flags [.], ack 5001
4 IP 127.0.0.1.51234 > 127.0.0.1.8000: Flags [P.], seq 1001:1150, ack 5001
payload: GET / HTTP/1.1... (PSH: app-data!)
5 IP 127.0.0.1.8000 > 127.0.0.1.51234: Flags [.], ack 1150
6 IP 127.0.0.1.8000 > 127.0.0.1.51234: Flags [P.], seq 5001:6350, ack 1150
payload: HTTP/1.1 200 OK...
7 IP 127.0.0.1.51234 > 127.0.0.1.8000: Flags [.], ack 6350
8 IP 127.0.0.1.51234 > 127.0.0.1.8000: Flags [F.], seq 1150, ack 6350
9 IP 127.0.0.1.8000 > 127.0.0.1.51234: Flags [F.], seq 6350, ack 1151
10 IP 127.0.0.1.51234 > 127.0.0.1.8000: Flags [.], ack 6351Drill: [S] [S.] [.] = three-way handshake হুবহু diagram-অনুযায়ী;
P. = PSH+ACK data-carrying; line-4 seq 1001:1150 byte-range notation
(149-byte payload); lines 8-9 graceful close — দুইদিকে FIN+ACK, half-close-
concept live; মোট ১০ packet per request — overhead-হিসাবের raw-material।
Wireshark extra: colorize, expert-info (healthy conversation = quiet), follow-stream side-by-side, Statistics → Conversations per-host bytes।
ছবিতে
Capture-stack আর pcap-file anatomy
CAPTURE PATH PCAP FILE FORMAT
┌────────────────────────┐
┌──────────┐ │ Global Header (24B) │
│ NIC │ frame │ magic a1b2c3d4 │
└────┬─────┘ │ version 2.4 │
▼ │ snaplen linktype(1=Eth)│
kernel driver ├────────────────────────┤
├─ normal: stack → app │ Record #1: │
▼ │ ts_sec ts_usec │
kernel TAP (copy) │ incl_len orig_len │
▼ │ ── frame bytes ── │
BPF filter VM ◀─ bytecode ├────────────────────────┤
▼ pass? │ Record #2 ... EOF │
ring buffer (mmap) └────────────────────────┘
▼
libpcap API → tcpdump / Wireshark /
আপনার Python struct-parser
magic-এর byte-order = writer-endianness! a1b2c3d4 big-endian লিখলে
d4c3b2a1 little-endian — parser দুটোই চিনবে। incl_len < orig_len ⇒
snapshot truncation।নিজে চালিয়ে দেখুন
Guided capture — নিজের browsing ধরুন, ১০ filter-drill পাস করুন
Scope: localhost + নিজের machine — ethics-gate satisfied।
ধাপ ১ — test server:
mkdir -p /tmp/capsite && cd /tmp/capsite
echo '<html><body><h1>capture me</h1></body></html>' > index.html
python3 -m http.server 8000ধাপ ২ — capture (দ্বিতীয় terminal):
sudo tcpdump -i any -nn -s 96 -w /tmp/browse.pcap 'tcp port 8000'
# macOS loopback না ধরলে: -i lo0
# -nn: name-resolution off; -s 96: headers-only snapshotধাপ ৩ — traffic: browser refresh / curl http://localhost:8000
কয়েকবার; Ctrl-C।
ধাপ ৪ — দুই ভাষায় analysis:
tcpdump -nn -r /tmp/browse.pcap
open -a Wireshark /tmp/browse.pcap # follow-stream try!Checklist: Follow TCP Stream (GET+response readable?), Statistics →
Conversations, filter-bar http.request। HTTPS-এ সব TLS-record হয়ে
অদৃশ্য — plaintext-local-server-ই শেখার মাঠ।
ধাপ ৫ — ১০টা capture-filter drill (আগে নিজে লিখুন):
১. 192.168.1.50-এর সাথে either-direction সব
২. শুধু HTTP (port 80)
৩. 10.4.0.0/24 subnet-এর সব
৪. SSH (22) বাদে সব
৫. ICMP ping শুধু
৬. DNS query শুধু (UDP 53)
৭. শুধু SYN packets — hint: tcp[13] & 2
৮. 10.0.0.5 থেকে বেরোনো UDP
৯. port 80 বা 443 — কিন্তু host 192.168.1.1 নয়
১০. ARP trafficAnswers:
১. host 192.168.1.50 ৬. udp port 53
২. port 80 ৭. tcp[13] & 2 != 0
৩. net 10.4.0.0/24 ৮. src 10.0.0.5 and udp
৪. not port 22 ৯. (port 80 or port 443) and not host 192.168.1.1
৫. icmp ১০. arpDrill-৭-এর tcp[13]: TCP-header-এর 13th byte = flags; & 2 = SYN-mask।
Wireshark-equivalent: tcp.flags.syn == 1 && tcp.flags.ack == 0 — এক
concept, দুই grammar।
Plaintext local-HTTP browsing-এর পূর্ণ capture নিজে নিয়ে filter/Wireshark/follow-stream দিয়ে dissect করলে theory-র প্রতিটা claim হাতে verify হয়।
নিজে বানান
read_pcap.py — pcap parser from scratch: struct → Ethernet → IP → TCP
- Magic 4-byte দেখে endianness decide (a1b2c3d4 vs d4c3b2a1)
- Global header unpack: version/snaplen/linktype validate
- Loop: per-packet 16-byte record-header (ts_sec,ts_usec,incl_len,orig_len)
- Frame → Ethernet → IPv4 (ihl,proto,addrs) → TCP (ports,flags)
- Mini-table print + tcpdump -r দিয়ে verify
~110 লাইন, stdlib struct:
#!/usr/bin/env python3
"""read_pcap.py FILE — classic-pcap parser: eth→ip→tcp mini-table"""
import socket
import struct
import sys
def mac(b):
return ':'.join(f'{x:02x}' for x in b)
def ipv4(b):
return socket.inet_ntoa(b)
def decode_frame(frame):
if len(frame) < 14:
return None
dst, src = frame[:6], frame[6:12]
etype = int.from_bytes(frame[12:14], 'big')
if etype != 0x0800:
return ('non-ip', f'{mac(src)}>{mac(dst)} etype={etype:#06x}', '')
ip = frame[14:]
if len(ip) < 20:
return None
ihl = (ip[0] & 0x0F) * 4
proto = ip[9]
src, dst_ip = ipv4(ip[12:16]), ipv4(ip[16:20])
l4 = ip[ihl:]
if proto == 6 and len(l4) >= 20: # TCP
sport, dport = struct.unpack('!HH', l4[:4])
flags = l4[13]
bits = [(flags & 0x01, 'F'), (flags & 0x02, 'S'), (flags & 0x04, 'R'),
(flags & 0x08, 'P'), (flags & 0x10, 'A'), (flags & 0x20, 'U')]
fl = ''.join(ch for bit, ch in bits if bit) or '.'
seq = int.from_bytes(l4[4:8], 'big')
return ('tcp', f'{src}.{sport} > {dst_ip}.{dport}', f'[{fl}] seq={seq}')
if proto == 17 and len(l4) >= 8: # UDP
sport, dport = struct.unpack('!HH', l4[:4])
return ('udp', f'{src}.{sport} > {dst_ip}.{dport}', '')
return ('other', f'{src} > {dst_ip}', f'proto={proto}')
def main(path):
with open(path, 'rb') as fh:
data = fh.read()
magic = data[:4]
if magic == b'\xa1\xb2\xc3\xd4':
endian = '>' # big-endian writer
elif magic == b'\xd4\xc3\xb2\xa1':
endian = '<' # little-endian (common)
elif magic == b'\x0a\x0d\x0d\x0a':
sys.exit('pcapng detected — editcap -F pcap দিয়ে convert করুন')
else:
sys.exit(f'unrecognized magic {magic.hex()}')
vmaj, vmin, _tz, _sig, snaplen, linktype = struct.unpack(
endian + 'HHiIII', data[4:24])
print(f'# pcap v{vmaj}.{vmin} snaplen={snaplen} '
f'endian={"big" if endian == ">" else "little"}')
if linktype != 1:
sys.exit('# শুধু Ethernet (linktype 1) supported')
off, n = 24, 0
print(f'{"#":>3} {"timestamp":>15} {"flow":<44} info')
while off + 16 <= len(data):
ts_sec, ts_usec, incl_len, orig_len = struct.unpack(
endian + 'IIII', data[off:off + 16])
off += 16
frame = data[off:off + incl_len]
off += incl_len
n += 1
decoded = decode_frame(frame)
if decoded is None:
continue
kind, flow, info = decoded
stamp = f'{ts_sec}.{ts_usec:06d}'
trunc = ' SNAP-TRUNCATED' if incl_len < orig_len else ''
print(f'{n:>3} {stamp:>15} {kind:<5} {flow:<38} {info}{trunc}')
print(f'# total packets: {n}')
if __name__ == '__main__':
main(sys.argv[1] if len(sys.argv) > 1 else '/tmp/browse.pcap')Verify against ground truth:
tcpdump -nn -r /tmp/browse.pcap | head -6
python3 read_pcap.py /tmp/browse.pcap | head -8
# flows, flags, seq — হুবহু মিলবে (timestamp formatting ভিন্ন, values এক)Endianness-lesson-এর payoff: Mac (little-endian) আর old-Sparc (big-endian)
writer-এর file এক parser-ই পড়ে — শুধু endian prefix বদলে।
নিজে বাড়ান: (১) UDP/DNS question-name decode; (২) truncated-TCP-header
handling (incl_len < 54 guard); (৩) per-flow stats-dict; (৪) pcapng
block-based global-header parse।
বাস্তব সিস্টেমে
Packet capture বাস্তবে
Incident-response/SRE। Production-outage debugging-এ last-resort superpower: pre-positioned rotating-capture → incident-window replay → retransmission-storm/RST-bomb ধরা। Cloud/AWS-scale-এ eBPF/XDP continuous observability — BPF-idea-র modern incarnation, drop-reason tracing পর্যন্ত।
Security-এর দুই মুখ। Defensive: IDS/IPS (Snort/Suricata) — pcap-stream-এ signature/anomaly-engine; forensic evidence-chain। Attacker-side awareness: same-tools reconnaissance — তাই encryption-everywhere (TLS 1.3, DoH) আর visibility-loss tension industry-র চলমান যুদ্ধ।
Protocol-development নিত্যসঙ্গী। QUIC-interop testing workflow: capture → qlog/Wireshark-dissect → spec-compliance diff। Stevens-এর Illustrated-এর সব diagram tcpdump-session-জন্ম — book-writing method-ই আজকের lesson।
Privacy-law। GDPR/ePrivacy-র অধীনে employee-traffic capture-এ impact-assessment; corporate monitoring disclosure বহু jurisdiction-এ mandatory। Technical-power বড়, governance-ও তাই — access-control আর retention-policy infrastructure-feature, afterthought নয়।
আপনার next step। Home-router DNS-audit (কোন device কাকে query?), IoT phone-home check — defensive-curiosity-র সঠিক মাঠ। Wireshark sample-capture wiki — হাজার হাতে-গড়া trace free library।
যে ভুলগুলো সবাই করে
“Wireshark HTTPS password-ও দেখাতে পারে — TLS নিরাপদ নয়।”
দেখায় শুধু key-log-file (SSLKEYLOGFILE) available হলে — যেটা browser আপনার নিজের machine-এ, নিজের config-এ export করে। Network-observer-র key নেই; ECDHE forward-secrecy মানে recorded-traffic future-key-তেও decrypt হয় না। Wireshark-decryption = endpoint-cooperation feature, wire-attack নয়। ভুলটা false-paranoia জন্মায়, আর সত্যিকারer metadata-leak (SNI/DNS) ignore করায়।
“Promiscuous mode চালু করলেই অফিসের সবার traffic দেখা যাবে।”
Hub-era truth, switched-era myth। Switch MAC-learning-এ unicast শুধু destination-port-এ — wire-এ frame পৌঁছায়-ই না। দেখা যাবে: নিজের traffic, broadcast/multicast, flooding-attacks (CAM-table overflow!)। Full-visibility = admin SPAN/TAP — authorized path।
“Capture আর display filter interchangeable — শুধু লেখা ভিন্ন।”
Timing-semantics-ই মূল: capture-filter kernel-এ arrival-moment-এ — reject মানে record-ই নেই, undo নেই; display-filter post-hoc view। Rule: evidence-collection broad, investigation narrow। Grammar-paradigm-ও ভিন্ন: BPF positional byte-test DSL (fast, kernel), Wireshark protocol-field-aware expression-tree (expressive, post-hoc)।
“tcpdump আর Wireshark alternative — একটা শিখলেই হবে।”
এক foundation (libpcap+pcap) — skill-transfer near-total; তবে workflow
complementary: tcpdump servers/headless/scriptable; Wireshark deep-dissect/follow-stream/expert-heuristics।
Production-flow: remote-box-এ tcpdump -w, laptop-এ Wireshark analysis।
Pair-ই complete।
বুঝেছেন কি না দেখুন
1BPF compile-to-kernel design না থাকলে (সব frame user-space-এ উঠে তারপর
filter) কী খরচ বাড়ত? কোন use-case-এ old-model তবু ভালো?
যুক্তি
খরচ: প্রতি frame kernel→user copy (memory-bandwidth+syscall), context-switch, buffer-pressure — gigabit+ box-এ CPU capture-ই খায়, drops বাড়ে। Kernel-BPF non-matching frame-এ copy-ই বাঁচায়। Old-model ভালো highly-dynamic interactive-filtering-এ (Wireshark live-click exploration) — per-change kernel-reload দামি হতো; তাই layered filtering আজও: broad-kernel + rich-user-display।
2iRTT 38ms connection-এ হঠাৎ ৫ dup-ack, 310ms gap, retransmission, তারপর
normal — event-chain explain করুন; user-symptom কী?
প্রয়োগ
Chain: segment lost → receiver-hole-পরের segments dup-ACK trigger → sender fast-retransmit → recovery-window ≈ observed 310ms (~2×RTT+processing) → resume। Symptom: single-object fetch jerk; h2-page-এ সব-stream freeze (transport-HOL — QUIC ghost!)। Dup-ack-count + gap-ratio-ই loss-vs-latency differential-diagnosis।
3snaplen-truncation disk বাঁচায়। কোন analysis silently ভাঙে? Parser-এ
incl_len-orig_len check কেন?
যুক্তি
snaplen-truncation disk বাঁচায়। কোন analysis silently ভাঙে? Parser-এ
incl_len-orig_len check কেন?Payload-dependent সব: HTTP content, DNS names, TLS certs; বড় TCP-options (timestamps, SACK — latency-fields!); tunnel-inner protocols। Parser-check কারণ: truncated-frame-এ offset-read silent-garbage — length-guard ছাড়া struct ভুল bytes-ই নেয়; explicit flag honest-reporting। Truncation-awareness = correctness-vs-storage budget-decision, accidental নয়।
4Microservice-cluster-এ intermittent p99-spikes, root-cause unknown —
capture-based investigation-plan: placement, filters, retention, privacy-guard।
ডিজাইন
Placement: suspected-hop boundaries (pod-loopback, node-eth0, LB-front) —
gap-triangulate। Capture: rotating-ring (-C 100 -W 10) background,
broad-scoped filter, -s 128; alert-triggered ring-freeze। Analysis:
io-graph + tcp.analysis.flags density, iRTT-trend per-peer। Retention:
72h rolling। Privacy: snapshot-len minimization (TLS stays encrypted —
metadata-analysis), export-audit-log, policy-doc। Design-moral: observability
pre-built + governed — panic-time improvisation নয়।
5pcap global-header fields, record-header fields, আর magic-values?
স্মরণ
Global (24B): magic (endianness-marker a1b2c3d4/d4c3b2a1), version 2.4, thiszone+sigfigs (historical), snaplen, linktype (1=Ethernet)। Record-header (16B): ts_sec, ts_usec, incl_len (stored), orig_len (wire-actual — truncation-detector: incl less than orig)। Build-এ হুবহু layout-unpack করেছেন।
এরপর কী
Module wrap — networking-এর যাত্রা শেষ
Level-7 module পূর্ণ। যাত্রা: wire-physics (physical) → Ethernet-framing → ARP → IP-routing → subnetting → IPv6 → BGP → NAT → ICMP → UDP/TCP → DHCP-bootstrap → TLS-trust → HTTP-ভাষা → QUIC-reinvention → WebSocket-duplex → edge-scale → আজ capture-এ সবকিছুর সত্য-পরীক্ষা।
এক অভ্যাস নিয়ে যান: claims demand traces। Protocol-document যা-ই
বলুক, sudo tcpdump -i any -nn সবচেয়ে সৎ উত্তরদাতা।
এরপর Level 8 — Databases। Data-র persistence, consistency, query-power: disk থেকে B-tree, ACID-এর আসল অর্থ, indexing-economics, isolation-anomaly-zoo — distributed-systems-এর আগের শেষ ভিত। Networking-module-এর sockets, latency-thinking, failure-models সেখানে প্রতিদিন কাজে — database-ও শেষে এক network-service।
আরও পড়ুন
- The BSD Packet Filter: A New Architecture for User-level Packet Capture — Steven McCanne, Van Jacobson (USENIX 1993) · BPF-র মূল গবেষণাপত্র — filter-to-VM-compilation design-এর জন্মপত্র
- TCP/IP Illustrated, Volume 1 (2nd Edition) — Kevin R. Fall, Richard W. Stevens · tcpdump-output-reading-এর প্রামাণ্য শিক্ষক — পুরো বইটাই capture-trace-driven
- RFC 793 — Transmission Control Protocol — J. Postel (ed.) · Flags, sequence semantics — Wireshark TCP-analysis heuristics-গুলোর ভিত্তি