What is my Ethernet address?

John Chambers jc at minya.UUCP
Wed Aug 1 14:05:59 AEST 1990


[Well, I tried posting this to comp.sys.sun, but my active file says
that's now moderated, and attempts to find a moderator failed, so I
guess I oughta ask elsewhere.  Maybe the wizards will know.  ;-]

A couple days ago, after quite a few months of inquiring of anyone who
might know, I finally got handed an interesting piece of code which, on
an Ultrix system, determined the true Ethernet address of an interface.
A big of grepping turned up the fact that it was indeed not documented
anywhere in the manuals.  But the secret is now out, and I know how to
do it.

A couple more hours of digging turned up a different, equally effective,
and (wonders!) documented way to do the job on an HP 9000 system (hp-ux).

That's the good news.  Now, lest y'all think I'm just bragging...

A few hours of grepping through several varieties of Sun workstation was
a total, dismal failure.  The keywords that worked on the Ultrix and
HP systems didn't exist in the Sun manuals, and following the SEE ALSOs
turned up nothing but dead ends.  Grepping around in /usr/include/* was
also a waste of time.  If the answer was there, it didn't bite me.

So, does anyone out there know if there is a way that a user process
running on SunOS can determine the actual Ethernet address of an interface?
Is it actually documented somewhere that I should have looked but didn't?
Or is it perhaps there under some clever name that I can't guess?

Note that I'm not interested in answers of the form "Look in /etc/ethers".  
This is not a correct answer to the question.  For one example, consider 
that I'm writing an installation routine whose job is to build /etc/ethers.  
For another example, consider that the machine has been taken down for some 
servicing, and the Ethernet card was swapped for a new one which naturally
has a different address than the old card.  The machine has been booted, 
and my program must detect the fact that /etc/ethers is incorrect and needs 
updating.  No, I don't want a human to spend hours diagnosing the problem 
and correcting it by hand; I want to correct it automatically from rc.local,
regardless of how unconventional such an approach might be.

The only correct answer is one that gives the Ethernet address that is
on the card at this very instant, not one that "should" be there according
to some file or server which should (but may not) be correct.  I'm trying 
to determine whether those files and servers are correct; I can't very well 
ask them whether they're lying to me.  (Well, maybe I can; what does the
request packet look like? :-)

It is easy to prove that the information is available to the software.
Just boot the machine, and you will see the Ethernet address appear on
the screen.  Those pixels didn't get changed by magic; they were written
by some software that knows how to get the Ethernet address.  Now if I
could only figure out how to write a routine that does a reboot and reads
the address off the screen, without bothering other processes, of course...

In any case, I strongly suspect that the 6 bytes are at some reasonably
fixed location within /dev/kmem, but there are lots of bytes there, and
it's not obvious where to look.  Not that I have any qualms about mucking
about in /dev/kmem, y'know, though it is sorta like opening a jar of jam
with dynamite.  But if they won't tell you the "right" way to do it, you
do it however you can.  For instance, I get the netmask and broadcast
address out of /dev/kmem.  Yeah, I know there's an ioctl to do it.  But
for some inexplicable reason, you have to be a super-user for it to work,
and I don't like filling the disk with gratuitously setuid-root programs.
You don't have to be a super-user to read /dev/kmem, only setgid-kmem,
so I do it that way.  Sigh.

BTW, this is not really just a SunOS question.  I'd also like to find out
how it's done on other Unix systems.  I'm aiming at a program that shows
behavior like:
	% addr -e se0
	08:5A:00:6C:04:FC
	% addr -i se0
	16.121.0.95
	% addr -e se1
	08:5A:00:72:49:7B
	% addr -i se1
	16.20.32.95
	% addr -i sl0
	19.56.2.31
	% addr -b se0
	16.121.15.255
	% addr -m se1
	255.255.240.0
and so on.  It'd be real handy during installation of lots of packages.  
Thus a SLIP or PPP package would really like to be an arp server, for 
which you need to do an "arp -s" command, and it requires your Ethernet 
address on the command line.  With the above command, my startup script
could do something like:
	arp -s `addr -i sl0` `addr -e ie0`
with appropriate variables for the interface names, of course.

I suspect that the addr program will contain lots of #ifdefs.  Any idea 
how a user process gets an Ethernet address on your favorite Unix?

[It constantly amazes me that something needed so often is so difficult 
to determine.  What were those people thinking of (or smoking ;-) when 
they built the software?]

[And don't those folks at HP know that they're violating a long tradition
by telling users how to get at the network addresses? :-]

-- 
Zippy-Says: I was there when ELMER FUDD met HAMLET on the MOON.
Uucp: ...!{harvard.edu,ima.com,eddie.mit.edu,ora.com}!minya!jc (John Chambers)
Home: 1-617-484-6393
Work: 1-508-952-3274



More information about the Comp.unix.wizards mailing list