3 Examine and modify omapi objects. */
6 * Copyright (c) 2004-2007 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
25 * https://www.isc.org/
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 * ``https://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''.
47 isc_result_t
find_class (struct class **c
, const char *n
, const char *f
, int l
)
51 int parse_allow_deny (struct option_cache
**oc
, struct parse
*cfile
, int flag
)
55 void dhcp (struct packet
*packet
) { }
56 void bootp (struct packet
*packet
) { }
59 /* XXX: should we warn or something here? */
60 void dhcpv6(struct packet
*packet
) { }
63 int check_collection (struct packet
*p
, struct lease
*l
, struct collection
*c
)
67 void classify (struct packet
*packet
, struct class *class) { }
69 static void usage (char *s
) {
70 fprintf (stderr
, "Usage: %s\n", s
);
74 static void check (isc_result_t status
, const char *func
) {
75 if (status
!= ISC_R_SUCCESS
) {
76 fprintf (stderr
, "%s: %s\n", func
, isc_result_totext (status
));
82 main(int argc
, char **argv
) {
83 isc_result_t status
, waitstatus
;
84 dhcpctl_handle connection
;
85 dhcpctl_handle authenticator
;
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. */
105 openlog ("omshell", LOG_NDELAY
, DHCPD_LOG_FACILITY
);
106 status
= dhcpctl_initialize ();
107 if (status
!= ISC_R_SUCCESS
) {
108 fprintf (stderr
, "dhcpctl_initialize: %s\n",
109 isc_result_totext (status
));
113 memset (&oh
, 0, sizeof oh
);
117 } else if (oh
== NULL
) {
118 printf ("obj: <null>\n");
120 dhcpctl_remote_object_t
*r
= (dhcpctl_remote_object_t
*)oh
;
121 omapi_generic_object_t
*g
=
122 (omapi_generic_object_t
*)(r
-> inner
);
126 if (r
-> rtype
-> type
!= omapi_datatype_string
) {
130 (int)(r
-> rtype
-> u
. buffer
. len
),
131 r
-> rtype
-> u
. buffer
. value
);
134 for (i
= 0; i
< g
-> nvalues
; i
++) {
135 omapi_value_t
*v
= g
-> values
[i
];
137 if (!g
-> values
[i
])
140 printf ("%.*s = ", (int)v
-> name
-> len
,
147 switch (v
-> value
-> type
) {
148 case omapi_datatype_int
:
150 v
-> value
-> u
. integer
);
153 case omapi_datatype_string
:
154 printf ("\"%.*s\"\n",
155 (int) v
-> value
-> u
.buffer
.len
,
156 v
-> value
-> u
.buffer
.value
);
159 case omapi_datatype_data
:
161 print_hex_1 (v
-> value
-> u
.buffer
.len
,
162 v
-> value
-> u
.buffer
.value
,
166 case omapi_datatype_object
:
173 fputs ("> ", stdout
);
175 if (fgets (buf
, sizeof(buf
), stdin
) == NULL
)
178 status
= new_parse (&cfile
, -1, buf
, strlen(buf
), "<STDIN>", 1);
179 check(status
, "new_parse()");
181 token
= next_token (&val
, (unsigned *)0, cfile
);
184 parse_warn (cfile
, "unknown token: %s", val
);
185 skip_to_semi (cfile
);
194 printf ("Commands:\n");
195 printf (" port <server omapi port>\n");
196 printf (" server <server address>\n");
197 printf (" key <key name> <key value>\n");
198 printf (" connect\n");
199 printf (" new <object-type>\n");
200 printf (" set <name> = <value>\n");
201 printf (" create\n");
203 printf (" update\n");
204 printf (" unset <name>\n");
205 printf (" refresh\n");
206 printf (" remove\n");
207 skip_to_semi (cfile
);
211 token
= next_token (&val
, (unsigned *)0, cfile
);
212 if (is_identifier (token
)) {
214 se
= getservbyname (val
, "tcp");
216 port
= ntohs (se
-> s_port
);
218 printf ("unknown service name: %s\n", val
);
221 } else if (token
== NUMBER
) {
224 skip_to_semi (cfile
);
225 printf ("usage: port <port>\n");
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
);
237 token
= next_token (&val
, (unsigned *)0, cfile
);
238 if (token
== NUMBER
) {
239 int alen
= (sizeof buf
) - 1;
244 if (len
+ 1 > alen
) {
246 printf ("usage: server <server>\n");
247 skip_to_semi (cfile
);
251 token
= next_token (&val
, (unsigned *)0, cfile
);
255 token
= next_token (&val
, (unsigned *)0, cfile
);
263 token
= next_token (&val
, (unsigned *)0, cfile
);
267 token
= next_token (&val
, (unsigned *)0, cfile
);
275 token
= next_token (&val
, (unsigned *)0, cfile
);
279 token
= next_token (&val
, (unsigned *)0, cfile
);
287 } else if (is_identifier (token
)) {
288 /* Use val directly. */
290 printf ("usage: server <server>\n");
291 skip_to_semi (cfile
);
295 s
= dmalloc (strlen (val
) + 1, MDL
);
297 printf ("no memory to store server name.\n");
298 skip_to_semi (cfile
);
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
);
313 token
= peek_token(&val
, (unsigned *)0, cfile
);
314 if (token
== STRING
) {
315 token
= next_token (&val
, (unsigned *)0, cfile
);
316 if (!is_identifier (token
)) {
317 printf ("usage: key <name> <value>\n");
318 skip_to_semi (cfile
);
321 s
= dmalloc (strlen (val
) + 1, MDL
);
323 printf ("no memory for key name.\n");
324 skip_to_semi (cfile
);
329 s
= parse_host_name(cfile
);
331 printf ("usage: key <name> <value>\n");
338 memset (&secret
, 0, sizeof secret
);
339 if (!parse_base64 (&secret
, cfile
)) {
340 skip_to_semi (cfile
);
343 token
= next_token (&val
, (unsigned *)0, cfile
);
344 if (token
!= END_OF_FILE
&& token
!= EOL
) {
345 printf ("usage: key <name> <secret>\n");
346 skip_to_semi (cfile
);
352 token
= next_token (&val
, (unsigned *)0, cfile
);
353 if (token
!= END_OF_FILE
&& token
!= EOL
) {
354 printf ("usage: connect\n");
355 skip_to_semi (cfile
);
359 authenticator
= dhcpctl_null_handle
;
362 status
= dhcpctl_new_authenticator (&authenticator
,
367 if (status
!= ISC_R_SUCCESS
) {
369 "Cannot create authenticator: %s\n",
370 isc_result_totext (status
));
375 memset (&connection
, 0, sizeof connection
);
376 status
= dhcpctl_connect (&connection
,
377 server
, port
, authenticator
);
378 if (status
!= ISC_R_SUCCESS
) {
379 fprintf (stderr
, "dhcpctl_connect: %s\n",
380 isc_result_totext (status
));
387 token
= next_token (&val
, (unsigned *)0, cfile
);
388 if ((!is_identifier (token
) && token
!= STRING
)) {
389 printf ("usage: new <object-type>\n");
394 printf ("an object is already open.\n");
395 skip_to_semi (cfile
);
400 printf ("not connected.\n");
401 skip_to_semi (cfile
);
405 status
= dhcpctl_new_object (&oh
, connection
, val
);
406 if (status
!= ISC_R_SUCCESS
) {
407 printf ("can't create object: %s\n",
408 isc_result_totext (status
));
412 token
= next_token (&val
, (unsigned *)0, cfile
);
413 if (token
!= END_OF_FILE
&& token
!= EOL
) {
414 printf ("usage: new <object-type>\n");
415 skip_to_semi (cfile
);
421 token
= next_token (&val
, (unsigned *)0, cfile
);
422 if (token
!= END_OF_FILE
&& token
!= EOL
) {
423 printf ("usage: close\n");
424 skip_to_semi (cfile
);
429 printf ("not connected.\n");
430 skip_to_semi (cfile
);
435 printf ("not open.\n");
436 skip_to_semi (cfile
);
439 omapi_object_dereference (&oh
, MDL
);
444 token
= next_token (&val
, (unsigned *)0, cfile
);
446 if ((!is_identifier (token
) && token
!= STRING
)) {
448 printf ("usage: set <name> = <value>\n");
449 skip_to_semi (cfile
);
454 printf ("no open object.\n");
455 skip_to_semi (cfile
);
460 printf ("not connected.\n");
461 skip_to_semi (cfile
);
466 strncat (s1
, val
, sizeof(s1
)-1);
468 token
= next_token (&val
, (unsigned *)0, cfile
);
472 token
= next_token (&val
, (unsigned *)0, cfile
);
475 dhcpctl_set_string_value (oh
, val
, s1
);
476 token
= next_token (&val
, (unsigned *)0, cfile
);
481 token
= peek_token (&val
, (unsigned *)0, cfile
);
482 /* Colon-separated hex list? */
485 else if (token
== DOT
) {
489 int intval
= atoi (val
);
492 "dotted octet > 255: %s",
494 skip_to_semi (cfile
);
498 token
= next_token (&val
,
499 (unsigned *)0, cfile
);
503 while ((token
= next_token (&val
,
504 (unsigned *)0, cfile
)) == DOT
)
506 } while (token
== NUMBER
);
507 dhcpctl_set_data_value (oh
, buf
,
512 dhcpctl_set_int_value (oh
, atoi (buf
), s1
);
513 token
= next_token (&val
, (unsigned *)0, cfile
);
523 convert_num (cfile
, (unsigned char *)s
,
526 token
= next_token (&val
,
527 (unsigned *)0, cfile
);
530 token
= next_token (&val
,
531 (unsigned *)0, cfile
);
532 } while (token
== NUMBER
||
533 token
== NUMBER_OR_NAME
);
534 dhcpctl_set_data_value (oh
, buf
,
535 (unsigned)(s
- buf
), s1
);
539 printf ("invalid value.\n");
540 skip_to_semi (cfile
);
543 if (token
!= END_OF_FILE
&& token
!= EOL
)
548 token
= next_token (&val
, (unsigned *)0, cfile
);
550 if ((!is_identifier (token
) && token
!= STRING
)) {
552 printf ("usage: unset <name>\n");
553 skip_to_semi (cfile
);
558 printf ("no open object.\n");
559 skip_to_semi (cfile
);
564 printf ("not connected.\n");
565 skip_to_semi (cfile
);
570 strncat (s1
, val
, sizeof(s1
)-1);
572 token
= next_token (&val
, (unsigned *)0, cfile
);
573 if (token
!= END_OF_FILE
&& token
!= EOL
)
576 dhcpctl_set_null_value (oh
, s1
);
583 token
= next_token (&val
, (unsigned *)0, cfile
);
584 if (token
!= END_OF_FILE
&& token
!= EOL
) {
585 printf ("usage: %s\n", val
);
586 skip_to_semi (cfile
);
591 printf ("not connected.\n");
592 skip_to_semi (cfile
);
597 printf ("you must make a new object first!\n");
598 skip_to_semi (cfile
);
602 if (i
== TOKEN_CREATE
)
603 i
= DHCPCTL_CREATE
| DHCPCTL_EXCL
;
607 status
= dhcpctl_open_object (oh
, connection
, i
);
608 if (status
== ISC_R_SUCCESS
)
609 status
= dhcpctl_wait_for_completion
611 if (status
== ISC_R_SUCCESS
)
613 if (status
!= ISC_R_SUCCESS
) {
614 printf ("can't open object: %s\n",
615 isc_result_totext (status
));
622 token
= next_token (&val
, (unsigned *)0, cfile
);
623 if (token
!= END_OF_FILE
&& token
!= EOL
) {
624 printf ("usage: %s\n", val
);
625 skip_to_semi (cfile
);
630 printf ("not connected.\n");
631 skip_to_semi (cfile
);
636 printf ("you haven't opened an object yet!\n");
637 skip_to_semi (cfile
);
641 status
= dhcpctl_object_update(connection
, oh
);
642 if (status
== ISC_R_SUCCESS
)
643 status
= dhcpctl_wait_for_completion
645 if (status
== ISC_R_SUCCESS
)
647 if (status
!= ISC_R_SUCCESS
) {
648 printf ("can't update object: %s\n",
649 isc_result_totext (status
));
656 token
= next_token (&val
, (unsigned *)0, cfile
);
657 if (token
!= END_OF_FILE
&& token
!= EOL
) {
658 printf ("usage: remove\n");
659 skip_to_semi (cfile
);
664 printf ("not connected.\n");
669 printf ("no object.\n");
673 status
= dhcpctl_object_remove(connection
, oh
);
674 if (status
== ISC_R_SUCCESS
)
675 status
= dhcpctl_wait_for_completion
677 if (status
== ISC_R_SUCCESS
)
679 if (status
!= ISC_R_SUCCESS
) {
680 printf ("can't destroy object: %s\n",
681 isc_result_totext (status
));
684 omapi_object_dereference (&oh
, MDL
);
688 token
= next_token (&val
, (unsigned *)0, cfile
);
689 if (token
!= END_OF_FILE
&& token
!= EOL
) {
690 printf ("usage: refresh\n");
691 skip_to_semi (cfile
);
696 printf ("not connected.\n");
701 printf ("no object.\n");
705 status
= dhcpctl_object_refresh(connection
, oh
);
706 if (status
== ISC_R_SUCCESS
)
707 status
= dhcpctl_wait_for_completion
709 if (status
== ISC_R_SUCCESS
)
711 if (status
!= ISC_R_SUCCESS
) {
712 printf ("can't refresh object: %s\n",
713 isc_result_totext (status
));
726 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
727 control_object_state_t newstate
)
729 return ISC_R_SUCCESS
;