4 Created: Feb 2001 by Philip Homburg <philip@f-mnx.phicoh.com>
9 #define _POSIX_C_SOURCE 2
20 #include <sys/ioctl.h>
24 #include <net/netlib.h>
25 #include <net/gen/in.h>
26 #include <net/gen/inet.h>
27 #include <net/gen/netdb.h>
28 #include <net/gen/socket.h>
29 #include <net/gen/tcp.h>
30 #include <net/gen/tcp_io.h>
32 #define BUF_SIZE 10240
39 static int stdout_issocket
= 0;
42 static void do_conn(char *hostname
, char *portname
);
43 static void alrm_conn(int sig
);
44 static void alrm_io(int sig
);
45 static void fullduplex(void);
46 static void fatal(char *msg
, ...);
47 static void usage(void);
49 int main(int argc
, char *argv
[])
55 int B_flag
, P_flag
, s_flag
;
58 (progname
=strrchr(argv
[0],'/')) ? progname
++ : (progname
=argv
[0]);
64 while (c
= getopt(argc
, argv
, "BPst:?"), c
!= -1)
68 case 'B': B_flag
= 1; break;
69 case 'P': P_flag
= 1; break;
70 case 's': s_flag
= 1; break;
71 case 't': t_arg
= optarg
; break;
74 fatal("getopt failed: '%c'", c
);
79 timeout
= strtol(t_arg
, &check
, 0);
81 fatal("unable to parse timeout '%s'\n", t_arg
);
83 fatal("bad timeout '%d'\n", timeout
);
90 hostname
= argv
[optind
++];
91 portname
= argv
[optind
++];
95 stdout_issocket
= s_flag
;
97 do_conn(hostname
, portname
);
102 signal(SIGALRM
, alrm_io
);
110 static void do_conn(char *hostname
, char *portname
)
116 char *tcp_device
, *check
;
117 nwio_tcpconf_t tcpconf
;
119 nwio_tcpopt_t tcpopt
;
121 if (!inet_aton(hostname
, &addr
))
123 he
= gethostbyname(hostname
);
125 fatal("unknown hostname '%s'", hostname
);
126 if (he
->h_addrtype
!= AF_INET
|| he
->h_length
!= sizeof(addr
))
127 fatal("bad address for '%s'", hostname
);
128 memcpy(&addr
, he
->h_addr
, sizeof(addr
));
131 port
= strtol(portname
, &check
, 0);
134 se
= getservbyname(portname
, "tcp");
136 fatal("unkown port '%s'", portname
);
137 port
= ntohs(se
->s_port
);
140 tcp_device
= getenv("TCP_DEVICE");
141 if (tcp_device
== NULL
) tcp_device
= TCP_DEVICE
;
143 tcpfd
= open(tcp_device
, O_RDWR
);
145 fatal("unable to open '%s': %s", tcp_device
, strerror(errno
));
146 tcpconf
.nwtc_flags
= NWTC_EXCL
| NWTC_LP_SEL
| NWTC_SET_RA
|
148 tcpconf
.nwtc_remaddr
= addr
;
149 tcpconf
.nwtc_remport
= htons(port
);;
150 if (ioctl(tcpfd
, NWIOSTCPCONF
, &tcpconf
) == -1)
151 fatal("NWIOSTCPCONF failed: %s", strerror(errno
));
155 signal(SIGALRM
, alrm_conn
);
159 tcpcl
.nwtcl_flags
= 0;
160 if (ioctl(tcpfd
, NWIOTCPCONN
, &tcpcl
) == -1)
162 fatal("unable to connect to %s:%u: %s", inet_ntoa(addr
),
163 ntohs(tcpconf
.nwtc_remport
), strerror(errno
));
170 tcpopt
.nwto_flags
= NWTO_BULK
;
171 if (ioctl(tcpfd
, NWIOSTCPOPT
, &tcpopt
) == -1)
172 fatal("NWIOSTCPOPT failed: %s", strerror(errno
));
176 static void alrm_conn(int sig
)
178 fatal("timeout during connect");
181 static void alrm_io(int sig
)
183 fatal("timeout during io");
186 static void fullduplex(void)
189 int o
, r
, s
, s_errno
, loc
;
194 case -1: fatal("fork failed: %s", strerror(errno
));
196 /* Read from TCP, write to stdout. */
199 r
= read(tcpfd
, buf
, BUF_SIZE
);
206 ioctl(1, NWIOTCPSHUTDOWN
, NULL
);
207 fatal("error reading from TCP conn.: %s",
211 for (o
= 0; o
<s
; o
+= r
)
213 r
= write(1, buf
+o
, s
-o
);
216 fatal("error writing to stdout: %s",
224 r
= ioctl(1, NWIOTCPSHUTDOWN
, NULL
);
227 fatal("NWIOTCPSHUTDOWN failed on stdout: %s",
236 /* Read from stdin, write to TCP. */
239 r
= read(0, buf
, BUF_SIZE
);
246 fatal("error reading from stdin: %s",
250 for (o
= 0; o
<s
; o
+= r
)
252 r
= write(tcpfd
, buf
+o
, s
-o
);
257 fatal("error writing to TCP conn.: %s",
263 ioctl(tcpfd
, NWIOTCPPUSH
, NULL
);
265 if (ioctl(tcpfd
, NWIOTCPSHUTDOWN
, NULL
) == -1)
269 fatal("unable to shut down TCP conn.: %s", strerror(s_errno
));
272 r
= waitpid(cpid
, &loc
, 0);
277 fatal("waitpid failed: %s", strerror(s_errno
));
280 exit(WEXITSTATUS(loc
));
281 kill(getpid(), WTERMSIG(loc
));
285 static void fatal(char *fmt
, ...)
290 fprintf(stderr
, "%s: ", progname
);
291 vfprintf(stderr
, fmt
, ap
);
292 fprintf(stderr
, "\n");
297 static void usage(void)
299 fprintf(stderr
, "Usage: %s [-BPs] [-t timeout] hostname portname\n",
305 * $PchId: socket.c,v 1.3 2005/01/31 22:33:20 philip Exp $