名 前
packet − デ バ イ ス レ ベ ル の パ ケ ッ ト イ ン タ ー フ ェ ー ス
書 式
#include
<sys/socket.h>
#include <linux/if_packet.h>
#include <net/ethernet.h> /* L2 プ ロ
ト コ ル */
packet_socket = socket(AF_PACKET, int socket_type, int protocol);
説 明
packet ソ ケ ッ ト は 、 デ バ イ ス ド ラ イ バ (OSI レ イ ヤ 2) レ ベ ル で 生 の パ ケ ッ ト (raw packet) を 送 受 信 す る た め に 用 い ら れ る 。 packet ソ ケ ッ ト を 使 う と 、 ユ ー ザ ー 空 間 で 物 理 層 の 上 に プ ロ ト コ ル モ ジ ュ ー ル を 実 装 す る こ と が で き る 。
socket_type に は SOCK_RAW と SOCK_DGRAM の い ず れ か を 指 定 す る 。 SOCK_RAW は リ ン ク レ ベ ル ヘ ッ ダ ー を 含 む raw パ ケ ッ ト を 、 SOCK_DGRAM は リ ン ク レ ベ ル ヘ ッ ダ ー が 削 除 さ れ た 加 工 済 み パ ケ ッ ト を 示 す 。 リ ン ク レ ベ ル ヘ ッ ダ ー 情 報 は sockaddr_ll で 共 通 の フ ォ ー マ ッ ト で 入 手 で き る 。 protocol に は IEEE 802.3 プ ロ ト コ ル 番 号 を ネ ッ ト ワ ー ク バ イ ト オ ー ダ ー で 指 定 す る 。 指 定 で き る プ ロ ト コ ル の リ ス ト は 、 イ ン ク ル ー ド フ ァ イ ル <linux/if_ether.h> を 参 照 。 プ ロ ト コ ル を htons(ETH_P_ALL) に す る と 、 全 て の プ ロ ト コ ル が 受 信 さ れ る 。 外 部 か ら 来 た パ ケ ッ ト の う ち 指 定 し た プ ロ ト コ ル の も の は 、 カ ー ネ ル に 実 装 さ れ て い る プ ロ ト コ ル に 渡 さ れ る 前 の 段 階 で 、 packet ソ ケ ッ ト に 渡 さ れ る 。
packet ソ ケ ッ ト を オ ー プ ン で き る の は 、 実 効 ユ ー ザ ー ID が 0 の プ ロ セ ス か 、 CAP_NET_RAW ケ ー パ ビ リ テ ィ を 持 つ プ ロ セ ス だ け で あ る 。
SOCK_RAW パ ケ ッ ト で は 、 パ ケ ッ ト を デ バ イ ス ド ラ イ バ と 受 け 渡 し す る 際 、 パ ケ ッ ト デ ー タ に 変 更 が 行 わ れ る こ と は な い 。 パ ケ ッ ト の 受 信 時 に は 、 ア ド レ ス の 解 析 だ け は 行 わ れ 、 標 準 的 な sockaddr_ll ア ド レ ス 構 造 体 に 渡 さ れ る 。 パ ケ ッ ト の 送 信 時 に は 、 ユ ー ザ ー が 指 定 す る バ ッ フ ァ ー に 物 理 層 の ヘ ッ ダ ー が 含 ま れ て い る 必 要 が あ る 。 パ ケ ッ ト は そ の ま ま 修 正 を 受 け ず に 、 行 き 先 ア ド レ ス か ら 決 定 さ れ る イ ン タ ー フ ェ ー ス の ネ ッ ト ワ ー ク ド ラ イ バ に キ ュ ー イ ン グ さ れ る 。 デ バ イ ス ド ラ イ バ に よ っ て は 、 他 の ヘ ッ ダ ー を 常 に 追 加 す る も の も あ る 。 SOCK_RAW は Linux 2.0 の obosolete な AF_INET/SOCK_PACKET と 似 て い る が 、 互 換 性 が あ る わ け で は な い 。
SOCK_DGRAM は や や 高 位 の レ ベ ル で 動 作 す る 。 物 理 ヘ ッ ダ ー は 、 パ ケ ッ ト が ユ ー ザ ー に 渡 さ れ る 前 に 削 除 さ れ る 。 SOCK_DGRAM の packet ソ ケ ッ ト を 通 し て 送 ら れ る パ ケ ッ ト は 、 sockaddr_ll の 行 き 先 ア ド レ ス の 情 報 に 基 づ き 、 適 切 な 物 理 層 の ヘ ッ ダ ー が 付 加 さ れ て か ら 、 キ ュ ー に 送 ら れ る 。 デ フ ォ ル ト で は 、 指 定 し た プ ロ ト コ ル 型 の パ ケ ッ ト は す べ て packet ソ ケ ッ ト に 送 ら れ る 。 特 定 の イ ン タ ー フ ェ ー ス か ら の パ ケ ッ ト だ け を 取 得 し た い 場 合 に は 、 struct sockaddr_ll に ア ド レ ス を 指 定 し て bind(2) を 呼 び 、 packet ソ ケ ッ ト を そ の イ ン タ ー フ ェ ー ス に 結 び 付 け る (バ イ ン ド す る )。 バ イ ン ド の 際 に は 、 ア ド レ ス フ ィ ー ル ド の う ち sll_protocol と sll_ifindex だ け が 用 い ら れ る 。
connect(2) 操 作 は packet ソ ケ ッ ト で は サ ポ ー ト さ れ て い な い 。
MSG_TRUNC
フ ラ グ が recvmsg(2),
recv(2), recvfrom(2) に 渡
さ れ る と 、 (バ
ッ フ ァ ー サ イ
ズ よ り 大 き か
っ た と し て も )
常 に 実 際 に 通
信 さ れ た パ ケ
ッ ト の 長 さ が
返 さ れ る 。 ア
ド レ ス の タ イ
プ
sockaddr_ll は デ バ イ ス
に 依 存 し な い
物 理 層 の ア ド
レ ス で あ る 。
struct
sockaddr_ll {
unsigned short sll_family; /* 常 に AF_PACKET */
unsigned short sll_protocol; /* 物 理 層
の プ ロ ト コ ル */
int sll_ifindex; /* イ ン タ ー
フ ェ ー ス 番 号 */
unsigned short sll_hatype; /* ARP ハ ー ド
ウ ェ ア 種 別 */
unsigned char sll_pkttype; /* パ ケ ッ
ト 種 別 */
unsigned char sll_halen; /* ア ド レ
ス の 長 さ */
unsigned char sll_addr[8]; /* 物 理 層
の ア ド レ ス */ };
sll_protocol
は 標 準 的 な イ
ー サ ネ ッ ト プ
ロ ト コ ル の タ
イ プ で 、 ネ ッ
ト ワ ー ク バ イ
ト オ ー ダ ー で
記 述 す る 。 イ
ン ク ル ー ド フ
ァ イ ル <linux/if_ether.h>
で 定 義 さ れ て
い る 。 こ れ が
こ の ソ ケ ッ ト
の プ ロ ト コ ル
の デ フ ォ ル ト
と な る 。 sll_ifindex
は そ の イ ン タ
ー フ ェ ー ス の
interface index で あ る
(netdevice(7) を 参 照 )。 0
は (バ イ ン ド が
許 可 さ れ て い
る ) 任 意 の イ ン
タ ー フ ェ ー ス
に マ ッ チ す る
。 sll_hatype は 、 イ
ン ク ル ー ド フ
ァ イ ル <linux/if_arp.h>
で 定 義 さ れ て
い る ARP 種 別 で あ
る 。 sll_pkttype は パ
ケ ッ ト 種 別 で
あ る 。 指 定 で
き る 種 別 は 以
下 の い ず れ か
で あ る : PACKET_HOST (ロ
ー カ ル ホ ス ト
向 け の パ ケ ッ
ト )、 PACKET_BORADCAST (物
理 層 の ブ ロ ー
ド キ ャ ス ト パ
ケ ッ ト )、 PACKET_MULTICAST
(物 理 層 の マ ル
チ キ ャ ス ト ア
ド レ ス に 送 る
パ ケ ッ ト )、
PACKET_OTHERHOST (他 の ホ ス
ト に 向 け ら れ
た パ ケ ッ ト の
う ち 、 無 差 別
モ ー ド (promiscuous mode: 後
述 ) の デ バ イ ス
ド ラ イ バ に よ
り 補 足 さ れ た
も の )、 PACKET_OUTGOING (ロ
ー カ ル ホ ス ト
か ら 発 信 さ れ
、 packet ソ ケ ッ ト に
ル ー プ バ ッ ク
し て き た パ ケ
ッ ト )。 こ れ ら
の 種 別 が 意 味
を 持 つ の は 受
信 時 の み で あ
る 。 sll_addr と sll_halen
は 、 物 理 層 の
(つ ま り IEEE 802.3 の ) ア
ド レ ス と そ の
長 さ で あ る 。
厳 密 な 解 釈 は
デ バ イ ス に 依
存 す る 。 パ ケ
ッ ト を 送 る 場
合 は 、 sll_family,
sll_addr, sll_halen, sll_ifindex
を 指 定 す れ ば
十 分 で あ る 。
そ の 他 の フ ィ
ー ル ド は 0 に し
て お く べ き で
あ る 。 sll_hatype と
sll_pkttype に は 受 信
し た パ ケ ッ ト
の 情 報 が 設 定
さ れ る 。 バ イ
ン ド の 際 に は
、 sll_protocol と sll_ifindex
だ け が 使 用 さ
れ る 。 ソ ケ ッ
ト オ プ シ ョ ン
パ ケ ッ ト ソ ケ
ッ ト の オ プ シ
ョ ン は 、 レ ベ
ル SOL_PACKET を 指 定
し て setsockopt(2) を 呼
び 出 す こ と で
設 定 で き る 。
PACKET_ADD_MEMBERSHIP
PACKET_DROP_MEMBERSHIP
packet ソ ケ ッ ト は 、 物 理 層 の マ ル チ キ ャ ス ト や 無 差 別 モ ー ド (promiscuous mode) を 設 定 し て 使 う こ と が で き る 。 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_type パ ラ メ ー タ ー は 実 行 す る 動 作 を 指 定 す る : PACKET_MR_PROMISC は 、 共 有 し て い る 媒 体 か ら の 全 て の パ ケ ッ ト を 受 信 で き る よ う に す る (し ば し ば "無 差 別 モ ー ド (promiscuous mode)" と 呼 ば れ る )。 PACKET_MR_MULTICAST は 、 そ の ソ ケ ッ ト を 、 mr_address と mr_alen で 指 定 さ れ る 物 理 層 の マ ル チ キ ャ ス ト ブ ル ー プ に バ イ ン ド す る 。 PACKET_MR_ALLMULTI は socket を up に し て 、 そ の イ ン タ ー フ ェ ー ス に 到 達 し た す べ て の マ ル チ キ ャ ス ト パ ケ ッ ト を 受 信 で き る よ う に す る 。 昔 か ら あ る ioctl だ け で な く 、 SIOCSIFFLAGS, SIOCADDMULTI, SIOCDELMULTI を 同 じ 目 的 に 用 い る こ と が で き る 。
PACKET_AUXDATA (Linux 2.6.21 以 降 ) ブ ー ル 値 の オ プ シ ョ ン を 有 効 す る と 、 パ ケ ッ ト ソ ケ ッ ト は 、 パ ケ ッ ト と 一 緒 に メ タ デ ー タ 構 造 体 を recvmsg(2) コ ン ト ロ ー ル フ ィ ー ル ド で 渡 す 。 こ の 構 造 体 は cmsg(3) を 使 っ て 読 む こ と が で き る 。 定 義 は 以 下 の 通 り で あ る 。
struct
tpacket_auxdata {
__u32 tp_status;
__u32 tp_len; /* パ ケ ッ ト
長 */
__u32 tp_snaplen; /* キ ャ プ チ
ャ し た 長 さ */
__u16 tp_mac;
__u16 tp_net;
__u16 tp_vlan_tci;
__u16 tp_padding; };
PACKET_FANOUT (Linux 3.1
以 降 ) ス レ ッ ド
に ま た が っ て
処 理 を ス ケ ー
ル さ せ る た め
、 パ ケ ッ ト ソ
ケ ッ ト は フ ァ
ン ア ウ ト グ ル
ー プ を 構 成 す
る こ と が で き
る 。 こ の モ ー
ド で は 、 マ ッ
チ し た そ れ ぞ
れ の パ ケ ッ ト
は グ ル ー プ 内
の い ず れ か 一
つ の ソ ケ ッ ト
に だ け キ ュ ー
イ ン グ さ れ る
。 ソ ケ ッ ト を
フ ァ ン ア ウ ト
グ ル ー プ に 参
加 さ せ る に は
、 レ ベ ル SOL_PACKET
で オ プ シ ョ ン
PACKET_FANOUT を 指 定 し
て setsockopt(2) を 呼 び
出 す 。 ネ ッ ト
ワ ー ク 名 前 空
間 毎 に 最 大 65536 個
の 独 立 し た グ
ル ー プ を 持 つ
こ と が で き る
。 整 数 の オ プ
シ ョ ン 値 の 先
頭 16 ビ ッ ト に ID を
エ ン コ ー ド す
る こ と で 、 ソ
ケ ッ ト は グ ル
ー プ を 選 択 す
る 。 あ る グ ル
ー プ へ の 最 初
の パ ケ ッ ト ソ
ケ ッ ト の 参 加
が あ っ た 時 点
で 、 グ ル ー プ
は 暗 黙 の う ち
に 作 成 さ れ る
。 既 存 の グ ル
ー プ へ の 参 加
が 成 功 す る た
め に は 、 そ れ
以 降 に そ の グ
ル ー プ に 参 加
し よ う と す る
パ ケ ッ ト ソ ケ
ッ ト は 、 プ ロ
ト コ ロ 、 デ バ
イ ス 設 定 、 フ
ァ ン ア ウ ト モ
ー ド 、 フ ラ グ
が 同 じ で あ る
必 要 が あ る (下
記 参 照 )。 パ ケ
ッ ト ソ ケ ッ ト
が フ ァ ン ア ウ
ト グ ル ー プ か
ら 抜 け る の は
、 そ の ソ ケ ッ
ト を ク ロ ー ズ
し た 場 合 だ け
で あ る 。 フ ァ
ン ア ウ ト グ ル
ー プ は 最 後 の
ソ ケ ッ ト が ク
ロ ー ズ し た 場
合 に 削 除 さ れ
る 。 フ ァ ン ア
ウ ト で は 、 複
数 の ソ ケ ッ ト
に ト ラ フ ィ ッ
ク を 分 散 さ せ
る ア ル ゴ リ ズ
ム を 複 数 サ ポ
ー ト し て い る
。 デ フ ォ ル ト
の モ ー ド で あ
る PACKET_FANOUT_HASH で は
、 同 じ フ ロ ー
の パ ケ ッ ト は
同 じ ソ ケ ッ ト
に 送 信 さ れ 、
フ ロ ー 単 位 の
順 序 が 維 持 さ
れ る 。 パ ケ ッ
ト ご と に 、 パ
ケ ッ ト フ ロ ー
の ハ ッ シ ュ の
、 そ の グ ル ー
プ の ソ ケ ッ ト
数 に 対 す る 剰
余 が 計 算 さ れ
、 ソ ケ ッ ト が
選 択 さ れ る 。
な お 、 フ ロ ー
ハ ッ シ ュ は ネ
ッ ト ワ ー ク 層
の ア ド レ ス と
ト ラ ン ス ポ ー
ト 層 の ポ ー ト
フ ィ ー ル ド に
対 す る ハ ッ シ
ュ で あ る (ト ラ
ン ス ポ ー ト 層
ポ ー ト は 存 在
す る 場 合 の み
)。 負 荷 分 散 モ
ー ド PACKET_FANOUT_LB は ラ
ウ ン ド ロ ビ ン
ア ル ゴ リ ズ ム
が 採 用 さ れ て
い る 。 PACKET_FANOUT_CPU で
は 、 パ ケ ッ ト
が 到 着 し た CPU に
基 づ い て ソ ケ
ッ ト を 選 択 す
る 。 PACKET_FANOUT_ROLLOVER は
す べ て の デ ー
タ を 一 つ の ソ
ケ ッ ト で 処 理
し 、 そ の ソ ケ
ッ ト で 処 理 待
ち (backlog) が 発 生 し
た 場 合 に 次 の
ソ ケ ッ ト に 移
る 。 PACKET_FANOUT_RND で は
擬 似 乱 数 発 生
器 を 使 っ て ソ
ケ ッ ト が 選 択
さ れ る 。 PACKET_FANOUT_QM
(Linux 3.14 以 降 で 利 用
可 能 ) で は 受 信 skb
に 記 録 さ れ た
queue_mapping を 使 っ て ソ
ケ ッ ト が 選 択
さ れ る 。 フ ァ
ン ア ウ ト モ ー
ド で は 追 加 の
オ プ シ ョ ン が
あ る 。 IP フ ラ グ
メ ン テ ー シ ョ
ン が 起 こ る と
、 同 じ フ ロ ー
の パ ケ ッ ト の
フ ロ ー ハ ッ シ
ュ が 異 な る ハ
ッ シ ュ を 持 つ
こ と に な る 。
フ ラ グ PACKET_FANOUT_FLAG_DEFRAG
を セ ッ ト す る
と 、 パ ケ ッ ト
は フ ァ ン ア ウ
ト を 行 う 前 に
フ ラ グ メ ン ト
再 構 築 が 行 わ
れ る よ う に な
り 、 フ ラ グ メ
ン ト が あ っ た
場 合 で も 順 序
が 維 持 さ れ る
。 フ ァ ン ア ウ
ト モ ー ド と オ
プ シ ョ ン は 、
整 数 の オ プ シ
ョ ン 値 の 下 位 16
ビ ッ ト で 指 定
さ れ る 。 フ ラ
グ PACKET_FANOUT_FLAG_ROLLOVER を
指 定 す る と 、
バ ッ ク ア ッ プ
戦 略 と し て ロ
ー ル オ ー バ ー
方 式 が 有 効 に
な る 。 元 の フ
ァ ン ア ウ ト ア
ル ゴ リ ズ ム が
backlog ソ ケ ッ ト を
選 択 し て い れ
ば 、 パ ケ ッ ト
は 次 の 利 用 可
能 な ソ ケ ッ ト
に ロ ー ル オ ー
バ ー さ れ る 。
PACKET_LOSS (PACKET_TX_RING で 使
用 ) 送 信 リ ン グ
で 不 正 な 形 式
の パ ケ ッ ト に
遭 遇 し た 場 合
、 デ フ ォ ル ト
で は そ の リ ン
グ の tp_status を
TP_STATUS_WRONG_FORMAT に 戻 し
、 そ の 送 信 を
直 ち に 中 止 す
る 。 不 正 な 形
式 の パ ケ ッ ト
に よ り 、 そ の
パ ケ ッ ト 自 身
と そ の 以 降 に
キ ュ ー に 入 れ
ら れ た パ ケ ッ
ト の 送 信 が ブ
ロ ッ ク さ れ る
。 形 式 エ ラ ー
を 修 正 し 、 関
連 す る tp_status を
TP_STATUS_SEND_REQUEST に 設 定
し 直 し 、 send(2) を
使 っ て 送 信 処
理 を 再 開 し な
け れ ば な ら な
い 。 し か し な
が ら 、 PACKET_LOSS が
セ ッ ト さ れ て
い る 場 合 、 不
正 な 形 式 の パ
ケ ッ ト は す べ
て ス キ ッ プ さ
れ 、 そ の 送 信
リ ン グ の tp_status
は TP_STATUS_AVAILABLE に 設
定 し 直 さ れ 、
送 信 処 理 は 継
続 さ れ る 。
PACKET_RESERVE (PACKET_RX_RING で 使
用 ) デ フ ォ ル ト
で は 、 パ ケ ッ
ト 受 信 リ ン グ
は メ タ デ ー タ
構 造 体 と ア ラ
イ メ ン ト 用 の
パ デ ィ ン グ の
直 後 に パ ケ ッ
ト を 書 き 込 む
。 こ の 整 数 オ
プ シ ョ ン を 設
定 す る と 、 パ
ケ ッ ト の 前 に
追 加 で 領 域 が
予 約 さ れ る 。
PACKET_RX_RING 非 同 期 で
の パ ケ ッ ト 受
信 用 の メ モ リ
ー マ ッ プ さ れ
た リ ン グ バ ッ
フ ァ ー を 作 成
す る 。 パ ケ ッ
ト ソ ケ ッ ト は
ア プ リ ケ ー シ
ョ ン の ア ド レ
ス 空 間 に 連 続
す る 領 域 を 確
保 し 、 そ こ に
パ ケ ッ ト ス ロ
ッ ト の 配 列 を
構 成 し 、 (最 大
tp_snaplen 個 の ) パ ケ
ッ ト を 順 に ス
ロ ッ ト に コ ピ
ー す る 。 各 パ
ケ ッ ト の 前 に
は tpacket_auxdata に 似 た
メ タ デ ー タ 構
造 体 が 置 か れ
る 。 プ ロ ト コ
ル フ ィ ー ル ド
に は 、 デ ー タ
の 、 メ タ デ ー
タ ヘ ッ ダ ー の
先 頭 か ら の オ
フ セ ッ ト が 入
る 。 tp_net に は ネ
ッ ト ワ ー ク 層
へ の オ フ セ ッ
ト が 格 納 さ れ
る 。 パ ケ ッ ト
ソ ケ ッ ト が
SOCK_DGRAM 型 の 場 合
、 tp_mac も 同 じ で
あ る 。 SOCK_RAW 型 の
場 合 、 tp_net に は
リ ン ク 層 の フ
レ ー ム へ の オ
フ セ ッ ト が 入
る 。 パ ケ ッ ト
ソ ケ ッ ト と ア
プ リ ケ ー シ ョ
ン は tp_status フ ィ
ー ル ド を 通 し
て リ ン グ の 先
頭 (head) と 末 尾 (tail) の
情 報 を 受 け 渡
す 。 パ ケ ッ ト
ソ ケ ッ ト は
tp_status が TP_STATUS_KERNEL の
す べ て の ス ロ
ッ ト を 所 有 し
て お り 、 ス ロ
ッ ト に デ ー タ
が 入 る と 、 パ
ケ ッ ト ソ ケ ッ
ト は そ の ス ロ
ッ ト の ス テ ー
タ ス を ア プ リ
ケ ー シ ョ ン に
所 有 権 を 渡 す
状 態 に 変 更 す
る 。 通 常 の 動
作 で は 、 新 し
い tp_status で 少 な
く と も TP_STATUS_USER ビ
ッ ト が セ ッ ト
さ れ て い れ ば
、 受 信 さ れ た
パ ケ ッ ト が 格
納 さ れ た こ と
を 示 し て い る
。 ア プ リ ケ ー
シ ョ ン が パ ケ
ッ ト の 処 理 を
終 え る と 、 ア
プ リ ケ ー シ ョ
ン は そ の ス ロ
ッ ト の tp_status を
TP_STATUS_KERNEL に 設 定 し
、 そ の ス ロ ッ
ト の 所 有 権 を
ソ ケ ッ ト に 返
す 。 パ ケ ッ ト
ソ ケ ッ ト は 、
複 数 バ ー ジ ョ
ン の パ ケ ッ ト
リ ン グ を 実 装
し て い る 。 実
装 の 詳 細 は Linux カ
ー ネ ル ソ ー ス
ツ リ ー の
Documentation/networking/packet_mmap.txt で
説 明 さ れ て い
る 。
PACKET_STATISTICS パ ケ ッ ト
ソ ケ ッ ト の 統
計 情 報 を 次 の
構 造 体 形 式 で
取 得 す る 。
struct
tpacket_stats {
unsigned int tp_packets; /* 総 パ ケ
ッ ト 数 */
unsigned int tp_drops; /* ド ロ ッ
プ パ ケ ッ ト 数 */ };
統 計 情 報 を 取
得 す る と 、 内
部 カ ウ ン タ ー
は リ セ ッ ト さ
れ る 。 TPACKET_V3 の
リ ン グ を 使 う
場 合 に は 、 統
計 情 報 構 造 体
は 違 う も の に
な る 。
PACKET_TIMESTAMP
(PACKET_RX_RING で 使 用 ; Linux
2.6.36 以 降 ) パ ケ ッ
ト 受 信 リ ン グ
で は 常 に タ イ
ム ス タ ン プ が
メ タ デ ー タ ヘ
ッ ダ ー に 格 納
さ れ る 。 デ フ
ォ ル ト で は 、
タ イ ム ス タ ン
プ は パ ケ ッ ト
が リ ン グ に コ
ピ ー さ れ た 時
点 で 生 成 さ れ
る ソ フ ト ウ ェ
ア に よ る タ イ
ム ス タ ン プ で
あ る 。 こ の 整
数 オ プ シ ョ ン
に よ り タ イ ム
ス タ ン プ の 種
類 を 選 択 で き
る 。 デ フ ォ ル
ト 以 外 で は 、 Linux
カ ー ネ ル ソ ー
ス ツ リ ー の
Documentation/networking/timestamping.txt に
説 明 が あ る 2 種
類 の ハ ー ド ウ
ェ ア フ ォ ー マ
ッ ト が サ ポ ー
ト さ れ て い る
。
PACKET_TX_RING (Linux 2.6.31 以 降 )
パ ケ ッ ト 送 信
用 の メ モ リ ー
マ ッ プ さ れ た
リ ン グ バ ッ フ
ァ ー を 作 成 す
る 。 こ の オ プ
シ ョ ン は PACKET_RX_RING
と 同 様 で 、 同
じ 引 き 数 を 取
る 。 ア プ リ ケ
ー シ ョ ン は
tp_status が TP_STATUS_AVAILABLE
の ス ロ ッ ト に
パ ケ ッ ト を 書
き 込 み 、 tp_status
を TP_STATUS_SEND_REQUEST に 変
更 す る こ と で
そ の パ ケ ッ ト
の 送 信 を 予 約
す る 。 パ ケ ッ
ト の 送 信 準 備
が で き た ら 、
ア プ リ ケ ー シ
ョ ン は 続 け て
send(2) 系 の シ ス テ
ム コ ー ル を 呼
び 出 す 。 シ ス
テ ム コ ー ル の
引 き 数 buf と len
は 無 視 さ れ る
。 sendto(2) や sendmsg(2)
を 使 っ て ア ド
レ ス が 渡 さ れ
た 場 合 、 ソ ケ
ッ ト の デ フ ォ
ル ト 値 で は な
く そ の ア ド レ
ス が 使 用 さ れ
る 。 送 信 に 成
功 す る と 、 ソ
ケ ッ ト は そ の
ス ロ ッ ト の
tp_status を TP_STATUS_AVAILABLE
に 戻 す 。 エ ラ
ー の 場 合 、
PACKET_LOSS が セ ッ ト
さ れ て い な け
れ ば 、 直 ち に
送 信 を 中 断 し
エ ラ ー を 上 げ
る 。
PACKET_VERSION (PACKET_RX_RING で 使
用 ; Linux 2.6.27 以 降 ) デ
フ ォ ル ト で は
、 PACKET_RX_RING は TPACKET_V1
の パ ケ ッ ト 受
信 リ ン グ を 作
成 す る 。 別 の
バ ー ジ ョ ン の
リ ン グ を 作 成
す る に は 、 そ
の リ ン グ を 作
成 す る 前 に 希
望 す る バ ー ジ
ョ ン が 使 わ れ
る よ う に こ の
整 数 オ プ シ ョ
ン を 設 定 す る
こ と 。
PACKET_QDISC_BYPASS (Linux 3.14 以 降 )
デ フ ォ ル ト で
は 、 パ ケ ッ ト
は カ ー ネ ル の qdisc
(ト ラ フ ィ ッ ク
制 御 ) レ イ ヤ ー
経 由 で 渡 さ れ
る 。 こ れ は 大
半 の ユ ー ス ケ
ー ス に 合 っ て
い る 。 ネ ッ ト
ワ ー ク に 対 し
て 可 能 な 限 り
パ ケ ッ ト を 送
信 す る (例 え ば
pkggen と 同 様 の 方 法
で 負 荷 対 象 の
デ バ イ ス を 試
験 す る ) の に パ
ケ ッ ト ソ ケ ッ
ト を 使 う ト ラ
フ ィ ッ ク 生 成
ア プ ラ イ ア ン
ス で は 、 こ の
整 数 オ プ シ ョ
ン を 1 に 設 定 す
る こ と で qdisc レ イ
ヤ ー を 飛 ば す
こ と が で き る
。 qdisc レ イ ヤ ー で
の パ ケ ッ ト バ
ッ フ ァ ー が 行
わ れ な く な る
と い う 副 作 用
が あ る 。 こ れ
に よ り 、 ネ ッ
ト ワ ー ク デ バ
イ ス の 送 信 キ
ュ ー の 使 用 量
が 高 い 場 合 に
パ ケ ッ ト 廃 棄
が 起 き や す く
な る 。
ioctl
SIOCGSTAMP を 用 い る と
、 最 後 に 受 信
し た パ ケ ッ ト
の タ イ ム ス タ
ン プ を 得 る こ
と が で き る 。
引 き 数 は struct timeval
型 の 変 数 で あ
る 。 さ ら に 、
netdevice(7) お よ び
socket(7) で 定 義 さ
れ て い る 標 準
の ioctl は い ず れ も
packet ソ ケ ッ ト に 指
定 可 能 で あ る
。 エ ラ ー 処 理
packet ソ ケ ッ ト は 、
パ ケ ッ ト を デ
バ イ ス ド ラ イ
バ に 渡 す と き
に 起 き た エ ラ
ー し か 処 理 し
な い 。 遅 延 エ
ラ ー (pending error) に 関 す
る 概 念 は 持 っ
て い な い 。
エ ラ ー
EADDRNOTAVAIL 不 明 な マ ル チ キ ャ ス ト グ ル ー プ ア ド レ ス が 渡 さ れ た 。
EFAULT ユ ー ザ ー が 渡 し た メ モ リ ー ア ド レ ス が 不 正 。 |
||
EINVAL 引 き 数 が 不 正 。 |
EMSGSIZE パ
ケ ッ ト が イ ン
タ ー フ ェ ー ス
の MTU よ り 大 き い
。
ENETDOWN イ ン タ ー フ
ェ ー ス が up で な
い 。
ENOBUFS パ ケ ッ ト に
割 り 当 て る メ
モ リ ー が 足 り
な い 。
ENODEV デ バ イ ス 名 が 不 明 。 あ る い は イ ン タ ー フ ェ ー ス ア ド レ ス で 指 定 さ れ た イ ン タ ー フ ェ ー ス イ ン デ ッ ク ス が 不 明 。 | |
ENOENT パ ケ ッ ト を 一 つ も 受 信 し て い な い 。 |
ENOTCONN イ ン タ ー フ ェ ー ス ア ド レ ス が 渡 さ れ な か っ た 。
ENXIO イ ン タ ー フ ェ ー ス ア ド レ ス に 不 正 な イ ン タ ー フ ェ ー ス イ ン デ ッ ク ス が 含 ま れ て い る 。 | |
EPERM こ の 操 作 を 行 う の に 必 要 な 権 限 を ユ ー ザ ー が 持 っ て い な い 。 上 記 以 外 の エ ラ ー が 、 低 レ ベ ル の ド ラ イ バ で 生 成 さ れ る こ と が あ る 。 |
バ ー ジ ョ ン
AF_PACKET は Linux 2.2 の 新 機 能 で あ る 。 こ れ よ り 古 い バ ー ジ ョ ン の Linux で は SOCK_PACKET の み を サ ポ ー ト し て い た 。
注 意
移 植 性 の 必 要 な プ ロ グ ラ ム で は 、 pcap(3) 経 由 で AF_PACKET を 用 い る こ と を お 薦 め す る 。 た だ し 、 こ の 方 法 で は AF_PACKET の 機 能 す べ て を 利 用 す る こ と は で き な い 。
SOCK_DGRAM packet ソ ケ ッ ト は 、 IEEE 802.3 フ レ ー ム の IEEE 802.2 LLC ヘ ッ ダ ー の 生 成 や 解 析 を 行 お う と し な い 。 ETH_P_802_3 が 送 信 プ ロ ト コ ル に 指 定 さ れ る と 、 カ ー ネ ル は 802.3 フ レ ー ム を 生 成 し て length フ ィ ー ル ド に 書 き 込 む 。 完 全 に 準 拠 し た パ ケ ッ ト を 得 る た め に は ユ ー ザ ー が LLC ヘ ッ ダ ー を 与 え る 必 要 が あ る 。 到 着 し た 802.3 パ ケ ッ ト で は 、 DSAP/SSAP protocol の 各 フ ィ ー ル ド は 多 重 化 (multiplex) さ れ て い な い 。 代 わ り に こ れ ら は LLC ヘ ッ ダ ー が 前 置 さ れ た ETH_P_802_2 プ ロ ト コ ル と し て 与 え ら れ る 。 し た が っ て 、 ETH_P_802_3 に バ イ ン ド す る こ と は で き な い 。 か わ り に ETH_P_802_2 に バ イ ン ド し 、 自 分 自 身 で プ ロ ト コ ル の 多 重 化 を 行 う こ と 。 送 信 の デ フ ォ ル ト は 、 プ ロ ト コ ル フ ィ ー ル ド を 持 つ 標 準 の Ethernet DIX encapsulation で あ る 。
packet ソ
ケ ッ ト は 入 出
力 の firewall chain に 影 響
を う け な い 。
移 植 性
Linux 2.0 で は 、 packet ソ
ケ ッ ト を 得 る
方 法 は socket(AF_INET,
SOCK_PACKET, protocol) を 呼
ぶ や り 方 し か
な か っ た 。 こ
の 方 法 は ま だ
サ ポ ー ト さ れ
て い る が 、 用
い な い こ と を
強 く 推 奨 す る
。 現 在 の 方 法
と の 主 な 違 い
は 、 SOCK_PACKET で は
イ ン タ ー フ ェ
ー ス の 指 定 に
古 い struct sockaddr_pkt を
用 い る 点 で あ
る 。 こ れ に は
物 理 層 か ら の
独 立 性 が な い
。
struct
sockaddr_pkt {
unsigned short spkt_family;
unsigned char spkt_device[14];
unsigned short spkt_protocol; };
spkt_family は デ バ イ ス の タ イ プ 、 spkt_protocol は <sys/if_ether.h> で 定 義 さ れ て い る IEEE 802.3 プ ロ ト コ ル タ イ プ 、 spkt_device は デ バ イ ス の 名 前 を ヌ ル 終 端 さ れ た 文 字 列 で 与 え た も の (例 : eth0) で あ る 。 こ の 構 造 体 は obsolete で あ り 、 新 し く コ ー ド を 書 く 時 に は 用 い る べ き で な い 。
バ グ
glibc 2.1 に は SOL_PACKET の 定 義 が な い 。 回 避 策 と し て は 、 以 下 の よ う に す る と よ い 。
#ifndef
SOL_PACKET
#define SOL_PACKET 263
#endif こ の 問 題 は そ
れ 以 降 の バ ー
ジ ョ ン の glibc で は
修 正 さ れ て い
る 。
IEEE 802.2/803.3 の LLC の 扱 い 方 は 、 バ グ と 考 え て も 良 い だ ろ う 。 ソ ケ ッ ト フ ィ ル タ ー に つ い て 記 載 さ れ て い な い 。
MSG_TRUNC recvmsg(2) 拡 張 は 非 常 に ま ず い 対 処 で あ り 、 制 御 メ ッ セ ー ジ で 置 き 換 え る べ き で あ る 。 今 の と こ ろ SOCK_DGRAM 経 由 で パ ケ ッ ト に つ い て い た 宛 先 ア ド レ ス を 得 る 方 法 が な い 。
関 連 項 目
socket(2), pcap(3), capabilities(7), ip(7), raw(7), socket(7) 標 準 IP Ethernet encapsulation に 関 し て は RFC 894 を 、 IEEE 802.3 IP encapsulation に 関 し て は RFC 1700 を 参 照 。 物 理 層 の プ ロ ト コ ル に 関 す る 記 述 は <linux/if_ether.h> イ ン ク ル ー ド フ ァ イ ル に あ る 。
Linux カ ー ネ ル の ソ ー ス ツ リ ー 。 /Documentation/networking/filter.txt に は Berkeley Packet Filters を パ ケ ッ ト ソ ケ ッ ト に ど の よ う に 適 用 す る か の 説 明 が あ る 。 /tools/testing/selftests/net/psock_tpacket.c に は 、 PACKET_RX_RING と PACKET_TX_RING の 利 用 可 能 な す べ て の バ ー ジ ョ ン の サ ン プ ル ソ ー ス コ ー ド が あ る 。
こ の 文 書 に つ い て
こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。