Provided by: manpages-zh_1.6.3.6-1_all bug

NAME

       分組(也譯為資料包),PF_PACKET  -  在裝置層的分組介面  譯註:PF_PACKET  中的 PF 是 protocol
       family(協議族)的縮寫。

SYNOPSIS 總覽

       #include <sys/socket.h>
       #include <features.h> /* 需要裡面的 glibc 版本號 */
       #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
       #include <netpacket/packet.h>
       #include <net/ethernet.h> /* 鏈路層(L2)協議 */
       #else
       #include <asm/types.h>
       #include <linux/if_packet.h>
       #include <linux/if_ether.h> /* 鏈路層協議 */
       #endif

       packet_socket=socket(PF_PACKET,intsocket_type,intprotocol);

DESCRIPTION 描述

       分組套介面(也譯為插口或套接字)被用於在裝置層(OSI 的鏈路層) 收發原始(raw  )分組。它允許使用
       者在使用者空間實現在物理層之上的 協議模組。

       對於包含鏈路層報頭的原始分組,socket_type 引數是 SOCK_RAW; 對於去除了鏈路層報頭的加工過的
       分組,socket_type 引數是 SOCK_DGRAM。鏈路層報頭資訊可在作為一般格式的 sockaddr_ll 中  的中
       得到。socket 的 protocol 引數指的是 IEEE 802.3 的按網路 層排序的協議號,在標頭檔案中有所有
       被允許的 協議的列表。當 protocol 被設定為 htons(ETH_P_ALL)時,可以接  收所有的協議。到來的
       此種類型的分組在傳送到在核心實現的協議 之前要先傳送給分組套介面。

       譯註:DGRAM  是資料報的意思,htons 函式名是 hosts to networks of a short (16位整數的從主機
       到網路的位元組序變換)的縮寫。

       只有有效 uid 是 0 或有 CAP_NET_RAW 能力的程序可以開啟分組 套介面。

       傳送到裝置和從裝置傳送來的 SOCK_RAW 分組不改變任何分組資料。 當收到一個  SOCK_RAW  分組時,
       地址仍被分析並傳送到一個標準的  sockaddr_ll 地址結構中。當傳送一個 SOCK_RAW 分組時, 使用者
       供 給的緩衝區應該包含物理層報頭。接著此分組不加修改的放入目的 地址定義的介面的網路驅動程式
       的佇列中。一些裝置驅動程式總是   增加其他報頭。SOCK_RAW   分組與已被廢棄的  Linux  2.0  的
       SOCK_PACKET 分組類似但不相容。

       對  SOCK_DGRAM   分組的操作要稍微高一層次。在分組被傳送到使用者   之前物理報頭已被去除。從
       SOCK_DGRAM分組套介面送出的分組在被 放入網路驅動程式的佇列之前,基於在 sockaddr_ll 中的目的
       地址 得到一個適合的物理層報頭。

       預設的所有特定協議型別的分組被髮送到分組套介面。為了只從特 定的介面得到分組,使用bind(2)來
       指定一個在  sockaddr_ll 結構 中的地址,以此把一個分組套介面繫結到一個介面上。只有地址字 段
       sll_protocol 和 sll_ifindex 被繫結用途所使用。

       不支援在分組套介面上的 connect(2) 操作。(不能作為客戶端使用)

