summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorss150715 <none@none>2007-06-12 20:58:49 -0700
committerss150715 <none@none>2007-06-12 20:58:49 -0700
commit948f2876ce2a3010558f4f6937e16086ebcd36f2 (patch)
treed3effbbe7ac9273659031d182e09c63978319d45 /usr/src/lib
parentd5782879d27b85dce3fec2c6791f149d26545295 (diff)
downloadillumos-joyent-948f2876ce2a3010558f4f6937e16086ebcd36f2.tar.gz
PSARC 2007/282 DLPI MAC-Type Mapping Functions
4714297 libdlpi ought to detect stream hangup properly 6397009 core dumped from get_ethernet_address() 6505649 need DLPI type mapping routines 6524620 dlpi_to_arp belongs in libdlpi, not libdhcputil 6524636 dhcpagent should be ported to libdlpi 6534006 libuuid should be ported to libdlpi 6534017 zoneadm should be ported to libdlpi 6534023 in.rarpd should be ported to libdlpi 6534263 show_linkprop_onelink() should use dlpi_open() instead of open() 6549358 64-bit version of libdladm needed for libuuid 6562226 fsck should link to libraries instead of directly pulling source --HG-- rename : usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c => deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c rename : usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h => deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h rename : usr/src/cmd/zoneadm/dlprims.c => deleted_files/usr/src/cmd/zoneadm/dlprims.c
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/Makefile2
-rw-r--r--usr/src/lib/libdhcpagent/common/dhcp_stable.c2
-rw-r--r--usr/src/lib/libdhcputil/common/dhcp_inittab.c54
-rw-r--r--usr/src/lib/libdhcputil/common/dhcp_inittab.h3
-rw-r--r--usr/src/lib/libdhcputil/common/mapfile-vers1
-rw-r--r--usr/src/lib/libdladm/Makefile1
-rw-r--r--usr/src/lib/libdladm/amd64/Makefile31
-rw-r--r--usr/src/lib/libdladm/common/linkprop.c7
-rw-r--r--usr/src/lib/libdladm/sparcv9/Makefile31
-rw-r--r--usr/src/lib/libdlpi/common/libdlpi.c80
-rw-r--r--usr/src/lib/libdlpi/common/libdlpi.h2
-rw-r--r--usr/src/lib/libdlpi/common/mapfile-vers2
-rw-r--r--usr/src/lib/libuuid/Makefile.com4
-rw-r--r--usr/src/lib/libuuid/common/etheraddr.c818
-rw-r--r--usr/src/lib/libuuid/common/etheraddr.h45
15 files changed, 212 insertions, 871 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index ef6a96f1b8..25d2e96f28 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -482,7 +482,7 @@ libinetcfg: libnsl libsocket libdevinfo
libkmf: libcryptoutil pkcs11 openssl
libnsl: libmd5 libscf
libmapid: libresolv
-libuuid: libsocket
+libuuid: libdlpi libdladm
libinetutil: libsocket
libsecdb: libnsl
libsasl: libgss libsocket pkcs11 libmd
diff --git a/usr/src/lib/libdhcpagent/common/dhcp_stable.c b/usr/src/lib/libdhcpagent/common/dhcp_stable.c
index e240164549..3f4c41e868 100644
--- a/usr/src/lib/libdhcpagent/common/dhcp_stable.c
+++ b/usr/src/lib/libdhcpagent/common/dhcp_stable.c
@@ -145,7 +145,7 @@ make_stable_duid(const char *physintf, size_t *duidlen)
if (dlpi_open(physintf, &dh, 0) == DLPI_SUCCESS &&
dlpi_info(dh, &dlinfo, 0) == DLPI_SUCCESS &&
(len = dlinfo.di_physaddrlen) > 0 &&
- (arptype = dlpi_to_arp(dlinfo.di_mactype) != 0)) {
+ (arptype = dlpi_arptype(dlinfo.di_mactype) != 0)) {
duid_llt_t *dllt;
time_t now;
diff --git a/usr/src/lib/libdhcputil/common/dhcp_inittab.c b/usr/src/lib/libdhcputil/common/dhcp_inittab.c
index 861dbc3f57..0010fdfabe 100644
--- a/usr/src/lib/libdhcputil/common/dhcp_inittab.c
+++ b/usr/src/lib/libdhcputil/common/dhcp_inittab.c
@@ -101,58 +101,6 @@ static category_map_entry_t category_map[] = {
};
/*
- * dlpi_to_arp(): converts DLPI datalink types into ARP datalink types
- *
- * input: uint_t: the DLPI datalink type
- * output: uint_t: the ARP datalink type (0 if no corresponding code)
- *
- * note: this function does not belong in this library, but it's here until
- * dhcpagent is ported over to libdlpi. It should move to libdlpi
- * instead.
- */
-
-uint_t
-dlpi_to_arp(uint_t dlpi_type)
-{
- switch (dlpi_type) {
-
- case DL_ETHER:
- return (ARPHRD_ETHER);
-
- case DL_FRAME:
- return (ARPHRD_FRAME);
-
- case DL_ATM:
- return (ARPHRD_ATM);
-
- case DL_IPATM:
- return (ARPHRD_IPATM);
-
- case DL_HDLC:
- return (ARPHRD_HDLC);
-
- case DL_FC:
- return (ARPHRD_FC);
-
- case DL_CSMACD: /* ieee 802 networks */
- case DL_TPB:
- case DL_TPR:
- case DL_METRO:
- case DL_FDDI:
- return (ARPHRD_IEEE802);
-
- case DL_IB:
- return (ARPHRD_IB);
-
- case DL_IPV4:
- case DL_IPV6:
- return (ARPHRD_TUNNEL);
- }
-
- return (0);
-}
-
-/*
* inittab_load(): returns all inittab entries with the specified criteria
*
* input: uchar_t: the categories the consumer is interested in
@@ -571,7 +519,7 @@ get_mac_addr(const char *str, int *ierrnop, uint16_t *hwret, int hwtype,
(void) memcpy(outbuf, dlinfo.di_physaddr, maclen);
dlpi_close(dh);
if (hwtype == -1)
- hwtype = dlpi_to_arp(dlinfo.di_mactype);
+ hwtype = dlpi_arptype(dlinfo.di_mactype);
}
}
if (hwtype == -1)
diff --git a/usr/src/lib/libdhcputil/common/dhcp_inittab.h b/usr/src/lib/libdhcputil/common/dhcp_inittab.h
index 030d057667..d4f94aabb8 100644
--- a/usr/src/lib/libdhcputil/common/dhcp_inittab.h
+++ b/usr/src/lib/libdhcputil/common/dhcp_inittab.h
@@ -111,9 +111,6 @@ extern char *inittab_decode(const dhcp_symbol_t *, const uchar_t *,
extern char *inittab_decode_e(const dhcp_symbol_t *,
const uchar_t *, uint16_t, boolean_t, int *);
-/* temporary; should be in libdlpi */
-extern uint_t dlpi_to_arp(uint_t);
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/libdhcputil/common/mapfile-vers b/usr/src/lib/libdhcputil/common/mapfile-vers
index 851b69b1b7..174dce2410 100644
--- a/usr/src/lib/libdhcputil/common/mapfile-vers
+++ b/usr/src/lib/libdhcputil/common/mapfile-vers
@@ -33,7 +33,6 @@ SUNWprivate_1.2 {
dhcp_options_scan;
dhcpv6_find_option;
dhcpv6_pkt_option;
- dlpi_to_arp;
} SUNWprivate_1.1;
SUNWprivate_1.1 {
diff --git a/usr/src/lib/libdladm/Makefile b/usr/src/lib/libdladm/Makefile
index 77c7824ae4..c1aa64b78b 100644
--- a/usr/src/lib/libdladm/Makefile
+++ b/usr/src/lib/libdladm/Makefile
@@ -32,6 +32,7 @@ HDRS = libdladm.h libdladm_impl.h libdllink.h libdlaggr.h \
HDRDIR = common
SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
POFILE = libdladm.po
MSGFILES = common/libdladm.c common/linkprop.c common/secobj.c \
diff --git a/usr/src/lib/libdladm/amd64/Makefile b/usr/src/lib/libdladm/amd64/Makefile
new file mode 100644
index 0000000000..51f031cb3e
--- /dev/null
+++ b/usr/src/lib/libdladm/amd64/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c
index 0e0f990b7d..21ea999749 100644
--- a/usr/src/lib/libdladm/common/linkprop.c
+++ b/usr/src/lib/libdladm/common/linkprop.c
@@ -437,7 +437,8 @@ process_linkprop_init(linkprop_db_state_t *lsp, char *buf,
* values from listp.
*/
for (lvp = lip->li_val, valcnt = 0;
- lvp != NULL; lvp = lvp->lv_nextval, valcnt++);
+ lvp != NULL; lvp = lvp->lv_nextval, valcnt++)
+ ;
propval = malloc(sizeof (char *) * valcnt);
if (propval == NULL) {
@@ -880,7 +881,7 @@ do_set_zone(const char *link, val_desc_t *vdp, uint_t val_cnt)
return (status);
/* Do nothing if setting to current value */
- zid_new = (zoneid_t)vdp->vd_val;
+ zid_new = (intptr_t)(void *)vdp->vd_val;
if (zid_new == zid_old)
return (DLADM_STATUS_OK);
@@ -963,7 +964,7 @@ do_check_zone(prop_desc_t *pdp, char **prop_val, uint_t val_cnt,
if (vdp == NULL)
return (DLADM_STATUS_NOMEM);
- vdp->vd_val = (void *)zid;
+ vdp->vd_val = (void *)(uintptr_t)zid;
*vdpp = vdp;
return (DLADM_STATUS_OK);
}
diff --git a/usr/src/lib/libdladm/sparcv9/Makefile b/usr/src/lib/libdladm/sparcv9/Makefile
new file mode 100644
index 0000000000..51f031cb3e
--- /dev/null
+++ b/usr/src/lib/libdladm/sparcv9/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libdlpi/common/libdlpi.c b/usr/src/lib/libdlpi/common/libdlpi.c
index 42ac808382..3fcddf1b31 100644
--- a/usr/src/lib/libdlpi/common/libdlpi.c
+++ b/usr/src/lib/libdlpi/common/libdlpi.c
@@ -42,6 +42,8 @@
#include <alloca.h>
#include <sys/sysmacros.h>
#include <ctype.h>
+#include <net/if_types.h>
+#include <netinet/arp.h>
#include <libdlpi.h>
#include <libintl.h>
#include <libinetutil.h>
@@ -586,7 +588,7 @@ dlpi_send(dlpi_handle_t dh, const void *daddrp, size_t daddrlen,
if (dip->dli_oflags & DLPI_RAW)
return (i_dlpi_strputmsg(dip->dli_fd, NULL, msgbuf, msglen, 0));
- if (daddrp == NULL || daddrlen > DLPI_PHYSADDR_MAX)
+ if ((daddrlen > 0 && daddrp == NULL) || daddrlen > DLPI_PHYSADDR_MAX)
return (DLPI_EINVAL);
DLPI_MSG_CREATE(req, DL_UNITDATA_REQ);
@@ -765,6 +767,80 @@ dlpi_style(dlpi_handle_t dh)
return (dip->dli_style);
}
+uint_t
+dlpi_arptype(uint_t dlpitype)
+{
+ switch (dlpitype) {
+
+ case DL_ETHER:
+ return (ARPHRD_ETHER);
+
+ case DL_FRAME:
+ return (ARPHRD_FRAME);
+
+ case DL_ATM:
+ return (ARPHRD_ATM);
+
+ case DL_IPATM:
+ return (ARPHRD_IPATM);
+
+ case DL_HDLC:
+ return (ARPHRD_HDLC);
+
+ case DL_FC:
+ return (ARPHRD_FC);
+
+ case DL_CSMACD: /* ieee 802 networks */
+ case DL_TPB:
+ case DL_TPR:
+ case DL_METRO:
+ case DL_FDDI:
+ return (ARPHRD_IEEE802);
+
+ case DL_IB:
+ return (ARPHRD_IB);
+
+ case DL_IPV4:
+ case DL_IPV6:
+ return (ARPHRD_TUNNEL);
+ }
+
+ return (0);
+}
+
+uint_t
+dlpi_iftype(uint_t dlpitype)
+{
+ switch (dlpitype) {
+
+ case DL_ETHER:
+ return (IFT_ETHER);
+
+ case DL_ATM:
+ return (IFT_ATM);
+
+ case DL_CSMACD:
+ return (IFT_ISO88023);
+
+ case DL_TPB:
+ return (IFT_ISO88024);
+
+ case DL_TPR:
+ return (IFT_ISO88025);
+
+ case DL_FDDI:
+ return (IFT_FDDI);
+
+ case DL_IB:
+ return (IFT_IB);
+
+ case DL_OTHER:
+ return (IFT_OTHER);
+ }
+
+ return (0);
+}
+
/*
* This function attempts to open linkname under the following namespaces:
* - /dev
@@ -1094,6 +1170,8 @@ i_dlpi_strgetmsg(int fd, int msec, dlpi_msg_t *dlreplyp, t_uscalar_t dlreqprim,
switch (poll(&pfd, 1, msec)) {
default:
+ if (pfd.revents & POLLHUP)
+ return (DL_SYSERR);
break;
case 0:
return (DLPI_ETIMEDOUT);
diff --git a/usr/src/lib/libdlpi/common/libdlpi.h b/usr/src/lib/libdlpi/common/libdlpi.h
index 0099727cc5..a0f5b918e8 100644
--- a/usr/src/lib/libdlpi/common/libdlpi.h
+++ b/usr/src/lib/libdlpi/common/libdlpi.h
@@ -160,6 +160,8 @@ extern int dlpi_send(dlpi_handle_t, const void *, size_t, const void *, size_t,
const dlpi_sendinfo_t *);
extern int dlpi_fd(dlpi_handle_t);
extern int dlpi_set_timeout(dlpi_handle_t, int);
+extern uint_t dlpi_arptype(uint_t);
+extern uint_t dlpi_iftype(uint_t);
/*
* These are Consolidation Private interfaces and are subject to change.
diff --git a/usr/src/lib/libdlpi/common/mapfile-vers b/usr/src/lib/libdlpi/common/mapfile-vers
index 31ae2a5aa1..457f0b39cb 100644
--- a/usr/src/lib/libdlpi/common/mapfile-vers
+++ b/usr/src/lib/libdlpi/common/mapfile-vers
@@ -27,12 +27,14 @@
SUNW_1.1 { # first release of libdlpi, Solaris 11
global:
+ dlpi_arptype;
dlpi_bind;
dlpi_close;
dlpi_disabmulti;
dlpi_enabmulti;
dlpi_fd;
dlpi_get_physaddr;
+ dlpi_iftype;
dlpi_info;
dlpi_linkname;
dlpi_mactype;
diff --git a/usr/src/lib/libuuid/Makefile.com b/usr/src/lib/libuuid/Makefile.com
index 7329255870..d1178c5bc6 100644
--- a/usr/src/lib/libuuid/Makefile.com
+++ b/usr/src/lib/libuuid/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -35,7 +35,7 @@ include ../../Makefile.lib
include ../../Makefile.rootfs
LIBS = $(DYNLIB) $(LINTLIB)
-LDLIBS += -lsocket -lnsl -lc
+LDLIBS += -lsocket -lnsl -lc -ldlpi -ldladm
SRCDIR = ../common
$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
diff --git a/usr/src/lib/libuuid/common/etheraddr.c b/usr/src/lib/libuuid/common/etheraddr.c
index 527a82c98d..6b2011150e 100644
--- a/usr/src/lib/libuuid/common/etheraddr.c
+++ b/usr/src/lib/libuuid/common/etheraddr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,62 +19,35 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#include "etheraddr.h"
#include <stdlib.h>
#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
#include <strings.h>
-#include <libdevinfo.h>
#include <stropts.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include <sys/sockio.h>
+#include <libdlpi.h>
+#include <libdllink.h>
#include <sys/utsname.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#include <sys/dlpi.h>
+#include "etheraddr.h"
+
/*
* debugging flag
*/
static int debug = 0;
-
-/* Timeout for DLPI acks */
-static int dlpi_timeout = DLPI_TIMEOUT;
-
-/*
- * Global functions
- */
-int dlpi_get_address(char *, struct ether_addr *);
-int get_net_if_names(char ***);
-void free_net_if_names(char **);
-
-
-/*
- * local functions
- */
-static int dlpi_info_req(int, dl_info_ack_t *);
-static int timed_getmsg(int, struct strbuf *, int *, int, char *, char *);
-static int ifrm_num(char *, unsigned int *);
-static int open_dev(dev_att_t *, int, int *, int);
-static void pf_dev_att(dev_att_t *);
-static void parse_ifname(dev_att_t *);
-static int ifname_open(char *, dev_att_t *);
-static int dlpi_open_attach(char *);
-static int dlpi_attach(int, int, int);
-static int dlpi_get_phys(int, uchar_t *);
-static int dlpi_info_req(int, dl_info_ack_t *);
-static int timed_getmsg(int, struct strbuf *, int *, int, char *, char *);
+static void get_etheraddr(void *arg, const char *linkname);
/*
* get an individual arp entry
@@ -122,764 +94,70 @@ arp_get(uuid_node_t *node)
return (0);
}
-
-/* Get all interface names. This will include IPv6 names. */
-int
-get_net_if_names(char ***names)
-{
- char *buf; /* buffer for socket info */
- int sd; /* socket descriptor */
- int ifn; /* interface count structure */
- struct ifconf ifc; /* interface config buffer */
- struct ifreq *ifrp;
- int numifs;
- char **tmpnames;
- int n;
- char *tmpname;
- sd = socket(AF_INET, SOCK_DGRAM, 0);
- if (sd < 0)
- return (-1);
-
- if (ioctl(sd, SIOCGIFNUM, &ifn) < 0) {
- (void) close(sd);
- return (-1);
- }
-
- if (!(buf = malloc(ifn * sizeof (struct ifreq)))) {
- (void) close(sd);
- return (-1);
- }
-
- ifc.ifc_len = ifn * sizeof (struct ifreq);
- ifc.ifc_buf = (caddr_t)buf;
- if (ioctl(sd, SIOCGIFCONF, (char *)&ifc) < 0) {
- free(buf);
- (void) close(sd);
- return (-1);
- }
- (void) close(sd);
-
- ifrp = ifc.ifc_req;
- numifs = ifc.ifc_len / sizeof (struct ifreq);
- tmpnames = (char **)calloc((numifs+1), sizeof (char *));
-
- if (tmpnames == NULL) {
- free(buf);
- return (-1);
- }
- for (n = 0; n < numifs; n++, ifrp++) {
- if ((tmpnames[n] = strdup(ifrp->ifr_name)) == NULL)
- break;
- }
- free(buf);
- *names = tmpnames;
- return (0);
-}
-
-/*
- * frees previously-allocated array from get_net_if_names
- */
-void
-free_net_if_names(char **ifnames)
-{
- int i;
-
- i = 0;
- while (ifnames[i] != NULL) {
- free(ifnames[i]);
- i++;
- }
- free(ifnames);
-}
-
-
/*
- * attempt to remove ppa from end of file name
- * return -1 if none found
- * return ppa if found and remove the ppa from the filename
+ * Name: get_ethernet_address
+ *
+ * Description: Obtains the system ethernet address.
+ *
+ * Returns: 0 on success, non-zero otherwise. The system ethernet
+ * address is copied into the passed-in variable.
*/
-static int
-ifrm_num(char *fname, unsigned int *ppa)
+int
+get_ethernet_address(uuid_node_t *node)
{
- int i;
- uint_t p = 0;
- unsigned int m = 1;
+ walker_arg_t state;
- i = strlen(fname) - 1;
- while (i >= 0 && '0' <= fname[i] && fname[i] <= '9') {
- p += (fname[i] - '0')*m;
- m *= 10;
- i--;
- }
- if (m == 1) {
- return (-1);
- }
- fname[i + 1] = '\0';
- *ppa = p;
- return (0);
-}
-
-/*
- * Open the device defined in dev_att with the given mode starting with
- * the module indicated by mod_cnt (1 indexed). If mod_cnt > 0, fd must
- * contain the file descriptor that modules are to be pushed on.
- * Returns -1 if device could not be opened, the index of
- * the module that could not be pushed or 0 on success.
- */
-static int
-open_dev(dev_att_t *dev_att, int mode, int *fd, int mod_cnt)
-{
- int cnt;
- int local_fd;
+ if (arp_get(node) == 0)
+ return (0);
- if (debug)
- (void) printf("open_dev: ifname: %s : dev %s fd %d "
- " mod_cnt %d\n",
- dev_att->ifname, dev_att->devname, *fd, mod_cnt);
/*
- * if no module count is given, try and open the device
+ * Try to get physical (ethernet) address from network interfaces.
*/
- if (mod_cnt == 0) {
- if (debug)
- (void) printf("open_dev: opening %s\n",
- dev_att->devname);
- if ((local_fd = open(dev_att->devname, mode)) < 0) {
- if (debug) {
- perror("open_dev: device");
- (void) printf("\n");
- }
- *fd = local_fd;
- return (-1);
- }
- *fd = local_fd;
- cnt = 1;
- } else {
- local_fd = *fd;
- cnt = mod_cnt;
+ state.wa_addrvalid = B_FALSE;
+ if (dladm_walk(get_etheraddr, &state) == 0 && state.wa_addrvalid) {
+ bcopy(state.wa_etheraddr, node, state.wa_etheraddrlen);
}
- /*
- * Try and push modules (if any) onto the device stream
- */
- for (; cnt <= dev_att->mod_cnt; cnt++) {
- if (debug)
- (void) printf(" pushing: mod %s",
- dev_att->modlist[cnt - 1]);
- if (ioctl(local_fd, I_PUSH, dev_att->modlist[cnt - 1]) == -1) {
- if (debug) {
- perror("open_dev: push");
- (void) printf("\n");
- }
- return (cnt);
- }
- }
- if (debug)
- (void) printf("\n");
- return (0);
-}
-
-/*
- * Debug routine to print out dev_att_t structure
- */
-static void
-pf_dev_att(dev_att_t *dev_att)
-{
- int cnt;
-
- (void) printf("\tifname: %s\n", dev_att->ifname);
- (void) printf("\t style: %d\n", dev_att->style);
- (void) printf("\t ppa: %d\n", dev_att->ppa);
- (void) printf("\t mod_cnt: %d\n", dev_att->mod_cnt);
- (void) printf("\t devname: %s\n", dev_att->devname);
- for (cnt = 0; cnt < dev_att->mod_cnt; cnt++) {
- (void) printf("\t module: %s\n", dev_att->modlist[cnt]);
- }
+ return (state.wa_addrvalid ? 0 : -1);
}
/*
- * This function parses a '.' delimited interface name of the form
- * dev[.module[.module...]][:lun]
- * and places the device and module name into dev_att
+ * Get the physical address via dlpi and update the flag to true upon success.
*/
static void
-parse_ifname(dev_att_t *dev_att)
+get_etheraddr(void *arg, const char *linkname)
{
- char *lunstr;
- char *modlist = NULL; /* list of modules to push */
- int cnt = 0; /* number of modules to push */
- char modbuf[LIFNAMSIZ];
- char *nxtmod;
-
- /*
- * check for specified lun at end of interface and
- * strip it off.
- */
- lunstr = strchr(dev_att->ifname, ':');
-
- if (lunstr) {
- char *endptr;
-
- *lunstr = '\0';
- lunstr++;
- endptr = lunstr;
- dev_att->lun = strtoul(lunstr, &endptr, 10);
-
- if (endptr == lunstr || *endptr != '\0') {
- (void) printf("Invalid logical unit number:%s", lunstr);
- exit(-1);
- }
- } else {
- dev_att->lun = 0;
- }
-
- (void) strlcpy(modbuf, dev_att->ifname, LIFNAMSIZ);
-
- /* parse '.' delmited module list */
- modlist = strchr(modbuf, '.');
- if (modlist) {
- /* null-terminate interface name (device) */
- *modlist = '\0';
- modlist++;
- if (strlen(modlist) == 0)
- modlist = NULL;
- while (modlist && cnt < MAX_MODS) {
- nxtmod = strchr(modlist, '.');
- if (nxtmod) {
- *nxtmod = '\0';
- nxtmod++;
- }
- (void) strncpy(dev_att->modlist[cnt], modlist,
- LIFNAMSIZ);
- cnt++;
- modlist = nxtmod;
- }
- }
- (void) snprintf(dev_att->devname, LIFNAMSIZ, "%s/%s", DEVDIR, modbuf);
- dev_att->mod_cnt = cnt;
-}
-
-/*
- * given a interface name (with possible modules to push)
- * interface name must have the format of
- * dev[ppa][.module[.module...][ppa]][:lun]
- * where only one ppa may be specified e.g. ip0.foo.tun or ip.foo.tun0
- */
-static int
-ifname_open(char *dev_name, dev_att_t *dev_att)
-{
- int fd;
- uint_t ppa;
- int res;
- int style;
- dl_info_ack_t dl_info;
- int mod_id;
-
- if (debug)
- (void) printf("ifname_open: %s\n", dev_name);
-
- if (strlen(dev_name) > LIFNAMSIZ - 1) {
- errno = EINVAL;
- return (-1);
- }
-
- /* save copy of original device name */
- (void) strncpy(dev_att->ifname, dev_name, LIFNAMSIZ);
-
- /* parse modules */
- parse_ifname(dev_att);
-
- /* try DLPI style 1 device first */
+ int retval;
+ dlpi_handle_t dh;
+ walker_arg_t *statep = arg;
- if (debug) {
- pf_dev_att(dev_att);
- }
- mod_id = open_dev(dev_att, O_RDWR, &fd, 0);
- if (mod_id != 0) {
- if (debug) {
- (void) printf("Error on open_dev style 1 mod_id: %d"
- " attemping style 2\n", mod_id);
- pf_dev_att(dev_att);
- }
- if (mod_id == -1) {
- res = ifrm_num(dev_att->devname, &ppa);
- mod_id = 0;
- if (res < 0) {
- if (debug)
- (void) fprintf(stderr,
- "%s: No such file or directory\n",
- dev_att->devname);
- (void) close(fd);
- return (-1);
- }
- /*
- * ensure that it's the last module
- * in the list to extract
- * ppa
- */
- } else if ((mod_id != dev_att->mod_cnt) ||
- (res = ifrm_num(dev_att->modlist[dev_att->mod_cnt - 1],
- &ppa)) < 0) {
+ if (!(statep->wa_addrvalid)) {
+ if (debug)
+ (void) printf("get_etheraddr: opening %s\n", linkname);
+ if ((retval = dlpi_open(linkname, &dh, 0)) != DLPI_SUCCESS) {
if (debug) {
- (void) fprintf(stderr,
- "Error on open_dev style 2 mod_id: %d \n",
- mod_id);
+ (void) fprintf(stderr, "get_etheraddr: "
+ "cannot open link: \"%s\" %s\n",
+ linkname, retval);
}
- if (mod_id == dev_att->mod_cnt)
- (void) fprintf(stderr, "libuuid: could not "
- "locate ppa in %s\n",
- dev_att->ifname);
- (void) close(fd);
- return (-1);
+ return;
}
- goto style2;
- }
- dev_att->style = 1;
- dev_att->ppa = 0;
- style = DL_STYLE1;
- goto dl_info_chk;
-style2:
- dev_att->ppa = ppa;
- mod_id = open_dev(dev_att, O_RDWR, &fd, mod_id);
- if (mod_id != 0) {
+
if (debug) {
- (void) fprintf(stderr,
- "Error on open_dev style 2 mod_id: %d \n",
- mod_id);
- if (mod_id > 0) {
- (void) fprintf(stderr, "%s: No such module\n",
- dev_att->modlist[mod_id - 2]);
- }
- pf_dev_att(dev_att);
+ (void) printf("get_etheraddr: getting ethernet address"
+ " from link: %s\n", linkname);
}
- (void) close(fd);
- return (-1);
- }
- dev_att->style = 2;
- style = DL_STYLE2;
-dl_info_chk:
- if (dlpi_info_req(fd, &dl_info) < 0) {
- (void) close(fd);
- pf_dev_att(dev_att);
- return (-1);
- }
- if (dl_info.dl_provider_style != style) {
+ statep->wa_etheraddrlen = DLPI_PHYSADDR_MAX;
+ retval = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR,
+ statep->wa_etheraddr, &(statep->wa_etheraddrlen));
if (debug) {
- (void) fprintf(stderr, "DLPI provider style mismatch: "
- "expected style %s got style %s (0x%lx)\n",
- style == DL_STYLE1 ? "1" : "2",
- dl_info.dl_provider_style == DL_STYLE1 ? "1" : "2",
- dl_info.dl_provider_style);
+ (void) fprintf(stderr, "get_etheraddr: "
+ "dlpi_get_physaddr: \"%s\" %s\n", linkname, retval);
}
- (void) close(fd);
- return (-1);
- }
- if (debug) {
- (void) printf("pars_dev_att() success\n");
- pf_dev_att(dev_att);
- }
- return (fd);
-}
-static int
-dlpi_open_attach(char *ifname)
-{
- int fd;
- dev_att_t dev_att;
-
- if (debug)
- (void) printf("dlpi_open_attach %s\n", ifname);
+ if (retval == DLPI_SUCCESS)
+ statep->wa_addrvalid = B_TRUE;
- /* if lun is specified fail (backwards compat) */
- if (strchr(ifname, ':') != NULL) {
- return (-1);
- }
- if ((fd = ifname_open(ifname, &dev_att)) < 0) {
- /* Not found */
- errno = ENXIO;
- return (-1);
+ dlpi_close(dh);
}
- if (dlpi_attach(fd, dev_att.ppa, dev_att.style) < 0) {
- (void) close(fd);
- return (-1);
- }
- return (fd);
-}
-
-static int
-dlpi_attach(int fd, int ppa, int style)
-{
- union DL_primitives *dlp;
- char *buf;
- struct strbuf ctl;
- int flags;
-
- if (style != 2)
- return (0);
-
- /* Allocate required buffers */
- if ((buf = malloc(BUFSIZ)) == NULL) {
- (void) fprintf(stderr, "libuuid: malloc() failed\n");
- return (-1);
- }
-
- /* Issue DL_ATTACH_REQ */
- /* LINTED: malloc returns a pointer aligned for any use */
- dlp = (union DL_primitives *)buf;
- dlp->attach_req.dl_primitive = DL_ATTACH_REQ;
- dlp->attach_req.dl_ppa = ppa;
- ctl.buf = (char *)dlp;
- ctl.len = DL_ATTACH_REQ_SIZE;
- if (putmsg(fd, &ctl, NULL, 0) < 0) {
- perror("libuuid: putmsg");
- free(buf);
- return (-1);
- }
-
- /* read reply */
- ctl.buf = (char *)dlp;
- ctl.len = 0;
- ctl.maxlen = BUFSIZ;
- flags = 0;
-
- /* start timeout for DL_OK_ACK reply */
- if (timed_getmsg(fd, &ctl, &flags, dlpi_timeout,
- "DL_OK_ACK", "DL_ATTACH_REQ") == 0) {
- free(buf);
- return (-1);
- }
-
- if (debug) {
- (void) printf("ok_ack: ctl.len[%d] flags[%d]\n", ctl.len,
- flags);
- }
-
- /* Validate DL_OK_ACK reply. */
- if (ctl.len < sizeof (t_uscalar_t)) {
- (void) fprintf(stderr,
- "libuuid: attach failed: short reply to attach request\n");
- free(buf);
- return (-1);
- }
-
- if (dlp->dl_primitive == DL_ERROR_ACK) {
- if (debug)
- (void) fprintf(stderr,
- "attach failed: dl_errno %lu errno %lu\n",
- dlp->error_ack.dl_errno,
- dlp->error_ack.dl_unix_errno);
- free(buf);
- errno = ENXIO;
- return (-1);
- }
- if (dlp->dl_primitive != DL_OK_ACK) {
- (void) fprintf(stderr,
- "libuuid: attach failed: "
- "unrecognizable dl_primitive %lu received",
- dlp->dl_primitive);
- free(buf);
- return (-1);
- }
- if (ctl.len < DL_OK_ACK_SIZE) {
- (void) fprintf(stderr,
- "libuuid: attach failed: "
- "short attach acknowledgement received\n");
- free(buf);
- return (-1);
- }
- if (dlp->ok_ack.dl_correct_primitive != DL_ATTACH_REQ) {
- (void) fprintf(stderr,
- "libuuid: attach failed: "
- "returned prim %lu != requested prim %lu\n",
- dlp->ok_ack.dl_correct_primitive,
- (t_uscalar_t)DL_ATTACH_REQ);
- free(buf);
- return (-1);
- }
- if (debug)
- (void) printf("attach done\n");
-
- free(buf);
- return (0);
-}
-
-static int
-dlpi_get_phys(int fd, uchar_t *eaddr)
-{
- union DL_primitives *dlp;
- char *buf;
- struct strbuf ctl;
- int flags;
-
- /* Allocate required buffers */
- if ((buf = malloc(BUFSIZ)) == NULL) {
- (void) fprintf(stderr, "libuuid: malloc() failed\n");
- return (-1);
- }
- /* Issue DL_PHYS_ADDR_REQ */
- /* LINTED: malloc returns a pointer aligned for any use */
- dlp = (union DL_primitives *)buf;
- dlp->physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ;
- dlp->physaddr_req.dl_addr_type = DL_CURR_PHYS_ADDR;
- ctl.buf = (char *)dlp;
- ctl.len = DL_PHYS_ADDR_REQ_SIZE;
- if (putmsg(fd, &ctl, NULL, 0) < 0) {
- perror("libuuid: putmsg");
- free(buf);
- return (-1);
- }
-
- /* read reply */
- ctl.buf = (char *)dlp;
- ctl.len = 0;
- ctl.maxlen = BUFSIZ;
- flags = 0;
-
- if (timed_getmsg(fd, &ctl, &flags, dlpi_timeout,
- "DL_PHYS_ADDR_ACK", "DL_PHYS_ADDR_REQ (DL_CURR_PHYS_ADDR)") == 0) {
- free(buf);
- return (-1);
- }
-
- if (debug) {
- (void) printf("phys_addr_ack: ctl.len[%d] flags[%d]\n", ctl.len,
- flags);
- }
-
- /* Validate DL_PHYS_ADDR_ACK reply. */
- if (ctl.len < sizeof (t_uscalar_t)) {
- (void) fprintf(stderr, "libuuid: phys_addr failed: "
- "short reply to phys_addr request\n");
- free(buf);
- return (-1);
- }
-
- if (dlp->dl_primitive == DL_ERROR_ACK) {
- /*
- * Do not print errors for DL_UNSUPPORTED and DL_NOTSUPPORTED
- */
- if (dlp->error_ack.dl_errno != DL_UNSUPPORTED &&
- dlp->error_ack.dl_errno != DL_NOTSUPPORTED) {
- (void) fprintf(stderr, "libuuid: phys_addr failed: "
- "dl_errno %lu errno %lu\n",
- dlp->error_ack.dl_errno,
- dlp->error_ack.dl_unix_errno);
- }
- free(buf);
- return (-1);
- }
- if (dlp->dl_primitive != DL_PHYS_ADDR_ACK) {
- (void) fprintf(stderr, "libuuid: phys_addr failed: "
- "unrecognizable dl_primitive %lu received\n",
- dlp->dl_primitive);
- free(buf);
- return (-1);
- }
- if (ctl.len < DL_PHYS_ADDR_ACK_SIZE) {
- (void) fprintf(stderr, "libuuid: phys_addr failed: "
- "short phys_addr acknowledgement received\n");
- free(buf);
- return (-1);
- }
- /* Check length of address. */
- if (dlp->physaddr_ack.dl_addr_length != ETHERADDRL) {
- free(buf);
- return (-1);
- }
-
- /* copy Ethernet address */
- (void) memcpy(eaddr, &buf[dlp->physaddr_ack.dl_addr_offset],
- ETHERADDRL);
-
- free(buf);
- return (0);
-}
-
-
-
-static int
-dlpi_info_req(int fd, dl_info_ack_t *info_ack)
-{
- dl_info_req_t info_req;
- int buf[BUFSIZ/sizeof (int)];
- union DL_primitives *dlp = (union DL_primitives *)buf;
- struct strbuf ctl;
- int flags;
-
- info_req.dl_primitive = DL_INFO_REQ;
-
- ctl.len = DL_INFO_REQ_SIZE;
- ctl.buf = (char *)&info_req;
-
- flags = RS_HIPRI;
-
- if (putmsg(fd, &ctl, (struct strbuf *)NULL, flags) < 0) {
- perror("libuuid: putmsg");
- return (-1);
- }
-
- /* read reply */
- ctl.buf = (char *)dlp;
- ctl.len = 0;
- ctl.maxlen = BUFSIZ;
- flags = 0;
- /* start timeout for DL_BIND_ACK reply */
- if (timed_getmsg(fd, &ctl, &flags, dlpi_timeout, "DL_INFO_ACK",
- "DL_INFO_ACK") == 0) {
- return (-1);
- }
-
- if (debug) {
- (void) printf("info_ack: ctl.len[%d] flags[%d]\n", ctl.len,
- flags);
- }
-
- /* Validate DL_BIND_ACK reply. */
- if (ctl.len < sizeof (t_uscalar_t)) {
- (void) fprintf(stderr,
- "libuuid: info req failed: short reply to info request\n");
- return (-1);
- }
-
- if (dlp->dl_primitive == DL_ERROR_ACK) {
- (void) fprintf(stderr,
- "libuuid: info req failed: dl_errno %lu errno %lu\n",
- dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno);
- return (-1);
- }
- if (dlp->dl_primitive != DL_INFO_ACK) {
- (void) fprintf(stderr,
- "libuuid: info req failed: "
- "unrecognizable dl_primitive %lu received\n",
- dlp->dl_primitive);
- return (-1);
- }
- if (ctl.len < DL_INFO_ACK_SIZE) {
- (void) fprintf(stderr,
- "libuuid: info req failed: "
- "short info acknowledgement received\n");
- return (-1);
- }
- *info_ack = *(dl_info_ack_t *)dlp;
- return (0);
-}
-
-
-/*
- * interface called from libuuid to get the ethernet address - jhf
- */
-int
-dlpi_get_address(char *ifname, struct ether_addr *ea)
-{
- int fd;
-
- if (debug)
- (void) printf("dlpi_get_address: dlpi_open_attach\t");
- fd = dlpi_open_attach(ifname);
- if (fd < 0) {
- /* Do not report an error */
- return (-1);
- }
-
- if (debug)
- (void) printf("dlpi_get_address: dlpi_get_phys %s\n", ifname);
- if (dlpi_get_phys(fd, (uchar_t *)ea) < 0) {
- (void) close(fd);
- return (-1);
- }
- (void) close(fd);
- return (0);
-}
-
-static int
-timed_getmsg(int fd, struct strbuf *ctlp, int *flagsp, int timeout, char *kind,
- char *request)
-{
- char perrorbuf[BUFSIZ];
- struct pollfd pfd;
- int ret;
-
- pfd.fd = fd;
-
- pfd.events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI;
- if ((ret = poll(&pfd, 1, timeout * 1000)) == 0) {
- (void) fprintf(stderr, "libuuid: %s timed out\n", kind);
- return (0);
- } else if (ret == -1) {
- (void) snprintf(perrorbuf, sizeof (perrorbuf),
- "libuuid: poll for %s from %s", kind, request);
- perror(perrorbuf);
- return (0);
- }
-
- /* poll returned > 0 for this fd so getmsg should not block */
- if ((ret = getmsg(fd, ctlp, NULL, flagsp)) < 0) {
- (void) snprintf(perrorbuf, sizeof (perrorbuf),
- "libuuid: getmsg expecting %s for %s", kind, request);
- perror(perrorbuf);
- return (0);
- }
-
- return (1);
-}
-
-/*
- * Name: get_ethernet_address
- *
- * Description: Obtains the system ethernet address.
- *
- * Returns: 0 on success, non-zero otherwise. The system ethernet
- * address is copied into the passed-in variable.
- */
-int
-get_ethernet_address(uuid_node_t *node)
-{
- char **ifnames;
- char *ifname;
- int i;
- struct ether_addr addr;
- int found;
-
- if (arp_get(node) == 0)
- return (0);
-
- /*
- * go get all interface names
- */
- if (get_net_if_names(&ifnames) != 0) {
- return (-1);
- }
-
- /*
- * Assume failure
- */
- found = -1;
-
- /*
- * for each interface, query it through dlpi to get its physical
- * (ethernet) address
- */
- if (ifnames != NULL) {
- i = 0;
- while ((ifnames[i] != NULL) && found) {
- ifname = ifnames[i];
- /* Gross hack to avoid getting errors from /dev/lo0 */
- if (strcmp(ifname, LOOPBACK_IF) != 0) {
- if (dlpi_get_address(ifname, &addr) == 0) {
- bcopy(&addr, node, 6);
- /*
- * found one, set result to successful
- */
- found = 0;
- continue;
- }
- }
- i++;
- }
- free_net_if_names(ifnames);
- }
-
- /*
- * Couldn't get ethernet address from any interfaces...
- */
- return (found);
}
diff --git a/usr/src/lib/libuuid/common/etheraddr.h b/usr/src/lib/libuuid/common/etheraddr.h
index b2fdeaacf3..1f56a7b2e2 100644
--- a/usr/src/lib/libuuid/common/etheraddr.h
+++ b/usr/src/lib/libuuid/common/etheraddr.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2000,2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,40 +46,14 @@ extern "C" {
#include <netinet/if_ether.h>
#include <sys/uuid.h>
-/* max modules that can be pushed on intr */
-#define MAX_MODS 9
+typedef struct walker_arg {
+ uchar_t wa_etheraddr[DLPI_PHYSADDR_MAX];
+ size_t wa_etheraddrlen;
+ boolean_t wa_addrvalid;
+} walker_arg_t;
-/* used to avoid getting errors from lo0 */
-#define LOOPBACK_IF "lo0"
-
-/*
- * Local structure encapsulating an interface
- * device and its associated modules
- */
-typedef struct dev_att {
- char ifname[LIFNAMSIZ]; /* interface name, such as "le0" */
- int style; /* DLPI message style */
- int ppa; /* Physical point of attachment */
- int lun; /* logical unit number */
- int mod_cnt; /* # modules to push onto stream */
- char devname[LIFNAMSIZ]; /* device name, such as "/dev/le0" */
- char modlist[MAX_MODS][LIFNAMSIZ]; /* modules to push onto stream */
-} dev_att_t;
-
-
-/* where devices are located */
-#define DEVDIR "/dev"
-
-/* how long to wait for dlpi requests to succeed */
-#define DLPI_TIMEOUT 60
-
-/*
- * Global functions
- */
+/* global function */
int arp_get(uuid_node_t *);
-int dlpi_get_address(char *, struct ether_addr *);
-int get_net_if_names(char ***);
-void free_net_if_names(char **);
int get_ethernet_address(uuid_node_t *);
#ifdef __cplusplus