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

NAME

       分組(也譯為數據包),PF_PACKET - 在設備層的分組接口 譯注:PF_PACKET 中的
       PF 是 protocol family(協議族)的縮寫。

SYNOPSIS`覽
       #include <sys/socket.h>
       #include <features.h> /*n glibc */
       #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
       #include <netpacket/packet.h>
       #include <net/ethernet.h> /*h]L2*/
       #else
       #include <asm/types.h>
       #include <linux/if_packet.h>
       #include <linux/if_ether.h> /*h */
       #endif

       packet_socket=socket(PF_PACKET,intsocket_type,intprotocol);

DESCRIPTIONyz
       分組套接口(也譯為插口或套接字)被用於在設備層(OSI 的鏈路層)  收發鴝l(raw
       )分組。它允許使用者在使用者空間實現在物理層之上的 協議模塊。

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

       譯注:DGRAM 是數據報的意思,htons 函數名是 hosts to networks of a short
       (16位整數的從主機到網路的字節序變換)的縮寫。

       只有有效 uid 是 0 或有 CAP_NET_RAW 能力的進程可以打開分組 套接口。

       傳送到設備和從設備傳送來的  SOCK_RAW 分組不改變任何分組數據。 當收到一
       SOCK_RAW     分組時,     地址仍被分析並傳送到一蚍郱      sockaddr_ll
       地址結構中。當發送一         SOCK_RAW         分組時,         使用者供
       給的緩沖區應該包含物理層報頭。接著此分組不加蚹麊漫韙J目的
       地址定義的接口的網路驅動程式的隊列中。一些設備驅動程式總是
       增加其他報頭。SOCK_RAW  分組與已被廢棄的  Linux  2.0   的   SOCK_PACKET
       分組類似但不相容。

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

       預設的所有特定協議類型的分組被發送到分組套接口。為了只從特
       定的接口得到分組,使用bind(2)來指定一茼b        sockaddr_ll        結構
       中的地址,以此把一茪徽晢M接口綁定到一荓竣f上。只有地址字             段
       sll_protocol 和 sll_ifindex 被綁定用途所使用。

       不支持在分組套接口上的 connect(2) 操作。(不能作為客戶端使用)

ADDRESS TYPESa}型
       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       ,發送到一-
       茠垓z層多路廣播地址的分組用的                        PACKET_MULTICAST,
       在混雜(promiscuous)模式下的設備驅動器發向其他主機的分組用的
       PACKET_OTHERHOST,本源於本地主機的分組被環回到分組套接口用           的
       PACKET_OUTGOING。這些類型只對接收到的分組有意義。sll_addr 和  sll_halen
       包括物理層(例如 IEEE 802.3)地址和地址長度。精確 的解釋依賴於設備。

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

SOCKET OPTIONSMf項
       分組套接口可被用來配置物理層的多路廣播和混雜模式。配置通過調用
       setsockopt(2)實現,套接口參數是一茪徽晢M接口、層次參數為     SOL_PACKET
       、選項參數中的  PACKET_ADD_MEMBERSHIP  用於增加一   虒j定,選項參數中的
       PACKET_DROP_MEMBERSHIP     用於刪除一虒j     定。兩蚇龠絨˙愯作為參數的
       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
       也能用於實現同樣的目的。

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

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

ERROR HANDLING~Bz
       分組套接只對傳送分組到設備驅動程式時發生的錯誤做錯誤處理,
       其他不做錯誤處理。這裏沒有等待解決的錯誤的概念。

COMPATIBILITYe性
       在   Linux   2.0   中,得到分組套接口的唯一方法是調用   socket(PF_INET,
       SOCK_PACKET, protocol)。它仍被支持但變得 沒有價C兩種方法的主n不同在於
       SOCK_PACKET         使用老的         sockaddr_pkt         結構來指定一-
       荓竣f,沒有提供物理層接口無關性。 (依賴於物理設備)

              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" 就是一茈H null (' ')終結的字符串。

       這茧硎c已經被廢棄,不應在新的代碼中使用。

NOTES`N
       不建議對n求可移植的程式通過 pcap(3) 使用 PF_PACKET 協議族;  它只覆蓋了
       PF_PACKET 特征的一茪l集。

       譯注:該函數庫可在 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
       封裝並填寫協議字段。

       譯注:   長度字段和協議字段其實都是以太楨的第四字段,這茼r段   的b小於
       1518  時表示此以太楨是  IEEE  802.3 楨,在大於1536 時表示此以太楨是 DIX
       楨。DIX 中的 D 代表 DEC,I 代表 Intel, X 代表 Xerox。

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

ERRORS~T息
       ENETDOWN
              接口未啟動。

       ENOTCONN
              未傳遞接口地址。

       ENODEV 在接口地址中指定了未知的設備名或接口索引。

       EMSGSIZE
              分組比接口的 MTU(最大傳輸單元)大。

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

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

       EINVAL 無效參數。

       ENXIO  接口地址包含非法接口索引號。

       EPERM  使用者沒有足夠的權來執行這蚞犑@。

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

       ENOENT 未收到分組。

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

VERSIONS本
       PF_PACKET 是 Linux 2.2 的新特征。Linux 的朽薊岩誑u支持 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^m者
       本手冊隄O 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-I慟therneC
       RFC1700-I截EEE802.3楨封裝標準。
      Y莛inux/if_ether.]tzhC

[]
       mhss <jijingzhisheng@up369.com>

[]
       2000/10/15

mlinuxan:
       http://cmpp.linuxforum.net