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$ 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 dhcpctl_data_string cid
, ip_addr
;
86 dhcpctl_data_string result
, groupname
, identifier
;
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. */
106 openlog ("omshell", LOG_NDELAY
);
107 log_priority
= DHCPD_LOG_FACILITY
;
109 openlog ("omshell", LOG_NDELAY
, DHCPD_LOG_FACILITY
);
111 status
= dhcpctl_initialize ();
112 if (status
!= ISC_R_SUCCESS
) {
113 fprintf (stderr
, "dhcpctl_initialize: %s\n",
114 isc_result_totext (status
));
118 memset (&oh
, 0, sizeof oh
);
122 } else if (oh
== NULL
) {
123 printf ("obj: <null>\n");
125 dhcpctl_remote_object_t
*r
= (dhcpctl_remote_object_t
*)oh
;
126 omapi_generic_object_t
*g
=
127 (omapi_generic_object_t
*)(r
-> inner
);
131 if (r
-> rtype
-> type
!= omapi_datatype_string
) {
135 (int)(r
-> rtype
-> u
. buffer
. len
),
136 r
-> rtype
-> u
. buffer
. value
);
139 for (i
= 0; i
< g
-> nvalues
; i
++) {
140 omapi_value_t
*v
= g
-> values
[i
];
142 if (!g
-> values
[i
])
145 printf ("%.*s = ", (int)v
-> name
-> len
,
152 switch (v
-> value
-> type
) {
153 case omapi_datatype_int
:
155 v
-> value
-> u
. integer
);
158 case omapi_datatype_string
:
159 printf ("\"%.*s\"\n",
160 (int) v
-> value
-> u
.buffer
.len
,
161 v
-> value
-> u
.buffer
.value
);
164 case omapi_datatype_data
:
166 print_hex_1 (v
-> value
-> u
.buffer
.len
,
167 v
-> value
-> u
.buffer
.value
,
171 case omapi_datatype_object
:
178 fputs ("> ", stdout
);
180 if (fgets (buf
, sizeof(buf
), stdin
) == NULL
)
183 status
= new_parse (&cfile
, 0, buf
, strlen(buf
), "<STDIN>", 1);
184 check(status
, "new_parse()");
186 token
= next_token (&val
, (unsigned *)0, cfile
);
189 parse_warn (cfile
, "unknown token: %s", val
);
190 skip_to_semi (cfile
);
199 printf ("Commands:\n");
200 printf (" port <server omapi port>\n");
201 printf (" server <server address>\n");
202 printf (" key <key name> <key value>\n");
203 printf (" connect\n");
204 printf (" new <object-type>\n");
205 printf (" set <name> = <value>\n");
206 printf (" create\n");
208 printf (" update\n");
209 printf (" unset <name>\n");
210 printf (" refresh\n");
211 printf (" remove\n");
212 skip_to_semi (cfile
);
216 token
= next_token (&val
, (unsigned *)0, cfile
);
217 if (is_identifier (token
)) {
219 se
= getservbyname (val
, "tcp");
221 port
= ntohs (se
-> s_port
);
223 printf ("unknown service name: %s\n", val
);
226 } else if (token
== NUMBER
) {
229 skip_to_semi (cfile
);
230 printf ("usage: port <port>\n");
233 token
= next_token (&val
, (unsigned *)0, cfile
);
234 if (token
!= END_OF_FILE
&& token
!= EOL
) {
235 printf ("usage: port <server>\n");
236 skip_to_semi (cfile
);
242 token
= next_token (&val
, (unsigned *)0, cfile
);
243 if (token
== NUMBER
) {
244 int alen
= (sizeof buf
) - 1;
249 if (len
+ 1 > alen
) {
251 printf ("usage: server <server>\n");
252 skip_to_semi (cfile
);
256 token
= next_token (&val
, (unsigned *)0, cfile
);
260 token
= next_token (&val
, (unsigned *)0, cfile
);
268 token
= next_token (&val
, (unsigned *)0, cfile
);
272 token
= next_token (&val
, (unsigned *)0, cfile
);
280 token
= next_token (&val
, (unsigned *)0, cfile
);
284 token
= next_token (&val
, (unsigned *)0, cfile
);
292 } else if (is_identifier (token
)) {
293 /* Use val directly. */
295 printf ("usage: server <server>\n");
296 skip_to_semi (cfile
);
300 s
= dmalloc (strlen (val
) + 1, MDL
);
302 printf ("no memory to store server name.\n");
303 skip_to_semi (cfile
);
309 token
= next_token (&val
, (unsigned *)0, cfile
);
310 if (token
!= END_OF_FILE
&& token
!= EOL
) {
311 printf ("usage: server <server>\n");
312 skip_to_semi (cfile
);
318 token
= next_token (&val
, (unsigned *)0, cfile
);
319 if (!is_identifier (token
)) {
320 printf ("usage: key <name> <value>\n");
321 skip_to_semi (cfile
);
324 s
= dmalloc (strlen (val
) + 1, MDL
);
326 printf ("no memory for key name.\n");
327 skip_to_semi (cfile
);
332 memset (&secret
, 0, sizeof secret
);
333 if (!parse_base64 (&secret
, cfile
)) {
334 skip_to_semi (cfile
);
337 token
= next_token (&val
, (unsigned *)0, cfile
);
338 if (token
!= END_OF_FILE
&& token
!= EOL
) {
339 printf ("usage: key <name> <secret>\n");
340 skip_to_semi (cfile
);
346 token
= next_token (&val
, (unsigned *)0, cfile
);
347 if (token
!= END_OF_FILE
&& token
!= EOL
) {
348 printf ("usage: connect\n");
349 skip_to_semi (cfile
);
353 authenticator
= dhcpctl_null_handle
;
356 status
= dhcpctl_new_authenticator (&authenticator
,
361 if (status
!= ISC_R_SUCCESS
) {
363 "Cannot create authenticator: %s\n",
364 isc_result_totext (status
));
369 memset (&connection
, 0, sizeof connection
);
370 status
= dhcpctl_connect (&connection
,
371 server
, port
, authenticator
);
372 if (status
!= ISC_R_SUCCESS
) {
373 fprintf (stderr
, "dhcpctl_connect: %s\n",
374 isc_result_totext (status
));
381 token
= next_token (&val
, (unsigned *)0, cfile
);
382 if ((!is_identifier (token
) && token
!= STRING
)) {
383 printf ("usage: new <object-type>\n");
388 printf ("an object is already open.\n");
389 skip_to_semi (cfile
);
394 printf ("not connected.\n");
395 skip_to_semi (cfile
);
399 status
= dhcpctl_new_object (&oh
, connection
, val
);
400 if (status
!= ISC_R_SUCCESS
) {
401 printf ("can't create object: %s\n",
402 isc_result_totext (status
));
406 token
= next_token (&val
, (unsigned *)0, cfile
);
407 if (token
!= END_OF_FILE
&& token
!= EOL
) {
408 printf ("usage: new <object-type>\n");
409 skip_to_semi (cfile
);
415 token
= next_token (&val
, (unsigned *)0, cfile
);
416 if (token
!= END_OF_FILE
&& token
!= EOL
) {
417 printf ("usage: close\n");
418 skip_to_semi (cfile
);
423 printf ("not connected.\n");
424 skip_to_semi (cfile
);
429 printf ("not open.\n");
430 skip_to_semi (cfile
);
433 omapi_object_dereference (&oh
, MDL
);
438 token
= next_token (&val
, (unsigned *)0, cfile
);
440 if ((!is_identifier (token
) && token
!= STRING
)) {
442 printf ("usage: set <name> = <value>\n");
443 skip_to_semi (cfile
);
448 printf ("no open object.\n");
449 skip_to_semi (cfile
);
454 printf ("not connected.\n");
455 skip_to_semi (cfile
);
460 strncat (s1
, val
, sizeof(s1
)-1);
462 token
= next_token (&val
, (unsigned *)0, cfile
);
466 token
= next_token (&val
, (unsigned *)0, cfile
);
469 dhcpctl_set_string_value (oh
, val
, s1
);
470 token
= next_token (&val
, (unsigned *)0, cfile
);
475 token
= peek_token (&val
, (unsigned *)0, cfile
);
476 /* Colon-seperated hex list? */
479 else if (token
== DOT
) {
483 int intval
= atoi (val
);
487 "dotted octet > 255: %s",
489 skip_to_semi (cfile
);
493 token
= next_token (&val
,
494 (unsigned *)0, cfile
);
498 while ((token
= next_token (&val
,
499 (unsigned *)0, cfile
)) == DOT
)
501 } while (token
== NUMBER
);
502 dhcpctl_set_data_value (oh
, buf
,
507 dhcpctl_set_int_value (oh
, atoi (buf
), s1
);
508 token
= next_token (&val
, (unsigned *)0, cfile
);
518 convert_num (cfile
, (unsigned char *)s
,
521 token
= next_token (&val
,
522 (unsigned *)0, cfile
);
525 token
= next_token (&val
,
526 (unsigned *)0, cfile
);
527 } while (token
== NUMBER
||
528 token
== NUMBER_OR_NAME
);
529 dhcpctl_set_data_value (oh
, buf
,
530 (unsigned)(s
- buf
), s1
);
534 printf ("invalid value.\n");
535 skip_to_semi (cfile
);
538 if (token
!= END_OF_FILE
&& token
!= EOL
)
543 token
= next_token (&val
, (unsigned *)0, cfile
);
545 if ((!is_identifier (token
) && token
!= STRING
)) {
547 printf ("usage: unset <name>\n");
548 skip_to_semi (cfile
);
553 printf ("no open object.\n");
554 skip_to_semi (cfile
);
559 printf ("not connected.\n");
560 skip_to_semi (cfile
);
565 strncat (s1
, val
, sizeof(s1
)-1);
567 token
= next_token (&val
, (unsigned *)0, cfile
);
568 if (token
!= END_OF_FILE
&& token
!= EOL
)
571 dhcpctl_set_null_value (oh
, s1
);
578 token
= next_token (&val
, (unsigned *)0, cfile
);
579 if (token
!= END_OF_FILE
&& token
!= EOL
) {
580 printf ("usage: %s\n", val
);
581 skip_to_semi (cfile
);
586 printf ("not connected.\n");
587 skip_to_semi (cfile
);
592 printf ("you must make a new object first!\n");
593 skip_to_semi (cfile
);
597 if (i
== TOKEN_CREATE
)
598 i
= DHCPCTL_CREATE
| DHCPCTL_EXCL
;
602 status
= dhcpctl_open_object (oh
, connection
, i
);
603 if (status
== ISC_R_SUCCESS
)
604 status
= dhcpctl_wait_for_completion
606 if (status
== ISC_R_SUCCESS
)
608 if (status
!= ISC_R_SUCCESS
) {
609 printf ("can't open object: %s\n",
610 isc_result_totext (status
));
617 token
= next_token (&val
, (unsigned *)0, cfile
);
618 if (token
!= END_OF_FILE
&& token
!= EOL
) {
619 printf ("usage: %s\n", val
);
620 skip_to_semi (cfile
);
625 printf ("not connected.\n");
626 skip_to_semi (cfile
);
631 printf ("you haven't opened an object yet!\n");
632 skip_to_semi (cfile
);
636 status
= dhcpctl_object_update(connection
, oh
);
637 if (status
== ISC_R_SUCCESS
)
638 status
= dhcpctl_wait_for_completion
640 if (status
== ISC_R_SUCCESS
)
642 if (status
!= ISC_R_SUCCESS
) {
643 printf ("can't update object: %s\n",
644 isc_result_totext (status
));
651 token
= next_token (&val
, (unsigned *)0, cfile
);
652 if (token
!= END_OF_FILE
&& token
!= EOL
) {
653 printf ("usage: remove\n");
654 skip_to_semi (cfile
);
659 printf ("not connected.\n");
664 printf ("no object.\n");
668 status
= dhcpctl_object_remove(connection
, oh
);
669 if (status
== ISC_R_SUCCESS
)
670 status
= dhcpctl_wait_for_completion
672 if (status
== ISC_R_SUCCESS
)
674 if (status
!= ISC_R_SUCCESS
) {
675 printf ("can't destroy object: %s\n",
676 isc_result_totext (status
));
679 omapi_object_dereference (&oh
, MDL
);
683 token
= next_token (&val
, (unsigned *)0, cfile
);
684 if (token
!= END_OF_FILE
&& token
!= EOL
) {
685 printf ("usage: refresh\n");
686 skip_to_semi (cfile
);
691 printf ("not connected.\n");
696 printf ("no object.\n");
700 status
= dhcpctl_object_refresh(connection
, oh
);
701 if (status
== ISC_R_SUCCESS
)
702 status
= dhcpctl_wait_for_completion
704 if (status
== ISC_R_SUCCESS
)
706 if (status
!= ISC_R_SUCCESS
) {
707 printf ("can't refresh object: %s\n",
708 isc_result_totext (status
));
721 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
722 control_object_state_t newstate
)
724 return ISC_R_SUCCESS
;