3 Examine and modify omapi objects. */
6 * Copyright (c) 2009-2011,2013 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 2001-2003 by Internet Software Consortium
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * Internet Systems Consortium, Inc.
24 * Redwood City, CA 94063
26 * https://www.isc.org/
28 * This software has been written for Internet Systems Consortium
29 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
30 * To learn more about Internet Systems Consortium, see
31 * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
32 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
33 * ``http://www.nominum.com''.
50 isc_result_t
find_class (struct class **c
, const char *n
, const char *f
, int l
)
54 int parse_allow_deny (struct option_cache
**oc
, struct parse
*cfile
, int flag
)
58 void dhcp (struct packet
*packet
) { }
59 void bootp (struct packet
*packet
) { }
62 /* XXX: should we warn or something here? */
63 void dhcpv6(struct packet
*packet
) { }
66 int check_collection (struct packet
*p
, struct lease
*l
, struct collection
*c
)
70 void classify (struct packet
*packet
, struct class *class) { }
72 static void usage (char *s
) {
73 fprintf (stderr
, "Usage: %s\n", s
);
77 static void check (isc_result_t status
, const char *func
) {
78 if (status
!= ISC_R_SUCCESS
) {
79 fprintf (stderr
, "%s: %s\n", func
, isc_result_totext (status
));
85 main(int argc
, char **argv
) {
86 isc_result_t status
, waitstatus
;
87 dhcpctl_handle connection
;
88 dhcpctl_handle authenticator
;
90 struct data_string secret
;
91 const char *name
= 0, *algorithm
= "hmac-md5";
94 const char *server
= "127.0.0.1";
96 enum dhcp_token token
;
104 for (i
= 1; i
< argc
; i
++) {
108 /* Initially, log errors to stderr as well as to syslogd. */
109 openlog ("omshell", LOG_NDELAY
, DHCPD_LOG_FACILITY
);
110 status
= dhcpctl_initialize ();
111 if (status
!= ISC_R_SUCCESS
) {
112 fprintf (stderr
, "dhcpctl_initialize: %s\n",
113 isc_result_totext (status
));
117 memset (&oh
, 0, sizeof oh
);
121 } else if (oh
== NULL
) {
122 printf ("obj: <null>\n");
124 dhcpctl_remote_object_t
*r
= (dhcpctl_remote_object_t
*)oh
;
125 omapi_generic_object_t
*g
=
126 (omapi_generic_object_t
*)(r
-> inner
);
130 if (r
-> rtype
-> type
!= omapi_datatype_string
) {
134 (int)(r
-> rtype
-> u
. buffer
. len
),
135 r
-> rtype
-> u
. buffer
. value
);
138 for (i
= 0; i
< g
-> nvalues
; i
++) {
139 omapi_value_t
*v
= g
-> values
[i
];
141 if (!g
-> values
[i
])
144 printf ("%.*s = ", (int)v
-> name
-> len
,
151 switch (v
-> value
-> type
) {
152 case omapi_datatype_int
:
154 v
-> value
-> u
. integer
);
157 case omapi_datatype_string
:
158 printf ("\"%.*s\"\n",
159 (int) v
-> value
-> u
.buffer
.len
,
160 v
-> value
-> u
.buffer
.value
);
163 case omapi_datatype_data
:
164 print_hex_or_string(v
->value
->u
.buffer
.len
,
165 v
->value
->u
.buffer
.value
,
166 sizeof(hex_buf
), hex_buf
);
167 printf("%s\n", hex_buf
);
170 case omapi_datatype_object
:
177 fputs ("> ", stdout
);
179 if (fgets (buf
, sizeof(buf
), stdin
) == NULL
)
182 status
= new_parse (&cfile
, -1, buf
, strlen(buf
), "<STDIN>", 1);
183 check(status
, "new_parse()");
185 token
= next_token (&val
, (unsigned *)0, cfile
);
188 parse_warn (cfile
, "unknown token: %s", val
);
189 skip_to_semi (cfile
);
193 case ENDOFLINE
: /* EOL: */
197 case QUESTIONMARK
: /* '?': */
198 printf ("Commands:\n");
199 printf (" port <server omapi port>\n");
200 printf (" server <server address>\n");
201 printf (" key <key name> <key value>\n");
202 printf (" connect\n");
203 printf (" new <object-type>\n");
204 printf (" set <name> = <value>\n");
205 printf (" create\n");
207 printf (" update\n");
208 printf (" unset <name>\n");
209 printf (" refresh\n");
210 printf (" remove\n");
211 skip_to_semi (cfile
);
215 token
= next_token (&val
, (unsigned *)0, cfile
);
216 if (is_identifier (token
)) {
218 se
= getservbyname (val
, "tcp");
220 port
= ntohs (se
-> s_port
);
222 printf ("unknown service name: %s\n", val
);
225 } else if (token
== NUMBER
) {
228 skip_to_semi (cfile
);
229 printf ("usage: port <port>\n");
232 token
= next_token (&val
, (unsigned *)0, cfile
);
233 if (token
!= END_OF_FILE
&& token
!= EOL
) {
234 printf ("usage: port <server>\n");
235 skip_to_semi (cfile
);
241 token
= next_token (&val
, (unsigned *)0, cfile
);
242 if (token
== NUMBER
) {
243 int alen
= (sizeof buf
) - 1;
248 if (len
+ 1 > alen
) {
250 printf ("usage: server <server>\n");
251 skip_to_semi (cfile
);
255 token
= next_token (&val
, (unsigned *)0, cfile
);
259 token
= next_token (&val
, (unsigned *)0, cfile
);
267 token
= next_token (&val
, (unsigned *)0, cfile
);
271 token
= next_token (&val
, (unsigned *)0, cfile
);
279 token
= next_token (&val
, (unsigned *)0, cfile
);
283 token
= next_token (&val
, (unsigned *)0, cfile
);
291 } else if (is_identifier (token
)) {
292 /* Use val directly. */
294 printf ("usage: server <server>\n");
295 skip_to_semi (cfile
);
299 s
= dmalloc (strlen (val
) + 1, MDL
);
301 printf ("no memory to store server name.\n");
302 skip_to_semi (cfile
);
308 token
= next_token (&val
, (unsigned *)0, cfile
);
309 if (token
!= END_OF_FILE
&& token
!= EOL
) {
310 printf ("usage: server <server>\n");
311 skip_to_semi (cfile
);
317 token
= peek_token(&val
, (unsigned *)0, cfile
);
318 if (token
== STRING
) {
319 token
= next_token (&val
, (unsigned *)0, cfile
);
320 if (!is_identifier (token
)) {
321 printf ("usage: key <name> <value>\n");
322 skip_to_semi (cfile
);
325 s
= dmalloc (strlen (val
) + 1, MDL
);
327 printf ("no memory for key name.\n");
328 skip_to_semi (cfile
);
333 s
= parse_host_name(cfile
);
335 printf ("usage: key <name> <value>\n");
342 memset (&secret
, 0, sizeof secret
);
343 if (!parse_base64 (&secret
, cfile
)) {
344 skip_to_semi (cfile
);
347 token
= next_token (&val
, (unsigned *)0, cfile
);
348 if (token
!= END_OF_FILE
&& token
!= EOL
) {
349 printf ("usage: key <name> <secret>\n");
350 skip_to_semi (cfile
);
356 token
= next_token (&val
, (unsigned *)0, cfile
);
357 if (token
!= END_OF_FILE
&& token
!= EOL
) {
358 printf ("usage: connect\n");
359 skip_to_semi (cfile
);
363 authenticator
= dhcpctl_null_handle
;
366 status
= dhcpctl_new_authenticator (&authenticator
,
371 if (status
!= ISC_R_SUCCESS
) {
373 "Cannot create authenticator: %s\n",
374 isc_result_totext (status
));
379 memset (&connection
, 0, sizeof connection
);
380 status
= dhcpctl_connect (&connection
,
381 server
, port
, authenticator
);
382 if (status
!= ISC_R_SUCCESS
) {
383 fprintf (stderr
, "dhcpctl_connect: %s\n",
384 isc_result_totext (status
));
391 token
= next_token (&val
, (unsigned *)0, cfile
);
392 if ((!is_identifier (token
) && token
!= STRING
)) {
393 printf ("usage: new <object-type>\n");
398 printf ("an object is already open.\n");
399 skip_to_semi (cfile
);
404 printf ("not connected.\n");
405 skip_to_semi (cfile
);
409 status
= dhcpctl_new_object (&oh
, connection
, val
);
410 if (status
!= ISC_R_SUCCESS
) {
411 printf ("can't create object: %s\n",
412 isc_result_totext (status
));
416 token
= next_token (&val
, (unsigned *)0, cfile
);
417 if (token
!= END_OF_FILE
&& token
!= EOL
) {
418 printf ("usage: new <object-type>\n");
419 skip_to_semi (cfile
);
425 token
= next_token (&val
, (unsigned *)0, cfile
);
426 if (token
!= END_OF_FILE
&& token
!= EOL
) {
427 printf ("usage: close\n");
428 skip_to_semi (cfile
);
433 printf ("not connected.\n");
434 skip_to_semi (cfile
);
439 printf ("not open.\n");
440 skip_to_semi (cfile
);
443 omapi_object_dereference (&oh
, MDL
);
448 token
= next_token (&val
, (unsigned *)0, cfile
);
450 if ((!is_identifier (token
) && token
!= STRING
)) {
452 printf ("usage: set <name> = <value>\n");
453 skip_to_semi (cfile
);
458 printf ("no open object.\n");
459 skip_to_semi (cfile
);
464 printf ("not connected.\n");
465 skip_to_semi (cfile
);
470 strlcpy (s1
, val
, sizeof(s1
));
473 strncat (s1
, val
, sizeof(s1
)-strlen(s1
)-1);
476 token
= next_token (&val
, (unsigned *)0, cfile
);
480 token
= next_token (&val
, (unsigned *)0, cfile
);
483 dhcpctl_set_string_value (oh
, val
, s1
);
484 token
= next_token (&val
, (unsigned *)0, cfile
);
489 token
= peek_token (&val
, (unsigned *)0, cfile
);
490 /* Colon-separated hex list? */
493 else if (token
== DOT
) {
497 int intval
= atoi (val
);
500 "dotted octet > 255: %s",
502 skip_to_semi (cfile
);
506 token
= next_token (&val
,
507 (unsigned *)0, cfile
);
511 while ((token
= next_token (&val
,
512 (unsigned *)0, cfile
)) == DOT
)
514 } while (token
== NUMBER
);
515 dhcpctl_set_data_value (oh
, buf
,
520 dhcpctl_set_int_value (oh
, atoi (buf
), s1
);
521 token
= next_token (&val
, (unsigned *)0, cfile
);
531 convert_num (cfile
, (unsigned char *)s
,
534 token
= next_token (&val
,
535 (unsigned *)0, cfile
);
538 token
= next_token (&val
,
539 (unsigned *)0, cfile
);
540 } while (token
== NUMBER
||
541 token
== NUMBER_OR_NAME
);
542 dhcpctl_set_data_value (oh
, buf
,
543 (unsigned)(s
- buf
), s1
);
547 printf ("invalid value.\n");
548 skip_to_semi (cfile
);
551 if (token
!= END_OF_FILE
&& token
!= EOL
)
556 token
= next_token (&val
, (unsigned *)0, cfile
);
558 if ((!is_identifier (token
) && token
!= STRING
)) {
560 printf ("usage: unset <name>\n");
561 skip_to_semi (cfile
);
566 printf ("no open object.\n");
567 skip_to_semi (cfile
);
572 printf ("not connected.\n");
573 skip_to_semi (cfile
);
578 strlcpy (s1
, val
, sizeof(s1
));
581 strncat (s1
, val
, sizeof(s1
)-strlen(s1
)-1);
584 token
= next_token (&val
, (unsigned *)0, cfile
);
585 if (token
!= END_OF_FILE
&& token
!= EOL
)
588 dhcpctl_set_null_value (oh
, s1
);
595 token
= next_token (&val
, (unsigned *)0, cfile
);
596 if (token
!= END_OF_FILE
&& token
!= EOL
) {
597 printf ("usage: %s\n", val
);
598 skip_to_semi (cfile
);
603 printf ("not connected.\n");
604 skip_to_semi (cfile
);
609 printf ("you must make a new object first!\n");
610 skip_to_semi (cfile
);
614 if (i
== TOKEN_CREATE
)
615 i
= DHCPCTL_CREATE
| DHCPCTL_EXCL
;
619 status
= dhcpctl_open_object (oh
, connection
, i
);
620 if (status
== ISC_R_SUCCESS
)
621 status
= dhcpctl_wait_for_completion
623 if (status
== ISC_R_SUCCESS
)
625 if (status
!= ISC_R_SUCCESS
) {
626 printf ("can't open object: %s\n",
627 isc_result_totext (status
));
634 token
= next_token (&val
, (unsigned *)0, cfile
);
635 if (token
!= END_OF_FILE
&& token
!= EOL
) {
636 printf ("usage: %s\n", val
);
637 skip_to_semi (cfile
);
642 printf ("not connected.\n");
643 skip_to_semi (cfile
);
648 printf ("you haven't opened an object yet!\n");
649 skip_to_semi (cfile
);
653 status
= dhcpctl_object_update(connection
, oh
);
654 if (status
== ISC_R_SUCCESS
)
655 status
= dhcpctl_wait_for_completion
657 if (status
== ISC_R_SUCCESS
)
659 if (status
!= ISC_R_SUCCESS
) {
660 printf ("can't update object: %s\n",
661 isc_result_totext (status
));
668 token
= next_token (&val
, (unsigned *)0, cfile
);
669 if (token
!= END_OF_FILE
&& token
!= EOL
) {
670 printf ("usage: remove\n");
671 skip_to_semi (cfile
);
676 printf ("not connected.\n");
681 printf ("no object.\n");
685 status
= dhcpctl_object_remove(connection
, oh
);
686 if (status
== ISC_R_SUCCESS
)
687 status
= dhcpctl_wait_for_completion
689 if (status
== ISC_R_SUCCESS
)
691 if (status
!= ISC_R_SUCCESS
) {
692 printf ("can't destroy object: %s\n",
693 isc_result_totext (status
));
696 omapi_object_dereference (&oh
, MDL
);
700 token
= next_token (&val
, (unsigned *)0, cfile
);
701 if (token
!= END_OF_FILE
&& token
!= EOL
) {
702 printf ("usage: refresh\n");
703 skip_to_semi (cfile
);
708 printf ("not connected.\n");
713 printf ("no object.\n");
717 status
= dhcpctl_object_refresh(connection
, oh
);
718 if (status
== ISC_R_SUCCESS
)
719 status
= dhcpctl_wait_for_completion
721 if (status
== ISC_R_SUCCESS
)
723 if (status
!= ISC_R_SUCCESS
) {
724 printf ("can't refresh object: %s\n",
725 isc_result_totext (status
));
738 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
739 control_object_state_t newstate
)
741 return ISC_R_SUCCESS
;