jc@minya.UUCP (John Chambers) (08/01/90)
[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
buck@siswat.UUCP (A. Lester Buck) (08/02/90)
In article <432@minya.UUCP>, jc@minya.UUCP (John Chambers) writes: > 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? :-) I hate to ruin your day, but there may not be any "one" Ethernet address on the card at this very instant. I have written an Ethernet driver, and the adapter I wrote for had its manufacturer supplied unique address in a PROM, but that was then loaded into a register on the Ethernet chip. Nothing prevents the software from putting any Ethernet address it wants into that register. I am not really familiar with the Sun, but I thought I read at one time that Suns could load whatever Ethernet address they wanted from /etc/ethers onto the adapter. So whatever answer you get at this instant may not be the hardware answer you really wanted. -- A. Lester Buck buck@siswat.lonestar.org ...!texbell!moray!siswat!buck
chris@mimsy.umd.edu (Chris Torek) (08/02/90)
There are several things to keep in mind here: a. There may be no Ethernet address, or more than one Ethernet address. b. The Ethernet addresses of two different interfaces may be the same. (This is perfectly normal on a Xerox NS packet forwarder, for instance.) c. There may be some network interfaces with no Ethernet addresses. d. The Ethernet address, if any, on any given interface may be changeable. In article <432@minya.UUCP> jc@minya.UUCP (John Chambers) writes: >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 Such a program could (given reasonable kernel support) handle all of the things noted above. Any kernel support devised (the obvious method is an ioctl on a socket; a better [my opinion] method would be an ioctl on the file descriptor resulting from an open of /dev/se0, e.g.]) should keep these in mind as well. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
gregt@sdl.monet.scs.com (gregt) (08/04/90)
In article <545@siswat.UUCP> buck@siswat.UUCP (A. Lester Buck) writes: In article <432@minya.UUCP>, jc@minya.UUCP (John Chambers) writes: > 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? :-) ... register. I am not really familiar with the Sun, but I thought I read at one time that Suns could load whatever Ethernet address they wanted from /etc/ethers onto the adapter. ... I not sure about that, but the way you read the address is by opening /dev/nit, and hitting it with a SIOCGIFADDR ioctl - ala int f; struct ifreq if; if ((f = open("/dev/nit", 0)) < 0) { perror("open()"); exit(1); } bzero(&if, sizeof(struct ifreq)); if.ifr_addr.sa_family = AF_NIT; strcpy(if.ifr_name, "ie0"); /* insert interface name here */ if (ioctl(f, NIOCBIND, &if) < 0) { perror("ioctl()"); exit(2); } if (ioctl(f, SIOCGIFADDR, &if) < 0) { perror("ioctl()"); exit(3); } The address is filled in if.ifr_addr.sa_data cheers, greg tusar (gregt@sdl.scs.com) -- A. Lester Buck buck@siswat.lonestar.org ...!texbell!moray!siswat!buck -- "Of all kinds of painting, figure painting is the most difficult; then comes landscape painting, and next dogs and horses." - Ku K'ai-Chih : gregt@sdl.scs.com // Gregory Tusar // Silicon Compiler Sys. // Warren, NJ