How to get the local mac address?

D

Daniel Crespo

Hi, I tried:

import ctypes
import socket
import struct

def get_macaddress(host):
""" Returns the MAC address of a network host, requires >= WIN2K.
"""

# Check for api availability
try:
SendARP = ctypes.windll.Iphlpapi.SendARP
except:
raise NotImplementedError('Usage only on Windows 2000 and
above')

# Doesn't work with loopbacks, but let's try and help.
if host == '127.0.0.1' or host.lower() == 'localhost':
host = socket.gethostname()

# gethostbyname blocks, so use it wisely.
try:
inetaddr = ctypes.windll.wsock32.inet_addr(host)
if inetaddr in (0, -1):
raise Exception
except:
hostip = socket.gethostbyname(host)
inetaddr = ctypes.windll.wsock32.inet_addr(hostip)

buffer = ctypes.c_buffer(6)
addlen = ctypes.c_ulong(ctypes.sizeof(buffer))
if SendARP(inetaddr, 0, ctypes.byref(buffer), ctypes.byref(addlen))
!= 0:
raise WindowsError('Retreival of mac address(%s) - failed' %
host)

# Convert binary data into a string.
macaddr = ''
for intval in struct.unpack('BBBBBB', buffer):
if intval > 15:
replacestr = '0x'
else:
replacestr = 'x'
macaddr = ''.join([macaddr, hex(intval).replace(replacestr,
'')])

return macaddr.upper()

if __name__ == '__main__':
print 'Your mac address is %s' % get_macaddress('localhost')

It works perfect under W2K and above. But I would like to run it on
Win98 too. Any help?

Thanks

Daniel
 
S

Scott David Daniels

Daniel said:
Hi, I tried: ...
# Convert binary data into a string.
macaddr = ''
for intval in struct.unpack('BBBBBB', buffer):
if intval > 15:
replacestr = '0x'
else:
replacestr = 'x'
macaddr = ''.join([macaddr, hex(intval).replace(replacestr, '')])

Replace the above by:
return '%02X' * 6 % struct.unpack('BBBBBB', buffer)

(doesn't help with win98, though)
 
D

Daniel Crespo

Hi, Scott,

Thanks for your answer
Hi, I tried: ...
# Convert binary data into a string.
macaddr = ''
for intval in struct.unpack('BBBBBB', buffer):
if intval > 15:
replacestr = '0x'
else:
replacestr = 'x'
macaddr = ''.join([macaddr, hex(intval).replace(replacestr, '')])


Replace the above by:
return '%02X' * 6 % struct.unpack('BBBBBB', buffer)

Replace all the above? I mean all this:

# Convert binary data into a string.
macaddr = ''
for intval in struct.unpack('BBBBBB', buffer):
if intval > 15:
replacestr = '0x'
else:
replacestr = 'x'
macaddr = ''.join([macaddr, hex(intval).replace(replacestr,
'')])

?
(doesn't help with win98, though)

Sorry, but I don't understand... I would like it to get running on
Win98. I know I have to change some code here, but don't know what :(
 
B

bonono

Daniel said:
Hi, I tried:

import ctypes
import socket
import struct

def get_macaddress(host):
""" Returns the MAC address of a network host, requires >= WIN2K.
"""

# Check for api availability
try:
SendARP = ctypes.windll.Iphlpapi.SendARP
except:
raise NotImplementedError('Usage only on Windows 2000 and
above')

# Doesn't work with loopbacks, but let's try and help.
if host == '127.0.0.1' or host.lower() == 'localhost':
host = socket.gethostname()

# gethostbyname blocks, so use it wisely.
try:
inetaddr = ctypes.windll.wsock32.inet_addr(host)
if inetaddr in (0, -1):
raise Exception
except:
hostip = socket.gethostbyname(host)
inetaddr = ctypes.windll.wsock32.inet_addr(hostip)

buffer = ctypes.c_buffer(6)
addlen = ctypes.c_ulong(ctypes.sizeof(buffer))
if SendARP(inetaddr, 0, ctypes.byref(buffer), ctypes.byref(addlen))
!= 0:
raise WindowsError('Retreival of mac address(%s) - failed' %
host)

# Convert binary data into a string.
macaddr = ''
for intval in struct.unpack('BBBBBB', buffer):
if intval > 15:
replacestr = '0x'
else:
replacestr = 'x'
macaddr = ''.join([macaddr, hex(intval).replace(replacestr,
'')])

return macaddr.upper()

if __name__ == '__main__':
print 'Your mac address is %s' % get_macaddress('localhost')

It works perfect under W2K and above. But I would like to run it on
Win98 too. Any help?
Sorry that I can't help you in any way but have a question myself. Is
there an OS independent way to get this thing(regardless of how to
format it) in Python ? I know this may not matter if all you want is
Windows but there is just another thread talking about one should write
programs that is OS independent.

Is this a problem of the network library of python ?
 
F

Frank Millman

Sorry that I can't help you in any way but have a question myself. Is
there an OS independent way to get this thing(regardless of how to
format it) in Python ? I know this may not matter if all you want is
Windows but there is just another thread talking about one should write
programs that is OS independent.

Is this a problem of the network library of python ?

This is not a generic solution, but it works for me on Linux and
Windows

def getMacAddress():
if sys.platform == 'win32':
for line in os.popen("ipconfig /all"):
if line.lstrip().startswith('Physical Address'):
mac = line.split(':')[1].strip().replace('-',':')
break
else:
for line in os.popen("/sbin/ifconfig"):
if line.find('Ether') > -1:
mac = line.split()[4]
break
return mac

HTH

Frank Millman
 
B

bonono

Frank said:
Sorry that I can't help you in any way but have a question myself. Is
there an OS independent way to get this thing(regardless of how to
format it) in Python ? I know this may not matter if all you want is
Windows but there is just another thread talking about one should write
programs that is OS independent.

Is this a problem of the network library of python ?

This is not a generic solution, but it works for me on Linux and
Windows

def getMacAddress():
if sys.platform == 'win32':
for line in os.popen("ipconfig /all"):
if line.lstrip().startswith('Physical Address'):
mac = line.split(':')[1].strip().replace('-',':')
break
else:
for line in os.popen("/sbin/ifconfig"):
if line.find('Ether') > -1:
mac = line.split()[4]
break
return mac
Thanks, but how can I associate the result to the socket, assuming that
is the reason for wanting to get at the MAC ?

I see that some *nix implementation use fcntl/ioctl to read this info
out of the file handle of a socket but these modules don't exist on
Windows(may be some other platform as well).
 
S

Steve Holden

Frank said:
Sorry that I can't help you in any way but have a question myself. Is
there an OS independent way to get this thing(regardless of how to
format it) in Python ? I know this may not matter if all you want is
Windows but there is just another thread talking about one should write
programs that is OS independent.

Is this a problem of the network library of python ?

This is not a generic solution, but it works for me on Linux and
Windows

def getMacAddress():
if sys.platform == 'win32':
for line in os.popen("ipconfig /all"):
if line.lstrip().startswith('Physical Address'):
mac = line.split(':')[1].strip().replace('-',':')
break
else:
for line in os.popen("/sbin/ifconfig"):
if line.find('Ether') > -1:
mac = line.split()[4]
break
return mac

Thanks, but how can I associate the result to the socket, assuming that
is the reason for wanting to get at the MAC ?
Why should you want to associate a MAC address with a socket? Each
interface has an IP address, and it's that you should be using.
I see that some *nix implementation use fcntl/ioctl to read this info
out of the file handle of a socket but these modules don't exist on
Windows(may be some other platform as well).
Indeed, and that's why most networkers probably wouldn't regard this as
a deficiency in Python's network handling but an inevitable consequence
of the diversity of architectures, utilities and drivers in today's world.

It may well be possible to write Python code that will run on all
platforms (for example, the same way as the os.path module does, by
importing the correct piece of code according to the platform), but it
would need maintenance. Since the interface MAC address is unimportant
for most network applications I guess nobody has so far thought it worth
contributing to the core.

regards
Steve
 
F

Frank Millman

Frank said:
Sorry that I can't help you in any way but have a question myself. Is
there an OS independent way to get this thing(regardless of how to
format it) in Python ? I know this may not matter if all you want is
Windows but there is just another thread talking about one should write
programs that is OS independent.

Is this a problem of the network library of python ?

This is not a generic solution, but it works for me on Linux and
Windows

def getMacAddress():
if sys.platform == 'win32':
for line in os.popen("ipconfig /all"):
if line.lstrip().startswith('Physical Address'):
mac = line.split(':')[1].strip().replace('-',':')
break
else:
for line in os.popen("/sbin/ifconfig"):
if line.find('Ether') > -1:
mac = line.split()[4]
break
return mac
Thanks, but how can I associate the result to the socket, assuming that
is the reason for wanting to get at the MAC ?

I see that some *nix implementation use fcntl/ioctl to read this info
out of the file handle of a socket but these modules don't exist on
Windows(may be some other platform as well).

As you can see, this is a quick and dirty solution.

I am sure you can hack at it some more, bring up the associated ip
address, and compare it with socket.gethostbyaddr() or similar.

I don't know of a more correct solution - maybe someone else can advise
better.

BTW I recall a response some time ago warning that you cannot rely on a
mac address, as they can be modified. Depending on your intended use,
this may or may not be important.

Sorry I cannot be of more help

Frank
 
B

bonono

Steve said:
Why should you want to associate a MAC address with a socket? Each
interface has an IP address, and it's that you should be using.
Say for example I want to find out the MAC if a particular interface in
python.
It may well be possible to write Python code that will run on all
platforms (for example, the same way as the os.path module does, by
importing the correct piece of code according to the platform), but it
would need maintenance. Since the interface MAC address is unimportant
for most network applications I guess nobody has so far thought it worth
contributing to the core.
That is a reasonable explanation.
 
S

Steve Holden

Say for example I want to find out the MAC if a particular interface in
python.
When you are asked "why would you want to do something" it isn't
normally considered sufficient to reply "suppose I want to do
something". I'm still trying to find out what use case (apart from
curiosity) drives this need to know.

regards
Steve
 
B

bonono

Steve said:
When you are asked "why would you want to do something" it isn't
normally considered sufficient to reply "suppose I want to do
something". I'm still trying to find out what use case (apart from
curiosity) drives this need to know.
That is nothing but curiosity of why there is no such thing. I didn't
start a thread with "what the xyz@!% hell that I cannot get MAC address
through the socket module".

And I answer things the way I want to, if it does fit your expected
answer, there is nothing I can do. I am not here to convince you.
 
S

Steve Holden

That is nothing but curiosity of why there is no such thing. I didn't
start a thread with "what the xyz@!% hell that I cannot get MAC address
through the socket module".

And I answer things the way I want to, if it does fit your expected
answer, there is nothing I can do. I am not here to convince you.
Temper, temper.

regards
Steve
 
S

Steve Holden

you can read my temper from what I write ?
Nope, but I can make inferences, whose correctness you can choose to lie
or tell the truth about. I was merely trying to make the point that your
response failed to further anybody's understanding of anything. I'm not
really bothered *why* you do what you do.

I asked "Why should you want to associate a MAC address with a socket?"
and you replied "Say for example I want to find out the MAC if a
particular interface in python". Fine. But if you don't want to engage
in a dialogue, why bother posting at all?

regards
Steve
 
B

bonono

Steve said:
Nope, but I can make inferences, whose correctness you can choose to lie
or tell the truth about. I was merely trying to make the point that your
response failed to further anybody's understanding of anything. I'm not
really bothered *why* you do what you do.
That is nice try. I said I am not, you can fit it as "I am lying". As
for failed or not failed, I don't know what anybody want to get out of
it. I just curious why there is no such function in the socket model,
when I saw a "OS dependent" implementation of getting MAC. Nothing
more. And your answer that there is not sufficient need for putting it
in the standard libary(for the maintainance work needed), answered my
puzzle.
I asked "Why should you want to associate a MAC address with a socket?"
and you replied "Say for example I want to find out the MAC if a
particular interface in python". Fine. But if you don't want to engage
in a dialogue, why bother posting at all?
Huh ? You ask why, I come up with an example. I said it all started
with curiosity, not out of need. I don't see why it is not a dialogue.
You think that it is not because it doesn't meet your expectation
answer(thus your "you are supposed" response), that I can do nothing as
that is your right or thought.
 
S

Steve Holden

That is nice try. I said I am not, you can fit it as "I am lying". As
for failed or not failed, I don't know what anybody want to get out of
it. I just curious why there is no such function in the socket model,
when I saw a "OS dependent" implementation of getting MAC. Nothing
more. And your answer that there is not sufficient need for putting it
in the standard libary(for the maintainance work needed), answered my
puzzle.



Huh ? You ask why, I come up with an example. I said it all started
with curiosity, not out of need. I don't see why it is not a dialogue.
You think that it is not because it doesn't meet your expectation
answer(thus your "you are supposed" response), that I can do nothing as
that is your right or thought.
I'm probably just not reading your responses carefully enough.

regards
Steve
 
B

bonono

Steve said:
I'm probably just not reading your responses carefully enough.
That is fine, misunderstanding happens all the time. And why I am
curious that there is no such thing in Python, it is because of this :

http://search.cpan.org/~lds/IO-Interface-0.98/Interface.pm

I am learning python and from time to time, I would come up with
ideas(yup, nothing but ideas as an excercise) of how to implement
certain thing in python, most of them have no usage value. The OP just
prompt me to the idea of "what if I want to implement something like
ifconfig in python".
 
J

Jorge Godoy

Steve Holden said:
When you are asked "why would you want to do something" it isn't normally
considered sufficient to reply "suppose I want to do something". I'm still
trying to find out what use case (apart from curiosity) drives this need to
know.

One thing that I've seen more than once is restricting the use of the software
to one machine. There you can use the MAC address as an item of assurance
that you're on the authorized machine.

Of course, MAC addresses can be cloned, changed, etc. But this is one use
case for knowing the MAC address and not using it with networking.
 
G

Grant Edwards

That is nothing but curiosity of why there is no such thing. I
didn't start a thread with "what the xyz@!% hell that I cannot
get MAC address through the socket module".

And I answer things the way I want to, if it does fit your
expected answer, there is nothing I can do. I am not here to
convince you.

Taking an attitude like that towards one of the most respected
people in the Python community is bound to be rather counter
productive.

Nobody owes you any answers, so yes, in fact, you _are_ here to
convince people that you deserve their help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top