名前
netdevice - Linux ネットワークデバイスへの低レベルアクセス
書式
#include <sys/ioctl.h> #include <net/if.h>
説明
この man ページでは、ネットワークデバイスを設定するために 用いるソケットインターフェースについて解説する。
Linux はネットワークデバイスを設定するための標準的な ioctl を いくつか備えている。これらはどんなソケットのファイルディスクリプタにも 用いることができる。ファミリーやタイプは何でもよい。 これらの ioctl は ifreq 構造体を渡す。
struct ifreq {
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char * ifr_data;
};
};
struct ifconf {
int ifc_len; /* size of buffer */
union {
char * ifc_buf; /* buffer address */
struct ifreq * ifc_req; /* array of structures */
};
};
通常、ユーザーによる設定対象デバイスの指定は、 ifr_name にインターフェースの名前をセットすることによって行う。 他の構造体の全てのメンバは、メモリを共有する。
ioctl
「特権が必要」と記述されている ioctl を実行するには、 実効ユーザー ID が 0 か、 CAP_NET_ADMIN 権限が必要である。これが満たされていない場合は EPERM が返される。
SIOCGIFNAME | |||||||||||||||||||||||||||||||||||
ifr_ifindex を受け取り、インターフェースの名前を ifr_name に入れて返す。これは結果を ifr_name として返す唯一の ioctl である。 | |||||||||||||||||||||||||||||||||||
SIOCGIFINDEX | |||||||||||||||||||||||||||||||||||
インターフェースの interface index を取得し、 ifr_ifindex に入れて返す。 | |||||||||||||||||||||||||||||||||||
SIOCGIFFLAGS, SIOCSIFFLAGS | |||||||||||||||||||||||||||||||||||
デバイスの active フラグワードを取得または設定する。
ifr_flags には以下の値のビットマスクが入る。
| |||||||||||||||||||||||||||||||||||
SIOCGIFMETRIC, SIOCSIFMETRIC | |||||||||||||||||||||||||||||||||||
デバイスのメトリックを ifr_metric を用いて取得・設定する。 これはまだ実装されていない。読み出そうとすると ifr_metric に 0 をセットして返り、設定しようとすると EOPNOTSUPP が返る。 | |||||||||||||||||||||||||||||||||||
SIOCGIFMTU, SIOCSIFMTU | |||||||||||||||||||||||||||||||||||
デバイスの MTU (Maximum Transfer Unit) を ifr_mtu を用いて取得・設定する。 MTU の設定は特権が必要な操作である。 MTU の値を小さくしすぎるとカーネルがクラッシュするかもしれない。 | |||||||||||||||||||||||||||||||||||
SIOCGIFHWADDR, SIOCSIFHWADDR | |||||||||||||||||||||||||||||||||||
デバイスのハードウェアアドレスを ifr_hwaddr を用いて取得・設定する。 ハードウェアアドレスは sockaddr 構造体に設定される。 sa_family には ARPHRD_* デバイスタイプが入り、 sa_data はバイト 0 から始まる L2 ハードウェアアドレスが入る。 ハードウェアアドレスの設定は特権が必要な操作である。 | |||||||||||||||||||||||||||||||||||
SIOCSIFHWBROADCAST | |||||||||||||||||||||||||||||||||||
デバイスのハードウェアブロードキャストアドレスを ifr_hwaddr の値に設定する。この操作には特権が必要である。 | |||||||||||||||||||||||||||||||||||
SIOCGIFMAP, SIOCSIFMAP | |||||||||||||||||||||||||||||||||||
インターフェースのハードウェアのパラメータを
ifr_map を用いて取得・設定する。
パラメータの設定は特権が必要な操作である。
struct ifmap { unsigned long mem_start; unsigned long mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port; }; ifmap 構造体の解釈はデバイスドライバとアーキテクチャに依存する。 | |||||||||||||||||||||||||||||||||||
SIOCADDMULTI, SIOCDELMULTI | |||||||||||||||||||||||||||||||||||
デバイスのリンク層のマルチキャストフィルターから、 ifr_hwaddr のアドレスを追加・削除する。これらの操作には特権が必要である。 別法が packet(7) で解説されている。 | |||||||||||||||||||||||||||||||||||
SIOCGIFTXQLEN, SIOCSIFTXQLEN | |||||||||||||||||||||||||||||||||||
デバイスの送信キューの長さを ifr_qlen に取得・設定する。送信キューの長さの設定には特権が必要である。 | |||||||||||||||||||||||||||||||||||
SIOCSIFNAME | |||||||||||||||||||||||||||||||||||
ifr_name で指定したインターフェースの名前を ifr_newname に変更する。この操作には特権が必要である。インターフェースが up していない 時にのみ使用できる。 | |||||||||||||||||||||||||||||||||||
SIOCGIFCONF | |||||||||||||||||||||||||||||||||||
インターフェース(トランスポート層)アドレスのリストを返す。 現在のところ、互換性のために AF_INET (IPv4) ファミリーのアドレスのみである。 ユーザーは ifconf 構造体を ioctl の引数として渡す。 これには ifreq 構造体の配列へのポインタである ifc_req と、その長さをバイト単位で指定する ifc_len を含む。 カーネルは ifreqs を現在動作している全ての L3 インターフェースアドレスで埋める。 ifr_name にはインターフェース名 (eth0:1 など) が入り、 ifr_addr にはアドレスが入る。 カーネルは実際の長さを ifc_len に返す。 ifc_len が元のバッファの長さと同じだった場合、 オーバーフローを起こしている可能性があるので、 全てのアドレスを所得するためにより大きなバッファで再試行するべきである。 エラーがなかった場合は ioctl は 0 を返す。 エラーがあった場合は -1 を返す。 オーバーフローはエラーとは見なされない。 | |||||||||||||||||||||||||||||||||||
さらに、デバイスによってはプライベートな ioctl がある。 これらはここでは説明しない。
注意
厳密にいうと、 SIOCGIFCONF は IP 固有であり、 ip(7) に属する。
アドレスがなかったり、 IFF_RUNNING フラグがセットされていないインターフェースの名前は /proc/net/dev で見つけることが出来る。
ローカル IPV6 IP アドレスは /proc/net か rtnetlink(7) で見つけることが出来る。
バグ
glibc 2.1 では net/if.h に ifr_newname マクロがない。 とりあえずの対応策として、以下のコードを追加しておくこと。
#ifndef ifr_newname #define ifr_newname ifr_ifru.ifru_slave #endif