linux sock_raw原始套接字編程

sock_raw原始套接字編程可以接收到本機網卡上的數據幀或者數據包,對與監聽網絡的流量和分析是很有作用的.一共可以有3種方式創建這種socket
?
1.socket(AF_INET, SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP)發送接收ip數據包
2.socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))發送接收以太網數據幀
3.socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))過時了,不要用啊
?
理解一下SOCK_RAW的原理, 比如網卡收到了一個 14+20+8+100+4 的udp的以太網數據幀.
?
首 先,網卡對該數據幀進行硬過濾(根據網卡的模式不同會有不同的動作,如果設置了promisc混雜模式的話,則不做任何過濾直接交給下一層輸 入例程,否則非本機mac或者廣播mac會被直接丟棄).按照上面的例子,如果成功的話,會進入ip輸入例程.但是在進入ip輸入例程之前,系統會檢查系 統中是否有通過socket(AF_PACKET, SOCK_RAW, ..)創建的套接字.如果有的話并且協議相符,在這個例子中就是需要ETH_P_IP或者ETH_P_ALL類型.系統就給每個這樣的socket接收緩 沖區發送一個數據幀拷貝.然后進入下一步.
?
其次,進入了ip輸入例程(ip層會對該數據包進行軟過濾,就是檢查校驗或者丟棄非本機ip 或者廣播ip的數據包等,具體要參考源代碼),例子 中就是如果成功的話會進入udp輸入例程.但是在交給udp輸入例程之前,系統會檢查系統中是否有通過socket(AF_INET, SOCK_RAW, ..)創建的套接字.如果有的話并且協議相符,在這個例子中就是需要IPPROTO_UDP類型.系統就給每個這樣的socket接收緩沖區發送一個數據 幀拷貝.然后進入下一步.
?
最后,進入udp輸入例程 ...
?
ps:如果校驗和出錯的話,內核會直接丟棄該數據包的.而不會拷貝給sock_raw的套接字,因為校驗和都出錯了,數據肯定有問題的包括所有信息都沒有意義了.
?
進一步分析他們的能力.
1. socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
能:該套接字可以接收協議類型為(tcp udp icmp等)發往本機的ip數據包,從上面看的就是20+8+100.
不能:不能收到非發往本地ip的數據包(ip軟過濾會丟棄這些不是發往本機ip的數據包).
不能:不能收到從本機發送出去的數據包.
發送的話需要自己組織tcp udp icmp等頭部.可以setsockopt來自己包裝ip頭部
這種套接字用來寫個ping程序比較適合
????
2. socket(PF_PACKET, SOCK_RAW, htons(x));?
這個套接字比較強大,創建這種套接字可以監聽網卡上的所有數據幀.從上面看就是20+20+8+100.最后一個以太網crc從來都不算進來的,因為內核已經判斷過了,對程序來說沒有任何意義了.
能: 接收發往本地mac的數據幀
能: 接收從本機發送出去的數據幀(第3個參數需要設置為ETH_P_ALL)
能: 接收非發往本地mac的數據幀(網卡需要設置為promisc混雜模式)
協議類型一共有四個
ETH_P_IP? 0x800????? 只接收發往本機mac的ip類型的數據幀
ETH_P_ARP 0x806????? 只接受發往本機mac的arp類型的數據幀
ETH_P_ARP 0x8035???? 只接受發往本機mac的rarp類型的數據幀
ETH_P_ALL 0x3??????? 接收發往本機mac的所有類型ip arp rarp的數據幀, 接收從本機發出的所有類型的數據幀.(混雜模式打開的情況下,會接收到非發往本地mac的數據幀)
?
發 送的時候需要自己組織整個以太網數據幀.所有相關的地址使用struct sockaddr_ll 而不是struct sockaddr_in(因為協議簇是PF_PACKET不是AF_INET了),比如發送給某個機器,對方的地址需要使用struct sockaddr_ll.
?
這種socket大小通吃,強悍
linux socket調用與arp報文發送

