diff options
author | Matt Johnston <matt@ucc.asn.au> | 2022-04-01 14:13:52 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2022-04-01 14:13:52 +0800 |
commit | dd305c15334d604c328a14b1606baf35971b2aa0 (patch) | |
tree | 7e8513852e372dc95dc59046713cc67003d41c20 /common-runopts.c | |
parent | 7894254afa9b1d3a836911b7ccea1fe18391b881 (diff) | |
download | dropbear-dd305c15334d604c328a14b1606baf35971b2aa0.tar.gz |
Fix IPv6 address parsing for dbclient -b
Now can correctly handle '-b [ipv6address]:port'
Code is shared with dropbear -p, though they handle colon-less arguments
differently
Diffstat (limited to 'common-runopts.c')
-rw-r--r-- | common-runopts.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/common-runopts.c b/common-runopts.c index 37f153c..e9ad314 100644 --- a/common-runopts.c +++ b/common-runopts.c @@ -116,3 +116,58 @@ void parse_recv_window(const char* recv_window_arg) { } } + +/* Splits addr:port. Handles IPv6 [2001:0011::4]:port style format. + Returns first/second parts as malloced strings, second will + be NULL if no separator is found. + :port -> (NULL, "port") + port -> (port, NULL) + addr:port (addr, port) + addr: -> (addr, "") + Returns DROPBEAR_SUCCESS/DROPBEAR_FAILURE */ +int split_address_port(const char* spec, char **first, char ** second) { + char *spec_copy = NULL, *addr = NULL, *colon = NULL; + int ret = DROPBEAR_FAILURE; + + *first = NULL; + *second = NULL; + spec_copy = m_strdup(spec); + addr = spec_copy; + + if (*addr == '[') { + addr++; + colon = strchr(addr, ']'); + if (!colon) { + dropbear_log(LOG_WARNING, "Bad address '%s'", spec); + goto out; + } + *colon = '\0'; + colon++; + if (*colon == '\0') { + /* No port part */ + colon = NULL; + } else if (*colon != ':') { + dropbear_log(LOG_WARNING, "Bad address '%s'", spec); + goto out; + } + } else { + /* search for ':', that separates address and port */ + colon = strrchr(addr, ':'); + } + + /* colon points to ':' now, or is NULL */ + if (colon) { + /* Split the address/port */ + *colon = '\0'; + colon++; + *second = m_strdup(colon); + } + if (strlen(addr)) { + *first = m_strdup(addr); + } + ret = DROPBEAR_SUCCESS; + +out: + m_free(spec_copy); + return ret; +} |