summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Lemon <source@isc.org>2001-05-02 06:45:58 +0000
committerTed Lemon <source@isc.org>2001-05-02 06:45:58 +0000
commitf27f6d6c5a7b9893f86b4ff86175313ffe7d4738 (patch)
treee54d267d3b42b2092d68346b7408a986e0b22b93
parent263a2ed031d4852edf97b432243f6065d0088fd0 (diff)
downloadisc-dhcp-f27f6d6c5a7b9893f86b4ff86175313ffe7d4738.tar.gz
Revamp parsing, do connections interactively, support base64 keys.
-rw-r--r--dhcpctl/omshell.c635
1 files changed, 406 insertions, 229 deletions
diff --git a/dhcpctl/omshell.c b/dhcpctl/omshell.c
index 5402e67e..24d2b6bf 100644
--- a/dhcpctl/omshell.c
+++ b/dhcpctl/omshell.c
@@ -90,44 +90,22 @@ int main (int argc, char **argv, char **envp)
dhcpctl_handle oh;
dhcpctl_data_string cid, ip_addr;
dhcpctl_data_string result, groupname, identifier;
- const char *name = 0, *pass = 0, *algorithm = "hmac-md5";
+ struct data_string secret;
+ const char *name = 0, *algorithm = "hmac-md5";
int i, j;
int port = 7911;
const char *server = "127.0.0.1";
struct parse *cfile;
enum dhcp_token token;
const char *val;
+ char *s;
char buf[1024];
char s1[1024];
+ int connected = 0;
for (i = 1; i < argc; i++) {
- if (!strcmp (argv[i], "-n")) {
- if (++i == argc)
- usage(argv[0]);
- name = argv[i];
- } else if (!strcmp (argv[i], "-p")) {
- if (++i == argc)
- usage(argv[0]);
- pass = argv[i];
- } else if (!strcmp (argv[i], "-a")) {
- if (++i == argc)
- usage(argv[0]);
- algorithm = argv[i];
- } else if (!strcmp (argv[i], "-s")) {
- if (++i == argc)
- usage(argv[0]);
- server = argv[i];
- } else if (!strcmp (argv[i], "-P")) {
- if (++i == argc)
- usage(argv[0]);
- port = atoi (argv[i]);
- } else {
- usage(argv[0]);
- }
- }
-
- if ((name || pass) && !(name && pass))
usage(argv[0]);
+ }
status = dhcpctl_initialize ();
if (status != ISC_R_SUCCESS) {
@@ -136,220 +114,419 @@ int main (int argc, char **argv, char **envp)
exit (1);
}
- authenticator = dhcpctl_null_handle;
-
- if (name) {
- status = dhcpctl_new_authenticator (&authenticator,
- name, algorithm, pass,
- strlen (pass) + 1);
- if (status != ISC_R_SUCCESS) {
- fprintf (stderr, "Cannot create authenticator: %s\n",
- isc_result_totext (status));
- exit (1);
- }
- }
-
- memset (&connection, 0, sizeof connection);
- status = dhcpctl_connect (&connection, server, port, authenticator);
- if (status != ISC_R_SUCCESS) {
- fprintf (stderr, "dhcpctl_connect: %s\n",
- isc_result_totext (status));
- exit (1);
- }
-
memset (&oh, 0, sizeof oh);
do {
+ if (!connected) {
+ } else if (oh == NULL) {
+ printf ("obj: <null>\n");
+ } else {
+ dhcpctl_remote_object_t *r = (dhcpctl_remote_object_t *)oh;
+ omapi_generic_object_t *g =
+ (omapi_generic_object_t *)(r -> inner);
+
printf ("obj: ");
- if (oh == NULL) {
- printf ("<null>\n");
- } else {
- dhcpctl_remote_object_t *r =
- (dhcpctl_remote_object_t *)oh;
- omapi_generic_object_t *g =
- (omapi_generic_object_t *)(r -> inner);
-
- if (r -> rtype -> type != omapi_datatype_string) {
- printf ("?\n");
- } else {
- printf ("%.*s\n",
- (int)(r -> rtype -> u . buffer . len),
- r -> rtype -> u . buffer . value);
- }
-
- for (i = 0; i < g -> nvalues; i++) {
- omapi_value_t *v = g -> values [i];
- printf ("%.*s = ", (int)v -> name -> len,
- v -> name -> value);
-
- switch (v -> value -> type) {
- case omapi_datatype_int:
- printf ("%d\n",
- v -> value -> u . integer);
- break;
-
- case omapi_datatype_string:
- printf ("\"%.*s\"\n",
- (int)v -> value -> u.buffer.len,
- v -> value -> u.buffer.value);
- break;
-
- case omapi_datatype_data:
- printf ("%s\n",
- print_hex_1
- (v -> value -> u.buffer.len,
+ if (r -> rtype -> type != omapi_datatype_string) {
+ printf ("?\n");
+ } else {
+ printf ("%.*s\n",
+ (int)(r -> rtype -> u . buffer . len),
+ r -> rtype -> u . buffer . value);
+ }
+
+ for (i = 0; i < g -> nvalues; i++) {
+ omapi_value_t *v = g -> values [i];
+
+ printf ("%.*s = ", (int)v -> name -> len,
+ v -> name -> value);
+
+ switch (v -> value -> type) {
+ case omapi_datatype_int:
+ printf ("%d\n",
+ v -> value -> u . integer);
+ break;
+
+ case omapi_datatype_string:
+ printf ("\"%.*s\"\n",
+ (int) v -> value -> u.buffer.len,
+ v -> value -> u.buffer.value);
+ break;
+
+ case omapi_datatype_data:
+ printf ("%s\n",
+ print_hex_1 (v -> value -> u.buffer.len,
v -> value -> u.buffer.value,
60));
- break;
-
- case omapi_datatype_object:
- printf ("<obj>\n");
- break;
- }
- }
+ break;
+
+ case omapi_datatype_object:
+ printf ("<obj>\n");
+ break;
+ }
}
-
- fputs ("> ", stdout);
- fflush (stdout);
- if (fgets (buf, sizeof(buf), stdin) == NULL)
- break;
-
- status = new_parse (&cfile, 0, buf, strlen(buf), "<STDIN>");
- check(status, "new_parse()");
-
- token = next_token (&val, (unsigned *)0, cfile);
- switch (token) {
- default:
- parse_warn (cfile, "unknown token: %s", val);
- break;
-
- case END_OF_FILE:
- break;
-
- case TOKEN_HELP:
- case '?':
- printf ("Commands:\n");
- printf (" new <object-type>\n");
- printf (" set <name> = <value>\n");
- printf (" create\n");
- printf (" open\n");
- break;
-
- case TOKEN_NEW:
- token = next_token (&val, (unsigned *)0, cfile);
- if ((!is_identifier (token) && token != STRING) ||
- next_token (NULL,
- (unsigned *)0, cfile) != END_OF_FILE)
- {
- printf ("usage: new <object-type>\n");
- break;
- }
-
- if (oh) {
- printf ("an object is already open.\n");
- break;
- }
-
- status = dhcpctl_new_object (&oh, connection, val);
- if (status != ISC_R_SUCCESS) {
- printf ("can't create object: %s\n",
- isc_result_totext (status));
- break;
- }
-
- break;
-
- case TOKEN_CLOSE:
- if (next_token (NULL,
- (unsigned *)0, cfile) != END_OF_FILE) {
- printf ("usage: close\n");
- }
-
- omapi_object_dereference (&oh, MDL);
-
- break;
-
- case TOKEN_SET:
- token = next_token (&val, (unsigned *)0, cfile);
-
- if ((!is_identifier (token) && token != STRING) ||
- next_token (NULL, (unsigned *)0, cfile) != '=')
- {
- printf ("usage: set <name> = <value>\n");
- break;
- }
-
- if (oh == NULL) {
- printf ("no open object.\n");
- break;
- }
-
- s1[0] = '\0';
- strncat (s1, val, sizeof(s1)-1);
-
- token = next_token (&val, (unsigned *)0, cfile);
- switch (token) {
- case STRING:
- dhcpctl_set_string_value (oh, val, s1);
- break;
-
- case NUMBER:
- dhcpctl_set_int_value (oh, atoi (val), s1);
+ }
+
+ fputs ("> ", stdout);
+ fflush (stdout);
+ if (fgets (buf, sizeof(buf), stdin) == NULL)
+ break;
+
+ status = new_parse (&cfile, 0, buf, strlen(buf), "<STDIN>", 1);
+ check(status, "new_parse()");
+
+ token = next_token (&val, (unsigned *)0, cfile);
+ switch (token) {
+ default:
+ parse_warn (cfile, "unknown token: %s", val);
+ skip_to_semi (cfile);
+ break;
+
+ case END_OF_FILE:
+ case EOL:
+ break;
+
+ case TOKEN_HELP:
+ case '?':
+ printf ("Commands:\n");
+ printf (" port <server omapi port>\n");
+ printf (" server <server address>\n");
+ printf (" key <key name> <key value>\n");
+ printf (" connect\n");
+ printf (" new <object-type>\n");
+ printf (" set <name> = <value>\n");
+ printf (" create\n");
+ printf (" open\n");
+ skip_to_semi (cfile);
+ break;
+
+ case PORT:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (is_identifier (token)) {
+ struct servent *se;
+ se = getservbyname (val, "tcp");
+ if (se)
+ port = ntohs (se -> s_port);
+ else {
+ printf ("unknown service name: %s", val);
+ break;
+ }
+ } else if (token == NUMBER) {
+ port = atoi (val);
+ } else {
+ skip_to_semi (cfile);
+ printf ("usage: port <port>\n");
+ break;
+ }
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: port <server>\n");
+ skip_to_semi (cfile);
+ break;
+ }
+ break;
+
+ case SERVER:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token == NUMBER) {
+ int alen = (sizeof buf) - 1;
+ int len;
+
+ s = &buf [0];
+ len = strlen (val);
+ if (len + 1 > alen) {
+ baddq:
+ printf ("usage: server <server>\n");
+ skip_to_semi (cfile);
break;
+ } strcpy (buf, val);
+ s += len;
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != DOT)
+ goto baddq;
+ *s++ = '.';
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != NUMBER)
+ goto baddq;
+ len = strlen (val);
+ if (len + 1 > alen)
+ goto baddq;
+ strcpy (s, val);
+ s += len;
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != DOT)
+ goto baddq;
+ *s++ = '.';
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != NUMBER)
+ goto baddq;
+ len = strlen (val);
+ if (len + 1 > alen)
+ goto baddq;
+ strcpy (s, val);
+ s += len;
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != DOT)
+ goto baddq;
+ *s++ = '.';
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != NUMBER)
+ goto baddq;
+ len = strlen (val);
+ if (len + 1 > alen)
+ goto baddq;
+ strcpy (s, val);
+ val = &buf [0];
+ } else if (is_identifier (token)) {
+ /* Use val directly. */
+ } else {
+ printf ("usage: server <server>\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ s = dmalloc (strlen (val) + 1, MDL);
+ if (!server) {
+ printf ("no memory to store server name.");
+ skip_to_semi (cfile);
+ break;
+ }
+ strcpy (s, val);
+ server = s;
+
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: server <server>\n");
+ skip_to_semi (cfile);
+ break;
+ }
+ break;
+
+ case KEY:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (!is_identifier (token)) {
+ printf ("usage: key <name> <value>");
+ skip_to_semi (cfile);
+ break;
+ }
+ s = dmalloc (strlen (val) + 1, MDL);
+ if (!s) {
+ printf ("no memory for key name.");
+ skip_to_semi (cfile);
+ break;
+ }
+ strcpy (s, val);
+ name = s;
+ memset (&secret, 0, sizeof secret);
+ if (!parse_base64 (&secret, cfile)) {
+ skip_to_semi (cfile);
+ break;
+ }
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: key <name> <secret>\n");
+ skip_to_semi (cfile);
+ break;
+ }
+ break;
+
+ case CONNECT:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: connect\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ authenticator = dhcpctl_null_handle;
+
+ if (name) {
+ status = dhcpctl_new_authenticator (&authenticator,
+ name, algorithm,
+ secret.data,
+ secret.len);
- default:
- printf ("invalid value.\n");
- }
-
- break;
-
- case TOKEN_CREATE:
- case TOKEN_OPEN:
- if (next_token (NULL,
- (unsigned *)0, cfile) != END_OF_FILE) {
- printf ("usage: %s\n", val);
- }
-
- i = 0;
- if (token == TOKEN_CREATE)
- i = DHCPCTL_CREATE | DHCPCTL_EXCL;
-
- status = dhcpctl_open_object (oh, connection, i);
- if (status == ISC_R_SUCCESS)
- status = dhcpctl_wait_for_completion
- (oh, &waitstatus);
- if (status == ISC_R_SUCCESS)
- status = waitstatus;
- if (status != ISC_R_SUCCESS) {
- printf ("can't open object: %s\n",
- isc_result_totext (status));
- break;
- }
-
- break;
-
- case UPDATE:
- if (next_token (NULL, (unsigned *)0,
- cfile) != END_OF_FILE) {
- printf ("usage: %s\n", val);
- }
-
- status = dhcpctl_object_update(connection, oh);
- if (status == ISC_R_SUCCESS)
- status = dhcpctl_wait_for_completion
- (oh, &waitstatus);
- if (status == ISC_R_SUCCESS)
- status = waitstatus;
if (status != ISC_R_SUCCESS) {
- printf ("can't update object: %s\n",
- isc_result_totext (status));
- break;
+ fprintf (stderr,
+ "Cannot create authenticator: %s\n",
+ isc_result_totext (status));
+ break;
}
-
- break;
- }
- } while (1);
+ }
+
+ memset (&connection, 0, sizeof connection);
+ status = dhcpctl_connect (&connection,
+ server, port, authenticator);
+ if (status != ISC_R_SUCCESS) {
+ fprintf (stderr, "dhcpctl_connect: %s\n",
+ isc_result_totext (status));
+ break;
+ }
+ connected = 1;
+ break;
+
+ case TOKEN_NEW:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if ((!is_identifier (token) && token != STRING)) {
+ printf ("usage: new <object-type>\n");
+ break;
+ }
+
+ if (oh) {
+ printf ("an object is already open.\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (!connected) {
+ printf ("not connected.");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ status = dhcpctl_new_object (&oh, connection, val);
+ if (status != ISC_R_SUCCESS) {
+ printf ("can't create object: %s\n",
+ isc_result_totext (status));
+ break;
+ }
+
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: new <object-type>\n");
+ skip_to_semi (cfile);
+ break;
+ }
+ break;
+
+ case TOKEN_CLOSE:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: close\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (!connected) {
+ printf ("not connected.");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ omapi_object_dereference (&oh, MDL);
+
+ break;
+
+ case TOKEN_SET:
+ token = next_token (&val, (unsigned *)0, cfile);
+
+ if ((!is_identifier (token) && token != STRING)) {
+ set_usage:
+ printf ("usage: set <name> = <value>\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (oh == NULL) {
+ printf ("no open object.\n");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (!connected) {
+ printf ("not connected.");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ s1[0] = '\0';
+ strncat (s1, val, sizeof(s1)-1);
+
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != EQUAL)
+ goto set_usage;
+
+ token = next_token (&val, (unsigned *)0, cfile);
+ switch (token) {
+ case STRING:
+ dhcpctl_set_string_value (oh, val, s1);
+ break;
+
+ case NUMBER:
+ dhcpctl_set_int_value (oh, atoi (val), s1);
+ break;
+
+ default:
+ printf ("invalid value.\n");
+ }
+
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL)
+ goto set_usage;
+ break;
+
+ case TOKEN_CREATE:
+ case TOKEN_OPEN:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: %s\n", val);
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (!connected) {
+ printf ("not connected.");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ i = 0;
+ if (token == TOKEN_CREATE)
+ i = DHCPCTL_CREATE | DHCPCTL_EXCL;
+
+ status = dhcpctl_open_object (oh, connection, i);
+ if (status == ISC_R_SUCCESS)
+ status = dhcpctl_wait_for_completion
+ (oh, &waitstatus);
+ if (status == ISC_R_SUCCESS)
+ status = waitstatus;
+ if (status != ISC_R_SUCCESS) {
+ printf ("can't open object: %s\n",
+ isc_result_totext (status));
+ break;
+ }
+
+ break;
+
+ case UPDATE:
+ token = next_token (&val, (unsigned *)0, cfile);
+ if (token != END_OF_FILE && token != EOL) {
+ printf ("usage: %s\n", val);
+ skip_to_semi (cfile);
+ break;
+ }
+
+ if (!connected) {
+ printf ("not connected.");
+ skip_to_semi (cfile);
+ break;
+ }
+
+ status = dhcpctl_object_update(connection, oh);
+ if (status == ISC_R_SUCCESS)
+ status = dhcpctl_wait_for_completion
+ (oh, &waitstatus);
+ if (status == ISC_R_SUCCESS)
+ status = waitstatus;
+ if (status != ISC_R_SUCCESS) {
+ printf ("can't update object: %s\n",
+ isc_result_totext (status));
+ break;
+ }
+
+ break;
+ }
+ } while (token != END_OF_FILE);
exit (0);
}