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; }; };
通常、ユーザーによる設定対象デバイスの指定は、 ifr_name にインターフェースの名前をセットすることによって行う。 他の構造体の全てのメンバは、メモリーを共有する。
デバイスフラグ | |
IFF_UP | インターフェースは動作中。 |
IFF_BROADCAST | 有効なブロードキャストアドレスがセットされている。 |
IFF_DEBUG | 内部のデバッグフラグ。 |
IFF_LOOPBACK | インターフェースはループバックである。 |
IFF_POINTOPOINT | インターフェースは point-to-point リンクである。 |
IFF_RUNNING | リソースが割り当て済み。 |
IFF_NOARP |
arp プロトコルがない。 L2 宛先アドレスが設定されていない。
|
IFF_PROMISC | インターフェースは promiscuous モードである。 |
IFF_NOTRAILERS | trailer の利用を避ける。 |
IFF_ALLMULTI | 全てのマルチキャストパケットを受信する。 |
IFF_MASTER | 負荷分散グループのマスターである。 |
IFF_SLAVE | 負荷分散グループのスレーブである。 |
IFF_MULTICAST | マルチキャストをサポートしている。 |
IFF_PORTSEL | ifmap によってメディアタイプを選択できる。 |
IFF_AUTOMEDIA | 自動メディア選択が有効になっている。 |
IFF_DYNAMIC |
このインターフェースが閉じると、アドレスは失われる。
|
IFF_LOWER_UP | ドライバからの L1 アップの通知 (Linux 2.6.17 以降) |
IFF_DORMANT | ドライバからの休止状態の通知 (Linux 2.6.17 以降) |
IFF_ECHO | 送られたパケットをエコーする (Linux 2.6.25 以降) |
プライベートフラグ | |
IFF_802_1Q_VLAN | インターフェースは 802.1Q VLAN デバイスである。 |
IFF_EBRIDGE | インターフェースは Ethernet ブリッジデバイスである。 |
IFF_SLAVE_INACTIVE | インターフェースは非アクティブな bonding のスレーブである。 |
IFF_MASTER_8023AD | インターフェースは 802.3ad bonding のマスターである。 |
IFF_MASTER_ALB | インターフェースは balanced-alb bonding のマスターである。 |
IFF_BONDING | インターフェースは bonding のマスターかスレーブである。 |
IFF_SLAVE_NEEDARP | インターフェースは検証に APR が必要である。 |
IFF_ISATAP | インターフェースは RFC4214 ISATAP インターフェースである。 |
拡張 (プライベート) インターフェースフラグの設定には特権が必要である。
struct ifmap { unsigned long mem_start; unsigned long mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port; };
ifmap 構造体の解釈はデバイスドライバとアーキテクチャーに依存する。
struct ifconf { int ifc_len; /* バッファーサイズ */ union { char *ifc_buf; /* バッファーアドレス */ struct ifreq *ifc_req; /* 構造体の配列 */ }; };
ifc_req が NULL の場合、 SIOCGIFCONF はすべての取得できるアドレスを受け取るのに必要なバッファーサイズ (バイト数) を ifc_len に格納して返す。 それ以外の場合は、ifc_req には ifreq 構造体の配列へのポインターを渡す。 この構造体の配列には現在アクティブな L3 インターフェースアドレスがすべて格納される。 ifc_len はバイト単位の配列のサイズを渡す。 ifreq 構造体内では、 ifr_name にインターフェース名が、 ifr_addr にそのアドレスが入る。 実際に格納されたバイト数は ifc_len で返される。
ifc_len で指定されたサイズがすべてのアドレスを格納するのに不十分な場合、 カーネルは超過分をスキップし、成功を返す。 この状況になった場合、それを検出する信頼できる方法はない。 したがって、 前もって ifc_req を NULL に設定して SIOCGIFCONF を呼び出して必要なバッファーサイズを決定するか、 返された ifc_len と元の値の差分が sizeof(struct ifreq) よりも小さい場合は必ずバッファーを大きくして再度呼び出すか、 のいずれかを行うことが推奨される。
ifconf か ifreq 構造体へのアクセスでエラーが置こった場合には EFAULT が返される。
ほとんどのプロトコルには、専用のインターフェースオプションを 設定するための独自の ioctl が存在する。 説明は各プロトコルの man ページを見よ。 IP アドレスの設定に関しては ip(7) を参照。
さらに、デバイスによってはプライベートな ioctl がある。 これらはここでは説明しない。
アドレスがなかったり、 IFF_RUNNING フラグがセットされていないインターフェースの名前は /proc/net/dev で知ることができる。
ローカル IPV6 IP アドレスは /proc/net か rtnetlink(7) で知ることができる。
#ifndef ifr_newname #define ifr_newname ifr_ifru.ifru_slave #endif