Linux提供最常用的網絡通信應用程序開發接口--Berkerley套接字(Socket).它既適用于同一主機上進程間通信(IPC),又適用于不同主機上的進程間通信。套接字的設置通過socket調用完成:

int socket(int family,int type,int protocol);

其中family指通信域或協議族,Linux系統支持的網絡協議族有PF_UNIX,PF_IPX,PF_PACKET等幾十種;type為套接字類型,目前有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET等;protocol是套接字所用的特定協議類型號.

Linux系統提供的基于數據鏈路層開發應用程序的接口集成在套接字中,它是通過創建packet類型的套接宇.使應用程序可直接在數據鏈路層接收或發送未被系統處理的原始的數據報文(如ARP報文),用戶也可以使用packet類型的套接宇在物理層上定義自己特殊的網絡協議。只有注冊號為0的用戶(超級用戶)進程才能建立或打開用于訪問網絡低層的套接字.在Linux系統中,用以下三種方式創建的packet套接字可直接用于訪問數據鏈路層:
(1)PF_INET協議族中SOCK_PACKEI類型的套接字
(2)PF_PACKET協議族中SOCK_RAW類型的套接字
(3)PF_PACKET協議族中SOCK_DGRAM類型的套接字

Linux 2.0中對數據鏈路層的操作主要使用SOCK_PACKET定義的packet套接字.初始化定義如下:
sockfd=socket(AF_INET,SOCK_PACKET,protocol);
其中,protocol用于決定套接字所使用的物理層協議(在IEEE802.3中定義).筆者在此選擇常用的物理層協議ETH_P_IP(Internet協議).SOCK_PACKET使用一種比較老的sockaddr_pkt數據結構來設置網絡接口。

在Linux 2 2中使用PF_PACKET代替SOCK_PACKET來定義packet套接字.這種套接字的初始化定義如下:
sockfd=socket(PF_PACKET,socket_type,protocol);
其中socket_type只能為SOCK_RAW或SOCK_DGRAM,protocol為物理層通信協議(同上)。SOCK_RAW和SOCK_DGRAM類型套接字使用一種與設備無關的標準物理層地址結構sockaddr_ll,但具體操作的報文格式不同。SOCK_RAW套接字直接向網絡硬件驅動程序發送(或從網絡硬件驅動程序接收)沒有任何處理的完整數據報文(包括物理幀的幀頭),這就要求程序員必須了解對應設備的物理幀幀頭結構,才能正確地裝載和分析報文。SOCK_DGRAM套接字收到的數據報文的物理幀幀頭會被系統自動去掉,同樣,在發送時.系統將會根據sockaddr_ll結構中的目的地址信息為數據報文舔加一個臺適的物理幀幀頭。

默認情況下.從任何接口收到的符合指定協議的所有數據報文都會被傳送到packet套接字。使用bind系統調用以一個sochddr_l1地址結構將paccket套接字與某個網絡接口相綁定,可使套接字只接收指定接口的
數據報文.socaddr_ll地址結構定義如下:
struct sockaddr_ll
{
unsigned short sll_family; /* 總是 AF_PACKET */
unsigned short sll_protocol; /* 物理層的協議 */
int sll_ifindex; /* 接口號 */
unsigned short sll_hatype; /* 報頭類型 */
unsigned char sll_pkttype; /* 分組類型 */
unsigned char sll_halen; /* 地址長度 */
unsigned char sll_addr[8]; /* 物理層地址 */
};

