|
HOME > Linux Tips ( 目次 ) > Linux コマンド 一覧表 > p > packet - 約束事その他の説明 packet - 約束事その他の説明 - Linux コマンド集 一覧表名前packet, PF_PACKET - デバイスレベルのパケットインターフェース 書式
#include <sys/socket.h> 説明
packet ソケットは、デバイスドライバ (OSI レイヤ 2) レベルで
生のパケット (raw packet) を送受信するために用いられる。
packet ソケットを使うと、ユーザー空間で物理層の上に
プロトコルモジュールを実装することができる。
アドレスのタイプ
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 はそのインターフェースの 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 だけが使用される。 ソケットオプション
packet ソケットは、物理層のマルチキャストや
無差別モード (promiscuous mode) を設定して使うことができる。
これには SOL_PACKET と以下のオプションのいずれかを指定して
setsockopt
(2)を呼べばよい。
バインドを追加する場合は
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 を同じ目的に用いることができる。 IOCTL
SIOCGSTAMP
を用いると、最後に受信したパケットのタイムスタンプを得ることができる。
引き数は
struct timeval
である。
エラー処理packet ソケットは、パケットをデバイスドライバに渡すときに 起きたエラーしか処理しない。遅延エラー (pending error) に関する概念は持っていない。 移植性
Linux 2.0 では、 packet ソケットを得る方法は
socket(PF_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 はデバイスの名前を NULL 終端された文字列で与えたもの (例: eth0) である。 この構造体は obsolete であり、 新しくコードを書く時には用いるべきでない。 注意
移植性の必要なプログラムでは、
pcap
(3)経由で
PF_PACKET
を用いることをお薦めする。ただし、この方法では
PF_PACKET
の機能すべてを利用することはできない。
エラー
バージョンPF_PACKET は Linux 2.2 の新機能である。これより古いバージョンの Linux では SOCK_PACKET のみをサポートしていた。 バグ
glibc 2.1 には
SOL_PACKET
の定義がない。回避策としては、以下のようにするとよい。
#ifndef SOL_PACKET #define SOL_PACKET 263 #endif この問題は新しいバージョンの glibc では修正されている。 libc5 のシステムにはこの問題はない。 IEEE 802.2/803.3 の LLC の扱い方は、バグと考えても良いだろう。 ソケットフィルターについて記載されていない。 MSG_TRUNC recvmsg ()拡張は非常にまずい対処であり、制御メッセージで置き換えるべきである。 今のところ SOCK_DGRAM 経由でパケットについていた宛先アドレスを得る方法がない。 歴史
インクルードファイル
<netpacket/packet.h>
が存在するのは glibc2.1 以降である。
それ以前のシステムでは以下のようにする必要がある:
#include <asm/types.h> 関連項目
socket
(2),
pcap
(3),
capabilities
(7),
ip
(7),
raw
(7),
socket
(7)
|
|