From 0d0f7a0e7c32842edff533246a1f8523306f9ab0 Mon Sep 17 00:00:00 2001 From: John Denker Date: Fri, 1 Jun 2012 23:07:51 -0700 Subject: as downloaded : ucspi-tcp --- ucspi-tcp-0.88/tcpclient.c | 224 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 ucspi-tcp-0.88/tcpclient.c (limited to 'ucspi-tcp-0.88/tcpclient.c') diff --git a/ucspi-tcp-0.88/tcpclient.c b/ucspi-tcp-0.88/tcpclient.c new file mode 100644 index 0000000..9f6d7f2 --- /dev/null +++ b/ucspi-tcp-0.88/tcpclient.c @@ -0,0 +1,224 @@ +#include +#include +#include +#include "sig.h" +#include "exit.h" +#include "sgetopt.h" +#include "uint16.h" +#include "fmt.h" +#include "scan.h" +#include "str.h" +#include "ip4.h" +#include "uint16.h" +#include "socket.h" +#include "fd.h" +#include "stralloc.h" +#include "buffer.h" +#include "error.h" +#include "strerr.h" +#include "pathexec.h" +#include "timeoutconn.h" +#include "remoteinfo.h" +#include "dns.h" + +#define FATAL "tcpclient: fatal: " +#define CONNECT "tcpclient: unable to connect to " + +void nomem(void) +{ + strerr_die2x(111,FATAL,"out of memory"); +} +void usage(void) +{ + strerr_die1x(100,"tcpclient: usage: tcpclient \ +[ -hHrRdDqQv ] \ +[ -i localip ] \ +[ -p localport ] \ +[ -T timeoutconn ] \ +[ -l localname ] \ +[ -t timeoutinfo ] \ +host port program"); +} + +int verbosity = 1; +int flagdelay = 1; +int flagremoteinfo = 1; +int flagremotehost = 1; +unsigned long itimeout = 26; +unsigned long ctimeout[2] = { 2, 58 }; + +char iplocal[4] = { 0,0,0,0 }; +uint16 portlocal = 0; +char *forcelocal = 0; + +char ipremote[4]; +uint16 portremote; + +char *hostname; +static stralloc addresses; +static stralloc moreaddresses; + +static stralloc tmp; +static stralloc fqdn; +char strnum[FMT_ULONG]; +char ipstr[IP4_FMT]; + +char seed[128]; + +main(int argc,char **argv) +{ + unsigned long u; + int opt; + char *x; + int j; + int s; + int cloop; + + dns_random_init(seed); + + close(6); + close(7); + sig_ignore(sig_pipe); + + while ((opt = getopt(argc,argv,"dDvqQhHrRi:p:t:T:l:")) != opteof) + switch(opt) { + case 'd': flagdelay = 1; break; + case 'D': flagdelay = 0; break; + case 'v': verbosity = 2; break; + case 'q': verbosity = 0; break; + case 'Q': verbosity = 1; break; + case 'l': forcelocal = optarg; break; + case 'H': flagremotehost = 0; break; + case 'h': flagremotehost = 1; break; + case 'R': flagremoteinfo = 0; break; + case 'r': flagremoteinfo = 1; break; + case 't': scan_ulong(optarg,&itimeout); break; + case 'T': j = scan_ulong(optarg,&ctimeout[0]); + if (optarg[j] == '+') ++j; + scan_ulong(optarg + j,&ctimeout[1]); + break; + case 'i': if (!ip4_scan(optarg,iplocal)) usage(); break; + case 'p': scan_ulong(optarg,&u); portlocal = u; break; + default: usage(); + } + argv += optind; + + if (!verbosity) + buffer_2->fd = -1; + + hostname = *argv; + if (!hostname) usage(); + if (str_equal(hostname,"")) hostname = "127.0.0.1"; + if (str_equal(hostname,"0")) hostname = "127.0.0.1"; + + x = *++argv; + if (!x) usage(); + if (!x[scan_ulong(x,&u)]) + portremote = u; + else { + struct servent *se; + se = getservbyname(x,"tcp"); + if (!se) + strerr_die3x(111,FATAL,"unable to figure out port number for ",x); + portremote = ntohs(se->s_port); + /* i continue to be amazed at the stupidity of the s_port interface */ + } + + if (!*++argv) usage(); + + if (!stralloc_copys(&tmp,hostname)) nomem(); + if (dns_ip4_qualify(&addresses,&fqdn,&tmp) == -1) + strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": "); + if (addresses.len < 4) + strerr_die3x(111,FATAL,"no IP address for ",hostname); + + if (addresses.len == 4) { + 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(); + if (s == -1) + strerr_die2sys(111,FATAL,"unable to create socket: "); + if (socket_bind4(s,iplocal,portlocal) == -1) + strerr_die2sys(111,FATAL,"unable to bind socket: "); + if (timeoutconn(s,addresses.s + j,portremote,ctimeout[cloop]) == 0) + goto CONNECTED; + close(s); + if (!cloop && ctimeout[1] && (errno == error_timeout)) { + if (!stralloc_catb(&moreaddresses,addresses.s + j,4)) nomem(); + } + else { + strnum[fmt_ulong(strnum,portremote)] = 0; + ipstr[ip4_fmt(ipstr,addresses.s + j)] = 0; + strerr_warn5(CONNECT,ipstr," port ",strnum,": ",&strerr_sys); + } + } + if (!stralloc_copy(&addresses,&moreaddresses)) nomem(); + } + + _exit(111); + + + + CONNECTED: + + if (!flagdelay) + socket_tcpnodelay(s); /* if it fails, bummer */ + + if (!pathexec_env("PROTO","TCP")) nomem(); + + if (socket_local4(s,iplocal,&portlocal) == -1) + strerr_die2sys(111,FATAL,"unable to get local address: "); + + strnum[fmt_ulong(strnum,portlocal)] = 0; + if (!pathexec_env("TCPLOCALPORT",strnum)) nomem(); + ipstr[ip4_fmt(ipstr,iplocal)] = 0; + if (!pathexec_env("TCPLOCALIP",ipstr)) nomem(); + + x = forcelocal; + if (!x) + if (dns_name4(&tmp,iplocal) == 0) { + if (!stralloc_0(&tmp)) nomem(); + x = tmp.s; + } + if (!pathexec_env("TCPLOCALHOST",x)) nomem(); + + if (socket_remote4(s,ipremote,&portremote) == -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 (!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 (!stralloc_0(&tmp)) nomem(); + x = tmp.s; + } + if (!pathexec_env("TCPREMOTEHOST",x)) nomem(); + + x = 0; + if (flagremoteinfo) + if (remoteinfo(&tmp,ipremote,portremote,iplocal,portlocal,itimeout) == 0) { + if (!stralloc_0(&tmp)) nomem(); + x = tmp.s; + } + if (!pathexec_env("TCPREMOTEINFO",x)) nomem(); + + if (fd_move(6,s) == -1) + strerr_die2sys(111,FATAL,"unable to set up descriptor 6: "); + if (fd_copy(7,6) == -1) + strerr_die2sys(111,FATAL,"unable to set up descriptor 7: "); + sig_uncatch(sig_pipe); + + pathexec(argv); + strerr_die4sys(111,FATAL,"unable to run ",*argv,": "); +} -- cgit v1.2.3