summaryrefslogtreecommitdiff
path: root/tcpclient.c
diff options
context:
space:
mode:
authorJon Marler <jmarler@debian.org>2006-01-30 16:43:31 -0600
committerDmitry Bogatov <KAction@debian.org>2018-11-29 05:18:30 +0000
commitb4de5e82cf2c89f89d102aa8bc735d4499582add (patch)
tree8664b160556e424d6759a07bf4df40239722cb5f /tcpclient.c
parent9153362023a649853b7cfff374ed686b6586761f (diff)
Import Debian changes 0.88-10
ucspi-tcp (0.88-10) unstable; urgency=low * Added IPV6 Patch (Closes: #151550) * New man pages included with IPV6 patch (Closes: #142736) * Added man pages back into build script (Closes: #105610) * Moved ucspi-tcp-misc programs into ucspi-tcp package (Closes: #255707)
Diffstat (limited to 'tcpclient.c')
-rw-r--r--tcpclient.c73
1 files changed, 47 insertions, 26 deletions
diff --git a/tcpclient.c b/tcpclient.c
index 9f6d7f2..77b1ad5 100644
--- a/tcpclient.c
+++ b/tcpclient.c
@@ -9,6 +9,7 @@
#include "scan.h"
#include "str.h"
#include "ip4.h"
+#include "ip6.h"
#include "uint16.h"
#include "socket.h"
#include "fd.h"
@@ -20,6 +21,7 @@
#include "timeoutconn.h"
#include "remoteinfo.h"
#include "dns.h"
+#include "byte.h"
#define FATAL "tcpclient: fatal: "
#define CONNECT "tcpclient: unable to connect to "
@@ -31,27 +33,30 @@ void nomem(void)
void usage(void)
{
strerr_die1x(100,"tcpclient: usage: tcpclient \
-[ -hHrRdDqQv ] \
+[ -46hHrRdDqQv ] \
[ -i localip ] \
[ -p localport ] \
[ -T timeoutconn ] \
[ -l localname ] \
[ -t timeoutinfo ] \
+[ -I interface ] \
host port program");
}
+int forcev6 = 0;
int verbosity = 1;
int flagdelay = 1;
int flagremoteinfo = 1;
int flagremotehost = 1;
unsigned long itimeout = 26;
unsigned long ctimeout[2] = { 2, 58 };
+uint32 netif = 0;
-char iplocal[4] = { 0,0,0,0 };
+char iplocal[16] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
uint16 portlocal = 0;
char *forcelocal = 0;
-char ipremote[4];
+char ipremote[16];
uint16 portremote;
char *hostname;
@@ -61,12 +66,13 @@ static stralloc moreaddresses;
static stralloc tmp;
static stralloc fqdn;
char strnum[FMT_ULONG];
-char ipstr[IP4_FMT];
+char ipstr[IP6_FMT];
char seed[128];
main(int argc,char **argv)
{
+ int fakev4=0;
unsigned long u;
int opt;
char *x;
@@ -80,8 +86,10 @@ main(int argc,char **argv)
close(7);
sig_ignore(sig_pipe);
- while ((opt = getopt(argc,argv,"dDvqQhHrRi:p:t:T:l:")) != opteof)
+ while ((opt = getopt(argc,argv,"46dDvqQhHrRi:p:t:T:l:I:")) != opteof)
switch(opt) {
+ case '4': noipv6 = 1; break;
+ case '6': forcev6 = 1; break;
case 'd': flagdelay = 1; break;
case 'D': flagdelay = 0; break;
case 'v': verbosity = 2; break;
@@ -97,7 +105,8 @@ main(int argc,char **argv)
if (optarg[j] == '+') ++j;
scan_ulong(optarg + j,&ctimeout[1]);
break;
- case 'i': if (!ip4_scan(optarg,iplocal)) usage(); break;
+ case 'i': if (!scan_ip6(optarg,iplocal)) usage(); break;
+ case 'I': netif=socket_getifidx(optarg); break;
case 'p': scan_ulong(optarg,&u); portlocal = u; break;
default: usage();
}
@@ -108,8 +117,8 @@ main(int argc,char **argv)
hostname = *argv;
if (!hostname) usage();
- if (str_equal(hostname,"")) hostname = "127.0.0.1";
- if (str_equal(hostname,"0")) hostname = "127.0.0.1";
+ if (!hostname[0] || str_equal(hostname,"0"))
+ hostname = (noipv6?"127.0.0.1":"::1");
x = *++argv;
if (!x) usage();
@@ -127,33 +136,36 @@ main(int argc,char **argv)
if (!*++argv) usage();
if (!stralloc_copys(&tmp,hostname)) nomem();
- if (dns_ip4_qualify(&addresses,&fqdn,&tmp) == -1)
+ if (dns_ip6_qualify(&addresses,&fqdn,&tmp) == -1)
strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": ");
- if (addresses.len < 4)
+ if (addresses.len < 16)
strerr_die3x(111,FATAL,"no IP address for ",hostname);
- if (addresses.len == 4) {
+ if (addresses.len == 16) {
ctimeout[0] += ctimeout[1];
ctimeout[1] = 0;
}
for (cloop = 0;cloop < 2;++cloop) {
if (!stralloc_copys(&moreaddresses,"")) nomem();
- for (j = 0;j + 4 <= addresses.len;j += 4) {
- s = socket_tcp();
+ for (j = 0;j + 16 <= addresses.len;j += 4) {
+ s = socket_tcp6();
if (s == -1)
strerr_die2sys(111,FATAL,"unable to create socket: ");
- if (socket_bind4(s,iplocal,portlocal) == -1)
+ if (socket_bind6(s,iplocal,portlocal,netif) == -1)
strerr_die2sys(111,FATAL,"unable to bind socket: ");
- if (timeoutconn(s,addresses.s + j,portremote,ctimeout[cloop]) == 0)
+ if (timeoutconn6(s,addresses.s + j,portremote,ctimeout[cloop],netif) == 0)
goto CONNECTED;
close(s);
if (!cloop && ctimeout[1] && (errno == error_timeout)) {
- if (!stralloc_catb(&moreaddresses,addresses.s + j,4)) nomem();
+ if (!stralloc_catb(&moreaddresses,addresses.s + j,16)) nomem();
}
else {
strnum[fmt_ulong(strnum,portremote)] = 0;
- ipstr[ip4_fmt(ipstr,addresses.s + j)] = 0;
+ if (ip6_isv4mapped(addresses.s+j))
+ ipstr[ip4_fmt(ipstr,addresses.s + j + 12)] = 0;
+ else
+ ipstr[ip6_fmt(ipstr,addresses.s + j)] = 0;
strerr_warn5(CONNECT,ipstr," port ",strnum,": ",&strerr_sys);
}
}
@@ -169,37 +181,46 @@ main(int argc,char **argv)
if (!flagdelay)
socket_tcpnodelay(s); /* if it fails, bummer */
- if (!pathexec_env("PROTO","TCP")) nomem();
-
- if (socket_local4(s,iplocal,&portlocal) == -1)
+ if (socket_local6(s,iplocal,&portlocal,&netif) == -1)
strerr_die2sys(111,FATAL,"unable to get local address: ");
+ if (!forcev6 && (ip6_isv4mapped(iplocal) || byte_equal(iplocal,16,V6any)))
+ fakev4=1;
+
+ if (!pathexec_env("PROTO",fakev4?"TCP":"TCP6")) nomem();
+
strnum[fmt_ulong(strnum,portlocal)] = 0;
if (!pathexec_env("TCPLOCALPORT",strnum)) nomem();
- ipstr[ip4_fmt(ipstr,iplocal)] = 0;
+ if (fakev4)
+ ipstr[ip4_fmt(ipstr,iplocal+12)] = 0;
+ else
+ ipstr[ip6_fmt(ipstr,iplocal)] = 0;
if (!pathexec_env("TCPLOCALIP",ipstr)) nomem();
x = forcelocal;
if (!x)
- if (dns_name4(&tmp,iplocal) == 0) {
+ if (dns_name6(&tmp,iplocal) == 0) {
if (!stralloc_0(&tmp)) nomem();
x = tmp.s;
}
if (!pathexec_env("TCPLOCALHOST",x)) nomem();
- if (socket_remote4(s,ipremote,&portremote) == -1)
+ if (socket_remote6(s,ipremote,&portremote,&netif) == -1)
strerr_die2sys(111,FATAL,"unable to get remote address: ");
strnum[fmt_ulong(strnum,portremote)] = 0;
if (!pathexec_env("TCPREMOTEPORT",strnum)) nomem();
- ipstr[ip4_fmt(ipstr,ipremote)] = 0;
+ if (fakev4)
+ ipstr[ip4_fmt(ipstr,ipremote+12)] = 0;
+ else
+ ipstr[ip6_fmt(ipstr,ipremote)] = 0;
if (!pathexec_env("TCPREMOTEIP",ipstr)) nomem();
if (verbosity >= 2)
strerr_warn4("tcpclient: connected to ",ipstr," port ",strnum,0);
x = 0;
if (flagremotehost)
- if (dns_name4(&tmp,ipremote) == 0) {
+ if (dns_name6(&tmp,ipremote) == 0) {
if (!stralloc_0(&tmp)) nomem();
x = tmp.s;
}
@@ -207,7 +228,7 @@ main(int argc,char **argv)
x = 0;
if (flagremoteinfo)
- if (remoteinfo(&tmp,ipremote,portremote,iplocal,portlocal,itimeout) == 0) {
+ if (remoteinfo6(&tmp,ipremote,portremote,iplocal,portlocal,itimeout,netif) == 0) {
if (!stralloc_0(&tmp)) nomem();
x = tmp.s;
}