]>
Commit | Line | Data |
---|---|---|
b7080c8e A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights | |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.0 (the 'License'). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
13 | * | |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License." | |
21 | * | |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | /* | |
25 | * Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved | |
26 | * | |
27 | * bpwhoami.c | |
28 | * - do a bootparams whoami call and echo the results to stdout | |
29 | * | |
30 | * The output is of the form: | |
31 | * host_name=<hostname> | |
32 | * nis_domain=<nis domain name> | |
33 | * router=<router ip address> | |
34 | * server_name=<server host name> | |
35 | * server_ip_address=<server ip address> | |
36 | * | |
37 | * The program will exit with the following codes: | |
38 | * 0 Successfully retrieved info | |
39 | * 1 RPC timed out while attempting to retrieve info | |
40 | * 2 Unrecoverable error ie. don't bother trying to call again | |
41 | * | |
42 | * Modification History: | |
43 | * Aug 5, 1997 Dieter Siegund (dieter@apple.com) | |
44 | * - lifted code from the old hostname -AUTOMATIC- source | |
45 | */ | |
46 | ||
47 | ||
48 | #include <sys/param.h> | |
49 | ||
50 | #include <err.h> | |
51 | #include <stdio.h> | |
52 | #include <stdlib.h> | |
53 | #include <string.h> | |
54 | #include <unistd.h> | |
55 | ||
56 | void usage __P((void)); | |
57 | ||
58 | #include <netdb.h> | |
59 | #include <signal.h> | |
60 | #include <mach/boolean.h> | |
61 | #include <sys/types.h> | |
62 | #include <sys/file.h> | |
63 | #include <sys/fcntl.h> | |
64 | #include <sys/ioctl_compat.h> | |
65 | #include <sys/ioctl.h> | |
66 | #include <sys/socket.h> | |
67 | #include <sys/time.h> | |
68 | #include <net/if.h> | |
69 | #include <rpc/rpc.h> | |
70 | #include <arpa/inet.h> | |
71 | #include "bootparam_prot.h" | |
72 | ||
73 | struct in_addr ip_address; | |
74 | struct in_addr net_mask; | |
75 | ||
76 | static __inline__ | |
77 | u_long iptohl(struct in_addr ip) | |
78 | { | |
79 | return (ntohl(ip.s_addr)); | |
80 | } | |
81 | ||
82 | static __inline__ boolean_t | |
83 | in_subnet(struct in_addr netaddr, struct in_addr netmask, struct in_addr ip) | |
84 | { | |
85 | if ((iptohl(ip) & iptohl(netmask)) | |
86 | != (iptohl(netaddr) & iptohl(netmask))) { | |
87 | return (FALSE); | |
88 | } | |
89 | return (TRUE); | |
90 | } | |
91 | ||
92 | bool_t | |
93 | each_whoresult(result, from) | |
94 | bp_whoami_res *result; | |
95 | struct sockaddr_in *from; | |
96 | { | |
97 | if (result) { | |
98 | struct hostent * host; | |
99 | struct in_addr * router; | |
100 | ||
101 | /* | |
102 | * guard against bogus router replies by making sure | |
103 | * that the default router is on the same subnet | |
104 | */ | |
105 | router = (struct in_addr *) | |
106 | &result->router_address.bp_address_u.ip_addr; | |
107 | if (in_subnet(*router, net_mask, ip_address)) { | |
108 | if (result->client_name && result->client_name[0]) | |
109 | printf("host_name=%s\n", result->client_name); | |
110 | if (result->domain_name && result->domain_name[0]) | |
111 | printf("nis_domain=%s\n", result->domain_name); | |
112 | printf("router=%s\n", inet_ntoa(*router)); | |
113 | host = gethostbyaddr((char *) &from->sin_addr, | |
114 | sizeof (from->sin_addr), AF_INET); | |
115 | if (host) { | |
116 | printf("server_name=%s\n", host->h_name); | |
117 | } | |
118 | printf("server_ip_address=%s\n", inet_ntoa(from->sin_addr)); | |
119 | return(TRUE); | |
120 | } | |
121 | } | |
122 | return(FALSE); | |
123 | } | |
124 | ||
125 | #define MAX_IF 16 | |
126 | ||
127 | static boolean_t | |
128 | getFirstInterface(struct ifreq * ret_p) | |
129 | { | |
130 | struct ifconf ifconf; /* points to ifreq */ | |
131 | struct ifreq * ifreq = NULL; | |
132 | struct ifreq * ifrp; | |
133 | int size = sizeof(struct ifreq) * MAX_IF; | |
134 | int sockfd; | |
135 | ||
136 | if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | |
137 | fprintf(stderr, "bpwhoami: socket call failed\n"); | |
138 | return (FALSE); | |
139 | } | |
140 | ||
141 | while (1) { | |
142 | if (ifreq != NULL) | |
143 | ifreq = (struct ifreq *)realloc(ifreq, size); | |
144 | else | |
145 | ifreq = (struct ifreq *)malloc(size); | |
146 | ||
147 | if (ifreq == NULL) | |
148 | goto err; | |
149 | ||
150 | ifconf.ifc_len = size; | |
151 | ifconf.ifc_req = ifreq; | |
152 | if (ioctl(sockfd, SIOCGIFCONF, (caddr_t)&ifconf) < 0 | |
153 | || ifconf.ifc_len <= 0) { | |
154 | fprintf(stderr, "bpwhoami: ioctl SIOCGIFCONF failed\n"); | |
155 | goto err; | |
156 | } | |
157 | if ((ifconf.ifc_len + sizeof(struct ifreq)) < size) | |
158 | break; | |
159 | size *= 2; | |
160 | } | |
161 | #define IFR_NEXT(ifr) \ | |
162 | ((struct ifreq *) ((char *) (ifr) + sizeof(*(ifr)) + \ | |
163 | MAX(0, (int) (ifr)->ifr_addr.sa_len \ | |
164 | - (int) sizeof((ifr)->ifr_addr)))) | |
165 | for (ifrp = (struct ifreq *) ifconf.ifc_buf; | |
166 | (char *) ifrp < &ifconf.ifc_buf[ifconf.ifc_len]; | |
167 | ifrp = IFR_NEXT(ifrp)) { | |
168 | if (ifrp->ifr_addr.sa_family == AF_INET) { | |
169 | struct ifreq ifr; | |
170 | ||
171 | strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); | |
172 | if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) | |
173 | ; | |
174 | else if ((ifr.ifr_flags & IFF_LOOPBACK) | |
175 | || !(ifr.ifr_flags & IFF_UP)) | |
176 | ; | |
177 | else if (ioctl(sockfd, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) | |
178 | ; | |
179 | else { | |
180 | net_mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; | |
181 | *ret_p = *ifrp; | |
182 | close(sockfd); | |
183 | if (ifreq) | |
184 | free(ifreq); | |
185 | return (TRUE); | |
186 | } | |
187 | } | |
188 | } | |
189 | err: | |
190 | close(sockfd); | |
191 | if (ifreq) | |
192 | free(ifreq); | |
193 | return (FALSE); | |
194 | } | |
195 | ||
196 | /* | |
197 | * Routine: bp_whoami | |
198 | * Function: | |
199 | * Do a BOOTPARAMS WHOAMI RPC to find out hostname, domain, | |
200 | * bootparams server, default router. | |
201 | */ | |
202 | int | |
203 | bp_whoami() | |
204 | { | |
205 | extern enum clnt_stat clnt_broadcast(); | |
206 | struct ifreq ifr; | |
207 | struct sockaddr_in *sockin; | |
208 | enum clnt_stat stat; | |
209 | struct bp_whoami_arg who_arg; | |
210 | struct bp_whoami_res who_res; | |
211 | ||
212 | if (getFirstInterface(&ifr) == FALSE) | |
213 | return (2); | |
214 | ||
215 | sockin = (struct sockaddr_in *) &ifr.ifr_addr; | |
216 | ip_address = sockin->sin_addr; | |
217 | who_arg.client_address.bp_address_u.ip_addr = | |
218 | *((ip_addr_t *)&sockin->sin_addr); | |
219 | who_arg.client_address.address_type = IP_ADDR_TYPE; | |
220 | bzero(&who_res, sizeof (who_res)); | |
221 | ||
222 | /* | |
223 | * Broadcast the whoami. | |
224 | */ | |
225 | stat = clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS, | |
226 | BOOTPARAMPROC_WHOAMI, xdr_bp_whoami_arg, | |
227 | &who_arg, xdr_bp_whoami_res, &who_res, | |
228 | each_whoresult); | |
229 | ||
230 | if (stat == RPC_SUCCESS) { | |
231 | return (0); | |
232 | } | |
233 | if (stat == RPC_TIMEDOUT) | |
234 | return (1); | |
235 | fprintf(stderr, "bpwhoami: "); | |
236 | clnt_perrno(stat); | |
237 | return (2); | |
238 | } | |
239 | ||
240 | int | |
241 | main(argc,argv) | |
242 | int argc; | |
243 | char *argv[]; | |
244 | { | |
245 | exit(bp_whoami()); | |
246 | } |