]> git.saurik.com Git - apple/network_cmds.git/blame - bootparams/bpwhoami.tproj/bpwhoami.c
network_cmds-76.tar.gz
[apple/network_cmds.git] / bootparams / bpwhoami.tproj / bpwhoami.c
CommitLineData
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
56void 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
73struct in_addr ip_address;
74struct in_addr net_mask;
75
76static __inline__
77u_long iptohl(struct in_addr ip)
78{
79 return (ntohl(ip.s_addr));
80}
81
82static __inline__ boolean_t
83in_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
92bool_t
93each_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
127static boolean_t
128getFirstInterface(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 */
202int
203bp_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
240int
241main(argc,argv)
242 int argc;
243 char *argv[];
244{
245 exit(bp_whoami());
246}