khasin@canstar.UUCP (Kha Sin Teow) (05/04/90)
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@canstar.uucp (canstar!khasin@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 -----