1 【原創(chuàng)】借windump初窺網(wǎng)絡(luò)底層
標(biāo) 題: 【原創(chuàng)】借windump初窺網(wǎng)絡(luò)底層
作 者: thisIs
時 間: 2012-03-09,15:26:42
鏈 接: http://bbs.pediy.com/showthread.php?t=147644
最近在學(xué)ndis以及網(wǎng)絡(luò)方面的知識,今天借論壇寶地整理一些筆記出來,與大家共同分享下
<太過基礎(chǔ)的原理就不做說明了,大家可以去網(wǎng)上搜索>
首先是各種包的格式定義:
以太頭:
代碼:
// MAC地址長度#define MAC_ADDRESS_LEN 6// 常用的以太網(wǎng)幀類型#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]; // 目標(biāo)MAC UCHAR SrcMacAddr[MAC_ADDRESS_LEN]; // 源MAC USHORT FrmType; // 類型}EthernetHeader, *PEthernetHeader;
ARP,RARP頭
代碼:
// 定義ARP操作類型#define ARP_QUERY 0x0001 // ARP請求 #define ARP_REPLY 0x0002 // ARP應(yīng)答#define RARP_QUERY 0x0003 // RARP請求#define RARP_REPLY 0x0004 // RARP應(yīng)答// 定義ARP硬件類型#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; // 硬件類型 USHORT ProType; // 協(xié)議類型 UCHAR HrdAddrLen; // 硬件地址長度 UCHAR ProAddrLen; // 協(xié)議地址長度 USHORT Opr; // 操作字段 <是ARP請求或者應(yīng)答 異或RARP請求或者應(yīng)答> 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數(shù)據(jù)報(bào)中的協(xié)議類型#define ICMP_PROTOCOL 0x0001 // ICMP 報(bào)文#define IGMP_PROTOCOL 0x0002 // IGMP 報(bào)文#define TCP_PROTOCOL 0x0006 // TCP 報(bào)文#define UDP_PROTOCOL 0x0011 // UDP 報(bào)文 17// IP標(biāo)志#define IP_DF_MASK 0x4000 // 如果置位,表示不能被分割#define IP_MF_MASK 0x2000 // 為1表示還有更多的數(shù)據(jù)報(bào)分片 為0表示已經(jīng)是最后一個分片typedef struct _IPHeader // IP頭 20 BYTES{ UCHAR Ver:4; // 版本信息 UCHAR HdrLen:4; // IP數(shù)據(jù)報(bào)首部的雙字個數(shù),一般為5即20字節(jié)長 UCHAR TOS; // 服務(wù)類型<一般忽略> USHORT TotalLen; // IP數(shù)據(jù)報(bào)總長度<字節(jié)單位>,包括了IP頭,這個長度減去HdrLen就是數(shù)據(jù)實(shí)際長度 USHORT PktID; // 封包ID 每發(fā)送一個包這里加一 USHORT FlagSeg; // 標(biāo)致字段和片偏移 3位標(biāo)志 13位偏移 UCHAR TTL; // 存活周期 UCHAR Protocol; // 協(xié)議類型 USHORT Checksum; // 效驗(yàn)和 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頭標(biāo)志位掩碼 OffFlag#define TCP_HDR_LEN 0xF000 // TCP頭長度<雙字的個數(shù)>轉(zhuǎn)化為字節(jié)數(shù)需要x4 #define TCP_URG_FLAG 0x0020 // URG標(biāo)志#define TCP_ACK_FLAG 0x0010 // ACK標(biāo)志 應(yīng)答1或請求0#define TCP_PSH_FLAG 0x0008 // psh標(biāo)志 以最快速度傳輸數(shù)據(jù)#define TCP_RST_FLAG 0x0004 // RST標(biāo)志 先斷開連接,再重建連接#define TCP_SYN_FLAG 0x0002 // SYN標(biāo)志 用來建立連接#define TCP_FIN_FLAG 0x0001 // FIN標(biāo)志 發(fā)送方完成數(shù)據(jù)發(fā)送typedef struct _TcpHeader // TCP頭 20 BYTES{ USHORT SrcPort; // 源端口 USHORT DstPort; // 目的端口 ULONG SeqNum; // 序號 ULONG AckNum; // 確認(rèn)號 USHORT OffFlag; // 首部長度<首部雙字的個數(shù)>+保留位+標(biāo)志位 USHORT WndSize; // 窗口大小<實(shí)現(xiàn)流量控制> USHORT Checksum; // 效驗(yàn)和 USHORT UrgPointer; // 緊急指針}TcpHeader, *PTcpHeader;// OffFlag : 4位首部長度 + 6位保留位 + URG+ACK+PSH+RST+SYN+FINtypedef struct _TCPPACKET // TCP封包 <當(dāng)ip中沒有附加數(shù)據(jù)時>{ 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; // 長度 頭+數(shù)據(jù)字節(jié)長 最小8字節(jié) USHORT Checksum; // 效驗(yàn)和}UdpHeader, *PUdpHeader;typedef struct _UDPPACKET // UDP封包 <當(dāng)ip中沒有附加數(shù)據(jù)時>{ EthernetHeader Ehhdr; IPHeader Iphdr; UdpHeader Udphdr;}UDPPACKET, *PUDPPACKET;
上面這些頭在傳輸時都是網(wǎng)絡(luò)字節(jié)序列,在訪問時需要注意,而且不會進(jìn)行雙字對其.
所以最好使用對其標(biāo)志將結(jié)構(gòu)包起來:
代碼:
#pragma pack(push)#pragma pack(1)....#pragma pack(pop)
介紹完結(jié)構(gòu)我們就抓幾個包來實(shí)踐一下,抓包工具我使用了windump,不過這個是基于控制臺的程序,
大家看著不方便也可以使用其他的抓包工具,比如wireshark
windump我會在最后的附加中上傳,使用它需要先安裝winpcap
打開CMD命令提示符,定位到windump的目錄然后輸入windump,就能讓它運(yùn)行起來了:
<可以使用Ctrl+C停止windump>
如果你的電腦上有多個網(wǎng)卡,可以用windump -D指令首先列出可來監(jiān)聽的接口列表,
然后在啟動windump的時候用 -i 指令來指定使用哪個接口來監(jiān)聽, 比如 : windump -i3
如果沒有附加條件,windump默認(rèn)將dump所有經(jīng)過網(wǎng)卡的封包,下面我會介紹幾個過濾條件,
更多的信息可以在附件中附帶的幫助文檔中找到.也可以在網(wǎng)上搜索到詳細(xì)介紹
首先我們看一下網(wǎng)絡(luò)中的ARP封包,可以通過 windump -n arp 命令來過濾
其中-n表示不要將主機(jī)的ip地址顯示為主機(jī)名稱;arp表示只過濾arp封包
<我的測試環(huán)境是局域網(wǎng),路由ip:192.168.1.1, 我的ip:192.168.1.23, OS:win7 sp1>
監(jiān)聽一會就能捕獲一些局域網(wǎng)上的ARP封包:
arp who-has 192.168.1.1 (00:25:86:99:2c:d6) tell 192.168.1.23
可以理解為我的主機(jī)在主動判斷網(wǎng)關(guān)地址是否存在
reply 192.168.1.1 is-at 00:25:86:99:2c:d6
則是路由對我的主機(jī)的回復(fù)
我們現(xiàn)在使用命令 windump -n -XX arp 來打印出封包的具體內(nèi)容
-XX表示使用16進(jìn)制和ASCii碼的形式打印封包內(nèi)容.-X與之相仿,不過不會打印以太頭:
前14個字節(jié)描述了以太頭的相關(guān)信息,windump完全按照字節(jié)序列進(jìn)行打印,
以太頭最后的 0806 代表了后面幀的類型,代表了ARP幀<參見前面的定義>
接下來是ARP頭,我們來看第一個封包的內(nèi)容,
代碼:
0x000E: 0001 表示硬件類型是以太網(wǎng)類型0x0010: 0800 表示協(xié)議類型是IP協(xié)議0x0012: 0604 表示硬件地址<MAC>長為6字節(jié),協(xié)議地址<IP>長為4字節(jié)0x0014: 0001 表示操作類型為ARP請求 ARP_QUERY
后面就依次是源MAC,源IP,目標(biāo)MAC,目標(biāo)IP了
第二個封包描述了路由器對ARP請求的應(yīng)答,不過末尾多了一部分?jǐn)?shù)據(jù),我找了一些資料也沒找到相關(guān)說明,
如果哪位朋友知道可以告訴我一下,先行謝過了~~
最后的部分:
代碼:
2 packets captured // 捕獲的包的數(shù)量49 packets received by filter // 被過濾的包的數(shù)量0 packets dropped by kernel // 被內(nèi)核丟棄的包的數(shù)量
接下來我們監(jiān)聽一下當(dāng)電腦的IP地址發(fā)生變更的時候會有什么情況發(fā)生,
執(zhí)行 windump -n arp, 然后我更改本機(jī)IP為192.168.1.24
可以看到,我的電腦先向本地網(wǎng)絡(luò)進(jìn)行廣播<目標(biāo)MAC為 FF:FF:FF:FF:FF>,詢問是否有主機(jī)在使用192.168.1.24這個地址,
在廣播了三次沒有收到回復(fù)之后就設(shè)置本機(jī)IP為192.168.1.24,之后又廣播一條信息來詢問網(wǎng)關(guān)的MAC地址.
前面的三次廣播源地址都設(shè)置為了0,我想此時可能因?yàn)楸緳C(jī)IP已經(jīng)改變而且新的IP還沒有正式被啟用的緣故<此時沒有IP>
而局域網(wǎng)中數(shù)據(jù)傳輸是不需要IP地址的,只依靠MAC就能進(jìn)行通訊
如果本地網(wǎng)絡(luò)中有人占用了我們向設(shè)置的IP,會在廣播之后收到一條回復(fù),表示"我正在使用這個IP,你不能使用它",
接下來我們將會看到Windows的窗口提示,然后本機(jī)IP會被設(shè)置為一個值<我不知道這個值是否是隨機(jī)的.不過它不屬于本網(wǎng)絡(luò)>
接下來毫無疑問地?cái)嗑W(wǎng)了,大家有條件的可以試一下
下面看復(fù)雜一點(diǎn)的,觀察瀏覽器在連接網(wǎng)站時的底層封包發(fā)送接收流程,為了減少干擾,我關(guān)閉了所有能聯(lián)網(wǎng)的程序.
我們使用 windump -n ip 命令,也就是將IP包過濾上來,不過卻出現(xiàn)了莫名的干擾:
過濾出了很多路由器的組播包,我們需要再次向windump傳遞過濾指令.
我們使用 windump -n ip and not host 239.255.255.250
如果我們打算向windump傳遞多于一個的條件表達(dá)式作為過濾條件的時候需要用 and 將它們連接起來
這里的 ip 和 not host 239.255.255.250 就屬于兩個條件表達(dá)式,可以想象為C的描述 if ( ip && !host )
host用來指定主機(jī), windump host 192.168.1.1 表示過濾出所有 192.168.1.1 相關(guān)的封包,包括收和發(fā)
windump src host 192.168.1.1 表示過濾出所有 192.168.1.1 發(fā)出的封包
windump dst host 192.168.1.1 表示過濾出所有 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
表示過濾表示收發(fā)地址中不包括 239.255.255.250 的IP封包,且不要將主機(jī)地址顯示為主機(jī)名稱
更多的條件表達(dá)式用法大家可以搜一搜,用法非常靈活
執(zhí)行命令前我用ipconfig /flushdns清空了本地dns緩存,這樣就可以也將dns的查詢情況捕獲了
另外如果捕獲大量的封包,應(yīng)該對CMD窗口進(jìn)行一下調(diào)整,防止因顯示行數(shù)不足之前的回顯被覆蓋掉.
主要就是調(diào)整屏幕緩沖區(qū)大小以及窗口的寬度
同時為了顯示的更直觀,最好使用IE瀏覽器
現(xiàn)在我們進(jìn)行一下封包的捕獲,先執(zhí)行 windump -n ip and not host 239.255.255.250 然后打開IE連接 www.baidu.com
瞬間CMD窗口就鋪滿了:
我們可以想一下:當(dāng)瀏覽器連接一個網(wǎng)站時,首先需要知道其IP地址,這需要通過DNS服務(wù)來獲取,
當(dāng)前前提是在本地DNS緩沖中沒有相關(guān)記錄的情況下,但是之前我們清空了本地DNS,
所以迫使系統(tǒng)必須借助DNS服務(wù)來獲取連接目標(biāo)的IP地址
我們捕獲的前個封包正是系統(tǒng)發(fā)送和接收到的DNS查詢和回復(fù),下面第三個封包就開始與目標(biāo)建立連接了.
先來看一下DNS封包中都有什么內(nèi)容.
再次使用ipconfig /flushdns 清空了dns緩沖,然后再次監(jiān)聽封包,但是這次我們打印出封包的內(nèi)容,而且進(jìn)行更嚴(yán)密的過濾
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)
過濾表達(dá)式表示過濾出發(fā)送端IP為 192.168.1.1 或 192.168.1.23 并且 接收端IP為 192.168.1.1 或 192.168.1.23 的IP封包
也就是說只監(jiān)聽dump出 192.168.1.1 和 192.168.1.23 的雙向通訊
新添加的 -s0 參數(shù)表示dump整個封包大小,默認(rèn)windump只是dump最大96個字節(jié)的封包,這將導(dǎo)致封包dump不全
再次監(jiān)聽,連接百度:
前兩個封包是對www.baidu.com這個域名的DNS查詢, 下面是對gimg.baidu.com域名的查詢,這里只看前兩個封包
先看一下關(guān)于DNS報(bào)頭的一些信息
// DNS報(bào)文
代碼:
0 15 31-----------------------------------------------------------------| Transaction ID | Flags |-----------------------------------------------------------------| Questions | Answer RRs |-----------------------------------------------------------------| Authority RRs | Additional RRs |-----------------------------------------------------------------| Question |-----------------------------------------------------------------| Answer |-----------------------------------------------------------------| Authority |-----------------------------------------------------------------| Additional |-----------------------------------------------------------------
<下面信息摘自 TCP IP詳解>
報(bào)頭中前12字節(jié)是必需的,也就是前6個域,下面四個域可選
Transaction ID : 客戶程序設(shè)置并由服務(wù)器返回,用來進(jìn)行匹配
Flags : 該域被分割為多個字段
--------------------------------
|Q| op |A|T|R|R| 0 | rcode|
|R| |A|C|D|A| | |
--------------------------------
1 4 1 1 1 1 3 4
//QR : 0表示查詢報(bào)文 1表示響應(yīng)報(bào)文
//op : 通常值為0表示標(biāo)準(zhǔn)查詢,1表示反向查詢
//AA : 表示授權(quán)回答,該名字服務(wù)器是授權(quán)于該域的
//TC : 表示可截?cái)?使用UDP時,表示當(dāng)應(yīng)答長度超過512字節(jié),只返回前512字節(jié)
//RD : 表示期望遞歸.它在查詢中設(shè)置并在響應(yīng)中返回.置為1表示必須處理這個查詢,如果置0,服務(wù)器可能在沒有一個授權(quán)回答時返回一個能解答該查詢的其他名字服務(wù)器列表
//RA : 表示可用遞歸.如果名字服務(wù)器支持遞歸查詢,則在響應(yīng)中將該比特置1
//rcode : 返回碼字段.0表示沒有差錯,3表示名字差錯表示指定的域名不存在
后面四個雙字節(jié)長的字段表示后面可選的域的條目數(shù)目
一般查詢報(bào)文會將Questions置1,其余填0;應(yīng)答報(bào)文回答數(shù)至少是1,剩下的兩項(xiàng)是0或非0
//Question部分格式如下:
代碼:
0 15 31-----------------------------------------------------------------| Name |-----------------------------------------------------------------| Type | class |-----------------------------------------------------------------
Name指要查找的名字,它是一個或多個標(biāo)識符序列.每個標(biāo)識符以首字節(jié)的計(jì)數(shù)值來說明隨后標(biāo)識符的字節(jié)長度
每個名字以最后字節(jié)為0結(jié)束.計(jì)數(shù)字節(jié)值必須是0-63的數(shù)
每個問題有一個類型Type,每個響應(yīng)也有一個類型
代碼:
----------------------------------------------------------------- 名字 | 數(shù)值 | 描述 | 類型 | 查詢類型 ----------------------------------------------------------------- A | 1 | IP地址 | NS | 2 | 名字服務(wù)器 | CNAME | 5 | 規(guī)范名稱 | PTR | 12 | 指針記錄 | HINFO | 13 | 主機(jī)信息 | MX | 15 | 郵件交換記錄 | ----------------------------------------------------------------- AXFR | 252 | 對區(qū)域轉(zhuǎn)換的請求 | ANY | 255 | 對所有記錄的請求 | -----------------------------------------------------------------
常用的查詢類型是A,表示獲得域名的IP;PTR請求獲得IP地址對應(yīng)的域名
class通常置1,表示互聯(lián)網(wǎng)地址
//Answer Authority Additional部分
這三部分使用同一種格式稱作資源記錄<Resource Record RR>
代碼:
0 15 31-----------------------------------------------------------------| Name |-----------------------------------------------------------------| Type | Class |-----------------------------------------------------------------| TTL |-----------------------------------------------------------------| Data Len | Data |---------------------------------| Data |-----------------------------------------------------------------
Name Type Class與上面的那些字段相同
TTL是客戶程序保留該資源記錄的秒數(shù)
DataLen說明資源數(shù)據(jù)的數(shù)量
Data的格式依賴于類型字段的值對于類型1資源數(shù)據(jù)是4字節(jié)的IP地址
下面先解析第一個包,也就是DNS查詢封包
代碼:
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字節(jié)是以太頭,其中協(xié)議域是 0800 也就是說后面是ip頭,其中ip頭長的指示域?yàn)?,它表示ip頭的雙字個數(shù)為5,所以字節(jié)長為20,
其中ip頭的協(xié)議域?yàn)?nbsp;0x11 <地址0x0017處>,所以跟在ip頭后面的是UDP頭,起始地址為 0x000E+0x14=0x22
UDP頭中源端口號為 0xc11f = 49439; 目的端口號 0x0035 = 53
越過8字節(jié)長的UDP頭就到了DNS報(bào)頭位置 0x002C: 36a8
結(jié)合DNS頭結(jié)構(gòu)看一下:
Transaction ID : 36a8 ID號,它應(yīng)當(dāng)被服務(wù)器傳回用來進(jìn)行包的匹配確認(rèn)
Flags : 0100 轉(zhuǎn)為二進(jìn)制:0000 0001 0000 0000 結(jié)合前面的標(biāo)志位說明,這個標(biāo)志是遞歸查詢標(biāo)志,表示必須完成這個查詢
Questions : 0001 問題數(shù)1
Answer : 0000 沒有回答數(shù)
Authority : 0000 沒有授權(quán)回答
Additional : 0000 沒有附加信息
走完DNS報(bào)頭,下面到了Question域
Question域首個域是Name,它是一個或多個標(biāo)識符序列.每個標(biāo)識符以首字節(jié)的計(jì)數(shù)值來說明隨后標(biāo)識符的字節(jié)長度
在這里表示方法就是分段描述,www用03描述,baidu用05描述,com用03描述,最后以一個00字節(jié)結(jié)尾
然后是Type域兩個字節(jié)長,起始地址 0x0045,值為 0001 表示 A - 查詢IP地址
Class域一般總是 0001
最后回過頭看一下 IP 192.168.1.23.49439 > 192.168.1.1.53: 13992+ A? www.baidu.com. (31)
基本就能看懂了 13992 代表了Transaction ID
A 代表了查詢類型,后面就是要查詢的域名,31表示DNS包長度
下面看一下DNS的查詢回答,第二個包
代碼:
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 轉(zhuǎn)為二進(jìn)制:1000 0001 1000 0000 最高位為1表示響應(yīng)
Questions : 0001 問題數(shù)1
Answer : 0003 回答數(shù)3
Authority : 0006 授權(quán)回答6
Additional : 0006 附加信息6
Question地址范圍: 0x0035~0x0048 與前面的問題相同
第一個Answer起始地址: 0x0049
這里有一個特例,就是當(dāng)Name域首個字節(jié)是0xC0的時候要進(jìn)行跳轉(zhuǎn),規(guī)則是跳轉(zhuǎn)到距離DNS報(bào)頭的一個偏移地址,
這個偏移地址由0xC0后面的一個字節(jié)給出<如果目標(biāo)地址首個字節(jié)還是0xC0,需要繼續(xù)跳轉(zhuǎn)>,
這里的偏移是0x0C,加上DNS報(bào)頭地址 0x002A 得到地址 0x0036 這里是百度域名的起始,
所以第一個Answer的Name域?yàn)?nbsp;www.baidu.com
接下來是Type域: 0x004B, 值為 0005, CNAME - 規(guī)范名稱<具體什么意思我也沒弄懂,大概就像是域名跳轉(zhuǎn)>
Class域 : 0x004D, 值為 0001
TTL域 : 0x004F, 值為 00000232
DataLen域 : 0x0053, 值為 000F
data域是一個字串: www.a.shifen.com, 注意最后的com是經(jīng)過跳轉(zhuǎn)得到
第一個應(yīng)答:
Name : www.baidu.com
TYPE : CNAME
CLASS : 1
TTL : 0x232
LEN : 0x0F
DATA : www.a.shifen.com
后面的應(yīng)答,授權(quán)回答以及附加信息都可以依次推導(dǎo)出來
可以想象,這些回答隨后都會被系統(tǒng)存到本地緩存中,可以通過ipconfig /displaydns 查看一下:
現(xiàn)在,再使用 windump -n ip and not host 239.255.255.250 看一下<清空dns緩沖之后>:
前兩個封包進(jìn)行DNS查詢,之后就可以看到熟悉的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
默認(rèn)情況下windump顯示格式如下:
協(xié)議 源IP.端口 > 目的IP.端口
后面則是根據(jù)情況顯示, 如果是TCP連接一般首先是TCP封包中的標(biāo)志比如見到的 S<SYN> P<PSH>,如果沒有標(biāo)志被置位則顯示".",
后面將是序號和確認(rèn)號,確認(rèn)號如果有效<ACK標(biāo)志被置位>,將會以 ack xxxx 的形式顯示出來
不過默認(rèn)情況序號和確認(rèn)號會以增量的形式表示,比如第三行第四行,表示對于第一個序號的增量,通過添加 -S 參數(shù)將可以打印絕對序號
后面的win xxxx表示滑動窗口的大小,再之后就是一些附加的選項(xiàng)
下面的注釋針對于上面的封包,各行序號對應(yīng)入座
1.發(fā)起連接,向服務(wù)器發(fā)送SYN封包
2.服務(wù)器確認(rèn)SYN分包并向我們發(fā)送服務(wù)器的SYN封包
3.確認(rèn)收到服務(wù)器的SYN封包,連接正式建立起來
4.向服務(wù)器提交請求數(shù)據(jù)
5.服務(wù)器確認(rèn)收到請求數(shù)據(jù)
6,7:服務(wù)器向我們傳送網(wǎng)頁數(shù)據(jù),兩次共傳遞1852字節(jié)
8.向服務(wù)器確認(rèn)收到了1852字節(jié)數(shù)據(jù)
9,10:服務(wù)器向我們傳送網(wǎng)頁數(shù)據(jù),共3812字節(jié)<加上之前>
11:向服務(wù)器確認(rèn)收到了總共3812字節(jié)的數(shù)據(jù)
12:向服務(wù)器提交請求數(shù)據(jù)
13:進(jìn)行DNS查詢,域名為gimg.baidu.com.
14~16:發(fā)起另外一個連接
基本上TCP傳輸都是這樣進(jìn)行,服務(wù)器沒法送兩三個攜帶數(shù)據(jù)的封包,我們客戶端就進(jìn)行一次確認(rèn)
最后再說一下win的作用,這個是向服務(wù)器說明客戶端這里還有多大的緩沖區(qū)用來接收數(shù)據(jù),
服務(wù)器會根據(jù)這個值來調(diào)整自己發(fā)送的封包的長度,如果指定為0,則服務(wù)器會暫停發(fā)送,
直到再次收到另一個封包指定了一個非0值的win,此時ack與上一個相同
寫了這么多手都麻了,也不知道自己的這些理解是否是正確的,
如果有錯誤,希望能得到指正, QQ:2575439022
windump : 也包含了Windows下面能用的tcpdump
tcpdump.rar[誰下載?]