# GetMac.py
from psutil import net_if_addrs
import re
def get_all_if_info():
try:
if_infos = net_if_addrs()
if_name = if_infos.keys()
d1 = {}
for i in if_name:
if_detail = if_infos.get(i)
d2 = {'ip_addr': None, 'mac_addr': None}
for j in if_detail:
info = j[1]
flag = re.match('^([0-9]{1,3}\.){3}[0-9]{1,3}$', info)
if flag:
d2['ip_addr'] = info
else:
flag = re.match('^(([a-f0-9]{2}:)|([a-f0-9]{2}-)){5}[a-f0-9]{2}$', info, re.IGNORECASE)
if flag:
d2['mac_addr'] = info
d1.update({i: d2})
return d1
except Exception as e:
return None
if __name__ == '__main__':
result = get_all_if_info()
for k, v in result.items():
print(k, v)
#MacoOen.py
# -*- coding: utf-8 -*-
import make_package
import send_package
import re
def macopen(ip, mac, isp):
# 合法性校验
try:
# ip
index = re.match('^([0-9]{1,3}\\.){3}[0-9]{1,3}$', str(ip))
if index:
ip = ip[index.start():index.end()]
else:
return None
# mac
index = re.search('^(([a-f0-9]{2}:)|([a-f0-9]{2}-)){5}[a-f0-9]{2}$', str(mac), re.IGNORECASE)
if index:
mac = mac[index.start():index.end()]
else:
return None
# isp
index = re.search('^[1-3]$', str(isp))
if index:
isp = isp[index.start():index.end()]
else:
return None
print(ip, mac, isp)
package = make_package.MakePackage().do(ip=ip, mac=mac, isp=isp)
result = send_package.SendPackage().send_udp(host='172.16.1.1', port=20015, package=package)
if result:
return result
else:
return None
except Exception as e:
print(e)
return None
# make_package.py
# -*- coding: utf-8 -*-
import struct
class MakePackage:
@staticmethod
def _checksum(data):
cs = 0x4e67c6a7
for b in data:
cs &= 0xffffffff
if cs < 0x80000000:
cs ^= ((cs >> 2) + (cs << 5) + b) & 0xffffffff
else:
cs ^= (((cs >> 2) | 0xC0000000) + (cs << 5) + b) & 0xffffffff
# print(bin(cs))
return cs & 0x7fffffff
def _make_packet(self, ip, mac, isp):
packet = struct.pack('!1s 29x 4s 17s 3x 1s 1x', '1'.encode(), ip, mac, isp)
# print('[packet]', packet.hex())
cs = self._checksum(packet)
# print('[checksum]', cs)
return struct.pack('<56s I', packet, cs)
def do(self, ip, mac, isp):
try:
# 处理ip
byte_array = bytes()
for i in str(ip).split('.'):
byte_array += int(i).to_bytes(1, 'little')
ip = byte_array
print('[process_ip]', ip.hex())
# 处理mac
byte_array = bytes()
mac = str(mac).replace('-', ':').upper().strip()
for i in mac: # 取每一个字符,转换为bytes
byte_array += i.encode()
mac = byte_array
print('[process_mac]', mac.hex())
# 处理isp
isp = int(isp).to_bytes(1, 'little')
print('[process_isp]', isp.hex())
# 生成数据包
package = self._make_packet(ip, mac, isp)
return package
except Exception as e:
print(e)
raise RuntimeError('Make Package Error')
# send_package.py
# -*- coding: utf-8 -*-
import socket
class SendPackage:
@staticmethod
def send_udp(host, port, package):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setblocking(True) # 设置为阻塞模式,启用set_timeout功能
s.settimeout(3)
# 使用socket发送数据包,等待接收数据包
try:
print('[INFO] [--sending--] ', package.hex())
s.sendto(package, (host, port))
recv_package, address = s.recvfrom(1024)
print('[INFO] [--received--] ', recv_package.hex(), address)
s.close()
return str(recv_package.hex())
except Exception as e:
print(e)
return None
使用的说明,用GetMac.py得到网卡的信息
然后MacOpen.py利用得到的网卡信息,调用make_packet和send_pack
两种方式的利用
import GetMac
import MacOpen
ip = ''
mac = ''
isp = ''
def get_info_mac():
all_mac_ip = GetMac.get_all_if_info() # 得到全部的mac和ip
for k, v in all_mac_ip.items():
print(k, v)
if __name__ == '__main__':
get_info_mac()
print("联通 1\t电信 2\t移动 3")
print("请根据获取得到的数据输入信息")
# mac = input('MAC:')
# ip = input('IP:')
# isp = input('运营商')
status = MacOpen.macopen(ip, mac, isp)
print("找到的state:", status)
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5 import QtGui
import GetMac
import MacOpen
class MyWindown(QWidget):
def __init__(self, parent=None):
"""
界面的初始化
:param parent:
"""
super(MyWindown, self).__init__(parent)
self.setFont(QtGui.QFont('Arial', 10))
self.top_layout = QHBoxLayout()
self.isp = "2" # 服务商默认电信,其中联通1,移动3
self.button_layout = QHBoxLayout()
self.main_layout = QVBoxLayout()
# 窗体上半部分的布局
self.ip_label = QLabel("ip:")
self.ip_input = QLineEdit()
self.ip_input.setFixedSize(200, 30)
self.mac_label = QLabel("mac:")
self.mac_input = QLineEdit()
self.mac_input.setFixedSize(200, 30)
self.top_layout.addStretch()
self.top_layout.addWidget(self.ip_label)
self.top_layout.addWidget(self.ip_input)
self.top_layout.addSpacing(70)
self.top_layout.addWidget(self.mac_label)
self.top_layout.addWidget(self.mac_input)
self.top_layout.addStretch()
# 中间的布局
self.list_info = QListWidget()
self.list_info.setFont(QtGui.QFont('Arial', 10))
# 下部分的布局
self.lt_button = QPushButton("联通")
self.dx_button = QPushButton("电信")
self.yd_button = QPushButton("移动")
self.status_label = QLabel()
self.button_layout.addStretch()
self.button_layout.addWidget(self.lt_button)
self.button_layout.addWidget(self.dx_button)
self.button_layout.addWidget(self.yd_button)
self.button_layout.addSpacing(70)
self.button_layout.addWidget(self.status_label)
self.button_layout.addStretch()
# 总的布局和窗口的设置
self.setWindowTitle("专用出校器")
icon = QIcon()
icon.addPixmap(QPixmap("icon.png"), QIcon.Normal, QIcon.Off)
self.setWindowIcon(icon)
self.main_layout.addLayout(self.top_layout)
self.main_layout.addWidget(self.list_info)
self.main_layout.addLayout(self.button_layout)
self.setFixedSize(700, 400)
self.setLayout(self.main_layout)
self.show()
self.signal_slot()
self.get_infos()
def signal_slot(self):
"""
qt信号和槽的连接
:return:
"""
self.lt_button.clicked.connect(self.choose_lt_server)
self.dx_button.clicked.connect(self.choose_dx_server)
self.yd_button.clicked.connect(self.choose_yd_server)
self.list_info.itemClicked.connect(self.choose_item)
def open_mac(self):
"""
开放mac地址
:return:
"""
try:
status = MacOpen.macopen(self.ip_input.text(), self.mac_input.text(), self.isp)
print(status)
if status:
self.status_label.setText("mac地址已经开放")
print("状态%s \tmac地址已经开放,可以进行DSL拨号" % (str(status),))
else:
self.status_label.setText("预拨号失败")
except Exception as e:
self.status_label.setText("超时")
print(e)
def get_infos(self):
"""
获得网卡的信息,将信息填入窗体,任取除了127.0.0.1那个地址
:return:
"""
all_mac_ip = GetMac.get_all_if_info() # 得到全部的mac和ip
for k, v in all_mac_ip.items():
print(k, v)
ip_info = v['ip_addr']
mac_info = v['mac_addr']
if not mac_info:
continue
if not ip_info:
continue
self.list_info.addItem(QListWidgetItem("{:27}\t{:27}\t{:27}".format(mac_info, ip_info, k)))
if k == '以太网':
self.ip_input.setText(v['ip_addr'])
self.mac_input.setText(v['mac_addr'])
def choose_item(self, item):
"""
槽函数,随着listwidgetd的选择做出改变
:param item:
:return:
"""
item = item.text()
item = item.split("\t")
self.ip_input.setText(item[1].strip())
self.mac_input.setText(item[0].strip())
def choose_lt_server(self):
self.isp = "1"
self.open_mac()
def choose_dx_server(self):
self.isp = "2"
self.open_mac()
def choose_yd_server(self):
self.isp = "3"
self.open_mac()
if __name__ == '__main__':
app = QApplication(sys.argv)
windown = MyWindown()
windown.show()
sys.exit(app.exec_())
windows打包:
pip install pyinstaller
pyinstaller -F xx.py