Linux網(wǎng)絡(luò)編程:原始套接字編程及實例分析_第1頁
Linux網(wǎng)絡(luò)編程:原始套接字編程及實例分析_第2頁
Linux網(wǎng)絡(luò)編程:原始套接字編程及實例分析_第3頁
Linux網(wǎng)絡(luò)編程:原始套接字編程及實例分析_第4頁
Linux網(wǎng)絡(luò)編程:原始套接字編程及實例分析_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、應(yīng)用層I FT? W TCP ip I NFS I I ARP RARP Linux網(wǎng)絡(luò)編程:原始套接字編程及實 例分析 一、原始套接字能干什么? 通常情況下程序員接所接觸到的套接字(Socket )為兩類: (1) 流式套接字(SOCK_STREAM) 種面向連接的 Socket,針對于面向連接的 TCP服務(wù)應(yīng)用; (2) 數(shù)據(jù)報式套接字(SOCK_DGRAM) 種無連接的Socket,對應(yīng)于無連接的 UDP服務(wù)應(yīng)用。 從用戶的角度來看,SOCK_STREAM SOCK_DGRAM這兩類套接字似乎的確涵蓋了TCP/IP應(yīng) 用的全部,因為基于TCP/IP的應(yīng)用,從協(xié)議棧的層次上講,在傳輸層的確

2、只可能建立于 TCP 或UDP協(xié)議之上,而 SOCK_STREAM SOCK_DGRAM又分別對應(yīng)于 TCP和UDP,所以幾乎 所有的應(yīng)用都可以用這兩類套接字實現(xiàn)。 網(wǎng)絡(luò)層; I 媒體(介質(zhì)) 但是,當(dāng)我們面對如下問題時,SOCK_STREAM SOCK_DGRAM將顯得這樣無助: (1) 怎樣發(fā)送一個自定義的IP包? (2) 怎樣發(fā)送一個ICMP協(xié)議包? (3) 怎樣分析所有經(jīng)過網(wǎng)絡(luò)的包,而不管這樣包是否是發(fā)給自己的? (4) 怎樣偽裝本地的IP地址? 這使得我們必須面對另外一個深刻的主題一一原始套接字(SOCK_RAW)原始套接字廣泛應(yīng) 用于高級網(wǎng)絡(luò)編程,也是一種廣泛的黑客手段。著名的網(wǎng)絡(luò)

3、sniffer(種基于被動偵聽原理 的網(wǎng)絡(luò)分析方式)、拒絕服務(wù)攻擊(DOS) IP欺騙等都可以通過原始套接字實現(xiàn)。 原始套接字(SOCK_RAW可以用來自行組裝數(shù)據(jù)包,可以接收本機網(wǎng)卡上所有的數(shù)據(jù)幀(數(shù)據(jù) 包),對于監(jiān)聽網(wǎng)絡(luò)流量和分析網(wǎng)絡(luò)數(shù)據(jù)很有作用。 原始套接字是基于IP數(shù)據(jù)包的編程(SOCK_PACKET是基于數(shù)據(jù)鏈路層的編程)。另外,必須 在管理員權(quán)限下才能使用原始套接字。 原始套接字(SOCK_RAW與標準套接字(SOCK_STREAMSOCK_DGRAM的區(qū)別在于原始套接字 直接置“根”于操作系統(tǒng)網(wǎng)絡(luò)核心(Network Core),而SOCK_STREAM SOCK_DGRAM則“

4、懸 浮”于TCP和UDP協(xié)議的外圍。 應(yīng)用程序 標準套接字 原始套接字 內(nèi)核空間 用戶空間 UDP 2 IP 10 流式套接字只能收發(fā)TCP協(xié)議的數(shù)據(jù),數(shù)據(jù)報套接字只能收發(fā)UDP協(xié)議的數(shù)據(jù),原始套 接字可以收發(fā)內(nèi)核沒有處理的數(shù)據(jù)包。 二、原始套接字編程 原始套接字編程和之前的UDP編程差不多,無非就是創(chuàng)建一個套接字后,通過這個套接字 接收數(shù)據(jù)或者發(fā)送數(shù)據(jù)。區(qū)別在于,原始套接字可以自行組裝數(shù)據(jù)包(偽裝本地IP,本地 MAC),可以接收本機網(wǎng)卡上所有的數(shù)據(jù)幀(數(shù)據(jù)包)。另外,必須在管理員權(quán)限下才能使用原 始套接字。 原始套接字的創(chuàng)建: int socket ( int family, int ty

5、pe, int protocol ); 參數(shù): family:協(xié)議族 這里寫 PF_PACKET type: 套接字類,這里寫 SOCK_RAW 不能寫“ 0”,取值如下,注意, protocol :協(xié)議類別,指定可以接收或發(fā)送的數(shù)據(jù)包類型, 傳參時需要用 htons() 進行字節(jié)序轉(zhuǎn)換。 ETH_P_IP IPV4數(shù)據(jù)包 ETH_P_ARP ARP數(shù)據(jù)包 ETH_P_ALL 任何協(xié)議類型的數(shù)據(jù)包 返回值 成功( 0 ) 套接字,這里為鏈路層的套接字 失敗( 0 ) 出錯 實例如下 / 所需頭文件 #include #include #include / perror int main(int

6、 argc,charchar *argv) int sock_raw_fd = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_ALL ) ); if(sock_raw_fd 0) perror(socket); return -1; return 0; 獲取鏈路層的數(shù)據(jù)包 ssize_t recvfrom( int sockfd, void *buf, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen ); 參數(shù) sockfd: 原始套接字 buf 接收數(shù)據(jù)緩沖區(qū) nbyt

