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".
42 #include <sys/resource.h>
44 #include <stdio_ext.h>
48 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <sys/sockio.h>
56 #include <netinet/if_ether.h>
57 #include <netinet/in.h>
58 #include <arpa/inet.h>
60 #include <libinetutil.h>
62 #include <net/if_types.h>
63 #include <net/if_dl.h>
65 #define BOOTDIR "/tftpboot" /* boot files directory */
66 #define DEVIP "/dev/ip" /* path to ip driver */
67 #define DEVARP "/dev/arp" /* path to arp driver */
69 #define BUFSIZE 2048 /* max receive frame length */
70 #define MAXPATHL 128 /* max path length */
71 #define MAXHOSTL 128 /* max host name length */
75 * Logical network devices
78 char ldevice
[IFNAMSIZ
];
80 ipaddr_t ipaddr
; /* network order */
81 ipaddr_t if_netmask
; /* host order */
82 ipaddr_t if_ipaddr
; /* host order */
83 ipaddr_t if_netnum
; /* host order, with subnet */
88 * Physical network device
91 char device
[DLPI_LINKNAME_MAX
];
93 dlpi_handle_t dh_rarp
;
94 uchar_t physaddr
[DLPI_PHYSADDR_MAX
];
95 /* mac address of interface */
96 uint_t physaddrlen
; /* mac address length */
97 int ifrarplen
; /* size of rarp data packet */
98 struct ifdev
*ifdev
; /* private interface info */
99 struct rarpdev
*next
; /* list of managed devices */
103 struct rarpdev
*rdev
; /* which device reply for */
104 struct timeval tv
; /* send RARP reply by when */
105 uchar_t
*lldest
; /* target mac to send reply */
106 uchar_t
*arprep
; /* [R]ARP response */
107 struct rarpreply
*next
;
110 static struct rarpreply
*delay_list
;
111 static sema_t delay_sema
;
112 static mutex_t delay_mutex
;
113 static mutex_t debug_mutex
;
115 static struct rarpdev
*rarpdev_head
;
118 * Globals initialized before multi-threading
120 static char *cmdname
; /* command name from argv[0] */
121 static int dflag
= 0; /* enable diagnostics */
122 static int aflag
= 0; /* start rarpd on all interfaces */
124 static void getintf(void);
125 static struct rarpdev
*find_device(ifspec_t
*);
126 static void init_rarpdev(struct rarpdev
*);
127 static void do_rarp(void *);
128 static void rarp_request(struct rarpdev
*, struct arphdr
*,
130 static void add_arp(struct rarpdev
*, uchar_t
*, uchar_t
*);
131 static void arp_request(struct rarpdev
*, struct arphdr
*, uchar_t
*);
132 static void do_delay_write(void *);
133 static void delay_write(struct rarpdev
*, struct rarpreply
*);
134 static int mightboot(ipaddr_t
);
135 static void get_ifdata(char *, int, ipaddr_t
*, ipaddr_t
*);
136 static int get_ipaddr(struct rarpdev
*, uchar_t
*, uchar_t
*, ipaddr_t
*);
137 static int strioctl(int, int, int, int, char *);
139 static void syserr(const char *);
141 static void error(const char *, ...);
142 static void debug(char *, ...);
148 main(int argc
, char *argv
[])
152 struct rarpdev
*rdev
;
157 while ((c
= getopt(argc
, argv
, "ad")) != -1) {
172 if ((!aflag
&& (argc
- optind
) != 2) ||
173 (aflag
&& (argc
- optind
) != 0)) {
190 default: /* parent */
193 for (i
= 0; i
< 3; i
++) {
196 (void) open("/", O_RDONLY
, 0);
206 rl
.rlim_cur
= RLIM_INFINITY
;
207 rl
.rlim_max
= RLIM_INFINITY
;
208 if (setrlimit(RLIMIT_NOFILE
, &rl
) == -1)
210 (void) enable_extended_FILE_stdio(-1, -1);
212 (void) openlog(cmdname
, LOG_PID
, LOG_DAEMON
);
216 * Get each interface name and load rarpdev list.
222 char buf
[IFNAMSIZ
+ 1];
225 * Load specified device as only element of the list.
227 rarpdev_head
= (struct rarpdev
*)calloc(1,
228 sizeof (struct rarpdev
));
229 if (rarpdev_head
== NULL
) {
230 error("out of memory");
232 (void) strncpy(buf
, argv
[optind
], IFNAMSIZ
);
233 (void) strncat(buf
, argv
[optind
+ 1], IFNAMSIZ
- strlen(buf
));
235 if ((ifdev
= calloc(1, sizeof (struct ifdev
))) == NULL
) {
236 error("out of memory");
239 if (!ifparse_ifspec(buf
, &ifsp
))
240 error("invalid interface specification");
242 if (ifsp
.ifsp_lunvalid
) {
243 (void) snprintf(ifdev
->ldevice
,
244 sizeof (ifdev
->ldevice
), "%s%d:",
245 ifsp
.ifsp_devnm
, ifsp
.ifsp_ppa
);
246 ifdev
->lunit
= ifsp
.ifsp_lun
;
248 ifdev
->lunit
= -1; /* no logical unit */
250 (void) strlcpy(rarpdev_head
->device
, ifsp
.ifsp_devnm
,
251 sizeof (rarpdev_head
->device
));
252 rarpdev_head
->unit
= ifsp
.ifsp_ppa
;
254 ifdev
->next
= rarpdev_head
->ifdev
;
255 rarpdev_head
->ifdev
= ifdev
;
259 * Initialize each rarpdev.
261 for (rdev
= rarpdev_head
; rdev
!= NULL
; rdev
= rdev
->next
) {
265 (void) sema_init(&delay_sema
, 0, USYNC_THREAD
, NULL
);
266 (void) mutex_init(&delay_mutex
, USYNC_THREAD
, NULL
);
267 (void) mutex_init(&debug_mutex
, USYNC_THREAD
, NULL
);
270 * Start delayed processing thread.
272 (void) thr_create(NULL
, 0, (void *(*)(void *))do_delay_write
, NULL
,
276 * Start RARP processing for each device.
278 for (rdev
= rarpdev_head
; rdev
!= NULL
; rdev
= rdev
->next
) {
279 if (rdev
->dh_rarp
!= NULL
) {
280 (void) thr_create(NULL
, 0,
281 (void *(*)(void *))do_rarp
, (void *)rdev
,
300 struct ifreq
*reqbuf
;
301 struct ifconf ifconf
;
303 struct rarpdev
*rdev
;
307 * Open the IP provider.
309 if ((fd
= open(DEVIP
, O_RDONLY
)) < 0)
313 * Ask IP for the list of configured interfaces.
315 if (ioctl(fd
, SIOCGIFNUM
, (char *)&numifs
) < 0) {
318 bufsize
= numifs
* sizeof (struct ifreq
);
319 reqbuf
= (struct ifreq
*)malloc(bufsize
);
320 if (reqbuf
== NULL
) {
321 error("out of memory");
324 ifconf
.ifc_len
= bufsize
;
325 ifconf
.ifc_buf
= (caddr_t
)reqbuf
;
326 if (ioctl(fd
, SIOCGIFCONF
, (char *)&ifconf
) < 0)
327 syserr("SIOCGIFCONF");
330 * Initialize a rarpdev for each interface.
332 for (ifr
= ifconf
.ifc_req
; ifconf
.ifc_len
> 0;
333 ifr
++, ifconf
.ifc_len
-= sizeof (struct ifreq
)) {
336 if (ioctl(fd
, SIOCGIFFLAGS
, (char *)ifr
) < 0) {
337 syserr("ioctl SIOCGIFFLAGS");
340 if ((ifr
->ifr_flags
& IFF_LOOPBACK
) ||
341 !(ifr
->ifr_flags
& IFF_UP
) ||
342 !(ifr
->ifr_flags
& IFF_BROADCAST
) ||
343 (ifr
->ifr_flags
& IFF_NOARP
) ||
344 (ifr
->ifr_flags
& IFF_POINTOPOINT
))
347 if (!ifparse_ifspec(ifr
->ifr_name
, &ifsp
))
348 error("ifparse_ifspec failed");
351 * Look for an existing device for logical interfaces.
353 if ((rdev
= find_device(&ifsp
)) == NULL
) {
354 rdev
= calloc(1, sizeof (struct rarpdev
));
356 error("out of memory");
358 (void) strlcpy(rdev
->device
, ifsp
.ifsp_devnm
,
359 sizeof (rdev
->device
));
360 rdev
->unit
= ifsp
.ifsp_ppa
;
362 rdev
->next
= rarpdev_head
;
366 if ((ifdev
= calloc(1, sizeof (struct ifdev
))) == NULL
)
367 error("out of memory");
369 if (ifsp
.ifsp_lunvalid
) {
370 (void) snprintf(ifdev
->ldevice
,
371 sizeof (ifdev
->ldevice
), "%s%d:",
372 ifsp
.ifsp_devnm
, ifsp
.ifsp_ppa
);
373 ifdev
->lunit
= ifsp
.ifsp_lun
;
375 ifdev
->lunit
= -1; /* no logical unit */
377 ifdev
->next
= rdev
->ifdev
;
380 (void) free((char *)reqbuf
);
383 static struct rarpdev
*
384 find_device(ifspec_t
*specp
)
386 struct rarpdev
*rdev
;
388 for (rdev
= rarpdev_head
; rdev
!= NULL
; rdev
= rdev
->next
) {
389 if (specp
->ifsp_ppa
== rdev
->unit
&&
390 strcmp(specp
->ifsp_devnm
, rdev
->device
) == 0)
397 init_rarpdev(struct rarpdev
*rdev
)
404 uint_t physaddrlen
= DLPI_PHYSADDR_MAX
;
405 char linkname
[DLPI_LINKNAME_MAX
];
408 (void) snprintf(linkname
, DLPI_LINKNAME_MAX
, "%s%d", rdev
->device
,
411 * Open datalink provider and get our mac address.
413 if ((retval
= dlpi_open(linkname
, &dh
, 0)) != DLPI_SUCCESS
) {
414 error("cannot open link %s: %s", linkname
,
415 dlpi_strerror(retval
));
418 if ((retval
= dlpi_bind(dh
, ETHERTYPE_REVARP
, NULL
)) != DLPI_SUCCESS
) {
420 error("dlpi_bind failed: %s", dlpi_strerror(retval
));
424 * Save our mac address.
426 if ((retval
= dlpi_get_physaddr(dh
, DL_CURR_PHYS_ADDR
, rdev
->physaddr
,
427 &physaddrlen
)) != DLPI_SUCCESS
) {
429 error("dlpi_get_physaddr failed: %s", dlpi_strerror(retval
));
432 rdev
->physaddrlen
= physaddrlen
;
433 rdev
->ifrarplen
= sizeof (struct arphdr
) + (2 * sizeof (ipaddr_t
)) +
437 str
= _link_ntoa(rdev
->physaddr
, str
,
438 rdev
->physaddrlen
, IFT_OTHER
);
440 debug("device %s physical address %s", linkname
, str
);
446 * Assign dlpi handle to rdev.
451 * Get the IP address and netmask from directory service for
452 * each logical interface.
454 for (ifdev
= rdev
->ifdev
; ifdev
!= NULL
; ifdev
= ifdev
->next
) {
456 * If lunit == -1 then this is the primary interface name.
458 if (ifdev
->lunit
== -1) {
462 dev
= ifdev
->ldevice
;
465 get_ifdata(dev
, unit
, &ifdev
->if_ipaddr
, &ifdev
->if_netmask
);
468 * Use IP address of the interface.
470 ifdev
->if_netnum
= ifdev
->if_ipaddr
& ifdev
->if_netmask
;
471 ifdev
->ipaddr
= (ipaddr_t
)htonl(ifdev
->if_ipaddr
);
478 struct rarpdev
*rdev
= buf
;
483 size_t anslen
= rdev
->ifrarplen
;
487 if (((shost
= malloc(rdev
->physaddrlen
)) == NULL
) ||
488 ((ans
= malloc(rdev
->ifrarplen
)) == NULL
))
492 str
= _link_ntoa(rdev
->physaddr
, str
, rdev
->physaddrlen
,
495 debug("starting rarp service on device %s%d physical"
496 " address %s", rdev
->device
, rdev
->unit
, str
);
502 * Read RARP packets and respond to them.
505 saddrlen
= DLPI_PHYSADDR_MAX
;
506 retval
= dlpi_recv(rdev
->dh_rarp
, shost
,
507 &saddrlen
, ans
, &anslen
, -1, NULL
);
508 if (retval
== DLPI_ETIMEDOUT
) {
510 } else if (retval
!= DLPI_SUCCESS
) {
511 error("error in dlpi_recv %s: %s", rdev
->dh_rarp
,
512 dlpi_strerror(retval
));
517 if (anslen
< rdev
->ifrarplen
)
518 cause
= "short packet";
519 else if (ans
->ar_hrd
!= htons(ARPHRD_ETHER
))
520 cause
= "hardware type not Ethernet";
521 else if (ans
->ar_pro
!= htons(ETHERTYPE_IP
))
522 cause
= "protocol type not IP";
523 else if (ans
->ar_hln
!= rdev
->physaddrlen
)
524 cause
= "unexpected hardware address length";
525 else if (ans
->ar_pln
!= sizeof (ipaddr_t
))
526 cause
= "unexpected protocol address length";
529 debug("RARP packet received but "
530 "discarded: %s", cause
);
535 * Handle the request.
537 switch (ntohs(ans
->ar_op
)) {
539 rarp_request(rdev
, ans
, shost
);
543 arp_request(rdev
, ans
, shost
);
548 debug("REVARP_REPLY ignored");
553 debug("ARPOP_REPLY ignored");
558 debug("unknown opcode 0x%x", ans
->ar_op
);
565 * Reverse address determination and allocation code.
568 rarp_request(struct rarpdev
*rdev
, struct arphdr
*rp
, uchar_t
*shost
)
571 struct rarpreply
*rrp
;
572 uchar_t
*shap
, *thap
, *spap
, *tpap
;
576 shap
= (uchar_t
*)rp
+ sizeof (struct arphdr
);
577 spap
= shap
+ rp
->ar_hln
;
578 thap
= spap
+ rp
->ar_pln
;
579 tpap
= thap
+ rp
->ar_hln
;
582 str
= _link_ntoa(thap
, str
, rdev
->physaddrlen
, IFT_OTHER
);
584 debug("RARP_REQUEST for %s", str
);
590 * Third party lookups are rare and wonderful.
592 if ((memcmp(shap
, thap
, rdev
->physaddrlen
) != 0) ||
593 (memcmp(shap
, shost
, rdev
->physaddrlen
) != 0)) {
595 debug("weird (3rd party lookup)");
599 * Fill in given parts of reply packet.
601 (void) memcpy(shap
, rdev
->physaddr
, rdev
->physaddrlen
);
604 * If a good address is stored in our lookup tables, return it
605 * immediately or after a delay. Store it in our kernel's ARP cache.
607 if (get_ipaddr(rdev
, thap
, tpap
, &spa
))
609 (void) memcpy(spap
, &spa
, sizeof (spa
));
611 add_arp(rdev
, tpap
, thap
);
613 rp
->ar_op
= htons(REVARP_REPLY
);
618 (void) memcpy(&addr
, tpap
, sizeof (ipaddr_t
));
619 debug("good lookup, maps to %s", inet_ntoa(addr
));
622 rrp
= calloc(1, sizeof (struct rarpreply
) + rdev
->physaddrlen
+
625 error("out of memory");
626 rrp
->lldest
= (uchar_t
*)rrp
+ sizeof (struct rarpreply
);
627 rrp
->arprep
= rrp
->lldest
+ rdev
->physaddrlen
;
630 * Create rarpreply structure.
632 (void) gettimeofday(&rrp
->tv
, NULL
);
633 rrp
->tv
.tv_sec
+= 3; /* delay */
635 (void) memcpy(rrp
->lldest
, shost
, rdev
->physaddrlen
);
636 (void) memcpy(rrp
->arprep
, rp
, rdev
->ifrarplen
);
639 * If this is diskless and we're not its bootserver, let the
640 * bootserver reply first by delaying a while.
642 (void) memcpy(&tpa
, tpap
, sizeof (ipaddr_t
));
643 if (mightboot(ntohl(tpa
))) {
644 retval
= dlpi_send(rdev
->dh_rarp
, rrp
->lldest
,
645 rdev
->physaddrlen
, rrp
->arprep
, rdev
->ifrarplen
, NULL
);
646 if (retval
!= DLPI_SUCCESS
) {
647 error("dlpi_send failed: %s", dlpi_strerror(retval
));
649 debug("immediate reply sent");
653 delay_write(rdev
, rrp
);
658 * Download an ARP entry into our kernel.
661 add_arp(struct rarpdev
*rdev
, uchar_t
*ip
, uchar_t
*laddr
)
664 struct sockaddr_in
*sin
;
668 * Common part of query or set.
670 (void) memset(&ar
, 0, sizeof (ar
));
671 ar
.xarp_pa
.ss_family
= AF_INET
;
672 sin
= (struct sockaddr_in
*)&ar
.xarp_pa
;
673 (void) memcpy(&sin
->sin_addr
, ip
, sizeof (ipaddr_t
));
676 * Open the IP provider.
678 if ((fd
= open(DEVARP
, O_RDONLY
)) < 0)
684 (void) memcpy(LLADDR(&ar
.xarp_ha
), laddr
, rdev
->physaddrlen
);
685 ar
.xarp_ha
.sdl_alen
= rdev
->physaddrlen
;
686 ar
.xarp_ha
.sdl_family
= AF_LINK
;
687 (void) strioctl(fd
, SIOCDXARP
, -1, sizeof (struct xarpreq
),
689 if (strioctl(fd
, SIOCSXARP
, -1, sizeof (struct xarpreq
),
697 * The RARP spec says we must be able to process ARP requests,
698 * even through the packet type is RARP. Let's hope this feature
699 * is not heavily used.
702 arp_request(struct rarpdev
*rdev
, struct arphdr
*rp
, uchar_t
*shost
)
704 struct rarpreply
*rrp
;
706 uchar_t
*shap
, *thap
, *spap
, *tpap
;
709 shap
= (uchar_t
*)rp
+ sizeof (struct arphdr
);
710 spap
= shap
+ rp
->ar_hln
;
711 thap
= spap
+ rp
->ar_pln
;
712 tpap
= thap
+ rp
->ar_hln
;
715 debug("ARPOP_REQUEST");
717 for (ifdev
= rdev
->ifdev
; ifdev
!= NULL
; ifdev
= ifdev
->next
) {
718 if (memcmp(&ifdev
->ipaddr
, tpap
, sizeof (ipaddr_t
)) == 0)
724 rp
->ar_op
= ARPOP_REPLY
;
725 (void) memcpy(shap
, rdev
->physaddr
, rdev
->physaddrlen
);
726 (void) memcpy(spap
, &ifdev
->ipaddr
, sizeof (ipaddr_t
));
727 (void) memcpy(thap
, rdev
->physaddr
, rdev
->physaddrlen
);
729 add_arp(rdev
, tpap
, thap
);
732 * Create rarp reply structure.
734 rrp
= calloc(1, sizeof (struct rarpreply
) + rdev
->physaddrlen
+
737 error("out of memory");
738 rrp
->lldest
= (uchar_t
*)rrp
+ sizeof (struct rarpreply
);
739 rrp
->arprep
= rrp
->lldest
+ rdev
->physaddrlen
;
742 (void) memcpy(rrp
->lldest
, shost
, rdev
->physaddrlen
);
743 (void) memcpy(rrp
->arprep
, rp
, rdev
->ifrarplen
);
745 retval
= dlpi_send(rdev
->dh_rarp
, rrp
->lldest
, rdev
->physaddrlen
,
746 rrp
->arprep
, rdev
->ifrarplen
, NULL
);
748 if (retval
!= DLPI_SUCCESS
)
749 error("dlpi_send failed: %s", dlpi_strerror(retval
));
754 do_delay_write(void *buf
)
757 struct rarpreply
*rrp
;
758 struct rarpdev
*rdev
;
762 if ((err
= sema_wait(&delay_sema
)) != 0) {
765 error("do_delay_write: sema_wait failed");
768 (void) mutex_lock(&delay_mutex
);
771 delay_list
= delay_list
->next
;
772 (void) mutex_unlock(&delay_mutex
);
774 (void) gettimeofday(&tv
, NULL
);
775 if (tv
.tv_sec
< rrp
->tv
.tv_sec
)
776 (void) sleep(rrp
->tv
.tv_sec
- tv
.tv_sec
);
778 err
= dlpi_send(rdev
->dh_rarp
, rrp
->lldest
, rdev
->physaddrlen
,
779 rrp
->arprep
, rdev
->ifrarplen
, NULL
);
780 if (err
!= DLPI_SUCCESS
)
781 error("dlpi_send failed: %s", dlpi_strerror(err
));
789 delay_write(struct rarpdev
*rdev
, struct rarpreply
*rrp
)
791 struct rarpreply
*trp
;
793 (void) mutex_lock(&delay_mutex
);
794 if (delay_list
== NULL
) {
798 while (trp
->next
!= NULL
)
802 (void) mutex_unlock(&delay_mutex
);
804 (void) sema_post(&delay_sema
);
808 * See if we have a TFTP boot file for this guy. Filenames in TFTP
809 * boot requests are of the form <ipaddr> for Sun-3's and of the form
810 * <ipaddr>.<arch> for all other architectures. Since we don't know
811 * the client's architecture, either format will do.
814 mightboot(ipaddr_t ipa
)
820 (void) snprintf(path
, sizeof (path
), "%s/%08X", BOOTDIR
, ipa
);
823 * Try a quick access() first.
825 if (access(path
, 0) == 0)
829 * Not there, do it the slow way by
830 * reading through the directory.
832 (void) sprintf(path
, "%08X", ipa
);
834 if (!(dirp
= opendir(BOOTDIR
)))
837 while ((dp
= readdir(dirp
)) != NULL
) {
838 if (strncmp(dp
->d_name
, path
, 8) != 0)
840 if ((strlen(dp
->d_name
) != 8) && (dp
->d_name
[8] != '.'))
845 (void) closedir(dirp
);
847 return ((dp
!= NULL
) ? 1 : 0);
851 * Get our IP address and local netmask.
854 get_ifdata(char *dev
, int unit
, ipaddr_t
*ipp
, ipaddr_t
*maskp
)
858 struct sockaddr_in
*sin
;
861 sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
864 * Open the IP provider.
866 if ((fd
= open(DEVIP
, O_RDONLY
)) < 0)
870 * Ask IP for our IP address.
872 (void) snprintf(ifr
.ifr_name
, sizeof (ifr
.ifr_name
), "%s%d", dev
, unit
);
873 if (strioctl(fd
, SIOCGIFADDR
, -1, sizeof (struct ifreq
),
875 syserr("SIOCGIFADDR");
876 *ipp
= (ipaddr_t
)ntohl(sin
->sin_addr
.s_addr
);
879 debug("device %s%d address %s", dev
, unit
,
880 inet_ntoa(sin
->sin_addr
));
883 * Ask IP for our netmask.
885 if (strioctl(fd
, SIOCGIFNETMASK
, -1, sizeof (struct ifreq
),
887 syserr("SIOCGIFNETMASK");
888 *maskp
= (ipaddr_t
)ntohl(sin
->sin_addr
.s_addr
);
891 debug("device %s%d subnet mask %s", dev
, unit
,
892 inet_ntoa(sin
->sin_addr
));
901 * Translate mac address to IP address.
902 * Return 0 on success, nonzero on failure.
905 get_ipaddr(struct rarpdev
*rdev
, uchar_t
*laddr
, uchar_t
*ipp
, ipaddr_t
*ipaddr
)
908 char hbuffer
[BUFSIZE
];
909 struct hostent
*hp
, res
;
915 if (rdev
->physaddrlen
!= ETHERADDRL
) {
917 debug("%s %s", " cannot map non 6 byte hardware ",
918 "address to IP address");
923 * Translate mac address to hostname and IP address.
925 if (ether_ntohost(host
, (struct ether_addr
*)laddr
) != 0 ||
926 !(hp
= gethostbyname_r(host
, &res
, hbuffer
, sizeof (hbuffer
),
928 hp
->h_addrtype
!= AF_INET
|| hp
->h_length
!= sizeof (ipaddr_t
)) {
930 debug("could not map hardware address to IP address");
935 * Find the IP address on the right net.
937 for (p
= hp
->h_addr_list
; *p
; p
++) {
938 (void) memcpy(&addr
, *p
, sizeof (ipaddr_t
));
939 for (ifdev
= rdev
->ifdev
; ifdev
!= NULL
; ifdev
= ifdev
->next
) {
941 struct in_addr daddr
;
944 netnum
= htonl(ifdev
->if_netnum
);
945 (void) memcpy(&daddr
, &netnum
,
947 if (ifdev
->lunit
== -1)
948 debug("trying physical netnum %s"
949 " mask %x", inet_ntoa(daddr
),
952 debug("trying logical %d netnum %s"
953 " mask %x", ifdev
->lunit
,
957 if ((ntohl(addr
.s_addr
) & ifdev
->if_netmask
) ==
960 * Return the correct IP address.
962 (void) memcpy(ipp
, &addr
, sizeof (ipaddr_t
));
965 * Return the interface's ipaddr
967 (void) memcpy(ipaddr
, &ifdev
->ipaddr
,
976 debug("got host entry but no IP address on this net");
981 strioctl(int fd
, int cmd
, int timout
, int len
, char *dp
)
986 si
.ic_timout
= timout
;
989 return (ioctl(fd
, I_STR
, &si
));
995 error("Usage: %s [ -ad ] device unit", cmdname
);
999 syserr(const char *s
)
1004 (void) snprintf(buf
, sizeof (buf
), "%s: %s", s
, strerror(errno
));
1005 (void) fprintf(stderr
, "%s: %s\n", cmdname
, buf
);
1006 syslog(LOG_ERR
, "%s", buf
);
1011 error(const char *fmt
, ...)
1018 (void) vsprintf(buf
, fmt
, ap
);
1020 (void) fprintf(stderr
, "%s: %s\n", cmdname
, buf
);
1021 syslog(LOG_ERR
, buf
);
1027 debug(char *fmt
, ...)
1031 (void) mutex_lock(&debug_mutex
);
1033 (void) fprintf(stderr
, "%s:[%u] ", cmdname
, thr_self());
1034 (void) vfprintf(stderr
, fmt
, ap
);
1035 (void) fprintf(stderr
, "\n");
1037 (void) mutex_unlock(&debug_mutex
);