■flagからプロミスキャスモードのインターフェイスを探す。 $ lsb_release -d Description: Debian GNU/Linux 8.3 (jessie) ■ifconfig、ipコマンドを使用する。 $ ip a list | awk '/PROMISC/{print $2}' eth1: $ env LANG=C /sbin/ifconfig | awk '/^[a-z]|PROMISC/{print $1,$4}' eth0 HWaddr eth1 HWaddr UP PROMISC lo Loopback vmnet1 HWaddr vmnet8 HWaddr $ /sbin/ifconfig | awk '/^[a-z]|PROMISC/{print $1,$4}' eth0 ハードウェアアドレス eth1 ハードウェアアドレス UP PROMISC lo vmnet1 ハードウェアアドレス vmnet8 ハードウェアアドレス ■netstatのフラグを利用する。 ioctl経由で呼び出していることが分かる。 $ netstat -in | awk '/BMPRU/{print $1}' eth1 $ sudo strace netstat -i 2>&1 | grep -i promisc --color ioctl(5, SIOCGIFFLAGS, {ifr_name="eth1", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_PROMISC|IFF_MULTICAST}) = 0 ■/sysのフラグを利用する。 $ grep . /sys/class/net/*/flags | awk '/0x1103/' /sys/class/net/eth1/flags:0x1103 ■それぞれのフラグの意味は以下。 $ man netdevice | awk '/^ *IFF_/ && (/LOOPBACK/ || /CAST/ || /PROMISC/ || /RUNNING/ || /UP/){print}' IFF_UP インターフェースは動作中。 IFF_BROADCAST 有効なブロードキャストアドレスがセットされている。 IFF_LOOPBACK インターフェースはループバックである。 IFF_RUNNING リソースが割り当て済み。 IFF_PROMISC インターフェースは promiscuous モードである。 IFF_MULTICAST マルチキャストをサポートしている。 IFF_LOWER_UP ドライバからの L1 アップの通知 (Linux 2.6.17 以降) ■if.hのソースからフラグを確認してみる。 $ man netdevice | grep include #include <sys/ioctl.h> #include <net/if.h> $ apt-get source --download-only linux-headers-3.16.0-4-common $ apt-file search /linux/if.h dietlibc-dev: /usr/include/diet/linux/if.h linux-headers-3.16.0-4-common: /usr/src/linux-headers-3.16.0-4-common/include/uapi/linux/if.h linux-libc-dev: /usr/include/linux/if.h $ tar Jtvf linux_3.16.7-ckt20.orig.tar.xz | awk '/\/if.h$/{print $NF}' linux-3.16.7-ckt20/include/uapi/linux/if.h $ tar Jxvf linux_3.16.7-ckt20.orig.tar.xz linux-3.16.7-ckt20/include/uapi/linux/if.h linux-3.16.7-ckt20/include/uapi/linux/if.h $ awk '/IFF_.*1<</' linux-3.16.7-ckt20/include/uapi/linux/if.h
IFF_UP = 1<<0, /* sysfs */
IFF_BROADCAST = 1<<1, /* volatile */
IFF_DEBUG = 1<<2, /* sysfs */
IFF_LOOPBACK = 1<<3, /* volatile */
IFF_POINTOPOINT = 1<<4, /* volatile */
IFF_NOTRAILERS = 1<<5, /* sysfs */
IFF_RUNNING = 1<<6, /* volatile */
IFF_NOARP = 1<<7, /* sysfs */
IFF_PROMISC = 1<<8, /* sysfs */
IFF_ALLMULTI = 1<<9, /* sysfs */
IFF_MASTER = 1<<10, /* volatile */
IFF_SLAVE = 1<<11, /* volatile */
IFF_MULTICAST = 1<<12, /* sysfs */
IFF_PORTSEL = 1<<13, /* sysfs */
IFF_AUTOMEDIA = 1<<14, /* sysfs */
IFF_DYNAMIC = 1<<15, /* sysfs */
IFF_LOWER_UP = 1<<16, /* volatile */
IFF_DORMANT = 1<<17, /* volatile */
IFF_ECHO = 1<<18, /* volatile */
■左シフトビットなので、以下の数値の和になるはず。 $ awk '/IFF_.*1<</{sub(",","");print "echo "$1,"$(("$3"))"}' linux-3.16.7-ckt20/include/uapi/linux/if.h | bash IFF_UP 1 IFF_BROADCAST 2 IFF_DEBUG 4 IFF_LOOPBACK 8 IFF_POINTOPOINT 16 IFF_NOTRAILERS 32 IFF_RUNNING 64 IFF_NOARP 128 IFF_PROMISC 256 IFF_ALLMULTI 512 IFF_MASTER 1024 IFF_SLAVE 2048 IFF_MULTICAST 4096 IFF_PORTSEL 8192 IFF_AUTOMEDIA 16384 IFF_DYNAMIC 32768 IFF_LOWER_UP 65536 IFF_DORMANT 131072 IFF_ECHO 262144 ■ん?0x40も違う。。。64はRUNNING分? $ awk '/IFF_.*1<</{sub(",","");print "echo "$1,"$(("$3"))"}' linux-3.16.7-ckt20/include/uapi/linux/if.h | bash | \ awk '{if(/IFF_UP/ || /IFF_.*CAST/ || /PROMISC/ || /RUNNING/){sum+=$2;print $1}};END{printf "0x%x\n",sum}' IFF_UP IFF_BROADCAST IFF_RUNNING IFF_PROMISC IFF_MULTICAST 0x1143 $ awk '/IFF_.*1<</{sub(",","");print "echo "$1,"$(("$3"))"}' linux-3.16.7-ckt20/include/uapi/linux/if.h | bash | \ awk '{if(/IFF_UP/ || /IFF_.*CAST/ || /PROMISC/ ){sum+=$2;print $1}};END{printf "0x%x\n",sum}'IFF_UP IFF_BROADCAST IFF_PROMISC IFF_MULTICAST 0x1103 ■「IFF_UP」はdownで消せる。「IFF_RUNNING」フラグも消えているが、 そもそも「IFF_RUNNING」と「IFF_LOWERUP」は計算されていないように見える。 $ awk '/IFF_.*1<</{sub(",","");print "echo "$1,"$(("$3"))"}' linux-3.16.7-ckt20/include/uapi/linux/if.h | bash | \ awk '{if(/IFF_.*UP/ || /RUNNING/){printf "%s,%d,0x%x\n",$1,$2,$2}}' IFF_UP,1,0x1 IFF_RUNNING,64,0x40 IFF_LOWER_UP,65536,0x10000 $ sudo ifconfig eth1 down $ ip a list eth1 | grep "<" | sed -e 's/.*<//g' -e 's/>.*//g' BROADCAST,MULTICAST,PROMISC $ cat /sys/class/net/eth1/flags 0x1102 ■「IFF_PROMISC」は256なので、「0x100」分減るのは想定通り。 $ echo 256 | awk '{printf "0x%x\n",$1}' 0x100 $ sudo ifconfig eth1 -promisc down $ ip a list eth1 | grep "<" | sed -e 's/.*<//g' -e 's/>.*//g' BROADCAST,MULTICAST $ cat /sys/class/net/eth1/flags 0x1002 $ sudo ifconfig eth1 promisc down $ ip a list eth1 | grep "<" | sed -e 's/.*<//g' -e 's/>.*//g' BROADCAST,MULTICAST,PROMISC $ cat /sys/class/net/eth1/flags 0x1102 $ sudo ifconfig eth1 promisc up $ ip a list eth1 | grep "<" | sed -e 's/.*<//g' -e 's/>.*//g' BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP $ cat /sys/class/net/eth1/flags 0x1103