3 Examine and modify omapi objects. */
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 2001-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
36 static char copyright[] =
37 "$Id: omshell.c,v 1.7.2.17 2004/09/30 23:11:50 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
46 #include <isc-dhcp/result.h>
51 isc_result_t find_class (struct class **c, const char *n, const char *f, int l)
55 int parse_allow_deny (struct option_cache **oc, struct parse *cfile, int flag)
59 void dhcp (struct packet *packet) { }
60 void bootp (struct packet *packet) { }
61 int check_collection (struct packet *p, struct lease *l, struct collection *c)
65 void classify (struct packet *packet, struct class *class) { }
67 static void usage (char *s) {
68 fprintf (stderr, "Usage: %s\n", s);
72 static void check (isc_result_t status, const char *func) {
73 if (status != ISC_R_SUCCESS) {
74 fprintf (stderr, "%s: %s\n", func, isc_result_totext (status));
79 int main (int argc, char **argv, char **envp)
81 isc_result_t status, waitstatus;
82 dhcpctl_handle connection;
83 dhcpctl_handle authenticator;
85 dhcpctl_data_string cid, ip_addr;
86 dhcpctl_data_string result, groupname, identifier;
87 struct data_string secret;
88 const char *name = 0, *algorithm = "hmac-md5";
91 const char *server = "127.0.0.1";
93 enum dhcp_token token;
100 for (i = 1; i < argc; i++) {
104 /* Initially, log errors to stderr as well as to syslogd. */
106 openlog ("omshell", LOG_NDELAY);
107 log_priority = DHCPD_LOG_FACILITY;
109 openlog ("omshell", LOG_NDELAY, DHCPD_LOG_FACILITY);
111 status = dhcpctl_initialize ();
112 if (status != ISC_R_SUCCESS) {
113 fprintf (stderr, "dhcpctl_initialize: %s\n",
114 isc_result_totext (status));
118 memset (&oh, 0, sizeof oh);
122 } else if (oh == NULL) {
123 printf ("obj: <null>\n");
125 dhcpctl_remote_object_t *r = (dhcpctl_remote_object_t *)oh;
126 omapi_generic_object_t *g =
127 (omapi_generic_object_t *)(r -> inner);
131 if (r -> rtype -> type != omapi_datatype_string) {
135 (int)(r -> rtype -> u . buffer . len),
136 r -> rtype -> u . buffer . value);
139 for (i = 0; i < g -> nvalues; i++) {
140 omapi_value_t *v = g -> values [i];
142 if (!g -> values [i])
145 printf ("%.*s = ", (int)v -> name -> len,
152 switch (v -> value -> type) {
153 case omapi_datatype_int:
155 v -> value -> u . integer);
158 case omapi_datatype_string:
159 printf ("\"%.*s\"\n",
160 (int) v -> value -> u.buffer.len,
161 v -> value -> u.buffer.value);
164 case omapi_datatype_data:
166 print_hex_1 (v -> value -> u.buffer.len,
167 v -> value -> u.buffer.value,
171 case omapi_datatype_object:
178 fputs ("> ", stdout);
180 if (fgets (buf, sizeof(buf), stdin) == NULL)
183 status = new_parse (&cfile, 0, buf, strlen(buf), "<STDIN>", 1);
184 check(status, "new_parse()");
186 token = next_token (&val, (unsigned *)0, cfile);
189 parse_warn (cfile, "unknown token: %s", val);
190 skip_to_semi (cfile);
199 printf ("Commands:\n");
200 printf (" port <server omapi port>\n");
201 printf (" server <server address>\n");
202 printf (" key <key name> <key value>\n");
203 printf (" connect\n");
204 printf (" new <object-type>\n");
205 printf (" set <name> = <value>\n");
206 printf (" create\n");
208 printf (" update\n");
209 printf (" unset <name>\n");
210 printf (" refresh\n");
211 printf (" remove\n");
212 skip_to_semi (cfile);
216 token = next_token (&val, (unsigned *)0, cfile);
217 if (is_identifier (token)) {
219 se = getservbyname (val, "tcp");
221 port = ntohs (se -> s_port);
223 printf ("unknown service name: %s\n", val);
226 } else if (token == NUMBER) {
229 skip_to_semi (cfile);
230 printf ("usage: port <port>\n");
233 token = next_token (&val, (unsigned *)0, cfile);
234 if (token != END_OF_FILE && token != EOL) {
235 printf ("usage: port <server>\n");
236 skip_to_semi (cfile);
242 token = next_token (&val, (unsigned *)0, cfile);
243 if (token == NUMBER) {
244 int alen = (sizeof buf) - 1;
249 if (len + 1 > alen) {
251 printf ("usage: server <server>\n");
252 skip_to_semi (cfile);
256 token = next_token (&val, (unsigned *)0, cfile);
260 token = next_token (&val, (unsigned *)0, cfile);
268 token = next_token (&val, (unsigned *)0, cfile);
272 token = next_token (&val, (unsigned *)0, cfile);
280 token = next_token (&val, (unsigned *)0, cfile);
284 token = next_token (&val, (unsigned *)0, cfile);
292 } else if (is_identifier (token)) {
293 /* Use val directly. */
295 printf ("usage: server <server>\n");
296 skip_to_semi (cfile);
300 s = dmalloc (strlen (val) + 1, MDL);
302 printf ("no memory to store server name.\n");
303 skip_to_semi (cfile);
309 token = next_token (&val, (unsigned *)0, cfile);
310 if (token != END_OF_FILE && token != EOL) {
311 printf ("usage: server <server>\n");
312 skip_to_semi (cfile);
318 token = next_token (&val, (unsigned *)0, cfile);
319 if (!is_identifier (token)) {
320 printf ("usage: key <name> <value>\n");
321 skip_to_semi (cfile);
324 s = dmalloc (strlen (val) + 1, MDL);
326 printf ("no memory for key name.\n");
327 skip_to_semi (cfile);
332 memset (&secret, 0, sizeof secret);
333 if (!parse_base64 (&secret, cfile)) {
334 skip_to_semi (cfile);
337 token = next_token (&val, (unsigned *)0, cfile);
338 if (token != END_OF_FILE && token != EOL) {
339 printf ("usage: key <name> <secret>\n");
340 skip_to_semi (cfile);
346 token = next_token (&val, (unsigned *)0, cfile);
347 if (token != END_OF_FILE && token != EOL) {
348 printf ("usage: connect\n");
349 skip_to_semi (cfile);
353 authenticator = dhcpctl_null_handle;
356 status = dhcpctl_new_authenticator (&authenticator,
361 if (status != ISC_R_SUCCESS) {
363 "Cannot create authenticator: %s\n",
364 isc_result_totext (status));
369 memset (&connection, 0, sizeof connection);
370 status = dhcpctl_connect (&connection,
371 server, port, authenticator);
372 if (status != ISC_R_SUCCESS) {
373 fprintf (stderr, "dhcpctl_connect: %s\n",
374 isc_result_totext (status));
381 token = next_token (&val, (unsigned *)0, cfile);
382 if ((!is_identifier (token) && token != STRING)) {
383 printf ("usage: new <object-type>\n");
388 printf ("an object is already open.\n");
389 skip_to_semi (cfile);
394 printf ("not connected.\n");
395 skip_to_semi (cfile);
399 status = dhcpctl_new_object (&oh, connection, val);
400 if (status != ISC_R_SUCCESS) {
401 printf ("can't create object: %s\n",
402 isc_result_totext (status));
406 token = next_token (&val, (unsigned *)0, cfile);
407 if (token != END_OF_FILE && token != EOL) {
408 printf ("usage: new <object-type>\n");
409 skip_to_semi (cfile);
415 token = next_token (&val, (unsigned *)0, cfile);
416 if (token != END_OF_FILE && token != EOL) {
417 printf ("usage: close\n");
418 skip_to_semi (cfile);
423 printf ("not connected.\n");
424 skip_to_semi (cfile);
429 printf ("not open.\n");
430 skip_to_semi (cfile);
433 omapi_object_dereference (&oh, MDL);
438 token = next_token (&val, (unsigned *)0, cfile);
440 if ((!is_identifier (token) && token != STRING)) {
442 printf ("usage: set <name> = <value>\n");
443 skip_to_semi (cfile);
448 printf ("no open object.\n");
449 skip_to_semi (cfile);
454 printf ("not connected.\n");
455 skip_to_semi (cfile);
460 strncat (s1, val, sizeof(s1)-1);
462 token = next_token (&val, (unsigned *)0, cfile);
466 token = next_token (&val, (unsigned *)0, cfile);
469 dhcpctl_set_string_value (oh, val, s1);
470 token = next_token (&val, (unsigned *)0, cfile);
475 token = peek_token (&val, (unsigned *)0, cfile);
476 /* Colon-seperated hex list? */
479 else if (token == DOT) {
483 int intval = atoi (val);
487 "dotted octet > 255: %s",
489 skip_to_semi (cfile);
493 token = next_token (&val,
494 (unsigned *)0, cfile);
498 while ((token = next_token (&val,
499 (unsigned *)0, cfile)) == DOT)
501 } while (token == NUMBER);
502 dhcpctl_set_data_value (oh, buf,
507 dhcpctl_set_int_value (oh, atoi (buf), s1);
508 token = next_token (&val, (unsigned *)0, cfile);
518 convert_num (cfile, (unsigned char *)s,
521 token = next_token (&val,
522 (unsigned *)0, cfile);
525 token = next_token (&val,
526 (unsigned *)0, cfile);
527 } while (token == NUMBER ||
528 token == NUMBER_OR_NAME);
529 dhcpctl_set_data_value (oh, buf,
530 (unsigned)(s - buf), s1);
534 printf ("invalid value.\n");
535 skip_to_semi (cfile);
538 if (token != END_OF_FILE && token != EOL)
543 token = next_token (&val, (unsigned *)0, cfile);
545 if ((!is_identifier (token) && token != STRING)) {
547 printf ("usage: unset <name>\n");
548 skip_to_semi (cfile);
553 printf ("no open object.\n");
554 skip_to_semi (cfile);
559 printf ("not connected.\n");
560 skip_to_semi (cfile);
565 strncat (s1, val, sizeof(s1)-1);
567 token = next_token (&val, (unsigned *)0, cfile);
568 if (token != END_OF_FILE && token != EOL)
571 dhcpctl_set_null_value (oh, s1);
578 token = next_token (&val, (unsigned *)0, cfile);
579 if (token != END_OF_FILE && token != EOL) {
580 printf ("usage: %s\n", val);
581 skip_to_semi (cfile);
586 printf ("not connected.\n");
587 skip_to_semi (cfile);
592 printf ("you must make a new object first!\n");
593 skip_to_semi (cfile);
597 if (i == TOKEN_CREATE)
598 i = DHCPCTL_CREATE | DHCPCTL_EXCL;
602 status = dhcpctl_open_object (oh, connection, i);
603 if (status == ISC_R_SUCCESS)
604 status = dhcpctl_wait_for_completion
606 if (status == ISC_R_SUCCESS)
608 if (status != ISC_R_SUCCESS) {
609 printf ("can't open object: %s\n",
610 isc_result_totext (status));
617 token = next_token (&val, (unsigned *)0, cfile);
618 if (token != END_OF_FILE && token != EOL) {
619 printf ("usage: %s\n", val);
620 skip_to_semi (cfile);
625 printf ("not connected.\n");
626 skip_to_semi (cfile);
631 printf ("you haven't opened an object yet!\n");
632 skip_to_semi (cfile);
636 status = dhcpctl_object_update(connection, oh);
637 if (status == ISC_R_SUCCESS)
638 status = dhcpctl_wait_for_completion
640 if (status == ISC_R_SUCCESS)
642 if (status != ISC_R_SUCCESS) {
643 printf ("can't update object: %s\n",
644 isc_result_totext (status));
651 token = next_token (&val, (unsigned *)0, cfile);
652 if (token != END_OF_FILE && token != EOL) {
653 printf ("usage: remove\n");
654 skip_to_semi (cfile);
659 printf ("not connected.\n");
664 printf ("no object.\n");
668 status = dhcpctl_object_remove(connection, oh);
669 if (status == ISC_R_SUCCESS)
670 status = dhcpctl_wait_for_completion
672 if (status == ISC_R_SUCCESS)
674 if (status != ISC_R_SUCCESS) {
675 printf ("can't destroy object: %s\n",
676 isc_result_totext (status));
679 omapi_object_dereference (&oh, MDL);
683 token = next_token (&val, (unsigned *)0, cfile);
684 if (token != END_OF_FILE && token != EOL) {
685 printf ("usage: refresh\n");
686 skip_to_semi (cfile);
691 printf ("not connected.\n");
696 printf ("no object.\n");
700 status = dhcpctl_object_refresh(connection, oh);
701 if (status == ISC_R_SUCCESS)
702 status = dhcpctl_wait_for_completion
704 if (status == ISC_R_SUCCESS)
706 if (status != ISC_R_SUCCESS) {
707 printf ("can't refresh object: %s\n",
708 isc_result_totext (status));
721 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
722 control_object_state_t newstate)
724 return ISC_R_SUCCESS;