06.addrs_dlpi.c.patch revision 306
306N/A--- addrs_dlpi.c.orig Tue Feb 10 13:55:04 2009
306N/A+++ addrs_dlpi.c Fri Jan 16 12:42:53 2009
306N/A@@ -24,11 +24,8 @@
306N/A #include <sys/sockio.h>
306N/A #include <sys/ioctl.h>
306N/A #include <sys/socket.h>
306N/A-#include <sys/dlpi.h>
306N/A #include <net/if.h>
306N/A
306N/A-#include "dlcommon.h"
306N/A-
306N/A extern char *split_dname(char *device, int *unitp);
306N/A extern char *strncpy2(char *dest, char *src, int n);
306N/A extern char *strncat2(char *dest, char *src, int n);
306N/A@@ -56,123 +53,8 @@
306N/A int got_ip_addr = 0;
306N/A
306N/A int fd;
306N/A- long buf[MAXDLBUF]; /* long aligned */
306N/A- union DL_primitives *dlp;
306N/A-
306N/A- char *cp;
306N/A- int unit_num = 0;
306N/A- int sap = 0;
306N/A-
306N/A- char *devname = NULL;
306N/A- char *devname2 = NULL;
306N/A- char fulldevpath[256];
306N/A-
306N/A struct ifreq ifr = {};
306N/A
306N/A- /* -- */
306N/A-
306N/A- memset(if_hw_addr, 0, 6);
306N/A-
306N/A- // we want to be able to process either a fully qualified /dev/ge0
306N/A- // type interface definition, or just ge0.
306N/A-
306N/A- if (strncmp(interface, "/dev/", strlen("/dev/")) == 0) {
306N/A- devname = interface + strlen("/dev/");
306N/A- } else {
306N/A- devname = interface;
306N/A- }
306N/A-
306N/A- strncpy2(fulldevpath, "/dev/", sizeof(fulldevpath)-1);
306N/A- cp = strncat2(fulldevpath, interface, sizeof(fulldevpath));
306N/A-
306N/A- if (strlen(cp) != 0) {
306N/A- fprintf(stderr, "device name buffer overflow %s\n", fulldevpath);
306N/A- return -1;
306N/A- }
306N/A-
306N/A- fprintf(stderr,"interface: %s\n", devname);
306N/A-
306N/A- // on Solaris, even though we are wanting to talk to ethernet device
306N/A- // ge0, we have to open /dev/ge, then bind to unit 0. Dupe our
306N/A- // full path, then identify and cut off the unit number
306N/A-
306N/A- devname2 = strdup(fulldevpath);
306N/A-
306N/A- cp = split_dname(devname2, &unit_num);
306N/A-
306N/A- if (cp == NULL) {
306N/A- free(devname2);
306N/A- goto get_ip_address;
306N/A- } else {
306N/A- *cp = '\0'; /* null terminate devname2 right before numeric extension */
306N/A- }
306N/A-
306N/A- // devname2 should now be something akin to /dev/ge. Try to open
306N/A- // it, and if it fails, fall back to the full /dev/ge0.
306N/A-
306N/A- if ((fd = open(devname2, O_RDWR)) < 0) {
306N/A- if (errno != ENOENT) {
306N/A- fprintf(stderr, "Couldn't open %s\n", devname2);
306N/A- free(devname2);
306N/A- goto get_ip_address;
306N/A- } else {
306N/A- if ((fd = open(fulldevpath, O_RDWR)) < 0) {
306N/A- fprintf(stderr, "Couldn't open %s\n", fulldevpath);
306N/A- free(devname2);
306N/A- goto get_ip_address;
306N/A- }
306N/A- }
306N/A- }
306N/A-
306N/A- free(devname2);
306N/A- devname2 = NULL;
306N/A-
306N/A- /* Use the dlcommon functions to get access to the DLPI information for this
306N/A- * interface. All of these functions exit() out on failure
306N/A- */
306N/A-
306N/A- dlp = (union DL_primitives*) buf;
306N/A-
306N/A- /*
306N/A- * DLPI attach to our low-level device
306N/A- */
306N/A-
306N/A- dlattachreq(fd, unit_num);
306N/A- dlokack(fd, buf);
306N/A-
306N/A- /*
306N/A- * DLPI bind
306N/A- */
306N/A-
306N/A- dlbindreq(fd, sap, 0, DL_CLDLS, 0, 0);
306N/A- dlbindack(fd, buf);
306N/A-
306N/A- /*
306N/A- * DLPI DL_INFO_REQ
306N/A- */
306N/A-
306N/A- dlinforeq(fd);
306N/A- dlinfoack(fd, buf);
306N/A-
306N/A- /*
306N/A- printdlprim(dlp); // uncomment this to dump out info from DLPI
306N/A- */
306N/A-
306N/A- if (dlp->info_ack.dl_addr_length + dlp->info_ack.dl_sap_length == 6) {
306N/A- memcpy(if_hw_addr,
306N/A- OFFADDR(dlp, dlp->info_ack.dl_addr_offset),
306N/A- dlp->info_ack.dl_addr_length);
306N/A- got_hw_addr = 1;
306N/A- } else {
306N/A- fprintf(stderr, "Error, bad length for hardware interface %s -- %d\n",
306N/A- interface,
306N/A- dlp->info_ack.dl_addr_length);
306N/A- }
306N/A-
306N/A- close(fd);
306N/A-
306N/A- get_ip_address:
306N/A-
306N/A /* Get the IP address of the interface */
306N/A
306N/A #ifdef SIOCGIFADDR