Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!rutgers!mcnc!decvax.dec.com!ima!minya!jc From: jc@minya.UUCP (John Chambers) Newsgroups: comp.unix.wizards Subject: What is my Ethernet address? Keywords: Ethernet SunOS Message-ID: <432@minya.UUCP> Date: 1 Aug 90 04:05:59 GMT Lines: 104 [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