日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

(十三)Packet socket 和 sockaddr_ll

發布時間:2023/12/15 综合教程 42 生活家
生活随笔 收集整理的這篇文章主要介紹了 (十三)Packet socket 和 sockaddr_ll 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

描述
本文簡單描述了數據鏈路層的socket使用的兩種方法
正文
Linux下有兩種方式接收數據鏈路層的數據包:
(1)原始的方法,即創建一個類型為SOCK_PACKET的socket,該方法很普遍,但是缺乏靈活性;
(2)最新的方法,引入了幀過濾功能和性能上的提升,即創建一個指定協議簇為 PF_PACKET的socket,這需要root權限(類似于創建一個raw socket),并且socket的第三個參數必須指定一個以太網幀類型(Ethernet frame type);
使用第二種方法時,socket的第二個參數可以被設置為SOCK_DGRAM,主要區別是當指定SOCK_DGRAM時,獲取的數據包是去掉了數據鏈路層的頭(link-layer header),當指定SOCK_RAW時,獲取的數據包是一個完整的數據鏈路層數據包; SOCK_PACKET只返返回完整的數據鏈路層數據包,示例,接收完整的數據鏈路層數據包,可以這樣寫:

fd=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL));/*older systems*/


或者

fd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));/*newer systems*/


這樣將會接收到數據鏈路層所有協議幀;
如果我們只需要IPv4幀,可以這樣寫:

fd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP));/*new systems*/


或者

fd=socket(AF_INET,SOCK_PACKET,htons(ETH_P_IP));/*older systems*/


其它數據鏈路層類型定義的常量參數有 ETH_P_ARP 和 ETH_P_IPV6;
指定協議(protocol)為ETH_P_XXX即告訴數據鏈路層我只接收該類型的幀(frame),socket會自動過濾。如果數據鏈路支持混雜模式(promiscuous mode),可以設置socket可選參數PACKET_ADD_MEMBERSHIP選項,使用packet_mreq結構體指定一個以太網接口和混雜模式行為(PACKET_MR_PROMISC)。

接下來詳解 數據鏈路層的頭信息結構體sockaddr_ll

點擊(此處)折疊或打開

#include<sys/socket.h>
#include<linux/if_packet.h>
#include<net/ethernet.h>/*the L2 protocols*/

packet_socket=socket(AF_PACKET,intsocket_type,intprotocol);


數據鏈路層的頭信息通常定義在sockaddr_ll 的結構體中,protocol是按照網絡字節順序(network byte order),大部分定義在頭文件中,設置協議時,例如 htons(ETH_P_ALL)來接收所有的數據包;
如果要獲取從指定以太網接口卡上的數據包時,在 struct sockaddr_ll中指定網絡接口卡,綁定(bind)數據包到該interface上。只有sll_protocolsll_ifindex這兩個地址字段是用來bind的。

struct sockaddr_ll{
unsigned short sll_family;/*Always AF_PACKET*/
unsigned short sll_protocol;/*Physical-layer protocol*/
intsll_ifindex;/*Interface number*/
unsigned short sll_hatype;/*ARP hardware type*/
unsigned char sll_pkttype;/*Packet type*/
unsigned char sll_halen;/*Length of address*/
unsigned char sll_addr[8];/*Physical-layer address*/
};


sll_protocol: 標準以太網協議類型,按網絡字節順序。定義在中。
sll_ifindex: interface索引,0 匹配所有的網絡接口卡;
sll_hatype: ARP 硬件地址類型(hardware address type) 定義在中,常用 ARPHRD_ETHER
sll_pkttype: 包含了packet類型。
PACK_HOST 包地址為本地主機地址。
PACK_BROADCAST 物理層廣播包。
PACK_MULTICAST 發送到物理層多播地址的包。
PACK_OTHERHOST 發往其它在混雜模式下被設備捕獲的主機的包。
PACK_OUTGOING 本地回環包;
sll_addrssl_halen包含了物理層地址和其長度;

當發送數據包時,指定 sll_family, sll_addr, sll_halen, sll_ifindex, sll_protocol 就足夠了。其它字段設置為0; sll_hatype和 sll_pkttype是在接收數據包時使用的; 如果要bind, 只需要使用 sll_protocol和 sll_ifindex;

總結

以上是生活随笔為你收集整理的(十三)Packet socket 和 sockaddr_ll的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。