[comp.sys.sgi] How do you determine Ethernet #?

porter@caip.rutgers.edu (Adam Porter) (09/28/90)

Is there a way to determine the Ethernet number of a Personal Iris?

Thanks...
-- 
Adam Porter: Assistant SysAdmin, NEC Research Institute, Princeton NJ
adam@research.nec.com   {...}!princeton!necserve!adam        C:\> alp

rpw3@rigden.wpd.sgi.com (Rob Warnock) (09/30/90)

In article <Sep.28.12.11.34.1990.21193@caip.rutgers.edu>
porter@caip.rutgers.edu (Adam Porter) writes:
+---------------
| Is there a way to determine the Ethernet number of a Personal Iris?
+---------------

I've posted this before, but here it is again. This doesn't depend on being
run on a PI, per se, but it does depend on SGI's particular version of "raw"
sockets. A similar thing can be written for most other machines which provide
some sort of raw socket access to the network link layer.

On machines with more than one network interface, it only shows the MAC address
of the "primary" interface, the one that was "ifconfig"d first at boot time.
(If you like, add code to set the variable "interface" from a command-line
option.)

Due to the use of "raw" sockets, it must be run as root or be setuid root.


-Rob

[p.s. MAC addresses of other nodes on the same network can be shown by first
"ping"ing the hosts and then typing "arp -a" to see the cached MAC addresses.]

-----
Rob Warnock, MS-9U/510		rpw3@sgi.com		rpw3@pei.com
Silicon Graphics, Inc.		(415)335-1673		Protocol Engines, Inc.
2011 N. Shoreline Blvd.
Mountain View, CA  94039-7311

============== attachment: macaddr.c ==========================
/*
 * macaddr.c - show Ethernet address of primary interface
 *
 * 900716 rpw3@sgi.com
 */

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>
#include <net/raw.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>

char	*ether_aton();

char	*interface;		/* change for other than default interface */
char	*my_etheraddr;		/* result */

main()
{
	static struct sockaddr_raw sr;	/* static, so "interface" lives on */
	static struct ifreq ifreq;	/* static, so "my_etheraddr" lives on */
	int s, n;

        s = socket(AF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
        if (s < 0) {
                perror("socket");
                exit(errno);
        }
	/*
	 * A raw bind() can be done without knowing the interface name,
	 * but we can't do the raw getsockname() without the bind(). So
	 * we do the bind() first, with a null interface name if needed.
	 */
        sr.sr_family = AF_RAW;
        sr.sr_port = 0;
        if (interface)
                (void) strncpy(sr.sr_ifname, interface, sizeof sr.sr_ifname);
        else
		bzero(sr.sr_ifname, sizeof sr.sr_ifname);
        if (bind(s, &sr, sizeof sr) < 0) {
                perror("bind");
                exit(errno);
        }
	/*
	 * Now get the "sockname", which for a raw socket is the interface
	 * name: "lo0", "ec0", "ipg0", or some such.
	 */
        if (interface == 0) {
                n = sizeof sr;
                if (getsockname(s, (struct sockaddr *)&sr, &n) < 0) {
                        perror("getsockname");
                        exit(errno);
                }
                interface = sr.sr_ifname;
		printf("primary interface = '%s'\n", interface);
        }

	/*
	 * Now get the "sockname", which for a raw socket is our link-level
	 * (Ethernet or FDDI or other MAC-level) address. Store a pointer to
	 * this in "my_etheraddr" for later inclusion in transmitted packets.
	 */
	ifreq.ifr_addr.sa_family = AF_RAW;
        (void) strncpy(ifreq.ifr_name, interface, sizeof ifreq.ifr_name);
	if (ioctl(s, SIOCGIFADDR, &ifreq) < 0) {
		/* XXX - use better error handler */
		perror("couldn't SIOCGIFADDR");
                exit(errno);
	}
	my_etheraddr = &ifreq.ifr_addr.sa_data[0];
	printf("MAC-level address of '%s' = %s\n",
		interface,
		ether_ntoa(my_etheraddr));

	exit(0);
}

vjs@rhyolite.wpd.sgi.com (Vernon Schryver) (10/01/90)

The quickest hack to find target's ethernet address is to
`/usr/etc/ping -c 5 target; /usr/etc/arp target`.

Many uses of the Ethernet MAC address are for "software node locking."
This is a grievious misuse, because the Ethernet address can change
when the ethernet board is replaced in systems where the ethernet
board is separate, including MP systems where the ethernet is on the
IO[23].  There is also an ioctl() that changes the ethernet address,
making such ethernet address "node locking" kind of loose.

Sysinfo(1) and sysid(2) describe how to obtain a better number.


Vernon Schryver,    vjs@sgi.com

mberger@RELAY.NSWC.NAVY.MIL (10/01/90)

The 'eaddr' command can be issued from the prom monitor.

I've also heard that 'arp' will work in multi-user but have not tried it.