ipFind.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import ipaddress
  2. import re
  3. import subprocess
  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. net_card_data.append({'flag': True, 'gateway1': '172.30.130.1', 'mask': '255.255.255.0'})
  35. for x in res[0].splitlines():
  36. try:
  37. # 匹配IP正则
  38. 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}')
  39. # 测试发现有的网关会默认在下一行,情况见说明一,所以这边检查到默认网关,发现没有匹配到,则从下一行找
  40. if gateway_error:
  41. temp_dict['gateway1'] = pattern.search(x).group()
  42. gateway_error = False
  43. #print("当前网卡 %s 获取第二行网关信息 %s" % (temp_dict['card_name'], temp_dict['gateway1']))
  44. continue
  45. # 如果发现新的适配器,则重置上一个网卡是否可用的状态
  46. if "适配器" in x:
  47. temp_dict = dict(flag=True)
  48. temp_dict['card_name'] = x.split(" ", 1)[1][:-1]
  49. #print("当前网卡 %s" % (temp_dict['card_name']))
  50. continue
  51. if "IPv4 地址" in x:
  52. temp_dict['ip'] = pattern.search(x).group()
  53. #print("当前网卡 %s 获取IP信息 %s" % (temp_dict['card_name'], temp_dict['ip']))
  54. continue
  55. elif "子网掩码" in x:
  56. temp_dict['mask'] = pattern.search(x).group()
  57. #print("当前网卡 %s 获取子网掩码信息 %s" % (temp_dict['card_name'], temp_dict['mask']))
  58. continue
  59. # 测试发现有的网关会默认在下一行,情况见说明一,所以这边做了异常处理
  60. elif "默认网关" in x:
  61. try:
  62. temp_dict['gateway1'] = pattern.search(x).group()
  63. #temp_dict['gateway1'] = "172.27.115.254"
  64. #print("当前网卡 %s 获取默认网关信息 %s" % (temp_dict['card_name'], temp_dict['gateway1']))
  65. except:
  66. gateway_error = True
  67. #print("当前网卡 %s 解析当前行默认网关信息错误" % (temp_dict['card_name']))
  68. # 如果检查到网关,代表当前适配器信息已经获取完毕 重置网关状态与适配器信息字典
  69. if temp_dict.get("gateway1"):
  70. net_card_data.append(temp_dict)
  71. #print("当前网卡 %s 当前适配器信息获取完毕 %s \n\n" % (temp_dict['card_name'], temp_dict))
  72. temp_dict = dict(flag=True)
  73. continue
  74. # 发现媒体已断开则更改当前适配器状态
  75. elif "媒体已断开" in x:
  76. #print("当前网卡 %s 已断开 跳过\n\n" % (temp_dict['card_name']))
  77. temp_dict['flag'] = False
  78. continue
  79. # 判断媒体状态正常,IP、子网掩码、网关都正常后,保持起来
  80. if temp_dict.get("flag") and temp_dict.get("ip") and temp_dict.get("mask") and temp_dict.get("gateway1"):
  81. #print("当前网卡 %s 当前适配器信息获取完毕 %s \n\n" % (temp_dict['card_name'], temp_dict))
  82. net_card_data.append(temp_dict)
  83. # 重置网关状态与适配器信息字典
  84. temp_dict = dict(flag=True)
  85. continue
  86. except Exception as e:
  87. # print(e)
  88. # print(x)
  89. pass
  90. # for i in net_card_data:
  91. # print("%s:%s" % (i.get("card_name"), i))
  92. #print(net_card_data)
  93. return net_card_data
  94. # 子网掩码地址转长度
  95. def netmask_to_bit_length(netmask):
  96. """
  97. >>> netmask_to_bit_length('255.255.255.0')
  98. 24
  99. >>>
  100. """
  101. # 分割字符串格式的子网掩码为四段列表
  102. # 计算二进制字符串中 '1' 的个数
  103. # 转换各段子网掩码为二进制, 计算十进制
  104. return sum([bin(int(i)).count('1') for i in netmask.split('.')])
  105. # 子网掩码长度转地址
  106. def bit_length_to_netmask(mask_int):
  107. """
  108. >>> bit_length_to_netmask(24)
  109. '255.255.255.0'
  110. >>>
  111. """
  112. bin_array = ["1"] * mask_int + ["0"] * (32 - mask_int)
  113. tmpmask = [''.join(bin_array[i * 8:i * 8 + 8]) for i in range(4)]
  114. tmpmask = [str(int(netmask, 2)) for netmask in tmpmask]
  115. return '.'.join(tmpmask)
  116. def getStartIP(gateway:str,mask:str):
  117. gatewayList = gateway.split('.')
  118. maskList = mask.split('.')
  119. newStartIP=''
  120. for i in range(4):
  121. bgate = list(bin(int(gatewayList[i])).replace('0b','').zfill(8))
  122. bmask = list(bin(int(maskList[i])).replace('0b','').zfill(8))
  123. # print('gate:{}'.format(bgate))
  124. # print('mask:{}'.format(bmask))
  125. ngate = [0, 0, 0, 0, 0, 0, 0, 0]
  126. for n in range(8):
  127. if bmask[n]=='0':
  128. ngate[n]=0
  129. else:
  130. ngate[n]=bgate[n]
  131. # print("newGate:{}".format(ngate))
  132. nbgate = ''
  133. for item in ngate:
  134. nbgate+=str(item)
  135. # print(nbgate)
  136. # print('formate gate:{}'.format(int(nbgate, 2)))
  137. newStartIP += str(int(nbgate, 2))
  138. newStartIP += '.'
  139. # print(gatewayList)
  140. # print(newStartIP[:-1])
  141. return newStartIP[:-1]
  142. def ipFind():
  143. res = get_net_card()
  144. #print(res)
  145. allNetIP = []
  146. for i in res:
  147. ip = i['gateway1']
  148. ipl = ip.split('.')
  149. mask = i['mask']
  150. newip = getStartIP(ip, mask)
  151. masklen = netmask_to_bit_length(mask)
  152. net = ipaddress.ip_network('{}/{}'.format(newip, masklen))
  153. for x in net.hosts():
  154. allNetIP.append(str(x))
  155. return allNetIP
  156. if __name__ == '__main__':
  157. allNetIP = ipFind()
  158. print(allNetIP)