get physical address of if_ether (SunOS)

Kha Sin Teow khasin at canstar.UUCP
Fri May 4 07:24:01 AEST 1990


I need to somehow extract the physical addresses of all ethernet interfaces
on a Sun 3 and 4 (SunOS4.0.3).
I wrote a C program to dive into the kernel and peek at the
ie_softc structure.
The structure contains an arpcom structure which in turn contains an
ethernet address structure.
Bingo! I thought I solved the problem.
When i tried the program with our Sun4 which has two ethernet
interfaces (ie0 and ie1), both ethernet addresses are exactly identical
although the socket addresses are different.
I can certainly verify that the ethernet address of ie0 is correct.
Another interesting thing is that when I used adb to dig at the same location,
I got identical results as my program.
I have two questions for the wizards:
(1) is there a better method to accomplish what I need to do?
	Note that I don't have source licence for SunOS.

(2) why the second ethernet address is exactly the same as the first one?
	(Program and script will accompany at the end).

Please mail the answer directly.
I'll post a summary if others are interested.

thanks in advance.

khasin at canstar.uucp
(canstar!khasin at hub.toronto.edu)

---- listing of iepeek.c -----
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netdb.h>
#include <nlist.h>

#include <sys/time.h>
#include "/sys/sunif/if_ievar.h"


/* global variables */
struct	nlist nl[] = {
	{"_ie_softc", 0, 0, 0, 0 },
	"",
};

int	fdkmem = -1;	/* file descriptor */
off_t	firstie_softc;	/* point to the first ie_softc */
struct ie_softc ie_softc[2];	/* assume there are two */

/* initialize the kernel dive */
kmeminit()
{
	char	*system = "/vmunix";		/* System Name */
	char	*kmemf  = "/dev/kmem";			/* Kernel Name */
	off_t	offset;				/* Interface Value */
	char	*ether_ntoa(), *inet_ntoa();
	int	rc;

	printf("kmeminit()\n");

	rc = nlist(system, nl);/* Read the symbol entry from kernel file*/
	printf("nlist -> %d\n", rc);
	if (nl[0].n_value == 0) {
		printf("kmeminit: nlist failed\n");
		return(-1);
	}
	printf("nl[0].n_type 0x%x  n_value 0x%x\n", nl[0].n_type, nl[0].n_value);

	if ((fdkmem = open(kmemf, 0)) < 0) {	/* Open Kernel File   */
		printf("kmeminit: open /dev/kmem failed\n");
		return(-1);
	}

#define ENADDR(i)	ie_softc[i].es_enaddr.ether_addr_octet
#define IPADDR(i)	ie_softc[i].es_ac.ac_ipaddr

	firstie_softc = (off_t) (nl[0].n_value);
	if (firstie_softc) {
		lseek(fdkmem, firstie_softc, 0);
		if ( read(fdkmem, &ie_softc[0], sizeof(struct ie_softc)) < 0 ) {
			printf("kmeminit: read /dev/kmem failed\n");
			return(-1);
		}
		printf("ethernet address: %s\n", ether_ntoa(ENADDR(0)));
		printf("sockaddr %s\n", inet_ntoa(IPADDR(0)));
		lseek(fdkmem, firstie_softc+sizeof(struct ie_softc), 0);
		if ( read(fdkmem, &ie_softc[1], sizeof(struct ie_softc)) < 0 ) {
			printf("kmeminit: read /dev/kmem failed\n");
			return(-1);
		}
		printf("ethernet address: %s\n", ether_ntoa(ENADDR(1)));
		printf("sockaddr %s\n", inet_ntoa(IPADDR(1)));
	}
	return(fdkmem);
}

main(argc, argv)
int	argc;
char	**argv;
{
	int	fd;

	printf("kmeminit  sizeof(struct ifnet) %d\n", sizeof(struct ifnet));
	printf("sizeof struct ie_softc %d\n", sizeof(struct ie_softc));
	if ( (fd = kmeminit()) == -1 ) {
		printf("kmeminit failed\n");
		return(1);
	}
	return(0);
}
------- end of iepeek.c ------
------- Log script ------
Script started on Thu May  3 16:03:23 1990
earth% iepeek
kmeminit  sizeof(struct ifnet) 112
sizeof struct ie_softc 384
kmeminit()
nl[0].n_type 0x9  n_value 0xf80f6d78
ethernet address: 8:0:20:0:81:2
sockaddr 64.0.0.15
ethernet address: 8:0:20:0:81:2
sockaddr 65.0.0.15
earth% 
earth% adb -k /vmunix /dev/mem
physmem	3fd
ie_softc+70/X				# ie_softc[0].es_enaddr.ether_addr_octet
_ie_softc+0x70:	8002000
_ie_softc+0x74:	81020000
_ie_softc+0x78:	4000000f 		# ie_softc[0].es_ac.ac_ipaddr
ie_softc+1f0/X				# ie_softc[1].es_enaddr.ether_addr_octet
_ie_softc+0x1f0:	8002000
_ie_softc+0x1f4:	81020000
_ie_softc+0x1f8:	4100000f 	# ie_softc[1].es_ac.ac_ipaddr
$q
earth% exit
script done on Thu May  3 16:07:53 1990
------- End of Log script -----



More information about the Comp.unix.wizards mailing list