ipFind.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import ipaddress
  2. import subprocess
  3. import re
  4. # 执行windows命令
  5. def exec_command(commands) -> list:
  6. """执行windows命令"""
  7. if not commands:
  8. return list()
  9. # 子进程的标准输出设置为管道对象
  10. if isinstance(commands, str):
  11. commands = [commands]
  12. return_list = []
  13. for i in commands:
  14. p = subprocess.Popen(i, shell=True, stdout=subprocess.PIPE, universal_newlines=True)
  15. p.wait()
  16. res = "".join(p.stdout.readlines())
  17. return_list.append(res)
  18. return return_list
  19. def get_net_card():
  20. """
  21. 功能:通过ipconfig返回的文本解析网卡名字、ip、掩码、网关等信息
  22. 注释:简单做了注释
  23. 测试:在window10 专业版测试通过(可以检测到以太网两个(包含手机、网线)、wifi一个)
  24. 测试反馈:如果使用发现其余问题可以反馈到 sunnylishaoxu@163.com,非常感谢
  25. 说明一:
  26. 默认网关. . . . . . . . . . . . . : fe80::10b1:1865:86e8:ad10%41
  27. 172.20.10.1
  28. """
  29. net_card_data = list()
  30. res = exec_command("ipconfig")
  31. temp_dict = dict(flag=True)
  32. gateway_error = False
  33. net_card_data.append({'flag': True, 'gateway1': '172.27.115.254', 'mask': '255.255.255.0'})
  34. for x in res[0].splitlines():
  35. try:
  36. # 匹配IP正则
  37. pattern = re.compile(r'((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}')
  38. # 测试发现有的网关会默认在下一行,情况见说明一,所以这边检查到默认网关,发现没有匹配到,则从下一行找
  39. if gateway_error:
  40. temp_dict['gateway1'] = pattern.search(x).group()
  41. gateway_error = False
  42. #print("当前网卡 %s 获取第二行网关信息 %s" % (temp_dict['card_name'], temp_dict['gateway1']))
  43. continue
  44. # 如果发现新的适配器,则重置上一个网卡是否可用的状态
  45. if "适配器" in x:
  46. temp_dict = dict(flag=True)
  47. temp_dict['card_name'] = x.split(" ", 1)[1][:-1]
  48. #print("当前网卡 %s" % (temp_dict['card_name']))
  49. continue
  50. if "IPv4 地址" in x:
  51. temp_dict['ip'] = pattern.search(x).group()
  52. #print("当前网卡 %s 获取IP信息 %s" % (temp_dict['card_name'], temp_dict['ip']))
  53. continue
  54. elif "子网掩码" in x:
  55. temp_dict['mask'] = pattern.search(x).group()
  56. #print("当前网卡 %s 获取子网掩码信息 %s" % (temp_dict['card_name'], temp_dict['mask']))
  57. continue
  58. # 测试发现有的网关会默认在下一行,情况见说明一,所以这边做了异常处理
  59. elif "默认网关" in x:
  60. try:
  61. temp_dict['gateway1'] = pattern.search(x).group()
  62. #temp_dict['gateway1'] = "172.27.115.254"
  63. #print("当前网卡 %s 获取默认网关信息 %s" % (temp_dict['card_name'], temp_dict['gateway1']))
  64. except:
  65. gateway_error = True
  66. #print("当前网卡 %s 解析当前行默认网关信息错误" % (temp_dict['card_name']))
  67. # 如果检查到网关,代表当前适配器信息已经获取完毕 重置网关状态与适配器信息字典
  68. if temp_dict.get("gateway1"):
  69. net_card_data.append(temp_dict)
  70. #print("当前网卡 %s 当前适配器信息获取完毕 %s \n\n" % (temp_dict['card_name'], temp_dict))
  71. temp_dict = dict(flag=True)
  72. continue
  73. # 发现媒体已断开则更改当前适配器状态
  74. elif "媒体已断开" in x:
  75. #print("当前网卡 %s 已断开 跳过\n\n" % (temp_dict['card_name']))
  76. temp_dict['flag'] = False
  77. continue
  78. # 判断媒体状态正常,IP、子网掩码、网关都正常后,保持起来
  79. if temp_dict.get("flag") and temp_dict.get("ip") and temp_dict.get("mask") and temp_dict.get("gateway1"):
  80. #print("当前网卡 %s 当前适配器信息获取完毕 %s \n\n" % (temp_dict['card_name'], temp_dict))
  81. net_card_data.append(temp_dict)
  82. # 重置网关状态与适配器信息字典
  83. temp_dict = dict(flag=True)
  84. continue
  85. except Exception as e:
  86. # print(e)
  87. # print(x)
  88. pass
  89. # for i in net_card_data:
  90. # print("%s:%s" % (i.get("card_name"), i))
  91. #print(net_card_data)
  92. return net_card_data
  93. # 子网掩码地址转长度
  94. def netmask_to_bit_length(netmask):
  95. """
  96. >>> netmask_to_bit_length('255.255.255.0')
  97. 24
  98. >>>
  99. """
  100. # 分割字符串格式的子网掩码为四段列表
  101. # 计算二进制字符串中 '1' 的个数
  102. # 转换各段子网掩码为二进制, 计算十进制
  103. return sum([bin(int(i)).count('1') for i in netmask.split('.')])
  104. # 子网掩码长度转地址
  105. def bit_length_to_netmask(mask_int):
  106. """
  107. >>> bit_length_to_netmask(24)
  108. '255.255.255.0'
  109. >>>
  110. """
  111. bin_array = ["1"] * mask_int + ["0"] * (32 - mask_int)
  112. tmpmask = [''.join(bin_array[i * 8:i * 8 + 8]) for i in range(4)]
  113. tmpmask = [str(int(netmask, 2)) for netmask in tmpmask]
  114. return '.'.join(tmpmask)
  115. def getStartIP(gateway:str,mask:str):
  116. gatewayList = gateway.split('.')
  117. maskList = mask.split('.')
  118. newStartIP=''
  119. for i in range(4):
  120. bgate = list(bin(int(gatewayList[i])).replace('0b','').zfill(8))
  121. bmask = list(bin(int(maskList[i])).replace('0b','').zfill(8))
  122. # print('gate:{}'.format(bgate))
  123. # print('mask:{}'.format(bmask))
  124. ngate = [0, 0, 0, 0, 0, 0, 0, 0]
  125. for n in range(8):
  126. if bmask[n]=='0':
  127. ngate[n]=0
  128. else:
  129. ngate[n]=bgate[n]
  130. # print("newGate:{}".format(ngate))
  131. nbgate = ''
  132. for item in ngate:
  133. nbgate+=str(item)
  134. # print(nbgate)
  135. # print('formate gate:{}'.format(int(nbgate, 2)))
  136. newStartIP += str(int(nbgate, 2))
  137. newStartIP += '.'
  138. # print(gatewayList)
  139. # print(newStartIP[:-1])
  140. return newStartIP[:-1]
  141. def ipFind():
  142. res = get_net_card()
  143. #print(res)
  144. allNetIP = []
  145. for i in res:
  146. ip = i['gateway1']
  147. ipl = ip.split('.')
  148. mask = i['mask']
  149. newip = getStartIP(ip, mask)
  150. masklen = netmask_to_bit_length(mask)
  151. net = ipaddress.ip_network('{}/{}'.format(newip, masklen))
  152. for x in net.hosts():
  153. allNetIP.append(str(x))
  154. return allNetIP
  155. if __name__ == '__main__':
  156. allNetIP = ipFind()
  157. print(allNetIP)