1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino This code is not copyright, and is placed in the public domain. Feel free to
4*86d7f5d3SJohn Marino use and modify. Please send modifications and/or suggestions + bug fixes to
5*86d7f5d3SJohn Marino 
6*86d7f5d3SJohn Marino         Klas Heggemann <klas@nada.kth.se>
7*86d7f5d3SJohn Marino 
8*86d7f5d3SJohn Marino */
9*86d7f5d3SJohn Marino 
10*86d7f5d3SJohn Marino /*
11*86d7f5d3SJohn Marino  * $FreeBSD: src/usr.sbin/bootparamd/callbootd/callbootd.c,v 1.8 1999/08/28 01:15:40 peter Exp $
12*86d7f5d3SJohn Marino  * $DragonFly: src/usr.sbin/bootparamd/callbootd/callbootd.c,v 1.5 2007/11/25 01:28:24 swildner Exp $
13*86d7f5d3SJohn Marino  */
14*86d7f5d3SJohn Marino #include "bootparam_prot.h"
15*86d7f5d3SJohn Marino #include <rpc/rpc.h>
16*86d7f5d3SJohn Marino #include <sys/types.h>
17*86d7f5d3SJohn Marino #include <sys/socket.h>
18*86d7f5d3SJohn Marino #include <netinet/in.h>
19*86d7f5d3SJohn Marino #include <arpa/inet.h>
20*86d7f5d3SJohn Marino #include <err.h>
21*86d7f5d3SJohn Marino #include <netdb.h>
22*86d7f5d3SJohn Marino 
23*86d7f5d3SJohn Marino 
24*86d7f5d3SJohn Marino /* #define bp_address_u bp_address */
25*86d7f5d3SJohn Marino #include <stdio.h>
26*86d7f5d3SJohn Marino #include <stdlib.h>
27*86d7f5d3SJohn Marino #include <string.h>
28*86d7f5d3SJohn Marino 
29*86d7f5d3SJohn Marino int broadcast;
30*86d7f5d3SJohn Marino 
31*86d7f5d3SJohn Marino char cln[MAX_MACHINE_NAME+1];
32*86d7f5d3SJohn Marino char dmn[MAX_MACHINE_NAME+1];
33*86d7f5d3SJohn Marino char path[MAX_PATH_LEN+1];
34*86d7f5d3SJohn Marino extern char *inet_ntoa();
35*86d7f5d3SJohn Marino static void usage(void);
36*86d7f5d3SJohn Marino int printgetfile(bp_getfile_res *);
37*86d7f5d3SJohn Marino int printwhoami(bp_whoami_res *);
38*86d7f5d3SJohn Marino 
39*86d7f5d3SJohn Marino int
eachres_whoami(bp_whoami_res * resultp,struct sockaddr_in * raddr)40*86d7f5d3SJohn Marino eachres_whoami(bp_whoami_res *resultp, struct sockaddr_in *raddr)
41*86d7f5d3SJohn Marino {
42*86d7f5d3SJohn Marino   struct hostent *he;
43*86d7f5d3SJohn Marino 
44*86d7f5d3SJohn Marino   he = gethostbyaddr(&raddr->sin_addr.s_addr,4,AF_INET);
45*86d7f5d3SJohn Marino   printf("%s answered:\n", he ? he->h_name : inet_ntoa(raddr->sin_addr));
46*86d7f5d3SJohn Marino   printwhoami(resultp);
47*86d7f5d3SJohn Marino   printf("\n");
48*86d7f5d3SJohn Marino   return(0);
49*86d7f5d3SJohn Marino }
50*86d7f5d3SJohn Marino 
51*86d7f5d3SJohn Marino bool_t
eachres_getfile(bp_getfile_res * resultp,struct sockaddr_in * raddr)52*86d7f5d3SJohn Marino eachres_getfile(bp_getfile_res *resultp, struct sockaddr_in *raddr)
53*86d7f5d3SJohn Marino {
54*86d7f5d3SJohn Marino   struct hostent *he;
55*86d7f5d3SJohn Marino 
56*86d7f5d3SJohn Marino   he = gethostbyaddr(&raddr->sin_addr.s_addr,4,AF_INET);
57*86d7f5d3SJohn Marino   printf("%s answered:\n", he ? he->h_name : inet_ntoa(raddr->sin_addr));
58*86d7f5d3SJohn Marino   printgetfile(resultp);
59*86d7f5d3SJohn Marino   printf("\n");
60*86d7f5d3SJohn Marino   return(0);
61*86d7f5d3SJohn Marino }
62*86d7f5d3SJohn Marino 
63*86d7f5d3SJohn Marino 
64*86d7f5d3SJohn Marino int
main(int argc,char ** argv)65*86d7f5d3SJohn Marino main(int argc, char **argv)
66*86d7f5d3SJohn Marino {
67*86d7f5d3SJohn Marino   char *server;
68*86d7f5d3SJohn Marino 
69*86d7f5d3SJohn Marino   bp_whoami_arg whoami_arg;
70*86d7f5d3SJohn Marino   bp_whoami_res *whoami_res, stat_whoami_res;
71*86d7f5d3SJohn Marino   bp_getfile_arg getfile_arg;
72*86d7f5d3SJohn Marino   bp_getfile_res *getfile_res, stat_getfile_res;
73*86d7f5d3SJohn Marino 
74*86d7f5d3SJohn Marino 
75*86d7f5d3SJohn Marino   long the_inet_addr;
76*86d7f5d3SJohn Marino   CLIENT *clnt;
77*86d7f5d3SJohn Marino   enum clnt_stat clnt_stat;
78*86d7f5d3SJohn Marino 
79*86d7f5d3SJohn Marino   stat_whoami_res.client_name = cln;
80*86d7f5d3SJohn Marino   stat_whoami_res.domain_name = dmn;
81*86d7f5d3SJohn Marino 
82*86d7f5d3SJohn Marino   stat_getfile_res.server_name = cln;
83*86d7f5d3SJohn Marino   stat_getfile_res.server_path = path;
84*86d7f5d3SJohn Marino 
85*86d7f5d3SJohn Marino   if (argc < 3)
86*86d7f5d3SJohn Marino     usage();
87*86d7f5d3SJohn Marino 
88*86d7f5d3SJohn Marino   server = argv[1];
89*86d7f5d3SJohn Marino   if ( ! strcmp(server , "all") ) broadcast = 1;
90*86d7f5d3SJohn Marino 
91*86d7f5d3SJohn Marino   if ( ! broadcast ) {
92*86d7f5d3SJohn Marino     clnt = clnt_create(server,BOOTPARAMPROG, BOOTPARAMVERS, "udp");
93*86d7f5d3SJohn Marino   }
94*86d7f5d3SJohn Marino 
95*86d7f5d3SJohn Marino   if ( clnt == NULL )
96*86d7f5d3SJohn Marino      errx(1, "could not contact bootparam server on host %s", server);
97*86d7f5d3SJohn Marino 
98*86d7f5d3SJohn Marino   switch (argc) {
99*86d7f5d3SJohn Marino   case 3:
100*86d7f5d3SJohn Marino     whoami_arg.client_address.address_type = IP_ADDR_TYPE;
101*86d7f5d3SJohn Marino     the_inet_addr = inet_addr(argv[2]);
102*86d7f5d3SJohn Marino     if ( the_inet_addr == -1)
103*86d7f5d3SJohn Marino       errx(2, "bogus addr %s", argv[2]);
104*86d7f5d3SJohn Marino     bcopy(&the_inet_addr,&whoami_arg.client_address.bp_address_u.ip_addr,4);
105*86d7f5d3SJohn Marino 
106*86d7f5d3SJohn Marino     if (! broadcast ) {
107*86d7f5d3SJohn Marino       whoami_res = bootparamproc_whoami_1(&whoami_arg, clnt);
108*86d7f5d3SJohn Marino       printf("Whoami returning:\n");
109*86d7f5d3SJohn Marino       if (printwhoami(whoami_res)) {
110*86d7f5d3SJohn Marino 	errx(1, "bad answer returned from server %s", server);
111*86d7f5d3SJohn Marino       } else
112*86d7f5d3SJohn Marino 	exit(0);
113*86d7f5d3SJohn Marino      } else {
114*86d7f5d3SJohn Marino        clnt_stat=clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS,
115*86d7f5d3SJohn Marino 			       BOOTPARAMPROC_WHOAMI,
116*86d7f5d3SJohn Marino 			       (xdrproc_t)xdr_bp_whoami_arg, &whoami_arg,
117*86d7f5d3SJohn Marino 			       (xdrproc_t)xdr_bp_whoami_res, &stat_whoami_res,
118*86d7f5d3SJohn Marino 			       (resultproc_t)eachres_whoami);
119*86d7f5d3SJohn Marino        exit(0);
120*86d7f5d3SJohn Marino      }
121*86d7f5d3SJohn Marino 
122*86d7f5d3SJohn Marino   case 4:
123*86d7f5d3SJohn Marino 
124*86d7f5d3SJohn Marino     getfile_arg.client_name = argv[2];
125*86d7f5d3SJohn Marino     getfile_arg.file_id = argv[3];
126*86d7f5d3SJohn Marino 
127*86d7f5d3SJohn Marino     if (! broadcast ) {
128*86d7f5d3SJohn Marino       getfile_res = bootparamproc_getfile_1(&getfile_arg,clnt);
129*86d7f5d3SJohn Marino       printf("getfile returning:\n");
130*86d7f5d3SJohn Marino       if (printgetfile(getfile_res)) {
131*86d7f5d3SJohn Marino 	errx(1, "bad answer returned from server %s", server);
132*86d7f5d3SJohn Marino       } else
133*86d7f5d3SJohn Marino 	exit(0);
134*86d7f5d3SJohn Marino     } else {
135*86d7f5d3SJohn Marino       clnt_stat=clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS,
136*86d7f5d3SJohn Marino 			       BOOTPARAMPROC_GETFILE,
137*86d7f5d3SJohn Marino 			       (xdrproc_t)xdr_bp_getfile_arg, &getfile_arg,
138*86d7f5d3SJohn Marino 			       (xdrproc_t)xdr_bp_getfile_res, &stat_getfile_res,
139*86d7f5d3SJohn Marino 			       (resultproc_t)eachres_getfile);
140*86d7f5d3SJohn Marino       exit(0);
141*86d7f5d3SJohn Marino     }
142*86d7f5d3SJohn Marino 
143*86d7f5d3SJohn Marino   default:
144*86d7f5d3SJohn Marino 
145*86d7f5d3SJohn Marino     usage();
146*86d7f5d3SJohn Marino   }
147*86d7f5d3SJohn Marino 
148*86d7f5d3SJohn Marino }
149*86d7f5d3SJohn Marino 
150*86d7f5d3SJohn Marino 
151*86d7f5d3SJohn Marino static void
usage(void)152*86d7f5d3SJohn Marino usage(void)
153*86d7f5d3SJohn Marino {
154*86d7f5d3SJohn Marino 	fprintf(stderr,
155*86d7f5d3SJohn Marino 		"usage: callbootd server procnum (IP-addr | host fileid)\n");
156*86d7f5d3SJohn Marino     exit(1);
157*86d7f5d3SJohn Marino }
158*86d7f5d3SJohn Marino 
159*86d7f5d3SJohn Marino int
printwhoami(bp_whoami_res * res)160*86d7f5d3SJohn Marino printwhoami(bp_whoami_res *res)
161*86d7f5d3SJohn Marino {
162*86d7f5d3SJohn Marino       if ( res) {
163*86d7f5d3SJohn Marino 	printf("client_name:\t%s\ndomain_name:\t%s\n",
164*86d7f5d3SJohn Marino 	     res->client_name, res->domain_name);
165*86d7f5d3SJohn Marino 	printf("router:\t%d.%d.%d.%d\n",
166*86d7f5d3SJohn Marino 	     255 &  res->router_address.bp_address_u.ip_addr.net,
167*86d7f5d3SJohn Marino 	     255 & res->router_address.bp_address_u.ip_addr.host,
168*86d7f5d3SJohn Marino 	     255 &  res->router_address.bp_address_u.ip_addr.lh,
169*86d7f5d3SJohn Marino 	     255 & res->router_address.bp_address_u.ip_addr.impno);
170*86d7f5d3SJohn Marino 	return(0);
171*86d7f5d3SJohn Marino       } else {
172*86d7f5d3SJohn Marino 	warnx("null answer!!!");
173*86d7f5d3SJohn Marino 	return(1);
174*86d7f5d3SJohn Marino       }
175*86d7f5d3SJohn Marino     }
176*86d7f5d3SJohn Marino 
177*86d7f5d3SJohn Marino 
178*86d7f5d3SJohn Marino 
179*86d7f5d3SJohn Marino 
180*86d7f5d3SJohn Marino int
printgetfile(bp_getfile_res * res)181*86d7f5d3SJohn Marino printgetfile(bp_getfile_res *res)
182*86d7f5d3SJohn Marino {
183*86d7f5d3SJohn Marino       if (res) {
184*86d7f5d3SJohn Marino 	printf("server_name:\t%s\nserver_address:\t%s\npath:\t%s\n",
185*86d7f5d3SJohn Marino 	       res->server_name,
186*86d7f5d3SJohn Marino 	       inet_ntoa(*(struct in_addr *)&res->server_address.bp_address_u.ip_addr),
187*86d7f5d3SJohn Marino 	       res->server_path);
188*86d7f5d3SJohn Marino 	return(0);
189*86d7f5d3SJohn Marino       } else {
190*86d7f5d3SJohn Marino 	warnx("null answer!!!");
191*86d7f5d3SJohn Marino 	return(1);
192*86d7f5d3SJohn Marino       }
193*86d7f5d3SJohn Marino     }
194