ip2hwaddr

ip2hwaddr

Post by jako.. » Thu, 05 Oct 2006 04:51:19



Hi.
I need a real safe way of mapping an ip to hwaddr. I thought I had it
working with a function I wrote that uses arp to resolve the hwaddr,
but sadly enough it only works on remote hosts. I have thought about
parsing the output of ifconfig, but it isn't "safe" in the long run
since I can't be sure if the command will keep on outputing the same
way.

I don't mind splitting up the ip2hwaddr function in a remote and a
local part.

Can I map the ip address safely, and how (/proc maybe, but where?) ?

 
 
 

ip2hwaddr

Post by Ken Robert » Thu, 05 Oct 2006 05:14:49


For parsing ifconfig, you need not worry about the format of the
output, especially since it varies somewhat from distro to distro.

You need a regular expression and a script, maybe in perl.  One regex
for a valid IP address, and one for a valid HW address.

Even so, you need to be careful about virtual interfaces, such as
127.0.0.1, which has no hardware address.


> Hi.
> I need a real safe way of mapping an ip to hwaddr. I thought I had it
> working with a function I wrote that uses arp to resolve the hwaddr,
> but sadly enough it only works on remote hosts. I have thought about
> parsing the output of ifconfig, but it isn't "safe" in the long run
> since I can't be sure if the command will keep on outputing the same
> way.

> I don't mind splitting up the ip2hwaddr function in a remote and a
> local part.

> Can I map the ip address safely, and how (/proc maybe, but where?) ?


 
 
 

ip2hwaddr

Post by Ken Robert » Thu, 05 Oct 2006 05:23:52



> For parsing ifconfig, you need not worry about the format of the
> output, especially since it varies somewhat from distro to distro.

> You need a regular expression and a script, maybe in perl.  One regex
> for a valid IP address, and one for a valid HW address.

> Even so, you need to be careful about virtual interfaces, such as
> 127.0.0.1, which has no hardware address.

Sorry, I neglected to finish before I posted.

One thing that's consistent across all platforms I think is that the
interface name is left justified, and the rest is indented.  I think
you can also rely on an empty record separator.  If you match in pairs
in an array, and increment the index when you see either a blank or an
untabbed entry, that would match no matter what order.

 
 
 

ip2hwaddr

Post by jako.. » Thu, 05 Oct 2006 05:29:33


Ken Roberts skrev:


> > For parsing ifconfig, you need not worry about the format of the
> > output, especially since it varies somewhat from distro to distro.

> > You need a regular expression and a script, maybe in perl.  One regex
> > for a valid IP address, and one for a valid HW address.

> > Even so, you need to be careful about virtual interfaces, such as
> > 127.0.0.1, which has no hardware address.

> Sorry, I neglected to finish before I posted.

> One thing that's consistent across all platforms I think is that the
> interface name is left justified, and the rest is indented.  I think
> you can also rely on an empty record separator.  If you match in pairs
> in an array, and increment the index when you see either a blank or an
> untabbed entry, that would match no matter what order.

OK thanks Ken. I have done this in python already :) here is the
function for other who might be interested

def ip2hwaddr(ip):
        try:
                arp = open('/proc/net/arp')
                lines = arp.readlines()
                arp.close()
                c=re.compile('^(\S+)\s+\S+\s+\S+\s+(\S+)')
                for l in lines[1:]:
                        m=c.match(l)
                        if m and m.groups()[0]==ip:
                                return m.groups()[1]
        except:
                pass
        try:
                rx_newif=re.compile('^(\w+)')
                rx_hwaddr=re.compile('^(\w+).+([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})')
                rx_inet_addr=re.compile('^.+inet
addr:(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})')
                o = os.popen('ifconfig')
                out = o.readlines()
                o.close()

                ip_maps = {}
                cur_if = None
                cur_hwaddr = None
                for l in out:
                        m = rx_newif.match(l)
                        if m:
                                cur_hwaddr = None
                        m = rx_hwaddr.match(l)
                        if m:
                                cur_if = m.groups()[0]
                                cur_hwaddr = m.groups()[1]
                        m = rx_inet_addr.match(l)
                        if m and cur_hwaddr:
                                ip_maps[m.groups()[0]] = cur_hwaddr

                if ip_maps.has_key(ip.strip()):
                        return ip_maps[ip.strip()]

        except:
                pass
        return None

 
 
 

ip2hwaddr

Post by Ken Robert » Thu, 05 Oct 2006 07:52:38



> rx_hwaddr=re.compile('^(\w+).+([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})')
>            rx_inet_addr=re.compile('^.+inet
> addr:(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})')

rx_hwaddr=re.compile('^(\w+).+([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})')
rx_inet_addr=re.compile('^.+inet
addr:(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})')

I think I'd avoid anchoring to anything here.  You want your mac
address to be a definitive mac address, which means that the characters
on either side are NOT acceptable to be a mac address, meaning they're
whitespace or similar, or an end of line.  Also, the inet address is
anchored to the front of the line, which it isn't guaranteed to do.
You have "^.+inet addr" but maybe \<inet addr:?\s*(\d{1,3}... would
work better?

Forgive my regular expressions, I haven't worked in Python ever, and
haven't worked perl in a long while.  My regex syntax is probably mixed
in a little with how it works in vim.  My point is, to take the
absolute minimum hardware address and the absolute minimum inet
address, and only look at those.