Last active
August 29, 2015 14:25
-
-
Save jxinging/33464c6096de873a9087 to your computer and use it in GitHub Desktop.
机器网络接口信息探测(获取机器的公网IP,内网IP信息)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf8 | |
from subprocess import check_output | |
from socket import inet_aton | |
import struct | |
try: | |
from cStringIO import StringIO | |
except ImportError: | |
from StringIO import StringIO | |
def ip2int(ip_str): | |
return struct.unpack('!I', inet_aton(ip_str))[0] | |
__LOOPBACK_IP_RANGE = ((ip2int('127.0.0.0'), ip2int('127.255.255.255')),) | |
__PRIVATE_IP_RANGE = ((ip2int('10.0.0.0'), ip2int('10.255.255.255')), | |
(ip2int('172.16.0.0'), ip2int('172.31.255.255')), | |
(ip2int('192.168.0.0'), ip2int('192.168.255.255'))) | |
def check_ip_range(ip_str, check_range): | |
ip_int = ip2int(ip_str) | |
for s, e in check_range: | |
if s <= ip_int <= e: | |
return True | |
return False | |
is_loopback_ip = lambda x: check_ip_range(x, __LOOPBACK_IP_RANGE) | |
is_private_ip = lambda x: check_ip_range(x, __PRIVATE_IP_RANGE) | |
is_public_ip = lambda x: not (is_private_ip(x) or is_loopback_ip(x)) | |
def get_ip_type(ip_str): | |
if is_loopback_ip(ip_str): | |
return 'loopback' | |
elif is_private_ip(ip_str): | |
return 'private' | |
else: | |
return 'public' | |
def detect_interface_info(): | |
output = check_output('ip address show', close_fds=True, shell=True) | |
stream = StringIO(output) | |
# [{"name": "eth0", "link_type": "ether", "ip": "192.168.1.1/24", | |
# "ip_type": "private", "mac": "08:00:27:70:f9:ec"}] | |
info_list = [] | |
line = stream.readline() | |
info = None | |
while line: | |
line = line.strip() | |
# 新信息接口开始 | |
if line[0].isdigit() and line[1] == ':': | |
if info: | |
info_list.append(info) | |
info = {'name': line.split()[1].strip(':')} | |
else: | |
line_sp = line.split() | |
if line.startswith('link/'): | |
info['link_type'] = line_sp[0].split('/')[1] | |
info['mac'] = line_sp[1] | |
elif line.startswith('inet '): | |
info['ip'] = line_sp[1] | |
info['ip_type'] = get_ip_type(info['ip'].split('/')[0]) | |
line = stream.readline() | |
if info: | |
info_list.append(info) | |
return info_list | |
def csv_output(info_list, seq=',', attr_names=('name', 'ip', 'ip_type', 'mac', 'link_type')): | |
result = ["#" + seq.join(attr_names), ] | |
for info in info_list: | |
result.append(seq.join(map(lambda an: info.get(an, 'None'), | |
attr_names))) | |
return "\n".join(result) | |
if __name__ == '__main__': | |
import sys | |
filter_ip_type = None | |
if len(sys.argv) > 1: | |
filter_ip_type = sys.argv[1] | |
if_info_list = detect_interface_info() | |
if filter_ip_type: | |
if_info_list = filter(lambda x: x['ip_type'] == filter_ip_type, if_info_list) | |
print csv_output(if_info_list) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment