Python读取PXE启动时的机器MAC地址
服务器上电,通过PXE口启动,批量安装时需要GUID或者MAC地址来区分不同机器,有些服务器厂家出厂时没有把mac地址贴出来,比如HP,有些厂家贴在包装箱和机器后面板,比如DELL,没有的话,可以给服务器加电,让其用PXE启动,向外发送DHCP DISCOVER请求,通过以下脚本就可以收到该机器的mac地址,需要自己的笔记本设置为静态ip格式,具体ip地址随便。
当然如果交换机可登入的话,可以用show mac address-table看到所有连接到该交换机的机器的mac地址和对应端口号。
#!/usr/bin/env python
# -*- coding: gbk -*-
import os, sys, string
import time
import socket
import traceback
import msvcrt
import array
import struct
programName=”
class GetMacAddr_Class(object):
def __init__(self):
self.mac_list = []
#print get_ip_address(‘lo’)
#print get_ip_address(‘eth0’)
#print get_ip_address(‘eth1’)
#print get_ip_address(‘eth2’)
#print get_ip_address(‘bond0’)
def __del__(self):
pass
def Run(self):
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# Allow multiple sockets to use the same PORT number
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self_ip=” # Symbolic name meaning all available interfaces
recv_port = 67
f = file(‘mac_addr_list.csv’,’at+’)
f.seek(0, os.SEEK_END)
line_index = 0
s.bind((self_ip, recv_port))
s.setblocking(False)
msg_num = 0
print “等待数据中(按’z’键正常退出)。。。。”
while 1:
if msvcrt.kbhit():
ch = msvcrt.getch()
#print ch
if ch == ‘\x5A’ or ch == ‘\x7A’: # ‘Z’ or ‘z’
break;
time.sleep(0.001)
try:
data,src_sock_addr = s.recvfrom(8192)
dhcp_pkg = array.array(‘B’,data)
print “%s 在 %s发来 %u字节数据 :%s “%(src_sock_addr,time.ctime(),len(dhcp_pkg),dhcp_pkg)
msg_num += 1
print ‘########## No. %4u Start ##################################################’ % (msg_num)
print ‘DHCP Message: ‘
index = 0
print ‘ op[1 byte]: 0x%02x (1:request, 2:response)’ % (dhcp_pkg[index])
index += 1
print ‘ htype[1 byte]: 0x%02x (1:ethernet, …)’ % (dhcp_pkg[index])
index += 1
print ‘ hlen[1 byte]: 0x%02x ‘ % (dhcp_pkg[index])
index += 1
print ‘ hops[1 byte]: 0x%02x ‘ % (dhcp_pkg[index])
index += 1
print ‘ xid[4 byte]: 0x%08x ‘ % (toUint32(dhcp_pkg[index:]))
index += 4
print ‘ secs[2 byte]: 0x%04x ‘ % (toUint16(dhcp_pkg[index:]))
index += 2
print ‘ flags[2 byte]: 0x%04x (0: unicast, non-0: broadcast)’ % (toUint16(dhcp_pkg[index:]))
index += 2
print ‘ ciaddr[4 byte]: 0x%08x ‘ % (toUint32(dhcp_pkg[index:]))
index += 4
print ‘ yiaddr[4 byte]: 0x%08x ‘ % (toUint32(dhcp_pkg[index:]))
index += 4
print ‘ siaddr[4 byte]: 0x%08x ‘ % (toUint32(dhcp_pkg[index:]))
index += 4
print ‘ giaddr[4 byte]: 0x%08x ‘ % (toUint32(dhcp_pkg[index:]))
index += 4
print ‘ chaddr[16 byte] HEX (MAC address): %02x’ % (dhcp_pkg[index]),
for i in range(1, 16):
print ‘%02x’ % (dhcp_pkg[index+i]),
print ”
mac_addr = array.array(‘B’)
for i in range(0, 16):
mac_addr.append(dhcp_pkg[index+i])
index = 0
for mac in self.mac_list:
if mac == mac_addr:
break
index += 1
if index == len(self.mac_list):
self.mac_list += [ mac_addr]
line = ‘%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x’ % \
(mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5],mac_addr[6],mac_addr[7],
mac_addr[8],mac_addr[9],mac_addr[10],mac_addr[11],mac_addr[12],mac_addr[13],mac_addr[14],mac_addr[15])
line = ‘%u,%s,’ % (line_index+1, line)
line_index += 1
print ‘WRITE to file: ‘ + line
f.write(line+’\n’)
f.flush()
index += 16
print ‘ sname[64 byte] HEX: %02x’ % (dhcp_pkg[index]),
for i in range(1, 64):
print ‘%02x’ % (dhcp_pkg[index+i]),
print ”
print ‘ { sname[64 byte] STR: %s }’ % (struct.unpack(“64s”,dhcp_pkg[index:index+64]))
index += 64
print ‘ file[128 byte] HEX: %02x ‘ % (dhcp_pkg[index]),
for i in range(1, 128):
print ‘%02x’ % (dhcp_pkg[index+i]),
print ”
print ‘ { file[128 byte] STR: %s }’ % (struct.unpack(“128s”,dhcp_pkg[index:index+128]))
index += 128
print ‘ options[64 byte] HEX: %02x ‘ % (dhcp_pkg[index]),
for i in range(1, 64):
print ‘%02x’ % (dhcp_pkg[index+i]),
print ”
print ‘ { options[64 byte] STR: %s }’ % (struct.unpack(“64s”,dhcp_pkg[index:index+64]))
index += 64
print ‘########## No. %4u End ####################################################’ % (msg_num)
except Exception,data:
#print traceback.print_exc()
continue
s.close()
f.close()
for index, mac in enumerate(self.mac_list):
print ‘No.%4u MAC : ‘ % (index),
for i in range(0,16):
print ‘%02x’ % (mac[i]),
line = ‘%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x’ % \
(mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],mac[6],mac[7],mac[8],mac[9],mac[10],mac[11],mac[12],mac[13],mac[14],mac[15])
print ‘ ( ‘ + line + ‘ )’
def toUint32(bytes):
uint32 = bytes[0]<<24
uint32 += bytes[1]<<16
uint32 += bytes[2]<<8
uint32 += bytes[3]
return uint32
def toUint16(bytes):
uint16 = bytes[0]<<8
uint16 += bytes[1]
return uint16
# Unix:
”’
def get_ip_address(ifname=”eth0″):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip = ”
try:
ip = socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack(‘256s’, ifname[:15])
)[20:24])
except Exception,data:
print traceback.print_exc()
return ip
”’
# Windows:
def get_ip_address():
ip = socket.gethostbyname(socket.gethostname())
return ip
def OutputHelp():
print ‘Get MAC address by PXE DHCP broadcast packet: ‘
print ‘Usage: ‘ + programName + ”
print ‘Example: ‘ + programName + ”
print ‘ ‘
if __name__ == ‘__main__’ :
programName = sys.argv[0]
if len(sys.argv) > 1:
OutputHelp()
sys.exit(0)
GetMacAddr = GetMacAddr_Class()
GetMacAddr.Run()
sys.exit()