1171831Skan/*
2171831Skan
3171831SkanThis code is not copyright, and is placed in the public domain. Feel free to
4171831Skanuse and modify. Please send modifications and/or suggestions + bug fixes to
5169695Skan
6169695Skan        Klas Heggemann <klas@nada.kth.se>
7169695Skan
8169695Skan*/
9169695Skan
10169695Skan#ifndef lint
11169695Skanstatic const char rcsid[] =
12169695Skan  "$FreeBSD$";
13169695Skan#endif /* not lint */
14169695Skan
15169695Skan#include "bootparam_prot.h"
16169695Skan#include <rpc/rpc.h>
17169695Skan#include <sys/types.h>
18169695Skan#include <sys/socket.h>
19169695Skan#include <netinet/in.h>
20169695Skan#include <arpa/inet.h>
21169695Skan#include <err.h>
22169695Skan#include <netdb.h>
23169695Skan#include <stdlib.h>
24169695Skan
25169695Skan
26169695Skan/* #define bp_address_u bp_address */
27169695Skan#include <stdio.h>
28169695Skan#include <string.h>
29169695Skan
30169695Skanint broadcast;
31169695Skan
32169695Skanchar cln[MAX_MACHINE_NAME+1];
33169695Skanchar dmn[MAX_MACHINE_NAME+1];
34169695Skanchar path[MAX_PATH_LEN+1];
35169695Skanextern char *inet_ntoa();
36169695Skanstatic void usage(void);
37169695Skanint printgetfile(bp_getfile_res *);
38169695Skanint printwhoami(bp_whoami_res *);
39169695Skan
40169695Skanbool_t
41169695Skaneachres_whoami(resultp, raddr)
42169695Skanbp_whoami_res *resultp;
43169695Skanstruct sockaddr_in *raddr;
44169695Skan{
45169695Skan  struct hostent *he;
46169695Skan
47169695Skan  he = gethostbyaddr((char *)&raddr->sin_addr.s_addr,4,AF_INET);
48169695Skan  printf("%s answered:\n", he ? he->h_name : inet_ntoa(raddr->sin_addr));
49169695Skan  printwhoami(resultp);
50169695Skan  printf("\n");
51169695Skan  return(0);
52169695Skan}
53169695Skan
54169695Skanbool_t
55169695Skaneachres_getfile(resultp, raddr)
56169695Skanbp_getfile_res *resultp;
57169695Skanstruct sockaddr_in *raddr;
58169695Skan{
59169695Skan  struct hostent *he;
60169695Skan
61169695Skan  he = gethostbyaddr((char *)&raddr->sin_addr.s_addr,4,AF_INET);
62169695Skan  printf("%s answered:\n", he ? he->h_name : inet_ntoa(raddr->sin_addr));
63169695Skan  printgetfile(resultp);
64169695Skan  printf("\n");
65169695Skan  return(0);
66169695Skan}
67169695Skan
68169695Skan
69169695Skanint
70169695Skanmain(argc, argv)
71169695Skanint argc;
72169695Skanchar **argv;
73169695Skan{
74169695Skan  char *server;
75169695Skan
76169695Skan  bp_whoami_arg whoami_arg;
77169695Skan  bp_whoami_res *whoami_res, stat_whoami_res;
78169695Skan  bp_getfile_arg getfile_arg;
79169695Skan  bp_getfile_res *getfile_res, stat_getfile_res;
80169695Skan
81169695Skan
82169695Skan  long the_inet_addr;
83169695Skan  CLIENT *clnt;
84169695Skan
85169695Skan  stat_whoami_res.client_name = cln;
86169695Skan  stat_whoami_res.domain_name = dmn;
87169695Skan
88169695Skan  stat_getfile_res.server_name = cln;
89169695Skan  stat_getfile_res.server_path = path;
90169695Skan
91169695Skan  if (argc < 3)
92169695Skan    usage();
93169695Skan
94169695Skan  server = argv[1];
95169695Skan  if ( ! strcmp(server , "all") ) broadcast = 1;
96169695Skan
97169695Skan  if ( ! broadcast ) {
98169695Skan    clnt = clnt_create(server,BOOTPARAMPROG, BOOTPARAMVERS, "udp");
99169695Skan    if ( clnt == NULL )
100169695Skan      errx(1, "could not contact bootparam server on host %s", server);
101169695Skan  }
102169695Skan
103169695Skan  switch (argc) {
104169695Skan  case 3:
105169695Skan    whoami_arg.client_address.address_type = IP_ADDR_TYPE;
106169695Skan    the_inet_addr = inet_addr(argv[2]);
107169695Skan    if ( the_inet_addr == -1)
108169695Skan      errx(2, "bogus addr %s", argv[2]);
109169695Skan    bcopy(&the_inet_addr,&whoami_arg.client_address.bp_address_u.ip_addr,4);
110169695Skan
111169695Skan    if (! broadcast ) {
112169695Skan      whoami_res = bootparamproc_whoami_1(&whoami_arg, clnt);
113169695Skan      printf("Whoami returning:\n");
114169695Skan      if (printwhoami(whoami_res)) {
115169695Skan	errx(1, "bad answer returned from server %s", server);
116169695Skan      } else
117169695Skan	exit(0);
118169695Skan     } else {
119169695Skan       (void)clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS,
120169695Skan			       BOOTPARAMPROC_WHOAMI,
121169695Skan			       (xdrproc_t)xdr_bp_whoami_arg,
122169695Skan			       (char *)&whoami_arg,
123169695Skan			       (xdrproc_t)xdr_bp_whoami_res,
124169695Skan			       (char *)&stat_whoami_res,
125169695Skan			       (resultproc_t)eachres_whoami);
126169695Skan       exit(0);
127169695Skan     }
128169695Skan
129169695Skan  case 4:
130169695Skan
131169695Skan    getfile_arg.client_name = argv[2];
132169695Skan    getfile_arg.file_id = argv[3];
133169695Skan
134169695Skan    if (! broadcast ) {
135169695Skan      getfile_res = bootparamproc_getfile_1(&getfile_arg,clnt);
136169695Skan      printf("getfile returning:\n");
137169695Skan      if (printgetfile(getfile_res)) {
138169695Skan	errx(1, "bad answer returned from server %s", server);
139169695Skan      } else
140169695Skan	exit(0);
141169695Skan    } else {
142169695Skan      (void)clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS,
143169695Skan			       BOOTPARAMPROC_GETFILE,
144169695Skan			       (xdrproc_t)xdr_bp_getfile_arg,
145169695Skan			       (char *)&getfile_arg,
146169695Skan			       (xdrproc_t)xdr_bp_getfile_res,
147169695Skan			       (char *)&stat_getfile_res,
148169695Skan			       (resultproc_t)eachres_getfile);
149169695Skan      exit(0);
150169695Skan    }
151169695Skan
152169695Skan  default:
153169695Skan
154169695Skan    usage();
155169695Skan  }
156169695Skan
157169695Skan}
158169695Skan
159169695Skan
160169695Skanstatic void
161169695Skanusage()
162169695Skan{
163169695Skan	fprintf(stderr,
164169695Skan		"usage: callbootd server procnum (IP-addr | host fileid)\n");
165169695Skan    exit(1);
166169695Skan}
167169695Skan
168169695Skanint
169169695Skanprintwhoami(res)
170169695Skanbp_whoami_res *res;
171169695Skan{
172169695Skan      if ( res) {
173169695Skan	printf("client_name:\t%s\ndomain_name:\t%s\n",
174169695Skan	     res->client_name, res->domain_name);
175169695Skan	printf("router:\t%d.%d.%d.%d\n",
176169695Skan	     255 &  res->router_address.bp_address_u.ip_addr.net,
177169695Skan	     255 & res->router_address.bp_address_u.ip_addr.host,
178169695Skan	     255 &  res->router_address.bp_address_u.ip_addr.lh,
179169695Skan	     255 & res->router_address.bp_address_u.ip_addr.impno);
180169695Skan	return(0);
181169695Skan      } else {
182169695Skan	warnx("null answer!!!");
183169695Skan	return(1);
184169695Skan      }
185169695Skan    }
186169695Skan
187169695Skan
188169695Skan
189169695Skan
190169695Skanint
191169695Skanprintgetfile(res)
192169695Skanbp_getfile_res *res;
193169695Skan{
194169695Skan      if (res) {
195169695Skan	printf("server_name:\t%s\nserver_address:\t%s\npath:\t%s\n",
196169695Skan	       res->server_name,
197169695Skan	       inet_ntoa(*(struct in_addr *)&res->server_address.bp_address_u.ip_addr),
198169695Skan	       res->server_path);
199169695Skan	return(0);
200169695Skan      } else {
201169695Skan	warnx("null answer!!!");
202169695Skan	return(1);
203169695Skan      }
204169695Skan    }
205169695Skan