summaryrefslogtreecommitdiff
path: root/common-runopts.c
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2022-04-01 14:13:52 +0800
committerMatt Johnston <matt@ucc.asn.au>2022-04-01 14:13:52 +0800
commitdd305c15334d604c328a14b1606baf35971b2aa0 (patch)
tree7e8513852e372dc95dc59046713cc67003d41c20 /common-runopts.c
parent7894254afa9b1d3a836911b7ccea1fe18391b881 (diff)
downloaddropbear-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.c55
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;
+}