プラットフォーム共通でIPアドレス情報+αを表示するプログラムをPythonで作成しようとして、結局GiveUp
機器に割り当てられている、IPアドレス、Link Up/Downなどの情報をプラットフォーム共通(ここでは、Linux、Windows、MacOS)のPythonプログラムを作成しようとして、結局のところできずじまい、、、という経緯を記録として残す。
固有モジュール
Windowsでは、「ろうとるがPythonを扱う、、(その11:Python+tkinterにてIPアドレス設定 )」でも使った
を使うと、Windowsから各種情報が取得できる。
Linuxでは
にて、ネットワーク情報が取得できる。
netifaces
何度か利用したことがあり、これを利用できると思った。実行例は下記のとおり(一部、故意に改行)。
>>> import netifaces
>>> netifaces.AF_LINK
17
>>> netifaces.AF_INET
2
>>> netifaces.interfaces()
['lo', 'eth0', 'eth1', 'eth2']
>>> net0 = netifaces.ifaddresses('eth0')
>>> net1 = netifaces.ifaddresses('eth1')
>>> net0
{17: [{'addr': 'XX:XX:XX:d8:13:d9', 'broadcast': 'ff:ff:ff:ff:ff:ff'}],
2: [{'addr': '192.168.2.53', 'netmask': '255.255.255.0', 'broadcast': '192.168.2.255'}],
10: [{'addr': 'fe80::YYYY:30d5:cbff:e00e%eth0', 'netmask': 'ffff:ffff:ffff:ffff::/64'}]}
>>> net1
{17: [{'addr': 'XX:XX:XX:37:b5:4b', 'broadcast': 'ff:ff:ff:ff:ff:ff'}]}
>>> net0.get(netifaces.AF_LINK)[0].get('addr')
'XX:XX:XX:d8:13:d9'
>>> net0.get(netifaces.AF_INET)[0].get('addr')
'192.168.2.53'
>>> net1.get(netifaces.AF_LINK)[0].get('addr')
'XX:XX:XX:37:b5:4b'
'eth0'にはLANケーブルが接続されており、'eth1'には接続されていない。AF_INET有無で、Link Up/Downがわかると判断。これらから、下記コードを作成。
from tabulate import *
import netifaces
headers = ['I/F', 'Mac address', 'IP address', 'Netmask', 'Broadcast', 'Status']
IFtable = {}
for key in headers:
IFtable[key] = []
for ifname in netifaces.interfaces():
netif = netifaces.ifaddresses(ifname)
if netifaces.AF_LINK in netif:
IFtable[headers[0]].append(ifname)
macaddr = netif.get(netifaces.AF_LINK)[0].get('addr')
IFtable[headers[1]].append(macaddr)
if netifaces.AF_INET in netif:
ipaddr = netif.get(netifaces.AF_INET)[0].get('addr')
IFtable[headers[2]].append(ipaddr)
netmask = netif.get(netifaces.AF_INET)[0].get('netmask')
IFtable[headers[3]].append(netmask)
broadcast = netif.get(netifaces.AF_INET)[0].get('broadcast')
IFtable[headers[4]].append(broadcast)
IFtable[headers[5]].append('Up')
else:
IFtable[headers[2]].append('')
IFtable[headers[3]].append('')
IFtable[headers[4]].append('')
IFtable[headers[5]].append('Down')
print(tabulate(IFtable, headers=headers, tablefmt='fancy_grid'))
AF_INETがあるときは、Link Up、IPアドレスなどを表示、AF_INETがないときは、Link Down、Macアドレスのみを表示している。なお、tabulateを用いて表形式で表示している。これについては、下記参照。
Linuxでの結果
╒═══════╤═══════════════════╤══════════════╤═══════════════╤═══════════════╤══════════╕
│ I/F │ Mac address │ IP address │ Netmask │ Broadcast │ Status │
╞═══════╪═══════════════════╪══════════════╪═══════════════╪═══════════════╪══════════╡
│ lo │ 00:00:00:00:00:00 │ 127.0.0.1 │ 255.0.0.0 │ │ Up │
├───────┼───────────────────┼──────────────┼───────────────┼───────────────┼──────────┤
│ eth0 │ XX:XX:XX:d8:13:d9 │ 192.168.2.53 │ 255.255.255.0 │ 192.168.2.255 │ Up │
├───────┼───────────────────┼──────────────┼───────────────┼───────────────┼──────────┤
│ eth1 │ XX:XX:XX:37:b5:4b │ │ │ │ Down │
├───────┼───────────────────┼──────────────┼───────────────┼───────────────┼──────────┤
│ eth2 │ XX:XX:XX:d8:13:d9 │ │ │ │ Down │
╘═══════╧═══════════════════╧══════════════╧═══════════════╧═══════════════╧══════════╛
OK。
Macでの結果
╒═══════════╤═══════════════════╤════════════════╤═══════════════╤════════════════╤══════════╕
│ I/F │ Mac address │ IP address │ Netmask │ Broadcast │ Status │
╞═══════════╪═══════════════════╪════════════════╪═══════════════╪════════════════╪══════════╡
│ en0 │ XX:XX:XX:06:da:b8 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼────────────────┼──────────┤
│ en1 │ XX:XX:XX:b9:c4:44 │ 192.168.10.201 │ 255.255.255.0 │ 192.168.10.255 │ Up │
├───────────┼───────────────────┼────────────────┼───────────────┼────────────────┼──────────┤
│ p2p0 │ XX:XX:XX:b9:c4:44 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼────────────────┼──────────┤
│ awdl0 │ XX:XX:XX:d4:f8:ff │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼────────────────┼──────────┤
│ en2 │ XX:XX:XX:71:59:d0 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼────────────────┼──────────┤
│ en3 │ XX:XX:XX:71:59:d1 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼────────────────┼──────────┤
│ bridge0 │ XX:XX:XX:71:59:d0 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼────────────────┼──────────┤
│ bridge100 │ XX:XX:XX:60:15:64 │ 192.168.2.1 │ 255.255.255.0 │ 192.168.2.255 │ Up │
╘═══════════╧═══════════════════╧════════════════╧═══════════════╧════════════════╧══════════╛
OK。
Windowsでの結果
╒════════════════════════════════════════╤═══════════════════╤════════════════╤═══════════════╤═════════════════╤══════════╕
│ I/F │ Mac address │ IP address │ Netmask │ Broadcast │ Status │
╞════════════════════════════════════════╪═══════════════════╪════════════════╪═══════════════╪═════════════════╪══════════╡
│ {1C20D698-D1CB-4F16-A297-FDCF07852266} │ XX:XX:XX:e7:4d:42 │ │ │ │ Down │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {EAC691BF-3B4A-4BB4-9D76-03D5AF486FE3} │ XX:XX:XX:8a:51:8e │ │ │ │ Down │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {8EA4950F-0DED-4187-9499-2347980DAEA4} │ XX:XX:XX:8a:51:8f │ │ │ │ Down │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {F99FE886-BC25-4909-8C8B-F0177F2BC3C9} │ XX:XX:XX:70:8d:fc │ 172.26.208.1 │ 255.255.240.0 │ 172.26.223.255 │ Up │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {22436D02-C2EE-4ED1-B370-ED48B78DDFDB} │ XX:XX:XX:00:00:08 │ 192.168.56.1 │ 255.255.255.0 │ 192.168.56.255 │ Up │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {D23B393F-9FB4-430F-83AB-4FD4A3DEEC75} │ XX:XX:XX:00:00:21 │ 192.168.219.1 │ 255.255.255.0 │ 192.168.219.255 │ Up │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {9E21F708-247C-4A54-B478-1F8299119C49} │ XX:XX:XX:08:54:81 │ 192.168.2.29 │ 255.255.255.0 │ 192.168.2.255 │ Up │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {E282A14A-88F9-4C2D-A4A4-46C2247D1E9A} │ XX:XX:XX:e5:e4:13 │ │ │ │ Down │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {C9F3F5FC-7ED5-40F1-8E98-09D17B856B8A} │ XX:XX:XX:e5:e4:12 │ │ │ │ Down │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {833539D9-7F84-48C1-B648-2B744509569C} │ XX:XX:XX:c0:00:01 │ 192.168.42.1 │ 255.255.255.0 │ 192.168.42.255 │ Up │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {B37F799C-F960-40F2-8999-AAA4BD4867F6} │ XX:XX:XX:c0:00:08 │ 192.168.59.1 │ 255.255.255.0 │ 192.168.59.255 │ Up │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {60DC4B5F-78DF-4263-BFBA-3AD2F6FEB2E6} │ XX:XX:XX:e5:e4:12 │ 192.168.10.202 │ 255.255.255.0 │ 192.168.10.255 │ Up │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {B79DBB08-3C12-4AD2-A20F-500094C3F10A} │ XX:XX:XX:e5:e4:16 │ │ │ │ Down │
├────────────────────────────────────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ {03F3FF20-EBD5-11E7-81CC-806E6F6E6963} │ │ 127.0.0.1 │ 255.0.0.0 │ 127.255.255.255 │ Up │
╘════════════════════════════════════════╧═══════════════════╧════════════════╧═══════════════╧═════════════════╧══════════╛
I/F名がWindows特有のIDのようなものになっており、「イーサネット」など具体名が見えない。
どうにかならないかと思い、トライを続ける。
psutil
psutilは、OS周りの情報を扱うモジュール。実行例は下記のとおり(一部、故意に改行かつ情報割愛)。
>>> import psutil
>>> netif = psutil.net_if_addrs()
>>> netif
{'lo': [snicaddr(family=<AddressFamily.AF_INET: 2>,
address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None),
...
'eth0': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.2.53', netmask='255.255.255.0', broadcast='192.168.2.255', ptp=None),
...
],
...
}
>>> netif['eth1']
[snicaddr(family=<AddressFamily.AF_PACKET: 17>,
address='c2:ec:03:37:b5:4b', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]
>>> netif['eth0']
[snicaddr(family=<AddressFamily.AF_INET: 2>,
address='192.168.2.53', netmask='255.255.255.0', broadcast='192.168.2.255', ptp=None),
...
snicaddr(family=<AddressFamily.AF_PACKET: 17>,
address='12:50:3d:d8:13:d9', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]
'eth0'にはLANケーブルが接続されており、'eth1'には接続されていない。AF_INET有無で、Link Up/Downがわかると判断。また、LinuxでのAF_PACKETは、MacおよびWindowsではAF_LINKで相当するようであった。これらから、下記コードを作成。
import psutil
from tabulate import *
### Table (Dictionary) ###
IFtable = {}
header = ['I/F', 'Mac address', 'IP address', 'Netmask', 'Broadcast', 'Status']
### Network Interface ###
for key in header:
IFtable[key] = []
AllIFs = psutil.net_if_addrs()
for IFname, IFinfo in AllIFs.items():
Found_Link = 0
Found_Inet = 0
for data in IFinfo:
if data.family.name == 'AF_LINK' or data.family.name == 'AF_PACKET':
Found_Link = 1
macaddr = data.address
if data.family.name == 'AF_INET':
Found_Inet = 1
ipaddr = data.address
netmask = data.netmask
broadcast = data.broadcast
if Found_Link == 1:
IFtable[header[0]].append(IFname)
IFtable[header[1]].append(macaddr)
if Found_Inet == 1:
IFtable[header[2]].append(ipaddr)
IFtable[header[3]].append(netmask)
IFtable[header[4]].append(broadcast)
IFtable[header[5]].append('Up')
else:
IFtable[header[2]].append('')
IFtable[header[3]].append('')
IFtable[header[4]].append('')
IFtable[header[5]].append('Down')
print(tabulate(IFtable, headers=header, tablefmt='fancy_grid'))
Linuxでの結果
╒═══════╤═══════════════════╤══════════════╤═══════════════╤═══════════════╤══════════╕
│ I/F │ Mac address │ IP address │ Netmask │ Broadcast │ Status │
╞═══════╪═══════════════════╪══════════════╪═══════════════╪═══════════════╪══════════╡
│ lo │ 00:00:00:00:00:00 │ 127.0.0.1 │ 255.0.0.0 │ │ Up │
├───────┼───────────────────┼──────────────┼───────────────┼───────────────┼──────────┤
│ eth0 │ XX:XX:XX:d8:13:d9 │ 192.168.2.53 │ 255.255.255.0 │ 192.168.2.255 │ Up │
├───────┼───────────────────┼──────────────┼───────────────┼───────────────┼──────────┤
│ eth1 │ XX:XX:XX:37:b5:4b │ │ │ │ Down │
├───────┼───────────────────┼──────────────┼───────────────┼───────────────┼──────────┤
│ eth2 │ XX:XX:XX:d8:13:d9 │ │ │ │ Down │
╘═══════╧═══════════════════╧══════════════╧═══════════════╧═══════════════╧══════════╛
OK。
Macでの結果
╒═══════════╤═══════════════════╤════════════════╤═══════════════╤═════════════════╤══════════╕
│ I/F │ Mac address │ IP address │ Netmask │ Broadcast │ Status │
╞═══════════╪═══════════════════╪════════════════╪═══════════════╪═════════════════╪══════════╡
│ en0 │ XX:XX:XX:06:da:b8 │ 169.254.164.57 │ 255.255.0.0 │ 169.254.255.255 │ Up │
├───────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ en1 │ XX:XX:XX:b9:c4:44 │ 192.168.10.201 │ 255.255.255.0 │ 192.168.10.255 │ Up │
├───────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ bridge100 │ XX:XX:XX:60:15:64 │ 192.168.2.1 │ 255.255.255.0 │ 192.168.2.255 │ Up │
├───────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ p2p0 │ XX:XX:XX:b9:c4:44 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ awdl0 │ XX:XX:XX:5f:14:d5 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ en2 │ XX:XX:XX:71:59:d0 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ en3 │ XX:XX:XX:71:59:d1 │ │ │ │ Down │
├───────────┼───────────────────┼────────────────┼───────────────┼─────────────────┼──────────┤
│ bridge0 │ XX:XX:XX:71:59:d0 │ │ │ │ Down │
╘═══════════╧═══════════════════╧════════════════╧═══════════════╧═════════════════╧══════════╛
OK。
Windowsでの結果
╒═══════════════════════════════╤═══════════════════╤═════════════════╤═══════════════╤═════════════╤══════════╕
│ I/F │ Mac address │ IP address │ Netmask │ Broadcast │ Status │
╞═══════════════════════════════╪═══════════════════╪═════════════════╪═══════════════╪═════════════╪══════════╡
│ VPN - VPN Client │ XX-XX-XX-E7-4D-42 │ 169.254.19.210 │ 255.255.0.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ イーサネット 3 │ XX-XX-XX-8A-51-8E │ 169.254.240.119 │ 255.255.0.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ イーサネット 4 │ XX-XX-XX-8A-51-8F │ 169.254.55.16 │ 255.255.0.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ vEthernet (WSL) │ XX-XX-XX-70-8D-FC │ 172.26.208.1 │ 255.255.240.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ イーサネット 6 │ XX-XX-XX-00-00-08 │ 192.168.56.1 │ 255.255.255.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ イーサネット 7 │ XX-XX-XX-00-00-21 │ 192.168.219.1 │ 255.255.255.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ イーサネット 11 │ XX-XX-XX-08-54-81 │ 192.168.2.29 │ 255.255.255.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ ローカル エリア接続* 2 │ XX-XX-XX-E5-E4-13 │ 169.254.7.211 │ 255.255.0.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ ローカル エリア接続* 3 │ XX-XX-XX-E5-E4-12 │ 169.254.137.203 │ 255.255.0.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ VMware Network Adapter VMnet1 │ XX-XX-XX-C0-00-01 │ 192.168.42.1 │ 255.255.255.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ VMware Network Adapter VMnet8 │ XX-XX-XX-C0-00-08 │ 192.168.59.1 │ 255.255.255.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ Wi-Fi 5 │ XX-XX-XX-E5-E4-12 │ 192.168.10.202 │ 255.255.255.0 │ │ Up │
├───────────────────────────────┼───────────────────┼─────────────────┼───────────────┼─────────────┼──────────┤
│ Bluetooth ネットワーク接続 3 │ XX-XX-XX-E5-E4-16 │ 169.254.224.155 │ 255.255.0.0 │ │ Up │
╘═══════════════════════════════╧═══════════════════╧═════════════════╧═══════════════╧═════════════╧══════════╛
I/F名は正しく表示されるが、Broadcastアドレスが取得できない、LANケーブル未接続でも、Link Up表示されてしまった。
Link Up/Downについて
psutil.net_if_stats()にて、I/F情報が取得できる。
Linux
>>> netstat = psutil.net_if_stats()
>>> netstat
{'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536), 'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1000, mtu=1500), 'eth1': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=65535, mtu=1500), 'eth2': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=65535, mtu=1500)}
>>> netstat['eth0']
snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1000, mtu=1500)
>>> netstat['eth1']
snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=65535, mtu=1500)
- 'eth0':LANケーブル接続 → speed=1000
- 'eth1':LANケーブル未接続 → speed=65535
Mac
>>> netstat['en0']
snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1000, mtu=1500, flags='up,broadcast,notrailers,running,promisc,multicast,simplex')
>>> netstat['en1']
snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=1500, flags='up,broadcast,notrailers,running,multicast,simplex')
>>> netstat['en2']
snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500, flags='up,broadcast,notrailers,running,promisc,multicast,simplex')
- 'en0':LANケーブル接続 → speed=1000
- 'en1':WiFi接続 → speed=0
- 'en2':LANケーブル未接続 → speed=0
Windows
>>> netstat['イーサネット 11']
snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1000, mtu=1500, flags='')
>>> netstat['イーサネット 3']
snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500, flags='')
>>> netstat['Wi-Fi 5']
snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=866, mtu=1500, flags='')
- 'イーサネット 11':LANケーブル接続 → speed=1000
- 'イーサネット 3':LANケーブル未接続 → speed=0
- 'Wi-Fi 5':WiFi接続 → speed=866
単純には共通化できず、、、
LANケーブル接続時には数値(ここでは1000Mbps)が共通のようだが、未接続時には”0”と”65535”とがあり、WiFi接続時には”0”と”866”とがある。
結論(みたいなもの)
OS情報を取得して、OSごとに取得方法を変えるしかないか、、。