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. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * @(#) Copyright (c) 1988, 1993 The Regents of the University of California. All rights reserved.
34 * @(#)hostname.c 8.1 (Berkeley) 5/31/93
35 * $FreeBSD: src/bin/hostname/hostname.c,v 1.10.2.1 2001/08/01 02:40:23 obrien Exp $
36 * $DragonFly: src/bin/hostname/hostname.c,v 1.13 2005/03/21 16:59:31 liamfoy Exp $
39 #include <sys/param.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
42 #include <sys/sysctl.h>
43 #include <sys/module.h>
44 #include <sys/linker.h>
46 #include <net/ethernet.h>
48 #include <net/if_var.h>
49 #include <net/if_dl.h>
50 #include <net/if_types.h>
51 #include <net/route.h>
52 #include <netinet/in.h>
61 #include <sys/types.h>
62 #include <netinet/in.h>
63 #include <arpa/inet.h>
67 #define HST_IF (1 << 0)
68 #define HST_IF_V6 (1 << 1)
69 #define HST_IF_V4 (1 << 2)
74 * Expand the compacted form of addresses as returned via the
75 * configuration read via sysctl().
76 * Lifted from getifaddrs(3)
79 static void rt_xaddrs(caddr_t
, caddr_t
, struct rt_addrinfo
*);
80 static void usage (void);
83 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
84 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
88 rt_xaddrs(caddr_t cp
, caddr_t cplim
, struct rt_addrinfo
*rtinfo
)
93 memset(rtinfo
->rti_info
, 0, sizeof(rtinfo
->rti_info
));
94 for (i
= 0; (i
< RTAX_MAX
) && (cp
< cplim
); i
++) {
95 if ((rtinfo
->rti_addrs
& (1 << i
)) == 0)
97 rtinfo
->rti_info
[i
] = sa
= (struct sockaddr
*)cp
;
103 main(int argc
, char **argv
)
105 int ch
, sflag
, rflag
, ret
, flag6
, iflag
;
107 char hostname
[MAXHOSTNAMELEN
];
108 char *srflag
, *siflag
;
115 char *buf
,*lim
,*next
,*p
;
117 struct sockaddr_dl
*sdl
;
118 struct rt_msghdr
*rtm
;
119 struct if_msghdr
*ifm
;
120 struct ifa_msghdr
*ifam
;
121 struct rt_addrinfo info
;
122 struct sockaddr_in
*sai
;
123 struct sockaddr_in6
*sai6
;
127 iflag
= sflag
= rflag
= 0;
131 while ((ch
= getopt(argc
, argv
, "46i:r:s")) != -1) {
141 silen
= strlen(siflag
);
167 if (rflag
&& (iflag
& HST_IF
))
170 if ((iflag
& HST_IF_V6
) && (iflag
& HST_IF_V4
))
173 if (!(iflag
& HST_IF
) && ((iflag
& HST_IF_V6
)||iflag
& HST_IF_V4
))
176 if (iflag
& HST_IF
) {
181 mib
[4] = NET_RT_IFLIST
;
187 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) < 0)
188 err(1, "sysctl: iflist-sysctl-estimate");
189 if ((buf
= malloc(needed
)) == NULL
)
190 err(1, "malloc failed");
191 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) < 0)
192 err(1, "sysctl: retrieval of interface table");
196 for (next
= buf
; next
< buf
+ needed
; next
+= rtm
->rtm_msglen
) {
197 rtm
= (struct rt_msghdr
*)(void *)next
;
198 if (rtm
->rtm_version
!= RTM_VERSION
)
200 switch (rtm
->rtm_type
) {
202 ifm
= (struct if_msghdr
*)(void *)rtm
;
204 if ((ifm
->ifm_addrs
& RTA_IFP
) == 0)
206 sdl
= (struct sockaddr_dl
*)(ifm
+ 1);
207 if (silen
!= sdl
->sdl_nlen
)
209 if (!strncmp(siflag
, sdl
->sdl_data
, silen
)) {
210 idx
= ifm
->ifm_index
;
214 ifam
= (struct ifa_msghdr
*)(void *)rtm
;
216 if (ifam
->ifam_index
== idx
) {
217 info
.rti_addrs
= ifam
->ifam_addrs
;
218 rt_xaddrs((char *)(ifam
+ 1),
219 ifam
->ifam_msglen
+ (char *)ifam
, &info
);
220 sai
= (struct sockaddr_in
*)info
.rti_info
[RTAX_IFA
];
222 if (iflag
& HST_IF_V6
) {
223 if (sai
->sin_family
== AF_INET6
) {
224 sai6
= (struct sockaddr_in6
*)info
.rti_info
[RTAX_IFA
];
225 hst
= gethostbyaddr((const char*)&sai6
->sin6_addr
,
226 sizeof(sai6
->sin6_addr
),AF_INET6
);
228 if (h_errno
== NETDB_SUCCESS
) {
234 if ((sai
->sin_family
== AF_INET
)) {
236 hst
= gethostbyaddr((const char*)&sai
->sin_addr
,
237 sizeof(sai
->sin_addr
),AF_INET
);
239 if (h_errno
== NETDB_SUCCESS
) {
253 errx(1,"interface not found");
255 errx(1, "ip not found on interface");
257 if (h_errno
== NETDB_SUCCESS
) {
258 if (sethostname(hst
->h_name
, (int)strlen(hst
->h_name
)))
259 err(1, "sethostname");
260 } else if (h_errno
== HOST_NOT_FOUND
) {
261 errx(1,"hostname not found");
263 herror("gethostbyaddr");
267 ret
= inet_pton(AF_INET
, srflag
, &ia
);
270 ret
= inet_pton(AF_INET6
, srflag
, &ia6
);
273 errx(1, "invalid ip address");
280 hst
= gethostbyaddr((const char*)&ia6
, sizeof(ia6
), AF_INET6
);
282 hst
= gethostbyaddr((const char*)&ia
, sizeof(ia
), AF_INET
);
284 if (h_errno
== HOST_NOT_FOUND
)
285 errx(1,"host not found\n");
288 if (sethostname(hst
->h_name
, (int)strlen(hst
->h_name
)))
289 err(1, "sethostname");
291 if (sethostname(*argv
, (int)strlen(*argv
)))
292 err(1, "sethostname");
294 if (gethostname(hostname
, (int)sizeof(hostname
)))
295 err(1, "gethostname");
296 if (sflag
&& (p
= strchr(hostname
, '.')))
298 printf("%s\n", hostname
);
306 fprintf(stderr
, "usage: hostname [-s] [name-of-host |"
307 " -r ip-address | -i interface [-4 | -6]]\n");