3 Examine and modify omapi objects. */
6 * Copyright (c) 2001-2002 Internet Software Consortium.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
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''.
50 #include <isc-dhcp/result.h>
55 isc_result_t find_class (struct class **c, const char *n, const char *f, int l)
59 int parse_allow_deny (struct option_cache **oc, struct parse *cfile, int flag)
63 void dhcp (struct packet *packet) { }
64 void bootp (struct packet *packet) { }
65 int check_collection (struct packet *p, struct lease *l, struct collection *c)
69 void classify (struct packet *packet, struct class *class) { }
71 static void usage (char *s) {
72 fprintf (stderr, "Usage: %s\n", s);
76 static void check (isc_result_t status, const char *func) {
77 if (status != ISC_R_SUCCESS) {
78 fprintf (stderr, "%s: %s\n", func, isc_result_totext (status));
83 int main (int argc, char **argv, char **envp)
85 isc_result_t status, waitstatus;
86 dhcpctl_handle connection;
87 dhcpctl_handle authenticator;
89 dhcpctl_data_string cid, ip_addr;
90 dhcpctl_data_string result, groupname, identifier;
91 struct data_string secret;
92 const char *name = 0, *algorithm = "hmac-md5";
95 const char *server = "127.0.0.1";
97 enum dhcp_token token;
104 for (i = 1; i < argc; i++) {
108 /* Initially, log errors to stderr as well as to syslogd. */
110 openlog ("omshell", LOG_NDELAY);
111 log_priority = DHCPD_LOG_FACILITY;
113 openlog ("omshell", LOG_NDELAY, DHCPD_LOG_FACILITY);
115 status = dhcpctl_initialize ();
116 if (status != ISC_R_SUCCESS) {
117 fprintf (stderr, "dhcpctl_initialize: %s\n",
118 isc_result_totext (status));
122 memset (&oh, 0, sizeof oh);
126 } else if (oh == NULL) {
127 printf ("obj: <null>\n");
129 dhcpctl_remote_object_t *r = (dhcpctl_remote_object_t *)oh;
130 omapi_generic_object_t *g =
131 (omapi_generic_object_t *)(r -> inner);
135 if (r -> rtype -> type != omapi_datatype_string) {
139 (int)(r -> rtype -> u . buffer . len),
140 r -> rtype -> u . buffer . value);
143 for (i = 0; i < g -> nvalues; i++) {
144 omapi_value_t *v = g -> values [i];
146 if (!g -> values [i])
149 printf ("%.*s = ", (int)v -> name -> len,
156 switch (v -> value -> type) {
157 case omapi_datatype_int:
159 v -> value -> u . integer);
162 case omapi_datatype_string:
163 printf ("\"%.*s\"\n",
164 (int) v -> value -> u.buffer.len,
165 v -> value -> u.buffer.value);
168 case omapi_datatype_data:
170 print_hex_1 (v -> value -> u.buffer.len,
171 v -> value -> u.buffer.value,
175 case omapi_datatype_object:
182 fputs ("> ", stdout);
184 if (fgets (buf, sizeof(buf), stdin) == NULL)
187 status = new_parse (&cfile, 0, buf, strlen(buf), "<STDIN>", 1);
188 check(status, "new_parse()");
190 token = next_token (&val, (unsigned *)0, cfile);
193 parse_warn (cfile, "unknown token: %s", val);
194 skip_to_semi (cfile);
203 printf ("Commands:\n");
204 printf (" port <server omapi port>\n");
205 printf (" server <server address>\n");
206 printf (" key <key name> <key value>\n");
207 printf (" connect\n");
208 printf (" new <object-type>\n");
209 printf (" set <name> = <value>\n");
210 printf (" create\n");
212 printf (" update\n");
213 printf (" unset <name>\n");
214 printf (" refresh\n");
215 printf (" remove\n");
216 skip_to_semi (cfile);
220 token = next_token (&val, (unsigned *)0, cfile);
221 if (is_identifier (token)) {
223 se = getservbyname (val, "tcp");
225 port = ntohs (se -> s_port);
227 printf ("unknown service name: %s\n", val);
230 } else if (token == NUMBER) {
233 skip_to_semi (cfile);
234 printf ("usage: port <port>\n");
237 token = next_token (&val, (unsigned *)0, cfile);
238 if (token != END_OF_FILE && token != EOL) {
239 printf ("usage: port <server>\n");
240 skip_to_semi (cfile);
246 token = next_token (&val, (unsigned *)0, cfile);
247 if (token == NUMBER) {
248 int alen = (sizeof buf) - 1;
253 if (len + 1 > alen) {
255 printf ("usage: server <server>\n");
256 skip_to_semi (cfile);
260 token = next_token (&val, (unsigned *)0, cfile);
264 token = next_token (&val, (unsigned *)0, cfile);
272 token = next_token (&val, (unsigned *)0, cfile);
276 token = next_token (&val, (unsigned *)0, cfile);
284 token = next_token (&val, (unsigned *)0, cfile);
288 token = next_token (&val, (unsigned *)0, cfile);
296 } else if (is_identifier (token)) {
297 /* Use val directly. */
299 printf ("usage: server <server>\n");
300 skip_to_semi (cfile);
304 s = dmalloc (strlen (val) + 1, MDL);
306 printf ("no memory to store server name.\n");
307 skip_to_semi (cfile);
313 token = next_token (&val, (unsigned *)0, cfile);
314 if (token != END_OF_FILE && token != EOL) {
315 printf ("usage: server <server>\n");
316 skip_to_semi (cfile);
322 token = next_token (&val, (unsigned *)0, cfile);
323 if (!is_identifier (token)) {
324 printf ("usage: key <name> <value>\n");
325 skip_to_semi (cfile);
328 s = dmalloc (strlen (val) + 1, MDL);
330 printf ("no memory for key name.\n");
331 skip_to_semi (cfile);
336 memset (&secret, 0, sizeof secret);
337 if (!parse_base64 (&secret, cfile)) {
338 skip_to_semi (cfile);
341 token = next_token (&val, (unsigned *)0, cfile);
342 if (token != END_OF_FILE && token != EOL) {
343 printf ("usage: key <name> <secret>\n");
344 skip_to_semi (cfile);
350 token = next_token (&val, (unsigned *)0, cfile);
351 if (token != END_OF_FILE && token != EOL) {
352 printf ("usage: connect\n");
353 skip_to_semi (cfile);
357 authenticator = dhcpctl_null_handle;
360 status = dhcpctl_new_authenticator (&authenticator,
365 if (status != ISC_R_SUCCESS) {
367 "Cannot create authenticator: %s\n",
368 isc_result_totext (status));
373 memset (&connection, 0, sizeof connection);
374 status = dhcpctl_connect (&connection,
375 server, port, authenticator);
376 if (status != ISC_R_SUCCESS) {
377 fprintf (stderr, "dhcpctl_connect: %s\n",
378 isc_result_totext (status));
385 token = next_token (&val, (unsigned *)0, cfile);
386 if ((!is_identifier (token) && token != STRING)) {
387 printf ("usage: new <object-type>\n");
392 printf ("an object is already open.\n");
393 skip_to_semi (cfile);
398 printf ("not connected.\n");
399 skip_to_semi (cfile);
403 status = dhcpctl_new_object (&oh, connection, val);
404 if (status != ISC_R_SUCCESS) {
405 printf ("can't create object: %s\n",
406 isc_result_totext (status));
410 token = next_token (&val, (unsigned *)0, cfile);
411 if (token != END_OF_FILE && token != EOL) {
412 printf ("usage: new <object-type>\n");
413 skip_to_semi (cfile);
419 token = next_token (&val, (unsigned *)0, cfile);
420 if (token != END_OF_FILE && token != EOL) {
421 printf ("usage: close\n");
422 skip_to_semi (cfile);
427 printf ("not connected.\n");
428 skip_to_semi (cfile);
433 printf ("not open.\n");
434 skip_to_semi (cfile);
437 omapi_object_dereference (&oh, MDL);
442 token = next_token (&val, (unsigned *)0, cfile);
444 if ((!is_identifier (token) && token != STRING)) {
446 printf ("usage: set <name> = <value>\n");
447 skip_to_semi (cfile);
452 printf ("no open object.\n");
453 skip_to_semi (cfile);
458 printf ("not connected.\n");
459 skip_to_semi (cfile);
464 strncat (s1, val, sizeof(s1)-1);
466 token = next_token (&val, (unsigned *)0, cfile);
470 token = next_token (&val, (unsigned *)0, cfile);
473 dhcpctl_set_string_value (oh, val, s1);
474 token = next_token (&val, (unsigned *)0, cfile);
479 token = peek_token (&val, (unsigned *)0, cfile);
480 /* Colon-seperated hex list? */
483 else if (token == DOT) {
487 int intval = atoi (val);
491 "dotted octet > 255: %s",
493 skip_to_semi (cfile);
497 token = next_token (&val,
498 (unsigned *)0, cfile);
502 while ((token = next_token (&val,
503 (unsigned *)0, cfile)) == DOT)
505 } while (token == NUMBER);
506 dhcpctl_set_data_value (oh, buf,
511 dhcpctl_set_int_value (oh, atoi (buf), s1);
512 token = next_token (&val, (unsigned *)0, cfile);
522 convert_num (cfile, (unsigned char *)s,
525 token = next_token (&val,
526 (unsigned *)0, cfile);
529 token = next_token (&val,
530 (unsigned *)0, cfile);
531 } while (token == NUMBER ||
532 token == NUMBER_OR_NAME);
533 dhcpctl_set_data_value (oh, buf,
534 (unsigned)(s - buf), s1);
538 printf ("invalid value.\n");
539 skip_to_semi (cfile);
542 if (token != END_OF_FILE && token != EOL)
547 token = next_token (&val, (unsigned *)0, cfile);
549 if ((!is_identifier (token) && token != STRING)) {
551 printf ("usage: unset <name>\n");
552 skip_to_semi (cfile);
557 printf ("no open object.\n");
558 skip_to_semi (cfile);
563 printf ("not connected.\n");
564 skip_to_semi (cfile);
569 strncat (s1, val, sizeof(s1)-1);
571 token = next_token (&val, (unsigned *)0, cfile);
572 if (token != END_OF_FILE && token != EOL)
575 dhcpctl_set_null_value (oh, s1);
582 token = next_token (&val, (unsigned *)0, cfile);
583 if (token != END_OF_FILE && token != EOL) {
584 printf ("usage: %s\n", val);
585 skip_to_semi (cfile);
590 printf ("not connected.\n");
591 skip_to_semi (cfile);
596 printf ("you must make a new object first!\n");
597 skip_to_semi (cfile);
601 if (i == TOKEN_CREATE)
602 i = DHCPCTL_CREATE | DHCPCTL_EXCL;
606 status = dhcpctl_open_object (oh, connection, i);
607 if (status == ISC_R_SUCCESS)
608 status = dhcpctl_wait_for_completion
610 if (status == ISC_R_SUCCESS)
612 if (status != ISC_R_SUCCESS) {
613 printf ("can't open object: %s\n",
614 isc_result_totext (status));
621 token = next_token (&val, (unsigned *)0, cfile);
622 if (token != END_OF_FILE && token != EOL) {
623 printf ("usage: %s\n", val);
624 skip_to_semi (cfile);
629 printf ("not connected.\n");
630 skip_to_semi (cfile);
635 printf ("you haven't opened an object yet!\n");
636 skip_to_semi (cfile);
640 status = dhcpctl_object_update(connection, oh);
641 if (status == ISC_R_SUCCESS)
642 status = dhcpctl_wait_for_completion
644 if (status == ISC_R_SUCCESS)
646 if (status != ISC_R_SUCCESS) {
647 printf ("can't update object: %s\n",
648 isc_result_totext (status));
655 token = next_token (&val, (unsigned *)0, cfile);
656 if (token != END_OF_FILE && token != EOL) {
657 printf ("usage: remove\n");
658 skip_to_semi (cfile);
663 printf ("not connected.\n");
668 printf ("no object.\n");
672 status = dhcpctl_object_remove(connection, oh);
673 if (status == ISC_R_SUCCESS)
674 status = dhcpctl_wait_for_completion
676 if (status == ISC_R_SUCCESS)
678 if (status != ISC_R_SUCCESS) {
679 printf ("can't destroy object: %s\n",
680 isc_result_totext (status));
683 omapi_object_dereference (&oh, MDL);
687 token = next_token (&val, (unsigned *)0, cfile);
688 if (token != END_OF_FILE && token != EOL) {
689 printf ("usage: refresh\n");
690 skip_to_semi (cfile);
695 printf ("not connected.\n");
700 printf ("no object.\n");
704 status = dhcpctl_object_refresh(connection, oh);
705 if (status == ISC_R_SUCCESS)
706 status = dhcpctl_wait_for_completion
708 if (status == ISC_R_SUCCESS)
710 if (status != ISC_R_SUCCESS) {
711 printf ("can't refresh object: %s\n",
712 isc_result_totext (status));
724 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
725 control_object_state_t newstate)
727 return ISC_R_SUCCESS;