3 Examine and modify omapi objects. */
6 * Copyright (c) 2004-2006 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.14 2007/05/19 18:47:14 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
46 #include <isc-dhcp/result.h>
52 isc_result_t
find_class (struct class **c
, const char *n
, const char *f
, int l
)
56 int parse_allow_deny (struct option_cache
**oc
, struct parse
*cfile
, int flag
)
60 void dhcp (struct packet
*packet
) { }
61 void bootp (struct packet
*packet
) { }
64 /* XXX: should we warn or something here? */
65 void dhcpv6(struct packet
*packet
) { }
68 int check_collection (struct packet
*p
, struct lease
*l
, struct collection
*c
)
72 void classify (struct packet
*packet
, struct class *class) { }
74 static void usage (char *s
) {
75 fprintf (stderr
, "Usage: %s\n", s
);
79 static void check (isc_result_t status
, const char *func
) {
80 if (status
!= ISC_R_SUCCESS
) {
81 fprintf (stderr
, "%s: %s\n", func
, isc_result_totext (status
));
87 main(int argc
, char **argv
) {
88 isc_result_t status
, waitstatus
;
89 dhcpctl_handle connection
;
90 dhcpctl_handle authenticator
;
92 dhcpctl_data_string cid
, ip_addr
;
93 dhcpctl_data_string result
, groupname
, identifier
;
94 struct data_string secret
;
95 const char *name
= 0, *algorithm
= "hmac-md5";
98 const char *server
= "127.0.0.1";
100 enum dhcp_token token
;
107 for (i
= 1; i
< argc
; i
++) {
111 /* Initially, log errors to stderr as well as to syslogd. */
112 openlog ("omshell", LOG_NDELAY
, DHCPD_LOG_FACILITY
);
113 status
= dhcpctl_initialize ();
114 if (status
!= ISC_R_SUCCESS
) {
115 fprintf (stderr
, "dhcpctl_initialize: %s\n",
116 isc_result_totext (status
));
120 memset (&oh
, 0, sizeof oh
);
124 } else if (oh
== NULL
) {
125 printf ("obj: <null>\n");
127 dhcpctl_remote_object_t
*r
= (dhcpctl_remote_object_t
*)oh
;
128 omapi_generic_object_t
*g
=
129 (omapi_generic_object_t
*)(r
-> inner
);
133 if (r
-> rtype
-> type
!= omapi_datatype_string
) {
137 (int)(r
-> rtype
-> u
. buffer
. len
),
138 r
-> rtype
-> u
. buffer
. value
);
141 for (i
= 0; i
< g
-> nvalues
; i
++) {
142 omapi_value_t
*v
= g
-> values
[i
];
144 if (!g
-> values
[i
])
147 printf ("%.*s = ", (int)v
-> name
-> len
,
154 switch (v
-> value
-> type
) {
155 case omapi_datatype_int
:
157 v
-> value
-> u
. integer
);
160 case omapi_datatype_string
:
161 printf ("\"%.*s\"\n",
162 (int) v
-> value
-> u
.buffer
.len
,
163 v
-> value
-> u
.buffer
.value
);
166 case omapi_datatype_data
:
168 print_hex_1 (v
-> value
-> u
.buffer
.len
,
169 v
-> value
-> u
.buffer
.value
,
173 case omapi_datatype_object
:
180 fputs ("> ", stdout
);
182 if (fgets (buf
, sizeof(buf
), stdin
) == NULL
)
185 status
= new_parse (&cfile
, -1, buf
, strlen(buf
), "<STDIN>", 1);
186 check(status
, "new_parse()");
188 token
= next_token (&val
, (unsigned *)0, cfile
);
191 parse_warn (cfile
, "unknown token: %s", val
);
192 skip_to_semi (cfile
);
201 printf ("Commands:\n");
202 printf (" port <server omapi port>\n");
203 printf (" server <server address>\n");
204 printf (" key <key name> <key value>\n");
205 printf (" connect\n");
206 printf (" new <object-type>\n");
207 printf (" set <name> = <value>\n");
208 printf (" create\n");
210 printf (" update\n");
211 printf (" unset <name>\n");
212 printf (" refresh\n");
213 printf (" remove\n");
214 skip_to_semi (cfile
);
218 token
= next_token (&val
, (unsigned *)0, cfile
);
219 if (is_identifier (token
)) {
221 se
= getservbyname (val
, "tcp");
223 port
= ntohs (se
-> s_port
);
225 printf ("unknown service name: %s\n", val
);
228 } else if (token
== NUMBER
) {
231 skip_to_semi (cfile
);
232 printf ("usage: port <port>\n");
235 token
= next_token (&val
, (unsigned *)0, cfile
);
236 if (token
!= END_OF_FILE
&& token
!= EOL
) {
237 printf ("usage: port <server>\n");
238 skip_to_semi (cfile
);
244 token
= next_token (&val
, (unsigned *)0, cfile
);
245 if (token
== NUMBER
) {
246 int alen
= (sizeof buf
) - 1;
251 if (len
+ 1 > alen
) {
253 printf ("usage: server <server>\n");
254 skip_to_semi (cfile
);
258 token
= next_token (&val
, (unsigned *)0, cfile
);
262 token
= next_token (&val
, (unsigned *)0, cfile
);
270 token
= next_token (&val
, (unsigned *)0, cfile
);
274 token
= next_token (&val
, (unsigned *)0, cfile
);
282 token
= next_token (&val
, (unsigned *)0, cfile
);
286 token
= next_token (&val
, (unsigned *)0, cfile
);
294 } else if (is_identifier (token
)) {
295 /* Use val directly. */
297 printf ("usage: server <server>\n");
298 skip_to_semi (cfile
);
302 s
= dmalloc (strlen (val
) + 1, MDL
);
304 printf ("no memory to store server name.\n");
305 skip_to_semi (cfile
);
311 token
= next_token (&val
, (unsigned *)0, cfile
);
312 if (token
!= END_OF_FILE
&& token
!= EOL
) {
313 printf ("usage: server <server>\n");
314 skip_to_semi (cfile
);
320 token
= next_token (&val
, (unsigned *)0, cfile
);
321 if (!is_identifier (token
)) {
322 printf ("usage: key <name> <value>\n");
323 skip_to_semi (cfile
);
326 s
= dmalloc (strlen (val
) + 1, MDL
);
328 printf ("no memory for key name.\n");
329 skip_to_semi (cfile
);
334 memset (&secret
, 0, sizeof secret
);
335 if (!parse_base64 (&secret
, cfile
)) {
336 skip_to_semi (cfile
);
339 token
= next_token (&val
, (unsigned *)0, cfile
);
340 if (token
!= END_OF_FILE
&& token
!= EOL
) {
341 printf ("usage: key <name> <secret>\n");
342 skip_to_semi (cfile
);
348 token
= next_token (&val
, (unsigned *)0, cfile
);
349 if (token
!= END_OF_FILE
&& token
!= EOL
) {
350 printf ("usage: connect\n");
351 skip_to_semi (cfile
);
355 authenticator
= dhcpctl_null_handle
;
358 status
= dhcpctl_new_authenticator (&authenticator
,
363 if (status
!= ISC_R_SUCCESS
) {
365 "Cannot create authenticator: %s\n",
366 isc_result_totext (status
));
371 memset (&connection
, 0, sizeof connection
);
372 status
= dhcpctl_connect (&connection
,
373 server
, port
, authenticator
);
374 if (status
!= ISC_R_SUCCESS
) {
375 fprintf (stderr
, "dhcpctl_connect: %s\n",
376 isc_result_totext (status
));
383 token
= next_token (&val
, (unsigned *)0, cfile
);
384 if ((!is_identifier (token
) && token
!= STRING
)) {
385 printf ("usage: new <object-type>\n");
390 printf ("an object is already open.\n");
391 skip_to_semi (cfile
);
396 printf ("not connected.\n");
397 skip_to_semi (cfile
);
401 status
= dhcpctl_new_object (&oh
, connection
, val
);
402 if (status
!= ISC_R_SUCCESS
) {
403 printf ("can't create object: %s\n",
404 isc_result_totext (status
));
408 token
= next_token (&val
, (unsigned *)0, cfile
);
409 if (token
!= END_OF_FILE
&& token
!= EOL
) {
410 printf ("usage: new <object-type>\n");
411 skip_to_semi (cfile
);
417 token
= next_token (&val
, (unsigned *)0, cfile
);
418 if (token
!= END_OF_FILE
&& token
!= EOL
) {
419 printf ("usage: close\n");
420 skip_to_semi (cfile
);
425 printf ("not connected.\n");
426 skip_to_semi (cfile
);
431 printf ("not open.\n");
432 skip_to_semi (cfile
);
435 omapi_object_dereference (&oh
, MDL
);
440 token
= next_token (&val
, (unsigned *)0, cfile
);
442 if ((!is_identifier (token
) && token
!= STRING
)) {
444 printf ("usage: set <name> = <value>\n");
445 skip_to_semi (cfile
);
450 printf ("no open object.\n");
451 skip_to_semi (cfile
);
456 printf ("not connected.\n");
457 skip_to_semi (cfile
);
462 strncat (s1
, val
, sizeof(s1
)-1);
464 token
= next_token (&val
, (unsigned *)0, cfile
);
468 token
= next_token (&val
, (unsigned *)0, cfile
);
471 dhcpctl_set_string_value (oh
, val
, s1
);
472 token
= next_token (&val
, (unsigned *)0, cfile
);
477 token
= peek_token (&val
, (unsigned *)0, cfile
);
478 /* Colon-separated hex list? */
481 else if (token
== DOT
) {
485 int intval
= atoi (val
);
489 "dotted octet > 255: %s",
491 skip_to_semi (cfile
);
495 token
= next_token (&val
,
496 (unsigned *)0, cfile
);
500 while ((token
= next_token (&val
,
501 (unsigned *)0, cfile
)) == DOT
)
503 } while (token
== NUMBER
);
504 dhcpctl_set_data_value (oh
, buf
,
509 dhcpctl_set_int_value (oh
, atoi (buf
), s1
);
510 token
= next_token (&val
, (unsigned *)0, cfile
);
520 convert_num (cfile
, (unsigned char *)s
,
523 token
= next_token (&val
,
524 (unsigned *)0, cfile
);
527 token
= next_token (&val
,
528 (unsigned *)0, cfile
);
529 } while (token
== NUMBER
||
530 token
== NUMBER_OR_NAME
);
531 dhcpctl_set_data_value (oh
, buf
,
532 (unsigned)(s
- buf
), s1
);
536 printf ("invalid value.\n");
537 skip_to_semi (cfile
);
540 if (token
!= END_OF_FILE
&& token
!= EOL
)
545 token
= next_token (&val
, (unsigned *)0, cfile
);
547 if ((!is_identifier (token
) && token
!= STRING
)) {
549 printf ("usage: unset <name>\n");
550 skip_to_semi (cfile
);
555 printf ("no open object.\n");
556 skip_to_semi (cfile
);
561 printf ("not connected.\n");
562 skip_to_semi (cfile
);
567 strncat (s1
, val
, sizeof(s1
)-1);
569 token
= next_token (&val
, (unsigned *)0, cfile
);
570 if (token
!= END_OF_FILE
&& token
!= EOL
)
573 dhcpctl_set_null_value (oh
, s1
);
580 token
= next_token (&val
, (unsigned *)0, cfile
);
581 if (token
!= END_OF_FILE
&& token
!= EOL
) {
582 printf ("usage: %s\n", val
);
583 skip_to_semi (cfile
);
588 printf ("not connected.\n");
589 skip_to_semi (cfile
);
594 printf ("you must make a new object first!\n");
595 skip_to_semi (cfile
);
599 if (i
== TOKEN_CREATE
)
600 i
= DHCPCTL_CREATE
| DHCPCTL_EXCL
;
604 status
= dhcpctl_open_object (oh
, connection
, i
);
605 if (status
== ISC_R_SUCCESS
)
606 status
= dhcpctl_wait_for_completion
608 if (status
== ISC_R_SUCCESS
)
610 if (status
!= ISC_R_SUCCESS
) {
611 printf ("can't open object: %s\n",
612 isc_result_totext (status
));
619 token
= next_token (&val
, (unsigned *)0, cfile
);
620 if (token
!= END_OF_FILE
&& token
!= EOL
) {
621 printf ("usage: %s\n", val
);
622 skip_to_semi (cfile
);
627 printf ("not connected.\n");
628 skip_to_semi (cfile
);
633 printf ("you haven't opened an object yet!\n");
634 skip_to_semi (cfile
);
638 status
= dhcpctl_object_update(connection
, oh
);
639 if (status
== ISC_R_SUCCESS
)
640 status
= dhcpctl_wait_for_completion
642 if (status
== ISC_R_SUCCESS
)
644 if (status
!= ISC_R_SUCCESS
) {
645 printf ("can't update object: %s\n",
646 isc_result_totext (status
));
653 token
= next_token (&val
, (unsigned *)0, cfile
);
654 if (token
!= END_OF_FILE
&& token
!= EOL
) {
655 printf ("usage: remove\n");
656 skip_to_semi (cfile
);
661 printf ("not connected.\n");
666 printf ("no object.\n");
670 status
= dhcpctl_object_remove(connection
, oh
);
671 if (status
== ISC_R_SUCCESS
)
672 status
= dhcpctl_wait_for_completion
674 if (status
== ISC_R_SUCCESS
)
676 if (status
!= ISC_R_SUCCESS
) {
677 printf ("can't destroy object: %s\n",
678 isc_result_totext (status
));
681 omapi_object_dereference (&oh
, MDL
);
685 token
= next_token (&val
, (unsigned *)0, cfile
);
686 if (token
!= END_OF_FILE
&& token
!= EOL
) {
687 printf ("usage: refresh\n");
688 skip_to_semi (cfile
);
693 printf ("not connected.\n");
698 printf ("no object.\n");
702 status
= dhcpctl_object_refresh(connection
, oh
);
703 if (status
== ISC_R_SUCCESS
)
704 status
= dhcpctl_wait_for_completion
706 if (status
== ISC_R_SUCCESS
)
708 if (status
!= ISC_R_SUCCESS
) {
709 printf ("can't refresh object: %s\n",
710 isc_result_totext (status
));
723 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
724 control_object_state_t newstate
)
726 return ISC_R_SUCCESS
;