21#include "timeoutconn.h"
26#define WHO "tcpclient"
30 logmsg(
WHO,111,FATAL,
"out of memory");
34 logmsg(
WHO,100,USAGE,
"tcpclient \
53char iplocal[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
62static stralloc addresses;
63static stralloc moreaddresses;
67static char strnum[FMT_ULONG];
68static char ipstr[IP6_FMT];
72int main(
int argc,
char *
const *argv)
83 dns_random_init(
seed);
89 while ((opt = getoptb(argc,(
char **)argv,
"46dDvqQhHrRi:p:t:T:l:I:")) != opteof)
91 case '4': ipflag = 1;
break;
92 case '6': ipflag = 2;
break;
103 case 't': scan_ulong(optarg,&
itimeout);
break;
104 case 'T': j = scan_ulong(optarg,&
ctimeout[0]);
105 if (optarg[j] ==
'+') ++j;
106 scan_ulong(optarg + j,&
ctimeout[1]);
break;
107 case 'i':
if (!ip6_scan(optarg,
iplocal))
usage();
break;
108 case 'I':
netif = socket_getifidx(optarg);
break;
109 case 'p': scan_ulong(optarg,&u);
portlocal = u;
break;
123 if (!x[scan_ulong(x,&u)])
127 se = getservbyname(x,
"tcp");
129 logmsg(
WHO,111,FATAL,B(
"unable to figure out port number for: ",x));
130 uint16_unpack_big((
char *)&se->s_port,&
portremote);
134 if (!*++argv)
usage();
139 if (!stralloc_copyb(&addresses,(
char *)V4mappedprefix,12))
nomem();
141 byte_copy(
iplocal,16,addresses.s);
144 byte_copy(
iplocal,16,addresses.s);
147 if (addresses.len < 4) {
149 dns_ip_qualify(&addresses,&fqdn,&tmp);
150 if (addresses.len < 16)
151 logmsg(
WHO,111,ERROR,B(
"No IP address for: ",
hostname));
154 if (addresses.len == 16) {
159 for (cloop = 0; cloop < 2; ++cloop) {
160 if (!stralloc_copys(&moreaddresses,
""))
nomem();
161 for (j = 0; j + 16 <= addresses.len; j += 16) {
162 if (ipflag == 1 || ip6_isv4mapped(addresses.s + j)) {
164 if (s == -1) logmsg(
WHO,111,FATAL,
"unable to create socket");
168 if (s == -1) logmsg(
WHO,111,FATAL,
"unable to create socket");
172 if (r == -1) logmsg(
WHO,111,FATAL,B(
"unable to bind to socket for local port: ",strnum));
176 if (!cloop &&
ctimeout[1] && (errno == ETIMEDOUT)) {
177 if (!stralloc_catb(&moreaddresses,addresses.s + j,16))
nomem();
181 if (ip6_isv4mapped(addresses.s + j))
182 ipstr[ip4_fmt(ipstr,addresses.s + j + 12)] = 0;
184 ipstr[ip6_fmt(ipstr,addresses.s + j)] = 0;
187 if (!stralloc_copy(&addresses,&moreaddresses))
nomem();
189 logmsg(
WHO,110,DROP,B(
"unable to connect to: ",ipstr,
" port: ",strnum));
197 socket_tcpnodelay(s);
202 logmsg(
WHO,111,FATAL,
"unable to get local address");
204 if (!pathexec_env(
"PROTO",(ipflag - 1)?
"TCP":
"TCP6"))
nomem();
207 if (!pathexec_env(
"TCPLOCALPORT",strnum))
nomem();
210 ipstr[ip6_fmt(ipstr,
iplocal)] = 0;
211 if (!pathexec_env(
"TCP6LOCALIP",ipstr))
nomem();
212 if (!pathexec_env(
"TCP6LOCALPORT",strnum))
nomem();
214 ipstr[ip4_fmt(ipstr,
iplocal + 12)] = 0;
215 if (!pathexec_env(
"TCPLOCALIP",ipstr))
nomem();
219 if (dns_name(&tmp,
iplocal) < 0) {
220 if (!stralloc_0(&tmp))
nomem();
223 if (!pathexec_env(
"TCPLOCALHOST",x))
nomem();
228 logmsg(
WHO,111,FATAL,
"unable to get remote address");
231 if (!pathexec_env(
"TCPREMOTEPORT",strnum))
nomem();
235 if (!pathexec_env(
"TCP6REMOTEIP",ipstr))
nomem();
236 if (!pathexec_env(
"TCP6REMOTEPORT",strnum))
nomem();
238 ipstr[ip4_fmt(ipstr,
ipremote + 12)] = 0;
239 if (!pathexec_env(
"TCPREMOTEIP",ipstr))
nomem();
242 log_who(
WHO,B(
"connected to ",ipstr,
" port ",strnum));
247 if (!stralloc_0(&tmp))
nomem();
250 if (!pathexec_env(
"TCPREMOTEHOST",x))
nomem();
255 if (!stralloc_0(&tmp))
nomem();
258 if (!pathexec_env(
"TCPREMOTEINFO",x))
nomem();
260 if (fd_move(6,s) == -1)
261 logmsg(
WHO,111,FATAL,
"unable to set up descriptor 6");
262 if (fd_copy(7,6) == -1)
263 logmsg(
WHO,111,FATAL,
"unable to set up descriptor 7");
264 sig_uncatch(sig_pipe);
267 logmsg(
WHO,111,FATAL,B(
"unable to run: ",*argv));
int remoteinfo(stralloc *out, char ipremote[16], uint16 portremote, char iplocal[16], uint16 portlocal, unsigned int timeout, uint32 netif)
unsigned long ctimeout[2]