ADDRESS TYPES 地址型別

       sockaddr_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]; /* 物理層地址 */
              };

       sll_protocol  是在  linux/if_ether.h   標頭檔案中定義的按網路層排   序的標準的以太楨協議型
       別。sll_ifindex 是介面的索引號(參見 netdevice(2));0 匹配所有的介面(當然只有合法的才用於繫
       結)。 sll_hatype 是在 linux/if_arp.h 中定義的 ARP  硬體地址型別。  sll_pkttype  包含分組型
       別。有效的分組型別是:目標地址是本地     主機的分組用的    PACKET_HOST,物理層廣播分組用的
       PACKET_BROADCAST    ,傳送到一個物理層多路廣播地址的分組用的    PACKET_MULTICAST,    在混
       雜(promiscuous)模式下的裝置驅動器發向其他主機的分組用的 PACKET_OTHERHOST,本源於本地主機的
       分組被環回到分組套介面用 的  PACKET_OUTGOING。這些型別只對接收到的分組有意義。sll_addr  和
       sll_halen 包括物理層(例如 IEEE 802.3)地址和地址長度。精確 的解釋依賴於裝置。

       譯註:  (1) 對於乙太網(ethernet) OSI 模型不完全適用,以太楨定義包 括物理層和鏈路層的基本內
       容, 所謂的以太楨協議型別標識的是網路 層的協議。IEEE 802 委員會為與 OSI  相一致,把以太楨定
       義稱為   MAC(medium   access  control)層,在  MAC  層與網路層之間加入  LLC  (logical  link
       control)層,補充上了 OSI 標準的鏈路層。但在BSD TCP/IP 中是為了相容官方標準才被實現的。對於
       TCP/IP 協議族 OSI 模型也不完全適用,TCP/IP 沒定義鏈路層,只能用 UNIX 的設 備驅動程式去對應
       鏈路層。無論如何這是既成事實,在本手冊頁中物   理層、鏈路層、裝置層指的都是乙太網的    MAC
       層。餘以為不必嚴格 按層次劃分去理解問題,現在這個協議棧是優勝劣汰的結果,不是委 員會討論出
       來的。 (2) 乙太網地址分為三類,物理地址(最高位為0),多路廣播地址  (最高位為1),廣播地址(全
       是1)。以  DP8390 為例,它的接收配置 暫存器的 D2 位用來指定 NIC 是否接受廣播楨,D3 位用來指
       定   NIC   是否對多路廣播楨進行過濾,D4   位用來指定   NIC是否接受所有的物    理地址楨。混
       雜(Promiscuous)模式就是接收所有物理地址楨。

SOCKET OPTIONS 套介面選項

       分組套介面可被用來配置物理層的多路廣播和混雜模式。配置透過呼叫 setsockopt(2)實現,套介面引
       數是一個分組套介面、層次引數為 SOL_PACKET 、選項引數中的 PACKET_ADD_MEMBERSHIP  用於增加一
       個繫結,選項引數中的  PACKET_DROP_MEMBERSHIP  用於刪除一個綁  定。兩個選項都需要作為引數的
       packet_mreq 結構:

              struct packet_mreq
              {
              int mr_ifindex; /* 介面索引號 */
              unsigned short mr_type; /* 動作 */
              unsigned short mr_alen; /* 地址長度 */
              unsigned char mr_address[8]; /* 物理層地址 */
              };

       mr_ifindex 包括介面的介面索引號,mr_ifindex 的狀態是可以改 變的。mr_type  引數指定完成那個
       動作。PACKET_MR_PROMISC   允許  接收在共享介質上的所有分組,這種接受狀態常被稱為混雜模式;
       PACKET_MR_MULTICAST   把套介面繫結到由mr_address   和    mr_alen    指定的物理層多路廣播組
       上;PACKET_MR_ALLMULTI 設定套介面接 收所有的來到介面的多路廣播分組。

       除此之外傳統的 ioctls 如 SIOCSIFFLAGS, SIOCADDMULTI, SIOCDELMULTI 也能用於實現同樣的目的。

IOCTLS 輸入輸出控制

       SIOCGSTAMP 用來接收最新收到的分組的時間戳。它的引數是 timeval 結構。

       除此之外,所有的在 netdevice(7) 和 socket(7) 中定義的標準 的 ioctl 在分組套介面上均有效。

ERROR HANDLING 錯誤處理

       分組套接只對傳送分組到裝置驅動程式時發生的錯誤做錯誤處理,  其他不做錯誤處理。這裡沒有等待
       解決的錯誤的概念。

COMPATIBILITY 相容性

       在 Linux 2.0 中,得到分組套介面的唯一方法是呼叫 socket(PF_INET, SOCK_PACKET, protocol)。它
       仍被支援但變得 沒有價值。兩種方法的主要不同在於 SOCK_PACKET 使用老的 sockaddr_pkt 結構來指
       定一個介面,沒有提供物理層介面無關性。 (依賴於物理裝置)

              struct sockaddr_pkt
              {
              unsigned short spkt_family;
              unsigned char spkt_device[14];
              unsigned short spkt_protocol;
              };

       spkt_family 包括裝置型別,spkt_protocol 是在 中定義的 IEEE 802.3 協議型別,spkt_device  是
       表示裝置名的 null 終結的字串,例如 eth0。

       譯註: "who is nntp" 就是一個以 null (' ')終結的字串。

       這個結構已經被廢棄,不應在新的程式碼中使用。

