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.5 2005/08/11 17:13:21 drochner 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 struct data_string secret
;
86 const char *name
= 0, *algorithm
= "hmac-md5";
89 const char *server
= "127.0.0.1";
91 enum dhcp_token token
;
98 for (i
= 1; i
< argc
; i
++) {
102 /* Initially, log errors to stderr as well as to syslogd. */
104 openlog ("omshell", LOG_NDELAY
);
105 log_priority
= DHCPD_LOG_FACILITY
;
107 openlog ("omshell", LOG_NDELAY
, DHCPD_LOG_FACILITY
);
109 status
= dhcpctl_initialize ();
110 if (status
!= ISC_R_SUCCESS
) {
111 fprintf (stderr
, "dhcpctl_initialize: %s\n",
112 isc_result_totext (status
));
116 memset (&oh
, 0, sizeof oh
);
120 } else if (oh
== NULL
) {
121 printf ("obj: <null>\n");
123 dhcpctl_remote_object_t
*r
= (dhcpctl_remote_object_t
*)oh
;
124 omapi_generic_object_t
*g
=
125 (omapi_generic_object_t
*)(r
-> inner
);
129 if (r
-> rtype
-> type
!= omapi_datatype_string
) {
133 (int)(r
-> rtype
-> u
. buffer
. len
),
134 r
-> rtype
-> u
. buffer
. value
);
137 for (i
= 0; i
< g
-> nvalues
; i
++) {
138 omapi_value_t
*v
= g
-> values
[i
];
140 if (!g
-> values
[i
])
143 printf ("%.*s = ", (int)v
-> name
-> len
,
150 switch (v
-> value
-> type
) {
151 case omapi_datatype_int
:
153 v
-> value
-> u
. integer
);
156 case omapi_datatype_string
:
157 printf ("\"%.*s\"\n",
158 (int) v
-> value
-> u
.buffer
.len
,
159 v
-> value
-> u
.buffer
.value
);
162 case omapi_datatype_data
:
164 print_hex_1 (v
-> value
-> u
.buffer
.len
,
165 v
-> value
-> u
.buffer
.value
,
169 case omapi_datatype_object
:
176 fputs ("> ", stdout
);
178 if (fgets (buf
, sizeof(buf
), stdin
) == NULL
)
181 status
= new_parse (&cfile
, 0, buf
, strlen(buf
), "<STDIN>", 1);
182 check(status
, "new_parse()");
184 token
= next_token (&val
, (unsigned *)0, cfile
);
187 parse_warn (cfile
, "unknown token: %s", val
);
188 skip_to_semi (cfile
);
197 printf ("Commands:\n");
198 printf (" port <server omapi port>\n");
199 printf (" server <server address>\n");
200 printf (" key <key name> <key value>\n");
201 printf (" connect\n");
202 printf (" new <object-type>\n");
203 printf (" set <name> = <value>\n");
204 printf (" create\n");
206 printf (" update\n");
207 printf (" unset <name>\n");
208 printf (" refresh\n");
209 printf (" remove\n");
210 skip_to_semi (cfile
);
214 token
= next_token (&val
, (unsigned *)0, cfile
);
215 if (is_identifier (token
)) {
217 se
= getservbyname (val
, "tcp");
219 port
= ntohs (se
-> s_port
);
221 printf ("unknown service name: %s\n", val
);
224 } else if (token
== NUMBER
) {
227 skip_to_semi (cfile
);
228 printf ("usage: port <port>\n");
231 token
= next_token (&val
, (unsigned *)0, cfile
);
232 if (token
!= END_OF_FILE
&& token
!= EOL
) {
233 printf ("usage: port <server>\n");
234 skip_to_semi (cfile
);
240 token
= next_token (&val
, (unsigned *)0, cfile
);
241 if (token
== NUMBER
) {
242 int alen
= (sizeof buf
) - 1;
247 if (len
+ 1 > alen
) {
249 printf ("usage: server <server>\n");
250 skip_to_semi (cfile
);
254 token
= next_token (&val
, (unsigned *)0, cfile
);
258 token
= next_token (&val
, (unsigned *)0, cfile
);
266 token
= next_token (&val
, (unsigned *)0, cfile
);
270 token
= next_token (&val
, (unsigned *)0, cfile
);
278 token
= next_token (&val
, (unsigned *)0, cfile
);
282 token
= next_token (&val
, (unsigned *)0, cfile
);
290 } else if (is_identifier (token
)) {
291 /* Use val directly. */
293 printf ("usage: server <server>\n");
294 skip_to_semi (cfile
);
298 s
= dmalloc (strlen (val
) + 1, MDL
);
300 printf ("no memory to store server name.\n");
301 skip_to_semi (cfile
);
307 token
= next_token (&val
, (unsigned *)0, cfile
);
308 if (token
!= END_OF_FILE
&& token
!= EOL
) {
309 printf ("usage: server <server>\n");
310 skip_to_semi (cfile
);
316 token
= next_token (&val
, (unsigned *)0, cfile
);
317 if (!is_identifier (token
)) {
318 printf ("usage: key <name> <value>\n");
319 skip_to_semi (cfile
);
322 s
= dmalloc (strlen (val
) + 1, MDL
);
324 printf ("no memory for key name.\n");
325 skip_to_semi (cfile
);
330 memset (&secret
, 0, sizeof secret
);
331 if (!parse_base64 (&secret
, cfile
)) {
332 skip_to_semi (cfile
);
335 token
= next_token (&val
, (unsigned *)0, cfile
);
336 if (token
!= END_OF_FILE
&& token
!= EOL
) {
337 printf ("usage: key <name> <secret>\n");
338 skip_to_semi (cfile
);
344 token
= next_token (&val
, (unsigned *)0, cfile
);
345 if (token
!= END_OF_FILE
&& token
!= EOL
) {
346 printf ("usage: connect\n");
347 skip_to_semi (cfile
);
351 authenticator
= dhcpctl_null_handle
;
354 status
= dhcpctl_new_authenticator (&authenticator
,
359 if (status
!= ISC_R_SUCCESS
) {
361 "Cannot create authenticator: %s\n",
362 isc_result_totext (status
));
367 memset (&connection
, 0, sizeof connection
);
368 status
= dhcpctl_connect (&connection
,
369 server
, port
, authenticator
);
370 if (status
!= ISC_R_SUCCESS
) {
371 fprintf (stderr
, "dhcpctl_connect: %s\n",
372 isc_result_totext (status
));
379 token
= next_token (&val
, (unsigned *)0, cfile
);
380 if ((!is_identifier (token
) && token
!= STRING
)) {
381 printf ("usage: new <object-type>\n");
386 printf ("an object is already open.\n");
387 skip_to_semi (cfile
);
392 printf ("not connected.\n");
393 skip_to_semi (cfile
);
397 status
= dhcpctl_new_object (&oh
, connection
, val
);
398 if (status
!= ISC_R_SUCCESS
) {
399 printf ("can't create object: %s\n",
400 isc_result_totext (status
));
404 token
= next_token (&val
, (unsigned *)0, cfile
);
405 if (token
!= END_OF_FILE
&& token
!= EOL
) {
406 printf ("usage: new <object-type>\n");
407 skip_to_semi (cfile
);
413 token
= next_token (&val
, (unsigned *)0, cfile
);
414 if (token
!= END_OF_FILE
&& token
!= EOL
) {
415 printf ("usage: close\n");
416 skip_to_semi (cfile
);
421 printf ("not connected.\n");
422 skip_to_semi (cfile
);
427 printf ("not open.\n");
428 skip_to_semi (cfile
);
431 omapi_object_dereference (&oh
, MDL
);
436 token
= next_token (&val
, (unsigned *)0, cfile
);
438 if ((!is_identifier (token
) && token
!= STRING
)) {
440 printf ("usage: set <name> = <value>\n");
441 skip_to_semi (cfile
);
446 printf ("no open object.\n");
447 skip_to_semi (cfile
);
452 printf ("not connected.\n");
453 skip_to_semi (cfile
);
458 strncat (s1
, val
, sizeof(s1
)-1);
460 token
= next_token (&val
, (unsigned *)0, cfile
);
464 token
= next_token (&val
, (unsigned *)0, cfile
);
467 dhcpctl_set_string_value (oh
, val
, s1
);
468 token
= next_token (&val
, (unsigned *)0, cfile
);
473 token
= peek_token (&val
, (unsigned *)0, cfile
);
474 /* Colon-seperated hex list? */
477 else if (token
== DOT
) {
481 int intval
= atoi (val
);
485 "dotted octet > 255: %s",
487 skip_to_semi (cfile
);
491 token
= next_token (&val
,
492 (unsigned *)0, cfile
);
496 while ((token
= next_token (&val
,
497 (unsigned *)0, cfile
)) == DOT
)
499 } while (token
== NUMBER
);
500 dhcpctl_set_data_value (oh
, buf
,
505 dhcpctl_set_int_value (oh
, atoi (buf
), s1
);
506 token
= next_token (&val
, (unsigned *)0, cfile
);
516 convert_num (cfile
, (unsigned char *)s
,
519 token
= next_token (&val
,
520 (unsigned *)0, cfile
);
523 token
= next_token (&val
,
524 (unsigned *)0, cfile
);
525 } while (token
== NUMBER
||
526 token
== NUMBER_OR_NAME
);
527 dhcpctl_set_data_value (oh
, buf
,
528 (unsigned)(s
- buf
), s1
);
532 printf ("invalid value.\n");
533 skip_to_semi (cfile
);
536 if (token
!= END_OF_FILE
&& token
!= EOL
)
541 token
= next_token (&val
, (unsigned *)0, cfile
);
543 if ((!is_identifier (token
) && token
!= STRING
)) {
545 printf ("usage: unset <name>\n");
546 skip_to_semi (cfile
);
551 printf ("no open object.\n");
552 skip_to_semi (cfile
);
557 printf ("not connected.\n");
558 skip_to_semi (cfile
);
563 strncat (s1
, val
, sizeof(s1
)-1);
565 token
= next_token (&val
, (unsigned *)0, cfile
);
566 if (token
!= END_OF_FILE
&& token
!= EOL
)
569 dhcpctl_set_null_value (oh
, s1
);
576 token
= next_token (&val
, (unsigned *)0, cfile
);
577 if (token
!= END_OF_FILE
&& token
!= EOL
) {
578 printf ("usage: %s\n", val
);
579 skip_to_semi (cfile
);
584 printf ("not connected.\n");
585 skip_to_semi (cfile
);
590 printf ("you must make a new object first!\n");
591 skip_to_semi (cfile
);
595 if (i
== TOKEN_CREATE
)
596 i
= DHCPCTL_CREATE
| DHCPCTL_EXCL
;
600 status
= dhcpctl_open_object (oh
, connection
, i
);
601 if (status
== ISC_R_SUCCESS
)
602 status
= dhcpctl_wait_for_completion
604 if (status
== ISC_R_SUCCESS
)
606 if (status
!= ISC_R_SUCCESS
) {
607 printf ("can't open object: %s\n",
608 isc_result_totext (status
));
615 token
= next_token (&val
, (unsigned *)0, cfile
);
616 if (token
!= END_OF_FILE
&& token
!= EOL
) {
617 printf ("usage: %s\n", val
);
618 skip_to_semi (cfile
);
623 printf ("not connected.\n");
624 skip_to_semi (cfile
);
629 printf ("you haven't opened an object yet!\n");
630 skip_to_semi (cfile
);
634 status
= dhcpctl_object_update(connection
, oh
);
635 if (status
== ISC_R_SUCCESS
)
636 status
= dhcpctl_wait_for_completion
638 if (status
== ISC_R_SUCCESS
)
640 if (status
!= ISC_R_SUCCESS
) {
641 printf ("can't update object: %s\n",
642 isc_result_totext (status
));
649 token
= next_token (&val
, (unsigned *)0, cfile
);
650 if (token
!= END_OF_FILE
&& token
!= EOL
) {
651 printf ("usage: remove\n");
652 skip_to_semi (cfile
);
657 printf ("not connected.\n");
662 printf ("no object.\n");
666 status
= dhcpctl_object_remove(connection
, oh
);
667 if (status
== ISC_R_SUCCESS
)
668 status
= dhcpctl_wait_for_completion
670 if (status
== ISC_R_SUCCESS
)
672 if (status
!= ISC_R_SUCCESS
) {
673 printf ("can't destroy object: %s\n",
674 isc_result_totext (status
));
677 omapi_object_dereference (&oh
, MDL
);
681 token
= next_token (&val
, (unsigned *)0, cfile
);
682 if (token
!= END_OF_FILE
&& token
!= EOL
) {
683 printf ("usage: refresh\n");
684 skip_to_semi (cfile
);
689 printf ("not connected.\n");
694 printf ("no object.\n");
698 status
= dhcpctl_object_refresh(connection
, oh
);
699 if (status
== ISC_R_SUCCESS
)
700 status
= dhcpctl_wait_for_completion
702 if (status
== ISC_R_SUCCESS
)
704 if (status
!= ISC_R_SUCCESS
) {
705 printf ("can't refresh object: %s\n",
706 isc_result_totext (status
));
719 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
720 control_object_state_t newstate
)
722 return ISC_R_SUCCESS
;