7、es: 接收數(shù)據(jù)緩沖區(qū)的大小 flags套接字標志 (常為 0) from這里沒有用,寫 NULL addrlen 這里沒有用,寫 NULL 返回值 成功 接收到的字符數(shù) 失敗 -1 實例如下 #include #in elude #include #in elude int main (i nt argc,charchar *argv) unsigned char buf1024 = 0; int sock_raw_fd = socket (PF_PACKET, SOCK_RAW, hto ns(ETH_P_ALL ); /獲取鏈路層的數(shù)據(jù)包 int len = recvfrom (sock

8、_raw_fd, buf, sizeof(buf), 0, NULL, NU LL); prin tf(len = %dn, le n); return 0; 混雜模式 默認的情況下,我們接收數(shù)據(jù),目的地址是本地地址,才會接收。有時候我們想接收所有經(jīng) 過網(wǎng)卡的所有數(shù)據(jù)流,而不論其目的地址是否是它,這時候我們需要設(shè)置網(wǎng)卡為混雜模式。 網(wǎng)卡的混雜模式一般在網(wǎng)絡(luò)管理員分析網(wǎng)絡(luò)數(shù)據(jù)作為網(wǎng)絡(luò)故障診斷手段時用到,同時這個模 式也被網(wǎng)絡(luò)黑客利用來作為網(wǎng)絡(luò)數(shù)據(jù)竊聽的入口。在Linux操作系統(tǒng)中設(shè)置網(wǎng)卡混雜模式 時需要管理員權(quán)限。在Windows操作系統(tǒng)和Linux操作系統(tǒng)中都有使用混雜模式的抓包工 具,比如著

9、名的開源軟件Wireshark。 通過命令給Linux網(wǎng)卡設(shè)置混雜模式(需要管理員權(quán)限) 設(shè)置混雜模式:ifeonfig eth0 promisc :sudo- ifeonfig thO吾番 也丸崔 去 sudo password for wencong:7又JB此 wencongsz:.$ ifeonfig thO 查看網(wǎng)卡信息 ethDLink encap:以太網(wǎng) 硬件還證 c3: 9c: de:ec:b5:ef MTU: 15DG 躍點數(shù):丄 2棄過救巾貞數(shù) 劭辭喘霰嚴 int 地址:10 + 221,0.71 廣播:10*221 + D.255 掩碼:255.255.255.0 i n

10、et6 地址:feBD: ca9c:f: reec:t-5ef5cope: Link UP BROADCAST RUNNING PROMIScMULTICAST 接收數(shù)據(jù)包 :80291 錯誤 發(fā)送數(shù)據(jù) 碰撞:0 2 矮收字節(jié) t 102451D3 (10-2 MB) 發(fā)送字節(jié) 15506656 (5.5 MS) 取消混雜模式:ifeonfig eth0 -promisc wiiconcjsz:3udo ifconlig ethC -p工omi占二 wsrj 匚- $ if conf ig th04 ethOLink encap: UA太網(wǎng) inet 地址:10.221.0.71 廣播:10餐

11、1.0.255 n毗電 地址:fmBCi: m9u:dc:Ef:徒罕匚:b5ef/64 Scope:Link 心 EKOADXT FXJNNDdG1417:1500 躍點數(shù):1 岡卡住亂取消混雜模式 足 ch : 9*: dc:ec :b5: ef 掩碼:255.255.255.0 接收數(shù)揭包;B0弭 發(fā)送敵據(jù)包:藥1* 錯課汕-jf:o過載汀載波:o 沒隸牒 錯i吳:D丟棄巧過載詢 通過代碼給Linux網(wǎng)卡設(shè)置混雜模式 送字節(jié):5509910 i:5.5 M6) ?truct 丄freq ethreq ? ftrncpYlwthfKbifr, 就liciutl fgack-fw HHffT哉

