2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * @(#) Copyright (c) 1988, 1993 The Regents of the University of California. All rights reserved.
30 * @(#)hostname.c 8.1 (Berkeley) 5/31/93
31 * $FreeBSD: src/bin/hostname/hostname.c,v 1.10.2.1 2001/08/01 02:40:23 obrien Exp $
34 #include <sys/param.h>
35 #include <sys/ioctl.h>
36 #include <sys/socket.h>
37 #include <sys/sysctl.h>
38 #include <sys/module.h>
39 #include <sys/linker.h>
41 #include <net/ethernet.h>
43 #include <net/if_var.h>
44 #include <net/if_dl.h>
45 #include <net/if_types.h>
46 #include <net/route.h>
47 #include <netinet/in.h>
56 #include <sys/types.h>
57 #include <arpa/inet.h>
61 #define HST_IF (1 << 0)
62 #define HST_IF_V6 (1 << 1)
63 #define HST_IF_V4 (1 << 2)
66 * Expand the compacted form of addresses as returned via the
67 * configuration read via sysctl().
68 * Lifted from getifaddrs(3)
71 static void rt_xaddrs(caddr_t
, caddr_t
, struct rt_addrinfo
*);
72 static void usage (void);
75 #define RT_ROUNDUP(a) \
76 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
79 #define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len))
84 rt_xaddrs(caddr_t cp
, caddr_t cplim
, struct rt_addrinfo
*rtinfo
)
89 memset(rtinfo
->rti_info
, 0, sizeof(rtinfo
->rti_info
));
90 for (i
= 0; (i
< RTAX_MAX
) && (cp
< cplim
); i
++) {
91 if ((rtinfo
->rti_addrs
& (1 << i
)) == 0)
93 rtinfo
->rti_info
[i
] = sa
= (struct sockaddr
*)cp
;
99 main(int argc
, char **argv
)
101 int ch
, sflag
, rflag
, ret
, flag6
, iflag
;
103 char hostname
[MAXHOSTNAMELEN
];
104 char *srflag
, *siflag
;
111 char *buf
, *next
, *p
;
113 struct sockaddr_dl
*sdl
;
114 struct rt_msghdr
*rtm
;
115 struct if_msghdr
*ifm
;
116 struct ifa_msghdr
*ifam
;
117 struct rt_addrinfo info
;
118 struct sockaddr_in
*sai
;
119 struct sockaddr_in6
*sai6
;
123 iflag
= sflag
= rflag
= 0;
127 while ((ch
= getopt(argc
, argv
, "46i:r:s")) != -1) {
137 silen
= strlen(siflag
);
163 if (rflag
&& (iflag
& HST_IF
))
166 if ((iflag
& HST_IF_V6
) && (iflag
& HST_IF_V4
))
169 if (!(iflag
& HST_IF
) && ((iflag
& HST_IF_V6
)||iflag
& HST_IF_V4
))
172 if (iflag
& HST_IF
) {
177 mib
[4] = NET_RT_IFLIST
;
183 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) < 0)
184 err(1, "sysctl: iflist-sysctl-estimate");
185 if ((buf
= malloc(needed
)) == NULL
)
186 err(1, "malloc failed");
187 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) < 0)
188 err(1, "sysctl: retrieval of interface table");
190 for (next
= buf
; next
< buf
+ needed
; next
+= rtm
->rtm_msglen
) {
191 rtm
= (struct rt_msghdr
*)(void *)next
;
192 if (rtm
->rtm_version
!= RTM_VERSION
)
194 switch (rtm
->rtm_type
) {
196 ifm
= (struct if_msghdr
*)(void *)rtm
;
198 if ((ifm
->ifm_addrs
& RTA_IFP
) == 0)
200 sdl
= (struct sockaddr_dl
*)(ifm
+ 1);
201 if (silen
!= sdl
->sdl_nlen
)
203 if (!strncmp(siflag
, sdl
->sdl_data
, silen
)) {
204 idx
= ifm
->ifm_index
;
208 ifam
= (struct ifa_msghdr
*)(void *)rtm
;
210 if (ifam
->ifam_index
== idx
) {
211 info
.rti_addrs
= ifam
->ifam_addrs
;
212 rt_xaddrs((char *)(ifam
+ 1),
213 ifam
->ifam_msglen
+ (char *)ifam
, &info
);
214 sai
= (struct sockaddr_in
*)info
.rti_info
[RTAX_IFA
];
216 if (iflag
& HST_IF_V6
) {
217 if (sai
->sin_family
== AF_INET6
) {
218 sai6
= (struct sockaddr_in6
*)info
.rti_info
[RTAX_IFA
];
219 hst
= gethostbyaddr(&sai6
->sin6_addr
,
220 sizeof(sai6
->sin6_addr
),AF_INET6
);
222 if (h_errno
== NETDB_SUCCESS
) {
228 if ((sai
->sin_family
== AF_INET
)) {
230 hst
= gethostbyaddr(&sai
->sin_addr
,
231 sizeof(sai
->sin_addr
),AF_INET
);
233 if (h_errno
== NETDB_SUCCESS
) {
247 errx(1,"interface not found");
249 errx(1, "ip not found on interface");
251 if (h_errno
== NETDB_SUCCESS
) {
252 if (sethostname(hst
->h_name
, (int)strlen(hst
->h_name
)))
253 err(1, "sethostname");
254 } else if (h_errno
== HOST_NOT_FOUND
) {
255 errx(1,"hostname not found");
257 herror("gethostbyaddr");
261 ret
= inet_pton(AF_INET
, srflag
, &ia
);
264 ret
= inet_pton(AF_INET6
, srflag
, &ia6
);
267 errx(1, "invalid ip address");
274 hst
= gethostbyaddr(&ia6
, sizeof(ia6
), AF_INET6
);
276 hst
= gethostbyaddr(&ia
, sizeof(ia
), AF_INET
);
278 if (h_errno
== HOST_NOT_FOUND
)
279 errx(1,"host not found\n");
282 if (sethostname(hst
->h_name
, (int)strlen(hst
->h_name
)))
283 err(1, "sethostname");
285 if (sethostname(*argv
, (int)strlen(*argv
)))
286 err(1, "sethostname");
288 if (gethostname(hostname
, (int)sizeof(hostname
)))
289 err(1, "gethostname");
290 if (sflag
&& (p
= strchr(hostname
, '.')))
292 printf("%s\n", hostname
);
300 fprintf(stderr
, "usage: hostname [-s] [name-of-host |"
301 " -r ip-address | -i interface [-4 | -6]]\n");