4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
29 * Portions of this source code were derived from Berkeley 4.3 BSD
30 * under license from the Regents of the University of California.
34 * rarpd.c Reverse-ARP server.
35 * Refer to RFC 903 "A Reverse Address Resolution Protocol".
44 #include <sys/resource.h>
46 #include <stdio_ext.h>
50 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <sys/sockio.h>
58 #include <netinet/if_ether.h>
59 #include <netinet/in.h>
60 #include <arpa/inet.h>
62 #include <libinetutil.h>
64 #include <net/if_types.h>
65 #include <net/if_dl.h>
67 #define BOOTDIR "/tftpboot" /* boot files directory */
68 #define DEVIP "/dev/ip" /* path to ip driver */
69 #define DEVARP "/dev/arp" /* path to arp driver */
71 #define BUFSIZE 2048 /* max receive frame length */
72 #define MAXPATHL 128 /* max path length */
73 #define MAXHOSTL 128 /* max host name length */
77 * Logical network devices
80 char ldevice
[IFNAMSIZ
];
82 ipaddr_t ipaddr
; /* network order */
83 ipaddr_t if_netmask
; /* host order */
84 ipaddr_t if_ipaddr
; /* host order */
85 ipaddr_t if_netnum
; /* host order, with subnet */
90 * Physical network device
93 char device
[DLPI_LINKNAME_MAX
];
95 dlpi_handle_t dh_rarp
;
96 uchar_t physaddr
[DLPI_PHYSADDR_MAX
];
97 /* mac address of interface */
98 uint_t physaddrlen
; /* mac address length */
99 int ifrarplen
; /* size of rarp data packet */
100 struct ifdev
*ifdev
; /* private interface info */
101 struct rarpdev
*next
; /* list of managed devices */
105 struct rarpdev
*rdev
; /* which device reply for */
106 struct timeval tv
; /* send RARP reply by when */
107 uchar_t
*lldest
; /* target mac to send reply */
108 uchar_t
*arprep
; /* [R]ARP response */
109 struct rarpreply
*next
;
112 static struct rarpreply
*delay_list
;
113 static sema_t delay_sema
;
114 static mutex_t delay_mutex
;
115 static mutex_t debug_mutex
;
117 static struct rarpdev
*rarpdev_head
;
120 * Globals initialized before multi-threading
122 static char *cmdname
; /* command name from argv[0] */
123 static int dflag
= 0; /* enable diagnostics */
124 static int aflag
= 0; /* start rarpd on all interfaces */
126 static void getintf(void);
127 static struct rarpdev
*find_device(ifspec_t
*);
128 static void init_rarpdev(struct rarpdev
*);
129 static void do_rarp(void *);
130 static void rarp_request(struct rarpdev
*, struct arphdr
*,
132 static void add_arp(struct rarpdev
*, uchar_t
*, uchar_t
*);
133 static void arp_request(struct rarpdev
*, struct arphdr
*, uchar_t
*);
134 static void do_delay_write(void *);
135 static void delay_write(struct rarpdev
*, struct rarpreply
*);
136 static int mightboot(ipaddr_t
);
137 static void get_ifdata(char *, int, ipaddr_t
*, ipaddr_t
*);
138 static int get_ipaddr(struct rarpdev
*, uchar_t
*, uchar_t
*, ipaddr_t
*);
139 static int strioctl(int, int, int, int, char *);
141 static void syserr(const char *);
143 static void error(const char *, ...);
144 static void debug(char *, ...);
150 main(int argc
, char *argv
[])
154 struct rarpdev
*rdev
;
159 while ((c
= getopt(argc
, argv
, "ad")) != -1) {
174 if ((!aflag
&& (argc
- optind
) != 2) ||
175 (aflag
&& (argc
- optind
) != 0)) {
192 default: /* parent */
195 for (i
= 0; i
< 3; i
++) {
198 (void) open("/", O_RDONLY
, 0);
208 rl
.rlim_cur
= RLIM_INFINITY
;
209 rl
.rlim_max
= RLIM_INFINITY
;
210 if (setrlimit(RLIMIT_NOFILE
, &rl
) == -1)
212 (void) enable_extended_FILE_stdio(-1, -1);
214 (void) openlog(cmdname
, LOG_PID
, LOG_DAEMON
);
218 * Get each interface name and load rarpdev list.
224 char buf
[IFNAMSIZ
+ 1];
227 * Load specified device as only element of the list.
229 rarpdev_head
= (struct rarpdev
*)calloc(1,
230 sizeof (struct rarpdev
));
231 if (rarpdev_head
== NULL
) {
232 error("out of memory");
234 (void) strncpy(buf
, argv
[optind
], IFNAMSIZ
);
235 (void) strncat(buf
, argv
[optind
+ 1], IFNAMSIZ
- strlen(buf
));
237 if ((ifdev
= calloc(1, sizeof (struct ifdev
))) == NULL
) {
238 error("out of memory");
241 if (!ifparse_ifspec(buf
, &ifsp
))
242 error("invalid interface specification");
244 if (ifsp
.ifsp_lunvalid
) {
245 (void) snprintf(ifdev
->ldevice
,
246 sizeof (ifdev
->ldevice
), "%s%d:",
247 ifsp
.ifsp_devnm
, ifsp
.ifsp_ppa
);
248 ifdev
->lunit
= ifsp
.ifsp_lun
;
250 ifdev
->lunit
= -1; /* no logical unit */
252 (void) strlcpy(rarpdev_head
->device
, ifsp
.ifsp_devnm
,
253 sizeof (rarpdev_head
->device
));
254 rarpdev_head
->unit
= ifsp
.ifsp_ppa
;
256 ifdev
->next
= rarpdev_head
->ifdev
;
257 rarpdev_head
->ifdev
= ifdev
;
261 * Initialize each rarpdev.
263 for (rdev
= rarpdev_head
; rdev
!= NULL
; rdev
= rdev
->next
) {
267 (void) sema_init(&delay_sema
, 0, USYNC_THREAD
, NULL
);
268 (void) mutex_init(&delay_mutex
, USYNC_THREAD
, NULL
);
269 (void) mutex_init(&debug_mutex
, USYNC_THREAD
, NULL
);
272 * Start delayed processing thread.
274 (void) thr_create(NULL
, NULL
, (void *(*)(void *))do_delay_write
, NULL
,
278 * Start RARP processing for each device.
280 for (rdev
= rarpdev_head
; rdev
!= NULL
; rdev
= rdev
->next
) {
281 if (rdev
->dh_rarp
!= NULL
) {
282 (void) thr_create(NULL
, NULL
,
283 (void *(*)(void *))do_rarp
, (void *)rdev
,
302 struct ifreq
*reqbuf
;
303 struct ifconf ifconf
;
305 struct rarpdev
*rdev
;
309 * Open the IP provider.
311 if ((fd
= open(DEVIP
, 0)) < 0)
315 * Ask IP for the list of configured interfaces.
317 if (ioctl(fd
, SIOCGIFNUM
, (char *)&numifs
) < 0) {
320 bufsize
= numifs
* sizeof (struct ifreq
);
321 reqbuf
= (struct ifreq
*)malloc(bufsize
);
322 if (reqbuf
== NULL
) {
323 error("out of memory");
326 ifconf
.ifc_len
= bufsize
;
327 ifconf
.ifc_buf
= (caddr_t
)reqbuf
;
328 if (ioctl(fd
, SIOCGIFCONF
, (char *)&ifconf
) < 0)
329 syserr("SIOCGIFCONF");
332 * Initialize a rarpdev for each interface.
334 for (ifr
= ifconf
.ifc_req
; ifconf
.ifc_len
> 0;
335 ifr
++, ifconf
.ifc_len
-= sizeof (struct ifreq
)) {
338 if (ioctl(fd
, SIOCGIFFLAGS
, (char *)ifr
) < 0) {
339 syserr("ioctl SIOCGIFFLAGS");
342 if ((ifr
->ifr_flags
& IFF_LOOPBACK
) ||
343 !(ifr
->ifr_flags
& IFF_UP
) ||
344 !(ifr
->ifr_flags
& IFF_BROADCAST
) ||
345 (ifr
->ifr_flags
& IFF_NOARP
) ||
346 (ifr
->ifr_flags
& IFF_POINTOPOINT
))
349 if (!ifparse_ifspec(ifr
->ifr_name
, &ifsp
))
350 error("ifparse_ifspec failed");
353 * Look for an existing device for logical interfaces.
355 if ((rdev
= find_device(&ifsp
)) == NULL
) {
356 rdev
= calloc(1, sizeof (struct rarpdev
));
358 error("out of memory");
360 (void) strlcpy(rdev
->device
, ifsp
.ifsp_devnm
,
361 sizeof (rdev
->device
));
362 rdev
->unit
= ifsp
.ifsp_ppa
;
364 rdev
->next
= rarpdev_head
;
368 if ((ifdev
= calloc(1, sizeof (struct ifdev
))) == NULL
)
369 error("out of memory");
371 if (ifsp
.ifsp_lunvalid
) {
372 (void) snprintf(ifdev
->ldevice
,
373 sizeof (ifdev
->ldevice
), "%s%d:",
374 ifsp
.ifsp_devnm
, ifsp
.ifsp_ppa
);
375 ifdev
->lunit
= ifsp
.ifsp_lun
;
377 ifdev
->lunit
= -1; /* no logical unit */
379 ifdev
->next
= rdev
->ifdev
;
382 (void) free((char *)reqbuf
);
385 static struct rarpdev
*
386 find_device(ifspec_t
*specp
)
388 struct rarpdev
*rdev
;
390 for (rdev
= rarpdev_head
; rdev
!= NULL
; rdev
= rdev
->next
) {
391 if (specp
->ifsp_ppa
== rdev
->unit
&&
392 strcmp(specp
->ifsp_devnm
, rdev
->device
) == 0)
399 init_rarpdev(struct rarpdev
*rdev
)
406 uint_t physaddrlen
= DLPI_PHYSADDR_MAX
;
407 char linkname
[DLPI_LINKNAME_MAX
];
410 (void) snprintf(linkname
, DLPI_LINKNAME_MAX
, "%s%d", rdev
->device
,
413 * Open datalink provider and get our mac address.
415 if ((retval
= dlpi_open(linkname
, &dh
, 0)) != DLPI_SUCCESS
) {
416 error("cannot open link %s: %s", linkname
,
417 dlpi_strerror(retval
));
420 if ((retval
= dlpi_bind(dh
, ETHERTYPE_REVARP
, NULL
)) != DLPI_SUCCESS
) {
422 error("dlpi_bind failed: %s", dlpi_strerror(retval
));
426 * Save our mac address.
428 if ((retval
= dlpi_get_physaddr(dh
, DL_CURR_PHYS_ADDR
, rdev
->physaddr
,
429 &physaddrlen
)) != DLPI_SUCCESS
) {
431 error("dlpi_get_physaddr failed: %s", dlpi_strerror(retval
));
434 rdev
->physaddrlen
= physaddrlen
;
435 rdev
->ifrarplen
= sizeof (struct arphdr
) + (2 * sizeof (ipaddr_t
)) +
439 str
= _link_ntoa(rdev
->physaddr
, str
,
440 rdev
->physaddrlen
, IFT_OTHER
);
442 debug("device %s physical address %s", linkname
, str
);
448 * Assign dlpi handle to rdev.
453 * Get the IP address and netmask from directory service for
454 * each logical interface.
456 for (ifdev
= rdev
->ifdev
; ifdev
!= NULL
; ifdev
= ifdev
->next
) {
458 * If lunit == -1 then this is the primary interface name.
460 if (ifdev
->lunit
== -1) {
464 dev
= ifdev
->ldevice
;
467 get_ifdata(dev
, unit
, &ifdev
->if_ipaddr
, &ifdev
->if_netmask
);
470 * Use IP address of the interface.
472 ifdev
->if_netnum
= ifdev
->if_ipaddr
& ifdev
->if_netmask
;
473 ifdev
->ipaddr
= (ipaddr_t
)htonl(ifdev
->if_ipaddr
);
480 struct rarpdev
*rdev
= buf
;
485 size_t anslen
= rdev
->ifrarplen
;
489 if (((shost
= malloc(rdev
->physaddrlen
)) == NULL
) ||
490 ((ans
= malloc(rdev
->ifrarplen
)) == NULL
))
494 str
= _link_ntoa(rdev
->physaddr
, str
, rdev
->physaddrlen
,
497 debug("starting rarp service on device %s%d physical"
498 " address %s", rdev
->device
, rdev
->unit
, str
);
504 * Read RARP packets and respond to them.
507 saddrlen
= DLPI_PHYSADDR_MAX
;
508 retval
= dlpi_recv(rdev
->dh_rarp
, shost
,
509 &saddrlen
, ans
, &anslen
, -1, NULL
);
510 if (retval
== DLPI_ETIMEDOUT
) {
512 } else if (retval
!= DLPI_SUCCESS
) {
513 error("error in dlpi_recv %s: %s", rdev
->dh_rarp
,
514 dlpi_strerror(retval
));
519 if (anslen
< rdev
->ifrarplen
)
520 cause
= "short packet";
521 else if (ans
->ar_hrd
!= htons(ARPHRD_ETHER
))
522 cause
= "hardware type not Ethernet";
523 else if (ans
->ar_pro
!= htons(ETHERTYPE_IP
))
524 cause
= "protocol type not IP";
525 else if (ans
->ar_hln
!= rdev
->physaddrlen
)
526 cause
= "unexpected hardware address length";
527 else if (ans
->ar_pln
!= sizeof (ipaddr_t
))
528 cause
= "unexpected protocol address length";
531 debug("RARP packet received but "
532 "discarded: %s", cause
);
537 * Handle the request.
539 switch (ntohs(ans
->ar_op
)) {
541 rarp_request(rdev
, ans
, shost
);
545 arp_request(rdev
, ans
, shost
);
550 debug("REVARP_REPLY ignored");
555 debug("ARPOP_REPLY ignored");
560 debug("unknown opcode 0x%x", ans
->ar_op
);
567 * Reverse address determination and allocation code.
570 rarp_request(struct rarpdev
*rdev
, struct arphdr
*rp
, uchar_t
*shost
)
573 struct rarpreply
*rrp
;
574 uchar_t
*shap
, *thap
, *spap
, *tpap
;
578 shap
= (uchar_t
*)rp
+ sizeof (struct arphdr
);
579 spap
= shap
+ rp
->ar_hln
;
580 thap
= spap
+ rp
->ar_pln
;
581 tpap
= thap
+ rp
->ar_hln
;
584 str
= _link_ntoa(thap
, str
, rdev
->physaddrlen
, IFT_OTHER
);
586 debug("RARP_REQUEST for %s", str
);
592 * Third party lookups are rare and wonderful.
594 if ((memcmp(shap
, thap
, rdev
->physaddrlen
) != 0) ||
595 (memcmp(shap
, shost
, rdev
->physaddrlen
) != 0)) {
597 debug("weird (3rd party lookup)");
601 * Fill in given parts of reply packet.
603 (void) memcpy(shap
, rdev
->physaddr
, rdev
->physaddrlen
);
606 * If a good address is stored in our lookup tables, return it
607 * immediately or after a delay. Store it in our kernel's ARP cache.
609 if (get_ipaddr(rdev
, thap
, tpap
, &spa
))
611 (void) memcpy(spap
, &spa
, sizeof (spa
));
613 add_arp(rdev
, tpap
, thap
);
615 rp
->ar_op
= htons(REVARP_REPLY
);
620 (void) memcpy(&addr
, tpap
, sizeof (ipaddr_t
));
621 debug("good lookup, maps to %s", inet_ntoa(addr
));
624 rrp
= calloc(1, sizeof (struct rarpreply
) + rdev
->physaddrlen
+
627 error("out of memory");
628 rrp
->lldest
= (uchar_t
*)rrp
+ sizeof (struct rarpreply
);
629 rrp
->arprep
= rrp
->lldest
+ rdev
->physaddrlen
;
632 * Create rarpreply structure.
634 (void) gettimeofday(&rrp
->tv
, NULL
);
635 rrp
->tv
.tv_sec
+= 3; /* delay */
637 (void) memcpy(rrp
->lldest
, shost
, rdev
->physaddrlen
);
638 (void) memcpy(rrp
->arprep
, rp
, rdev
->ifrarplen
);
641 * If this is diskless and we're not its bootserver, let the
642 * bootserver reply first by delaying a while.
644 (void) memcpy(&tpa
, tpap
, sizeof (ipaddr_t
));
645 if (mightboot(ntohl(tpa
))) {
646 retval
= dlpi_send(rdev
->dh_rarp
, rrp
->lldest
,
647 rdev
->physaddrlen
, rrp
->arprep
, rdev
->ifrarplen
, NULL
);
648 if (retval
!= DLPI_SUCCESS
) {
649 error("dlpi_send failed: %s", dlpi_strerror(retval
));
651 debug("immediate reply sent");
655 delay_write(rdev
, rrp
);
660 * Download an ARP entry into our kernel.
663 add_arp(struct rarpdev
*rdev
, uchar_t
*ip
, uchar_t
*laddr
)
666 struct sockaddr_in
*sin
;
670 * Common part of query or set.
672 (void) memset(&ar
, 0, sizeof (ar
));
673 ar
.xarp_pa
.ss_family
= AF_INET
;
674 sin
= (struct sockaddr_in
*)&ar
.xarp_pa
;
675 (void) memcpy(&sin
->sin_addr
, ip
, sizeof (ipaddr_t
));
678 * Open the IP provider.
680 if ((fd
= open(DEVARP
, 0)) < 0)
686 (void) memcpy(LLADDR(&ar
.xarp_ha
), laddr
, rdev
->physaddrlen
);
687 ar
.xarp_ha
.sdl_alen
= rdev
->physaddrlen
;
688 ar
.xarp_ha
.sdl_family
= AF_LINK
;
689 (void) strioctl(fd
, SIOCDXARP
, -1, sizeof (struct xarpreq
),
691 if (strioctl(fd
, SIOCSXARP
, -1, sizeof (struct xarpreq
),
699 * The RARP spec says we must be able to process ARP requests,
700 * even through the packet type is RARP. Let's hope this feature
701 * is not heavily used.
704 arp_request(struct rarpdev
*rdev
, struct arphdr
*rp
, uchar_t
*shost
)
706 struct rarpreply
*rrp
;
708 uchar_t
*shap
, *thap
, *spap
, *tpap
;
711 shap
= (uchar_t
*)rp
+ sizeof (struct arphdr
);
712 spap
= shap
+ rp
->ar_hln
;
713 thap
= spap
+ rp
->ar_pln
;
714 tpap
= thap
+ rp
->ar_hln
;
717 debug("ARPOP_REQUEST");
719 for (ifdev
= rdev
->ifdev
; ifdev
!= NULL
; ifdev
= ifdev
->next
) {
720 if (memcmp(&ifdev
->ipaddr
, tpap
, sizeof (ipaddr_t
)) == 0)
726 rp
->ar_op
= ARPOP_REPLY
;
727 (void) memcpy(shap
, rdev
->physaddr
, rdev
->physaddrlen
);
728 (void) memcpy(spap
, &ifdev
->ipaddr
, sizeof (ipaddr_t
));
729 (void) memcpy(thap
, rdev
->physaddr
, rdev
->physaddrlen
);
731 add_arp(rdev
, tpap
, thap
);
734 * Create rarp reply structure.
736 rrp
= calloc(1, sizeof (struct rarpreply
) + rdev
->physaddrlen
+
739 error("out of memory");
740 rrp
->lldest
= (uchar_t
*)rrp
+ sizeof (struct rarpreply
);
741 rrp
->arprep
= rrp
->lldest
+ rdev
->physaddrlen
;
744 (void) memcpy(rrp
->lldest
, shost
, rdev
->physaddrlen
);
745 (void) memcpy(rrp
->arprep
, rp
, rdev
->ifrarplen
);
747 retval
= dlpi_send(rdev
->dh_rarp
, rrp
->lldest
, rdev
->physaddrlen
,
748 rrp
->arprep
, rdev
->ifrarplen
, NULL
);
750 if (retval
!= DLPI_SUCCESS
)
751 error("dlpi_send failed: %s", dlpi_strerror(retval
));
756 do_delay_write(void *buf
)
759 struct rarpreply
*rrp
;
760 struct rarpdev
*rdev
;
764 if ((err
= sema_wait(&delay_sema
)) != 0) {
767 error("do_delay_write: sema_wait failed");
770 (void) mutex_lock(&delay_mutex
);
773 delay_list
= delay_list
->next
;
774 (void) mutex_unlock(&delay_mutex
);
776 (void) gettimeofday(&tv
, NULL
);
777 if (tv
.tv_sec
< rrp
->tv
.tv_sec
)
778 (void) sleep(rrp
->tv
.tv_sec
- tv
.tv_sec
);
780 err
= dlpi_send(rdev
->dh_rarp
, rrp
->lldest
, rdev
->physaddrlen
,
781 rrp
->arprep
, rdev
->ifrarplen
, NULL
);
782 if (err
!= DLPI_SUCCESS
)
783 error("dlpi_send failed: %s", dlpi_strerror(err
));
791 delay_write(struct rarpdev
*rdev
, struct rarpreply
*rrp
)
793 struct rarpreply
*trp
;
795 (void) mutex_lock(&delay_mutex
);
796 if (delay_list
== NULL
) {
800 while (trp
->next
!= NULL
)
804 (void) mutex_unlock(&delay_mutex
);
806 (void) sema_post(&delay_sema
);
810 * See if we have a TFTP boot file for this guy. Filenames in TFTP
811 * boot requests are of the form <ipaddr> for Sun-3's and of the form
812 * <ipaddr>.<arch> for all other architectures. Since we don't know
813 * the client's architecture, either format will do.
816 mightboot(ipaddr_t ipa
)
822 (void) snprintf(path
, sizeof (path
), "%s/%08X", BOOTDIR
, ipa
);
825 * Try a quick access() first.
827 if (access(path
, 0) == 0)
831 * Not there, do it the slow way by
832 * reading through the directory.
834 (void) sprintf(path
, "%08X", ipa
);
836 if (!(dirp
= opendir(BOOTDIR
)))
839 while ((dp
= readdir(dirp
)) != NULL
) {
840 if (strncmp(dp
->d_name
, path
, 8) != 0)
842 if ((strlen(dp
->d_name
) != 8) && (dp
->d_name
[8] != '.'))
847 (void) closedir(dirp
);
849 return ((dp
!= NULL
) ? 1 : 0);
853 * Get our IP address and local netmask.
856 get_ifdata(char *dev
, int unit
, ipaddr_t
*ipp
, ipaddr_t
*maskp
)
860 struct sockaddr_in
*sin
;
863 sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
866 * Open the IP provider.
868 if ((fd
= open(DEVIP
, 0)) < 0)
872 * Ask IP for our IP address.
874 (void) snprintf(ifr
.ifr_name
, sizeof (ifr
.ifr_name
), "%s%d", dev
, unit
);
875 if (strioctl(fd
, SIOCGIFADDR
, -1, sizeof (struct ifreq
),
877 syserr("SIOCGIFADDR");
878 *ipp
= (ipaddr_t
)ntohl(sin
->sin_addr
.s_addr
);
881 debug("device %s%d address %s", dev
, unit
,
882 inet_ntoa(sin
->sin_addr
));
885 * Ask IP for our netmask.
887 if (strioctl(fd
, SIOCGIFNETMASK
, -1, sizeof (struct ifreq
),
889 syserr("SIOCGIFNETMASK");
890 *maskp
= (ipaddr_t
)ntohl(sin
->sin_addr
.s_addr
);
893 debug("device %s%d subnet mask %s", dev
, unit
,
894 inet_ntoa(sin
->sin_addr
));
903 * Translate mac address to IP address.
904 * Return 0 on success, nonzero on failure.
907 get_ipaddr(struct rarpdev
*rdev
, uchar_t
*laddr
, uchar_t
*ipp
, ipaddr_t
*ipaddr
)
910 char hbuffer
[BUFSIZE
];
911 struct hostent
*hp
, res
;
917 if (rdev
->physaddrlen
!= ETHERADDRL
) {
919 debug("%s %s", " cannot map non 6 byte hardware ",
920 "address to IP address");
925 * Translate mac address to hostname and IP address.
927 if (ether_ntohost(host
, (struct ether_addr
*)laddr
) != 0 ||
928 !(hp
= gethostbyname_r(host
, &res
, hbuffer
, sizeof (hbuffer
),
930 hp
->h_addrtype
!= AF_INET
|| hp
->h_length
!= sizeof (ipaddr_t
)) {
932 debug("could not map hardware address to IP address");
937 * Find the IP address on the right net.
939 for (p
= hp
->h_addr_list
; *p
; p
++) {
940 (void) memcpy(&addr
, *p
, sizeof (ipaddr_t
));
941 for (ifdev
= rdev
->ifdev
; ifdev
!= NULL
; ifdev
= ifdev
->next
) {
943 struct in_addr daddr
;
946 netnum
= htonl(ifdev
->if_netnum
);
947 (void) memcpy(&daddr
, &netnum
,
949 if (ifdev
->lunit
== -1)
950 debug("trying physical netnum %s"
951 " mask %x", inet_ntoa(daddr
),
954 debug("trying logical %d netnum %s"
955 " mask %x", ifdev
->lunit
,
959 if ((ntohl(addr
.s_addr
) & ifdev
->if_netmask
) ==
962 * Return the correct IP address.
964 (void) memcpy(ipp
, &addr
, sizeof (ipaddr_t
));
967 * Return the interface's ipaddr
969 (void) memcpy(ipaddr
, &ifdev
->ipaddr
,
978 debug("got host entry but no IP address on this net");
983 strioctl(int fd
, int cmd
, int timout
, int len
, char *dp
)
988 si
.ic_timout
= timout
;
991 return (ioctl(fd
, I_STR
, &si
));
997 error("Usage: %s [ -ad ] device unit", cmdname
);
1001 syserr(const char *s
)
1006 (void) snprintf(buf
, sizeof (buf
), "%s: %s", s
, strerror(errno
));
1007 (void) fprintf(stderr
, "%s: %s\n", cmdname
, buf
);
1008 syslog(LOG_ERR
, "%s", buf
);
1013 error(const char *fmt
, ...)
1020 (void) vsprintf(buf
, fmt
, ap
);
1022 (void) fprintf(stderr
, "%s: %s\n", cmdname
, buf
);
1023 syslog(LOG_ERR
, buf
);
1029 debug(char *fmt
, ...)
1033 (void) mutex_lock(&debug_mutex
);
1035 (void) fprintf(stderr
, "%s:[%u] ", cmdname
, thr_self());
1036 (void) vfprintf(stderr
, fmt
, ap
);
1037 (void) fprintf(stderr
, "\n");
1039 (void) mutex_unlock(&debug_mutex
);