NOTES 注意

       不建議對要求可移植的程式透過 pcap(3) 使用 PF_PACKET 協議族; 它只覆蓋了 PF_PACKET 特徵的一
       個子集。

       譯註:該函式庫可在 ftp://ftp.ee.lbl.gov/libpcap.tar.Z 得到。

       SOCK_DGRAM 分組套介面對 IEEE 802.3 楨不做生成或分析 IEEE 802.2 LLC  報頭的嘗試。當在套介面
       中指定了  ETH_P_802_3  協議,  告知核心生成 802.3 楨,並填寫了長度欄位;使用者必須提供提供
       LLC 報頭來產生符合標準的分組。到來的 802.3 分組不在協議 欄位 DSAP/SSAP  上實現多路複用;而
       是故意的把  ETH_P_802_2 協議的 LLC 報頭提供給使用者。所以不可能繫結到 ETH_P_802_3; 而可以
       繫結到 ETH_P_802_2 並自己做多路複用。預設的傳送的是 標準的乙太網 DIX 封裝並填寫協議欄位。

       譯註: 長度欄位和協議欄位其實都是以太楨的第四欄位,這個欄位 的值在小於 1518  時表示此以太楨
       是  IEEE 802.3 楨,在大於1536 時表示此以太楨是 DIX 楨。DIX 中的 D 代表 DEC,I 代表 Intel,
       X 代表 Xerox。

       分組套介面不是輸入或輸出防火牆的系列主題。

ERRORS 錯誤資訊

       ENETDOWN
              介面未啟動。

       ENOTCONN
              未傳遞介面地址。

       ENODEV 在介面地址中指定了未知的裝置名或介面索引。

       EMSGSIZE
              分組比介面的 MTU(最大傳輸單元)大。

       ENOBUFS
              沒有足夠的記憶體分配給分組。

       EFAULT 使用者傳遞了無效的地址。

       EINVAL 無效引數。

       ENXIO  介面地址包含非法介面索引號。

       EPERM  使用者沒有足夠的許可權來執行這個操作。

       EADDRNOTAVAIL
              傳遞了未知的多路廣播組地址。

       ENOENT 未收到分組。

              除此之外,底層的驅動程式可能產生其他的錯誤資訊。

VERSIONS 版本

       PF_PACKET 是 Linux 2.2 的新特徵。Linux 的早期版本只支援 SOCK_PACKET。

BUGS 缺陷

       glibc 2.1 沒有定義 SOL_PACKET。建議的補救是使用
              #ifndef SOL_PACKET
              #define SOL_PACKET 263
              #endif
       在此以後的 glibc 版本中更正了錯誤並且在 libc5 系統上不會發生。

       沒有對 IEEE 802.2/803.3 LLC 的處理被認為是缺陷。

       套介面過濾器未歸入文件。

CREDITS 貢獻者

       本手冊頁是 Andi Kleen 寫的,他得到了 Matthew Wilcox 的幫助。 在 Linux 2.2  中的  PF_PACKET
       是 Alexey Kuznetsov 實現的,他 的實現是以 Alan Cox 和其他人的程式碼為基礎的。

SEE ALSO 參見

       ip(7),socket(7),socket(2),raw(7),pcap(3).            RFC894-IP資料報的Ethernet楨封裝標準。
       RFC1700-IP資料報的IEEE802.3楨封裝標準。 標頭檔案linux/if_ether.h包含物理層協議。

[中文版維護人]

       mhss <jijingzhisheng@up369.com>

[中文版最新更新]

       2000/10/15

《中國linux論壇man手冊頁翻譯計劃》:

       http://cmpp.linuxforum.net

       本頁面中文版由中文 man 手冊頁計劃提供。
       中文 man 手冊頁計劃:https://github.com/man-pages-zh/manpages-zh