ipFind.py 6.6 KB

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