一、利用PF_lNET協議族中SOCK_PACKET類型的套接宇實現ARP
(1)建套接字
創建套接宇采用socket系統調用,格式如下:
sockfd=socket(PF_INET,SOCK_PACKET,htons(ETH_P_ARP));
(2)裝載報文
對于SOCK_PACKET類型的套接字,以太網物理幀頭應作為所發送報文一部分由程序員設置,物理幀頭的格式定義如下:(in /usr/include/linux/if_ether.h)
92 struct ethhdr
93 {
94 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
95 unsigned char h_source[ETH_ALEN]; /* source ether addr */
96 unsigned short h_proto; /* packet type ID field */
97 };
實際發送的地址解析報文幀由以太網物理幀頭與幀數據(ARP報文)共同組成,用結構體ARPPACKET表
示如下:
typedef struct {
struct ethhdr eth_header; //struct defined in linux/if_ether.h
ARPHDR arp_header;
}ARPPACKET;
上述報文結構的裝載比較簡單。對ARP部分,arp_header的設置如下:
ptk.arp_header.ar_hrd=htons(ARPHRD_ETHER); //ARPHRD_ETHER is defined in linux/if_arp.h
ptk.arp_header.ar_pro=htons(ETHERTYPE_IP);
ptk.arp_header.ar_hln=6;
ptk.arp_header.ar_pln=4;
ptk.arp_header.ar_op=htons(ARPOP_REQUEST);

pkt.arp_header.ar_sha[]、pkt.arp_header.ar_sip[]、pkt_arp_header.ar_tip[]分別填入本機的物理地址、ip地址和要解析的對方主機的ip地址.返回報文中pkt.arp_header.tha[]中的內容就是解析
得到的對方主機的物理地址。

對于以太網幀頭部分,pkt.eth_header.h_dest[]為目的地址,即廣播物理地址0xFFFFFF, pkt.eth_header.source[]為本機物理地址(同pkt.arp_header.ar_sha[]),
pkt.eth_header.h_proto賦值htons(ETHERTYPE_ARP)表示為地址解析類型報文。
ETHERTYPE_ARP與ETH_P_ARP的值都是0x0806,只是定義的文件不同。前者定義在net/ethernet.h,后者定義在linux/if_ether.h

(3)報文的發送與接收
在數據鏈路層發送/接收報文與在IP層發送/接收數據報文類似,分別用系統調用sendto()和recvfrom()
完成,只是要將配置好的含有目標地址的報文發往本地網絡硬件而不是目標主機。相應的程序段如下:
struct sockaddr to,from;
int fromlen=0;
strcpy(to.sa_data,"eth0");
sendto(sockfd,pkt,sizeof(struct ARPPACKET),0,&to,sizeof(struct sockaddr));
recvfrom(sockfd,buf,PACKET_SIZE,0,&from,&fromlen);
其中buf為包含結構體ARPPACKET的字符型指針。

通過檢驗所接收到的ARP應答報文中arp_header.ar_op項是否為ARPOP_REPLY(ARP應答)同時arp_header.ar_tip是否為已知的對方主機的IP地址來判斷所得到的解析地址是否正確.


二、利用PF_PACKET協議族中SOCK_RAW類型的套接字實現ARP
(1)創建套接字
sockfd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ARP));
(2)裝載報文
與SOCK_PACKET類型的套接字相同,SOCK_RAW類型的套接字對鏈路層操作時,也要求以太網物理幀頭應作為所發送報文一部分由程序員設置.
(3)報文的發送與接收
SOCK_RAW類型套接字使用標準的物理層地址結構sockaddr_ll,所以,報文發送之前,應將套接字綁定到(使用bind()系統調用)配置好的本地物理地址結構my_etheraddr,同時還需配置目的物理地址結構broad_etheraddr.
示例如下:
struct aockaddr_ll my_etheraddr,broad_etheraddr;
my_etheraddr.sll_family=AF_PACKET;
my_etheraddr.sll_protocol=htons(ETH_P_ARP);
my_etheraddr.sll_ifindex=2; /*接口號2表示是eth0*/
my_etheraddr.sll_hatype=ARPHRD_ETHER;
my_etheraddr.sll_pkttype=PACKET_HOST;
my_etheraddr.sll_halen=ETH_ALEN;
my_etheraddr.sll_addr[8]中放入本主機的物理地址。

