From 0eccbd66c5ee0cffbbd4b37b8d0872b13a1ea563 Mon Sep 17 00:00:00 2001 From: cel Date: Thu, 4 Oct 2018 12:57:30 -1000 Subject: [PATCH] Add -4, -6 options (IPv4/IPv6) --- sbotc.1 | 11 +++++++++++ sbotc.c | 27 ++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/sbotc.1 b/sbotc.1 index 57aed60..d91fb77 100644 --- a/sbotc.1 +++ b/sbotc.1 @@ -21,6 +21,11 @@ .Oo .Op Fl s Ar host .Op Fl p Ar port +.Oo +.Fl 4 +| +.Fl 6 +.Oc | .Op Fl u Ar socket_path .Oc @@ -47,6 +52,10 @@ This option makes the and .Fl c options have no effect and output a warning if used. +.It Fl 4 +Connect to server over IPv4 only. +.It Fl 6 +Connect to server over IPv6 only. .It Fl c Ar cap Capability key for secret-handshake. Default is SSB's capability key, .Li 1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s= . @@ -119,6 +128,8 @@ If none of the options .Fl k , .Fl K , .Fl c , +.Fl 4 , +.Fl 6 , or .Fl T are specified, diff --git a/sbotc.c b/sbotc.c index 5a50754..250e55d 100644 --- a/sbotc.c +++ b/sbotc.c @@ -87,6 +87,12 @@ enum stream_state { stream_state_ended_error, }; +enum ip_family { + ip_family_ipv4 = AF_INET, + ip_family_ipv6 = AF_INET6, + ip_family_any = AF_UNSPEC +}; + static unsigned char zeros[24] = {0}; static const unsigned char ssb_cap[] = { @@ -99,12 +105,12 @@ static const unsigned char ssb_cap[] = { static void usage() { fputs("usage: sbotc [-j] [-T]\n" " [ -n | [-c ] [-k ] [-K ] ]\n" - " [ [-s ] [-p ] | [-u ] ]\n" + " [ [-s ] [-p ] [ -4 | -6 ] | [-u ] ]\n" " [-t ] [...]\n", stderr); exit(EXIT_FAILURE); } -static int tcp_connect(const char *host, const char *port) { +static int tcp_connect(const char *host, const char *port, enum ip_family ip_family) { struct addrinfo hints; struct addrinfo *result, *rp; int s; @@ -112,7 +118,7 @@ static int tcp_connect(const char *host, const char *port) { int err; memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; + hints.ai_family = ip_family; hints.ai_protocol = IPPROTO_TCP; s = getaddrinfo(host, port, &hints, &result); @@ -863,6 +869,9 @@ int main(int argc, char *argv[]) { bool port_arg = false; bool key_arg = false; bool shs_cap_key_str_arg = false; + bool ipv4_arg = false; + bool ipv6_arg = false; + enum ip_family ip_family; get_app_dir(app_dir, sizeof(app_dir)); @@ -893,11 +902,19 @@ int main(int argc, char *argv[]) { case 'u': socket_path = argv[++i]; break; case 't': typestr = argv[++i]; break; case 'n': noauth = true; break; + case '4': ipv4_arg = true; break; + case '6': ipv6_arg = true; break; default: usage(); } } if (i < argc) methodstr = argv[i++]; else if (!test) usage(); + if (ipv4_arg && ipv6_arg) errx(1, "options -4 and -6 conflict"); + ip_family = + ipv4_arg ? ip_family_ipv4 : + ipv6_arg ? ip_family_ipv6 : + ip_family_any; + if (shs_cap_key_str) { rc = pubkey_decode(shs_cap_key_str, shs_cap_key); if (rc < 0) err(1, "unable to decode cap key '%s'", shs_cap_key_str); @@ -957,7 +974,7 @@ int main(int argc, char *argv[]) { memcpy(remote_key, public_key, 32); } - bool implied_tcp = host_arg || port_arg; + bool implied_tcp = host_arg || port_arg || ipv4_arg || ipv6_arg; bool implied_auth = key_arg || keypair_seed_str || shs_cap_key_str_arg || test; if (test) { @@ -984,7 +1001,7 @@ int main(int argc, char *argv[]) { } else { do_tcp_connect: - s = tcp_connect(host, port); + s = tcp_connect(host, port, ip_family); if (s < 0) err(1, "tcp_connect"); infd = outfd = s; }