I wrote a module that has a variety of ways to get a MAC address on different platorms, it may be useful:
import sys import os def rawtohex(raw): """converts a raw mac address to hex""" return ":".join(["%02X" % (ord(ch),) for ch in raw]) def getmacs_netbios(): """uses netbios to find mac addresses""" # code ported from "HOWTO: Get the MAC Address for an Ethernet Adapter" # MS KB ID: Q118623 import netbios ncb = netbios.NCB() ncb.Command = netbios.NCBENUM la_enum = netbios.LANA_ENUM() ncb.Buffer = la_enum rc = netbios.Netbios(ncb) if rc != 0: raise RuntimeError, "Unexpected result %d" % (rc,) for i in range(la_enum.length): ncb.Reset() ncb.Command = netbios.NCBRESET ncb.Lana_num = ord(la_enum.lana[i]) rc = netbios.Netbios(ncb) if rc != 0: raise RuntimeError, "Unexpected result %d" % (rc,) ncb.Reset() ncb.Command = netbios.NCBASTAT ncb.Lana_num = ord(la_enum.lana[i]) ncb.Callname = "* " adapter = netbios.ADAPTER_STATUS() ncb.Buffer = adapter netbios.Netbios(ncb) address = rawtohex(adapter.adapter_address) yield address def getmacs_wmi(): """uses wmi interface to find mac addresses""" # this uses wmi from http://tgolden.sc.sabren.com/python/wmi.html # its from the example at http://tgolden.sc.sabren.com/python/wmi_cookbook.html#ip_addresses import wmi c = wmi.WMI () for interface in c.Win32_NetworkAdapterConfiguration (IPEnabled=1): hasip = False for ipaddress in interface.IPAddress: if ipaddress: hasip = True if hasip: yield interface.MACAddress def getmacs_ifconfig(): """parses the output of unix ifconfig to find mac addresses""" lines = os.popen("ifconfig", "r").readlines() headerlines = [line for line in lines if line and not line[:1].isspace()] for line in headerlines: parts = line.split() ifname = parts[0] if 'HWaddr' in parts: hwpart = parts.index('HWaddr') if hwpart+1 < len(parts): mac = parts[hwpart+1] yield mac def getmacs_ipconfig(): """parses the output of windows ipconfig to find MAC addresses""" lines = os.popen("ipconfig /all", "r").readlines() for line in lines: if line and not line[:1].isspace(): header = line ipaddress, mac = None, None elif line.strip(): if line.strip().startswith("IP Address") and ":" in line: ipaddress = line.split(":", 1)[1].strip() if mac: yield mac ipaddress, mac = None, None if line.strip().startswith("Physical Address") and ":" in line: mac = line.split(":", 1)[1].strip() if ipaddress: yield mac ipaddress, mac = None, None def getmacs_winarp(): """parses the output of windows arp to find MAC addresses""" lines = os.popen("arp -a", "r").readlines() for line in lines: if line.startswith("Interface"): header = line ipaddress, mac = None, None elif line.strip().startswith("Internet Address"): pass elif line.strip(): ipaddress, mac = line.strip().split()[:2] yield mac def ipaddr2mac_winarp(ipaddr): """uses SendARP and ctypes to convert an IP Address to an ethernet address""" # see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/347812 import ctypes try: SendARP = ctypes.windll.Iphlpapi.SendARP except: raise NotImplementedError('Usage only on Windows 2000 and above') import struct ip = ipaddr if isinstance(ip, (str, unicode)): ip = [int(i) for i in ip.split(".")] ip = struct.pack("BBBB", *ip) ip = struct.unpack("l", ip)[0] buffer = ctypes.c_buffer(6) addlen = ctypes.c_ulong(ctypes.sizeof(buffer)) if SendARP(ip, 0, ctypes.byref(buffer), ctypes.byref(addlen)) != 0: raise WindowsError('Retrieval of mac address(%s) - failed' % ipaddr) macaddr = rawtohex(struct.unpack('6s', buffer)[0]) return macaddr def getethdevs_ifconfig(): """parses the output of ifconfig to get a list of ethernet devices""" lines = os.popen("ifconfig", "r").readlines() headerlines = [line for line in lines if line and not line[:1].isspace()] for line in headerlines: parts = line.split() ifname = parts[0] yield ifname def getethdevs_proc(): """looks at /proc/net/dev to get a list of ethernet devices""" lines = open("/proc/net/dev").readlines() for line in lines: if ":" in line: ethdev = line.split(":", 1)[0].strip() yield ethdev getethdevs = getethdevs_proc def getmac_socket(ethdev): """returns the mac address by opening a socket on the given device. requires right permissions""" import socket s = socket.socket(socket.AF_PACKET,socket.SOCK_RAW) s.bind((ethdev,9999)) rawmac = s.getsockname()[-1] return rawtohex(rawmac) def getmacs_socket(): """returns the mac address by opening a socket on the devices found by getethdevs. requires right permissions""" for ethdev in getethdevs(): mac = getmac_socket(ethdev) if mac: yield mac def getmac_ioctl(ethdev): """returns the mac address by using ioctl calls on a socket""" # http://groups-beta.google.com/group/comp.lang.python/search?q=fcntl+socket+ifconfig # look at http://www.webservertalk.com/message891078.html for some C code import fcntl import struct import socket ifrn_name = ethdev ifru_addr_family = socket.AF_INET ifru_addr_data = "" ifr = struct.pack("16sH14s", ifrn_name, ifru_addr_family, "") SIOCGIFADDR = 0x8915 SIOCGIFHWADDR = 0x8927 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sfd = s.fileno() # get the IP address try: ifr_result = fcntl.ioctl(sfd, SIOCGIFADDR, ifr) ipaddr = struct.unpack("16sHH4B8s", ifr_result)[3:7] ipaddr = ".".join([str(d) for d in ipaddr]) except IOError: ipaddr = None # get the ethernet address try: ifr_result = fcntl.ioctl(sfd, SIOCGIFHWADDR, ifr) ethaddr = struct.unpack("16sH6s8s", ifr_result)[2] if sum([ord(c) for c in ethaddr]) == 0: return None ethaddr = rawtohex(ethaddr) except IOError: ethaddr = None return ethaddr def getmacs_ioctl(): """returns the mac address by opening a socket on the devices found by getethdevs. requires right permissions""" for ethdev in getethdevs(): mac = getmac_ioctl(ethdev) if mac: yield mac def getmacs(): if sys.platform == 'linux2': return getmacs_ioctl() elif sys.platform == 'win32': return getmacs_winarp() if __name__ == "__main__": for address in getmacs(): print address le dahut wrote: >Thanks for your advice. A colleague told me how to get those >informations. First install WMI on the 95/98 station, then write the >program and compile it with py2exe, then it should work on every 95/98 >station (also where WMI is NOT installed !). > >Note that 'ipconfig' is available on win98 so a >os.popen('ipconfig /all') can be parsed to get infos. > > >K. > >Le vendredi 09 septembre 2005 à 10:44 -0700, Tim Roberts a écrit : > > >>On Fri, 09 Sep 2005 09:42:18 +0200, le dahut <[EMAIL PROTECTED]> wrote: >> >> >> >>>Maybe I can parse the output of a 'ipfonfig' command, >>> >>> >>> >>Nope, that won't work. Ipconfig is NT-only. 95 and 98 have winipcfg, >>but it is a GUI tool, not a command-line tool. >> >> >> >>>but commands.getoutput only work with unix, not with windows. Is there >>>another way to get the output of a command line program under windows ? >>> >>> >>> >>The usual way is to use os.popen, which works everywhere. However, as I >>said, that won't help you with this information. >> >>In fact, it is surprisingly difficult to get information about the >>network interfaces on a 95/98 machine. Have you tried the downloadable >>WMI support mentioned earlier? >> _______________________________________________ Python-win32 mailing list Python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32