broad_etheraddr的配置除了sll_pkttype取PACKET_BROADCAST和sll_addr取廣播物理地址(0xFFFFFF)外,其他選項與my_etheraddr配置相同。

綁定格式如下:
bind(sockfd,(struct sockaddr *)&my_etheraddr,sizeof(my_etheraddr));

發送與接收調用程序如下:
sendto(sockfd,buf,sizeof(struct ARPPACKET),0,
(struct sockaddr *)&broad_etheraddr,sizeof(broad_etheraddr));

recvform(sockfd,buf,PACKET_SIZE,&from,&fromlen);

三、利用PF_PACKET協議族中SOCK_DGRAM類型的套接字實現ARP
SOCK_DGRAM類型的套接字不要求程序員配置以太網幀頭,所以所發送的報文只有數據區(ARP報文)部分,其它與SOCK_RAW類型的套接字相同。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253803.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253803.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253803.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

邏輯綜合——施加約束

Design Compiler時一個約束驅動(constraint-driven)的綜合工具,它的結果與設計者施加的約束條件密切相關。 一、面積約束 進行面積的約束,也就是告訴DC綜合的電路面積要在多少以內。在介紹約束命令之前,先了解一下面積…

[Codevs] 1004 四子連棋

1004 四子連棋 時間限制: 1 s空間限制: 128000 KB題目等級 : 黃金 Gold題目描述 Description在一個4*4的棋盤上擺放了14顆棋子,其中有7顆白色棋子,7顆黑色棋子,有兩個空白地帶,任何一顆黑白棋子都可以向上下左右四個方向移動到相鄰…

鏈接中獲取文件名

算得上是-test.pdf 獲取文件名 var str http://aaa.com/s/ddd/算得上是-test.pdf; console.log(str.match(/([^/*.])\.\w$/)) console.log(str.match(/([^/*.])\.\w$/)[0]) // 轉載于:https://www.cnblogs.com/cssfirefly/p/6163370.html

邏輯綜合——優化電路

對進行時序路徑、工作環境、設計規則等進行約束完成之后,DC就可以進行綜合、優化時序了,DC在優化過程中主要的策略將在下面進行說明。然而,當普通模式下不能進行優化的,就需要我們進行編寫腳本來改進DC的優化來達到時序要求。 DC…

DOM包裹wrap()方法

DOM包裹wrap()方法 如果要將元素用其他元素包裹起來,也就是給它增加一個父元素,針對這樣的處理,JQuery提供了一個wrap方法 .wrap( wrappingElement ):在集合中匹配的每個元素周圍包裹一個HTML結構 簡單的看一段代碼: &…

usleep函數

usleep功能把進程掛起一段時間, 單位是微秒(百萬分之一秒); 頭文件: unistd.h 語法: void usleep(int micro_seconds); 返回值: 無 內容說明:本函數可暫時使程序停止執行。參數 micro_seconds 為要暫停的微…

限制Xamarin獲取圖片的大小

限制Xamarin獲取圖片的大小在App開發中,經常會使用網絡圖片。因為這樣不僅可以減少App的大小,還可以動態更新圖片。但是手機使用網絡環境千差萬別。當網絡環境不是理想的情況下,加載網絡圖片就是一個棘手的問題了。為了避免長時間加載圖片影響…

Linux應用開發自學之路

前言 在 「關于我 」那篇博文里,朋友們應該知道了我不是科班出身,是由機械強行轉行到Linux應用開發方向。下面我就詳細向大家介紹自己這一路上的轉行歷程,希望對大家有所啟發。 我是學機械專業的,對于機械專業我還是很感興趣&…

Verdi 基礎教程

