承接上篇,本文專注於從 WinPcap 取得原始封包後的解析邏輯,以 IPv4 為例,詳細說明表頭各欄位含義與標頭檢驗和(Header Checksum)的計算方法。
| 位移 | 長度 | 說明 |
|---|---|---|
| 0-5 | 6 bytes | 目的 MAC 位址 |
| 6-11 | 6 bytes | 來源 MAC 位址 |
| 12-13 | 2 bytes | 乙太網類型 |
| 14 | 1 byte | 版本 (高 4 bits) + 標頭長度 (低 4 bits,單位 4 bytes) |
| 15 | 1 byte | 服務類型 (TOS) |
| 16-17 | 2 bytes | 總長度 = 封包長度 - 14 (乙太網表頭) |
| 18-19 | 2 bytes | 識別碼 |
| 20-21 | 2 bytes | Flags + Fragment Offset |
| 22 | 1 byte | TTL |
| 23 | 1 byte | 協定 (TCP=6, UDP=17, ICMP=1, IGMP=2...) |
| 24-25 | 2 bytes | 標頭檢驗和 |
| 26-29 | 4 bytes | 來源 IP 位址 |
| 30-33 | 4 bytes | 目的 IP 位址 |
| 34+ | 可選 | Options (較少見) |
範圍:從位移 14 開始,長度為 IHL * 4 bytes。步驟:
long sum = 0;
for (int i = 0; i < headLen; i += 2) {
sum += (data[i + 14] << 8) + data[i + 15];
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16); // 防止上一步產生新進位
bool valid = ((short)(~sum) == 0);
下一篇將一併講解 TCP 與 UDP 封包的解析邏輯(也是筆者目前實作支援的兩大傳輸層協定)。