Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/libexec/bootpd/dumptab.c
34856 views
1
/*
2
* dumptab.c - handles dumping the database
3
*/
4
5
#include <sys/types.h>
6
#include <netinet/in.h>
7
#include <arpa/inet.h> /* inet_ntoa */
8
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <strings.h>
12
#include <syslog.h>
13
#include <time.h>
14
15
#include "bootp.h"
16
#include "hash.h"
17
#include "hwaddr.h"
18
#include "report.h"
19
#include "patchlevel.h"
20
#include "bootpd.h"
21
22
#ifdef DEBUG
23
static void dump_generic(FILE *, struct shared_bindata *);
24
static void dump_host(FILE *, struct host *);
25
static void list_ipaddresses(FILE *, struct in_addr_list *);
26
#endif
27
28
#ifndef DEBUG
29
void
30
dumptab(char *filename)
31
{
32
report(LOG_INFO, "No dumptab support!");
33
}
34
35
#else /* DEBUG */
36
37
/*
38
* Dump the internal memory database to bootpd_dump.
39
*/
40
41
void
42
dumptab(char *filename)
43
{
44
int n;
45
struct host *hp;
46
FILE *fp;
47
time_t t;
48
/* Print symbols in alphabetical order for reader's convenience. */
49
static char legend[] = "#\n# Legend:\t(see bootptab.5)\n\
50
#\tfirst field -- hostname (not indented)\n\
51
#\tbf -- bootfile\n\
52
#\tbs -- bootfile size in 512-octet blocks\n\
53
#\tcs -- cookie servers\n\
54
#\tdf -- dump file name\n\
55
#\tdn -- domain name\n\
56
#\tds -- domain name servers\n\
57
#\tef -- extension file\n\
58
#\tex -- exec file (YORK_EX_OPTION)\n\
59
#\tgw -- gateways\n\
60
#\tha -- hardware address\n\
61
#\thd -- home directory for bootfiles\n\
62
#\thn -- host name set for client\n\
63
#\tht -- hardware type\n\
64
#\tim -- impress servers\n\
65
#\tip -- host IP address\n\
66
#\tlg -- log servers\n\
67
#\tlp -- LPR servers\n\
68
#\tms -- message size\n\
69
#\tmw -- min wait (secs)\n\
70
#\tns -- IEN-116 name servers\n\
71
#\tnt -- NTP servers (RFC 1129)\n\
72
#\tra -- reply address override\n\
73
#\trl -- resource location protocol servers\n\
74
#\trp -- root path\n\
75
#\tsa -- boot server address\n\
76
#\tsm -- subnet mask\n\
77
#\tsw -- swap server\n\
78
#\ttc -- template host (points to similar host entry)\n\
79
#\ttd -- TFTP directory\n\
80
#\tto -- time offset (seconds)\n\
81
#\tts -- time servers\n\
82
#\tvm -- vendor magic number\n\
83
#\tyd -- YP (NIS) domain\n\
84
#\tys -- YP (NIS) servers\n\
85
#\tTn -- generic option tag n\n\
86
\n";
87
88
/*
89
* Open bootpd.dump file.
90
*/
91
if ((fp = fopen(filename, "w")) == NULL) {
92
report(LOG_ERR, "error opening \"%s\": %s",
93
filename, get_errmsg());
94
exit(1);
95
}
96
t = time(NULL);
97
fprintf(fp, "\n# %s %s.%d\n", progname, VERSION, PATCHLEVEL);
98
fprintf(fp, "# %s: dump of bootp server database.\n", filename);
99
fprintf(fp, "# Dump taken %s", ctime(&t));
100
fwrite(legend, 1, sizeof(legend) - 1, fp);
101
102
n = 0;
103
for (hp = (struct host *) hash_FirstEntry(nmhashtable); hp != NULL;
104
hp = (struct host *) hash_NextEntry(nmhashtable)) {
105
dump_host(fp, hp);
106
fprintf(fp, "\n");
107
n++;
108
}
109
fclose(fp);
110
111
report(LOG_INFO, "dumped %d entries to \"%s\".", n, filename);
112
}
113
114
115
116
/*
117
* Dump all the available information on the host pointed to by "hp".
118
* The output is sent to the file pointed to by "fp".
119
*/
120
121
static void
122
dump_host(FILE *fp, struct host *hp)
123
{
124
/* Print symbols in alphabetical order for reader's convenience. */
125
if (hp) {
126
fprintf(fp, "%s:", (hp->hostname ?
127
hp->hostname->string : "?"));
128
if (hp->flags.bootfile) {
129
fprintf(fp, "\\\n\t:bf=%s:", hp->bootfile->string);
130
}
131
if (hp->flags.bootsize) {
132
fprintf(fp, "\\\n\t:bs=");
133
if (hp->flags.bootsize_auto) {
134
fprintf(fp, "auto:");
135
} else {
136
fprintf(fp, "%lu:", (u_long)hp->bootsize);
137
}
138
}
139
if (hp->flags.cookie_server) {
140
fprintf(fp, "\\\n\t:cs=");
141
list_ipaddresses(fp, hp->cookie_server);
142
fprintf(fp, ":");
143
}
144
if (hp->flags.dump_file) {
145
fprintf(fp, "\\\n\t:df=%s:", hp->dump_file->string);
146
}
147
if (hp->flags.domain_name) {
148
fprintf(fp, "\\\n\t:dn=%s:", hp->domain_name->string);
149
}
150
if (hp->flags.domain_server) {
151
fprintf(fp, "\\\n\t:ds=");
152
list_ipaddresses(fp, hp->domain_server);
153
fprintf(fp, ":");
154
}
155
if (hp->flags.exten_file) {
156
fprintf(fp, "\\\n\t:ef=%s:", hp->exten_file->string);
157
}
158
if (hp->flags.exec_file) {
159
fprintf(fp, "\\\n\t:ex=%s:", hp->exec_file->string);
160
}
161
if (hp->flags.gateway) {
162
fprintf(fp, "\\\n\t:gw=");
163
list_ipaddresses(fp, hp->gateway);
164
fprintf(fp, ":");
165
}
166
/* FdC: swap_server (see below) */
167
if (hp->flags.homedir) {
168
fprintf(fp, "\\\n\t:hd=%s:", hp->homedir->string);
169
}
170
/* FdC: dump_file (see above) */
171
/* FdC: domain_name (see above) */
172
/* FdC: root_path (see below) */
173
if (hp->flags.name_switch && hp->flags.send_name) {
174
fprintf(fp, "\\\n\t:hn:");
175
}
176
if (hp->flags.htype) {
177
int hlen = haddrlength(hp->htype);
178
fprintf(fp, "\\\n\t:ht=%u:", (unsigned) hp->htype);
179
if (hp->flags.haddr) {
180
fprintf(fp, "ha=\"%s\":",
181
haddrtoa(hp->haddr, hlen));
182
}
183
}
184
if (hp->flags.impress_server) {
185
fprintf(fp, "\\\n\t:im=");
186
list_ipaddresses(fp, hp->impress_server);
187
fprintf(fp, ":");
188
}
189
/* NetBSD: swap_server (see below) */
190
if (hp->flags.iaddr) {
191
fprintf(fp, "\\\n\t:ip=%s:", inet_ntoa(hp->iaddr));
192
}
193
if (hp->flags.log_server) {
194
fprintf(fp, "\\\n\t:lg=");
195
list_ipaddresses(fp, hp->log_server);
196
fprintf(fp, ":");
197
}
198
if (hp->flags.lpr_server) {
199
fprintf(fp, "\\\n\t:lp=");
200
list_ipaddresses(fp, hp->lpr_server);
201
fprintf(fp, ":");
202
}
203
if (hp->flags.msg_size) {
204
fprintf(fp, "\\\n\t:ms=%lu:", (u_long)hp->msg_size);
205
}
206
if (hp->flags.min_wait) {
207
fprintf(fp, "\\\n\t:mw=%lu:", (u_long)hp->min_wait);
208
}
209
if (hp->flags.name_server) {
210
fprintf(fp, "\\\n\t:ns=");
211
list_ipaddresses(fp, hp->name_server);
212
fprintf(fp, ":");
213
}
214
if (hp->flags.ntp_server) {
215
fprintf(fp, "\\\n\t:nt=");
216
list_ipaddresses(fp, hp->ntp_server);
217
fprintf(fp, ":");
218
}
219
if (hp->flags.reply_addr) {
220
fprintf(fp, "\\\n\t:ra=%s:", inet_ntoa(hp->reply_addr));
221
}
222
if (hp->flags.rlp_server) {
223
fprintf(fp, "\\\n\t:rl=");
224
list_ipaddresses(fp, hp->rlp_server);
225
fprintf(fp, ":");
226
}
227
if (hp->flags.root_path) {
228
fprintf(fp, "\\\n\t:rp=%s:", hp->root_path->string);
229
}
230
if (hp->flags.bootserver) {
231
fprintf(fp, "\\\n\t:sa=%s:", inet_ntoa(hp->bootserver));
232
}
233
if (hp->flags.subnet_mask) {
234
fprintf(fp, "\\\n\t:sm=%s:", inet_ntoa(hp->subnet_mask));
235
}
236
if (hp->flags.swap_server) {
237
fprintf(fp, "\\\n\t:sw=%s:", inet_ntoa(hp->subnet_mask));
238
}
239
if (hp->flags.tftpdir) {
240
fprintf(fp, "\\\n\t:td=%s:", hp->tftpdir->string);
241
}
242
/* NetBSD: rootpath (see above) */
243
/* NetBSD: domainname (see above) */
244
/* NetBSD: dumpfile (see above) */
245
if (hp->flags.time_offset) {
246
fprintf(fp, "\\\n\t:to=%ld:", (long)hp->time_offset);
247
}
248
if (hp->flags.time_server) {
249
fprintf(fp, "\\\n\t:ts=");
250
list_ipaddresses(fp, hp->time_server);
251
fprintf(fp, ":");
252
}
253
if (hp->flags.vm_cookie) {
254
fprintf(fp, "\\\n\t:vm=");
255
if (!bcmp(hp->vm_cookie, vm_rfc1048, 4)) {
256
fprintf(fp, "rfc1048:");
257
} else if (!bcmp(hp->vm_cookie, vm_cmu, 4)) {
258
fprintf(fp, "cmu:");
259
} else {
260
fprintf(fp, "%d.%d.%d.%d:",
261
(int) ((hp->vm_cookie)[0]),
262
(int) ((hp->vm_cookie)[1]),
263
(int) ((hp->vm_cookie)[2]),
264
(int) ((hp->vm_cookie)[3]));
265
}
266
}
267
if (hp->flags.nis_domain) {
268
fprintf(fp, "\\\n\t:yd=%s:",
269
hp->nis_domain->string);
270
}
271
if (hp->flags.nis_server) {
272
fprintf(fp, "\\\n\t:ys=");
273
list_ipaddresses(fp, hp->nis_server);
274
fprintf(fp, ":");
275
}
276
/*
277
* XXX - Add new tags here (or above,
278
* so they print in alphabetical order).
279
*/
280
281
if (hp->flags.generic) {
282
dump_generic(fp, hp->generic);
283
}
284
}
285
}
286
287
288
static void
289
dump_generic(FILE *fp, struct shared_bindata *generic)
290
{
291
u_char *bp = generic->data;
292
u_char *ep = bp + generic->length;
293
u_char tag;
294
int len;
295
296
while (bp < ep) {
297
tag = *bp++;
298
if (tag == TAG_PAD)
299
continue;
300
if (tag == TAG_END)
301
return;
302
len = *bp++;
303
if (bp + len > ep) {
304
fprintf(fp, " #junk in generic! :");
305
return;
306
}
307
fprintf(fp, "\\\n\t:T%d=", tag);
308
while (len) {
309
fprintf(fp, "%02X", *bp);
310
bp++;
311
len--;
312
if (len)
313
fprintf(fp, ".");
314
}
315
fprintf(fp, ":");
316
}
317
}
318
319
320
321
/*
322
* Dump an entire struct in_addr_list of IP addresses to the indicated file.
323
*
324
* The addresses are printed in standard ASCII "dot" notation and separated
325
* from one another by a single space. A single leading space is also
326
* printed before the first address.
327
*
328
* Null lists produce no output (and no error).
329
*/
330
331
static void
332
list_ipaddresses(FILE *fp, struct in_addr_list *ipptr)
333
{
334
unsigned count;
335
struct in_addr *addrptr;
336
337
if (ipptr) {
338
count = ipptr->addrcount;
339
addrptr = ipptr->addr;
340
while (count > 0) {
341
fprintf(fp, "%s", inet_ntoa(*addrptr++));
342
count--;
343
if (count)
344
fprintf(fp, ", ");
345
}
346
}
347
}
348
349
#endif /* DEBUG */
350
351
/*
352
* Local Variables:
353
* tab-width: 4
354
* c-indent-level: 4
355
* c-argdecl-indent: 4
356
* c-continued-statement-offset: 4
357
* c-continued-brace-offset: -4
358
* c-label-offset: -4
359
* c-brace-offset: 0
360
* End:
361
*/
362
363