一、Verdi 功能 查看設計debugVerdi不能自己產生波形 二、Verdi使用流程 1、Verdi環境配置 .bashrc中配置 export Verdi_HOME$Synopsys_Dir/Verdi2015 #export NOVAS_HOME$Synopsys_Dir/Verdi2015 export PATH$Verdi_HOME/bin:$PATH export LD_LIBRARY_PATH"/opt/Syno…

ida和idr機制分析(盤符分配機制)

內核ida和idr機制分析(盤符分配機制) ida和idr的機制在我個人看來,是內核管理整數資源的一種方法。在內核中,許多地方都用到了該結構(例如class的id,disk的id),更直觀的說&#xff0…

MIPI CSI-2學習

CSI(Camera Serial Interface)定義了攝像頭外設與主機控制器之間的接口,旨在確定攝像頭與主機控制器在移動應用中的標準。 關鍵詞描述 縮寫解釋CCICamera Control Interface(物理層組件,通常使用I2C或I3C進行通信&…

internet網絡 checksum校驗和計算方法

http://hi.baidu.com/%CE%C4%B3%AD%B9%AB/blog/item/7d9a4e08f82d72b32eddd4cb.html

最有效的創建大數據模型的6個技巧

數據建模是一門復雜的科學,涉及組織企業的數據以適應業務流程的需求。它需要設計邏輯關系,以便數據可以相互關聯,并支持業務。然后將邏輯設計轉換成物理模型,該物理模型由存儲數據的存儲設備、數據庫和文件組成。 歷史上&#xff…

【轉】Castle Windsor之組件注冊

【轉】Castle Windsor之組件注冊 注冊方式較多&#xff0c;大體有這么幾種&#xff0c;學習得比較粗淺&#xff0c;先記錄&#xff1a;1、逐個注冊組件即對每個接口通過代碼指定其實現類&#xff0c;代碼&#xff1a;container.Register(Component.For<IMyService>() //接…

Verilog 補碼加法溢出判斷及處理

補碼加法運算溢出判斷三種方法&#xff1a; 一、符號位判斷 Xf、Yf分別兩個數的符號位,Zf為運算結果符號位。 當Xf Yf 0&#xff08;兩數同為正&#xff09;,而Zf1(結果為負)時,負溢出&#xff1b;當出現Xf Yf 1&#xff08;兩數同為負&#xff09;,而Zf0&#xff08;結果為…

Android繪制(三):Path結合屬性動畫, 讓圖標動起來!

Android繪制(一):來用shape繪出想要的圖形吧! Android繪制(二):來用Path繪出想要的圖形吧! 目錄 效果圖前言繪制屬性動畫最后效果圖 不廢話, 直接上效果圖, 感興趣再看下去. 其實不單單是效果圖演示的, 運用熟練的話各種圖標之間都是可以切換的. 前言 之前的文章也說了, path還…

{{view 視圖層}}微信小程序

微信小程序 view 視圖層//自學 1.數據綁定 數據綁定WXML中的動態數據均來自對應Page的data。 簡單綁定數據綁定使用"Mustache"語法&#xff08;雙大括號&#xff09;將變量包起來&#xff0c;可以作用于&#xff1a; 內容<view> {{ message }} </view>Pa…

CMOS圖像傳感器——概述

一、概述 圖像傳感器是把光學圖像信息轉換成電信號的器件。圖像傳感器是隨著電視技術在20世紀30年代發展起來的,早期圖像傳感器技術的最重要貢獻在于建立了掃描(Scan)的概念,用掃描的方法把二維空間平面上的光電信息離散成行(Line)和幀(Frame),然后按空間順序讀出形成…

nand flash壞塊管理OOB,BBT,ECC

0.NAND的操作管理方式 NAND FLASH的管理方式&#xff1a;以三星FLASH為例&#xff0c;一片Nand flash為一個設備(device)&#xff0c;1 (Device) xxxx (Blocks)&#xff0c;1 (Block) xxxx (Pages)&#xff0c;1(Page) 528 (Bytes) 數據塊大小(512Bytes) OOB 塊大小(16Byte…