summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorss150715 <none@none>2007-02-09 16:50:26 -0800
committerss150715 <none@none>2007-02-09 16:50:26 -0800
commitc7e4935f5b755b4bbeaec416f1ad24337aeac7a4 (patch)
treeb0f2f912e4898d18e49625b694ac3fee2ec32a85
parent72b9fce97841381c0dae054e0dddd25d76672405 (diff)
downloadillumos-joyent-c7e4935f5b755b4bbeaec416f1ad24337aeac7a4.tar.gz
PSARC/2006/436 Public DLPI Library
PSARC/2006/634 Public DLPI Library Addendum 6266613 libdlpi should provide a default timeout 6336199 snoop should be ported to libdlpi 6340802 libdlpi needs a more robust mechanism of handling expected messages 6512059 public libdlpi library needed --HG-- rename : usr/src/cmd/cmd-inet/usr.sbin/snoop/dlprims.c => deleted_files/usr/src/cmd/cmd-inet/usr.sbin/snoop/dlprims.c
-rw-r--r--deleted_files/usr/src/cmd/cmd-inet/usr.sbin/snoop/dlprims.c (renamed from usr/src/cmd/cmd-inet/usr.sbin/snoop/dlprims.c)0
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c155
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.h12
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/ifconfig/revarp.c545
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile2
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c30
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h14
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c285
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/syncinit.c57
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/syncloop.c64
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/syncstat.c97
-rw-r--r--usr/src/cmd/dladm/dladm.c76
-rw-r--r--usr/src/cmd/iscsi/iscsitgtd/Makefile.com4
-rw-r--r--usr/src/cmd/iscsi/iscsitgtd/target.h2
-rw-r--r--usr/src/cmd/iscsi/iscsitgtd/util_ifname.c190
-rw-r--r--usr/src/lib/Makefile1
-rw-r--r--usr/src/lib/libdhcpagent/common/dhcp_stable.c45
-rw-r--r--usr/src/lib/libdhcputil/common/dhcp_inittab.c31
-rw-r--r--usr/src/lib/libdladm/common/libdladm.c34
-rw-r--r--usr/src/lib/libdlpi/Makefile3
-rw-r--r--usr/src/lib/libdlpi/Makefile.com4
-rw-r--r--usr/src/lib/libdlpi/amd64/Makefile31
-rw-r--r--usr/src/lib/libdlpi/common/libdlpi.c2242
-rw-r--r--usr/src/lib/libdlpi/common/libdlpi.h178
-rw-r--r--usr/src/lib/libdlpi/common/libdlpi_impl.h120
-rw-r--r--usr/src/lib/libdlpi/common/mapfile-vers45
-rw-r--r--usr/src/lib/libdlpi/sparcv9/Makefile31
-rw-r--r--usr/src/lib/libinetutil/common/ifspec.c52
-rw-r--r--usr/src/pkgdefs/SUNWarcr/prototype_i3863
-rw-r--r--usr/src/pkgdefs/SUNWarcr/prototype_sparc3
-rw-r--r--usr/src/pkgdefs/SUNWcslr/prototype_i3864
-rw-r--r--usr/src/pkgdefs/SUNWcslr/prototype_sparc2
-rw-r--r--usr/src/tools/abi/etc/exceptions1
33 files changed, 2155 insertions, 2208 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/dlprims.c b/deleted_files/usr/src/cmd/cmd-inet/usr.sbin/snoop/dlprims.c
index b2a36c9525..b2a36c9525 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/dlprims.c
+++ b/deleted_files/usr/src/cmd/cmd-inet/usr.sbin/snoop/dlprims.c
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c b/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c
index c297c2c75a..f5207c1303 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c
@@ -14,10 +14,7 @@
#include "strings.h"
#include "ifconfig.h"
#include <compat.h>
-
-#include <sys/dlpi.h>
#include <libdlpi.h>
-
#include <inet/ip.h>
#define LOOPBACK_IF "lo0"
@@ -459,8 +456,7 @@ main(int argc, char *argv[])
}
if (!all) {
(void) fprintf(stderr,
- "ifconfig: %s: no such interface\n",
- name);
+ "ifconfig: %s: no such interface\n", name);
exit(1);
}
foreachinterface(ifconfig, argc, argv, af, onflags, offflags,
@@ -3778,21 +3774,33 @@ get_lun(char *rsrc)
* the utility must use SIOCSLIFMUXID.
*/
static void
-plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
+plumb_one_device(int af)
{
- int arp_fd = -1;
int arp_muxid = -1, ip_muxid;
- int mux_fd;
+ int mux_fd, ip_fd, arp_fd;
+ int retval;
+ uint_t ppa;
char *udp_dev_name;
- dlpi_if_attr_t dia;
+ char provider[DLPI_LINKNAME_MAX];
+ dlpi_handle_t dh_arp, dh_ip;
- if (debug)
- (void) printf("plumb_one_device: ifname %s, ppa %d\n",
- diap->ifname, diap->ppa);
+ /*
+ * We use DLPI_NOATTACH because the ip module will do the attach
+ * itself for DLPI style-2 devices.
+ */
+ retval = dlpi_open(name, &dh_ip, DLPI_NOATTACH);
+ if (retval != DLPI_SUCCESS)
+ Perrdlpi_exit("cannot open link", name, retval);
- if (diap->style == DL_STYLE2 && dlpi_detach(ip_fd, -1) < 0)
- Perror0_exit("dlpi_detach");
+ if ((retval = dlpi_parselink(name, provider, &ppa)) != DLPI_SUCCESS)
+ Perrdlpi_exit("dlpi_parselink", name, retval);
+ if (debug) {
+ (void) printf("ifconfig: plumb_one_device: provider %s,"
+ " ppa %u\n", provider, ppa);
+ }
+
+ ip_fd = dlpi_fd(dh_ip);
if (ioctl(ip_fd, I_PUSH, IP_MOD_NAME) == -1)
Perror2_exit("I_PUSH", IP_MOD_NAME);
@@ -3813,7 +3821,6 @@ plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
* At this point in time the kernel also allows an
* override of the CANTCHANGE flags.
*/
-
lifr.lifr_name[0] = '\0';
if (ioctl(ip_fd, SIOCGLIFFLAGS, (char *)&lifr) == -1)
Perror0_exit("plumb_one_device: SIOCGLIFFLAGS");
@@ -3828,7 +3835,7 @@ plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
}
/* record the device and module names as interface name */
- lifr.lifr_ppa = diap->ppa;
+ lifr.lifr_ppa = ppa;
(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
/* set the interface name */
@@ -3853,7 +3860,7 @@ plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
Perror0_exit("plumb_one_device: SIOCFLIFFLAGS");
if (debug) {
- (void) printf("plumb_one_device: %s got flags: \n",
+ (void) printf("ifconfig: plumb_one_device: %s got flags:\n",
lifr.lifr_name);
print_flags(lifr.lifr_flags);
(void) putchar('\n');
@@ -3885,9 +3892,8 @@ plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
* PLINK the interface stream so that ifconfig can exit
* without tearing down the stream.
*/
- if ((ip_muxid = ioctl(mux_fd, I_PLINK, ip_fd)) == -1) {
+ if ((ip_muxid = ioctl(mux_fd, I_PLINK, ip_fd)) == -1)
Perror0_exit("I_PLINK for ip");
- }
(void) close(mux_fd);
return;
}
@@ -3899,15 +3905,18 @@ plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
* Note: modules specified by the user are pushed
* only on the interface stream, not on the ARP stream.
*/
-
if (debug)
- (void) printf("plumb_one_device: ifname: %s\n",
- diap->ifname);
- arp_fd = dlpi_if_open(diap->ifname, &dia, _B_FALSE);
+ (void) printf("ifconfig: plumb_one_device: ifname: %s\n", name);
- if (dia.style == DL_STYLE2 && dlpi_detach(arp_fd, -1) < 0)
- Perror0_exit("dlpi_detach");
+ /*
+ * We use DLPI_NOATTACH because the arp module will do the attach
+ * itself for DLPI style-2 devices.
+ */
+ retval = dlpi_open(name, &dh_arp, DLPI_NOATTACH);
+ if (retval != DLPI_SUCCESS)
+ Perrdlpi_exit("cannot open link", name, retval);
+ arp_fd = dlpi_fd(dh_arp);
if (ioctl(arp_fd, I_PUSH, ARP_MOD_NAME) == -1)
Perror2_exit("I_PUSH", ARP_MOD_NAME);
@@ -3920,7 +3929,8 @@ plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
if (errno != EEXIST)
Perror0_exit("SIOCSLIFNAME for arp");
Perror0("SIOCSLIFNAME for arp");
- (void) close(arp_fd);
+ dlpi_close(dh_arp);
+ dlpi_close(dh_ip);
(void) close(mux_fd);
return;
}
@@ -3928,9 +3938,8 @@ plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
* PLINK the IP and ARP streams so that ifconfig can exit
* without tearing down the stream.
*/
- if ((ip_muxid = ioctl(mux_fd, I_PLINK, ip_fd)) == -1) {
+ if ((ip_muxid = ioctl(mux_fd, I_PLINK, ip_fd)) == -1)
Perror0_exit("I_PLINK for ip");
- }
if ((arp_muxid = ioctl(mux_fd, I_PLINK, arp_fd)) == -1) {
(void) ioctl(mux_fd, I_PUNLINK, ip_muxid);
Perror0_exit("I_PLINK for arp");
@@ -3938,7 +3947,8 @@ plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
if (debug)
(void) printf("arp muxid = %d\n", arp_muxid);
- (void) close(arp_fd);
+ dlpi_close(dh_ip);
+ dlpi_close(dh_arp);
(void) close(mux_fd);
}
@@ -4061,8 +4071,6 @@ static int
inetplumb(char *arg, int64_t param)
{
char *strptr;
- int dev_fd;
- dlpi_if_attr_t dia;
boolean_t islo;
zoneid_t zoneid;
@@ -4123,13 +4131,7 @@ inetplumb(char *arg, int64_t param)
if (debug)
(void) printf("inetplumb: %s af %d\n", name, afp->af_af);
- if ((dev_fd = dlpi_if_open(name, &dia, _B_FALSE)) < 0) {
- Perror2_exit("plumb", name);
- /* NOTREACHED */
- }
-
- plumb_one_device(&dia, dev_fd, afp->af_af);
- (void) close(dev_fd);
+ plumb_one_device(afp->af_af);
return (0);
}
@@ -4216,6 +4218,23 @@ Perror2_exit(char *cmd, char *str)
/* NOTREACHED */
}
+void
+Perrdlpi(const char *cmd, const char *linkname, int err)
+{
+ (void) fprintf(stderr, "ifconfig: %s \"%s\": %s\n", cmd,
+ linkname, dlpi_strerror(err));
+}
+
+/*
+ * Print out error message (Perrdlpi()) and exit
+ */
+void
+Perrdlpi_exit(const char *cmd, const char *linkname, int err)
+{
+ Perrdlpi(cmd, linkname, err);
+ exit(1);
+}
+
/*
* If the last argument is non-NULL allow a <addr>/<n> syntax and
* pass out <n> in *plenp.
@@ -4515,63 +4534,31 @@ add_ni(char *name)
static int
devfs_entry(di_node_t node, di_minor_t minor, void *arg)
{
- char *provider;
- int fd;
- uint_t ppa;
- dl_info_ack_t dlia;
- char ifname[LIFNAMSIZ];
+ char *provider;
+ char linkname[DLPI_LINKNAME_MAX];
+ dlpi_handle_t dh;
provider = di_minor_name(minor);
-
- if (strlen(provider) > LIFNAMSIZ)
- return (DI_WALK_CONTINUE);
-
if (debug > 2)
- fprintf(stderr, "provider = %s\n", provider);
+ (void) fprintf(stderr, "provider = %s\n", provider);
- if ((fd = dlpi_open(provider)) < 0)
+ if (dlpi_makelink(linkname, provider,
+ di_instance(node)) != DLPI_SUCCESS)
return (DI_WALK_CONTINUE);
- if (debug > 2)
- fprintf(stderr, "getting DL_INFO_ACK\n");
-
- if (dlpi_info(fd, -1, &dlia, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
- goto done;
-
- if (dlia.dl_provider_style == DL_STYLE1) {
- if (debug > 2)
- fprintf(stderr, "provider is DL_STYLE1\n");
- add_ni(provider);
- goto done;
- }
-
- if (debug > 2)
- fprintf(stderr, "provider is DL_STYLE2\n");
+ if (dlpi_open(linkname, &dh, 0) != DLPI_SUCCESS)
+ return (DI_WALK_CONTINUE);
- if (di_minor_type(minor) != DDM_ALIAS) {
+ if (di_minor_type(minor) == DDM_ALIAS) {
if (debug > 2)
- (void) fprintf(stderr,
- "non-alias node, ignoring\n");
- goto done;
- }
-
- if (debug > 2)
- (void) fprintf(stderr,
- "alias node, using instance\n");
- ppa = di_instance(node);
-
- if (dlpi_attach(fd, -1, ppa) < 0) {
+ (void) fprintf(stderr, "alias node, using instance\n");
+ add_ni(linkname);
+ } else {
if (debug > 2)
- (void) fprintf(stderr,
- "non-existent PPA, ignoring\n");
- goto done;
+ (void) fprintf(stderr, "non-alias node, ignoring\n");
}
- (void) snprintf(ifname, LIFNAMSIZ, "%s%d", provider, ppa);
- add_ni(ifname);
-
-done:
- (void) dlpi_close(fd);
+ dlpi_close(dh);
return (DI_WALK_CONTINUE);
}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.h b/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.h
index be5990ce13..49af9e8f0a 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.h
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
@@ -25,8 +25,6 @@ extern "C" {
#define BAD_ADDR -1 /* prefix is invalid */
#define NO_PREFIX -2 /* no prefix was found */
-#define MAX_MODS 9 /* max modules that can be pushed on intr */
-
/* No suitable header file defines this, though it's in libsocket */
extern int getnetmaskbyaddr(struct in_addr, struct in_addr *);
@@ -36,11 +34,13 @@ extern void Perror0(char *);
extern void Perror0_exit(char *);
extern void Perror2(char *, char *);
extern void Perror2_exit(char *, char *);
+extern void Perrdlpi(const char *, const char *, int);
+extern void Perrdlpi_exit(const char *, const char *, int);
-extern int doifrevarp(char *, struct sockaddr_in *);
+extern int doifrevarp(const char *, struct sockaddr_in *);
-extern int dlpi_set_address(char *, uchar_t *, int);
-extern void dlpi_print_address(char *);
+extern int dlpi_set_address(const char *, uchar_t *, uint_t);
+extern void dlpi_print_address(const char *);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/revarp.c b/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/revarp.c
index 6b20803da5..af798ca2c6 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/revarp.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/revarp.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,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -31,13 +30,15 @@
#include "defs.h"
#include "ifconfig.h"
#include <sys/types.h>
-#include <sys/dlpi.h>
#include <libdlpi.h>
#include <sys/sysmacros.h>
+#include <sys/time.h>
#include <deflt.h>
#define IPADDRL sizeof (struct in_addr)
#define RARPRETRIES 5
+#define MSEC2NSEC(msec) ((msec) * 1000000)
+#define NSEC2MSEC(nsec) ((nsec) / 1000000)
/*
* The following value (8) is determined to work reliably in switched 10/100MB
@@ -50,71 +51,66 @@ static char retries_var[] = "RARP_RETRIES=";
static int rarp_timeout = RARPTIMEOUT;
static int rarp_retries = RARPRETRIES;
-static int rarp_write(int, struct arphdr *, uchar_t *, size_t, size_t);
-static int rarp_open(char *, t_uscalar_t, size_t *, uchar_t **,
- uchar_t **);
+static dlpi_handle_t rarp_open(const char *, size_t *, uchar_t *, uchar_t *);
+static int rarp_recv(dlpi_handle_t, struct arphdr *, size_t, size_t, int64_t);
-/* ARGSUSED */
int
-doifrevarp(char *ifname, struct sockaddr_in *laddr)
+doifrevarp(const char *linkname, struct sockaddr_in *laddr)
{
- int if_fd;
- struct pollfd pfd;
- int s, flags, ret;
- char *ctlbuf, *databuf, *cause;
- struct strbuf ctl, data;
+ int s, retval;
struct arphdr *req, *ans;
struct in_addr from;
struct in_addr answer;
- union DL_primitives *dlp;
struct lifreq lifr;
- struct timeval senttime;
- struct timeval currenttime;
- int waittime;
int tries_left;
- size_t ifaddrlen, ifrarplen;
- uchar_t *my_macaddr = NULL, *my_broadcast = NULL;
+ size_t physaddrlen, ifrarplen;
+ uchar_t my_macaddr[DLPI_PHYSADDR_MAX];
+ uchar_t my_broadcast[DLPI_PHYSADDR_MAX];
+ dlpi_handle_t dh;
-
- if (ifname[0] == '\0') {
+ if (linkname[0] == '\0') {
(void) fprintf(stderr, "ifconfig: doifrevarp: name not set\n");
exit(1);
}
if (debug)
- (void) printf("doifrevarp interface %s\n", ifname);
+ (void) printf("doifrevarp interface %s\n", linkname);
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
Perror0_exit("socket");
- }
- (void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
- if (ioctl(s, SIOCGLIFFLAGS, (char *)&lifr) < 0)
+
+ (void) strlcpy(lifr.lifr_name, linkname, sizeof (lifr.lifr_name));
+ if (ioctl(s, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
+ (void) close(s);
Perror0_exit("SIOCGLIFFLAGS");
+ }
/* don't try to revarp if we know it won't work */
if ((lifr.lifr_flags & IFF_LOOPBACK) ||
(lifr.lifr_flags & IFF_NOARP) ||
- (lifr.lifr_flags & IFF_POINTOPOINT))
+ (lifr.lifr_flags & IFF_POINTOPOINT)) {
+ (void) close(s);
return (0);
+ }
/* open rarp interface */
- if_fd = rarp_open(ifname, ETHERTYPE_REVARP, &ifaddrlen, &my_macaddr,
- &my_broadcast);
- if (if_fd < 0)
+ dh = rarp_open(linkname, &physaddrlen, my_macaddr, my_broadcast);
+ if (dh == NULL) {
+ (void) close(s);
return (0);
+ }
/*
* RARP looks at /etc/ethers and NIS, which only works
* with 6 byte addresses currently.
*/
- if (ifaddrlen != ETHERADDRL) {
- (void) close(if_fd);
- free(my_macaddr);
- free(my_broadcast);
+ if (physaddrlen != ETHERADDRL) {
+ dlpi_close(dh);
+ (void) close(s);
return (0);
}
- ifrarplen = sizeof (struct arphdr) + (2 * IPADDRL) + (2 * ifaddrlen);
+ ifrarplen = sizeof (struct arphdr) + (2 * IPADDRL) + (2 * physaddrlen);
/* look for adjustments to rarp_retries in the RARP defaults file */
if (defopen(defaultfile) == 0) {
@@ -131,12 +127,11 @@ doifrevarp(char *ifname, struct sockaddr_in *laddr)
}
/* allocate request and response buffers */
- if (((req = (struct arphdr *)malloc(ifrarplen)) == NULL) ||
- ((ans = (struct arphdr *)malloc(ifrarplen)) == NULL)) {
- (void) close(if_fd);
+ if (((req = malloc(ifrarplen)) == NULL) ||
+ ((ans = malloc(ifrarplen)) == NULL)) {
+ dlpi_close(dh);
+ (void) close(s);
free(req);
- free(my_macaddr);
- free(my_broadcast);
return (0);
}
@@ -144,385 +139,249 @@ doifrevarp(char *ifname, struct sockaddr_in *laddr)
(void) memset(req, 0, ifrarplen);
req->ar_hrd = htons(ARPHRD_ETHER);
req->ar_pro = htons(ETHERTYPE_IP);
- req->ar_hln = ifaddrlen;
+ req->ar_hln = physaddrlen;
req->ar_pln = IPADDRL;
req->ar_op = htons(REVARP_REQUEST);
- (void) memcpy((uchar_t *)req + sizeof (struct arphdr), my_macaddr,
- ifaddrlen);
+ (void) memcpy(&req[1], my_macaddr, physaddrlen);
(void) memcpy((uchar_t *)req + sizeof (struct arphdr) + IPADDRL +
- ifaddrlen, my_macaddr, ifaddrlen);
-
- tries_left = rarp_retries;
-rarp_retry:
- /* send the request */
- if (rarp_write(if_fd, req, my_broadcast, ifaddrlen, ifrarplen) < 0)
- goto fail;
-
- gettimeofday(&senttime, NULL);
-
- if (debug)
- (void) printf("rarp sent\n");
-
-
- /* read the answers */
- if ((databuf = malloc(BUFSIZ)) == NULL) {
- (void) fprintf(stderr, "ifconfig: malloc() failed\n");
- goto fail;
- }
- if ((ctlbuf = malloc(BUFSIZ)) == NULL) {
- (void) fprintf(stderr, "ifconfig: malloc() failed\n");
- goto fail;
- }
- for (;;) {
- ctl.len = 0;
- ctl.maxlen = BUFSIZ;
- ctl.buf = ctlbuf;
- data.len = 0;
- data.maxlen = BUFSIZ;
- data.buf = databuf;
- flags = 0;
-
- /*
- * Check to see when the packet was last sent.
- * If we have not sent a packet in the last
- * RARP_TIMEOUT seconds, we should send one now.
- * Note that if some other host on the network is
- * sending a broadcast packet, poll will return and we
- * will find out that it does not match the reply we
- * are waiting for and then go back to poll. If the
- * frequency of such packets is > rarp_timeout, we don't
- * want to just go back to poll. We should send out one
- * more RARP request before blocking in poll.
- */
-
- gettimeofday(&currenttime, NULL);
- waittime = rarp_timeout -
- (currenttime.tv_sec - senttime.tv_sec);
-
- if (waittime <= 0) {
- if (--tries_left > 0) {
- if (debug)
- (void) printf("rarp retry\n");
- goto rarp_retry;
- } else {
- if (debug)
- (void) printf("rarp timeout\n");
- goto fail;
- }
- }
-
- /* start RARP reply timeout */
- pfd.fd = if_fd;
- pfd.events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI;
- if ((ret = poll(&pfd, 1, waittime * 1000)) == 0) {
- if (--tries_left > 0) {
- if (debug)
- (void) printf("rarp retry\n");
- goto rarp_retry;
- } else {
- if (debug)
- (void) printf("rarp timeout\n");
- goto fail;
- }
- } else if (ret == -1) {
- perror("ifconfig: RARP reply poll");
- goto fail;
+ physaddrlen, my_macaddr, physaddrlen);
+
+ for (tries_left = rarp_retries; tries_left > 0; --tries_left) {
+ /* send the request */
+ retval = dlpi_send(dh, my_broadcast, physaddrlen, req,
+ ifrarplen, NULL);
+ if (retval != DLPI_SUCCESS) {
+ Perrdlpi("doifrevarp: cannot send rarp request",
+ linkname, retval);
+ break;
}
- /* poll returned > 0 for this fd so getmsg should not block */
- if ((ret = getmsg(if_fd, &ctl, &data, &flags)) < 0) {
- perror("ifconfig: RARP reply getmsg");
- goto fail;
- }
+ if (debug)
+ (void) printf("rarp sent\n");
- if (debug) {
- (void) printf("rarp: ret[%d] ctl.len[%d] data.len[%d] "
- "flags[%d]\n", ret, ctl.len, data.len, flags);
- }
- /* Validate DL_UNITDATA_IND. */
- /* LINTED: malloc returns a pointer aligned for any use */
- dlp = (union DL_primitives *)ctlbuf;
- if (debug) {
- (void) printf("rarp: dl_primitive[%lu]\n",
- dlp->dl_primitive);
- if (dlp->dl_primitive == DL_ERROR_ACK) {
- (void) printf(
- "rarp: err ak: dl_errno %lu errno %lu\n",
- dlp->error_ack.dl_errno,
- dlp->error_ack.dl_unix_errno);
- }
- if (dlp->dl_primitive == DL_UDERROR_IND) {
- (void) printf("rarp: ud err: err[%lu] len[%lu] "
- "off[%lu]\n",
- dlp->uderror_ind.dl_errno,
- dlp->uderror_ind.dl_dest_addr_length,
- dlp->uderror_ind.dl_dest_addr_offset);
- }
- }
- (void) memcpy(ans, databuf, ifrarplen);
- cause = NULL;
- if (ret & MORECTL)
- cause = "MORECTL flag";
- else if (ret & MOREDATA)
- cause = "MOREDATA flag";
- else if (ctl.len == 0)
- cause = "missing control part of message";
- else if (ctl.len < 0)
- cause = "short control part of message";
- else if (dlp->dl_primitive != DL_UNITDATA_IND)
- cause = "not unitdata_ind";
- else if (ctl.len < DL_UNITDATA_IND_SIZE)
- cause = "short unitdata_ind";
-
- else if (data.len < ifrarplen)
- cause = "short arp";
- else if (ans->ar_hrd != htons(ARPHRD_ETHER))
- cause = "hrd";
- else if (ans->ar_pro != htons(ETHERTYPE_IP))
- cause = "pro";
- else if (ans->ar_hln != ifaddrlen)
- cause = "hln";
- else if (ans->ar_pln != IPADDRL)
- cause = "pln";
- if (cause) {
- (void) fprintf(stderr,
- "sanity check failed; cause: %s\n", cause);
- continue;
- }
+ retval = rarp_recv(dh, ans, ifrarplen, physaddrlen,
+ rarp_timeout * MILLISEC);
- switch (ntohs(ans->ar_op)) {
- case ARPOP_REQUEST:
- if (debug)
- (void) printf("Got an arp request\n");
+ if (retval != DLPI_ETIMEDOUT)
break;
- case ARPOP_REPLY:
- if (debug)
- (void) printf("Got an arp reply.\n");
- break;
-
- case REVARP_REQUEST:
- if (debug)
- (void) printf("Got a rarp request.\n");
- break;
+ if (debug)
+ (void) printf("rarp retry\n");
+ }
- case REVARP_REPLY:
+ if (retval == DLPI_SUCCESS) {
+ (void) memcpy(&answer, (uchar_t *)ans +
+ sizeof (struct arphdr) + (2 * physaddrlen) + IPADDRL,
+ sizeof (answer));
+ (void) memcpy(&from, (uchar_t *)ans + physaddrlen +
+ sizeof (struct arphdr), sizeof (from));
- (void) memcpy(&answer, (uchar_t *)ans +
- sizeof (struct arphdr) + (2 * ifaddrlen) +
- IPADDRL, sizeof (answer));
- (void) memcpy(&from, (uchar_t *)ans +
- sizeof (struct arphdr) + ifaddrlen, sizeof (from));
- if (debug) {
- (void) printf("answer: %s", inet_ntoa(answer));
- (void) printf(" [from %s]\n", inet_ntoa(from));
- }
- laddr->sin_addr = answer;
- (void) close(if_fd);
- free(req);
- free(ans);
- free(my_macaddr);
- free(my_broadcast);
- return (1);
-
- default:
- (void) fprintf(stderr,
- "ifconfig: unknown opcode 0x%xd\n", ans->ar_op);
- break;
+ if (debug) {
+ (void) printf("answer: %s", inet_ntoa(answer));
+ (void) printf(" [from %s]\n", inet_ntoa(from));
}
+ laddr->sin_addr = answer;
+ } else if (debug) {
+ Perrdlpi("doifrevarp: could not receive rarp reply",
+ linkname, retval);
}
- /* NOTREACHED */
-fail:
- (void) close(if_fd);
+
+ dlpi_close(dh);
+ (void) close(s);
free(req);
free(ans);
- free(my_macaddr);
- free(my_broadcast);
- return (0);
+ return (retval == DLPI_SUCCESS);
}
/*
* Open the datalink provider device and bind to the REVARP type.
- * Return the resulting descriptor.
+ * Return the resulting DLPI handle.
*/
-static int
-rarp_open(char *ifname, t_uscalar_t type, size_t *alen, uchar_t **myaddr,
- uchar_t **mybaddr)
+static dlpi_handle_t
+rarp_open(const char *linkname, size_t *alen, uchar_t *myaddr, uchar_t *mybaddr)
{
- int fd, len;
- char *str;
- dl_info_ack_t dlinfo;
- dlpi_if_attr_t dia;
- int i;
+ int retval;
+ char *physaddr, *bcastaddr;
+ dlpi_info_t dlinfo;
+ dlpi_handle_t dh;
if (debug)
- (void) printf("rarp_open %s\n", ifname);
+ (void) printf("rarp_open %s\n", linkname);
- fd = dlpi_if_open(ifname, &dia, _B_FALSE);
- if (fd < 0) {
- (void) fprintf(stderr, "ifconfig: could not open device for "
- "%s\n", ifname);
- return (-1);
+ if ((retval = dlpi_open(linkname, &dh, 0)) != DLPI_SUCCESS) {
+ Perrdlpi("rarp_open: dlpi_open failed", linkname, retval);
+ return (NULL);
}
- if (dlpi_info(fd, -1, &dlinfo, NULL, NULL, NULL, NULL, NULL,
- NULL) < 0) {
- (void) fprintf(stderr, "ifconfig: info req failed\n");
+ if ((retval = dlpi_bind(dh, ETHERTYPE_REVARP, NULL)) != DLPI_SUCCESS) {
+ Perrdlpi("rarp_open: dlpi_bind failed", linkname, retval);
goto failed;
}
- if ((*mybaddr = malloc(dlinfo.dl_brdcst_addr_length)) == NULL) {
- (void) fprintf(stderr, "rarp_open: malloc() failed\n");
+ if ((retval = dlpi_info(dh, &dlinfo, 0)) != DLPI_SUCCESS) {
+ Perrdlpi("rarp_open: dlpi_info failed", linkname, retval);
goto failed;
}
- if (dlpi_info(fd, -1, &dlinfo, NULL, NULL, NULL, NULL, *mybaddr,
- NULL) < 0) {
- (void) fprintf(stderr, "ifconfig: info req failed\n");
+ if (dlinfo.di_bcastaddrlen == 0) {
+ (void) fprintf(stderr, "ifconfig: rarp_open: %s broadcast "
+ "not supported\n", linkname);
goto failed;
}
- if (debug) {
- (void) printf("broadcast addr: ");
- for (i = 0; i < dlinfo.dl_brdcst_addr_length; i++)
- (void) printf("%02x", (*mybaddr)[i]);
- (void) printf("\n");
- }
+ /* we assume the following are equal and fill in 'alen' */
+ assert(dlinfo.di_bcastaddrlen == dlinfo.di_physaddrlen);
- len = *alen = dlinfo.dl_addr_length - abs(dlinfo.dl_sap_length);
+ (void) memcpy(mybaddr, dlinfo.di_bcastaddr, dlinfo.di_bcastaddrlen);
- if (debug)
- (void) printf("rarp_open: addr length = %d\n", len);
+ *alen = dlinfo.di_physaddrlen;
- if ((*myaddr = malloc(len)) == NULL) {
- (void) fprintf(stderr, "rarp_open: malloc() failed\n");
- goto failed;
- }
-
- if (dlpi_bind(fd, -1, type, DL_CLDLS, _B_FALSE, NULL, NULL,
- *myaddr, NULL) < 0) {
- (void) fprintf(stderr, "rarp_open: dlpi_bind failed\n");
- goto failed;
- }
+ (void) memcpy(myaddr, dlinfo.di_physaddr, dlinfo.di_physaddrlen);
if (debug) {
- str = _link_ntoa(*myaddr, str, len, IFT_OTHER);
- if (str != NULL) {
- (void) printf("device %s mac address %s\n",
- ifname, str);
- free(str);
+ bcastaddr = _link_ntoa(mybaddr, NULL, dlinfo.di_bcastaddrlen,
+ IFT_OTHER);
+
+ physaddr = _link_ntoa(myaddr, NULL, dlinfo.di_physaddrlen,
+ IFT_OTHER);
+
+ if (physaddr != NULL && bcastaddr != NULL) {
+ (void) printf("device %s: broadcast address %s, mac "
+ "address %s\n", linkname, bcastaddr, physaddr);
}
+
+ free(physaddr);
+ free(bcastaddr);
+
+ (void) printf("rarp_open: addr length = %d\n",
+ dlinfo.di_physaddrlen);
}
- return (fd);
+ return (dh);
failed:
- (void) dlpi_close(fd);
- free(*mybaddr);
- free(*myaddr);
- return (-1);
+ dlpi_close(dh);
+ return (NULL);
}
+/*
+ * Read reply for RARP request. If a reply is received within waitms,
+ * validate the reply. If it is a correct RARP reply return DLPI_SUCCESS,
+ * otherwise return DLPI_ETIMEDOUT. If there is an error while reading retrun
+ * the error code.
+ */
static int
-rarp_write(int fd, struct arphdr *ahdr, uchar_t *dhost, size_t maclen,
- size_t rarplen)
+rarp_recv(dlpi_handle_t dh, struct arphdr *ans, size_t msglen,
+ size_t physaddrlen, int64_t waitms)
{
- struct strbuf ctl, data;
- union DL_primitives *dlp;
- char *ctlbuf;
- int ret;
- ushort_t etype = ETHERTYPE_REVARP;
+ int retval;
+ char *cause;
+ size_t anslen = msglen;
+ hrtime_t endtime = gethrtime() + MSEC2NSEC(waitms);
+ hrtime_t currtime;
+
+ while ((currtime = gethrtime()) < endtime) {
+ waitms = NSEC2MSEC(endtime - currtime);
+ retval = dlpi_recv(dh, NULL, NULL, ans, &anslen, waitms, NULL);
+ if (retval == DLPI_SUCCESS) {
+ cause = NULL;
+
+ if (anslen < msglen)
+ cause = "short packet";
+ else if (ans->ar_hrd != htons(ARPHRD_ETHER))
+ cause = "hardware type not Ethernet";
+ else if (ans->ar_pro != htons(ETHERTYPE_IP))
+ cause = "protocol type not IP";
+ else if (ans->ar_hln != physaddrlen)
+ cause = "unexpected hardware address length";
+ else if (ans->ar_pln != IPADDRL)
+ cause = "unexpected protocol address length";
+ if (cause != NULL) {
+ (void) fprintf(stderr, "RARP packet received "
+ "but discarded (%s)\n", cause);
+ continue;
+ }
+ switch (ntohs(ans->ar_op)) {
+ case REVARP_REQUEST:
+ if (debug)
+ (void) printf("Got a rarp request.\n");
+ break;
- /*
- * Construct DL_UNITDATA_REQ. Allocate at least BUFSIZ bytes.
- */
- ctl.len = DL_UNITDATA_REQ_SIZE + maclen + sizeof (ushort_t);
- if ((ctl.buf = ctlbuf = malloc(ctl.len)) == NULL) {
- (void) fprintf(stderr, "ifconfig: malloc() failed\n");
- return (-1);
+ case REVARP_REPLY:
+ return (DLPI_SUCCESS);
+
+ default:
+ (void) fprintf(stderr, "ifconfig: unknown "
+ "RARP opcode 0x%x\n", ans->ar_op);
+ break;
+ }
+ } else if (retval != DLPI_ETIMEDOUT) {
+ Perrdlpi("doifrevarp: dlpi_recv failed",
+ dlpi_linkname(dh), retval);
+ return (retval);
+ }
}
- /* LINTED: malloc returns a pointer aligned for any use */
- dlp = (union DL_primitives *)ctlbuf;
- dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ;
- dlp->unitdata_req.dl_dest_addr_length = maclen + sizeof (ushort_t);
- dlp->unitdata_req.dl_dest_addr_offset = DL_UNITDATA_REQ_SIZE;
- dlp->unitdata_req.dl_priority.dl_min = 0;
- dlp->unitdata_req.dl_priority.dl_max = 0;
- /*
- * XXX FIXME Assumes a specific DLPI address format.
- */
- (void) memcpy(ctlbuf + DL_UNITDATA_REQ_SIZE, dhost, maclen);
- (void) memcpy(ctlbuf + DL_UNITDATA_REQ_SIZE + maclen, &etype,
- sizeof (etype));
-
- /* Send DL_UNITDATA_REQ. */
- data.len = rarplen;
- data.buf = (char *)ahdr;
- ret = putmsg(fd, &ctl, &data, 0);
- free(ctlbuf);
- return (ret);
+ return (DLPI_ETIMEDOUT);
}
int
-dlpi_set_address(char *ifname, uchar_t *ea, int length)
+dlpi_set_address(const char *linkname, uchar_t *physaddr, uint_t physaddrlen)
{
- int fd;
- dlpi_if_attr_t dia;
+ int retval;
+ dlpi_handle_t dh;
- fd = dlpi_if_open(ifname, &dia, _B_FALSE);
- if (fd < 0) {
- (void) fprintf(stderr, "ifconfig: could not open device for "
- "%s\n", ifname);
+ if ((retval = dlpi_open(linkname, &dh, 0)) != DLPI_SUCCESS) {
+ Perrdlpi("dlpi_open failed", linkname, retval);
return (-1);
}
- if (dlpi_set_phys_addr(fd, -1, ea, length) < 0) {
- (void) dlpi_close(fd);
+ if ((retval = dlpi_set_physaddr(dh, DL_CURR_PHYS_ADDR, physaddr,
+ physaddrlen)) != DLPI_SUCCESS) {
+ Perrdlpi("dlpi_set_physaddr failed", linkname, retval);
+ dlpi_close(dh);
return (-1);
}
- (void) dlpi_close(fd);
+ dlpi_close(dh);
return (0);
}
void
-dlpi_print_address(char *ifname)
+dlpi_print_address(const char *linkname)
{
- int fd, len;
- uchar_t *laddr;
- dl_info_ack_t dl_info;
- char *str = NULL;
- dlpi_if_attr_t dia;
-
- fd = dlpi_if_open(ifname, &dia, _B_FALSE);
- if (fd < 0) {
+ uint_t physaddrlen = DLPI_PHYSADDR_MAX;
+ uchar_t physaddr[DLPI_PHYSADDR_MAX];
+ char *str;
+ int retv;
+ dlpi_handle_t dh;
+ dlpi_info_t dlinfo;
+
+ if (dlpi_open(linkname, &dh, 0) != DLPI_SUCCESS) {
/* Do not report an error */
return;
}
- if (dlpi_info(fd, -1, &dl_info, NULL, NULL, NULL, NULL, NULL,
- NULL) < 0) {
- (void) fprintf(stderr, "ifconfig: info req failed\n");
- (void) dlpi_close(fd);
+ retv = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, physaddr, &physaddrlen);
+ if (retv != DLPI_SUCCESS) {
+ Perrdlpi("dlpi_get_physaddr failed", linkname, retv);
+ dlpi_close(dh);
return;
}
- len = dl_info.dl_addr_length - abs(dl_info.dl_sap_length);
- if ((laddr = malloc(len)) == NULL) {
- goto failed;
+ retv = dlpi_info(dh, &dlinfo, 0);
+ if (retv != DLPI_SUCCESS) {
+ Perrdlpi("dlpi_info failed", linkname, retv);
+ dlpi_close(dh);
+ return;
}
+ dlpi_close(dh);
- if (dlpi_phys_addr(fd, -1, DL_CURR_PHYS_ADDR, laddr, NULL) < 0) {
- (void) fprintf(stderr, "ifconfig: phys_addr failed\n");
- goto failed;
- }
+ str = _link_ntoa(physaddr, NULL, physaddrlen, IFT_OTHER);
- (void) dlpi_close(fd);
- str = _link_ntoa(laddr, str, len, IFT_OTHER);
if (str != NULL) {
- switch (dl_info.dl_mac_type) {
+ switch (dlinfo.di_mactype) {
case DL_IB:
(void) printf("\tipib %s \n", str);
break;
@@ -532,8 +391,4 @@ dlpi_print_address(char *ifname)
}
free(str);
}
-
-failed:
- free(laddr);
- (void) dlpi_close(fd);
}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile
index 4be340b128..ee1dec05cb 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile
@@ -28,7 +28,7 @@
#
PROG= snoop
-OBJS= dlprims.o nfs4_xdr.o snoop.o snoop_aarp.o snoop_adsp.o snoop_aecho.o \
+OBJS= nfs4_xdr.o snoop.o snoop_aarp.o snoop_adsp.o snoop_aecho.o \
snoop_apple.o snoop_arp.o snoop_atp.o snoop_bparam.o \
snoop_capture.o snoop_dhcp.o snoop_dhcpv6.o snoop_display.o \
snoop_dns.o snoop_ether.o \
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c
index ff43c225a7..fc083aeeb0 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -110,7 +110,6 @@ main(int argc, char **argv)
int Cflg = 0;
int first = 1;
int last = 0x7fffffff;
- int ppa;
int use_kern_pf;
char *p, *p2;
char names[MAXPATHLEN + 1];
@@ -123,6 +122,7 @@ main(int argc, char **argv)
stack_t sigstk;
char *output_area;
int nbytes;
+ dlpi_handle_t dh;
names[0] = '\0';
/*
@@ -361,7 +361,7 @@ main(int argc, char **argv)
* requested was chosen, but that's too hard.
*/
if (!icapfile) {
- use_kern_pf = check_device(&device, &ppa);
+ use_kern_pf = check_device(&dh, &device);
} else {
cap_open_read(icapfile);
@@ -479,11 +479,12 @@ main(int argc, char **argv)
timeout.tv_usec = 0;
}
- initdevice(device, snaplen, chunksize, &timeout, fp, ppa);
+ initdevice(dh, snaplen, chunksize, &timeout, fp);
if (! qflg && ocapfile)
show_count();
resetperm();
- net_read(chunksize, filter, proc, flags);
+ net_read(dh, chunksize, filter, proc, flags);
+ dlpi_close(dh);
if (!(flags & F_NOW))
(void) printf("\n");
@@ -733,6 +734,25 @@ pr_err(const char *fmt, ...)
}
/*
+ * Store a copy of linkname associated with the DLPI handle.
+ * Save errno before closing the dlpi handle so that the
+ * correct error value is used if 'err' is a system error.
+ */
+void
+pr_errdlpi(dlpi_handle_t dh, const char *cmd, int err)
+{
+ int save_errno = errno;
+ char linkname[DLPI_LINKNAME_MAX];
+
+ (void) strlcpy(linkname, dlpi_linkname(dh), sizeof (linkname));
+
+ dlpi_close(dh);
+ errno = save_errno;
+
+ pr_err("%s on \"%s\": %s", cmd, linkname, dlpi_strerror(err));
+}
+
+/*
* Ye olde usage proc
* PLEASE keep this up to date!
* Naive users *love* this stuff.
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h
index ff40866bd4..e9274319f2 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h
@@ -44,6 +44,7 @@
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
#include <net/pppoe.h>
+#include <libdlpi.h>
#ifdef __cplusplus
extern "C" {
@@ -176,14 +177,14 @@ extern int pf_compile(char *, int);
extern void compile(char *, int);
extern void load_names(char *);
extern void cap_write(struct sb_hdr *, char *, int, int);
-extern void cap_open_read(char *);
-extern void cap_open_write(char *);
+extern void cap_open_read(const char *);
+extern void cap_open_write(const char *);
extern void cap_read(int, int, int, void (*)(), int);
extern void cap_close(void);
-extern boolean_t check_device(char **, int *);
-extern void initdevice(char *, ulong_t, ulong_t, struct timeval *,
- struct Pf_ext_packetfilt *, int);
-extern void net_read(int, int, void (*)(), int);
+extern boolean_t check_device(dlpi_handle_t *, char **);
+extern void initdevice(dlpi_handle_t, ulong_t, ulong_t, struct timeval *,
+ struct Pf_ext_packetfilt *);
+extern void net_read(dlpi_handle_t, size_t, int, void (*)(), int);
extern void click(int);
extern void show_pktinfo(int, int, char *, char *, struct timeval *,
struct timeval *, int, int);
@@ -193,6 +194,7 @@ extern char *showxdr_time(char *);
extern char *addrtoname(int, const void *);
extern char *show_string(const char *, int, int);
extern void pr_err(const char *, ...);
+extern void pr_errdlpi(dlpi_handle_t, const char *, int);
extern void check_retransmit(char *, ulong_t);
extern char *nameof_prog(int);
extern char *getproto(int);
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c
index 5d24744e66..206835c407 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c
@@ -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.
*/
@@ -45,7 +45,6 @@
#include <sys/stat.h>
#include <sys/stropts.h>
#include <sys/bufmod.h>
-#include <sys/dlpi.h>
#include <unistd.h>
#include <stropts.h>
@@ -75,74 +74,27 @@ void convert_to_network();
void convert_from_network();
static void convert_old(struct ohdr *);
extern sigjmp_buf jmp_env, ojmp_env;
-static int netfd;
-static union DL_primitives netdl; /* info_ack for interface */
+static dlpi_info_t dlinfo;
static char *bufp; /* pointer to read buffer */
static int strioctl(int, int, int, int, void *);
/*
- * Convert a device id to a ppa value
- * e.g. "le0" -> 0
- */
-static int
-device_ppa(char *device)
-{
- char *p;
- char *tp;
-
- p = strpbrk(device, "0123456789");
- if (p == NULL)
- return (0);
- /* ignore numbers within device names */
- for (tp = p; *tp != '\0'; tp++)
- if (!isdigit(*tp))
- return (device_ppa(tp));
- return (atoi(p));
-}
-
-/*
- * Convert a device id to a pathname.
- * Level 1 devices: "le0" -> "/dev/le0".
- * Level 2 devices: "le0" -> "/dev/le".
- */
-static char *
-device_path(char *device)
-{
- static char buff[IF_NAMESIZE + 1];
- struct stat st;
- char *p;
-
- (void) strcpy(buff, "/dev/");
- (void) strlcat(buff, device, IF_NAMESIZE);
-
- if (stat(buff, &st) == 0)
- return (buff);
-
- for (p = buff + (strlen(buff) - 1); p > buff; p--) {
- if (isdigit(*p))
- *p = '\0';
- else
- break;
- }
- return (buff);
-}
-
-/*
- * Open up the device, and start finding out something about it,
- * especially stuff about the data link headers. We need that information
+ * Open up the device in raw mode and passive mode
+ * (see dlpi_open(3DLPI)) and start finding out something about it,
+ * especially stuff about the data link headers. We need that information
* to build the proper packet filters.
*/
boolean_t
-check_device(char **devicep, int *ppap)
+check_device(dlpi_handle_t *dhp, char **devicep)
{
- char *devname;
+ int retval;
+
/*
* Determine which network device
* to use if none given.
* Should get back a value like "le0".
*/
-
if (*devicep == NULL) {
char *cbuf;
static struct ifconf ifc;
@@ -199,78 +151,51 @@ check_device(char **devicep, int *ppap)
(void) close(s);
}
- devname = device_path(*devicep);
- if ((netfd = open(devname, O_RDWR)) < 0)
- pr_err("%s: %m", devname);
-
- *ppap = device_ppa(*devicep);
-
- /*
- * Check for DLPI Version 2.
- */
- dlinforeq(netfd, &netdl);
- if (netdl.info_ack.dl_version != DL_VERSION_2)
- pr_err("DL_INFO_ACK: incompatible version %d",
- netdl.info_ack.dl_version);
-
- /*
- * Attach for DLPI Style 2.
- */
- if (netdl.info_ack.dl_provider_style == DL_STYLE2) {
- dlattachreq(netfd, *ppap);
- /* Reread more specific information */
- dlinforeq(netfd, &netdl);
+ retval = dlpi_open(*devicep, dhp, DLPI_PASSIVE|DLPI_RAW);
+ if (retval != DLPI_SUCCESS) {
+ pr_err("cannot open \"%s\": %s", *devicep,
+ dlpi_strerror(retval));
}
- /* Enable passive mode so that we can snoop on aggregated links. */
- dlpi_passive(netfd, -1);
+ if ((retval = dlpi_info(*dhp, &dlinfo, 0)) != DLPI_SUCCESS)
+ pr_errdlpi(*dhp, "dlpi_info failed", retval);
for (interface = &INTERFACES[0]; interface->mac_type != -1; interface++)
- if (interface->mac_type == netdl.info_ack.dl_mac_type)
+ if (interface->mac_type == dlinfo.di_mactype)
break;
- /* allow limited functionality even is interface isn't known */
+ /* allow limited functionality even if interface isn't known */
if (interface->mac_type == -1) {
- fprintf(stderr,
- "snoop: WARNING: Mac Type = %lx not supported\n",
- netdl.info_ack.dl_mac_type);
+ (void) fprintf(stderr, "snoop: WARNING: Mac Type = %x "
+ "not supported\n", dlinfo.di_mactype);
}
/* for backward compatibility, allow known interface mtu_sizes */
- if (interface->mtu_size > (uint_t)netdl.info_ack.dl_max_sdu)
- netdl.info_ack.dl_max_sdu = (t_scalar_t)interface->mtu_size;
+ if (interface->mtu_size > dlinfo.di_max_sdu)
+ dlinfo.di_max_sdu = interface->mtu_size;
return (interface->try_kernel_filter);
}
/*
* Do whatever is necessary to initialize the interface
- * for packet capture. Bind the device opened and attached (if DL_STYLE2)
- * in check_device(), request raw ethernet packets and set promiscuous mode,
- * push the streams buffer module and packet filter module, set various buffer
- * parameters.
+ * for packet capture. Bind the device opened in check_device(), set
+ * promiscuous mode, push the streams buffer module and packet filter
+ * module, set various buffer parameters.
*/
-/* ARGSUSED */
void
-initdevice(device, snaplen, chunksize, timeout, fp, ppa)
- char *device;
- ulong_t snaplen, chunksize;
- struct timeval *timeout;
- struct Pf_ext_packetfilt *fp;
- int ppa;
+initdevice(dlpi_handle_t dh, ulong_t snaplen, ulong_t chunksize,
+ struct timeval *timeout, struct Pf_ext_packetfilt *fp)
{
extern int Pflg;
+ int retv;
+ int netfd;
- /*
- * Bind to SAP 2 on token ring, 0 on other interface types.
- * (SAP 0 has special significance on token ring)
- */
- if (interface->mac_type == DL_TPR)
- dlbindreq(netfd, 2, 0, DL_CLDLS, 0);
- else
- dlbindreq(netfd, 0, 0, DL_CLDLS, 0);
+ retv = dlpi_bind(dh, DLPI_ANY_SAP, NULL);
+ if (retv != DLPI_SUCCESS)
+ pr_errdlpi(dh, "cannot bind on", retv);
- (void) fprintf(stderr, "Using device %s ", device_path(device));
+ (void) fprintf(stderr, "Using device %s ", dlpi_linkname(dh));
/*
* If Pflg not set - use physical level
@@ -278,67 +203,59 @@ initdevice(device, snaplen, chunksize, timeout, fp, ppa)
*/
if (!Pflg) {
(void) fprintf(stderr, "(promiscuous mode)\n");
- dlpromiscon(netfd, DL_PROMISC_PHYS);
+ retv = dlpi_promiscon(dh, DL_PROMISC_PHYS);
+ if (retv != DLPI_SUCCESS) {
+ pr_errdlpi(dh, "promiscuous mode(physical) failed",
+ retv);
+ }
} else {
(void) fprintf(stderr, "(non promiscuous)\n");
- dlpromiscon(netfd, DL_PROMISC_MULTI);
+ retv = dlpi_promiscon(dh, DL_PROMISC_MULTI);
+ if (retv != DLPI_SUCCESS) {
+ pr_errdlpi(dh, "promiscuous mode(multicast) failed",
+ retv);
+ }
}
- dlpromiscon(netfd, DL_PROMISC_SAP);
+ retv = dlpi_promiscon(dh, DL_PROMISC_SAP);
+ if (retv != DLPI_SUCCESS)
+ pr_errdlpi(dh, "promiscuous mode(SAP) failed", retv);
- if (ioctl(netfd, DLIOCRAW, 0) < 0) {
- (void) close(netfd);
- pr_err("ioctl: DLIOCRAW: %s: %m", device_path(device));
- }
+ netfd = dlpi_fd(dh);
if (fp) {
/*
* push and configure the packet filtering module
*/
- if (ioctl(netfd, I_PUSH, "pfmod") < 0) {
- (void) close(netfd);
- pr_err("ioctl: I_PUSH pfmod: %s: %m",
- device_path(device));
- }
+ if (ioctl(netfd, I_PUSH, "pfmod") < 0)
+ pr_errdlpi(dh, "cannot push \"pfmod\"", DL_SYSERR);
if (strioctl(netfd, PFIOCSETF, -1, sizeof (*fp),
- (char *)fp) < 0) {
- (void) close(netfd);
- pr_err("PFIOCSETF: %s: %m", device_path(device));
- }
+ (char *)fp) < 0)
+ pr_errdlpi(dh, "PFIOCSETF", DL_SYSERR);
}
- if (ioctl(netfd, I_PUSH, "bufmod") < 0) {
- (void) close(netfd);
- pr_err("push bufmod: %s: %m", device_path(device));
- }
+ if (ioctl(netfd, I_PUSH, "bufmod") < 0)
+ pr_errdlpi(dh, "cannot push \"bufmod\"", DL_SYSERR);
if (strioctl(netfd, SBIOCSTIME, -1, sizeof (struct timeval),
- (char *)timeout) < 0) {
- (void) close(netfd);
- pr_err("SBIOCSTIME: %s: %m", device_path(device));
- }
+ (char *)timeout) < 0)
+ pr_errdlpi(dh, "SBIOCSTIME", DL_SYSERR);
if (strioctl(netfd, SBIOCSCHUNK, -1, sizeof (uint_t),
- (char *)&chunksize) < 0) {
- (void) close(netfd);
- pr_err("SBIOCGCHUNK: %s: %m", device_path(device));
- }
+ (char *)&chunksize) < 0)
+ pr_errdlpi(dh, "SBIOCGCHUNK", DL_SYSERR);
if (strioctl(netfd, SBIOCSSNAP, -1, sizeof (uint_t),
- (char *)&snaplen) < 0) {
- (void) close(netfd);
- pr_err("SBIOCSSNAP: %s: %m", device_path(device));
- }
+ (char *)&snaplen) < 0)
+ pr_errdlpi(dh, "SBIOCSSNAP", DL_SYSERR);
/*
* Flush the read queue, to get rid of anything that
* accumulated before the device reached its final configuration.
*/
- if (ioctl(netfd, I_FLUSH, FLUSHR) < 0) {
- (void) close(netfd);
- pr_err("I_FLUSH: %s: %m", device_path(device));
- }
+ if (ioctl(netfd, I_FLUSH, FLUSHR) < 0)
+ pr_errdlpi(dh, "cannot flush \"I_FLUSH\"", DL_SYSERR);
}
/*
@@ -349,54 +266,38 @@ initdevice(device, snaplen, chunksize, timeout, fp, ppa)
* or interpreted for display on the fly.
*/
void
-net_read(chunksize, filter, proc, flags)
- int chunksize, filter;
- void (*proc)();
- int flags;
+net_read(dlpi_handle_t dh, size_t chunksize, int filter, void (*proc)(),
+ int flags)
{
- int r = 0;
- struct strbuf data;
- int flgs;
+ int retval;
extern int count;
+ size_t msglen;
- data.len = 0;
count = 0;
/* allocate a read buffer */
-
bufp = malloc(chunksize);
if (bufp == NULL)
- pr_err("no memory for %dk buffer", chunksize);
+ pr_err("no memory for %d buffer", chunksize);
/*
- * read frames
+ * read frames
*/
for (;;) {
- data.maxlen = chunksize;
- data.len = 0;
- data.buf = bufp;
- flgs = 0;
-
- r = getmsg(netfd, NULL, &data, &flgs);
+ msglen = chunksize;
+ retval = dlpi_recv(dh, NULL, NULL, bufp, &msglen, -1, NULL);
- if (r < 0 || quitting)
+ if (retval != DLPI_SUCCESS || quitting)
break;
- if (data.len <= 0)
- continue;
-
- scan(bufp, data.len, filter, 0, 0, proc, 0, 0, flags);
+ if (msglen != 0)
+ scan(bufp, msglen, filter, 0, 0, proc, 0, 0, flags);
}
free(bufp);
- (void) close(netfd);
- if (!quitting) {
- if (r < 0)
- pr_err("network read failed: %m");
- else
- pr_err("network read returned %d", r);
- }
+ if (!quitting)
+ pr_errdlpi(dh, "network read failed", retval);
}
#ifdef DEBUG
@@ -512,24 +413,24 @@ scan(char *buf, int len, int filter, int cap, int old, void (*proc)(),
(nhdrp->sbh_totlen < nhdrp->sbh_msglen) ||
(nhdrp->sbh_timestamp.tv_sec == 0)) {
if (cap)
- fprintf(stderr, "(warning) bad packet header "
- "in capture file");
+ (void) fprintf(stderr, "(warning) bad packet "
+ "header in capture file");
else
- fprintf(stderr, "(warning) bad packet header "
- "in buffer");
+ (void) fprintf(stderr, "(warning) bad packet "
+ "header in buffer");
(void) fprintf(stderr, " offset %d: length=%d\n",
bp - buf, nhdrp->sbh_totlen);
goto err;
}
if (nhdrp->sbh_totlen >
- (uint_t)(netdl.info_ack.dl_max_sdu + MAX_HDRTRAILER)) {
+ (dlinfo.di_max_sdu + MAX_HDRTRAILER)) {
if (cap)
- fprintf(stderr, "(warning) packet length "
- "greater than MTU in capture file");
+ (void) fprintf(stderr, "(warning) packet length"
+ " greater than MTU in capture file");
else
- fprintf(stderr, "(warning) packet length "
- "greater than MTU in buffer");
+ (void) fprintf(stderr, "(warning) packet length"
+ " greater than MTU in buffer");
(void) fprintf(stderr, " offset %d: length=%d\n",
bp - buf, nhdrp->sbh_totlen);
@@ -542,7 +443,7 @@ scan(char *buf, int len, int filter, int cap, int old, void (*proc)(),
* a warning.
*/
if (pktp + nhdrp->sbh_msglen > bufstop) {
- fprintf(stderr, "truncated packet buffer\n");
+ (void) fprintf(stderr, "truncated packet buffer\n");
nhdrp->sbh_msglen = bufstop - pktp;
}
@@ -574,7 +475,8 @@ scan(char *buf, int len, int filter, int cap, int old, void (*proc)(),
}
if (maxcount && count >= maxcount) {
- fprintf(stderr, "%d packets captured\n", count);
+ (void) fprintf(stderr, "%d packets captured\n",
+ count);
exit(0);
}
@@ -692,8 +594,7 @@ static const int snoop_idlen = 8;
static const int snoop_version = 2;
void
-cap_open_write(name)
- char *name;
+cap_open_write(const char *name)
{
int vers;
@@ -721,8 +622,7 @@ static int cap_len = 0;
static int cap_new;
void
-cap_open_read(name)
- char *name;
+cap_open_read(const char *name)
{
struct stat st;
int cap_vers;
@@ -795,15 +695,11 @@ cap_open_read(name)
if (mprotect(cap_buffp, cap_len, PROT_READ | PROT_WRITE) < 0)
pr_err("mprotect: %s: %m", name);
}
- netdl.info_ack.dl_max_sdu = MAXINT; /* Decode any stored packet. */
+ dlinfo.di_max_sdu = MAXINT; /* Decode any stored packet. */
}
void
-cap_read(first, last, filter, proc, flags)
- int first, last;
- int filter;
- void (*proc)();
- int flags;
+cap_read(int first, int last, int filter, void (*proc)(), int flags)
{
extern int count;
@@ -816,10 +712,7 @@ cap_read(first, last, filter, proc, flags)
/* ARGSUSED */
void
-cap_write(hdrp, pktp, num, flags)
- struct sb_hdr *hdrp;
- char *pktp;
- int num, flags;
+cap_write(struct sb_hdr *hdrp, char *pktp, int num, int flags)
{
int pktlen, mac;
static int first = 1;
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/syncinit.c b/usr/src/cmd/cmd-inet/usr.sbin/syncinit.c
index d93bd2a531..de300e4d92 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/syncinit.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/syncinit.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,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -98,22 +97,21 @@ static char *portab[] = {
#endif
#define equal(a, b) (strcmp((a), (b)) == 0)
-#define MAXWAIT 15
int
main(int argc, char **argv)
{
- char cnambuf[MAXPATHLEN];
+ char cnambuf[DLPI_LINKNAME_MAX], device[DLPI_LINKNAME_MAX];
struct scc_mode sm;
struct strioctl sioc;
int fd, speed;
+ int retval;
char *arg, *cp;
char loopchange = 0;
char echochange = 0;
char clockchange = 0;
- char *devstr = "/dev/";
- int devstrlen;
- ulong_t ppa;
+ uint_t ppa;
+ dlpi_handle_t dh;
if (argc == 1) {
usage();
@@ -121,41 +119,35 @@ main(int argc, char **argv)
}
argc--;
argv++;
- devstrlen = strlen(devstr);
- if (strncmp(devstr, argv[0], devstrlen) != 0) {
- if (snprintf(cnambuf, sizeof (cnambuf), "%s%s", devstr,
- argv[0]) >= sizeof (cnambuf)) {
- (void) fprintf(stderr,
- "syncinit: invalid device name (too long) %s\n",
- argv[0]);
- exit(1);
- }
+
+ if (strlcpy(cnambuf, argv[0], sizeof (cnambuf)) >=
+ sizeof (cnambuf)) {
+ (void) fprintf(stderr,
+ "syncinit: invalid device name (too long) %s\n", argv[0]);
+ exit(1);
}
+
cp = cnambuf;
while (*cp) /* find the end of the name */
cp++;
cp--;
if (!isdigit(*cp)) {
(void) fprintf(stderr,
- "syncinit: %s missing minor device number\n", argv[0]);
- exit(1);
- }
- while (isdigit(*(cp - 1)))
- cp--;
- ppa = strtoul(cp, NULL, 10);
- *cp = '\0'; /* drop number, leaving name of clone device. */
- fd = open(cnambuf, O_RDWR|O_EXCL, 0);
- if (fd < 0) {
- perror("syncinit: open");
+ "syncinit: %s missing minor device number\n", cnambuf);
exit(1);
}
- if (dlpi_attach(fd, MAXWAIT, ppa) != 0) {
- perror("syncinit: dlpi_attach");
+ retval = dlpi_open(cnambuf, &dh, DLPI_EXCL|DLPI_SERIAL);
+ if (retval != DLPI_SUCCESS) {
+ (void) fprintf(stderr, "syncinit: dlpi_open %s: %s\n", cnambuf,
+ dlpi_strerror(retval));
exit(1);
}
- (void) printf("device: %s ppa: %d\n", cnambuf, (int)ppa);
+ (void) dlpi_parselink(cnambuf, device, &ppa);
+ (void) printf("device: %s ppa: %u\n", device, ppa);
+
+ fd = dlpi_fd(dh);
argc--;
argv++;
@@ -164,6 +156,7 @@ main(int argc, char **argv)
sioc.ic_timout = -1;
sioc.ic_len = sizeof (struct scc_mode);
sioc.ic_dp = (char *)&sm;
+
if (ioctl(fd, I_STR, &sioc) < 0) {
perror("S_IOCGETMODE");
(void) fprintf(stderr,
@@ -266,7 +259,7 @@ main(int argc, char **argv)
exit(1);
}
(void) printf(
-"speed=%d, loopback=%s, echo=%s, nrzi=%s, txc=%s, rxc=%s\n",
+ "speed=%d, loopback=%s, echo=%s, nrzi=%s, txc=%s, rxc=%s\n",
sm.sm_baudrate,
yesno[((int)(sm.sm_config & CONN_LPBK) > 0)],
yesno[((int)(sm.sm_config & CONN_ECHO) > 0)],
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/syncloop.c b/usr/src/cmd/cmd-inet/usr.sbin/syncloop.c
index 59865b0ecd..d2df175428 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/syncloop.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/syncloop.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,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -54,7 +53,6 @@ static void first_packet();
static void many_packets();
static void printhex(char *cp, int len);
-static char *portname = NULL;
static unsigned int speed = 9600;
static int reccount = 100;
static int reclen = 100;
@@ -94,17 +92,20 @@ static char *rxnames[] = {
};
#define MAXPACKET 4096
-#define MAXWAIT 15
int
main(int argc, char **argv)
{
- char cnambuf[MAXPATHLEN], dnambuf[MAXPATHLEN], *cp, *cpp;
+ char *portname;
+ char dnambuf[MAXPATHLEN], *cp;
+ char device[DLPI_LINKNAME_MAX];
struct scc_mode sm;
struct strioctl sioc;
- ulong_t ppa;
+ uint_t ppa;
char *devstr = "/dev/";
int devstrlen;
+ int retval;
+ dlpi_handle_t dh;
argc--;
argv++;
@@ -171,37 +172,40 @@ main(int argc, char **argv)
perror(dnambuf);
exit(1);
}
- for (cp = portname; (*cp) && (!isdigit(*cp)); cp++) {}
- ppa = strtoul(cp, &cpp, 10);
- if (cpp == cp) {
+
+ cp = portname;
+ while (*cp) /* find the end of the name */
+ cp++;
+ cp--;
+ if (!isdigit(*cp)) {
(void) fprintf(stderr,
- "syncloop: %s missing minor device number\n", portname);
+ "syncloop: %s missing minor device number\n", portname);
exit(1);
}
- *cp = '\0'; /* drop number, leaving name of clone device. */
- /* the following won't fail since cnambuf and dnambuf are same size */
- if (strncmp(devstr, portname, devstrlen) != 0) {
- (void) snprintf(cnambuf, sizeof (cnambuf), "%s%s", devstr,
+
+ if (strlen(portname) >= DLPI_LINKNAME_MAX) {
+ (void) fprintf(stderr,
+ "syncloop: invalid device name (too long) %s\n",
portname);
- }
- cfd = open(cnambuf, O_RDWR);
- if (cfd < 0) {
- (void) fprintf(stderr, "syncloop: cannot open %s\n", cnambuf);
- perror(cnambuf);
exit(1);
}
- if (dlpi_attach(cfd, MAXWAIT, ppa) != 0) {
- perror("syncloop: dlpi_attach");
+ if ((retval = dlpi_open(portname, &dh, DLPI_SERIAL)) != DLPI_SUCCESS) {
+ (void) fprintf(stderr, "syncloop: dlpi_open %s: %s\n", portname,
+ dlpi_strerror(retval));
exit(1);
}
+ (void) dlpi_parselink(portname, device, &ppa);
+
if (reclen < 0 || reclen > MAXPACKET) {
(void) printf("invalid packet length: %d\n", reclen);
exit(1);
}
- (void) printf("[ Data device: %s | Control device: %s, ppa=%ld ]\n",
- dnambuf, cnambuf, ppa);
+ (void) printf("[ Data device: %s | Control device: %s, ppa=%u ]\n",
+ dnambuf, device, ppa);
+
+ cfd = dlpi_fd(dh);
sioc.ic_cmd = S_IOCGETMODE;
sioc.ic_timout = -1;
@@ -209,8 +213,8 @@ main(int argc, char **argv)
sioc.ic_dp = (char *)&sm;
if (ioctl(cfd, I_STR, &sioc) < 0) {
perror("S_IOCGETMODE");
- (void) fprintf(stderr,
- "syncloop: can't get sync mode info for %s\n", cnambuf);
+ (void) fprintf(stderr, "syncloop: can't get sync mode info "
+ "for %s\n", portname);
exit(1);
}
while (looptype < 1 || looptype > 4) {
@@ -273,7 +277,7 @@ main(int argc, char **argv)
if (ioctl(cfd, I_STR, &sioc) < 0) {
perror("S_IOCSETMODE");
(void) fprintf(stderr,
- "syncloop: can't set sync mode info for %s\n", cnambuf);
+ "syncloop: can't set sync mode info for %s\n", portname);
exit(1);
}
@@ -285,8 +289,8 @@ no_params:
sioc.ic_dp = (char *)&sm;
if (ioctl(cfd, I_STR, &sioc) < 0) {
perror("S_IOCGETMODE");
- (void) fprintf(stderr,
- "syncloop: can't get sync mode info for %s\n", cnambuf);
+ (void) fprintf(stderr, "syncloop: can't get sync mode info "
+ "for %s\n", portname);
exit(1);
}
(void) printf("speed=%d, loopback=%s, nrzi=%s, txc=%s, rxc=%s\n",
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/syncstat.c b/usr/src/cmd/cmd-inet/usr.sbin/syncstat.c
index b939067405..9add6a4776 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/syncstat.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/syncstat.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,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,33 +42,28 @@
#include <sys/ser_sync.h>
#include <libdlpi.h>
-#define MAXWAIT 15
-
static struct scc_mode sm;
static struct sl_stats st;
static void usage(void);
static void sample(int count, int period);
-/*
- * errstr is MAXPATHLEN + 11; 11 = 10 for "syncstat: " + null
- */
-static char errstr[11 + MAXPATHLEN] = "syncstat: /dev/";
-static char *ifdevice = errstr + 10;
-static char *ifname = errstr + 15;
+static char sername[DLPI_LINKNAME_MAX];
static int fd;
int
main(int argc, char **argv)
{
- int len;
char *cp;
+ char serdevice[DLPI_LINKNAME_MAX];
int do_clear = 0;
int period = 0;
int isize, osize;
int count;
+ int retval;
struct strioctl sioc;
- ulong_t ppa;
+ uint_t ppa;
+ dlpi_handle_t dh;
if (argc == 1) {
usage();
@@ -102,15 +96,14 @@ main(int argc, char **argv)
period = atoi(*argv);
if (period == 0) {
(void) fprintf(stderr,
- "syncstat: bad interval: %s\n", *argv);
+ "syncstat: bad interval: %s\n", *argv);
exit(1);
}
} else {
- len = sizeof (errstr) - strlen(errstr);
- if (snprintf(ifname, len, "%s", *argv) >= len) {
- (void) fprintf(stderr,
- "syncstat: invalid device name "
- "(too long) %s\n", *argv);
+ if (snprintf(sername, sizeof (sername), "%s",
+ *argv) >= sizeof (sername)) {
+ (void) fprintf(stderr, "syncstat: invalid "
+ "device name (too long) %s\n", *argv);
exit(1);
}
}
@@ -118,27 +111,23 @@ main(int argc, char **argv)
argv++;
}
- for (cp = ifname; (*cp) && (!isdigit(*cp)); cp++) {}
+ for (cp = sername; (*cp) && (!isdigit(*cp)); cp++) {}
if (*cp == '\0') { /* hit the end without finding a number */
(void) fprintf(stderr,
- "syncstat: %s missing minor device number\n", ifname);
- exit(1);
- }
- ppa = strtoul(cp, NULL, 10);
- *cp = '\0'; /* drop number, leaving name of clone device. */
- fd = open(ifdevice, O_RDWR);
- if (fd < 0) {
- perror(errstr);
+ "syncstat: %s missing minor device number\n", sername);
exit(1);
}
- if (dlpi_attach(fd, MAXWAIT, ppa) != 0) {
- perror("syncstat: dlpi_attach");
+ if ((retval = dlpi_open(sername, &dh, DLPI_SERIAL)) != DLPI_SUCCESS) {
+ (void) fprintf(stderr, "syncstat: dlpi_open %s: %s\n", sername,
+ dlpi_strerror(retval));
exit(1);
}
- (void) printf("syncstat: control device: %s, ppa=%ld\n", ifdevice, ppa);
+ (void) dlpi_parselink(sername, serdevice, &ppa);
+ (void) printf("syncstat: control device: %s, ppa=%u\n", serdevice, ppa);
+ fd = dlpi_fd(dh);
sioc.ic_cmd = S_IOCGETMODE;
sioc.ic_timout = -1;
sioc.ic_len = sizeof (struct scc_mode);
@@ -146,8 +135,7 @@ main(int argc, char **argv)
if (ioctl(fd, I_STR, &sioc) < 0) {
perror("S_IOCGETMODE");
(void) fprintf(stderr,
- "syncstat: can't get sync mode info for %s\n",
- ifname);
+ "syncstat: can't get sync mode info for %s\n", sername);
exit(1);
}
if (do_clear) {
@@ -158,8 +146,7 @@ main(int argc, char **argv)
if (ioctl(fd, I_STR, &sioc) < 0) {
perror("S_IOCCLRSTATS");
(void) fprintf(stderr,
- "syncstat: can't clear stats for %s\n",
- ifname);
+ "syncstat: can't clear stats for %s\n", sername);
exit(1);
}
}
@@ -171,7 +158,7 @@ main(int argc, char **argv)
if (ioctl(fd, I_STR, &sioc) < 0) {
perror("S_IOCGETSTATS");
(void) fprintf(stderr, "syncstat: can't get stats for %s\n",
- ifname);
+ sername);
exit(1);
}
if (period) {
@@ -190,17 +177,11 @@ main(int argc, char **argv)
osize = st.ochar / st.opack;
if (st.ipack)
isize = st.ichar / st.ipack;
- (void) printf(
-" speed ipkts opkts undrun ovrrun abort crc isize osize\n");
- (void) printf(" %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
- sm.sm_baudrate,
- st.ipack,
- st.opack,
- st.underrun,
- st.overrun,
- st.abort,
- st.crc,
- isize, osize);
+ (void) printf(" speed ipkts opkts undrun ovrrun abort "
+ "crc isize osize\n");
+ (void) printf(" %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", sm.sm_baudrate,
+ st.ipack, st.opack, st.underrun, st.overrun, st.abort, st.crc,
+ isize, osize);
return (0);
}
@@ -218,7 +199,7 @@ sample(int count, int period)
if (ioctl(fd, I_STR, &sioc) < 0) {
perror("S_IOCGETSTATS");
(void) fprintf(stderr, "syncstat: can't get stats for %s\n",
- ifname);
+ sername);
exit(1);
}
@@ -234,16 +215,11 @@ sample(int count, int period)
iutil = 100 * iutil / sm.sm_baudrate;
outil = 8 * st.ochar / period;
outil = 100 * outil / sm.sm_baudrate;
- if ((count % 20) == 0) (void) printf(
-" ipkts opkts undrun ovrrun abort crc iutil outil\n");
- (void) printf(" %7d %7d %7d %7d %7d %7d %6d%% %6d%%\n",
- st.ipack,
- st.opack,
- st.underrun,
- st.overrun,
- st.abort,
- st.crc,
- iutil, outil);
+ if ((count % 20) == 0)
+ (void) printf(" ipkts opkts undrun ovrrun abort "
+ "crc iutil outil\n");
+ (void) printf(" %7d %7d %7d %7d %7d %7d %6d%% %6d%%\n", st.ipack,
+ st.opack, st.underrun, st.overrun, st.abort, st.crc, iutil, outil);
st = nst;
}
@@ -251,6 +227,5 @@ sample(int count, int period)
static void
usage()
{
- (void) fprintf(stderr, "%s\n",
- "Usage: syncstat [-c] device [period]");
+ (void) fprintf(stderr, "Usage: syncstat [-c] device [period]\n");
}
diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c
index c088f44b68..e7a5b8e744 100644
--- a/usr/src/cmd/dladm/dladm.c
+++ b/usr/src/cmd/dladm/dladm.c
@@ -32,7 +32,6 @@
#include <stdarg.h>
#include <stdlib.h>
#include <fcntl.h>
-#include <stdarg.h>
#include <string.h>
#include <stropts.h>
#include <errno.h>
@@ -670,11 +669,11 @@ do_down_aggr(int argc, char *argv[])
static void
print_link_parseable(const char *name, dladm_attr_t *dap, boolean_t legacy)
{
- char type[TYPE_WIDTH];
+ char type[TYPE_WIDTH];
if (!legacy) {
- char drv[LIFNAMSIZ];
- int instance;
+ char drv[DLPI_LINKNAME_MAX];
+ uint_t instance;
if (dap->da_vid != 0) {
(void) snprintf(type, TYPE_WIDTH, "vlan %u",
@@ -682,8 +681,10 @@ print_link_parseable(const char *name, dladm_attr_t *dap, boolean_t legacy)
} else {
(void) snprintf(type, TYPE_WIDTH, "non-vlan");
}
- if (dlpi_if_parse(dap->da_dev, drv, &instance) != 0)
+
+ if (dlpi_parselink(dap->da_dev, drv, &instance) != DLPI_SUCCESS)
return;
+
if (strncmp(drv, AGGR_DRV, sizeof (AGGR_DRV)) == 0) {
(void) printf("%s type=%s mtu=%d key=%u\n",
name, type, dap->da_max_sdu, instance);
@@ -700,11 +701,11 @@ print_link_parseable(const char *name, dladm_attr_t *dap, boolean_t legacy)
static void
print_link(const char *name, dladm_attr_t *dap, boolean_t legacy)
{
- char type[TYPE_WIDTH];
+ char type[TYPE_WIDTH];
if (!legacy) {
- char drv[LIFNAMSIZ];
- int instance;
+ char drv[DLPI_LINKNAME_MAX];
+ uint_t instance;
if (dap->da_vid != 0) {
(void) snprintf(type, TYPE_WIDTH, gettext("vlan %u"),
@@ -712,7 +713,8 @@ print_link(const char *name, dladm_attr_t *dap, boolean_t legacy)
} else {
(void) snprintf(type, TYPE_WIDTH, gettext("non-vlan"));
}
- if (dlpi_if_parse(dap->da_dev, drv, &instance) != 0)
+
+ if (dlpi_parselink(dap->da_dev, drv, &instance) != DLPI_SUCCESS)
return;
if (strncmp(drv, AGGR_DRV, sizeof (AGGR_DRV)) == 0) {
(void) printf(gettext("%-9s\ttype: %s\tmtu: %d"
@@ -737,26 +739,27 @@ get_if_info(const char *name, dladm_attr_t *dlattrp, boolean_t *legacy)
if ((err = dladm_info(name, dlattrp)) == 0) {
*legacy = B_FALSE;
} else if (err < 0 && errno == ENODEV) {
- int fd;
- dlpi_if_attr_t dia;
- dl_info_ack_t dlia;
+ dlpi_handle_t dh;
+ dlpi_info_t dlinfo;
/*
* A return value of ENODEV means that the specified
* device is not gldv3.
*/
- if ((fd = dlpi_if_open(name, &dia, B_FALSE)) != -1 &&
- dlpi_info(fd, -1, &dlia, NULL, NULL, NULL, NULL,
- NULL, NULL) != -1) {
- (void) dlpi_close(fd);
-
- *legacy = B_TRUE;
- bzero(dlattrp, sizeof (*dlattrp));
- dlattrp->da_max_sdu = (uint_t)dlia.dl_max_sdu;
- } else {
+ if (dlpi_open(name, &dh, 0) != DLPI_SUCCESS) {
errno = ENOENT;
return (-1);
}
+ if (dlpi_info(dh, &dlinfo, 0) != DLPI_SUCCESS) {
+ dlpi_close(dh);
+ errno = EINVAL;
+ return (-1);
+ }
+ dlpi_close(dh);
+ *legacy = B_TRUE;
+ bzero(dlattrp, sizeof (*dlattrp));
+ dlattrp->da_max_sdu = dlinfo.di_max_sdu;
+
} else {
/*
* If the return value is not ENODEV, this means that
@@ -1308,8 +1311,8 @@ do_show_dev(int argc, char *argv[])
usage();
if (dev != NULL) {
- int index;
- char drv[LIFNAMSIZ];
+ uint_t ppa;
+ char drv[DLPI_LINKNAME_MAX];
dladm_attr_t dlattr;
boolean_t legacy;
@@ -1317,9 +1320,9 @@ do_show_dev(int argc, char *argv[])
* Check for invalid devices.
* aggregations and vlans are not considered devices.
*/
- if (strncmp(dev, "aggr", 4) == 0 ||
- dlpi_if_parse(dev, drv, &index) < 0 ||
- index >= 1000 || get_if_info(dev, &dlattr, &legacy) < 0)
+ if (dlpi_parselink(dev, drv, &ppa) != DLPI_SUCCESS ||
+ strcmp(drv, "aggr") == 0 || ppa >= 1000 ||
+ get_if_info(dev, &dlattr, &legacy) < 0)
die("invalid device '%s'", dev);
}
@@ -1521,10 +1524,10 @@ bail:
static void
get_mac_stats(const char *dev, pktsum_t *stats)
{
- char module[LIFNAMSIZ];
- int instance;
+ char module[DLPI_LINKNAME_MAX];
+ uint_t instance;
- if (dlpi_if_parse(dev, module, &instance) != 0)
+ if (dlpi_parselink(dev, module, &instance) != DLPI_SUCCESS)
return;
bzero(stats, sizeof (*stats));
get_stats(module, instance, "mac", stats);
@@ -1533,10 +1536,10 @@ get_mac_stats(const char *dev, pktsum_t *stats)
static void
get_link_stats(const char *link, pktsum_t *stats)
{
- char module[LIFNAMSIZ];
- int instance;
+ char module[DLPI_LINKNAME_MAX];
+ uint_t instance;
- if (dlpi_if_parse(link, module, &instance) != 0)
+ if (dlpi_parselink(link, module, &instance) != DLPI_SUCCESS)
return;
bzero(stats, sizeof (*stats));
get_stats(module, instance, (char *)link, stats);
@@ -1546,18 +1549,19 @@ static int
get_single_mac_stat(const char *dev, const char *name, uint8_t type,
void *val)
{
- char module[LIFNAMSIZ];
- int instance;
+ char module[DLPI_LINKNAME_MAX];
+ uint_t instance;
kstat_ctl_t *kcp;
kstat_t *ksp;
+ if (dlpi_parselink(dev, module, &instance) != DLPI_SUCCESS)
+ return (-1);
+
if ((kcp = kstat_open()) == NULL) {
warn("kstat open operation failed");
return (-1);
}
- if (dlpi_if_parse(dev, module, &instance) != 0)
- return (-1);
if ((ksp = kstat_lookup(kcp, module, instance, "mac")) == NULL &&
(ksp = kstat_lookup(kcp, module, instance, NULL)) == NULL) {
/*
diff --git a/usr/src/cmd/iscsi/iscsitgtd/Makefile.com b/usr/src/cmd/iscsi/iscsitgtd/Makefile.com
index 226a1b90ae..60b8584fb9 100644
--- a/usr/src/cmd/iscsi/iscsitgtd/Makefile.com
+++ b/usr/src/cmd/iscsi/iscsitgtd/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"
@@ -52,7 +52,7 @@ CLEANFILES += $(OBJS)
all: $(PROG)
LDLIBS += -lumem -luuid -lxml2 -lsocket -lnsl -ldoor -lavl -lmd5 -ladm -lefi
-LDLIBS += -liscsitgt -lzfs
+LDLIBS += -liscsitgt -lzfs -ldlpi
$(PROG): $(OBJS) $(COMMON_OBJS)
$(LINK.c) $(OBJS) $(COMMON_OBJS) -o $@ $(LDLIBS)
diff --git a/usr/src/cmd/iscsi/iscsitgtd/target.h b/usr/src/cmd/iscsi/iscsitgtd/target.h
index c852337948..6c4ed53c1b 100644
--- a/usr/src/cmd/iscsi/iscsitgtd/target.h
+++ b/usr/src/cmd/iscsi/iscsitgtd/target.h
@@ -190,7 +190,7 @@ extern char *target_log;
extern char *config_file;
extern tgt_node_t *targets_config;
extern tgt_node_t *main_config;
-extern uchar_t *mac_addr;
+extern uchar_t mac_addr[];
extern size_t mac_len;
extern int main_vers_maj,
main_vers_min,
diff --git a/usr/src/cmd/iscsi/iscsitgtd/util_ifname.c b/usr/src/cmd/iscsi/iscsitgtd/util_ifname.c
index 76ea64f469..d1c3b15d19 100644
--- a/usr/src/cmd/iscsi/iscsitgtd/util_ifname.c
+++ b/usr/src/cmd/iscsi/iscsitgtd/util_ifname.c
@@ -20,18 +20,18 @@
*/
/*
- * 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 <sys/types.h>
-#include <sys/dlpi.h>
#include <libdlpi.h>
#include <ctype.h>
#include <sys/sysmacros.h>
#include <net/if_types.h>
+#include <net/if.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
@@ -59,18 +59,13 @@
* at this given time will have the same MAC address and as time moves along
* well, time will change.
*/
-uchar_t *mac_addr;
-size_t mac_len;
-
-#define PATH_PART "/dev/"
+uchar_t mac_addr[DLPI_PHYSADDR_MAX];
+size_t mac_len;
static struct lifreq *if_setup(int *n);
static void dump_addr_to_ascii(struct sockaddr *addr, char *buf,
size_t len);
-static int strputmsg(int fd, uint8_t *ctl_buf, size_t ctl_len, int flags);
-static int strgetmsg(int fd, char *ctl_buf, size_t *ctl_lenp, char *data_buf,
- size_t *data_lenp);
-static Boolean_t grab_address(char *ifname, uchar_t **addr, size_t *lp);
+static Boolean_t grab_address(char *ifname, uchar_t *addrp, size_t *addrlenp);
/*
* []----
@@ -89,13 +84,15 @@ if_find_mac(target_queue_t *mgmt)
{
struct lifreq *lifrp, *first;
int n;
- char *str = NULL;
+ char *str;
+
+ mac_len = DLPI_PHYSADDR_MAX;
first = if_setup(&n);
for (lifrp = first; n > 0; n--, lifrp++) {
- if (grab_address(lifrp->lifr_name, &mac_addr,
+ if (grab_address(lifrp->lifr_name, mac_addr,
&mac_len) == True) {
- str = _link_ntoa(mac_addr, str, mac_len, IFT_OTHER);
+ str = _link_ntoa(mac_addr, NULL, mac_len, IFT_OTHER);
if ((str != NULL) && (mgmt != NULL)) {
queue_prt(mgmt, Q_GEN_DETAILS,
"MAIN %s: %s \n", lifrp->lifr_name, str);
@@ -338,171 +335,18 @@ if_setup(int *n)
return (lifc.lifc_req);
}
-static int
-strputmsg(int fd, uint8_t *ctl_buf, size_t ctl_len, int flags)
-{
- struct strbuf ctl;
-
- bzero(&ctl, sizeof (ctl));
- ctl.buf = (char *)ctl_buf;
- ctl.len = ctl_len;
-
- return (putmsg(fd, &ctl, NULL, flags));
-}
-
-static int
-strgetmsg(int fd, char *ctl_buf, size_t *ctl_lenp, char *data_buf,
- size_t *data_lenp)
-{
- struct strbuf ctl;
- struct strbuf data;
- int flags = 0,
- res;
-
- bzero(&ctl, sizeof (ctl));
- ctl.buf = ctl_buf;
- ctl.len = 0;
- ctl.maxlen = (ctl_lenp != NULL) ? *ctl_lenp : 0;
-
- bzero(&data, sizeof (data));
- data.buf = data_buf;
- data.len = 0;
- data.maxlen = (data_lenp != NULL) ? *data_lenp : 0;
-
- res = getmsg(fd, &ctl, &data, &flags);
- if (ctl_lenp != NULL)
- *ctl_lenp = ctl.len;
- if (data_lenp != NULL)
- *data_lenp = data.len;
-
- return (res);
-}
-
static Boolean_t
-ppa_attach(int fd, int ppa)
+grab_address(char *ifname, uchar_t *addrp, size_t *addrlenp)
{
- union DL_primitives *buf = NULL;
- dl_attach_req_t dlar;
- size_t size;
- Boolean_t rval = False;
-
- size = 0;
- size = MAX(sizeof (dl_ok_ack_t), size);
- size = MAX(sizeof (dl_error_ack_t), size);
+ int retval;
+ dlpi_handle_t dh;
- if ((buf = malloc(size)) == NULL)
+ if (dlpi_open(ifname, &dh, 0) != DLPI_SUCCESS)
return (False);
- dlar.dl_primitive = DL_ATTACH_REQ;
- dlar.dl_ppa = ppa;
+ retval = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, addrp, addrlenp);
- if (strputmsg(fd, (uint8_t *)&dlar, DL_ATTACH_REQ_SIZE, 0) == -1)
- goto error;
+ dlpi_close(dh);
- if (strgetmsg(fd, (char *)buf, &size, NULL, NULL) == -1)
- goto error;
-
- if (size < sizeof (t_uscalar_t))
- goto error;
-
- switch (buf->dl_primitive) {
- case DL_OK_ACK:
- if (size == DL_OK_ACK_SIZE)
- rval = True;
- break;
- }
-
-error:
- if (buf != NULL)
- free(buf);
-
- return (rval);
-}
-
-static Boolean_t
-grab_address(char *ifname, uchar_t **addr, size_t *lp)
-{
- char *dev_name = NULL,
- *p;
- size_t len;
- int ppa,
- fd = -1;
- union DL_primitives *buf = NULL;
- dl_phys_addr_req_t dlpar;
- dl_phys_addr_ack_t *dlpaap;
- Boolean_t rval = False;
-
- if (strcmp(ifname, LOCAL_LOOPBACK) == 0)
- return (False);
-
- bzero(&dlpar, sizeof (dlpar));
- len = strlen(PATH_PART) + strlen(ifname) + 1;
- if ((dev_name = (char *)malloc(len)) == NULL) {
- goto error;
- }
- (void) snprintf(dev_name, len, "%s%s", PATH_PART, ifname);
-
- if ((fd = open(dev_name, O_RDWR)) < 0) {
- for (p = dev_name; *p; p++) {
- if (isdigit(*p)) {
- ppa = atoi(p);
- *p = '\0';
- if (((fd = open(dev_name, O_RDWR)) < 0) ||
- (ppa_attach(fd, ppa) == False)) {
- goto error;
- }
- break;
- }
- }
- if (fd == -1)
- goto error;
- }
-
- len = 0;
- len = MAX(sizeof (dl_phys_addr_ack_t) + MAXADDRLEN, len);
- len = MAX(sizeof (dl_error_ack_t), len);
-
- if ((buf = calloc(len, 1)) == NULL)
- goto error;
- dlpar.dl_primitive = DL_PHYS_ADDR_REQ;
- dlpar.dl_addr_type = DL_CURR_PHYS_ADDR;
-
- if (strputmsg(fd, (uint8_t *)&dlpar, DL_PHYS_ADDR_REQ_SIZE, 0) == -1) {
- goto error;
- }
-
- if (strgetmsg(fd, (char *)buf, &len, NULL, NULL) == -1) {
- goto error;
- }
-
- switch (buf->dl_primitive) {
- case DL_PHYS_ADDR_ACK:
- if (len < DL_PHYS_ADDR_ACK_SIZE) {
- goto error;
- }
-
- dlpaap = (dl_phys_addr_ack_t *)buf;
- if (dlpaap->dl_addr_offset != 0) {
- if (dlpaap->dl_addr_length == 0) {
- goto error;
- }
- *addr = malloc(dlpaap->dl_addr_length);
- if (*addr == NULL)
- goto error;
- bcopy((char *)buf + dlpaap->dl_addr_offset, *addr,
- dlpaap->dl_addr_length);
- *lp = dlpaap->dl_addr_length;
- rval = True;
- }
- break;
- }
-
-error:
- if (fd != -1)
- (void) close(fd);
- if (dev_name != NULL)
- free(dev_name);
- if (buf != NULL)
- free(buf);
- return (rval);
+ return (retval == DLPI_SUCCESS);
}
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index f0e102ed89..4fc879cad9 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -473,6 +473,7 @@ libdevinfo: libnvpair libsec
libdhcpagent: libsocket libdhcputil libuuid libdlpi
libdhcpsvc: libinetutil
libdhcputil: libnsl libgen libinetutil libdlpi
+libdlpi: libinetutil
libdladm: libdlpi libdevinfo libwladm libinetutil
libdtrace: libproc libgen libctf
libdtrace_jni: libuutil libdtrace
diff --git a/usr/src/lib/libdhcpagent/common/dhcp_stable.c b/usr/src/lib/libdhcpagent/common/dhcp_stable.c
index 7ae11346f6..e240164549 100644
--- a/usr/src/lib/libdhcpagent/common/dhcp_stable.c
+++ b/usr/src/lib/libdhcpagent/common/dhcp_stable.c
@@ -131,9 +131,10 @@ write_stable_duid(const uchar_t *duid, size_t duidlen)
uchar_t *
make_stable_duid(const char *physintf, size_t *duidlen)
{
- int fd, len;
- dl_info_ack_t dl_info;
- dlpi_if_attr_t dia;
+ int len;
+ dlpi_info_t dlinfo;
+ dlpi_handle_t dh = NULL;
+ uint_t arptype;
duid_en_t *den;
/*
@@ -141,35 +142,29 @@ make_stable_duid(const char *physintf, size_t *duidlen)
* provided as a hint. If that works, we can use a DUID-LLT.
*/
- fd = dlpi_if_open(physintf, &dia, B_FALSE);
- if (fd != -1 &&
- dlpi_info(fd, -1, &dl_info, NULL, NULL, NULL, NULL, NULL,
- NULL) != -1 &&
- (len = dl_info.dl_addr_length - abs(dl_info.dl_sap_length)) > 0) {
+ 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)) {
duid_llt_t *dllt;
- uint_t arptype;
-
- arptype = dlpi_to_arp(dl_info.dl_mac_type);
+ time_t now;
if ((dllt = malloc(sizeof (*dllt) + len)) == NULL) {
- (void) dlpi_close(fd);
+ dlpi_close(dh);
return (NULL);
}
- if (arptype != 0 && dlpi_phys_addr(fd, -1, DL_CURR_PHYS_ADDR,
- (uint8_t *)(dllt + 1), NULL) == 0) {
- time_t now;
- dllt->dllt_dutype = htons(DHCPV6_DUID_LLT);
- dllt->dllt_hwtype = htons(arptype);
- now = time(NULL) - DUID_TIME_BASE;
- dllt->dllt_time = htonl(now);
- *duidlen = sizeof (*dllt) + len;
- return ((uchar_t *)dllt);
- }
- free(dllt);
+ (void) memcpy((dllt + 1), dlinfo.di_physaddr, len);
+ dllt->dllt_dutype = htons(DHCPV6_DUID_LLT);
+ dllt->dllt_hwtype = htons(arptype);
+ now = time(NULL) - DUID_TIME_BASE;
+ dllt->dllt_time = htonl(now);
+ *duidlen = sizeof (*dllt) + len;
+ dlpi_close(dh);
+ return ((uchar_t *)dllt);
}
- if (fd != -1)
- (void) dlpi_close(fd);
+ if (dh != NULL)
+ dlpi_close(dh);
/*
* If we weren't able to create a DUID based on the network interface
diff --git a/usr/src/lib/libdhcputil/common/dhcp_inittab.c b/usr/src/lib/libdhcputil/common/dhcp_inittab.c
index e16b241f23..861dbc3f57 100644
--- a/usr/src/lib/libdhcputil/common/dhcp_inittab.c
+++ b/usr/src/lib/libdhcputil/common/dhcp_inittab.c
@@ -526,17 +526,16 @@ static int
get_mac_addr(const char *str, int *ierrnop, uint16_t *hwret, int hwtype,
uchar_t *outbuf)
{
- int fd = -1;
int maclen;
int dig, val;
- dlpi_if_attr_t dia;
- dl_info_ack_t dl_info;
+ dlpi_handle_t dh;
+ dlpi_info_t dlinfo;
char chr;
if (*str != '\0') {
if (*str++ != ',')
goto failed;
- if ((fd = dlpi_if_open(str, &dia, B_FALSE)) == -1) {
+ if (dlpi_open(str, &dh, 0) != DLPI_SUCCESS) {
maclen = 0;
dig = val = 0;
/*
@@ -564,19 +563,15 @@ get_mac_addr(const char *str, int *ierrnop, uint16_t *hwret, int hwtype,
}
}
} else {
- if (dlpi_info(fd, -1, &dl_info, NULL, NULL, NULL,
- NULL, NULL, NULL) == -1)
+ if (dlpi_info(dh, &dlinfo, 0) != DLPI_SUCCESS) {
+ dlpi_close(dh);
goto failed;
- maclen = dl_info.dl_addr_length -
- abs(dl_info.dl_sap_length);
- if (maclen > MAXADDRLEN)
- goto failed;
- if (dlpi_phys_addr(fd, -1, DL_CURR_PHYS_ADDR, outbuf,
- NULL) == -1)
- goto failed;
- (void) dlpi_close(fd);
+ }
+ maclen = dlinfo.di_physaddrlen;
+ (void) memcpy(outbuf, dlinfo.di_physaddr, maclen);
+ dlpi_close(dh);
if (hwtype == -1)
- hwtype = dlpi_to_arp(dl_info.dl_mac_type);
+ hwtype = dlpi_to_arp(dlinfo.di_mactype);
}
}
if (hwtype == -1)
@@ -585,8 +580,6 @@ get_mac_addr(const char *str, int *ierrnop, uint16_t *hwret, int hwtype,
return (maclen);
failed:
- if (fd != -1)
- (void) dlpi_close(fd);
*ierrnop = ITAB_BAD_NUMBER;
return (-1);
}
@@ -651,8 +644,8 @@ inittab_encode_e(const dhcp_symbol_t *ie, const char *value, uint16_t *lengthp,
case DSYM_DUID:
/* Worst case is ":::::" */
n_entries = strlen(value);
- if (n_entries < MAXADDRLEN)
- n_entries = MAXADDRLEN;
+ if (n_entries < DLPI_PHYSADDR_MAX)
+ n_entries = DLPI_PHYSADDR_MAX;
n_entries += sizeof (duid_llt_t);
break;
diff --git a/usr/src/lib/libdladm/common/libdladm.c b/usr/src/lib/libdladm/common/libdladm.c
index 2a62bb8232..5a5c06c464 100644
--- a/usr/src/lib/libdladm/common/libdladm.c
+++ b/usr/src/lib/libdladm/common/libdladm.c
@@ -129,37 +129,17 @@ i_dladm_nt_net_add(void *arg, char *name)
static int
i_dladm_nt_net_walk(di_node_t node, di_minor_t minor, void *arg)
{
- dl_info_ack_t dlia;
- char name[IFNAMSIZ];
- int fd;
- char *provider;
- uint_t ppa;
-
- provider = di_minor_name(minor);
-
- if ((fd = dlpi_open(provider)) < 0)
- return (DI_WALK_CONTINUE);
-
- if (dlpi_info(fd, -1, &dlia, NULL, NULL, NULL, NULL, NULL, NULL) < 0) {
- (void) dlpi_close(fd);
- return (DI_WALK_CONTINUE);
- }
+ char linkname[DLPI_LINKNAME_MAX];
+ dlpi_handle_t dh;
- if (dlia.dl_provider_style == DL_STYLE1) {
- i_dladm_nt_net_add(arg, provider);
- (void) dlpi_close(fd);
+ if (dlpi_makelink(linkname, di_minor_name(minor),
+ di_instance(node)) != DLPI_SUCCESS)
return (DI_WALK_CONTINUE);
- }
- ppa = di_instance(node);
-
- if (dlpi_attach(fd, -1, ppa) < 0) {
- (void) dlpi_close(fd);
- return (DI_WALK_CONTINUE);
+ if (dlpi_open(linkname, &dh, 0) == DLPI_SUCCESS) {
+ i_dladm_nt_net_add(arg, linkname);
+ dlpi_close(dh);
}
- (void) snprintf(name, IFNAMSIZ - 1, "%s%d", provider, ppa);
- i_dladm_nt_net_add(arg, name);
- (void) dlpi_close(fd);
return (DI_WALK_CONTINUE);
}
diff --git a/usr/src/lib/libdlpi/Makefile b/usr/src/lib/libdlpi/Makefile
index a354d4de53..1f0a03b675 100644
--- a/usr/src/lib/libdlpi/Makefile
+++ b/usr/src/lib/libdlpi/Makefile
@@ -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"
@@ -31,6 +31,7 @@ HDRS = libdlpi.h
HDRDIR = common
SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
POFILE = libdlpi.po
MSGFILES = common/libdlpi.c
diff --git a/usr/src/lib/libdlpi/Makefile.com b/usr/src/lib/libdlpi/Makefile.com
index 2ce8d412af..a8b5e6be1f 100644
--- a/usr/src/lib/libdlpi/Makefile.com
+++ b/usr/src/lib/libdlpi/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"
@@ -36,7 +36,7 @@ include ../../Makefile.rootfs
LIBS = $(DYNLIB) $(LINTLIB)
-LDLIBS += -lc
+LDLIBS += -lc -linetutil
SRCDIR = ../common
$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
diff --git a/usr/src/lib/libdlpi/amd64/Makefile b/usr/src/lib/libdlpi/amd64/Makefile
new file mode 100644
index 0000000000..a76ebb70e3
--- /dev/null
+++ b/usr/src/lib/libdlpi/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.
+#
+#pragma 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 fc6dbe0f83..42ac808382 100644
--- a/usr/src/lib/libdlpi/common/libdlpi.c
+++ b/usr/src/lib/libdlpi/common/libdlpi.c
@@ -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.
*/
@@ -28,7 +28,6 @@
/*
* Data-Link Provider Interface (Version 2)
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -40,1285 +39,1408 @@
#include <stropts.h>
#include <sys/dlpi.h>
#include <errno.h>
+#include <alloca.h>
#include <sys/sysmacros.h>
#include <ctype.h>
#include <libdlpi.h>
-#include <libdladm.h>
-
-typedef enum dlpi_multi_op {
- DLPI_MULTI_DISABLE = 0,
- DLPI_MULTI_ENABLE
-} dlpi_multi_op_t;
-
-typedef enum dlpi_promisc_op {
- DLPI_PROMISC_OFF = 0,
- DLPI_PROMISC_ON
-} dlpi_promisc_op_t;
-
-const char *i_dlpi_mac_type[] = {
- "CSMA/CD", /* 0x00 */
- "Token Bus", /* 0x01 */
- "Token Ring", /* 0x02 */
- "Metro Net", /* 0x03 */
- "Ethernet", /* 0x04 */
- "HDLC", /* 0x05 */
- "Sync Character", /* 0x06 */
- "CTCA", /* 0x07 */
- "FDDI", /* 0x08 */
- "unknown", /* 0x09 */
- "Frame Relay (LAPF)", /* 0x0a */
- "MP Frame Relay", /* 0x0b */
- "Async Character", /* 0x0c */
- "X.25 (Classic IP)", /* 0x0d */
- "Software Loopback", /* 0x0e */
- "undefined", /* 0x0f */
- "Fiber Channel", /* 0x10 */
- "ATM", /* 0x11 */
- "ATM (Classic IP)", /* 0x12 */
- "X.25 (LAPB)", /* 0x13 */
- "ISDN", /* 0x14 */
- "HIPPI", /* 0x15 */
- "100BaseVG Ethernet", /* 0x16 */
- "100BaseVG Token Ring", /* 0x17 */
- "Ethernet/IEEE 802.3", /* 0x18 */
- "100BaseT", /* 0x19 */
- "Infiniband" /* 0x1a */
-};
-
-static int i_dlpi_ifrm_num(char *, unsigned int *);
-
-const char *
-dlpi_mac_type(uint_t type)
-{
- if (type >= sizeof (i_dlpi_mac_type) / sizeof (i_dlpi_mac_type[0]))
- return ("ERROR");
-
- return (i_dlpi_mac_type[type]);
-}
-
-static int
-strputmsg(int fd, uint8_t *ctl_buf, size_t ctl_len, int flags)
-{
- struct strbuf ctl;
-
- ctl.buf = (char *)ctl_buf;
- ctl.len = ctl_len;
-
- return (putmsg(fd, &ctl, NULL, flags));
-}
+#include <libintl.h>
+#include <libinetutil.h>
+
+#include "libdlpi_impl.h"
+
+static int i_dlpi_open(const char *, int *, uint_t);
+static int i_dlpi_style1_open(dlpi_impl_t *);
+static int i_dlpi_style2_open(dlpi_impl_t *);
+static int i_dlpi_checkstyle(dlpi_impl_t *, t_uscalar_t);
+static int i_dlpi_remove_ppa(char *);
+static int i_dlpi_attach(dlpi_impl_t *);
+static void i_dlpi_passive(dlpi_impl_t *);
+
+static int i_dlpi_strputmsg(int, const dlpi_msg_t *, const void *, size_t, int);
+static int i_dlpi_strgetmsg(int, int, dlpi_msg_t *, t_uscalar_t, t_uscalar_t,
+ size_t, void *, size_t *, size_t *);
+static int i_dlpi_msg_common(dlpi_impl_t *, const dlpi_msg_t *, dlpi_msg_t *,
+ size_t, int);
+
+static size_t i_dlpi_getprimsize(t_uscalar_t);
+static int i_dlpi_multi(dlpi_handle_t, t_uscalar_t, const uint8_t *, size_t);
+static int i_dlpi_promisc(dlpi_handle_t, t_uscalar_t, uint_t);
+static uint_t i_dlpi_buildsap(uint8_t *, uint_t);
+static void i_dlpi_writesap(void *, uint_t, uint_t);
-static int
-strgetmsg(int fd, int timeout, char *ctl_buf,
- size_t *ctl_lenp, char *data_buf, size_t *data_lenp)
+int
+dlpi_open(const char *linkname, dlpi_handle_t *dhp, uint_t flags)
{
- struct strbuf ctl;
- struct strbuf data;
- int res;
- struct pollfd pfd;
- int flags = 0;
-
- pfd.fd = fd;
- pfd.events = POLLIN | POLLPRI;
-
- switch (poll(&pfd, 1, timeout)) {
- default:
- ctl.buf = ctl_buf;
- ctl.len = 0;
- ctl.maxlen = (ctl_lenp != NULL) ? *ctl_lenp : 0;
+ int retval;
+ int cnt;
+ ifspec_t ifsp;
+ dlpi_impl_t *dip;
- data.buf = data_buf;
- data.len = 0;
- data.maxlen = (data_lenp != NULL) ? *data_lenp : 0;
+ /*
+ * Validate linkname, fail if logical unit number (lun) is specified,
+ * otherwise decompose the contents into ifsp.
+ */
+ if (linkname == NULL || (strchr(linkname, ':') != NULL) ||
+ !ifparse_ifspec(linkname, &ifsp))
+ return (DLPI_ELINKNAMEINVAL);
+
+ /* Allocate a new dlpi_impl_t. */
+ if ((dip = calloc(1, sizeof (dlpi_impl_t))) == NULL)
+ return (DL_SYSERR);
+
+ /* Fill in known/default libdlpi handle values. */
+ dip->dli_timeout = DLPI_DEF_TIMEOUT;
+ dip->dli_ppa = ifsp.ifsp_ppa;
+ dip->dli_mod_cnt = ifsp.ifsp_modcnt;
+ dip->dli_oflags = flags;
+
+ for (cnt = 0; cnt != dip->dli_mod_cnt; cnt++) {
+ (void) strlcpy(dip->dli_modlist[cnt], ifsp.ifsp_mods[cnt],
+ DLPI_LINKNAME_MAX);
+ }
- if ((res = getmsg(fd, &ctl, &data, &flags)) < 0)
- goto failed;
+ /* Copy linkname provided to the function. */
+ if (strlcpy(dip->dli_linkname, linkname, sizeof (dip->dli_linkname)) >=
+ sizeof (dip->dli_linkname)) {
+ free(dip);
+ return (DLPI_ELINKNAMEINVAL);
+ }
- if (ctl_buf != NULL) {
- if (res & MORECTL) {
- errno = E2BIG;
- goto failed;
- }
+ /* Copy provider name. */
+ (void) strlcpy(dip->dli_provider, ifsp.ifsp_devnm,
+ sizeof (dip->dli_provider));
- *ctl_lenp = ctl.len;
+ /*
+ * Special case: DLPI_SERIAL flag is set to indicate a synchronous
+ * serial line interface (see syncinit(1M), syncstat(1M),
+ * syncloop(1M)), which is not a DLPI link.
+ */
+ if (dip->dli_oflags & DLPI_SERIAL) {
+ if ((retval = i_dlpi_style2_open(dip)) != DLPI_SUCCESS) {
+ free(dip);
+ return (retval);
}
- if (data_buf != NULL) {
- if (res & MOREDATA) {
- errno = E2BIG;
- goto failed;
- }
+ *dhp = (dlpi_handle_t)dip;
+ return (retval);
+ }
- *data_lenp = data.len;
+ if (i_dlpi_style1_open(dip) != DLPI_SUCCESS) {
+ if ((retval = i_dlpi_style2_open(dip)) != DLPI_SUCCESS) {
+ free(dip);
+ return (retval);
}
-
- break;
- case 0:
- errno = ETIME;
- /*FALLTHRU*/
- case -1:
- goto failed;
}
- return (0);
-failed:
- return (-1);
-}
-
-int
-dlpi_open(const char *provider)
-{
- char devname[MAXPATHLEN];
- char path[MAXPATHLEN];
- int fd;
- struct stat st;
+ if (dip->dli_oflags & DLPI_PASSIVE)
+ i_dlpi_passive(dip);
- (void) snprintf(devname, MAXPATHLEN, "/dev/%s", provider);
-
- if ((fd = open(devname, O_RDWR)) != -1)
- return (fd);
-
- (void) snprintf(path, MAXPATHLEN, "/devices/pseudo/clone@0:%s",
- provider);
+ if ((dip->dli_oflags & DLPI_RAW) &&
+ ioctl(dip->dli_fd, DLIOCRAW, 0) < 0) {
+ dlpi_close((dlpi_handle_t)dip);
+ return (DLPI_ERAWNOTSUP);
+ }
- if (stat(path, &st) == 0) {
- (void) strlcpy(devname, path, sizeof (devname));
- if ((fd = open(devname, O_RDWR)) != -1)
- return (fd);
+ /*
+ * We intentionally do not care if this request fails, as this
+ * indicates the underlying DLPI device does not support Native mode
+ * (pre-GLDV3 device drivers).
+ */
+ if (dip->dli_oflags & DLPI_NATIVE) {
+ if ((retval = ioctl(dip->dli_fd, DLIOCNATIVE, 0)) > 0)
+ dip->dli_mactype = retval;
}
- return (-1);
+ *dhp = (dlpi_handle_t)dip;
+ return (DLPI_SUCCESS);
}
-int
-dlpi_close(int fd)
+void
+dlpi_close(dlpi_handle_t dh)
{
- return (close(fd));
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
+
+ if (dip != NULL) {
+ (void) close(dip->dli_fd);
+ free(dip);
+ }
}
+/*
+ * NOTE: The opt argument must be zero and is reserved for future use to extend
+ * fields to the dlpi_info_t structure (see dlpi_info(3DLPI)).
+ */
int
-dlpi_info(int fd, int timeout, dl_info_ack_t *ackp,
- union DL_qos_types *selp, union DL_qos_types *rangep,
- uint8_t *addrp, size_t *addrlenp, uint8_t *brdcst_addrp,
- size_t *brdcst_addrlenp)
+dlpi_info(dlpi_handle_t dh, dlpi_info_t *infop, uint_t opt)
{
- int rc = -1;
- size_t size;
- dl_info_ack_t *buf;
- dl_info_req_t dlir;
- dl_info_ack_t *dliap;
- union DL_qos_types *uqtp;
-
- size = sizeof (dl_info_ack_t); /* DL_INFO_ACK */
- size += sizeof (union DL_qos_types); /* QoS selections */
- size += sizeof (union DL_qos_types); /* QoS ranges */
- size += MAXADDRLEN + MAXSAPLEN; /* DLSAP Address */
- size += MAXADDRLEN; /* Broadcast Address */
-
- if ((buf = malloc(size)) == NULL)
- return (-1);
-
- dlir.dl_primitive = DL_INFO_REQ;
-
- if (strputmsg(fd, (uint8_t *)&dlir, DL_INFO_REQ_SIZE, RS_HIPRI) == -1)
- goto done;
-
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
-
- if (size < DL_INFO_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
+ int retval;
+ dlpi_msg_t req, ack;
+ dl_info_ack_t *infoackp;
+ uint8_t *sapp, *addrp;
+ caddr_t ackendp, datap;
+ t_uscalar_t dataoff, datalen;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
+
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
+
+ if (infop == NULL || opt != 0)
+ return (DLPI_EINVAL);
+
+ (void) memset(infop, 0, sizeof (dlpi_info_t));
+
+ /* Set QoS range parameters to default unsupported value. */
+ infop->di_qos_range.dl_qos_type = (t_uscalar_t)DL_UNKNOWN;
+ infop->di_qos_range.dl_trans_delay.dl_target_value = DL_UNKNOWN;
+ infop->di_qos_range.dl_trans_delay.dl_accept_value = DL_UNKNOWN;
+ infop->di_qos_range.dl_priority.dl_min = DL_UNKNOWN;
+ infop->di_qos_range.dl_priority.dl_max = DL_UNKNOWN;
+ infop->di_qos_range.dl_protection.dl_min = DL_UNKNOWN;
+ infop->di_qos_range.dl_protection.dl_max = DL_UNKNOWN;
+ infop->di_qos_range.dl_residual_error = DL_UNKNOWN;
+
+ /* Set QoS parameters to default unsupported value. */
+ infop->di_qos_sel.dl_qos_type = (t_uscalar_t)DL_UNKNOWN;
+ infop->di_qos_sel.dl_trans_delay = DL_UNKNOWN;
+ infop->di_qos_sel.dl_priority = DL_UNKNOWN;
+ infop->di_qos_sel.dl_protection = DL_UNKNOWN;
+ infop->di_qos_sel.dl_residual_error = DL_UNKNOWN;
+
+ DLPI_MSG_CREATE(req, DL_INFO_REQ);
+ DLPI_MSG_CREATE(ack, DL_INFO_ACK);
+
+ retval = i_dlpi_msg_common(dip, &req, &ack, DL_INFO_ACK_SIZE, RS_HIPRI);
+ if (retval != DLPI_SUCCESS)
+ return (retval);
+
+ infoackp = &(ack.dlm_msg->info_ack);
+ if (infoackp->dl_version != DL_VERSION_2)
+ return (DLPI_EVERNOTSUP);
+
+ if (infoackp->dl_service_mode != DL_CLDLS)
+ return (DLPI_EMODENOTSUP);
+
+ dip->dli_style = infoackp->dl_provider_style;
+ dip->dli_mactype = infoackp->dl_mac_type;
+
+ ackendp = (caddr_t)ack.dlm_msg + ack.dlm_msgsz;
+
+ /* Check and save QoS selection information, if any. */
+ datalen = infoackp->dl_qos_length;
+ dataoff = infoackp->dl_qos_offset;
+ if (dataoff != 0 && datalen != 0) {
+ datap = (caddr_t)infoackp + dataoff;
+ if (datalen > sizeof (dl_qos_cl_sel1_t) ||
+ dataoff < DL_INFO_ACK_SIZE || datap + datalen > ackendp)
+ return (DLPI_EBADMSG);
+
+ (void) memcpy(&infop->di_qos_sel, datap, datalen);
+ if (infop->di_qos_sel.dl_qos_type != DL_QOS_CL_SEL1)
+ return (DLPI_EMODENOTSUP);
}
- dliap = (dl_info_ack_t *)buf;
- if (dliap->dl_primitive != DL_INFO_ACK ||
- dliap->dl_version != DL_VERSION_2) {
- errno = EPROTO;
- goto done;
+ /* Check and save QoS range information, if any. */
+ datalen = infoackp->dl_qos_range_length;
+ dataoff = infoackp->dl_qos_range_offset;
+ if (dataoff != 0 && datalen != 0) {
+ datap = (caddr_t)infoackp + dataoff;
+ if (datalen > sizeof (dl_qos_cl_range1_t) ||
+ dataoff < DL_INFO_ACK_SIZE || datap + datalen > ackendp)
+ return (DLPI_EBADMSG);
+
+ (void) memcpy(&infop->di_qos_range, datap, datalen);
+ if (infop->di_qos_range.dl_qos_type != DL_QOS_CL_RANGE1)
+ return (DLPI_EMODENOTSUP);
}
- (void) memcpy(ackp, buf, DL_INFO_ACK_SIZE);
-
- if (dliap->dl_qos_offset != 0) {
- if (dliap->dl_qos_length < sizeof (t_uscalar_t)) {
- errno = EPROTO;
- goto done;
- }
-
- uqtp = (union DL_qos_types *)
- ((uintptr_t)buf + dliap->dl_qos_offset);
- if (uqtp->dl_qos_type != DL_QOS_CO_SEL1 &&
- uqtp->dl_qos_type != DL_QOS_CL_SEL1) {
- errno = EPROTO;
- goto done;
- }
-
- if (selp != NULL)
- (void) memcpy(selp, (char *)buf + dliap->dl_qos_offset,
- dliap->dl_qos_length);
- }
-
- if (dliap->dl_qos_range_offset != 0) {
- if (dliap->dl_qos_range_length < sizeof (t_uscalar_t)) {
- errno = EPROTO;
- goto done;
- }
-
- uqtp = (union DL_qos_types *)
- ((uintptr_t)buf + dliap->dl_qos_range_offset);
- if (uqtp->dl_qos_type != DL_QOS_CO_RANGE1 &&
- uqtp->dl_qos_type != DL_QOS_CL_RANGE1) {
- errno = EPROTO;
- goto done;
- }
-
- if (rangep != NULL)
- (void) memcpy(rangep,
- (char *)buf + dliap->dl_qos_range_offset,
- dliap->dl_qos_range_length);
+ /* Check and save physical address and SAP information. */
+ dip->dli_saplen = abs(infoackp->dl_sap_length);
+ dip->dli_sapbefore = (infoackp->dl_sap_length > 0);
+ infop->di_physaddrlen = infoackp->dl_addr_length - dip->dli_saplen;
+
+ if (infop->di_physaddrlen > DLPI_PHYSADDR_MAX ||
+ dip->dli_saplen > DLPI_SAPLEN_MAX)
+ return (DL_BADADDR);
+
+ dataoff = infoackp->dl_addr_offset;
+ datalen = infoackp->dl_addr_length;
+ if (dataoff != 0 && datalen != 0) {
+ datap = (caddr_t)infoackp + dataoff;
+ if (dataoff < DL_INFO_ACK_SIZE || datap + datalen > ackendp)
+ return (DLPI_EBADMSG);
+
+ sapp = addrp = (uint8_t *)datap;
+ if (dip->dli_sapbefore)
+ addrp += dip->dli_saplen;
+ else
+ sapp += infop->di_physaddrlen;
+
+ (void) memcpy(infop->di_physaddr, addrp, infop->di_physaddrlen);
+ infop->di_sap = i_dlpi_buildsap(sapp, dip->dli_saplen);
}
- if (dliap->dl_addr_offset != 0) {
- if (dliap->dl_addr_length == 0) {
- errno = EPROTO;
- goto done;
- }
-
- if (addrlenp != NULL)
- *addrlenp = dliap->dl_addr_length;
- if (addrp != NULL)
- (void) memcpy(addrp,
- (char *)buf + dliap->dl_addr_offset,
- dliap->dl_addr_length);
+ /* Check and save broadcast address information, if any. */
+ datalen = infoackp->dl_brdcst_addr_length;
+ dataoff = infoackp->dl_brdcst_addr_offset;
+ if (dataoff != 0 && datalen != 0) {
+ datap = (caddr_t)infoackp + dataoff;
+ if (dataoff < DL_INFO_ACK_SIZE || datap + datalen > ackendp)
+ return (DLPI_EBADMSG);
+ if (datalen != infop->di_physaddrlen)
+ return (DL_BADADDR);
+
+ infop->di_bcastaddrlen = datalen;
+ (void) memcpy(infop->di_bcastaddr, datap, datalen);
}
- if (dliap->dl_brdcst_addr_offset != 0) {
- if (dliap->dl_brdcst_addr_length == 0) {
- errno = EPROTO;
- goto done;
- }
+ infop->di_max_sdu = infoackp->dl_max_sdu;
+ infop->di_min_sdu = infoackp->dl_min_sdu;
+ infop->di_state = infoackp->dl_current_state;
+ infop->di_mactype = infoackp->dl_mac_type;
- if (brdcst_addrlenp != NULL)
- *brdcst_addrlenp = dliap->dl_brdcst_addr_length;
- if (brdcst_addrp != NULL)
- (void) memcpy(brdcst_addrp,
- (char *)buf + dliap->dl_brdcst_addr_offset,
- dliap->dl_brdcst_addr_length);
- }
+ /* Information retrieved from the handle. */
+ (void) strlcpy(infop->di_linkname, dip->dli_linkname,
+ sizeof (infop->di_linkname));
+ infop->di_timeout = dip->dli_timeout;
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
+ return (DLPI_SUCCESS);
}
+/*
+ * This function parses 'linkname' and stores the 'provider' name and 'PPA'.
+ */
int
-dlpi_attach(int fd, int timeout, uint_t ppa)
+dlpi_parselink(const char *linkname, char *provider, uint_t *ppa)
{
- int rc = -1;
- size_t size;
- dl_attach_req_t dlar;
- dl_error_ack_t *dleap;
- union DL_primitives *buf;
- union DL_primitives *udlp;
+ ifspec_t ifsp;
- size = 0;
- size = MAX(sizeof (dl_ok_ack_t), size);
- size = MAX(sizeof (dl_error_ack_t), size);
+ if (linkname == NULL || !ifparse_ifspec(linkname, &ifsp))
+ return (DLPI_ELINKNAMEINVAL);
- if ((buf = malloc(size)) == NULL)
- return (-1);
+ if (provider != NULL)
+ (void) strlcpy(provider, ifsp.ifsp_devnm, DLPI_LINKNAME_MAX);
- dlar.dl_primitive = DL_ATTACH_REQ;
- dlar.dl_ppa = ppa;
+ if (ppa != NULL)
+ *ppa = ifsp.ifsp_ppa;
- if (strputmsg(fd, (uint8_t *)&dlar, DL_ATTACH_REQ_SIZE, 0) == -1)
- goto done;
+ return (DLPI_SUCCESS);
+}
+
+/*
+ * This function takes a provider name and a PPA and stores a full linkname
+ * as 'linkname'. If 'provider' already is a full linkname 'provider' name
+ * is stored in 'linkname'.
+ */
+int
+dlpi_makelink(char *linkname, const char *provider, uint_t ppa)
+{
+ int provlen = strlen(provider);
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
+ if (linkname == NULL || provlen == 0 || provlen >= DLPI_LINKNAME_MAX)
+ return (DLPI_ELINKNAMEINVAL);
- if (size < sizeof (t_uscalar_t)) {
- errno = EBADMSG;
- goto done;
+ if (!isdigit(provider[provlen - 1])) {
+ (void) snprintf(linkname, DLPI_LINKNAME_MAX, "%s%d", provider,
+ ppa);
+ } else {
+ (void) strlcpy(linkname, provider, DLPI_LINKNAME_MAX);
}
- udlp = (union DL_primitives *)buf;
- switch (udlp->dl_primitive) {
- case DL_OK_ACK:
- if (size < DL_OK_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
- break;
+ return (DLPI_SUCCESS);
+}
- case DL_ERROR_ACK:
- if (size < DL_ERROR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
+int
+dlpi_bind(dlpi_handle_t dh, uint_t sap, uint_t *boundsap)
+{
+ int retval;
+ dlpi_msg_t req, ack;
+ dl_bind_req_t *bindreqp;
+ dl_bind_ack_t *bindackp;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
- dleap = (dl_error_ack_t *)buf;
- switch (dleap->dl_errno) {
- case DL_BADPPA:
- errno = EINVAL;
- break;
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
- case DL_ACCESS:
- errno = EPERM;
- break;
+ DLPI_MSG_CREATE(req, DL_BIND_REQ);
+ DLPI_MSG_CREATE(ack, DL_BIND_ACK);
+ bindreqp = &(req.dlm_msg->bind_req);
- case DL_SYSERR:
- errno = dleap->dl_unix_errno;
- break;
+ /*
+ * If 'sap' is DLPI_ANY_SAP, bind to SAP 2 on token ring, else 0 on
+ * other interface types (SAP 0 has special significance on token ring).
+ */
+ if (sap == DLPI_ANY_SAP)
+ bindreqp->dl_sap = ((dip->dli_mactype == DL_TPR) ? 2 : 0);
+ else
+ bindreqp->dl_sap = sap;
- default:
- errno = EPROTO;
- break;
- }
+ bindreqp->dl_service_mode = DL_CLDLS;
+ bindreqp->dl_conn_mgmt = 0;
+ bindreqp->dl_max_conind = 0;
+ bindreqp->dl_xidtest_flg = 0;
- goto done;
+ retval = i_dlpi_msg_common(dip, &req, &ack, DL_BIND_ACK_SIZE, 0);
+ if (retval != DLPI_SUCCESS)
+ return (retval);
- default:
- errno = EBADMSG;
- goto done;
+ bindackp = &(ack.dlm_msg->bind_ack);
+ /*
+ * Received a DLPI_BIND_ACK, now verify that the bound SAP
+ * is equal to the SAP requested. Some DLPI MAC type may bind
+ * to a different SAP than requested, in this case 'boundsap'
+ * returns the actual bound SAP. For the case where 'boundsap'
+ * is NULL and 'sap' is not DLPI_ANY_SAP, dlpi_bind fails.
+ */
+ if (boundsap != NULL) {
+ *boundsap = bindackp->dl_sap;
+ } else if (sap != DLPI_ANY_SAP && bindackp->dl_sap != sap) {
+ if (dlpi_unbind(dh) != DLPI_SUCCESS)
+ return (DLPI_FAILURE);
+ else
+ return (DLPI_EUNAVAILSAP);
}
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
+ dip->dli_sap = bindackp->dl_sap; /* save sap value in handle */
+ return (DLPI_SUCCESS);
}
int
-dlpi_detach(int fd, int timeout)
+dlpi_unbind(dlpi_handle_t dh)
{
- int rc = -1;
- size_t size;
- dl_detach_req_t dldr;
- dl_error_ack_t *dleap;
- union DL_primitives *buf;
- union DL_primitives *udlp;
+ dlpi_msg_t req, ack;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
- size = 0;
- size = MAX(sizeof (dl_ok_ack_t), size);
- size = MAX(sizeof (dl_error_ack_t), size);
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
- if ((buf = malloc(size)) == NULL)
- return (-1);
+ DLPI_MSG_CREATE(req, DL_UNBIND_REQ);
+ DLPI_MSG_CREATE(ack, DL_OK_ACK);
- dldr.dl_primitive = DL_DETACH_REQ;
-
- if (strputmsg(fd, (uint8_t *)&dldr, DL_DETACH_REQ_SIZE, 0) == -1)
- goto done;
-
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
+ return (i_dlpi_msg_common(dip, &req, &ack, DL_OK_ACK_SIZE, 0));
+}
- if (size < sizeof (t_uscalar_t)) {
- errno = EBADMSG;
- goto done;
- }
+/*
+ * This function is invoked by dlpi_enabmulti() or dlpi_disabmulti() and
+ * based on the "op" value, multicast address is enabled/disabled.
+ */
+static int
+i_dlpi_multi(dlpi_handle_t dh, t_uscalar_t op, const uint8_t *addrp,
+ size_t addrlen)
+{
+ dlpi_msg_t req, ack;
+ dl_enabmulti_req_t *multireqp;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
- udlp = (union DL_primitives *)buf;
- switch (udlp->dl_primitive) {
- case DL_OK_ACK:
- if (size < DL_OK_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
- break;
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
- case DL_ERROR_ACK:
- if (size < DL_ERROR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
+ if (addrlen > DLPI_PHYSADDR_MAX)
+ return (DLPI_EINVAL);
- dleap = (dl_error_ack_t *)buf;
- switch (dleap->dl_errno) {
- case DL_SYSERR:
- errno = dleap->dl_unix_errno;
- break;
+ DLPI_MSG_CREATE(req, op);
+ DLPI_MSG_CREATE(ack, DL_OK_ACK);
- default:
- errno = EPROTO;
- break;
- }
- goto done;
+ multireqp = &(req.dlm_msg->enabmulti_req);
+ multireqp->dl_addr_length = addrlen;
+ multireqp->dl_addr_offset = sizeof (dl_enabmulti_req_t);
+ (void) memcpy(&multireqp[1], addrp, addrlen);
- default:
- errno = EBADMSG;
- goto done;
- }
+ return (i_dlpi_msg_common(dip, &req, &ack, DL_OK_ACK_SIZE, 0));
+}
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
+int
+dlpi_enabmulti(dlpi_handle_t dh, const void *addrp, size_t addrlen)
+{
+ return (i_dlpi_multi(dh, DL_ENABMULTI_REQ, addrp, addrlen));
}
int
-dlpi_bind(int fd, int timeout, uint_t sap, uint16_t mode,
- boolean_t conn_mgmt, uint32_t *max_conn_ind,
- uint32_t *xid_test, uint8_t *addrp, size_t *addrlenp)
+dlpi_disabmulti(dlpi_handle_t dh, const void *addrp, size_t addrlen)
{
- int rc = -1;
- size_t size;
- dl_bind_req_t dlbr;
- dl_bind_ack_t *dlbap;
- dl_error_ack_t *dleap;
- union DL_primitives *buf;
- union DL_primitives *udlp;
-
- size = 0;
- size = MAX(sizeof (dl_bind_ack_t) + MAXADDRLEN + MAXSAPLEN, size);
- size = MAX(sizeof (dl_error_ack_t), size);
-
- if ((buf = malloc(size)) == NULL)
- return (-1);
-
- dlbr.dl_primitive = DL_BIND_REQ;
- dlbr.dl_sap = sap;
- dlbr.dl_service_mode = mode;
- dlbr.dl_conn_mgmt = (conn_mgmt) ? 1 : 0;
- dlbr.dl_max_conind = (max_conn_ind != NULL) ? *max_conn_ind : 0;
- dlbr.dl_xidtest_flg = (xid_test != NULL) ? *xid_test : 0;
-
- if (strputmsg(fd, (uint8_t *)&dlbr, DL_BIND_REQ_SIZE, 0) == -1)
- goto done;
-
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
-
- if (size < sizeof (t_uscalar_t)) {
- errno = EBADMSG;
- goto done;
- }
+ return (i_dlpi_multi(dh, DL_DISABMULTI_REQ, addrp, addrlen));
+}
- udlp = (union DL_primitives *)buf;
- switch (udlp->dl_primitive) {
- case DL_BIND_ACK:
- if (size < DL_BIND_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
+/*
+ * This function is invoked by dlpi_promiscon() or dlpi_promiscoff(). Based
+ * on the value of 'op', promiscuous mode is turned on/off at the specified
+ * 'level'.
+ */
+static int
+i_dlpi_promisc(dlpi_handle_t dh, t_uscalar_t op, uint_t level)
+{
+ dlpi_msg_t req, ack;
+ dl_promiscon_req_t *promiscreqp;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
- dlbap = (dl_bind_ack_t *)buf;
- if (max_conn_ind != NULL)
- *max_conn_ind = dlbap->dl_max_conind;
- if (xid_test != NULL)
- *xid_test = dlbap->dl_xidtest_flg;
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
- if (dlbap->dl_addr_offset != 0) {
- if (dlbap->dl_addr_length == 0) {
- errno = EPROTO;
- goto done;
- }
+ DLPI_MSG_CREATE(req, op);
+ DLPI_MSG_CREATE(ack, DL_OK_ACK);
- if (addrlenp != NULL)
- *addrlenp = dlbap->dl_addr_length;
- if (addrp != NULL)
- (void) memcpy(addrp,
- (char *)buf + dlbap->dl_addr_offset,
- dlbap->dl_addr_length);
- }
+ promiscreqp = &(req.dlm_msg->promiscon_req);
+ promiscreqp->dl_level = level;
- break;
+ return (i_dlpi_msg_common(dip, &req, &ack, DL_OK_ACK_SIZE, 0));
+}
- case DL_ERROR_ACK:
- if (size < DL_ERROR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
+int
+dlpi_promiscon(dlpi_handle_t dh, uint_t level)
+{
+ return (i_dlpi_promisc(dh, DL_PROMISCON_REQ, level));
+}
- dleap = (dl_error_ack_t *)buf;
- switch (dleap->dl_errno) {
- case DL_BADADDR:
- errno = EINVAL;
- break;
-
- case DL_INITFAILED:
- case DL_NOTINIT:
- errno = EIO;
- break;
-
- case DL_ACCESS:
- errno = EACCES;
- break;
-
- case DL_NOADDR:
- errno = EFAULT;
- break;
-
- case DL_UNSUPPORTED:
- case DL_NOAUTO:
- case DL_NOXIDAUTO:
- case DL_NOTESTAUTO:
- errno = ENOTSUP;
- break;
-
- case DL_SYSERR:
- errno = dleap->dl_unix_errno;
- break;
-
- default:
- errno = EPROTO;
- break;
- }
- goto done;
+int
+dlpi_promiscoff(dlpi_handle_t dh, uint_t level)
+{
+ return (i_dlpi_promisc(dh, DL_PROMISCOFF_REQ, level));
+}
- default:
- errno = EBADMSG;
- goto done;
+int
+dlpi_get_physaddr(dlpi_handle_t dh, uint_t type, void *addrp, size_t *addrlenp)
+{
+ int retval;
+ dlpi_msg_t req, ack;
+ dl_phys_addr_req_t *physreqp;
+ dl_phys_addr_ack_t *physackp;
+ t_uscalar_t dataoff, datalen;
+ caddr_t datap, physackendp;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
+
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
+
+ if (addrlenp == NULL || addrp == NULL || *addrlenp < DLPI_PHYSADDR_MAX)
+ return (DLPI_EINVAL);
+
+ DLPI_MSG_CREATE(req, DL_PHYS_ADDR_REQ);
+ DLPI_MSG_CREATE(ack, DL_PHYS_ADDR_ACK);
+
+ physreqp = &(req.dlm_msg->physaddr_req);
+ physreqp->dl_addr_type = type;
+
+ retval = i_dlpi_msg_common(dip, &req, &ack, DL_PHYS_ADDR_ACK_SIZE, 0);
+ if (retval != DLPI_SUCCESS)
+ return (retval);
+
+ /* Received DL_PHYS_ADDR_ACK, store the physical address and length. */
+ physackp = &(ack.dlm_msg->physaddr_ack);
+ physackendp = (caddr_t)ack.dlm_msg + ack.dlm_msgsz;
+ dataoff = physackp->dl_addr_offset;
+ datalen = physackp->dl_addr_length;
+ if (dataoff != 0 && datalen != 0) {
+ datap = (caddr_t)physackp + dataoff;
+ if (datalen > DLPI_PHYSADDR_MAX)
+ return (DL_BADADDR);
+ if (dataoff < DL_PHYS_ADDR_ACK_SIZE ||
+ datap + datalen > physackendp)
+ return (DLPI_EBADMSG);
+
+ *addrlenp = physackp->dl_addr_length;
+ (void) memcpy(addrp, datap, datalen);
+ } else {
+ *addrlenp = datalen;
}
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
+ return (DLPI_SUCCESS);
}
int
-dlpi_unbind(int fd, int timeout)
+dlpi_set_physaddr(dlpi_handle_t dh, uint_t type, const void *addrp,
+ size_t addrlen)
{
- int rc = -1;
- size_t size;
- dl_unbind_req_t dlubr;
- dl_error_ack_t *dleap;
- union DL_primitives *buf;
- union DL_primitives *udlp;
+ dlpi_msg_t req, ack;
+ dl_set_phys_addr_req_t *setphysreqp;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
- size = 0;
- size = MAX(sizeof (dl_ok_ack_t), size);
- size = MAX(sizeof (dl_error_ack_t), size);
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
- if ((buf = malloc(size)) == NULL)
- return (-1);
+ if (addrp == NULL || type != DL_CURR_PHYS_ADDR ||
+ addrlen > DLPI_PHYSADDR_MAX)
+ return (DLPI_EINVAL);
- dlubr.dl_primitive = DL_UNBIND_REQ;
+ DLPI_MSG_CREATE(req, DL_SET_PHYS_ADDR_REQ);
+ DLPI_MSG_CREATE(ack, DL_OK_ACK);
- if (strputmsg(fd, (uint8_t *)&dlubr, DL_UNBIND_REQ_SIZE, 0) == -1)
- goto done;
+ setphysreqp = &(req.dlm_msg->set_physaddr_req);
+ setphysreqp->dl_addr_length = addrlen;
+ setphysreqp->dl_addr_offset = sizeof (dl_set_phys_addr_req_t);
+ (void) memcpy(&setphysreqp[1], addrp, addrlen);
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
+ return (i_dlpi_msg_common(dip, &req, &ack, DL_OK_ACK_SIZE, 0));
+}
- if (size < sizeof (t_uscalar_t)) {
- errno = EBADMSG;
- goto done;
+int
+dlpi_send(dlpi_handle_t dh, const void *daddrp, size_t daddrlen,
+ const void *msgbuf, size_t msglen, const dlpi_sendinfo_t *sendp)
+{
+ dlpi_msg_t req;
+ dl_unitdata_req_t *udatareqp;
+ uint_t sap;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
+
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
+
+ if (dip->dli_oflags & DLPI_RAW)
+ return (i_dlpi_strputmsg(dip->dli_fd, NULL, msgbuf, msglen, 0));
+
+ if (daddrp == NULL || daddrlen > DLPI_PHYSADDR_MAX)
+ return (DLPI_EINVAL);
+
+ DLPI_MSG_CREATE(req, DL_UNITDATA_REQ);
+ udatareqp = &(req.dlm_msg->unitdata_req);
+
+ /* Set priority to default priority range. */
+ udatareqp->dl_priority.dl_min = 0;
+ udatareqp->dl_priority.dl_max = 0;
+
+ /* Use SAP value if specified otherwise use bound SAP value. */
+ if (sendp != NULL) {
+ sap = sendp->dsi_sap;
+ if (sendp->dsi_prio.dl_min != DL_QOS_DONT_CARE)
+ udatareqp->dl_priority.dl_min = sendp->dsi_prio.dl_min;
+ if (sendp->dsi_prio.dl_max != DL_QOS_DONT_CARE)
+ udatareqp->dl_priority.dl_max = sendp->dsi_prio.dl_max;
+ } else {
+ sap = dip->dli_sap;
}
- udlp = (union DL_primitives *)buf;
- switch (udlp->dl_primitive) {
- case DL_OK_ACK:
- if (size < DL_OK_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
- break;
-
- case DL_ERROR_ACK:
- if (size < DL_ERROR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
-
- dleap = (dl_error_ack_t *)buf;
- switch (dleap->dl_errno) {
- case DL_SYSERR:
- errno = dleap->dl_unix_errno;
- break;
+ udatareqp->dl_dest_addr_length = daddrlen + dip->dli_saplen;
+ udatareqp->dl_dest_addr_offset = DL_UNITDATA_REQ_SIZE;
- default:
- errno = EPROTO;
- break;
- }
- goto done;
-
- default:
- errno = EBADMSG;
- goto done;
+ /*
+ * Since `daddrp' only has the link-layer destination address,
+ * we must prepend or append the SAP (according to dli_sapbefore)
+ * to make a full DLPI address.
+ */
+ if (dip->dli_sapbefore) {
+ i_dlpi_writesap(&udatareqp[1], sap, dip->dli_saplen);
+ (void) memcpy((caddr_t)&udatareqp[1] + dip->dli_saplen,
+ daddrp, daddrlen);
+ } else {
+ (void) memcpy(&udatareqp[1], daddrp, daddrlen);
+ i_dlpi_writesap((caddr_t)&udatareqp[1] + daddrlen, sap,
+ dip->dli_saplen);
}
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
+ return (i_dlpi_strputmsg(dip->dli_fd, &req, msgbuf, msglen, 0));
}
-static int
-i_dlpi_multi(int fd, int timeout, dlpi_multi_op_t op,
- uint8_t *addrp, size_t addr_length)
+int
+dlpi_recv(dlpi_handle_t dh, void *saddrp, size_t *saddrlenp, void *msgbuf,
+ size_t *msglenp, int msec, dlpi_recvinfo_t *recvp)
{
- int rc = -1;
- size_t opsize;
- size_t size;
- dl_enabmulti_req_t *dlemrp;
- dl_disabmulti_req_t *dldmrp;
- dl_error_ack_t *dleap;
- union DL_primitives *buf;
- union DL_primitives *udlp;
-
- opsize = (op == DLPI_MULTI_ENABLE) ? sizeof (dl_enabmulti_req_t) :
- sizeof (dl_disabmulti_req_t);
- opsize += addr_length;
-
- size = 0;
- size = MAX(opsize, size);
- size = MAX(sizeof (dl_ok_ack_t), size);
- size = MAX(sizeof (dl_error_ack_t), size);
-
- if ((buf = malloc(size)) == NULL)
- return (-1);
-
- if (op == DLPI_MULTI_ENABLE) {
- dlemrp = (dl_enabmulti_req_t *)buf;
- dlemrp->dl_primitive = DL_ENABMULTI_REQ;
- dlemrp->dl_addr_length = addr_length;
- dlemrp->dl_addr_offset = sizeof (dl_enabmulti_req_t);
- (void) memcpy(&dlemrp[1], addrp, addr_length);
- } else {
- dldmrp = (dl_disabmulti_req_t *)buf;
- dldmrp->dl_primitive = DL_DISABMULTI_REQ;
- dldmrp->dl_addr_length = addr_length;
- dldmrp->dl_addr_offset = sizeof (dl_disabmulti_req_t);
- (void) memcpy(&dldmrp[1], addrp, addr_length);
- }
+ int retval;
+ dlpi_msg_t ind;
+ size_t totmsglen;
+ dl_unitdata_ind_t *udatap;
+ t_uscalar_t dataoff, datalen;
+ caddr_t datap, indendp;
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
+
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
+ /*
+ * If handle is in raw mode ignore everything except total message
+ * length.
+ */
+ if (dip->dli_oflags & DLPI_RAW) {
+ retval = i_dlpi_strgetmsg(dip->dli_fd, msec, NULL, 0, 0, 0,
+ msgbuf, msglenp, &totmsglen);
- if (strputmsg(fd, (uint8_t *)buf, opsize, 0) == -1)
- goto done;
+ if (retval == DLPI_SUCCESS && recvp != NULL)
+ recvp->dri_totmsglen = totmsglen;
+ return (retval);
+ }
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
+ DLPI_MSG_CREATE(ind, DL_UNITDATA_IND);
+ udatap = &(ind.dlm_msg->unitdata_ind);
+ indendp = (caddr_t)ind.dlm_msg + ind.dlm_msgsz;
- if (size < sizeof (t_uscalar_t)) {
- errno = EBADMSG;
- goto done;
- }
+ if ((retval = i_dlpi_strgetmsg(dip->dli_fd, msec, &ind,
+ DL_UNITDATA_IND, DL_UNITDATA_IND, DL_UNITDATA_IND_SIZE,
+ msgbuf, msglenp, &totmsglen)) != DLPI_SUCCESS)
+ return (retval);
- udlp = (union DL_primitives *)buf;
- switch (udlp->dl_primitive) {
- case DL_OK_ACK:
- if (size < DL_OK_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
+ /*
+ * If DLPI link provides source address, store source address in
+ * 'saddrp' and source length in 'saddrlenp', else set saddrlenp to 0.
+ */
+ if (saddrp != NULL && saddrlenp != NULL) {
+ if (*saddrlenp < DLPI_PHYSADDR_MAX)
+ return (DLPI_EINVAL);
+
+ dataoff = udatap->dl_src_addr_offset;
+ datalen = udatap->dl_src_addr_length;
+ if (dataoff != 0 && datalen != 0) {
+ datap = (caddr_t)udatap + dataoff;
+ if (dataoff < DL_UNITDATA_IND_SIZE ||
+ datap + datalen > indendp)
+ return (DLPI_EBADMSG);
+
+ *saddrlenp = datalen - dip->dli_saplen;
+ if (*saddrlenp > DLPI_PHYSADDR_MAX)
+ return (DL_BADADDR);
+
+ if (dip->dli_sapbefore)
+ datap += dip->dli_saplen;
+ (void) memcpy(saddrp, datap, *saddrlenp);
+ } else {
+ *saddrlenp = 0;
}
- break;
+ }
- case DL_ERROR_ACK:
- if (size < DL_ERROR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
+ /*
+ * If destination address requested, check and save destination
+ * address, if any.
+ */
+ if (recvp != NULL) {
+ dataoff = udatap->dl_dest_addr_offset;
+ datalen = udatap->dl_dest_addr_length;
+ if (dataoff != 0 && datalen != 0) {
+ datap = (caddr_t)udatap + dataoff;
+ if (dataoff < DL_UNITDATA_IND_SIZE ||
+ datap + datalen > indendp)
+ return (DLPI_EBADMSG);
+
+ recvp->dri_destaddrlen = datalen - dip->dli_saplen;
+ if (recvp->dri_destaddrlen > DLPI_PHYSADDR_MAX)
+ return (DL_BADADDR);
+
+ if (dip->dli_sapbefore)
+ datap += dip->dli_saplen;
+ (void) memcpy(recvp->dri_destaddr, datap,
+ recvp->dri_destaddrlen);
+ } else {
+ recvp->dri_destaddrlen = 0;
}
- dleap = (dl_error_ack_t *)buf;
- switch (dleap->dl_errno) {
- case DL_BADADDR:
- errno = EINVAL;
- break;
-
- case DL_TOOMANY:
- errno = ENOSPC;
- break;
+ recvp->dri_dstaddrtype = udatap->dl_group_address;
+ recvp->dri_totmsglen = totmsglen;
+ }
- case DL_NOTSUPPORTED:
- errno = ENOTSUP;
- break;
+ return (DLPI_SUCCESS);
+}
- case DL_NOTENAB:
- errno = EINVAL;
- break;
+int
+dlpi_fd(dlpi_handle_t dh)
+{
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
- case DL_SYSERR:
- errno = dleap->dl_unix_errno;
- break;
+ return (dip != NULL ? dip->dli_fd : -1);
+}
- default:
- errno = EPROTO;
- break;
- }
- goto done;
+int
+dlpi_set_timeout(dlpi_handle_t dh, int sec)
+{
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
- default:
- errno = EBADMSG;
- goto done;
- }
+ if (dip == NULL)
+ return (DLPI_EINHANDLE);
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
+ dip->dli_timeout = sec;
+ return (DLPI_SUCCESS);
}
-int
-dlpi_enabmulti(int fd, int timeout, uint8_t *addrp,
- size_t addr_length)
+const char *
+dlpi_linkname(dlpi_handle_t dh)
{
- return (i_dlpi_multi(fd, timeout, DLPI_MULTI_ENABLE, addrp,
- addr_length));
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
+
+ return (dip != NULL ? dip->dli_linkname : NULL);
}
-int
-dlpi_disabmulti(int fd, int timeout, uint8_t *addrp,
- size_t addr_length)
+/*
+ * Returns DLPI style stored in the handle.
+ * Note: This function is used for test purposes only. Do not remove without
+ * fixing the DLPI testsuite.
+ */
+uint_t
+dlpi_style(dlpi_handle_t dh)
{
- return (i_dlpi_multi(fd, timeout, DLPI_MULTI_DISABLE, addrp,
- addr_length));
+ dlpi_impl_t *dip = (dlpi_impl_t *)dh;
+
+ return (dip->dli_style);
}
+/*
+ * This function attempts to open linkname under the following namespaces:
+ * - /dev
+ * - /devices
+ * If open doesn't succeed and link doesn't exist (ENOENT), this function
+ * returns DLPI_ENOLINK, otherwise returns DL_SYSERR.
+ */
static int
-i_dlpi_promisc(int fd, int timeout, dlpi_promisc_op_t op,
- uint_t level)
+i_dlpi_open(const char *provider, int *fd, uint_t flags)
{
- int rc = -1;
- size_t opsize;
- size_t size;
- dl_promiscon_req_t *dlpnrp;
- dl_promiscoff_req_t *dlpfrp;
- dl_error_ack_t *dleap;
- union DL_primitives *buf;
- union DL_primitives *udlp;
-
- opsize = (op == DLPI_PROMISC_ON) ? sizeof (dl_promiscon_req_t) :
- sizeof (dl_promiscoff_req_t);
-
- size = 0;
- size = MAX(opsize, size);
- size = MAX(sizeof (dl_ok_ack_t), size);
- size = MAX(sizeof (dl_error_ack_t), size);
-
- if ((buf = malloc(size)) == NULL)
- return (-1);
-
- if (op == DLPI_PROMISC_ON) {
- dlpnrp = (dl_promiscon_req_t *)buf;
- dlpnrp->dl_primitive = DL_PROMISCON_REQ;
- dlpnrp->dl_level = level;
-
- if (strputmsg(fd, (uint8_t *)dlpnrp, opsize, 0) == -1)
- goto done;
- } else {
- dlpfrp = (dl_promiscoff_req_t *)buf;
- dlpfrp->dl_primitive = DL_PROMISCOFF_REQ;
- dlpfrp->dl_level = level;
-
- if (strputmsg(fd, (uint8_t *)dlpfrp, opsize, 0) == -1)
- goto done;
- }
+ char path[MAXPATHLEN];
+ int oflags;
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
+ oflags = O_RDWR;
+ if (flags & DLPI_EXCL)
+ oflags |= O_EXCL;
- if (size < sizeof (t_uscalar_t)) {
- errno = EBADMSG;
- goto done;
- }
+ (void) snprintf(path, sizeof (path), "/dev/%s", provider);
- udlp = (union DL_primitives *)buf;
- switch (udlp->dl_primitive) {
- case DL_OK_ACK:
- if (size < DL_OK_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
- break;
+ if ((*fd = open(path, oflags)) != -1)
+ return (DLPI_SUCCESS);
- case DL_ERROR_ACK:
- if (size < DL_ERROR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
+ /*
+ * On diskless boot, it's possible the /dev links have not yet
+ * been created; fallback to /devices. When /dev links are
+ * created on demand, this code can be removed.
+ */
+ (void) snprintf(path, sizeof (path), "/devices/pseudo/clone@0:%s",
+ provider);
- dleap = (dl_error_ack_t *)buf;
- switch (dleap->dl_errno) {
- case DL_NOTSUPPORTED:
- case DL_UNSUPPORTED:
- errno = ENOTSUP;
- break;
+ if ((*fd = open(path, oflags)) != -1)
+ return (DLPI_SUCCESS);
- case DL_NOTENAB:
- errno = EINVAL;
- break;
+ return (errno == ENOENT ? DLPI_ENOLINK : DL_SYSERR);
+}
- case DL_SYSERR:
- errno = dleap->dl_unix_errno;
- break;
+/*
+ * Open a style 1 link. PPA is implicitly attached.
+ */
+static int
+i_dlpi_style1_open(dlpi_impl_t *dip)
+{
+ int retval, save_errno;
+ int fd;
- default:
- errno = EPROTO;
- break;
- }
- goto done;
+ /*
+ * In order to support open of syntax like device[.module[.module...]]
+ * where modules need to be pushed onto the device stream, open only
+ * device name, otherwise open the full linkname.
+ */
+ retval = i_dlpi_open((dip->dli_mod_cnt != 0) ? dip->dli_provider :
+ dip->dli_linkname, &fd, dip->dli_oflags);
- default:
- errno = EBADMSG;
- goto done;
+ if (retval != DLPI_SUCCESS) {
+ dip->dli_mod_pushed = 0;
+ return (retval);
}
+ dip->dli_fd = fd;
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
-}
+ /*
+ * Try to push modules (if any) onto the device stream. If I_PUSH
+ * fails, we increment count of modules pushed (dli_mod_pushed)
+ * expecting it is last module to be pushed and thus will be pushed
+ * in i_dlpi_style2_open().
+ */
+ for (dip->dli_mod_pushed = 0; dip->dli_mod_pushed < dip->dli_mod_cnt;
+ dip->dli_mod_pushed++) {
+ if (ioctl(fd, I_PUSH,
+ dip->dli_modlist[dip->dli_mod_pushed]) == -1) {
+ dip->dli_mod_pushed++;
+ return (DLPI_FAILURE);
+ }
+ }
-int
-dlpi_promiscon(int fd, int timeout, uint_t level)
-{
- return (i_dlpi_promisc(fd, timeout, DLPI_PROMISC_ON, level));
-}
+ if ((retval = i_dlpi_checkstyle(dip, DL_STYLE1)) != DLPI_SUCCESS) {
+ save_errno = errno;
+ (void) close(dip->dli_fd);
+ errno = save_errno;
+ dip->dli_mod_pushed = 0;
+ return (retval);
+ }
-int
-dlpi_promiscoff(int fd, int timeout, uint_t level)
-{
- return (i_dlpi_promisc(fd, timeout, DLPI_PROMISC_OFF, level));
+ return (DLPI_SUCCESS);
}
-int
-dlpi_phys_addr(int fd, int timeout, uint_t type, uint8_t *addrp,
- size_t *addrlenp)
+/*
+ * Open a style 2 link. PPA must be explicitly attached.
+ */
+static int
+i_dlpi_style2_open(dlpi_impl_t *dip)
{
- int rc = -1;
- size_t size;
- dl_phys_addr_req_t dlpar;
- dl_phys_addr_ack_t *dlpaap;
- dl_error_ack_t *dleap;
- union DL_primitives *buf;
- union DL_primitives *udlp;
+ int fd;
+ int retval, save_errno;
- size = 0;
- size = MAX(sizeof (dl_phys_addr_ack_t) + MAXADDRLEN, size);
- size = MAX(sizeof (dl_error_ack_t), size);
+ /*
+ * If style 1 open failed, we need to determine how far it got and
+ * finish up the open() call as a style 2 open.
+ *
+ * If no modules were pushed (mod_pushed == 0), then we need to
+ * open it as a style 2 link.
+ *
+ * If the pushing of the last module failed, we need to
+ * try pushing it as a style 2 module. Decrement dli_mod_pushed
+ * count so it can be pushed onto the stream.
+ *
+ * Otherwise we failed during the push of an intermediate module and
+ * must fail out and close the link.
+ */
+ if (dip->dli_mod_pushed == 0) {
+ if ((retval = i_dlpi_open(dip->dli_provider, &fd,
+ dip->dli_oflags)) != DLPI_SUCCESS)
+ return (retval);
+
+ dip->dli_fd = fd;
+ } else if (dip->dli_mod_pushed == dip->dli_mod_cnt) {
+ if (i_dlpi_remove_ppa(dip->dli_modlist[dip->dli_mod_cnt - 1])
+ != DLPI_SUCCESS)
+ return (DLPI_ELINKNAMEINVAL);
+
+ dip->dli_mod_pushed--;
+ fd = dip->dli_fd;
+ } else {
+ return (DLPI_ELINKNAMEINVAL);
+ }
- if ((buf = malloc(size)) == NULL)
- return (-1);
+ /* Try and push modules (if any) onto the device stream. */
+ for (; dip->dli_mod_pushed < dip->dli_mod_cnt; dip->dli_mod_pushed++) {
+ if (ioctl(fd, I_PUSH,
+ dip->dli_modlist[dip->dli_mod_pushed]) == -1) {
+ retval = DL_SYSERR;
+ goto failure;
+ }
+ }
- dlpar.dl_primitive = DL_PHYS_ADDR_REQ;
- dlpar.dl_addr_type = type;
+ /*
+ * Special case: DLPI_SERIAL flag (synchronous serial lines) is not a
+ * DLPI link so attach and ignore rest.
+ */
+ if (dip->dli_oflags & DLPI_SERIAL)
+ goto attach;
- if (strputmsg(fd, (uint8_t *)&dlpar, DL_PHYS_ADDR_REQ_SIZE, 0) == -1)
- goto done;
+ if ((retval = i_dlpi_checkstyle(dip, DL_STYLE2)) != DLPI_SUCCESS)
+ goto failure;
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
+ /*
+ * Succeeded opening the link and verified it is style2. Now attach to
+ * PPA only if DLPI_NOATTACH is not set.
+ */
+ if (dip->dli_oflags & DLPI_NOATTACH)
+ return (DLPI_SUCCESS);
- if (size < sizeof (t_uscalar_t)) {
- errno = EBADMSG;
- goto done;
- }
+attach:
+ if ((retval = i_dlpi_attach(dip)) != DLPI_SUCCESS)
+ goto failure;
- udlp = (union DL_primitives *)buf;
- switch (udlp->dl_primitive) {
- case DL_PHYS_ADDR_ACK:
- if (size < DL_PHYS_ADDR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
+ return (DLPI_SUCCESS);
- dlpaap = (dl_phys_addr_ack_t *)buf;
- if (dlpaap->dl_addr_offset != 0) {
- if (dlpaap->dl_addr_length == 0) {
- errno = EPROTO;
- goto done;
- }
+failure:
+ save_errno = errno;
+ (void) close(dip->dli_fd);
+ errno = save_errno;
+ return (retval);
+}
- if (addrlenp != NULL)
- *addrlenp = dlpaap->dl_addr_length;
+/*
+ * Verify with DLPI that the link is the expected DLPI 'style' device,
+ * dlpi_info sets the DLPI style in the DLPI handle.
+ */
+static int
+i_dlpi_checkstyle(dlpi_impl_t *dip, t_uscalar_t style)
+{
+ int retval;
+ dlpi_info_t dlinfo;
- if (addrp != NULL)
- (void) memcpy(addrp,
- (char *)buf + dlpaap->dl_addr_offset,
- dlpaap->dl_addr_length);
- }
- break;
+ retval = dlpi_info((dlpi_handle_t)dip, &dlinfo, 0);
+ if (retval == DLPI_SUCCESS && dip->dli_style != style)
+ retval = DLPI_EBADLINK;
- case DL_ERROR_ACK:
- if (size < DL_ERROR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
+ return (retval);
+}
- dleap = (dl_error_ack_t *)buf;
- switch (dleap->dl_errno) {
- case DL_SYSERR:
- errno = dleap->dl_unix_errno;
- break;
+/*
+ * Remove PPA from end of linkname.
+ * Return DLPI_SUCCESS if found, else return DLPI_FAILURE.
+ */
+static int
+i_dlpi_remove_ppa(char *linkname)
+{
+ int i = strlen(linkname) - 1;
- default:
- errno = EPROTO;
- break;
- }
- goto done;
+ if (i == -1 || !isdigit(linkname[i--]))
+ return (DLPI_FAILURE);
- default:
- errno = EBADMSG;
- goto done;
- }
+ while (i >= 0 && isdigit(linkname[i]))
+ i--;
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
+ linkname[i + 1] = '\0';
+ return (DLPI_SUCCESS);
}
-int
-dlpi_set_phys_addr(int fd, int timeout, uint8_t *addrp,
- size_t addr_length)
+/*
+ * For DLPI style 2 providers, an explicit attach of PPA is required.
+ */
+static int
+i_dlpi_attach(dlpi_impl_t *dip)
{
- int rc = -1;
- size_t opsize;
- size_t size;
- dl_set_phys_addr_req_t *dlspap;
- dl_error_ack_t *dleap;
- union DL_primitives *buf;
- union DL_primitives *udlp;
-
- opsize = sizeof (dl_set_phys_addr_req_t) + addr_length;
-
- size = 0;
- size = MAX(opsize, size);
- size = MAX(sizeof (dl_ok_ack_t), size);
- size = MAX(sizeof (dl_error_ack_t), size);
-
- if ((buf = malloc(size)) == NULL)
- return (-1);
-
- dlspap = (dl_set_phys_addr_req_t *)buf;
- dlspap->dl_primitive = DL_SET_PHYS_ADDR_REQ;
- dlspap->dl_addr_length = addr_length;
- dlspap->dl_addr_offset = sizeof (dl_set_phys_addr_req_t);
- (void) memcpy(&dlspap[1], addrp, addr_length);
-
- if (strputmsg(fd, (uint8_t *)dlspap, opsize, 0) == -1)
- goto done;
-
- if (strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL) == -1)
- goto done;
-
- if (size < sizeof (t_uscalar_t)) {
- errno = EBADMSG;
- goto done;
- }
-
- udlp = (union DL_primitives *)buf;
- switch (udlp->dl_primitive) {
- case DL_OK_ACK:
- if (size < DL_OK_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
- break;
+ dlpi_msg_t req, ack;
+ dl_attach_req_t *attachreqp;
- case DL_ERROR_ACK:
- if (size < DL_ERROR_ACK_SIZE) {
- errno = EBADMSG;
- goto done;
- }
+ /*
+ * Special case: DLPI_SERIAL flag (synchronous serial lines)
+ * is not a DLPI link so ignore DLPI style.
+ */
+ if (dip->dli_style != DL_STYLE2 && !(dip->dli_oflags & DLPI_SERIAL))
+ return (DLPI_ENOTSTYLE2);
- dleap = (dl_error_ack_t *)buf;
- switch (dleap->dl_errno) {
- case DL_BADADDR:
- errno = EINVAL;
- break;
+ DLPI_MSG_CREATE(req, DL_ATTACH_REQ);
+ DLPI_MSG_CREATE(ack, DL_OK_ACK);
- case DL_NOTSUPPORTED:
- errno = ENOTSUP;
- break;
+ attachreqp = &(req.dlm_msg->attach_req);
+ attachreqp->dl_ppa = dip->dli_ppa;
- case DL_SYSERR:
- errno = dleap->dl_unix_errno;
- break;
+ return (i_dlpi_msg_common(dip, &req, &ack, DL_OK_ACK_SIZE, 0));
+}
- default:
- errno = EPROTO;
- break;
- }
- goto done;
+/*
+ * Enable DLPI passive mode on a DLPI handle. We intentionally do not care
+ * if this request fails, as this indicates the underlying DLPI device does
+ * not support link aggregation (pre-GLDV3 device drivers), and thus will
+ * see the expected behavior without failing with DL_SYSERR/EBUSY when issuing
+ * DLPI primitives like DL_BIND_REQ. For further info see dlpi(7p).
+ */
+static void
+i_dlpi_passive(dlpi_impl_t *dip)
+{
+ dlpi_msg_t req, ack;
- default:
- errno = EBADMSG;
- goto done;
- }
+ DLPI_MSG_CREATE(req, DL_PASSIVE_REQ);
+ DLPI_MSG_CREATE(ack, DL_OK_ACK);
- rc = 0; /* success */
-done:
- free(buf);
- return (rc);
+ (void) i_dlpi_msg_common(dip, &req, &ack, DL_OK_ACK_SIZE, 0);
}
-void
-dlpi_passive(int fd, int timeout)
+/*
+ * Send a dlpi control message and/or data message on a stream. The inputs
+ * for this function are:
+ * int fd: file descriptor of open stream to send message
+ * const dlpi_msg_t *dlreqp: request message structure
+ * void *databuf: data buffer
+ * size_t datalen: data buffer len
+ * int flags: flags to set for putmsg()
+ * Returns DLPI_SUCCESS if putmsg() succeeds, otherwise DL_SYSERR on failure.
+ */
+static int
+i_dlpi_strputmsg(int fd, const dlpi_msg_t *dlreqp,
+ const void *databuf, size_t datalen, int flags)
{
- size_t size;
- dl_passive_req_t dlpr;
- union DL_primitives *buf;
+ int retval;
+ struct strbuf ctl;
+ struct strbuf data;
- size = MAX(sizeof (dl_ok_ack_t), sizeof (dl_error_ack_t));
+ if (dlreqp != NULL) {
+ ctl.buf = (void *)dlreqp->dlm_msg;
+ ctl.len = dlreqp->dlm_msgsz;
+ }
- if ((buf = malloc(size)) == NULL)
- return;
+ data.buf = (void *)databuf;
+ data.len = datalen;
- dlpr.dl_primitive = DL_PASSIVE_REQ;
+ retval = putmsg(fd, (dlreqp == NULL ? NULL: &ctl),
+ (databuf == NULL ? NULL : &data), flags);
- /*
- * We don't care about the outcome of this operation. We at least
- * don't want to return until the operation completes or the
- * timeout expires.
- */
- if (strputmsg(fd, (uint8_t *)&dlpr, DL_PASSIVE_REQ_SIZE, 0) == 0)
- (void) strgetmsg(fd, timeout, (char *)buf, &size, NULL, NULL);
- free(buf);
+ return ((retval == 0) ? DLPI_SUCCESS : DL_SYSERR);
}
+/*
+ * Get a DLPI control message and/or data message from a stream. The inputs
+ * for this function are:
+ * int fd: file descriptor of open stream
+ * int msec: timeout to wait for message
+ * dlpi_msg_t *dlreplyp: reply message structure, the message size
+ * member on return stores actual size received
+ * t_uscalar_t dlreqprim: requested primitive
+ * t_uscalar_t dlreplyprim:acknowledged primitive in response to request
+ * size_t dlreplyminsz: minimum size of acknowledged primitive size
+ * void *databuf: data buffer
+ * size_t *datalenp: data buffer len
+ * size_t *totdatalenp: total data received. Greater than 'datalenp' if
+ * actual data received is larger than 'databuf'
+ * Function returns DLPI_SUCCESS if requested message is retrieved
+ * otherwise returns error code or timeouts.
+ */
static int
-i_dlpi_style1_open(dlpi_if_attr_t *diap)
+i_dlpi_strgetmsg(int fd, int msec, dlpi_msg_t *dlreplyp, t_uscalar_t dlreqprim,
+ t_uscalar_t dlreplyprim, size_t dlreplyminsz, void *databuf,
+ size_t *datalenp, size_t *totdatalenp)
{
- int fd;
- int cnt;
- dl_info_ack_t dlia;
+ int retval;
+ int flags = 0;
+ struct strbuf ctl, data;
+ struct pollfd pfd;
+ hrtime_t start, current;
+ long bufc[DLPI_CHUNKSIZE / sizeof (long)];
+ long bufd[DLPI_CHUNKSIZE / sizeof (long)];
+ union DL_primitives *dlprim;
+ boolean_t infinite = (msec < 0); /* infinite timeout */
+
+ if ((dlreplyp == NULL && databuf == NULL) ||
+ (databuf == NULL && datalenp != NULL) ||
+ (databuf != NULL && datalenp == NULL))
+ return (DLPI_EINVAL);
- /* Open device */
- if ((fd = dlpi_open(diap->devname)) == -1) {
- diap->style1_failed = B_TRUE;
- diap->mod_pushed = 0;
- return (-1);
- } else {
- diap->style1_fd = fd;
- }
+ pfd.fd = fd;
+ pfd.events = POLLIN | POLLPRI;
- /*
- * Try to push modules (if any) onto the device stream
- */
- for (cnt = 0; cnt < diap->mod_cnt; cnt++) {
- if (ioctl(fd, I_PUSH, diap->modlist[cnt]) == -1) {
- diap->mod_pushed = cnt+1;
- return (-1);
+ ctl.buf = (dlreplyp == NULL) ? bufc : (void *)dlreplyp->dlm_msg;
+ ctl.len = 0;
+ ctl.maxlen = (dlreplyp == NULL) ? sizeof (bufc) : dlreplyp->dlm_msgsz;
+
+ data.buf = (databuf == NULL) ? bufd : databuf;
+ data.len = 0;
+ data.maxlen = (databuf == NULL) ? sizeof (bufd): *datalenp;
+
+ for (;;) {
+ if (!infinite)
+ start = gethrtime() / (NANOSEC / MILLISEC);
+
+ switch (poll(&pfd, 1, msec)) {
+ default:
+ break;
+ case 0:
+ return (DLPI_ETIMEDOUT);
+ case -1:
+ return (DL_SYSERR);
}
- }
- if (dlpi_info(fd, -1, &dlia, NULL, NULL, NULL, NULL, NULL, NULL) == -1)
- goto failed;
+ if ((retval = getmsg(fd, &ctl, &data, &flags)) < 0)
+ return (DL_SYSERR);
+
+ if (totdatalenp != NULL)
+ *totdatalenp = data.len;
+
+ /*
+ * The supplied DLPI_CHUNKSIZE sized buffers are large enough
+ * to retrieve all valid DLPI responses in one iteration.
+ * If MORECTL or MOREDATA is set, we are not interested in the
+ * remainder of the message. Temporary buffers are used to
+ * drain the remainder of this message.
+ * The special case we have to account for is if
+ * a higher priority messages is enqueued whilst handling
+ * this condition. We use a change in the flags parameter
+ * returned by getmsg() to indicate the message has changed.
+ */
+ while (retval & (MORECTL | MOREDATA)) {
+ struct strbuf cscratch, dscratch;
+ int oflags = flags;
+
+ cscratch.buf = (char *)bufc;
+ dscratch.buf = (char *)bufd;
+ cscratch.len = dscratch.len = 0;
+ cscratch.maxlen = dscratch.maxlen =
+ sizeof (bufc);
+
+ if ((retval = getmsg(fd, &cscratch, &dscratch,
+ &flags)) < 0)
+ return (DL_SYSERR);
+
+ if (totdatalenp != NULL)
+ *totdatalenp += dscratch.len;
+ /*
+ * In the special case of higher priority
+ * message received, the low priority message
+ * received earlier is discarded, if no data
+ * or control message is left.
+ */
+ if ((flags != oflags) &&
+ !(retval & (MORECTL | MOREDATA)) &&
+ (cscratch.len != 0)) {
+ ctl.len = MIN(cscratch.len, DLPI_CHUNKSIZE);
+ if (dlreplyp != NULL)
+ (void) memcpy(dlreplyp->dlm_msg, bufc,
+ ctl.len);
+ break;
+ }
+ }
+
+ /*
+ * If we were expecting a data message, and we got one, set
+ * *datalenp. If we aren't waiting on a control message, then
+ * we're done.
+ */
+ if (databuf != NULL && data.len >= 0) {
+ *datalenp = data.len;
+ if (dlreplyp == NULL)
+ break;
+ }
+
+ /*
+ * If we were expecting a control message, and the message
+ * we received is at least big enough to be a DLPI message,
+ * then verify it's a reply to something we sent. If it
+ * is a reply to something we sent, also verify its size.
+ */
+ if (dlreplyp != NULL && ctl.len >= sizeof (t_uscalar_t)) {
+ dlprim = dlreplyp->dlm_msg;
+ if (dlprim->dl_primitive == dlreplyprim) {
+ if (ctl.len < dlreplyminsz)
+ return (DLPI_EBADMSG);
+ dlreplyp->dlm_msgsz = ctl.len;
+ break;
+ } else if (dlprim->dl_primitive == DL_ERROR_ACK) {
+ if (ctl.len < DL_ERROR_ACK_SIZE)
+ return (DLPI_EBADMSG);
+
+ /* Is it ours? */
+ if (dlprim->error_ack.dl_error_primitive ==
+ dlreqprim)
+ break;
+ }
+ }
- if (dlia.dl_provider_style != DL_STYLE1)
- goto failed;
+ if (!infinite) {
+ current = gethrtime() / (NANOSEC / MILLISEC);
+ msec -= (current - start);
- diap->style = DL_STYLE1;
- diap->style1_failed = B_FALSE;
+ if (msec <= 0)
+ return (DLPI_ETIMEDOUT);
+ }
+ }
- return (fd);
-failed:
- diap->style1_failed = B_TRUE;
- (void) dlpi_close(fd);
- return (-1);
+ return (DLPI_SUCCESS);
}
+/*
+ * Common routine invoked by all DLPI control routines. The inputs for this
+ * function are:
+ * dlpi_impl_t *dip: internal dlpi handle
+ * const dlpi_msg_t *dlreqp: request message structure
+ * dlpi_msg_t *dlreplyp: reply message structure
+ * size_t dlreplyminsz: minimum size of reply primitive
+ * int flags: flags to be set to send a message
+ * This routine succeeds if the message is an expected request/acknowledged
+ * message. Unexpected asynchronous messages (e.g. unexpected DL_NOTIFY_IND
+ * messages) will be discarded.
+ */
static int
-i_dlpi_style2_open(dlpi_if_attr_t *diap)
+i_dlpi_msg_common(dlpi_impl_t *dip, const dlpi_msg_t *dlreqp,
+ dlpi_msg_t *dlreplyp, size_t dlreplyminsz, int flags)
{
- int fd;
- uint_t ppa;
- dl_info_ack_t dlia;
+ int retval;
+ t_uscalar_t dlreqprim = dlreqp->dlm_msg->dl_primitive;
+ t_uscalar_t dlreplyprim = dlreplyp->dlm_msg->dl_primitive;
- /*
- * If style 1 open failed, we need to determine how far it got and
- * finish up the open() call as a style 2 open
- *
- * If no modules were pushed (mod_pushed == 0), then we need to
- * strip off the ppa off the device name and open it as a style 2
- * device
- *
- * If the pushing of the last module failed, we need to strip off the
- * ppa from that module and try pushing it as a style 2 module
- *
- * Otherwise we failed during the push of an intermediate module and
- * must fail out and close the device.
- *
- * And if style1 did not fail (i.e. we called style2 open directly),
- * just open the device
- */
- if (diap->style1_failed) {
- if (!diap->mod_pushed) {
- if (i_dlpi_ifrm_num(diap->devname, &ppa) < 0)
- return (-1);
- if ((fd = dlpi_open(diap->devname)) == -1)
- return (-1);
- } else if (diap->mod_pushed == diap->mod_cnt) {
- if (i_dlpi_ifrm_num(
- diap->modlist[diap->mod_cnt - 1], &ppa) < 0)
- return (-1);
- diap->mod_pushed--;
- fd = diap->style1_fd;
- } else {
- return (-1);
- }
- } else {
- if ((fd = dlpi_open(diap->devname)) == -1)
- return (-1);
- }
+ /* Put the requested primitive on the stream. */
+ retval = i_dlpi_strputmsg(dip->dli_fd, dlreqp, NULL, 0, flags);
+ if (retval != DLPI_SUCCESS)
+ return (retval);
+
+ /* Retrieve acknowledged message for requested primitive. */
+ retval = i_dlpi_strgetmsg(dip->dli_fd, (dip->dli_timeout * MILLISEC),
+ dlreplyp, dlreqprim, dlreplyprim, dlreplyminsz, NULL, NULL, NULL);
+ if (retval != DLPI_SUCCESS)
+ return (retval);
/*
- * Try and push modules (if any) onto the device stream
+ * If primitive is DL_ERROR_ACK, set errno.
*/
- for (; diap->mod_pushed < diap->mod_cnt; diap->mod_pushed++) {
- if (ioctl(fd, I_PUSH,
- diap->modlist[diap->mod_pushed]) == -1)
- goto failed;
+ if (dlreplyp->dlm_msg->dl_primitive == DL_ERROR_ACK) {
+ errno = dlreplyp->dlm_msg->error_ack.dl_unix_errno;
+ retval = dlreplyp->dlm_msg->error_ack.dl_errno;
}
- if (dlpi_info(fd, -1, &dlia, NULL, NULL, NULL, NULL, NULL,
- NULL) == -1)
- goto failed;
-
- if (dlia.dl_provider_style != DL_STYLE2)
- goto failed;
+ return (retval);
+}
- diap->style = DL_STYLE2;
+/*
+ * DLPI error codes.
+ */
+static const char *dlpi_errlist[] = {
+ "bad LSAP selector", /* DL_BADSAP 0x00 */
+ "DLSAP address in improper format or invalid", /* DL_BADADDR 0x01 */
+ "improper permissions for request", /* DL_ACCESS 0x02 */
+ "primitive issued in improper state", /* DL_OUTSTATE 0x03 */
+ NULL, /* DL_SYSERR 0x04 */
+ "sequence number not from outstanding DL_CONN_IND",
+ /* DL_BADCORR 0x05 */
+ "user data exceeded provider limit", /* DL_BADDATA 0x06 */
+ "requested service not supplied by provider",
+ /* DL_UNSUPPORTED 0x07 */
+ "specified PPA was invalid", /* DL_BADPPA 0x08 */
+ "primitive received not known by provider", /* DL_BADPRIM 0x09 */
+ "QoS parameters contained invalid values",
+ /* DL_BADQOSPARAM 0x0a */
+ "QoS structure type is unknown/unsupported", /* DL_BADQOSTYPE 0x0b */
+ "token used not an active stream", /* DL_BADTOKEN 0x0c */
+ "attempted second bind with dl_max_conind", /* DL_BOUND 0x0d */
+ "physical link initialization failed", /* DL_INITFAILED 0x0e */
+ "provider couldn't allocate alternate address", /* DL_NOADDR 0x0f */
+ "physical link not initialized", /* DL_NOTINIT 0x10 */
+ "previous data unit could not be delivered",
+ /* DL_UNDELIVERABLE 0x11 */
+ "primitive is known but unsupported",
+ /* DL_NOTSUPPORTED 0x12 */
+ "limit exceeded", /* DL_TOOMANY 0x13 */
+ "promiscuous mode not enabled", /* DL_NOTENAB 0x14 */
+ "other streams for PPA in post-attached", /* DL_BUSY 0x15 */
+ "automatic handling XID&TEST unsupported", /* DL_NOAUTO 0x16 */
+ "automatic handling of XID unsupported", /* DL_NOXIDAUTO 0x17 */
+ "automatic handling of TEST unsupported", /* DL_NOTESTAUTO 0x18 */
+ "automatic handling of XID response", /* DL_XIDAUTO 0x19 */
+ "automatic handling of TEST response", /* DL_TESTAUTO 0x1a */
+ "pending outstanding connect indications" /* DL_PENDING 0x1b */
+};
- if (dlpi_attach(fd, -1, diap->ppa) < 0)
- goto failed;
+/*
+ * libdlpi error codes.
+ */
+static const char *libdlpi_errlist[] = {
+ "DLPI operation succeeded", /* DLPI_SUCCESS */
+ "invalid argument", /* DLPI_EINVAL */
+ "invalid DLPI linkname", /* DLPI_ELINKNAMEINVAL */
+ "DLPI link does not exist", /* DLPI_ENOLINK */
+ "bad DLPI link", /* DLPI_EBADLINK */
+ "invalid DLPI handle", /* DLPI_EINHANDLE */
+ "DLPI operation timed out", /* DLPI_ETIMEDOUT */
+ "unsupported DLPI version", /* DLPI_EVERNOTSUP */
+ "unsupported DLPI connection mode", /* DLPI_EMODENOTSUP */
+ "unavailable DLPI SAP", /* DLPI_EUNAVAILSAP */
+ "DLPI operation failed", /* DLPI_FAILURE */
+ "DLPI style-2 node reports style-1", /* DLPI_ENOTSTYLE2 */
+ "bad DLPI message", /* DLPI_EBADMSG */
+ "DLPI raw mode not supported" /* DLPI_ERAWNOTSUP */
+};
- return (fd);
-failed:
- (void) dlpi_close(fd);
- return (-1);
+const char *
+dlpi_strerror(int err)
+{
+ if (err == DL_SYSERR)
+ return (strerror(errno));
+ else if (err >= 0 && err < NELEMS(dlpi_errlist))
+ return (dgettext(TEXT_DOMAIN, dlpi_errlist[err]));
+ else if (err > DLPI_SUCCESS && err < DLPI_ERRMAX)
+ return (dgettext(TEXT_DOMAIN, libdlpi_errlist[err -
+ DLPI_SUCCESS]));
+ else
+ return (dgettext(TEXT_DOMAIN, "Unknown DLPI error"));
}
-static int
-i_dlpi_ifname_parse(const char *ifname, dlpi_if_attr_t *diap)
+/*
+ * Each table entry comprises a DLPI/Private mactype and the description.
+ */
+static const dlpi_mactype_t dlpi_mactypes[] = {
+ { DL_CSMACD, "CSMA/CD" },
+ { DL_TPB, "Token Bus" },
+ { DL_TPR, "Token Ring" },
+ { DL_METRO, "Metro Net" },
+ { DL_ETHER, "Ethernet" },
+ { DL_HDLC, "HDLC" },
+ { DL_CHAR, "Sync Character" },
+ { DL_CTCA, "CTCA" },
+ { DL_FDDI, "FDDI" },
+ { DL_FRAME, "Frame Relay (LAPF)" },
+ { DL_MPFRAME, "MP Frame Relay" },
+ { DL_ASYNC, "Async Character" },
+ { DL_IPX25, "X.25 (Classic IP)" },
+ { DL_LOOP, "Software Loopback" },
+ { DL_FC, "Fiber Channel" },
+ { DL_ATM, "ATM" },
+ { DL_IPATM, "ATM (Classic IP)" },
+ { DL_X25, "X.25 (LAPB)" },
+ { DL_ISDN, "ISDN" },
+ { DL_HIPPI, "HIPPI" },
+ { DL_100VG, "100BaseVG Ethernet" },
+ { DL_100VGTPR, "100BaseVG Token Ring" },
+ { DL_ETH_CSMA, "Ethernet/IEEE 802.3" },
+ { DL_100BT, "100BaseT" },
+ { DL_IB, "Infiniband" },
+ { DL_IPV4, "IPv4 Tunnel" },
+ { DL_IPV6, "IPv6 Tunnel" },
+ { DL_WIFI, "IEEE 802.11" }
+};
+
+const char *
+dlpi_mactype(uint_t mactype)
{
- char *modlist = NULL; /* list of modules to push */
- int cnt = 0; /* number of modules to push */
- char modbuf[LIFNAMSIZ + 32];
- char *nxtmod;
- char *p;
- int len;
-
- /* if lun is specified fail (backwards compat) */
- if (strchr(ifname, ':') != NULL)
- return (-1);
-
- /* save copy of original device name */
- if (strlcpy(diap->ifname, ifname, sizeof (diap->ifname)) >=
- sizeof (diap->ifname))
- return (-1);
-
- /* initialize ppa */
- diap->ppa = -1;
-
- /* get provider name and ppa from ifname */
- len = strlen(ifname);
- for (p = (char *)ifname + len; --p != ifname; len--) {
- if (!isdigit(*p)) {
- (void) strlcpy(diap->provider, ifname, len + 1);
- diap->ppa = atoi(p + 1);
- break;
- }
- }
+ int i;
- if (strlcpy(modbuf, diap->ifname, sizeof (modbuf)) >=
- sizeof (modbuf))
- return (-1);
-
- /* parse '.' delimited module list */
- modlist = strchr(modbuf, '.');
- if (modlist != NULL) {
- /* null-terminate interface name (device) */
- *modlist = '\0';
- modlist++;
- while (modlist && cnt < MAX_MODS) {
- if (*modlist == '\0')
- return (-1);
-
- nxtmod = strchr(modlist, '.');
- if (nxtmod) {
- *nxtmod = '\0';
- nxtmod++;
- }
- if (strlcpy(diap->modlist[cnt], modlist,
- sizeof (diap->modlist[cnt])) >=
- sizeof (diap->modlist[cnt]))
- return (-1);
- cnt++;
- modlist = nxtmod;
- }
+ for (i = 0; i < NELEMS(dlpi_mactypes); i++) {
+ if (dlpi_mactypes[i].dm_mactype == mactype)
+ return (dlpi_mactypes[i].dm_desc);
}
- diap->mod_cnt = cnt;
- if (strlcpy(diap->devname, modbuf, sizeof (diap->devname)) >=
- sizeof (diap->devname))
- return (-1);
-
- return (0);
+ return ("Unknown MAC Type");
}
-int
-dlpi_if_open(const char *ifname, dlpi_if_attr_t *diap,
- boolean_t force_style2)
-{
- int fd;
-
- if (i_dlpi_ifname_parse(ifname, diap) == -1) {
- errno = EINVAL;
- return (-1);
- }
+/*
+ * Each table entry comprises a DLPI primitive and the maximum buffer
+ * size needed, in bytes, for the DLPI message (see <sys/dlpi.h> for details).
+ */
+static const dlpi_primsz_t dlpi_primsizes[] = {
+{ DL_INFO_REQ, DL_INFO_REQ_SIZE },
+{ DL_INFO_ACK, DL_INFO_ACK_SIZE + (2 * DLPI_PHYSADDR_MAX) +
+ DLPI_SAPLEN_MAX + (2 * sizeof (union DL_qos_types))},
+{ DL_ATTACH_REQ, DL_ATTACH_REQ_SIZE },
+{ DL_BIND_REQ, DL_BIND_REQ_SIZE },
+{ DL_BIND_ACK, DL_BIND_ACK_SIZE + DLPI_PHYSADDR_MAX +
+ DLPI_SAPLEN_MAX },
+{ DL_UNBIND_REQ, DL_UNBIND_REQ_SIZE },
+{ DL_ENABMULTI_REQ, DL_ENABMULTI_REQ_SIZE + DLPI_PHYSADDR_MAX },
+{ DL_DISABMULTI_REQ, DL_DISABMULTI_REQ_SIZE + DLPI_PHYSADDR_MAX },
+{ DL_PROMISCON_REQ, DL_PROMISCON_REQ_SIZE },
+{ DL_PROMISCOFF_REQ, DL_PROMISCOFF_REQ_SIZE },
+{ DL_PASSIVE_REQ, DL_PASSIVE_REQ_SIZE },
+{ DL_UNITDATA_REQ, DL_UNITDATA_REQ_SIZE + DLPI_PHYSADDR_MAX +
+ DLPI_SAPLEN_MAX },
+{ DL_UNITDATA_IND, DL_UNITDATA_IND_SIZE + (2 * (DLPI_PHYSADDR_MAX +
+ DLPI_SAPLEN_MAX)) },
+{ DL_PHYS_ADDR_REQ, DL_PHYS_ADDR_REQ_SIZE },
+{ DL_PHYS_ADDR_ACK, DL_PHYS_ADDR_ACK_SIZE + DLPI_PHYSADDR_MAX },
+{ DL_SET_PHYS_ADDR_REQ, DL_SET_PHYS_ADDR_REQ_SIZE + DLPI_PHYSADDR_MAX },
+{ DL_OK_ACK, MAX(DL_ERROR_ACK_SIZE, DL_OK_ACK_SIZE) }
+};
- diap->style1_failed = B_TRUE;
+/*
+ * Refers to the dlpi_primsizes[] table to return corresponding maximum
+ * buffer size.
+ */
+static size_t
+i_dlpi_getprimsize(t_uscalar_t prim)
+{
+ int i;
- if (!force_style2) {
- if ((fd = i_dlpi_style1_open(diap)) != -1)
- return (fd);
+ for (i = 0; i < NELEMS(dlpi_primsizes); i++) {
+ if (dlpi_primsizes[i].dp_prim == prim)
+ return (dlpi_primsizes[i].dp_primsz);
}
- if ((fd = i_dlpi_style2_open(diap)) == -1)
- return (-1);
-
- return (fd);
+ return (sizeof (t_uscalar_t));
}
-int
-dlpi_if_parse(const char *ifname, char *provider, int *ppap)
+/*
+ * sap values vary in length and are in host byte order, build sap value
+ * by writing saplen bytes, so that the sap value is left aligned.
+ */
+static uint_t
+i_dlpi_buildsap(uint8_t *sapp, uint_t saplen)
{
- dlpi_if_attr_t diap;
-
- if (i_dlpi_ifname_parse(ifname, &diap) == -1) {
- errno = EINVAL;
- return (-1);
+ int i;
+ uint_t sap = 0;
+
+#ifdef _LITTLE_ENDIAN
+ for (i = saplen - 1; i >= 0; i--) {
+#else
+ for (i = 0; i < saplen; i++) {
+#endif
+ sap <<= 8;
+ sap |= sapp[i];
}
- if (strlcpy(provider, diap.provider, LIFNAMSIZ) > LIFNAMSIZ)
- return (-1);
-
- if (ppap != NULL)
- *ppap = diap.ppa;
-
- return (0);
+ return (sap);
}
/*
- * 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
+ * Copy sap value to a buffer in host byte order. saplen is the number of
+ * bytes to copy.
*/
-static int
-i_dlpi_ifrm_num(char *fname, unsigned int *ppa)
+static void
+i_dlpi_writesap(void *dstbuf, uint_t sap, uint_t saplen)
{
- int i;
- uint_t p = 0;
- unsigned int m = 1;
+ uint8_t *sapp;
- i = strlen(fname) - 1;
-
- while (i >= 0 && isdigit(fname[i])) {
- p += (fname[i] - '0')*m;
- m *= 10;
- i--;
- }
-
- if (m == 1) {
- return (-1);
- }
+#ifdef _LITTLE_ENDIAN
+ sapp = (uint8_t *)&sap;
+#else
+ sapp = (uint8_t *)&sap + (sizeof (sap) - saplen);
+#endif
- fname[i + 1] = '\0';
- *ppa = p;
- return (0);
+ (void) memcpy(dstbuf, sapp, saplen);
}
diff --git a/usr/src/lib/libdlpi/common/libdlpi.h b/usr/src/lib/libdlpi/common/libdlpi.h
index e8c6f80207..0099727cc5 100644
--- a/usr/src/lib/libdlpi/common/libdlpi.h
+++ b/usr/src/lib/libdlpi/common/libdlpi.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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,56 +30,143 @@
#include <sys/types.h>
#include <sys/dlpi.h>
-#include <net/if.h>
#ifdef __cplusplus
extern "C" {
#endif
-#define MAXADDRLEN 64
-#define MAXSAPLEN 64
-#define MAX_MODS 9
-
-typedef struct dlpi_if_attr {
- char ifname[LIFNAMSIZ];
- int style;
- int ppa;
- int mod_cnt;
- int mod_pushed;
- boolean_t style1_failed;
- int style1_fd;
- char devname[LIFNAMSIZ + 32]; /* added space for /dev path */
- char modlist[MAX_MODS][LIFNAMSIZ];
- char provider[LIFNAMSIZ];
-} dlpi_if_attr_t;
-
-extern const char *dlpi_mac_type(uint_t);
-
-extern int dlpi_open(const char *);
-extern int dlpi_close(int);
-extern int dlpi_info(int, int, dl_info_ack_t *, union DL_qos_types *,
- union DL_qos_types *, uint8_t *, size_t *, uint8_t *, size_t *);
-extern int dlpi_attach(int, int, uint_t);
-extern int dlpi_detach(int, int);
-extern int dlpi_bind(int, int, uint_t, uint16_t, boolean_t, uint32_t *,
- uint32_t *, uint8_t *, size_t *);
-extern int dlpi_unbind(int, int);
-extern int dlpi_enabmulti(int, int, uint8_t *, size_t);
-extern int dlpi_disabmulti(int, int, uint8_t *, size_t);
-extern int dlpi_promiscon(int, int, uint_t);
-extern int dlpi_promiscoff(int, int, uint_t);
-extern int dlpi_phys_addr(int, int, uint_t, uint8_t *, size_t *);
-extern int dlpi_set_phys_addr(int, int, uint8_t *, size_t);
-extern void dlpi_passive(int, int);
+/*
+ * Maximum Physical (hardware) address length, in bytes.
+ * Must be as large as MAXMACADDRLEN (see <sys/mac.h>).
+ */
+#define DLPI_PHYSADDR_MAX 64
+
+/*
+ * Maximum link name length, including terminating NUL, in bytes.
+ */
+#define DLPI_LINKNAME_MAX 32
+
+/*
+ * Constant used to indicate bind to any SAP value
+ */
+#define DLPI_ANY_SAP (uint_t)-1
+
+/*
+ * Flag values for dlpi_open(); those not documented in dlpi_open(3DLPI)
+ * are Consolidation Private and subject to change or removal.
+ */
+#define DLPI_EXCL 0x0001 /* Exclusive open */
+#define DLPI_PASSIVE 0x0002 /* Open DLPI link in passive mode */
+#define DLPI_RAW 0x0004 /* Open DLPI link in raw mode */
+#define DLPI_SERIAL 0x0008 /* Synchronous serial line interface */
+#define DLPI_NOATTACH 0x0010 /* Do not attach PPA */
+#define DLPI_NATIVE 0x0020 /* Open DLPI link in Native mode */
+
+/*
+ * Timeout to be used in DLPI-related operations, in seconds.
+ */
+#define DLPI_DEF_TIMEOUT 5
+
+/*
+ * Since this library returns error codes defined in either <sys/dlpi.h> or
+ * <libdlpi.h>, libdlpi specific error codes will start at value 10000 to
+ * avoid overlap. DLPI_SUCCESS cannot be 0 because 0 is already DL_BADSAP in
+ * <sys/dlpi.h>.
+ */
+enum {
+ DLPI_SUCCESS = 10000, /* DLPI operation succeeded */
+ DLPI_EINVAL, /* invalid argument */
+ DLPI_ELINKNAMEINVAL, /* invalid DLPI linkname */
+ DLPI_ENOLINK, /* DLPI link does not exist */
+ DLPI_EBADLINK, /* bad DLPI link */
+ DLPI_EINHANDLE, /* invalid DLPI handle */
+ DLPI_ETIMEDOUT, /* DLPI operation timed out */
+ DLPI_EVERNOTSUP, /* unsupported DLPI Version */
+ DLPI_EMODENOTSUP, /* unsupported DLPI connection mode */
+ DLPI_EUNAVAILSAP, /* unavailable DLPI SAP */
+ DLPI_FAILURE, /* DLPI operation failed */
+ DLPI_ENOTSTYLE2, /* DLPI style-2 node reports style-1 */
+ DLPI_EBADMSG, /* bad DLPI message */
+ DLPI_ERAWNOTSUP, /* DLPI raw mode not supported */
+ DLPI_ERRMAX /* Highest + 1 libdlpi error code */
+};
+
+/*
+ * DLPI information; see dlpi_info(3DLPI).
+ */
+typedef struct {
+ uint_t di_opts;
+ uint_t di_max_sdu;
+ uint_t di_min_sdu;
+ uint_t di_state;
+ uint_t di_mactype;
+ char di_linkname[DLPI_LINKNAME_MAX];
+ uchar_t di_physaddr[DLPI_PHYSADDR_MAX];
+ uchar_t di_physaddrlen;
+ uchar_t di_bcastaddr[DLPI_PHYSADDR_MAX];
+ uchar_t di_bcastaddrlen;
+ uint_t di_sap;
+ int di_timeout;
+ dl_qos_cl_sel1_t di_qos_sel;
+ dl_qos_cl_range1_t di_qos_range;
+} dlpi_info_t;
+
+/*
+ * DLPI send information; see dlpi_send(3DLPI).
+ */
+typedef struct {
+ uint_t dsi_sap;
+ dl_priority_t dsi_prio;
+} dlpi_sendinfo_t;
+
+/*
+ * Destination DLPI address type; see dlpi_recv(3DLPI).
+ */
+typedef enum {
+ DLPI_ADDRTYPE_UNICAST,
+ DLPI_ADDRTYPE_GROUP
+} dlpi_addrtype_t;
+
+/*
+ * DLPI receive information; see dlpi_recv(3DLPI).
+ */
+typedef struct {
+ uchar_t dri_destaddr[DLPI_PHYSADDR_MAX];
+ uchar_t dri_destaddrlen;
+ dlpi_addrtype_t dri_dstaddrtype;
+ size_t dri_totmsglen;
+} dlpi_recvinfo_t;
+
+typedef struct __dlpi_handle *dlpi_handle_t;
+
+extern const char *dlpi_mactype(uint_t);
+extern const char *dlpi_strerror(int);
+extern const char *dlpi_linkname(dlpi_handle_t);
+
+extern int dlpi_open(const char *, dlpi_handle_t *, uint_t);
+extern void dlpi_close(dlpi_handle_t);
+extern int dlpi_info(dlpi_handle_t, dlpi_info_t *, uint_t);
+extern int dlpi_bind(dlpi_handle_t, uint_t, uint_t *);
+extern int dlpi_unbind(dlpi_handle_t);
+extern int dlpi_enabmulti(dlpi_handle_t, const void *, size_t);
+extern int dlpi_disabmulti(dlpi_handle_t, const void *, size_t);
+extern int dlpi_promiscon(dlpi_handle_t, uint_t);
+extern int dlpi_promiscoff(dlpi_handle_t, uint_t);
+extern int dlpi_get_physaddr(dlpi_handle_t, uint_t, void *, size_t *);
+extern int dlpi_set_physaddr(dlpi_handle_t, uint_t, const void *, size_t);
+extern int dlpi_recv(dlpi_handle_t, void *, size_t *, void *, size_t *,
+ int, dlpi_recvinfo_t *);
+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);
/*
- * dlpi_if_open()
- * Takes interface name in the following formats
- * o Specific physical unit (ex. "bge0" or "ce0")
- * o Tunnels (ex. "ip.tun0" or "ip6.tun0")
+ * These are Consolidation Private interfaces and are subject to change.
*/
-extern int dlpi_if_open(const char *, dlpi_if_attr_t *, boolean_t);
-extern int dlpi_if_parse(const char *, char *, int *);
+extern int dlpi_parselink(const char *, char *, uint_t *);
+extern int dlpi_makelink(char *, const char *, uint_t);
+extern uint_t dlpi_style(dlpi_handle_t);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libdlpi/common/libdlpi_impl.h b/usr/src/lib/libdlpi/common/libdlpi_impl.h
new file mode 100644
index 0000000000..313a37127c
--- /dev/null
+++ b/usr/src/lib/libdlpi/common/libdlpi_impl.h
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+#ifndef _LIBDLPI_IMPL_H
+#define _LIBDLPI_IMPL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libdlpi.h>
+#include <sys/sysmacros.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Maximum DLPI response size, in bytes.
+ */
+#define DLPI_CHUNKSIZE 8192
+
+/*
+ * Maximum SAP length, in bytes.
+ */
+#define DLPI_SAPLEN_MAX 4
+
+/*
+ * Maximum number of modules that can be pushed onto a device stream.
+ */
+#define DLPI_MODS_MAX 9
+
+/*
+ * Number of elements in 'arr'.
+ */
+#define NELEMS(arr) (sizeof (arr) / sizeof ((arr)[0]))
+
+/*
+ * Allocate buffer size for DLPI message, in bytes and set DLPI primitive.
+ */
+#define DLPI_MSG_CREATE(dlmsg, dlprimitive) \
+ (dlmsg).dlm_msgsz = i_dlpi_getprimsize((dlprimitive)); \
+ (dlmsg).dlm_msg = alloca((dlmsg).dlm_msgsz); \
+ (dlmsg).dlm_msg->dl_primitive = (dlprimitive);
+
+/*
+ * Used in a mactype lookup table.
+ */
+typedef struct dlpi_mactype_s {
+ uint_t dm_mactype; /* DLPI/Private mactype */
+ char *dm_desc; /* Description of mactype */
+} dlpi_mactype_t;
+
+/*
+ * Used to get the maximum DLPI message buffer size, in bytes.
+ */
+typedef struct dlpi_primsz {
+ t_uscalar_t dp_prim; /* store DLPI primitive */
+ size_t dp_primsz;
+ /* max. message size, in bytes, for dp_prim */
+} dlpi_primsz_t;
+
+/*
+ * Used to create DLPI message.
+ */
+typedef struct dlpi_msg {
+ union DL_primitives *dlm_msg;
+ /* store DLPI primitive message */
+ size_t dlm_msgsz;
+ /* provide buffer size for dlm_msg */
+} dlpi_msg_t;
+
+/*
+ * Private libdlpi structure associated with each DLPI handle.
+ */
+typedef struct dlpi_impl_s {
+ int dli_fd; /* fd attached to stream */
+ int dli_timeout; /* timeout for operations, in sec */
+ char dli_linkname[DLPI_LINKNAME_MAX];
+ /* full linkname including PPA */
+ char dli_provider[DLPI_LINKNAME_MAX];
+ /* only provider name */
+ t_uscalar_t dli_style; /* style 1 or 2 */
+ uint_t dli_saplen; /* bound SAP length */
+ uint_t dli_sap; /* bound SAP value */
+ boolean_t dli_sapbefore; /* true if SAP precedes address */
+ uint_t dli_ppa; /* physical point of attachment */
+ uint_t dli_mod_cnt; /* number of modules to be pushed */
+ uint_t dli_mod_pushed; /* number of modules pushed */
+ char dli_modlist[DLPI_MODS_MAX][DLPI_LINKNAME_MAX];
+ /* array of mods */
+ uint_t dli_mactype; /* mac type */
+ uint_t dli_oflags; /* flags set at open */
+} dlpi_impl_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBDLPI_IMPL_H */
diff --git a/usr/src/lib/libdlpi/common/mapfile-vers b/usr/src/lib/libdlpi/common/mapfile-vers
index 8a263e2d5c..31ae2a5aa1 100644
--- a/usr/src/lib/libdlpi/common/mapfile-vers
+++ b/usr/src/lib/libdlpi/common/mapfile-vers
@@ -19,31 +19,38 @@
# 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"
#
-SUNWprivate_1.1 {
+SUNW_1.1 { # first release of libdlpi, Solaris 11
global:
- dlpi_attach;
- dlpi_bind;
- dlpi_close;
- dlpi_detach;
- dlpi_disabmulti;
- dlpi_enabmulti;
- dlpi_if_open;
- dlpi_if_parse;
- dlpi_info;
- dlpi_mac_type;
- dlpi_open;
- dlpi_passive;
- dlpi_phys_addr;
- dlpi_promiscoff;
- dlpi_promiscon;
- dlpi_set_phys_addr;
- dlpi_unbind;
+ dlpi_bind;
+ dlpi_close;
+ dlpi_disabmulti;
+ dlpi_enabmulti;
+ dlpi_fd;
+ dlpi_get_physaddr;
+ dlpi_info;
+ dlpi_linkname;
+ dlpi_mactype;
+ dlpi_open;
+ dlpi_promiscoff;
+ dlpi_promiscon;
+ dlpi_recv;
+ dlpi_send;
+ dlpi_set_physaddr;
+ dlpi_set_timeout;
+ dlpi_strerror;
+ dlpi_unbind;
+};
+SUNWprivate {
+ global:
+ dlpi_parselink;
+ dlpi_makelink;
+ dlpi_style;
local:
*;
};
diff --git a/usr/src/lib/libdlpi/sparcv9/Makefile b/usr/src/lib/libdlpi/sparcv9/Makefile
new file mode 100644
index 0000000000..600ff73f12
--- /dev/null
+++ b/usr/src/lib/libdlpi/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/libinetutil/common/ifspec.c b/usr/src/lib/libinetutil/common/ifspec.c
index 58f7c5ae71..157b497efd 100644
--- a/usr/src/lib/libinetutil/common/ifspec.c
+++ b/usr/src/lib/libinetutil/common/ifspec.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,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 2001 by 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"
@@ -85,7 +84,7 @@ getppa(const char *bp, int bpsize, uint_t *ppa)
char *ep = (char *)&bp[bpsize - 1];
char *tp;
- if (isdigit(*bp) || !isdigit(*ep)) {
+ if (!isdigit(*ep)) {
errno = EINVAL;
return (-1);
}
@@ -104,8 +103,8 @@ getppa(const char *bp, int bpsize, uint_t *ppa)
/*
* Given an ifconfig-style inet relative-path interface specification
- * (e.g: hme0.foo.ip.udp:2), validate its form and decompose the contents
- * into a dynamically allocated ifspec_t.
+ * (e.g: hme.[module].[module][PPA]:2), validate its form and decompose the
+ * contents into a dynamically allocated ifspec_t.
*
* Returns ifspec_t for success, NULL pointer if spec is malformed.
*/
@@ -131,9 +130,10 @@ ifparse_ifspec(const char *ifname, ifspec_t *ifsp)
/*
* An interface name must have the format of:
- * dev[ppa][.module[.module...][ppa]][:lun]
+ * dev[.module[.module...]][ppa][:lun]
*
- * where only one ppa may be specified e.g. ip0.foo.tun or ip.foo.tun0
+ * where the ppa must be specified at the end of the interface name.
+ * e.g. ip.foo.tun0
*
* lun - logical unit number.
*
@@ -180,27 +180,25 @@ ifparse_ifspec(const char *ifname, ifspec_t *ifsp)
(void) strlcpy(ifsp->ifsp_devnm, ifnamecp, LIFNAMSIZ);
- /* Find ppa - has to be part of devname or part of last module name */
- /* This should be changed to require the latter of the two */
- if (getppa(ifsp->ifsp_devnm, strlen(ifsp->ifsp_devnm),
- &ifsp->ifsp_ppa) == 0)
- have_ppa = B_TRUE;
+ /*
+ * Find ppa - has to be part of devname or if modules exist part of
+ * last module name.
+ */
if (ifsp->ifsp_modcnt != 0 &&
getppa(ifsp->ifsp_mods[ifsp->ifsp_modcnt - 1],
strlen(ifsp->ifsp_mods[ifsp->ifsp_modcnt - 1]),
&ifsp->ifsp_ppa) == 0) {
- if (!have_ppa)
- have_ppa = B_TRUE;
- else
- return (B_FALSE); /* only one please */
- }
- if (!have_ppa)
- return (B_FALSE);
+ have_ppa = B_TRUE;
+ } else if (ifsp->ifsp_modcnt == 0 &&
+ getppa(ifsp->ifsp_devnm, strlen(ifsp->ifsp_devnm),
+ &ifsp->ifsp_ppa) == 0) {
+ have_ppa = B_TRUE;
- /* strip the ppa off of the device name if present */
- for (tp = &ifsp->ifsp_devnm[strlen(ifsp->ifsp_devnm) - 1];
- tp >= ifsp->ifsp_devnm && isdigit(*tp); tp--)
- *tp = '\0';
+ /* strip the ppa off of the device name if present */
+ for (tp = &ifsp->ifsp_devnm[strlen(ifsp->ifsp_devnm) - 1];
+ tp >= ifsp->ifsp_devnm && isdigit(*tp); tp--)
+ *tp = '\0';
+ }
- return (B_TRUE);
+ return (have_ppa);
}
diff --git a/usr/src/pkgdefs/SUNWarcr/prototype_i386 b/usr/src/pkgdefs/SUNWarcr/prototype_i386
index f02fab5d83..c05a6a50fd 100644
--- a/usr/src/pkgdefs/SUNWarcr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWarcr/prototype_i386
@@ -21,7 +21,7 @@
#
#
-# 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"
@@ -64,6 +64,7 @@ f none lib/amd64/llib-ldevice.ln 644 root bin
f none lib/amd64/llib-ldevid.ln 644 root bin
f none lib/amd64/llib-ldevinfo.ln 644 root bin
f none lib/amd64/llib-ldl.ln 644 root bin
+f none lib/amd64/llib-ldlpi.ln 644 root bin
f none lib/amd64/llib-ldoor.ln 644 root bin
f none lib/amd64/llib-lefi.ln 644 root bin
f none lib/amd64/llib-lelf.ln 644 root bin
diff --git a/usr/src/pkgdefs/SUNWarcr/prototype_sparc b/usr/src/pkgdefs/SUNWarcr/prototype_sparc
index 9cee1f2ca2..e0635d7204 100644
--- a/usr/src/pkgdefs/SUNWarcr/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWarcr/prototype_sparc
@@ -21,7 +21,7 @@
#
#
-# 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"
@@ -64,6 +64,7 @@ f none lib/sparcv9/llib-ldevice.ln 644 root bin
f none lib/sparcv9/llib-ldevid.ln 644 root bin
f none lib/sparcv9/llib-ldevinfo.ln 644 root bin
f none lib/sparcv9/llib-ldl.ln 644 root bin
+f none lib/sparcv9/llib-ldlpi.ln 644 root bin
f none lib/sparcv9/llib-ldoor.ln 644 root bin
f none lib/sparcv9/llib-lefi.ln 644 root bin
f none lib/sparcv9/llib-lelf.ln 644 root bin
diff --git a/usr/src/pkgdefs/SUNWcslr/prototype_i386 b/usr/src/pkgdefs/SUNWcslr/prototype_i386
index d7ab2182f3..94057d2a78 100644
--- a/usr/src/pkgdefs/SUNWcslr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWcslr/prototype_i386
@@ -21,7 +21,7 @@
#
#
-# 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"
@@ -78,6 +78,8 @@ s none lib/amd64/libdevinfo.so=libdevinfo.so.1
f none lib/amd64/libdevinfo.so.1 755 root bin
s none lib/amd64/libdl.so=libdl.so.1
f none lib/amd64/libdl.so.1 755 root bin
+s none lib/amd64/libdlpi.so=libdlpi.so.1
+f none lib/amd64/libdlpi.so.1 755 root bin
s none lib/amd64/libdoor.so=libdoor.so.1
f none lib/amd64/libdoor.so.1 755 root bin
s none lib/amd64/libefi.so=libefi.so.1
diff --git a/usr/src/pkgdefs/SUNWcslr/prototype_sparc b/usr/src/pkgdefs/SUNWcslr/prototype_sparc
index be4f18ddb5..c902bf36f4 100644
--- a/usr/src/pkgdefs/SUNWcslr/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWcslr/prototype_sparc
@@ -79,6 +79,8 @@ s none lib/sparcv9/libdevinfo.so=libdevinfo.so.1
f none lib/sparcv9/libdevinfo.so.1 755 root bin
s none lib/sparcv9/libdl.so=libdl.so.1
f none lib/sparcv9/libdl.so.1 755 root bin
+s none lib/sparcv9/libdlpi.so=libdlpi.so.1
+f none lib/sparcv9/libdlpi.so.1 755 root bin
s none lib/sparcv9/libdoor.so=libdoor.so.1
f none lib/sparcv9/libdoor.so.1 755 root bin
s none lib/sparcv9/libefi.so=libefi.so.1
diff --git a/usr/src/tools/abi/etc/exceptions b/usr/src/tools/abi/etc/exceptions
index edf114334a..8f97028267 100644
--- a/usr/src/tools/abi/etc/exceptions
+++ b/usr/src/tools/abi/etc/exceptions
@@ -409,7 +409,6 @@ PSARC 2002/762: RULE W3: usr/lib/amd64/libtsol.so.2
PSARC 2002/762: RULE W3: lib/libtsol.so.2
PSARC 2002/762: RULE W3: lib/sparcv9/libtsol.so.2
PSARC 2002/762: RULE W3: lib/amd64/libtsol.so.2
-6289029: RULE W3: lib/libdlpi.so.1
PSARC 2005/204: RULE W3: usr/lib/libraidcfg.so.1
PSARC 2005/204: RULE W3: usr/lib/amd64/libraidcfg.so.1
PSARC 2005/204: RULE W3: usr/lib/sparcv9/libraidcfg.so.1