src/test: Remove "sock".

Now available via HaikuPorts if needed.
This commit is contained in:
Augustin Cavalier
2023-03-14 15:23:24 -04:00
parent f3dc3eabfc
commit f6fad5e8c2
27 changed files with 0 additions and 2844 deletions
-1
View File
@@ -24,6 +24,5 @@ SubInclude HAIKU_TOP src tests system network icmp ;
SubInclude HAIKU_TOP src tests system network ipv6 ;
SubInclude HAIKU_TOP src tests system network multicast ;
SubInclude HAIKU_TOP src tests system network posixnet ;
SubInclude HAIKU_TOP src tests system network sock ;
SubInclude HAIKU_TOP src tests system network tcp_shell ;
SubInclude HAIKU_TOP src tests system network tcptester ;
-11
View File
@@ -1,11 +0,0 @@
SubDir HAIKU_TOP src tests system network sock ;
UseHeaders $(SUBDIR) : true ;
SimpleTest sock :
buffers.c cliopen.c crlf.c error.c looptcp.c
loopudp.c main.c multicast.c pattern.c servopen.c
sleepus.c sockopts.c sourceroute.c sourcetcp.c
sourceudp.c sinktcp.c sinkudp.c tellwait.c write.c writen.c
: $(TARGET_NETWORK_LIBS)
;
-49
View File
@@ -1,49 +0,0 @@
/* -*- c-basic-offset: 8; -*- */
#ifndef ADDRINFO_H
#define ADDRINFO_H
/*
* Everything here really belongs in <netdb.h>.
* These defines are separate for now, to avoid having to modify the
* system's header.
*/
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* IPPROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canonical name for host */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
/* following for getaddrinfo() */
#define AI_PASSIVE 1 /* socket is intended for bind() + listen() */
#define AI_CANONNAME 2 /* return canonical name */
/* following for getnameinfo() */
#define NI_MAXHOST 1025 /* max hostname returned */
#define NI_MAXSERV 32 /* max service name returned */
#define NI_NOFQDN 1 /* do not return FQDN */
#define NI_NUMERICHOST 2 /* return numeric form of hostname */
#define NI_NAMEREQD 4 /* return error if hostname not found */
#define NI_NUMERICSERV 8 /* return numeric form of service name */
#define NI_DGRAM 16 /* datagram service for getservbyname() */
/* error returns */
#define EAI_ADDRFAMILY 1 /* address family for host not supported */
#define EAI_AGAIN 2 /* temporary failure in name resolution */
#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
#define EAI_FAIL 4 /* non-recoverable fail in name resolution */
#define EAI_FAMILY 5 /* ai_family not supported */
#define EAI_MEMORY 6 /* memory allocation failure */
#define EAI_NODATA 7 /* no address associated with host */
#define EAI_NONAME 8 /* host nor service provided, or not known */
#define EAI_SERVICE 9 /* service not supported for ai_socktype */
#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
#define EAI_SYSTEM 11 /* system error returned in errno */
#endif
-60
View File
@@ -1,60 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <sock.h>
void buffers(int sockfd)
{
int n;
socklen_t optlen;
/* Allocate the read and write buffers. */
if (rbuf == NULL) {
if ( (rbuf = malloc(readlen)) == NULL)
err_sys("malloc error for read buffer");
}
if (wbuf == NULL) {
if ( (wbuf = malloc(writelen)) == NULL)
err_sys("malloc error for write buffer");
}
/* Set the socket send and receive buffer sizes (if specified).
The receive buffer size is tied to TCP's advertised window. */
if (rcvbuflen) {
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuflen,
sizeof(rcvbuflen)) < 0)
err_sys("SO_RCVBUF setsockopt error");
optlen = sizeof(n);
if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, &optlen) < 0)
err_sys("SO_RCVBUF getsockopt error");
if (n != rcvbuflen)
err_quit("error: requested rcvbuflen = %d, resulting SO_RCVBUF = %d", rcvbuflen, n);
if (verbose)
fprintf(stderr, "SO_RCVBUF = %d\n", n);
}
if (sndbuflen) {
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sndbuflen,
sizeof(sndbuflen)) < 0)
err_sys("SO_SNDBUF setsockopt error");
optlen = sizeof(n);
if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &n, &optlen) < 0)
err_sys("SO_SNDBUF getsockopt error");
if (n != sndbuflen)
err_quit("error: requested sndbuflen = %d, resulting SO_SNDBUF = %d", sndbuflen, n);
if (verbose)
fprintf(stderr, "SO_SNDBUF = %d\n", n);
}
}
-132
View File
@@ -1,132 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "sock.h"
int cliopen(char *host, char *port)
{
int fd, i, on;
char *protocol;
struct in_addr inaddr;
struct servent *sp;
struct hostent *hp;
protocol = udp ? "udp" : "tcp";
/* initialize socket address structure */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
/* see if "port" is a service name or number */
if ( (i = atoi(port)) == 0) {
if ( (sp = getservbyname(port, protocol)) == NULL)
err_quit("getservbyname() error for: %s/%s", port, protocol);
servaddr.sin_port = sp->s_port;
} else
servaddr.sin_port = htons(i);
/*
* First try to convert the host name as a dotted-decimal number.
* Only if that fails do we call gethostbyname().
*/
if (inet_aton(host, &inaddr) == 1)
servaddr.sin_addr = inaddr; /* it's dotted-decimal */
else if ( (hp = gethostbyname(host)) != NULL)
bcopy(hp->h_addr, &servaddr.sin_addr, hp->h_length);
else
err_quit("invalid hostname: %s", host);
if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
err_sys("socket() error");
if (reuseaddr) {
on = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
err_sys("setsockopt of SO_REUSEADDR error");
}
#ifdef SO_REUSEPORT
if (reuseport) {
on = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof (on)) < 0)
err_sys("setsockopt of SO_REUSEPORT error");
}
#endif
/*
* User can specify port number for client to bind. Only real use
* is to see a TCP connection initiated by both ends at the same time.
* Also, if UDP is being used, we specifically call bind() to assign
* an ephemeral port to the socket.
* Also, for experimentation, client can also set local IP address
* (and port) using -l option. Allow localip[] to be set but bindport
* to be 0.
*/
if (bindport != 0 || localip[0] != 0 || udp) {
bzero(&cliaddr, sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(bindport); /* can be 0 */
if (localip[0] != 0) {
if (inet_aton(localip, &cliaddr.sin_addr) == 0)
err_quit("invalid IP address: %s", localip);
} else
cliaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */
if (bind(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0)
err_sys("bind() error");
}
/* Need to allocate buffers before connect(), since they can affect
* TCP options (window scale, etc.).
*/
buffers(fd);
sockopts(fd, 0); /* may also want to set SO_DEBUG */
/*
* Connect to the server. Required for TCP, optional for UDP.
*/
if (udp == 0 || connectudp) {
for ( ; ; ) {
if (connect(fd, (struct sockaddr *) &servaddr, sizeof(servaddr))
== 0)
break; /* all OK */
if (errno == EINTR) /* can happen with SIGIO */
continue;
if (errno == EISCONN) /* can happen with SIGIO */
break;
err_sys("connect() error");
}
}
if (verbose) {
/* Call getsockname() to find local address bound to socket:
TCP ephemeral port was assigned by connect() or bind();
UDP ephemeral port was assigned by bind(). */
i = sizeof(cliaddr);
if (getsockname(fd, (struct sockaddr *) &cliaddr, &i) < 0)
err_sys("getsockname() error");
/* Can't do one fprintf() since inet_ntoa() stores
the result in a static location. */
fprintf(stderr, "connected on %s.%d ",
INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
fprintf(stderr, "to %s.%d\n",
INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port));
}
sockopts(fd, 1); /* some options get set after connect() */
return(fd);
}
-186
View File
@@ -1,186 +0,0 @@
/* config.h. Generated by configure. */
/* config.h.in. Generated from configure.in by autoheader. */
/* Define the following if you have the corresponding header */
/* #undef CPU_VENDOR_OS */
/* #undef HAVE_NETCONFIG_H */ /* <netconfig.h> */
/* #undef HAVE_NETDIR_H */ /* <netdir.h> */
/* #undef HAVE_POLL_H */ /* <poll.h> */
/* #undef HAVE_PTHREAD_H */ /* <pthread.h> */
/* #undef HAVE_STRINGS_H */ /* <strings.h> */
/* #undef HAVE_SYS_FILIO_H */ /* <sys/filio.h> */
/* #undef HAVE_SYS_IOCTL_H */ /* <sys/ioctl.h> */
/* #undef HAVE_SYS_SELECT_H */ /* <sys/select.h> */
/* #undef HAVE_SYS_SOCKIO_H */ /* <sys/sockio.h> */
/* #undef HAVE_SYS_SYSCTL_H */ /* <sys/sysctl.h> */
/* #undef HAVE_SYS_TIME_H */ /* <sys/time.h> */
/* #undef HAVE_SYS_TYPES_H */ /* <sys/types.> */
/* Define the following to the appropriate datatype, if necessary */
/* #undef int8_t */ /* <sys/types.h> */
/* #undef int16_t */ /* <sys/types.h> */
/* #undef int32_t */ /* <sys/types.h> */
/* #undef u_int8_t */ /* <sys/types.h> */
/* #undef u_int16_t */ /* <sys/types.h> */
/* #undef u_int32_t */ /* <sys/types.h> */
/* #undef DEBUG */
/* #undef HAVE_ADDRINFO_STRUCT */ /* <netdb.h> */
#define HAVE_MSGHDR_MSG_CONTROL
#define HAVE_ADDRINFO_PROTO 1
/* struct addrinfo is defined */
#define HAVE_ADDRINFO_STRUCT
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `nsl' library (-lnsl). */
#define HAVE_LIBNSL 1
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* struct msghdr has msg_control field */
#define HAVE_MSGHDR_MSG_CONTROL
/* Define to 1 if you have the <netconfig.h> header file. */
/* #undef HAVE_NETCONFIG_H */
/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define to 1 if you have the <netdir.h> header file. */
/* #undef HAVE_NETDIR_H */
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <poll.h> header file. */
#define HAVE_POLL_H 1
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Define to 1 if you have the `setlinebuf' function. */
#define HAVE_SETLINEBUF 1
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <stropts.h> header file. */
#define HAVE_STROPTS_H 1
/* Define to 1 if you have the <sys/filio.h> header file. */
/* #undef HAVE_SYS_FILIO_H */
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/sockio.h> header file. */
#define HAVE_SYS_SOCKIO_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#define HAVE_SYS_SYSCTL_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define to 1 if you have the <sys/un.h> header file. */
#define HAVE_SYS_UN_H 1
/* Define to 1 if you have the <sys/wait.h> header file. */
#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Name of package */
#define PACKAGE "sock"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.3"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef size_t */
-51
View File
@@ -1,51 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "sock.h"
/* Convert newline to return/newline. */
int
crlf_add(char *dst, int dstsize, const char *src, int lenin)
{
int lenout;
char c;
if ( (lenout = lenin) > dstsize)
err_quit("crlf_add: destination not big enough");
for ( ; lenin > 0; lenin--) {
if ( (c = *src++) == '\n') {
if (++lenout >= dstsize)
err_quit("crlf_add: destination not big enough");
*dst++ = '\r';
}
*dst++ = c;
}
return(lenout);
}
int
crlf_strip(char *dst, int dstsize, const char *src, int lenin)
{
int lenout;
char c;
for (lenout = 0; lenin > 0; lenin--) {
if ( (c = *src++) != '\r') {
if (++lenout >= dstsize)
err_quit("crlf_strip: destination not big enough");
*dst++ = c;
}
}
return(lenout);
}
-104
View File
@@ -1,104 +0,0 @@
/* -*- c-basic-offset: 8; -*- */
#include <errno.h> /* for definition of errno */
#include <stdarg.h> /* ANSI C header file */
#include "ourhdr.h"
static void err_doit(int, const char *, va_list);
char *pname = NULL; /* caller can set this from argv[0] */
/* Nonfatal error related to a system call.
* Print a message and return. */
void
/* $f err_ret $ */
err_ret(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, fmt, ap);
va_end(ap);
return;
}
/* Fatal error related to a system call.
* Print a message and terminate. */
void
/* $f err_sys $ */
err_sys(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, fmt, ap);
va_end(ap);
exit(1);
}
/* Fatal error related to a system call.
* Print a message, dump core, and terminate. */
void
/* $f err_dump $ */
err_dump(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, fmt, ap);
va_end(ap);
abort(); /* dump core and terminate */
exit(1); /* shouldn't get here */
}
/* Nonfatal error unrelated to a system call.
* Print a message and return. */
void
/* $f err_msg $ */
err_msg(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(0, fmt, ap);
va_end(ap);
return;
}
/* Fatal error unrelated to a system call.
* Print a message and terminate. */
void
/* $f err_quit $ */
err_quit(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(0, fmt, ap);
va_end(ap);
exit(1);
}
/* Print a message and return to caller.
* Caller specifies "errnoflag". */
static void
err_doit(int errnoflag, const char *fmt, va_list ap)
{
int errno_save;
char buf[MAXLINE];
errno_save = errno; /* value caller might want printed */
vsprintf(buf, fmt, ap);
if (errnoflag)
sprintf(buf+strlen(buf), ": %s", strerror(errno_save));
strcat(buf, "\n");
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(stderr); /* SunOS 4.1.* doesn't grok NULL argument */
return;
}
-41
View File
@@ -1,41 +0,0 @@
/* -*- c-basic-offset: 8; -*- */
#ifndef GLOBAL_H
#define GLOBAL_H
#include "config.h" /* configuration options for current OS */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <errno.h>
#include <sys/socket.h>
#ifndef HAVE_ADDRINFO_STRUCT
#include "addrinfo.h"
#endif
/* Older resolvers do not have gethostbyname2() */
#ifndef HAVE_GETHOSTBYNAME2
#define gethostbyname2(host,family) gethostbyname((host))
#endif
/* This avoids a warning with glibc compilation */
#ifndef errno
extern int errno;
#endif
/* Miscellaneous constants */
#define MAXLINE 4096 /* max text line length */
#define MAXSOCKADDR 128 /* max socket address structure size */
#define BUFFSIZE 8192 /* buffer size for reads and writes */
/* stdin and stdout file descriptors */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
-101
View File
@@ -1,101 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "sock.h"
/* Copy everything from stdin to "sockfd",
* and everything from "sockfd" to stdout. */
void loop_tcp(int sockfd)
{
int maxfdp1, nread, ntowrite, stdineof, flags;
fd_set rset;
if (pauseinit)
sleep_us(pauseinit*1000); /* intended for server */
flags = 0;
stdineof = 0;
FD_ZERO(&rset);
maxfdp1 = sockfd + 1; /* check descriptors [0..sockfd] */
for ( ; ; ) {
if (stdineof == 0)
FD_SET(STDIN_FILENO, &rset);
FD_SET(sockfd, &rset);
if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0)
err_sys("select error");
if (FD_ISSET(STDIN_FILENO, &rset)) {
/* data to read on stdin */
if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0)
err_sys("read error from stdin");
else if (nread == 0) {
/* EOF on stdin */
if (halfclose) {
if (shutdown(sockfd, SHUT_WR) < 0)
err_sys("shutdown() error");
FD_CLR(STDIN_FILENO, &rset);
stdineof = 1; /* don't read stdin anymore */
continue; /* back to select() */
}
break; /* default: stdin EOF -> done */
}
if (crlf) {
ntowrite = crlf_add(wbuf, writelen, rbuf, nread);
if (dowrite(sockfd, wbuf, ntowrite) != ntowrite)
err_sys("write error");
} else {
if (dowrite(sockfd, rbuf, nread) != nread)
err_sys("write error");
}
}
if (FD_ISSET(sockfd, &rset)) {
/* data to read from socket */
/* msgpeek = 0 or MSG_PEEK */
flags = msgpeek;
oncemore:
if ( (nread = recv(sockfd, rbuf, readlen, flags)) < 0)
err_sys("recv error");
else if (nread == 0) {
if (verbose)
fprintf(stderr, "connection closed by peer\n");
break; /* EOF, terminate */
}
if (crlf) {
ntowrite = crlf_strip(wbuf, writelen, rbuf, nread);
if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite)
err_sys("writen error to stdout");
} else {
if (writen(STDOUT_FILENO, rbuf, nread) != nread)
err_sys("writen error to stdout");
}
if (flags != 0) {
flags = 0; /* no infinite loop */
goto oncemore; /* read the message again */
}
}
}
if (pauseclose) {
if (verbose)
fprintf(stderr, "pausing before close\n");
sleep_us(pauseclose*1000);
}
if (close(sockfd) < 0)
err_sys("close error"); /* since SO_LINGER may be set */
}
-217
View File
@@ -1,217 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "sock.h"
/* Copy everything from stdin to "sockfd",
* and everything from "sockfd" to stdout. */
void
loop_udp(int sockfd)
{
int maxfdp1, nread, ntowrite, stdineof, clilen, servlen, flags;
fd_set rset;
struct sockaddr_in cliaddr; /* for UDP server */
struct sockaddr_in servaddr; /* for UDP client */
#ifdef HAVE_MSGHDR_MSG_CONTROL
struct iovec iov[1];
struct msghdr msg;
#ifdef IP_RECVDSTADDR /* 4.3BSD Reno and later */
static struct cmsghdr *cmptr = NULL; /* malloc'ed */
struct in_addr dstinaddr; /* for UDP server */
#define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(struct in_addr))
#endif /* IP_RECVDSTADDR */
#endif /* MSG_TRUNC */
if (pauseinit)
sleep_us(pauseinit*1000); /* intended for server */
flags = 0;
stdineof = 0;
FD_ZERO(&rset);
maxfdp1 = sockfd + 1; /* check descriptors [0..sockfd] */
/* If UDP client issues connect(), recv() and write() are used.
Server is harder since cannot issue connect(). We use recvfrom()
or recvmsg(), depending on OS. */
for ( ; ; ) {
if (stdineof == 0)
FD_SET(STDIN_FILENO, &rset);
FD_SET(sockfd, &rset);
if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0)
err_sys("select error");
if (FD_ISSET(STDIN_FILENO, &rset)) {
/* data to read on stdin */
if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0)
err_sys("read error from stdin");
else if (nread == 0) {
/* EOF on stdin */
if (halfclose) {
if (shutdown(sockfd, SHUT_WR) < 0)
err_sys("shutdown() error");
FD_CLR(STDIN_FILENO, &rset);
stdineof = 1; /* don't read stdin anymore */
continue; /* back to select() */
}
break; /* default: stdin EOF -> done */
}
if (crlf) {
ntowrite = crlf_add(wbuf, writelen, rbuf, nread);
if (connectudp) {
if (write(sockfd, wbuf, ntowrite) != ntowrite)
err_sys("write error");
} else {
if (sendto(sockfd, wbuf, ntowrite, 0,
(struct sockaddr *) &servaddr, sizeof(servaddr))
!= ntowrite)
err_sys("sendto error");
}
} else {
if (connectudp) {
if (write(sockfd, rbuf, nread) != nread)
err_sys("write error");
} else {
if (sendto(sockfd, rbuf, nread, 0,
(struct sockaddr *) &servaddr, sizeof(servaddr))
!= nread)
err_sys("sendto error");
}
}
}
if (FD_ISSET(sockfd, &rset)) {
/* data to read from socket */
if (server) {
clilen = sizeof(cliaddr);
#ifndef MSG_TRUNC /* vanilla BSD sockets */
nread = recvfrom(sockfd, rbuf, readlen, 0,
(struct sockaddr *) &cliaddr, &clilen);
#else /* 4.3BSD Reno and later; use recvmsg() to get at MSG_TRUNC flag */
/* Also lets us get at control information (destination address) */
iov[0].iov_base = rbuf;
iov[0].iov_len = readlen;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = (caddr_t) &cliaddr;
msg.msg_namelen = clilen;
#ifdef IP_RECVDSTADDR
if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL)
err_sys("malloc error for control buffer");
msg.msg_control = (caddr_t) cmptr; /* for dest address */
msg.msg_controllen = CONTROLLEN;
#else
msg.msg_control = (caddr_t) 0; /* no ancillary data */
msg.msg_controllen = 0;
#endif /* IP_RECVDSTADDR */
msg.msg_flags = 0; /* flags returned here */
nread = recvmsg(sockfd, &msg, 0);
#endif /* HAVE_MSGHDR_MSG_CONTROL */
if (nread < 0)
err_sys("datagram receive error");
if (verbose) {
printf("from %s", INET_NTOA(cliaddr.sin_addr));
#ifdef HAVE_MSGHDR_MSG_CONTROL
#ifdef IP_RECVDSTADDR
if (recvdstaddr) {
if (cmptr->cmsg_len != CONTROLLEN)
err_quit("control length (%d) != %d",
cmptr->cmsg_len, CONTROLLEN);
if (cmptr->cmsg_level != IPPROTO_IP)
err_quit("control level != IPPROTO_IP");
if (cmptr->cmsg_type != IP_RECVDSTADDR)
err_quit("control type != IP_RECVDSTADDR");
bcopy(CMSG_DATA(cmptr), &dstinaddr,
sizeof(struct in_addr));
bzero(cmptr, CONTROLLEN);
printf(", to %s", INET_NTOA(dstinaddr));
}
#endif /* IP_RECVDSTADDR */
#endif /* HAVE_MSGHDR_MSG_CONTROL */
printf(": ");
fflush(stdout);
}
#ifdef MSG_TRUNC
if (msg.msg_flags & MSG_TRUNC)
printf("(datagram truncated)\n");
#endif
} else if (connectudp) {
/* msgpeek = 0 or MSG_PEEK */
flags = msgpeek;
oncemore:
if ( (nread = recv(sockfd, rbuf, readlen, flags)) < 0)
err_sys("recv error");
else if (nread == 0) {
if (verbose)
fprintf(stderr, "connection closed by peer\n");
break; /* EOF, terminate */
}
} else {
/* Must use recvfrom() for unconnected UDP client */
servlen = sizeof(servaddr);
nread = recvfrom(sockfd, rbuf, readlen, 0,
(struct sockaddr *) &servaddr, &servlen);
if (nread < 0)
err_sys("datagram recvfrom() error");
if (verbose) {
printf("from %s", INET_NTOA(servaddr.sin_addr));
printf(": ");
fflush(stdout);
}
}
if (crlf) {
ntowrite = crlf_strip(wbuf, writelen, rbuf, nread);
if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite)
err_sys("writen error to stdout");
} else {
if (writen(STDOUT_FILENO, rbuf, nread) != nread)
err_sys("writen error to stdout");
}
if (flags != 0) {
flags = 0; /* no infinite loop */
goto oncemore; /* read the message again */
}
}
}
if (pauseclose) {
if (verbose)
fprintf(stderr, "pausing before close\n");
sleep_us(pauseclose*1000);
}
if (close(sockfd) < 0)
err_sys("close error"); /* since SO_LINGER may be set */
}
-447
View File
@@ -1,447 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <string.h>
#include "sock.h"
char *host; /* hostname or dotted-decimal string */
char *port;
/* DefinE global variables */
int bindport; /* 0 or TCP or UDP port number to bind */
/* set by -b or -l options */
int broadcast; /* SO_BROADCAST */
int cbreak; /* set terminal to cbreak mode */
int chunkwrite; /* write in small chunks; not all-at-once */
int client = 1; /* acting as client is the default */
int connectudp = 1; /* connect UDP client */
int crlf; /* convert newline to CR/LF & vice versa */
int debug; /* SO_DEBUG */
int dofork; /* concurrent server, do a fork() */
int dontroute; /* SO_DONTROUTE */
char foreignip[32]; /* foreign IP address, dotted-decimal string */
int foreignport; /* foreign port number */
int halfclose; /* TCP half close option */
int ignorewerr; /* true if write() errors should be ignored */
int iptos = -1; /* IP_TOS opton */
int ipttl = -1; /* IP_TTL opton */
char joinip[32]; /* multicast IP address, dotted-decimal string */
int keepalive; /* SO_KEEPALIVE */
long linger = -1; /* 0 or positive turns on option */
int listenq = 5; /* listen queue for TCP Server */
char localip[32]; /* local IP address, dotted-decimal string */
int maxseg; /* TCP_MAXSEG */
int mcastttl; /* multicast TTL */
int msgpeek; /* MSG_PEEK */
int nodelay; /* TCP_NODELAY (Nagle algorithm) */
int nbuf = 1024; /* number of buffers to write (sink mode) */
int onesbcast; /* set IP_ONESBCAST for 255.255.255.255 bcasts */
int pauseclose; /* #ms to sleep after recv FIN, before close */
int pauseinit; /* #ms to sleep before first read */
int pauselisten; /* #ms to sleep after listen() */
int pauserw; /* #ms to sleep before each read or write */
int reuseaddr; /* SO_REUSEADDR */
int reuseport; /* SO_REUSEPORT */
int readlen = 1024; /* default read length for socket */
int writelen = 1024; /* default write length for socket */
int recvdstaddr; /* IP_RECVDSTADDR option */
int rcvbuflen; /* size for SO_RCVBUF */
int sndbuflen; /* size for SO_SNDBUF */
long rcvtimeo; /* SO_RCVTIMEO */
long sndtimeo; /* SO_SNDTIMEO */
int sroute_cnt; /* count of #IP addresses in route */
char *rbuf; /* pointer that is malloc'ed */
char *wbuf; /* pointer that is malloc'ed */
int server; /* to act as server requires -s option */
int sigio; /* send SIGIO */
int sourcesink; /* source/sink mode */
int udp; /* use UDP instead of TCP */
int urgwrite; /* write urgent byte after this write */
int verbose; /* each -v increments this by 1 */
int usewritev; /* use writev() instead of write() */
struct sockaddr_in cliaddr, servaddr;
static void usage(const char *);
int
main(int argc, char *argv[])
{
int c, fd;
char *ptr;
if (argc < 2)
usage("");
opterr = 0; /* don't want getopt() writing to stderr */
while ( (c = getopt(argc, argv, "2b:cf:g:hij:kl:n:op:q:r:st:uvw:x:y:ABCDEFG:H:IJ:KL:NO:P:Q:R:S:TU:VWX:YZ")) != -1) {
switch (c) {
#ifdef IP_ONESBCAST
case '2': /* use 255.255.255.255 as broadcast address */
onesbcast = 1;
break;
#endif
case 'b':
bindport = atoi(optarg);
break;
case 'c': /* convert newline to CR/LF & vice versa */
crlf = 1;
break;
case 'f': /* foreign IP address and port#: a.b.c.d.p */
if ( (ptr = strrchr(optarg, '.')) == NULL)
usage("invalid -f option");
*ptr++ = 0; /* null replaces final period */
foreignport = atoi(ptr); /* port number */
strcpy(foreignip, optarg); /* save dotted-decimal IP */
break;
case 'g': /* loose source route */
sroute_doopt(0, optarg);
break;
case 'h': /* TCP half-close option */
halfclose = 1;
break;
case 'i': /* source/sink option */
sourcesink = 1;
break;
#ifdef IP_ADD_MEMBERSHIP
case 'j': /* join multicast group a.b.c.d */
strcpy(joinip, optarg); /* save dotted-decimal IP */
break;
#endif
case 'k': /* chunk-write option */
chunkwrite = 1;
break;
case 'l': /* local IP address and port#: a.b.c.d.p */
if ( (ptr = strrchr(optarg, '.')) == NULL)
usage("invalid -l option");
*ptr++ = 0; /* null replaces final period */
bindport = atoi(ptr); /* port number */
strcpy(localip, optarg); /* save dotted-decimal IP */
break;
case 'n': /* number of buffers to write */
nbuf = atol(optarg);
break;
case 'o': /* do not connect UDP client */
connectudp = 0;
break;
case 'p': /* pause before each read or write */
pauserw = atoi(optarg);
break;
case 'q': /* listen queue for TCP server */
listenq = atoi(optarg);
break;
case 'r': /* read() length */
readlen = atoi(optarg);
break;
case 's': /* server */
server = 1;
client = 0;
break;
#ifdef IP_MULTICAST_TTL
case 't': /* IP_MULTICAST_TTL */
mcastttl = atoi(optarg);
break;
#endif
case 'u': /* use UDP instead of TCP */
udp = 1;
break;
case 'v': /* output what's going on */
verbose++;
break;
case 'w': /* write() length */
writelen = atoi(optarg);
break;
case 'x': /* SO_RCVTIMEO socket option */
rcvtimeo = atol(optarg);
break;
case 'y': /* SO_SNDTIMEO socket option */
sndtimeo = atol(optarg);
break;
case 'A': /* SO_REUSEADDR socket option */
reuseaddr = 1;
break;
case 'B': /* SO_BROADCAST socket option */
broadcast = 1;
break;
case 'C': /* set standard input to cbreak mode */
cbreak = 1;
break;
case 'D': /* SO_DEBUG socket option */
debug = 1;
break;
case 'E': /* IP_RECVDSTADDR socket option */
recvdstaddr = 1;
break;
case 'F': /* concurrent server, do a fork() */
dofork = 1;
break;
case 'G': /* strict source route */
sroute_doopt(1, optarg);
break;
#ifdef IP_TOS
case 'H': /* IP_TOS socket option */
iptos = atoi(optarg);
break;
#endif
case 'I': /* SIGIO signal */
sigio = 1;
break;
#ifdef IP_TTL
case 'J': /* IP_TTL socket option */
ipttl = atoi(optarg);
break;
#endif
case 'K': /* SO_KEEPALIVE socket option */
keepalive = 1;
break;
case 'L': /* SO_LINGER socket option */
linger = atol(optarg);
break;
case 'N': /* SO_NODELAY socket option */
nodelay = 1;
break;
case 'O': /* pause before listen(), before first accept() */
pauselisten = atoi(optarg);
break;
case 'P': /* pause before first read() */
pauseinit = atoi(optarg);
break;
case 'Q': /* pause after receiving FIN, but before close() */
pauseclose = atoi(optarg);
break;
case 'R': /* SO_RCVBUF socket option */
rcvbuflen = atoi(optarg);
break;
case 'S': /* SO_SNDBUF socket option */
sndbuflen = atoi(optarg);
break;
#ifdef SO_REUSEPORT
case 'T': /* SO_REUSEPORT socket option */
reuseport = 1;
break;
#endif
case 'U': /* when to write urgent byte */
urgwrite = atoi(optarg);
break;
case 'V': /* use writev() instead of write() */
usewritev = 1;
chunkwrite = 1; /* implies this option too */
break;
case 'W': /* ignore write errors */
ignorewerr = 1;
break;
case 'X': /* TCP maximum segment size option */
maxseg = atoi(optarg);
break;
case 'Y': /* SO_DONTROUTE socket option */
dontroute = 1;
break;
case 'Z': /* MSG_PEEK option */
msgpeek = MSG_PEEK;
break;
case '?':
usage("unrecognized option");
}
}
/* check for options that don't make sense */
if (udp && halfclose)
usage("can't specify -h and -u");
if (udp && debug)
usage("can't specify -D and -u");
if (udp && linger >= 0)
usage("can't specify -L and -u");
if (udp && nodelay)
usage("can't specify -N and -u");
#ifdef notdef
if (udp == 0 && broadcast)
usage("can't specify -B with TCP");
#endif
if (udp == 0 && foreignip[0] != 0)
usage("can't specify -f with TCP");
if (client) {
if (optind != argc-2)
usage("missing <hostname> and/or <port>");
host = argv[optind];
port = argv[optind+1];
} else {
/* If server specifies host and port, then local address is
bound to the "host" argument, instead of being wildcarded. */
if (optind == argc-2) {
host = argv[optind];
port = argv[optind+1];
} else if (optind == argc-1) {
host = NULL;
port = argv[optind];
} else
usage("missing <port>");
}
if (client)
fd = cliopen(host, port);
else
fd = servopen(host, port);
if (sourcesink) { /* ignore stdin/stdout */
if (client) {
if (udp)
source_udp(fd);
else
source_tcp(fd);
} else {
if (udp)
sink_udp(fd);
else
sink_tcp(fd);
}
} else { /* copy stdin/stdout to/from socket */
if (udp)
loop_udp(fd);
else
loop_tcp(fd);
}
exit(0);
}
static void
usage(const char *msg)
{
err_msg(
"usage: sock [ options ] <host> <port> (for client; default)\n"
" sock [ options ] -s [ <IPaddr> ] <port> (for server)\n"
" sock [ options ] -i <host> <port> (for \"source\" client)\n"
" sock [ options ] -i -s [ <IPaddr> ] <port> (for \"sink\" server)\n"
"options: -b n bind n as client's local port number\n"
" -c convert newline to CR/LF & vice versa\n"
" -f a.b.c.d.p foreign IP address = a.b.c.d, foreign port# = p\n"
" -g a.b.c.d loose source route\n"
" -h issue TCP half close on standard input EOF\n"
" -i \"source\" data to socket, \"sink\" data from socket (w/-s)\n"
#ifdef IP_ADD_MEMBERSHIP
" -j a.b.c.d join multicast group\n"
#endif
" -k write or writev in chunks\n"
" -l a.b.c.d.p client's local IP address = a.b.c.d, local port# = p\n"
" -n n #buffers to write for \"source\" client (default 1024)\n"
" -o do NOT connect UDP client\n"
" -p n #ms to pause before each read or write (source/sink)\n"
" -q n size of listen queue for TCP server (default 5)\n"
" -r n #bytes per read() for \"sink\" server (default 1024)\n"
" -s operate as server instead of client\n"
#ifdef IP_MULTICAST_TTL
" -t n set multicast ttl\n"
#endif
" -u use UDP instead of TCP\n"
" -v verbose\n"
" -w n #bytes per write() for \"source\" client (default 1024)\n"
" -x n #ms for SO_RCVTIMEO (receive timeout)\n"
" -y n #ms for SO_SNDTIMEO (send timeout)\n"
" -A SO_REUSEADDR option\n"
" -B SO_BROADCAST option\n"
" -C set terminal to cbreak mode\n"
" -D SO_DEBUG option\n"
" -E IP_RECVDSTADDR option\n"
" -F fork after connection accepted (TCP concurrent server)\n"
" -G a.b.c.d strict source route\n"
#ifdef IP_TOS
" -H n IP_TOS option (16=min del, 8=max thru, 4=max rel, 2=min$)\n"
#endif
" -I SIGIO signal\n"
#ifdef IP_TTL
" -J n IP_TTL option\n"
#endif
" -K SO_KEEPALIVE option\n"
" -L n SO_LINGER option, n = linger time\n"
" -N TCP_NODELAY option\n"
" -O n #ms to pause after listen, but before first accept\n"
" -P n #ms to pause before first read or write (source/sink)\n"
" -Q n #ms to pause after receiving FIN, but before close\n"
" -R n SO_RCVBUF option\n"
" -S n SO_SNDBUF option\n"
#ifdef SO_REUSEPORT
" -T SO_REUSEPORT option\n"
#endif
" -U n enter urgent mode before write number n (source only)\n"
" -V use writev() instead of write(); enables -k too\n"
" -W ignore write errors for sink client\n"
" -X n TCP_MAXSEG option (set MSS)\n"
" -Y SO_DONTROUTE option\n"
" -Z MSG_PEEK\n"
#ifdef IP_ONESBCAST
" -2 IP_ONESBCAST option (255.255.255.255 for broadcast\n"
#endif
);
if (msg[0] != 0)
err_quit("%s", msg);
exit(1);
}
-33
View File
@@ -1,33 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "sock.h"
void
join_mcast(int fd, struct sockaddr_in *sin)
{
#ifdef IP_ADD_MEMBERSHIP /* only include if host supports mcasting */
u_long inaddr;
struct ip_mreq mreq;
inaddr = sin->sin_addr.s_addr;
if (IN_MULTICAST(inaddr) == 0)
return; /* not a multicast address */
mreq.imr_multiaddr.s_addr = inaddr;
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /* need way to change */
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) == -1 )
err_sys("IP_ADD_MEMBERSHIP error");
if (verbose)
fprintf(stderr, "multicast group joined\n");
#endif /* IP_ADD_MEMBERSHIP */
}
-122
View File
@@ -1,122 +0,0 @@
/* -*- c-basic-offset: 8; -*- */
/* Our own header, to be included *after* all standard system headers */
#ifndef __ourhdr_h
#define __ourhdr_h
#include <sys/types.h> /* required for some of our prototypes */
#include <stdio.h> /* for convenience */
#include <stdlib.h> /* for convenience */
#include <string.h> /* for convenience */
#include <unistd.h> /* for convenience */
#ifdef notdef /* delete for systems that don't define this (SunOS 4.x) */
typedef int ssize_t;
#endif
#ifdef notdef /* delete if <stdlib.h> doesn't define these for getopt() */
extern char *optarg;
extern int optind, opterr, optopt;
#endif
#ifdef notdef /* delete if send() not supported (DEC OSF/1) */
#define send(a,b,c,d) sendto((a), (b), (c), (d), (struct sockaddr *) NULL, 0)
#endif
#define MAXLINE 4096 /* max line length */
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
/* default file access permissions for new files */
#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
/* default permissions for new directories */
typedef void Sigfunc(int); /* for signal handlers */
/* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */
#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((Sigfunc *)-1)
#endif
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
/* prototypes for our own functions */
char *path_alloc(int *); /* {Prog pathalloc} */
int open_max(void); /* {Prog openmax} */
void clr_fl(int, int); /* {Prog setfl} */
void set_fl(int, int); /* {Prog setfl} */
void pr_exit(int); /* {Prog prexit} */
void pr_mask(const char *); /* {Prog prmask} */
Sigfunc *signal_intr(int, Sigfunc *);/* {Prog signal_intr_function} */
int tty_cbreak(int); /* {Prog raw} */
int tty_raw(int); /* {Prog raw} */
int tty_reset(int); /* {Prog raw} */
void tty_atexit(void); /* {Prog raw} */
#ifdef ECHO /* only if <termios.h> has been included */
struct termios *tty_termios(void); /* {Prog raw} */
#endif
void sleep_us(unsigned int); /* {Ex sleepus} */
ssize_t readn(int, void *, size_t);/* {Prog readn} */
ssize_t writen(int, const void *, size_t);/* {Prog writen} */
int daemon_init(void); /* {Prog daemoninit} */
int s_pipe(int *); /* {Progs svr4_spipe bsd_spipe} */
int recv_fd(int, ssize_t (*func)(int, const void *, size_t));
/* {Progs recvfd_svr4 recvfd_43bsd} */
int send_fd(int, int); /* {Progs sendfd_svr4 sendfd_43bsd} */
int send_err(int, int, const char *);/* {Prog senderr} */
int serv_listen(const char *); /* {Progs servlisten_svr4 servlisten_44bsd} */
int serv_accept(int, uid_t *); /* {Progs servaccept_svr4 servaccept_44bsd} */
int cli_conn(const char *); /* {Progs cliconn_svr4 cliconn_44bsd} */
int buf_args(char *, int (*func)(int, char **));
/* {Prog bufargs} */
int ptym_open(char *); /* {Progs ptyopen_svr4 ptyopen_44bsd} */
int ptys_open(int, char *); /* {Progs ptyopen_svr4 ptyopen_44bsd} */
#ifdef TIOCGWINSZ
pid_t pty_fork(int *, char *, const struct termios *,
const struct winsize *); /* {Prog ptyfork} */
#endif
int lock_reg(int, int, int, off_t, int, off_t);
/* {Prog lockreg} */
#define read_lock(fd, offset, whence, len) \
lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len)
#define readw_lock(fd, offset, whence, len) \
lock_reg(fd, F_SETLKW, F_RDLCK, offset, whence, len)
#define write_lock(fd, offset, whence, len) \
lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len)
#define writew_lock(fd, offset, whence, len) \
lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len)
#define un_lock(fd, offset, whence, len) \
lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len)
pid_t lock_test(int, int, off_t, int, off_t);
/* {Prog locktest} */
#define is_readlock(fd, offset, whence, len) \
lock_test(fd, F_RDLCK, offset, whence, len)
#define is_writelock(fd, offset, whence, len) \
lock_test(fd, F_WRLCK, offset, whence, len)
void err_dump(const char *, ...); /* {App misc_source} */
void err_msg(const char *, ...);
void err_quit(const char *, ...);
void err_ret(const char *, ...);
void err_sys(const char *, ...);
void log_msg(const char *, ...); /* {App misc_source} */
void log_open(const char *, int, int);
void log_quit(const char *, ...);
void log_ret(const char *, ...);
void log_sys(const char *, ...);
void TELL_WAIT(void); /* parent/child from {Sec race_conditions} */
void TELL_PARENT(pid_t);
void TELL_CHILD(pid_t);
void WAIT_PARENT(void);
void WAIT_CHILD(void);
#endif /* __ourhdr_h */
-25
View File
@@ -1,25 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "sock.h"
#include <ctype.h>
void
pattern(char *ptr, int len)
{
char c;
c = 0;
while(len-- > 0) {
while(isprint((c & 0x7F)) == 0)
c++; /* skip over nonprinting characters */
*ptr++ = (c++ & 0x7F);
}
}
-154
View File
@@ -1,154 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "sock.h"
int
servopen(char *host, char *port)
{
int fd, newfd, i, on, pid;
char *protocol;
struct in_addr inaddr;
struct servent *sp;
protocol = udp ? "udp" : "tcp";
/* Initialize the socket address structure */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
/* Caller normally wildcards the local Internet address, meaning
a connection will be accepted on any connected interface.
We only allow an IP address for the "host", not a name. */
if (host == NULL)
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */
else {
if (inet_aton(host, &inaddr) == 0)
err_quit("invalid host name for server: %s", host);
servaddr.sin_addr = inaddr;
}
/* See if "port" is a service name or number */
if ( (i = atoi(port)) == 0) {
if ( (sp = getservbyname(port, protocol)) == NULL)
err_ret("getservbyname() error for: %s/%s", port, protocol);
servaddr.sin_port = sp->s_port;
} else
servaddr.sin_port = htons(i);
if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
err_sys("socket() error");
if (reuseaddr) {
on = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
err_sys("setsockopt of SO_REUSEADDR error");
}
#ifdef SO_REUSEPORT
if (reuseport) {
on = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
err_sys("setsockopt of SO_REUSEPORT error");
}
#endif
/* Bind our well-known port so the client can connect to us. */
if (bind(fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
err_sys("can't bind local address");
join_mcast(fd, &servaddr);
if (udp) {
buffers(fd);
if (foreignip[0] != 0) { /* connect to foreignip/port# */
bzero(&cliaddr, sizeof(cliaddr));
if (inet_aton(foreignip, &cliaddr.sin_addr) == 0)
err_quit("invalid IP address: %s", foreignip);
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(foreignport);
/* connect() for datagram socket doesn't appear to allow
wildcarding of either IP address or port number */
if (connect(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr))
< 0)
err_sys("connect() error");
}
sockopts(fd, 1);
return(fd); /* nothing else to do */
}
buffers(fd); /* may set receive buffer size; must do here to get
correct window advertised on SYN */
sockopts(fd, 0); /* only set some socket options for fd */
listen(fd, listenq);
if (pauselisten)
sleep_us(pauselisten*1000); /* lets connection queue build up */
if (dofork)
TELL_WAIT(); /* initialize synchronization primitives */
for ( ; ; ) {
i = sizeof(cliaddr);
if ( (newfd = accept(fd, (struct sockaddr *) &cliaddr, &i)) < 0)
err_sys("accept() error");
if (dofork) {
if ( (pid = fork()) < 0)
err_sys("fork error");
if (pid > 0) {
close(newfd); /* parent closes connected socket */
WAIT_CHILD(); /* wait for child to output to terminal */
continue; /* and back to for(;;) for another accept() */
} else {
close(fd); /* child closes listening socket */
}
}
/* child (or iterative server) continues here */
if (verbose) {
/* Call getsockname() to find local address bound to socket:
local internet address is now determined (if multihomed). */
i = sizeof(servaddr);
if (getsockname(newfd, (struct sockaddr *) &servaddr, &i) < 0)
err_sys("getsockname() error");
/* Can't do one fprintf() since inet_ntoa() stores
the result in a static location. */
fprintf(stderr, "connection on %s.%d ",
INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port));
fprintf(stderr, "from %s.%d\n",
INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
}
buffers(newfd); /* setsockopt() again, in case it didn't propagate
from listening socket to connected socket */
sockopts(newfd, 1); /* can set all socket options for this socket */
if (dofork)
TELL_PARENT(getppid()); /* tell parent we're done with terminal */
return(newfd);
}
}
-62
View File
@@ -1,62 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <stdio.h>
#include "sock.h"
void
sink_tcp(int sockfd)
{
int n, flags;
if (pauseinit)
sleep_us(pauseinit*1000);
for ( ; ; ) { /* read until peer closes connection; -n opt ignored */
/* msgpeek = 0 or MSG_PEEK */
flags = msgpeek;
oncemore:
if ( (n = recv(sockfd, rbuf, readlen, flags)) < 0) {
err_sys("recv error");
} else if (n == 0) {
if (verbose)
fprintf(stderr, "connection closed by peer\n");
break;
#ifdef notdef /* following not possible with TCP */
} else if (n != readlen)
err_quit("read returned %d, expected %d", n, readlen);
#else
}
#endif
if (verbose)
fprintf(stderr, "received %d bytes%s\n", n,
(flags == MSG_PEEK) ? " (MSG_PEEK)" : "");
if (pauserw)
sleep_us(pauserw*1000);
if (flags != 0) {
flags = 0; /* no infinite loop */
goto oncemore; /* read the message again */
}
}
if (pauseclose) { /* pausing here puts peer into FIN_WAIT_2 */
if (verbose)
fprintf(stderr, "pausing before close\n");
sleep_us(pauseclose*1000);
}
if (close(sockfd) < 0)
err_sys("close error"); /* since SO_LINGER may be set */
}
-70
View File
@@ -1,70 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <stdio.h>
#include "sock.h"
void
sink_udp(int sockfd) /* TODO: use recvfrom ?? */
{
int n, flags;
if (pauseinit)
sleep_us(pauseinit*1000);
for ( ; ; ) { /* read until peer closes connection; -n opt ignored */
/* msgpeek = 0 or MSG_PEEK */
flags = msgpeek;
oncemore:
if ( (n = recv(sockfd, rbuf, readlen, flags)) < 0) {
err_sys("recv error");
} else if (n == 0) {
if (verbose)
fprintf(stderr, "connection closed by peer\n");
break;
#ifdef notdef /* following not possible with TCP */
} else if (n != readlen)
err_quit("read returned %d, expected %d", n, readlen);
#else
}
#endif
if (verbose) {
fprintf(stderr, "received %d bytes%s\n", n,
(flags == MSG_PEEK) ? " (MSG_PEEK)" : "");
if (verbose > 1) {
fprintf(stderr, "printing %d bytes\n", n);
rbuf[n] = 0; /* make certain it's null terminated */
fprintf(stderr, "SDAP header: %lx\n", *((long *) rbuf));
fprintf(stderr, "next long: %lx\n", *((long *) rbuf+4));
fputs(&rbuf[8], stderr);
}
}
if (pauserw)
sleep_us(pauserw*1000);
if (flags != 0) {
flags = 0; /* avoid infinite loop */
goto oncemore; /* read the message again */
}
}
if (pauseclose) {
if (verbose)
fprintf(stderr, "pausing before close\n");
sleep_us(pauseclose*1000);
}
if (close(sockfd) < 0)
err_sys("close error");
}
-30
View File
@@ -1,30 +0,0 @@
/* -*- c-basic-offset: 8; -*- */
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <stddef.h>
#include "ourhdr.h"
void
sleep_us(unsigned int nusecs)
{
struct timeval tval;
for ( ; ; ) {
tval.tv_sec = nusecs / 1000000;
tval.tv_usec = nusecs % 1000000;
if (select(0, NULL, NULL, NULL, &tval) == 0)
break; /* all OK */
/*
* Note than on an interrupted system call (i.e, SIGIO) there's not
* much we can do, since the timeval{} isn't updated with the time
* remaining. We could obtain the clock time before the call, and
* then obtain the clock time here, subtracting them to determine
* how long select() blocked before it was interrupted, but that
* seems like too much work :-)
*/
if (errno == EINTR)
continue;
err_sys("sleep_us: select error");
}
}
-163
View File
@@ -1,163 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "config.h" /* configuration options for current OS */
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <errno.h>
#include <sys/param.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifndef HAVE_ADDRINFO_STRUCT
#include "addrinfo.h"
#endif
#include <sys/uio.h>
#ifdef __bsdi__
#include <machine/endian.h> /* required before tcp.h, for BYTE_ORDER */
#endif
#include <netinet/tcp.h> /* TCP_NODELAY */
#include <netdb.h> /* getservbyname(), gethostbyname() */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
/* Older resolvers do not have gethostbyname2() */
#ifndef HAVE_GETHOSTBYNAME2
#define gethostbyname2(host,family) gethostbyname((host))
#endif
/* This avoids a warning with glibc compilation */
#ifndef errno
extern int errno;
#endif
/* Miscellaneous constants */
#define MAXLINE 4096 /* max text line length */
#define MAXSOCKADDR 128 /* max socket address structure size */
#define BUFFSIZE 8192 /* buffer size for reads and writes */
/* stdin and stdout file descriptors */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
/* declare global variables */
extern int bindport;
extern int broadcast;
extern int cbreak;
extern int chunkwrite;
extern int client;
extern int connectudp;
extern int crlf;
extern int debug;
extern int dofork;
extern int dontroute;
extern char foreignip[];
extern int foreignport;
extern int halfclose;
extern int ignorewerr;
extern int iptos;
extern int ipttl;
extern char joinip[];
extern int keepalive;
extern long linger;
extern int listenq;
extern char localip[];
extern int maxseg;
extern int mcastttl;
extern int msgpeek;
extern int nodelay;
extern int nbuf;
extern int onesbcast;
extern int pauseclose;
extern int pauseinit;
extern int pauselisten;
extern int pauserw;
extern int reuseaddr;
extern int reuseport;
extern int readlen;
extern int writelen;
extern int recvdstaddr;
extern int rcvbuflen;
extern int sndbuflen;
extern long rcvtimeo;
extern long sndtimeo;
extern char *rbuf;
extern char *wbuf;
extern int server;
extern int sigio;
extern int sourcesink;
extern int sroute_cnt;
extern int udp;
extern int urgwrite;
extern int verbose;
extern int usewritev;
extern struct sockaddr_in cliaddr, servaddr;
/* Earlier versions of gcc under SunOS 4.x have problems passing arguments
that are structs (as opposed to pointers to structs). This shows up
with inet_ntoa, whose argument is a "struct in_addr". */
#if defined(sun) && defined(__GNUC__) && defined(GCC_STRUCT_PROBLEM)
#define INET_NTOA(foo) inet_ntoa(&foo)
#else
#define INET_NTOA(foo) inet_ntoa(foo)
#endif
/* function prototypes */
void buffers(int);
int cliopen(char *, char *);
int crlf_add(char *, int, const char *, int);
int crlf_strip(char *, int, const char *, int);
void join_mcast(int, struct sockaddr_in *);
void loop_tcp(int);
void loop_udp(int);
void pattern(char *, int);
int servopen(char *, char *);
void sink_tcp(int);
void sink_udp(int);
void source_tcp(int);
void source_udp(int);
void sroute_doopt(int, char *);
void sroute_set(int);
void sleep_us(unsigned int);
void sockopts(int, int);
ssize_t dowrite(int, const void *, size_t);
void TELL_WAIT(void);
void TELL_PARENT(pid_t);
void WAIT_PARENT(void);
void TELL_CHILD(pid_t);
void WAIT_CHILD(void);
void err_dump(const char *, ...);
void err_msg(const char *, ...);
void err_quit(const char *, ...);
void err_ret(const char *, ...);
void err_sys(const char *, ...);
ssize_t writen(int, const void *, size_t);
-374
View File
@@ -1,374 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include "sock.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#ifdef FIOASYNC
static void sigio_func(int);
static void
sigio_func(int signo)
{
fprintf(stderr, "SIGIO\n");
/* shouldn't printf from a signal handler ... */
}
#endif
void
sockopts(int sockfd, int doall)
{
int option;
unsigned optlen;
struct linger ling;
struct timeval timer;
/* "doall" is 0 for a server's listening socket (i.e., before
accept() has returned.) Some socket options such as SO_KEEPALIVE
don't make sense at this point, while others like SO_DEBUG do. */
if (debug) {
option = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_DEBUG,
&option, sizeof(option)) < 0)
err_sys("SO_DEBUG setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, SOL_SOCKET, SO_DEBUG,
&option, &optlen) < 0)
err_sys("SO_DEBUG getsockopt error");
if (option == 0)
err_quit("SO_DEBUG not set (%d)", option);
if (verbose)
fprintf(stderr, "SO_DEBUG set\n");
}
if (dontroute) {
option = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE,
&option, sizeof(option)) < 0)
err_sys("SO_DONTROUTE setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE,
&option, &optlen) < 0)
err_sys("SO_DONTROUTE getsockopt error");
if (option == 0)
err_quit("SO_DONTROUTE not set (%d)", option);
if (verbose)
fprintf(stderr, "SO_DONTROUTE set\n");
}
#ifdef IP_TOS
if (iptos != -1 && doall == 0) {
if (setsockopt(sockfd, IPPROTO_IP, IP_TOS,
&iptos, sizeof(iptos)) < 0)
err_sys("IP_TOS setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, IPPROTO_IP, IP_TOS,
&option, &optlen) < 0)
err_sys("IP_TOS getsockopt error");
if (option != iptos)
err_quit("IP_TOS not set (%d)", option);
if (verbose)
fprintf(stderr, "IP_TOS set to %d\n", iptos);
}
#endif
#ifdef IP_TTL
if (ipttl != -1 && doall == 0) {
if (setsockopt(sockfd, IPPROTO_IP, IP_TTL,
&ipttl, sizeof(ipttl)) < 0)
err_sys("IP_TTL setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, IPPROTO_IP, IP_TTL,
&option, &optlen) < 0)
err_sys("IP_TTL getsockopt error");
if (option != ipttl)
err_quit("IP_TTL not set (%d)", option);
if (verbose)
fprintf(stderr, "IP_TTL set to %d\n", ipttl);
}
#endif
if (maxseg && udp == 0) {
/* Need to set MSS for server before connection established */
/* Beware: some kernels do not let the process set this socket
option; others only let it be decreased. */
if (setsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,
&maxseg, sizeof(maxseg)) < 0)
err_sys("TCP_MAXSEG setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,
&option, &optlen) < 0)
err_sys("TCP_MAXSEG getsockopt error");
if (verbose)
fprintf(stderr, "TCP_MAXSEG = %d\n", option);
}
if (sroute_cnt > 0)
sroute_set(sockfd);
if (broadcast) {
option = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
&option, sizeof(option)) < 0)
err_sys("SO_BROADCAST setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
&option, &optlen) < 0)
err_sys("SO_BROADCAST getsockopt error");
if (option == 0)
err_quit("SO_BROADCAST not set (%d)", option);
if (verbose)
fprintf(stderr, "SO_BROADCAST set\n");
#ifdef IP_ONESBCAST
if (onesbcast) {
option = 1;
if (setsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST,
&option, sizeof(option)) < 0)
err_sys("IP_ONESBCAST setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST,
&option, &optlen) < 0)
err_sys("IP_ONESBCAST getsockopt error");
if (option == 0)
err_quit("IP_ONESBCAST not set (%d)", option);
if (verbose)
fprintf(stderr, "IP_ONESBCAST set\n");
}
#endif
}
#ifdef IP_ADD_MEMBERSHIP
if (joinip[0]) {
struct ip_mreq join;
if (inet_aton(joinip, &join.imr_multiaddr) == 0)
err_quit("invalid multicast address: %s", joinip);
join.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&join, sizeof(join)) < 0)
err_sys("IP_ADD_MEMBERSHIP setsockopt error");
if (verbose)
fprintf(stderr, "IP_ADD_MEMBERSHIP set\n");
}
#endif
#ifdef IP_MULTICAST_TTL
if (mcastttl) {
u_char ttl = mcastttl;
if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
&ttl, sizeof(ttl)) < 0)
err_sys("IP_MULTICAST_TTL setsockopt error");
optlen = sizeof(ttl);
if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
&ttl, &optlen) < 0)
err_sys("IP_MULTICAST_TTL getsockopt error");
if (ttl != mcastttl)
err_quit("IP_MULTICAST_TTL not set (%d)", ttl);
if (verbose)
fprintf(stderr, "IP_MULTICAST_TTL set to %d\n", ttl);
}
#endif
if (keepalive && doall && udp == 0) {
option = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
&option, sizeof(option)) < 0)
err_sys("SO_KEEPALIVE setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
&option, &optlen) < 0)
err_sys("SO_KEEPALIVE getsockopt error");
if (option == 0)
err_quit("SO_KEEPALIVE not set (%d)", option);
if (verbose)
fprintf(stderr, "SO_KEEPALIVE set\n");
}
if (nodelay && doall && udp == 0) {
option = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
&option, sizeof(option)) < 0)
err_sys("TCP_NODELAY setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
&option, &optlen) < 0)
err_sys("TCP_NODELAY getsockopt error");
if (option == 0)
err_quit("TCP_NODELAY not set (%d)", option);
if (verbose)
fprintf(stderr, "TCP_NODELAY set\n");
}
if (doall && verbose && udp == 0) { /* just print MSS if verbose */
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,
&option, &optlen) < 0)
err_sys("TCP_MAXSEG getsockopt error");
fprintf(stderr, "TCP_MAXSEG = %d\n", option);
}
if (linger >= 0 && doall && udp == 0) {
ling.l_onoff = 1;
ling.l_linger = linger; /* 0 for abortive disconnect */
if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER,
&ling, sizeof(ling)) < 0)
err_sys("SO_LINGER setsockopt error");
ling.l_onoff = 0;
ling.l_linger = -1;
optlen = sizeof(struct linger);
if (getsockopt(sockfd, SOL_SOCKET, SO_LINGER,
&ling, &optlen) < 0)
err_sys("SO_LINGER getsockopt error");
if (ling.l_onoff == 0 || ling.l_linger != linger)
err_quit("SO_LINGER not set (%d, %d)", ling.l_onoff, ling.l_linger);
if (verbose)
fprintf(stderr, "linger %s, time = %d\n",
ling.l_onoff ? "on" : "off", ling.l_linger);
}
if (doall && rcvtimeo) {
#ifdef SO_RCVTIMEO
/* User specifies millisec, must convert to sec/usec */
timer.tv_sec = rcvtimeo / 1000;
timer.tv_usec = (rcvtimeo % 1000) * 1000;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,
&timer, sizeof(timer)) < 0)
err_sys("SO_RCVTIMEO setsockopt error");
timer.tv_sec = timer.tv_usec = 0;
optlen = sizeof(timer);
if (getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,
&timer, &optlen) < 0)
err_sys("SO_RCVTIMEO getsockopt error");
if (verbose)
fprintf(stderr, "SO_RCVTIMEO: %ld.%06ld\n",
timer.tv_sec, timer.tv_usec);
#else
fprintf(stderr, "warning: SO_RCVTIMEO not supported by host\n");
#endif
}
if (doall && sndtimeo) {
#ifdef SO_SNDTIMEO
/* User specifies millisec, must convert to sec/usec */
timer.tv_sec = sndtimeo / 1000;
timer.tv_usec = (sndtimeo % 1000) * 1000;
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO,
&timer, sizeof(timer)) < 0)
err_sys("SO_SNDTIMEO setsockopt error");
timer.tv_sec = timer.tv_usec = 0;
optlen = sizeof(timer);
if (getsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO,
&timer, &optlen) < 0)
err_sys("SO_SNDTIMEO getsockopt error");
if (verbose)
fprintf(stderr, "SO_SNDTIMEO: %ld.%06ld\n",
timer.tv_sec, timer.tv_usec);
#else
fprintf(stderr, "warning: SO_SNDTIMEO not supported by host\n");
#endif
}
if (recvdstaddr && udp) {
#ifdef IP_RECVDSTADDR
option = 1;
if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR,
&option, sizeof(option)) < 0)
err_sys("IP_RECVDSTADDR setsockopt error");
option = 0;
optlen = sizeof(option);
if (getsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR,
&option, &optlen) < 0)
err_sys("IP_RECVDSTADDR getsockopt error");
if (option == 0)
err_quit("IP_RECVDSTADDR not set (%d)", option);
if (verbose)
fprintf(stderr, "IP_RECVDSTADDR set\n");
#else
fprintf(stderr, "warning: IP_RECVDSTADDR not supported by host\n");
#endif
}
if (sigio) {
#ifdef FIOASYNC
/*
* Should be able to set this with fcntl(O_ASYNC) or fcntl(FASYNC),
* but some systems (AIX?) only do it with ioctl().
*
* Need to set this for listening socket and for connected socket.
*/
signal(SIGIO, sigio_func);
if (fcntl(sockfd, F_SETOWN, getpid()) < 0)
err_sys("fcntl F_SETOWN error");
option = 1;
if (ioctl(sockfd, FIOASYNC, (char *) &option) < 0)
err_sys("ioctl FIOASYNC error");
if (verbose)
fprintf(stderr, "FIOASYNC set\n");
#else
fprintf(stderr, "warning: FIOASYNC not supported by host\n");
#endif
}
}
-114
View File
@@ -1,114 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <stdio.h>
#include "sock.h"
#include <netinet/ip.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*
* There is a fundamental limit of 9 IP addresses in a source route.
* But we allocate sroute_opt[44] with room for 10 IP addresses (and
* the 3-byte source route type/len/offset) because with the BSD
* IP_OPTIONS socket option we can specify up to 9 addresses, followed
* by the destination address. The in_pcbopts() function in the kernel
* then takes the final address in the list (the destination) and moves
* it to the front, as shown in Figure 9.33 of "TCP/IP Illustrated,
* Volume 2". Also note that this destination address that we pass as
* the final IP address in our array overrides the destination address
* of the sendto() (Figure 9.28 of Volume 2).
*/
u_char sroute_opt[44]; /* some implementations require this to be
on a 4-byte boundary */
u_char *optr; /* pointer into options being formed */
/*
* Process either the -g (loose) or -G (strict) command-line option,
* specifying one hop in a source route.
* Either option can be specified up to 9 times.
* With IPv4 the entire source route is either loose or strict, but we
* set the source route type field based on the first option encountered,
* either -g or -G.
*/
void
sroute_doopt(int strict, char *argptr)
{
struct in_addr inaddr;
struct hostent *hp;
if (sroute_cnt >= 9)
err_quit("too many source routes with: %s", argptr);
if (sroute_cnt == 0) { /* first one */
bzero(sroute_opt, sizeof(sroute_opt));
optr = sroute_opt;
*optr++ = strict ? IPOPT_SSRR : IPOPT_LSRR;
optr++; /* we fill in the total length later */
*optr++ = 4; /* ptr to first source-route address */
}
if (inet_aton(argptr, &inaddr) == 1) {
bcopy(&inaddr, optr, sizeof(u_long)); /* dotted decimal */
if (verbose)
fprintf(stderr, "source route to %s\n", inet_ntoa(inaddr));
} else if ( (hp = gethostbyname(argptr)) != NULL) {
bcopy(hp->h_addr, optr, sizeof(u_long));/* hostname */
if (verbose)
fprintf(stderr, "source route to %s\n",
inet_ntoa(*((struct in_addr *) hp->h_addr)));
} else
err_quit("unknown host: %s\n", argptr);
optr += sizeof(u_long); /* for next IP addr in list */
sroute_cnt++;
}
/*
* Set the actual source route with the IP_OPTIONS socket option.
* This function is called if srouce_cnt is nonzero.
* The final destination goes at the end of the list of IP addresses.
*/
void
sroute_set(int sockfd)
{
sroute_cnt++; /* account for destination */
sroute_opt[1] = 3 + (sroute_cnt * 4); /* total length, incl. destination */
/* destination must be stored as final entry */
bcopy(&servaddr.sin_addr, optr, sizeof(u_long));
optr += sizeof(u_long);
if (verbose) {
fprintf(stderr, "source route to %s\n", inet_ntoa(servaddr.sin_addr));
fprintf(stderr, "source route size %d bytes\n", sroute_opt[1]);
}
/*
* The number of bytes that we pass to setsockopt() must be a multiple
* of 4. Since the buffer was initialized to 0, this leaves an EOL
* following the final IP address.
* For optimization we could put a NOP before the 3-byte type/len/offset
* field, which would then align all the IP addresses on 4-byte boundaries,
* but the source routing code is not exactly in the fast path of most
* routers.
*/
while ((optr - sroute_opt) & 3)
optr++;
if (setsockopt(sockfd, IPPROTO_IP, IP_OPTIONS,
sroute_opt, optr - sroute_opt) < 0)
err_sys("setsockopt error for IP_OPTIONS");
sroute_cnt = 0; /* don't call this function again */
}
-62
View File
@@ -1,62 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <stdio.h>
#include "sock.h"
void
source_tcp(int sockfd)
{
int i, n, option;
socklen_t optlen;
char oob;
pattern(wbuf, writelen); /* fill send buffer with a pattern */
if (pauseinit)
sleep_us(pauseinit*1000);
for (i = 1; i <= nbuf; i++) {
if (urgwrite == i) {
oob = urgwrite;
if ( (n = send(sockfd, &oob, 1, MSG_OOB)) != 1)
err_sys("send of MSG_OOB returned %d, expected %d",
n, writelen);
if (verbose)
fprintf(stderr, "wrote %d byte of urgent data\n", n);
}
if ( (n = write(sockfd, wbuf, writelen)) != writelen) {
if (ignorewerr) {
err_ret("write returned %d, expected %d", n, writelen);
/* also call getsockopt() to clear so_error */
optlen = sizeof(option);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
&option, &optlen) < 0)
err_sys("SO_ERROR getsockopt error");
} else
err_sys("write returned %d, expected %d", n, writelen);
} else if (verbose)
fprintf(stderr, "wrote %d bytes\n", n);
if (pauserw)
sleep_us(pauserw*1000);
}
if (pauseclose) {
if (verbose)
fprintf(stderr, "pausing before close\n");
sleep_us(pauseclose*1000);
}
if (close(sockfd) < 0)
err_sys("close error"); /* since SO_LINGER may be set */
}
-72
View File
@@ -1,72 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include "sock.h"
void
source_udp(int sockfd) /* TODO: use sendto ?? */
{
int i, n, option;
socklen_t optlen;
pattern(wbuf, writelen); /* fill send buffer with a pattern */
if (pauseinit)
sleep_us(pauseinit*1000);
for (i = 1; i <= nbuf; i++) {
if (connectudp) {
if ( (n = write(sockfd, wbuf, writelen)) != writelen) {
if (ignorewerr) {
err_ret("write returned %d, expected %d", n, writelen);
/* also call getsockopt() to clear so_error */
optlen = sizeof(option);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
&option, &optlen) < 0)
err_sys("SO_ERROR getsockopt error");
} else
err_sys("write returned %d, expected %d", n, writelen);
}
} else {
if ( (n = sendto(sockfd, wbuf, writelen, 0,
(struct sockaddr *) &servaddr,
sizeof(struct sockaddr))) != writelen) {
if (ignorewerr) {
err_ret("sendto returned %d, expected %d", n, writelen);
/* also call getsockopt() to clear so_error */
optlen = sizeof(option);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
&option, &optlen) < 0)
err_sys("SO_ERROR getsockopt error");
} else
err_sys("sendto returned %d, expected %d", n, writelen);
}
}
if (verbose)
fprintf(stderr, "wrote %d bytes\n", n);
if (pauserw)
sleep_us(pauserw*1000);
}
if (pauseclose) {
if (verbose)
fprintf(stderr, "pausing before close\n");
sleep_us(pauseclose*1000);
}
if (close(sockfd) < 0)
err_sys("close error"); /* since SO_LINGER may be set */
}
-68
View File
@@ -1,68 +0,0 @@
/* -*- c-basic-offset: 8; -*- */
#include <signal.h>
#include "ourhdr.h"
static volatile sig_atomic_t sigflag;
/* set nonzero by signal handler */
static sigset_t newmask, oldmask, zeromask;
static void
sig_usr(int signo) /* one signal handler for SIGUSR1 and SIGUSR2 */
{
sigflag = 1;
return;
}
void
TELL_WAIT()
{
if (signal(SIGUSR1, sig_usr) == SIG_ERR)
err_sys("signal(SIGINT) error");
if (signal(SIGUSR2, sig_usr) == SIG_ERR)
err_sys("signal(SIGQUIT) error");
sigemptyset(&zeromask);
sigemptyset(&newmask);
sigaddset(&newmask, SIGUSR1);
sigaddset(&newmask, SIGUSR2);
/* block SIGUSR1 and SIGUSR2, and save current signal mask */
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error");
}
void
TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we're done */
}
void
WAIT_PARENT(void)
{
while (sigflag == 0)
sigsuspend(&zeromask); /* and wait for parent */
sigflag = 0;
/* reset signal mask to original value */
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
}
void
TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1); /* tell child we're done */
}
void
WAIT_CHILD(void)
{
while (sigflag == 0)
sigsuspend(&zeromask); /* and wait for child */
sigflag = 0;
/* reset signal mask to original value */
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
}
-67
View File
@@ -1,67 +0,0 @@
/* -*- c-basic-offset: 8; -*-
*
* Copyright (c) 1993 W. Richard Stevens. All rights reserved.
* Permission to use or modify this software and its documentation only for
* educational purposes and without fee is hereby granted, provided that
* the above copyright notice appear in all copies. The author makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "sock.h"
#ifndef UIO_MAXIOV
#define UIO_MAXIOV 16 /* we assume this; may not be true? */
#endif
ssize_t
dowrite(int fd, const void *vptr, size_t nbytes)
{
struct iovec iov[UIO_MAXIOV];
const char *ptr;
int chunksize, i, n, nleft, nwritten, ntotal;
if (chunkwrite == 0 && usewritev == 0)
return(write(fd, vptr, nbytes)); /* common case */
/*
* Figure out what sized chunks to write.
* Try to use UIO_MAXIOV chunks.
*/
chunksize = nbytes / UIO_MAXIOV;
if (chunksize <= 0)
chunksize = 1;
else if ((nbytes % UIO_MAXIOV) != 0)
chunksize++;
ptr = vptr;
nleft = nbytes;
for (i = 0; i < UIO_MAXIOV; i++)
{
iov[i].iov_base = (void *) ptr;
n = (nleft >= chunksize) ? chunksize : nleft;
iov[i].iov_len = n;
if (verbose)
fprintf(stderr, "iov[%2d].iov_base = %x, iov[%2d].iov_len = %d\n",
i, (u_int32_t) iov[i].iov_base, i, (int) iov[i].iov_len);
ptr += n;
if ((nleft -= n) == 0)
break;
}
if (i == UIO_MAXIOV)
err_quit("i == UIO_MAXIOV");
if (usewritev)
return(writev(fd, iov, i+1));
else {
ntotal = 0;
for (n = 0; n <= i; n++) {
nwritten = write(fd, iov[n].iov_base, iov[n].iov_len);
if (nwritten != (int) iov[n].iov_len)
return(-1);
ntotal += nwritten;
}
return(ntotal);
}
}
-28
View File
@@ -1,28 +0,0 @@
/* -*- c-basic-offset: 8; -*- */
/* include writen */
#include "sock.h"
ssize_t /* Write "n" bytes to a descriptor. */
writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (errno == EINTR)
nwritten = 0; /* and call write() again */
else
return(-1); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
/* end writen */