Manpages

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 [AT] up369.com>

[中 文 版 最 新 更 新 ]

2000/10/15

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

http://cmpp.linuxforum.net

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