]> git.ipfire.org Git - thirdparty/dhcp.git/blame - dhcpctl/omshell.c
remove these from the mainline.
[thirdparty/dhcp.git] / dhcpctl / omshell.c
CommitLineData
0b69dcc8 1/* omshell.c
d142e03f 2
4bce547e 3 Examine and modify omapi objects. */
d142e03f
TL
4
5/*
4bce547e 6 * Copyright (c) 2001 Internet Software Consortium.
49733f31 7 * All rights reserved.
d142e03f 8 *
49733f31
TL
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
d142e03f 12 *
49733f31
TL
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
d142e03f 21 *
49733f31
TL
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38 * To learn more about the Internet Software Consortium, see
39 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
40 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
41 * ``http://www.nominum.com''.
d142e03f
TL
42 */
43
6a4c4be8 44#include <time.h>
0f6bb7e1 45#include <sys/time.h>
6a4c4be8
TL
46#include <stdio.h>
47#include <stdlib.h>
48#include <stdarg.h>
06f0ed06 49#include <string.h>
6a4c4be8 50#include <isc/result.h>
d142e03f 51#include "dhcpctl.h"
4bce547e 52#include "dhcpd.h"
d142e03f 53
4bce547e
TL
54/* Fixups */
55isc_result_t find_class (struct class **c, const char *n, const char *f, int l)
56{
57 return 0;
58}
59int parse_allow_deny (struct option_cache **oc, struct parse *cfile, int flag)
60{
61 return 0;
62}
63void dhcp (struct packet *packet) { }
64void bootp (struct packet *packet) { }
65int check_collection (struct packet *p, struct lease *l, struct collection *c)
66{
67 return 0;
68}
69void classify (struct packet *packet, struct class *class) { }
d142e03f 70
58941de4
DN
71static void usage (char *s) {
72 fprintf (stderr,
73 "Usage: %s [-n <username>] [-p <password>] "
984d434c 74 "[-a <algorithm>] [-P <port>]\n", s);
58941de4
DN
75 exit (1);
76}
77
031d30b7
DN
78static void check (isc_result_t status, const char *func) {
79 if (status != ISC_R_SUCCESS) {
80 fprintf (stderr, "%s: %s\n", func, isc_result_totext (status));
81 exit (1);
82 }
83}
84
4bce547e 85int main (int argc, char **argv, char **envp)
d142e03f
TL
86{
87 isc_result_t status, waitstatus;
88 dhcpctl_handle connection;
58941de4 89 dhcpctl_handle authenticator;
4bce547e 90 dhcpctl_handle oh;
bfacc53f 91 dhcpctl_data_string cid, ip_addr;
e6e9b9e8 92 dhcpctl_data_string result, groupname, identifier;
f27f6d6c
TL
93 struct data_string secret;
94 const char *name = 0, *algorithm = "hmac-md5";
031d30b7 95 int i, j;
4bce547e
TL
96 int port = 7911;
97 const char *server = "127.0.0.1";
98 struct parse *cfile;
99 enum dhcp_token token;
100 const char *val;
f27f6d6c 101 char *s;
031d30b7
DN
102 char buf[1024];
103 char s1[1024];
f27f6d6c 104 int connected = 0;
d142e03f 105
58941de4 106 for (i = 1; i < argc; i++) {
58941de4 107 usage(argv[0]);
f27f6d6c 108 }
58941de4 109
31bbee78
TL
110 /* Initially, log errors to stderr as well as to syslogd. */
111#ifdef SYSLOG_4_2
112 openlog ("dhcpd", LOG_NDELAY);
113 log_priority = DHCPD_LOG_FACILITY;
114#else
115 openlog ("dhcpd", LOG_NDELAY, DHCPD_LOG_FACILITY);
116#endif
d142e03f
TL
117 status = dhcpctl_initialize ();
118 if (status != ISC_R_SUCCESS) {
119 fprintf (stderr, "dhcpctl_initialize: %s\n",
120 isc_result_totext (status));
121 exit (1);
122 }
123
4bce547e
TL
124 memset (&oh, 0, sizeof oh);
125
4bce547e 126 do {
f27f6d6c
TL
127 if (!connected) {
128 } else if (oh == NULL) {
129 printf ("obj: <null>\n");
130 } else {
131 dhcpctl_remote_object_t *r = (dhcpctl_remote_object_t *)oh;
132 omapi_generic_object_t *g =
133 (omapi_generic_object_t *)(r -> inner);
134
031d30b7 135 printf ("obj: ");
031d30b7 136
f27f6d6c
TL
137 if (r -> rtype -> type != omapi_datatype_string) {
138 printf ("?\n");
139 } else {
140 printf ("%.*s\n",
141 (int)(r -> rtype -> u . buffer . len),
142 r -> rtype -> u . buffer . value);
143 }
144
145 for (i = 0; i < g -> nvalues; i++) {
146 omapi_value_t *v = g -> values [i];
147
148 printf ("%.*s = ", (int)v -> name -> len,
149 v -> name -> value);
150
151 switch (v -> value -> type) {
152 case omapi_datatype_int:
153 printf ("%d\n",
154 v -> value -> u . integer);
155 break;
156
157 case omapi_datatype_string:
158 printf ("\"%.*s\"\n",
159 (int) v -> value -> u.buffer.len,
160 v -> value -> u.buffer.value);
161 break;
162
163 case omapi_datatype_data:
164 printf ("%s\n",
165 print_hex_1 (v -> value -> u.buffer.len,
031d30b7
DN
166 v -> value -> u.buffer.value,
167 60));
f27f6d6c
TL
168 break;
169
170 case omapi_datatype_object:
171 printf ("<obj>\n");
172 break;
173 }
031d30b7 174 }
f27f6d6c
TL
175 }
176
177 fputs ("> ", stdout);
178 fflush (stdout);
179 if (fgets (buf, sizeof(buf), stdin) == NULL)
180 break;
181
182 status = new_parse (&cfile, 0, buf, strlen(buf), "<STDIN>", 1);
183 check(status, "new_parse()");
184
185 token = next_token (&val, (unsigned *)0, cfile);
186 switch (token) {
187 default:
188 parse_warn (cfile, "unknown token: %s", val);
189 skip_to_semi (cfile);
190 break;
191
192 case END_OF_FILE:
193 case EOL:
194 break;
195
196 case TOKEN_HELP:
197 case '?':
198 printf ("Commands:\n");
199 printf (" port <server omapi port>\n");
200 printf (" server <server address>\n");
201 printf (" key <key name> <key value>\n");
202 printf (" connect\n");
203 printf (" new <object-type>\n");
204 printf (" set <name> = <value>\n");
205 printf (" create\n");
206 printf (" open\n");
207 skip_to_semi (cfile);
208 break;
209
210 case PORT:
211 token = next_token (&val, (unsigned *)0, cfile);
212 if (is_identifier (token)) {
213 struct servent *se;
214 se = getservbyname (val, "tcp");
215 if (se)
216 port = ntohs (se -> s_port);
217 else {
31bbee78 218 printf ("unknown service name: %s\n", val);
f27f6d6c
TL
219 break;
220 }
221 } else if (token == NUMBER) {
222 port = atoi (val);
223 } else {
224 skip_to_semi (cfile);
225 printf ("usage: port <port>\n");
226 break;
227 }
228 token = next_token (&val, (unsigned *)0, cfile);
229 if (token != END_OF_FILE && token != EOL) {
230 printf ("usage: port <server>\n");
231 skip_to_semi (cfile);
232 break;
233 }
234 break;
235
236 case SERVER:
237 token = next_token (&val, (unsigned *)0, cfile);
238 if (token == NUMBER) {
239 int alen = (sizeof buf) - 1;
240 int len;
241
242 s = &buf [0];
243 len = strlen (val);
244 if (len + 1 > alen) {
245 baddq:
246 printf ("usage: server <server>\n");
247 skip_to_semi (cfile);
031d30b7 248 break;
f27f6d6c
TL
249 } strcpy (buf, val);
250 s += len;
251 token = next_token (&val, (unsigned *)0, cfile);
252 if (token != DOT)
253 goto baddq;
254 *s++ = '.';
255 token = next_token (&val, (unsigned *)0, cfile);
256 if (token != NUMBER)
257 goto baddq;
258 len = strlen (val);
259 if (len + 1 > alen)
260 goto baddq;
261 strcpy (s, val);
262 s += len;
263 token = next_token (&val, (unsigned *)0, cfile);
264 if (token != DOT)
265 goto baddq;
266 *s++ = '.';
267 token = next_token (&val, (unsigned *)0, cfile);
268 if (token != NUMBER)
269 goto baddq;
270 len = strlen (val);
271 if (len + 1 > alen)
272 goto baddq;
273 strcpy (s, val);
274 s += len;
275 token = next_token (&val, (unsigned *)0, cfile);
276 if (token != DOT)
277 goto baddq;
278 *s++ = '.';
279 token = next_token (&val, (unsigned *)0, cfile);
280 if (token != NUMBER)
281 goto baddq;
282 len = strlen (val);
283 if (len + 1 > alen)
284 goto baddq;
285 strcpy (s, val);
286 val = &buf [0];
287 } else if (is_identifier (token)) {
288 /* Use val directly. */
289 } else {
290 printf ("usage: server <server>\n");
291 skip_to_semi (cfile);
292 break;
293 }
294
295 s = dmalloc (strlen (val) + 1, MDL);
296 if (!server) {
31bbee78 297 printf ("no memory to store server name.\n");
f27f6d6c
TL
298 skip_to_semi (cfile);
299 break;
300 }
301 strcpy (s, val);
302 server = s;
303
304 token = next_token (&val, (unsigned *)0, cfile);
305 if (token != END_OF_FILE && token != EOL) {
306 printf ("usage: server <server>\n");
307 skip_to_semi (cfile);
308 break;
309 }
310 break;
311
312 case KEY:
313 token = next_token (&val, (unsigned *)0, cfile);
314 if (!is_identifier (token)) {
31bbee78 315 printf ("usage: key <name> <value>\n");
f27f6d6c
TL
316 skip_to_semi (cfile);
317 break;
318 }
319 s = dmalloc (strlen (val) + 1, MDL);
320 if (!s) {
31bbee78 321 printf ("no memory for key name.\n");
f27f6d6c
TL
322 skip_to_semi (cfile);
323 break;
324 }
325 strcpy (s, val);
326 name = s;
327 memset (&secret, 0, sizeof secret);
328 if (!parse_base64 (&secret, cfile)) {
329 skip_to_semi (cfile);
330 break;
331 }
332 token = next_token (&val, (unsigned *)0, cfile);
333 if (token != END_OF_FILE && token != EOL) {
334 printf ("usage: key <name> <secret>\n");
335 skip_to_semi (cfile);
336 break;
337 }
338 break;
339
340 case CONNECT:
341 token = next_token (&val, (unsigned *)0, cfile);
342 if (token != END_OF_FILE && token != EOL) {
343 printf ("usage: connect\n");
344 skip_to_semi (cfile);
345 break;
346 }
347
348 authenticator = dhcpctl_null_handle;
349
350 if (name) {
351 status = dhcpctl_new_authenticator (&authenticator,
352 name, algorithm,
353 secret.data,
354 secret.len);
472c048a 355
031d30b7 356 if (status != ISC_R_SUCCESS) {
f27f6d6c
TL
357 fprintf (stderr,
358 "Cannot create authenticator: %s\n",
359 isc_result_totext (status));
360 break;
031d30b7 361 }
f27f6d6c
TL
362 }
363
364 memset (&connection, 0, sizeof connection);
365 status = dhcpctl_connect (&connection,
366 server, port, authenticator);
367 if (status != ISC_R_SUCCESS) {
368 fprintf (stderr, "dhcpctl_connect: %s\n",
369 isc_result_totext (status));
370 break;
371 }
372 connected = 1;
373 break;
374
375 case TOKEN_NEW:
376 token = next_token (&val, (unsigned *)0, cfile);
377 if ((!is_identifier (token) && token != STRING)) {
378 printf ("usage: new <object-type>\n");
379 break;
380 }
381
382 if (oh) {
383 printf ("an object is already open.\n");
384 skip_to_semi (cfile);
385 break;
386 }
387
388 if (!connected) {
31bbee78 389 printf ("not connected.\n");
f27f6d6c
TL
390 skip_to_semi (cfile);
391 break;
392 }
393
394 status = dhcpctl_new_object (&oh, connection, val);
395 if (status != ISC_R_SUCCESS) {
396 printf ("can't create object: %s\n",
397 isc_result_totext (status));
398 break;
399 }
400
401 token = next_token (&val, (unsigned *)0, cfile);
402 if (token != END_OF_FILE && token != EOL) {
403 printf ("usage: new <object-type>\n");
404 skip_to_semi (cfile);
405 break;
406 }
407 break;
408
409 case TOKEN_CLOSE:
410 token = next_token (&val, (unsigned *)0, cfile);
411 if (token != END_OF_FILE && token != EOL) {
412 printf ("usage: close\n");
413 skip_to_semi (cfile);
414 break;
415 }
416
417 if (!connected) {
31bbee78 418 printf ("not connected.\n");
f27f6d6c
TL
419 skip_to_semi (cfile);
420 break;
421 }
422
423 omapi_object_dereference (&oh, MDL);
424
425 break;
426
427 case TOKEN_SET:
428 token = next_token (&val, (unsigned *)0, cfile);
429
430 if ((!is_identifier (token) && token != STRING)) {
431 set_usage:
432 printf ("usage: set <name> = <value>\n");
433 skip_to_semi (cfile);
434 break;
435 }
436
437 if (oh == NULL) {
438 printf ("no open object.\n");
439 skip_to_semi (cfile);
440 break;
441 }
442
443 if (!connected) {
31bbee78 444 printf ("not connected.\n");
f27f6d6c
TL
445 skip_to_semi (cfile);
446 break;
447 }
448
449 s1[0] = '\0';
450 strncat (s1, val, sizeof(s1)-1);
451
452 token = next_token (&val, (unsigned *)0, cfile);
453 if (token != EQUAL)
454 goto set_usage;
455
456 token = next_token (&val, (unsigned *)0, cfile);
457 switch (token) {
458 case STRING:
459 dhcpctl_set_string_value (oh, val, s1);
31bbee78 460 token = next_token (&val, (unsigned *)0, cfile);
f27f6d6c
TL
461 break;
462
463 case NUMBER:
31bbee78
TL
464 strcpy (buf, val);
465 token = peek_token (&val, (unsigned *)0, cfile);
466 /* Colon-seperated hex list? */
467 if (token == COLON)
468 goto cshl;
469 else if (token == DOT) {
470 s = buf;
471 val = buf;
472 do {
473 int intval = atoi (val);
474 if (intval > 255) {
475 parse_warn (cfile,
476 "dotted octet > 255: %s",
477 val);
478 skip_to_semi (cfile);
479 goto badnum;
480 }
481 *s++ = intval;
482 token = next_token (&val,
483 (unsigned *)0, cfile);
484 if (token != DOT)
485 break;
486 token = next_token (&val,
487 (unsigned *)0, cfile);
488 } while (token == NUMBER);
489 dhcpctl_set_data_value (oh, buf,
490 (unsigned)(s - buf),
491 s1);
492 break;
493 }
494 dhcpctl_set_int_value (oh, atoi (buf), s1);
495 token = next_token (&val, (unsigned *)0, cfile);
496 badnum:
f27f6d6c
TL
497 break;
498
31bbee78
TL
499 case NUMBER_OR_NAME:
500 strcpy (buf, val);
501 cshl:
502 s = buf;
503 val = buf;
504 do {
505 convert_num (cfile, s, val, 16, 8);
506 ++s;
507 token = next_token (&val,
508 (unsigned *)0, cfile);
509 if (token != COLON)
510 break;
511 token = next_token (&val,
512 (unsigned *)0, cfile);
513 } while (token == NUMBER ||
514 token == NUMBER_OR_NAME);
515 dhcpctl_set_data_value (oh, buf,
516 (unsigned)(s - buf), s1);
517 break;
518
f27f6d6c
TL
519 default:
520 printf ("invalid value.\n");
31bbee78 521 skip_to_semi (cfile);
f27f6d6c
TL
522 }
523
f27f6d6c
TL
524 if (token != END_OF_FILE && token != EOL)
525 goto set_usage;
526 break;
527
528 case TOKEN_CREATE:
529 case TOKEN_OPEN:
31bbee78 530 i = token;
f27f6d6c
TL
531 token = next_token (&val, (unsigned *)0, cfile);
532 if (token != END_OF_FILE && token != EOL) {
533 printf ("usage: %s\n", val);
534 skip_to_semi (cfile);
535 break;
536 }
537
538 if (!connected) {
31bbee78 539 printf ("not connected.\n");
f27f6d6c
TL
540 skip_to_semi (cfile);
541 break;
542 }
543
31bbee78
TL
544 if (!oh) {
545 printf ("you must make a new object first!\n");
546 skip_to_semi (cfile);
547 break;
548 }
549
550 if (i == TOKEN_CREATE)
f27f6d6c 551 i = DHCPCTL_CREATE | DHCPCTL_EXCL;
31bbee78
TL
552 else
553 i = 0;
f27f6d6c
TL
554
555 status = dhcpctl_open_object (oh, connection, i);
556 if (status == ISC_R_SUCCESS)
557 status = dhcpctl_wait_for_completion
558 (oh, &waitstatus);
559 if (status == ISC_R_SUCCESS)
560 status = waitstatus;
561 if (status != ISC_R_SUCCESS) {
562 printf ("can't open object: %s\n",
563 isc_result_totext (status));
564 break;
565 }
566
567 break;
568
569 case UPDATE:
570 token = next_token (&val, (unsigned *)0, cfile);
571 if (token != END_OF_FILE && token != EOL) {
572 printf ("usage: %s\n", val);
573 skip_to_semi (cfile);
574 break;
575 }
576
577 if (!connected) {
31bbee78 578 printf ("not connected.\n");
f27f6d6c
TL
579 skip_to_semi (cfile);
580 break;
581 }
582
583 status = dhcpctl_object_update(connection, oh);
584 if (status == ISC_R_SUCCESS)
585 status = dhcpctl_wait_for_completion
586 (oh, &waitstatus);
587 if (status == ISC_R_SUCCESS)
588 status = waitstatus;
589 if (status != ISC_R_SUCCESS) {
590 printf ("can't update object: %s\n",
591 isc_result_totext (status));
592 break;
593 }
594
31bbee78
TL
595 break;
596
597 case REMOVE:
598 token = next_token (&val, (unsigned *)0, cfile);
599 if (token != END_OF_FILE && token != EOL) {
600 printf ("usage: %s\n", val);
601 skip_to_semi (cfile);
602 break;
603 }
604
605 if (!connected) {
606 printf ("not connected.\n");
607 skip_to_semi (cfile);
608 break;
609 }
610
611 status = dhcpctl_object_remove(connection, oh);
612 if (status == ISC_R_SUCCESS)
613 status = dhcpctl_wait_for_completion
614 (oh, &waitstatus);
615 if (status == ISC_R_SUCCESS)
616 status = waitstatus;
617 if (status != ISC_R_SUCCESS) {
618 printf ("can't destroy object: %s\n",
619 isc_result_totext (status));
620 break;
621 }
622
f27f6d6c
TL
623 break;
624 }
31bbee78 625 } while (1);
eadee396 626
d142e03f
TL
627 exit (0);
628}