diff options
author | Ted Lemon <source@isc.org> | 2001-05-02 06:45:58 +0000 |
---|---|---|
committer | Ted Lemon <source@isc.org> | 2001-05-02 06:45:58 +0000 |
commit | f27f6d6c5a7b9893f86b4ff86175313ffe7d4738 (patch) | |
tree | e54d267d3b42b2092d68346b7408a986e0b22b93 /dhcpctl | |
parent | 263a2ed031d4852edf97b432243f6065d0088fd0 (diff) | |
download | isc-dhcp-f27f6d6c5a7b9893f86b4ff86175313ffe7d4738.tar.gz |
Revamp parsing, do connections interactively, support base64 keys.
Diffstat (limited to 'dhcpctl')
-rw-r--r-- | dhcpctl/omshell.c | 635 |
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); } |