xref: /titanic_41/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/revarp.c (revision 0689f76c08c5e553ff25ac43a852b56c430bb61e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5c7e4935fSss150715  * Common Development and Distribution License (the "License").
6c7e4935fSss150715  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*e11c3f44Smeem  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
267c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include "defs.h"
297c478bd9Sstevel@tonic-gate #include "ifconfig.h"
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <libdlpi.h>
327c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
33c7e4935fSss150715 #include <sys/time.h>
347c478bd9Sstevel@tonic-gate #include <deflt.h>
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #define	IPADDRL		sizeof (struct in_addr)
377c478bd9Sstevel@tonic-gate #define	RARPRETRIES	5
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate /*
407c478bd9Sstevel@tonic-gate  * The following value (8) is determined to work reliably in switched 10/100MB
417c478bd9Sstevel@tonic-gate  * ethernet environments. Use caution if you plan on decreasing it.
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate #define	RARPTIMEOUT	8
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate static char	defaultfile[] = "/etc/inet/rarp";
467c478bd9Sstevel@tonic-gate static char	retries_var[] = "RARP_RETRIES=";
477c478bd9Sstevel@tonic-gate static int rarp_timeout = RARPTIMEOUT;
487c478bd9Sstevel@tonic-gate static int rarp_retries = RARPRETRIES;
497c478bd9Sstevel@tonic-gate 
50c7e4935fSss150715 static dlpi_handle_t rarp_open(const char *, size_t *, uchar_t *, uchar_t *);
51c7e4935fSss150715 static int rarp_recv(dlpi_handle_t, struct arphdr *, size_t, size_t, int64_t);
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate int
doifrevarp(const char * linkname,struct sockaddr_in * laddr)54c7e4935fSss150715 doifrevarp(const char *linkname, struct sockaddr_in *laddr)
557c478bd9Sstevel@tonic-gate {
56c7e4935fSss150715 	int			s, retval;
577c478bd9Sstevel@tonic-gate 	struct arphdr		*req, *ans;
587c478bd9Sstevel@tonic-gate 	struct in_addr		from;
597c478bd9Sstevel@tonic-gate 	struct in_addr		answer;
607c478bd9Sstevel@tonic-gate 	struct lifreq		lifr;
617c478bd9Sstevel@tonic-gate 	int			tries_left;
62c7e4935fSss150715 	size_t			physaddrlen, ifrarplen;
63c7e4935fSss150715 	uchar_t			my_macaddr[DLPI_PHYSADDR_MAX];
64c7e4935fSss150715 	uchar_t 		my_broadcast[DLPI_PHYSADDR_MAX];
65c7e4935fSss150715 	dlpi_handle_t		dh;
667c478bd9Sstevel@tonic-gate 
67c7e4935fSss150715 	if (linkname[0] == '\0') {
687c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "ifconfig: doifrevarp: name not set\n");
697c478bd9Sstevel@tonic-gate 		exit(1);
707c478bd9Sstevel@tonic-gate 	}
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	if (debug)
73c7e4935fSss150715 		(void) printf("doifrevarp interface %s\n", linkname);
747c478bd9Sstevel@tonic-gate 
75c7e4935fSss150715 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
767c478bd9Sstevel@tonic-gate 		Perror0_exit("socket");
77c7e4935fSss150715 
78c7e4935fSss150715 	(void) strlcpy(lifr.lifr_name, linkname, sizeof (lifr.lifr_name));
79c7e4935fSss150715 	if (ioctl(s, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
80c7e4935fSss150715 		(void) close(s);
817c478bd9Sstevel@tonic-gate 		Perror0_exit("SIOCGLIFFLAGS");
82c7e4935fSss150715 	}
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	/* don't try to revarp if we know it won't work */
857c478bd9Sstevel@tonic-gate 	if ((lifr.lifr_flags & IFF_LOOPBACK) ||
867c478bd9Sstevel@tonic-gate 	    (lifr.lifr_flags & IFF_NOARP) ||
87*e11c3f44Smeem 	    (lifr.lifr_flags & IFF_IPMP) ||
88c7e4935fSss150715 	    (lifr.lifr_flags & IFF_POINTOPOINT)) {
89c7e4935fSss150715 		(void) close(s);
907c478bd9Sstevel@tonic-gate 		return (0);
91c7e4935fSss150715 	}
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	/* open rarp interface */
94c7e4935fSss150715 	dh = rarp_open(linkname, &physaddrlen, my_macaddr, my_broadcast);
95c7e4935fSss150715 	if (dh == NULL) {
96c7e4935fSss150715 		(void) close(s);
977c478bd9Sstevel@tonic-gate 		return (0);
98c7e4935fSss150715 	}
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	/*
1017c478bd9Sstevel@tonic-gate 	 * RARP looks at /etc/ethers and NIS, which only works
1027c478bd9Sstevel@tonic-gate 	 * with 6 byte addresses currently.
1037c478bd9Sstevel@tonic-gate 	 */
104c7e4935fSss150715 	if (physaddrlen != ETHERADDRL) {
105c7e4935fSss150715 		dlpi_close(dh);
106c7e4935fSss150715 		(void) close(s);
1077c478bd9Sstevel@tonic-gate 		return (0);
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 
110c7e4935fSss150715 	ifrarplen = sizeof (struct arphdr) + (2 * IPADDRL) + (2 * physaddrlen);
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	/* look for adjustments to rarp_retries in the RARP defaults file */
1137c478bd9Sstevel@tonic-gate 	if (defopen(defaultfile) == 0) {
1147c478bd9Sstevel@tonic-gate 		char	*cp;
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 		if (cp = defread(retries_var)) {
1177c478bd9Sstevel@tonic-gate 			int	ntries;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 			ntries = atoi(cp);
1207c478bd9Sstevel@tonic-gate 			if (ntries > 0)
1217c478bd9Sstevel@tonic-gate 				rarp_retries = ntries;
1227c478bd9Sstevel@tonic-gate 		}
1237c478bd9Sstevel@tonic-gate 		(void) defopen(NULL);	/* close default file */
1247c478bd9Sstevel@tonic-gate 	}
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	/* allocate request and response buffers */
127c7e4935fSss150715 	if (((req = malloc(ifrarplen)) == NULL) ||
128c7e4935fSss150715 	    ((ans = malloc(ifrarplen)) == NULL)) {
129c7e4935fSss150715 		dlpi_close(dh);
130c7e4935fSss150715 		(void) close(s);
1317c478bd9Sstevel@tonic-gate 		free(req);
1327c478bd9Sstevel@tonic-gate 		return (0);
1337c478bd9Sstevel@tonic-gate 	}
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	/* create rarp request */
1367c478bd9Sstevel@tonic-gate 	(void) memset(req, 0, ifrarplen);
1377c478bd9Sstevel@tonic-gate 	req->ar_hrd = htons(ARPHRD_ETHER);
1387c478bd9Sstevel@tonic-gate 	req->ar_pro = htons(ETHERTYPE_IP);
139c7e4935fSss150715 	req->ar_hln = physaddrlen;
1407c478bd9Sstevel@tonic-gate 	req->ar_pln = IPADDRL;
1417c478bd9Sstevel@tonic-gate 	req->ar_op = htons(REVARP_REQUEST);
1427c478bd9Sstevel@tonic-gate 
143c7e4935fSss150715 	(void) memcpy(&req[1], my_macaddr, physaddrlen);
1447c478bd9Sstevel@tonic-gate 	(void) memcpy((uchar_t *)req + sizeof (struct arphdr) + IPADDRL +
145c7e4935fSss150715 	    physaddrlen, my_macaddr, physaddrlen);
1467c478bd9Sstevel@tonic-gate 
147c7e4935fSss150715 	for (tries_left = rarp_retries; tries_left > 0; --tries_left) {
1487c478bd9Sstevel@tonic-gate 		/* send the request */
149c7e4935fSss150715 		retval = dlpi_send(dh, my_broadcast, physaddrlen, req,
150c7e4935fSss150715 		    ifrarplen, NULL);
151c7e4935fSss150715 		if (retval != DLPI_SUCCESS) {
152c7e4935fSss150715 			Perrdlpi("doifrevarp: cannot send rarp request",
153c7e4935fSss150715 			    linkname, retval);
154c7e4935fSss150715 			break;
155c7e4935fSss150715 		}
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 		if (debug)
1587c478bd9Sstevel@tonic-gate 			(void) printf("rarp sent\n");
1597c478bd9Sstevel@tonic-gate 
160c7e4935fSss150715 		retval = rarp_recv(dh, ans, ifrarplen, physaddrlen,
161c7e4935fSss150715 		    rarp_timeout * MILLISEC);
1627c478bd9Sstevel@tonic-gate 
163c7e4935fSss150715 		if (retval != DLPI_ETIMEDOUT)
164c7e4935fSss150715 			break;
165c7e4935fSss150715 
166c7e4935fSss150715 		if (debug)
167c7e4935fSss150715 			(void) printf("rarp retry\n");
1687c478bd9Sstevel@tonic-gate 	}
169c7e4935fSss150715 
170c7e4935fSss150715 	if (retval == DLPI_SUCCESS) {
171c7e4935fSss150715 		(void) memcpy(&answer, (uchar_t *)ans +
172c7e4935fSss150715 		    sizeof (struct arphdr) + (2 * physaddrlen) + IPADDRL,
173c7e4935fSss150715 		    sizeof (answer));
174c7e4935fSss150715 		(void) memcpy(&from, (uchar_t *)ans + physaddrlen +
175c7e4935fSss150715 		    sizeof (struct arphdr), sizeof (from));
176c7e4935fSss150715 
177c7e4935fSss150715 		if (debug) {
178c7e4935fSss150715 			(void) printf("answer: %s", inet_ntoa(answer));
179c7e4935fSss150715 			(void) printf(" [from %s]\n", inet_ntoa(from));
1807c478bd9Sstevel@tonic-gate 		}
181c7e4935fSss150715 		laddr->sin_addr = answer;
182c7e4935fSss150715 	} else if (debug) {
183c7e4935fSss150715 		Perrdlpi("doifrevarp: could not receive rarp reply",
184c7e4935fSss150715 		    linkname, retval);
185c7e4935fSss150715 	}
186c7e4935fSss150715 
187c7e4935fSss150715 	dlpi_close(dh);
188c7e4935fSss150715 	(void) close(s);
189c7e4935fSss150715 	free(req);
190c7e4935fSss150715 	free(ans);
191c7e4935fSss150715 	return (retval == DLPI_SUCCESS);
192c7e4935fSss150715 }
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate /*
195c7e4935fSss150715  * Open the datalink provider device and bind to the REVARP type.
196c7e4935fSss150715  * Return the resulting DLPI handle.
1977c478bd9Sstevel@tonic-gate  */
198c7e4935fSss150715 static	dlpi_handle_t
rarp_open(const char * linkname,size_t * alen,uchar_t * myaddr,uchar_t * mybaddr)199c7e4935fSss150715 rarp_open(const char *linkname, size_t *alen, uchar_t *myaddr, uchar_t *mybaddr)
200c7e4935fSss150715 {
201c7e4935fSss150715 	int		retval;
202c7e4935fSss150715 	char		*physaddr, *bcastaddr;
203c7e4935fSss150715 	dlpi_info_t	dlinfo;
204c7e4935fSss150715 	dlpi_handle_t	dh;
2057c478bd9Sstevel@tonic-gate 
206c7e4935fSss150715 	if (debug)
207c7e4935fSss150715 		(void) printf("rarp_open %s\n", linkname);
2087c478bd9Sstevel@tonic-gate 
209c7e4935fSss150715 	if ((retval = dlpi_open(linkname, &dh, 0)) != DLPI_SUCCESS) {
210c7e4935fSss150715 		Perrdlpi("rarp_open: dlpi_open failed", linkname, retval);
211c7e4935fSss150715 		return (NULL);
2127c478bd9Sstevel@tonic-gate 	}
2137c478bd9Sstevel@tonic-gate 
214c7e4935fSss150715 	if ((retval = dlpi_bind(dh, ETHERTYPE_REVARP, NULL)) != DLPI_SUCCESS) {
215c7e4935fSss150715 		Perrdlpi("rarp_open: dlpi_bind failed", linkname, retval);
216c7e4935fSss150715 		goto failed;
2177c478bd9Sstevel@tonic-gate 	}
2187c478bd9Sstevel@tonic-gate 
219c7e4935fSss150715 	if ((retval = dlpi_info(dh, &dlinfo, 0)) != DLPI_SUCCESS) {
220c7e4935fSss150715 		Perrdlpi("rarp_open: dlpi_info failed", linkname, retval);
221c7e4935fSss150715 		goto failed;
2227c478bd9Sstevel@tonic-gate 	}
2237c478bd9Sstevel@tonic-gate 
224c7e4935fSss150715 	if (dlinfo.di_bcastaddrlen == 0) {
225c7e4935fSss150715 		(void) fprintf(stderr, "ifconfig: rarp_open: %s broadcast "
226c7e4935fSss150715 		    "not supported\n", linkname);
227c7e4935fSss150715 		goto failed;
228c7e4935fSss150715 	}
229c7e4935fSss150715 
230c7e4935fSss150715 	/* we assume the following are equal and fill in 'alen' */
231c7e4935fSss150715 	assert(dlinfo.di_bcastaddrlen == dlinfo.di_physaddrlen);
232c7e4935fSss150715 
233c7e4935fSss150715 	(void) memcpy(mybaddr, dlinfo.di_bcastaddr, dlinfo.di_bcastaddrlen);
234c7e4935fSss150715 
235c7e4935fSss150715 	*alen = dlinfo.di_physaddrlen;
236c7e4935fSss150715 
237c7e4935fSss150715 	(void) memcpy(myaddr, dlinfo.di_physaddr, dlinfo.di_physaddrlen);
238c7e4935fSss150715 
2397c478bd9Sstevel@tonic-gate 	if (debug) {
240c7e4935fSss150715 		bcastaddr = _link_ntoa(mybaddr, NULL, dlinfo.di_bcastaddrlen,
241c7e4935fSss150715 		    IFT_OTHER);
242c7e4935fSss150715 
243c7e4935fSss150715 		physaddr = _link_ntoa(myaddr, NULL, dlinfo.di_physaddrlen,
244c7e4935fSss150715 		    IFT_OTHER);
245c7e4935fSss150715 
246c7e4935fSss150715 		if (physaddr != NULL && bcastaddr != NULL) {
247c7e4935fSss150715 			(void) printf("device %s: broadcast address %s, mac "
248c7e4935fSss150715 			    "address %s\n", linkname, bcastaddr, physaddr);
2497c478bd9Sstevel@tonic-gate 		}
250c7e4935fSss150715 
251c7e4935fSss150715 		free(physaddr);
252c7e4935fSss150715 		free(bcastaddr);
253c7e4935fSss150715 
254c7e4935fSss150715 		(void) printf("rarp_open: addr length = %d\n",
255c7e4935fSss150715 		    dlinfo.di_physaddrlen);
2567c478bd9Sstevel@tonic-gate 	}
257c7e4935fSss150715 
258c7e4935fSss150715 	return (dh);
259c7e4935fSss150715 
260c7e4935fSss150715 failed:
261c7e4935fSss150715 	dlpi_close(dh);
262c7e4935fSss150715 	return (NULL);
2637c478bd9Sstevel@tonic-gate }
264c7e4935fSss150715 
265c7e4935fSss150715 /*
266c7e4935fSss150715  * Read reply for RARP request. If a reply is received within waitms,
267c7e4935fSss150715  * validate the reply. If it is a correct RARP reply return DLPI_SUCCESS,
268c7e4935fSss150715  * otherwise return DLPI_ETIMEDOUT. If there is an error while reading retrun
269c7e4935fSss150715  * the error code.
270c7e4935fSss150715  */
271c7e4935fSss150715 static int
rarp_recv(dlpi_handle_t dh,struct arphdr * ans,size_t msglen,size_t physaddrlen,int64_t waitms)272c7e4935fSss150715 rarp_recv(dlpi_handle_t dh, struct arphdr *ans, size_t msglen,
273c7e4935fSss150715     size_t physaddrlen, int64_t waitms)
274c7e4935fSss150715 {
275c7e4935fSss150715 	int		retval;
276c7e4935fSss150715 	char		*cause;
277c7e4935fSss150715 	size_t		anslen = msglen;
278c7e4935fSss150715 	hrtime_t	endtime = gethrtime() + MSEC2NSEC(waitms);
279c7e4935fSss150715 	hrtime_t	currtime;
280c7e4935fSss150715 
281c7e4935fSss150715 	while ((currtime = gethrtime()) < endtime) {
282c7e4935fSss150715 		waitms = NSEC2MSEC(endtime - currtime);
283c7e4935fSss150715 		retval = dlpi_recv(dh, NULL, NULL, ans, &anslen, waitms, NULL);
284c7e4935fSss150715 		if (retval == DLPI_SUCCESS) {
2857c478bd9Sstevel@tonic-gate 			cause = NULL;
2867c478bd9Sstevel@tonic-gate 
287c7e4935fSss150715 			if (anslen < msglen)
288c7e4935fSss150715 				cause = "short packet";
2897c478bd9Sstevel@tonic-gate 			else if (ans->ar_hrd != htons(ARPHRD_ETHER))
290c7e4935fSss150715 				cause = "hardware type not Ethernet";
2917c478bd9Sstevel@tonic-gate 			else if (ans->ar_pro != htons(ETHERTYPE_IP))
292c7e4935fSss150715 				cause = "protocol type not IP";
293c7e4935fSss150715 			else if (ans->ar_hln != physaddrlen)
294c7e4935fSss150715 				cause = "unexpected hardware address length";
2957c478bd9Sstevel@tonic-gate 			else if (ans->ar_pln != IPADDRL)
296c7e4935fSss150715 				cause = "unexpected protocol address length";
297c7e4935fSss150715 			if (cause != NULL) {
298c7e4935fSss150715 				(void) fprintf(stderr, "RARP packet received "
299c7e4935fSss150715 				    "but discarded (%s)\n", cause);
3007c478bd9Sstevel@tonic-gate 				continue;
3017c478bd9Sstevel@tonic-gate 			}
3027c478bd9Sstevel@tonic-gate 			switch (ntohs(ans->ar_op)) {
3037c478bd9Sstevel@tonic-gate 			case REVARP_REQUEST:
3047c478bd9Sstevel@tonic-gate 				if (debug)
3057c478bd9Sstevel@tonic-gate 					(void) printf("Got a rarp request.\n");
3067c478bd9Sstevel@tonic-gate 				break;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 			case REVARP_REPLY:
309c7e4935fSss150715 				return (DLPI_SUCCESS);
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 			default:
312c7e4935fSss150715 				(void) fprintf(stderr, "ifconfig: unknown "
313c7e4935fSss150715 				    "RARP opcode 0x%x\n", ans->ar_op);
3147c478bd9Sstevel@tonic-gate 				break;
3157c478bd9Sstevel@tonic-gate 			}
316c7e4935fSss150715 		} else if (retval != DLPI_ETIMEDOUT) {
317c7e4935fSss150715 			Perrdlpi("doifrevarp: dlpi_recv failed",
318c7e4935fSss150715 			    dlpi_linkname(dh), retval);
319c7e4935fSss150715 			return (retval);
3207c478bd9Sstevel@tonic-gate 		}
3217c478bd9Sstevel@tonic-gate 	}
3227c478bd9Sstevel@tonic-gate 
323c7e4935fSss150715 	return (DLPI_ETIMEDOUT);
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate void
dlpi_print_address(const char * linkname)327c7e4935fSss150715 dlpi_print_address(const char *linkname)
3287c478bd9Sstevel@tonic-gate {
329c7e4935fSss150715 	uint_t	physaddrlen = DLPI_PHYSADDR_MAX;
330c7e4935fSss150715 	uchar_t	physaddr[DLPI_PHYSADDR_MAX];
331c7e4935fSss150715 	char	*str;
332c7e4935fSss150715 	int	retv;
333c7e4935fSss150715 	dlpi_handle_t	dh;
334c7e4935fSss150715 	dlpi_info_t	dlinfo;
3357c478bd9Sstevel@tonic-gate 
336c7e4935fSss150715 	if (dlpi_open(linkname, &dh, 0) != DLPI_SUCCESS) {
3377c478bd9Sstevel@tonic-gate 		/* Do not report an error */
3387c478bd9Sstevel@tonic-gate 		return;
3397c478bd9Sstevel@tonic-gate 	}
3407c478bd9Sstevel@tonic-gate 
341c7e4935fSss150715 	retv = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, physaddr, &physaddrlen);
342c7e4935fSss150715 	if (retv != DLPI_SUCCESS) {
343c7e4935fSss150715 		Perrdlpi("dlpi_get_physaddr failed", linkname, retv);
344c7e4935fSss150715 		dlpi_close(dh);
345b1241e9cSyw138387 		return;
3467c478bd9Sstevel@tonic-gate 	}
3477c478bd9Sstevel@tonic-gate 
348c7e4935fSss150715 	retv = dlpi_info(dh, &dlinfo, 0);
349c7e4935fSss150715 	if (retv != DLPI_SUCCESS) {
350c7e4935fSss150715 		Perrdlpi("dlpi_info failed", linkname, retv);
351c7e4935fSss150715 		dlpi_close(dh);
352c7e4935fSss150715 		return;
3537c478bd9Sstevel@tonic-gate 	}
354c7e4935fSss150715 	dlpi_close(dh);
3557c478bd9Sstevel@tonic-gate 
356c7e4935fSss150715 	str = _link_ntoa(physaddr, NULL, physaddrlen, IFT_OTHER);
3577c478bd9Sstevel@tonic-gate 
358c08e5e1aSdr146992 	if (str != NULL && physaddrlen != 0) {
359c7e4935fSss150715 		switch (dlinfo.di_mactype) {
3607c478bd9Sstevel@tonic-gate 			case DL_IB:
3617c478bd9Sstevel@tonic-gate 				(void) printf("\tipib %s \n", str);
3627c478bd9Sstevel@tonic-gate 				break;
3637c478bd9Sstevel@tonic-gate 			default:
3647c478bd9Sstevel@tonic-gate 				(void) printf("\tether %s \n", str);
3657c478bd9Sstevel@tonic-gate 				break;
3667c478bd9Sstevel@tonic-gate 		}
3677c478bd9Sstevel@tonic-gate 		free(str);
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate }
370