12、5?壽艮 #threq.lfr_fl*gs Fr_FROMisc. ir octJ. taGcic raw fd. Toci五uu*:-r“i !葉“誰愛比皿存IB口赫 亠_F prrrorr s octlr r1 close (sodk raw fd) t exite); *2 .設(shè)賈網(wǎng)塔揍口標志 代碼如下: struct ifreq ethreq; / 網(wǎng)絡(luò)接口地址 strncpy(ethreq.ifr_ name, ethO, IFNAMSIZ); / 稱 if( -1 = ioctl(sock_raw_fd, SIOCGIFINDEX, close(sock_raw_fd); exit

13、(-1); ethreq.ifr_flags |= IFF_PROMISC; if( -1 = ioctl(sock_raw_fd, SIOCSIFINDEX, close(sock_raw_fd); exit(-1); 發(fā)送自定義的數(shù)據(jù)包: ssize_t sen dto( int sockfd, const void *buf, size_t n bytes,i nt flags, 網(wǎng)卡設(shè)置混雜模 const struct sockaddr *to, sockle n_t addrle n ); 參數(shù): sockfd: 原始套接字 buf:發(fā)送數(shù)據(jù)緩沖區(qū) nbytes:發(fā)送數(shù)據(jù)緩沖區(qū)的大小

14、 flags: 一般為 0 to:本機網(wǎng)絡(luò)接口,指發(fā)送的數(shù)據(jù)應(yīng)該從本機的哪個網(wǎng)卡出去,而不是以前的目的地址 addrlen : to所指向內(nèi)容的長度 返回值: 成功:發(fā)送數(shù)據(jù)的字符數(shù) 失?。?1 本機網(wǎng)絡(luò)接口的定義 原始套接字地址結(jié)構(gòu) 網(wǎng)絡(luò)接口地址 指定網(wǎng)卡名 獲取網(wǎng)絡(luò)接 發(fā)送完整代碼如下: struct sockaddr_ll sll;/ struct ifreq ethreq;/ strncpy(ethreq.ifr_ name, eth0, IFNAMSIZ);/ 稱 if( -1 = ioctl(sock_raw_fd, SIOCGIFINDEX, ereq) / 口 perror(i

15、octl); close(sock_raw_fd); exit(-1); /*將網(wǎng)絡(luò)接口賦值給原始套接字地址結(jié)構(gòu)*/ bzero( sll.sll_ifi ndex= ethreq.ifr_ifi ndex; /發(fā)送數(shù)據(jù) / sen d_msg, msg_len這里還沒有定義,模擬一下 int len =sen dto (sock_raw_fd, sen d_msg, msg_le n, 0 , (struct sock addr *) if( len = -1) perror(se ndto); 這里頭文件情況如下: #include / struct ifreq #include / io

16、ctl 、SIOCGIFADDR #include / socket #in elude / ETH_P_ALL #in clude / struct sockaddr_ll 三、原始套接字實例:MAC頭部報文分析 那我們接 由上得知,我們可以通過原始套接字以及recvfrom()可以獲取鏈路層的數(shù)據(jù)包, 收的鏈路層數(shù)據(jù)包到底長什么樣的呢? 鏈路層封包格式 f 0 x030c| IP收擠擢 OvCBDS 010835 J KARP泮求陰存 MAC頭部(有線局域網(wǎng)) ll 乏一 1- 1 -II 1 II亠 1 I _1 注意:CRG PAD在組包時可以忽略 鏈路層數(shù)據(jù)包的其中一種情況: un

17、sig ned char msg1024 = / 組 MAC14 0 xb8, 0 x88, 0 xe3, 0 xe1,0 x10, 0 xe6, / dst_mac: b8:88:e3:e1:1 0:e6 0 xc8, 0 x9c, 0 xdc, 0 xb7, 0 x0f, 0 x19, / src_mac: c8:9c:dc:b7:0 f:19 協(xié)議 0 x08, 0 x00,/類型:0 x0800 IP / / ; 接收的鏈路層數(shù)據(jù)包,并對其進行簡單分析 #i nclude #i nclude #i nclude #i nclude #i nclude #i nclude #in clu

18、de int main (i nt argc,charchar *argv) int i =0; unsigned char buf1024=; int sock_raw_fd = socket (PF_PACKET, SOCK_RAW, hto ns(ETH_P_ALL ); while(1) un sig ned char src_mac18=; un sig ned char dst_mac18=; /獲取鏈路層的數(shù)據(jù)幀 recvfrom(sock_raw_fd, buf, sizeof(buf),0,NULL,NULL); /從buf里提取目的 mac、源 mac spri ntf(dst_mac,%02x:%02x:%02x:%02x:%02x:%02x, buf0, buf1, buf2, buf3, buf4, buf5); spri ntf(src_mac,%02x:%02x:%02x:%02x:%02x:%02x, buf6, buf7, buf8, buf9, buf10, buf11); /判斷是否為IP數(shù)據(jù)包 if(buf12=0 x08 prin tf(MAC:%s %sn,src_mac,dst_mac); /判斷是否為ARP數(shù)據(jù)包 else if(buf12=0 x08 prin tf(MAC:%s %sn,src_mac,dst_mac); /

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論