1 【原創(chuàng )】借windump初窺網(wǎng)絡(luò )底層
標 題: 【原創(chuàng )】借windump初窺網(wǎng)絡(luò )底層
作 者: thisIs
時(shí) 間: 2012-03-09,15:26:42
鏈 接: http://bbs.pediy.com/showthread.php?t=147644
最近在學(xué)ndis以及網(wǎng)絡(luò )方面的知識,今天借論壇寶地整理一些筆記出來(lái),與大家共同分享下
<太過(guò)基礎的原理就不做說(shuō)明了,大家可以去網(wǎng)上搜索>
首先是各種包的格式定義:
以太頭:
代碼:
// MAC地址長(cháng)度#define MAC_ADDRESS_LEN 6// 常用的以太網(wǎng)幀類(lèi)型#define ETHERNET_FRAME_IP 0x0800 // IP幀 #define ETHERNET_FRAME_ARP 0x0806 // ARP幀 #define ETHERNET_FRAME_RARP 0x8035 // RARP幀 #define ETHERNET_FRAME_IPv6 0x86DD // IP6幀 typedef struct _EthernetHeader // 以太頭{ UCHAR DstMacAddr[MAC_ADDRESS_LEN]; // 目標MAC UCHAR SrcMacAddr[MAC_ADDRESS_LEN]; // 源MAC USHORT FrmType; // 類(lèi)型}EthernetHeader, *PEthernetHeader;
ARP,RARP頭
代碼:
// 定義ARP操作類(lèi)型#define ARP_QUERY 0x0001 // ARP請求 #define ARP_REPLY 0x0002 // ARP應答#define RARP_QUERY 0x0003 // RARP請求#define RARP_REPLY 0x0004 // RARP應答// 定義ARP硬件類(lèi)型#define ARP_ETHER 0x0001 // 以太網(wǎng)格式#define ARP_IEEE802 0x0006 // 令牌環(huán)網(wǎng)#define ARP_FRELAY 0x000f // 幀中繼硬件格式typedef struct _ArpHeader // ARP頭<RARP>{ USHORT HrdType; // 硬件類(lèi)型 USHORT ProType; // 協(xié)議類(lèi)型 UCHAR HrdAddrLen; // 硬件地址長(cháng)度 UCHAR ProAddrLen; // 協(xié)議地址長(cháng)度 USHORT Opr; // 操作字段 <是ARP請求或者應答 異或RARP請求或者應答> UCHAR SrcMacAddr[MAC_ADDRESS_LEN]; // 發(fā)送端的MAC地址 ULONG SrcIp; // 發(fā)送端的IP地址 UCHAR DstMacAddr[MAC_ADDRESS_LEN]; // 目的MAC地址 ULONG DstIp; // 目的IP地址}ArpHeader, *PArpHeader;typedef struct _ARPPACKET // ARP封包{ EthernetHeader Ehhdr; ArpHeader Arphdr;}ARPPACKET, *PARPPACKET;
IP頭
代碼:
0 15 31-----------------------------------------------------------------| ver | HL | TOS | Total len |-----------------------------------------------------------------| Packet id |0|D|M| Fragment Offset |-----------------------------------------------------------------| TTL | protocol | checksum |-----------------------------------------------------------------| source ip address |-----------------------------------------------------------------| dest ip address |-----------------------------------------------------------------| Optional |-----------------------------------------------------------------| Data |-----------------------------------------------------------------// 定義IP數據報中的協(xié)議類(lèi)型#define ICMP_PROTOCOL 0x0001 // ICMP 報文#define IGMP_PROTOCOL 0x0002 // IGMP 報文#define TCP_PROTOCOL 0x0006 // TCP 報文#define UDP_PROTOCOL 0x0011 // UDP 報文 17// IP標志#define IP_DF_MASK 0x4000 // 如果置位,表示不能被分割#define IP_MF_MASK 0x2000 // 為1表示還有更多的數據報分片 為0表示已經(jīng)是最后一個(gè)分片typedef struct _IPHeader // IP頭 20 BYTES{ UCHAR Ver:4; // 版本信息 UCHAR HdrLen:4; // IP數據報首部的雙字個(gè)數,一般為5即20字節長(cháng) UCHAR TOS; // 服務(wù)類(lèi)型<一般忽略> USHORT TotalLen; // IP數據報總長(cháng)度<字節單位>,包括了IP頭,這個(gè)長(cháng)度減去HdrLen就是數據實(shí)際長(cháng)度 USHORT PktID; // 封包ID 每發(fā)送一個(gè)包這里加一 USHORT FlagSeg; // 標致字段和片偏移 3位標志 13位偏移 UCHAR TTL; // 存活周期 UCHAR Protocol; // 協(xié)議類(lèi)型 USHORT Checksum; // 效驗和 ULONG SrcIp; // 源IP ULONG DstIp; // 目的IP}IPHeader, *PIPHeader;typedef struct _IPPACKET // IP封包{ EthernetHeader Ehhdr; IPHeader Iphdr;}IPPACKET, *PIPPACKET;
TCP頭
代碼:
0 15 31-----------------------------------------------------------------| source port | destination port |-----------------------------------------------------------------| sequence number |-----------------------------------------------------------------| acknowledgment number |-----------------------------------------------------------------| HL | rsvd |C|E|U|A|P|R|S|F| window size |-----------------------------------------------------------------| TCP checksum | urgent pointer |-----------------------------------------------------------------| Optional |-----------------------------------------------------------------| Data |-----------------------------------------------------------------// TCP頭標志位掩碼 OffFlag#define TCP_HDR_LEN 0xF000 // TCP頭長(cháng)度<雙字的個(gè)數>轉化為字節數需要x4 #define TCP_URG_FLAG 0x0020 // URG標志#define TCP_ACK_FLAG 0x0010 // ACK標志 應答1或請求0#define TCP_PSH_FLAG 0x0008 // psh標志 以最快速度傳輸數據#define TCP_RST_FLAG 0x0004 // RST標志 先斷開(kāi)連接,再重建連接#define TCP_SYN_FLAG 0x0002 // SYN標志 用來(lái)建立連接#define TCP_FIN_FLAG 0x0001 // FIN標志 發(fā)送方完成數據發(fā)送typedef struct _TcpHeader // TCP頭 20 BYTES{ USHORT SrcPort; // 源端口 USHORT DstPort; // 目的端口 ULONG SeqNum; // 序號 ULONG AckNum; // 確認號 USHORT OffFlag; // 首部長(cháng)度<首部雙字的個(gè)數>+保留位+標志位 USHORT WndSize; // 窗口大小<實(shí)現流量控制> USHORT Checksum; // 效驗和 USHORT UrgPointer; // 緊急指針}TcpHeader, *PTcpHeader;// OffFlag : 4位首部長(cháng)度 + 6位保留位 + URG+ACK+PSH+RST+SYN+FINtypedef struct _TCPPACKET // TCP封包 <當ip中沒(méi)有附加數據時(shí)>{ EthernetHeader Ehhdr; IPHeader Iphdr; TcpHeader Tcphdr;}TCPPACKET, *PTCPPACKET;
UDP頭:
代碼:
0 15 31-----------------------------------------------------------------| source port | destination port |-----------------------------------------------------------------| udp len | udp checksum |-----------------------------------------------------------------| data |-----------------------------------------------------------------typedef struct _UdpHeader{ USHORT SrcPort; // 源端口 USHORT DstPort; // 目的端口 USHORT UdpLen; // 長(cháng)度 頭+數據字節長(cháng) 最小8字節 USHORT Checksum; // 效驗和}UdpHeader, *PUdpHeader;typedef struct _UDPPACKET // UDP封包 <當ip中沒(méi)有附加數據時(shí)>{ EthernetHeader Ehhdr; IPHeader Iphdr; UdpHeader Udphdr;}UDPPACKET, *PUDPPACKET;
上面這些頭在傳輸時(shí)都是網(wǎng)絡(luò )字節序列,在訪(fǎng)問(wèn)時(shí)需要注意,而且不會(huì )進(jìn)行雙字對其.
所以最好使用對其標志將結構包起來(lái):
代碼:
#pragma pack(push)#pragma pack(1)....#pragma pack(pop)
介紹完結構我們就抓幾個(gè)包來(lái)實(shí)踐一下,抓包工具我使用了windump,不過(guò)這個(gè)是基于控制臺的程序,
大家看著(zhù)不方便也可以使用其他的抓包工具,比如wireshark
windump我會(huì )在最后的附加中上傳,使用它需要先安裝winpcap
打開(kāi)CMD命令提示符,定位到windump的目錄然后輸入windump,就能讓它運行起來(lái)了:
<可以使用Ctrl+C停止windump>
如果你的電腦上有多個(gè)網(wǎng)卡,可以用windump -D指令首先列出可來(lái)監聽(tīng)的接口列表,
然后在啟動(dòng)windump的時(shí)候用 -i 指令來(lái)指定使用哪個(gè)接口來(lái)監聽(tīng), 比如 : windump -i3
如果沒(méi)有附加條件,windump默認將dump所有經(jīng)過(guò)網(wǎng)卡的封包,下面我會(huì )介紹幾個(gè)過(guò)濾條件,
更多的信息可以在附件中附帶的幫助文檔中找到.也可以在網(wǎng)上搜索到詳細介紹
首先我們看一下網(wǎng)絡(luò )中的ARP封包,可以通過(guò) windump -n arp 命令來(lái)過(guò)濾
其中-n表示不要將主機的ip地址顯示為主機名稱(chēng);arp表示只過(guò)濾arp封包
<我的測試環(huán)境是局域網(wǎng),路由ip:192.168.1.1, 我的ip:192.168.1.23, OS:win7 sp1>
監聽(tīng)一會(huì )就能捕獲一些局域網(wǎng)上的ARP封包:
arp who-has 192.168.1.1 (00:25:86:99:2c:d6) tell 192.168.1.23
可以理解為我的主機在主動(dòng)判斷網(wǎng)關(guān)地址是否存在
reply 192.168.1.1 is-at 00:25:86:99:2c:d6
則是路由對我的主機的回復
我們現在使用命令 windump -n -XX arp 來(lái)打印出封包的具體內容
-XX表示使用16進(jìn)制和ASCii碼的形式打印封包內容.-X與之相仿,不過(guò)不會(huì )打印以太頭:
前14個(gè)字節描述了以太頭的相關(guān)信息,windump完全按照字節序列進(jìn)行打印,
以太頭最后的 0806 代表了后面幀的類(lèi)型,代表了ARP幀<參見(jiàn)前面的定義>
接下來(lái)是ARP頭,我們來(lái)看第一個(gè)封包的內容,
代碼:
0x000E: 0001 表示硬件類(lèi)型是以太網(wǎng)類(lèi)型0x0010: 0800 表示協(xié)議類(lèi)型是IP協(xié)議0x0012: 0604 表示硬件地址<MAC>長(cháng)為6字節,協(xié)議地址<IP>長(cháng)為4字節0x0014: 0001 表示操作類(lèi)型為ARP請求 ARP_QUERY
后面就依次是源MAC,源IP,目標MAC,目標IP了
第二個(gè)封包描述了路由器對ARP請求的應答,不過(guò)末尾多了一部分數據,我找了一些資料也沒(méi)找到相關(guān)說(shuō)明,
如果哪位朋友知道可以告訴我一下,先行謝過(guò)了~~
最后的部分:
代碼:
2 packets captured // 捕獲的包的數量49 packets received by filter // 被過(guò)濾的包的數量0 packets dropped by kernel // 被內核丟棄的包的數量
接下來(lái)我們監聽(tīng)一下當電腦的IP地址發(fā)生變更的時(shí)候會(huì )有什么情況發(fā)生,
執行 windump -n arp, 然后我更改本機IP為192.168.1.24
可以看到,我的電腦先向本地網(wǎng)絡(luò )進(jìn)行廣播<目標MAC為 FF:FF:FF:FF:FF>,詢(xún)問(wèn)是否有主機在使用192.168.1.24這個(gè)地址,
在廣播了三次沒(méi)有收到回復之后就設置本機IP為192.168.1.24,之后又廣播一條信息來(lái)詢(xún)問(wèn)網(wǎng)關(guān)的MAC地址.
前面的三次廣播源地址都設置為了0,我想此時(shí)可能因為本機IP已經(jīng)改變而且新的IP還沒(méi)有正式被啟用的緣故<此時(shí)沒(méi)有IP>
而局域網(wǎng)中數據傳輸是不需要IP地址的,只依靠MAC就能進(jìn)行通訊
如果本地網(wǎng)絡(luò )中有人占用了我們向設置的IP,會(huì )在廣播之后收到一條回復,表示"我正在使用這個(gè)IP,你不能使用它",
接下來(lái)我們將會(huì )看到Windows的窗口提示,然后本機IP會(huì )被設置為一個(gè)值<我不知道這個(gè)值是否是隨機的.不過(guò)它不屬于本網(wǎng)絡(luò )>
接下來(lái)毫無(wú)疑問(wèn)地斷網(wǎng)了,大家有條件的可以試一下
下面看復雜一點(diǎn)的,觀(guān)察瀏覽器在連接網(wǎng)站時(shí)的底層封包發(fā)送接收流程,為了減少干擾,我關(guān)閉了所有能聯(lián)網(wǎng)的程序.
我們使用 windump -n ip 命令,也就是將IP包過(guò)濾上來(lái),不過(guò)卻出現了莫名的干擾:
過(guò)濾出了很多路由器的組播包,我們需要再次向windump傳遞過(guò)濾指令.
我們使用 windump -n ip and not host 239.255.255.250
如果我們打算向windump傳遞多于一個(gè)的條件表達式作為過(guò)濾條件的時(shí)候需要用 and 將它們連接起來(lái)
這里的 ip 和 not host 239.255.255.250 就屬于兩個(gè)條件表達式,可以想象為C的描述 if ( ip && !host )
host用來(lái)指定主機, windump host 192.168.1.1 表示過(guò)濾出所有 192.168.1.1 相關(guān)的封包,包括收和發(fā)
windump src host 192.168.1.1 表示過(guò)濾出所有 192.168.1.1 發(fā)出的封包
windump dst host 192.168.1.1 表示過(guò)濾出所有 192.168.1.1 收到的封包
那么這里 not host 239.255.255.250 就表示收發(fā)地址中不包括 239.255.255.250 的封包
windump -n ip and not host 239.255.255.250
表示過(guò)濾表示收發(fā)地址中不包括 239.255.255.250 的IP封包,且不要將主機地址顯示為主機名稱(chēng)
更多的條件表達式用法大家可以搜一搜,用法非常靈活
執行命令前我用ipconfig /flushdns清空了本地dns緩存,這樣就可以也將dns的查詢(xún)情況捕獲了
另外如果捕獲大量的封包,應該對CMD窗口進(jìn)行一下調整,防止因顯示行數不足之前的回顯被覆蓋掉.
主要就是調整屏幕緩沖區大小以及窗口的寬度
同時(shí)為了顯示的更直觀(guān),最好使用IE瀏覽器
現在我們進(jìn)行一下封包的捕獲,先執行 windump -n ip and not host 239.255.255.250 然后打開(kāi)IE連接 www.baidu.com
瞬間CMD窗口就鋪滿(mǎn)了:
我們可以想一下:當瀏覽器連接一個(gè)網(wǎng)站時(shí),首先需要知道其IP地址,這需要通過(guò)DNS服務(wù)來(lái)獲取,
當前前提是在本地DNS緩沖中沒(méi)有相關(guān)記錄的情況下,但是之前我們清空了本地DNS,
所以迫使系統必須借助DNS服務(wù)來(lái)獲取連接目標的IP地址
我們捕獲的前個(gè)封包正是系統發(fā)送和接收到的DNS查詢(xún)和回復,下面第三個(gè)封包就開(kāi)始與目標建立連接了.
先來(lái)看一下DNS封包中都有什么內容.
再次使用ipconfig /flushdns 清空了dns緩沖,然后再次監聽(tīng)封包,但是這次我們打印出封包的內容,而且進(jìn)行更嚴密的過(guò)濾
windump -n -s0 -XX ip and src host (192.168.1.1 or 192.168.1.23) and dst host (192.168.1.1 or 192.168.1.23)
過(guò)濾表達式表示過(guò)濾出發(fā)送端IP為 192.168.1.1 或 192.168.1.23 并且 接收端IP為 192.168.1.1 或 192.168.1.23 的IP封包
也就是說(shuō)只監聽(tīng)dump出 192.168.1.1 和 192.168.1.23 的雙向通訊
新添加的 -s0 參數表示dump整個(gè)封包大小,默認windump只是dump最大96個(gè)字節的封包,這將導致封包dump不全
再次監聽(tīng),連接百度:
前兩個(gè)封包是對www.baidu.com這個(gè)域名的DNS查詢(xún), 下面是對gimg.baidu.com域名的查詢(xún),這里只看前兩個(gè)封包
先看一下關(guān)于DNS報頭的一些信息
// DNS報文
代碼:
0 15 31-----------------------------------------------------------------| Transaction ID | Flags |-----------------------------------------------------------------| Questions | Answer RRs |-----------------------------------------------------------------| Authority RRs | Additional RRs |-----------------------------------------------------------------| Question |-----------------------------------------------------------------| Answer |-----------------------------------------------------------------| Authority |-----------------------------------------------------------------| Additional |-----------------------------------------------------------------
<下面信息摘自 TCP IP詳解>
報頭中前12字節是必需的,也就是前6個(gè)域,下面四個(gè)域可選
Transaction ID : 客戶(hù)程序設置并由服務(wù)器返回,用來(lái)進(jìn)行匹配
Flags : 該域被分割為多個(gè)字段
--------------------------------
|Q| op |A|T|R|R| 0 | rcode|
|R| |A|C|D|A| | |
--------------------------------
1 4 1 1 1 1 3 4
//QR : 0表示查詢(xún)報文 1表示響應報文
//op : 通常值為0表示標準查詢(xún),1表示反向查詢(xún)
//AA : 表示授權回答,該名字服務(wù)器是授權于該域的
//TC : 表示可截斷.使用UDP時(shí),表示當應答長(cháng)度超過(guò)512字節,只返回前512字節
//RD : 表示期望遞歸.它在查詢(xún)中設置并在響應中返回.置為1表示必須處理這個(gè)查詢(xún),如果置0,服務(wù)器可能在沒(méi)有一個(gè)授權回答時(shí)返回一個(gè)能解答該查詢(xún)的其他名字服務(wù)器列表
//RA : 表示可用遞歸.如果名字服務(wù)器支持遞歸查詢(xún),則在響應中將該比特置1
//rcode : 返回碼字段.0表示沒(méi)有差錯,3表示名字差錯表示指定的域名不存在
后面四個(gè)雙字節長(cháng)的字段表示后面可選的域的條目數目
一般查詢(xún)報文會(huì )將Questions置1,其余填0;應答報文回答數至少是1,剩下的兩項是0或非0
//Question部分格式如下:
代碼:
0 15 31-----------------------------------------------------------------| Name |-----------------------------------------------------------------| Type | class |-----------------------------------------------------------------
Name指要查找的名字,它是一個(gè)或多個(gè)標識符序列.每個(gè)標識符以首字節的計數值來(lái)說(shuō)明隨后標識符的字節長(cháng)度
每個(gè)名字以最后字節為0結束.計數字節值必須是0-63的數
每個(gè)問(wèn)題有一個(gè)類(lèi)型Type,每個(gè)響應也有一個(gè)類(lèi)型
代碼:
----------------------------------------------------------------- 名字 | 數值 | 描述 | 類(lèi)型 | 查詢(xún)類(lèi)型 ----------------------------------------------------------------- A | 1 | IP地址 | NS | 2 | 名字服務(wù)器 | CNAME | 5 | 規范名稱(chēng) | PTR | 12 | 指針記錄 | HINFO | 13 | 主機信息 | MX | 15 | 郵件交換記錄 | ----------------------------------------------------------------- AXFR | 252 | 對區域轉換的請求 | ANY | 255 | 對所有記錄的請求 | -----------------------------------------------------------------
常用的查詢(xún)類(lèi)型是A,表示獲得域名的IP;PTR請求獲得IP地址對應的域名
class通常置1,表示互聯(lián)網(wǎng)地址
//Answer Authority Additional部分
這三部分使用同一種格式稱(chēng)作資源記錄<Resource Record RR>
代碼:
0 15 31-----------------------------------------------------------------| Name |-----------------------------------------------------------------| Type | Class |-----------------------------------------------------------------| TTL |-----------------------------------------------------------------| Data Len | Data |---------------------------------| Data |-----------------------------------------------------------------
Name Type Class與上面的那些字段相同
TTL是客戶(hù)程序保留該資源記錄的秒數
DataLen說(shuō)明資源數據的數量
Data的格式依賴(lài)于類(lèi)型字段的值對于類(lèi)型1資源數據是4字節的IP地址
下面先解析第一個(gè)包,也就是DNS查詢(xún)封包
代碼:
IP 192.168.1.23.49439 > 192.168.1.1.53: 13992+ A? www.baidu.com. (31)0x0000: 0025 8699 2cd6 0030 18a2 17f7 0800 4500 .%..,..0......E.0x0010: 003b 1607 0000 8011 0000 c0a8 0117 c0a8 .;..............0x0020: 0101 c11f 0035 0027 83a1 36a8 0100 0001 .....5.'..6.....0x0030: 0000 0000 0000 0377 7777 0562 6169 6475 .......www.baidu0x0040: 0363 6f6d 0000 0100 01 .com.....
前14字節是以太頭,其中協(xié)議域是 0800 也就是說(shuō)后面是ip頭,其中ip頭長(cháng)的指示域為5,它表示ip頭的雙字個(gè)數為5,所以字節長(cháng)為20,
其中ip頭的協(xié)議域為 0x11 <地址0x0017處>,所以跟在ip頭后面的是UDP頭,起始地址為 0x000E+0x14=0x22
UDP頭中源端口號為 0xc11f = 49439; 目的端口號 0x0035 = 53
越過(guò)8字節長(cháng)的UDP頭就到了DNS報頭位置 0x002C: 36a8
結合DNS頭結構看一下:
Transaction ID : 36a8 ID號,它應當被服務(wù)器傳回用來(lái)進(jìn)行包的匹配確認
Flags : 0100 轉為二進(jìn)制:0000 0001 0000 0000 結合前面的標志位說(shuō)明,這個(gè)標志是遞歸查詢(xún)標志,表示必須完成這個(gè)查詢(xún)
Questions : 0001 問(wèn)題數1
Answer : 0000 沒(méi)有回答數
Authority : 0000 沒(méi)有授權回答
Additional : 0000 沒(méi)有附加信息
走完DNS報頭,下面到了Question域
Question域首個(gè)域是Name,它是一個(gè)或多個(gè)標識符序列.每個(gè)標識符以首字節的計數值來(lái)說(shuō)明隨后標識符的字節長(cháng)度
在這里表示方法就是分段描述,www用03描述,baidu用05描述,com用03描述,最后以一個(gè)00字節結尾
然后是Type域兩個(gè)字節長(cháng),起始地址 0x0045,值為 0001 表示 A - 查詢(xún)IP地址
Class域一般總是 0001
最后回過(guò)頭看一下 IP 192.168.1.23.49439 > 192.168.1.1.53: 13992+ A? www.baidu.com. (31)
基本就能看懂了 13992 代表了Transaction ID
A 代表了查詢(xún)類(lèi)型,后面就是要查詢(xún)的域名,31表示DNS包長(cháng)度
下面看一下DNS的查詢(xún)回答,第二個(gè)包
代碼:
IP 192.168.1.1.53 > 192.168.1.23.49439: 13992 3/6/6 CNAME www.a.shifen.com., A 119.75.218.77, A 119.75.217.56 (294)0x0000: 0030 18a2 17f7 0025 8699 2cd6 0800 4500 .0.....%..,...E.0x0010: 0142 17a3 0000 4011 de9f c0a8 0101 c0a8 .B....@.........0x0020: 0117 0035 c11f 012e b79a 36a8 8180 0001 ...5......6.....0x0030: 0003 0006 0006 0377 7777 0562 6169 6475 .......www.baidu0x0040: 0363 6f6d 0000 0100 01c0 0c00 0500 0100 .com............0x0050: 0002 3200 0f03 7777 7701 6106 7368 6966 ..2...www.a.shif0x0060: 656e c016 c02b 0001 0001 0000 00c3 0004 en...+..........0x0070: 774b da4d c02b 0001 0001 0000 00c3 0004 wK.M.+..........0x0080: 774b d938 c02f 0002 0001 0000 2710 0006 wK.8./......'...0x0090: 036e 7332 c02f c02f 0002 0001 0000 2710 .ns2././......'.0x00a0: 0006 036e 7335 c02f c02f 0002 0001 0000 ...ns5././......0x00b0: 2710 0006 036e 7334 c02f c02f 0002 0001 '....ns4././....0x00c0: 0000 2710 0006 036e 7336 c02f c02f 0002 ..'....ns6././..0x00d0: 0001 0000 2710 0006 036e 7339 c02f c02f ....'....ns9././0x00e0: 0002 0001 0000 2710 0006 036e 7337 c02f ......'....ns7./0x00f0: c066 0001 0001 0000 021b 0004 7b7d 7142 .f..........{}qB0x0100: c08a 0001 0001 0000 021b 0004 7b7d 7143 ............{}qC0x0110: c078 0001 0001 0000 021b 0004 dcb5 03b2 .x..............0x0120: c09c 0001 0001 0000 021b 0004 dcb5 04b2 ................0x0130: c0c0 0001 0001 0000 0015 0004 dcb5 262f ..............&/0x0140: c0ae 0001 0001 0000 00fb 0004 3d87 a6e2 ............=...
Transaction ID : 36a8 ID號
Flags : 8180 轉為二進(jìn)制:1000 0001 1000 0000 最高位為1表示響應
Questions : 0001 問(wèn)題數1
Answer : 0003 回答數3
Authority : 0006 授權回答6
Additional : 0006 附加信息6
Question地址范圍: 0x0035~0x0048 與前面的問(wèn)題相同
第一個(gè)Answer起始地址: 0x0049
這里有一個(gè)特例,就是當Name域首個(gè)字節是0xC0的時(shí)候要進(jìn)行跳轉,規則是跳轉到距離DNS報頭的一個(gè)偏移地址,
這個(gè)偏移地址由0xC0后面的一個(gè)字節給出<如果目標地址首個(gè)字節還是0xC0,需要繼續跳轉>,
這里的偏移是0x0C,加上DNS報頭地址 0x002A 得到地址 0x0036 這里是百度域名的起始,
所以第一個(gè)Answer的Name域為 www.baidu.com
接下來(lái)是Type域: 0x004B, 值為 0005, CNAME - 規范名稱(chēng)<具體什么意思我也沒(méi)弄懂,大概就像是域名跳轉>
Class域 : 0x004D, 值為 0001
TTL域 : 0x004F, 值為 00000232
DataLen域 : 0x0053, 值為 000F
data域是一個(gè)字串: www.a.shifen.com, 注意最后的com是經(jīng)過(guò)跳轉得到
第一個(gè)應答:
Name : www.baidu.com
TYPE : CNAME
CLASS : 1
TTL : 0x232
LEN : 0x0F
DATA : www.a.shifen.com
后面的應答,授權回答以及附加信息都可以依次推導出來(lái)
可以想象,這些回答隨后都會(huì )被系統存到本地緩存中,可以通過(guò)ipconfig /displaydns 查看一下:
現在,再使用 windump -n ip and not host 239.255.255.250 看一下<清空dns緩沖之后>:
前兩個(gè)封包進(jìn)行DNS查詢(xún),之后就可以看到熟悉的TCP的三次握手了,
代碼:
IP 192.168.1.23.50749 > 119.75.217.56.80: S 4004469303:4004469303(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK> IP 119.75.217.56.80 > 192.168.1.23.50749: S 2551825006:2551825006(0) ack 4004469304 win 8192 <mss 1440,nop,nop,nop,nop,nop,nop,sackOK> IP 192.168.1.23.50749 > 119.75.217.56.80: . ack 1 win 64800 IP 192.168.1.23.50749 > 119.75.217.56.80: P 1:409(408) ack 1 win 64800 IP 119.75.217.56.80 > 192.168.1.23.50749: . ack 409 win 6432 IP 119.75.217.56.80 > 192.168.1.23.50749: P 1:412(411) ack 409 win 6432 IP 119.75.217.56.80 > 192.168.1.23.50749: . 412:1852(1440) ack 409 win 6432 IP 192.168.1.23.50749 > 119.75.217.56.80: . ack 1852 win 64800 IP 119.75.217.56.80 > 192.168.1.23.50749: . 1852:3292(1440) ack 409 win 6432 IP 119.75.217.56.80 > 192.168.1.23.50749: P 3292:3812(520) ack 409 win 6432 IP 192.168.1.23.50749 > 119.75.217.56.80: . ack 3812 win 64800 IP 192.168.1.23.50749 > 119.75.217.56.80: P 409:816(407) ack 3812 win 64800 IP 192.168.1.23.50367 > 192.168.1.1.53: 60818+ A? gimg.baidu.com. (32) IP 192.168.1.23.50750 > 119.75.217.56.80: S 535857440:535857440(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK> IP 192.168.1.23.50751 > 119.75.217.56.80: S 271755341:271755341(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK> IP 119.75.217.56.80 > 192.168.1.23.50749: . ack 816 win 7504
默認情況下windump顯示格式如下:
協(xié)議 源IP.端口 > 目的IP.端口
后面則是根據情況顯示, 如果是TCP連接一般首先是TCP封包中的標志比如見(jiàn)到的 S<SYN> P<PSH>,如果沒(méi)有標志被置位則顯示".",
后面將是序號和確認號,確認號如果有效<ACK標志被置位>,將會(huì )以 ack xxxx 的形式顯示出來(lái)
不過(guò)默認情況序號和確認號會(huì )以增量的形式表示,比如第三行第四行,表示對于第一個(gè)序號的增量,通過(guò)添加 -S 參數將可以打印絕對序號
后面的win xxxx表示滑動(dòng)窗口的大小,再之后就是一些附加的選項
下面的注釋針對于上面的封包,各行序號對應入座
1.發(fā)起連接,向服務(wù)器發(fā)送SYN封包
2.服務(wù)器確認SYN分包并向我們發(fā)送服務(wù)器的SYN封包
3.確認收到服務(wù)器的SYN封包,連接正式建立起來(lái)
4.向服務(wù)器提交請求數據
5.服務(wù)器確認收到請求數據
6,7:服務(wù)器向我們傳送網(wǎng)頁(yè)數據,兩次共傳遞1852字節
8.向服務(wù)器確認收到了1852字節數據
9,10:服務(wù)器向我們傳送網(wǎng)頁(yè)數據,共3812字節<加上之前>
11:向服務(wù)器確認收到了總共3812字節的數據
12:向服務(wù)器提交請求數據
13:進(jìn)行DNS查詢(xún),域名為gimg.baidu.com.
14~16:發(fā)起另外一個(gè)連接
基本上TCP傳輸都是這樣進(jìn)行,服務(wù)器沒(méi)法送兩三個(gè)攜帶數據的封包,我們客戶(hù)端就進(jìn)行一次確認
最后再說(shuō)一下win的作用,這個(gè)是向服務(wù)器說(shuō)明客戶(hù)端這里還有多大的緩沖區用來(lái)接收數據,
服務(wù)器會(huì )根據這個(gè)值來(lái)調整自己發(fā)送的封包的長(cháng)度,如果指定為0,則服務(wù)器會(huì )暫停發(fā)送,
直到再次收到另一個(gè)封包指定了一個(gè)非0值的win,此時(shí)ack與上一個(gè)相同
寫(xiě)了這么多手都麻了,也不知道自己的這些理解是否是正確的,
如果有錯誤,希望能得到指正, QQ:2575439022
windump : 也包含了Windows下面能用的tcpdump
tcpdump.rar[誰(shuí)下載?]