From fe1337fe5fc6dfc81bedb0d2ea487a4985de2f25 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 22 May 2008 10:02:04 +0200 Subject: [PATCH 01/75] fixed bug in ip*-recv with bind option --- CHANGES | 5 +++++ VERSION | 2 +- test.sh | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ xio-rawip.c | 9 ++++++--- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 3606959..406c48a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ +corrections: + there was a bug in ip*-recv with bind option: it did not bind, and + with the first received packet an error occurred: + socket_init(): unknown address family 0 + ####################### V 1.6.0.1: new features: diff --git a/VERSION b/VERSION index 8821d46..ec9f0dd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1" +"1.6.0.1+ip4bind" diff --git a/test.sh b/test.sh index 7876223..05e9957 100755 --- a/test.sh +++ b/test.sh @@ -8141,6 +8141,60 @@ PORT=$((PORT+1)) N=$((N+1)) +# test: there was a bug with ip*-recv and bind option: it would not bind, and +# with the first received packet an error: +# socket_init(): unknown address family 0 +# occurred +NAME=RAWIP4RECVBIND +case "$TESTS" in +*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*) +TEST="$NAME: raw IPv4 receive with bind" +# idea: start a socat process with ip4-recv:...,bind=... and send it a packet +# if the packet passes the test succeeded +if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts1p=$PROTO; PROTO=$((PROTO+1)) +ts1a="127.0.0.1" +ts1="$ts1a:$ts1p" +da=$(date) +CMD1="$SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -" +CMD2="$SOCAT $opts -u - IP4-SENDTO:$ts1" +printf "test $F_n $TEST... " $N +$CMD1 >"$tf" 2>"${te}1" & +pid1="$!" +waitip4proto $ts1p 1 +echo "$da" |$CMD2 2>>"${te}2" +rc2="$?" +#ls -l $tf +i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done +kill "$pid1" 2>/dev/null; wait +if [ "$rc2" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD1 &" + echo "$CMD2" + cat "${te}1" + cat "${te}2" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi +fi # must be root ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/xio-rawip.c b/xio-rawip.c index 1fe7450..d88da13 100644 --- a/xio-rawip.c +++ b/xio-rawip.c @@ -253,6 +253,7 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, int pf, int socktype, int dummy3) { const char *protname = argv[1]; char *garbage; + bool needbind = false; union sockaddr_union us; socklen_t uslen = sizeof(us); int ipproto; @@ -286,16 +287,18 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, #endif } - if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, + if (retropt_bind(opts, pf, socktype, ipproto, &/*us.soa*/xfd->stream.para.socket.la.soa, &uslen, 1, xfd->stream.para.socket.ip.res_opts[0], - xfd->stream.para.socket.ip.res_opts[1]) != + xfd->stream.para.socket.ip.res_opts[1]) == STAT_OK) { + needbind = true; + } else { /* pf is required during xioread checks */ xfd->stream.para.socket.la.soa.sa_family = pf; } xfd->stream.dtype = XIODATA_RECV_SKIPIP; - result = _xioopen_dgram_recv(&xfd->stream, xioflags, NULL/*&us.soa*/, uslen, + result = _xioopen_dgram_recv(&xfd->stream, xioflags, &/*us.soa*/xfd->stream.para.socket.la.soa, uslen, opts, pf, socktype, ipproto, E_ERROR); _xio_openlate(&xfd->stream, opts); return result; From d0860019115c783ff25b48f4ce0b558593d780dd Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 22 May 2008 13:54:10 +0200 Subject: [PATCH 02/75] RECVFROM addresses with FORK option hung after processing the first packet --- CHANGES | 3 +++ VERSION | 2 +- test.sh | 48 +++++++++++++++++++++++++++++++++ xio-socket.c | 75 ++++++++++++++++++++++++++++++++++------------------ 4 files changed, 101 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index 406c48a..213c651 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,9 @@ corrections: with the first received packet an error occurred: socket_init(): unknown address family 0 + RECVFROM addresses with FORK option hung after processing the first + packet. + ####################### V 1.6.0.1: new features: diff --git a/VERSION b/VERSION index ec9f0dd..5f22ae7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind" +"1.6.0.1+ip4bind+recvfromfork" diff --git a/test.sh b/test.sh index 05e9957..9d2fff7 100755 --- a/test.sh +++ b/test.sh @@ -8195,6 +8195,54 @@ PORT=$((PORT+1)) N=$((N+1)) +# there was a bug in *-recvfrom with fork: due to an error in the appropriate +# signal handler the master process would hang after forking off the first +# child process. +NAME=UDP4RECVFROM_FORK +case "$TESTS" in +*%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) +TEST="$NAME: test if UDP4-RECVFROM handles more than one packet" +# idea: run a UDP4-RECVFROM process with fork and -T. Send it one packet; +# send it a second packet and check if this is processed properly. If yes, the +# test succeeded. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +tsp=$PORT +ts="$LOCALHOST:$tsp" +da=$(date) +CMD1="$SOCAT $opts -T 2 UDP4-RECVFROM:$tsp,reuseaddr,fork PIPE" +CMD2="$SOCAT $opts -T 1 - UDP4-SENDTO:$ts" +printf "test $F_n $TEST... " $N +$CMD1 >/dev/null 2>"${te}1" & +pid1=$! +waitudp4port $tsp 1 +echo "$da" |$CMD2 >/dev/null 2>>"${te}2" # this should always work +rc2a=$? +sleep 1 +echo "$da" |$CMD2 >"$tf" 2>>"${te}3" # this would fail when bug +rc2b=$? +kill $pid1 2>/dev/null; wait +if [ $rc2b -ne 0 ]; then + $PRINTF "$NO_RESULT\n" + numCANT=$((numCANT+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD1 &" + echo "$CMD2" + cat "${te}1" "${te}2" "${te}3" + cat "$tdiff" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/xio-socket.c b/xio-socket.c index 01fda15..36fdb59 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -509,8 +509,26 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */ } -static pid_t xio_waitingfor; -static bool xio_hashappened; +/* when the recvfrom address (with option fork) receives a packet it keeps this + packet in the IP stacks input queue and forks a sub process. The sub process + then reads this packet for processing its data. + There is a problem because the parent process would find the same packet + again if it calls select()/poll() before the client process reads the + packet. + To solve this problem we implement the following mechanism: + The sub process sends a SIGUSR1 when it has read the packet (or a SIGCHLD if + it dies before). The parent process waits until it receives that signal and + only then continues to listen. + To prevent a signal from another process to trigger our loop, we pass the + pid of the sub process to the signal handler in xio_waitingfor. The signal + handler sets xio_hashappened if the pid matched. +*/ +static pid_t xio_waitingfor; /* info from recv loop to signal handler: + indicates the pid that of the child process + that should send us the USR1 signal */ +static bool xio_hashappened; /* info from signal handler to loop: child + process has read ("consumed") the packet */ +/* this is the signal handler for USR1 and CHLD */ void xiosigaction_hasread(int signum, siginfo_t *siginfo, void *ucontext) { pid_t pid; int _errno; @@ -519,30 +537,35 @@ void xiosigaction_hasread(int signum, siginfo_t *siginfo, void *ucontext) { Debug5("xiosigaction_hasread(%d, {%d,%d,%d,"F_pid"}, )", signum, siginfo->si_signo, siginfo->si_errno, siginfo->si_code, siginfo->si_pid); - _errno = errno; - do { - pid = Waitpid(-1, &status, WNOHANG); - if (pid == 0) { - Msg(wassig?E_INFO:E_WARN, - "waitpid(-1, {}, WNOHANG): no child has exited"); - Info("childdied() finished"); - errno = _errno; - return; - } else if (pid < 0 && errno == ECHILD) { - Msg1(wassig?E_INFO:E_WARN, - "waitpid(-1, {}, WNOHANG): %s", strerror(errno)); - Info("childdied() finished"); - errno = _errno; - return; - } - wassig = true; - if (pid < 0) { - Warn2("waitpid(-1, {%d}, WNOHANG): %s", status, strerror(errno)); - Info("childdied() finished"); - errno = _errno; - return; - } - } while (1); + if (signum == SIGCHLD) { + _errno = errno; + do { + pid = Waitpid(-1, &status, WNOHANG); + if (pid == 0) { + Msg(wassig?E_INFO:E_WARN, + "waitpid(-1, {}, WNOHANG): no child has exited"); + Info("childdied() finished"); + errno = _errno; + Debug("xiosigaction_hasread() ->"); + return; + } else if (pid < 0 && errno == ECHILD) { + Msg1(wassig?E_INFO:E_WARN, + "waitpid(-1, {}, WNOHANG): %s", strerror(errno)); + Info("childdied() finished"); + errno = _errno; + Debug("xiosigaction_hasread() ->"); + return; + } + wassig = true; + if (pid < 0) { + Warn2("waitpid(-1, {%d}, WNOHANG): %s", status, strerror(errno)); + Info("childdied() finished"); + errno = _errno; + Debug("xiosigaction_hasread() ->"); + return; + } + } while (1); + } if (xio_waitingfor == siginfo->si_pid) { xio_hashappened = true; } From c4751d50ecaafaf8bf2ec26d525a7cd16777a758 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 22 May 2008 20:09:48 +0200 Subject: [PATCH 03/75] corrected a few mistakes that caused compiler warnings on 64bit hosts --- CHANGES | 2 ++ VERSION | 2 +- error.c | 4 ++-- procan-cdefs.c | 2 +- xioopts.c | 8 ++++---- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 213c651..4a635b1 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,8 @@ corrections: RECVFROM addresses with FORK option hung after processing the first packet. + corrected a few mistakes that caused compiler warnings on 64bit hosts + ####################### V 1.6.0.1: new features: diff --git a/VERSION b/VERSION index 5f22ae7..475d203 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork" +"1.6.0.1+ip4bind+recvfromfork+x64" diff --git a/error.c b/error.c index fbddb1f..a3adf6c 100644 --- a/error.c +++ b/error.c @@ -1,5 +1,5 @@ /* source: error.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the logging subsystem */ @@ -100,7 +100,7 @@ void diag_set(char what, const char *arg) { sizeof(facilitynames)/sizeof(struct wordent))) == NULL) { Error1("unknown syslog facility \"%s\"", arg); } else { - diagopts.logfacility = (int)keywd->desc; + diagopts.logfacility = (int)(size_t)keywd->desc; } } openlog(diagopts.progname, LOG_PID, diagopts.logfacility); diff --git a/procan-cdefs.c b/procan-cdefs.c index 14333de..b305578 100644 --- a/procan-cdefs.c +++ b/procan-cdefs.c @@ -20,7 +20,7 @@ int procan_cdefs(FILE *outfile) { fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE); #endif #ifdef NFDBITS - fprintf(outfile, "#define NFDBITS %u\n", NFDBITS); + fprintf(outfile, "#define NFDBITS %u\n", (unsigned int)NFDBITS); #endif #ifdef O_RDONLY fprintf(outfile, "#define O_RDONLY %u\n", O_RDONLY); diff --git a/xioopts.c b/xioopts.c index 1ccdca3..d3bc636 100644 --- a/xioopts.c +++ b/xioopts.c @@ -2030,7 +2030,7 @@ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, #if WITH_IP4 case TYPE_IP4NAME: { - struct sockaddr_in sa; size_t salen = sizeof(sa); + struct sockaddr_in sa; socklen_t salen = sizeof(sa); const char *ends[] = { NULL }; const char *nests[] = { "[","]", NULL }; char buff[512], *buffp=buff; size_t bufspc = sizeof(buff)-1; @@ -3515,9 +3515,9 @@ mc:ifname|ifind mc:addr */ union sockaddr_union sockaddr1; - size_t socklen1 = sizeof(sockaddr1.ip4); + socklen_t socklen1 = sizeof(sockaddr1.ip4); union sockaddr_union sockaddr2; - size_t socklen2 = sizeof(sockaddr2.ip4); + socklen_t socklen2 = sizeof(sockaddr2.ip4); /* first parameter is alway multicast address */ /*! result */ @@ -3613,7 +3613,7 @@ mc:addr { struct ipv6_mreq ip6_mreq = {{{{0}}}}; union sockaddr_union sockaddr1; - size_t socklen1 = sizeof(sockaddr1.ip6); + socklen_t socklen1 = sizeof(sockaddr1.ip6); /* always two parameters */ /* first parameter is multicast address */ From ad4bd0d9db41010dc866fa4c043ae29f872bd249 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 7 Jun 2008 10:14:56 +0200 Subject: [PATCH 04/75] EXEC and SYSTEM with stderr injected socat messages into the data stream --- CHANGES | 3 +++ VERSION | 2 +- error.c | 67 +++++++++++++++++++++++++++++++++++++-------- error.h | 5 ++-- test.sh | 18 +++++++++++++ xio-exec.c | 10 +++++-- xio-progcall.c | 73 +++++++++++++++++--------------------------------- xio-progcall.h | 7 +++-- xio-system.c | 8 +++++- 9 files changed, 126 insertions(+), 67 deletions(-) diff --git a/CHANGES b/CHANGES index 4a635b1..df0bf2a 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,9 @@ corrections: corrected a few mistakes that caused compiler warnings on 64bit hosts + EXEC and SYSTEM with stderr injected socat messages into the data + stream. test: EXECSTDERRLOG + ####################### V 1.6.0.1: new features: diff --git a/VERSION b/VERSION index 475d203..bb1254e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr" diff --git a/error.c b/error.c index a3adf6c..6284177 100644 --- a/error.c +++ b/error.c @@ -39,7 +39,6 @@ struct diag_opts { const char *progname; int msglevel; int exitlevel; - int logstderr; int syslog; FILE *logfile; int logfacility; @@ -51,7 +50,7 @@ struct diag_opts { struct diag_opts diagopts = - { NULL, E_ERROR, E_ERROR, 1, 0, NULL, LOG_DAEMON, false, 0 } ; + { NULL, E_ERROR, E_ERROR, 0, NULL, LOG_DAEMON, false, 0 } ; static void _msg(int level, const char *buff, const char *syslp); @@ -89,7 +88,21 @@ static struct wordent facilitynames[] = { } ; +static int diaginitialized; +static int diag_init(void) { + if (diaginitialized) { + return 0; + } + diaginitialized = 1; + /* gcc with GNU libc refuses to set this in the initializer */ + diagopts.logfile = stderr; + return 0; +} +#define DIAG_INIT ((void)(diaginitialized || diag_init())) + + void diag_set(char what, const char *arg) { + DIAG_INIT; switch (what) { const struct wordent *keywd; @@ -104,14 +117,24 @@ void diag_set(char what, const char *arg) { } } openlog(diagopts.progname, LOG_PID, diagopts.logfacility); - diagopts.logstderr = false; break; - case 'f': if ((diagopts.logfile = fopen(arg, "a")) == NULL) { + if (diagopts.logfile != NULL && diagopts.logfile != stderr) { + fclose(diagopts.logfile); + } + diagopts.logfile = NULL; + break; + case 'f': + if (diagopts.logfile != NULL && diagopts.logfile != stderr) { + fclose(diagopts.logfile); + } + if ((diagopts.logfile = fopen(arg, "a")) == NULL) { Error2("cannot open log file \"%s\": %s", arg, strerror(errno)); break; - } else { - diagopts.logstderr = false; break; } - case 's': diagopts.logstderr = true; break; /* logging to stderr is default */ + case 's': + if (diagopts.logfile != NULL && diagopts.logfile != stderr) { + fclose(diagopts.logfile); + } + diagopts.logfile = stderr; break; /* logging to stderr is default */ case 'p': diagopts.progname = arg; openlog(diagopts.progname, LOG_PID, diagopts.logfacility); break; @@ -122,6 +145,7 @@ void diag_set(char what, const char *arg) { } void diag_set_int(char what, int arg) { + DIAG_INIT; switch (what) { case 'D': diagopts.msglevel = arg; break; case 'e': diagopts.exitlevel = arg; break; @@ -138,9 +162,10 @@ void diag_set_int(char what, int arg) { } int diag_get_int(char what) { + DIAG_INIT; switch (what) { case 'y': return diagopts.syslog; - case 's': return diagopts.logstderr; + case 's': return diagopts.logfile == stderr; case 'd': case 'D': return diagopts.msglevel; case 'e': return diagopts.exitlevel; } @@ -148,6 +173,7 @@ int diag_get_int(char what) { } const char *diag_get_string(char what) { + DIAG_INIT; switch (what) { case 'p': return diagopts.progname; } @@ -170,6 +196,7 @@ void msg(int level, const char *format, ...) { size_t bytes; va_list ap; + DIAG_INIT; if (level < diagopts.msglevel) return; va_start(ap, format); #if HAVE_GETTIMEOFDAY || 1 @@ -236,9 +263,6 @@ void msg(int level, const char *format, ...) { static void _msg(int level, const char *buff, const char *syslp) { - if (diagopts.logstderr) { - fputs(buff, stderr); fflush(stderr); - } if (diagopts.syslog) { /* prevent format string attacks (thanks to CoKi) */ syslog(syslevel[level], "%s", syslp); @@ -247,3 +271,24 @@ static void _msg(int level, const char *buff, const char *syslp) { fputs(buff, diagopts.logfile); fflush(diagopts.logfile); } } + + +/* use a new log output file descriptor that is dup'ed from the current one. + this is useful when socat logs to stderr but fd 2 should be redirected to + serve other purposes */ +int diag_dup(void) { + int newfd; + + DIAG_INIT; + if (diagopts.logfile == NULL) { + return -1; + } + newfd = dup(fileno(diagopts.logfile)); + if (diagopts.logfile != stderr) { + fclose(diagopts.logfile); + } + if (newfd >= 0) { + diagopts.logfile = fdopen(newfd, "w"); + } + return newfd; +} diff --git a/error.h b/error.h index 537987f..45168ed 100644 --- a/error.h +++ b/error.h @@ -1,5 +1,5 @@ /* source: error.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __error_h_included @@ -202,7 +202,8 @@ extern void diag_set(char what, const char *arg); extern void diag_set_int(char what, int arg); extern int diag_get_int(char what); extern const char *diag_get_string(char what); - +extern int diag_dup(void); +extern int diag_dup2(int newfd); extern void msg(int level, const char *format, ...); #endif /* !defined(__error_h_included) */ diff --git a/test.sh b/test.sh index 9d2fff7..60ba633 100755 --- a/test.sh +++ b/test.sh @@ -5713,6 +5713,7 @@ esac N=$((N+1)) +# there was an error in address EXEC with options pipes,stderr NAME=EXECPIPESSTDERR case "$TESTS" in *%functions%*|*%$NAME%*) @@ -5721,6 +5722,23 @@ testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" esac N=$((N+1)) +# EXEC and SYSTEM with stderr injected socat messages into the data stream. +NAME=EXECSTDERRLOG +case "$TESTS" in +*%functions%*|*%$NAME%*) +TEST="$NAME: simple echo via exec of cat with pipes,stderr" +SAVE_opts="$opts" +# make sure at least two -d are there +case "$opts" in +*-d*-d*) ;; +*-d*) opts="$opts -d" ;; +*) opts="-d -d" ;; +esac +testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" +opts="$SAVE_opts" +esac +N=$((N+1)) + NAME=SIMPLEPARSE case "$TESTS" in diff --git a/xio-exec.c b/xio-exec.c index d562f12..0e2f09d 100644 --- a/xio-exec.c +++ b/xio-exec.c @@ -1,5 +1,5 @@ /* source: xio-exec.c */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of exec type */ @@ -32,6 +32,7 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts, ) { int status; bool dash = false; + int duptostderr; if (argc != 2) { Error3("\"%s:%s\": wrong number of parameters (%d instead of 1)", argv[0], argv[1], argc-1); @@ -39,7 +40,7 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts, retropt_bool(opts, OPT_DASH, &dash); - status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts); + status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ const char *ends[] = { " ", NULL }; @@ -118,6 +119,11 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts, return STAT_NORETRY; } + /* only now redirect stderr */ + if (duptostderr >= 0) { + diag_dup(); + Dup2(duptostderr, 2); + } Notice1("execvp'ing \"%s\"", token); result = Execvp(token, pargv); /* here we come only if execvp() failed */ diff --git a/xio-progcall.c b/xio-progcall.c index 1b9489f..0c9f8ed 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -44,7 +44,8 @@ const struct optdesc opt_sigquit = { "sigquit", NULL, OPT_SIGQUIT, GROUP_P int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ struct single *fd, unsigned groups, - struct opt **copts /* in: opts; out: opts for child */ + struct opt **copts, /* in: opts; out: opts for child */ + int *duptostderr /* out: redirect stderr to output fd */ ) { struct opt *popts; /* parent process options */ int numleft; @@ -261,7 +262,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ } if (tn == NULL) { Error("could not open pty"); - return STAT_NORETRY; + return -1; } #endif Info1("opened pseudo terminal %s", tn); @@ -280,7 +281,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ #endif /* HAVE_OPENPTY */ free(*copts); if ((*copts = moveopts(popts, GROUP_TERMIOS|GROUP_FORK|GROUP_EXEC|GROUP_PROCESS)) == NULL) { - return STAT_RETRYLATER; + return -1; } applyopts_cloexec(ptyfd, popts);/*!*/ /* exec:...,pty did not kill child process under some circumstances */ @@ -307,7 +308,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (rw != XIO_WRONLY) { if (Pipe(rdpip) < 0) { Error2("pipe(%p): %s", rdpip, strerror(errno)); - return STAT_RETRYLATER; + return -1; } } /*0 Info2("pipe({%d,%d})", rdpip[0], rdpip[1]);*/ @@ -315,7 +316,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ free(*copts); if ((*copts = moveopts(popts, GROUP_FORK|GROUP_EXEC|GROUP_PROCESS)) == NULL) { - return STAT_RETRYLATER; + return -1; } popts2 = copyopts(popts, GROUP_ALL); @@ -330,7 +331,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (rw != XIO_RDONLY) { if (Pipe(wrpip) < 0) { Error2("pipe(%p): %s", wrpip, strerror(errno)); - return STAT_RETRYLATER; + return -1; } } /*0 Info2("pipe({%d,%d})", wrpip[0], wrpip[1]);*/ @@ -364,13 +365,13 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (result < 0) { Error5("socketpair(%d, %d, %d, %p): %s", d, type, protocol, sv, strerror(errno)); - return STAT_RETRYLATER; + return -1; } /*0 Info5("socketpair(%d, %d, %d, {%d,%d})", d, type, protocol, sv[0], sv[1]);*/ free(*copts); if ((*copts = moveopts(popts, GROUP_FORK|GROUP_EXEC|GROUP_PROCESS)) == NULL) { - return STAT_RETRYLATER; + return -1; } applyopts(sv[0], *copts, PH_PASTSOCKET); applyopts(sv[1], popts, PH_PASTSOCKET); @@ -397,7 +398,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (applyopts_single(fd, popts, PH_LATE) < 0) return -1; } /*0 if ((optpr = copyopts(*copts, GROUP_PROCESS)) == NULL) - return STAT_RETRYLATER;*/ + return -1;*/ retropt_bool(*copts, OPT_STDERR, &withstderr); xiosetchilddied(); /* set SIGCHLD handler */ @@ -409,7 +410,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ pid = Fork(); if (pid < 0) { Error1("fork(): %s", strerror(errno)); - return STAT_RETRYLATER; + return -1; } /* gdb recommends to have env controlled sleep after fork */ if (forkwaitstring = getenv("SOCAT_FORK_WAIT")) { @@ -438,13 +439,13 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (rw != XIO_RDONLY && fdi != ttyfd) { if (Dup2(ttyfd, fdi) < 0) { Error3("dup2(%d, %d): %s", ttyfd, fdi, strerror(errno)); - return STAT_RETRYLATER; } + return -1; } /*0 Info2("dup2(%d, %d)", ttyfd, fdi);*/ } if (rw != XIO_WRONLY && fdo != ttyfd) { if (Dup2(ttyfd, fdo) < 0) { Error3("dup2(%d, %d): %s", ttyfd, fdo, strerror(errno)); - return STAT_RETRYLATER; } + return -1; } /*0 Info2("dup2(%d, %d)", ttyfd, fdo);*/ } if ((rw == XIO_RDONLY || fdi != ttyfd) && @@ -466,7 +467,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (fdi == rdpip[1]) { /* a conflict here */ if ((tmpi = Dup(wrpip[0])) < 0) { Error2("dup(%d): %s", wrpip[0], strerror(errno)); - return STAT_RETRYLATER; + return -1; } /*0 Info2("dup(%d) -> %d", wrpip[0], tmpi);*/ rdpip[1] = tmpi; @@ -474,7 +475,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (fdo == wrpip[0]) { /* a conflict here */ if ((tmpo = Dup(rdpip[1])) < 0) { Error2("dup(%d): %s", rdpip[1], strerror(errno)); - return STAT_RETRYLATER; + return -1; } /*0 Info2("dup(%d) -> %d", rdpip[1], tmpo);*/ wrpip[0] = tmpo; @@ -483,7 +484,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (rw != XIO_WRONLY && rdpip[1] != fdo) { if (Dup2(rdpip[1], fdo) < 0) { Error3("dup2(%d, %d): %s", rdpip[1], fdo, strerror(errno)); - return STAT_RETRYLATER; + return -1; } Close(rdpip[1]); /*0 Info2("dup2(%d, %d)", rdpip[1], fdo);*/ @@ -492,7 +493,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (rw != XIO_RDONLY && wrpip[0] != fdi) { if (Dup2(wrpip[0], fdi) < 0) { Error3("dup2(%d, %d): %s", wrpip[0], fdi, strerror(errno)); - return STAT_RETRYLATER; + return -1; } Close(wrpip[0]); /*0 Info2("dup2(%d, %d)", wrpip[0], fdi);*/ @@ -509,13 +510,13 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (rw != XIO_RDONLY && fdi != sv[1]) { if (Dup2(sv[1], fdi) < 0) { Error3("dup2(%d, %d): %s", sv[1], fdi, strerror(errno)); - return STAT_RETRYLATER; } + return -1; } /*0 Info2("dup2(%d, %d)", sv[1], fdi);*/ } if (rw != XIO_WRONLY && fdo != sv[1]) { if (Dup2(sv[1], fdo) < 0) { Error3("dup2(%d, %d): %s", sv[1], fdo, strerror(errno)); - return STAT_RETRYLATER; } + return -1; } /*0 Info2("dup2(%d, %d)", sv[1], fdo);*/ } if (fdi != sv[1] && fdo != sv[1]) { @@ -530,36 +531,6 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ applyopts(-1, *copts, PH_LATE); applyopts(-1, *copts, PH_LATE2); } - - /* what to do with stderr? */ - if (withstderr) { - /* handle it just like ordinary process output, i.e. copy output fd */ - if (!withfork) { - if (Dup2(fdo, 2) < 0) { - Error2("dup2(%d, 2): %s", fdo, strerror(errno)); - } - /*0 Info1("dup2(%d, 2)", fdo);*/ - } else -#if HAVE_PTY - if (usepty) { - if (Dup2(ttyfd, 2) < 0) { - Error2("dup2(%d, 2): %s", ttyfd, strerror(errno)); - } - /*0 Info1("dup2(%d, 2)", ttyfd);*/ - } else -#endif /* HAVE_PTY */ - if (usepipes) { - if (Dup2(/*rdpip[1]*/ fdo, 2) < 0) { - Error2("dup2(%d, 2): %s", /*rdpip[1]*/ fdo, strerror(errno)); - } - /*0 Info1("dup2(%d, 2)", rdpip[1]);*/ - } else { - if (Dup2(sv[1], 2) < 0) { - Error2("dup2(%d, 2): %s", sv[1], strerror(errno)); - } - /*0 Info1("dup2(%d, 2)", sv[1]);*/ - } - } _xioopen_setdelayeduser(); /* set group before user - maybe you are not permitted afterwards */ if (retropt_gidt(*copts, OPT_SETGID, &group) >= 0) { @@ -568,6 +539,12 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ if (retropt_uidt(*copts, OPT_SETUID, &user) >= 0) { Setuid(user); } + if (withstderr) { + *duptostderr = fdo; + } else { + *duptostderr = -1; + } + return 0; /* indicate child process */ } diff --git a/xio-progcall.h b/xio-progcall.h index 09fe607..706331f 100644 --- a/xio-progcall.h +++ b/xio-progcall.h @@ -1,5 +1,5 @@ /* source: xio-progcall.h */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_progcall_h_included @@ -21,8 +21,11 @@ extern const struct optdesc opt_sigquit; extern int _xioopen_foxec(int rw, /* O_RDONLY etc. */ struct single *fd, unsigned groups, - struct opt **opts + struct opt **opts, + int *duptostderr ); extern int setopt_path(struct opt *opts, char **path); +extern +int _xioopen_redir_stderr(int fdo); #endif /* !defined(__xio_progcall_h_included) */ diff --git a/xio-system.c b/xio-system.c index 71dd8eb..39a5193 100644 --- a/xio-system.c +++ b/xio-system.c @@ -31,10 +31,11 @@ static int xioopen_system(int argc, const char *argv[], struct opt *opts, ) { int status; char *path = NULL; + int duptostderr; int result; const char *string = argv[1]; - status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts); + status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ int numleft; @@ -50,6 +51,11 @@ static int xioopen_system(int argc, const char *argv[], struct opt *opts, return STAT_NORETRY; } + /* only now redirect stderr */ + if (duptostderr >= 0) { + diag_dup(); + Dup2(duptostderr, 2); + } Info1("executing shell command \"%s\"", string); result = System(string); if (result != 0) { From ae368e7cb98ce99b52f80a3a9b22d5d77ce3aeea Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 17 Jul 2008 21:49:52 +0200 Subject: [PATCH 05/75] EXEC address with consecutive spaces created additional empty arguments --- CHANGES | 4 ++++ VERSION | 2 +- test.sh | 35 +++++++++++++++++++++++++++++++++++ xio-exec.c | 2 +- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index df0bf2a..4dcb9c8 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,10 @@ corrections: EXEC and SYSTEM with stderr injected socat messages into the data stream. test: EXECSTDERRLOG + when the EXEC address got a string with consecutive spaces it created + additional empty arguments (thanks to Olivier Hervieu for reporting + this bug) + ####################### V 1.6.0.1: new features: diff --git a/VERSION b/VERSION index bb1254e..6d51c99 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces" diff --git a/test.sh b/test.sh index 60ba633..29d5359 100755 --- a/test.sh +++ b/test.sh @@ -8261,6 +8261,41 @@ PORT=$((PORT+1)) N=$((N+1)) +# there was a bug in parsing the arguments of exec: consecutive spaces resulted +# in additional empty arguments +NAME=EXECSPACES +case "$TESTS" in +*%functions%*|*%exec%*|*%parse%*|*%$NAME%*) +TEST="$NAME: correctly parse exec with consecutive spaces" +$PRINTF "test $F_n $TEST... " $N +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +da="test$N $(date) $RANDOM" +tdiff="$td/test$N.diff" +# put the test data as first argument after two spaces. expect the data in the +# first argument of the exec'd command. +$SOCAT $opts -u "exec:\"bash -c \\\"echo \$1\\\" \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te" +rc=$? +echo "$da" |diff - "$tf" >"$tdiff" +if [ "$rc" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + cat "$te" + numFAIL=$((numFAIL+1)) +elif [ -s "$tdiff" ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo diff: + cat "$tdiff" + if [ -n "$debug" ]; then cat $te; fi + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi +esac +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/xio-exec.c b/xio-exec.c index 0e2f09d..7a6958c 100644 --- a/xio-exec.c +++ b/xio-exec.c @@ -83,11 +83,11 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts, if (pargv[0] == NULL) pargv[0] = token; else ++pargv[0]; pargc = 1; while (*strp == ' ') { + while (*++strp == ' ') ; if ((pargc & 0x07) == 0) { pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; } - ++strp; pargv[pargc++] = tokp; if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) < 0) { From 780b4028fe26632f55ea0e05ddcd082cc38c5f34 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 23 Jul 2008 20:56:48 +0200 Subject: [PATCH 06/75] improved test.sh script --- CHANGES | 2 + test.sh | 321 ++++++++++++++++++++++++++++++-------------------------- 2 files changed, 173 insertions(+), 150 deletions(-) diff --git a/CHANGES b/CHANGES index 4dcb9c8..93b8802 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,8 @@ corrections: additional empty arguments (thanks to Olivier Hervieu for reporting this bug) + improved test.sh script + ####################### V 1.6.0.1: new features: diff --git a/test.sh b/test.sh index 29d5359..5846503 100755 --- a/test.sh +++ b/test.sh @@ -207,6 +207,7 @@ $SOCAT -? |sed '1,/address-head:/ d' |egrep 'groups=' |while IFS="$IFS:" read x if [ -s "$TF-diff" ]; then $ECHO "\n*** address array is not sorted. Wrong entries:" >&2 cat "$TD/socat-q-diff" >&2 + exit 1 else echo " ok" fi @@ -219,11 +220,12 @@ case "$TESTS" in # test if address options array ("optionnames") is sorted alphabetically: $ECHO "testing if address options are sorted...\c" TF="$TD/socat-qq" -$SOCAT -??? |sed '1,/opt:/ d' |egrep 'groups=' |awk '{print($1);}' >"$TF" -$SOCAT -??? |sed '1,/opt:/ d' |egrep 'groups=' |awk '{print($1);}' |LC_ALL=C sort |diff "$TF" - >"$TF-diff" +$SOCAT -??? |sed '1,/opt:/ d' |awk '{print($1);}' >"$TF" +LC_ALL=C sort "$TF" |diff "$TF" - >"$TF-diff" if [ -s "$TF-diff" ]; then $ECHO "\n*** option array is not sorted. Wrong entries:" >&2 cat "$TD/socat-qq-diff" >&2 + exit 1 else echo " ok" fi @@ -457,7 +459,7 @@ N=1 #TEST="$METHOD on file accepts all its options" # echo "### $TEST" #TF=$TD/file$N -#DA="$(date)" +#DA="test$N $(date) $RANDOM" #OPTGROUPS=$($SOCAT -? |fgrep " $method:" |sed 's/.*=//') #for g in $(echo $OPTGROUPS |tr ',' ' '); do # eval "OPTG=\$OPTS_$(echo $g |tr a-z- A-Z_)"; @@ -1420,7 +1422,7 @@ numCANT=0 # test if selected socat features work ("FUNCTIONS") testecho () { - local num="$1" + local N="$1" local title="$2" local arg1="$3"; [ -z "$arg1" ] && arg1="-" local arg2="$4"; [ -z "$arg2" ] && arg2="echo" @@ -1429,10 +1431,10 @@ testecho () { local tf="$td/test$N.stdout" local te="$td/test$N.stderr" local tdiff="$td/test$N.diff" - local da="$(date)" + local da="test$N $(date) $RANDOM" #local cmd="$SOCAT $opts $arg1 $arg2" - #$ECHO "testing $title (test $num)... \c" - $PRINTF "test $F_n %s... " $num "$title" + #$ECHO "testing $title (test $N)... \c" + $PRINTF "test $F_n %s... " $N "$title" #echo "$da" |$cmd >"$tf" 2>"$te" (echo "$da"; sleep $T) |($SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") & export rc1=$! @@ -1471,7 +1473,7 @@ testod () { local tf="$td/test$N.stdout" local te="$td/test$N.stderr" local tdiff="$td/test$N.diff" - local dain="$(date)" + local dain="$(date) $RANDOM" local daout="$(echo "$dain" |$OD_C)" $PRINTF "test $F_n %s... " $num "$title" (echo "$dain"; sleep $T) |$SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" @@ -1643,7 +1645,7 @@ waitip4proto () { while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -n -w -l |grep '^raw .* .*[0-9*]:'$proto' [ ]*0\.0\.0\.0:\*') ;; -# FreeBSD) l=$(netstat -an |grep '^raw4[6 ] .*[0-9*]\.'$proto' .* \*\.\*') ;; +# FreeBSD) l=$(netstat -an |egrep '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;; # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; # Darwin) case "$(uname -r)" in @@ -1683,8 +1685,8 @@ waitip6proto () { [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in - Linux) l=$(netstat -n -w -l |grep '^raw .* .*:[0-9*]*:'$proto' [ ]*:::\*') ;; -# FreeBSD) l=$(netstat -an |grep '^raw4[6 ] .*[0-9*]\.'$proto' .* \*\.\*') ;; + Linux) l=$(netstat -n -w -l |grep '^raw[6 ] .* .*:[0-9*]*:'$proto' [ ]*:::\*') ;; +# FreeBSD) l=$(netstat -an |egrep '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;; # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; # Darwin) case "$(uname -r)" in @@ -1696,7 +1698,7 @@ waitip6proto () { # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;; # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;; - *) #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;; + *) #l=$(netstat -an |egrep -i 'raw6? .*[0-9*][:.]'$proto' ') ;; sleep 1; return 0 ;; esac [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ @@ -1714,6 +1716,30 @@ waitip6port () { waitip6proto "$1" "$2" "$3" } +# check if a TCP4 port is in use +# exits with 0 when it is not used +checktcp4port () { + local port="$1" + local l + case "$UNAME" in + Linux) l=$(netstat -n -t |grep '^tcp .* .*[0-9*]:'$port' .* LISTEN') ;; + FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; + NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; + Darwin) case "$(uname -r)" in + [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; + *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; + esac ;; + AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; + SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; + HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; + OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; + CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; + *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;; + esac + [ -z "$l" ] && return 0 + return 1 +} + # wait until a TCP4 listen port is ready waittcp4port () { local port="$1" @@ -1731,7 +1757,7 @@ waittcp4port () { [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; esac ;; - AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; + AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; @@ -1759,7 +1785,7 @@ waitudp4port () { while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) l=$(netstat -n -u -l |grep '^udp .* .*[0-9*]:'$port' [ ]*0\.0\.0\.0:\*') ;; - FreeBSD) l=$(netstat -an |grep '^udp4[6 ] .*[0-9*]\.'$port' .* \*\.\*') ;; + FreeBSD) l=$(netstat -an |egrep '^udp46? .*[0-9*]\.'$port' .* \*\.\*') ;; NetBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;; Darwin) case "$(uname -r)" in @@ -1792,8 +1818,8 @@ waittcp6port () { [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in - Linux) l=$(netstat -an |grep '^tcp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN') ;; - FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;; + Linux) l=$(netstat -an |grep -E '^tcp6? .* [0-9a-f:]*:'$port' .* LISTEN') ;; + FreeBSD) l=$(netstat -an |egrep -i 'tcp(6|46) .*[0-9*][:.]'$port' .* listen') ;; NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; @@ -1821,7 +1847,7 @@ waitudp6port () { [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do case "$UNAME" in - Linux) l=$(netstat -an |grep '^udp[6 ] .* .*[0-9*:]:'$port' [ ]*:::\*') ;; + Linux) l=$(netstat -an |grep -E '^udp6? .* .*[0-9*:]:'$port' [ ]*:::\*') ;; FreeBSD) l=$(netstat -an |egrep '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;; NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; @@ -2303,7 +2329,7 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" ts="$td/test$N.socket" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UNIX-LISTEN:$ts PIPE" CMD2="$SOCAT $opts -!!- UNIX:$ts" printf "test $F_n $TEST... " $N @@ -2340,7 +2366,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N @@ -2384,7 +2410,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP6-listen:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N @@ -2430,7 +2456,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP-listen:$tsl,pf=ip4,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP:$ts" printf "test $F_n $TEST... " $N @@ -2476,7 +2502,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP-listen:$tsl,pf=ip6,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP:$ts" printf "test $F_n $TEST... " $N @@ -2524,7 +2550,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP6-listen:$tsl,ipv6-v6only=0,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N @@ -2572,7 +2598,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP6-listen:$tsl,ipv6-v6only=1,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N @@ -2617,7 +2643,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP-listen:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N @@ -2662,7 +2688,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP-listen:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N @@ -2710,7 +2736,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -4 TCP-listen:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N @@ -2755,7 +2781,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -6 TCP-listen:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N @@ -2804,7 +2830,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -6 TCP-listen:$tsl,pf=ip4,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N @@ -2849,7 +2875,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="[::1]:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -4 TCP-listen:$tsl,pf=ip6,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N @@ -2888,7 +2914,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UDP4-LISTEN:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts - UDP4:$ts" printf "test $F_n $TEST... " $N @@ -2935,7 +2961,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST6:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UDP6-LISTEN:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts - UDP6:$ts" printf "test $F_n $TEST... " $N @@ -2974,7 +3000,7 @@ tf1="$td/test$N.1.stdout" tf2="$td/test$N.2.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" echo "$da" >$tf1 CMD="$SOCAT $opts $tf1!!/dev/null /dev/null,ignoreeof!!-" printf "test $F_n $TEST... " $N @@ -3005,7 +3031,7 @@ tp="$td/pipe$N" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD="$SOCAT $opts $tp!!/dev/null /dev/null,ignoreeof!!$tf" printf "test $F_n $TEST... " $N #mknod $tp p # no mknod p on FreeBSD @@ -3145,7 +3171,7 @@ ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" CMD="$SOCAT $opts -u file:\"$ti\",ignoreeof -" printf "test $F_n $TEST... " $N touch "$ti" @@ -3211,7 +3237,7 @@ tt="$td/pty$N" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts pty,link=$tt pipe" CMD2="$SOCAT $opts - $tt,$PTYOPTS2" printf "test $F_n $TEST... " $N @@ -3252,7 +3278,7 @@ ff="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD="$SOCAT -u $opts - open:$ff,append,o-trunc" printf "test $F_n $TEST... " $N rm -f $ff; $ECHO "prefix-\c" >$ff @@ -3280,7 +3306,7 @@ ff="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD="$SOCAT -u $opts - open:$ff,append,ftruncate=0" printf "test $F_n $TEST... " $N rm -f $ff; $ECHO "prefix-\c" >$ff @@ -3416,13 +3442,14 @@ gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts exec:'openssl s_server -accept "$PORT" -quiet -cert testsrv.pem' pipe" #! CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT" CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id +# this might timeout when openssl opens tcp46 port like " :::$PORT" waittcp4port $PORT echo "$da" |$CMD >$tf 2>"${te}2" if ! echo "$da" |diff - "$tf" >"$tdiff"; then @@ -3461,7 +3488,7 @@ gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N @@ -3504,7 +3531,7 @@ gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" CMD="$SOCAT $opts - openssl:$LOCALHOST6:$PORT,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N @@ -3550,7 +3577,7 @@ gentestcert testsrv tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 exec:'$OD_C'" CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N @@ -3595,7 +3622,7 @@ gentestcert testcli tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=1,cafile=testsrv.crt,$SOCAT_EGD" printf "test $F_n $TEST... " $N @@ -3639,7 +3666,7 @@ gentestcert testcli tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,verify=1,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt,$SOCAT_EGD pipe" CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=0,cert=testcli.crt,key=testcli.key,$SOCAT_EGD" printf "test $F_n $TEST... " $N @@ -3686,7 +3713,7 @@ OPENSSL_FIPS=1 gentestcert testclifips tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,fips,$SOCAT_EGD,cert=testsrvfips.crt,key=testsrvfips.key,cafile=testclifips.crt pipe" CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,fips,verify=1,cert=testclifips.crt,key=testclifips.key,cafile=testsrvfips.crt,$SOCAT_EGD" printf "test $F_n $TEST... " $N @@ -3729,7 +3756,7 @@ else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # we have a normal tcp echo listening - so the socks header must appear in answer CMD2="$SOCAT tcp4-l:$PORT,reuseaddr exec:\"./socks4echo.sh\"" CMD="$SOCAT $opts - socks4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody" @@ -3772,7 +3799,7 @@ else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # we have a normal tcp echo listening - so the socks header must appear in answer CMD2="$SOCAT tcp6-l:$PORT,reuseaddr exec:\"./socks4echo.sh\"" CMD="$SOCAT $opts - socks4:$LOCALHOST6:32.98.76.54:32109,socksport=$PORT",socksuser="nobody" @@ -3816,7 +3843,7 @@ else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # we have a normal tcp echo listening - so the socks header must appear in answer CMD2="$SOCAT tcp4-l:$PORT,reuseaddr exec:\"./socks4a-echo.sh\"" CMD="$SOCAT $opts - socks4a:$LOCALHOST:localhost:32109,pf=ip4,socksport=$PORT",socksuser="nobody" @@ -3859,7 +3886,7 @@ else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # we have a normal tcp echo listening - so the socks header must appear in answer CMD2="$SOCAT tcp6-l:$PORT,reuseaddr exec:\"./socks4a-echo.sh\"" CMD="$SOCAT $opts - socks4a:$LOCALHOST6:localhost:32109,socksport=$PORT",socksuser="nobody" @@ -3904,7 +3931,7 @@ ts="$td/test$N.sh" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" #CMD2="$SOCAT tcp4-l:$PORT,crlf system:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" CMD2="$SOCAT tcp4-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh\"" CMD="$SOCAT $opts - proxy:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT" @@ -3948,7 +3975,7 @@ ts="$td/test$N.sh" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" #CMD2="$SOCAT tcp6-l:$PORT,crlf system:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" CMD2="$SOCAT tcp6-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh\"" CMD="$SOCAT $opts - proxy:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT" @@ -3987,7 +4014,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr exec:$CAT,nofork" CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N @@ -4048,7 +4075,7 @@ N=$((N+1)) #tf="$td/file$N" #tsl=65534 #ts="127.0.0.1:$tsl" -#da=$(date) +#da="test$N $(date) $RANDOM" #$SOCAT UDP-listen:$tsl PIPE & #sleep 2 #echo "$da" |$SOCAT stdin!!stdout UDP:$ts >"$tf" @@ -4065,7 +4092,7 @@ N=$((N+1)) #N=4 #tf="$td/file$N" #tp="$td/pipe$N" -#da=$(date) +#da="test$N $(date) $RANDOM" #rm -f "$tf.tmp" #echo "$da" |$SOCAT - FILE:$tf.tmp,ignoreeof >"$tf" #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then @@ -4089,7 +4116,7 @@ else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" CMD2="$SOCAT $opts -T 1 tcp4-listen:$PORT,reuseaddr pipe" CMD="$SOCAT $opts - tcp4-connect:$LOCALHOST:$PORT" printf "test $F_n $TEST... " $N @@ -4131,7 +4158,7 @@ ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" CMD="$SOCAT $opts -T 2 -u file:\"$ti\",ignoreeof -" printf "test $F_n $TEST... " $N touch "$ti" @@ -4172,7 +4199,7 @@ ts="$td/test$N.sh" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" #CMD2="$SOCAT tcp-l:$PORT,crlf system:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" CMD2="$SOCAT tcp4-l:$PORT,reuseaddr,crlf exec:\"/bin/bash proxyecho.sh -w 2\"" CMD="$SOCAT $opts - proxy:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT" @@ -4313,6 +4340,7 @@ if ! feat=$(testaddrs readline pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else +SAVETERM="$TERM"; TERM= # 'cause konsole might print controls even in raw SAVEMICS=$MICROS #MICROS=2000000 ts="$td/test$N.sh" @@ -4322,7 +4350,7 @@ tpo="$td/test$N.outpipe" te="$td/test$N.stderr" tr="$td/test$N.ref" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # the feature that we really want to test is in the readline.sh script: CMD="$SOCAT $opts open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" #echo "$CMD" >"$ts" @@ -4397,6 +4425,7 @@ else fi #kill $pid 2>/dev/null MICROS=$SAVEMICS +TERM="$SAVETERM" fi esac PORT=$((PORT+1)) @@ -4410,7 +4439,7 @@ TEST="$NAME: TCP4 \"gender changer\"" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" # this is the server in the protected network that we want to reach CMD1="$SOCAT -lpserver $opts tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST echo" # this is the double client in the protected network @@ -4467,7 +4496,7 @@ gentestcert testcli tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" # this is the server in the protected network that we want to reach CMD1="$SOCAT $opts -lpserver tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST echo" # this is the proxy in the protected network that provides a way out @@ -4529,7 +4558,13 @@ PORT=$((PORT+5)) N=$((N+1)) -#! +# test the TCP gender changer with almost production requirements: a double +# client repeatedly tries to connect to a double server via SSL through an HTTP +# proxy. the double servers SSL port becomes active for one connection only +# after a (real) client has connected to its TCP port. when the double client +# succeeded to establish an SSL connection, it connects with its second client +# side to the specified (protected) server. all three consecutive connections +# must function for full success of this test. PORT=$((RANDOM+16184)) #! NAME=INTRANETRIPPER @@ -4551,15 +4586,17 @@ da3="test$N.3 $(date) $RANDOM" # this is the server in the protected network that we want to reach CMD1="$SOCAT $opts -lpserver -t1 tcp4-l:$PORT,reuseaddr,bind=$LOCALHOST,fork echo" # this is the proxy in the protected network that provides a way out +# note: the proxy.sh script starts one or two more socat processes without +# setting the program name CMD2="$SOCAT $opts -lpproxy -t1 tcp4-l:$((PORT+1)),reuseaddr,bind=$LOCALHOST,fork exec:./proxy.sh" # this is our proxy connect wrapper in the protected network CMD3="$SOCAT $opts -lpwrapper -t3 tcp4-l:$((PORT+2)),reuseaddr,bind=$LOCALHOST,fork proxy:$LOCALHOST:$LOCALHOST:$((PORT+3)),pf=ip4,proxyport=$((PORT+1)),resolve" # this is our double client in the protected network using SSL -CMD4="$SOCAT $opts -lp2client -t3 ssl:$LOCALHOST:$((PORT+2)),retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,verify,fork,$SOCAT_EGD tcp4:$LOCALHOST:$PORT" +CMD4="$SOCAT $opts -lp2client -t3 ssl:$LOCALHOST:$((PORT+2)),retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,verify,fork,$SOCAT_EGD tcp4:$LOCALHOST:$PORT,forever,intervall=0.1" # this is the double server in the outside network -CMD5="$SOCAT $opts -lp2server -t4 tcp4-l:$((PORT+4)),reuseaddr,bind=$LOCALHOST,fork ssl-l:$((PORT+3)),pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt,retry=10" +CMD5="$SOCAT $opts -lp2server -t4 tcp4-l:$((PORT+4)),reuseaddr,bind=$LOCALHOST,backlog=3,fork ssl-l:$((PORT+3)),pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt,retry=20,intervall=0.5" # this is the outside client that wants to use the protected server -CMD6="$SOCAT $opts -lpclient -t5 - tcp4:$LOCALHOST:$((PORT+4)),retry=3" +CMD6="$SOCAT $opts -lpclient -t6 - tcp4:$LOCALHOST:$((PORT+4)),retry=3" printf "test $F_n $TEST... " $N # start the intranet infrastructure eval "$CMD1 2>\"${te}1\" &" @@ -4591,6 +4628,8 @@ wait $pid6_1 $pid6_2 $pid6_3 (echo "$da2"; sleep 2) |diff - "${tf}_2" >"${tdiff}2" (echo "$da3"; sleep 2) |diff - "${tf}_3" >"${tdiff}3" if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then + # FAILED only when none of the three transfers succeeded + if test -s "${tdiff}1" -a -s "${tdiff}2" -a -s "${tdiff}3"; then $PRINTF "$FAILED: $SOCAT:\n" echo "$CMD1 &" cat "${te}1" @@ -4612,6 +4651,11 @@ if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then cat "${te}6_3" cat "${tdiff}3" numFAIL=$((numFAIL+1)) + else + $PRINTF "$OK ${YELLOW}(partial failure)${NORMAL}\n" + if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi + numOK=$((numOK+1)) + fi else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi @@ -4631,7 +4675,7 @@ N=$((N+1)) # test the security features of a server address testserversec () { - local num="$1" + local N="$1" local title="$2" local opts="$3" local arg1="$4" # the server address @@ -4647,10 +4691,10 @@ testserversec () { local te="$td/test$N.stderr" local tdiff1="$td/test$N.diff1" local tdiff2="$td/test$N.diff2" - local da="$(date)" + local da="test$N.1 $(date) $RANDOM" local stat result - $PRINTF "test $F_n %s... " $num "$title" + $PRINTF "test $F_n %s... " $N "$title" #set -vx # first: without security # start server @@ -4718,6 +4762,7 @@ testserversec () { return fi # now use client + da="test$N.2 $(date) $RANDOM" (echo "$da"; sleep $T) |$SOCAT $opts - "$arg2" >"$tf" 2>"${te}4" stat=$? kill $spid 2>/dev/null @@ -5289,15 +5334,15 @@ testptywaitslave () { local PTYTYPE="$3" # ptmx or openpty local opts="$4" -tp="$td/test$N.pty" -ts="$td/test$N.socket" -tf="$td/test$N.file" -tdiff="$td/test$N.diff" -te1="$td/test$N.stderr1" -te2="$td/test$N.stderr2" -te3="$td/test$N.stderr3" -te4="$td/test$N.stderr4" -da="test$N.1 $(date) $RANDOM" + local tp="$td/test$N.pty" + local ts="$td/test$N.socket" + local tf="$td/test$N.file" + local tdiff="$td/test$N.diff" + local te1="$td/test$N.stderr1" + local te2="$td/test$N.stderr2" + local te3="$td/test$N.stderr3" + local te4="$td/test$N.stderr4" + local da="test$N $(date) $RANDOM" printf "test $F_n $TEST... " $N # first generate a pty, then a socket ($SOCAT $opts -lpsocat1 pty,$PTYTYPE,pty-wait-slave,link="$tp" unix-listen:"$ts" 2>"$te1"; rm -f "$tp") 2>/dev/null & @@ -5429,7 +5474,7 @@ gentestdsacert $SRVCERT tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=$SRVCERT.pem,key=$SRVCERT.key,verify=0 pipe" CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" $PRINTF "test $F_n $TEST... " $N @@ -5533,7 +5578,7 @@ ti="$td/test$N.in" to="$td/test$N.out" te="$td/test$N.err" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # the feature that we really want to test is in the readline.sh script: CMD="$SOCAT $opts -u open:$ti,readbytes=100 -" printf "test $F_n $TEST... " $N @@ -5718,7 +5763,11 @@ NAME=EXECPIPESSTDERR case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with pipes,stderr" +# this test is known to fail when logging is enabled with OPTS/opts env var. +SAVE_opts="$opts" +opts="$(echo "$opts" |sed 's/-d//g')" testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" +opts="$SAVE_opts" esac N=$((N+1)) @@ -5813,7 +5862,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="127.0.0.1:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP6-listen:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP6:$ts" printf "test $F_n $TEST... " $N @@ -5856,7 +5905,7 @@ ts1a="127.0.0.1" ts1="$ts1a:$ts1p" ts2p=$PORT; PORT=$((PORT+1)) ts2="127.0.0.1:$ts2p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE" CMD2="$SOCAT $opts - UDP4-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N @@ -5907,7 +5956,7 @@ tsa="[::1]" ts1="$tsa:$ts1p" ts2p=$PORT; PORT=$((PORT+1)) ts2="$tsa:$ts2p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UDP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE" CMD2="$SOCAT $opts - UDP6-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N @@ -5952,7 +6001,7 @@ ts1a="127.0.0.1" ts1="$ts1a:$ts1p" ts2a="$SECONDADDR" ts2="$ts2a:$ts2p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE" CMD2="$SOCAT $opts - IP4-SENDTO:$ts1,bind=$ts2a" printf "test $F_n $TEST... " $N @@ -5980,7 +6029,6 @@ else fi fi # must be root;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -6003,7 +6051,7 @@ ts1p=$PROTO; PROTO=$((PROTO+1)) tsa="[::1]" ts1="$tsa:$ts1p" ts2="$tsa" -da=$(date) +da="test$N $(date) $RANDOM" #CMD1="$SOCAT $opts IP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE" CMD2="$SOCAT $opts - IP6-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N @@ -6028,7 +6076,6 @@ else fi fi # must be root ;; esac -PORT=$((PORT+1)) N=$((N+1)) fi #false @@ -6042,7 +6089,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$td/test$N.socket1" ts2="$td/test$N.socket2" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UNIX-RECVFROM:$ts1,reuseaddr PIPE" CMD2="$SOCAT $opts - UNIX-SENDTO:$ts1,bind=$ts2" printf "test $F_n $TEST... " $N @@ -6069,7 +6116,6 @@ else numOK=$((numOK+1)) fi ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -6083,7 +6129,7 @@ tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="127.0.0.1" ts1="$ts1a:$ts1p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -u UDP4-RECV:$ts1p,reuseaddr -" CMD2="$SOCAT $opts -u - UDP4-SENDTO:$ts1" printf "test $F_n $TEST... " $N @@ -6116,7 +6162,6 @@ else numOK=$((numOK+1)) fi ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -6134,7 +6179,7 @@ tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="[::1]" ts1="$ts1a:$ts1p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -u UDP6-RECV:$ts1p,reuseaddr -" CMD2="$SOCAT $opts -u - UDP6-SENDTO:$ts1" printf "test $F_n $TEST... " $N @@ -6164,7 +6209,6 @@ else fi fi ;; # ! feat esac -PORT=$((PORT+1)) N=$((N+1)) @@ -6182,7 +6226,7 @@ tdiff="$td/test$N.diff" ts1p=$PROTO; PROTO=$((PROTO+1)) ts1a="127.0.0.1" ts1="$ts1a:$ts1p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -u IP4-RECV:$ts1p,reuseaddr -" CMD2="$SOCAT $opts -u - IP4-SENDTO:$ts1" printf "test $F_n $TEST... " $N @@ -6212,7 +6256,6 @@ else fi fi # must be root ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -6233,7 +6276,7 @@ tdiff="$td/test$N.diff" ts1p=$PROTO; PROTO=$((PROTO+1)) ts1a="[::1]" ts1="$ts1a:$ts1p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -u IP6-RECV:$ts1p,reuseaddr -" CMD2="$SOCAT $opts -u - IP6-SENDTO:$ts1" printf "test $F_n $TEST... " $N @@ -6262,7 +6305,6 @@ else fi fi # must be root ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -6275,7 +6317,7 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$ts" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -u UNIX-RECV:$ts1,reuseaddr -" CMD2="$SOCAT $opts -u - UNIX-SENDTO:$ts1" printf "test $F_n $TEST... " $N @@ -6303,7 +6345,6 @@ else numOK=$((numOK+1)) fi ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -6780,7 +6821,7 @@ else tf="$td/test$N.file" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" $PRINTF "test $F_n $TEST... " $N CMD="$SOCAT $opts -u open:\"${tf}1\",o-noatime /dev/null" # generate a file @@ -6829,7 +6870,7 @@ else tf="$td/test$N.file" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da=$(date) +da="test$N $(date) $RANDOM" $PRINTF "test $F_n $TEST... " $N touch ${tf}1 CMD="$SOCAT $opts -u -,o-noatime /dev/null <${tf}1" @@ -6881,7 +6922,7 @@ tf="$td/test$N.file" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$ts" -da=$(date) +da="test$N $(date) $RANDOM" $PRINTF "test $F_n $TEST... " $N CMD0="$SOCAT $opts -u /dev/null create:\"${tf}1\"" CMD="$SOCAT $opts -u /dev/null create:\"${tf}1\",ext2-noatime" @@ -6938,7 +6979,7 @@ ti="$td/test$N.pipe" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" # a reader that will terminate after 1 byte CMD1="$SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null" CMD="$SOCAT $opts -u - file:\"$ti\",cool-write" @@ -6985,7 +7026,7 @@ ti="$td/test$N.pipe" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" # a reader that will terminate after 1 byte CMD1="$SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null" CMD="$SOCAT $opts -,cool-write pipe >\"$ti\"" @@ -7097,28 +7138,12 @@ else numOK=$((numOK+1)) fi ;; esac -PORT=$((PORT+1)) -N=$((N+1)) - - -NAME=TCP4RANGEMASK -case "$TESTS" in -*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) -TEST="$NAME: security of TCP4-L with RANGE option" -if [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) -else -testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=127.0.0.0:255.255.0.0" "tcp4:127.1.0.0:$PORT" 4 tcp $PORT 0 -fi ;; # Linux -esac -PORT=$((PORT+1)) N=$((N+1)) NAME=UDP6LISTENBIND # this tests for a bug in (up to) 1.5.0.0: -# with upd*-listen, the bind option supported only IPv4 +# with udp*-listen, the bind option supported only IPv4 case "$TESTS" in *%functions%*|*%bugs%*|*%ip6%*|*%ipapp%*|*%udp%*|*%$NAME%*) TEST="$NAME: UDP6-LISTEN with bind" @@ -7131,7 +7156,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST6:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UDP6-LISTEN:$tsl,reuseaddr,bind=$LOCALHOST6 PIPE" CMD2="$SOCAT $opts - UDP6:$ts" printf "test $F_n $TEST... " $N @@ -7175,10 +7200,10 @@ else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" ha="$td/hosts.allow" $ECHO "test : ALL : allow" >"$ha" -CMD1="$SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,hosts-allow=$a,tcpwrap=test pipe" +CMD1="$SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr,hosts-allow=$ha,tcpwrap=test pipe" CMD2="$SOCAT $opts - TCP:$LOCALHOST:$PORT" printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & @@ -7219,7 +7244,7 @@ else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat : [::1] : allow" >"$ha" @@ -7269,7 +7294,7 @@ ts1p=$PORT; PORT=$((PORT+1)) ts1="$BCADDR:$ts1p" ts2p=$PORT; PORT=$((PORT+1)) ts2="$BCIFADDR:$ts2p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,broadcast PIPE" #CMD2="$SOCAT $opts - UDP4-BROADCAST:$ts1" CMD2="$SOCAT $opts - UDP4-DATAGRAM:$ts1,broadcast" @@ -7302,7 +7327,6 @@ else fi fi ;; # feats esac -PORT=$((PORT+1)) N=$((N+1)) @@ -7330,7 +7354,7 @@ ts1p=$PROTO ts1="$BCADDR:$ts1p" ts2p=$ts1p ts2="$BCIFADDR" -da="$(date) $RANDOM XXXX" +da="test$N $(date) $RANDOM XXXX" sh="$td/test$N-sed.sh" echo 'sed s/XXXX/YYYY/' >"$sh" chmod a+x "$sh" @@ -7394,7 +7418,7 @@ tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) ts1a="$SECONDADDR" ts1="$ts1a:$ts1p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT -u $opts UDP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -" CMD2="$SOCAT -u $opts - UDP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a" printf "test $F_n $TEST... " $N @@ -7423,7 +7447,6 @@ else fi fi ;; # not feats esac -PORT=$((PORT+1)) N=$((N+1)) NAME=IP4MULTICAST_UNIDIR @@ -7443,7 +7466,7 @@ tdiff="$td/test$N.diff" ts1p=$PROTO ts1a="$SECONDADDR" ts1="$ts1a:$ts1p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT -u $opts IP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -" CMD2="$SOCAT -u $opts - IP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a" printf "test $F_n $TEST... " $N @@ -7491,7 +7514,7 @@ tdiff="$td/test$N.diff" ts1p=$PORT; PORT=$((PORT+1)) if1="$MCINTERFACE" ts1a="[::1]" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT -u $opts UDP6-RECV:$ts1p,reuseaddr,ipv6-join-group=[ff02::2]:$if1 -" CMD2="$SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p,bind=$ts1a" printf "test $F_n $TEST... " $N @@ -7520,7 +7543,6 @@ else fi fi ;; # not feats esac -PORT=$((PORT+1)) N=$((N+1)) fi # false @@ -7536,7 +7558,7 @@ ts1a="$SECONDADDR" ts1="$ts1a:$ts1p" ts2p=$PORT; PORT=$((PORT+1)) ts2="$BCIFADDR:$ts2p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE" #CMD2="$SOCAT $opts - UDP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a" CMD2="$SOCAT $opts - UDP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a" @@ -7568,7 +7590,6 @@ else numOK=$((numOK+1)) fi ;; esac -PORT=$((PORT+1)) N=$((N+1)) NAME=IP4MULTICAST_BIDIR @@ -7588,7 +7609,7 @@ tdiff="$td/test$N.diff" ts1p=$PROTO ts1a="$SECONDADDR" ts1="$ts1a:$ts1p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE" #CMD2="$SOCAT $opts - IP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a" CMD2="$SOCAT $opts - IP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a" @@ -7596,6 +7617,7 @@ printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" waitip4port $ts1p 1 +usleep 100000 # give process a chance to add membership echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2="$?" kill "$pid1" 2>/dev/null; wait; @@ -7643,7 +7665,7 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" tl="$td/test$N.lock" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" dalen=$((${#da}+1)) TUNNET=10.255.255 CMD1="$SOCAT $opts -u - UDP4-SENDTO:$TUNNET.2:$PORT" @@ -7743,7 +7765,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$td/test$N.socket1" ts2="$td/test$N.socket2" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts ABSTRACT-RECVFROM:$ts1,reuseaddr PIPE" #CMD2="$SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2" CMD2="$SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2" @@ -7773,7 +7795,6 @@ else fi fi ;; # not feats esac -PORT=$((PORT+1)) N=$((N+1)) @@ -7790,7 +7811,7 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" ts1="$ts" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -u ABSTRACT-RECV:$ts1,reuseaddr -" CMD2="$SOCAT $opts -u - ABSTRACT-SENDTO:$ts1" printf "test $F_n $TEST... " $N @@ -7821,7 +7842,6 @@ else fi fi ;; # not feats esac -PORT=$((PORT+1)) N=$((N+1)) @@ -7848,7 +7868,7 @@ else tf="$td/test$N.out" te="$td/test$N.err" tdiff="$td/test$N.diff" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" SRVCERT=testsrv gentestcert "$SRVCERT" CMD1="$SOCAT $opts -u -T 1 -b $($ECHO "$da\c" |wc -c) OPENSSL-LISTEN:$PORT,reuseaddr,cert=$SRVCERT.pem,verify=0 -" @@ -7900,7 +7920,7 @@ ti="$td/test$N.in" to="$td/test$N.out" te="$td/test$N.err" tdiff="$td/test$N.diff" -da="$(date)" da="$da$($ECHO '\r')" +da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" CMD="$SOCAT $opts system:\"echo A; sleep 2\",readbytes=2!!- -!!/dev/null" printf "test $F_n $TEST... " $N (sleep 1; echo) |eval "$CMD" >"$to" 2>"$te" @@ -7983,10 +8003,11 @@ tdiff="$td/test$N.diff" # find a service entry we do not need root for (>=1024; here >=1100 for ease) SERVENT="$(grep '^[a-z][a-z]*[^!-~][^!-~]*[1-9][1-9][0-9][0-9]/tcp' /etc/services |head -n 1)" SERVICE="$(echo $SERVENT |cut -d' ' -f1)" +_PORT="$PORT" PORT="$(echo $SERVENT |sed 's/.* \([1-9][0-9]*\).*/\1/')" tsl="$PORT" ts="127.0.0.1:$SERVICE" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE" CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" printf "test $F_n $TEST... " $N @@ -8013,7 +8034,7 @@ fi kill $pid1 2>/dev/null wait ;; esac -#PORT=$((PORT+1)) +PORT="$_PORT" N=$((N+1)) @@ -8074,7 +8095,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -T 0.5 UDP4-LISTEN:$tsl,reuseaddr,fork PIPE" CMD2="$SOCAT $opts - UDP4:$ts" printf "test $F_n $TEST... " $N @@ -8115,7 +8136,7 @@ NAME=UDP4RECVFROM_SIGCHLD case "$TESTS" in *%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%zombie%*|*%$NAME%*) TEST="$NAME: test if UDP4-RECVFROM child becomes zombie" -# idea: run a udp-recvfrom process with fork and -T. Sent it one packet, so a +# idea: run a udp-recvfrom process with fork and -T. Send it one packet, so a # sub process is forked off. Make some transfer and wait until the -T timeout # is over. Now check for the child process: if it is zombie the test failed. # Correct is that child process terminated @@ -8124,7 +8145,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT ts="$LOCALHOST:$tsl" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -T 0.5 UDP4-RECVFROM:$tsl,reuseaddr,fork PIPE" CMD2="$SOCAT $opts - UDP4-SENDTO:$ts" printf "test $F_n $TEST... " $N @@ -8141,7 +8162,7 @@ if [ $rc2 -ne 0 ]; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAMM + $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM numCANT=$((numCANT+1)) elif $(isdefunct "$l"); then $PRINTF "$FAILED: $SOCAT:\n" @@ -8179,7 +8200,7 @@ tdiff="$td/test$N.diff" ts1p=$PROTO; PROTO=$((PROTO+1)) ts1a="127.0.0.1" ts1="$ts1a:$ts1p" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -" CMD2="$SOCAT $opts -u - IP4-SENDTO:$ts1" printf "test $F_n $TEST... " $N @@ -8209,7 +8230,7 @@ else fi fi # must be root ;; esac -PORT=$((PORT+1)) +PROTO=$((PROTO+1)) N=$((N+1)) @@ -8228,7 +8249,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsp=$PORT ts="$LOCALHOST:$tsp" -da=$(date) +da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts -T 2 UDP4-RECVFROM:$tsp,reuseaddr,fork PIPE" CMD2="$SOCAT $opts -T 1 - UDP4-SENDTO:$ts" printf "test $F_n $TEST... " $N From 5251c21479e0910f3c8ca688334eeace35a0a61d Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 24 Jul 2008 07:32:56 +0200 Subject: [PATCH 07/75] corrected alphabetical order of options (proxy-auth); bad conditional with token --- CHANGES | 4 ++++ VERSION | 2 +- procan-cdefs.c | 2 +- xioopts.c | 12 ++++-------- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 93b8802..e37d601 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,10 @@ corrections: additional empty arguments (thanks to Olivier Hervieu for reporting this bug) + corrected alphabetical order of options (proxy-auth) + + some minor corrections + improved test.sh script ####################### V 1.6.0.1: diff --git a/VERSION b/VERSION index 6d51c99..c6a20a5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics" diff --git a/procan-cdefs.c b/procan-cdefs.c index b305578..c5a7116 100644 --- a/procan-cdefs.c +++ b/procan-cdefs.c @@ -20,7 +20,7 @@ int procan_cdefs(FILE *outfile) { fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE); #endif #ifdef NFDBITS - fprintf(outfile, "#define NFDBITS %u\n", (unsigned int)NFDBITS); + fprintf(outfile, "#define NFDBITS "F_Zu"\n", NFDBITS); #endif #ifdef O_RDONLY fprintf(outfile, "#define O_RDONLY %u\n", O_RDONLY); diff --git a/xioopts.c b/xioopts.c index d3bc636..0652073 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1046,8 +1046,8 @@ const struct optname optionnames[] = { #ifdef SO_PROTOTYPE IF_SOCKET ("prototype", &opt_so_prototype) #endif - IF_PROXY ("proxy-authorization", &opt_proxy_authorization) IF_PROXY ("proxy-auth", &opt_proxy_authorization) + IF_PROXY ("proxy-authorization", &opt_proxy_authorization) IF_PROXY ("proxy-resolve", &opt_proxy_resolve) IF_PROXY ("proxyauth", &opt_proxy_authorization) IF_PROXY ("proxyport", &opt_proxyport) @@ -1304,7 +1304,7 @@ const struct optname optionnames[] = { #ifdef SO_USELOOPBACK /* AIX433, Solaris */ IF_SOCKET ("so-useloopback", &opt_so_useloopback) #endif /* SO_USELOOPBACK */ - IF_SOCKS4 ("socksport", &opt_socksport) + IF_SOCKS4 ("socksport", &opt_socksport) IF_SOCKS4 ("socksuser", &opt_socksuser) IF_IPAPP ("sourceport", &opt_sourceport) IF_IPAPP ("sp", &opt_sourceport) @@ -1714,12 +1714,8 @@ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, case TYPE_BYTE: { unsigned long ul; - if (token) { - char *rest; - ul = strtoul(token, &rest/*!*/, 0); - } else { - ul = 1; - } + char *rest; + ul = strtoul(token, &rest/*!*/, 0); if (ul > UCHAR_MAX) { Error3("parseopts(%s): byte value exceeds limit (%lu vs. %u), using max", a0, ul, UCHAR_MAX); From a1c0e96592c4831bbafdb89efc4ec1dd084b922a Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 24 Jul 2008 21:51:38 +0200 Subject: [PATCH 08/75] replaced the select() calls by poll() --- CHANGES | 3 ++ VERSION | 2 +- error.h | 4 ++ socat.c | 110 +++++++++++++++++++++++++++++---------------------- sycls.c | 16 +++++++- sysutils.c | 13 +++++- sysutils.h | 2 + xio-socket.c | 30 +++++++------- xio-udp.c | 8 ++-- 9 files changed, 118 insertions(+), 70 deletions(-) diff --git a/CHANGES b/CHANGES index e37d601..ed3fa25 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,9 @@ corrections: improved test.sh script + replaced the select() calls by poll() to cleanly fix the problems with + many file descriptors already open + ####################### V 1.6.0.1: new features: diff --git a/VERSION b/VERSION index c6a20a5..2b6e1d9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll" diff --git a/error.h b/error.h index 45168ed..1ef73a6 100644 --- a/error.h +++ b/error.h @@ -50,6 +50,8 @@ #define Error6(m,a1,a2,a3,a4,a5,a6) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6) #define Error7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7) #define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8) +#define Error9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9) +#define Error10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #else /* !(WITH_MSGLEVEL >= E_ERROR) */ #define Error(m) #define Error1(m,a1) @@ -60,6 +62,8 @@ #define Error6(m,a1,a2,a3,a4,a5,a6) #define Error7(m,a1,a2,a3,a4,a5,a6,a7) #define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8) +#define Error9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) +#define Error10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #endif /* !(WITH_MSGLEVEL <= E_ERROR) */ #if WITH_MSGLEVEL <= E_WARN diff --git a/socat.c b/socat.c index 6971c25..78eda0c 100644 --- a/socat.c +++ b/socat.c @@ -83,12 +83,16 @@ bool havelock; int main(int argc, const char *argv[]) { const char **arg1, *a; + char *mainwaitstring; char buff[10]; double rto; int i, argc0, result; struct utsname ubuf; int lockrc; + if (mainwaitstring = getenv("SOCAT_MAIN_WAIT")) { + sleep(atoi(mainwaitstring)); + } diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]); /* we must init before applying options because env settings have lower @@ -642,37 +646,32 @@ int socat(const char *address1, const char *address2) { returns >0 if child died and left data */ int childleftdata(xiofile_t *xfd) { - fd_set in, out, expt; + struct pollfd in; + int timeout = 0; /* milliseconds */ int retval; + /* have to check if a child process died before, but left read data */ if (XIO_READABLE(xfd) && (XIO_RDSTREAM(xfd)->howtoend == END_KILL || XIO_RDSTREAM(xfd)->howtoend == END_CLOSE_KILL || XIO_RDSTREAM(xfd)->howtoend == END_SHUTDOWN_KILL) && XIO_RDSTREAM(xfd)->para.exec.pid == 0) { - struct timeval time0 = { 0,0 }; - FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt); if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) { - FD_SET(XIO_GETRDFD(xfd), &in); - /*0 FD_SET(XIO_GETRDFD(xfd), &expt);*/ + in.fd = XIO_GETRDFD(xfd); + in.events = POLLIN/*|POLLRDBAND*/; + in.revents = 0; } do { - retval = Select(FD_SETSIZE, &in, &out, &expt, &time0); + retval = xiopoll(&in, 1, timeout); } while (retval < 0 && errno == EINTR); if (retval < 0) { -#if HAVE_FDS_BITS - Error5("select(%d, &0x%lx, &0x%lx, &0x%lx, {0}): %s", - FD_SETSIZE, in.fds_bits[0], out.fds_bits[0], - expt.fds_bits[0], strerror(errno)); -#else - Error5("select(%d, &0x%lx, &0x%lx, &0x%lx, {0}): %s", - FD_SETSIZE, in.__fds_bits[0], out.__fds_bits[0], - expt.__fds_bits[0], strerror(errno)); -#endif + Error4("xiopoll({%d,%0o}, 1, %d): %s", + in.fd, in.events, timeout, strerror(errno)); return -1; - } else if (retval == 0) { + } + if (retval == 0) { Info("terminated child did not leave data for us"); XIO_RDSTREAM(xfd)->eof = 2; xfd->stream.eof = 2; @@ -694,7 +693,11 @@ bool maywr2; /* sock2 can be written to, according to select() */ and their options are set/applied returns -1 on error or 0 on success */ int _socat(void) { - fd_set in, out, expt; + struct pollfd fds[4], + *fd1in = &fds[0], + *fd1out = &fds[1], + *fd2in = &fds[2], + *fd2out = &fds[3]; int retval; unsigned char *buff; ssize_t bytes1, bytes2; @@ -747,7 +750,7 @@ int _socat(void) { XIO_GETRDFD(sock2), XIO_GETWRFD(sock2)); while (XIO_RDSTREAM(sock1)->eof <= 1 || XIO_RDSTREAM(sock2)->eof <= 1) { - struct timeval timeout, *to = NULL; + int timeout; Debug6("data loop: sock1->eof=%d, sock2->eof=%d, closing=%d, wasaction=%d, total_to={"F_tv_sec"."F_tv_usec"}", XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock2)->eof, @@ -783,59 +786,77 @@ int _socat(void) { if (polling) { /* there is a ignoreeof poll timeout, use it */ - timeout = socat_opts.pollintv; - to = &timeout; + timeout = 1000*socat_opts.pollintv.tv_sec + + socat_opts.pollintv.tv_usec/1000; /*!!! overflow?*/ } else if (socat_opts.total_timeout.tv_sec != 0 || socat_opts.total_timeout.tv_usec != 0) { /* there might occur a total inactivity timeout */ - timeout = socat_opts.total_timeout; - to = &timeout; + timeout = 1000*socat_opts.total_timeout.tv_sec + + socat_opts.total_timeout.tv_usec/1000; } else { - to = NULL; + timeout = -1; /* forever */ } if (closing>=1) { /* first eof already occurred, start end timer */ - timeout = socat_opts.closwait; - to = &timeout; + timeout = 1000*socat_opts.closwait.tv_sec + + socat_opts.closwait.tv_usec/1000; closing = 2; } do { int _errno; - FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt); childleftdata(sock1); childleftdata(sock2); if (closing>=1) { /* first eof already occurred, start end timer */ - timeout = socat_opts.closwait; - to = &timeout; + timeout = 1000*socat_opts.closwait.tv_sec + + socat_opts.closwait.tv_usec/1000; closing = 2; } + /* now the fds are assigned */ if (XIO_READABLE(sock1) && !(XIO_RDSTREAM(sock1)->eof > 1 && !XIO_RDSTREAM(sock1)->ignoreeof) && !socat_opts.righttoleft) { if (!mayrd1) { - FD_SET(XIO_GETRDFD(sock1), &in); + fd1in->fd = XIO_GETRDFD(sock1); + fd1in->events = POLLIN; + } else { + fd1in->fd = -1; } if (!maywr2) { - FD_SET(XIO_GETWRFD(sock2), &out); + fd2out->fd = XIO_GETWRFD(sock2); + fd2out->events = POLLOUT; + } else { + fd2out->fd = -1; } + } else { + fd1in->fd = -1; + fd2out->fd = -1; } if (XIO_READABLE(sock2) && !(XIO_RDSTREAM(sock2)->eof > 1 && !XIO_RDSTREAM(sock2)->ignoreeof) && !socat_opts.lefttoright) { if (!mayrd2) { - FD_SET(XIO_GETRDFD(sock2), &in); + fd2in->fd = XIO_GETRDFD(sock2); + fd2in->events = POLLIN; + } else { + fd2in->fd = -1; } if (!maywr1) { - FD_SET(XIO_GETWRFD(sock1), &out); + fd1out->fd = XIO_GETWRFD(sock1); + fd1out->events = POLLOUT; + } else { + fd1out->fd = -1; } + } else { + fd1out->fd = -1; + fd2in->fd = -1; } - retval = Select(FD_SETSIZE, &in, &out, &expt, to); + retval = xiopoll(fds, 4, timeout); _errno = errno; if (retval < 0 && errno == EINTR) { Info1("select(): %s", strerror(errno)); @@ -849,17 +870,10 @@ int _socat(void) { */ if (retval < 0) { -#if HAVE_FDS_BITS - Error7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu): %s", - FD_SETSIZE, in.fds_bits[0], out.fds_bits[0], - expt.fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0, - strerror(errno)); -#else - Error7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu): %s", - FD_SETSIZE, in.__fds_bits[0], out.__fds_bits[0], - expt.__fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0, - strerror(errno)); -#endif + Error10("xiopoll({%d,%0o}{%d,%0o}{%d,%0o}{%d,%0o}, 4, %d): %s", + fds[0].fd, fds[0].events, fds[1].fd, fds[1].events, + fds[2].fd, fds[2].events, fds[3].fd, fds[3].events, + timeout, strerror(errno)); return -1; } else if (retval == 0) { Info2("select timed out (no data within %ld.%06ld seconds)", @@ -884,17 +898,17 @@ int _socat(void) { } if (XIO_READABLE(sock1) && XIO_GETRDFD(sock1) >= 0 && - FD_ISSET(XIO_GETRDFD(sock1), &in)) { + (fd1in->revents&(POLLIN|POLLHUP|POLLERR))) { mayrd1 = true; } if (XIO_READABLE(sock2) && XIO_GETRDFD(sock2) >= 0 && - FD_ISSET(XIO_GETRDFD(sock2), &in)) { + (fd2in->revents&(POLLIN|POLLHUP|POLLERR))) { mayrd2 = true; } - if (XIO_GETWRFD(sock1) >= 0 && FD_ISSET(XIO_GETWRFD(sock1), &out)) { + if (XIO_GETWRFD(sock1) >= 0 && (fd1out->revents&(POLLOUT|POLLERR))) { maywr1 = true; } - if (XIO_GETWRFD(sock2) >= 0 && FD_ISSET(XIO_GETWRFD(sock2), &out)) { + if (XIO_GETWRFD(sock2) >= 0 && (fd2out->revents&(POLLOUT|POLLERR))) { maywr2 = true; } diff --git a/sycls.c b/sycls.c index 8581436..fee5bca 100644 --- a/sycls.c +++ b/sycls.c @@ -677,9 +677,21 @@ int Chmod(const char *path, mode_t mode) { /* we only show the first struct pollfd; hope this is enough for most cases. */ int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { int result; - Debug4("poll({%d, 0x%02hx, }, %u, %d)", ufds[0].fd, ufds[0].events, nfds, timeout); + if (nfds == 4) { + Debug10("poll({%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}, , %u, %d)", + ufds[0].fd, ufds[0].events, ufds[1].fd, ufds[1].events, + ufds[2].fd, ufds[2].events, ufds[3].fd, ufds[3].events, + nfds, timeout); + } else { + Debug4("poll({%d,0x%02hx,}, , %u, %d)", ufds[0].fd, ufds[0].events, nfds, timeout); + } result = poll(ufds, nfds, timeout); - Debug2("poll(, {,, 0x%02hx}) -> %d", ufds[0].revents, result); + if (nfds == 4) { + Debug5("poll(, {,,0x%02hx}{,,0x%02hx}{,,0x%02hx}{,,0x%02hx}) -> %d", + ufds[0].revents, ufds[1].revents, ufds[2].revents, ufds[3].revents, result); + } else { + Debug2("poll(, {,,0x%02hx}) -> %d", ufds[0].revents, result); + } return result; } #endif /* HAVE_POLL */ diff --git a/sysutils.c b/sysutils.c index f2266c7..d113e4a 100644 --- a/sysutils.c +++ b/sysutils.c @@ -1,5 +1,5 @@ /* source: sysutils.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* translate socket addresses into human readable form */ @@ -400,6 +400,17 @@ const char *hstrerror(int err) { return h_messages[err]; } #endif /* !HAVE_HSTRERROR */ + + +/* this function behaves like poll(). It tries to do so even when the poll() + system call is not available. */ +int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout) { +#if HAVE_POLL + return Poll(fds, nfds, timeout); +#else /* HAVE_POLL */ + /*!!! wrap around Select() */ +#endif /* !HAVE_POLL */ +} #if WITH_TCP || WITH_UDP diff --git a/sysutils.h b/sysutils.h index c75e9a7..b9074b3 100644 --- a/sysutils.h +++ b/sysutils.h @@ -90,6 +90,8 @@ extern int getusergroups(const char *user, gid_t *list, size_t *ngroups); extern const char *hstrerror(int err); #endif +extern int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout); + extern int parseport(const char *portname, int proto); extern int ifindexbyname(const char *ifname); diff --git a/xio-socket.c b/xio-socket.c index 36fdb59..bca7746 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -269,19 +269,21 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, if (errno == EINPROGRESS) { if (xfd->para.socket.connect_timeout.tv_sec != 0 || xfd->para.socket.connect_timeout.tv_usec != 0) { - struct timeval timeout; - fd_set readfds, writefds, exceptfds; + int timeout; + struct pollfd writefd; int result; + Info4("connect(%d, %s, "F_Zd"): %s", xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); - timeout = xfd->para.socket.connect_timeout; - FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); - FD_SET(xfd->fd, &readfds); FD_SET(xfd->fd, &writefds); - result = - Select(xfd->fd+1, &readfds, &writefds, &exceptfds, &timeout); + timeout = 1000*xfd->para.socket.connect_timeout.tv_sec + + xfd->para.socket.connect_timeout.tv_usec/1000; + writefd.fd = xfd->fd; + writefd.events = (POLLIN|POLLHUP|POLLERR); + result = Poll(&writefd, 1, timeout); if (result < 0) { - Msg2(level, "select(%d,,,,): %s", xfd->fd+1, strerror(errno)); + Msg3(level, "poll({%d,POLLIN|POLLHUP|POLLER},,%d): %s", + xfd->fd, timeout, strerror(errno)); return STAT_RETRYLATER; } if (result == 0) { @@ -290,7 +292,7 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, strerror(ETIMEDOUT)); return STAT_RETRYLATER; } - if (FD_ISSET(xfd->fd, &readfds)) { + if (writefd.revents & POLLOUT) { #if 0 unsigned char dummy[1]; Read(xfd->fd, &dummy, 1); /* get error message */ @@ -726,16 +728,16 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, /* loop until select() returns valid */ do { - fd_set in, out, expt; + struct pollfd readfd; /*? int level = E_ERROR;*/ if (us != NULL) { Notice1("receiving on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname))); } else { Notice1("receiving IP protocol %u", proto); } - FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt); - FD_SET(xfd->fd, &in); - if (Select(xfd->fd+1, &in, &out, &expt, NULL) > 0) { + readfd.fd = xfd->fd; + readfd.events = POLLIN; + if (Poll(&readfd, 1, -1) > 0) { break; } @@ -743,7 +745,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, continue; } - Msg2(level, "select(, {%d}): %s", xfd->fd, strerror(errno)); + Msg2(level, "poll({%d,,},,-1): %s", xfd->fd, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } while (true); diff --git a/xio-udp.c b/xio-udp.c index 3907f98..8cedcff 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -84,7 +84,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, union sockaddr_union themunion; union sockaddr_union *them = &themunion; int socktype = SOCK_DGRAM; - fd_set in, out, expt; + struct pollfd readfd; bool dofork = false; pid_t pid; char *rangename; @@ -205,9 +205,9 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, Notice1("listening on UDP %s", sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff))); - FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt); - FD_SET(fd->stream.fd, &in); - while (Select(fd->stream.fd+1, &in, &out, &expt, NULL) < 0) { + readfd.fd = fd->stream.fd; + readfd.events = POLLIN|POLLERR; + while (Poll(&readfd, 1, -1) < 0) { if (errno != EINTR) break; } From e142c3da6bba3e2e1ba79525a6f03721dae82a51 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 4 Sep 2008 23:30:59 +0200 Subject: [PATCH 09/75] dont leave UDP-LISTEN socket open after reject --- CHANGES | 4 ++++ VERSION | 2 +- test.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- xio-udp.c | 1 + 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index ed3fa25..9c17a0d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ corrections: + when UDP-LISTEN continued to listen after packet dropped by, e.g., + range option, the old listen socket would not be closed but a new one + created. open sockets could accumulate. + there was a bug in ip*-recv with bind option: it did not bind, and with the first received packet an error occurred: socket_init(): unknown address family 0 diff --git a/VERSION b/VERSION index 2b6e1d9..5393aac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont" diff --git a/test.sh b/test.sh index 5846503..58b50d3 100755 --- a/test.sh +++ b/test.sh @@ -8032,9 +8032,9 @@ else numOK=$((numOK+1)) fi kill $pid1 2>/dev/null -wait ;; +wait +PORT="$_PORT" ;; esac -PORT="$_PORT" N=$((N+1)) @@ -8317,6 +8317,59 @@ esac N=$((N+1)) +# a bug was found in the way UDP-LISTEN handles the listening socket: +# when UDP-LISTEN continued to listen after a packet had been dropped by, e.g., +# range option, the old listen socket would not be closed but a new one created. +NAME=UDP4LISTENCONT +case "$TESTS" in +*%functions%*|*%bugs%*|*%ip4%*|*%udp%*|*%$NAME%*) +TEST="$NAME: let range drop a packet and see if old socket is closed" +# idea: run a UDP4-LISTEN process with range option. Send it one packet from an +# address outside range and check if two listening sockets are open then +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +while [ "$(netstat -an |grep "^udp.*127.0.0.1:$PORT" |wc -l)" -ne 0 ]; do + PORT=$((PORT+1)) +done +tp=$PORT +da1="test$N $(date) $RANDOM" +a1="$LOCALHOST" +a2="$SECONDADDR" +#CMD0="$SOCAT $opts UDP4-LISTEN:$tp,bind=$a1,range=$a2/32 PIPE" +CMD0="$SOCAT $opts UDP4-LISTEN:$tp,range=$a2/32 PIPE" +CMD1="$SOCAT $opts - UDP-CONNECT:$a1:$tp" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" & +pid1=$! +waitudp4port $tp 1 +echo "$da1" |$CMD1 >"${tf}1" 2>"${te}1" # this should fail +rc1=$? +waitudp4port $tp 1 +nsocks="$(netstat -an |grep "^udp.*[:.]$PORT" |wc -l)" +kill $pid1 2>/dev/null; wait +if [ $rc1 -ne 0 ]; then + $PRINTF "$NO_RESULT\n" + numCANT=$((numCANT+1)) +elif [ $nsocks -eq 0 ]; then + $PRINTF "$NO_RESULT\n" + numCANT=$((numCANT+1)) +elif [ $nsocks -ne 1 ]; then + $PRINTF "$FAILED ($nsocks listening sockets)\n" + echo "$CMD0 &" + echo "$CMD1" + cat "${te}0" "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/xio-udp.c b/xio-udp.c index 8cedcff..64cf04a 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -231,6 +231,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, /* drop packet */ char buff[512]; Recv(fd->stream.fd, buff, sizeof(buff), 0); + Close(fd->stream.fd); continue; } Info1("permitting UDP connection from %s", From 1924e17cf0ee19ff68ad66b0e179143aed1097fc Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 4 Sep 2008 23:42:52 +0200 Subject: [PATCH 10/75] replaced select() by poll() in comments --- socat.c | 22 +++++++++++----------- xio-socket.c | 2 +- xio-udp.c | 2 +- xioopts.c | 2 +- xioread.c | 4 ++-- xiowrite.c | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/socat.c b/socat.c index 78eda0c..f4cf771 100644 --- a/socat.c +++ b/socat.c @@ -684,10 +684,10 @@ int childleftdata(xiofile_t *xfd) { int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe, unsigned char **buff, size_t bufsiz, bool righttoleft); -bool mayrd1; /* sock1 has read data or eof, according to select() */ -bool mayrd2; /* sock2 has read data or eof, according to select() */ -bool maywr1; /* sock1 can be written to, according to select() */ -bool maywr2; /* sock2 can be written to, according to select() */ +bool mayrd1; /* sock1 has read data or eof, according to poll() */ +bool mayrd2; /* sock2 has read data or eof, according to poll() */ +bool maywr1; /* sock1 can be written to, according to poll() */ +bool maywr2; /* sock2 can be written to, according to poll() */ /* here we come when the sockets are opened (in the meaning of C language), and their options are set/applied @@ -702,7 +702,7 @@ int _socat(void) { unsigned char *buff; ssize_t bytes1, bytes2; int polling = 0; /* handling ignoreeof */ - int wasaction = 1; /* last select was active, do NOT sleep before next */ + int wasaction = 1; /* last poll was active, do NOT sleep before next */ struct timeval total_timeout; /* the actual total timeout timer */ #if WITH_FILAN @@ -760,7 +760,7 @@ int _socat(void) { /* for ignoreeof */ if (polling) { if (!wasaction) { - /* yes we could do it with select but I like readable trace output */ + /* yes we could do it with poll but I like readable trace output */ if (socat_opts.pollintv.tv_sec) Sleep(socat_opts.pollintv.tv_sec); if (socat_opts.pollintv.tv_usec) Usleep(socat_opts.pollintv.tv_usec); @@ -804,7 +804,7 @@ int _socat(void) { closing = 2; } - do { + do { /* loop over poll() EINTR */ int _errno; childleftdata(sock1); @@ -859,7 +859,7 @@ int _socat(void) { retval = xiopoll(fds, 4, timeout); _errno = errno; if (retval < 0 && errno == EINTR) { - Info1("select(): %s", strerror(errno)); + Info1("poll(): %s", strerror(errno)); } errno = _errno; } while (retval < 0 && errno == EINTR); @@ -876,7 +876,7 @@ int _socat(void) { timeout, strerror(errno)); return -1; } else if (retval == 0) { - Info2("select timed out (no data within %ld.%06ld seconds)", + Info2("poll timed out (no data within %ld.%06ld seconds)", closing>=1?socat_opts.closwait.tv_sec:socat_opts.total_timeout.tv_sec, closing>=1?socat_opts.closwait.tv_usec:socat_opts.total_timeout.tv_usec); if (polling && !wasaction) { @@ -927,7 +927,7 @@ int _socat(void) { maywr2 = false; total_timeout = socat_opts.total_timeout; wasaction = 1; - /* is more data available that has already passed select()? */ + /* is more data available that has already passed poll()? */ mayrd1 = (xiopending(sock1) > 0); if (XIO_RDSTREAM(sock1)->readbytes != 0 && XIO_RDSTREAM(sock1)->actbytes == 0) { @@ -955,7 +955,7 @@ int _socat(void) { maywr1 = false; total_timeout = socat_opts.total_timeout; wasaction = 1; - /* is more data available that has already passed select()? */ + /* is more data available that has already passed poll()? */ mayrd2 = (xiopending(sock2) > 0); if (XIO_RDSTREAM(sock2)->readbytes != 0 && XIO_RDSTREAM(sock2)->actbytes == 0) { diff --git a/xio-socket.c b/xio-socket.c index bca7746..cd11c14 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -726,7 +726,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, drop = true; } - /* loop until select() returns valid */ + /* loop until select()/poll() returns valid */ do { struct pollfd readfd; /*? int level = E_ERROR;*/ diff --git a/xio-udp.c b/xio-udp.c index 64cf04a..293b8be 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -251,7 +251,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, } break; } - /* server: continue loop with select */ + /* server: continue loop with socket()+recvfrom() */ /* when we dont close this we get awkward behaviour on Linux 2.4: recvfrom gives 0 bytes with invalid socket address */ if (Close(fd->stream.fd) < 0) { diff --git a/xioopts.c b/xioopts.c index 0652073..ad76434 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3446,7 +3446,7 @@ int applyopts_single(struct single *xfd, struct opt *opts, enum e_phase phase) { xfd->lock.intervall.tv_sec = 1; xfd->lock.intervall.tv_nsec = 0; - /*! this should be integrated into central select loop */ + /*! this should be integrated into central select()/poll() loop */ if (xiolock(&xfd->lock) < 0) { return -1; } diff --git a/xioread.c b/xioread.c index 141d7fe..5db886c 100644 --- a/xioread.c +++ b/xioread.c @@ -366,8 +366,8 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { /* this function is intended only for some special address types where the - select() call cannot strictly determine if (more) read data is available. - currently this is for the OpenSSL based addresses. + select()/poll() calls cannot strictly determine if (more) read data is + available. currently this is for the OpenSSL based addresses. */ ssize_t xiopending(xiofile_t *file) { struct single *pipe; diff --git a/xiowrite.c b/xiowrite.c index 88c01e1..d02e48b 100644 --- a/xiowrite.c +++ b/xiowrite.c @@ -1,5 +1,5 @@ /* source: xiowrite.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the extended write function */ @@ -13,9 +13,9 @@ /* ... - note that the write() call can block even if the select() call reported the - FD writeable: in case the FD is not nonblocking and a lock defers the - operation. + note that the write() call can block even if the select()/poll() call + reported the FD writeable: in case the FD is not nonblocking and a lock + defers the operation. on return value < 0: errno reflects the value from write() */ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) { ssize_t writt; From 31de787c8bb8c1620556fa954d6285a8a421619b Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 5 Sep 2008 00:06:07 +0200 Subject: [PATCH 11/75] RECVFROM with FORK hung after the first packet - still on BSD --- xio-socket.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xio-socket.c b/xio-socket.c index cd11c14..d93bb98 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -566,6 +566,11 @@ void xiosigaction_hasread(int signum, siginfo_t *siginfo, void *ucontext) { Debug("xiosigaction_hasread() ->"); return; } + if (pid == xio_waitingfor) { + xio_hashappened = true; + Debug("xiosigaction_hasread() ->"); + return; + } } while (1); } if (xio_waitingfor == siginfo->si_pid) { From 67e59494c466bbe81b1fc6c3e26a9fa153e102c3 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 5 Sep 2008 00:22:35 +0200 Subject: [PATCH 12/75] improve test for EXECSPACES to keep multiple spaces in arguments --- test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.sh b/test.sh index 58b50d3..5b154a8 100755 --- a/test.sh +++ b/test.sh @@ -8291,11 +8291,11 @@ TEST="$NAME: correctly parse exec with consecutive spaces" $PRINTF "test $F_n $TEST... " $N tf="$td/test$N.stdout" te="$td/test$N.stderr" -da="test$N $(date) $RANDOM" +da="test$N $(date) $RANDOM" # with a double space tdiff="$td/test$N.diff" # put the test data as first argument after two spaces. expect the data in the # first argument of the exec'd command. -$SOCAT $opts -u "exec:\"bash -c \\\"echo \$1\\\" \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te" +$SOCAT $opts -u "exec:\"bash -c \\\"echo \\\\\\\"\$1\\\\\\\"\\\" \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te" rc=$? echo "$da" |diff - "$tf" >"$tdiff" if [ "$rc" -ne 0 ]; then From f8496421f92874ade9d0bd826b453db1d23653e8 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 14 Sep 2008 18:33:28 +0200 Subject: [PATCH 13/75] some raw IP and UNIX datagram modes failed on BSD systems; test.sh: more stable timing, corrections for BSD --- CHANGES | 4 +- Makefile.in | 2 +- socat.c | 4 +- test.sh | 113 ++++++++++++++++++++++++++++++++++++---------------- xio-ip.c | 3 +- xio-rawip.c | 6 ++- xio-unix.c | 6 +++ 7 files changed, 97 insertions(+), 41 deletions(-) diff --git a/CHANGES b/CHANGES index 9c17a0d..202bcb2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ corrections: + some raw IP and UNIX datagram modes failed on BSD systems + when UDP-LISTEN continued to listen after packet dropped by, e.g., range option, the old listen socket would not be closed but a new one created. open sockets could accumulate. @@ -24,7 +26,7 @@ corrections: some minor corrections - improved test.sh script + improved test.sh script: more stable timing, corrections for BSD replaced the select() calls by poll() to cleanly fix the problems with many file descriptors already open diff --git a/Makefile.in b/Makefile.in index ddcdab8..583985b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -97,7 +97,7 @@ doc/socat.1: doc/socat.yo yodl2man -o $@ $+ doc/socat.html: doc/socat.yo - yodl2html -o $@ $+ + cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) diff --git a/socat.c b/socat.c index f4cf771..cb52870 100644 --- a/socat.c +++ b/socat.c @@ -905,10 +905,10 @@ int _socat(void) { (fd2in->revents&(POLLIN|POLLHUP|POLLERR))) { mayrd2 = true; } - if (XIO_GETWRFD(sock1) >= 0 && (fd1out->revents&(POLLOUT|POLLERR))) { + if (XIO_GETWRFD(sock1) >= 0 && (fd1out->revents&(POLLOUT|POLLHUP|POLLERR))) { maywr1 = true; } - if (XIO_GETWRFD(sock2) >= 0 && (fd2out->revents&(POLLOUT|POLLERR))) { + if (XIO_GETWRFD(sock2) >= 0 && (fd2out->revents&(POLLOUT|POLLHUP|POLLERR))) { maywr2 = true; } diff --git a/test.sh b/test.sh index 5b154a8..402814e 100755 --- a/test.sh +++ b/test.sh @@ -11,6 +11,30 @@ #set -vx +val_t=0.1 +while [ "$1" ]; do + case "X$1" in + X-t?*) val_t="${1#-t}" ;; + X-t) shift; val_t="$1" ;; + *) break; + esac + shift +done + +opt_t="-t $val_t" + +#MICROS=100000 +case "X$val_t" in + X*.???????*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS:0:6}" ;; + X*.*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS}000000"; uS="${uS:0:6}" ;; + X*) S="${val_t}"; uS="000000" ;; +esac +MICROS=${S}${uS} +MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0} +# +_MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}" +[ -z "$SECONDs" ] && SECONDs=0 + withroot=0 # perform privileged tests even if not run by root #PATH=$PATH:/opt/freeware/bin #PATH=$PATH:/usr/local/ssl/bin @@ -20,7 +44,7 @@ MISCDELAY=1 [ -z "$SOCAT" ] && SOCAT="./socat" [ -z "$PROCAN" ] && PROCAN="./procan" [ -z "$FILAN" ] && FILAN="./filan" -opts="-t0.1 $OPTS" +opts="$opt_t $OPTS" export SOCAT_OPTS="$opts" #debug="1" debug= @@ -31,18 +55,26 @@ MCINTERFACE=lo # !!! Linux only #LOCALHOST=localhost LOCALHOST=127.0.0.1 LOCALHOST6=[::1] -PROTO=$((192+RANDOM/1024)) +PROTO=$((144+RANDOM/2048)) PORT=12002 SOURCEPORT=2002 CAT=cat OD_C="od -c" +# precision sleep; takes seconds with fractional part +psleep () { + local T="$1" + [ "$T" = 0 ] && T=0.000002 + $SOCAT -T "$T" pipe pipe +} # time in microseconds to wait in some situations -MICROS=100000 if ! type usleep >/dev/null 2>&1; then usleep () { local n="$1" - # older bashes do not accept $1 here: - sleep $(((n+999999)/1000000)) + case "$n" in + *???????) S="${n%??????}"; uS="${n:${#n}-6}" ;; + *) S=0; uS="00000$n"; uS="${uS:${#uS}-6}" ;; + esac + $SOCAT -T $S.$uS pipe pipe } fi #USLEEP=usleep @@ -94,7 +126,7 @@ Linux) BCADDR=127.255.255.255 BCIFADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}' |cut -d: -f2) ;; FreeBSD|NetBSD|OpenBSD) - MAINIF=$($IFCONFIG -a |grep '^[a-z]' |head -1 |cut -d: -f1) + MAINIF=$($IFCONFIG -a |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1) BROADCASTIF="$MAINIF" SECONDADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}') BCIFADDR="$SECONDADDR" @@ -105,8 +137,10 @@ HP-UX) SECONDADDR=$($IFCONFIG $MAINIF |tail -n 1 |awk '{print($2);}') BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;; SunOS) + MAINIF=$($IFCONFIG -a |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1) + BROADCASTIF="$MAINIF" #BROADCASTIF=hme0 - BROADCASTIF=eri0 + #BROADCASTIF=eri0 SECONDADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}') BCIFADDR="$SECONDADDR" BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;; @@ -123,9 +157,12 @@ case "$UNAME" in ;; esac if [ -z "$SECONDIP6ADDR" ]; then - case "$TESTS" in - *%root2%*) $IFCONFIG eth0 ::2/128 - esac +# case "$TESTS" in +# *%root2%*) $IFCONFIG eth0 ::2/128 +# esac + SECONDIP6ADDR="$LOCALHOST6" +else + SECONDIP6ADDR="[$SECONDIP6ADDR]" fi TRUE=$(which true) @@ -147,7 +184,7 @@ vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color) RED="\0033[31m" GREEN="\0033[32m" YELLOW="\0033[33m" - if [ "$UNAME" = SunOS ]; then + if false && [ "$UNAME" = SunOS ]; then NORMAL="\0033[30m" else NORMAL="\0033[39m" @@ -156,7 +193,7 @@ vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color) RED="\033[31m" GREEN="\033[32m" YELLOW="\033[33m" - if [ "$UNAME" = SunOS ]; then + if false && [ "$UNAME" = SunOS ]; then NORMAL="\033[30m" else NORMAL="\033[39m" @@ -1436,7 +1473,7 @@ testecho () { #$ECHO "testing $title (test $N)... \c" $PRINTF "test $F_n %s... " $N "$title" #echo "$da" |$cmd >"$tf" 2>"$te" - (echo "$da"; sleep $T) |($SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") & + (psleep $T; echo "$da"; psleep $T) |($SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") & export rc1=$! #sleep 5 && kill $rc1 2>/dev/null & # rc2=$! @@ -1476,7 +1513,7 @@ testod () { local dain="$(date) $RANDOM" local daout="$(echo "$dain" |$OD_C)" $PRINTF "test $F_n %s... " $num "$title" - (echo "$dain"; sleep $T) |$SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" + (psleep $T; echo "$dain"; psleep $T) |$SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" if [ "$?" != 0 ]; then $PRINTF "$FAILED: $SOCAT:\n" echo "$SOCAT $opts $arg1 $arg2" @@ -1537,6 +1574,8 @@ ifprocess () { FreeBSD) l="$(ps -faje |grep "^........ $(printf %5u $1)")" ;; HP-UX) l="$(ps -fade |grep "^........ $(printf %5u $1)")" ;; Linux) l="$(ps -fade |grep "^........ $(printf %5u $1)")" ;; + NetBSD) l="$(ps -aj |grep "^........ $(printf %4u $1)")" ;; + OpenBSD) l="$(ps -kaj |grep "^........ $(printf %5u $1)")" ;; SunOS) l="$(ps -fade |grep "^........ $(printf %5u $1)")" ;; *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*$(printf %5u $1) ")" ;; esac @@ -1557,6 +1596,8 @@ childprocess () { FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;; HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; + NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)")" ;; + OpenBSD) l="$(ps -kaj |grep "^........ ..... $(printf %5u $1)")" ;; SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]**[ ][ ]*$(printf %5u $1) ")" ;; esac if [ -z "$l" ]; then @@ -2009,7 +2050,7 @@ NAME=SYSTEMSOCKET case "$TESTS" in *%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with socketpair" -testecho "$N" "$TEST" "" "system:$CAT" "$opts" +testecho "$N" "$TEST" "" "system:$CAT" "$opts" "$val_t" esac N=$((N+1)) @@ -2073,12 +2114,12 @@ NAME=DUALSYSTEMFDS case "$TESTS" in *%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: echo via dual system() of cat" -testecho "$N" "$TEST" "system:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" +testecho "$N" "$TEST" "system:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t" esac N=$((N+1)) -# test: send EOF to exec'ed sub process, let it finished its operation, and +# test: send EOF to exec'ed sub process, let it finish its operation, and # check if the sub process returns its data before terminating. NAME=EXECSOCKETFLUSH # idea: have socat exec'ing od; send data and EOF, and check if the od'ed data @@ -2095,7 +2136,7 @@ NAME=SYSTEMSOCKETFLUSH case "$TESTS" in *%functions%*|*%system%*|*%$NAME%*) TEST="$NAME: call to od via system() with socketpair" -testod "$N" "$TEST" "" "system:$OD_C" "$opts" +testod "$N" "$TEST" "" "system:$OD_C" "$opts" $val_t esac N=$((N+1)) @@ -3579,7 +3620,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD2="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 exec:'$OD_C'" -CMD="$SOCAT $opts - openssl:$LOCALHOST:$PORT,verify=0,$SOCAT_EGD" +CMD="$SOCAT -T1 $OPTS - openssl:$LOCALHOST:$PORT,verify=0,$SOCAT_EGD" printf "test $F_n $TEST... " $N eval "$CMD2 2>\"${te}1\" &" pid=$! # background process id @@ -4412,6 +4453,7 @@ EOF #0 if ! sed 's/.*\r//g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then #0 if ! sed 's/.*'"$($ECHO '\r\c')"'//dev/null 2>&1; then +wait if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr" - >"$tdiff" 2>&1; then $PRINTF "$FAILED: $SOCAT:\n" echo "$CMD" @@ -7110,15 +7152,15 @@ tdiff="$td/test$N.diff" da1a="$(date) $RANDOM" da1b="$(date) $RANDOM" CMD1="$SOCAT $opts - UNIX-CONNECT:$ts" -CMD="$SOCAT -t0.1 $opts EXEC:"$CAT",end-close UNIX-LISTEN:$ts,fork" +CMD="$SOCAT $opts EXEC:"$CAT",end-close UNIX-LISTEN:$ts,fork" printf "test $F_n $TEST... " $N $CMD 2>"${te}2" & pid2=$! waitfile $ts 1 echo "$da1a" |$CMD1 2>>"${te}1a" >"$tf" -usleep 100000 +usleep $MICROS echo "$da1b" |$CMD1 2>>"${te}1b" >>"$tf" -usleep 100000 +#usleep $MICROS kill "$pid2" 2>/dev/null wait if [ $? -ne 0 ]; then @@ -7285,6 +7327,7 @@ case "$TESTS" in TEST="$NAME: UDP/IPv4 broadcast" if [ -z "$BCADDR" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N + numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7921,9 +7964,9 @@ to="$td/test$N.out" te="$td/test$N.err" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -CMD="$SOCAT $opts system:\"echo A; sleep 2\",readbytes=2!!- -!!/dev/null" +CMD="$SOCAT $opts system:\"echo A; sleep $((2*SECONDs))\",readbytes=2!!- -!!/dev/null" printf "test $F_n $TEST... " $N -(sleep 1; echo) |eval "$CMD" >"$to" 2>"$te" +(usleep $((2*MICROS)); echo) |eval "$CMD" >"$to" 2>"$te" if test -s "$to"; then $PRINTF "$FAILED: $SOCAT:\n" echo "$CMD" @@ -7944,7 +7987,7 @@ NAME=EXECPTYKILL case "$TESTS" in *%functions%*|*%bugs%*|*%exec%*|*%$NAME%*) TEST="$NAME: exec:...,pty explicitely kills sub process" -# we want to check if the exec'd sub process is kill in time +# we want to check if the exec'd sub process is killed in time # for this we have a shell script that generates a file after two seconds; # it should be killed after one second, so if the file was generated the test # has failed @@ -7955,18 +7998,18 @@ tda="$td/test$N.data" tsh="$td/test$N.sh" tdiff="$td/test$N.diff" cat >"$tsh" <"${te}2" & pid1=$! -sleep 1 -waitfile $ts 1 +sleep $SECONDs +waitfile $ts $SECONDs $CMD 2>>"${te}1" >>"$tf" -usleep 2500000 +sleep $((2*SECONDs)) kill "$pid1" 2>/dev/null wait if [ $? -ne 0 ]; then @@ -8073,7 +8116,7 @@ done #echo "$REDIR" #testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1 #set -vx -eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T 1\"" 1 $REDIR +eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR #set +vx fi # could determine FOPEN_MAX esac @@ -8107,8 +8150,9 @@ rc2=$? sleep 1 #read -p ">" l="$(childprocess $pid1)" +rcc=$? kill $pid1 2>/dev/null; wait -if [ $rc2 -ne 0 ]; then +if [ $rc2 -ne 0 -o $rcc -ne 0 ]; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4STREAM numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then @@ -8157,8 +8201,9 @@ rc2=$? sleep 1 #read -p ">" l="$(childprocess $pid1)" +rcc=$? kill $pid1 2>/dev/null; wait -if [ $rc2 -ne 0 ]; then +if [ $rc2 -ne 0 -o $rcc -ne 0 ]; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then diff --git a/xio-ip.c b/xio-ip.c index df5a5b6..77dd71d 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -56,7 +56,8 @@ const struct optdesc opt_ip_router_alert={"ip-router-alert","routeralert",OPT_IP #endif /* following: Linux allows int but OpenBSD reqs char/byte */ const struct optdesc opt_ip_multicast_ttl={"ip-multicast-ttl","multicastttl",OPT_IP_MULTICAST_TTL,GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_BYTE,OFUNC_SOCKOPT,SOL_IP,IP_MULTICAST_TTL}; -const struct optdesc opt_ip_multicast_loop={"ip-multicast-loop","multicastloop",OPT_IP_MULTICAST_LOOP,GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_IP,IP_MULTICAST_LOOP}; +/* following: Linux allows int but OpenBSD reqs char/byte */ +const struct optdesc opt_ip_multicast_loop={"ip-multicast-loop","multicastloop",OPT_IP_MULTICAST_LOOP,GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_BYTE,OFUNC_SOCKOPT,SOL_IP,IP_MULTICAST_LOOP}; const struct optdesc opt_ip_multicast_if ={"ip-multicast-if", "multicast-if", OPT_IP_MULTICAST_IF, GROUP_SOCK_IP,PH_PASTSOCKET,TYPE_IP4NAME,OFUNC_SOCKOPT,SOL_IP,IP_MULTICAST_IF}; #ifdef IP_PKTOPTIONS const struct optdesc opt_ip_pktoptions = { "ip-pktoptions", "pktopts", OPT_IP_PKTOPTIONS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_PKTOPTIONS }; diff --git a/xio-rawip.c b/xio-rawip.c index d88da13..a1a0e09 100644 --- a/xio-rawip.c +++ b/xio-rawip.c @@ -298,8 +298,10 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, } xfd->stream.dtype = XIODATA_RECV_SKIPIP; - result = _xioopen_dgram_recv(&xfd->stream, xioflags, &/*us.soa*/xfd->stream.para.socket.la.soa, uslen, - opts, pf, socktype, ipproto, E_ERROR); + result = + _xioopen_dgram_recv(&xfd->stream, xioflags, + needbind?&xfd->stream.para.socket.la.soa:NULL, uslen, + opts, pf, socktype, ipproto, E_ERROR); _xio_openlate(&xfd->stream, opts); return result; } diff --git a/xio-unix.c b/xio-unix.c index 4e61994..b0c6b95 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -78,6 +78,9 @@ xiosetunix(struct sockaddr_un *saun, if (tight) { len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ MIN(pathlen, sizeof(saun->sun_path)); +#if HAVE_STRUCT_SOCKADDR_SALEN + saun->sun_len = len; +#endif } else { len = sizeof(struct sockaddr_un); } @@ -91,6 +94,9 @@ xiosetunix(struct sockaddr_un *saun, if (tight) { len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ MIN(pathlen+1, sizeof(saun->sun_path)); +#if HAVE_STRUCT_SOCKADDR_SALEN + saun->sun_len = len; +#endif } else { len = sizeof(struct sockaddr_un); } From 0e1eb7e4b468d3941752a5a91016e973b69e2414 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 19 Sep 2008 09:03:59 +0200 Subject: [PATCH 14/75] in ignoreeof mode socat also blocked data transfer in the other direction --- CHANGES | 4 +++ VERSION | 2 +- socat.c | 51 ++++++++++++++++++++-------- test.sh | 101 ++++++++++++++++++++++++++++++++++++++------------------ 4 files changed, 111 insertions(+), 47 deletions(-) diff --git a/CHANGES b/CHANGES index 202bcb2..e78e07a 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,10 @@ corrections: additional empty arguments (thanks to Olivier Hervieu for reporting this bug) + in ignoreeof polling mode socat also blocked data transfer in the other + direction during the 1s wait intervalls (thanks to Jorgen Cederlof for + reporting this bug) + corrected alphabetical order of options (proxy-auth) some minor corrections diff --git a/VERSION b/VERSION index 5393aac..9a06c88 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock" diff --git a/socat.c b/socat.c index cb52870..3128ec9 100644 --- a/socat.c +++ b/socat.c @@ -760,10 +760,6 @@ int _socat(void) { /* for ignoreeof */ if (polling) { if (!wasaction) { - /* yes we could do it with poll but I like readable trace output */ - if (socat_opts.pollintv.tv_sec) Sleep(socat_opts.pollintv.tv_sec); - if (socat_opts.pollintv.tv_usec) Usleep(socat_opts.pollintv.tv_usec); - if (socat_opts.total_timeout.tv_sec != 0 || socat_opts.total_timeout.tv_usec != 0) { if (total_timeout.tv_usec < socat_opts.pollintv.tv_usec) { @@ -804,6 +800,7 @@ int _socat(void) { closing = 2; } + /* frame 1: set the poll parameters and loop over poll() EINTR) */ do { /* loop over poll() EINTR */ int _errno; @@ -817,11 +814,20 @@ int _socat(void) { closing = 2; } - /* now the fds are assigned */ + /* use the ignoreeof timeout if appropriate */ + if (polling) { + int ptimeout = 1000*socat_opts.pollintv.tv_sec + + socat_opts.pollintv.tv_usec/1000; + if (closing == 0 || ptimeout < timeout) { + timeout = ptimeout; + } + } + + /* now the fds will be assigned */ if (XIO_READABLE(sock1) && !(XIO_RDSTREAM(sock1)->eof > 1 && !XIO_RDSTREAM(sock1)->ignoreeof) && !socat_opts.righttoleft) { - if (!mayrd1) { + if (!mayrd1 && !(XIO_RDSTREAM(sock1)->eof > 1)) { fd1in->fd = XIO_GETRDFD(sock1); fd1in->events = POLLIN; } else { @@ -840,7 +846,7 @@ int _socat(void) { if (XIO_READABLE(sock2) && !(XIO_RDSTREAM(sock2)->eof > 1 && !XIO_RDSTREAM(sock2)->ignoreeof) && !socat_opts.lefttoright) { - if (!mayrd2) { + if (!mayrd2 && !(XIO_RDSTREAM(sock2)->eof > 1)) { fd2in->fd = XIO_GETRDFD(sock2); fd2in->events = POLLIN; } else { @@ -856,13 +862,15 @@ int _socat(void) { fd1out->fd = -1; fd2in->fd = -1; } + /* frame 0: innermost part of the transfer loop: check FD status */ retval = xiopoll(fds, 4, timeout); - _errno = errno; - if (retval < 0 && errno == EINTR) { - Info1("poll(): %s", strerror(errno)); + if (retval >= 0 || errno != EINTR) { + break; } + _errno = errno; + Info1("poll(): %s", strerror(errno)); errno = _errno; - } while (retval < 0 && errno == EINTR); + } while (true); /* attention: when an exec'd process sends data and terminates, it is unpredictable @@ -881,7 +889,13 @@ int _socat(void) { closing>=1?socat_opts.closwait.tv_usec:socat_opts.total_timeout.tv_usec); if (polling && !wasaction) { /* there was a ignoreeof poll timeout, use it */ - ; + polling = 0; /*%%%*/ + if (XIO_RDSTREAM(sock1)->ignoreeof) { + mayrd1 = 0; + } + } else if (polling && wasaction) { + wasaction = 0; + } else if (socat_opts.total_timeout.tv_sec != 0 || socat_opts.total_timeout.tv_usec != 0) { /* there was a total inactivity timeout */ @@ -970,11 +984,15 @@ int _socat(void) { /* NOW handle EOFs */ + /*0 Debug4("bytes1=F_Zd, XIO_RDSTREAM(sock1)->eof=%d, XIO_RDSTREAM(sock1)->ignoreeof=%d, closing=%d", + bytes1, XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock1)->ignoreeof, + closing);*/ if (bytes1 == 0 || XIO_RDSTREAM(sock1)->eof >= 2) { if (XIO_RDSTREAM(sock1)->ignoreeof && !closing) { Debug1("socket 1 (fd %d) is at EOF, ignoring", XIO_RDSTREAM(sock1)->fd); /*! */ - polling = 1; + mayrd1 = true; + polling = 1; /* do not hook this eof fd to poll for pollintv*/ } else { Notice1("socket 1 (fd %d) is at EOF", XIO_GETRDFD(sock1)); xioshutdown(sock2, SHUT_WR); @@ -982,13 +1000,16 @@ int _socat(void) { break; } } + } else if (polling && XIO_RDSTREAM(sock1)->ignoreeof) { + polling = 0; } if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) { if (XIO_RDSTREAM(sock2)->ignoreeof && !closing) { Debug1("socket 2 (fd %d) is at EOF, ignoring", XIO_RDSTREAM(sock2)->fd); - polling = 1; + mayrd2 = true; + polling = 1; /* do not hook this eof fd to poll for pollintv*/ } else { Notice1("socket 2 (fd %d) is at EOF", XIO_GETRDFD(sock2)); xioshutdown(sock1, SHUT_WR); @@ -996,6 +1017,8 @@ int _socat(void) { break; } } + } else if (polling && XIO_RDSTREAM(sock2)->ignoreeof) { + polling = 0; } } diff --git a/test.sh b/test.sh index 402814e..5cbb3ec 100755 --- a/test.sh +++ b/test.sh @@ -3218,19 +3218,13 @@ printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! -sleep 1 +usleep 500000 echo "$da" >>"$ti" sleep 1 kill $bg 2>/dev/null if ! echo "$da" |diff - "$tf" >"$tdiff"; then - if [ -s "$te" ]; then - $PRINTF "$FAILED: $SOCAT:\n" - echo "$CMD" - cat "$te" - else - $PRINTF "$FAILED: diff:\n" - cat "$tdiff" - fi + $PRINTF "$FAILED: diff:\n" + cat "$tdiff" numFAIL=$((numFAIL+1)) else $PRINTF "$OK\n" @@ -3240,7 +3234,7 @@ fi wait esac N=$((N+1)) -#set +vx +set +vx NAME=EXECIGNOREEOF @@ -8152,7 +8146,7 @@ sleep 1 l="$(childprocess $pid1)" rcc=$? kill $pid1 2>/dev/null; wait -if [ $rc2 -ne 0 -o $rcc -ne 0 ]; then +if [ $rc2 -ne 0 ]; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4STREAM numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then @@ -8203,7 +8197,7 @@ sleep 1 l="$(childprocess $pid1)" rcc=$? kill $pid1 2>/dev/null; wait -if [ $rc2 -ne 0 -o $rcc -ne 0 ]; then +if [ $rc2 -ne 0 ]; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then @@ -8415,6 +8409,44 @@ PORT=$((PORT+1)) N=$((N+1)) +# during wait for next poll time option ignoreeof blocked the data transfer in +# the reverse direction +NAME=IGNOREEOFNOBLOCK +case "$TESTS" in +*%functions%*|*%socket%*|*%ignoreeof%*|*%$NAME%*) +TEST="$NAME: ignoreeof does not block other direction" +# have socat poll in ignoreeof mode. while it waits one second for next check, +# we send data in the reverse direction and then the total timeout fires. +# it the data has passed, the test succeeded. +tf="$td/test$N.stout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD0="$SOCAT $opts /dev/null,ignoreeof!!- -!!/dev/null" +printf "test $F_n $TEST... " $N +(usleep 333333; echo "$da") |$CMD0 >"$tf" 2>"${te}0" +rc0=$? +if [ $rc0 != 0 ]; then + $PRINTF "$FAILED\n" + echo "$CMD0 &" + echo "$CMD1" + cat "${te}0" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif echo "$da" |diff - "$tf" >/dev/null; then + $PRINTF "$OK\n" + numOK=$((numOK+1)) +else + $PRINTF "$FAILED\n" + echo "$CMD0 &" + echo "$CMD1" + cat "${te}0" + numFAIL=$((numFAIL+1)) +fi +esac +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then @@ -8437,32 +8469,37 @@ wait exit -# template -NAME=!!! +# test template + +# give a description of what is tested (a bugfix, a new feature...) +NAME=SHORT_UNIQUE_TESTNAME case "$TESTS" in -*%functions%*|*%$NAME%*) -TEST="$NAME: !!!" +*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*) +TEST="$NAME: give a one line description of test" +# describe how the test is performed, and what's the success criteria +tf="$td/test$N.stout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD0="$SOCAT $opts server-address PIPE" +CMD1="$SOCAT - client-address" printf "test $F_n $TEST... " $N -!!! +$CMD0 >/dev/null 2>"${te}0" & +pid0=$! +waitport $xy 1 +echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" +rc1=$? +kill $pid0 2>/dev/null; wait if [ !!! ]; then $PRINTF "$OK\n" + numOK=$((numOK+1)) else $PRINTF "$FAILED\n" - cat "$te" + echo "$CMD0 &" + echo "$CMD1" + cat "${te}0" + cat "${te}1" + numFAIL=$((numFAIL+1)) fi esac N=$((N+1)) - - -TEST="$NAME: transferring from one file to another with echo" -tf1="$td/file$N.input" -tf2="$td/file$N.output" -testecho "$N" "$TEST" "" "echo" "$opts" - - -# MANUAL TESTS - -# ZOMBIES -# have httpd on PORT/tcp -# nice -20 $SOCAT -d tcp-l:24080,fork tcp:$LOCALHOST:PORT -# i=0; while [ $i -lt 100 ]; do $ECHO 'GET / HTTP/1.0\n' |$SOCAT -t -,ignoreeof tcp:$LOCALHOST:24080 >/dev/null& i=$((i+1)); done From d70b8963aa3ebe6e43e7d6a6984f29fb38b084b9 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 19 Sep 2008 09:05:08 +0200 Subject: [PATCH 15/75] replaced // comments with C conforming /* */ --- filan_main.c | 6 +++--- sycls.c | 2 +- sysutils.c | 4 ---- xio-tun.c | 3 ++- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/filan_main.c b/filan_main.c index 3a52f2b..c03f8e2 100644 --- a/filan_main.c +++ b/filan_main.c @@ -127,11 +127,11 @@ int main(int argc, const char *argv[]) { exit(1); } if (outfname) { - // special cases + /* special cases */ if (!strcmp(outfname,"stdin")) { fdout=stdin; } else if (!strcmp(outfname,"stdout")) { fdout=stdout; } else if (!strcmp(outfname,"stderr")) { fdout=stderr; } - // file descriptor + /* file descriptor */ else if (*outfname == '+') { a = outfname+1; fildes = strtoul(a, (char **)&a, 0); @@ -140,7 +140,7 @@ int main(int argc, const char *argv[]) { exit(1); } } else { - // file name + /* file name */ if ((fdout = fopen(outfname, "w")) == NULL) { Error2("can't fopen '%s': %s\n", outfname, strerror(errno)); diff --git a/sycls.c b/sycls.c index fee5bca..347a7cb 100644 --- a/sycls.c +++ b/sycls.c @@ -678,7 +678,7 @@ int Chmod(const char *path, mode_t mode) { int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { int result; if (nfds == 4) { - Debug10("poll({%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}, , %u, %d)", + Debug10("poll({%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}, %u, %d)", ufds[0].fd, ufds[0].events, ufds[1].fd, ufds[1].events, ufds[2].fd, ufds[2].events, ufds[3].fd, ufds[3].events, nfds, timeout); diff --git a/sysutils.c b/sysutils.c index d113e4a..28ccae9 100644 --- a/sysutils.c +++ b/sysutils.c @@ -149,14 +149,10 @@ char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size if (salen > XIOUNIXSOCKOVERHEAD && sa->sa_data[0] == '\0') { char *nextc; -// nextc = -// sanitize_string((char *)&sa->sa_data+1, salen-XIOUNIXSOCKOVERHEAD-1, -// ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); nextc = sanitize_string((char *)&sa->sa_data, salen-XIOUNIXSOCKOVERHEAD, ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); *nextc = '\0'; -// snprintf(cp, blen, "\"\\0%s\"", ubuff); snprintf(cp, blen, "\"%s\"", ubuff); } else #endif /* WITH_ABSTRACT_UNIXSOCKET */ diff --git a/xio-tun.c b/xio-tun.c index c0e87cb..1bc8709 100644 --- a/xio-tun.c +++ b/xio-tun.c @@ -47,13 +47,14 @@ const struct optdesc opt_route = { "route", NULL, O #endif const struct addrdesc xioaddr_tun = { "tun", 3, xioopen_tun, GROUP_FD|GROUP_CHR|GROUP_NAMED|GROUP_OPEN|GROUP_TUN, 0, 0, 0 HELP(":/") }; -// "if-name"=tun3 +/* "if-name"=tun3 // "route"=address/netmask // "ip6-route"=address/netmask // "iff-broadcast" // "iff-debug" // "iff-promisc" // see .../linux/if.h +*/ #if LATER From 2c2508fc62d21a2bc8dd1cbbfd774c1c1cff30ce Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 2 May 2008 18:44:54 +0200 Subject: [PATCH 16/75] added address options: ioctl-void, ioctl-int, ioctl-intp, ioctl-bin, ioctl-string added option types: TYPE_INT_INT, TYPE_INT_BIN, TYPE_INT_STRING added syscall wrapper: Ioctl_int() added test: IOCTL_VOID --- CHANGES | 4 ++ EXAMPLES | 6 +++ VERSION | 2 +- sycls.c | 12 ++++- sycls.h | 4 +- test.sh | 58 +++++++++++++++++++++++ xio-fd.c | 9 +++- xio-fd.h | 7 ++- xio.h | 1 + xiohelp.c | 1 + xioopts.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ xioopts.h | 11 ++++- 12 files changed, 246 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index e78e07a..d61235a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +new features: + added address options IOCTL-VOID, IOCTL-INT, IOCTL-INTP, IOCTL-STRING, + IOCTL-BIN for generic ioctl() calls. + corrections: some raw IP and UNIX datagram modes failed on BSD systems diff --git a/EXAMPLES b/EXAMPLES index 8dc0628..d528e4b 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -285,6 +285,12 @@ $ socat -d -d -d -d - udp-datagram:224.0.0.2:6666,bind=:6666,ip-add-membership=2 // packets leave via wrong interface (set route: ...) // socket bound to specific address +//============================================================================= +// IOCTL + +// open CD drive (given value valid on Linux) +$ socat /dev/cdrom,o-nonblock,ioctl-void=0x5309 - + =============================================================================== // not tested, just ideas, or have problems diff --git a/VERSION b/VERSION index 9a06c88..049994b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+ioctl" diff --git a/sycls.c b/sycls.c index 347a7cb..6e4d37e 100644 --- a/sycls.c +++ b/sycls.c @@ -1,5 +1,5 @@ /* source: sycls.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* explicit system call and C library trace function, for those who miss strace @@ -593,6 +593,16 @@ int Ioctl(int d, int request, void *argp) { return retval; } +int Ioctl_int(int d, int request, int arg) { + int retval, _errno; + Debug3("ioctl(%d, 0x%x, %d)", d, request, arg); + retval = ioctl(d, request, arg); + _errno = errno; + Debug1("ioctl() -> %d", retval); + errno = _errno; + return retval; +} + int Close(int fd) { int retval, _errno; Info1("close(%d)", fd); diff --git a/sycls.h b/sycls.h index 8166d96..4f4d211 100644 --- a/sycls.h +++ b/sycls.h @@ -1,5 +1,5 @@ /* source: sycls.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sycls_h_included @@ -64,6 +64,7 @@ int Ftruncate64(int fd, off64_t length); #endif /* HAVE_FTRUNCATE64 */ int Flock(int fd, int operation); int Ioctl(int d, int request, void *argp); +int Ioctl_int(int d, int request, int arg); int Close(int fd); int Fchown(int fd, uid_t owner, gid_t group); int Fchmod(int fd, mode_t mode); @@ -195,6 +196,7 @@ void Add_history(const char *string); #define Ftruncate64(f,l) ftruncate64(f,l) #define Flock(f,o) flock(f,o) #define Ioctl(d,r,a) ioctl(d,r,a) +#define Ioctl_int(d,r,a) ioctl(d,r,a) #define Close(f) close(f) #define Fchown(f,o,g) fchown(f,o,g) #define Fchmod(f,m) fchmod(f,m) diff --git a/test.sh b/test.sh index 5cbb3ec..7acd059 100755 --- a/test.sh +++ b/test.sh @@ -8447,6 +8447,64 @@ esac N=$((N+1)) +# test the generic ioctl-void option +NAME=IOCTL_VOID +case "$TESTS" in +*%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) +TEST="$NAME: test the ioctl-void option" +# there are not many ioctls that apply to non global resources and do not +# require root. TIOCEXCL seems to fit: +# process 0 provides a pty; +# process 1 opens it with the TIOCEXCL ioctl; +# process 2 opens it too and fails with "device or resource busy" only when the +# previous ioctl was successful +if [ "$UNAME" != Linux ]; then + # we need access to more loopback addresses + $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tp="$td/test$N.pty" +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="$(date)" +CMD0="$SOCAT $opts PTY,LINK=$tp pipe" +CMD1="$SOCAT $opts - file:$tp,ioctl-void=0x540c,raw,echo=0" +CMD2="$SOCAT $opts - file:$tp,raw,echo=0" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" & +pid0=$! +waitfile $tp 1 +(echo "$da"; sleep 2) |$CMD1 >"$tf" 2>"${te}1" & # this should always work +pid1=$! +usleep 1000000 +$CMD2 >/dev/null 2>"${te}2" /dev/null; wait +if ! echo "$da" |diff - "$tf"; then + $PRINTF "${YELLOW}phase 1 failed{NORMAL}\n" + echo "$CMD0 &" + echo "$CMD1" + numCANT=$((numCANT+1)) +elif [ $rc2 -eq 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + echo "$CMD1" + echo "$CMD2" + cat "${te}0" "${te}1" "${te}2" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi + numOK=$((numOK+1)) +fi +fi # !Linux + ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/xio-fd.c b/xio-fd.c index 142e5fe..a982005 100644 --- a/xio-fd.c +++ b/xio-fd.c @@ -1,5 +1,5 @@ /* source: xio-fd.c */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains common file descriptor related option definitions */ @@ -75,3 +75,10 @@ const struct optdesc opt_cool_write = { "cool-write", "coolwrite", OPT_COOL_WRIT /* control closing of connections */ const struct optdesc opt_end_close = { "end-close", "close", OPT_END_CLOSE, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoend, END_CLOSE }; + +/****** generic ioctl() options ******/ +const struct optdesc opt_ioctl_void = { "ioctl-void", "ioctl", OPT_IOCTL_VOID, GROUP_FD, PH_FD, TYPE_INT, OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_ioctl_int = { "ioctl-int", NULL, OPT_IOCTL_INT, GROUP_FD, PH_FD, TYPE_INT_INT, OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_ioctl_intp = { "ioctl-intp", NULL, OPT_IOCTL_INTP, GROUP_FD, PH_FD, TYPE_INT_INT, OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_ioctl_bin = { "ioctl-bin", NULL, OPT_IOCTL_BIN, GROUP_FD, PH_FD, TYPE_INT_BIN, OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_ioctl_string = { "ioctl-string",NULL, OPT_IOCTL_STRING,GROUP_FD, PH_FD, TYPE_INT_STRING,OFUNC_SPEC, 0, 0, 0 }; diff --git a/xio-fd.h b/xio-fd.h index 25b25d0..a301b4e 100644 --- a/xio-fd.h +++ b/xio-fd.h @@ -1,10 +1,15 @@ /* source: xio-fd.h */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_fd_h_included #define __xio_fd_h_included 1 +extern const struct optdesc opt_ioctl_void; +extern const struct optdesc opt_ioctl_int; +extern const struct optdesc opt_ioctl_intp; +extern const struct optdesc opt_ioctl_bin; +extern const struct optdesc opt_ioctl_string; extern const struct optdesc opt_append; extern const struct optdesc opt_nonblock; extern const struct optdesc opt_o_ndelay; diff --git a/xio.h b/xio.h index f5b1926..ddfdd6b 100644 --- a/xio.h +++ b/xio.h @@ -355,6 +355,7 @@ union integral { struct opt { const struct optdesc *desc; union integral value; + union integral value2; } ; extern const char *PIPESEP; diff --git a/xiohelp.c b/xiohelp.c index a994cdb..4ed9323 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -29,6 +29,7 @@ static const char *optiontypenames[] = { "STRUCT-IP_MREQ", #endif "IP4NAME", + "INT:INT", "INT:BIN", "INT:STRING", } ; diff --git a/xioopts.c b/xioopts.c index ad76434..3d7b53e 100644 --- a/xioopts.c +++ b/xioopts.c @@ -583,6 +583,12 @@ const struct optname optionnames[] = { IF_RETRY ("interval", &opt_intervall) IF_RETRY ("intervall", &opt_intervall) IF_TERMIOS("intr", &opt_vintr) + IF_ANY ("ioctl", &opt_ioctl_void) + IF_ANY ("ioctl-bin", &opt_ioctl_bin) + IF_ANY ("ioctl-int", &opt_ioctl_int) + IF_ANY ("ioctl-intp", &opt_ioctl_intp) + IF_ANY ("ioctl-string", &opt_ioctl_string) + IF_ANY ("ioctl-void", &opt_ioctl_void) #ifdef IP_ADD_MEMBERSHIP IF_IP ("ip-add-membership", &opt_ip_add_membership) #endif @@ -1967,6 +1973,71 @@ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, (*opts)[i].value.u_linger.l_linger); break; #endif /* HAVE_STRUCT_LINGER */ + case TYPE_INT_INT: + if (!assign) { + Error1("option \"%s\": values required", a0); + continue; + } + { + char *rest; + (*opts)[i].value.u_int = strtoul(token, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 2 arguments required", + ent->desc->defname); + } + ++rest; + (*opts)[i].value2.u_int = strtoul(rest, &rest, 0); + } + Info3("setting option \"%s\" to %d:%d", ent->desc->defname, + (*opts)[i].value.u_int, (*opts)[i].value2.u_int); + break; + case TYPE_INT_BIN: + if (!assign) { + Error1("option \"%s\": values required", a0); + continue; + } + { + char *rest; + (*opts)[i].value.u_int = strtoul(token, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 2 arguments required", + ent->desc->defname); + } + ++rest; + optlen = 0; + if ((result = dalan(rest, optbuf, &optlen, sizeof(optbuf))) != 0) { + Error1("parseopts(): problem with \"%s\" data", rest); + continue; + } + if (((*opts)[i].value2.u_bin.b_data = memdup(optbuf, optlen)) == NULL) { + Error1("memdup(, "F_Zu"): out of memory", optlen); + return -1; + } + (*opts)[i].value2.u_bin.b_len = optlen; + } + Info2("setting option \"%s\" to %d:..."/*!!!*/, ent->desc->defname, + (*opts)[i].value.u_int); + break; + case TYPE_INT_STRING: + if (!assign) { + Error1("option \"%s\": values required", a0); + continue; + } + { + char *rest; + (*opts)[i].value.u_int = strtoul(token, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 2 arguments required", + ent->desc->defname); + } + ++rest; + if (((*opts)[i].value2.u_string = strdup(token)) == NULL) { + Error("out of memory"); return -1; + } + } + Info3("setting option \"%s\" to %d:\"$s\"", ent->desc->defname, + (*opts)[i].value.u_int, (*opts)[i].value2.u_string); + break; #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) case TYPE_IP_MREQN: { @@ -2998,6 +3069,72 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { } } break; + case OPT_IOCTL_VOID: + switch (opt->desc->type) { + case TYPE_INT: + if (Ioctl(fd, opt->value.u_int, NULL) < 0) { + Error3("ioctl(%d, 0x%x, NULL): %s", + fd, opt->value.u_int, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + default: + Error1("ioctl() data type %d not implemented", opt->desc->type); + } + break; + case OPT_IOCTL_INT: + switch (opt->desc->type) { + case TYPE_INT_INT: + if (Ioctl_int(fd, opt->value.u_int, opt->value2.u_int) < 0) { + Error4("ioctl(%d, %d, %p): %s", + fd, opt->value.u_int, opt->value2.u_int, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + default: + Error1("ioctl() data type %d not implemented", opt->desc->type); + } + break; + case OPT_IOCTL_INTP: + switch (opt->desc->type) { + case TYPE_INT_INT: + if (Ioctl(fd, opt->value.u_int, (void *)&opt->value2.u_int) < 0) { + Error4("ioctl(%d, 0x%x, %p): %s", + fd, opt->value.u_int, (void *)&opt->value2.u_int, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + default: + Error1("ioctl() data type %d not implemented", opt->desc->type); + } + break; + case OPT_IOCTL_BIN: + switch (opt->desc->type) { + case TYPE_INT_BIN: + if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data) < 0) { + Error4("ioctl(%d, 0x%x, %p): %s", + fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + default: + Error1("ioctl() data type %d not implemented", opt->desc->type); + } + break; + case OPT_IOCTL_STRING: + switch (opt->desc->type) { + case TYPE_INT_STRING: + if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_string) < 0) { + Error4("ioctl(%d, 0x%x, %p): %s", + fd, opt->value.u_int, (void *)opt->value2.u_string, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + default: + Error1("ioctl() data type %d not implemented", opt->desc->type); + } + break; + default: Error1("applyopts(): option \"%s\" not implemented", opt->desc->defname); opt->desc = ODESC_ERROR; ++opt; continue; diff --git a/xioopts.h b/xioopts.h index 849cb46..0981e45 100644 --- a/xioopts.h +++ b/xioopts.h @@ -53,6 +53,9 @@ enum e_types { TYPE_IP_MREQN, /* for struct ip_mreq or struct ip_mreqn */ #endif TYPE_IP4NAME, /* IPv4 hostname or address */ + TYPE_INT_INT, /* 2 parameters: first is int, second is int */ + TYPE_INT_BIN, /* 2 parameters: first is int, second is binary */ + TYPE_INT_STRING, /* 2 parameters: first is int, second is req string */ TYPE_2BYTE = TYPE_USHORT } ; @@ -64,7 +67,8 @@ enum e_func { OFUNC_SEEK32, /* lseek(): arg1 is whence (SEEK_SET etc.) */ OFUNC_SEEK64, /* lseek64(): arg1 is whence (SEEK_SET etc.) */ OFUNC_FCNTL, /* fcntl(, ): arg1 is cmd */ - OFUNC_IOCTL, /* ioctl(): arg1 is request */ + OFUNC_IOCTL, /* ioctl(): arg1 of option description is request, arg2 + is int setrequest */ OFUNC_IOCTL_MASK_LONG, /* arg1 is getrequest, arg2 is setrequest: ioctl(arg1, ); |= arg3; ioctl(arg2, ); */ OFUNC_SOCKOPT, /* setsockopt() */ @@ -329,6 +333,11 @@ enum e_optcode { #if 0 /* see Linux: man 7 netlink; probably not what we need yet */ OPT_IO_SIOCGIFNAME, #endif + OPT_IOCTL_BIN, /* generic ioctl with binary value (pointed to) */ + OPT_IOCTL_INT, /* generic ioctl with integer value */ + OPT_IOCTL_INTP, /* generic ioctl with integer value (pointed to) */ + OPT_IOCTL_STRING, /* generic ioctl with integer value (pointed to) */ + OPT_IOCTL_VOID, /* generic ioctl without value */ OPT_IP_ADD_MEMBERSHIP, #ifdef IP_HDRINCL OPT_IP_HDRINCL, From 52be3b085e1834c8fd426036e903010c06e98028 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 2 May 2008 21:17:05 +0200 Subject: [PATCH 17/75] doc for ioctl options --- doc/socat.yo | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/doc/socat.yo b/doc/socat.yo index 4befd5b..556aaeb 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1264,6 +1264,24 @@ label(OPTION_END_CLOSE)dit(bf(tt(end-close))) Similarly, when an address of type EXEC or SYSTEM is ended, socat usually will explicitely kill the sub process. With this option, it will just close the file descriptors. +label(OPTION_IOCTL_VOID)dit(bf(tt(ioctl-void=))) + Calls tt(ioctl()) with the request value as second argument and NULL as + third argument. This option allows to utilize ioctls that are not + explicitely implemented in socat. +label(OPTION_IOCTL_INT)dit(bf(tt(ioctl-int=:))) + Calls tt(ioctl()) with the request value as second argument and the integer + value as third argument. +label(OPTION_IOCTL_INTP)dit(bf(tt(ioctl-intp=:))) + Calls tt(ioctl()) with the request value as second argument and a pointer to + the integer value as third argument. +label(OPTION_IOCTL_BIN)dit(bf(tt(ioctl-bin=:))) + Calls tt(ioctl()) with the request value as second argument and a pointer to + the given data value as third argument. This data must be specified in + link()(TYPE_DATA) form. +label(OPTION_IOCTL_STRING)dit(bf(tt(ioctl-string=:))) + Calls tt(ioctl()) with the request value as second argument and a pointer to + the given string as third argument. + link()(TYPE_DATA) form. enddit() startdit()enddit()nl() @@ -2413,8 +2431,9 @@ label(TYPE_COMMAND_LINE)dit(command-line) A string specifying a program name and its arguments, separated by single spaces. label(TYPE_DATA)dit(data) - A raw data specification following em(dalan) syntax. The only documented - form is a string starting with 'x' followed by an even number of hex digits. + A raw data specification following em(dalan) syntax. Currently the only + valid form is a string starting with 'x' followed by an even number of hex + digits, specifying a sequence of bytes. label(TYPE_DIRECTORY)dit(directory) A string with usual unix() directory name semantics. label(TYPE_FACILITY)dit(facility) From 140443794b17c9b1f4acb49f4227a9baebe6a800 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 3 May 2008 21:44:48 +0200 Subject: [PATCH 18/75] add generic setsockopt address options --- CHANGES | 7 ++- EXAMPLES | 20 +++++++- VERSION | 2 +- doc/socat.yo | 16 ++++++ xio-socket.c | 6 +++ xio-socket.h | 3 ++ xio.h | 1 + xioopts.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++- xioopts.h | 6 +++ 9 files changed, 192 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index d61235a..8b50c67 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,10 @@ new features: - added address options IOCTL-VOID, IOCTL-INT, IOCTL-INTP, IOCTL-STRING, - IOCTL-BIN for generic ioctl() calls. + added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string, + ioctl-bin for generic ioctl() calls. + + added address options setsockopt-int, setsockopt-bin, and + setsockopt-string corrections: some raw IP and UNIX datagram modes failed on BSD systems diff --git a/EXAMPLES b/EXAMPLES index d528e4b..60ca020 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -286,11 +286,27 @@ $ socat -d -d -d -d - udp-datagram:224.0.0.2:6666,bind=:6666,ip-add-membership=2 // socket bound to specific address //============================================================================= -// IOCTL +// GENERIC FUNCTION CALLS -// open CD drive (given value valid on Linux) +// ioctl(): open CD drive (given value valid on Linux) +// on my Linux system I find in /usr/include/linux/cdrom.h the define: +// #define CDROMEJECT 0x5309 /* Ejects the cdrom media */ +// the following command makes something like ioctl(fd, CDROMEJECT, NULL) $ socat /dev/cdrom,o-nonblock,ioctl-void=0x5309 - +// setsockopt(): SO_REUSEADDR +// the following command performs - beyond lots of overhead - something like: +// myint=1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &myint, sizeof(myint)) +$ socat -u udp-recv:7777,setsockopt-int=1:2:1 - +// setsockopt(): SO_BINDTODEVICE + +// ways to apply SO_BINDTODEVICE without using the special socat address option +// so-bindtodevice: +// with string argument: +$ sudo ./socat tcp-l:7777,setsockopt-string=1:25:eth0 pipe +// with binary argument: +$ sudo ./socat tcp-l:7777,setsockopt-bin=1:25:x6574683000 pipe + =============================================================================== // not tested, just ideas, or have problems diff --git a/VERSION b/VERSION index 049994b..0b595f8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+ioctl" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+ioctl+ioctl+setsockopt" diff --git a/doc/socat.yo b/doc/socat.yo index 556aaeb..4df8cd2 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1653,6 +1653,22 @@ COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs))) label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=))) Forces the use of the specified IP version. can be something like "ip4" or "ip6". +label(OPTION_SETSOCKOPT_INT)dit(bf(tt(setsockopt-int=::))) + Invokes tt(setsockopt()) for the socket with the given parameters. tt(level) + [link(int)(TYPE_INT)] specifies the second argument to tt(setsockopt()) + which specifies the layer, e.g. SOL_TCP (=6 on Linux) for TCP, or SOL_SOCKET + (=1 on Linux) for the socket layer. tt(optname) [link(int)(TYPE_INT)] + selects the third argument to tt(setsockopt()) option. For the actual + integer values you might have to look up the appropriate include file of + your system. The 4th tt(setsockopt()) parameter, tt(value) + [link(int)(TYPE_INT)], is passed to the function per pointer, and the length + parameter to the tt(setsockopt()) call is derived from this type. +label(OPTION_SETSOCKOPT_BIN)dit(bf(tt(setsockopt-bin=::))) + Like tt(setsockopt-int), but is expected in link(dalan)(TYPE_DATA) + format and specifies an arbitrary sequence of bytes. +label(OPTION_SETSOCKOPT_STRING)dit(bf(tt(setsockopt-string=::))) + Like tt(setsockopt-int), but must be a link(string)(TYPE_STRING). + This string is passed to the function with trailing null character. enddit() startdit()enddit()nl() diff --git a/xio-socket.c b/xio-socket.c index d93bb98..5399967 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -128,6 +128,12 @@ const struct optdesc opt_bind = { "bind", NULL, OPT_BIND, GRO const struct optdesc opt_connect_timeout = { "connect-timeout", NULL, OPT_CONNECT_TIMEOUT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_TIMEVAL, OFUNC_OFFSET, (int)&((xiofile_t *)0)->stream.para.socket.connect_timeout }; const struct optdesc opt_protocol_family = { "protocol-family", "pf", OPT_PROTOCOL_FAMILY, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC }; +/* generic setsockopt() options */ +const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int", OPT_SETSOCKOPT_INT, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_INT, OFUNC_SPEC, 0, 0 }; +const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_BIN, OFUNC_SPEC, 0, 0 }; +const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_STRING, OFUNC_SPEC, 0, 0 }; + + /* a subroutine that is common to all socket addresses that want to connect to a peer address. might fork. diff --git a/xio-socket.h b/xio-socket.h index 04734f9..4947ead 100644 --- a/xio-socket.h +++ b/xio-socket.h @@ -50,6 +50,9 @@ extern const struct optdesc opt_fiosetown; extern const struct optdesc opt_siocspgrp; extern const struct optdesc opt_bind; extern const struct optdesc opt_protocol_family; +extern const struct optdesc opt_setsockopt_int; +extern const struct optdesc opt_setsockopt_bin; +extern const struct optdesc opt_setsockopt_string; extern int retropt_socket_pf(struct opt *opts, int *pf); diff --git a/xio.h b/xio.h index ddfdd6b..4dc1464 100644 --- a/xio.h +++ b/xio.h @@ -356,6 +356,7 @@ struct opt { const struct optdesc *desc; union integral value; union integral value2; + union integral value3; } ; extern const char *PIPESEP; diff --git a/xioopts.c b/xioopts.c index 3d7b53e..f843da2 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1196,6 +1196,9 @@ const struct optname optionnames[] = { #if WITH_EXEC || WITH_SYSTEM IF_EXEC ("setsid", &opt_setsid) #endif + IF_SOCKET ("setsockopt-bin", &opt_setsockopt_bin) + IF_SOCKET ("setsockopt-int", &opt_setsockopt_int) + IF_SOCKET ("setsockopt-string", &opt_setsockopt_string) IF_ANY ("setuid", &opt_setuid) IF_ANY ("setuid-early", &opt_setuid_early) #if WITH_EXEC || WITH_SYSTEM @@ -2031,13 +2034,97 @@ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, ent->desc->defname); } ++rest; - if (((*opts)[i].value2.u_string = strdup(token)) == NULL) { + if (((*opts)[i].value2.u_string = strdup(rest)) == NULL) { Error("out of memory"); return -1; } } - Info3("setting option \"%s\" to %d:\"$s\"", ent->desc->defname, + Info3("setting option \"%s\" to %d:\"%s\"", ent->desc->defname, (*opts)[i].value.u_int, (*opts)[i].value2.u_string); break; + case TYPE_INT_INT_INT: + if (!assign) { + Error1("option \"%s\": values required", a0); + continue; + } + { + char *rest; + (*opts)[i].value.u_int = strtoul(token, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 3 arguments required", + ent->desc->defname); + } + ++rest; + (*opts)[i].value2.u_int = strtoul(rest, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 3 arguments required", + ent->desc->defname); + } + ++rest; + (*opts)[i].value3.u_int = strtoul(rest, &rest, 0); + } + Info4("setting option \"%s\" to %d:%d:%d", ent->desc->defname, + (*opts)[i].value.u_int, (*opts)[i].value2.u_int, (*opts)[i].value3.u_int); + break; + case TYPE_INT_INT_BIN: + if (!assign) { + Error1("option \"%s\": values required", a0); + continue; + } + { + char *rest; + (*opts)[i].value.u_int = strtoul(token, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 3 arguments required", + ent->desc->defname); + } + ++rest; + (*opts)[i].value2.u_int = strtoul(rest, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 3 arguments required", + ent->desc->defname); + } + ++rest; + optlen = 0; + if ((result = dalan(rest, optbuf, &optlen, sizeof(optbuf))) != 0) { + Error1("parseopts(): problem with \"%s\" data", rest); + continue; + } + if (((*opts)[i].value3.u_bin.b_data = memdup(optbuf, optlen)) == NULL) { + Error1("memdup(, "F_Zu"): out of memory", optlen); + return -1; + } + (*opts)[i].value3.u_bin.b_len = optlen; + } + Info3("setting option \"%s\" to %d:%d:..."/*!!!*/, ent->desc->defname, + (*opts)[i].value.u_int, (*opts)[i].value2.u_int); + break; + case TYPE_INT_INT_STRING: + if (!assign) { + Error1("option \"%s\": values required", a0); + continue; + } + { + char *rest; + (*opts)[i].value.u_int = strtoul(token, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 3 arguments required", + ent->desc->defname); + } + ++rest; + (*opts)[i].value2.u_int = strtoul(rest, &rest, 0); + if (*rest != ':') { + Error1("option \"%s\": 3 arguments required", + ent->desc->defname); + } + ++rest; + if (((*opts)[i].value3.u_string = strdup(rest)) == NULL) { + Error("out of memory"); return -1; + } + } + Info4("setting option \"%s\" to %d:%d:\"%s\"", ent->desc->defname, + (*opts)[i].value.u_int, (*opts)[i].value2.u_int, + (*opts)[i].value3.u_int); + break; #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) case TYPE_IP_MREQN: { @@ -3134,6 +3221,53 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { Error1("ioctl() data type %d not implemented", opt->desc->type); } break; + case OPT_SETSOCKOPT_INT: + switch (opt->desc->type) { + case TYPE_INT_INT_INT: + if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, + &opt->value3.u_int, sizeof(int)) < 0) { + Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s", + fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_int, sizeof(int), strerror(errno)); + } + break; + default: + Error1("setsockopt() data type %d not implemented", + opt->desc->type); + } + break; + case OPT_SETSOCKOPT_BIN: + switch (opt->desc->type) { + case TYPE_INT_INT_BIN: + if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_bin.b_data, opt->value3.u_bin.b_len) < 0) { + Error5("setsockopt(%d, %d, %d, {...}, "F_Zu"): %s", + fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_bin.b_len, strerror(errno)); + } + break; + default: + Error1("setsockopt() data type %d not implemented", + opt->desc->type); + } + break; + case OPT_SETSOCKOPT_STRING: + switch (opt->desc->type) { + case TYPE_INT_INT_STRING: + if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_string, + strlen(opt->value3.u_string)+1) < 0) { + Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s", + fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_string, strlen(opt->value3.u_string)+1, + strerror(errno)); + } + break; + default: + Error1("setsockopt() data type %d not implemented", + opt->desc->type); + } + break; default: Error1("applyopts(): option \"%s\" not implemented", opt->desc->defname); diff --git a/xioopts.h b/xioopts.h index 0981e45..d6d9f59 100644 --- a/xioopts.h +++ b/xioopts.h @@ -56,6 +56,9 @@ enum e_types { TYPE_INT_INT, /* 2 parameters: first is int, second is int */ TYPE_INT_BIN, /* 2 parameters: first is int, second is binary */ TYPE_INT_STRING, /* 2 parameters: first is int, second is req string */ + TYPE_INT_INT_INT, /* 3 params: first and second are int, 3rd is int */ + TYPE_INT_INT_BIN, /* 3 params: first and second are int, 3rd is binary */ + TYPE_INT_INT_STRING, /* 3 params: first and second are int, 3rd is string */ TYPE_2BYTE = TYPE_USHORT } ; @@ -542,6 +545,9 @@ enum e_optcode { OPT_SETGID_EARLY, OPT_SETPGID, OPT_SETSID, + OPT_SETSOCKOPT_BIN, + OPT_SETSOCKOPT_INT, + OPT_SETSOCKOPT_STRING, OPT_SETUID, OPT_SETUID_EARLY, OPT_SIGHUP, From 8947cc92dc2dc37cb5a4041efe11733ab36a1a20 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 12 Aug 2008 07:30:10 +0200 Subject: [PATCH 19/75] added test SETSOCKOPT_INT; some corrections on generic ioctl and setsockopt features --- test.sh | 76 +++++++++++++++++++- xio-fd.c | 10 +-- xio-socket.c | 6 +- xio-socket.h | 2 +- xiohelp.c | 3 +- xioopts.c | 191 +++++++++++++++++++++------------------------------ xioopts.h | 26 ++++--- 7 files changed, 180 insertions(+), 134 deletions(-) diff --git a/test.sh b/test.sh index 7acd059..dee3739 100755 --- a/test.sh +++ b/test.sh @@ -8450,7 +8450,7 @@ N=$((N+1)) # test the generic ioctl-void option NAME=IOCTL_VOID case "$TESTS" in -*%functions%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) +*%functions%*|*%pty%*|*%generic%*|*%$NAME%*) TEST="$NAME: test the ioctl-void option" # there are not many ioctls that apply to non global resources and do not # require root. TIOCEXCL seems to fit: @@ -8459,7 +8459,7 @@ TEST="$NAME: test the ioctl-void option" # process 2 opens it too and fails with "device or resource busy" only when the # previous ioctl was successful if [ "$UNAME" != Linux ]; then - # we need access to more loopback addresses + # we use the numeric value of TIOCEXL which is system dependent $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8482,7 +8482,7 @@ $CMD2 >/dev/null 2>"${te}2" /dev/null; wait if ! echo "$da" |diff - "$tf"; then - $PRINTF "${YELLOW}phase 1 failed{NORMAL}\n" + $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" echo "$CMD0 &" echo "$CMD1" numCANT=$((numCANT+1)) @@ -8501,6 +8501,76 @@ fi fi # !Linux ;; esac +N=$((N+1)) + + +# test the generic setsockopt-int option +NAME=SETSOCKOPT_INT +case "$TESTS" in +*%functions%*|*%ip4%*|*%tcp%*|*%generic%*|*%$NAME%*) +TEST="$NAME: test the setsockopt-int option" +# there are not many socket options that apply to non global resources, do not +# require root, do not require a network connection, and can easily be +# tested. SO_REUSEADDR seems to fit: +# process 0 provides a tcp listening socket with reuseaddr; +# process 1 connects to this port; thus the port is connected but no longer +# listening +# process 2 tries to listen on this port with SO_REUSEADDR, will fail if the +# (generically specified) SO_REUSEADDR socket options did not work +# process 3 connects to this port; only if it is successful the test is ok +if [ "$UNAME" != Linux ]; then + # we use the numeric value of SO_REUSEADDR which might be system dependent + $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tp="$PORT" +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="$(date)" +# level=SOL_SOCKET=1, optname=SO_REUSEADDR=2, value=1 +CMD0="$SOCAT $opts TCP4-L:$tp,setsockopt-int=1:2:1 PIPE" +CMD1="$SOCAT $opts - TCP:localhost:$tp" +CMD2="$CMD0" +CMD3="$CMD1" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" & +pid0=$! +waittcp4port $tp 1 +(echo "$da"; sleep 3) |$CMD1 >"$tf" 2>"${te}1" & # this should always work +pid1=$! +usleep 1000000 +$CMD2 >/dev/null 2>"${te}2" & +pid2=$! +waittcp4port $tp 1 +(echo "$da") |$CMD3 >"${tf}3" 2>"${te}3" +rc3=$? +kill $pid0 $pid1 $pid2 2>/dev/null; wait +if ! echo "$da" |diff - "$tf"; then + $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" + echo "$CMD0 &" + echo "$CMD1" + numCANT=$((numCANT+1)) +elif [ $rc3 -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD2 &" + echo "$CMD3" + cat "${te}2" "${te}3" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "${tf}3"; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD2 &" + echo "$CMD3" + echo "$da" |diff - "${tf}3" + numCANT=$((numCANT+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi + numOK=$((numOK+1)) +fi +fi # !Linux + ;; +esac PORT=$((PORT+1)) N=$((N+1)) diff --git a/xio-fd.c b/xio-fd.c index a982005..9fc1d57 100644 --- a/xio-fd.c +++ b/xio-fd.c @@ -77,8 +77,8 @@ const struct optdesc opt_cool_write = { "cool-write", "coolwrite", OPT_COOL_WRIT const struct optdesc opt_end_close = { "end-close", "close", OPT_END_CLOSE, GROUP_FD, PH_INIT, TYPE_CONST, OFUNC_OFFSET, (bool)&((xiofile_t *)0)->stream.howtoend, END_CLOSE }; /****** generic ioctl() options ******/ -const struct optdesc opt_ioctl_void = { "ioctl-void", "ioctl", OPT_IOCTL_VOID, GROUP_FD, PH_FD, TYPE_INT, OFUNC_SPEC, 0, 0, 0 }; -const struct optdesc opt_ioctl_int = { "ioctl-int", NULL, OPT_IOCTL_INT, GROUP_FD, PH_FD, TYPE_INT_INT, OFUNC_SPEC, 0, 0, 0 }; -const struct optdesc opt_ioctl_intp = { "ioctl-intp", NULL, OPT_IOCTL_INTP, GROUP_FD, PH_FD, TYPE_INT_INT, OFUNC_SPEC, 0, 0, 0 }; -const struct optdesc opt_ioctl_bin = { "ioctl-bin", NULL, OPT_IOCTL_BIN, GROUP_FD, PH_FD, TYPE_INT_BIN, OFUNC_SPEC, 0, 0, 0 }; -const struct optdesc opt_ioctl_string = { "ioctl-string",NULL, OPT_IOCTL_STRING,GROUP_FD, PH_FD, TYPE_INT_STRING,OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_ioctl_void = { "ioctl-void", "ioctl", OPT_IOCTL_VOID, GROUP_FD, PH_FD, TYPE_INT, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; +const struct optdesc opt_ioctl_int = { "ioctl-int", NULL, OPT_IOCTL_INT, GROUP_FD, PH_FD, TYPE_INT_INT, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; +const struct optdesc opt_ioctl_intp = { "ioctl-intp", NULL, OPT_IOCTL_INTP, GROUP_FD, PH_FD, TYPE_INT_INTP, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; +const struct optdesc opt_ioctl_bin = { "ioctl-bin", NULL, OPT_IOCTL_BIN, GROUP_FD, PH_FD, TYPE_INT_BIN, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; +const struct optdesc opt_ioctl_string = { "ioctl-string",NULL, OPT_IOCTL_STRING,GROUP_FD, PH_FD, TYPE_INT_STRING,OFUNC_IOCTL_GENERIC, 0, 0, 0 }; diff --git a/xio-socket.c b/xio-socket.c index 5399967..2bb3b47 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -129,9 +129,9 @@ const struct optdesc opt_connect_timeout = { "connect-timeout", NULL, OPT_CONNEC const struct optdesc opt_protocol_family = { "protocol-family", "pf", OPT_PROTOCOL_FAMILY, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC }; /* generic setsockopt() options */ -const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int", OPT_SETSOCKOPT_INT, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_INT, OFUNC_SPEC, 0, 0 }; -const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_BIN, OFUNC_SPEC, 0, 0 }; -const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_STRING, OFUNC_SPEC, 0, 0 }; +const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int", OPT_SETSOCKOPT_INT, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_INT, OFUNC_SOCKOPT_GENERIC, 0, 0 }; +const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; +const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_STRING, OFUNC_SOCKOPT_GENERIC, 0, 0 }; /* a subroutine that is common to all socket addresses that want to connect diff --git a/xio-socket.h b/xio-socket.h index 4947ead..5a68920 100644 --- a/xio-socket.h +++ b/xio-socket.h @@ -1,5 +1,5 @@ /* source: xio-socket.h */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_socket_h_included diff --git a/xiohelp.c b/xiohelp.c index 4ed9323..b37115b 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -29,7 +29,8 @@ static const char *optiontypenames[] = { "STRUCT-IP_MREQ", #endif "IP4NAME", - "INT:INT", "INT:BIN", "INT:STRING", + "INT:INT", "INT:INTP", "INT:BIN", "INT:STRING", + "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING", } ; diff --git a/xioopts.c b/xioopts.c index f843da2..4022ca2 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1313,6 +1313,9 @@ const struct optname optionnames[] = { #ifdef SO_USELOOPBACK /* AIX433, Solaris */ IF_SOCKET ("so-useloopback", &opt_so_useloopback) #endif /* SO_USELOOPBACK */ + IF_SOCKET ("sockopt-bin", &opt_setsockopt_bin) + IF_SOCKET ("sockopt-int", &opt_setsockopt_int) + IF_SOCKET ("sockopt-string", &opt_setsockopt_string) IF_SOCKS4 ("socksport", &opt_socksport) IF_SOCKS4 ("socksuser", &opt_socksuser) IF_IPAPP ("sourceport", &opt_sourceport) @@ -2761,6 +2764,48 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { opt->desc = ODESC_ERROR; ++opt; continue; } + } else if (opt->desc->func == OFUNC_IOCTL_GENERIC) { + switch (opt->desc->type) { + case TYPE_INT: + if (Ioctl(fd, opt->value.u_int, NULL) < 0) { + Error3("ioctl(%d, 0x%x, NULL): %s", + fd, opt->value.u_int, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + case TYPE_INT_INT: + if (Ioctl_int(fd, opt->value.u_int, opt->value2.u_int) < 0) { + Error4("ioctl(%d, %d, %p): %s", + fd, opt->value.u_int, opt->value2.u_int, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + case TYPE_INT_INTP: + if (Ioctl(fd, opt->value.u_int, (void *)&opt->value2.u_int) < 0) { + Error4("ioctl(%d, 0x%x, %p): %s", + fd, opt->value.u_int, (void *)&opt->value2.u_int, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + case TYPE_INT_BIN: + if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data) < 0) { + Error4("ioctl(%d, 0x%x, %p): %s", + fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + case TYPE_INT_STRING: + if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_string) < 0) { + Error4("ioctl(%d, 0x%x, %p): %s", + fd, opt->value.u_int, (void *)opt->value2.u_string, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } + break; + default: + Error1("ioctl() data type %d not implemented", + opt->desc->type); + } + #if WITH_SOCKET } else if (opt->desc->func == OFUNC_SOCKOPT) { if (0) { @@ -2938,6 +2983,38 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { opt->desc->defname, opt->desc->type); break; } + } else if (opt->desc->func == OFUNC_SOCKOPT_GENERIC) { + switch (opt->desc->type) { + case TYPE_INT_INT_INT: + if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, + &opt->value3.u_int, sizeof(int)) < 0) { + Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s", + fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_int, sizeof(int), strerror(errno)); + } + break; + case TYPE_INT_INT_BIN: + if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_bin.b_data, opt->value3.u_bin.b_len) < 0) { + Error5("setsockopt(%d, %d, %d, {...}, "F_Zu"): %s", + fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_bin.b_len, strerror(errno)); + } + break; + case TYPE_INT_INT_STRING: + if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_string, + strlen(opt->value3.u_string)+1) < 0) { + Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s", + fd, opt->value.u_int, opt->value2.u_int, + opt->value3.u_string, strlen(opt->value3.u_string)+1, + strerror(errno)); + } + break; + default: + Error1("setsockopt() data type %d not implemented", + opt->desc->type); + } #endif /* WITH_SOCKET */ #if HAVE_FLOCK @@ -3156,119 +3233,7 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { } } break; - case OPT_IOCTL_VOID: - switch (opt->desc->type) { - case TYPE_INT: - if (Ioctl(fd, opt->value.u_int, NULL) < 0) { - Error3("ioctl(%d, 0x%x, NULL): %s", - fd, opt->value.u_int, strerror(errno)); - opt->desc = ODESC_ERROR; ++opt; continue; - } - break; - default: - Error1("ioctl() data type %d not implemented", opt->desc->type); - } - break; - case OPT_IOCTL_INT: - switch (opt->desc->type) { - case TYPE_INT_INT: - if (Ioctl_int(fd, opt->value.u_int, opt->value2.u_int) < 0) { - Error4("ioctl(%d, %d, %p): %s", - fd, opt->value.u_int, opt->value2.u_int, strerror(errno)); - opt->desc = ODESC_ERROR; ++opt; continue; - } - break; - default: - Error1("ioctl() data type %d not implemented", opt->desc->type); - } - break; - case OPT_IOCTL_INTP: - switch (opt->desc->type) { - case TYPE_INT_INT: - if (Ioctl(fd, opt->value.u_int, (void *)&opt->value2.u_int) < 0) { - Error4("ioctl(%d, 0x%x, %p): %s", - fd, opt->value.u_int, (void *)&opt->value2.u_int, strerror(errno)); - opt->desc = ODESC_ERROR; ++opt; continue; - } - break; - default: - Error1("ioctl() data type %d not implemented", opt->desc->type); - } - break; - case OPT_IOCTL_BIN: - switch (opt->desc->type) { - case TYPE_INT_BIN: - if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data) < 0) { - Error4("ioctl(%d, 0x%x, %p): %s", - fd, opt->value.u_int, (void *)opt->value2.u_bin.b_data, strerror(errno)); - opt->desc = ODESC_ERROR; ++opt; continue; - } - break; - default: - Error1("ioctl() data type %d not implemented", opt->desc->type); - } - break; - case OPT_IOCTL_STRING: - switch (opt->desc->type) { - case TYPE_INT_STRING: - if (Ioctl(fd, opt->value.u_int, (void *)opt->value2.u_string) < 0) { - Error4("ioctl(%d, 0x%x, %p): %s", - fd, opt->value.u_int, (void *)opt->value2.u_string, strerror(errno)); - opt->desc = ODESC_ERROR; ++opt; continue; - } - break; - default: - Error1("ioctl() data type %d not implemented", opt->desc->type); - } - break; - case OPT_SETSOCKOPT_INT: - switch (opt->desc->type) { - case TYPE_INT_INT_INT: - if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, - &opt->value3.u_int, sizeof(int)) < 0) { - Error6("setsockopt(%d, %d, %d, {%d}, "F_Zu"): %s", - fd, opt->value.u_int, opt->value2.u_int, - opt->value3.u_int, sizeof(int), strerror(errno)); - } - break; - default: - Error1("setsockopt() data type %d not implemented", - opt->desc->type); - } - break; - case OPT_SETSOCKOPT_BIN: - switch (opt->desc->type) { - case TYPE_INT_INT_BIN: - if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, - opt->value3.u_bin.b_data, opt->value3.u_bin.b_len) < 0) { - Error5("setsockopt(%d, %d, %d, {...}, "F_Zu"): %s", - fd, opt->value.u_int, opt->value2.u_int, - opt->value3.u_bin.b_len, strerror(errno)); - } - break; - default: - Error1("setsockopt() data type %d not implemented", - opt->desc->type); - } - break; - case OPT_SETSOCKOPT_STRING: - switch (opt->desc->type) { - case TYPE_INT_INT_STRING: - if (Setsockopt(fd, opt->value.u_int, opt->value2.u_int, - opt->value3.u_string, - strlen(opt->value3.u_string)+1) < 0) { - Error6("setsockopt(%d, %d, %d, \"%s\", "F_Zu"): %s", - fd, opt->value.u_int, opt->value2.u_int, - opt->value3.u_string, strlen(opt->value3.u_string)+1, - strerror(errno)); - } - break; - default: - Error1("setsockopt() data type %d not implemented", - opt->desc->type); - } - break; - + default: Error1("applyopts(): option \"%s\" not implemented", opt->desc->defname); opt->desc = ODESC_ERROR; ++opt; continue; diff --git a/xioopts.h b/xioopts.h index d6d9f59..db78829 100644 --- a/xioopts.h +++ b/xioopts.h @@ -22,45 +22,53 @@ enum e_types { TYPE_BIN, /* raw binary data, length determined by data */ TYPE_BOOL, /* value is 0 or 1 (no-value is interpreted as 1) */ TYPE_BYTE, /* unsigned char */ + TYPE_INT, /* int */ TYPE_LONG, /* long */ TYPE_STRING, /* char * */ TYPE_NAME = TYPE_STRING, TYPE_FILENAME = TYPE_STRING, TYPE_PTRDIFF, /* ptrdiff_t */ + TYPE_SHORT, /* short */ TYPE_SIZE_T, /* size_t */ TYPE_SOCKADDR, /* struct sockaddr * */ TYPE_UINT, /* unsigned int */ + TYPE_ULONG, /* unsigned long */ TYPE_USHORT, /* unsigned short */ + TYPE_2BYTE = TYPE_USHORT, TYPE_MODET, /* representation of mode_t */ TYPE_GIDT, /* representation of gid_t */ + TYPE_UIDT, /* representation of uid_t */ /*TYPE_FLAG,*/ TYPE_INT3, /* int[3] */ TYPE_TIMEVAL, /* struct timeval: {long;long;}, seconds and microsec. */ TYPE_TIMESPEC, /* struct timespec: {time_t;long;}, seconds and nanosec. */ -#if HAVE_STRUCT_LINGER - TYPE_LINGER, /* struct linger */ -#endif /* HAVE_STRUCT_LINGER */ + TYPE_DOUBLE, /* double */ TYPE_STRING_NULL, /* char *; string or NULL */ TYPE_LONGLONG, /* long long */ TYPE_OFF32, /* off_t */ + TYPE_OFF64, /* off64_t */ -#if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN - TYPE_IP_MREQN, /* for struct ip_mreq or struct ip_mreqn */ -#endif - TYPE_IP4NAME, /* IPv4 hostname or address */ TYPE_INT_INT, /* 2 parameters: first is int, second is int */ + TYPE_INT_INTP, /* 2 parameters: first is int, second is int* */ TYPE_INT_BIN, /* 2 parameters: first is int, second is binary */ + TYPE_INT_STRING, /* 2 parameters: first is int, second is req string */ TYPE_INT_INT_INT, /* 3 params: first and second are int, 3rd is int */ TYPE_INT_INT_BIN, /* 3 params: first and second are int, 3rd is binary */ TYPE_INT_INT_STRING, /* 3 params: first and second are int, 3rd is string */ - TYPE_2BYTE = TYPE_USHORT + TYPE_IP4NAME, /* IPv4 hostname or address */ +#if HAVE_STRUCT_LINGER + TYPE_LINGER, /* struct linger */ +#endif /* HAVE_STRUCT_LINGER */ +#if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN + TYPE_IP_MREQN, /* for struct ip_mreq or struct ip_mreqn */ +#endif } ; enum e_func { @@ -74,8 +82,10 @@ enum e_func { is int setrequest */ OFUNC_IOCTL_MASK_LONG, /* arg1 is getrequest, arg2 is setrequest: ioctl(arg1, ); |= arg3; ioctl(arg2, ); */ + OFUNC_IOCTL_GENERIC, /* generic ioctl() (request on cmdline) */ OFUNC_SOCKOPT, /* setsockopt() */ OFUNC_SOCKOPT_APPEND,/* getsockopt(), append data, setsockopt() */ + OFUNC_SOCKOPT_GENERIC,/* generic setsockopt() (level, optname on cmdline) */ OFUNC_FLOCK, /* flock() */ OFUNC_TERMIO, /* termio() ? */ OFUNC_SPEC, /* special, i.e. no generalizable function call */ From 13b73776e7547c393f52ce1ffc41fffabddba4f6 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 17 Aug 2008 23:28:11 +0200 Subject: [PATCH 20/75] ported generic socket to *BSD; minor improvements --- CHANGES | 5 + VERSION | 2 +- config.h.in | 1 + configure.in | 8 + dalan.c | 1 + doc/socat.yo | 138 ++++++++++ fdname.c | 8 +- filan.c | 22 +- filan.h | 6 +- hostan.c | 6 +- procan-cdefs.c | 15 ++ readline-test.sh | 9 +- sysutils.c | 9 + sysutils.h | 26 +- test.sh | 432 ++++++++++++++++++++++++++++--- xio-ip.c | 86 ------- xio-ip.h | 7 +- xio-ip4.c | 54 +++- xio-ip4.h | 6 +- xio-ip6.c | 19 +- xio-ip6.h | 8 +- xio-listen.c | 22 +- xio-rawip.c | 8 +- xio-socket.c | 656 ++++++++++++++++++++++++++++++++++++++++++++++- xio-socket.h | 12 + xio-tun.c | 8 +- xio-udp.c | 6 +- xio-unix.c | 5 +- xio.h | 2 +- xioclose.c | 4 +- xioconfig.h | 10 +- xiomodes.h | 6 +- xioopen.c | 19 +- xioopts.c | 59 +++-- xioread.c | 4 +- xioshutdown.c | 6 +- xiowrite.c | 4 +- 37 files changed, 1441 insertions(+), 258 deletions(-) diff --git a/CHANGES b/CHANGES index 8b50c67..d21a958 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,10 @@ new features: + added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN, + SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow + protocol independent socket handling; all parameters are explicitely + specified as numbers or hex data + added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string, ioctl-bin for generic ioctl() calls. diff --git a/VERSION b/VERSION index 0b595f8..a877d7d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+ioctl+ioctl+setsockopt" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+ioctl+setsockopt+genericsocket" diff --git a/config.h.in b/config.h.in index 2e330da..dfe0c36 100644 --- a/config.h.in +++ b/config.h.in @@ -456,6 +456,7 @@ #undef WITH_IP4 #undef WITH_IP6 #undef WITH_RAWIP +#undef WITH_GENERICSOCKET #undef WITH_TCP #undef WITH_UDP #undef WITH_LISTEN diff --git a/configure.in b/configure.in index f3161ce..e094ffc 100644 --- a/configure.in +++ b/configure.in @@ -196,6 +196,14 @@ AC_ARG_ENABLE(rawip, [ --disable-rawip disable raw IP support], esac], [AC_DEFINE(WITH_RAWIP) AC_MSG_RESULT(yes)]) +AC_MSG_CHECKING(whether to include generic socket support) +AC_ARG_ENABLE(rawsocket, [ --disable-genericsocket disable generic socket support], + [case "$enableval" in + no) AC_MSG_RESULT(no);; + *) AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes);; + esac], + [AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes)]) + AC_MSG_CHECKING(whether to include TCP support) AC_ARG_ENABLE(tcp, [ --disable-tcp disable TCP support], [case "$enableval" in diff --git a/dalan.c b/dalan.c index bc475cd..1d7334f 100644 --- a/dalan.c +++ b/dalan.c @@ -68,6 +68,7 @@ void dalan_init(void) { /* read data description from line, write result to data; do not write so much data that *p exceeds n ! + p must be initialized to 0. return 0 on success, -1 if the data was cut due to n limit, 1 if a syntax error occurred diff --git a/doc/socat.yo b/doc/socat.yo index 4df8cd2..741461a 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -599,6 +599,144 @@ label(ADDRESS_READLINE)dit(bf(tt(READLINE))) link(noecho)(OPTION_NOECHO)nl() See also: link(STDIO)(ADDRESS_STDIO) +label(ADDRESS_SOCKET_CONNECT)dit(bf(tt(SOCKET-CONNECT:::))) + Creates a stream socket using the first and second given socket parameters + and tt(SOCK_STREAM) (see man + socket(2)) and connects to the remote-address. The + two socket parameters have to be specified as numbers of type + link(int)(TYPE_INT). Consult your OS documentation and include files to find + the desired values. The remote-address must be the link(data)(TYPE_DATA) + representation of a sockaddr structure without the sa_family component.nl() + Please note that you can - beyond the options of the specified groups - also + apply options of higher level protocols when you use socat option + link(-s)(option_s).nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY)nl() + Useful options: + link(bind)(OPTION_BIND), + link(setsockopt-int)(OPTION_SETSOCKOPT_INT), + link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), + link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) + nl() + See also: + link(TCP)(ADDRESS_TCP_CONNECT), + link(UDP-CONNECT)(ADDRESS_UDP_CONNECT), + link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT), + link(SOCKET-LISTEN)(ADDRESS_SOCKET_LISTEN), + link(SOCKET-SENDTO)(ADDRESS_SOCKET_SENDTO) +label(ADDRESS_SOCKET_DATAGRAM)dit(bf(tt(SOCKET-DATAGRAM::::))) + Creates a datagram socket using the first three given socket parameters (see man + socket(2)) and sends outgoing data to the remote-address. The + three socket parameters have to be specified as numbers of type + link(int)(TYPE_INT). Consult your OS documentation and include files to find + the desired values. The remote-address must be the link(data)(TYPE_DATA) + representation of a sockaddr structure without the sa_family component.nl() + Please note that you can - beyond the options of the specified groups - also + apply options of higher level protocols when you use socat option + link(-s)(option_s).nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(RANGE)(GROUP_RANGE) + Useful options: + link(bind)(OPTION_BIND), + link(range)(OPTION_RANGE), + link(setsockopt-int)(OPTION_SETSOCKOPT_INT), + link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), + link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) + nl() + See also: + link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM), + link(IP-DATAGRAM)(ADDRESS_IP_DATAGRAM), + link(SOCKET-SENDTO)(ADDRESS_SOCKET_SENDTO), + link(SOCKET-RECV)(ADDRESS_SOCKET_RECV), + link(SOCKET-RECVFROM)(ADDRESS_SOCKET_RECVFROM) +label(ADDRESS_SOCKET_LISTEN)dit(bf(tt(SOCKET-LISTEN:::))) + Creates a stream socket using the first and second given socket parameters + and tt(SOCK_STREAM) (see man + socket(2)) and waits for incoming connections on local-address. The + two socket parameters have to be specified as numbers of type + link(int)(TYPE_INT). Consult your OS documentation and include files to find + the desired values. The local-address must be the link(data)(TYPE_DATA) + representation of a sockaddr structure without the sa_family component.nl() + Please note that you can - beyond the options of the specified groups - also + apply options of higher level protocols when you use socat option + link(-s)(option_s).nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(RANGE)(GROUP_RANGE),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY)nl() + Useful options: + link(setsockopt-int)(OPTION_SETSOCKOPT_INT), + link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), + link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) + nl() + See also: + link(TCP)(ADDRESS_TCP_LISTEN), + link(UDP-CONNECT)(ADDRESS_UDP_LISTEN), + link(UNIX-CONNECT)(ADDRESS_UNIX_LISTEN), + link(SOCKET-LISTEN)(ADDRESS_SOCKET_CONNECT), + link(SOCKET-SENDTO)(ADDRESS_SOCKET_RECVFROM), + link(SOCKET-SENDTO)(ADDRESS_SOCKET_RECV) +label(ADDRESS_SOCKET_RECV)dit(bf(tt(SOCKET_RECV::::))) + Creates a socket using the three given socket parameters (see man + socket(2)) and binds it to . Receives arriving data. The + three parameters have to be specified as numbers of type + link(int)(TYPE_INT). Consult your OS documentation and include files to find + the desired values. The local-address must be the link(data)(TYPE_DATA) + representation of a sockaddr structure without the sa_family component.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(RANGE)(GROUP_RANGE) + Useful options: + link(range)(OPTION_RANGE), + link(setsockopt-int)(OPTION_SETSOCKOPT_INT), + link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), + link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) + nl() + See also: + link(UDP-RECV)(ADDRESS_UDP_RECV), + link(IP-RECV)(ADDRESS_IP_RECV), + link(UNIX-RECV)(ADDRESS_UNIX_RECV), + link(SOCKET-DATAGRAM)(ADDRESS_SOCKET_DATAGRAM), + link(SOCKET-SENDTO)(ADDRESS_SOCKET_SENDTO), + link(SOCKET-RECVFROM)(ADDRESS_SOCKET_RECVFROM) +label(ADDRESS_SOCKET_RECVFROM)dit(bf(tt(SOCKET_RECVFROM::::))) + Creates a socket using the three given socket parameters (see man + socket(2)) and binds it to . Receives arriving data and sends + replies back to the sender. The first three parameters have to be specified as + numbers of type link(int)(TYPE_INT). Consult your OS documentation and + include files to find the desired values. The local-address must be the + link(data)(TYPE_DATA) + representation of a sockaddr structure without the sa_family component.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) + Useful options: + link(fork)(OPTION_FORK), + link(range)(OPTION_RANGE), + link(setsockopt-int)(OPTION_SETSOCKOPT_INT), + link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), + link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) + nl() + See also: + link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM), + link(IP-RECVFROM)(ADDRESS_IP_RECVFROM), + link(UNIX-RECVFROM)(ADDRESS_UNIX_RECVFROM), + link(SOCKET-DATAGRAM)(ADDRESS_SOCKET_DATAGRAM), + link(SOCKET-SENDTO)(ADDRESS_SOCKET_SENDTO), + link(SOCKET-RECV)(ADDRESS_SOCKET_RECV) +label(ADDRESS_SOCKET_SENDTO)dit(bf(tt(SOCKET_SENDTO::::))) + Creates a socket using the three given socket parameters (see man + socket(2)). Sends outgoing data to the given address and receives replies. + The three parameters have to be specified as + numbers of type link(int)(TYPE_INT). Consult your OS documentation and + include files to find the desired values. The remote-address must be the + link(data)(TYPE_DATA) representation of a sockaddr structure without the + sa_family component.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) + Useful options: + link(bind)(OPTION_BIND), + link(setsockopt-int)(OPTION_SETSOCKOPT_INT), + link(setsockopt-bin)(OPTION_SETSOCKOPT_BIN), + link(setsockopt-string)(OPTION_SETSOCKOPT_STRING) + nl() + See also: + link(UDP-SENDTO)(ADDRESS_UDP_SENDTO), + link(IP-SENDTO)(ADDRESS_IP_SENDTO), + link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO), + link(SOCKET-DATAGRAM)(ADDRESS_SOCKET_DATAGRAM), + link(SOCKET-RECV)(ADDRESS_SOCKET_RECV) + link(SOCKET-RECVFROM)(ADDRESS_SOCKET_RECVFROM) label(ADDRESS_SOCKS4)dit(bf(tt(SOCKS4:::))) Connects via [link(IP address)(TYPE_IP_ADDRESS)] to [link(IPv4 address)(TYPE_IPV4_ADDRESS)] diff --git a/fdname.c b/fdname.c index 8ede9fe..5309360 100644 --- a/fdname.c +++ b/fdname.c @@ -139,7 +139,7 @@ int statname(const char *file, int fd, int filetype, FILE *outfile) { if (file) fprintf(outfile, " %s", file); break; case (S_IFSOCK>>12): /* 12, socket */ -#if WITH_SOCKET +#if _WITH_SOCKET if (fd >= 0) { result = sockname(fd, outfile); } else if (file) { @@ -150,7 +150,7 @@ int statname(const char *file, int fd, int filetype, FILE *outfile) { #else Error("SOCKET support not compiled in"); return -1; -#endif /* !WITH_SOCKET */ +#endif /* !_WITH_SOCKET */ break; } /* ioctl() */ @@ -185,7 +185,7 @@ int cdevname(int fd, FILE *outfile) { } -#if WITH_SOCKET +#if _WITH_SOCKET int sockname(int fd, FILE *outfile) { #define FDNAME_OPTLEN 256 #define FDNAME_NAMELEN 256 @@ -320,7 +320,7 @@ int sockname(int fd, FILE *outfile) { #undef FDNAME_OPTLEN #undef FDNAME_NAMELEN } -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ diff --git a/filan.c b/filan.c index e0477d1..fe5e63e 100644 --- a/filan.c +++ b/filan.c @@ -1,5 +1,5 @@ /* source: filan.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the subroutine filan makes a "FILe descriptor ANalysis". It checks the @@ -150,7 +150,7 @@ int filan_fd(int fd, FILE *outfile) { } } #endif /* defined(FIONREAD) */ -#if WITH_SOCKET && defined(MSG_DONTWAIT) +#if _WITH_SOCKET && defined(MSG_DONTWAIT) if ((ufds.revents & POLLIN) && isasocket(fd)) { char _peername[SOCKADDR_MAX]; struct sockaddr *pa = (struct sockaddr *)_peername; @@ -186,7 +186,7 @@ int filan_fd(int fd, FILE *outfile) { fprintf(outfile, "recvmsg="F_Zd", ", bytes); } } -#endif /* WITH_SOCKET && defined(MSG_DONTWAIT) */ +#endif /* _WITH_SOCKET && defined(MSG_DONTWAIT) */ } } } @@ -371,12 +371,12 @@ int filan_stat( break; #ifdef S_IFSOCK case (S_IFSOCK): /* 12, socket */ -#if WITH_SOCKET +#if _WITH_SOCKET result = sockan(statfd, outfile); #else Warn("SOCKET support not compiled in"); return -1; -#endif /* !WITH_SOCKET */ +#endif /* !_WITH_SOCKET */ break; #endif /* S_IFSOCK */ } @@ -462,7 +462,7 @@ int cdevan(int fd, FILE *outfile) { } -#if WITH_SOCKET +#if _WITH_SOCKET int sockan(int fd, FILE *outfile) { #define FILAN_OPTLEN 256 #define FILAN_NAMELEN 256 @@ -634,7 +634,7 @@ int sockan(int fd, FILE *outfile) { #undef FILAN_OPTLEN #undef FILAN_NAMELEN } -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ #if WITH_IP4 || WITH_IP6 @@ -823,7 +823,7 @@ int tcpan(int fd, FILE *outfile) { #endif /* WITH_TCP */ -#if WITH_SOCKET +#if _WITH_SOCKET int sockoptan(int fd, const struct sockopt *optname, int socklay, FILE *outfile) { #define FILAN_OPTLEN 256 char optval[FILAN_OPTLEN]; @@ -859,10 +859,10 @@ int sockoptan(int fd, const struct sockopt *optname, int socklay, FILE *outfile) return 0; #undef FILAN_OPTLEN } -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ -#if WITH_SOCKET +#if _WITH_SOCKET int isasocket(int fd) { int retval; #if HAVE_STAT64 @@ -883,7 +883,7 @@ int isasocket(int fd) { /* note: when S_ISSOCK was undefined, it always gives 0 */ return S_ISSOCK(props.st_mode); } -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ const char *getfiletypestring(int st_mode) { diff --git a/filan.h b/filan.h index 8ed3484..1abff1b 100644 --- a/filan.h +++ b/filan.h @@ -1,5 +1,5 @@ /* source: filan.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ @@ -26,12 +26,12 @@ extern int filan_stat( extern int cdevan(int fd, FILE *outfile); -#if WITH_SOCKET +#if _WITH_SOCKET extern int isasocket(int fd); extern int sockan(int fd, FILE *outfile); extern int ipan(int fd, FILE *outfile); extern int ip6an(int fd, FILE *outfile); -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ extern int fdname(const char *file, int fd, FILE *outfile); diff --git a/hostan.c b/hostan.c index 8862bf5..8033dc0 100644 --- a/hostan.c +++ b/hostan.c @@ -20,14 +20,14 @@ static int iffan(FILE *outfile); int hostan(FILE *outfile) { -#if WITH_SOCKET +#if _WITH_SOCKET fprintf(outfile, "\nIP INTERFACES\n"); iffan(outfile); #endif return 0; } -#if WITH_SOCKET +#if _WITH_SOCKET static int iffan(FILE *outfile) { /* Linux: man 7 netdevice */ /* FreeBSD: man 4 networking */ @@ -80,4 +80,4 @@ static int iffan(FILE *outfile) { #endif /* defined(SIOCGIFINDEX) */ return 0; } -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ diff --git a/procan-cdefs.c b/procan-cdefs.c index c5a7116..f85ca8a 100644 --- a/procan-cdefs.c +++ b/procan-cdefs.c @@ -75,10 +75,25 @@ int procan_cdefs(FILE *outfile) { #ifdef CSIZE fprintf(outfile, "#define CSIZE 0%011o\n", CSIZE); #endif +#ifdef TIOCEXCL + fprintf(outfile, "#define TIOCEXCL 0x%lx\n", (unsigned long)TIOCEXCL); +#endif /* stdio constants */ #ifdef FOPEN_MAX fprintf(outfile, "#define FOPEN_MAX %u\n", FOPEN_MAX); #endif + + /* socket constants */ +#ifdef SOCK_DGRAM + fprintf(outfile, "#define SOCK_DGRAM %d\n", SOCK_DGRAM); +#endif +#ifdef SOL_SOCKET + fprintf(outfile, "#define SOL_SOCKET 0x%x\n", SOL_SOCKET); +#endif +#ifdef SO_REUSEADDR + fprintf(outfile, "#define SO_REUSEADDR %d\n", SO_REUSEADDR); +#endif + return 0; } diff --git a/readline-test.sh b/readline-test.sh index 569bff6..2242ea9 100755 --- a/readline-test.sh +++ b/readline-test.sh @@ -1,6 +1,6 @@ #! /bin/bash # source: readline-test.sh -# Copyright Gerhard Rieger 2003 +# Copyright Gerhard Rieger 2003-2008 # Published under the GNU General Public License V.2, see file COPYING # script that simulates a simple program with authentication. @@ -29,8 +29,9 @@ trap "$ECHO $0 got SIGQUIT" QUIT # print banner $ECHO "$BANNER" -read -r -p "$($ECHO "$USERPROMPT")" USERNAME -read -rs -p "$PWDPROMPT" PASSWORD +# on (some) ksh read -p does not mean prompt +$ECHO "$USERPROMPT\c"; read -r USERNAME +$ECHO "$PWDPROMPT\c"; read -rs PASSWORD $ECHO if [ "$USERNAME" != "$CREDUSER" -o "$PASSWORD" != "$CREDPASS" ]; then @@ -38,7 +39,7 @@ if [ "$USERNAME" != "$CREDUSER" -o "$PASSWORD" != "$CREDPASS" ]; then exit -1 fi -while read -r -p "$PROMPT" COMMAND; do +while $ECHO "$PROMPT\c"; read -r COMMAND; do if [ "$COMMAND" = "exit" ]; then break; fi diff --git a/sysutils.c b/sysutils.c index 28ccae9..43629c3 100644 --- a/sysutils.c +++ b/sysutils.c @@ -106,6 +106,7 @@ void socket_in6_init(struct sockaddr_in6 *sa) { length of the specific socket address, or 0 on error. */ socklen_t socket_init(int af, union sockaddr_union *sa) { switch (af) { + case AF_UNSPEC: memset(sa, 0, sizeof(*sa)); return sizeof(*sa); #if WITH_UNIX case AF_UNIX: socket_un_init(&sa->un); return sizeof(sa->un); #endif @@ -134,6 +135,14 @@ char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size char *cp = lbuff; int n; +#if HAVE_STRUCT_SOCKADDR_SALEN + if ((n = snprintf(cp, blen, "LEN=%d ", sa->sa_len)) < 0) { + Warn1("sockaddr_info(): buffer too short ("F_Zu")", blen); + *buff = '\0'; + return buff; + } + cp += n, blen -= n; +#endif if ((n = snprintf(cp, blen, "AF=%d ", sa->sa_family)) < 0) { Warn1("sockaddr_info(): buffer too short ("F_Zu")", blen); *buff = '\0'; diff --git a/sysutils.h b/sysutils.h index b9074b3..6cbe1fe 100644 --- a/sysutils.h +++ b/sysutils.h @@ -15,6 +15,7 @@ union xioin6_u { } ; #endif /* WITH_IP6 */ +#if _WITH_SOCKET union sockaddr_union { struct sockaddr soa; #if WITH_UNIX @@ -27,29 +28,12 @@ union sockaddr_union { struct sockaddr_in6 ip6; #endif /* WITH_IP6 */ } ; - -#if _WITH_IP4 -struct xiorange_ip4 { - struct in_addr netaddr; /* network byte order */ - struct in_addr netmask; /* network byte order */ -} ; -#endif /* _WITH_IP4 */ - -#if _WITH_IP6 -struct xiorange_ip6 { - struct in6_addr addr; - struct in6_addr mask; -} ; -#endif /* _WITH_IP4 */ +#endif /* _WITH_SOCKET */ #if _WITH_SOCKET -union xiorange_union { -#if _WITH_IP4 - struct xiorange_ip4 ip4; -#endif /* _WITH_IP4 */ -#if _WITH_IP6 - struct xiorange_ip6 ip6; -#endif /* _WITH_IP6 */ +struct xiorange { + union sockaddr_union netaddr; + union sockaddr_union netmask; } ; #endif /* _WITH_SOCKET */ diff --git a/test.sh b/test.sh index dee3739..4255347 100755 --- a/test.sh +++ b/test.sh @@ -141,14 +141,21 @@ SunOS) BROADCASTIF="$MAINIF" #BROADCASTIF=hme0 #BROADCASTIF=eri0 - SECONDADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}') - BCIFADDR="$SECONDADDR" - BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;; + #SECONDADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}') + SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |fgrep -v ' 127.0.0.1 '| head -n 1)" : '.*inet \([0-9.]*\) .*') + #BCIFADDR="$SECONDADDR" + #BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') + ;; #AIX|FreeBSD|Solaris) *) - SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |fgrep -v ' 127.0.0.1 '| head -n 1)" : '.*inet \([0-9.]*\) .*') + SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |fgrep -v ' 127.0.0.1 ' |head -n 1)" : '.*inet \([0-9.]*\) .*') ;; esac +# for generic sockets we need this address in hex form +if [ "$SECONDADDR" ]; then + SECONDADDRHEX="$(printf "%02x%02x%02x%02x\n" $(echo "$SECONDADDR" |tr '.' ' +'))" +fi # for some tests we need a second local IPv6 address case "$UNAME" in @@ -184,20 +191,20 @@ vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color) RED="\0033[31m" GREEN="\0033[32m" YELLOW="\0033[33m" - if false && [ "$UNAME" = SunOS ]; then - NORMAL="\0033[30m" - else +# if [ "$UNAME" = SunOS ]; then +# NORMAL="\0033[30m" +# else NORMAL="\0033[39m" - fi +# fi else RED="\033[31m" GREEN="\033[32m" YELLOW="\033[33m" - if false && [ "$UNAME" = SunOS ]; then - NORMAL="\033[30m" - else +# if [ "$UNAME" = SunOS ]; then +# NORMAL="\033[30m" +# else NORMAL="\033[39m" - fi +# fi fi OK="${GREEN}OK${NORMAL}" FAILED="${RED}FAILED${NORMAL}" @@ -1509,9 +1516,11 @@ testod () { local T="$6"; [ -z "$T" ] && T=0 local tf="$td/test$N.stdout" local te="$td/test$N.stderr" + local tr="$td/test$N.ref" local tdiff="$td/test$N.diff" local dain="$(date) $RANDOM" - local daout="$(echo "$dain" |$OD_C)" + echo "$dain" |$OD_C >"$tr" +# local daout="$(echo "$dain" |$OD_C)" $PRINTF "test $F_n %s... " $num "$title" (psleep $T; echo "$dain"; psleep $T) |$SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" if [ "$?" != 0 ]; then @@ -1519,7 +1528,8 @@ testod () { echo "$SOCAT $opts $arg1 $arg2" cat "$te" numFAIL=$((numFAIL+1)) - elif echo "$daout" |diff - "$tf" >"$tdiff" 2>&1; then +# elif echo "$daout" |diff - "$tf" >"$tdiff" 2>&1; then + elif diff "$tr" "$tf" >"$tdiff" 2>&1; then $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) @@ -1574,7 +1584,8 @@ ifprocess () { FreeBSD) l="$(ps -faje |grep "^........ $(printf %5u $1)")" ;; HP-UX) l="$(ps -fade |grep "^........ $(printf %5u $1)")" ;; Linux) l="$(ps -fade |grep "^........ $(printf %5u $1)")" ;; - NetBSD) l="$(ps -aj |grep "^........ $(printf %4u $1)")" ;; +# NetBSD) l="$(ps -aj |grep "^........ $(printf %4u $1)")" ;; + NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*$(printf %5u $1) ")" ;; OpenBSD) l="$(ps -kaj |grep "^........ $(printf %5u $1)")" ;; SunOS) l="$(ps -fade |grep "^........ $(printf %5u $1)")" ;; *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*$(printf %5u $1) ")" ;; @@ -1596,8 +1607,9 @@ childprocess () { FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;; HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; - NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)")" ;; - OpenBSD) l="$(ps -kaj |grep "^........ ..... $(printf %5u $1)")" ;; +# NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)")" ;; + NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;; + OpenBSD) l="$(ps -aj |grep "^........ ..... $(printf %5u $1)")" ;; SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]**[ ][ ]*$(printf %5u $1) ")" ;; esac if [ -z "$l" ]; then @@ -4387,7 +4399,7 @@ tr="$td/test$N.ref" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" # the feature that we really want to test is in the readline.sh script: -CMD="$SOCAT $opts open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" +CMD="$SOCAT $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" #echo "$CMD" >"$ts" #chmod a+x "$ts" printf "test $F_n $TEST... " $N @@ -4459,7 +4471,8 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -#kill $pid 2>/dev/null +kill $pid 2>/dev/null # necc on OpenBSD +wait MICROS=$SAVEMICS TERM="$SAVETERM" fi @@ -4857,7 +4870,13 @@ NAME=TCP4RANGEBITS case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" +if [ -z "$SECONDADDR" ]; then + # we need access to a second addresses + $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 +fi ;; # $SECONDADDR esac PORT=$((PORT+1)) N=$((N+1)) @@ -4866,6 +4885,22 @@ NAME=TCP4RANGEMASK case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" +if [ -z "$SECONDADDR" ]; then + # we need access to a second addresses + $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR:255.255.255.255" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 +fi ;; # $SECONDADDR +esac +PORT=$((PORT+1)) +N=$((N+1)) + +# like TCP4RANGEMASK, but the "bad" address is within the same class A network +NAME=TCP4RANGEMASKHAIRY +case "$TESTS" in +*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) +TEST="$NAME: security of TCP4-L with RANGE option" if [ "$UNAME" != Linux ]; then # we need access to more loopback addresses $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N @@ -5544,7 +5579,7 @@ N=$((N+1)) signum () { if [ ! "$BASH_VERSION" ]; then # we expect: - for i in $(kill -l); do echo $i; done |grep -n -i $1 |cut -d: -f1 + for i in $(POSIXLY_CORRECT=1 kill -l); do echo $i; done |grep -n -i "^$1$" |cut -d: -f1 else # expect: # " 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL" @@ -5566,12 +5601,12 @@ if ! feat=$(testaddrs pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr a-z A-Z) not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else -SIG=$(signum $signam) +SIG="$(signum $signam)" te="$td/test$N.stderr" tpp="$td/test$N.ppid" tp="$td/test$N.pid" $PRINTF "test $F_n $TEST... " $N -(sleep 1; kill -$SIG $(cat "$tpp")) & +(sleep 1; kill -"$SIG" "$(cat "$tpp")") & # a simple "system:echo $PPID..." does not work on NetBSD, OpenBSD #$SOCAT $opts echo system:'exec /bin/bash -c "echo \$PPID '">$tpp"'; echo \$$ '">$tp; read x\"",nofork 2>"$te"; stat=$? tsh="$td/test$N.sh" @@ -5929,10 +5964,13 @@ PORT=$((PORT+1)) N=$((N+1)) +# test the UDP4-SENDTO and UDP4-RECVFROM addresses together NAME=UDP4DGRAM case "$TESTS" in *%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*) -TEST="$NAME: UDP/IPv4 datagram" +TEST="$NAME: UDP/IPv4 sendto and recvfrom" +# start a UDP4-RECVFROM process that echoes data, and send test data using +# UDP4-SENDTO. The sent data should be returned. tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -5954,16 +5992,16 @@ kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $SOCAT:\n" echo "$CMD1 &" - echo "$CMD2" cat "${te}1" + echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" echo "$CMD1 &" - echo "$CMD2" cat "${te}1" + echo "$CMD2" cat "${te}2" numFAIL=$((numFAIL+1)) else @@ -8447,6 +8485,334 @@ esac N=$((N+1)) +# test the SOCKET-CONNECT address (against TCP4-LISTEN) +NAME=SOCKET_CONNECT +case "$TESTS" in +*%functions%*|*%generic%*|*%socket%*|*%$NAME%*) +TEST="$NAME: socket connect with TCP/IPv4" +# start a TCP4-LISTEN process that echoes data, and send test data using +# SOCKET-CONNECT, selecting TCP/IPv4. The sent data should be returned. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts0p=$PORT; PORT=$((PORT+1)) +ts0a="127.0.0.1" +ts1p=$(printf "%04x" $ts0p); +ts1a="7f000001" # "127.0.0.1" +ts1="x${ts1p}${ts1a}x0000000000000000" +ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) +da="$(date) $RANDOM" +CMD0="$SOCAT $opts TCP4-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE" +CMD1="$SOCAT $opts - SOCKET-CONNECT:2:6:$ts1,bind=x${ts1b}00000000x0000000000000000" +printf "test $F_n $TEST... " $N +$CMD0 2>"${te}0" & +pid0="$!" +waittcp4port $ts0p 1 +echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" +rc1="$?" +kill "$pid0" 2>/dev/null; wait; +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + +# test the SOCKET-LISTEN address (with TCP4-CONNECT) +NAME=SOCKET_LISTEN +case "$TESTS" in +*%functions%*|*%generic%*|*%socket%*|*%$NAME%*) +TEST="$NAME: socket recvfrom with TCP/IPv4" +# start a SOCKET-LISTEN process that uses TCP/IPv4 and echoes data, and +# send test data using TCP4-CONNECT. The sent data should be returned. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts1p=$PORT; PORT=$((PORT+1)) +ts1a="127.0.0.1" +ts0p=$(printf "%04x" $ts1p); +ts0a="7f000001" # "127.0.0.1" +ts0="x${ts0p}${ts0a}x0000000000000000" +ts1b=$PORT; PORT=$((PORT+1)) +ts1="$ts1a:$ts1p" +da="$(date) $RANDOM" +CMD0="$SOCAT $opts SOCKET-LISTEN:2:6:$ts0,reuseaddr PIPE" +CMD1="$SOCAT $opts - TCP4-CONNECT:$ts1,bind=:$ts1b" +printf "test $F_n $TEST... " $N +$CMD0 2>"${te}0" & +pid0="$!" +#sleep 1 +waittcp4port $ts1p 1 +echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" +rc1="$?" +kill "$pid0" 2>/dev/null; wait; +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + +SOCK_DGRAM="$($PROCAN -c |grep "^#define[[:space:]]*SOCK_DGRAM[[:space:]]" |cut -d' ' -f3)" + +# test the SOCKET-SENDTO address (against UDP4-RECVFROM) +NAME=SOCKET_SENDTO +case "$TESTS" in +*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) +TEST="$NAME: socket sendto with UDP/IPv4" +# start a UDP4-RECVFROM process that echoes data, and send test data using +# SOCKET-SENDTO, selecting UDP/IPv4. The sent data should be returned. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts0p=$PORT; PORT=$((PORT+1)) +ts0a="127.0.0.1" +ts1p=$(printf "%04x" $ts0p); +ts1a="7f000001" # "127.0.0.1" +ts1="x${ts1p}${ts1a}x0000000000000000" +ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) +da="$(date) $RANDOM" +CMD0="$SOCAT $opts UDP4-RECVFROM:$ts0p,reuseaddr,bind=$ts0a PIPE" +CMD1="$SOCAT $opts - SOCKET-SENDTO:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000" +printf "test $F_n $TEST... " $N +$CMD0 2>"${te}0" & +pid0="$!" +waitudp4port $ts0p 1 +echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" +rc1="$?" +kill "$pid0" 2>/dev/null; wait; +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + +# test the SOCKET-RECVFROM address (with UDP4-SENDTO) +NAME=SOCKET_RECVFROM +case "$TESTS" in +*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) +TEST="$NAME: socket recvfrom with UDP/IPv4" +# start a SOCKET-RECVFROM process that uses UDP/IPv4 and echoes data, and +# send test data using UDP4-SENDTO. The sent data should be returned. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts1p=$PORT; PORT=$((PORT+1)) +ts1a="127.0.0.1" +ts0p=$(printf "%04x" $ts1p); +ts0a="7f000001" # "127.0.0.1" +ts0="x${ts0p}${ts0a}x0000000000000000" +ts1b=$PORT; PORT=$((PORT+1)) +ts1="$ts1a:$ts1p" +da="$(date) $RANDOM" +CMD0="$SOCAT $opts SOCKET-RECVFROM:2:$SOCK_DGRAM:17:$ts0,reuseaddr PIPE" +CMD1="$SOCAT $opts - UDP4-SENDTO:$ts1,bind=:$ts1b" +printf "test $F_n $TEST... " $N +$CMD0 2>"${te}0" & +pid0="$!" +sleep 1 # waitudp4port $ts1p 1 +echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" +rc1="$?" +kill "$pid0" 2>/dev/null; wait; +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + +# test the SOCKET-RECV address (with UDP4-SENDTO) +NAME=SOCKET_RECV +case "$TESTS" in +*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) +TEST="$NAME: socket recv with UDP/IPv4" +# start a SOCKET-RECV process that uses UPD/IPv4 and writes received data to file, and +# send test data using UDP4-SENDTO. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts1p=$PORT; PORT=$((PORT+1)) +ts1a="127.0.0.1" +ts0p=$(printf "%04x" $ts1p); +ts0a="7f000001" # "127.0.0.1" +ts0="x${ts0p}${ts0a}x0000000000000000" +ts1b=$PORT; PORT=$((PORT+1)) +ts1="$ts1a:$ts1p" +da="$(date) $RANDOM" +CMD0="$SOCAT $opts -u SOCKET-RECV:2:$SOCK_DGRAM:17:$ts0,reuseaddr -" +CMD1="$SOCAT $opts -u - UDP4-SENDTO:$ts1,bind=:$ts1b" +printf "test $F_n $TEST... " $N +$CMD0 2>"${te}0" >"$tf" & +pid0="$!" +sleep 1 # waitudp4port $ts1p 1 +echo "$da" |$CMD1 2>>"${te}1" +rc1="$?" +sleep 1 +kill "$pid0" 2>/dev/null; wait; +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + +# test SOCKET-DATAGRAM (with UDP4-DATAGRAM) +NAME=SOCKET_DATAGRAM +case "$TESTS" in +*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) +TEST="$NAME: socket datagram via UDP/IPv4" +# start a UDP4-DATAGRAM process that echoes data, and send test data using +# SOCKET-DATAGRAM, selecting UDP/IPv4. The sent data should be returned. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts0p=$PORT; PORT=$((PORT+1)) +ts1p=$PORT; PORT=$((PORT+1)) +ts0a="127.0.0.1" +ts1b=$(printf "%04x" $ts0p); +ts1a="7f000001" # "127.0.0.1" +ts0b=$(printf "%04x" $ts0p) +ts1b=$(printf "%04x" $ts1p) +ts1="x${ts0b}${ts1a}x0000000000000000" +da="$(date) $RANDOM" +CMD0="$SOCAT $opts UDP4-DATAGRAM:$ts0a:$ts1p,bind=:$ts0p,reuseaddr PIPE" +CMD1="$SOCAT $opts - SOCKET-DATAGRAM:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000" +printf "test $F_n $TEST... " $N +$CMD0 2>"${te}0" & +pid0="$!" +waitudp4port $ts0p 1 +echo "$da" |$CMD1 2>>"${te}1" >"$tf" +rc1="$?" +kill "$pid0" 2>/dev/null; wait; +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + +NAME=SOCKETRANGEMASK +case "$TESTS" in +*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%$NAME%*) +TEST="$NAME: security of generic socket-listen with RANGE option" +if [ -z "$SECONDADDR" ]; then + # we need access to more loopback addresses + $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +ts1p=$(printf "%04x" $PORT); +testserversec "$N" "$TEST" "$opts -s" "SOCKET-LISTEN:2:6:x${ts1p}x00000000x0000000000000000,reuseaddr,fork,retry=1" "" "range=x0000x7f000000:x0000xffffffff" "SOCKET-CONNECT:2:6:x${ts1p}x${SECONDADDRHEX}x0000000000000000" 4 tcp $PORT 0 +fi ;; # $SECONDADDR +esac +PORT=$((PORT+1)) +N=$((N+1)) + + +TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |cut -d' ' -f3)" + # test the generic ioctl-void option NAME=IOCTL_VOID case "$TESTS" in @@ -8458,9 +8824,9 @@ TEST="$NAME: test the ioctl-void option" # process 1 opens it with the TIOCEXCL ioctl; # process 2 opens it too and fails with "device or resource busy" only when the # previous ioctl was successful -if [ "$UNAME" != Linux ]; then +if [ -z "$TIOCEXCL" ]; then # we use the numeric value of TIOCEXL which is system dependent - $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N + $PRINTF "test $F_n $TEST... ${YELLOW}no value of TIOCEXCL${NORMAL}\n" $N numCANT=$((numCANT+1)) else tp="$td/test$N.pty" @@ -8469,7 +8835,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="$(date)" CMD0="$SOCAT $opts PTY,LINK=$tp pipe" -CMD1="$SOCAT $opts - file:$tp,ioctl-void=0x540c,raw,echo=0" +CMD1="$SOCAT $opts - file:$tp,ioctl-void=$TIOCEXCL,raw,echo=0" CMD2="$SOCAT $opts - file:$tp,raw,echo=0" printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & @@ -8504,6 +8870,9 @@ esac N=$((N+1)) +SOL_SOCKET="$($PROCAN -c |grep "^#define[[:space:]]*SOL_SOCKET[[:space:]]" |cut -d' ' -f3)" +SO_REUSEADDR="$($PROCAN -c |grep "^#define[[:space:]]*SO_REUSEADDR[[:space:]]" |cut -d' ' -f3)" + # test the generic setsockopt-int option NAME=SETSOCKOPT_INT case "$TESTS" in @@ -8518,9 +8887,9 @@ TEST="$NAME: test the setsockopt-int option" # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the # (generically specified) SO_REUSEADDR socket options did not work # process 3 connects to this port; only if it is successful the test is ok -if [ "$UNAME" != Linux ]; then +if [ -z "SO_REUSEADDR" ]; then # we use the numeric value of SO_REUSEADDR which might be system dependent - $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N + $PRINTF "test $F_n $TEST... ${YELLOW}value of SO_REUSEADDR not known${NORMAL}\n" $N numCANT=$((numCANT+1)) else tp="$PORT" @@ -8528,8 +8897,7 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="$(date)" -# level=SOL_SOCKET=1, optname=SO_REUSEADDR=2, value=1 -CMD0="$SOCAT $opts TCP4-L:$tp,setsockopt-int=1:2:1 PIPE" +CMD0="$SOCAT $opts TCP4-L:$tp,setsockopt-int=$SOL_SOCKET:$SO_REUSEADDR:1 PIPE" CMD1="$SOCAT $opts - TCP:localhost:$tp" CMD2="$CMD0" CMD3="$CMD1" diff --git a/xio-ip.c b/xio-ip.c index 77dd71d..6adb86e 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -423,90 +423,4 @@ int xiogetaddrinfo(const char *node, const char *service, return STAT_OK; } - -int xioparsenetwork(const char *rangename, int pf, union xiorange_union *range) { -#if WITH_IP4 - struct in_addr *netaddr_in = &range->ip4.netaddr; - struct in_addr *netmask_in = &range->ip4.netmask; -#endif /* WITH_IP4 */ - struct hostent *maskaddr; - char *delimpos; /* absolute address of delimiter */ - int bits; - - switch (pf) { -#if WITH_IP4 - char *rangename1; /* a copy of rangename with writing allowed */ - case PF_INET: - if ((rangename1 = strdup(rangename)) == NULL) { - Error1("strdup(\"%s\"): out of memory", rangename); - return STAT_RETRYLATER; - } - - if (delimpos = strchr(rangename1, '/')) { - bits = strtoul(delimpos+1, NULL, 10); - netmask_in->s_addr = htonl((0xffffffff << (32-bits))); - } else if (delimpos = strchr(rangename1, ':')) { - if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) { - Error2("gethostbyname(\"%s\"): %s", delimpos+1, - h_errno == NETDB_INTERNAL ? strerror(errno) : - hstrerror(h_errno)); - return STAT_NORETRY; - } - netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0]; - } else { - Error1("xioparsenetwork(\"%s\",,): missing netmask delimiter", rangename); - free(rangename1); - return STAT_NORETRY; - } - { - struct hostent *nameaddr; - *delimpos = 0; - if ((nameaddr = Gethostbyname(rangename1)) == NULL) { - Error2("gethostbyname(\"%s\"): %s", rangename1, - h_errno == NETDB_INTERNAL ? strerror(errno) : - hstrerror(h_errno)); - free(rangename1); - return STAT_NORETRY; - } - netaddr_in->s_addr = *(unsigned long *)nameaddr->h_addr_list[0]; - } - free(rangename1); - break; -#endif /* WITH_IP4 */ -#if WITH_IP6 - case PF_INET6: - return xioparsenetwork_ip6(rangename, &range->ip6); - break; -#endif /* WITH_IP6 */ - default: - Error1("range option not supported with address family %d", pf); - return STAT_NORETRY; - } - return STAT_OK; -} - -/* parses a string of form address/bits or address:mask, and fills the fields - of the range union. The addr component is masked with mask. */ -int parserange(const char *rangename, int pf, union xiorange_union *range) { - if (xioparsenetwork(rangename, pf, range) < 0) { - return -1; - } - switch (pf) { -#if WITH_IP4 - case PF_INET: - range->ip4.netaddr.s_addr &= range->ip4.netmask.s_addr; - break; -#endif /* WITH_IP4 */ -#if WITH_IP6 - case PF_INET6: - return xiorange_ip6andmask(&range->ip6); - break; -#endif /* WITH_IP6 */ - default: - Error1("range option not supported with address family %d", pf); - return STAT_NORETRY; - } - return 0; -} - #endif /* _WITH_IP4 || _WITH_IP6 */ diff --git a/xio-ip.h b/xio-ip.h index 4d68012..9b4aab2 100644 --- a/xio-ip.h +++ b/xio-ip.h @@ -1,5 +1,5 @@ /* source: xio-ip.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip_h_included @@ -39,10 +39,5 @@ extern int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, union sockaddr_union *sa, socklen_t *socklen, unsigned long res_opts0, unsigned long res_opts1); -extern -int xioparsenetwork(const char *rangename, int pf, - union xiorange_union *range); -extern -int parserange(const char *rangename, int pf, union xiorange_union *range); #endif /* !defined(__xio_ip_h_included) */ diff --git a/xio-ip4.c b/xio-ip4.c index 6e8ff23..6cdaf60 100644 --- a/xio-ip4.c +++ b/xio-ip4.c @@ -1,5 +1,5 @@ /* source: xio-ip4.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP4 related functions */ @@ -13,11 +13,57 @@ #include "xio-ip.h" #include "xio-ip4.h" + +int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) { + struct hostent *maskaddr; + struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr; + struct in_addr *netmask_in = &range->netmask.ip4.sin_addr; + char *rangename1; /* a copy of rangename with writing allowed */ + char *delimpos; /* absolute address of delimiter */ + int bits; + + if ((rangename1 = strdup(rangename)) == NULL) { + Error1("strdup(\"%s\"): out of memory", rangename); + return STAT_RETRYLATER; + } + + if (delimpos = strchr(rangename1, '/')) { + bits = strtoul(delimpos+1, NULL, 10); + netmask_in->s_addr = htonl((0xffffffff << (32-bits))); + } else if (delimpos = strchr(rangename1, ':')) { + if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) { + Error2("gethostbyname(\"%s\"): %s", delimpos+1, + h_errno == NETDB_INTERNAL ? strerror(errno) : + hstrerror(h_errno)); + return STAT_NORETRY; + } + netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0]; + } else { + Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename); + free(rangename1); + return STAT_NORETRY; + } + { + struct hostent *nameaddr; + *delimpos = 0; + if ((nameaddr = Gethostbyname(rangename1)) == NULL) { + Error2("gethostbyname(\"%s\"): %s", rangename1, + h_errno == NETDB_INTERNAL ? strerror(errno) : + hstrerror(h_errno)); + free(rangename1); + return STAT_NORETRY; + } + netaddr_in->s_addr = *(unsigned long *)nameaddr->h_addr_list[0]; + } + free(rangename1); + return STAT_OK; +} + /* check if peer address is within permitted range. return >= 0 if so. */ -int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange_ip4 *range) { - struct in_addr *netaddr_in = &range->netaddr; - struct in_addr *netmask_in = &range->netmask; +int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range) { + struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr; + struct in_addr *netmask_in = &range->netmask.ip4.sin_addr; char addrbuf[256], maskbuf[256]; char peername[256]; diff --git a/xio-ip4.h b/xio-ip4.h index 9357dcc..bbc855b 100644 --- a/xio-ip4.h +++ b/xio-ip4.h @@ -1,5 +1,5 @@ /* source: xio-ip4.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip4_h_included @@ -8,6 +8,8 @@ extern const struct optdesc opt_ip4_add_membership; extern -int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange_ip4 *range); +int xioparsenetwork_ip4(const char *rangename, struct xiorange *range); +extern +int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range); #endif /* !defined(__xio_ip4_h_included) */ diff --git a/xio-ip6.c b/xio-ip6.c index 0bf8577..b56facc 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -1,5 +1,5 @@ /* source: xio-ip6.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP6 related functions */ @@ -21,15 +21,15 @@ const struct optdesc opt_ipv6_v6only = { "ipv6-v6only", "ipv6only", OPT_IPV6_V6O const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTBIND, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IPV6, IPV6_JOIN_GROUP }; #endif -int xioparsenetwork_ip6(const char *rangename, struct xiorange_ip6 *range) { +int xioparsenetwork_ip6(const char *rangename, struct xiorange *range) { char *delimpos; /* absolute address of delimiter */ size_t delimind; /* index of delimiter in string */ int bits; char *baseaddr; union sockaddr_union sockaddr; socklen_t sockaddrlen = sizeof(sockaddr); - union xioin6_u *rangeaddr = (union xioin6_u *)&range->addr; - union xioin6_u *rangemask = (union xioin6_u *)&range->mask; + union xioin6_u *rangeaddr = (union xioin6_u *)&range->netaddr.ip6.sin6_addr; + union xioin6_u *rangemask = (union xioin6_u *)&range->netmask.ip6.sin6_addr; union xioin6_u *nameaddr = (union xioin6_u *)&sockaddr.ip6.sin6_addr; if (rangename[0] != '[' || rangename[strlen(rangename)-1] != ']') { @@ -87,7 +87,7 @@ int xioparsenetwork_ip6(const char *rangename, struct xiorange_ip6 *range) { return 0; } -int xiorange_ip6andmask(struct xiorange_ip6 *range) { +int xiorange_ip6andmask(struct xiorange *range) { int i; #if 0 range->addr.s6_addr32[0] &= range->mask.s6_addr32[0]; @@ -96,7 +96,8 @@ int xiorange_ip6andmask(struct xiorange_ip6 *range) { range->addr.s6_addr32[3] &= range->mask.s6_addr32[3]; #else for (i = 0; i < 16; ++i) { - range->addr.s6_addr[i] &= range->mask.s6_addr[i]; + range->netaddr.ip6.sin6_addr.s6_addr[i] &= + range->netmask.ip6.sin6_addr.s6_addr[i]; } #endif return 0; @@ -104,12 +105,12 @@ int xiorange_ip6andmask(struct xiorange_ip6 *range) { /* check if peer address is within permitted range. return >= 0 if so. */ -int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange_ip6 *range) { +int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) { union xioin6_u masked; int i; char peername[256]; - union xioin6_u *rangeaddr = (union xioin6_u *)&range->addr; - union xioin6_u *rangemask = (union xioin6_u *)&range->mask; + union xioin6_u *rangeaddr = (union xioin6_u *)&range->netaddr.ip6.sin6_addr; + union xioin6_u *rangemask = (union xioin6_u *)&range->netmask.ip6; Debug16("permitted client subnet: [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", htons(rangeaddr->u6_addr16[0]), htons(rangeaddr->u6_addr16[1]), diff --git a/xio-ip6.h b/xio-ip6.h index 431d4d1..5b03eb8 100644 --- a/xio-ip6.h +++ b/xio-ip6.h @@ -1,5 +1,5 @@ /* source: xio-ip6.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip6_h_included @@ -11,11 +11,11 @@ extern const struct optdesc opt_ipv6_v6only; extern const struct optdesc opt_ipv6_join_group; extern -int xioparsenetwork_ip6(const char *rangename, struct xiorange_ip6 *range); -extern int xiorange_ip6andmask(struct xiorange_ip6 *range); +int xioparsenetwork_ip6(const char *rangename, struct xiorange *range); +extern int xiorange_ip6andmask(struct xiorange *range); extern -int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange_ip6 *range); +int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range); #endif /* WITH_IP6 */ diff --git a/xio-listen.c b/xio-listen.c index 38a65c6..225beaf 100644 --- a/xio-listen.c +++ b/xio-listen.c @@ -83,6 +83,9 @@ int /* waits for incoming connection, checks its source address and port. Depending on fork option, it may fork a subprocess. + pf specifies the syntax expected for range option. In the case of generic + socket it is 0 (expcting raw binary data), and the real pf can be obtained + from us->af_family; for other socket types pf == us->af_family Returns 0 if a connection was accepted; with fork option, this is always in a subprocess! Other return values indicate a problem; this can happen in the master @@ -119,9 +122,9 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl xiosetchilddied(); /* set SIGCHLD handler */ } - if ((xfd->fd = Socket(pf, socktype, proto)) < 0) { + if ((xfd->fd = Socket(us->sa_family, socktype, proto)) < 0) { Msg4(level, - "socket(%d, %d, %d): %s", pf, socktype, proto, strerror(errno)); + "socket(%d, %d, %d): %s", us->sa_family, socktype, proto, strerror(errno)); return STAT_RETRYLATER; } @@ -161,15 +164,10 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl } #endif /* WITH_UNIX */ - retropt_int(opts, OPT_BACKLOG, &backlog); - if (Listen(xfd->fd, backlog) < 0) { - Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno)); - return STAT_RETRYLATER; - } - #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (parserange(rangename, us->sa_family, &xfd->para.socket.range) < 0) { + if (xioparserange(rangename, pf, &xfd->para.socket.range) + < 0) { free(rangename); return STAT_NORETRY; } @@ -189,6 +187,12 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport); #endif /* WITH_TCP || WITH_UDP */ + retropt_int(opts, OPT_BACKLOG, &backlog); + if (Listen(xfd->fd, backlog) < 0) { + Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno)); + return STAT_RETRYLATER; + } + if (xioopts.logopt == 'm') { Info("starting accept loop, switching to syslog"); diag_set('y', xioopts.syslogfac); xioopts.logopt = 'y'; diff --git a/xio-rawip.c b/xio-rawip.c index a1a0e09..df54555 100644 --- a/xio-rawip.c +++ b/xio-rawip.c @@ -170,7 +170,7 @@ int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts, /* which reply packets will be accepted - determine by range option */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (parserange(rangename, pf, &xfd->para.socket.range) < 0) { + if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } @@ -287,7 +287,8 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, #endif } - if (retropt_bind(opts, pf, socktype, ipproto, &/*us.soa*/xfd->stream.para.socket.la.soa, &uslen, 1, + if (retropt_bind(opts, pf, socktype, ipproto, + &/*us.soa*/xfd->stream.para.socket.la.soa, &uslen, 1, xfd->stream.para.socket.ip.res_opts[0], xfd->stream.para.socket.ip.res_opts[1]) == STAT_OK) { @@ -300,7 +301,8 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, xfd->stream.dtype = XIODATA_RECV_SKIPIP; result = _xioopen_dgram_recv(&xfd->stream, xioflags, - needbind?&xfd->stream.para.socket.la.soa:NULL, uslen, + needbind?&/*us.soa*/xfd->stream.para.socket.la.soa:NULL, + uslen, opts, pf, socktype, ipproto, E_ERROR); _xio_openlate(&xfd->stream, opts); return result; diff --git a/xio-socket.c b/xio-socket.c index 2bb3b47..4c83f18 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -2,7 +2,8 @@ /* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ -/* this file contains the source for socket related functions */ +/* this file contains the source for socket related functions, and the + implementation of generic socket addresses */ #include "xiosysincludes.h" @@ -18,9 +19,54 @@ #include "xio-ip6.h" #endif /* WITH_IP6 */ #include "xio-ip.h" +#include "xio-listen.h" #include "xio-ipapp.h" /*! not clean */ #include "xio-tcpwrap.h" + +static +int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xfd, unsigned groups, + int dummy1, int dummy2, int dummy3); +static +int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xfd, unsigned groups, + int dummy1, int dummy2, int dummy3); +static +int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xfd, unsigned groups, + int dummy1, int dummy2, int dummy3); +static +int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xfd, unsigned groups, + int dummy1, int dummy2, int dummy3); +static +int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xfd, unsigned groups, + int dummy1, int socktype, int dummy3); +static +int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xfd, unsigned groups, + int dumy1, int dummy2, int dummy3); + +static +int _xioopen_socket_sendto(const char *pfname, const char *type, + const char *proto, const char *address, + struct opt *opts, int xioflags, xiofile_t *xxfd, + unsigned groups); + + +/* generic socket addresses */ +const struct addrdesc xioaddr_socket_connect = { "socket-connect", 1, xioopen_socket_connect, GROUP_FD|GROUP_SOCKET|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; +const struct addrdesc xioaddr_socket_listen = { "socket-listen", 1, xioopen_socket_listen, GROUP_FD|GROUP_SOCKET|GROUP_LISTEN|GROUP_RANGE|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; +const struct addrdesc xioaddr_socket_sendto = { "socket-sendto", 3, xioopen_socket_sendto, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP("::::") }; +const struct addrdesc xioaddr_socket_datagram= { "socket-datagram", 3, xioopen_socket_datagram, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; +const struct addrdesc xioaddr_socket_recvfrom= { "socket-recvfrom", 3, xioopen_socket_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_RANGE|GROUP_CHILD, 0, 0, 0 HELP("::::") }; +const struct addrdesc xioaddr_socket_recv = { "socket-recv", 1, xioopen_socket_recv, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; + + +/* the following options apply not only to generic socket addresses but to all + addresses that have anything to do with sockets */ const struct optdesc opt_so_debug = { "so-debug", "debug", OPT_SO_DEBUG, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_DEBUG }; #ifdef SO_ACCEPTCONN /* AIX433 */ const struct optdesc opt_so_acceptconn={ "so-acceptconn","acceptconn",OPT_SO_ACCEPTCONN,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_ACCEPTCONN}; @@ -133,6 +179,498 @@ const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_STRING, OFUNC_SOCKOPT_GENERIC, 0, 0 }; +static +int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, + int dummy1, int dummy2, int dummy3) { + struct single *xfd = &xxfd->stream; + const char *pfname = argv[1]; + const char *protname = argv[2]; + const char *address = argv[3]; + char *garbage; + int pf; + int proto; + int socktype = SOCK_STREAM; + int needbind = 0; + union sockaddr_union them; socklen_t themlen; + union sockaddr_union us; socklen_t uslen = sizeof(us); + int result; + + if (argc != 4) { + Error2("%s: wrong number of parameters (%d instead of 3)", + argv[0], argc-1); + return STAT_NORETRY; + } + + pf = strtoul(pfname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + proto = strtoul(protname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + retropt_socket_pf(opts, &pf); + retropt_int(opts, OPT_SO_TYPE, &socktype); + /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ + xfd->howtoend = END_SHUTDOWN; + + applyopts(-1, opts, PH_INIT); + if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; + applyopts(-1, opts, PH_EARLY); + + themlen = 0; + if ((result = + dalan(address, (char *)&them.soa.sa_data, &themlen, sizeof(them))) + < 0) { + Error1("data too long: \"%s\"", address); + } else if (result > 0) { + Error1("syntax error in \"%s\"", address); + } + them.soa.sa_family = pf; + themlen += +#if HAVE_STRUCT_SOCKADDR_SALEN + sizeof(them.soa.sa_len) + +#endif + sizeof(them.soa.sa_family); + + xfd->dtype = XIOREAD_STREAM|XIOWRITE_STREAM; + + socket_init(0, &us); + if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3, + 0, 0) + != STAT_NOACTION) { + needbind = true; + us.soa.sa_family = pf; + } + + if ((result = + xioopen_connect(xfd, + needbind?(struct sockaddr *)&us:NULL, uslen, + (struct sockaddr *)&them, themlen, + opts, pf, socktype, proto, false)) != 0) { + return result; + } + if ((result = _xio_openlate(xfd, opts)) < 0) { + return result; + } + return STAT_OK; +} + +static +int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, + int dummy1, int dummy2, int dummy3) { + struct single *xfd = &xxfd->stream; + const char *pfname = argv[1]; + const char *protname = argv[2]; + const char *usname = argv[3]; + char *garbage; + int pf; + int proto; + int socktype = SOCK_STREAM; + union sockaddr_union us; socklen_t uslen; + struct opt *opts0; + int result; + + if (argc != 4) { + Error2("%s: wrong number of parameters (%d instead of 3)", + argv[0], argc-1); + return STAT_NORETRY; + } + + pf = strtoul(pfname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + proto = strtoul(protname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + retropt_socket_pf(opts, &pf); + retropt_int(opts, OPT_SO_TYPE, &socktype); + /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ + xfd->howtoend = END_SHUTDOWN; + + socket_init(0, &us); + uslen = 0; + if ((result = + dalan(usname, (char *)&us.soa.sa_data, &uslen, sizeof(us))) + < 0) { + Error1("data too long: \"%s\"", usname); + } else if (result > 0) { + Error1("syntax error in \"%s\"", usname); + } + uslen += sizeof(us.soa.sa_family) +#if HAVE_STRUCT_SOCKADDR_SALEN + + sizeof(us.soa.sa_len) +#endif + ; + us.soa.sa_family = pf; + + if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; + applyopts(-1, opts, PH_INIT); + applyopts(-1, opts, PH_EARLY); + + opts0 = copyopts(opts, GROUP_ALL); + + if ((result = + xioopen_listen(xfd, xioflags, + (struct sockaddr *)&us, uslen, + opts, opts0, 0/*instead of pf*/, socktype, proto)) + != STAT_OK) + return result; + return STAT_OK; +} + +/* we expect the form: ...:domain:type:protocol:remote-address */ +static +int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, + int dummy1, int dummy2, int dummy3) { + int result; + + if (argc != 5) { + Error2("%s: wrong number of parameters (%d instead of 4)", + argv[0], argc-1); + return STAT_NORETRY; + } + if ((result = + _xioopen_socket_sendto(argv[1], argv[2], argv[3], argv[4], + opts, xioflags, xxfd, groups)) + != STAT_OK) { + return result; + } + _xio_openlate(&xxfd->stream, opts); + return STAT_OK; +} + +static +int _xioopen_socket_sendto(const char *pfname, const char *type, + const char *protname, const char *address, + struct opt *opts, int xioflags, xiofile_t *xxfd, + unsigned groups) { + xiosingle_t *xfd = &xxfd->stream; + char *garbage; + union sockaddr_union us = {{0}}; + socklen_t uslen = 0; + socklen_t themlen = 0; + int pf; + int socktype = SOCK_RAW; + int proto; + bool needbind = false; + char *bindstring = NULL; + int result; + + pf = strtoul(pfname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + socktype = strtoul(type, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + proto = strtoul(protname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + retropt_socket_pf(opts, &pf); + retropt_int(opts, OPT_SO_TYPE, &socktype); + /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ + xfd->howtoend = END_SHUTDOWN; + + xfd->peersa.soa.sa_family = pf; + themlen = 0; + if ((result = + dalan(address, (char *)&xfd->peersa.soa.sa_data, &themlen, + sizeof(xfd->peersa))) + < 0) { + Error1("data too long: \"%s\"", address); + } else if (result > 0) { + Error1("syntax error in \"%s\"", address); + } + xfd->salen = themlen + sizeof(sa_family_t) +#if HAVE_STRUCT_SOCKADDR_SALEN + + sizeof(xfd->peersa.soa.sa_len) +#endif + ; +#if HAVE_STRUCT_SOCKADDR_SALEN + xfd->peersa.soa.sa_len = + sizeof(xfd->peersa.soa.sa_len) + sizeof(xfd->peersa.soa.sa_family) + + themlen; +#endif + + /* ...res_opts[] */ + if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; + applyopts(-1, opts, PH_INIT); + + if (pf == PF_UNSPEC) { + pf = xfd->peersa.soa.sa_family; + } + + xfd->dtype = XIODATA_RECVFROM; + + if (retropt_string(opts, OPT_BIND, &bindstring) == 0) { + uslen = 0; + if ((result = + dalan(bindstring, (char *)&us.soa.sa_data, &uslen, sizeof(us))) + < 0) { + Error1("data too long: \"%s\"", bindstring); + } else if (result > 0) { + Error1("syntax error in \"%s\"", bindstring); + } + us.soa.sa_family = pf; + uslen += sizeof(sa_family_t) +#if HAVE_STRUCT_SOCKADDR_SALEN + + sizeof(us.soa.sa_len) +#endif + ; + needbind = true; + } + + return + _xioopen_dgram_sendto(needbind?&us:NULL, uslen, + opts, xioflags, xfd, groups, pf, socktype, proto); +} + + +/* we expect the form: ...:domain:socktype:protocol:local-address */ +static +int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, + int dummy, int summy2, int dummy3) { + struct single *xfd = &xxfd->stream; + const char *pfname = argv[1]; + const char *typename = argv[2]; + const char *protname = argv[3]; + const char *address = argv[4]; + char *garbage; + union sockaddr_union *us = &xfd->para.socket.la; + socklen_t uslen = sizeof(*us); + int pf, socktype, proto; + char *rangename; + int result; + + if (argc != 5) { + Error2("%s: wrong number of parameters (%d instead of 4)", + argv[0], argc-1); + return STAT_NORETRY; + } + + pf = strtoul(pfname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + socktype = strtoul(typename, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + proto = strtoul(protname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + retropt_socket_pf(opts, &pf); + retropt_int(opts, OPT_SO_TYPE, &socktype); + /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ + xfd->howtoend = END_NONE; + + uslen = 0; + if ((result = + dalan(address, (char *)&us->soa.sa_data, &uslen, sizeof(*us))) + < 0) { + Error1("data too long: \"%s\"", address); + } else if (result > 0) { + Error1("syntax error in \"%s\"", address); + } + us->soa.sa_family = pf; + uslen += sizeof(us->soa.sa_family) +#if HAVE_STRUCT_SOCKADDR_SALEN + + sizeof(us->soa.sa_len); +#endif + ; + xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; + + if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { + if (xioparserange(rangename, 0, &xfd->para.socket.range) < 0) { + return STAT_NORETRY; + } + xfd->para.socket.dorange = true; + free(rangename); + } + + if ((result = + _xioopen_dgram_recvfrom(xfd, xioflags, &us->soa, uslen, + opts, pf, socktype, proto, E_ERROR)) + != STAT_OK) { + return result; + } + _xio_openlate(xfd, opts); + return STAT_OK; +} + +/* we expect the form: ...:domain:type:protocol:local-address */ +static +int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, + int dummy1, int dummy2, int dummy3) { + struct single *xfd = &xxfd->stream; + const char *pfname = argv[1]; + const char *typename = argv[2]; + const char *protname = argv[3]; + const char *address = argv[4]; + char *garbage; + union sockaddr_union us; + socklen_t uslen = sizeof(us); + int pf, socktype, proto; + char *rangename; + int result; + + if (argc != 5) { + Error2("%s: wrong number of parameters (%d instead of 4)", + argv[0], argc-1); + return STAT_NORETRY; + } + + pf = strtoul(pfname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + socktype = strtoul(typename, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + proto = strtoul(protname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + retropt_socket_pf(opts, &pf); + retropt_int(opts, OPT_SO_TYPE, &socktype); + /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ + xfd->howtoend = END_NONE; + + uslen = 0; + if ((result = + dalan(address, (char *)&us.soa.sa_data, &uslen, sizeof(us))) + < 0) { + Error1("data too long: \"%s\"", address); + } else if (result > 0) { + Error1("syntax error in \"%s\"", address); + } + us.soa.sa_family = pf; + uslen += sizeof(sa_family_t) +#if HAVE_STRUCT_SOCKADDR_SALEN + +sizeof(us.soa.sa_len) +#endif + ; + xfd->dtype = XIOREAD_RECV; + xfd->para.socket.la.soa.sa_family = pf; + + if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { + if (xioparserange(rangename, 0, &xfd->para.socket.range) < 0) { + return STAT_NORETRY; + } + xfd->para.socket.dorange = true; + free(rangename); + } + + if ((result = + _xioopen_dgram_recv(xfd, xioflags, &us.soa, + uslen, opts, pf, socktype, proto, E_ERROR)) + != STAT_OK) { + return result; + } + _xio_openlate(xfd, opts); + return STAT_OK; +} + + +/* we expect the form: ...:domain:type:protocol:remote-address */ +static +int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, + int dummy1, int dummy2, int dummy3) { + xiosingle_t *xfd = &xxfd->stream; + const char *pfname = argv[1]; + const char *typename = argv[2]; + const char *protname = argv[3]; + const char *address = argv[4]; + char *garbage; + char *rangename; + socklen_t themlen; + int pf; + int result; + + if (argc != 5) { + Error2("%s: wrong number of parameters (%d instead of 4)", + argv[0], argc-1); + return STAT_NORETRY; + } + + pf = strtoul(pfname, &garbage, 0); + if (*garbage != '\0') { + Warn1("garbage in parameter: \"%s\"", garbage); + } + + retropt_socket_pf(opts, &pf); + /*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/ + xfd->howtoend = END_SHUTDOWN; + + xfd->peersa.soa.sa_family = pf; + themlen = 0; + if ((result = + dalan(address, (char *)&xfd->peersa.soa.sa_data, &themlen, + sizeof(xfd->peersa))) + < 0) { + Error1("data too long: \"%s\"", address); + } else if (result > 0) { + Error1("syntax error in \"%s\"", address); + } + xfd->salen = themlen + sizeof(sa_family_t); +#if HAVE_STRUCT_SOCKADDR_SALEN + xfd->peersa.soa.sa_len = + sizeof(xfd->peersa.soa.sa_len) + sizeof(xfd->peersa.soa.sa_family) + + themlen; +#endif + + if ((result = + _xioopen_socket_sendto(pfname, typename, protname, address, + opts, xioflags, xxfd, groups)) + != STAT_OK) { + return result; + } + + xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; + + xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family; + + /* which reply sockets will accept - determine by range option */ + if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { + if (xioparserange(rangename, 0, &xfd->para.socket.range) < 0) { + free(rangename); + return STAT_NORETRY; + } + xfd->para.socket.dorange = true; + xfd->dtype |= XIOREAD_RECV_CHECKRANGE; + free(rangename); + } + + _xio_openlate(xfd, opts); + return STAT_OK; +} + /* a subroutine that is common to all socket addresses that want to connect to a peer address. @@ -658,9 +1196,9 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, } #endif /* WITH_UNIX */ -#if WITH_IP4 /*|| WITH_IP6*/ + /* for generic sockets, this has already been retrieved */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (parserange(rangename, pf, &xfd->para.socket.range) + if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) { free(rangename); return STAT_NORETRY; @@ -668,7 +1206,6 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, free(rangename); xfd->para.socket.dorange = true; } -#endif #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(xfd, opts); @@ -913,7 +1450,7 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags, #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (parserange(rangename, pf, &xfd->para.socket.range) + if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) { free(rangename); return STAT_NORETRY; @@ -1032,17 +1569,17 @@ int xiogetpacketsrc(int fd, union sockaddr_union *pa, socklen_t *palen) { } -int xiocheckrange(union sockaddr_union *sa, union xiorange_union *range) { +int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) { switch (sa->soa.sa_family) { #if WITH_IP4 case PF_INET: return - xiocheckrange_ip4(&sa->ip4, &range->ip4); + xiocheckrange_ip4(&sa->ip4, range); #endif /* WITH_IP4 */ #if WITH_IP6 case PF_INET6: return - xiocheckrange_ip6(&sa->ip6, &range->ip6); + xiocheckrange_ip6(&sa->ip6, range); #endif /* WITH_IP6 */ } return -1; @@ -1133,4 +1670,107 @@ int xiocheckpeer(xiosingle_t *xfd, return 0; /* permitted */ } + +/* parses a network specification consisting of an address and a mask. */ +int xioparsenetwork(const char *rangename, int pf, struct xiorange *range) { + size_t addrlen = 0, masklen = 0; + int result; + + switch (pf) { +#if WITH_IP4 + case PF_INET: + return xioparsenetwork_ip4(rangename, range); + break; +#endif /* WITH_IP4 */ +#if WITH_IP6 + case PF_INET6: + return xioparsenetwork_ip6(rangename, range); + break; +#endif /* WITH_IP6 */ + case PF_UNSPEC: + { + char *addrname; + const char *maskname; + if ((maskname = strchr(rangename, ':')) == NULL) { + Error1("syntax error in range \"%s\": use :", rangename); + return STAT_NORETRY; + } + ++maskname; /* skip ':' */ + if ((addrname = Malloc(maskname-rangename)) == NULL) { + return STAT_NORETRY; + } + strncpy(addrname, rangename, maskname-rangename-1); + result = + dalan(addrname, (char *)&range->netaddr.soa.sa_data, &addrlen, + sizeof(range->netaddr)-(size_t)(&((struct sockaddr *)0)->sa_data) + /* data length */); + if (result < 0) { + Error1("data too long: \"%s\"", addrname); + free(addrname); return STAT_NORETRY; + } else if (result > 0) { + Error1("syntax error in \"%s\"", addrname); + free(addrname); return STAT_NORETRY; + } + free(addrname); + result = + dalan(maskname, (char *)&range->netmask.soa.sa_data, &masklen, + sizeof(range->netaddr)-(size_t)(&((struct sockaddr *)0)->sa_data) + /* data length */); + if (result < 0) { + Error1("data too long: \"%s\"", maskname); + return STAT_NORETRY; + } else if (result > 0) { + Error1("syntax error in \"%s\"", maskname); + return STAT_NORETRY; + } + if (addrlen != masklen) { + Error2("network address is "F_Zu" bytes long, mask is "F_Zu" bytes long", + addrlen, masklen); + /* recover by padding the shorter component with 0 */ + memset((char *)&range->netaddr.soa.sa_data+addrlen, 0, + MAX(0, addrlen-masklen)); + memset((char *)&range->netmask.soa.sa_data+masklen, 0, + MAX(0, masklen-addrlen)); + } + } + break; + default: + Error1("range option not supported with address family %d", pf); + return STAT_NORETRY; + } + return STAT_OK; +} + +/* parses a string of form address/bits or address:mask, and fills the fields + of the range union. The addr component is masked with mask. */ +int xioparserange(const char *rangename, int pf, struct xiorange *range) { + int i; + if (xioparsenetwork(rangename, pf, range) < 0) { + return -1; + } + /* we have parsed the address and mask; now we make sure that the stored + address has 0 where mask is 0, to simplify comparisions */ + switch (pf) { +#if WITH_IP4 + case PF_INET: + range->netaddr.ip4.sin_addr.s_addr &= range->netmask.ip4.sin_addr.s_addr; + break; +#endif /* WITH_IP4 */ +#if WITH_IP6 + case PF_INET6: + return xiorange_ip6andmask(range); + break; +#endif /* WITH_IP6 */ + case PF_UNSPEC: + for (i = 0; i < sizeof(range->netaddr); ++i) { + ((char *)&range->netaddr)[i] &= ((char *)&range->netmask)[i]; + } + break; + default: + Error1("range option not supported with address family %d", pf); + return STAT_NORETRY; + } + return 0; +} + #endif /* _WITH_SOCKET */ diff --git a/xio-socket.h b/xio-socket.h index 5a68920..7f8ac0c 100644 --- a/xio-socket.h +++ b/xio-socket.h @@ -5,6 +5,13 @@ #ifndef __xio_socket_h_included #define __xio_socket_h_included 1 +extern const struct addrdesc xioaddr_socket_connect; +extern const struct addrdesc xioaddr_socket_listen; +extern const struct addrdesc xioaddr_socket_sendto; +extern const struct addrdesc xioaddr_socket_datagram; +extern const struct addrdesc xioaddr_socket_recvfrom; +extern const struct addrdesc xioaddr_socket_recv; + extern const struct optdesc opt_connect_timeout; extern const struct optdesc opt_so_debug; extern const struct optdesc opt_so_acceptconn; @@ -89,5 +96,10 @@ int xiogetpacketsrc(int fd, union sockaddr_union *pa, socklen_t *palen); extern int xiocheckpeer(xiosingle_t *xfd, union sockaddr_union *pa, union sockaddr_union *la); +extern +int xioparsenetwork(const char *rangename, int pf, + struct xiorange *range); +extern +int xioparserange(const char *rangename, int pf, struct xiorange *range); #endif /* !defined(__xio_socket_h_included) */ diff --git a/xio-tun.c b/xio-tun.c index 1bc8709..3729d5b 100644 --- a/xio-tun.c +++ b/xio-tun.c @@ -70,7 +70,7 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl char *tundevice = NULL; char *tunname = NULL, *tuntype = NULL; int pf = /*! PF_UNSPEC*/ PF_INET; - union xiorange_union network; + struct xiorange network; bool no_pi = false; const char *namedargv[] = { "tun", NULL, NULL }; int rw = (xioflags & XIO_ACCMODE); @@ -157,12 +157,14 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl return result; } socket_init(pf, (union sockaddr_union *)&ifr.ifr_addr); - ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = network.ip4.netaddr; + ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = + network.netaddr.ip4.sin_addr; if (Ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) { Error4("ioctl(%d, SIOCSIFADDR, {\"%s\", \"%s\"}: %s", sockfd, ifr.ifr_name, ifaddr, strerror(errno)); } - ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr = network.ip4.netmask; + ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr = + network.netmask.ip4.sin_addr; if (Ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) { Error4("ioctl(%d, SIOCSIFNETMASK, {\"0x%08u\", \"%s\"}, %s", sockfd, ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr, diff --git a/xio-udp.c b/xio-udp.c index 293b8be..101adca 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -145,7 +145,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (parserange(rangename, pf, &fd->stream.para.socket.range) < 0) { + if (xioparserange(rangename, pf, &fd->stream.para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } @@ -424,7 +424,7 @@ int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, /* which reply packets will be accepted - determine by range option */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (parserange(rangename, pf, &xfd->para.socket.range) < 0) { + if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } @@ -582,7 +582,7 @@ int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { - if (parserange(rangename, pf, &xfd->stream.para.socket.range) < 0) { + if (xioparserange(rangename, pf, &xfd->stream.para.socket.range) < 0) { return STAT_NORETRY; } xfd->stream.para.socket.dorange = true; diff --git a/xio-unix.c b/xio-unix.c index b0c6b95..c8d8510 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -84,6 +84,9 @@ xiosetunix(struct sockaddr_un *saun, } else { len = sizeof(struct sockaddr_un); } +#if HAVE_STRUCT_SOCKADDR_SALEN + saun->sun_len = len; +#endif } else { if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) { Warn2("socket address "F_Zu" characters long, truncating to "F_Zu"", @@ -225,7 +228,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, if ((result = _xio_openlate(xfd, opts)) < 0) { return result; } - return 0; + return STAT_OK; } diff --git a/xio.h b/xio.h index 4dc1464..eea9db6 100644 --- a/xio.h +++ b/xio.h @@ -177,7 +177,7 @@ typedef struct single { union sockaddr_union la; /* local socket address */ bool emptyiseof; /* with dgram: empty packet means EOF */ bool dorange; - union xiorange_union range; /* restrictions for peer address */ + struct xiorange range; /* restrictions for peer address */ #if _WITH_IP4 || _WITH_IP6 struct { unsigned int res_opts[2]; /* bits to be set in _res.options are diff --git a/xioclose.c b/xioclose.c index 850e26f..e08666b 100644 --- a/xioclose.c +++ b/xioclose.c @@ -66,12 +66,12 @@ int xioclose1(struct single *pipe) { case END_CLOSE: case END_CLOSE_KILL: if (Close(pipe->fd) < 0) { Info2("close(%d): %s", pipe->fd, strerror(errno)); } break; -#if WITH_SOCKET +#if _WITH_SOCKET case END_SHUTDOWN: case END_SHUTDOWN_KILL: if (Shutdown(pipe->fd, 2) < 0) { Info3("shutdown(%d, %d): %s", pipe->fd, 2, strerror(errno)); } break; -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ case END_UNLINK: if (Unlink((const char *)pipe->name) < 0) { Warn2("unlink(\"%s\"): %s", pipe->name, strerror(errno)); } break; diff --git a/xioconfig.h b/xioconfig.h index f474b61..a0379c6 100644 --- a/xioconfig.h +++ b/xioconfig.h @@ -47,13 +47,13 @@ # endif #endif -#if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_RAWIP -# define WITH_SOCKET 1 +#if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_RAWIP || WITH_GENERICSOCKET +# define _WITH_SOCKET 1 #else -# undef WITH_SOCKET +# undef _WITH_SOCKET #endif -#if !WITH_SOCKET +#if !_WITH_SOCKET # undef WITH_LISTEN #endif @@ -61,7 +61,7 @@ # undef WITH_LIBWRAP #endif -#if WITH_SOCKET || WITH_TUN +#if WITH_GENERICSOCKET || WITH_TUN # define _WITH_SOCKET 1 #endif diff --git a/xiomodes.h b/xiomodes.h index b48c9b7..90a6745 100644 --- a/xiomodes.h +++ b/xiomodes.h @@ -1,5 +1,5 @@ /* source: xiomodes.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiomodes_h_included @@ -15,7 +15,7 @@ #include "xio-creat.h" #include "xio-gopen.h" #include "xio-pipe.h" -#if WITH_SOCKET +#if _WITH_SOCKET #include "xio-socket.h" #include "xio-listen.h" #include "xio-unix.h" @@ -30,7 +30,7 @@ #include "xio-udp.h" #include "xio-socks.h" #include "xio-proxy.h" -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ #include "xio-progcall.h" #include "xio-exec.h" #include "xio-system.h" diff --git a/xioopen.c b/xioopen.c index f944740..e178231 100644 --- a/xioopen.c +++ b/xioopen.c @@ -37,6 +37,10 @@ const struct addrname addressnames[] = { { "creat", &addr_creat }, { "create", &addr_creat }, #endif +#if WITH_GENERICSOCKET + { "datagram", &xioaddr_socket_datagram }, + { "dgram", &xioaddr_socket_datagram }, +#endif #if WITH_PIPE { "echo", &addr_pipe }, #endif @@ -131,6 +135,17 @@ const struct addrname addressnames[] = { #if WITH_READLINE { "readline", &addr_readline }, #endif +#if WITH_GENERICSOCKET + { "sendto", &xioaddr_socket_sendto }, +#endif +#if WITH_GENERICSOCKET + { "socket-connect", &xioaddr_socket_connect }, + { "socket-datagram", &xioaddr_socket_datagram }, + { "socket-listen", &xioaddr_socket_listen }, + { "socket-recv", &xioaddr_socket_recv }, + { "socket-recvfrom", &xioaddr_socket_recvfrom }, + { "socket-sendto", &xioaddr_socket_sendto }, +#endif #if WITH_SOCKS4 { "socks", &addr_socks4_connect }, { "socks4", &addr_socks4_connect }, @@ -296,9 +311,9 @@ static xiofile_t *xioallocfd(void) { fd->stream.fd = -1; fd->stream.dtype = XIODATA_STREAM; -#if WITH_SOCKET +#if _WITH_SOCKET /* fd->stream.salen = 0; */ -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ fd->stream.howtoend = END_UNSPEC; /* fd->stream.name = NULL; */ /* fd->stream.para.exec.pid = 0; */ diff --git a/xioopts.c b/xioopts.c index 4022ca2..674b901 100644 --- a/xioopts.c +++ b/xioopts.c @@ -40,7 +40,7 @@ bool xioopts_ignoregroups; # define IF_EXEC(a,b) #endif -#if WITH_SOCKET +#if _WITH_SOCKET # define IF_SOCKET(a,b) {a,b}, #else # define IF_SOCKET(a,b) @@ -2608,13 +2608,13 @@ int retropt_string(struct opt *opts, int optcode, char **result) { } -#if WITH_SOCKET +#if _WITH_SOCKET /* looks for an bind option and, if found, overwrites the complete contents of sa with the appropriate value(s). returns STAT_OK if option exists and could be resolved, STAT_NORETRY if option exists but had error, or STAT_NOACTION if it does not exist */ -/* currently only for IP (v4, v6) */ +/* currently only for IP (v4, v6) and raw (PF_UNSPEC) */ int retropt_bind(struct opt *opts, int af, int socktype, @@ -2636,22 +2636,26 @@ int retropt_bind(struct opt *opts, if (retropt_string(opts, OPT_BIND, &bindname) < 0) { return STAT_NOACTION; } - addrallowed = true; - portallowed = (feats>=2); bindp = bindname; - nestlex((const char **)&bindp, &hostp, &hostlen, ends, NULL, NULL, nests, - true, false, false); - *hostp++ = '\0'; - if (!strncmp(bindp, portsep, strlen(portsep))) { - if (!portallowed) { - Error("port specification not allowed in this bind option"); - return STAT_NORETRY; - } else { - portp = bindp + strlen(portsep); - } - } switch (af) { + + case AF_UNSPEC: + { + size_t p = 0; + dalan(bindname, (char *)sa->sa_data, &p, *salen-sizeof(sa->sa_family)); + *salen = p + sizeof(sa->sa_family); + *salen = p + +#if HAVE_STRUCT_SOCKADDR_SALEN + sizeof(sa->sa_len) + +#endif + sizeof(sa->sa_family); +#if HAVE_STRUCT_SOCKADDR_SALEN + sa->sa_len = *salen; +#endif + } + break; + #if WITH_IP4 || WITH_IP6 #if WITH_IP4 case AF_INET: @@ -2659,6 +2663,19 @@ int retropt_bind(struct opt *opts, #if WITH_IP6 case AF_INET6: #endif /*WITH_IP6 */ + addrallowed = true; + portallowed = (feats>=2); + nestlex((const char **)&bindp, &hostp, &hostlen, ends, NULL, NULL, nests, + true, false, false); + *hostp++ = '\0'; + if (!strncmp(bindp, portsep, strlen(portsep))) { + if (!portallowed) { + Error("port specification not allowed in this bind option"); + return STAT_NORETRY; + } else { + portp = bindp + strlen(portsep); + } + } if ((result = xiogetaddrinfo(hostname[0]!='\0'?hostname:NULL, portp, af, socktype, ipproto, @@ -2687,7 +2704,7 @@ int retropt_bind(struct opt *opts, } return STAT_OK; } -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ /* applies to fd all options belonging to phase */ @@ -2806,7 +2823,7 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { opt->desc->type); } -#if WITH_SOCKET +#if _WITH_SOCKET } else if (opt->desc->func == OFUNC_SOCKOPT) { if (0) { ; @@ -3015,7 +3032,7 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { Error1("setsockopt() data type %d not implemented", opt->desc->type); } -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ #if HAVE_FLOCK } else if (opt->desc->func == OFUNC_FLOCK) { @@ -3728,7 +3745,7 @@ int applyopts_single(struct single *xfd, struct opt *opts, enum e_phase phase) { } break; -#if WITH_SOCKET +#if _WITH_SOCKET case OFUNC_SOCKOPT: switch (opt->desc->optcode) { #if WITH_IP4 && (defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)) @@ -3879,7 +3896,7 @@ mc:addr ++opt; continue; } break; -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ default: ++opt; diff --git a/xioread.c b/xioread.c index 5db886c..039401f 100644 --- a/xioread.c +++ b/xioread.c @@ -109,7 +109,7 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { break; #endif /* WITH_OPENSSL */ -#if WITH_SOCKET +#if _WITH_SOCKET case XIOREAD_RECV: if (pipe->dtype & XIOREAD_RECV_FROM) { #if WITH_RAWIP || WITH_UDP || WITH_UNIX @@ -354,7 +354,7 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { } break; -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ default: Error("internal: undefined read operation"); diff --git a/xioshutdown.c b/xioshutdown.c index 0f48639..30d3adf 100644 --- a/xioshutdown.c +++ b/xioshutdown.c @@ -1,5 +1,5 @@ /* source: xioshutdown.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source of the extended shutdown function */ @@ -65,7 +65,7 @@ int xioshutdown(xiofile_t *sock, int how) { sock->stream.para.exec.fdout, strerror(errno)); } } -#if WITH_SOCKET +#if _WITH_SOCKET } else if (sock->stream.howtoend == END_SHUTDOWN) { if ((result = Shutdown(sock->stream.fd, how)) < 0) { Info3("shutdown(%d, %d): %s", @@ -107,7 +107,7 @@ int xioshutdown(xiofile_t *sock, int how) { sock->stream.eof = 2; sock->stream.fd = -1; } -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ #if 0 } else { Error1("xioshutdown(): bad data type specification %d", sock->stream.dtype); diff --git a/xiowrite.c b/xiowrite.c index d02e48b..2bc9379 100644 --- a/xiowrite.c +++ b/xiowrite.c @@ -76,7 +76,7 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) { } break; -#if WITH_SOCKET +#if _WITH_SOCKET case XIOWRITE_SENDTO: /*union { char space[sizeof(struct sockaddr_un)]; @@ -117,7 +117,7 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) { sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff))); } break; -#endif /* WITH_SOCKET */ +#endif /* _WITH_SOCKET */ case XIOWRITE_PIPE: do { From 3d95d9d6795f16eb7374a73e2ef9757a173691e5 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 20 Sep 2008 21:42:50 +0200 Subject: [PATCH 21/75] improve docu and comments of generic sockets --- doc/socat.yo | 113 ++++++++++++++++++++++++++------------------------- xio-listen.c | 12 +++--- 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/doc/socat.yo b/doc/socat.yo index 741461a..d88f492 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -10,7 +10,7 @@ def(Filan)(0)(bf(Filan)) def(procan)(0)(bf(procan)) def(Procan)(0)(bf(Procan)) -manpage(socat)(1)(Feb 2008)(socat)() +manpage(socat)(1)(Sep 2008)(socat)() whenhtml( label(CONTENTS) @@ -601,15 +601,15 @@ label(ADDRESS_READLINE)dit(bf(tt(READLINE))) link(STDIO)(ADDRESS_STDIO) label(ADDRESS_SOCKET_CONNECT)dit(bf(tt(SOCKET-CONNECT:::))) Creates a stream socket using the first and second given socket parameters - and tt(SOCK_STREAM) (see man - socket(2)) and connects to the remote-address. The - two socket parameters have to be specified as numbers of type - link(int)(TYPE_INT). Consult your OS documentation and include files to find - the desired values. The remote-address must be the link(data)(TYPE_DATA) - representation of a sockaddr structure without the sa_family component.nl() + and tt(SOCK_STREAM) (see man socket(2)) and connects to the remote-address. + The two socket parameters have to be specified by link(int)(TYPE_INT) + numbers. Consult your OS documentation and include files to find the + appropriate values. The remote-address must be the link(data)(TYPE_DATA) + representation of a sockaddr structure without sa_family and (BSD) sa_len + components.nl() Please note that you can - beyond the options of the specified groups - also - apply options of higher level protocols when you use socat option - link(-s)(option_s).nl() + use options of higher level protocols when you apply socat option + link(-g)(option_g).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY)nl() Useful options: link(bind)(OPTION_BIND), @@ -624,15 +624,16 @@ label(ADDRESS_SOCKET_CONNECT)dit(bf(tt(SOCKET-CONNECT::::::))) - Creates a datagram socket using the first three given socket parameters (see man - socket(2)) and sends outgoing data to the remote-address. The - three socket parameters have to be specified as numbers of type - link(int)(TYPE_INT). Consult your OS documentation and include files to find - the desired values. The remote-address must be the link(data)(TYPE_DATA) - representation of a sockaddr structure without the sa_family component.nl() + Creates a datagram socket using the first three given socket parameters (see + man socket(2)) and sends outgoing data to the remote-address. The three + socket parameters have to be specified by link(int)(TYPE_INT) + numbers. Consult your OS documentation and include files to find the + appropriate values. The remote-address must be the link(data)(TYPE_DATA) + representation of a sockaddr structure without sa_family and (BSD) sa_len + components.nl() Please note that you can - beyond the options of the specified groups - also - apply options of higher level protocols when you use socat option - link(-s)(option_s).nl() + use options of higher level protocols when you apply socat option + link(-g)(option_g).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(RANGE)(GROUP_RANGE) Useful options: link(bind)(OPTION_BIND), @@ -649,15 +650,15 @@ label(ADDRESS_SOCKET_DATAGRAM)dit(bf(tt(SOCKET-DATAGRAM:::::))) Creates a stream socket using the first and second given socket parameters - and tt(SOCK_STREAM) (see man - socket(2)) and waits for incoming connections on local-address. The - two socket parameters have to be specified as numbers of type - link(int)(TYPE_INT). Consult your OS documentation and include files to find - the desired values. The local-address must be the link(data)(TYPE_DATA) - representation of a sockaddr structure without the sa_family component.nl() + and tt(SOCK_STREAM) (see man socket(2)) and waits for incoming connections + on local-address. The two socket parameters have to be specified by + link(int)(TYPE_INT) numbers. Consult your OS documentation and include files + to find the appropriate values. The local-address must be the + link(data)(TYPE_DATA) representation of a sockaddr structure without + sa_family and (BSD) sa_len components.nl() Please note that you can - beyond the options of the specified groups - also - apply options of higher level protocols when you use socat option - link(-s)(option_s).nl() + use options of higher level protocols when you apply socat option + link(-g)(option_g).nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(RANGE)(GROUP_RANGE),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY)nl() Useful options: link(setsockopt-int)(OPTION_SETSOCKOPT_INT), @@ -672,12 +673,12 @@ label(ADDRESS_SOCKET_LISTEN)dit(bf(tt(SOCKET-LISTEN::::::))) - Creates a socket using the three given socket parameters (see man - socket(2)) and binds it to . Receives arriving data. The - three parameters have to be specified as numbers of type - link(int)(TYPE_INT). Consult your OS documentation and include files to find - the desired values. The local-address must be the link(data)(TYPE_DATA) - representation of a sockaddr structure without the sa_family component.nl() + Creates a socket using the three given socket parameters (see man socket(2)) + and binds it to . Receives arriving data. The three + parameters have to be specified by link(int)(TYPE_INT) numbers. Consult your + OS documentation and include files to find the appropriate values. The + local-address must be the link(data)(TYPE_DATA) representation of a sockaddr + structure without sa_family and (BSD) sa_len components.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(RANGE)(GROUP_RANGE) Useful options: link(range)(OPTION_RANGE), @@ -693,13 +694,13 @@ label(ADDRESS_SOCKET_RECV)dit(bf(tt(SOCKET_RECV:::::::))) - Creates a socket using the three given socket parameters (see man - socket(2)) and binds it to . Receives arriving data and sends - replies back to the sender. The first three parameters have to be specified as - numbers of type link(int)(TYPE_INT). Consult your OS documentation and - include files to find the desired values. The local-address must be the - link(data)(TYPE_DATA) - representation of a sockaddr structure without the sa_family component.nl() + Creates a socket using the three given socket parameters (see man socket(2)) + and binds it to . Receives arriving data and sends replies + back to the sender. The first three parameters have to be specified as + link(int)(TYPE_INT) numbers. Consult your OS documentation and include files + to find the appropriate values. The local-address must be the + link(data)(TYPE_DATA) representation of a sockaddr structure without + sa_family and (BSD) sa_len components.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) Useful options: link(fork)(OPTION_FORK), @@ -717,12 +718,12 @@ label(ADDRESS_SOCKET_RECVFROM)dit(bf(tt(SOCKET_RECVFROM::::::))) Creates a socket using the three given socket parameters (see man - socket(2)). Sends outgoing data to the given address and receives replies. - The three parameters have to be specified as - numbers of type link(int)(TYPE_INT). Consult your OS documentation and - include files to find the desired values. The remote-address must be the - link(data)(TYPE_DATA) representation of a sockaddr structure without the - sa_family component.nl() + socket(2)). Sends outgoing data to the given address and receives replies. + The three parameters have to be specified as link(int)(TYPE_INT) + numbers. Consult your OS documentation and include files to find the + appropriate values. The remote-address must be the link(data)(TYPE_DATA) + representation of a sockaddr structure without sa_family and (BSD) sa_len + components.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) Useful options: link(bind)(OPTION_BIND), @@ -1793,20 +1794,22 @@ label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=))) something like "ip4" or "ip6". label(OPTION_SETSOCKOPT_INT)dit(bf(tt(setsockopt-int=::))) Invokes tt(setsockopt()) for the socket with the given parameters. tt(level) - [link(int)(TYPE_INT)] specifies the second argument to tt(setsockopt()) - which specifies the layer, e.g. SOL_TCP (=6 on Linux) for TCP, or SOL_SOCKET - (=1 on Linux) for the socket layer. tt(optname) [link(int)(TYPE_INT)] - selects the third argument to tt(setsockopt()) option. For the actual - integer values you might have to look up the appropriate include file of - your system. The 4th tt(setsockopt()) parameter, tt(value) - [link(int)(TYPE_INT)], is passed to the function per pointer, and the length - parameter to the tt(setsockopt()) call is derived from this type. + [link(int)(TYPE_INT)] is used as second argument to tt(setsockopt()) and + specifies the layer, e.g. SOL_TCP for TCP (6 on Linux), or SOL_SOCKET for + the socket layer (1 on Linux). tt(optname) [link(int)(TYPE_INT)] is the + third argument to tt(setsockopt()) and tells which socket option is to be + set. For the actual numbers you might have to look up the appropriate include + files of your system. The 4th tt(setsockopt()) parameter, tt(value) + [link(int)(TYPE_INT)], is passed to the function per pointer, and for the + length parameter sizeof(int) is taken implicitely. label(OPTION_SETSOCKOPT_BIN)dit(bf(tt(setsockopt-bin=::))) - Like tt(setsockopt-int), but is expected in link(dalan)(TYPE_DATA) - format and specifies an arbitrary sequence of bytes. + Like tt(setsockopt-int), but must be provided in + link(dalan)(TYPE_DATA) format and specifies an arbitrary sequence of bytes; + the length parameter is automatically derived from the data. label(OPTION_SETSOCKOPT_STRING)dit(bf(tt(setsockopt-string=::))) Like tt(setsockopt-int), but must be a link(string)(TYPE_STRING). - This string is passed to the function with trailing null character. + This string is passed to the function with trailing null character, and the + length parameter is automatically derived from the data. enddit() startdit()enddit()nl() diff --git a/xio-listen.c b/xio-listen.c index 225beaf..a788c6f 100644 --- a/xio-listen.c +++ b/xio-listen.c @@ -81,18 +81,18 @@ int } -/* waits for incoming connection, checks its source address and port. Depending +/* Waits for incoming connection, checks its source address and port. Depending on fork option, it may fork a subprocess. pf specifies the syntax expected for range option. In the case of generic - socket it is 0 (expcting raw binary data), and the real pf can be obtained + socket it is 0 (expecting raw binary data), and the real pf can be obtained from us->af_family; for other socket types pf == us->af_family - Returns 0 if a connection was accepted; with fork option, this is always in - a subprocess! + Returns 0 if a connection was accepted; with fork option, this is already in + the subprocess! Other return values indicate a problem; this can happen in the master - process or in a subprocess. + process or in the subprocess. This function does not retry. If you need retries, handle this is a loop in the calling function. - after fork, we set the forever/retry of the child process to 0 + After fork, we set the forever/retry of the child process to 0 */ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level) { From 9809b977e2d8dc6e05032b39f0c5dfa51590c182 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 11 Feb 2008 21:54:01 +0100 Subject: [PATCH 22/75] filan -s prefixes output with FD number if more than one FD --- CHANGES | 3 +++ fdname.c | 7 +++++-- filan.h | 5 +++-- filan_main.c | 22 +++++++++++++++------- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index e78e07a..d9bb2b9 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,9 @@ corrections: replaced the select() calls by poll() to cleanly fix the problems with many file descriptors already open +further changes: + filan -s prefixes output with FD number if more than one FD + ####################### V 1.6.0.1: new features: diff --git a/fdname.c b/fdname.c index 8ede9fe..b0d6210 100644 --- a/fdname.c +++ b/fdname.c @@ -1,5 +1,5 @@ /* source: fdname.c */ -/* Copyright Gerhard Rieger 2003-2007 */ +/* Copyright Gerhard Rieger 2003-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the subroutine sockname prints the basic info about the address of a socket @@ -32,7 +32,7 @@ int unixame(int fd, FILE *outfile); int tcpname(int fd, FILE *outfile); -int fdname(const char *file, int fd, FILE *outfile) { +int fdname(const char *file, int fd, FILE *outfile, const char *numform) { struct stat buf = {0}; int filetype; Debug1("checking file descriptor %u", fd); @@ -46,6 +46,9 @@ int fdname(const char *file, int fd, FILE *outfile) { } } filetype = (buf.st_mode&S_IFMT)>>12; + if (numform != NULL) { + fprintf(outfile, numform, fd); + } return statname(file, fd, filetype, outfile); } else { if (Stat(file, &buf) < 0) { diff --git a/filan.h b/filan.h index 8ed3484..ca02950 100644 --- a/filan.h +++ b/filan.h @@ -1,5 +1,5 @@ /* source: filan.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ @@ -33,6 +33,7 @@ extern int ipan(int fd, FILE *outfile); extern int ip6an(int fd, FILE *outfile); #endif /* WITH_SOCKET */ -extern int fdname(const char *file, int fd, FILE *outfile); +extern + int fdname(const char *file, int fd, FILE *outfile, const char *numform); #endif /* !defined(__filan_h_included) */ diff --git a/filan_main.c b/filan_main.c index c03f8e2..32366a1 100644 --- a/filan_main.c +++ b/filan_main.c @@ -1,5 +1,5 @@ /* source: filan_main.c */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ const char copyright[] = "filan by Gerhard Rieger - see http://www.dest-unreach.org/socat/"; @@ -23,7 +23,8 @@ static void filan_usage(FILE *fd); int main(int argc, const char *argv[]) { const char **arg1, *a; const char *filename = NULL, *waittimetxt; - unsigned int m = 0, n = 1024; /* this is default on my Linux */ + unsigned int m = 0; /* first FD (default) */ + unsigned int n = 1024; /* last excl.; this is default on my Linux */ unsigned int i; int style = 0; struct timespec waittime = { 0, 0 }; @@ -57,7 +58,7 @@ int main(int argc, const char *argv[]) { } } m = strtoul(a, (char **)&a, 0); - n = m+1; + n = m; break; case 'n': if (arg1[0][2]) { a = *arg1+2; @@ -168,6 +169,9 @@ int main(int argc, const char *argv[]) { #endif filan_file(filename, fdout); } else { + if (m == n) { + ++n; + } for (i = m; i < n; ++i) { filan_fd(i, fdout); } @@ -189,12 +193,16 @@ int main(int argc, const char *argv[]) { Debug2("open(\"%s\", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0700): %s", filename, strerror(errno)); } - fdname(filename, fd, fdout); + fdname(filename, fd, fdout, NULL); #endif - fdname(filename, -1, fdout); + fdname(filename, -1, fdout, NULL); } else { - for (i = m; i < n; ++i) { - fdname("", i, fdout); + if (m == n) { + fdname("", m, fdout, NULL); + } else { + for (i = m; i < n; ++i) { + fdname("", i, fdout, "%5u "); + } } } } From e74c247fafe39e1ad0de390b57b87477dc62ffca Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 16 Feb 2008 10:45:34 +0100 Subject: [PATCH 23/75] use FD_SETSIZE instead of 1024 as FD limit --- filan_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/filan_main.c b/filan_main.c index 32366a1..866b271 100644 --- a/filan_main.c +++ b/filan_main.c @@ -24,7 +24,7 @@ int main(int argc, const char *argv[]) { const char **arg1, *a; const char *filename = NULL, *waittimetxt; unsigned int m = 0; /* first FD (default) */ - unsigned int n = 1024; /* last excl.; this is default on my Linux */ + unsigned int n = FD_SETSIZE; /* last excl. */ unsigned int i; int style = 0; struct timespec waittime = { 0, 0 }; @@ -233,7 +233,7 @@ static void filan_usage(FILE *fd) { fputs(" -ls log to stderr (default if no other log)\n", fd); #endif fputs(" -i only analyze this fd\n", fd); - fputs(" -n analyze all fds from 0 up to fdnum-1 (default: 1024)\n", fd); + fprintf(fd, " -n analyze all fds from 0 up to fdnum-1 (default: %u)\n", FD_SETSIZE); fputs(" -s simple output with just type and socket address or path\n", fd); /* fputs(" -c alternate device visualization\n", fd);*/ fputs(" -f analyze file system entry\n", fd); From c86345a615c33547f531f47615b22e5ecba67c97 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 20 Sep 2008 23:01:10 +0200 Subject: [PATCH 24/75] new address option "escape" allows to break a socat instance --- CHANGES | 4 +++ VERSION | 2 +- doc/socat.yo | 18 ++++++++----- socat.c | 72 ++++++++++++++++++++++++++++++++++++++++++---------- test.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++ xio-tun.c | 4 +-- xio.h | 2 ++ xiolayer.c | 1 + xiolayer.h | 3 ++- xioopen.c | 3 ++- xioopts.c | 3 +++ xioopts.h | 3 +++ 12 files changed, 152 insertions(+), 26 deletions(-) diff --git a/CHANGES b/CHANGES index e78e07a..4b1f8df 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +new features: + new address option "escape" allows to break a socat instance even when + raw terminal mode prevents ^C etc. + corrections: some raw IP and UNIX datagram modes failed on BSD systems diff --git a/VERSION b/VERSION index 9a06c88..f509df5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape" diff --git a/doc/socat.yo b/doc/socat.yo index 4befd5b..d422aef 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -10,7 +10,7 @@ def(Filan)(0)(bf(Filan)) def(procan)(0)(bf(procan)) def(Procan)(0)(bf(Procan)) -manpage(socat)(1)(Feb 2008)(socat)() +manpage(socat)(1)(Jul 2008)(socat)() whenhtml( label(CONTENTS) @@ -1516,6 +1516,10 @@ label(OPTION_LOCKFILE)dit(bf(tt(lockfile=))) label(OPTION_WAITLOCK)dit(bf(tt(waitlock=))) If lockfile exists, waits until it disappears. When lockfile does not exist, creates it and continues, unlinks lockfile on exit. +label(OPTION_ESCAPE)dit(bf(tt(escape=))) + Specifies the numeric code of a character that triggers EOF on the input + stream. It is useful with a terminal in raw mode + (link(example)(EXAMPLE_OPTION_ESCAPE)). enddit() startdit()enddit()nl() @@ -2630,13 +2634,15 @@ at most 512 data bytes per packet (link(mss)(OPTION_MSS)). label(EXAMPLE_ADDRESS_GOPEN) label(EXAMPLE_OPTION_RAW) label(EXAMPLE_OPTION_ECHO) -dit(bf(tt(socat - /dev/ttyS0,raw,echo=0,crnl))) +label(EXAMPLE_OPTION_ESCAPE) +dit(bf(tt(socat -,raw,echo=0,escape=0x0f /dev/ttyS0,raw,echo=0,crnl))) Opens an interactive connection via the serial line, e.g. for talking with a -modem. link(raw)(OPTION_RAW) and link(echo)(OPTION_ECHO) set ttyS0's terminal -parameters to practicable values, link(crnl)(OPTION_CRNL) -converts to correct newline characters. Consider using -link(READLINE)(ADDRESS_READLINE) instead of `-'. +modem. link(raw)(OPTION_RAW) and link(echo)(OPTION_ECHO) set the console's and +ttyS0's terminal parameters to practicable values, link(crnl)(OPTION_CRNL) +converts to correct newline characters. link(escape)(OPTION_ESCAPE) allows to +terminate the socat process with character control-O. +Consider using link(READLINE)(ADDRESS_READLINE) instead of the first address. label(EXAMPLE_ADDRESS_UNIX_LISTEN) diff --git a/socat.c b/socat.c index 3128ec9..3ff3d17 100644 --- a/socat.c +++ b/socat.c @@ -947,7 +947,11 @@ int _socat(void) { XIO_RDSTREAM(sock1)->actbytes == 0) { /* avoid idle when all readbytes already there */ mayrd1 = true; - } + } + /* escape char occurred? */ + if (XIO_RDSTREAM(sock1)->actescape) { + bytes1 = 0; /* indicate EOF */ + } } /* (bytes1 == 0) handled later */ } else { @@ -976,6 +980,10 @@ int _socat(void) { /* avoid idle when all readbytes already there */ mayrd2 = true; } + /* escape char occurred? */ + if (XIO_RDSTREAM(sock2)->actescape) { + bytes2 = 0; /* indicate EOF */ + } } /* (bytes2 == 0) handled later */ } else { @@ -988,7 +996,8 @@ int _socat(void) { bytes1, XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock1)->ignoreeof, closing);*/ if (bytes1 == 0 || XIO_RDSTREAM(sock1)->eof >= 2) { - if (XIO_RDSTREAM(sock1)->ignoreeof && !closing) { + if (XIO_RDSTREAM(sock1)->ignoreeof && + !XIO_RDSTREAM(sock1)->actescape && !closing) { Debug1("socket 1 (fd %d) is at EOF, ignoring", XIO_RDSTREAM(sock1)->fd); /*! */ mayrd1 = true; @@ -996,16 +1005,20 @@ int _socat(void) { } else { Notice1("socket 1 (fd %d) is at EOF", XIO_GETRDFD(sock1)); xioshutdown(sock2, SHUT_WR); + XIO_RDSTREAM(sock1)->eof = 2; + XIO_RDSTREAM(sock1)->ignoreeof = false; if (socat_opts.lefttoright) { break; } + closing = 1; } } else if (polling && XIO_RDSTREAM(sock1)->ignoreeof) { polling = 0; } if (bytes2 == 0 || XIO_RDSTREAM(sock2)->eof >= 2) { - if (XIO_RDSTREAM(sock2)->ignoreeof && !closing) { + if (XIO_RDSTREAM(sock2)->ignoreeof && + !XIO_RDSTREAM(sock2)->actescape && !closing) { Debug1("socket 2 (fd %d) is at EOF, ignoring", XIO_RDSTREAM(sock2)->fd); mayrd2 = true; @@ -1013,9 +1026,12 @@ int _socat(void) { } else { Notice1("socket 2 (fd %d) is at EOF", XIO_GETRDFD(sock2)); xioshutdown(sock1, SHUT_WR); + XIO_RDSTREAM(sock2)->eof = 2; + XIO_RDSTREAM(sock2)->ignoreeof = false; if (socat_opts.righttoleft) { break; } + closing = 1; } } else if (polling && XIO_RDSTREAM(sock2)->ignoreeof) { polling = 0; @@ -1102,8 +1118,9 @@ static int /* inpipe is suspected to have read data available; read at most bufsiz bytes and transfer them to outpipe. Perform required data conversions. - buff should be at least twice as large as bufsiz, to allow all standard - conversions. Returns the number of bytes written, or 0 on EOF or <0 if an + buff must be a malloc()'ed storage and might be realloc()'ed in this + function if more space is required after conversions. + Returns the number of bytes written, or 0 on EOF or <0 if an error occurred or when data was read but none written due to conversions (with EAGAIN). EAGAIN also occurs when reading from a nonblocking FD where the file has a mandatory lock. @@ -1113,9 +1130,9 @@ static int /* inpipe, outpipe must be single descriptors (not dual!) */ int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe, unsigned char **buff, size_t bufsiz, bool righttoleft) { - ssize_t bytes, writt; + ssize_t bytes, writt = 0; - bytes = xioread(inpipe, *buff, socat_opts.bufsiz); + bytes = xioread(inpipe, *buff, bufsiz); if (bytes < 0) { if (errno != EAGAIN) XIO_RDSTREAM(inpipe)->eof = 2; @@ -1123,14 +1140,35 @@ int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe, return -1; } if (bytes == 0 && XIO_RDSTREAM(inpipe)->ignoreeof && !closing) { - writt = 0; + ; } else if (bytes == 0) { XIO_RDSTREAM(inpipe)->eof = 2; closing = MAX(closing, 1); - writt = 0; } - else /* if (bytes > 0)*/ { + if (bytes > 0) { + /* handle escape char */ + if (XIO_RDSTREAM(inpipe)->escape != -1) { + /* check input data for escape char */ + unsigned char *ptr = *buff; + size_t ctr = 0; + while (ctr < bytes) { + if (*ptr == XIO_RDSTREAM(inpipe)->escape) { + /* found: set flag, truncate input data */ + XIO_RDSTREAM(inpipe)->actescape = true; + bytes = ctr; + Info("escape char found in input"); + break; + } + ++ptr; ++ctr; + } + if (ctr != bytes) { + XIO_RDSTREAM(inpipe)->eof = 2; + } + } + } + + if (bytes > 0) { if (XIO_RDSTREAM(inpipe)->lineterm != XIO_WRSTREAM(outpipe)->lineterm) { @@ -1248,8 +1286,14 @@ int xiotransfer(xiofile_t *inpipe, xiofile_t *outpipe, #define LF '\n' -int cv_newline(unsigned char **buff, ssize_t *bytes, +/* converts the newline characters (or character sequences) from the one + specified in lineterm1 to that of lineterm2. Possible values are + LINETERM_CR, LINETERM_CRNL, LINETERM_RAW. + buff points to the malloc()'ed data, input and output. It may be subject to + realloc(). bytes specifies the number of bytes input and output */ +int cv_newline(unsigned char **buff, ssize_t *bufsiz, int lineterm1, int lineterm2) { + ssize_t *bytes = bufsiz; /* must perform newline changes */ if (lineterm1 <= LINETERM_CR && lineterm2 <= LINETERM_CR) { /* no change in data length */ @@ -1287,7 +1331,7 @@ int cv_newline(unsigned char **buff, ssize_t *bytes, *t++ = *s++; } } - *bytes = t - *buff; + *bufsiz = t - *buff; } else { /* buffer becomes longer, must alloc another space */ unsigned char *buf2; @@ -1297,7 +1341,7 @@ int cv_newline(unsigned char **buff, ssize_t *bytes, } else { from = '\r'; } - if ((buf2 = Malloc(2*socat_opts.bufsiz+1)) == NULL) { + if ((buf2 = Malloc(2*socat_opts.bufsiz/*sic!*/+1)) == NULL) { return -1; } s = *buff; t = buf2; z = *buff + *bytes; @@ -1312,7 +1356,7 @@ int cv_newline(unsigned char **buff, ssize_t *bytes, } free(*buff); *buff = buf2; - *bytes = t - buf2;; + *bufsiz = t - buf2;; } return 0; } diff --git a/test.sh b/test.sh index 5cbb3ec..1398ed1 100755 --- a/test.sh +++ b/test.sh @@ -8447,6 +8447,69 @@ esac N=$((N+1)) +# test the escape option +NAME=ESCAPE +case "$TESTS" in +*%functions%*|*%escape%*|*%$NAME%*) +TEST="$NAME: escape character triggers EOF" +# idea: start socat just echoing input, but apply escape option. send a string +# containing the escape character and check if the output is truncated +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD="$SOCAT $opts -,escape=27 pipe" +printf "test $F_n $TEST... " $N +$ECHO "$da\n\x1bXYZ" |$CMD >"$tf" 2>"$te" +if [ $? -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD" + cat "$te" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED: diff:\n" + cat "$tdiff" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi +esac +N=$((N+1)) + +# test the escape option combined with ignoreeof +NAME=ESCAPE_IGNOREEOF +case "$TESTS" in +*%functions%*|*%ignoreeof%*|*%escape%*|*%$NAME%*) +TEST="$NAME: escape character triggers EOF" +# idea: start socat just echoing input, but apply escape option. send a string +# containing the escape character and check if the output is truncated +ti="$td/test$N.file" +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD="$SOCAT -T 5 $opts file:$ti,ignoreeof,escape=27!!- pipe" +printf "test $F_n $TEST... " $N +>"$ti" +$CMD >"$tf" 2>"$te" & +$ECHO "$da\n\x1bXYZ" >>"$ti" +sleep 1 +if ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED: diff:\n" + cat "$tdiff" + cat "$te" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi +esac +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/xio-tun.c b/xio-tun.c index 1bc8709..dbc86cc 100644 --- a/xio-tun.c +++ b/xio-tun.c @@ -1,5 +1,5 @@ /* source: xio-tun.c */ -/* Copyright Gerhard Rieger 2007 */ +/* Copyright Gerhard Rieger 2007-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of tun/tap type */ @@ -17,8 +17,6 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); -#define XIO_OFFSETOF(x) ((size_t)&((xiosingle_t *)0)->x) - /****** TUN addresses ******/ const struct optdesc opt_tun_device = { "tun-device", NULL, OPT_TUN_DEVICE, GROUP_TUN, PH_OPEN, TYPE_FILENAME, OFUNC_SPEC }; const struct optdesc opt_tun_name = { "tun-name", NULL, OPT_TUN_NAME, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC }; diff --git a/xio.h b/xio.h index f5b1926..930d6bd 100644 --- a/xio.h +++ b/xio.h @@ -167,6 +167,8 @@ typedef struct single { const char *name; /* only with END_UNLINK */ int (*sigchild)(struct single *); /* callback after sigchild */ pid_t ppid; /* parent pid, only if we send it signals */ + int escape; /* escape character; -1 for no escape */ + bool actescape; /* escape character found in input data */ union { struct { int fdout; /* use fd for output */ diff --git a/xiolayer.c b/xiolayer.c index 4801b92..7ae6bd3 100644 --- a/xiolayer.c +++ b/xiolayer.c @@ -16,6 +16,7 @@ const struct optdesc opt_crnl = { "crnl", NULL, OPT_CRNL, GROUP_A const struct optdesc opt_readbytes = { "readbytes", "bytes", OPT_READBYTES, GROUP_APPL, PH_LATE, TYPE_SIZE_T, OFUNC_EXT, (int)(&((struct single *)0)->readbytes), sizeof(((struct single *)0)->readbytes) }; const struct optdesc opt_lockfile = { "lockfile", NULL, OPT_LOCKFILE, GROUP_APPL, PH_INIT, TYPE_FILENAME, OFUNC_EXT, 0, 0 }; const struct optdesc opt_waitlock = { "waitlock", NULL, OPT_WAITLOCK, GROUP_APPL, PH_INIT, TYPE_FILENAME, OFUNC_EXT, 0, 0 }; +const struct optdesc opt_escape = { "escape", NULL, OPT_ESCAPE, GROUP_APPL, PH_INIT, TYPE_INT, OFUNC_OFFSET, XIO_OFFSETOF(escape), sizeof(((xiosingle_t *)0)->escape) }; /****** APPL addresses ******/ #if WITH_RETRY const struct optdesc opt_forever = { "forever", NULL, OPT_FOREVER, GROUP_RETRY, PH_INIT, TYPE_BOOL, OFUNC_EXT, (int)(&((struct single *)0)->forever), sizeof(((struct single *)0)->forever) }; diff --git a/xiolayer.h b/xiolayer.h index 926dede..4ec2c5e 100644 --- a/xiolayer.h +++ b/xiolayer.h @@ -1,5 +1,5 @@ /* source: xiolayer.h */ -/* Copyright Gerhard Rieger 2001-2005 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiolayer_h_included @@ -11,6 +11,7 @@ extern const struct optdesc opt_crnl; extern const struct optdesc opt_readbytes; extern const struct optdesc opt_lockfile; extern const struct optdesc opt_waitlock; +extern const struct optdesc opt_escape; extern const struct optdesc opt_forever; extern const struct optdesc opt_intervall; extern const struct optdesc opt_retry; diff --git a/xioopen.c b/xioopen.c index f944740..76f3a91 100644 --- a/xioopen.c +++ b/xioopen.c @@ -1,5 +1,5 @@ /* source: xioopen.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source file of the extended open function */ @@ -301,6 +301,7 @@ static xiofile_t *xioallocfd(void) { #endif /* WITH_SOCKET */ fd->stream.howtoend = END_UNSPEC; /* fd->stream.name = NULL; */ + fd->stream.escape = -1; /* fd->stream.para.exec.pid = 0; */ fd->stream.lineterm = LINETERM_RAW; diff --git a/xioopts.c b/xioopts.c index ad76434..dfbb1ef 100644 --- a/xioopts.c +++ b/xioopts.c @@ -397,6 +397,7 @@ const struct optname optionnames[] = { IF_TERMIOS("eol2", &opt_veol2) IF_TERMIOS("erase", &opt_verase) IF_SOCKET ("error", &opt_so_error) + IF_ANY ("escape", &opt_escape) IF_OPEN ("excl", &opt_o_excl) #if WITH_EXT2 && defined(EXT2_APPEND_FL) IF_ANY ("ext2-append", &opt_ext2_append) @@ -3339,6 +3340,8 @@ static int applyopt_offset(struct single *xfd, struct opt *opt) { switch (opt->desc->type) { case TYPE_BOOL: *(bool *)ptr = opt->value.u_bool; break; + case TYPE_INT: + *(int *)ptr = opt->value.u_int; break; case TYPE_DOUBLE: *(double *)ptr = opt->value.u_double; break; case TYPE_TIMEVAL: diff --git a/xioopts.h b/xioopts.h index 849cb46..81ff412 100644 --- a/xioopts.h +++ b/xioopts.h @@ -9,6 +9,8 @@ #define ODESC_DONE ((void *)-1) /* indicates that option has been applied */ #define ODESC_ERROR ODESC_DONE /* maybe later */ +#define XIO_OFFSETOF(x) ((size_t)&((xiosingle_t *)0)->x) + /* atomic structure for use in the option search table; keep compatible with struct wordent! */ struct optname { @@ -250,6 +252,7 @@ enum e_optcode { OPT_ECHOPRT, /* termios.c_lflag */ #endif OPT_END_CLOSE, /* xfd.stream.howtoend = END_CLOSE */ + OPT_ESCAPE, OPT_EXT2_SECRM, OPT_EXT2_UNRM, OPT_EXT2_COMPR, From de910892f2798c5184c1234fe21afd83a9d56f88 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 20 Sep 2008 23:37:56 +0200 Subject: [PATCH 25/75] new address "interface" for transparent network interface handling --- CHANGES | 4 ++ Makefile.in | 12 ++++-- VERSION | 2 +- config.h.in | 9 ++++- configure.in | 23 +++++++++++ doc/socat.yo | 29 +++++++++++-- socat.c | 5 +++ sysincludes.h | 8 +++- sysutils.c | 31 +++++++++----- sysutils.h | 6 +-- test.sh | 55 +++++++++++++++++++++++++ xio-interface.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ xio-interface.h | 10 +++++ xio-socket.c | 4 +- xiomodes.h | 3 +- xioopen.c | 8 +++- xioopts.c | 8 ++-- xioread.c | 9 +++++ 18 files changed, 300 insertions(+), 31 deletions(-) create mode 100644 xio-interface.c create mode 100644 xio-interface.h diff --git a/CHANGES b/CHANGES index e78e07a..c783fb0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +new features: + new address "interface" for transparent network interface handling + (suggested by Stuart Nicholson) + corrections: some raw IP and UNIX datagram modes failed on BSD systems diff --git a/Makefile.in b/Makefile.in index 583985b..aabc06e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -44,7 +44,9 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ - xio-socket.c xio-listen.c xio-unix.c xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c xio-socks.c xio-proxy.c xio-udp.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c \ @@ -59,9 +61,11 @@ PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ - xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h xio-socket.h \ - xio-listen.h xio-unix.h xio-rawip.h xio-ip.h xio-ip4.h xio-ip6.h \ - xio-ipapp.h xio-tcp.h xio-udp.h xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h diff --git a/VERSION b/VERSION index 9a06c88..8119a18 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+interface" diff --git a/config.h.in b/config.h.in index 2e330da..b99d769 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,5 @@ /* source: config.h.in */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included @@ -227,6 +227,12 @@ /* Define if you have the header file. */ #undef HAVE_LINUX_IF_TUN_H +/* Define if you have the header file. */ +#undef HAVE_NETPACKET_PACKET_H + +/* Define if you have the header file. */ +#undef HAVE_NETINET_IF_ETHER_H + /* Define if you have the header file. */ #undef HAVE_SYS_UTSNAME_H @@ -456,6 +462,7 @@ #undef WITH_IP4 #undef WITH_IP6 #undef WITH_RAWIP +#undef WITH_INTERFACE #undef WITH_TCP #undef WITH_UDP #undef WITH_LISTEN diff --git a/configure.in b/configure.in index f3161ce..69a5150 100644 --- a/configure.in +++ b/configure.in @@ -196,6 +196,29 @@ AC_ARG_ENABLE(rawip, [ --disable-rawip disable raw IP support], esac], [AC_DEFINE(WITH_RAWIP) AC_MSG_RESULT(yes)]) +AC_MSG_CHECKING(whether to include raw network INTERFACE support) +AC_ARG_ENABLE(interface, [ --disable-interface disable network interface support], + [case "$enableval" in + no) AC_MSG_RESULT(no); WITH_INTERFACE= ;; + *) AC_MSG_RESULT(yes); WITH_INTERFACE=1 ;; + esac], + [AC_MSG_RESULT(yes); WITH_INTERFACE=1 ]) +if test "$WITH_INTERFACE"; then + AC_CHECK_HEADER(netpacket/packet.h, + AC_DEFINE(HAVE_NETPACKET_PACKET_H), + [WITH_INTERFACE=; + AC_MSG_WARN([include file netpacket/packet.h not found, disabling INTERFACE])]) +fi +if test "$WITH_INTERFACE"; then + AC_CHECK_HEADER(netinet/if_ether.h, + AC_DEFINE(HAVE_NETINET_IF_ETHER_H), + [WITH_INTERFACE=; + AC_MSG_WARN([include file netinet/if_ether.h not found, disabling INTERFACE])]) +fi +if test "$WITH_INTERFACE"; then + AC_DEFINE(WITH_INTERFACE) +fi + AC_MSG_CHECKING(whether to include TCP support) AC_ARG_ENABLE(tcp, [ --disable-tcp disable TCP support], [case "$enableval" in diff --git a/doc/socat.yo b/doc/socat.yo index 4befd5b..c141e11 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -540,6 +540,15 @@ label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:))) link(mode)(OPTION_MODE), link(unlink-early)(OPTION_UNLINK_EARLY)nl() See also: link(unnamed pipe)(ADDRESS_UNNAMED_PIPE) +label(ADDRESS_INTERFACE)dit(bf(tt(INTERFACE:))) + Communicate with a network connected on an interface using raw packets + including link level data. link()(TYPE_INTERFACE) is the name of + the network interface. Currently only available on Linux. + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) nl() + Useful options: + link(pf)(OPTION_PROTOCOL_FAMILY) + link(so-type)(OPTION_SO_TYPE)nl() + See also: link(ip-recv)(ADDRESS_IP_RECV) label(ADDRESS_UNNAMED_PIPE)dit(bf(tt(PIPE))) Creates an unnamed pipe and uses it for reading and writing. It works as an echo, because everything written @@ -1585,7 +1594,7 @@ label(OPTION_SNDLOWAT)dit(bf(tt(sndlowat=))) layer will send the data to [link(int)(TYPE_INT)]. label(OPTION_SNDTIMEO)dit(bf(tt(sndtimeo=))) Sets the send timeout to seconds [link(timeval)(TYPE_TIMEVAL)]. -label(OPTION_TYPE)dit(bf(tt(type=))) +label(OPTION_SO_TYPE)dit(bf(tt(type=))) Sets the type of the socket, usually as argument to the code(socket()) or code(socketpair()) call, to [link(int)(TYPE_INT)]. Under Linux, 1 means stream oriented socket, 2 means datagram socket, and 3 @@ -1633,8 +1642,8 @@ COMMENT(label(OPTION_SIOCSPGRP)dit(bf(tt(siocspgrp=))) COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs))) Set the code(SO_USE_IFBUFS) socket option.) label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=))) - Forces the use of the specified IP version. can be - something like "ip4" or "ip6". + Forces the use of the specified IP version or protocol family. can + be something like "ip4" or "ip6" or a number. enddit() startdit()enddit()nl() @@ -2433,7 +2442,8 @@ label(TYPE_INT)dit(int) "0", i.e. decimal number, octal number with leading "0", or hexadecimal number with leading "0x". The value must fit into a C int. label(TYPE_INTERFACE)dit(interface) - A string specifying the device name of a network interface, e.g. "eth0". + A string specifying the device name of a network interface + as shown by ifconfig or procan, e.g. "eth0". label(TYPE_IP_ADDRESS)dit(IP address) An IPv4 address in numbers-and-dots notation, an IPv6 address in hex notation enclosed in brackets, or a hostname that resolves to an IPv4 or an @@ -2883,6 +2893,17 @@ client and server authentication (see OpenSSL link(client)(EXAMPLE_ADDRESS_OPENSSL_CONNECT) and link(server)(EXAMPLE_ADDRESS_OPENSSL_LISTEN)). + +label(EXAMPLE_INTERFACE) +dit(bf(tt(socat PTY,link=/var/run/ppp,raw,echo=0 INTERFACE:hdlc0))) + +circumvents the problem that pppd requires a serial device and thus might not +be able to work on a synchronous line that is represented by a network device. +socat creates a PTY to make pppd happy, binds to the network interface hdlc0, +and can transfer data between both devices. Use pppd on device /var/run/ppp +then. + + enddit() diff --git a/socat.c b/socat.c index 3128ec9..40c2831 100644 --- a/socat.c +++ b/socat.c @@ -426,6 +426,11 @@ void socat_version(FILE *fd) { #else fputs(" #undef WITH_RAWIP\n", fd); #endif +#ifdef WITH_INTERFACE + fprintf(fd, " #define WITH_INTERFACE %d\n", WITH_INTERFACE); +#else + fputs(" #undef WITH_INTERFACE\n", fd); +#endif #ifdef WITH_TCP fprintf(fd, " #define WITH_TCP %d\n", WITH_TCP); #else diff --git a/sysincludes.h b/sysincludes.h index f233358..7f62497 100644 --- a/sysincludes.h +++ b/sysincludes.h @@ -1,5 +1,5 @@ /* source: sysincludes.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sysincludes_h_included @@ -116,6 +116,12 @@ #if HAVE_NET_IF_H #include #endif /* HAVE_NET_IF_H */ +#if HAVE_NETPACKET_PACKET_H +#include +#endif +#if HAVE_NETINET_IF_ETHER_H +#include +#endif #if HAVE_LINUX_IF_TUN_H #include #endif diff --git a/sysutils.c b/sysutils.c index 28ccae9..d55b636 100644 --- a/sysutils.c +++ b/sysutils.c @@ -115,7 +115,7 @@ socklen_t socket_init(int af, union sockaddr_union *sa) { #if WITH_IP6 case AF_INET6: socket_in6_init(&sa->ip6); return sizeof(sa->ip6); #endif - default: Error1("socket_init(): unknown address family %d", af); + default: Info1("socket_init(): unknown address family %d", af); memset(sa, 0, sizeof(union sockaddr_union)); sa->soa.sa_family = af; return 0; @@ -436,8 +436,12 @@ int parseport(const char *portname, int ipproto) { #if WITH_IP4 || WITH_IP6 /* check the systems interfaces for ifname and return its index - or -1 if no interface with this name was found */ -int ifindexbyname(const char *ifname) { + or -1 if no interface with this name was found + The system calls require an arbitrary socket; the calling program may + provide one in anysock to avoid creation of a dummy socket. anysock must be + <0 if it does not specify a socket fd. + */ +int ifindexbyname(const char *ifname, int anysock) { /* Linux: man 7 netdevice */ /* FreeBSD: man 4 networking */ /* Solaris: man 7 if_tcp */ @@ -445,29 +449,35 @@ int ifindexbyname(const char *ifname) { #if defined(HAVE_STRUCT_IFREQ) && defined(SIOCGIFCONF) && defined(SIOCGIFINDEX) /* currently we support Linux, FreeBSD; not Solaris */ -#define IFBUFSIZ 1024 +#define IFBUFSIZ 32*sizeof(struct ifreq) /*1024*/ int s; struct ifreq ifr; if (ifname[0] == '\0') { return -1; } - if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + if (anysock >= 0) { + s = anysock; + } else if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno)); return -1; } strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) { - Close(s); - Info3("ioctl(%d, SIOCGIFINDEX, {%s}): %s", + Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s", s, ifr.ifr_name, strerror(errno)); + Close(s); return -1; } Close(s); #if HAVE_STRUCT_IFREQ_IFR_INDEX + Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}) -> { %d }", + s, ifname, ifr.ifr_index); return ifr.ifr_index; #elif HAVE_STRUCT_IFREQ_IFR_IFINDEX + Info3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}) -> { %d }", + s, ifname, ifr.ifr_ifindex); return ifr.ifr_ifindex; #endif /* HAVE_STRUCT_IFREQ_IFR_IFINDEX */ @@ -477,10 +487,11 @@ int ifindexbyname(const char *ifname) { } -/* like ifindexbyname(), but allows an index number as input. +/* like ifindexbyname(), but also allows the index number as input - in this + case it does not lookup the index. writes the resulting index to *ifindex and returns 0, or returns -1 on error */ -int ifindex(const char *ifname, unsigned int *ifindex) { +int ifindex(const char *ifname, unsigned int *ifindex, int anysock) { char *endptr; long int val; @@ -493,7 +504,7 @@ int ifindex(const char *ifname, unsigned int *ifindex) { return 0; } - if ((val = ifindexbyname(ifname)) < 0) { + if ((val = ifindexbyname(ifname, anysock)) < 0) { return -1; } *ifindex = val; diff --git a/sysutils.h b/sysutils.h index b9074b3..84cf84d 100644 --- a/sysutils.h +++ b/sysutils.h @@ -1,5 +1,5 @@ /* source: sysutils.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sysutils_h_included @@ -94,7 +94,7 @@ extern int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout); extern int parseport(const char *portname, int proto); -extern int ifindexbyname(const char *ifname); -extern int ifindex(const char *ifname, unsigned int *ifindex); +extern int ifindexbyname(const char *ifname, int anysock); +extern int ifindex(const char *ifname, unsigned int *ifindex, int anysock); #endif /* !defined(__sysutils_h_included) */ diff --git a/test.sh b/test.sh index 5cbb3ec..aa6543d 100755 --- a/test.sh +++ b/test.sh @@ -7737,6 +7737,61 @@ PORT=$((PORT+1)) N=$((N+1)) +# use the INTERFACE address on a tun/tap device and transfer data fully +# transparent +NAME=TUNINTERFACE +case "$TESTS" in +*%functions%*|*%tun%*|*%interface%*|*%root%*|*%$NAME%*) +TEST="$NAME: pass data through tun interface using INTERFACE" +#idea: create a TUN interface and send a raw packet on the interface side. +# It should arrive unmodified on the tunnel side. +if ! feat=$(testaddrs ip4 tun interface) || ! runsip4 >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N + numCANT=$((numCANT+1)) +elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +tl="$td/test$N.lock" +da="$(date) $RANDOM" +dalen=$((${#da}+1)) +TUNNET=10.255.255 +TUNNAME=tun9 +CMD1="$SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME echo" +CMD="$SOCAT $opts - INTERFACE:$TUNNAME" +printf "test $F_n $TEST... " $N +$CMD1 2>"${te}1" & +pid1="$!" +#waitinterface "$TUNNAME" +sleep 1 +echo "$da" |$CMD 2>"${te}1" >"$tf" 2>"${te}" +kill $pid1 2>/dev/null +wait +if [ $? -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD &" + echo "$CMD1" + cat "${te}" "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + cat "${te}" "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi + numOK=$((numOK+1)) +fi +fi ;; # not feats, not root +esac +PORT=$((PORT+1)) +N=$((N+1)) + + NAME=ABSTRACTSTREAM case "$TESTS" in *%functions%*|*%unix%*|*%abstract%*|*%connect%*|*%listen%*|*%$NAME%*) diff --git a/xio-interface.c b/xio-interface.c new file mode 100644 index 0000000..f7ebb1b --- /dev/null +++ b/xio-interface.c @@ -0,0 +1,105 @@ +/* source: xio-interface.c */ +/* Copyright Gerhard Rieger 2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +/* this file contains the source for opening addresses of raw socket type */ + +#include "xiosysincludes.h" + +#if WITH_INTERFACE + +#include "xioopen.h" +#include "xio-socket.h" + +#include "xio-interface.h" + + +static +int xioopen_interface(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xfd, unsigned groups, int pf, + int dummy2, int dummy3); + +const struct addrdesc xioaddr_interface= { "interface", 3, xioopen_interface, GROUP_FD|GROUP_SOCKET, PF_PACKET, 0, 0 HELP(":") }; + + +static +int _xioopen_interface(const char *ifname, + struct opt *opts, int xioflags, xiofile_t *xxfd, + unsigned groups, int pf) { + xiosingle_t *xfd = &xxfd->stream; + union sockaddr_union us = {{0}}; + socklen_t uslen; + int socktype = SOCK_RAW; + unsigned int ifidx; + bool needbind = false; + char *bindstring = NULL; + struct sockaddr_ll sall = { 0 }; + + if (ifindex(ifname, &ifidx, -1) < 0) { + Error1("unknown interface \"%s\"", ifname); + ifidx = 0; /* desparate attempt to continue */ + } + + xfd->howtoend = END_SHUTDOWN; + retropt_int(opts, OPT_SO_TYPE, &socktype); + + retropt_socket_pf(opts, &pf); + + /* ...res_opts[] */ + if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; + applyopts(-1, opts, PH_INIT); + + xfd->salen = sizeof(xfd->peersa); + if (pf == PF_UNSPEC) { + pf = xfd->peersa.soa.sa_family; + } + + xfd->dtype = XIODATA_RECVFROM_SKIPIP; + + if (retropt_string(opts, OPT_BIND, &bindstring)) { + needbind = true; + } + /*!!! parse by ':' */ + ((struct sockaddr_ll *)&us)->sll_family = pf; + ((struct sockaddr_ll *)&us)->sll_protocol = htons(ETH_P_ALL); + ((struct sockaddr_ll *)&us)->sll_ifindex = ifidx; + uslen = sizeof(sall); + needbind = true; + xfd->peersa = (union sockaddr_union)us; + + return + _xioopen_dgram_sendto(needbind?&us:NULL, uslen, + opts, xioflags, xfd, groups, pf, socktype, 0); +} + +static +int xioopen_interface(int argc, const char *argv[], struct opt *opts, + int xioflags, xiofile_t *xxfd, unsigned groups, + int pf, int dummy2, int dummy3) { + xiosingle_t *xfd = &xxfd->stream; + int result; + + if (argc != 2) { + Error2("%s: wrong number of parameters (%d instead of 1)", + argv[0], argc-1); + return STAT_NORETRY; + } + + if ((result = + _xioopen_interface(argv[1], opts, xioflags, xxfd, groups, pf)) + != STAT_OK) { + return result; + } + + xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; + if (pf == PF_INET) { + xfd->dtype |= XIOREAD_RECV_SKIPIP; + } + + xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family; + + _xio_openlate(xfd, opts); + return STAT_OK; +} + +#endif /* WITH_INTERFACE */ diff --git a/xio-interface.h b/xio-interface.h new file mode 100644 index 0000000..c7ed866 --- /dev/null +++ b/xio-interface.h @@ -0,0 +1,10 @@ +/* source: xio-interface.h */ +/* Copyright Gerhard Rieger 2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __xio_interface_h_included +#define __xio_interface_h_included 1 + +extern const struct addrdesc xioaddr_interface; + +#endif /* !defined(__xio_interface_h_included) */ diff --git a/xio-socket.c b/xio-socket.c index d93bb98..b0dcfcc 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -936,8 +936,8 @@ int retropt_socket_pf(struct opt *opts, int *pf) { char *pfname; if (retropt_string(opts, OPT_PROTOCOL_FAMILY, &pfname) >= 0) { - if (false) { - ; + if (isdigit(pfname[0])) { + *pf = strtoul(pfname, NULL /*!*/, 0); #if WITH_IP4 } else if (!strcasecmp("inet", pfname) || !strcasecmp("inet4", pfname) || diff --git a/xiomodes.h b/xiomodes.h index b48c9b7..8576a2b 100644 --- a/xiomodes.h +++ b/xiomodes.h @@ -1,5 +1,5 @@ /* source: xiomodes.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xiomodes_h_included @@ -20,6 +20,7 @@ #include "xio-listen.h" #include "xio-unix.h" #include "xio-rawip.h" +#include "xio-interface.h" #include "xio-ip.h" #if WITH_IP4 #include "xio-ip4.h" diff --git a/xioopen.c b/xioopen.c index f944740..3d19fe5 100644 --- a/xioopen.c +++ b/xioopen.c @@ -1,5 +1,5 @@ /* source: xioopen.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source file of the extended open function */ @@ -55,6 +55,9 @@ const struct addrname addressnames[] = { #if WITH_GOPEN { "gopen", &addr_gopen }, #endif +#if WITH_INTERFACE + { "if", &xioaddr_interface }, +#endif #if (WITH_IP4 || WITH_IP6) && WITH_TCP { "inet", &addr_tcp_connect }, #endif @@ -76,6 +79,9 @@ const struct addrname addressnames[] = { { "inet6-l", &addr_tcp6_listen }, { "inet6-listen", &addr_tcp6_listen }, #endif +#if WITH_INTERFACE + { "interface", &xioaddr_interface }, +#endif #if WITH_RAWIP #if (WITH_IP4 || WITH_IP6) { "ip", &addr_rawip_sendto }, diff --git a/xioopts.c b/xioopts.c index ad76434..c55d1b0 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3535,7 +3535,7 @@ mc:addr ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr; /* third parameter is interface */ if (ifindex(opt->value.u_ip_mreq.ifindex, - (unsigned int *)&ip4_mreqn.mreqn.imr_ifindex) + (unsigned int *)&ip4_mreqn.mreqn.imr_ifindex, -1) < 0) { Error1("cannot resolve interface \"%s\"", opt->value.u_ip_mreq.ifindex); @@ -3548,7 +3548,8 @@ mc:addr #if HAVE_STRUCT_IP_MREQN /* there is a form with two parameters that uses mreqn */ } else if (ifindex(opt->value.u_ip_mreq.param2, - (unsigned int *)&ip4_mreqn.mreqn.imr_ifindex) + (unsigned int *)&ip4_mreqn.mreqn.imr_ifindex, + -1) >= 0) { /* yes, second param converts to interface */ ip4_mreqn.mreq.imr_interface.s_addr = htonl(0); @@ -3620,7 +3621,8 @@ mc:addr &sockaddr1, &socklen1, 0, 0); ip6_mreq.ipv6mr_multiaddr = sockaddr1.ip6.sin6_addr; if (ifindex(opt->value.u_ip_mreq.param2, - &ip6_mreq.ipv6mr_interface) < 0) { + &ip6_mreq.ipv6mr_interface, -1) + < 0) { Error1("interface \"%s\" not found", opt->value.u_ip_mreq.param2); ip6_mreq.ipv6mr_interface = htonl(0); diff --git a/xioread.c b/xioread.c index 5db886c..57049d8 100644 --- a/xioread.c +++ b/xioread.c @@ -131,6 +131,15 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { errno = _errno; return -1; } + /* on packet type we also receive outgoing packets, this is not desired + */ + if (from.soa.sa_family == PF_PACKET) { + if ((((struct sockaddr_ll *)&from.soa)->sll_pkttype & PACKET_OUTGOING) + == 0) { + errno = EAGAIN; return -1; + } + } + Notice2("received packet with "F_Zu" bytes from %s", bytes, sockaddr_info(&from.soa, fromlen, infobuff, sizeof(infobuff))); From b6c2d46008007841054f5c69a24a384df2b736c3 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 24 Aug 2008 11:04:08 +0200 Subject: [PATCH 26/75] cleanup xio-unix.c: merged classic with abstract functions; names, ... --- CHANGES | 3 + test.sh | 2 +- xio-unix.c | 596 +++++++++++++++++------------------------------------ xio-unix.h | 16 +- xioopen.c | 22 +- xioopts.c | 4 +- 6 files changed, 209 insertions(+), 434 deletions(-) diff --git a/CHANGES b/CHANGES index e78e07a..2e5a048 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,9 @@ corrections: replaced the select() calls by poll() to cleanly fix the problems with many file descriptors already open +further changes: + cleanup in xio-unix.c + ####################### V 1.6.0.1: new features: diff --git a/test.sh b/test.sh index 5cbb3ec..aba5733 100755 --- a/test.sh +++ b/test.sh @@ -2364,7 +2364,7 @@ N=$((N+1)) NAME=UNIXSOCKET case "$TESTS" in -*%functions%*|*%$NAME%*) +*%functions%*|*%unix%*|*%$NAME%*) TEST="$NAME: echo via connection to UNIX domain socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" diff --git a/xio-unix.c b/xio-unix.c index b0c6b95..a19ad6c 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -1,5 +1,5 @@ /* source: xio-unix.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of UNIX socket type */ @@ -15,52 +15,56 @@ #if WITH_UNIX -static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); -static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); -static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3); -static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3); +/* to avoid unneccessary "live" if () conditionals when no abstract support is + compiled in (or at least to give optimizing compilers a good chance) we need + a constant that can be used in C expressions */ +#if WITH_ABSTRACT_UNIXSOCKET +# define ABSTRACT 1 +#else +# define ABSTRACT 0 +#endif + +static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3); +static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3); +static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3); +static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3); static int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int ipproto); + int xioflags, xiofile_t *xxfd, unsigned groups, + int abstract, int dummy2, int dummy3); static -int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3); +int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3); +/* the first free parameter is 0 for "normal" unix domain sockets, or 1 for + abstract unix sockets (Linux); the second and third free parameter are + unsused */ +const struct addrdesc xioaddr_unix_connect = { "unix-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; +#if WITH_LISTEN +const struct addrdesc xioaddr_unix_listen = { "unix-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":") }; +#endif /* WITH_LISTEN */ +const struct addrdesc xioaddr_unix_sendto = { "unix-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_recvfrom= { "unix-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_recv = { "unix-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_client = { "unix-client", 3, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; #if WITH_ABSTRACT_UNIXSOCKET -static int xioopen_abstract_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); -static int xioopen_abstract_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); -static int xioopen_abstract_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3); -static int xioopen_abstract_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3); -static -int xioopen_abstract_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int ipproto); -static -int xioopen_abstract_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3); +const struct addrdesc xioaddr_abstract_connect = { "abstract-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; +#if WITH_LISTEN +const struct addrdesc xioaddr_abstract_listen = { "abstract-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":") }; +#endif /* WITH_LISTEN */ +const struct addrdesc xioaddr_abstract_sendto = { "abstract-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_recvfrom= { "abstract-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_recv = { "abstract-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_client = { "abstract-client", 3, xioopen_unix_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; #endif /* WITH_ABSTRACT_UNIXSOCKET */ -const struct addrdesc addr_unix_connect = { "unix-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":") }; -#if WITH_LISTEN -const struct addrdesc addr_unix_listen = { "unix-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":") }; -#endif /* WITH_LISTEN */ -const struct addrdesc addr_unix_sendto = { "unix-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_DGRAM, 0 HELP(":") }; -const struct addrdesc addr_unix_recvfrom= { "unix-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, PF_UNIX, SOCK_DGRAM, 0 HELP(":") }; -const struct addrdesc addr_unix_recv = { "unix-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, SOCK_DGRAM, 0 HELP(":") }; -const struct addrdesc addr_unix_client = { "unix-client", 3, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, 0, 0 HELP(":") }; -#if WITH_ABSTRACT_UNIXSOCKET -const struct addrdesc xioaddr_abstract_connect = { "abstract-connect", 3, xioopen_abstract_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":") }; -#if WITH_LISTEN -const struct addrdesc xioaddr_abstract_listen = { "abstract-listen", 3, xioopen_abstract_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":") }; -#endif /* WITH_LISTEN */ -const struct addrdesc xioaddr_abstract_sendto = { "abstract-sendto", 3, xioopen_abstract_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_DGRAM, 0 HELP(":") }; -const struct addrdesc xioaddr_abstract_recvfrom= { "abstract-recvfrom", 3, xioopen_abstract_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, PF_UNIX, SOCK_DGRAM, 0 HELP(":") }; -const struct addrdesc xioaddr_abstract_recv = { "abstract-recv", 1, xioopen_abstract_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, SOCK_DGRAM, 0 HELP(":") }; -const struct addrdesc xioaddr_abstract_client = { "abstract-client", 3, xioopen_abstract_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, 0, 0 HELP(":") }; -#endif /* WITH_ABSTRACT_UNIXSOCKET */ - -const struct optdesc opt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_INIT, TYPE_BOOL, OFUNC_SPEC, 0, 0 }; +const struct optdesc xioopt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_INIT, TYPE_BOOL, OFUNC_SPEC, 0, 0 }; +/* fills the socket address struct and returns its effective length. + abstract is usually 0; != 0 generates an abstract socket address on Linux. + tight calculates the resulting length from the path length, not from the + struct length. +*/ socklen_t xiosetunix(struct sockaddr_un *saun, const char *path, @@ -69,22 +73,8 @@ xiosetunix(struct sockaddr_un *saun, size_t pathlen; socklen_t len; - if (!abstract) { - if ((pathlen = strlen(path)) > sizeof(saun->sun_path)) { - Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"", - pathlen, sizeof(saun->sun_path)); - } - strncpy(saun->sun_path, path, sizeof(saun->sun_path)); - if (tight) { - len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ - MIN(pathlen, sizeof(saun->sun_path)); -#if HAVE_STRUCT_SOCKADDR_SALEN - saun->sun_len = len; -#endif - } else { - len = sizeof(struct sockaddr_un); - } - } else { +#ifdef WITH_ABSTRACT_UNIXSOCKET + if (abstract) { if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) { Warn2("socket address "F_Zu" characters long, truncating to "F_Zu"", pathlen+1, sizeof(saun->sun_path)); @@ -100,15 +90,32 @@ xiosetunix(struct sockaddr_un *saun, } else { len = sizeof(struct sockaddr_un); } + return len; + } +#endif /* WITH_ABSTRACT_UNIXSOCKET */ + + if ((pathlen = strlen(path)) > sizeof(saun->sun_path)) { + Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"", + pathlen, sizeof(saun->sun_path)); + } + strncpy(saun->sun_path, path, sizeof(saun->sun_path)); + if (tight) { + len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+ + MIN(pathlen, sizeof(saun->sun_path)); + } else { + len = sizeof(struct sockaddr_un); } return len; } #if WITH_LISTEN -static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) { +static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) { /* we expect the form: filename */ const char *name; xiosingle_t *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_STREAM; + int protocol = 0; struct sockaddr_un us; socklen_t uslen; bool tight = true; @@ -127,37 +134,41 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - uslen = xiosetunix(&us, name, false, tight); - - retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); - retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); - - if (opt_unlink_close) { - if ((xfd->unlink_close = strdup(name)) == NULL) { - Error1("strdup(\"%s\"): out of memory", name); - } - xfd->opt_unlink_close = true; - } + uslen = xiosetunix(&us, name, abstract, tight); xfd->howtoend = END_SHUTDOWN; + if (!(ABSTRACT && abstract)) { + /* only for non abstract because abstract do not work in file system */ + retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); + retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); + if (opt_unlink_close) { + if ((xfd->unlink_close = strdup(name)) == NULL) { + Error1("strdup(\"%s\"): out of memory", name); + } + xfd->opt_unlink_close = true; + } + } + applyopts(-1, opts, PH_INIT); if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_EARLY); - if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); + if (!(ABSTRACT && abstract)) { + if (opt_unlink_early) { + if (Unlink(name) < 0) { + if (errno == ENOENT) { + Warn2("unlink(\"%s\"): %s", name, strerror(errno)); + } else { + Error2("unlink(\"%s\"): %s", name, strerror(errno)); + } } } - } - /* trying to set user-early, perm-early etc. here is useless because - file system entry is available only past bind() call. */ - applyopts_named(name, opts, PH_EARLY); /* umask! */ + /* trying to set user-early, perm-early etc. here is useless because + file system entry is available only past bind() call. */ + applyopts_named(name, opts, PH_EARLY); /* umask! */ + } retropt_int(opts, OPT_SO_TYPE, &socktype); @@ -166,7 +177,7 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i if ((result = xioopen_listen(xfd, xioflags, (struct sockaddr *)&us, uslen, - opts, opts0, PF_UNIX, socktype, 0)) + opts, opts0, pf, socktype, protocol)) != 0) return result; return 0; @@ -174,10 +185,13 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i #endif /* WITH_LISTEN */ -static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) { +static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) { /* we expect the form: filename */ const char *name; struct single *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_STREAM; + int protocol = 0; struct sockaddr_un them, us; socklen_t themlen, uslen; bool tight = true; @@ -196,9 +210,11 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - themlen = xiosetunix(&them, name, false, tight); - retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); - + themlen = xiosetunix(&them, name, abstract, tight); + if (!(ABSTRACT && abstract)) { + /* only for non abstract because abstract do not work in file system */ + retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); + } if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0) != STAT_NOACTION) { needbind = true; @@ -219,7 +235,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, xioopen_connect(xfd, needbind?(struct sockaddr *)&us:NULL, uslen, (struct sockaddr *)&them, themlen, - opts, PF_UNIX, socktype, 0, false)) != 0) { + opts, pf, socktype, protocol, false)) != 0) { return result; } if ((result = _xio_openlate(xfd, opts)) < 0) { @@ -229,13 +245,16 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, } -static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) { +static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy, int dummy3) { + /* we expect the form: filename */ const char *name; xiosingle_t *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_DGRAM; + int protocol = 0; union sockaddr_union us; socklen_t uslen; bool tight = true; - int pf = PF_UNIX; bool needbind = false; bool opt_unlink_close = false; @@ -254,9 +273,12 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - xfd->salen = xiosetunix(&xfd->peersa.un, name, false, tight); + xfd->salen = xiosetunix(&xfd->peersa.un, name, abstract, tight); - retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); + if (!(ABSTRACT && abstract)) { + /* only for non abstract because abstract do not work in file system */ + retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); + } xfd->dtype = XIODATA_RECVFROM; @@ -277,15 +299,21 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, pf, socktype, 0); + opts, xioflags, xfd, groups, + pf, socktype, protocol); } static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int dummy3) { + int xioflags, xiofile_t *xxfd, unsigned groups, + int abstract, int dummy2, int dummy3) { + /* we expect the form: filename */ const char *name; + xiosingle_t *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_DGRAM; + int protocol = 0; struct sockaddr_un us; socklen_t uslen; bool tight = true; @@ -303,45 +331,53 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - uslen = xiosetunix(&us, name, false, tight); + uslen = xiosetunix(&us, name, abstract, tight); - xfd->stream.howtoend = END_NONE; + xfd->howtoend = END_NONE; retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_bind(opts, pf, socktype, 0, (struct sockaddr *)&us, &uslen, 1, 0, 0); - retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); - retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); - if (opt_unlink_close) { - if ((xfd->stream.unlink_close = strdup(name)) == NULL) { - Error1("strdup(\"%s\"): out of memory", name); + if (!(ABSTRACT && abstract)) { + /* only for non abstract because abstract do not work in file system */ + retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); + retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); + if (opt_unlink_close) { + if ((xfd->unlink_close = strdup(name)) == NULL) { + Error1("strdup(\"%s\"): out of memory", name); + } + xfd->opt_unlink_close = true; } - xfd->stream.opt_unlink_close = true; - } - if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); + if (opt_unlink_early) { + if (Unlink(name) < 0) { + if (errno == ENOENT) { + Warn2("unlink(\"%s\"): %s", name, strerror(errno)); + } else { + Error2("unlink(\"%s\"): %s", name, strerror(errno)); + } } } } - xfd->stream.para.socket.la.soa.sa_family = pf; + xfd->para.socket.la.soa.sa_family = pf; - xfd->stream.dtype = XIODATA_RECVFROM_ONE; - return _xioopen_dgram_recvfrom(&xfd->stream, xioflags, + xfd->dtype = XIODATA_RECVFROM_ONE; + return _xioopen_dgram_recvfrom(xfd, xioflags, needbind?(struct sockaddr *)&us:NULL, uslen, - opts, pf, socktype, 0, E_ERROR); + opts, pf, socktype, protocol, E_ERROR); } static int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int ipproto) { + int xioflags, xiofile_t *xxfd, unsigned groups, + int abstract, int dummy2, int dummy3) { + /* we expect the form: filename */ const char *name; + xiosingle_t *xfd = &xxfd->stream; + int pf = PF_UNIX; + int socktype = SOCK_DGRAM; + int protocol = 0; union sockaddr_union us; socklen_t uslen; bool tight = true; @@ -361,49 +397,54 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - uslen = xiosetunix(&us.un, name, false, tight); + uslen = xiosetunix(&us.un, name, abstract, tight); #if 1 /*!!! why bind option? */ - retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, 0, 0); + retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 1, 0, 0); #endif - retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); - if (opt_unlink_early) { - if (Unlink(name) < 0) { - if (errno == ENOENT) { - Warn2("unlink(\"%s\"): %s", name, strerror(errno)); - } else { - Error2("unlink(\"%s\"): %s", name, strerror(errno)); + if (!(ABSTRACT && abstract)) { + /* only for non abstract because abstract do not work in file system */ + retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); + if (opt_unlink_early) { + if (Unlink(name) < 0) { + if (errno == ENOENT) { + Warn2("unlink(\"%s\"): %s", name, strerror(errno)); + } else { + Error2("unlink(\"%s\"): %s", name, strerror(errno)); + } } } - } - retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); + retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); - if (opt_unlink_close) { - if ((xfd->stream.unlink_close = strdup(name)) == NULL) { - Error1("strdup(\"%s\"): out of memory", name); + if (opt_unlink_close) { + if ((xfd->unlink_close = strdup(name)) == NULL) { + Error1("strdup(\"%s\"): out of memory", name); + } + xfd->opt_unlink_close = true; } - xfd->stream.opt_unlink_close = true; } - xfd->stream.para.socket.la.soa.sa_family = pf; + xfd->para.socket.la.soa.sa_family = pf; - xfd->stream.dtype = XIODATA_RECV; - result = _xioopen_dgram_recv(&xfd->stream, xioflags, &us.soa, uslen, - opts, pf, socktype, ipproto, E_ERROR); + xfd->dtype = XIODATA_RECV; + result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen, + opts, pf, socktype, protocol, E_ERROR); return result; } -static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) { +static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) { + /* we expect the form: filename */ const char *name; xiosingle_t *xfd = &xxfd->stream; - bool tight = true; int pf = PF_UNIX; + int socktype = 0; /* to be determined by server socket type */ + int protocol = 0; union sockaddr_union them, us; - socklen_t themlen; - socklen_t uslen; + socklen_t themlen, uslen; + bool tight = true; bool needbind = false; bool opt_unlink_close = false; int result; @@ -420,9 +461,12 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - themlen = xiosetunix(&them.un, name, false, tight); + themlen = xiosetunix(&them.un, name, abstract, tight); - retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); + if (!(ABSTRACT && abstract)) { + /* only for non abstract because abstract do not work in file system */ + retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); + } if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0) != STAT_NOACTION) { @@ -439,9 +483,10 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i /* xfd->dtype = DATA_STREAM; // is default */ if ((result = xioopen_connect(xfd, - needbind?(struct sockaddr *)&us:NULL, uslen, + needbind?(struct sockaddr *)&us:NULL, uslen, (struct sockaddr *)&them, themlen, - opts, PF_UNIX, socktype?socktype:SOCK_STREAM, 0, false)) != 0) { + opts, pf, socktype?socktype:SOCK_STREAM, protocol, + false)) != 0) { if (errno == EPROTOTYPE) { if (needbind) { Unlink(us.un.sun_path); @@ -454,8 +499,8 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i xfd->salen = sizeof(struct sockaddr_un); if ((result = _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, pf, - socktype?socktype:SOCK_DGRAM, 0)) + opts, xioflags, xfd, groups, + pf, socktype?socktype:SOCK_DGRAM, protocol)) != 0) { return result; } @@ -468,277 +513,4 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i return 0; } - -#if WITH_ABSTRACT_UNIXSOCKET -#if WITH_LISTEN -static int xioopen_abstract_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) { - /* we expect the form: filename */ - const char *name; - xiosingle_t *xfd = &xxfd->stream; - bool tight = true; - struct sockaddr_un us; - socklen_t uslen; - struct opt *opts0 = NULL; - int result; - - if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); - return STAT_NORETRY; - } - - socket_un_init(&us); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); - name = argv[1]; - uslen = xiosetunix(&us, name, true, tight); - - xfd->howtoend = END_SHUTDOWN; - - applyopts(-1, opts, PH_INIT); - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(-1, opts, PH_EARLY); - - /* trying to set user-early, perm-early etc. here is useless because - file system entry is available only past bind() call. */ - - retropt_int(opts, OPT_SO_TYPE, &socktype); - - opts0 = copyopts(opts, GROUP_ALL); - - if ((result = - xioopen_listen(xfd, xioflags, - (struct sockaddr *)&us, uslen, - opts, opts0, PF_UNIX, socktype, 0)) - != 0) - return result; - return 0; -} -#endif /* WITH_LISTEN */ - -static int xioopen_abstract_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) { - /* we expect the form: filename */ - const char *name; - struct single *xfd = &xxfd->stream; - bool tight = true; - struct sockaddr_un them, us; - socklen_t themlen, uslen; - bool needbind = false; - int result; - - if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); - return STAT_NORETRY; - } - - socket_un_init(&us); - socket_un_init(&them); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); - name = argv[1]; - themlen = xiosetunix(&them, name, true, tight); - - if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0) - != STAT_NOACTION) { - needbind = true; - } - - applyopts(-1, opts, PH_INIT); - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - applyopts(-1, opts, PH_EARLY); - - if ((result = - xioopen_connect(xfd, - needbind?(struct sockaddr *)&us:NULL, uslen, - (struct sockaddr *)&them, themlen, - opts, PF_UNIX, socktype, 0, false)) != 0) { - return result; - } - if ((result = _xio_openlate(xfd, opts)) < 0) { - return result; - } - return 0; -} - - -static int xioopen_abstract_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) { - const char *name; - xiosingle_t *xfd = &xxfd->stream; - union sockaddr_union us; - socklen_t uslen; - bool tight = true; - int pf = PF_UNIX; - bool needbind = false; - - if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); - return STAT_NORETRY; - } - - uslen = socket_init(pf, &us); - xfd->salen = socket_init(pf, &xfd->peersa); - - xfd->howtoend = END_SHUTDOWN; - - retropt_int(opts, OPT_SO_TYPE, &socktype); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); - name = argv[1]; - xfd->salen = xiosetunix(&xfd->peersa.un, name, true, tight); - - xfd->dtype = XIODATA_RECVFROM; - - if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0) - != STAT_NOACTION) { - needbind = true; - } - - applyopts(-1, opts, PH_INIT); - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - - return - _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, pf, socktype, 0); -} - - -static -int xioopen_abstract_recvfrom(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int dummy3) { - const char *name; - struct sockaddr_un us; - socklen_t uslen; - bool tight = true; - bool needbind = true; - - if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); - return STAT_NORETRY; - } - - socket_un_init(&us); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); - name = argv[1]; - uslen = xiosetunix(&us, name, true, tight); - - xfd->stream.howtoend = END_NONE; - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_bind(opts, pf, socktype, 0, (struct sockaddr *)&us, &uslen, 1, 0, 0); - - xfd->stream.para.socket.la.soa.sa_family = pf; - - xfd->stream.dtype = XIODATA_RECVFROM_ONE; - return _xioopen_dgram_recvfrom(&xfd->stream, xioflags, - needbind?(struct sockaddr *)&us:NULL, uslen, - opts, pf, socktype, 0, E_ERROR); -} - - -static -int xioopen_abstract_recv(int argc, const char *argv[], struct opt *opts, - int xioflags, xiofile_t *xfd, unsigned groups, - int pf, int socktype, int ipproto) { - const char *name; - union sockaddr_union us; - socklen_t uslen; - bool tight = true; - int result; - - if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", - argv[0], argc-1); - return STAT_NORETRY; - } - - retropt_int(opts, OPT_SO_TYPE, &socktype); - - socket_un_init(&us.un); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); - name = argv[1]; - uslen = xiosetunix(&us.un, name, true, tight); - -#if 1 /*!!! why bind option? */ - retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, 0, 0); -#endif - - xfd->stream.para.socket.la.soa.sa_family = pf; - - xfd->stream.dtype = XIODATA_RECV; - result = _xioopen_dgram_recv(&xfd->stream, xioflags, &us.soa, uslen, - opts, pf, socktype, ipproto, E_ERROR); - return result; -} - - -static int xioopen_abstract_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) { - const char *name; - xiosingle_t *xfd = &xxfd->stream; - bool tight = true; - int pf = PF_UNIX; - union sockaddr_union them, us; - socklen_t themlen; - socklen_t uslen; - bool needbind = false; - int result; - - if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); - } - - xfd->howtoend = END_SHUTDOWN; - retropt_int(opts, OPT_SO_TYPE, &socktype); - - uslen = socket_init(pf, &us); - themlen = socket_init(pf, &them); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); - name = argv[1]; - themlen = xiosetunix(&them.un, name, true, tight); - - if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0) - != STAT_NOACTION) { - needbind = true; - } - - /* xfd->dtype = DATA_STREAM; // is default */ - if ((result = - xioopen_connect(xfd, - needbind?(struct sockaddr *)&us:NULL, uslen, - (struct sockaddr *)&them, themlen, - opts, PF_UNIX, socktype?socktype:SOCK_STREAM, 0, false)) != 0) { - if (errno == EPROTOTYPE) { - if (needbind) { - Unlink(us.un.sun_path); - } - - /* ...res_opts[] */ - applyopts(-1, opts, PH_INIT); - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; - - xfd->peersa = them; - xfd->salen = themlen; - if ((result = - _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, pf, - socktype?socktype:SOCK_DGRAM, 0)) - != 0) { - return result; - } - xfd->dtype = XIODATA_RECVFROM; - } - } - if ((result = _xio_openlate(xfd, opts)) < 0) { - return result; - } - return 0; -} - -#endif /* WITH_ABSTRACT_UNIXSOCKET */ - #endif /* WITH_UNIX */ diff --git a/xio-unix.h b/xio-unix.h index 9b09efe..9d9ad51 100644 --- a/xio-unix.h +++ b/xio-unix.h @@ -1,16 +1,16 @@ /* source: xio-unix.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_unix_h_included #define __xio_unix_h_included 1 -extern const struct addrdesc addr_unix_connect; -extern const struct addrdesc addr_unix_listen; -extern const struct addrdesc addr_unix_sendto; -extern const struct addrdesc addr_unix_recvfrom; -extern const struct addrdesc addr_unix_recv; -extern const struct addrdesc addr_unix_client; +extern const struct addrdesc xioaddr_unix_connect; +extern const struct addrdesc xioaddr_unix_listen; +extern const struct addrdesc xioaddr_unix_sendto; +extern const struct addrdesc xioaddr_unix_recvfrom; +extern const struct addrdesc xioaddr_unix_recv; +extern const struct addrdesc xioaddr_unix_client; extern const struct addrdesc xioaddr_abstract_connect; extern const struct addrdesc xioaddr_abstract_listen; extern const struct addrdesc xioaddr_abstract_sendto; @@ -18,7 +18,7 @@ extern const struct addrdesc xioaddr_abstract_recvfrom; extern const struct addrdesc xioaddr_abstract_recv; extern const struct addrdesc xioaddr_abstract_client; -extern const struct optdesc opt_unix_tightsocklen; +extern const struct optdesc xioopt_unix_tightsocklen; extern socklen_t xiosetunix(struct sockaddr_un *saun, diff --git a/xioopen.c b/xioopen.c index f944740..60ff998 100644 --- a/xioopen.c +++ b/xioopen.c @@ -1,5 +1,5 @@ /* source: xioopen.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this is the source file of the extended open function */ @@ -106,7 +106,7 @@ const struct addrname addressnames[] = { #endif #endif /* WITH_RAWIP */ #if WITH_UNIX - { "local", &addr_unix_connect }, + { "local", &xioaddr_unix_connect }, #endif #if WITH_FILE { "open", &addr_open }, @@ -231,19 +231,19 @@ const struct addrname addressnames[] = { { "udp6-sendto", &addr_udp6_sendto }, #endif #if WITH_UNIX - { "unix", &addr_unix_client }, - { "unix-client", &addr_unix_client }, - { "unix-connect", &addr_unix_connect }, + { "unix", &xioaddr_unix_client }, + { "unix-client", &xioaddr_unix_client }, + { "unix-connect", &xioaddr_unix_connect }, #endif #if WITH_UNIX && WITH_LISTEN - { "unix-l", &addr_unix_listen }, - { "unix-listen", &addr_unix_listen }, + { "unix-l", &xioaddr_unix_listen }, + { "unix-listen", &xioaddr_unix_listen }, #endif #if WITH_UNIX - { "unix-recv", &addr_unix_recv }, - { "unix-recvfrom", &addr_unix_recvfrom }, - { "unix-send", &addr_unix_sendto }, - { "unix-sendto", &addr_unix_sendto }, + { "unix-recv", &xioaddr_unix_recv }, + { "unix-recvfrom", &xioaddr_unix_recvfrom }, + { "unix-send", &xioaddr_unix_sendto }, + { "unix-sendto", &xioaddr_unix_sendto }, #endif #else /* !0 */ # if WITH_INTEGRATE diff --git a/xioopts.c b/xioopts.c index ad76434..291f3ae 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1443,7 +1443,7 @@ const struct optname optionnames[] = { #ifdef O_TEXT IF_ANY ("text", &opt_o_text) #endif - IF_UNIX ("tightsocklen", &opt_unix_tightsocklen) + IF_UNIX ("tightsocklen", &xioopt_unix_tightsocklen) IF_TERMIOS("time", &opt_vtime) IF_TERMIOS("tiocsctty", &opt_tiocsctty) #if WITH_EXT2 && defined(EXT2_TOPDIR_FL) @@ -1470,7 +1470,7 @@ const struct optname optionnames[] = { IF_NAMED ("uid-e", &opt_user_early) IF_ANY ("uid-l", &opt_user_late) IF_NAMED ("umask", &opt_umask) - IF_UNIX ("unix-tightsocklen", &opt_unix_tightsocklen) + IF_UNIX ("unix-tightsocklen", &xioopt_unix_tightsocklen) IF_NAMED ("unlink", &opt_unlink) IF_NAMED ("unlink-close", &opt_unlink_close) IF_NAMED ("unlink-early", &opt_unlink_early) From 376b9d50c3322c12d7b63e5bf25b0e0c4b5893c0 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 20 Sep 2008 23:47:06 +0200 Subject: [PATCH 27/75] reworked so-type, so-prototype --- CHANGES | 5 +++ VERSION | 2 +- doc/socat.yo | 23 ++++++---- filan.c | 3 ++ test.sh | 4 +- xio-gopen.c | 113 ++++------------------------------------------- xio-ip.c | 12 +++++ xio-ipapp.c | 29 ++++++++----- xio-ipapp.h | 6 +-- xio-listen.c | 25 ++++++++--- xio-openssl.c | 4 +- xio-progcall.c | 14 +++--- xio-proxy.c | 2 +- xio-rawip.c | 32 ++++++++------ xio-socket.c | 93 +++++++++++++++++++++++++++++---------- xio-socket.h | 18 ++++++-- xio-socks.c | 2 +- xio-udp.c | 16 ++++--- xio-unix.c | 116 ++++++++++++++++++++++++++----------------------- xio-unix.h | 7 ++- xioopts.c | 12 ++++- xioopts.h | 8 ++-- 22 files changed, 293 insertions(+), 253 deletions(-) diff --git a/CHANGES b/CHANGES index 2e5a048..75b1c42 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ +new features: + so-type now only affect the socket() and socketpair() calls, not the + name resolution. so-type and so-prototype can be applied to all socket + based addresses. + corrections: some raw IP and UNIX datagram modes failed on BSD systems diff --git a/VERSION b/VERSION index 9a06c88..721ab27 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+protocol" diff --git a/doc/socat.yo b/doc/socat.yo index 4befd5b..99b134b 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1585,11 +1585,23 @@ label(OPTION_SNDLOWAT)dit(bf(tt(sndlowat=))) layer will send the data to [link(int)(TYPE_INT)]. label(OPTION_SNDTIMEO)dit(bf(tt(sndtimeo=))) Sets the send timeout to seconds [link(timeval)(TYPE_TIMEVAL)]. -label(OPTION_TYPE)dit(bf(tt(type=))) - Sets the type of the socket, usually as argument to the code(socket()) or - code(socketpair()) call, to [link(int)(TYPE_INT)]. +label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=))) + Forces the use of the specified IP version or protocol. can be + something like "ip4" or "ip6". The resulting value is + used as first argument to the code(socket()) or code(socketpair()) calls. + This option affects address resolution and the required syntax of bind and + range options. +label(OPTION_SO_TYPE)dit(bf(tt(type=))) + Sets the type of the socket, specified as second argument to the + code(socket()) or code(socketpair()) calls, to + [link(int)(TYPE_INT)]. Address resolution is not affected by this option. Under Linux, 1 means stream oriented socket, 2 means datagram socket, and 3 means raw socket. +label(OPTION_SO_PROTOTYPE)dit(bf(tt(prototype))) + Sets the protocol of the socket, specified as third argument to the + code(socket()) or code(socketpair()) calls, to + [link(int)(TYPE_INT)]. Address resolution is not affected by this option. + 6 means TCP, 17 means UDP. COMMENT(label(OPTION_USELOOPBACK)dit(bf(tt(useloopback))) Sets the code(SO_USELOOPBACK) socket option.) COMMENT(label(OPTION_ACCEPTCONN)dit(bf(tt(acceptconn))) @@ -1618,8 +1630,6 @@ COMMENT(label(OPTION_PASSCRED)dit(bf(tt(passcred))) Set the code(SO_PASSCRED) socket option.) COMMENT(label(OPTION_PEERCRED)dit(bf(tt(peercred))) This is a read-only socket option.) -COMMENT(label(OPTION_PROTOTYPE)dit(bf(tt(prototype))) - Tries to set the code(SO_PROTOTYPE) socket option.) COMMENT(label(OPTION_REUSEPORT)dit(bf(tt(reuseport))) Set the code(SO_REUSEPORT) socket option.) COMMENT(label(OPTION_SECUTIYAUTHENTICATION)dit(bf(tt(securityauthentication))) @@ -1632,9 +1642,6 @@ COMMENT(label(OPTION_SIOCSPGRP)dit(bf(tt(siocspgrp=))) Set the SIOCSPGRP with code(ioclt()) to enable SIGIO.) COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs))) Set the code(SO_USE_IFBUFS) socket option.) -label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=))) - Forces the use of the specified IP version. can be - something like "ip4" or "ip6". enddit() startdit()enddit()nl() diff --git a/filan.c b/filan.c index e0477d1..3b3d045 100644 --- a/filan.c +++ b/filan.c @@ -479,6 +479,9 @@ int sockan(int fd, FILE *outfile) { {SO_REUSEADDR, "REUSEADDR"}, {SO_TYPE, "TYPE"}, {SO_ERROR, "ERROR"}, +#ifdef SO_PROTOTYPE + {SO_PROTOTYPE, "PROTOTYPE"}, +#endif {SO_DONTROUTE, "DONTROUTE"}, {SO_BROADCAST, "BROADCAST"}, {SO_SNDBUF, "SNDBUF"}, diff --git a/test.sh b/test.sh index aba5733..90005af 100755 --- a/test.sh +++ b/test.sh @@ -2362,7 +2362,7 @@ N=$((N+1)) #} -NAME=UNIXSOCKET +NAME=UNIXSTREAM case "$TESTS" in *%functions%*|*%unix%*|*%$NAME%*) TEST="$NAME: echo via connection to UNIX domain socket" @@ -2372,7 +2372,7 @@ ts="$td/test$N.socket" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD1="$SOCAT $opts UNIX-LISTEN:$ts PIPE" -CMD2="$SOCAT $opts -!!- UNIX:$ts" +CMD2="$SOCAT $opts -!!- UNIX-CONNECT:$ts" printf "test $F_n $TEST... " $N $CMD1 $tf 2>"${te}1" & bg=$! # background process id diff --git a/xio-gopen.c b/xio-gopen.c index bc172ed..7c1497f 100644 --- a/xio-gopen.c +++ b/xio-gopen.c @@ -45,113 +45,17 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio /* note: when S_ISSOCK was undefined, it always gives 0 */ if (exists && S_ISSOCK(st_mode)) { #if WITH_UNIX - int socktype = SOCK_STREAM; - int optsotype = -1; - struct sockaddr_un sa, us; - socklen_t salen, uslen = sizeof(us); - bool needbind = false; + union sockaddr_union us; + socklen_t uslen; char infobuff[256]; - struct opt *opts2; - - socket_un_init(&sa); - socket_un_init(&us); Info1("\"%s\" is a socket, connecting to it", filename); - if (retropt_int(opts, OPT_SO_TYPE, &optsotype) == 0) { - socktype = optsotype; + + result = + _xioopen_unix_client(&fd->stream, xioflags, groups, 0, opts, filename); + if (result < 0) { + return result; } - - if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0) != STAT_NOACTION) { - needbind = true; - } - - retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); - if (opt_unlink_close) { - if ((fd->stream.unlink_close = strdup(filename)) == NULL) { - Error1("strdup(\"%s\"): out of memory", filename); - } - fd->stream.opt_unlink_close = true; - } - - /* save options, because we might have to start again with Socket() */ - opts2 = copyopts(opts, GROUP_ALL); - - if ((fd->stream.fd = Socket(PF_UNIX, socktype, 0)) < 0) { - Error2("socket(PF_UNIX, %d, 0): %s", socktype, strerror(errno)); - return STAT_RETRYLATER; - } - /*0 Info2("socket(PF_UNIX, %d, 0) -> %d", socktype, fd->stream.fd);*/ - applyopts(fd->stream.fd, opts, PH_PASTSOCKET); - applyopts(fd->stream.fd, opts, PH_FD); - - applyopts_cloexec(fd->stream.fd, opts); - - sa.sun_family = AF_UNIX; - salen = xiosetunix(&sa, filename, false, false); - -#if 0 - applyopts(fd->stream.fd, opts, PH_PREBIND); - applyopts(fd->stream.fd, opts, PH_BIND); - if (us) { - if (Bind(fd->stream.fd, us, uslen) < 0) { - Error4("bind(%d, {%s}, "F_Zd"): %s", - fd->fd, sockaddr_info(us, infobuff, sizeof(infobuff)), - uslen, strerror(errno)); - if (fd->forever || --fd->retry) { - Nanosleep(&fd->intervall, NULL); - continue; - } else - return STAT_RETRYLATER; - } - } - applyopts(fd->stream.fd, opts, PH_PASTBIND); -#endif /* 0 */ - - applyopts(fd->stream.fd, opts, PH_CONNECT); - if ((result = Connect(fd->stream.fd, (struct sockaddr *)&sa, salen)) < 0) { - if (errno == EINPROGRESS) { - Warn4("connect(%d, %s, "F_Zd"): %s", - fd->stream.fd, sockaddr_unix_info(&sa, salen, infobuff, sizeof(infobuff)), - sizeof(sa), strerror(errno)); - } else if (errno == EPROTOTYPE && optsotype != SOCK_STREAM) { - Warn4("connect(%d, %s, "F_Zd"): %s", - fd->stream.fd, sockaddr_unix_info(&sa, salen, infobuff, sizeof(infobuff)), - sizeof(sa), strerror(errno)); - Info("assuming datagram socket"); - Close(fd->stream.fd); - - opts = opts2; - if ((fd->stream.fd = Socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - Error1("socket(PF_UNIX, SOCK_DGRAM, 0): %s", strerror(errno)); - return STAT_RETRYLATER; - } - /*0 Info1("socket(PF_UNIX, SOCK_DGRAM, 0) -> %d", fd->stream.fd);*/ - - applyopts(fd->stream.fd, opts, PH_PASTSOCKET); - applyopts(fd->stream.fd, opts, PH_FD); - - applyopts_cloexec(fd->stream.fd, opts); - - sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, filename, sizeof(sa.sun_path)); - - fd->stream.dtype = XIODATA_RECVFROM; - fd->stream.salen = sizeof(sa); - memcpy(&fd->stream.peersa.soa, &sa, fd->stream.salen); - } else { - Error4("connect(%d, %s, "F_Zd"): %s", - fd->stream.fd, sockaddr_unix_info(&sa, fd->stream.salen, infobuff, sizeof(infobuff)), - sizeof(sa), strerror(errno)); - return STAT_RETRYLATER; - } - } - if (fd->stream.howtoend == END_UNSPEC) { - fd->stream.howtoend = END_SHUTDOWN; - } - - applyopts_fchown(fd->stream.fd, opts); - applyopts(fd->stream.fd, opts, PH_CONNECTED); - applyopts(fd->stream.fd, opts, PH_LATE); applyopts_named(filename, opts, PH_PASTOPEN); /* unlink-late */ if (Getsockname(fd->stream.fd, (struct sockaddr *)&us, &uslen) < 0) { @@ -159,7 +63,8 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio fd->stream.fd, &us, uslen, strerror(errno)); } else { Notice1("successfully connected via %s", - sockaddr_unix_info(&us, uslen, infobuff, sizeof(infobuff))); + sockaddr_unix_info(&us.un, uslen, + infobuff, sizeof(infobuff))); } #else Error("\"%s\" is a socket, but UNIX socket support is not compiled in"); diff --git a/xio-ip.c b/xio-ip.c index 77dd71d..7519870 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -205,6 +205,18 @@ int xiogetaddrinfo(const char *node, const char *service, if (node != NULL || service != NULL) { struct addrinfo *record; + if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) { + /* actual socket type value is not supported - fallback to a good one */ + socktype = SOCK_DGRAM; + } + if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) { + /* actual protocol value is not supported - fallback to a good one */ + if (socktype == SOCK_DGRAM) { + protocol = IPPROTO_UDP; + } else { + protocol = IPPROTO_TCP; + } + } hints.ai_flags |= AI_PASSIVE; hints.ai_family = family; hints.ai_socktype = socktype; diff --git a/xio-ipapp.c b/xio-ipapp.c index 1a3effd..c9106ea 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -52,8 +52,8 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], - them, &themlen, us, &uslen, &needbind, &lowport, - &socktype) != STAT_OK) { + them, &themlen, us, &uslen, &needbind, &lowport, + socktype) != STAT_OK) { return STAT_NORETRY; } @@ -147,7 +147,11 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, } -/* returns STAT_OK on success or some other value on failure */ +/* returns STAT_OK on success or some other value on failure + applies and consumes the following options: + PH_EARLY + OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT + */ int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, @@ -158,7 +162,7 @@ int union sockaddr_union *them, socklen_t *themlen, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport, - int *socktype) { + int socktype) { uint16_t port; char infobuff[256]; int result; @@ -167,7 +171,7 @@ int if ((result = xiogetaddrinfo(hostname, portname, - *pf, *socktype, protocol, + *pf, socktype, protocol, (union sockaddr_union *)them, themlen, res_opts0, res_opts1 )) @@ -181,7 +185,7 @@ int applyopts(-1, opts, PH_EARLY); /* 3 means: IP address AND port accepted */ - if (retropt_bind(opts, *pf, *socktype, protocol, (struct sockaddr *)us, uslen, 3, + if (retropt_bind(opts, *pf, socktype, protocol, (struct sockaddr *)us, uslen, 3, res_opts0, res_opts1) != STAT_NOACTION) { *needbind = true; @@ -210,7 +214,6 @@ int } retropt_bool(opts, OPT_LOWPORT, lowport); - retropt_int(opts, OPT_SO_TYPE, socktype); *opts0 = copyopts(opts, GROUP_ALL); @@ -222,22 +225,24 @@ int #if WITH_TCP && WITH_LISTEN +/* + applies and consumes the following options: + OPT_PROTOCOL_FAMILY, OPT_BIND + */ int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, unsigned long res_opts0, unsigned long res_opts1, union sockaddr_union *us, socklen_t *uslen, - int *socktype) { + int socktype) { char *bindname = NULL; int result; - retropt_int(opts, OPT_SO_TYPE, socktype); - retropt_socket_pf(opts, pf); retropt_string(opts, OPT_BIND, &bindname); if ((result = - xiogetaddrinfo(bindname, portname, *pf, *socktype, ipproto, + xiogetaddrinfo(bindname, portname, *pf, socktype, ipproto, (union sockaddr_union *)us, uslen, res_opts0, res_opts1)) != STAT_OK) { @@ -284,7 +289,7 @@ int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto, fd->stream.para.socket.ip.res_opts[1], fd->stream.para.socket.ip.res_opts[0], - us, &uslen, &socktype) + us, &uslen, socktype) != STAT_OK) { return STAT_NORETRY; } diff --git a/xio-ipapp.h b/xio-ipapp.h index ce5ece1..c2dcb1e 100644 --- a/xio-ipapp.h +++ b/xio-ipapp.h @@ -1,5 +1,5 @@ /* source: xio-ipapp.h */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ipapp_h_included @@ -25,7 +25,7 @@ extern int union sockaddr_union *them, socklen_t *themlen, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport, - int *socktype); + int socktype); extern int _xioopen_ip4app_connect(const char *hostname, const char *portname, struct single *xfd, int socktype, int ipproto, void *protname, @@ -39,7 +39,7 @@ extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, unsigned long res_opts0, unsigned long res_opts1, union sockaddr_union *us, socklen_t *uslen, - int *socktype); + int socktype); extern int xioopen_ip6app_connect(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, unsigned groups, int socktype, int ipproto, diff --git a/xio-listen.c b/xio-listen.c index 38a65c6..e17bcaf 100644 --- a/xio-listen.c +++ b/xio-listen.c @@ -25,6 +25,13 @@ const struct optdesc opt_range = { "range", NULL, OPT_RANGE, GROUP_R #endif +/* + applies and consumes the following option: + PH_INIT, PH_PASTSOCKET, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY, + PH_PREOPEN, PH_FD, PH_CONNECTED, PH_LATE, PH_LATE2 + OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap, + OPT_SOURCEPORT, OPT_LOWPORT, cloexec + */ int xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, @@ -81,15 +88,21 @@ int } -/* waits for incoming connection, checks its source address and port. Depending - on fork option, it may fork a subprocess. +/* creates the listening socket, bind, applies options; waits for incoming + connection, checks its source address and port. Depending on fork option, it + may fork a subprocess. Returns 0 if a connection was accepted; with fork option, this is always in a subprocess! Other return values indicate a problem; this can happen in the master process or in a subprocess. - This function does not retry. If you need retries, handle this is a - loop in the calling function. + This function does not retry. If you need retries, handle this in a + loop in the calling function (and always provide the options...) after fork, we set the forever/retry of the child process to 0 + applies and consumes the following option: + PH_INIT, PH_PASTSOCKET, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY, + PH_PREOPEN, PH_FD, PH_CONNECTED, PH_LATE, PH_LATE2 + OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap, + OPT_SOURCEPORT, OPT_LOWPORT, cloexec */ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level) { @@ -119,9 +132,7 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl xiosetchilddied(); /* set SIGCHLD handler */ } - if ((xfd->fd = Socket(pf, socktype, proto)) < 0) { - Msg4(level, - "socket(%d, %d, %d): %s", pf, socktype, proto, strerror(errno)); + if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } diff --git a/xio-openssl.c b/xio-openssl.c index 4fa17bc..ba76a52 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -200,7 +200,7 @@ static int xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], them, &themlen, us, &uslen, - &needbind, &lowport, &socktype); + &needbind, &lowport, socktype); if (result != STAT_OK) return STAT_NORETRY; if (xioopts.logopt == 'm') { @@ -440,7 +440,7 @@ static int if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], - us, &uslen, &socktype) + us, &uslen, socktype) != STAT_OK) { return STAT_NORETRY; } diff --git a/xio-progcall.c b/xio-progcall.c index 0c9f8ed..63fd562 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -10,6 +10,9 @@ #include "xio-process.h" #include "xio-progcall.h" +#include "xio-socket.h" + + /* these options are used by address pty too */ #if HAVE_OPENPTY const struct optdesc opt_openpty = { "openpty", NULL, OPT_OPENPTY, GROUP_PTY, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC }; @@ -49,7 +52,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ ) { struct opt *popts; /* parent process options */ int numleft; - int d, type, protocol, sv[2], rdpip[2], wrpip[2]; + int d, sv[2], rdpip[2], wrpip[2]; int rw = (xioflags & XIO_ACCMODE); bool usepipes = false; #if HAVE_PTY @@ -358,13 +361,10 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ applyopts(fd->fd, popts, PH_LATE); if (applyopts_single(fd, popts, PH_LATE) < 0) return -1; } else { - d = AF_UNIX; type = SOCK_STREAM; - protocol = 0; /* PF_UNIX does not work on AIX */ - retropt_int(popts, OPT_SO_TYPE, &type); - result = Socketpair(d, type, protocol, sv); + d = AF_UNIX; + retropt_int(popts, OPT_PROTOCOL_FAMILY, &d); + result = xiosocketpair(popts, d, SOCK_STREAM, 0, sv); if (result < 0) { - Error5("socketpair(%d, %d, %d, %p): %s", - d, type, protocol, sv, strerror(errno)); return -1; } /*0 Info5("socketpair(%d, %d, %d, {%d,%d})", diff --git a/xio-proxy.c b/xio-proxy.c index 23ab032..fe15ffd 100644 --- a/xio-proxy.c +++ b/xio-proxy.c @@ -131,7 +131,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], them, &themlen, us, &uslen, - &needbind, &lowport, &socktype); + &needbind, &lowport, socktype); if (result != STAT_OK) return result; Notice4("opening connection to %s:%u via proxy %s:%s", diff --git a/xio-rawip.c b/xio-rawip.c index a1a0e09..7df1b39 100644 --- a/xio-rawip.c +++ b/xio-rawip.c @@ -17,7 +17,6 @@ #include "xio-rawip.h" - static int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int pf, @@ -38,7 +37,7 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, static int _xioopen_rawip_sendto(const char *hostname, const char *protname, struct opt *opts, int xioflags, - xiofile_t *xxfd, unsigned groups, int pf); + xiofile_t *xxfd, unsigned groups, int *pf); const struct addrdesc addr_rawip_sendto = { "ip-sendto", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6, PF_UNSPEC, 0, 0 HELP("::") }; const struct addrdesc addr_rawip_datagram= { "ip-datagram", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, 0, 0 HELP("::") }; @@ -75,17 +74,24 @@ int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts, return STAT_NORETRY; } if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd, - groups, pf)) != STAT_OK) { + groups, &pf)) != STAT_OK) { return result; } _xio_openlate(&xxfd->stream, opts); return STAT_OK; } +/* + applies and consumes the following options: + PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE + OFUNC_OFFSET + OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, + OPT_GROUP, OPT_CLOEXEC + */ static int _xioopen_rawip_sendto(const char *hostname, const char *protname, struct opt *opts, int xioflags, xiofile_t *xxfd, - unsigned groups, int pf) { + unsigned groups, int *pf) { char *garbage; xiosingle_t *xfd = &xxfd->stream; union sockaddr_union us; @@ -107,7 +113,7 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname, } xfd->howtoend = END_SHUTDOWN; - retropt_int(opts, OPT_SO_TYPE, &socktype); + retropt_int(opts, OPT_PROTOCOL_FAMILY, pf); /* ...res_opts[] */ if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; @@ -115,29 +121,29 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname, xfd->salen = sizeof(xfd->peersa); if ((result = - xiogetaddrinfo(hostname, NULL, pf, socktype, ipproto, + xiogetaddrinfo(hostname, NULL, *pf, socktype, ipproto, &xfd->peersa, &xfd->salen, xfd->para.socket.ip.res_opts[0], xfd->para.socket.ip.res_opts[1])) != STAT_OK) { return result; } - if (pf == PF_UNSPEC) { - pf = xfd->peersa.soa.sa_family; + if (*pf == PF_UNSPEC) { + *pf = xfd->peersa.soa.sa_family; } - uslen = socket_init(pf, &us); + uslen = socket_init(*pf, &us); xfd->dtype = XIODATA_RECVFROM_SKIPIP; - if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, feats, + if (retropt_bind(opts, *pf, socktype, ipproto, &us.soa, &uslen, feats, xfd->para.socket.ip.res_opts[0], xfd->para.socket.ip.res_opts[1]) != STAT_NOACTION) { needbind = true; } return _xioopen_dgram_sendto(needbind?&us:NULL, uslen, - opts, xioflags, xfd, groups, pf, socktype, ipproto); + opts, xioflags, xfd, groups, *pf, socktype, ipproto); } @@ -157,7 +163,7 @@ int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts, } if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd, - groups, pf)) != STAT_OK) { + groups, &pf)) != STAT_OK) { return result; } @@ -216,7 +222,6 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, /*return STAT_NORETRY;*/ } xfd->stream.howtoend = END_NONE; - retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_socket_pf(opts, &pf); if (pf == PF_UNSPEC) { @@ -274,7 +279,6 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, protname); /*return STAT_NORETRY;*/ } - retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_socket_pf(opts, &pf); if (pf == PF_UNSPEC) { diff --git a/xio-socket.c b/xio-socket.c index d93bb98..766f0ab 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -39,7 +39,7 @@ const struct optdesc opt_so_sndbuf_late={ "so-sndbuf-late","sndbuf-late",OPT_SO_ const struct optdesc opt_so_rcvbuf = { "so-rcvbuf", "rcvbuf", OPT_SO_RCVBUF, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_RCVBUF}; const struct optdesc opt_so_rcvbuf_late={"so-rcvbuf-late","rcvbuf-late",OPT_SO_RCVBUF_LATE,GROUP_SOCKET,PH_LATE,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_RCVBUF }; const struct optdesc opt_so_error = { "so-error", "error", OPT_SO_ERROR, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_ERROR}; -const struct optdesc opt_so_type = { "so-type", "type", OPT_SO_TYPE, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_TYPE }; +const struct optdesc opt_so_type = { "so-type", "type", OPT_SO_TYPE, GROUP_SOCKET, PH_SOCKET, TYPE_INT, OFUNC_SPEC, SOL_SOCKET, SO_TYPE }; const struct optdesc opt_so_dontroute= { "so-dontroute", "dontroute", OPT_SO_DONTROUTE,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_DONTROUTE }; #ifdef SO_RCVLOWAT const struct optdesc opt_so_rcvlowat = { "so-rcvlowat", "rcvlowat", OPT_SO_RCVLOWAT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_RCVLOWAT }; @@ -115,9 +115,9 @@ const struct optdesc opt_so_dgram_errind={"so-dgram-errind","dgramerrind",OPT_SO #ifdef SO_DONTLINGER /* Solaris */ const struct optdesc opt_so_dontlinger = {"so-dontlinger", "dontlinger", OPT_SO_DONTLINGER, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DONTLINGER }; #endif -#ifdef SO_PROTOTYPE /* Solaris, HP-UX */ -const struct optdesc opt_so_prototype = {"so-prototype", "prototype", OPT_SO_PROTOTYPE, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_PROTOTYPE }; -#endif +/* the SO_PROTOTYPE is OS defined on Solaris, HP-UX; we lend this for a more + general purpose */ +const struct optdesc opt_so_prototype = {"so-prototype", "prototype", OPT_SO_PROTOTYPE, GROUP_SOCKET,PH_SOCKET, TYPE_INT,OFUNC_SPEC, SOL_SOCKET,SO_PROTOTYPE }; #ifdef FIOSETOWN const struct optdesc opt_fiosetown = { "fiosetown", NULL, OPT_FIOSETOWN, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_IOCTL, FIOSETOWN }; #endif @@ -127,15 +127,21 @@ const struct optdesc opt_siocspgrp = { "siocspgrp", NULL, OPT_SIOCSPGRP, GRO const struct optdesc opt_bind = { "bind", NULL, OPT_BIND, GROUP_SOCKET, PH_BIND, TYPE_STRING,OFUNC_SPEC }; const struct optdesc opt_connect_timeout = { "connect-timeout", NULL, OPT_CONNECT_TIMEOUT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_TIMEVAL, OFUNC_OFFSET, (int)&((xiofile_t *)0)->stream.para.socket.connect_timeout }; const struct optdesc opt_protocol_family = { "protocol-family", "pf", OPT_PROTOCOL_FAMILY, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC }; +const struct optdesc opt_protocol = { "protocol", NULL, OPT_PROTOCOL, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC }; /* a subroutine that is common to all socket addresses that want to connect to a peer address. might fork. + applies and consumes the following options: + PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT, + PH_CONNECTED, PH_LATE, + OFUNC_OFFSET, + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC returns 0 on success. */ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, struct sockaddr *them, size_t themlen, - struct opt *opts, int pf, int stype, int proto, + struct opt *opts, int pf, int socktype, int protocol, bool alt, int level) { int fcntl_flags = 0; char infobuff[256]; @@ -144,9 +150,7 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, int _errno; int result; - if ((xfd->fd = Socket(pf, stype, proto)) < 0) { - Msg4(level, - "socket(%d, %d, %d): %s", pf, stype, proto, strerror(errno)); + if ((xfd->fd = xiosocket(opts, pf, socktype, protocol, level)) < 0) { return STAT_RETRYLATER; } @@ -340,7 +344,7 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, } } - applyopts_fchown(xfd->fd, opts); + applyopts_fchown(xfd->fd, opts); /* OPT_USER, OPT_GROUP */ applyopts(xfd->fd, opts, PH_CONNECTED); applyopts(xfd->fd, opts, PH_LATE); @@ -354,11 +358,16 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, /* a subroutine that is common to all socket addresses that want to connect to a peer address. might fork. + applies and consumes the following option: + PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT, + PH_CONNECTED, PH_LATE, + OFUNC_OFFSET, + OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC returns 0 on success. */ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, struct sockaddr *them, size_t themlen, - struct opt *opts, int pf, int stype, int proto, + struct opt *opts, int pf, int socktype, int protocol, bool alt) { bool dofork = false; struct opt *opts0; @@ -367,7 +376,6 @@ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, int result; retropt_bool(opts, OPT_FORK, &dofork); - retropt_int(opts, OPT_SO_TYPE, &stype); opts0 = copyopts(opts, GROUP_ALL); @@ -384,7 +392,7 @@ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, level = E_ERROR; result = _xioopen_connect(xfd, us, uslen, them, themlen, opts, - pf, stype, proto, alt, level); + pf, socktype, protocol, alt, level); switch (result) { case STAT_OK: break; #if WITH_RETRY @@ -454,7 +462,12 @@ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, } -/* common to xioopen_udp_sendto, ..unix_sendto, ..rawip */ +/* common to xioopen_udp_sendto, ..unix_sendto, ..rawip + applies and consumes the following option: + PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE + OFUNC_OFFSET + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + */ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */ union sockaddr_union *us, socklen_t uslen, struct opt *opts, @@ -464,9 +477,7 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */ union sockaddr_union la; socklen_t lalen = sizeof(la); char infobuff[256]; - if ((xfd->fd = Socket(pf, socktype, ipproto)) < 0) { - Msg4(level, - "socket(%d, %d, %d): %s", pf, socktype, ipproto, strerror(errno)); + if ((xfd->fd = xiosocket(opts, pf, socktype, ipproto, level)) < 0) { return STAT_RETRYLATER; } @@ -590,6 +601,10 @@ void xiosigaction_hasread(int signum, siginfo_t *siginfo, void *ucontext) { This function does not retry. If you need retries, handle this is a loop in the calling function. after fork, we set the forever/retry of the child process to 0 + applies and consumes the following options: + PH_INIT, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY, PH_PREOPEN, PH_FD, + PH_CONNECTED, PH_LATE, PH_LATE2 + OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, cloexec, OPT_RANGE, tcpwrap */ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, @@ -616,9 +631,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; - if ((xfd->fd = Socket(pf, socktype, proto)) < 0) { - Msg4(level, - "socket(%d, %d, %d): %s", pf, socktype, proto, strerror(errno)); + if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } @@ -869,9 +882,7 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags, if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; - if ((xfd->fd = Socket(pf, socktype, proto)) < 0) { - Msg4(level, - "socket(%d, %d, %d): %s", pf, socktype, proto, strerror(errno)); + if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } @@ -1128,3 +1139,41 @@ int xiocheckpeer(xiosingle_t *xfd, } #endif /* _WITH_SOCKET */ + +/* these do sockets internally */ + +/* retrieves options so-type and so-prototype from opts, calls socketpair, and + ev. generates an appropriate error message. + returns 0 on success or -1 if an error occurred. */ +int +xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { + int result; + + retropt_int(opts, OPT_SO_TYPE, &socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, &proto); + result = Socket(pf, socktype, proto); + if (result < 0) { + Msg4(msglevel, "socket(%d, %d, %d): %s", + pf, socktype, proto, strerror(errno)); + return -1; + } + return result; +} + +/* retrieves options so-type and so-prototype from opts, calls socketpair, and + ev. generates an appropriate error message. + returns 0 on success or -1 if an error occurred. */ +int +xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) { + int result; + + retropt_int(opts, OPT_SO_TYPE, &socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, &proto); + result = Socketpair(pf, socktype, proto, sv); + if (result < 0) { + Error5("socketpair(%d, %d, %d, %p): %s", + pf, socktype, proto, sv, strerror(errno)); + return -1; + } + return result; +} diff --git a/xio-socket.h b/xio-socket.h index 04734f9..bcd36b3 100644 --- a/xio-socket.h +++ b/xio-socket.h @@ -1,10 +1,16 @@ /* source: xio-socket.h */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_socket_h_included #define __xio_socket_h_included 1 +/* SO_PROTOTYPE is OS defined on Solaris, HP-UX; we lend this for a more + general purpose */ +#ifndef SO_PROTOTYPE +#define SO_PROTOTYPE 0x9999 +#endif + extern const struct optdesc opt_connect_timeout; extern const struct optdesc opt_so_debug; extern const struct optdesc opt_so_acceptconn; @@ -56,12 +62,14 @@ extern int retropt_socket_pf(struct opt *opts, int *pf); extern int xioopen_connect(struct single *fd, struct sockaddr *us, size_t uslen, struct sockaddr *them, size_t themlen, - struct opt *opts, int pf, int stype, int proto, + struct opt *opts, + int pf, int socktype, int protocol, bool alt); extern int _xioopen_connect(struct single *fd, struct sockaddr *us, size_t uslen, struct sockaddr *them, size_t themlen, - struct opt *opts, int pf, int stype, int proto, + struct opt *opts, + int pf, int socktype, int protocol, bool alt, int level); /* common to xioopen_udp_sendto, ..unix_sendto, ..rawip */ @@ -86,5 +94,9 @@ int xiogetpacketsrc(int fd, union sockaddr_union *pa, socklen_t *palen); extern int xiocheckpeer(xiosingle_t *xfd, union sockaddr_union *pa, union sockaddr_union *la); +extern int +xiosocket(struct opt *opts, int pf, int socktype, int proto, int level); +extern int +xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]); #endif /* !defined(__xio_socket_h_included) */ diff --git a/xio-socks.c b/xio-socks.c index 71c0ded..078f8d5 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -88,7 +88,7 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts xfd->para.socket.ip.res_opts[1], xfd->para.socket.ip.res_opts[0], them, &themlen, us, &uslen, - &needbind, &lowport, &socktype); + &needbind, &lowport, socktype); Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"", targetname, diff --git a/xio-udp.c b/xio-udp.c index 293b8be..9431d8e 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -114,7 +114,6 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, applyopts(-1, opts, PH_INIT); uslen = socket_init(pf, &us); - retropt_int(opts, OPT_SO_TYPE, &socktype); retropt_bind(opts, pf, socktype, IPPROTO_UDP, (struct sockaddr *)&us, &uslen, 1, fd->stream.para.socket.ip.res_opts[1], @@ -176,8 +175,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, union sockaddr_union _sockname; union sockaddr_union *la = &_sockname; /* local address */ - if ((fd->stream.fd = Socket(pf, socktype, ipproto)) < 0) { - Error4("socket(%d, %d, %d): %s", pf, socktype, ipproto, strerror(errno)); + if ((fd->stream.fd = xiosocket(opts, pf, socktype, ipproto, E_ERROR)) < 0) { return STAT_RETRYLATER; } applyopts(fd->stream.fd, opts, PH_PASTSOCKET); @@ -230,7 +228,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, if (xiocheckpeer(&fd->stream, them, la) < 0) { /* drop packet */ char buff[512]; - Recv(fd->stream.fd, buff, sizeof(buff), 0); + Recv(fd->stream.fd, buff, sizeof(buff), 0); /* drop packet */ Close(fd->stream.fd); continue; } @@ -296,6 +294,8 @@ int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, argv[0], argc-1); return STAT_NORETRY; } + + retropt_socket_pf(opts, &pf); if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xxfd, groups, pf, socktype, ipproto)) != STAT_OK) { @@ -305,6 +305,12 @@ int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, return STAT_OK; } +/* + applies and consumes the following option: + PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE + OFUNC_OFFSET + OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + */ static int _xioopen_udp_sendto(const char *hostname, const char *servname, struct opt *opts, @@ -318,7 +324,6 @@ int _xioopen_udp_sendto(const char *hostname, const char *servname, int result; xfd->howtoend = END_SHUTDOWN; - retropt_int(opts, OPT_SO_TYPE, &socktype); /* ...res_opts[] */ if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; @@ -405,6 +410,7 @@ int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, return STAT_RETRYLATER; } + retropt_socket_pf(opts, &pf); result = _xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd, groups, pf, socktype, ipproto); diff --git a/xio-unix.c b/xio-unix.c index a19ad6c..dfb3b59 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -62,17 +62,20 @@ const struct optdesc xioopt_unix_tightsocklen = { "unix-tightsocklen", "tight /* fills the socket address struct and returns its effective length. abstract is usually 0; != 0 generates an abstract socket address on Linux. - tight calculates the resulting length from the path length, not from the - struct length. + tight!=0 calculates the resulting length from the path length, not from the + structures length; this is more common. + the struct need not be initialized when calling this function. */ socklen_t -xiosetunix(struct sockaddr_un *saun, +xiosetunix(int pf, + struct sockaddr_un *saun, const char *path, bool abstract, bool tight) { size_t pathlen; socklen_t len; + socket_un_init(saun); #ifdef WITH_ABSTRACT_UNIXSOCKET if (abstract) { if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) { @@ -130,11 +133,10 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i return STAT_NORETRY; } - socket_un_init(&us); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - uslen = xiosetunix(&us, name, abstract, tight); + retropt_socket_pf(opts, &pf); + retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); + uslen = xiosetunix(pf, &us, name, abstract, tight); xfd->howtoend = END_SHUTDOWN; @@ -151,7 +153,6 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i } applyopts(-1, opts, PH_INIT); - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_EARLY); if (!(ABSTRACT && abstract)) { @@ -170,8 +171,6 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i applyopts_named(name, opts, PH_EARLY); /* umask! */ } - retropt_int(opts, OPT_SO_TYPE, &socktype); - opts0 = copyopts(opts, GROUP_ALL); if ((result = @@ -205,17 +204,15 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, return STAT_NORETRY; } - socket_un_init(&us); - socket_un_init(&them); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - themlen = xiosetunix(&them, name, abstract, tight); + retropt_socket_pf(opts, &pf); + retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); + themlen = xiosetunix(pf, &them, name, abstract, tight); if (!(ABSTRACT && abstract)) { /* only for non abstract because abstract do not work in file system */ retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); } - if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0) + if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, 0, 0, 0) != STAT_NOACTION) { needbind = true; } @@ -264,16 +261,12 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i return STAT_NORETRY; } - uslen = socket_init(pf, &us); - xfd->salen = socket_init(pf, &xfd->peersa); - - xfd->howtoend = END_SHUTDOWN; - - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - xfd->salen = xiosetunix(&xfd->peersa.un, name, abstract, tight); + retropt_socket_pf(opts, &pf); + xfd->salen = xiosetunix(pf, &xfd->peersa.un, name, abstract, tight); + + xfd->howtoend = END_SHUTDOWN; if (!(ABSTRACT && abstract)) { /* only for non abstract because abstract do not work in file system */ @@ -282,7 +275,7 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i xfd->dtype = XIODATA_RECVFROM; - if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0) + if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 0, 0, 0) != STAT_NOACTION) { needbind = true; } @@ -327,15 +320,14 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, return STAT_NORETRY; } - socket_un_init(&us); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - uslen = xiosetunix(&us, name, abstract, tight); + retropt_socket_pf(opts, &pf); + retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); + uslen = xiosetunix(pf, &us, name, abstract, tight); xfd->howtoend = END_NONE; - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_bind(opts, pf, socktype, 0, (struct sockaddr *)&us, &uslen, 1, 0, 0); + retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, + 1, 0, 0); if (!(ABSTRACT && abstract)) { /* only for non abstract because abstract do not work in file system */ @@ -362,9 +354,10 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, xfd->para.socket.la.soa.sa_family = pf; xfd->dtype = XIODATA_RECVFROM_ONE; - return _xioopen_dgram_recvfrom(xfd, xioflags, - needbind?(struct sockaddr *)&us:NULL, uslen, - opts, pf, socktype, protocol, E_ERROR); + return + _xioopen_dgram_recvfrom(xfd, xioflags, + needbind?(struct sockaddr *)&us:NULL, uslen, + opts, pf, socktype, protocol, E_ERROR); } @@ -391,13 +384,10 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, return STAT_NORETRY; } - retropt_int(opts, OPT_SO_TYPE, &socktype); - - socket_un_init(&us.un); - - retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); name = argv[1]; - uslen = xiosetunix(&us.un, name, abstract, tight); + retropt_socket_pf(opts, &pf); + retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); + uslen = xiosetunix(pf, &us.un, name, abstract, tight); #if 1 /*!!! why bind option? */ retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 1, 0, 0); @@ -437,8 +427,28 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) { /* we expect the form: filename */ - const char *name; - xiosingle_t *xfd = &xxfd->stream; + if (argc != 2) { + Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); + } + + return + _xioopen_unix_client(&xxfd->stream, xioflags, groups, abstract, opts, + argv[1]); +} + +/* establishes communication with an existing UNIX type socket. supports stream + and datagram socket types: first tries to connect(), but when this fails it + falls back to sendto(). + applies and consumes the following option: + PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, + PH_CONNECTED, PH_LATE, ?PH_CONNECT + OFUNC_OFFSET, + OPT_PROTOCOL_FAMILY, OPT_UNIX_TIGHTSOCKLEN, OPT_UNLINK_CLOSE, OPT_BIND, + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK, +*/ +int +_xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, + int abstract, struct opt *opts, const char *name) { int pf = PF_UNIX; int socktype = 0; /* to be determined by server socket type */ int protocol = 0; @@ -447,28 +457,24 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i bool tight = true; bool needbind = false; bool opt_unlink_close = false; + struct opt *opts0; int result; - if (argc != 2) { - Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); - } + applyopts(-1, opts, PH_INIT); + if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; xfd->howtoend = END_SHUTDOWN; - retropt_int(opts, OPT_SO_TYPE, &socktype); - - uslen = socket_init(pf, &us); - themlen = socket_init(pf, &them); + retropt_socket_pf(opts, &pf); retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight); - name = argv[1]; - themlen = xiosetunix(&them.un, name, abstract, tight); + themlen = xiosetunix(pf, &them.un, name, abstract, tight); if (!(ABSTRACT && abstract)) { /* only for non abstract because abstract do not work in file system */ retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); } - if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0) + if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 0, 0, 0) != STAT_NOACTION) { needbind = true; } @@ -480,6 +486,9 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i xfd->opt_unlink_close = true; } + /* save options, because we might have to start again */ + opts0 = copyopts(opts, GROUP_ALL); + /* xfd->dtype = DATA_STREAM; // is default */ if ((result = xioopen_connect(xfd, @@ -492,8 +501,7 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i Unlink(us.un.sun_path); } - applyopts(-1, opts, PH_INIT); - if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; + dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0; xfd->peersa = them; xfd->salen = sizeof(struct sockaddr_un); diff --git a/xio-unix.h b/xio-unix.h index 9d9ad51..343bc1a 100644 --- a/xio-unix.h +++ b/xio-unix.h @@ -21,9 +21,14 @@ extern const struct addrdesc xioaddr_abstract_client; extern const struct optdesc xioopt_unix_tightsocklen; extern socklen_t -xiosetunix(struct sockaddr_un *saun, +xiosetunix(int pf, + struct sockaddr_un *saun, const char *path, bool abstract, bool tight); +extern int +_xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, + int abstract, struct opt *opts, const char *name); + #endif /* !defined(__xio_unix_h_included) */ diff --git a/xioopts.c b/xioopts.c index 291f3ae..aea0c2b 100644 --- a/xioopts.c +++ b/xioopts.c @@ -2333,7 +2333,15 @@ int retropt_int(struct opt *opts, int optcode, int *result) { while (opt->desc != ODESC_END) { if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) { - *result = opt->value.u_int; + switch (opt->desc->type) { + case TYPE_INT: *result = opt->value.u_int; break; + case TYPE_STRING: *result = strtol(opt->value.u_string, NULL, 0); + break; + default: Error2("cannot convert type %d of option %s to int", + opt->desc->type, opt->desc->defname); + opt->desc = ODESC_ERROR; + return -1; + } opt->desc = ODESC_DONE; return 0; } @@ -2515,7 +2523,7 @@ int retropt_bind(struct opt *opts, { bool tight = false; struct sockaddr_un *s_un = (struct sockaddr_un *)sa; - *salen = xiosetunix(s_un, bindname, false, tight); + *salen = xiosetunix(af, s_un, bindname, false, tight); } break; #endif /* WITH_UNIX */ diff --git a/xioopts.h b/xioopts.h index 849cb46..dfa8ddc 100644 --- a/xioopts.h +++ b/xioopts.h @@ -499,7 +499,8 @@ enum e_optcode { OPT_PIPES, /*OPT_PORT,*/ OPT_PROMPT, /* readline */ - OPT_PROTOCOL_FAMILY, + OPT_PROTOCOL, /* 6=TCP, 17=UDP */ + OPT_PROTOCOL_FAMILY, /* 1=PF_UNIX, 2=PF_INET, 10=PF_INET6 */ OPT_PROXYPORT, OPT_PROXY_AUTHORIZATION, OPT_PROXY_RESOLVE, @@ -593,9 +594,7 @@ enum e_optcode { #ifdef SO_PRIORITY OPT_SO_PRIORITY, #endif -#ifdef SO_PROTOTYPE OPT_SO_PROTOTYPE, -#endif OPT_SO_RCVBUF, OPT_SO_RCVBUF_LATE, #ifdef SO_RCVLOWAT @@ -771,7 +770,8 @@ enum e_optcode { /* keep consistent with xiohelp.c:optionphasenames ! */ enum e_phase { - PH_ALL, /* not for options; use in apply funcs to say "all phases" */ + PH_ALL, /* not for option definitions; use in apply funcs to + say "all phases" */ PH_INIT, /* retrieving info from original state */ PH_EARLY, /* before any other processing */ PH_PREOPEN, /* before file descriptor is created/opened */ From 9d7c7f82441f4fa531636a5a73b97dd63da864f0 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 21 Sep 2008 18:05:53 +0200 Subject: [PATCH 28/75] Makefile now supports datarootdir --- CHANGES | 3 +++ Makefile.in | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index e78e07a..04443c7 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,9 @@ corrections: replaced the select() calls by poll() to cleanly fix the problems with many file descriptors already open + Makefile now supports datarootdir (thanks to Camillo Lugaresi for + providing the patch) + ####################### V 1.6.0.1: new features: diff --git a/Makefile.in b/Makefile.in index 583985b..e5b1f29 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,6 +15,7 @@ exec_prefix = @exec_prefix@ BINDEST = @bindir@ +datarootdir = @datarootdir@ MANDEST = @mandir@ srcdir = @srcdir@ @@ -124,13 +125,13 @@ doc: doc/xio.help strip: progs strip $(PROGS) -install: progs doc/socat.1 +install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 - $(INSTALL) -m 644 doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat From 9a097fc49df8bc2ae651c0d601942265ea6f7ddb Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 21 Sep 2008 18:08:26 +0200 Subject: [PATCH 29/75] socat should now build under MacOS X 10.4 --- CHANGES | 4 ++ configure.in | 156 ++++++++++++++++++++++----------------------------- test.sh | 7 ++- 3 files changed, 76 insertions(+), 91 deletions(-) diff --git a/CHANGES b/CHANGES index 04443c7..2ed730c 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,10 @@ corrections: Makefile now supports datarootdir (thanks to Camillo Lugaresi for providing the patch) +porting: + socat should now build under MacOS X 10.4 (thanks to Camillo Lugaresi for + providing the patch) + ####################### V 1.6.0.1: new features: diff --git a/configure.in b/configure.in index f3161ce..a0a3d80 100644 --- a/configure.in +++ b/configure.in @@ -55,13 +55,24 @@ AC_CHECK_HEADERS(pwd.h grp.h stdint.h sys/types.h sys/poll.h sys/socket.h sys/ui AC_CHECK_HEADERS(pty.h) AC_CHECK_HEADERS(netinet/in.h netinet/in_systm.h netinet/ip.h netinet/tcp.h) AC_CHECK_HEADERS(netinet6/in6.h) # found on OpenBSD, used for IPV6_* -AC_CHECK_HEADERS(arpa/nameser.h resolv.h) -AC_CHECK_HEADERS(termios.h net/if.h linux/if_tun.h) +AC_CHECK_HEADERS(net/if.h, [], [], [AC_INCLUDES_DEFAULT + #if HAVE_SYS_SOCKET_H + #include + #endif]) # Mac OS X requires including sys/socket.h +AC_CHECK_HEADERS(arpa/nameser.h) + +AC_HEADER_RESOLV() + +AC_CHECK_HEADERS(termios.h linux/if_tun.h) AC_CHECK_HEADERS(sys/utsname.h sys/select.h sys/file.h) AC_CHECK_HEADERS(util.h libutil.h sys/stropts.h regex.h) AC_CHECK_HEADERS(linux/fs.h linux/ext2_fs.h) +dnl Link libresolv if necessary (for Mac OS X) +AC_SEARCH_LIBS([res_9_init], [resolv]) + + dnl Check for extra socket library (for Solaris) AC_CHECK_FUNC(hstrerror, , AC_CHECK_LIB(resolv, hstrerror, [LIBS="$LIBS -lresolv"; AC_DEFINE(HAVE_HSTRERROR)])) AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) @@ -185,7 +196,11 @@ AC_ARG_ENABLE(ip6, [ --disable-ip6 disable IPv6 support], if test "$WITH_IP6"; then AC_CHECK_HEADERS([netinet/ip6.h], [AC_DEFINE(HAVE_NETINET_IP6_H) AC_DEFINE(WITH_IP6)], - [AC_MSG_WARN([include file netinet/ip6.h not found, disabling IP6])]) + [AC_MSG_WARN([include file netinet/ip6.h not found, disabling IP6])], + [AC_INCLUDES_DEFAULT + #ifdef HAVE_NETINET_IN_H + # include + #endif]) fi AC_MSG_CHECKING(whether to include raw IP support) @@ -284,93 +299,56 @@ AC_ARG_ENABLE(readline, [ --disable-readline disable readline support], esac], [AC_MSG_RESULT(yes); WITH_READLINE=1 ]) -# check if we find the components of GNU readline if test -n "$WITH_READLINE"; then - # first, we need to find the include file - AC_MSG_NOTICE(checking for components of readline) - #AC_CHECK_HEADERS(readline/readline.h readline/history.h) - AC_CACHE_VAL(sc_cv_have_readline_h, - [AC_TRY_COMPILE([#include /* FreeBSD needs "FILE *" */ -#include -#include ],[;], - [sc_cv_have_readline_h=yes; READLINE_ROOT=""; ], - [sc_cv_have_readline_h=no - for D in "/sw" "/usr/local" "/opt/freeware" "/usr/sfw"; do - I="$D/include" - i="$I/readline/readline.h" - if test -r "$i"; then - #V_INCL="$V_INCL -I$I/" - CPPFLAGS="$CPPFLAGS -I$I" - AC_MSG_NOTICE(found $i) - sc_cv_have_readline_h=yes; READLINE_ROOT="$D" - break; - fi - done]) - ]) - if test "$sc_cv_have_readline_h" = "yes"; then - AC_DEFINE(HAVE_READLINE_READLINE_H) - AC_DEFINE(HAVE_READLINE_HISTORY_H) - fi - AC_MSG_NOTICE(checked for readline.h... $sc_cv_have_readline_h) -fi # end checking for readline.h -# -if test -n "$WITH_READLINE" -a "$sc_cv_have_readline_h" = yes; then - # next, we search for the readline library (libreadline.*) - AC_MSG_CHECKING(for libreadline) - AC_CACHE_VAL(sc_cv_have_libreadline, - [ LIBS0="$LIBS" - if test -n "$READLINE_ROOT"; then - L="$READLINE_ROOT/lib"; LIBS="$LIBS0 -L$L -lreadline" - else - LIBS="$LIBS0 -lreadline" - fi - AC_TRY_LINK([#include /* FreeBSD needs FILE * */ -#include -#include ], - [readline(NULL)], - [sc_cv_have_libreadline='yes'], - [sc_cv_have_libreadline='no' - LIBS1="$LIBS" - LIBS="$LIBS -lcurses" - AC_TRY_LINK([#include /* FreeBSD needs FILE * */ -#include -#include ], - [readline(NULL)], - [sc_cv_have_libreadline='yes'], - [sc_cv_have_libreadline='no' - LIBS="$LIBS1 -lncurses" # eg for SuSE52 - AC_TRY_LINK([#include /* FreeBSD needs FILE * */ -#include -#include ], - [readline(NULL)], - [sc_cv_have_libreadline='yes'], - [sc_cv_have_libreadline='no']) - ])] - ) - if test "$sc_cv_have_libreadline" != 'yes'; then - LIBS="$LIBS0" - fi - ] -#! missing libcurses dependency; missing freeware places -# # we test if libcurses is available and if it can be used without further libs -# AC_CHECK_LIB(ncurses, main, , AC_CHECK_LIB(curses, main)) # some Linux work with this -# # we test if readline can be used without further libs -# AC_CHECK_LIB(readline, readline) -# # we see if using_history() is already in $LIBS; if not, we try it with curses -# AC_CHECK_FUNC(using_history, , AC_CHECK_LIB(history, using_history,,, -lcurses)) -#fi - ) - if test "$sc_cv_have_libreadline" = 'yes'; then - AC_DEFINE(HAVE_LIBREADLINE) - fi - AC_MSG_RESULT($sc_cv_have_libreadline) -fi -# -if test -n "$WITH_READLINE"; then - if test "$sc_cv_have_readline_h" = "yes" -a "$sc_cv_have_libreadline" = "yes"; then - AC_DEFINE(WITH_READLINE) - else - AC_MSG_WARN([not all components of readline found, disabling it]); + CPPFLAGS_ORIG=$CPPFLAGS + CFLAGS_ORIG=$CFLAGS + LIBS_ORIG=$LIBS + sc_usable_readline_found= + + for D in "" "/usr/local" "/opt/local" "/sw" "/opt/freeware" "/usr/sfw"; do + if test -n "$D" ; then + CPPFLAGS="$CPPFLAGS -I$D/include" + CFLAGS="$CFLAGS -L$D/lib" + DLOC="in location $D" + else + DLOC="in default location" + fi + AC_MSG_CHECKING(for usable readline $DLOC) + + # Some systems require -lcurses, some require -lncurses. + # Mac OS X 10.4 (and others) ships with libedit masquerading as readline, + # but it doesn't work well with socat. It can be recognized by the absence + # of append_history. + + for L in "" "-lcurses" "-lncurses"; do + LIBS="$LIBS_ORIG -lreadline $L" + AC_TRY_LINK( + [ #include + #include + #include ], + [ readline(NULL); + append_history(0, NULL); ], + [ sc_usable_readline_found=1 + break ]) + done + + if test -n "$sc_usable_readline_found"; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_READLINE_READLINE_H,1) + AC_DEFINE(HAVE_READLINE_HISTORY_H,1) + AC_DEFINE(HAVE_LIBREADLINE,1) + AC_DEFINE(WITH_READLINE,1) + break + else + AC_MSG_RESULT(no) + CPPFLAGS=$CPPFLAGS_ORIG + CFLAGS=$CFLAGS_ORIG + LIBS=$LIBS_ORIG + fi + done + + if test -z "$sc_usable_readline_found"; then + AC_MSG_WARN([no suitable version of readline found; perhaps you need to install a newer version]) fi fi diff --git a/test.sh b/test.sh index 5cbb3ec..6613a59 100755 --- a/test.sh +++ b/test.sh @@ -115,6 +115,7 @@ NetBSD)IFCONFIG=/sbin/ifconfig ;; OpenBSD)IFCONFIG=/sbin/ifconfig ;; OSF1) IFCONFIG=/sbin/ifconfig ;; SunOS) IFCONFIG=/sbin/ifconfig ;; +Darwin)IFCONFIG=/sbin/ifconfig ;; #*) IFCONFIG=/sbin/ifconfig ;; esac @@ -177,7 +178,7 @@ ECHO="echo $E" PRINTF="printf" case "$TERM" in -vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color) +vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color|xterm-color) # there are different behaviours of printf (and echo) # on some systems, echo behaves different than printf... if [ $($PRINTF "\0101") = "A" ]; then @@ -1637,6 +1638,7 @@ runsip4 () { OpenBSD)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');; OSF1) l=$($IFCONFIG -a |grep ' inet ') ;; SunOS) l=$($IFCONFIG -a |grep 'inet ') ;; + Darwin)l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; # *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; esac [ -z "$l" ] && return 1 @@ -1662,12 +1664,13 @@ runsip6 () { NetBSD)l=$(/sbin/ifconfig -a |grep 'inet6 ::1 ');; OSF1) l=$(/sbin/ifconfig -a |grep ' inet6 ') ;; SunOS) l=$(/sbin/ifconfig -a |grep 'inet6 ') ;; + Darwin)l=$(/sbin/ifconfig lo0 |grep 'inet6 ::1 ') ;; *) l=$(/sbin/ifconfig -a |grep ' ::1[^:0-9A-Fa-f]') ;; esac [ -z "$l" ] && return 1 # existence of interface might not suffice, check for routeability: case "$UNAME" in - Darwin) ping -c 1 ::1; l="$?" ;; + Darwin) ping6 -c 1 ::1; l="$?" ;; Linux) ping6 -c 1 ::1; l="$?" ;; *) if [ -n "$l" ]; then l=0; else l=1; fi ;; esac From b0adfb95ae17dfe1ae4b9ac84d7cd6a5caf6628f Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 22 Sep 2008 08:48:16 +0200 Subject: [PATCH 30/75] fixes bug with missing \0 in xioparsenetwork --- xio-socket.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xio-socket.c b/xio-socket.c index 4c83f18..b84f43d 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1700,6 +1700,7 @@ int xioparsenetwork(const char *rangename, int pf, struct xiorange *range) { return STAT_NORETRY; } strncpy(addrname, rangename, maskname-rangename-1); + addrname[maskname-rangename-1] = '\0'; result = dalan(addrname, (char *)&range->netaddr.soa.sa_data, &addrlen, sizeof(range->netaddr)-(size_t)(&((struct sockaddr *)0)->sa_data) From e337b514054f7387a0d6f5e1e855188475c6c6be Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 22 Sep 2008 21:48:00 +0200 Subject: [PATCH 31/75] test generic sockets for TCP6 and UNIX --- test.sh | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 9 deletions(-) diff --git a/test.sh b/test.sh index 4255347..e0cc7ae 100755 --- a/test.sh +++ b/test.sh @@ -8486,7 +8486,7 @@ N=$((N+1)) # test the SOCKET-CONNECT address (against TCP4-LISTEN) -NAME=SOCKET_CONNECT +NAME=SOCKET_CONNECT_TCP4 case "$TESTS" in *%functions%*|*%generic%*|*%socket%*|*%$NAME%*) TEST="$NAME: socket connect with TCP/IPv4" @@ -8501,7 +8501,7 @@ ts1p=$(printf "%04x" $ts0p); ts1a="7f000001" # "127.0.0.1" ts1="x${ts1p}${ts1a}x0000000000000000" ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts TCP4-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE" CMD1="$SOCAT $opts - SOCKET-CONNECT:2:6:$ts1,bind=x${ts1b}00000000x0000000000000000" printf "test $F_n $TEST... " $N @@ -8535,6 +8535,101 @@ esac PORT=$((PORT+1)) N=$((N+1)) +# test the SOCKET-CONNECT address (against TCP6-LISTEN) +NAME=SOCKET_CONNECT_TCP6 +case "$TESTS" in +*%functions%*|*%generic%*|*%tcp6%*|*%socket%*|*%$NAME%*) +TEST="$NAME: socket connect with TCP/IPv6" +# start a TCP6-LISTEN process that echoes data, and send test data using +# SOCKET-CONNECT, selecting TCP/IPv6. The sent data should be returned. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts0p=$PORT; PORT=$((PORT+1)) +ts0a="[::1]" +ts1p=$(printf "%04x" $ts0p); +ts1a="00000000000000000000000000000001" # "127.0.0.1" +ts1="x${ts1p}x000000000000x${ts1a}" +ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) +da="test$N $(date) $RANDOM" +CMD0="$SOCAT $opts TCP6-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE" +CMD1="$SOCAT $opts - SOCKET-CONNECT:10:6:$ts1,bind=x${ts1b}x000000000000x00000000000000000000000000000000" +printf "test $F_n $TEST... " $N +$CMD0 2>"${te}0" & +pid0="$!" +waittcp6port $ts0p 1 +echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" +rc1="$?" +kill "$pid0" 2>/dev/null; wait; +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) + +# test the SOCKET-CONNECT address (against UNIX-LISTEN) +NAME=SOCKET_CONNECT_UNIX +case "$TESTS" in +*%functions%*|*%generic%*|*%unix%*|*%socket%*|*%$NAME%*) +TEST="$NAME: socket connect with UNIX domain" +# start a UNIX-LISTEN process that echoes data, and send test data using +# SOCKET-CONNECT, selecting UNIX socket. The sent data should be returned. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts0="$td/test$N.server" +ts1="$td/test$N.client" +da="test$N $(date) $RANDOM" +CMD0="$SOCAT $opts UNIX-LISTEN:$ts0,reuseaddr PIPE" +CMD1="$SOCAT $opts - SOCKET-CONNECT:1:0:\\\"$ts0\\\0\\\",bind=\\\"$ts1\\\0\\\"" +printf "test $F_n $TEST... " $N +$CMD0 2>"${te}0" & +pid0="$!" +waitfile $ts0 1 +echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" +rc1="$?" +kill "$pid0" 2>/dev/null; wait; +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi ;; +esac +N=$((N+1)) + # test the SOCKET-LISTEN address (with TCP4-CONNECT) NAME=SOCKET_LISTEN case "$TESTS" in @@ -8552,7 +8647,7 @@ ts0a="7f000001" # "127.0.0.1" ts0="x${ts0p}${ts0a}x0000000000000000" ts1b=$PORT; PORT=$((PORT+1)) ts1="$ts1a:$ts1p" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts SOCKET-LISTEN:2:6:$ts0,reuseaddr PIPE" CMD1="$SOCAT $opts - TCP4-CONNECT:$ts1,bind=:$ts1b" printf "test $F_n $TEST... " $N @@ -8605,7 +8700,7 @@ ts1p=$(printf "%04x" $ts0p); ts1a="7f000001" # "127.0.0.1" ts1="x${ts1p}${ts1a}x0000000000000000" ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts UDP4-RECVFROM:$ts0p,reuseaddr,bind=$ts0a PIPE" CMD1="$SOCAT $opts - SOCKET-SENDTO:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000" printf "test $F_n $TEST... " $N @@ -8656,7 +8751,7 @@ ts0a="7f000001" # "127.0.0.1" ts0="x${ts0p}${ts0a}x0000000000000000" ts1b=$PORT; PORT=$((PORT+1)) ts1="$ts1a:$ts1p" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts SOCKET-RECVFROM:2:$SOCK_DGRAM:17:$ts0,reuseaddr PIPE" CMD1="$SOCAT $opts - UDP4-SENDTO:$ts1,bind=:$ts1b" printf "test $F_n $TEST... " $N @@ -8707,7 +8802,7 @@ ts0a="7f000001" # "127.0.0.1" ts0="x${ts0p}${ts0a}x0000000000000000" ts1b=$PORT; PORT=$((PORT+1)) ts1="$ts1a:$ts1p" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts -u SOCKET-RECV:2:$SOCK_DGRAM:17:$ts0,reuseaddr -" CMD1="$SOCAT $opts -u - UDP4-SENDTO:$ts1,bind=:$ts1b" printf "test $F_n $TEST... " $N @@ -8760,7 +8855,7 @@ ts1a="7f000001" # "127.0.0.1" ts0b=$(printf "%04x" $ts0p) ts1b=$(printf "%04x" $ts1p) ts1="x${ts0b}${ts1a}x0000000000000000" -da="$(date) $RANDOM" +da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts UDP4-DATAGRAM:$ts0a:$ts1p,bind=:$ts0p,reuseaddr PIPE" CMD1="$SOCAT $opts - SOCKET-DATAGRAM:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000" printf "test $F_n $TEST... " $N @@ -8833,7 +8928,7 @@ tp="$td/test$N.pty" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" +da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts PTY,LINK=$tp pipe" CMD1="$SOCAT $opts - file:$tp,ioctl-void=$TIOCEXCL,raw,echo=0" CMD2="$SOCAT $opts - file:$tp,raw,echo=0" @@ -8896,7 +8991,7 @@ tp="$PORT" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da="$(date)" +da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts TCP4-L:$tp,setsockopt-int=$SOL_SOCKET:$SO_REUSEADDR:1 PIPE" CMD1="$SOCAT $opts - TCP:localhost:$tp" CMD2="$CMD0" From 2ffe5a324eeb3aba48cfda17ef0f9a3cc4a22149 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 22 Sep 2008 22:17:55 +0200 Subject: [PATCH 32/75] merged features ancillary, envvar --- CHANGES | 33 +++- README | 12 ++ VERSION | 2 +- config.h.in | 12 ++ configure.in | 15 ++ doc/socat-multicast.html | 3 +- doc/socat.yo | 177 ++++++++++++++--- hostan.c | 9 +- socat.c | 2 + sycls.c | 31 ++- sycls.h | 6 +- sysincludes.h | 11 +- sysutils.c | 154 +++++++++++---- sysutils.h | 11 +- test.sh | 415 ++++++++++++++++++++++++++++++++++++++- utils.c | 16 +- utils.h | 5 +- xio-ascii.c | 51 ++++- xio-ascii.h | 6 +- xio-ip.c | 122 +++++++++++- xio-ip.h | 10 +- xio-ip4.c | 39 +++- xio-ip4.h | 6 +- xio-ip6.c | 228 ++++++++++++++++++++- xio-ip6.h | 29 ++- xio-ipapp.c | 25 +-- xio-listen.c | 46 ++--- xio-openssl.c | 29 +-- xio-progcall.c | 18 +- xio-proxy.c | 25 +-- xio-socket.c | 379 ++++++++++++++++++++++++++++------- xio-socket.h | 13 +- xio-socks.c | 23 +-- xio-tcpwrap.c | 3 +- xio-udp.c | 19 +- xio-unix.c | 23 ++- xio-unix.h | 6 +- xio.h | 2 + xioinitialize.c | 51 +++++ xioopts.c | 70 ++++++- xioopts.h | 20 ++ xioread.c | 28 ++- 42 files changed, 1898 insertions(+), 287 deletions(-) diff --git a/CHANGES b/CHANGES index 042c977..f402c88 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,34 @@ new features: new address option "escape" allows to break a socat instance even when raw terminal mode prevents ^C etc. + socat sets environment variables SOCAT_VERSION, SOCAT_PID, SOCAT_PPID + for use in executed scripts + + socat sets environment variables SOCAT_SOCKADDR, SOCAT_SOCKPORT, + SOCAT_PEERADDR, SOCAT_PEERPORT in LISTEN type addresses (feature + suggested by Ed Sawicki) + + socat receives all ancillary messages with each received packet on + datagram related addresses. The messages are logged in raw form with + debug level, and broken down with info level. note: each type of + ancillary message must be enabled by appropriate address options. + + socat provides the contents of ancillary messages received on RECVFROM + addresses in appropriate environment variables: + SOCAT_IP_PKTINFO_DSTADDR, SOCAT_IP_PKTINFO_IF, SOCAT_IP_PKTINFO_LOCADDR + (not on BSD); SOCAT_IP_RECVDSTADDR, SOCAT_IP_RECVIF (BSD); + SOCAT_SCM_TIMESTAMP, SOCAT_IP_OPTIONS, SOCAT_IP_TOS, SOCAT_IP_TTL, + SOCAT_IPV6_HOPLIMIT, SOCAT_IPV6_TCLASS, SOCAT_IPV6_PKTINFO_DSTADDR + + the following address options were added to enable ancillary messages: + so-timestamp, ip-pktinfo, ip-recvdstaddr, ip-recverr, ip-recvif, + ip-recvopts, ip-recvtos, ip-recvttl, ipv6-recvdstopts, ipv6-recverr, + ipv6-recvhoplimit, ipv6-recvhopopts, ipv6-recvpathmtu, + ipv6-recvpktinfo, ipv6-recvrthdr, ipv6-recvtclass + + new address options ipv6-tclass and ipv6-unicast-hops set the related + socket options. + corrections: some raw IP and UNIX datagram modes failed on BSD systems @@ -13,9 +41,10 @@ corrections: there was a bug in ip*-recv with bind option: it did not bind, and with the first received packet an error occurred: socket_init(): unknown address family 0 + test: RAWIP4RECVBIND RECVFROM addresses with FORK option hung after processing the first - packet. + packet. test: UDP4RECVFROM_FORK corrected a few mistakes that caused compiler warnings on 64bit hosts @@ -24,7 +53,7 @@ corrections: when the EXEC address got a string with consecutive spaces it created additional empty arguments (thanks to Olivier Hervieu for reporting - this bug) + this bug). test: EXECSPACES in ignoreeof polling mode socat also blocked data transfer in the other direction during the 1s wait intervalls (thanks to Jorgen Cederlof for diff --git a/README b/README index 6baad77..d92eb4a 100644 --- a/README +++ b/README @@ -180,10 +180,22 @@ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/sfw/lib For some shell scripts, it is preferable to have /usr/xpg4/bin at a prominent position in $PATH. +With the default compiler define _GNU_SOURCE, the CMSG_* macros are not +available, and therefore ancillary messages cannot be used. To enable these try +the following: +After running ./configure, edit Makefile and replace "-D_GNU_SOURCE" with +"-D_XPG4_2 -D__EXTENSIONS__" and run make + platform specifics - hp-ux -------------------------- +Ancillary messages cannot be compiled in with socat: both struct msghdr and +strutc cmsghdr are required. Compiling with -D_XOPEN_SOURCE_EXTENDED provides +struct msghdr but disables struct cmsghdr while -D_OPEN_SOURCE disables struct +msghdr but disables struct cmsghdr. Please contact socat development if you +know a solution. + Shutting down the write channel of a UNIX domain socket does not seem to trigger an EOF on the other socket. This makes problems with the exec and system addresses. diff --git a/VERSION b/VERSION index f509df5..f881903 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape+timestamp+ancillary+envvar" diff --git a/config.h.in b/config.h.in index 2e330da..0d8c9cc 100644 --- a/config.h.in +++ b/config.h.in @@ -224,6 +224,15 @@ /* Define if you have the header file. */ #undef HAVE_NET_IF_H +/* Define if you have the header file. */ +#undef HAVE_NET_IF_DL_H + +/* Define if you have the header file. */ +#undef HAVE_LINUX_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_LINUX_ERRQUEUE_H + /* Define if you have the header file. */ #undef HAVE_LINUX_IF_TUN_H @@ -334,6 +343,9 @@ /* define if your struct msghdr has msg_flag */ #undef HAVE_STRUCT_MSGHDR_MSGFLAGS +/* define if you have struct cmsghdr */ +#undef HAVE_STRUCT_CMSGHDR + /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #undef HAVE_STRUCT_IP_IP_HL diff --git a/configure.in b/configure.in index a0a3d80..013a2c3 100644 --- a/configure.in +++ b/configure.in @@ -64,6 +64,8 @@ AC_CHECK_HEADERS(arpa/nameser.h) AC_HEADER_RESOLV() AC_CHECK_HEADERS(termios.h linux/if_tun.h) +AC_CHECK_HEADERS(net/if_dl.h) +AC_CHECK_HEADERS(linux/types.h linux/errqueue.h) AC_CHECK_HEADERS(sys/utsname.h sys/select.h sys/file.h) AC_CHECK_HEADERS(util.h libutil.h sys/stropts.h regex.h) AC_CHECK_HEADERS(linux/fs.h linux/ext2_fs.h) @@ -1044,6 +1046,19 @@ if test $sc_cv_struct_msghdr_msgflags = yes; then fi AC_MSG_RESULT($sc_cv_struct_msghdr_msgflags) +dnl check for struct cmsghdr +AC_MSG_CHECKING(for struct cmsghdr) +AC_CACHE_VAL(sc_cv_struct_cmsghdr, +[AC_TRY_COMPILE([#include +#include +#include ],[struct cmsghdr s;], +[sc_cv_struct_cmsghdr=yes], +[sc_cv_struct_cmsghdr=no])]) +if test $sc_cv_struct_cmsghdr = yes; then + AC_DEFINE(HAVE_STRUCT_CMSGHDR) +fi +AC_MSG_RESULT($sc_cv_struct_cmsghdr) + dnl check for ip_hl in struct ip AC_MSG_CHECKING(for struct ip.ip_hl) AC_CACHE_VAL(sc_cv_struct_ip_ip_hl, diff --git a/doc/socat-multicast.html b/doc/socat-multicast.html index fc31f7b..829eba3 100644 --- a/doc/socat-multicast.html +++ b/doc/socat-multicast.html @@ -240,8 +240,7 @@ interfaces. This membership cannot be dropped on Linux. sockets without exception accept packets that are directly addressed to them; the multi- and broadcast receiving features are just extensions to the normal functionality. socat has no way to find out if an incoming packet is addressed -to a unicast, multicast or broadcast address. Please contact the author if you -know how the target address can be determined.

+to a unicast, multicast, or broadcast address.

Authentication or encryption are not available.

diff --git a/doc/socat.yo b/doc/socat.yo index d422aef..a432e90 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -127,7 +127,8 @@ dit(bf(tt(-lf))tt( )) dit(bf(tt(-ls))) Writes messages to stderr (this is the default). label(option_lp)dit(bf(tt(-lp))tt()) - Overrides the program name printed in error messages. + Overrides the program name printed in error messages and used for + constructing environment variable names. dit(bf(tt(-lu))) Extends the timestamp of error messages to microsecond resolution. Does not work when logging to syslog. @@ -364,6 +365,7 @@ label(ADDRESS_IP_DATAGRAM)dit(bf(tt(IP-DATAGRAM:
:))) Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(RANGE)(GROUP_RANGE) nl() Useful options: + link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(tcpwrap)(OPTION_TCPWRAPPERS), link(broadcast)(OPTION_SO_BROADCAST), @@ -373,7 +375,6 @@ label(ADDRESS_IP_DATAGRAM)dit(bf(tt(IP-DATAGRAM:
:))) link(ip-add-membership)(OPTION_IP_ADD_MEMBERSHIP), link(ttl)(OPTION_TTL), link(tos)(OPTION_TOS), - link(bind)(OPTION_BIND), link(pf)(OPTION_PROTOCOL_FAMILY)nl() See also: link(IP4-DATAGRAM)(ADDRESS_IP4_DATAGRAM), @@ -783,7 +784,8 @@ label(ADDRESS_UDP_DATAGRAM)dit(bf(tt(UDP-DATAGRAM:
:))) options. This address type can for example be used for implementing symmetric or asymmetric broadcast or multicast communications.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl() - Useful options: + Useful options: + link(bind)(OPTION_BIND), link(range)(OPTION_RANGE), link(tcpwrap)(OPTION_TCPWRAPPERS), link(broadcast)(OPTION_SO_BROADCAST), @@ -793,7 +795,6 @@ label(ADDRESS_UDP_DATAGRAM)dit(bf(tt(UDP-DATAGRAM:
:))) link(ip-add-membership)(OPTION_IP_ADD_MEMBERSHIP), link(ttl)(OPTION_TTL), link(tos)(OPTION_TOS), - link(bind)(OPTION_BIND), link(sourceport)(OPTION_SOURCEPORT), link(pf)(OPTION_PROTOCOL_FAMILY)nl() See also: @@ -1543,8 +1544,8 @@ label(OPTION_INTERFACE)dit(bf(tt(interface=))) label(OPTION_SO_BROADCAST)dit(bf(tt(broadcast))) For datagram sockets, allows sending to broadcast addresses and receiving packets addressed to broadcast addresses. -label(OPTION_BSDCOMPAT)dit(bf(tt(bsdcompat))) - Emulates some (old?) bugs of the BSD socket implementation. +COMMENT(label(OPTION_BSDCOMPAT)dit(bf(tt(bsdcompat))) + Emulates some (old?) bugs of the BSD socket implementation.) label(OPTION_DEBUG)dit(bf(tt(debug))) Enables socket debugging. label(OPTION_DONTROUTE)dit(bf(tt(dontroute))) @@ -1639,6 +1640,9 @@ COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs))) label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=))) Forces the use of the specified IP version. can be something like "ip4" or "ip6". +label(OPTION_SO_TIMESTAMP)dit(bf(tt(so-timestamp))) + Sets the SO_TIMESTAMP socket option. This enables receiving and logging of + timestamp ancillary messages. enddit() startdit()enddit()nl() @@ -1665,13 +1669,13 @@ label(OPTION_TOS)dit(bf(tt(tos=))) label(OPTION_TTL)dit(bf(tt(ttl=))) Sets the TTL (time to live) field of outgoing packets to [link(byte)(TYPE_BYTE)]. -label(OPTION_IPOPTIONS)dit(bf(tt(ipoptions=))) +label(OPTION_IPOPTIONS)dit(bf(tt(ip-options=))) Sets IP options like source routing. Must be given in binary form, recommended format is a leading "x" followed by an even number of hex digits. This option may be used multiple times, data are appended. E.g., to connect to host 10.0.0.1 via some gateway using a loose source route, use the gateway as address parameter and set a loose source route - using the option code(ipoptions=x8307040a000001).nl() + using the option code(ip-options=x8307040a000001).nl() IP options are defined in RFC 791. COMMENT(, RFC 2113)nl() COMMENT( x00 end of option list x01 no operation (nop) @@ -1690,20 +1694,32 @@ COMMENT(label(OPTION_IP_MULTICAST_LOOP)dit(bf(tt(multicastloop))) Allow looping back outgoing multicast to the local interface.) COMMENT(label(OPTION_IP_MULTICAST_TTL)dit(bf(tt(multicastttl))) Set the TTL for outgoing multicast packets.) -COMMENT(label(OPTION_PKTINFO)dit(bf(tt(pktinfo))) - Set the IP_PKTINFO socket option.) +label(OPTION_IP_PKTINFO)dit(bf(tt(pktinfo))) + Sets the IP_PKTINFO socket option. This enables receiving and logging of + ancillary messages containing destination address and interface (Linux). COMMENT(label(OPTION_PKTOPTS)dit(bf(tt(pktopts))) Set the IP_PKTOPTIONS socket option.) -COMMENT(label(OPTION_RECVERR)dit(bf(tt(recverr))) - Set the IP_RECVERR socket option.) -COMMENT(label(OPTION_RECVOPTS)dit(bf(tt(recvopts))) - Set the IP_RECVOPTS socket option.) -COMMENT(label(OPTION_RECVTOS)dit(bf(tt(recvtos))) - Set the IP_RECVTOS socket option.) -COMMENT(label(OPTION_RECVTTL)dit(bf(tt(recvttl))) - Set the IP_RECVTTL socket option.) +label(OPTION_IP_RECVERR)dit(bf(tt(recverr))) + Sets the IP_RECVERR socket option. This enables receiving and logging of + ancillary messages containing detailled error information. +label(OPTION_IP_RECVOPTS)dit(bf(tt(recvopts))) + Sets the IP_RECVOPTS socket option. This enables receiving and logging of IP + options ancillary messages (Linux, *BSD). +label(OPTION_IP_RECVTOS)dit(bf(tt(recvtos))) + Sets the IP_RECVTOS socket option. This enables receiving and logging of TOS + (type of service) ancillary messages (Linux). +label(OPTION_IP_RECVTTL)dit(bf(tt(recvttl))) + Sets the IP_RECVTTL socket option. This enables receiving and logging of TTL + (time to live) ancillary messages (Linux, *BSD). COMMENT(label(OPTION_RETOPTS)dit(bf(tt(retopts))) Set the IP_RETOPTS socket option.) +label(OPTION_IP_RECVDSTADDR)dit(bf(tt(recvdstaddr))) + Sets the IP_RECVDSTADDR socket option. This enables receiving and logging of + ancillary messages containing destination address + (*BSD). +label(OPTION_IP_RECVIF)dit(bf(tt(recvif))) + Sets the IP_RECVIF socket option. This enables receiving and logging of + interface ancillary messages (*BSD). COMMENT(label(OPTION_ROUTERALERT)dit(bf(tt(routeralert))) Set the IP_ROUTER_ALERT socket option.) label(OPTION_IP_ADD_MEMBERSHIP) @@ -1758,6 +1774,30 @@ label(OPTION_IPV6_V6ONLY)dit(bf(tt(ipv6only=))) Sets the IPV6_V6ONLY socket option. If 0, the TCP stack will also accept connections using IPv4 protocol on the same port. The default is system dependent. +label(OPTION_IPV6_RECVDSTOPTS)dit(bf(tt(ipv6-recvdstopts))) + Sets the IPV6_RECVDSTOPTS socket option. This enables receiving and logging + of ancillary messages containing the destination options. +label(OPTION_IPV6_RECVHOPLIMIT)dit(bf(tt(ipv6-recvhoplimit))) + Sets the IPV6_RECVHOPLIMIT socket option. This enables receiving and logging + of ancillary messages containing the hoplimit. +label(OPTION_IPV6_RECVHOPOPTS)dit(bf(tt(ipv6-recvhopopts))) + Sets the IPV6_RECVHOPOPTS socket option. This enables receiving and logging + of ancillary messages containing the hop options. +label(OPTION_IPV6_RECVPKTINFO)dit(bf(tt(ipv6-recvpktinfo))) + Sets the IPV6_RECVPKTINFO socket option. This enables receiving and logging + of ancillary messages containing destination address and interface. +label(OPTION_IPV6_UNICAST_HOPS)dit(bf(tt(ipv6-unicast-hops=link(TYPE_INT)()))) + Sets the IPV6_UNICAST_HOPS socket option. This sets the hop count limit + (TTL) for outgoing unicast packets. +label(OPTION_IPV6_RECVRTHDR)dit(bf(tt(ipv6-recvrthdr))) + Sets the IPV6_RECVRTHDR socket option. This enables receiving and logging + of ancillary messages containing routing information. +label(OPTION_IPV6_TCLASS)dit(bf(tt(ipv6-tclass))) + Sets the IPV6_TCLASS socket option. This sets the transfer class of outgoing + packets. +label(OPTION_IPV6_RECVTCLASS)dit(bf(tt(ipv6-recvtclass))) + Sets the IPV6_RECVTCLASS socket option. This enables receiving and logging + of ancillary messages containing the transfer class. enddit() startdit()enddit()nl() @@ -2932,45 +2972,126 @@ manpagefiles() label(ENVIRONMENT_VARIABLES) manpagesection(ENVIRONMENT VARIABLES) +Input variables carry information from the environment to socat, output +variables are set by socat for use in executed scripts and programs. + +In the output variables beginning with "SOCAT" this prefix is actually replaced +by the upper case name of the executable or the value of option +link(-lp)(option_lp). + startdit() -dit(bf(SOCAT_DEFAULT_LISTEN_IP)) (Values 4 or 6) Sets the IP version to be used +dit(bf(SOCAT_DEFAULT_LISTEN_IP) (input)) (Values 4 or 6) Sets the IP version to +be used for listen, recv, and recvfrom addresses if no link(pf)(OPTION_PROTOCOL_FAMILY) (protocol-family) option is given. Is overridden by socat options link(-4)(option_4) or link(-6)(option_6). -dit(bf(SOCAT_PREFERRED_RESOLVE_IP)) (Values 0, 4, or 6) Sets the IP version to +dit(bf(SOCAT_PREFERRED_RESOLVE_IP) (input)) (Values 0, 4, or 6) Sets the IP +version to be used when resolving target host names when version is not specified by address type, option link(pf)(OPTION_PROTOCOL_FAMILY) (protocol-family), or address format. If name resolution does not return a matching entry, the first result (with differing IP version) is taken. With value 0, socat always selects the first record and its IP version. -dit(bf(SOCAT_FORK_WAIT)) Specifies the time (seconds) to sleep the parent and -child processes after successful fork(). Useful for debugging. +dit(bf(SOCAT_FORK_WAIT) (input)) Specifies the time (seconds) to sleep the +parent and child processes after successful fork(). Useful for debugging. -dit(bf(HOSTNAME)) Is used to determine the hostname for logging (see +dit(bf(SOCAT_VERSION) (output)) Socat sets this variable to its version string, +e.g. tt("1.6.1.0") for released versions or e.g. tt("1.6.0.1+envvar") for +temporary versions; can be used in scripts invoked by socat. + +dit(bf(SOCAT_PID) (output)) Socat sets this variable to its process id. In case +of link(fork)(OPTION_FORK) address option, SOCAT_PID gets the child processes +id. Forking for link(exec)(ADDRESS_EXEC) and link(system)(ADDRESS_SYSTEM) does +not change SOCAT_PID. + +dit(bf(SOCAT_PPID) (output)) Socat sets this variable to its process id. In +case of link(fork)(OPTION_FORK), SOCAT_PPID keeps the pid of the master process. + +dit(bf(SOCAT_PEERADDR) (output)) With passive socket addresses (all LISTEN and +RECVFROM addresses), this variable is set to a string describing the peers +socket address. Port information is not included. + +dit(bf(SOCAT_PEERPORT) (output)) With appropriate passive socket addresses (TCP +and UDP - LISTEN and RECVFROM), this variable is set to a string containing the +number of the peer port. + +dit(bf(SOCAT_SOCKADDR) (output)) With all LISTEN addresses, this variable is +set to a string describing the local socket address. Port information is not +included. + +dit(bf(SOCAT_SOCKPORT) (output)) With TCP-LISTEN and UDP-LISTEN addresses, this +variable is set to the local port. + +dit(bf(SOCAT_TIMESTAMP) (output)) With all RECVFROM addresses where address +option link(so-timestamp)(OPTION_SO_TIMESTAMP) is applied, socat sets this +variable to the resulting timestamp. + +dit(bf(SOCAT_IP_OPTIONS) (output)) With all IPv4 based RECVFROM addresses where +address option link(ip-recvopts)(OPTION_IP_RECVOPTS) is applied, socat fills +this variable with the IP options of the received packet. + +dit(bf(SOCAT_IP_DSTADDR) (output)) With all IPv4 based RECVFROM addresses where +address option link(ip-recvdstaddr)(OPTION_IP_RECVDSTADDR) (BSD) or +link(ip-pktinfo)(OPTION_IP_PKTINFO) (other platforms) is applied, socat sets +this variable to the destination address of the received packet. This is +particularly useful to identify broadcast and multicast addressed packets. + +dit(bf(SOCAT_IP_IF) (output)) With all IPv4 based RECVFROM addresses where +address option link(ip-recvif)(OPTION_IP_RECVIF) (BSD) or +link(ip-pktinfo)(OPTION_IP_PKTINFO) (other platforms) is applied, socat sets +this variable to the name of the interface where the packet was received. + +dit(bf(SOCAT_IP_LOCADDR) (output)) With all IPv4 based RECVFROM +addresses where address option link(ip-pktinfo)(OPTION_IP_PKTINFO) is applied, +socat sets this variable to the address of the interface where the packet was +received. + +dit(bf(SOCAT_IP_TOS) (output)) With all IPv4 based RECVFROM addresses where +address option link(ip-recvtos)(OPTION_IP_RECVTOS) is applied, socat sets this +variable to the TOS (type of service) of the received packet. + +dit(bf(SOCAT_IP_TTL) (output)) With all IPv4 based RECVFROM addresses where +address option link(ip-recvttl)(OPTION_IP_RECVTTL) is applied, socat sets this +variable to the TTL (time to live) of the received packet. + +dit(bf(SOCAT_IPV6_HOPLIMIT) (output)) With all IPv6 based RECVFROM addresses +where address option link(ipv6-recvhoplimit)(OPTION_IPV6_RECVHOPLIMIT) is +applied, socat sets this variable to the hoplimit value of the received packet. + +dit(bf(SOCAT_IPV6_DSTADDR) (output)) With all IPv6 based RECVFROM +addresses where address option link(ipv6-recvpktinfo)(OPTION_IPV6_RECVPKTINFO) +is applied, socat sets this variable to the destination address of the received +packet. + +dit(bf(SOCAT_IPV6_TCLASS) (output)) With all IPv6 based RECVFROM addresses +where address option link(ipv6-recvtclass)(OPTION_IPV6_RECVTCLASS) is applied, +socat sets this variable to the transfer class of the received packet. + +dit(bf(HOSTNAME) (input)) Is used to determine the hostname for logging (see link(-lh)(option_lh)). -dit(bf(LOGNAME)) Is used as name for the socks client user name if no +dit(bf(LOGNAME) (input)) Is used as name for the socks client user name if no link(socksuser)(OPTION_SOCKSUSER) is given.nl() With options link(su)(OPTION_SUBSTUSER) and link(su-d)(OPTION_SUBSTUSER_DELAYED), LOGNAME is set to the given user name. -dit(bf(USER)) Is used as name for the socks client user name if no +dit(bf(USER) (input)) Is used as name for the socks client user name if no link(socksuser)(OPTION_SOCKSUSER) is given and LOGNAME is empty.nl() With options link(su)(OPTION_SUBSTUSER) and link(su-d)(OPTION_SUBSTUSER_DELAYED), USER is set to the given user name. -dit(bf(SHELL)) +dit(bf(SHELL) (output)) With options link(su)(OPTION_SUBSTUSER) and link(su-d)(OPTION_SUBSTUSER_DELAYED), SHELL is set to the login shell of the given user. -dit(bf(PATH)) +dit(bf(PATH) (output)) Can be set with option link(path)(OPTION_PATH) for link(exec)(ADDRESS_EXEC) and link(system)(ADDRESS_SYSTEM) addresses. -dit(bf(HOME)) +dit(bf(HOME) (output)) With options link(su)(OPTION_SUBSTUSER) and link(su-d)(OPTION_SUBSTUSER_DELAYED), HOME is set to the home directory of the given user. diff --git a/hostan.c b/hostan.c index 8862bf5..19829b2 100644 --- a/hostan.c +++ b/hostan.c @@ -30,12 +30,11 @@ int hostan(FILE *outfile) { #if WITH_SOCKET static int iffan(FILE *outfile) { /* Linux: man 7 netdevice */ - /* FreeBSD: man 4 networking */ + /* FreeBSD, NetBSD: man 4 networking */ /* Solaris: man 7 if_tcp */ /* currently we support Linux and a little FreeBSD */ #ifdef SIOCGIFCONF /* not Solaris */ -#ifdef SIOCGIFINDEX /* not OpenBSD */ #define IFBUFSIZ 32*sizeof(struct ifreq) /*1024*/ int s; @@ -62,22 +61,24 @@ static int iffan(FILE *outfile) { struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i); struct ifreq ifr; +#if 0 || defined(SIOCGIFINDEX) /* not NetBSD, OpenBSD */ strcpy(ifr.ifr_name, ifp->ifr_name); if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) { Error3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s", s, &ifr.ifr_name, strerror(errno)); return 1; } - /*fprintf(outfile, "%2d: %s\n", ifr.ifr_ifindex, ifp->ifr_ifrn.ifrn_name);*/ #if HAVE_STRUCT_IFREQ_IFR_INDEX fprintf(outfile, "%2d: %s\n", ifr.ifr_index, ifp->ifr_name); #elif HAVE_STRUCT_IFREQ_IFR_IFINDEX fprintf(outfile, "%2d: %s\n", ifr.ifr_ifindex, ifp->ifr_name); #endif /* HAVE_STRUCT_IFREQ_IFR_INDEX */ +#else /* !defined(SIOCGIFINDEX) */ + fprintf(outfile, "%2d: %s\n", i/sizeof(struct ifreq), ifp->ifr_name); +#endif /* defined(SIOCGIFINDEX) */ } Close(s); #endif /* defined(SIOCGIFCONF) */ -#endif /* defined(SIOCGIFINDEX) */ return 0; } #endif /* WITH_SOCKET */ diff --git a/socat.c b/socat.c index 3ff3d17..28698bf 100644 --- a/socat.c +++ b/socat.c @@ -267,12 +267,14 @@ int main(int argc, const char *argv[]) { Error("-U and -u must not be combined"); } + xioinitialize2(); Info(copyright_socat); #if WITH_OPENSSL Info(copyright_openssl); Info(copyright_ssleay); #endif Debug2("socat version %s on %s", socatversion, timestamp); + xiosetenv("VERSION", socatversion, 1); /* SOCAT_VERSION */ uname(&ubuf); /* ! here we circumvent internal tracing (Uname) */ Debug4("running on %s version %s, release %s, machine %s\n", ubuf.sysname, ubuf.version, ubuf.release, ubuf.machine); diff --git a/sycls.c b/sycls.c index 347a7cb..4ab902c 100644 --- a/sycls.c +++ b/sycls.c @@ -1,5 +1,5 @@ /* source: sycls.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* explicit system call and C library trace function, for those who miss strace @@ -1055,11 +1055,14 @@ int Recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, int Recvmsg(int s, struct msghdr *msgh, int flags) { int retval, _errno; char infobuff[256]; - Debug3("recvmsg(%d, %p, %d)", s, msgh, flags); + Debug10("recvmsg(%d, %p{%p,%u,%p,%u,%p,%u,%d}, %d)", s, msgh, + msgh->msg_name, msgh->msg_namelen, msgh->msg_iov, msgh->msg_iovlen, + msgh->msg_control, msgh->msg_controllen, msgh->msg_flags, flags); retval = recvmsg(s, msgh, flags); _errno = errno; - Debug2("recvmsg(, {%s}, ) -> %d", + Debug5("recvmsg(, {%s,%u,,%u,,%u,}, ) -> %d", msgh->msg_name?sockaddr_info(msgh->msg_name, msgh->msg_namelen, infobuff, sizeof(infobuff)):"NULL", + msgh->msg_namelen, msgh->msg_iovlen, msgh->msg_controllen, retval); errno = _errno; return retval; @@ -1419,6 +1422,28 @@ int Mkstemp(char *template) { return result; } +int Setenv(const char *name, const char *value, int overwrite) { + int result, _errno; + Debug3("setenv(\"%s\", \"%s\", %d)", name, value, overwrite); + result = setenv(name, value, overwrite); + _errno = errno; + Debug1("setenv() -> %d", result); + errno = _errno; + return result; +} + +/* on Linux it returns int but on FreeBSD void. + we do not expect many errors, so we take void which works on all systems. */ +void Unsetenv(const char *name) { + int _errno; + Debug1("unsetenv(\"%s\")", name); + unsetenv(name); + _errno = errno; + Debug("unsetenv() ->"); + errno = _errno; + return; +} + #if WITH_READLINE char *Readline(const char *prompt) { diff --git a/sycls.h b/sycls.h index 8166d96..03ecff0 100644 --- a/sycls.h +++ b/sycls.h @@ -1,5 +1,5 @@ /* source: sycls.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sycls_h_included @@ -137,6 +137,8 @@ int Atexit(void (*func)(void)); void Exit(int status); void Abort(void); int Mkstemp(char *template); +int Setenv(const char *name, const char *value, int overwrite); +void Unsetenv(const char *name); char *Readline(const char *prompt); void Using_history(void); @@ -256,6 +258,8 @@ void Add_history(const char *string); #define Exit(s) exit(s) #define Abort() abort() #define Mkstemp(t) mkstemp(t) +#define Setenv(n,v,o) setenv(n,v,o) +#define Unsetenv(n) unsetenv(n) #define Readline(p) readline(p) #define Using_history() using_history() diff --git a/sysincludes.h b/sysincludes.h index f233358..6d053b9 100644 --- a/sysincludes.h +++ b/sysincludes.h @@ -1,5 +1,5 @@ /* source: sysincludes.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sysincludes_h_included @@ -108,6 +108,9 @@ #include /* req for resolv.h (esp. on MacOSX) */ #endif #include +#if HAVE_NET_IF_DL_H +#include /* FreeBSD: struct sockaddr_dl */ +#endif #if HAVE_RESOLV_H #include /* _res */ #endif @@ -116,6 +119,12 @@ #if HAVE_NET_IF_H #include #endif /* HAVE_NET_IF_H */ +#if HAVE_LINUX_TYPES_H +#include /* __u32 for linux/errqueue.h */ +#endif +#if HAVE_LINUX_ERRQUEUE_H +#include /* struct sock_extended_err */ +#endif #if HAVE_LINUX_IF_TUN_H #include #endif diff --git a/sysutils.c b/sysutils.c index 28ccae9..4a27fe9 100644 --- a/sysutils.c +++ b/sysutils.c @@ -129,60 +129,48 @@ socklen_t socket_init(int af, union sockaddr_union *sa) { #if _WITH_SOCKET char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size_t blen) { - char ubuff[5*UNIX_PATH_MAX+3]; + union sockaddr_union *sau = (union sockaddr_union *)sa; char *lbuff = buff; char *cp = lbuff; int n; - if ((n = snprintf(cp, blen, "AF=%d ", sa->sa_family)) < 0) { + if ((n = snprintf(cp, blen, "AF=%d ", sau->soa.sa_family)) < 0) { Warn1("sockaddr_info(): buffer too short ("F_Zu")", blen); *buff = '\0'; return buff; } cp += n, blen -= n; - switch (sa->sa_family) { + switch (sau->soa.sa_family) { #if WITH_UNIX case 0: - case AF_UNIX: -#if WITH_ABSTRACT_UNIXSOCKET - if (salen > XIOUNIXSOCKOVERHEAD && - sa->sa_data[0] == '\0') { - char *nextc; - nextc = - sanitize_string((char *)&sa->sa_data, salen-XIOUNIXSOCKOVERHEAD, - ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); - *nextc = '\0'; - snprintf(cp, blen, "\"%s\"", ubuff); - } else -#endif /* WITH_ABSTRACT_UNIXSOCKET */ - { - char *nextc; - nextc = - sanitize_string((char *)&sa->sa_data, - MIN(UNIX_PATH_MAX, strlen((char *)&sa->sa_data)), - ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); - *nextc = '\0'; - snprintf(cp, blen, "\"%s\"", ubuff); - } + case AF_UNIX: sockaddr_unix_info(&sau->un, salen, cp+1, blen-1); + cp[0] = '"'; + *strchr(cp+1, '\0') = '"'; break; #endif #if WITH_IP4 - case AF_INET: sockaddr_inet4_info((struct sockaddr_in *)sa, cp, blen); + case AF_INET: sockaddr_inet4_info(&sau->ip4, cp, blen); break; #endif #if WITH_IP6 - case AF_INET6: sockaddr_inet6_info((struct sockaddr_in6 *)sa, cp, blen); + case AF_INET6: sockaddr_inet6_info(&sau->ip6, cp, blen); break; #endif default: + if ((n = snprintf(cp, blen, "AF=%d ", sa->sa_family)) < 0) { + Warn1("sockaddr_info(): buffer too short ("F_Zu")", blen); + *buff = '\0'; + return buff; + } + cp += n, blen -= n; if ((snprintf(cp, blen, "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - sa->sa_data[0], sa->sa_data[1], sa->sa_data[2], - sa->sa_data[3], sa->sa_data[4], sa->sa_data[5], - sa->sa_data[6], sa->sa_data[7], sa->sa_data[8], - sa->sa_data[9], sa->sa_data[10], sa->sa_data[11], - sa->sa_data[12], sa->sa_data[13])) < 0) { + sau->soa.sa_data[0], sau->soa.sa_data[1], sau->soa.sa_data[2], + sau->soa.sa_data[3], sau->soa.sa_data[4], sau->soa.sa_data[5], + sau->soa.sa_data[6], sau->soa.sa_data[7], sau->soa.sa_data[8], + sau->soa.sa_data[9], sau->soa.sa_data[10], sau->soa.sa_data[11], + sau->soa.sa_data[12], sau->soa.sa_data[13])) < 0) { Warn("sockaddr_info(): buffer too short"); *buff = '\0'; return buff; @@ -195,10 +183,26 @@ char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size #if WITH_UNIX char *sockaddr_unix_info(const struct sockaddr_un *sa, socklen_t salen, char *buff, size_t blen) { - blen = Min(blen, sizeof(sa->sun_path)); - strncpy(buff, sa->sun_path, blen); - if (strlen(buff) >= blen) { - buff[blen-1] = '\0'; + char ubuff[5*UNIX_PATH_MAX+3]; + char *nextc; + +#if WITH_ABSTRACT_UNIXSOCKET + if (salen > XIOUNIXSOCKOVERHEAD && + sa->sun_path[0] == '\0') { + nextc = + sanitize_string(sa->sun_path, salen-XIOUNIXSOCKOVERHEAD, + ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); + *nextc = '\0'; + strncpy(buff, ubuff, blen); + } else +#endif /* WITH_ABSTRACT_UNIXSOCKET */ + { + nextc = + sanitize_string(sa->sun_path, + MIN(UNIX_PATH_MAX, strlen(sa->sun_path)), + ubuff, XIOSAN_DEFAULT_BACKSLASH_OCT_3); + *nextc = '\0'; + strncpy(buff, ubuff, blen); } return buff; } @@ -276,7 +280,7 @@ const char *inet_ntop(int pf, const void *binaddr, #if WITH_IP6 /* convert the IP6 socket address to human readable form. buff should be at - least 50 chars long */ + least 50 chars long. output includes the port number */ char *sockaddr_inet6_info(const struct sockaddr_in6 *sa, char *buff, size_t blen) { if (snprintf(buff, blen, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%hu", #if HAVE_IP6_SOCKADDR==0 @@ -434,6 +438,7 @@ int parseport(const char *portname, int ipproto) { } #endif /* WITH_TCP || WITH_UDP */ + #if WITH_IP4 || WITH_IP6 /* check the systems interfaces for ifname and return its index or -1 if no interface with this name was found */ @@ -500,3 +505,80 @@ int ifindex(const char *ifname, unsigned int *ifindex) { return 0; } #endif /* WITH_IP4 || WITH_IP6 */ + + +/* constructs an environment variable whose name is built from socats uppercase + program name, and underscore and varname; if a variable of this name already + exists a non zero value of overwrite lets the old value be overwritten. + returns 0 on success or <0 if an error occurred. */ +int xiosetenv(const char *varname, const char *value, int overwrite) { +# define XIO_ENVNAMELEN 256 + const char *progname; + char envname[XIO_ENVNAMELEN]; + size_t i, l; + + progname = diag_get_string('p'); + strncpy(envname, progname, XIO_ENVNAMELEN-1); + l = strlen(progname); + strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l); + for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); + strncpy(envname+l+1, varname, XIO_ENVNAMELEN-1-l); + if (Setenv(envname, value, overwrite) < 0) { + Warn3("setenv(\"...\", \"%s\", 1): %s", + envname, value, strerror(errno)); + Unsetenv(envname); /* dont want to have a wrong value */ + return -1; + } + return 0; +# undef XIO_ENVNAMELEN +} + +int xiosetenv2(const char *varname, const char *varname2, const char *value, + int overwrite) { +# define XIO_ENVNAMELEN 256 + const char *progname; + char envname[XIO_ENVNAMELEN]; + size_t i, l; + + progname = diag_get_string('p'); + strncpy(envname, progname, XIO_ENVNAMELEN-1); + l = strlen(progname); + strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l); + l += 1; + strncpy(envname+l, varname, XIO_ENVNAMELEN-1-l); + l += strlen(varname); + strncpy(envname+l, "_", XIO_ENVNAMELEN-1-l); + l += 1; + strncpy(envname+l, varname2, XIO_ENVNAMELEN-1-l); + l += strlen(varname2); + for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); + if (Setenv(envname, value, overwrite) < 0) { + Warn3("setenv(\"...\", \"%s\", 1): %s", + envname, value, strerror(errno)); + Unsetenv(envname); /* dont want to have a wrong value */ + return -1; + } + return 0; +# undef XIO_ENVNAMELEN +} + + +/* like xiosetenv(), but uses an unsigned long value */ +int xiosetenvulong(const char *varname, unsigned long value, int overwrite) { +# define XIO_LONGLEN 21 /* should suffice for 64bit longs with \0 */ + char envbuff[XIO_LONGLEN]; + + snprintf(envbuff, XIO_LONGLEN, "%lu", value); + return xiosetenv(varname, envbuff, overwrite); +# undef XIO_LONGLEN +} + +/* like xiosetenv(), but uses an unsigned short value */ +int xiosetenvushort(const char *varname, unsigned short value, int overwrite) { +# define XIO_SHORTLEN 11 /* should suffice for 32bit shorts with \0 */ + char envbuff[XIO_SHORTLEN]; + + snprintf(envbuff, XIO_SHORTLEN, "%hu", value); + return xiosetenv(varname, envbuff, overwrite); +# undef XIO_SHORTLEN +} diff --git a/sysutils.h b/sysutils.h index b9074b3..33cfc45 100644 --- a/sysutils.h +++ b/sysutils.h @@ -1,5 +1,5 @@ /* source: sysutils.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sysutils_h_included @@ -97,4 +97,13 @@ extern int parseport(const char *portname, int proto); extern int ifindexbyname(const char *ifname); extern int ifindex(const char *ifname, unsigned int *ifindex); +extern int xiosetenv(const char *varname, const char *value, int overwrite); +extern int +xiosetenv2(const char *varname, const char *varname2, const char *value, + int overwrite); +extern int xiosetenvulong(const char *varname, unsigned long value, + int overwrite); +extern int xiosetenvushort(const char *varname, unsigned short value, + int overwrite); + #endif /* !defined(__sysutils_h_included) */ diff --git a/test.sh b/test.sh index 054673f..61455f8 100755 --- a/test.sh +++ b/test.sh @@ -48,13 +48,15 @@ opts="$opt_t $OPTS" export SOCAT_OPTS="$opts" #debug="1" debug= -TESTS="$@" +TESTS="$@"; export TESTS INTERFACE=eth0; # not used for function tests MCINTERFACE=lo # !!! Linux only #LOCALHOST=192.168.58.1 #LOCALHOST=localhost LOCALHOST=127.0.0.1 LOCALHOST6=[::1] +#PROTO=$(awk '{print($2);}' /etc/protocols |sort -n |tail -n 1) +#PROTO=$(($PROTO+1)) PROTO=$((144+RANDOM/2048)) PORT=12002 SOURCEPORT=2002 @@ -1912,14 +1914,21 @@ waitudp6port () { return 1 } +# we need this misleading function name for canonical reasons +waitunixport () { + waitfile "$1" "$2" "$3" +} + # wait until a filesystem entry exists waitfile () { local crit=-e case "X$1" in X-*) crit="$1"; shift ;; esac local file="$1" - local logic="$2" # 0..wait until gone; 1..wait until exists (default) + local logic="$2" # 0..wait until gone; 1..wait until exists (default); + # 2..wait until not empty local timeout="$3" [ "$logic" ] || logic=1 + [ "$logic" -eq 2 ] && crit=-s [ "$timeout" ] || timeout=5 while [ $timeout -gt 0 ]; do if [ \( \( $logic -ne 0 \) -a $crit "$file" \) -o \ @@ -7657,7 +7666,7 @@ printf "test $F_n $TEST... " $N $CMD1 2>"${te}1" & pid1="$!" waitip4port $ts1p 1 -usleep 100000 # give process a chance to add membership +usleep 100000 # give process a chance to add multicast membership echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2="$?" kill "$pid1" 2>/dev/null; wait; @@ -8147,13 +8156,12 @@ rc2=$? sleep 1 #read -p ">" l="$(childprocess $pid1)" -rcc=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then - $PRINTF "$NO_RESULT\n" # already handled in test UDP4STREAM + $PRINTF "$NO_RESULT (client failed)\n" # already handled in test UDP4STREAM numCANT=$((numCANT+1)) elif ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$NO_RESULT\n" # already handled in test UDP4STREAM + $PRINTF "$NO_RESULT (diff failed)\n" # already handled in test UDP4STREAM numCANT=$((numCANT+1)) elif $(isdefunct "$l"); then $PRINTF "$FAILED: $SOCAT:\n" @@ -8169,7 +8177,7 @@ fi ;; esac PORT=$((PORT+1)) N=$((N+1)) - +set +vx # there was a bug with udp-recvfrom and fork: terminating sub processes became # zombies because the master process caught SIGCHLD but did not wait() @@ -8198,7 +8206,6 @@ rc2=$? sleep 1 #read -p ">" l="$(childprocess $pid1)" -rcc=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM @@ -8513,6 +8520,398 @@ esac N=$((N+1)) +while read SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME SCM_VALUE +do + +# test: logging of ancillary message with ip-recvopt +NAME=UDP4SCM_$SCM_TYPE +case "$TESTS" in +*%functions%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%ancillary%*|*%$NAME%*) +#set -vx +TEST="$NAME: IPv4 ancillary messages" +# idea: start a socat process with udp4-recv:..,ip-recvopts and send it a packet +# with IP options (ip-options). check the info log for the appropriate output. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +ts1p=$PORT; PORT=$((PORT+1)) +ts1a="127.0.0.1" +ts1="$ts1a:$ts1p" +CMD0="$SOCAT $opts -d -d -d -u UDP4-RECV:$ts1p,reuseaddr,$SCM_RECV -" +CMD1="$SOCAT $opts -u - UDP4-SENDTO:$ts1,$SCM_ENABLE" +printf "test $F_n $TEST... " $N +# is this option supported? +if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then +$CMD0 >"$tf" 2>"${te}0" & +pid0="$!" +waitudp4port $ts1p 1 +echo "XYZ" |$CMD1 2>>"${te}1" +rc1="$?" +sleep 1 +i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done +kill "$pid0" 2>/dev/null; wait +# do not show more messages than requested +case "$opts" in +*-d*-d*-d*-d*) LEVELS="[EWNID]" ;; +*-d*-d*-d*) LEVELS="[EWNI]" ;; +*-d*-d*) LEVELS="[EWN]" ;; +*-d*) LEVELS="[EW]" ;; +*) LEVELS="[E]" ;; +esac +if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD0 &" + echo "$CMD1" + grep " $LEVELS " "${te}0" + grep " $LEVELS " "${te}1" + numFAIL=$((numFAIL+1)) +elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE" ${te}0 >/dev/null; then + $PRINTF "$FAILED\n" + echo "$CMD0 &" + echo "$CMD1" + grep " $LEVELS " "${te}0" + grep " $LEVELS " "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then + grep " $LEVELS " "${te}0"; echo; grep " $LEVELS " "${te}1"; + fi + numOK=$((numOK+1)) +fi +else # option is not supported + $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" + numCANT=$((numCANT+1)) +fi # option is not supported +set +vx +;; +esac +N=$((N+1)) + +done <<<"ip-options=x01000000 ip-recvopts IP_OPTIONS options x01000000 +, so-timestamp SCM_TIMESTAMP timestamp $(date '+%a %b %e %H:%M:.. %Y') +ip-ttl=53 ip-recvttl IP_TTL ttl 53 +ip-tos=7 ip-recvtos IP_TOS tos 7 +, ip-pktinfo IP_PKTINFO locaddr 127.0.0.1 +, ip-recvif IP_RECVIF if lo +, ip-recvdstaddr IP_RECVDSTADDR dstaddr 127.0.0.1" + + +# test: logging of ancillary message +while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VALUE +do +if [ -z "$PF" ]; then continue; fi +# +pf="$(echo $PF |tr A-Z a-z)" +proto="$(echo $KEYW |tr A-Z a-z)" +NAME=${KEYW}SCM_$SCM_TYPE +case "$TESTS" in +*%functions%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%$ROOT%*|*%$NAME%*) +TEST="$NAME: $KEYW log ancillary message $SCM_TYPE $SCM_NAME" +# idea: start a socat process with *-RECV:..,... , ev. with ancillary message +# enabling option and send it a packet, ev. with some option. check the info log +# for the appropriate output. +if [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +case "X$IPPORT" in + "XPORT") + tra="$PORT" # test recv address + tsa="$ADDR:$PORT" # test sendto address + PORT=$((PORT+1)) ;; + "XPROTO") + tra="$PROTO" # test recv address + tsa="$ADDR:$PROTO" # test sendto address + PROTO=$((PROTO+1)) ;; + *) + tra="$(eval echo "$ADDR")" # resolve $N + tsa="$tra" +esac +CMD0="$SOCAT $opts -d -d -d -u $KEYW-RECV:$tra,reuseaddr,$SCM_RECV -" +CMD1="$SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE" +printf "test $F_n $TEST... " $N +# is this option supported? +if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then +$CMD0 >"$tf" 2>"${te}0" & +pid0="$!" +wait${proto}port $tra 1 +echo "XYZ" |$CMD1 2>"${te}1" +rc1="$?" +sleep 1 +i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done +kill "$pid0" 2>/dev/null; wait +# do not show more messages than requested +case "$opts" in +*-d*-d*-d*-d*) LEVELS="[EWNID]" ;; +*-d*-d*-d*) LEVELS="[EWNI]" ;; +*-d*-d*) LEVELS="[EWN]" ;; +*-d*) LEVELS="[EW]" ;; +*) LEVELS="[E]" ;; +esac +if [ "$rc1" -ne 0 ]; then + $PRINTF "$NO_RESULT: $SOCAT:\n" + echo "$CMD0 &" + echo "$CMD1" + grep " $LEVELS " "${te}0" + grep " $LEVELS " "${te}1" + numCANT=$((numCANT+1)) +elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE" ${te}0 >/dev/null; then + $PRINTF "$FAILED\n" + echo "$CMD0 &" + echo "$CMD1" + grep " $LEVELS " "${te}0" + grep " $LEVELS " "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then + grep " $LEVELS " "${te}0"; echo; grep " $LEVELS " "${te}1"; + fi + numOK=$((numOK+1)) +fi +set +vx +else # option is not supported + $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" + numCANT=$((numCANT+1)) +fi # option is not supported +fi # must be root +;; +esac +N=$((N+1)) +# +done <<<" +IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS options user x01000000 +IP4 UDP4 127.0.0.1 PORT , so-timestamp SCM_TIMESTAMP timestamp user $(date '+%a %b %e %H:%M:.. %Y') +IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL ttl user 53 +IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS tos user 7 +IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO locaddr user 127.0.0.1 +IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO dstaddr user 127.0.0.1 +IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO if user lo +IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_RECVIF if user lo0 +IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_RECVDSTADDR dstaddr user 127.0.0.1 +IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS options root x01000000 +IP4 IP4 127.0.0.1 PROTO , so-timestamp SCM_TIMESTAMP timestamp root $(date '+%a %b %e %H:%M:.. %Y') +IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL ttl root 53 +IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS tos root 7 +IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO locaddr root 127.0.0.1 +IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO dstaddr root 127.0.0.1 +IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO if root lo +IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_RECVIF if root lo0 +IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_RECVDSTADDR dstaddr root 127.0.0.1 +IP6 UDP6 [::1] PORT , so-timestamp SCM_TIMESTAMP timestamp user $(date '+%a %b %e %H:%M:.. %Y') +IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_PKTINFO dstaddr user [[]0000:0000:0000:0000:0000:0000:0000:0001[]] +IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit user 35 +IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass user xaa000000 +IP6 IP6 [::1] PROTO , so-timestamp SCM_TIMESTAMP timestamp root $(date '+%a %b %e %H:%M:.. %Y') +IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_PKTINFO dstaddr root [[]0000:0000:0000:0000:0000:0000:0000:0001[]] +IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit root 35 +IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass root xaa000000 +UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP timestamp user $(date '+%a %b %e %H:%M:.. %Y') +" +# this one fails, appearently due to a Linux weakness: +# UNIX so-timestamp + + +# test: setting of environment variables that describe a stream socket +# connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT, +# SOCAT_PEERPORT when applicable +while read KEYW TEST_SOCKADDR TEST_PEERADDR TEST_SOCKPORT TEST_PEERPORT; do +if [ -z "$KEYW" ]; then continue; fi +# +test_proto="$(echo $KEYW |tr A-Z a-z)" +NAME=${KEYW}LISTENENV +case "$TESTS" in +*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$test_proto%*|*%envvar%*|*%$NAME%*) +TEST="$NAME: $KEYW-LISTEN fills environment variables with socket addresses" +# have a server accepting a connection and invoking some shell code. The shell +# code extracts and prints the SOCAT related environment vars. +# outside code then checks if the environment contains the variables correctly +# describing the peer and local sockets. +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +TEST_SOCKADDR="$(echo $TEST_SOCKADDR |sed "s/\$N/$N/g")" # actual vars +tsa="$TEST_SOCKADDR" # test server address +tsp="$TEST_SOCKPORT" # test server port +if [ "$tsp" != ',' ]; then + tsa1="$tsp"; tsa2="$tsa"; tsa="$tsa:$tsp" # tsa2 used for server bind= +else + tsa1="$tsa"; tsa2= # tsa1 used for addr parameter +fi +TEST_PEERADDR="$(echo $TEST_PEERADDR |sed "s/\$N/$N/g")" # actual vars +tca="$TEST_PEERADDR" # test client address +tcp="$TEST_PEERPORT" # test client port +if [ "$tcp" != ',' ]; then + tca="$tca:$tcp" +fi +CMD0="$SOCAT $opts -u $KEYW-LISTEN:$tsa1 system:\"export -p\"" +CMD1="$SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca" +printf "test $F_n $TEST... " $N +eval "$CMD0 2>\"${te}0\" >\"$tf\" &" +pid0=$! +wait${test_proto}port $tsa1 1 +echo |$CMD1 2>"${te}1" +rc1=$? +waitfile "$tf" 2 +kill $pid0 2>/dev/null; wait +#set -vx +if [ $rc1 != 0 ]; then + $PRINTF "$NO_RESULT (client failed):\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numCANT=$((numCANT+1)) +elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \ + "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \ + \( "$TEST_SOCKPORT" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$tsp" \) -a \ + \( "$TEST_PEERPORT" = ',' -o "$(grep SOCAT_PEERPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$tcp" \) \ + ]; then + $PRINTF "$OK\n" + if [ "$debug" ]; then + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + fi + numOK=$((numOK+1)) +else + $PRINTF "$FAILED\n" + echo "$CMD0 &" + cat "${te}0" + echo "$CMD1" + cat "${te}1" + numFAIL=$((numFAIL+1)) +fi +set +xv +;; +esac +N=$((N+1)) +# +done <<<" +TCP4 $LOCALHOST $SECONDADDR $PORT $((PORT+1)) +TCP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+2)) $((PORT+3)) +UDP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+6)) $((PORT+7)) +UNIX $td/test\$N.server $td/test\$N.client , , +" +# this one fails do to weakness in socats UDP4-LISTEN implementation: +#UDP4 $LOCALHOST $SECONDADDR $((PORT+4)) $((PORT+5)) + + +# test: environment variables from ancillary message +while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE +do +if [ -z "$PF" ]; then continue; fi +# +pf="$(echo $PF |tr A-Z a-z)" +proto="$(echo $KEYW |tr A-Z a-z)" +NAME=${KEYW}ENV_$SCM_ENVNAME +case "$TESTS" in +*%functions%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%envvar%*|*%$ROOT%*|*%$NAME%*) +#set -vx +TEST="$NAME: $KEYW ancillary message brings $SCM_ENVNAME into environment" +# idea: start a socat process with *-RECVFROM:..,... , ev. with ancillary +# message enabling option and send it a packet, ev. with some option. write +# the resulting environment to a file and check its contents for the +# appropriate variable. +if [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +case "X$IPPORT" in + "XPORT") + tra="$PORT" # test recv address + tsa="$ADDR:$PORT" # test sendto address + PORT=$((PORT+1)) ;; + "XPROTO") + tra="$PROTO" # test recv address + tsa="$ADDR:$PROTO" # test sendto address + PROTO=$((PROTO+1)) ;; + *) + tra="$(eval echo "$ADDR")" # resolve $N + tsa="$tra" +esac +#CMD0="$SOCAT $opts -u $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV system:\"export -p\"" +CMD0="$SOCAT $opts -u $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV system:\"echo \\\$SOCAT_$SCM_ENVNAME\"" +CMD1="$SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE" +printf "test $F_n $TEST... " $N +# is this option supported? +if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then +eval "$CMD0 >\"$tf\" 2>\"${te}0\" &" +pid0="$!" +wait${proto}port $tra 1 +echo "XYZ" |$CMD1 2>"${te}1" +rc1="$?" +waitfile "$tf" 2 +#i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done +kill "$pid0" 2>/dev/null; wait +# do not show more messages than requested +#set -vx +if [ "$rc1" -ne 0 ]; then + $PRINTF "$NO_RESULT: $SOCAT:\n" + echo "$CMD0 &" + echo "$CMD1" + cat "${te}0" + cat "${te}1" + numCANT=$((numCANT+1)) +#elif ! egrep "^export SOCAT_$SCM_ENVNAME=[\"']?$SCM_VALUE[\"']?\$" ${tf} >/dev/null; then +#elif ! eval echo "$SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then +elif ! expr "$(cat "$tf")" : "$(eval echo "\$SCM_VALUE")" >/dev/null; then + $PRINTF "$FAILED\n" + echo "$CMD0 &" + echo "$CMD1" + cat "${te}0" + cat "${te}1" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then + cat "${te}0"; echo; cat "${te}1"; + fi + numOK=$((numOK+1)) +fi +set +vx +else # option is not supported + $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" + numCANT=$((numCANT+1)) +fi # option is not supported +fi # must be root +;; +esac +N=$((N+1)) +# +done <<<" +IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS user x01000000 +IP4 UDP4 127.0.0.1 PORT , so-timestamp TIMESTAMP user $(date '+%a %b %e %H:%M:.. %Y'), ...... usecs +IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL user 53 +IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS user 7 +IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_LOCADDR user 127.0.0.1 +IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_DSTADDR user 127.0.0.1 +IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_IF user lo +IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_RECVIF user lo0 +IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_RECVDSTADDR user 127.0.0.1 +IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS root x01000000 +IP4 IP4 127.0.0.1 PROTO , so-timestamp TIMESTAMP root $(date '+%a %b %e %H:%M:.. %Y'), ...... usecs +IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL root 53 +IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS root 7 +IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_LOCADDR root 127.0.0.1 +IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_DSTADDR root 127.0.0.1 +IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_IF root lo +IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_RECVIF root lo0 +IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_RECVDSTADDR root 127.0.0.1 +IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_DSTADDR user [[]0000:0000:0000:0000:0000:0000:0000:0001[]] +IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT user 35 +IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS user xaa000000 +IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_DSTADDR root [[]0000:0000:0000:0000:0000:0000:0000:0001[]] +IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT root 35 +IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS root xaa000000 +UNIX UNIX $td/test\$N.server - , so-timestamp TIMESTAMP user $(date '+%a %b %e %H:%M:.. %Y') +" + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/utils.c b/utils.c index eeca60c..57904d9 100644 --- a/utils.c +++ b/utils.c @@ -1,5 +1,5 @@ /* source: utils.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* useful additions to C library */ @@ -145,3 +145,17 @@ char *sanitize_string(const char *data, /* input data */ } return coded; } + +/* copies a substring out of a given buff + returns scratch, \0 terminated; scratch must provide len+1 bytes +*/ +char *xiosubstr(char *scratch, const char *str, size_t from, size_t len) { + char *scratch0 = scratch; + str += from; + while (len--) { + *scratch++ = *str++; + } + *scratch = '\0'; + return scratch0; +} + diff --git a/utils.h b/utils.h index 4488358..f942db1 100644 --- a/utils.h +++ b/utils.h @@ -1,5 +1,5 @@ /* source: utils.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __utils_h_included @@ -63,6 +63,7 @@ char *sanitize_string(const char *data, /* input data */ size_t bytes, /* length of input data, >=0 */ char *coded, /* output buffer, must be long enough */ int style); +extern +char *xiosubstr(char *scratch, const char *str, size_t from, size_t len); #endif /* !defined(__utils_h_included) */ - diff --git a/xio-ascii.c b/xio-ascii.c index 88909dc..7cd8103 100644 --- a/xio-ascii.c +++ b/xio-ascii.c @@ -1,5 +1,5 @@ /* source: xio-ascii.c */ -/* Copyright Gerhard Rieger 2002-2006 */ +/* Copyright Gerhard Rieger 2002-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains functions for text encoding, decoding, and conversions */ @@ -105,3 +105,52 @@ char * } return coded; } + +/* write the binary data to output buffer codbuff in human readable form. + bytes gives the length of the data, codlen the available space in codbuff. + coding specifies how the data is to be presented. Not much to select now. + returns a pointer to the first char in codbuff that has not been overwritten; + it might also point to the first char after the buffer! +*/ +static char * +_xiodump(const unsigned char *data, size_t bytes, char *codbuff, size_t codlen, + int coding) { + int start = 1; + int space = coding & 0xff; + + if (bytes <= 0) { codbuff[0] = '\0'; return codbuff; } + if (space == 0) space = -1; + if (0) { + ; /* for canonical reasons */ + } else if (1) { + /* simple hexadecimal output */ + if (bytes > 2*codlen+1) { + bytes = (codlen-1)/2; + } + *codbuff++ = 'x'; --codlen; + while (bytes-- > 0) { + if (start == 0 && space == 0) { + *codbuff++ = ' '; + space = (coding & 0xff); + } + codbuff += sprintf(codbuff, "%02x", *data++); + start = 0; + } + } + return codbuff; +} + +/* write the binary data to codbuff in human readable form. + bytes gives the length of the data, codlen the available space in codbuff. + coding specifies how the data is to be presented. Not much to select now. + null terminates the output. returns a pointer to the output string. +*/ +char * +xiodump(const unsigned char *data, size_t bytes, char *codbuff, size_t codlen, + int coding) { + char *result; + + result = _xiodump(data, bytes, codbuff, codlen-1, coding); + *result = '\0'; + return codbuff; +} diff --git a/xio-ascii.h b/xio-ascii.h index 875623d..bcb760f 100644 --- a/xio-ascii.h +++ b/xio-ascii.h @@ -1,5 +1,5 @@ /* source: xio-ascii.h */ -/* Copyright Gerhard Rieger 2002-2006 */ +/* Copyright Gerhard Rieger 2002-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ascii_h_included @@ -17,4 +17,8 @@ extern char *xiosanitize(const char *data, /* input data */ extern char * xiohexdump(const unsigned char *data, size_t bytes, char *coded); +extern char * +xiodump(const unsigned char *data, size_t bytes, char *coded, size_t codlen, + int coding); + #endif /* !defined(__xio_ascii_h_included) */ diff --git a/xio-ip.c b/xio-ip.c index 77dd71d..f04d1fa 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -9,6 +9,8 @@ #if _WITH_IP4 || _WITH_IP6 #include "xioopen.h" + +#include "xio-ascii.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-ip6.h" @@ -25,7 +27,7 @@ const struct optdesc opt_ip_pktinfo = { "ip-pktinfo", "pktinfo", OPT_IP_PKTINF #ifdef IP_RECVTOS const struct optdesc opt_ip_recvtos = { "ip-recvtos", "recvtos", OPT_IP_RECVTOS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVTOS }; #endif -#ifdef IP_RECVTTL +#ifdef IP_RECVTTL /* -Cygwin */ const struct optdesc opt_ip_recvttl = { "ip-recvttl", "recvttl", OPT_IP_RECVTTL, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVTTL }; #endif #ifdef IP_RECVOPTS @@ -65,6 +67,12 @@ const struct optdesc opt_ip_pktoptions = { "ip-pktoptions", "pktopts", OPT_IP_PK #ifdef IP_ADD_MEMBERSHIP const struct optdesc opt_ip_add_membership = { "ip-add-membership", "membership",OPT_IP_ADD_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IP, IP_ADD_MEMBERSHIP }; #endif +#ifdef IP_RECVDSTADDR +const struct optdesc opt_ip_recvdstaddr = { "ip-recvdstaddr", "recvdstaddr",OPT_IP_RECVDSTADDR, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVDSTADDR }; +#endif +#ifdef IP_RECVIF +const struct optdesc opt_ip_recvif = { "ip-recvif", "recvdstaddrif",OPT_IP_RECVIF, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVIF }; +#endif #if HAVE_RESOLV_H const struct optdesc opt_res_debug = { "res-debug", NULL, OPT_RES_DEBUG, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, (size_t)&((xiosingle_t *)0)->para.socket.ip.res_opts, sizeof(unsigned long), RES_DEBUG }; @@ -509,4 +517,116 @@ int parserange(const char *rangename, int pf, union xiorange_union *range) { return 0; } + +#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) +/* these are valid for IPv4 and IPv6 */ +int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, + char *typbuff, int typlen, + char *nambuff, int namlen, + char *envbuff, int envlen, + char *valbuff, int vallen) { + const char *cmsgtype, *cmsgname = NULL, *cmsgenvn = NULL, *cmsgfmt = NULL; + size_t msglen; + char scratch1[16]; /* can hold an IPv4 address in ASCII */ + char scratch2[16]; + char scratch3[16]; + + msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); + envbuff[0] = '\0'; + switch (cmsg->cmsg_type) { + default: + *num = 1; + strncpy(typbuff, "IP", typlen); + snprintf(nambuff, namlen, "type_%u", cmsg->cmsg_type); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; +#ifdef IP_PKTINFO + case IP_PKTINFO: { + struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); + *num = 3; + strncpy(typbuff, "IP_PKTINFO", typlen); + snprintf(nambuff, namlen, "%s%c%s%c%s", "if", '\0', "locaddr", '\0', "dstaddr"); + snprintf(envbuff, envlen, "%s%c%s%c%s", "IP_IF", '\0', + "IP_LOCADDR", '\0', "IP_DSTADDR"); + snprintf(valbuff, vallen, "%s%c%s%c%s", + xiogetifname(pktinfo->ipi_ifindex, scratch1, -1), '\0', + inet4addr_info(ntohl(pktinfo->ipi_spec_dst.s_addr), scratch2, sizeof(scratch2)), '\0', + inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), scratch3, sizeof(scratch3))); + } + return STAT_OK; +#endif /* IP_PKTINFO */ +#ifdef IP_RECVERR + case IP_RECVERR: { + struct sock_extended_err *err = + (struct sock_extended_err *)CMSG_DATA(cmsg); + *num = 6; + strncpy(typbuff, "IP_RECVERR", typlen); + snprintf(nambuff, namlen, "%s%c%s%c%s%c%s%c%s%c%s", + "errno", '\0', "origin", '\0', "type", '\0', + "code", '\0', "info", '\0', "data"); + snprintf(envbuff, envlen, "%s%c%s%c%s%c%s%c%s%c%s", + "IP_RECVERR_ERRNO", '\0', "IP_RECVERR_ORIGIN", '\0', + "IP_RECVERR_TYPE", '\0', "IP_RECVERR_CODE", '\0', + "IP_RECVERR_INFO", '\0', "IP_RECVERR_DATA"); + snprintf(valbuff, vallen, "%u%c%u%c%u%c%u%c%u%c%u", + err->ee_errno, '\0', err->ee_origin, '\0', err->ee_type, '\0', + err->ee_code, '\0', err->ee_info, '\0', err->ee_data); + return STAT_OK; + } +#endif /* IP_RECVERR */ +#ifdef IP_RECVIF + case IP_RECVIF: { + /* spec in FreeBSD: /usr/include/net/if_dl.h */ + struct sockaddr_dl *sadl = (struct sockaddr_dl *)CMSG_DATA(cmsg); + *num = 1; + strncpy(typbuff, "IP_RECVIF", typlen); + strncpy(nambuff, "if", namlen); + strncpy(envbuff, "IP_IF", envlen); + strncpy(valbuff, + xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen); + return STAT_OK; + } +#endif /* defined(IP_RECVIF) */ +#ifdef IP_RECVDSTADDR + case IP_RECVDSTADDR: + *num = 1; + strncpy(typbuff, "IP_RECVDSTADDR", typlen); + strncpy(nambuff, "dstaddr", namlen); + strncpy(envbuff, "IP_DSTADDR", envlen); + inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen); + return STAT_OK; +#endif + case IP_OPTIONS: + case IP_RECVOPTS: + cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgfmt = NULL; break; + case IP_TOS: + cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgfmt = "%u"; break; + case IP_TTL: /* Linux */ +#ifdef IP_RECVTTL + case IP_RECVTTL: /* FreeBSD */ +#endif + cmsgtype = "IP_TTL"; cmsgname = "ttl"; cmsgfmt = "%u"; break; + } + /* when we come here we provide a single parameter + with type in cmsgtype, name in cmsgname, printf format in cmsgfmt */ + *num = 1; + if (strlen(cmsgtype) >= typlen) Fatal("buff too short"); + strncpy(typbuff, cmsgtype, typlen); + if (strlen(cmsgname) >= namlen) Fatal("buff too short"); + strncpy(nambuff, cmsgname, namlen); + if (cmsgenvn) { + if (strlen(cmsgenvn) >= envlen) Fatal("buff too short"); + strncpy(envbuff, cmsgenvn, envlen); + } else { + envbuff[0] = '\0'; + } + if (cmsgfmt != NULL) { + snprintf(valbuff, vallen, cmsgfmt, *(unsigned char *)CMSG_DATA(cmsg)); + } else { + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + } + return STAT_OK; +} +#endif /* defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) */ + #endif /* _WITH_IP4 || _WITH_IP6 */ diff --git a/xio-ip.h b/xio-ip.h index 4d68012..6522f49 100644 --- a/xio-ip.h +++ b/xio-ip.h @@ -1,5 +1,5 @@ /* source: xio-ip.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip_h_included @@ -24,6 +24,8 @@ extern const struct optdesc opt_ip_multicast_loop; extern const struct optdesc opt_ip_multicast_if; extern const struct optdesc opt_ip_pktoptions; extern const struct optdesc opt_ip_add_membership; +extern const struct optdesc opt_ip_recvdstaddr; +extern const struct optdesc opt_ip_recvif; extern const struct optdesc opt_res_debug; extern const struct optdesc opt_res_aaonly; @@ -44,5 +46,11 @@ int xioparsenetwork(const char *rangename, int pf, union xiorange_union *range); extern int parserange(const char *rangename, int pf, union xiorange_union *range); +extern +int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, + char *typbuff, int typlen, + char *nambuff, int namlen, + char *envbuff, int envlen, + char *valbuff, int vallen); #endif /* !defined(__xio_ip_h_included) */ diff --git a/xio-ip4.c b/xio-ip4.c index 6e8ff23..27b9128 100644 --- a/xio-ip4.c +++ b/xio-ip4.c @@ -1,5 +1,5 @@ /* source: xio-ip4.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP4 related functions */ @@ -43,4 +43,41 @@ int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange_ip4 *range) { return 0; } +/* returns information that can be used for constructing an environment + variable describing the socket address. + if idx is 0, this function writes "ADDR" into namebuff and the IP address + into valuebuff, and returns 1 (which means that one more info is there). + if idx is 1, it writes "PORT" into namebuff and the port number into + valuebuff, and returns 0 (no more info) + namelen and valuelen contain the max. allowed length of output chars in the + respective buffer. + on error this function returns -1. +*/ +int +xiosetsockaddrenv_ip4(int idx, char *namebuff, size_t namelen, + char *valuebuff, size_t valuelen, + struct sockaddr_in *sa, int ipproto) { + switch (idx) { + case 0: + strcpy(namebuff, "ADDR"); + strcpy(valuebuff, + inet4addr_info(ntohl(sa->sin_addr.s_addr), valuebuff, valuelen)); + switch (ipproto) { + case IPPROTO_TCP: + case IPPROTO_UDP: +#ifdef IPPROTO_SCTP + case IPPROTO_SCTP: +#endif + return 1; /* there is port information to also be retrieved */ + default: + return 0; /* no port info coming */ + } + case 1: + strcpy(namebuff, "PORT"); + snprintf(valuebuff, valuelen, "%u", ntohs(sa->sin_port)); + return 0; + } + return -1; +} + #endif /* WITH_IP4 */ diff --git a/xio-ip4.h b/xio-ip4.h index 9357dcc..15aefed 100644 --- a/xio-ip4.h +++ b/xio-ip4.h @@ -1,5 +1,5 @@ /* source: xio-ip4.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip4_h_included @@ -9,5 +9,9 @@ extern const struct optdesc opt_ip4_add_membership; extern int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange_ip4 *range); +extern int +xiosetsockaddrenv_ip4(int idx, char *namebuff, size_t namelen, + char *valuebuff, size_t valuelen, + struct sockaddr_in *sa, int ipproto); #endif /* !defined(__xio_ip4_h_included) */ diff --git a/xio-ip6.c b/xio-ip6.c index 0bf8577..870e80e 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -1,5 +1,5 @@ /* source: xio-ip6.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP6 related functions */ @@ -9,17 +9,47 @@ #if WITH_IP6 #include "xioopen.h" +#include "xio-ascii.h" #include "xio-socket.h" #include "xio-ip.h" /* xiogetaddrinfo() */ #include "xio-ip6.h" + +static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen); + + #ifdef IPV6_V6ONLY const struct optdesc opt_ipv6_v6only = { "ipv6-v6only", "ipv6only", OPT_IPV6_V6ONLY, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_V6ONLY }; #endif #ifdef IPV6_JOIN_GROUP const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTBIND, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IPV6, IPV6_JOIN_GROUP }; #endif +const struct optdesc opt_ipv6_pktinfo = { "ipv6-pktinfo", "pktinfo", OPT_IPV6_PKTINFO, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_PKTINFO }; +const struct optdesc opt_ipv6_recvpktinfo = { "ipv6-recvpktinfo", "recvpktinfo", OPT_IPV6_RECVPKTINFO, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVPKTINFO }; +const struct optdesc opt_ipv6_rthdr = { "ipv6-rthdr", "rthdr", OPT_IPV6_RTHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RTHDR }; +const struct optdesc opt_ipv6_recvrthdr = { "ipv6-recvrthdr", "recvrthdr", OPT_IPV6_RECVRTHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVRTHDR }; +#ifdef IPV6_AUTHHDR +const struct optdesc opt_ipv6_authhdr = { "ipv6-authhdr", "authhdr", OPT_IPV6_AUTHHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_AUTHHDR }; +#endif +const struct optdesc opt_ipv6_dstopts = { "ipv6-dstopts", "dstopts", OPT_IPV6_DSTOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_DSTOPTS }; +const struct optdesc opt_ipv6_recvdstopts = { "ipv6-recvdstopts", "recvdstopts", OPT_IPV6_RECVDSTOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVDSTOPTS }; +const struct optdesc opt_ipv6_hopopts = { "ipv6-hopopts", "hopopts", OPT_IPV6_HOPOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_HOPOPTS }; +const struct optdesc opt_ipv6_recvhopopts = { "ipv6-recvhopopts", "recvhopopts", OPT_IPV6_RECVHOPOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVHOPOPTS }; +#ifdef IPV6_FLOWINFO /* is in linux/in6.h */ +const struct optdesc opt_ipv6_flowinfo= { "ipv6-flowinfo","flowinfo",OPT_IPV6_FLOWINFO,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_FLOWINFO }; +#endif +const struct optdesc opt_ipv6_hoplimit= { "ipv6-hoplimit","hoplimit",OPT_IPV6_HOPLIMIT,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_HOPLIMIT }; +const struct optdesc opt_ipv6_unicast_hops= { "ipv6-unicast-hops","unicast-hops",OPT_IPV6_UNICAST_HOPS,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_UNICAST_HOPS }; +const struct optdesc opt_ipv6_recvhoplimit= { "ipv6-recvhoplimit","recvhoplimit",OPT_IPV6_RECVHOPLIMIT,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVHOPLIMIT }; +#ifdef IPV6_RECVERR +const struct optdesc opt_ipv6_recverr = { "ipv6-recverr", "recverr", OPT_IPV6_RECVERR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVERR }; +#endif +const struct optdesc opt_ipv6_tclass = { "ipv6-tclass", "tclass", OPT_IPV6_TCLASS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_TCLASS }; +const struct optdesc opt_ipv6_recvtclass = { "ipv6-recvtclass", "recvtclass", OPT_IPV6_RECVTCLASS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVTCLASS }; +#ifdef IPV6_RECVPATHMTU +const struct optdesc opt_ipv6_recvpathmtu = { "ipv6-recvpathmtu", "recvpathmtu", OPT_IPV6_RECVPATHMTU, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVPATHMTU }; +#endif int xioparsenetwork_ip6(const char *rangename, struct xiorange_ip6 *range) { char *delimpos; /* absolute address of delimiter */ @@ -142,4 +172,200 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange_ip6 *range) { return 0; } + +#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) +/* provides info about the ancillary message */ +int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, + char *typbuff, int typlen, + char *nambuff, int namlen, + char *envbuff, int envlen, + char *valbuff, int vallen) { + char scratch1[42]; /* can hold an IPv6 address in ASCII */ + char scratch2[32]; + size_t msglen; + + *num = 1; /* good for most message types */ + msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); + envbuff[0] = '\0'; + switch (cmsg->cmsg_type) { + case IPV6_PKTINFO: { + struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); + *num = 2; + strncpy(typbuff, "IPV6_PKTINFO", typlen); + snprintf(nambuff, namlen, "%s%c%s", "dstaddr", '\0', "if"); + snprintf(envbuff, envlen, "%s%c%s", "IPV6_DSTADDR", '\0', "IPV6_IF"); + snprintf(valbuff, vallen, "%s%c%s", + inet6addr_info(&pktinfo->ipi6_addr, scratch1, sizeof(scratch1)), + '\0', xiogetifname(pktinfo->ipi6_ifindex, scratch2, -1)); + } + return STAT_OK; + case IPV6_HOPLIMIT: + strncpy(typbuff, "IPV6_HOPLIMIT", typlen); + strncpy(nambuff, "hoplimit", namlen); + snprintf(valbuff, vallen, "%d", *(int *)CMSG_DATA(cmsg)); + return STAT_OK; + case IPV6_RTHDR: + strncpy(typbuff, "IPV6_RTHDR", typlen); + strncpy(nambuff, "rthdr", namlen); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; +#ifdef IPV6_AUTHHDR + case IPV6_AUTHHDR: + strncpy(typbuff, "IPV6_AUTHHDR", typlen); + strncpy(nambuff, "authhdr", namlen); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; +#endif + case IPV6_DSTOPTS: + strncpy(typbuff, "IPV6_DSTOPTS", typlen); + strncpy(nambuff, "dstopts", namlen); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; + case IPV6_HOPOPTS: + strncpy(typbuff, "IPV6_HOPOPTS", typlen); + strncpy(nambuff, "hopopts", namlen); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; +#ifdef IPV6_FLOWINFO + case IPV6_FLOWINFO: + strncpy(typbuff, "IPV6_FLOWINFO", typlen); + strncpy(nambuff, "flowinfo", namlen); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; +#endif + case IPV6_TCLASS: + strncpy(typbuff, "IPV6_TCLASS", typlen); + strncpy(nambuff, "tclass", namlen); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; + default: + snprintf(typbuff, typlen, "IPV6.%u", cmsg->cmsg_type); + strncpy(nambuff, "data", namlen); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; + } + return STAT_OK; +} +#endif /* defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) */ + + +/* convert the IP6 socket address to human readable form. buff should be at + least 50 chars long. output includes the port number */ +static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen) { + if (snprintf(buff, blen, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", +#if HAVE_IP6_SOCKADDR==0 + (sa->s6_addr[0]<<8)+sa->s6_addr[1], + (sa->s6_addr[2]<<8)+sa->s6_addr[3], + (sa->s6_addr[4]<<8)+sa->s6_addr[5], + (sa->s6_addr[6]<<8)+sa->s6_addr[7], + (sa->s6_addr[8]<<8)+sa->s6_addr[9], + (sa->s6_addr[10]<<8)+sa->s6_addr[11], + (sa->s6_addr[12]<<8)+sa->s6_addr[13], + (sa->s6_addr[14]<<8)+sa->s6_addr[15] +#elif HAVE_IP6_SOCKADDR==1 + ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[0]), + ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[1]), + ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[2]), + ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[3]), + ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[4]), + ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[5]), + ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[6]), + ntohs(((unsigned short *)&sa->u6_addr.u6_addr16)[7]) +#elif HAVE_IP6_SOCKADDR==2 + ntohs(((unsigned short *)&sa->u6_addr16)[0]), + ntohs(((unsigned short *)&sa->u6_addr16)[1]), + ntohs(((unsigned short *)&sa->u6_addr16)[2]), + ntohs(((unsigned short *)&sa->u6_addr16)[3]), + ntohs(((unsigned short *)&sa->u6_addr16)[4]), + ntohs(((unsigned short *)&sa->u6_addr16)[5]), + ntohs(((unsigned short *)&sa->u6_addr16)[6]), + ntohs(((unsigned short *)&sa->u6_addr16)[7]) +#elif HAVE_IP6_SOCKADDR==3 + ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[0]), + ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[1]), + ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[2]), + ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[3]), + ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[4]), + ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[5]), + ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[6]), + ntohs(((unsigned short *)&sa->in6_u.u6_addr16)[7]) +#elif HAVE_IP6_SOCKADDR==4 + (sa->_S6_un._S6_u8[0]<<8)|(sa->_S6_un._S6_u8[1]&0xff), + (sa->_S6_un._S6_u8[2]<<8)|(sa->_S6_un._S6_u8[3]&0xff), + (sa->_S6_un._S6_u8[4]<<8)|(sa->_S6_un._S6_u8[5]&0xff), + (sa->_S6_un._S6_u8[6]<<8)|(sa->_S6_un._S6_u8[7]&0xff), + (sa->_S6_un._S6_u8[8]<<8)|(sa->_S6_un._S6_u8[9]&0xff), + (sa->_S6_un._S6_u8[10]<<8)|(sa->_S6_un._S6_u8[11]&0xff), + (sa->_S6_un._S6_u8[12]<<8)|(sa->_S6_un._S6_u8[13]&0xff), + (sa->_S6_un._S6_u8[14]<<8)|(sa->_S6_un._S6_u8[15]&0xff) +#elif HAVE_IP6_SOCKADDR==5 + ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[0]), + ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[1]), + ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[2]), + ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[3]), + ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[4]), + ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[5]), + ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[6]), + ntohs(((unsigned short *)&sa->__u6_addr.__u6_addr16)[7]) +#endif + ) < 0) { + Warn("sockaddr_inet6_info(): buffer too short"); + buff[blen-1] = '\0'; + } + return buff; +} + + +/* returns information that can be used for constructing an environment + variable describing the socket address. + if idx is 0, this function writes "ADDR" into namebuff and the IP address + into valuebuff, and returns 1 (which means that one more info is there). + if idx is 1, it writes "PORT" into namebuff and the port number into + valuebuff, and returns 0 (no more info) + namelen and valuelen contain the max. allowed length of output chars in the + respective buffer. + on error this function returns -1. +*/ +int +xiosetsockaddrenv_ip6(int idx, char *namebuff, size_t namelen, + char *valuebuff, size_t valuelen, + struct sockaddr_in6 *sa, int ipproto) { + switch (idx) { + case 0: + strcpy(namebuff, "ADDR"); + snprintf(valuebuff, valuelen, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", + (sa->sin6_addr.s6_addr[0]<<8)+ + sa->sin6_addr.s6_addr[1], + (sa->sin6_addr.s6_addr[2]<<8)+ + sa->sin6_addr.s6_addr[3], + (sa->sin6_addr.s6_addr[4]<<8)+ + sa->sin6_addr.s6_addr[5], + (sa->sin6_addr.s6_addr[6]<<8)+ + sa->sin6_addr.s6_addr[7], + (sa->sin6_addr.s6_addr[8]<<8)+ + sa->sin6_addr.s6_addr[9], + (sa->sin6_addr.s6_addr[10]<<8)+ + sa->sin6_addr.s6_addr[11], + (sa->sin6_addr.s6_addr[12]<<8)+ + sa->sin6_addr.s6_addr[13], + (sa->sin6_addr.s6_addr[14]<<8)+ + sa->sin6_addr.s6_addr[15]); + switch (ipproto) { + case IPPROTO_TCP: + case IPPROTO_UDP: +#ifdef IPPROTO_SCTP + case IPPROTO_SCTP: +#endif + return 1; /* there is port information to also be retrieved */ + default: + return 0; /* no port info coming */ + } + case 1: + strcpy(namebuff, "PORT"); + snprintf(valuebuff, valuelen, "%u", ntohs(sa->sin6_port)); + return 0; + } + return -1; +} + #endif /* WITH_IP6 */ diff --git a/xio-ip6.h b/xio-ip6.h index 431d4d1..2e86725 100644 --- a/xio-ip6.h +++ b/xio-ip6.h @@ -1,5 +1,5 @@ /* source: xio-ip6.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_ip6_h_included @@ -9,6 +9,23 @@ extern const struct optdesc opt_ipv6_v6only; extern const struct optdesc opt_ipv6_join_group; +extern const struct optdesc opt_ipv6_pktinfo; +extern const struct optdesc opt_ipv6_recvpktinfo; +extern const struct optdesc opt_ipv6_rthdr; +extern const struct optdesc opt_ipv6_recvrthdr; +extern const struct optdesc opt_ipv6_authhdr; +extern const struct optdesc opt_ipv6_dstopts; +extern const struct optdesc opt_ipv6_recvdstopts; +extern const struct optdesc opt_ipv6_hopopts; +extern const struct optdesc opt_ipv6_unicast_hops; +extern const struct optdesc opt_ipv6_recvhopopts; +extern const struct optdesc opt_ipv6_flowinfo; +extern const struct optdesc opt_ipv6_hoplimit; +extern const struct optdesc opt_ipv6_recvhoplimit; +extern const struct optdesc opt_ipv6_recverr; +extern const struct optdesc opt_ipv6_tclass; +extern const struct optdesc opt_ipv6_recvtclass; +extern const struct optdesc opt_ipv6_recvpathmtu; extern int xioparsenetwork_ip6(const char *rangename, struct xiorange_ip6 *range); @@ -16,6 +33,16 @@ extern int xiorange_ip6andmask(struct xiorange_ip6 *range); extern int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange_ip6 *range); +extern +int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, + char *typbuff, int typlen, + char *nambuff, int namlen, + char *envbuff, int envlen, + char *valbuff, int vallen); +extern int +xiosetsockaddrenv_ip6(int idx, char *namebuff, size_t namelen, + char *valuebuff, size_t valuelen, + struct sockaddr_in6 *sa, int ipproto); #endif /* WITH_IP6 */ diff --git a/xio-ipapp.c b/xio-ipapp.c index 1a3effd..213a76f 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -104,30 +104,24 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, #if WITH_RETRY if (dofork) { pid_t pid; - while ((pid = Fork()) < 0) { - int level = E_ERROR; - if (xfd->forever || --xfd->retry) { - level = E_WARN; /* most users won't expect a problem here, + int level = E_ERROR; + if (xfd->forever || xfd->retry) { + level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ - } - Msg1(level, "fork(): %s", strerror(errno)); - if (xfd->forever || xfd->retry) { - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + } + while ((pid = xio_fork(false, level)) < 0) { + if (xfd->forever || --xfd->retry) { Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } - if (pid == 0) { /* child process */ - Info1("just born: TCP client process "F_pid, Getpid()); - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } + if (pid == 0) { /* child process */ + xfd->forever = false; xfd->retry = 0; break; } + /* parent process */ - Notice1("forked off child process "F_pid, pid); Close(xfd->fd); /* with and without retry */ Nanosleep(&xfd->intervall, NULL); @@ -139,6 +133,7 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, break; } } while (true); + /* only "active" process breaks (master without fork, or child) */ if ((result = _xio_openlate(xfd, opts)) < 0) { return result; diff --git a/xio-listen.c b/xio-listen.c index 38a65c6..0acb3dd 100644 --- a/xio-listen.c +++ b/xio-listen.c @@ -98,9 +98,14 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl int backlog = 5; /* why? 1 seems to cause problems under some load */ char *rangename; bool dofork = false; - pid_t pid; /* mostly int; only used with fork */ char infobuff[256]; char lisname[256]; + union sockaddr_union _peername; + union sockaddr_union _sockname; + union sockaddr_union *pa = &_peername; /* peer address */ + union sockaddr_union *la = &_sockname; /* local address */ + socklen_t pas = sizeof(_peername); /* peer address size */ + socklen_t las = sizeof(_sockname); /* local address size */ int result; retropt_bool(opts, OPT_FORK, &dofork); @@ -199,12 +204,6 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl char peername[256]; char sockname[256]; int ps; /* peer socket */ - union sockaddr_union _peername; - union sockaddr_union _sockname; - union sockaddr_union *pa = &_peername; /* peer address */ - union sockaddr_union *la = &_sockname; /* local address */ - socklen_t pas = sizeof(_peername); /* peer address size */ - socklen_t las = sizeof(_sockname); /* local address size */ salen = sizeof(struct sockaddr); do { @@ -232,16 +231,18 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl if (Getpeername(ps, &pa->soa, &pas) < 0) { Warn4("getpeername(%d, %p, {"F_socklen"}): %s", ps, pa, pas, strerror(errno)); + pa = NULL; } if (Getsockname(ps, &la->soa, &las) < 0) { Warn4("getsockname(%d, %p, {"F_socklen"}): %s", - ps, pa, pas, strerror(errno)); + ps, la, las, strerror(errno)); + la = NULL; } Notice2("accepting connection from %s on %s", - sockaddr_info(&pa->soa, pas, peername, sizeof(peername)), - sockaddr_info(&la->soa, las, sockname, sizeof(sockname))); + sockaddr_info(pa?&pa->soa:NULL, pas, peername, sizeof(peername)), + sockaddr_info(pa?&la->soa:NULL, las, sockname, sizeof(sockname))); - if (xiocheckpeer(xfd, pa, la) < 0) { + if (pa != NULL && la != NULL && xiocheckpeer(xfd, pa, la) < 0) { if (Shutdown(ps, 2) < 0) { Info2("shutdown(%d, 2): %s", ps, strerror(errno)); } @@ -253,16 +254,20 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl infobuff, sizeof(infobuff))); applyopts(xfd->fd, opts, PH_FD); - applyopts(xfd->fd, opts, PH_CONNECTED); if (dofork) { - if ((pid = Fork()) < 0) { - Msg1(level, "fork(): %s", strerror(errno)); + pid_t pid; /* mostly int; only used with fork */ + if ((pid = xio_fork(false, level==E_ERROR?level:E_WARN)) < 0) { Close(xfd->fd); return STAT_RETRYLATER; } if (pid == 0) { /* child */ + pid_t cpid = Getpid(); + + Info1("just born: client process "F_pid, cpid); + xiosetenvulong("PID", cpid, 1); + if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } @@ -270,16 +275,10 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl #if WITH_RETRY /* !? */ - xfd->retry = 0; - xfd->forever = 0; + xfd->forever = false; xfd->retry = 0; level = E_ERROR; #endif /* WITH_RETRY */ - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } - #if WITH_UNIX /* with UNIX sockets: only listening parent is allowed to remove the socket file */ @@ -295,7 +294,6 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl if (Close(ps) < 0) { Info2("close(%d): %s", ps, strerror(errno)); } - Notice1("forked off child process "F_pid, pid); Info("still listening"); } else { if (Close(xfd->fd) < 0) { @@ -308,6 +306,10 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl if ((result = _xio_openlate(xfd, opts)) < 0) return result; + /* set the env vars describing the local and remote sockets */ + xiosetsockaddrenv("SOCK", la, las, proto); + xiosetsockaddrenv("PEER", pa, pas, proto); + return 0; } diff --git a/xio-openssl.c b/xio-openssl.c index 4fa17bc..d03f291 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -275,32 +275,23 @@ static int #if WITH_RETRY if (dofork) { pid_t pid; - while ((pid = Fork()) < 0) { - int level = E_ERROR; - if (xfd->forever || xfd->retry) { - level = E_WARN; - } - Msg1(level, "fork(): %s", strerror(errno)); - if (xfd->forever || xfd->retry) { - Nanosleep(&xfd->intervall, NULL); - --xfd->retry; - continue; + int level = E_ERROR; + if (xfd->forever || xfd->retry) { + level = E_WARN; + } + while ((pid = xio_fork(false, level)) < 0) { + if (xfd->forever || --xfd->retry) { + Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } - if (pid == 0) { /* child process */ - Info1("just born: OpenSSL client process "F_pid, Getpid()); - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } - xfd->forever = false; - xfd->retry = 0; + if (pid == 0) { /* child process */ + xfd->forever = false; xfd->retry = 0; break; } + /* parent process */ - Notice1("forked off child process "F_pid, pid); Close(xfd->fd); sycSSL_free(xfd->para.openssl.ssl); xfd->para.openssl.ssl = NULL; diff --git a/xio-progcall.c b/xio-progcall.c index 0c9f8ed..a9f151e 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -404,26 +404,10 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ xiosetchilddied(); /* set SIGCHLD handler */ if (withfork) { - const char *forkwaitstring; - int forkwaitsecs = 0; - - pid = Fork(); + pid = xio_fork(true, E_ERROR); if (pid < 0) { - Error1("fork(): %s", strerror(errno)); return -1; } - /* gdb recommends to have env controlled sleep after fork */ - if (forkwaitstring = getenv("SOCAT_FORK_WAIT")) { - forkwaitsecs = atoi(forkwaitstring); - Sleep(forkwaitsecs); - } - - if (pid == 0) { /* child */ - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } - } } if (!withfork || pid == 0) { /* child */ uid_t user; diff --git a/xio-proxy.c b/xio-proxy.c index 23ab032..f5d1f38 100644 --- a/xio-proxy.c +++ b/xio-proxy.c @@ -192,30 +192,23 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, #if WITH_RETRY if (dofork) { pid_t pid; - while ((pid = Fork()) < 0) { - int level = E_ERROR; - if (xfd->forever || xfd->retry) { - level = E_WARN; - } - Msg1(level, "fork(): %s", strerror(errno)); - if (xfd->forever || xfd->retry--) { - Nanosleep(&xfd->intervall, NULL); - continue; + int level = E_ERROR; + if (xfd->forever || xfd->retry) { + level = E_WARN; + } + while ((pid = xio_fork(false, level)) < 0) { + if (xfd->forever || --xfd->retry) { + Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } - if (pid == 0) { /* child process */ - Info1("just born: proxy client process "F_pid, Getpid()); - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } + if (pid == 0) { /* child process */ xfd->forever = false; xfd->retry = 0; break; } + /* parent process */ - Notice1("forked off child process "F_pid, pid); Close(xfd->fd); Nanosleep(&xfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); diff --git a/xio-socket.c b/xio-socket.c index d93bb98..669925c 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -9,8 +9,10 @@ #if _WITH_SOCKET #include "xioopen.h" +#include "xio-ascii.h" #include "xio-socket.h" #include "xio-named.h" +#include "xio-unix.h" #if WITH_IP4 #include "xio-ip4.h" #endif /* WITH_IP4 */ @@ -21,6 +23,15 @@ #include "xio-ipapp.h" /*! not clean */ #include "xio-tcpwrap.h" + +static int +xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, + char *typbuff, int typlen, + char *nambuff, int namlen, + char *envbuff, int envlen, + char *valbuff, int vallen); + + const struct optdesc opt_so_debug = { "so-debug", "debug", OPT_SO_DEBUG, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_DEBUG }; #ifdef SO_ACCEPTCONN /* AIX433 */ const struct optdesc opt_so_acceptconn={ "so-acceptconn","acceptconn",OPT_SO_ACCEPTCONN,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_ACCEPTCONN}; @@ -73,6 +84,9 @@ const struct optdesc opt_so_bsdcompat= { "so-bsdcompat","bsdcompat",OPT_SO_BSDCO #ifdef SO_CKSUMRECV const struct optdesc opt_so_cksumrecv= { "so-cksumrecv","cksumrecv",OPT_SO_CKSUMRECV,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_CKSUMRECV }; #endif /* SO_CKSUMRECV */ +#ifdef SO_TIMESTAMP +const struct optdesc opt_so_timestamp= { "so-timestamp","timestamp",OPT_SO_TIMESTAMP,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_TIMESTAMP }; +#endif #ifdef SO_KERNACCEPT /* AIX 4.3.3 */ const struct optdesc opt_so_kernaccept={ "so-kernaccept","kernaccept",OPT_SO_KERNACCEPT,GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_KERNACCEPT}; #endif /* SO_KERNACCEPT */ @@ -410,30 +424,26 @@ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, #if WITH_RETRY if (dofork) { pid_t pid; - while ((pid = Fork()) < 0) { - int level = E_ERROR; - if (xfd->forever || --xfd->retry) { - level = E_WARN; /* most users won't expect a problem here, + int level = E_ERROR; + if (xfd->forever || xfd->retry) { + level = E_WARN; /* most users won't expect a problem here, so Notice is too weak */ - } - Msg1(level, "fork(): %s", strerror(errno)); + } + + while ((pid = xio_fork(false, level)) < 0) { + --xfd->retry; if (xfd->forever || xfd->retry) { dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } - if (pid == 0) { /* child process */ - Info1("just born: TCP client process "F_pid, Getpid()); - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } + if (pid == 0) { /* child process */ break; } + /* parent process */ - Notice1("forked off child process "F_pid, pid); Close(xfd->fd); /* with and without retry */ Nanosleep(&xfd->intervall, NULL); @@ -720,6 +730,8 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, union sockaddr_union *pa = &_peername; /* peer address */ union sockaddr_union *la = &_sockname; /* local address */ socklen_t palen = sizeof(_peername); /* peer address size */ + char ctrlbuff[1024]; /* ancillary messages */ + struct msghdr msgh = {0}; socket_init(pf, pa); salen = sizeof(struct sockaddr); @@ -755,14 +767,25 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, return STAT_RETRYLATER; } while (true); - if (xiogetpacketsrc(xfd->fd, pa, &palen) < 0) { + msgh.msg_name = pa; + msgh.msg_namelen = palen; +#if HAVE_STRUCT_MSGHDR_MSGCONTROL + msgh.msg_control = ctrlbuff; +#endif +#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN + msgh.msg_controllen = sizeof(ctrlbuff); +#endif + if (xiogetpacketsrc(xfd->fd, &msgh) < 0) { return STAT_RETRYLATER; } + palen = msgh.msg_namelen; Notice1("receiving packet from %s"/*"src"*/, sockaddr_info((struct sockaddr *)pa, palen, peername, sizeof(peername))/*, sockaddr_info(&la->soa, sockname, sizeof(sockname))*/); + xiodopacketinfo(&msgh, true, true); + if (xiocheckpeer(xfd, pa, la) < 0) { /* drop packet */ char buff[512]; @@ -773,6 +796,10 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, sockaddr_info((struct sockaddr *)pa, palen, infobuff, sizeof(infobuff))); + /* set the env vars describing the local and remote sockets */ + /*xiosetsockaddrenv("SOCK", la, lalen, proto);*/ + xiosetsockaddrenv("PEER", pa, palen, proto); + applyopts(xfd->fd, opts, PH_FD); applyopts(xfd->fd, opts, PH_CONNECTED); @@ -782,8 +809,6 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, if (dofork) { sigset_t mask_sigchldusr1; - const char *forkwaitstring; - int forkwaitsecs = 0; /* we must prevent that the current packet triggers another fork; therefore we wait for a signal from the recent child: USR1 @@ -795,17 +820,11 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, sigaddset(&mask_sigchldusr1, SIGUSR1); Sigprocmask(SIG_BLOCK, &mask_sigchldusr1, NULL); - if ((pid = Fork()) < 0) { - Msg1(level, "fork(): %s", strerror(errno)); + if ((pid = xio_fork(false, level)) < 0) { Close(xfd->fd); Sigprocmask(SIG_UNBLOCK, &mask_sigchldusr1, NULL); return STAT_RETRYLATER; } - /* gdb recommends to have env controlled sleep after fork */ - if (forkwaitstring = getenv("SOCAT_FORK_WAIT")) { - forkwaitsecs = atoi(forkwaitstring); - Sleep(forkwaitsecs); - } if (pid == 0) { /* child */ /* no reason to block SIGCHLD in child process */ @@ -820,11 +839,6 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, level = E_ERROR; #endif /* WITH_RETRY */ - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } - #if WITH_UNIX /* with UNIX sockets: only listening parent is allowed to remove the socket file */ @@ -835,8 +849,6 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, } /* server: continue loop with listen */ - Notice1("forked off child process "F_pid, pid); - xio_waitingfor = pid; /* now we are ready to handle signals */ Sigprocmask(SIG_UNBLOCK, &mask_sigchldusr1, NULL); @@ -964,65 +976,120 @@ int retropt_socket_pf(struct opt *opts, int *pf) { } - -int xiogetpacketsrc(int fd, union sockaddr_union *pa, socklen_t *palen) { - char infobuff[256]; +/* this function calls recvmsg(..., MSG_PEEK, ...) to obtain information about + the arriving packet. in msgh the msg_name pointer must refer to an (empty) + sockaddr storage. */ +int xiogetpacketsrc(int fd, struct msghdr *msgh) { char peekbuff[1]; - -#if 0 - - struct msghdr msgh = {0}; #if HAVE_STRUCT_IOVEC struct iovec iovec; #endif - char ctrlbuff[5120]; - msgh.msg_name = pa; - msgh.msg_namelen = *palen; #if HAVE_STRUCT_IOVEC iovec.iov_base = peekbuff; iovec.iov_len = sizeof(peekbuff); - msgh.msg_iov = &iovec; - msgh.msg_iovlen = 1; -#endif -#if HAVE_STRUCT_MSGHDR_MSGCONTROL - msgh.msg_control = ctrlbuff; -#endif -#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN - msgh.msg_controllen = sizeof(ctrlbuff); + msgh->msg_iov = &iovec; + msgh->msg_iovlen = 1; #endif #if HAVE_STRUCT_MSGHDR_MSGFLAGS - msgh.msg_flags = 0; + msgh->msg_flags = 0; #endif - if (Recvmsg(fd, &msgh, MSG_PEEK + if (Recvmsg(fd, msgh, MSG_PEEK #ifdef MSG_TRUNC - |MSG_TRUNC + |MSG_TRUNC #endif ) < 0) { - Notice1("packet from %s", - sockaddr_info(&pa->soa, infobuff, sizeof(infobuff))); Warn1("recvmsg(): %s", strerror(errno)); return STAT_RETRYLATER; } - *palen = msgh.msg_namelen; return STAT_OK; +} -#else - if (Recvfrom(fd, peekbuff, sizeof(peekbuff), MSG_PEEK -#ifdef MSG_TRUNC - |MSG_TRUNC -#endif - , - &pa->soa, palen) < 0) { - Notice1("packet from %s", - sockaddr_info(&pa->soa, *palen, infobuff, sizeof(infobuff))); - Warn1("recvfrom(): %s", strerror(errno)); - return STAT_RETRYLATER; +/* works through the ancillary messages found in the given socket header record + and logs the relevant information (E_DEBUG, E_INFO). + calls protocol/layer specific functions for handling the messages + creates appropriate environment vars if withenv is set */ +int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv) { +#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) + struct cmsghdr *cmsg; + + /* parse ancillary messages */ + cmsg = CMSG_FIRSTHDR(msgh); + while (cmsg != NULL) { + int num = 0; /* number of data components of a ancill.msg */ + int i; + char typbuff[16], *typp; + char nambuff[128], *namp; + char valbuff[256], *valp; + char envbuff[256], *envp; + + if (withlog) { + xiodump(CMSG_DATA(cmsg), + cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg), + valbuff, sizeof(valbuff)-1, 0); + Debug4("ancillary message: len="F_socklen", level=%d, type=%d, data=%s", + cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type, + valbuff); + } + + /* try to get the anc.msg. contents in handy components, protocol/level + dependent */ + switch (cmsg->cmsg_level) { + case SOL_SOCKET: + xiolog_ancillary_socket(cmsg, &num, typbuff, sizeof(typbuff)-1, + nambuff, sizeof(nambuff)-1, + envbuff, sizeof(envbuff)-1, + valbuff, sizeof(valbuff)-1); + break; + case SOL_IP: + xiolog_ancillary_ip(cmsg, &num, typbuff, sizeof(typbuff)-1, + nambuff, sizeof(nambuff)-1, + envbuff, sizeof(envbuff)-1, + valbuff, sizeof(valbuff)-1); + break; + case SOL_IPV6: + xiolog_ancillary_ip6(cmsg, &num, typbuff, sizeof(typbuff)-1, + nambuff, sizeof(nambuff)-1, + envbuff, sizeof(envbuff)-1, + valbuff, sizeof(valbuff)-1); + break; + default: + num = 1; + snprintf(typbuff, sizeof(typbuff)-1, "LEVEL%u", cmsg->cmsg_level); + snprintf(nambuff, sizeof(nambuff)-1, "type%u", cmsg->cmsg_type); + xiodump(CMSG_DATA(cmsg), + cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg), + valbuff, sizeof(valbuff)-1, 0); + } + /* here the info is in typbuff (one string), nambuff (num consecutive + strings), and valbuff (num consecutive strings) */ + i = 0; + typp = typbuff; namp = nambuff; envp = envbuff; valp = valbuff; + while (i < num) { + if (withlog) { + Info3("ancillary message: %s: %s=%s", typp, namp, valp); + } + if (withenv) { + if (*envp) { + xiosetenv(envp, valp, 1); + } else if (!strcasecmp(typp+strlen(typp)-strlen(namp), namp)) { + xiosetenv(typp, valp, 1); + } else { + xiosetenv2(typp, namp, valp, 1); + } + } + if (++i == num) break; + namp = strchr(namp, '\0')+1; + envp = strchr(envp, '\0')+1; + valp = strchr(valp, '\0')+1; + } + cmsg = CMSG_NXTHDR(msgh, cmsg); } - return STAT_OK; - -#endif + return 0; +#else /* !(defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)) */ + return -1; +#endif /* !(defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)) */ } @@ -1049,6 +1116,7 @@ int xiocheckpeer(xiosingle_t *xfd, #if WITH_IP4 if (xfd->para.socket.dorange) { + if (pa == NULL) { return -1; } if (xiocheckrange(pa, &xfd->para.socket.range) < 0) { char infobuff[256]; Warn1("refusing connection from %s due to range option", @@ -1064,6 +1132,7 @@ int xiocheckpeer(xiosingle_t *xfd, #if WITH_TCP || WITH_UDP if (xfd->para.socket.ip.dosourceport) { + if (pa == NULL) { return -1; } #if WITH_IP4 if (pa->soa.sa_family == AF_INET && ntohs(((struct sockaddr_in *)pa)->sin_port) != xfd->para.socket.ip.sourceport) { @@ -1086,6 +1155,7 @@ int xiocheckpeer(xiosingle_t *xfd, sockaddr_info((struct sockaddr *)pa, 0, infobuff, sizeof(infobuff))); } else if (xfd->para.socket.ip.lowport) { + if (pa == NULL) { return -1; } if (pa->soa.sa_family == AF_INET && ntohs(((struct sockaddr_in *)pa)->sin_port) >= IPPORT_RESERVED) { Warn1("refusing connection from %s due to lowport option", @@ -1127,4 +1197,177 @@ int xiocheckpeer(xiosingle_t *xfd, return 0; /* permitted */ } +/* converts the ancillary message in *cmsg into a form useable for further + processing. knows the specifics of common message types. + returns the number of resulting syntax elements is *num + returns a sequence of \0 terminated type strings in *typbuff + returns a sequence of \0 terminated name strings in *nambuff + returns a sequence of \0 terminated value strings in *valbuff + the respective len parameters specify the available space in the buffers + returns STAT_OK + */ +static int +xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, + char *typbuff, int typlen, + char *nambuff, int namlen, + char *envbuff, int envlen, + char *valbuff, int vallen) { + const char *cmsgtype, *cmsgname, *cmsgenvn; + size_t msglen; + struct timeval *tv; + +#if defined(CMSG_DATA) + + msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); + switch (cmsg->cmsg_type) { +#ifdef SO_PASSCRED + case SO_PASSCRED: /* this is really a UNIX/LOCAL message */ + /*! needs implementation */ +#endif /* SO_PASSCRED */ +#ifdef SO_RIGHTS + case SO_RIGHTS: /* this is really a UNIX/LOCAL message */ + /*! needs implementation */ +#endif + default: /* binary data */ + snprintf(typbuff, typlen, "SOCKET.%u", cmsg->cmsg_type); + strncpy(nambuff, "data", namlen); + xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + return STAT_OK; +#ifdef SO_TIMESTAMP +# ifdef SCM_TIMESTAMP + case SCM_TIMESTAMP: +# else + case SO_TIMESTAMP: +# endif + tv = (struct timeval *)CMSG_DATA(cmsg); + cmsgtype = +#ifdef SCM_TIMESTAMP + "SCM_TIMESTAMP" /* FreeBSD */ +#else + "SO_TIMESTAMP" /* Linux */ +#endif + ; + cmsgname = "timestamp"; + cmsgenvn = "TIMESTAMP"; + { time_t t = tv->tv_sec; ctime_r(&t, valbuff); } + sprintf(strchr(valbuff, '\0')-1/*del \n*/, ", %06ld usecs", tv->tv_usec); + break; +#endif /* defined(SO_TIMESTAMP) */ + ; + } + /* when we come here we provide a single parameter + with type in cmsgtype, name in cmsgname, + and value already in valbuff */ + *num = 1; + if (strlen(cmsgtype) >= typlen) Fatal("buff too short"); + strncpy(typbuff, cmsgtype, typlen); + if (strlen(cmsgname) >= namlen) Fatal("buff too short"); + strncpy(nambuff, cmsgname, namlen); + if (strlen(cmsgenvn) >= envlen) Fatal("buff too short"); + strncpy(envbuff, cmsgenvn, envlen); + return STAT_OK; + +#else /* !defined(CMSG_DATA) */ + + return STAT_NORETRY; + +#endif /* !defined(CMSG_DATA) */ +} + + +/* return the name of the interface with given index + or NULL if is fails + The system call requires an arbitrary socket; the calling program may + provide one in parameter ins to avoid creation of a dummy socket. ins must + be <0 if it does not specify a socket fd. */ +char *xiogetifname(int ind, char *val, int ins) { +#if 0 + int s; + struct ifreq ifr; + + if (ins >= 0) { + s = ins; + } else { + if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno)); + return NULL; + } + } + +#if HAVE_STRUCT_IFREQ_IFR_INDEX + ifr.ifr_index = ind; +#elif HAVE_STRUCT_IFREQ_IFR_IFINDEX + ifr.ifr_ifindex = ind; +#endif +#ifdef SIOCGIFNAME + if(Ioctl(s, SIOCGIFNAME, &ifr) < 0) { + Info3("ioctl(%d, SIOCGIFNAME, {..., ifr_ifindex=%d, ...}: %s", + s, ifr.ifr_ifindex, strerror(errno)); + if (ins < 0) Close(s); + return NULL; + } +#endif /* SIOCGIFNAME */ + if (ins < 0) Close(s); + strcpy(val, ifr.ifr_name); + return val; +#else /* ! 0 */ + return if_indextoname(ind, val); +#endif +} + + +/* set environment variables describing (part of) a socket address, e.g. + SOCAT_SOCKADDR. lr (local/remote) specifies a string like "SOCK" or "PEER". + proto should correspond to the third parameter of socket(2) and is used to + determine the presence of port information. */ +int xiosetsockaddrenv(const char *lr, + union sockaddr_union *sau, socklen_t salen, + int proto) { +# define XIOSOCKADDRENVLEN 256 + char namebuff[XIOSOCKADDRENVLEN]; + char valuebuff[XIOSOCKADDRENVLEN]; + int idx = 0, result; + + strcpy(namebuff, lr); + switch (sau->soa.sa_family) { + case PF_UNIX: + result = + xiosetsockaddrenv_unix(idx, strchr(namebuff, '\0'), XIOSOCKADDRENVLEN-strlen(lr), + valuebuff, XIOSOCKADDRENVLEN, + &sau->un, salen, proto); + xiosetenv(namebuff, valuebuff, 1); + break; + case PF_INET: + do { + result = + xiosetsockaddrenv_ip4(idx, strchr(namebuff, '\0'), XIOSOCKADDRENVLEN-strlen(lr), + valuebuff, XIOSOCKADDRENVLEN, + &sau->ip4, proto); + xiosetenv(namebuff, valuebuff, 1); + namebuff[strlen(lr)] = '\0'; ++idx; + } while (result > 0); + break; + case PF_INET6: + strcpy(namebuff, lr); + do { + result = + xiosetsockaddrenv_ip6(idx, strchr(namebuff, '\0'), XIOSOCKADDRENVLEN-strlen(lr), + valuebuff, XIOSOCKADDRENVLEN, + &sau->ip6, proto); + xiosetenv(namebuff, valuebuff, 1); + namebuff[strlen(lr)] = '\0'; ++idx; + } while (result > 0); + break; +#if LATER + case PF_PACKET: + result = xiosetsockaddrenv_packet(lr, (void *)sau, proto); break; +#endif + default: + result = -1; + break; + } + return result; +# undef XIOSOCKADDRENVLEN +} + #endif /* _WITH_SOCKET */ diff --git a/xio-socket.h b/xio-socket.h index 04734f9..6277bd9 100644 --- a/xio-socket.h +++ b/xio-socket.h @@ -1,5 +1,5 @@ /* source: xio-socket.h */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_socket_h_included @@ -31,6 +31,7 @@ extern const struct optdesc opt_so_detach_filter; extern const struct optdesc opt_so_bindtodevice; extern const struct optdesc opt_so_bsdcompat; extern const struct optdesc opt_so_cksumrecv; +extern const struct optdesc opt_so_timestamp; extern const struct optdesc opt_so_kernaccept; extern const struct optdesc opt_so_no_check; extern const struct optdesc opt_so_noreuseaddr; @@ -51,6 +52,10 @@ extern const struct optdesc opt_siocspgrp; extern const struct optdesc opt_bind; extern const struct optdesc opt_protocol_family; + +extern +char *xiogetifname(int ind, char *val, int ins); + extern int retropt_socket_pf(struct opt *opts, int *pf); extern int xioopen_connect(struct single *fd, @@ -81,10 +86,14 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level); +extern +int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv); extern -int xiogetpacketsrc(int fd, union sockaddr_union *pa, socklen_t *palen); +int xiogetpacketsrc(int fd, struct msghdr *msgh); extern int xiocheckpeer(xiosingle_t *xfd, union sockaddr_union *pa, union sockaddr_union *la); +extern +int xiosetsockaddrenv(const char *lr, union sockaddr_union *sau, socklen_t salen, int proto); #endif /* !defined(__xio_socket_h_included) */ diff --git a/xio-socks.c b/xio-socks.c index 71c0ded..9efa675 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -170,30 +170,25 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts #if WITH_RETRY if (dofork) { pid_t pid; - while ((pid = Fork()) < 0) { - int level = E_ERROR; - if (xfd->forever || xfd->retry) { - level = E_WARN; - } - Msg1(level, "fork(): %s", strerror(errno)); - if (xfd->forever || xfd->retry--) { + int level = E_ERROR; + if (xfd->forever || xfd->retry) { + level = E_WARN; /* most users won't expect a problem here, + so Notice is too weak */ + } + while ((pid = xio_fork(false, level)) < 0) { + if (xfd->forever || --xfd->retry) { Nanosleep(&xfd->intervall, NULL); continue; } return STAT_RETRYLATER; } - if (pid == 0) { /* child process */ - Info1("just born: socks client process "F_pid, Getpid()); - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } + if (pid == 0) { /* child process */ xfd->forever = false; xfd->retry = 0; break; } + /* parent process */ - Notice1("forked off child process "F_pid, pid); Close(xfd->fd); Nanosleep(&xfd->intervall, NULL); dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); diff --git a/xio-tcpwrap.c b/xio-tcpwrap.c index 2029ed2..20d482b 100644 --- a/xio-tcpwrap.c +++ b/xio-tcpwrap.c @@ -1,5 +1,5 @@ /* source: xio-tcpwrap.c */ -/* Copyright Gerhard Rieger 2006-2007 */ +/* Copyright Gerhard Rieger 2006-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for tcpwrapper handling stuff */ @@ -93,6 +93,7 @@ int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us, if (!xfd->para.socket.ip.dolibwrap) { return 0; } + if (us == NULL || them == NULL) { return -1; } #if defined(HAVE_HOSTS_ALLOW_TABLE) save_hosts_allow_table = hosts_allow_table; diff --git a/xio-udp.c b/xio-udp.c index 293b8be..f2bff42 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -238,26 +238,21 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff))); if (dofork) { - pid = Fork(); + pid = xio_fork(false, E_ERROR); if (pid < 0) { - Error1("fork(): %s", strerror(errno)); return STAT_RETRYLATER; } - if (pid == 0) { /* child */ - /* drop parents locks, reset FIPS... */ - if (xio_forked_inchild() != 0) { - Exit(1); - } + if (pid == 0) { /* child */ break; } + /* server: continue loop with socket()+recvfrom() */ /* when we dont close this we get awkward behaviour on Linux 2.4: recvfrom gives 0 bytes with invalid socket address */ if (Close(fd->stream.fd) < 0) { Info2("close(%d): %s", fd->stream.fd, strerror(errno)); } - Notice1("forked off child process "F_pid, pid); Sleep(1); /*! give child a chance to consume the old packet */ continue; @@ -274,6 +269,14 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, return STAT_RETRYLATER; } + /* set the env vars describing the local and remote sockets */ + if (Getsockname(fd->stream.fd, &us.soa, &uslen) < 0) { + Warn4("getsockname(%d, %p, {%d}): %s", + fd->stream.fd, &us.soa, uslen, strerror(errno)); + } + xiosetsockaddrenv("SOCK", &us, uslen, IPPROTO_UDP); + xiosetsockaddrenv("PEER", them, themlen, IPPROTO_UDP); + fd->stream.howtoend = END_SHUTDOWN; applyopts_fchown(fd->stream.fd, opts); applyopts(fd->stream.fd, opts, PH_LATE); diff --git a/xio-unix.c b/xio-unix.c index b0c6b95..acfc6a6 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -1,5 +1,5 @@ /* source: xio-unix.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of UNIX socket type */ @@ -741,4 +741,25 @@ static int xioopen_abstract_client(int argc, const char *argv[], struct opt *opt #endif /* WITH_ABSTRACT_UNIXSOCKET */ +/* returns information that can be used for constructing an environment + variable describing the socket address. + if idx is 0, this function writes "ADDR" into namebuff and the path into + valuebuff, and returns 0 (which means that no more info is there). + if idx is != 0, it returns -1 + namelen and valuelen contain the max. allowed length of output chars in the + respective buffer. + on error this function returns -1. +*/ +int +xiosetsockaddrenv_unix(int idx, char *namebuff, size_t namelen, + char *valuebuff, size_t valuelen, + struct sockaddr_un *sa, socklen_t salen, int ipproto) { + if (idx != 0) { + return -1; + } + strcpy(namebuff, "ADDR"); + sockaddr_unix_info(sa, salen, valuebuff, valuelen); + return 0; +} + #endif /* WITH_UNIX */ diff --git a/xio-unix.h b/xio-unix.h index 9b09efe..8050bab 100644 --- a/xio-unix.h +++ b/xio-unix.h @@ -1,5 +1,5 @@ /* source: xio-unix.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_unix_h_included @@ -25,5 +25,9 @@ xiosetunix(struct sockaddr_un *saun, const char *path, bool abstract, bool tight); +extern int +xiosetsockaddrenv_unix(int idx, char *namebuff, size_t namelen, + char *valuebuff, size_t valuelen, + struct sockaddr_un *sa, socklen_t salen, int ipproto); #endif /* !defined(__xio_unix_h_included) */ diff --git a/xio.h b/xio.h index 930d6bd..598e8ba 100644 --- a/xio.h +++ b/xio.h @@ -375,6 +375,8 @@ extern xiofile_t *sock[XIO_MAXSOCK]; not even by external changes correctable */ extern int xioinitialize(void); +extern int xioinitialize2(void); +extern pid_t xio_fork(bool subchild, int level); extern int xio_forked_inchild(void); extern int xiosetopt(char what, const char *arg); extern int xioinqopt(char what, char *arg, size_t n); diff --git a/xioinitialize.c b/xioinitialize.c index 81c6a29..d04ad71 100644 --- a/xioinitialize.c +++ b/xioinitialize.c @@ -107,6 +107,14 @@ int xioinitialize(void) { return 0; } +/* call this function when option -lp (reset program name) has been applied */ +int xioinitialize2(void) { + pid_t pid = Getpid(); + xiosetenvulong("PID", pid, 1); + xiosetenvulong("PPID", pid, 1); + return 0; +} + /* well, this function is not for initialization, but I could not find a better place for it @@ -162,6 +170,7 @@ static int xio_nokill(xiofile_t *sock) { returns 0 on success or != 0 if an error occurred */ int xio_forked_inchild(void) { int result = 0; + xiodroplocks(); #if WITH_FIPS if (xio_reset_fips_mode() != 0) { @@ -185,3 +194,45 @@ int xio_forked_inchild(void) { return result; } + +/* subchild != 0 means that the current process is already a child process of + the master process and thus the new sub child process should not set the + SOCAT_PID variable */ +pid_t xio_fork(bool subchild, int level) { + pid_t pid; + const char *forkwaitstring; + int forkwaitsecs = 0; + + if ((pid = Fork()) < 0) { + Msg1(level, "fork(): %s", strerror(errno)); + return pid; + } + + if (pid == 0) { /* child process */ + pid_t cpid = Getpid(); + + Info1("just born: client process "F_pid, cpid); + if (!subchild) { + /* set SOCAT_PID to new value */ + xiosetenvulong("PID", pid, 1); + } + /* gdb recommends to have env controlled sleep after fork */ + if (forkwaitstring = getenv("SOCAT_FORK_WAIT")) { + forkwaitsecs = atoi(forkwaitstring); + Sleep(forkwaitsecs); + } + if (xio_forked_inchild() != 0) { + Exit(1); + } + return 0; + } + + /* parent process */ + Notice1("forked off child process "F_pid, pid); + /* gdb recommends to have env controlled sleep after fork */ + if (forkwaitstring = getenv("SOCAT_FORK_WAIT")) { + forkwaitsecs = atoi(forkwaitstring); + Sleep(forkwaitsecs); + } + return pid; +} diff --git a/xioopts.c b/xioopts.c index dfbb1ef..2ac62c8 100644 --- a/xioopts.c +++ b/xioopts.c @@ -165,6 +165,9 @@ const struct optname optionnames[] = { #ifdef SO_AUDIT /* AIX 4.3.3 */ IF_SOCKET ("audit", &opt_so_audit) #endif /* SO_AUDIT */ +#ifdef IPV6_AUTHHDR + IF_IP6 ("authhdr", &opt_ipv6_authhdr) +#endif IF_TUN ("automedia", &opt_iff_automedia) #ifdef CBAUD IF_TERMIOS("b0", &opt_b0) @@ -375,6 +378,7 @@ const struct optname optionnames[] = { IF_SOCKET ("dontlinger", &opt_so_dontlinger) #endif IF_SOCKET ("dontroute", &opt_so_dontroute) + IF_IP6 ("dstopts", &opt_ipv6_dstopts) #ifdef VDSUSP /* HP-UX */ IF_TERMIOS("dsusp", &opt_vdsusp) #endif @@ -501,6 +505,9 @@ const struct optname optionnames[] = { IF_ANY ("flock-nb", &opt_flock_ex_nb) IF_ANY ("flock-sh", &opt_flock_sh) IF_ANY ("flock-sh-nb", &opt_flock_sh_nb) +#endif +#ifdef IPV4_FLOWINFO + IF_IP6 ("flowinfo", &opt_ipv6_flowinfo) #endif IF_TERMIOS("flusho", &opt_flusho) IF_RETRY ("forever", &opt_forever) @@ -528,6 +535,8 @@ const struct optname optionnames[] = { #endif IF_READLINE("history", &opt_history_file) IF_READLINE("history-file", &opt_history_file) + IF_IP6 ("hoplimit", &opt_ipv6_hoplimit) + IF_IP6 ("hopopts", &opt_ipv6_hopopts) #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE) IF_IPAPP ("hosts-allow", &opt_tcpwrap_hosts_allow_table) #endif @@ -614,9 +623,15 @@ const struct optname optionnames[] = { #ifdef IP_PKTOPTIONS IF_IP ("ip-pktoptions", &opt_ip_pktoptions) #endif +#ifdef IP_RECVDSTADDR + IF_IP ("ip-recvdstaddr", &opt_ip_recvdstaddr) +#endif #ifdef IP_RECVERR IF_IP ("ip-recverr", &opt_ip_recverr) #endif +#ifdef IP_RECVIF + IF_IP ("ip-recvif", &opt_ip_recvif) +#endif #ifdef IP_RECVOPTS IF_IP ("ip-recvopts", &opt_ip_recvopts) #endif @@ -657,6 +672,9 @@ const struct optname optionnames[] = { #ifdef IP_PKTOPTIONS IF_IP ("ippktoptions", &opt_ip_pktoptions) #endif +#ifdef IP_RECVDSTADDR + IF_IP ("iprecvdstaddr", &opt_ip_recvdstaddr) +#endif #ifdef IP_RECVERR IF_IP ("iprecverr", &opt_ip_recverr) #endif @@ -678,7 +696,32 @@ const struct optname optionnames[] = { IF_IP ("iptos", &opt_ip_tos) IF_IP ("ipttl", &opt_ip_ttl) IF_IP6 ("ipv6-add-membership", &opt_ipv6_join_group) +#ifdef IPV6_AUTHHDR + IF_IP6 ("ipv6-authhdr", &opt_ipv6_authhdr) +#endif + IF_IP6 ("ipv6-dstopts", &opt_ipv6_dstopts) +#ifdef IPV4_FLOWINFO + IF_IP6 ("ipv6-flowinfo", &opt_ipv6_flowinfo) +#endif + IF_IP6 ("ipv6-hoplimit", &opt_ipv6_hoplimit) + IF_IP6 ("ipv6-hopopts", &opt_ipv6_hopopts) IF_IP6 ("ipv6-join-group", &opt_ipv6_join_group) + IF_IP6 ("ipv6-pktinfo", &opt_ipv6_pktinfo) + IF_IP6 ("ipv6-recvdstopts", &opt_ipv6_recvdstopts) +#ifdef IPV6_RECVERR + IF_IP6 ("ipv6-recverr", &opt_ipv6_recverr) +#endif + IF_IP6 ("ipv6-recvhoplimit", &opt_ipv6_recvhoplimit) + IF_IP6 ("ipv6-recvhopopts", &opt_ipv6_recvhopopts) +#ifdef IPV6_PATHMTU + IF_IP6 ("ipv6-recvpathmtu", &opt_ipv6_recvpathmtu) +#endif + IF_IP6 ("ipv6-recvpktinfo", &opt_ipv6_recvpktinfo) + IF_IP6 ("ipv6-recvrthdr", &opt_ipv6_recvrthdr) + IF_IP6 ("ipv6-recvtclass", &opt_ipv6_recvtclass) + IF_IP6 ("ipv6-rthdr", &opt_ipv6_rthdr) + IF_IP6 ("ipv6-tclass", &opt_ipv6_tclass) + IF_IP6 ("ipv6-unicast-hops", &opt_ipv6_unicast_hops) #ifdef IPV6_V6ONLY IF_IP6 ("ipv6-v6only", &opt_ipv6_v6only) IF_IP6 ("ipv6only", &opt_ipv6_v6only) @@ -1087,12 +1130,23 @@ const struct optname optionnames[] = { #if HAVE_RESOLV_H IF_IP ("recurse", &opt_res_recurse) #endif /* HAVE_RESOLV_H */ +#ifdef IP_RECVDSTADDR + IF_IP ("recvdstaddr", &opt_ip_recvdstaddr) +#endif + IF_IP6 ("recvdstopts", &opt_ipv6_recvdstopts) #ifdef IP_RECVERR IF_IP ("recverr", &opt_ip_recverr) +#endif + IF_IP6 ("recvhoplimit", &opt_ipv6_recvhoplimit) + IF_IP6 ("recvhopopts", &opt_ipv6_recvhopopts) +#ifdef IP_RECVIF + IF_IP ("recvif", &opt_ip_recvif) #endif #ifdef IP_RECVOPTS IF_IP ("recvopts", &opt_ip_recvopts) #endif + IF_IP6 ("recvpktinfo", &opt_ipv6_recvpktinfo) + IF_IP6 ("recvrthdr", &opt_ipv6_recvrthdr) #ifdef IP_RECVTOS IF_IP ("recvtos", &opt_ip_recvtos) #endif @@ -1139,6 +1193,7 @@ const struct optname optionnames[] = { #ifdef O_RSYNC IF_OPEN ("rsync", &opt_o_rsync) #endif + IF_IP6 ("rthdr", &opt_ipv6_rthdr) IF_TUN ("running", &opt_iff_running) #ifdef TCP_SACK_DISABLE IF_TCP ("sack-disable", &opt_tcp_sack_disable) @@ -1297,6 +1352,9 @@ const struct optname optionnames[] = { #endif #ifdef SO_SNDTIMEO IF_SOCKET ("so-sndtimeo", &opt_so_sndtimeo) +#endif +#ifdef SO_TIMESTAMP + IF_SOCKET ("so-timestamp", &opt_so_timestamp) #endif IF_SOCKET ("so-type", &opt_so_type) #ifdef SO_USE_IFBUFS @@ -1446,6 +1504,9 @@ const struct optname optionnames[] = { #endif IF_UNIX ("tightsocklen", &opt_unix_tightsocklen) IF_TERMIOS("time", &opt_vtime) +#ifdef SO_TIMESTAMP + IF_SOCKET ("timestamp", &opt_so_timestamp) +#endif IF_TERMIOS("tiocsctty", &opt_tiocsctty) #if WITH_EXT2 && defined(EXT2_TOPDIR_FL) IF_ANY ("topdir", &opt_ext2_topdir) @@ -1471,6 +1532,7 @@ const struct optname optionnames[] = { IF_NAMED ("uid-e", &opt_user_early) IF_ANY ("uid-l", &opt_user_late) IF_NAMED ("umask", &opt_umask) + IF_IP6 ("unicast-hops", &opt_ipv6_unicast_hops) IF_UNIX ("unix-tightsocklen", &opt_unix_tightsocklen) IF_NAMED ("unlink", &opt_unlink) IF_NAMED ("unlink-close", &opt_unlink_close) @@ -1713,7 +1775,7 @@ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, (*opts)[i].value.u_bin.b_len = optlen; break; case TYPE_BYTE: - { + if (assign) { unsigned long ul; char *rest; ul = strtoul(token, &rest/*!*/, 0); @@ -1722,11 +1784,13 @@ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, a0, ul, UCHAR_MAX); (*opts)[i].value.u_byte = UCHAR_MAX; } else { - Info2("setting option \"%s\" to %d", ent->desc->defname, - (*opts)[i].value.u_byte); (*opts)[i].value.u_byte = ul; } + } else { + (*opts)[i].value.u_byte = 1; } + Info2("setting option \"%s\" to %d", ent->desc->defname, + (*opts)[i].value.u_byte); break; case TYPE_INT: if (assign) { diff --git a/xioopts.h b/xioopts.h index 81ff412..0f11223 100644 --- a/xioopts.h +++ b/xioopts.h @@ -327,7 +327,24 @@ enum e_optcode { OPT_INLCR, /* termios.c_iflag */ OPT_INPCK, /* termios.c_iflag */ OPT_INTERVALL, + OPT_IPV6_AUTHHDR, + OPT_IPV6_DSTOPTS, + OPT_IPV6_FLOWINFO, + OPT_IPV6_HOPLIMIT, + OPT_IPV6_HOPOPTS, OPT_IPV6_JOIN_GROUP, + OPT_IPV6_PKTINFO, + OPT_IPV6_RECVDSTOPTS, + OPT_IPV6_RECVERR, + OPT_IPV6_RECVHOPLIMIT, + OPT_IPV6_RECVHOPOPTS, + OPT_IPV6_RECVPATHMTU, + OPT_IPV6_RECVPKTINFO, + OPT_IPV6_RECVRTHDR, + OPT_IPV6_RECVTCLASS, + OPT_IPV6_RTHDR, + OPT_IPV6_TCLASS, + OPT_IPV6_UNICAST_HOPS, OPT_IPV6_V6ONLY, #if 0 /* see Linux: man 7 netlink; probably not what we need yet */ OPT_IO_SIOCGIFNAME, @@ -355,9 +372,11 @@ enum e_optcode { #ifdef IP_PKTOPTIONS OPT_IP_PKTOPTIONS, #endif + OPT_IP_RECVDSTADDR, #ifdef IP_RECVERR OPT_IP_RECVERR, #endif + OPT_IP_RECVIF, #ifdef IP_RECVOPTS OPT_IP_RECVOPTS, #endif @@ -628,6 +647,7 @@ enum e_optcode { #ifdef SO_SNDTIMEO OPT_SO_SNDTIMEO, #endif + OPT_SO_TIMESTAMP, /* Linux */ OPT_SO_TYPE, #ifdef SO_USELOOPBACK OPT_SO_USELOOPBACK, diff --git a/xioread.c b/xioread.c index 5db886c..d8bb574 100644 --- a/xioread.c +++ b/xioread.c @@ -113,10 +113,23 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { case XIOREAD_RECV: if (pipe->dtype & XIOREAD_RECV_FROM) { #if WITH_RAWIP || WITH_UDP || WITH_UNIX + struct msghdr msgh = {0}; union sockaddr_union from = {{0}}; socklen_t fromlen = sizeof(from); char infobuff[256]; + char ctrlbuff[1024]; /* ancillary messages */ + msgh.msg_name = &from; + msgh.msg_namelen = fromlen; +#if HAVE_STRUCT_MSGHDR_MSGCONTROL + msgh.msg_control = ctrlbuff; +#endif +#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN + msgh.msg_controllen = sizeof(ctrlbuff); +#endif + if (xiogetpacketsrc(pipe->fd, &msgh) < 0) { + return -1; + } do { bytes = Recvfrom(pipe->fd, buff, bufsiz, 0, &from.soa, &fromlen); @@ -283,12 +296,23 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { } else /* ~XIOREAD_RECV_FROM */ { union sockaddr_union from; socklen_t fromlen = sizeof(from); char infobuff[256]; + struct msghdr msgh = {0}; + char ctrlbuff[1024]; /* ancillary messages */ socket_init(pipe->para.socket.la.soa.sa_family, &from); /* get source address */ - if (xiogetpacketsrc(pipe->fd, &from, &fromlen) < 0) { - return STAT_RETRYNOW; + msgh.msg_name = &from; + msgh.msg_namelen = fromlen; +#if HAVE_STRUCT_MSGHDR_MSGCONTROL + msgh.msg_control = ctrlbuff; +#endif +#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN + msgh.msg_controllen = sizeof(ctrlbuff); +#endif + if (xiogetpacketsrc(pipe->fd, &msgh) < 0) { + return -1; } + xiodopacketinfo(&msgh, true, false); if (xiocheckpeer(pipe, &from, &pipe->para.socket.la) < 0) { Recvfrom(pipe->fd, buff, bufsiz, 0, &from.soa, &fromlen); /* drop */ errno = EAGAIN; return -1; From 91057b0b68a06fb2c6d868390cde312cccc15bd2 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 22 Sep 2008 23:21:26 +0200 Subject: [PATCH 33/75] merged feature sctp streams --- CHANGES | 4 ++ Makefile.in | 3 +- VERSION | 2 +- config.h.in | 3 +- configure.in | 8 +++ doc/socat.yo | 101 ++++++++++++++++++++++++++++---- socat.c | 5 ++ sysutils.c | 6 +- test.sh | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++ xio-sctp.c | 50 ++++++++++++++++ xio-sctp.h | 19 ++++++ xiohelp.c | 2 +- xiomodes.h | 1 + xioopen.c | 20 +++++++ xioopen.h | 2 +- xioopts.c | 13 +++++ xioopts.h | 4 ++ 17 files changed, 388 insertions(+), 17 deletions(-) create mode 100644 xio-sctp.c create mode 100644 xio-sctp.h diff --git a/CHANGES b/CHANGES index 6014cd2..6cb1d7c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ new features: + new address types SCTP-CONNECT and SCTP-LISTEN implement SCTP stream + mode for IPv4 and IPv6; new address options sctp-maxseg and + sctp-nodelay + added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN, SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow protocol independent socket handling; all parameters are explicitely diff --git a/Makefile.in b/Makefile.in index e5b1f29..7e505a4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -46,7 +46,7 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ xio-socket.c xio-listen.c xio-unix.c xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c xio-socks.c xio-proxy.c xio-udp.c \ - xio-rawip.c \ + xio-sctp.c xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ xio-pty.c xio-openssl.c \ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c @@ -63,6 +63,7 @@ HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes. xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h xio-socket.h \ xio-listen.h xio-unix.h xio-rawip.h xio-ip.h xio-ip4.h xio-ip6.h \ xio-ipapp.h xio-tcp.h xio-udp.h xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-sctp.h \ xio-system.h xio-termios.h xio-readline.h \ xio-pty.h xio-openssl.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h diff --git a/VERSION b/VERSION index 0573f31..64a05c6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape+timestamp+ancillary+envvar+protocol+ioctl+setsockopt+genericsocket" +"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape+timestamp+ancillary+envvar+protocol+ioctl+setsockopt+genericsocket+sctp" diff --git a/config.h.in b/config.h.in index ec9236a..7f7dcbc 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,5 @@ /* source: config.h.in */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included @@ -471,6 +471,7 @@ #undef WITH_GENERICSOCKET #undef WITH_TCP #undef WITH_UDP +#undef WITH_SCTP #undef WITH_LISTEN #undef WITH_SOCKS4 #undef WITH_SOCKS4A diff --git a/configure.in b/configure.in index 8bb4e10..26074c6 100644 --- a/configure.in +++ b/configure.in @@ -237,6 +237,14 @@ AC_ARG_ENABLE(udp, [ --disable-udp disable UDP support], esac], [AC_DEFINE(WITH_UDP) AC_MSG_RESULT(yes)]) +AC_MSG_CHECKING(whether to include SCTP support) +AC_ARG_ENABLE(tcp, [ --disable-sctp disable SCTP support], + [case "$enableval" in + no) AC_MSG_RESULT(no);; + *) AC_DEFINE(WITH_SCTP) AC_MSG_RESULT(yes);; + esac], + [AC_DEFINE(WITH_SCTP) AC_MSG_RESULT(yes)]) + AC_MSG_CHECKING(whether to include listen support) AC_ARG_ENABLE(listen, [ --disable-listen disable listen support], [case "$enableval" in diff --git a/doc/socat.yo b/doc/socat.yo index 2644c4d..5723b1e 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -600,6 +600,69 @@ label(ADDRESS_READLINE)dit(bf(tt(READLINE))) link(noecho)(OPTION_NOECHO)nl() See also: link(STDIO)(ADDRESS_STDIO) +label(ADDRESS_SCTP_CONNECT)dit(bf(tt(SCTP-CONNECT::))) + Establishes an SCTP stream connection to the specified [link(IP + address)(TYPE_IP_ADDRESS)] and [link(TCP service)(TYPE_TCP_SERVICE)] + using TCP/IP version 4 or 6 depending on address specification, name + resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY).nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() + Useful options: + link(bind)(OPTION_BIND), + link(pf)(OPTION_PROTOCOL_FAMILY), + link(connect-timeout)(OPTION_CONNECT_TIMEOUT), + link(tos)(OPTION_TOS), + link(mtudiscover)(OPTION_MTUDISCOVER), + link(mss)(OPTION_MSS), + link(nodelay)(OPTION_NODELAY), + link(nonblock)(OPTION_NONBLOCK), + link(sourceport)(OPTION_SOURCEPORT), + link(retry)(OPTION_RETRY), + link(readbytes)(OPTION_READBYTES)nl() + See also: + link(SCTP4-CONNECT)(ADDRESS_SCTP4_CONNECT), + link(SCTP6-CONNECT)(ADDRESS_SCTP6_CONNECT), + link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), + link(TCP-CONNECT)(ADDRESS_TCP_CONNECT) +label(ADDRESS_SCTP4_CONNECT)dit(bf(tt(SCTP4-CONNECT::))) + Like link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT), but only supports IPv4 protocol.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() +label(ADDRESS_SCTP6_CONNECT)dit(bf(tt(SCTP6-CONNECT::))) + Like link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT), but only supports IPv6 protocol.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl() +label(ADDRESS_SCTP_LISTEN)dit(bf(tt(SCTP-LISTEN:))) + Listens on [link(TCP service)(TYPE_TCP_SERVICE)] and accepts a + TCP/IP connection. The IP version is 4 or the one specified with + address option link(pf)(OPTION_PROTOCOL_FAMILY), socat option + (link(-4)(option_4), link(-6)(option_6)), or environment variable link(SOCAT_DEFAULT_LISTEN_IP)(ENV_SOCAT_DEFAULT_LISTEN_IP). + Note that opening + this address usually blocks until a client connects.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl() + Useful options: + link(crnl)(OPTION_CRNL), + link(fork)(OPTION_FORK), + link(bind)(OPTION_BIND), + link(range)(OPTION_RANGE), + link(tcpwrap)(OPTION_TCPWRAPPERS), + link(pf)(OPTION_PROTOCOL_FAMILY), + link(backlog)(OPTION_BACKLOG), + link(mss)(OPTION_MSS), + link(su)(OPTION_SUBSTUSER), + link(reuseaddr)(OPTION_REUSEADDR), + link(retry)(OPTION_RETRY), + link(cool-write)(OPTION_COOL_WRITE)nl() + See also: + link(SCTP4-LISTEN)(ADDRESS_SCTP4_LISTEN), + link(SCTP6-LISTEN)(ADDRESS_SCTP6_LISTEN), + link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), + link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT) +label(ADDRESS_SCTP4_LISTEN)dit(bf(tt(SCTP4-LISTEN:))) + Like link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), but only supports IPv4 + protocol.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl() +label(ADDRESS_SCTP6_LISTEN)dit(bf(tt(SCTP6-LISTEN:))) + Like link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), but only supports IPv6 + protocol.nl() + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_SOCKET_CONNECT)dit(bf(tt(SOCKET-CONNECT:::))) Creates a stream socket using the first and second given socket parameters and tt(SOCK_STREAM) (see man socket(2)) and connects to the remote-address. @@ -829,6 +892,7 @@ label(ADDRESS_TCP_CONNECT)dit(bf(tt(TCP::))) link(TCP6)(ADDRESS_TCP6_CONNECT), link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), link(UDP)(ADDRESS_UDP_CONNECT), + link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT), link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT) label(ADDRESS_TCP4_CONNECT)dit(bf(tt(TCP4::))) Like link(TCP)(ADDRESS_TCP_CONNECT), but only supports IPv4 protocol (link(example)(EXAMPLE_ADDRESS_TCP4_CONNECT)).nl() @@ -839,7 +903,8 @@ label(ADDRESS_TCP6_CONNECT)dit(bf(tt(TCP6::))) label(ADDRESS_TCP_LISTEN)dit(bf(tt(TCP-LISTEN:))) Listens on [link(TCP service)(TYPE_TCP_SERVICE)] and accepts a TCP/IP connection. The IP version is 4 or the one specified with - link(pf)(OPTION_PROTOCOL_FAMILY). + address option link(pf)(OPTION_PROTOCOL_FAMILY), socat option + (link(-4)(option_4), link(-6)(option_6)), or environment variable link(SOCAT_DEFAULT_LISTEN_IP)(ENV_SOCAT_DEFAULT_LISTEN_IP). Note that opening this address usually blocks until a client connects.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() @@ -855,13 +920,15 @@ label(ADDRESS_TCP_LISTEN)dit(bf(tt(TCP-LISTEN:))) link(su)(OPTION_SUBSTUSER), link(reuseaddr)(OPTION_REUSEADDR), link(retry)(OPTION_RETRY), - link(retry)(OPTION_COOL_WRITE)nl() + link(cool-write)(OPTION_COOL_WRITE)nl() See also: - link(TCP4-LISTEN)(ADDRESS_TCP4_CONNECT), + link(TCP4-LISTEN)(ADDRESS_TCP4_LISTEN), link(TCP6-LISTEN)(ADDRESS_TCP6_LISTEN), link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), + link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), - link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN) + link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN), + link(TCP-CONNECT)(ADDRESS_TCP_CONNECT) label(ADDRESS_TCP4_LISTEN)dit(bf(tt(TCP4-LISTEN:))) Like link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), but only supports IPv4 protocol (link(example)(EXAMPLE_ADDRESS_TCP4_LISTEN)).nl() @@ -2058,10 +2125,24 @@ enddit() startdit()enddit()nl() -em(bf(UDP and TCP option groups)) +label(GROUP_SCTP)em(bf(SCTP option group)) + +These options may be applied to SCTP stream sockets. +startdit() +label(OPTION_SCTP_NODELAY)dit(bf(tt(sctp-nodelay))) + Sets the SCTP_NODELAY socket option that disables the Nagle algorithm. +label(OPTION_SCTP_MAXSEG)dit(bf(tt(sctp-maxseg=))) + Sets the SCTP_MAXSEG socket option to [link(int)(TYPE_INT)]. This + value is then proposed to the peer with the SYN or SYN/ACK packet. +enddit() + +startdit()enddit()nl() + + +em(bf(UDP, TCP, and SCTP option groups)) Here we find options that are related to the network port mechanism and that -thus can be used with UDP and TCP, client and server addresses. +thus can be used with UDP, TCP, and SCTP client and server addresses. startdit() label(OPTION_SOURCEPORT)dit(bf(tt(sourceport=))) For outgoing (client) TCP and UDP connections, it sets the source @@ -3163,11 +3244,11 @@ by the upper case name of the executable or the value of option link(-lp)(option_lp). startdit() +label(ENV_SOCAT_DEFAULT_LISTEN_IP) dit(bf(SOCAT_DEFAULT_LISTEN_IP) (input)) (Values 4 or 6) Sets the IP version to -be used -for listen, recv, and recvfrom addresses if no link(pf)(OPTION_PROTOCOL_FAMILY) -(protocol-family) option is given. Is overridden by socat options -link(-4)(option_4) or link(-6)(option_6). +be used for listen, recv, and recvfrom addresses if no +link(pf)(OPTION_PROTOCOL_FAMILY) (protocol-family) option is given. Is +overridden by socat options link(-4)(option_4) or link(-6)(option_6). dit(bf(SOCAT_PREFERRED_RESOLVE_IP) (input)) (Values 0, 4, or 6) Sets the IP version to diff --git a/socat.c b/socat.c index 28698bf..cf56a83 100644 --- a/socat.c +++ b/socat.c @@ -438,6 +438,11 @@ void socat_version(FILE *fd) { #else fputs(" #undef WITH_UDP\n", fd); #endif +#ifdef WITH_SCTP + fprintf(fd, " #define WITH_SCTP %d\n", WITH_SCTP); +#else + fputs(" #undef WITH_SCTP\n", fd); +#endif #ifdef WITH_LISTEN fprintf(fd, " #define WITH_LISTEN %d\n", WITH_LISTEN); #else diff --git a/sysutils.c b/sysutils.c index 472d946..615fb55 100644 --- a/sysutils.c +++ b/sysutils.c @@ -423,7 +423,9 @@ int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout) { #if WITH_TCP || WITH_UDP -/* returns port in network byte order */ +/* returns port in network byte order; + ipproto==IPPROTO_UDP resolves as UDP service, every other value resolves as + TCP */ int parseport(const char *portname, int ipproto) { struct servent *se; char *extra; @@ -438,7 +440,7 @@ int parseport(const char *portname, int ipproto) { return result; } - if ((se = getservbyname(portname, ipproto==IPPROTO_TCP?"tcp":"udp")) == NULL) { + if ((se = getservbyname(portname, ipproto==IPPROTO_UDP?"udp":"tcp")) == NULL) { Error2("cannot resolve service \"%s/%d\"", portname, ipproto); return 0; } diff --git a/test.sh b/test.sh index b847500..f5ebbf1 100755 --- a/test.sh +++ b/test.sh @@ -1866,6 +1866,40 @@ waitudp4port () { return 1 } +# wait until an SCTP4 listen port is ready +waitsctp4port () { + local port="$1" + local logic="$2" # 0..wait until free; 1..wait until listening + local timeout="$3" + local l + [ "$logic" ] || logic=1 + [ "$timeout" ] || timeout=5 + while [ $timeout -gt 0 ]; do + case "$UNAME" in + Linux) l=$(netstat -n -a |grep '^sctp .* .*[0-9*]:'$port' .* LISTEN') ;; +# FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; +# Darwin) case "$(uname -r)" in +# [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# esac ;; +# AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; +# SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; +# HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; +# OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; +# CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; + *) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;; + esac + [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ + \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0 + sleep 1 + timeout=$((timeout-1)) + done + + $ECHO "!port $port timed out! \c" >&2 + return 1 +} + # wait until a tcp6 listen port is ready waittcp6port () { local port="$1" @@ -1926,6 +1960,36 @@ waitudp6port () { return 1 } +# wait until a sctp6 listen port is ready +# not all (Linux) variants show this in netstat +waitsctp6port () { + local port="$1" + local logic="$2" # 0..wait until free; 1..wait until listening + local timeout="$3" + local l + [ "$logic" ] || logic=1 + [ "$timeout" ] || timeout=5 + while [ $timeout -gt 0 ]; do + case "$UNAME" in + Linux) l=$(netstat -an |grep '^sctp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN') ;; +# FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;; +# NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; +# OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; +# AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; +# SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; +# #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; + *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; + esac + [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ + \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0 + sleep 1 + timeout=$((timeout-1)) + done + + $ECHO "!port $port timed out! \c" >&2 + return 1 +} + # we need this misleading function name for canonical reasons waitunixport () { waitfile "$1" "$2" "$3" @@ -9174,6 +9238,7 @@ esac PORT=$((PORT+1)) N=$((N+1)) + # test the SOCKET-RECV address (with UDP4-SENDTO) NAME=SOCKET_RECV case "$TESTS" in @@ -9427,6 +9492,103 @@ PORT=$((PORT+1)) N=$((N+1)) +NAME=SCTP4STREAM +case "$TESTS" in +*%functions%*|*%ip4%*|*%ipapp%*|*%sctp%*|*%$NAME%*) +TEST="$NAME: echo via connection to SCTP V4 socket" +if ! testaddrs sctp ip4 >/dev/null || ! runsip4 >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N + numCANT=$((numCANT+1)) +elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then + # RHEL5 based systems became unusable when an sctp socket was created but + # module sctp not loaded + $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +tsl=$PORT +ts="127.0.0.1:$tsl" +da=$(date) +CMD1="$SOCAT $opts SCTP4-LISTEN:$tsl,reuseaddr PIPE" +CMD2="$SOCAT $opts stdin!!stdout SCTP4:$ts" +printf "test $F_n $TEST... " $N +$CMD1 >"$tf" 2>"${te}1" & +pid1=$! +waitsctp4port $tsl 1 +# SCTP does not seem to support half close, so we let it 1s to finish +(echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2" +if [ $? -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD1 &" + cat "${te}1" + echo "$CMD2" + cat "${te}2" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi + numOK=$((numOK+1)) +fi +kill $pid1 2>/dev/null +wait +fi ;; # sctp +esac +PORT=$((PORT+1)) +N=$((N+1)) + +NAME=SCTP6STREAM +case "$TESTS" in +*%functions%*|*%ip6%*|*%ipapp%*|*%sctp%*|*%$NAME%*) +TEST="$NAME: echo via connection to SCTP V6 socket" +if ! testaddrs sctp ip6 >/dev/null || ! runsip6 >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N + numCANT=$((numCANT+1)) +elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then + $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +tsl=$PORT +ts="[::1]:$tsl" +da=$(date) +CMD1="$SOCAT $opts SCTP6-listen:$tsl,reuseaddr PIPE" +CMD2="$SOCAT $opts stdin!!stdout SCTP6:$ts" +printf "test $F_n $TEST... " $N +$CMD1 >"$tf" 2>"${te}1" & +pid=$! # background process id +waitsctp6port $tsl 1 +# SCTP does not seem to support half close, so we let it 1s to finish +(echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2" +if [ $? -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD1 &" + echo "$CMD2" + cat "$te" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED: diff:\n" + cat "$tdiff" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi + numOK=$((numOK+1)) +fi +kill $pid 2>/dev/null +fi ;; # sctp +esac +PORT=$((PORT+1)) +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/xio-sctp.c b/xio-sctp.c new file mode 100644 index 0000000..bcfec7e --- /dev/null +++ b/xio-sctp.c @@ -0,0 +1,50 @@ +/* source: xio-sctp.c */ +/* Copyright Gerhard Rieger 2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +/* this file contains the source for SCTP related functions and options */ + +#include "xiosysincludes.h" + +#if WITH_SCTP + +#include "xioopen.h" +#include "xio-listen.h" +#include "xio-ip4.h" +#include "xio-ipapp.h" +#include "xio-sctp.h" + +/****** SCTP addresses ******/ + +#if WITH_IP4 || WITH_IP6 +const struct addrdesc addr_sctp_connect = { "sctp-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_UNSPEC HELP("::") }; +#if WITH_LISTEN +const struct addrdesc addr_sctp_listen = { "sctp-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_UNSPEC HELP(":") }; +#endif +#endif + +#if WITH_IP4 +const struct addrdesc addr_sctp4_connect = { "sctp4-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET HELP("::") }; +#if WITH_LISTEN +const struct addrdesc addr_sctp4_listen = { "sctp4-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET HELP(":") }; +#endif +#endif /* WITH_IP4 */ + +#if WITH_IP6 +const struct addrdesc addr_sctp6_connect = { "sctp6-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET6 HELP("::") }; +#if WITH_LISTEN +const struct addrdesc addr_sctp6_listen = { "sctp6-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET6 HELP(":") }; +#endif +#endif /* WITH_IP6 */ + +/****** SCTP address options ******/ + +#ifdef SCTP_NODELAY +const struct optdesc opt_sctp_nodelay = { "sctp-nodelay", "nodelay", OPT_SCTP_NODELAY, GROUP_IP_SCTP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SCTP, SCTP_NODELAY }; +#endif +#ifdef SCTP_MAXSEG +const struct optdesc opt_sctp_maxseg = { "sctp-maxseg", "mss", OPT_SCTP_MAXSEG, GROUP_IP_SCTP, PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SCTP, SCTP_MAXSEG }; +const struct optdesc opt_sctp_maxseg_late={"sctp-maxseg-late","mss-late",OPT_SCTP_MAXSEG_LATE,GROUP_IP_SCTP,PH_CONNECTED,TYPE_INT,OFUNC_SOCKOPT, SOL_SCTP, SCTP_MAXSEG}; +#endif + +#endif /* WITH_SCTP */ diff --git a/xio-sctp.h b/xio-sctp.h new file mode 100644 index 0000000..de2adb3 --- /dev/null +++ b/xio-sctp.h @@ -0,0 +1,19 @@ +/* source: xio-sctp.h */ +/* Copyright Gerhard Rieger 2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __xio_sctp_h_included +#define __xio_sctp_h_included 1 + +extern const struct addrdesc addr_sctp_connect; +extern const struct addrdesc addr_sctp_listen; +extern const struct addrdesc addr_sctp4_connect; +extern const struct addrdesc addr_sctp4_listen; +extern const struct addrdesc addr_sctp6_connect; +extern const struct addrdesc addr_sctp6_listen; + +extern const struct optdesc opt_sctp_nodelay; +extern const struct optdesc opt_sctp_maxseg; +extern const struct optdesc opt_sctp_maxseg_late; + +#endif /* !defined(__xio_sctp_h_included) */ diff --git a/xiohelp.c b/xiohelp.c index b37115b..fe232cd 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -43,7 +43,7 @@ static const char *addressgroupnames[] = { "TERMIOS", "RANGE", "PTY", "PARENT", "UNIX", "IP4", "IP6", "INTERFACE", "UDP", "TCP", "SOCKS4", "OPENSSL", - "PROCESS", "APPL", "HTTP", "undef" + "PROCESS", "APPL", "HTTP", "SCTP" } ; diff --git a/xiomodes.h b/xiomodes.h index 90a6745..48f8dac 100644 --- a/xiomodes.h +++ b/xiomodes.h @@ -28,6 +28,7 @@ #include "xio-ipapp.h" #include "xio-tcp.h" #include "xio-udp.h" +#include "xio-sctp.h" #include "xio-socks.h" #include "xio-proxy.h" #endif /* _WITH_SOCKET */ diff --git a/xioopen.c b/xioopen.c index de42455..051bbc7 100644 --- a/xioopen.c +++ b/xioopen.c @@ -135,6 +135,26 @@ const struct addrname addressnames[] = { #if WITH_READLINE { "readline", &addr_readline }, #endif +#if (WITH_IP4 || WITH_IP6) && WITH_SCTP + { "sctp", &addr_sctp_connect }, + { "sctp-connect", &addr_sctp_connect }, +#if WITH_LISTEN + { "sctp-l", &addr_sctp_listen }, + { "sctp-listen", &addr_sctp_listen }, +#endif + { "sctp4", &addr_sctp4_connect }, + { "sctp4-connect", &addr_sctp4_connect }, +#if WITH_LISTEN + { "sctp4-l", &addr_sctp4_listen }, + { "sctp4-listen", &addr_sctp4_listen }, +#endif + { "sctp6", &addr_sctp6_connect }, + { "sctp6-connect", &addr_sctp6_connect }, +#if WITH_LISTEN + { "sctp6-l", &addr_sctp6_listen }, + { "sctp6-listen", &addr_sctp6_listen }, +#endif +#endif /* (WITH_IP4 || WITH_IP6) && WITH_SCTP */ #if WITH_GENERICSOCKET { "sendto", &xioaddr_socket_sendto }, #endif diff --git a/xioopen.h b/xioopen.h index ba8bc62..2002be4 100644 --- a/xioopen.h +++ b/xioopen.h @@ -1,5 +1,5 @@ /* source: xioopen.h */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xioopen_h_included diff --git a/xioopts.c b/xioopts.c index f66485f..550a292 100644 --- a/xioopts.c +++ b/xioopts.c @@ -82,6 +82,12 @@ bool xioopts_ignoregroups; # define IF_TCP(a,b) #endif +#if WITH_SCTP +# define IF_SCTP(a,b) {a,b}, +#else +# define IF_SCTP(a,b) +#endif + #if WITH_SOCKS4 # define IF_SOCKS4(a,b) {a,b}, #else @@ -1208,6 +1214,13 @@ const struct optname optionnames[] = { IF_TCP ("sackena", &opt_tcp_sackena) #endif IF_TERMIOS("sane", &opt_sane) +#ifdef SCTP_MAXSEG + IF_SCTP ("sctp-maxseg", &opt_sctp_maxseg) + IF_SCTP ("sctp-maxseg-late", &opt_sctp_maxseg_late) +#endif +#ifdef SCTP_NODELAY + IF_SCTP ("sctp-nodelay", &opt_sctp_nodelay) +#endif #if WITH_EXT2 && defined(EXT2_SECRM_FL) IF_ANY ("secrm", &opt_ext2_secrm) #endif diff --git a/xioopts.h b/xioopts.h index b5b846d..2a02362 100644 --- a/xioopts.h +++ b/xioopts.h @@ -166,6 +166,7 @@ enum e_func { #define GROUP_PROCESS 0x10000000 /* a process related option */ #define GROUP_APPL 0x20000000 /* option handled by data loop */ #define GROUP_HTTP 0x40000000 /* any HTTP client */ +#define GROUP_IP_SCTP 0x80000000 #define GROUP_ANY (GROUP_PROCESS|GROUP_APPL) #define GROUP_ALL 0xffffffff @@ -568,6 +569,9 @@ enum e_optcode { OPT_RES_USEVC, /* resolver(3) */ OPT_RETRY, OPT_SANE, /* termios */ + OPT_SCTP_MAXSEG, + OPT_SCTP_MAXSEG_LATE, + OPT_SCTP_NODELAY, OPT_SEEK32_CUR, OPT_SEEK32_END, OPT_SEEK32_SET, From cf84b71cea00c0c71a26a9436be71f2fd7bb07ea Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 22 Sep 2008 23:39:33 +0200 Subject: [PATCH 34/75] added SCTP stream environment variable tests --- test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test.sh b/test.sh index f5ebbf1..6820123 100755 --- a/test.sh +++ b/test.sh @@ -8819,9 +8819,11 @@ done <<<" TCP4 $LOCALHOST $SECONDADDR $PORT $((PORT+1)) TCP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+2)) $((PORT+3)) UDP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+6)) $((PORT+7)) +SCTP4 $LOCALHOST $SECONDADDR $((PORT+8)) $((PORT+9)) +SCTP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+10)) $((PORT+11)) UNIX $td/test\$N.server $td/test\$N.client , , " -# this one fails do to weakness in socats UDP4-LISTEN implementation: +# this one fails due to weakness in socats UDP4-LISTEN implementation: #UDP4 $LOCALHOST $SECONDADDR $((PORT+4)) $((PORT+5)) From 28cc25ec90078be506a06f3aeff199144a504dfe Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 23 Sep 2008 14:29:09 +0200 Subject: [PATCH 35/75] 1.7.0-rc1: ported to FreeBSD: test.sh runssctpx; small fixes --- VERSION | 2 +- procan-cdefs.c | 3 +++ sysutils.c | 2 +- test.sh | 42 +++++++++++++++++++++++++++++++++--------- xioread.c | 2 ++ 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/VERSION b/VERSION index 3c08469..f3bc8c2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape+timestamp+ancillary+envvar+protocol+ioctl+setsockopt+genericsocket+sctp+interface" +"1.7.0-rc0" diff --git a/procan-cdefs.c b/procan-cdefs.c index f85ca8a..d5c1729 100644 --- a/procan-cdefs.c +++ b/procan-cdefs.c @@ -85,6 +85,9 @@ int procan_cdefs(FILE *outfile) { #endif /* socket constants */ +#ifdef PF_INET6 + fprintf(outfile, "#define PF_INET6 %d\n", PF_INET6); +#endif #ifdef SOCK_DGRAM fprintf(outfile, "#define SOCK_DGRAM %d\n", SOCK_DGRAM); #endif diff --git a/sysutils.c b/sysutils.c index 1e1aa57..4fd63fd 100644 --- a/sysutils.c +++ b/sysutils.c @@ -136,7 +136,7 @@ char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size int n; #if HAVE_STRUCT_SOCKADDR_SALEN - if ((n = snprintf(cp, blen, "LEN=%d ", sas->soa.sa_len)) < 0) { + if ((n = snprintf(cp, blen, "LEN=%d ", sau->soa.sa_len)) < 0) { Warn1("sockaddr_info(): buffer too short ("F_Zu")", blen); *buff = '\0'; return buff; diff --git a/test.sh b/test.sh index 8f9e5e9..204a41a 100755 --- a/test.sh +++ b/test.sh @@ -1692,6 +1692,26 @@ runsip6 () { return $l; } +# check if SCTP on IPv4 is available on host +runssctp4 () { + PORT="$1" + $SOCAT /dev/null SCTP4-LISTEN:$PORT 2>"$td/sctp4.stderr" & + pid=$! + sleep 1 + kill "$pid" 2>/dev/null + test ! -s "$td/sctp4.stderr" +} + +# check if SCTP on IPv6 is available on host +runssctp6 () { + PORT="$1" + $SOCAT /dev/null SCTP6-LISTEN:$PORT 2>"$td/sctp6.stderr" & + pid=$! + sleep 1 + kill "$pid" 2>/dev/null + test ! -s "$td/sctp6.stderr" +} + # wait until an IP4 protocol is ready waitip4proto () { local proto="$1" @@ -8974,8 +8994,8 @@ IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_LOCADDR user 127.0.0.1 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_DSTADDR user 127.0.0.1 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_IF user lo -IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_RECVIF user lo0 -IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_RECVDSTADDR user 127.0.0.1 +IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_IF user lo0 +IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_DSTADDR user 127.0.0.1 IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS root x01000000 IP4 IP4 127.0.0.1 PROTO , so-timestamp TIMESTAMP root $(date '+%a %b %e %H:%M:.. %Y'), ...... usecs IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL root 53 @@ -8983,8 +9003,8 @@ IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_LOCADDR root 127.0.0.1 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_DSTADDR root 127.0.0.1 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_IF root lo -IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_RECVIF root lo0 -IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_RECVDSTADDR root 127.0.0.1 +IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_IF root lo0 +IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_DSTADDR root 127.0.0.1 IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_DSTADDR user [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT user 35 IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS user xaa000000 @@ -9045,6 +9065,8 @@ esac PORT=$((PORT+1)) N=$((N+1)) +PF_INET6="$($PROCAN -c |grep "^#define[[:space:]]*PF_INET6[[:space:]]" |cut -d' ' -f3)" + # test the SOCKET-CONNECT address (against TCP6-LISTEN) NAME=SOCKET_CONNECT_TCP6 case "$TESTS" in @@ -9058,12 +9080,12 @@ tdiff="$td/test$N.diff" ts0p=$PORT; PORT=$((PORT+1)) ts0a="[::1]" ts1p=$(printf "%04x" $ts0p); -ts1a="00000000000000000000000000000001" # "127.0.0.1" -ts1="x${ts1p}x000000000000x${ts1a}" +ts1a="00000000000000000000000000000001" # "[::1]" +ts1="x${ts1p}x00000000x${ts1a}x00000000" ts1b=$(printf "%04x" $PORT); PORT=$((PORT+1)) da="test$N $(date) $RANDOM" CMD0="$SOCAT $opts TCP6-LISTEN:$ts0p,reuseaddr,bind=$ts0a PIPE" -CMD1="$SOCAT $opts - SOCKET-CONNECT:10:6:$ts1,bind=x${ts1b}x000000000000x00000000000000000000000000000000" +CMD1="$SOCAT $opts - SOCKET-CONNECT:$PF_INET6:6:$ts1,bind=x${ts1b}x00000000x00000000000000000000000000000000x00000000" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" & pid0="$!" @@ -9553,7 +9575,8 @@ NAME=SCTP4STREAM case "$TESTS" in *%functions%*|*%ip4%*|*%ipapp%*|*%sctp%*|*%$NAME%*) TEST="$NAME: echo via connection to SCTP V4 socket" -if ! testaddrs sctp ip4 >/dev/null || ! runsip4 >/dev/null; then +PORT="$((PORT+1))" +if ! testaddrs sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 "$((PORT-1))" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then @@ -9603,7 +9626,8 @@ NAME=SCTP6STREAM case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%sctp%*|*%$NAME%*) TEST="$NAME: echo via connection to SCTP V6 socket" -if ! testaddrs sctp ip6 >/dev/null || ! runsip6 >/dev/null; then +PORT="$((PORT+1))" +if ! testaddrs sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 "$((PORT-1))" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then diff --git a/xioread.c b/xioread.c index 559d9be..e3d5342 100644 --- a/xioread.c +++ b/xioread.c @@ -146,12 +146,14 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { } /* on packet type we also receive outgoing packets, this is not desired */ +#ifdef PF_PACKET if (from.soa.sa_family == PF_PACKET) { if ((((struct sockaddr_ll *)&from.soa)->sll_pkttype & PACKET_OUTGOING) == 0) { errno = EAGAIN; return -1; } } +#endif /* PF_PACKET */ Notice2("received packet with "F_Zu" bytes from %s", bytes, From b7dc45661e7de53f08a1d969d4bf97c9776fd53f Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 24 Sep 2008 08:31:00 +0200 Subject: [PATCH 36/75] socat socat did not compile on Solaris when configured with --disable-termios --- CHANGES | 4 ++++ VERSION | 2 +- filan.c | 4 +++- sycls.c | 6 +++++- sysincludes.h | 6 +++--- xio-readline.c | 12 +++++++++++- xio-termios.c | 5 ++++- xio-termios.h | 6 +++--- xioconfig.h | 6 +++++- 9 files changed, 39 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 3606959..ef84189 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +corrections: + socat did not compile on Solaris when configured without termios + feature (thanks to Pavan Gadi for reporting this bug) + ####################### V 1.6.0.1: new features: diff --git a/VERSION b/VERSION index 8821d46..63dff7f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1" +"1.6.0.1+disable_termios" diff --git a/filan.c b/filan.c index e0477d1..df37ec4 100644 --- a/filan.c +++ b/filan.c @@ -1,5 +1,5 @@ /* source: filan.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the subroutine filan makes a "FILe descriptor ANalysis". It checks the @@ -412,6 +412,7 @@ int devinfo(int fd) { int cdevan(int fd, FILE *outfile) { int ret; +#if _WITH_TERMIOS if ((ret = Isatty(fd)) < 0) { Warn2("isatty(%d): %s", fd, strerror(errno)); return -1; @@ -458,6 +459,7 @@ int cdevan(int fd, FILE *outfile) { } } } +#endif /* _WITH_TERMIOS */ return 0; } diff --git a/sycls.c b/sycls.c index 8581436..8befb2a 100644 --- a/sycls.c +++ b/sycls.c @@ -1,5 +1,5 @@ /* source: sycls.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* explicit system call and C library trace function, for those who miss strace @@ -1233,6 +1233,7 @@ void *Realloc(void *ptr, size_t size) { return result; } +#if _WITH_TERMIOS int Tcgetattr(int fd, struct termios *termios_p) { int i, result, _errno; char chars[5*NCCS], *cp = chars; @@ -1252,7 +1253,9 @@ int Tcgetattr(int fd, struct termios *termios_p) { errno = _errno; return result; } +#endif /* _WITH_TERMIOS */ +#if _WITH_TERMIOS int Tcsetattr(int fd, int optional_actions, struct termios *termios_p) { int i, result, _errno; char chars[5*NCCS], *cp = chars; @@ -1270,6 +1273,7 @@ int Tcsetattr(int fd, int optional_actions, struct termios *termios_p) { errno = _errno; return result; } +#endif /* _WITH_TERMIOS */ char *Ttyname(int fd) { char *result; diff --git a/sysincludes.h b/sysincludes.h index f233358..ddda228 100644 --- a/sysincludes.h +++ b/sysincludes.h @@ -1,5 +1,5 @@ /* source: sysincludes.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __sysincludes_h_included @@ -34,7 +34,7 @@ #if HAVE_GRP_H #include /* getgrnam() */ #endif -#if HAVE_PTY_H +#if HAVE_PTY_H && _WITH_TERMIOS #include #endif #if HAVE_SYS_PARAM_H @@ -120,7 +120,7 @@ #include #endif -#if HAVE_TERMIOS_H && WITH_TERMIOS +#if HAVE_TERMIOS_H && _WITH_TERMIOS #include #endif #if HAVE_SYS_UTSNAME_H diff --git a/xio-readline.c b/xio-readline.c index 54ae29d..4db3ec2 100644 --- a/xio-readline.c +++ b/xio-readline.c @@ -1,5 +1,5 @@ /* source: xio-readline.c */ -/* Copyright Gerhard Rieger 2002-2007 */ +/* Copyright Gerhard Rieger 2002-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening the readline address */ @@ -120,8 +120,10 @@ static int xioopen_readline(int argc, const char *argv[], struct opt *opts, if (xfd->stream.para.readline.history_file) { Read_history(xfd->stream.para.readline.history_file); } +#if _WITH_TERMIOS xiotermios_clrflag(xfd->stream.fd, 3, ICANON); xiotermios_clrflag(xfd->stream.fd, 3, ECHO); +#endif /* _WITH_TERMIOS */ return _xio_openlate(&xfd->stream, opts); } @@ -137,6 +139,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { pipe->para.readline.hasnoecho && !regexec(&pipe->para.readline.noecho, pipe->para.readline.dynprompt, 0, NULL, 0)) { +#if _WITH_TERMIOS /* under these conditions, we do not echo input, thus we circumvent readline */ struct termios saveterm, setterm; @@ -145,6 +148,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { setterm = saveterm; setterm.c_lflag |= ICANON; Tcsetattr(pipe->fd, TCSANOW, &setterm); /*!*/ +#endif /* _WITH_TERMIOS */ do { bytes = Read(pipe->fd, buff, bufsiz); } while (bytes < 0 && errno == EINTR); @@ -155,16 +159,20 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { errno = _errno; return -1; } +#if _WITH_TERMIOS setterm.c_lflag &= ~ICANON; Tcgetattr(pipe->fd, &setterm); /*! error */ Tcsetattr(pipe->fd, TCSANOW, &saveterm); /*!*/ +#endif /* _WITH_TERMIOS */ pipe->para.readline.dynend = pipe->para.readline.dynprompt; /*Write(pipe->fd, "\n", 1);*/ /*!*/ return bytes; } #endif /* HAVE_REGEX_H */ +#if _WITH_TERMIOS xiotermios_setflag(pipe->fd, 3, ECHO); +#endif /* _WITH_TERMIOS */ if (pipe->para.readline.prompt || pipe->para.readline.dynprompt) { /* we must carriage return, because readline will first print the prompt */ @@ -191,7 +199,9 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { if (line == NULL) { return 0; /* EOF */ } +#if _WITH_TERMIOS xiotermios_clrflag(pipe->fd, 3, ECHO); +#endif /* _WITH_TERMIOS */ Add_history(line); bytes = strlen(line); strncpy(buff, line, bufsiz); diff --git a/xio-termios.c b/xio-termios.c index 04e46f3..a5c2fd8 100644 --- a/xio-termios.c +++ b/xio-termios.c @@ -1,5 +1,5 @@ /* source: xio-termios.c */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for terminal I/O options */ @@ -10,6 +10,7 @@ #include "xio-termios.h" /****** TERMIOS addresses ******/ +#if _WITH_TERMIOS #if WITH_TERMIOS const struct optdesc opt_tiocsctty={ "tiocsctty", "ctty",OPT_TIOCSCTTY, GROUP_TERMIOS, PH_LATE2, TYPE_BOOL, OFUNC_SPEC }; @@ -324,3 +325,5 @@ int xiotermios_clrflag(int fd, int word, tcflag_t mask) { return 0; } +#endif /* _WITH_TERMIOS */ + diff --git a/xio-termios.h b/xio-termios.h index 00e7118..7944c67 100644 --- a/xio-termios.h +++ b/xio-termios.h @@ -1,5 +1,5 @@ /* source: xio-termios.h */ -/* Copyright Gerhard Rieger 2001-2006 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xio_termios_h_included @@ -138,10 +138,10 @@ extern const struct optdesc opt_sane; extern const struct optdesc opt_ispeed; extern const struct optdesc opt_ospeed; -#if WITH_TERMIOS /* otherwise tcflag_t might be reported undefined */ +#if _WITH_TERMIOS /* otherwise tcflag_t might be reported undefined */ extern int xiotermios_setflag(int fd, int word, tcflag_t mask); extern int xiotermios_clrflag(int fd, int word, tcflag_t mask); extern int xiotermiosflag_applyopt(int fd, struct opt *opt); -#endif /* WITH_TERMIOS */ +#endif /* _WITH_TERMIOS */ #endif /* !defined(__xio_termios_h_included) */ diff --git a/xioconfig.h b/xioconfig.h index f474b61..f62e45e 100644 --- a/xioconfig.h +++ b/xioconfig.h @@ -1,5 +1,5 @@ /* source: xioconfig.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __xioconfig_h_included @@ -20,6 +20,10 @@ # define WITH_NAMED 1 #endif +#if WITH_TERMIOS || WITH_PTY || WITH_READLINE +# define _WITH_TERMIOS 1 +#endif + #if WITH_SOCKS4A # define WITH_SOCKS4 1 #endif From fe2eb7596686fdb4d9718ba6c8e4e85aeb5444a8 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 24 Sep 2008 08:41:12 +0200 Subject: [PATCH 37/75] disable SCTP when IPPROTO_SCTP is not defined --- configure.in | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index f52f996..6488ee8 100644 --- a/configure.in +++ b/configure.in @@ -260,12 +260,28 @@ AC_ARG_ENABLE(udp, [ --disable-udp disable UDP support], [AC_DEFINE(WITH_UDP) AC_MSG_RESULT(yes)]) AC_MSG_CHECKING(whether to include SCTP support) -AC_ARG_ENABLE(tcp, [ --disable-sctp disable SCTP support], +AC_ARG_ENABLE(sctp, [ --disable-sctp disable SCTP support], [case "$enableval" in - no) AC_MSG_RESULT(no);; - *) AC_DEFINE(WITH_SCTP) AC_MSG_RESULT(yes);; + no) AC_MSG_RESULT(no); WITH_SCTP= ;; + *) AC_MSG_RESULT(yes); WITH_SCTP=1 ;; esac], - [AC_DEFINE(WITH_SCTP) AC_MSG_RESULT(yes)]) + [AC_MSG_RESULT(yes); WITH_SCTP=1 ]) + +if test -n "$WITH_SCTP"; then +AC_MSG_CHECKING(for IPPROTO_SCTP) +AC_CACHE_VAL(sc_cv_define_ipproto_sctp, +[AC_TRY_COMPILE([#include +#include ], +[IPPROTO_SCTP;], +[sc_cv_define_ipproto_sctp=yes], +[sc_cv_define_ipproto_sctp=no])]) +AC_MSG_RESULT($sc_cv_define_ipproto_sctp) +if test $sc_cv_define_ipproto_sctp = yes; then + AC_DEFINE(WITH_SCTP) +else + AC_MSG_WARN([IPPROTO_SCTP undefined, disabling SCTP support]) +fi +fi AC_MSG_CHECKING(whether to include listen support) AC_ARG_ENABLE(listen, [ --disable-listen disable listen support], From b49b7eee089d534d9d10c6bed594f99fe9bf6b52 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 24 Sep 2008 08:42:11 +0200 Subject: [PATCH 38/75] check for SCTP feature; SCTP check on Solaris --- test.sh | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/test.sh b/test.sh index 204a41a..a534a89 100755 --- a/test.sh +++ b/test.sh @@ -1904,7 +1904,7 @@ waitsctp4port () { # *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; # esac ;; # AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; -# SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; + SunOS) l=$(netstat -an -f inet -P sctp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; # HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; # CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; @@ -1996,7 +1996,7 @@ waitsctp6port () { # NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; # OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; # AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; -# SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; + SunOS) l=$(netstat -an -f inet6 -P sctp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; # #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; esac @@ -8818,7 +8818,7 @@ UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP # test: setting of environment variables that describe a stream socket # connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT, # SOCAT_PEERPORT when applicable -while read KEYW TEST_SOCKADDR TEST_PEERADDR TEST_SOCKPORT TEST_PEERPORT; do +while read KEYW FEAT TEST_SOCKADDR TEST_PEERADDR TEST_SOCKPORT TEST_PEERPORT; do if [ -z "$KEYW" ]; then continue; fi # test_proto="$(echo $KEYW |tr A-Z a-z)" @@ -8830,6 +8830,10 @@ TEST="$NAME: $KEYW-LISTEN fills environment variables with socket addresses" # code extracts and prints the SOCAT related environment vars. # outside code then checks if the environment contains the variables correctly # describing the peer and local sockets. +if ! feat=$(testaddrs $FEAT); then + $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr a-z A-Z) not available${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else tf="$td/test$N.stdout" te="$td/test$N.stderr" TEST_SOCKADDR="$(echo $TEST_SOCKADDR |sed "s/\$N/$N/g")" # actual vars @@ -8846,7 +8850,8 @@ tcp="$TEST_PEERPORT" # test client port if [ "$tcp" != ',' ]; then tca="$tca:$tcp" fi -CMD0="$SOCAT $opts -u $KEYW-LISTEN:$tsa1 system:\"export -p\"" +#CMD0="$SOCAT $opts -u $KEYW-LISTEN:$tsa1 system:\"export -p\"" +CMD0="$SOCAT $opts -u $KEYW-LISTEN:$tsa1 system:\"echo SOCAT_SOCKADDR=\\\$SOCAT_SOCKADDR; echo SOCAT_PEERADDR=\\\$SOCAT_PEERADDR; echo SOCAT_SOCKPORT=\\\$SOCAT_SOCKPORT; echo SOCAT_PEERPORT=\\\$SOCAT_PEERPORT; sleep 1\"" CMD1="$SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca" printf "test $F_n $TEST... " $N eval "$CMD0 2>\"${te}0\" >\"$tf\" &" @@ -8886,17 +8891,17 @@ else numFAIL=$((numFAIL+1)) fi set +xv -;; +fi ;; # feat esac N=$((N+1)) # done <<<" -TCP4 $LOCALHOST $SECONDADDR $PORT $((PORT+1)) -TCP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+2)) $((PORT+3)) -UDP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+6)) $((PORT+7)) -SCTP4 $LOCALHOST $SECONDADDR $((PORT+8)) $((PORT+9)) -SCTP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+10)) $((PORT+11)) -UNIX $td/test\$N.server $td/test\$N.client , , +TCP4 TCP $LOCALHOST $SECONDADDR $PORT $((PORT+1)) +TCP6 IP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+2)) $((PORT+3)) +UDP6 IP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+6)) $((PORT+7)) +SCTP4 SCTP $LOCALHOST $SECONDADDR $((PORT+8)) $((PORT+9)) +SCTP6 SCTP [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] $((PORT+10)) $((PORT+11)) +UNIX UNIX $td/test\$N.server $td/test\$N.client , , " # this one fails due to weakness in socats UDP4-LISTEN implementation: #UDP4 $LOCALHOST $SECONDADDR $((PORT+4)) $((PORT+5)) @@ -9475,10 +9480,11 @@ usleep 1000000 $CMD2 >/dev/null 2>"${te}2" /dev/null; wait -if ! echo "$da" |diff - "$tf"; then +if ! echo "$da" |diff - "$tf" >/dev/null; then $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" echo "$CMD0 &" echo "$CMD1" + echo "$da" |diff - "$tf" numCANT=$((numCANT+1)) elif [ $rc2 -eq 0 ]; then $PRINTF "$FAILED: $SOCAT:\n" From adf1196e3ffe6b5ce45d2eed7549dffe7770f766 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 24 Sep 2008 08:43:05 +0200 Subject: [PATCH 39/75] make sycls.c compile on Solaris where struct msghdr.msg_control e.a. do not exist --- sycls.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sycls.c b/sycls.c index f9b4244..35dab59 100644 --- a/sycls.c +++ b/sycls.c @@ -1065,15 +1065,28 @@ int Recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, int Recvmsg(int s, struct msghdr *msgh, int flags) { int retval, _errno; char infobuff[256]; +#if defined(HAVE_STRUCT_MSGHDR_MSGCONTROL) && defined(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN) && defined(HAVE_STRUCT_MSGHDR_MSGFLAGS) Debug10("recvmsg(%d, %p{%p,%u,%p,%u,%p,%u,%d}, %d)", s, msgh, msgh->msg_name, msgh->msg_namelen, msgh->msg_iov, msgh->msg_iovlen, msgh->msg_control, msgh->msg_controllen, msgh->msg_flags, flags); +#else + Debug7("recvmsg(%d, %p{%p,%u,%p,%u}, %d)", s, msgh, + msgh->msg_name, msgh->msg_namelen, msgh->msg_iov, msgh->msg_iovlen, + flags); +#endif retval = recvmsg(s, msgh, flags); _errno = errno; +#if defined(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN) Debug5("recvmsg(, {%s,%u,,%u,,%u,}, ) -> %d", msgh->msg_name?sockaddr_info(msgh->msg_name, msgh->msg_namelen, infobuff, sizeof(infobuff)):"NULL", msgh->msg_namelen, msgh->msg_iovlen, msgh->msg_controllen, retval); +#else + Debug4("recvmsg(, {%s,%u,,%u,,}, ) -> %d", + msgh->msg_name?sockaddr_info(msgh->msg_name, msgh->msg_namelen, infobuff, sizeof(infobuff)):"NULL", + msgh->msg_namelen, msgh->msg_iovlen, + retval); +#endif errno = _errno; return retval; } From 084726e981b9d9ae515ae842d17f3809d92dd4bb Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 24 Sep 2008 16:14:42 +0200 Subject: [PATCH 40/75] adapted conditionals to genericsocket, interface --- sysutils.c | 6 ++++-- sysutils.h | 4 ++-- xio-ip.c | 4 ++++ xio-socket.c | 21 +++++++++++++++++++++ xioopen.c | 6 ++++++ xioread.c | 4 ++-- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/sysutils.c b/sysutils.c index 4fd63fd..1f39c2d 100644 --- a/sysutils.c +++ b/sysutils.c @@ -450,7 +450,7 @@ int parseport(const char *portname, int ipproto) { #endif /* WITH_TCP || WITH_UDP */ -#if WITH_IP4 || WITH_IP6 +#if WITH_IP4 || WITH_IP6 || WITH_INTERFACE /* check the systems interfaces for ifname and return its index or -1 if no interface with this name was found The system calls require an arbitrary socket; the calling program may @@ -501,8 +501,10 @@ int ifindexbyname(const char *ifname, int anysock) { return -1; #endif /* !defined(HAVE_ STRUCT_IFREQ) && defined(SIOCGIFCONF) && defined(SIOCGIFINDEX) */ } +#endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */ +#if WITH_IP4 || WITH_IP6 || WITH_INTERFACE /* like ifindexbyname(), but also allows the index number as input - in this case it does not lookup the index. writes the resulting index to *ifindex and returns 0, @@ -526,7 +528,7 @@ int ifindex(const char *ifname, unsigned int *ifindex, int anysock) { *ifindex = val; return 0; } -#endif /* WITH_IP4 || WITH_IP6 */ +#endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */ /* constructs an environment variable whose name is built from socats uppercase diff --git a/sysutils.h b/sysutils.h index 62664ae..f49b96b 100644 --- a/sysutils.h +++ b/sysutils.h @@ -21,9 +21,9 @@ union sockaddr_union { #if WITH_UNIX struct sockaddr_un un; #endif /* WITH_UNIX */ -#if WITH_IP4 +#if _WITH_IP4 struct sockaddr_in ip4; -#endif /* WITH_IP4 */ +#endif /* _WITH_IP4 */ #if WITH_IP6 struct sockaddr_in6 ip6; #endif /* WITH_IP6 */ diff --git a/xio-ip.c b/xio-ip.c index 27758f2..1c7a8ab 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -466,6 +466,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, snprintf(nambuff, namlen, "type_%u", cmsg->cmsg_type); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; +#if WITH_IP4 #ifdef IP_PKTINFO case IP_PKTINFO: { struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); @@ -481,6 +482,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, } return STAT_OK; #endif /* IP_PKTINFO */ +#endif /* WITH_IP4 */ #ifdef IP_RECVERR case IP_RECVERR: { struct sock_extended_err *err = @@ -513,6 +515,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, return STAT_OK; } #endif /* defined(IP_RECVIF) */ +#if WITH_IP4 #ifdef IP_RECVDSTADDR case IP_RECVDSTADDR: *num = 1; @@ -522,6 +525,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen); return STAT_OK; #endif +#endif /* WITH_IP4 */ case IP_OPTIONS: case IP_RECVOPTS: cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgfmt = NULL; break; diff --git a/xio-socket.c b/xio-socket.c index 1cbfa80..006fe42 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -65,13 +65,17 @@ xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, char *valbuff, int vallen); +#if WITH_GENERICSOCKET /* generic socket addresses */ const struct addrdesc xioaddr_socket_connect = { "socket-connect", 1, xioopen_socket_connect, GROUP_FD|GROUP_SOCKET|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; +#if WITH_LISTEN const struct addrdesc xioaddr_socket_listen = { "socket-listen", 1, xioopen_socket_listen, GROUP_FD|GROUP_SOCKET|GROUP_LISTEN|GROUP_RANGE|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; +#endif /* WITH_LISTEN */ const struct addrdesc xioaddr_socket_sendto = { "socket-sendto", 3, xioopen_socket_sendto, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP("::::") }; const struct addrdesc xioaddr_socket_datagram= { "socket-datagram", 3, xioopen_socket_datagram, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; const struct addrdesc xioaddr_socket_recvfrom= { "socket-recvfrom", 3, xioopen_socket_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_RANGE|GROUP_CHILD, 0, 0, 0 HELP("::::") }; const struct addrdesc xioaddr_socket_recv = { "socket-recv", 1, xioopen_socket_recv, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; +#endif /* WITH_GENERICSOCKET */ /* the following options apply not only to generic socket addresses but to all @@ -192,6 +196,9 @@ const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT_INT_STRING, OFUNC_SOCKOPT_GENERIC, 0, 0 }; + +#if WITH_GENERICSOCKET + static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, @@ -272,6 +279,7 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, return STAT_OK; } +#if WITH_LISTEN static int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, @@ -339,6 +347,7 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, return result; return STAT_OK; } +#endif /* WITH_LISTEN */ /* we expect the form: ...:domain:type:protocol:remote-address */ static @@ -684,6 +693,8 @@ int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, return STAT_OK; } +#endif /* WITH_GENERICSOCKET */ + /* a subroutine that is common to all socket addresses that want to connect to a peer address. @@ -1594,18 +1605,22 @@ int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv) { envbuff, sizeof(envbuff)-1, valbuff, sizeof(valbuff)-1); break; +#if WITH_IP4 || WITH_IP6 case SOL_IP: xiolog_ancillary_ip(cmsg, &num, typbuff, sizeof(typbuff)-1, nambuff, sizeof(nambuff)-1, envbuff, sizeof(envbuff)-1, valbuff, sizeof(valbuff)-1); break; +#endif /* WITH_IP4 || WITH_IP6 */ +#if WITH_IP6 case SOL_IPV6: xiolog_ancillary_ip6(cmsg, &num, typbuff, sizeof(typbuff)-1, nambuff, sizeof(nambuff)-1, envbuff, sizeof(envbuff)-1, valbuff, sizeof(valbuff)-1); break; +#endif /* WITH_IP6 */ default: num = 1; snprintf(typbuff, sizeof(typbuff)-1, "LEVEL%u", cmsg->cmsg_level); @@ -1988,6 +2003,7 @@ int xiosetsockaddrenv(const char *lr, strcpy(namebuff, lr); switch (sau->soa.sa_family) { +#if WITH_UNIX case PF_UNIX: result = xiosetsockaddrenv_unix(idx, strchr(namebuff, '\0'), XIOSOCKADDRENVLEN-strlen(lr), @@ -1995,6 +2011,8 @@ int xiosetsockaddrenv(const char *lr, &sau->un, salen, proto); xiosetenv(namebuff, valuebuff, 1); break; +#endif /* WITH_UNIX */ +#if WITH_IP4 case PF_INET: do { result = @@ -2005,6 +2023,8 @@ int xiosetsockaddrenv(const char *lr, namebuff[strlen(lr)] = '\0'; ++idx; } while (result > 0); break; +#endif /* WITH_IP4 */ +#if WITH_IP6 case PF_INET6: strcpy(namebuff, lr); do { @@ -2016,6 +2036,7 @@ int xiosetsockaddrenv(const char *lr, namebuff[strlen(lr)] = '\0'; ++idx; } while (result > 0); break; +#endif /* WITH_IP6 */ #if LATER case PF_PACKET: result = xiosetsockaddrenv_packet(lr, (void *)sau, proto); break; diff --git a/xioopen.c b/xioopen.c index 25ab136..88620c6 100644 --- a/xioopen.c +++ b/xioopen.c @@ -148,18 +148,22 @@ const struct addrname addressnames[] = { { "sctp-l", &addr_sctp_listen }, { "sctp-listen", &addr_sctp_listen }, #endif +#if WITH_IP4 { "sctp4", &addr_sctp4_connect }, { "sctp4-connect", &addr_sctp4_connect }, #if WITH_LISTEN { "sctp4-l", &addr_sctp4_listen }, { "sctp4-listen", &addr_sctp4_listen }, #endif +#endif /* WITH_IP4 */ +#if WITH_IP6 { "sctp6", &addr_sctp6_connect }, { "sctp6-connect", &addr_sctp6_connect }, #if WITH_LISTEN { "sctp6-l", &addr_sctp6_listen }, { "sctp6-listen", &addr_sctp6_listen }, #endif +#endif /* WITH_IP6 */ #endif /* (WITH_IP4 || WITH_IP6) && WITH_SCTP */ #if WITH_GENERICSOCKET { "sendto", &xioaddr_socket_sendto }, @@ -167,7 +171,9 @@ const struct addrname addressnames[] = { #if WITH_GENERICSOCKET { "socket-connect", &xioaddr_socket_connect }, { "socket-datagram", &xioaddr_socket_datagram }, +#if WITH_LISTEN { "socket-listen", &xioaddr_socket_listen }, +#endif /* WITH_LISTEN */ { "socket-recv", &xioaddr_socket_recv }, { "socket-recvfrom", &xioaddr_socket_recvfrom }, { "socket-sendto", &xioaddr_socket_sendto }, diff --git a/xioread.c b/xioread.c index e3d5342..01ffa50 100644 --- a/xioread.c +++ b/xioread.c @@ -146,14 +146,14 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { } /* on packet type we also receive outgoing packets, this is not desired */ -#ifdef PF_PACKET +#if defined(PF_PACKET) && defined(PACKET_OUTGOING) if (from.soa.sa_family == PF_PACKET) { if ((((struct sockaddr_ll *)&from.soa)->sll_pkttype & PACKET_OUTGOING) == 0) { errno = EAGAIN; return -1; } } -#endif /* PF_PACKET */ +#endif /* defined(PF_PACKET) && defined(PACKET_OUTGOING) */ Notice2("received packet with "F_Zu" bytes from %s", bytes, From 3684e5daa029f4c2de7fb80f9813abeb62e57424 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 24 Sep 2008 16:15:11 +0200 Subject: [PATCH 41/75] added genericsocket to -V --- socat.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/socat.c b/socat.c index cee4191..470ad23 100644 --- a/socat.c +++ b/socat.c @@ -428,6 +428,11 @@ void socat_version(FILE *fd) { #else fputs(" #undef WITH_RAWIP\n", fd); #endif +#ifdef WITH_GENERICSOCKET + fprintf(fd, " #define WITH_GENERICSOCKET %d\n", WITH_GENERICSOCKET); +#else + fputs(" #undef WITH_GENERICSOCKET\n", fd); +#endif #ifdef WITH_INTERFACE fprintf(fd, " #define WITH_INTERFACE %d\n", WITH_INTERFACE); #else From 43bb8e9ed612ca8b4d241c648e5aa484e0eaab4c Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 24 Sep 2008 20:00:23 +0200 Subject: [PATCH 42/75] corrections with msg (fprintf) format parameters --- sysutils.c | 4 ++-- xioopts.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sysutils.c b/sysutils.c index 1f39c2d..ed1a1fa 100644 --- a/sysutils.c +++ b/sysutils.c @@ -548,7 +548,7 @@ int xiosetenv(const char *varname, const char *value, int overwrite) { for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); strncpy(envname+l+1, varname, XIO_ENVNAMELEN-1-l); if (Setenv(envname, value, overwrite) < 0) { - Warn3("setenv(\"...\", \"%s\", 1): %s", + Warn3("setenv(\"%s\", \"%s\", 1): %s", envname, value, strerror(errno)); Unsetenv(envname); /* dont want to have a wrong value */ return -1; @@ -577,7 +577,7 @@ int xiosetenv2(const char *varname, const char *varname2, const char *value, l += strlen(varname2); for (i = 0; i < l; ++i) envname[i] = toupper(envname[i]); if (Setenv(envname, value, overwrite) < 0) { - Warn3("setenv(\"...\", \"%s\", 1): %s", + Warn3("setenv(\"%s\", \"%s\", 1): %s", envname, value, strerror(errno)); Unsetenv(envname); /* dont want to have a wrong value */ return -1; diff --git a/xioopts.c b/xioopts.c index cb969b0..9d9e88d 100644 --- a/xioopts.c +++ b/xioopts.c @@ -2204,7 +2204,7 @@ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, } Info4("setting option \"%s\" to %d:%d:\"%s\"", ent->desc->defname, (*opts)[i].value.u_int, (*opts)[i].value2.u_int, - (*opts)[i].value3.u_int); + (*opts)[i].value3.u_string); break; #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) case TYPE_IP_MREQN: @@ -2878,7 +2878,7 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { break; case TYPE_INT_INT: if (Ioctl_int(fd, opt->value.u_int, opt->value2.u_int) < 0) { - Error4("ioctl(%d, %d, %p): %s", + Error4("ioctl(%d, 0x%x, 0x%x): %s", fd, opt->value.u_int, opt->value2.u_int, strerror(errno)); opt->desc = ODESC_ERROR; ++opt; continue; } From 9922641b603ce7d7ec6e1c8dfe7489f5b14f694b Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 26 Sep 2008 08:12:32 +0200 Subject: [PATCH 43/75] MacOSX port: made defines IPV6_* conditional --- xio-ip6.c | 16 ++++++++++++++++ xioopts.c | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/xio-ip6.c b/xio-ip6.c index d8ee9bc..9a729f6 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -26,27 +26,41 @@ const struct optdesc opt_ipv6_v6only = { "ipv6-v6only", "ipv6only", OPT_IPV6_V6O const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTBIND, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IPV6, IPV6_JOIN_GROUP }; #endif const struct optdesc opt_ipv6_pktinfo = { "ipv6-pktinfo", "pktinfo", OPT_IPV6_PKTINFO, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_PKTINFO }; +#ifdef IPV6_RECVPKTINFO const struct optdesc opt_ipv6_recvpktinfo = { "ipv6-recvpktinfo", "recvpktinfo", OPT_IPV6_RECVPKTINFO, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVPKTINFO }; +#endif const struct optdesc opt_ipv6_rthdr = { "ipv6-rthdr", "rthdr", OPT_IPV6_RTHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RTHDR }; +#ifdef IPV6_RECVRTHDR const struct optdesc opt_ipv6_recvrthdr = { "ipv6-recvrthdr", "recvrthdr", OPT_IPV6_RECVRTHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVRTHDR }; +#endif #ifdef IPV6_AUTHHDR const struct optdesc opt_ipv6_authhdr = { "ipv6-authhdr", "authhdr", OPT_IPV6_AUTHHDR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_AUTHHDR }; #endif const struct optdesc opt_ipv6_dstopts = { "ipv6-dstopts", "dstopts", OPT_IPV6_DSTOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_DSTOPTS }; +#ifdef IPV6_RECVDSTOPTS const struct optdesc opt_ipv6_recvdstopts = { "ipv6-recvdstopts", "recvdstopts", OPT_IPV6_RECVDSTOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVDSTOPTS }; +#endif const struct optdesc opt_ipv6_hopopts = { "ipv6-hopopts", "hopopts", OPT_IPV6_HOPOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_HOPOPTS }; +#ifdef IPV6_RECVHOPOPTS const struct optdesc opt_ipv6_recvhopopts = { "ipv6-recvhopopts", "recvhopopts", OPT_IPV6_RECVHOPOPTS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVHOPOPTS }; +#endif #ifdef IPV6_FLOWINFO /* is in linux/in6.h */ const struct optdesc opt_ipv6_flowinfo= { "ipv6-flowinfo","flowinfo",OPT_IPV6_FLOWINFO,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_FLOWINFO }; #endif const struct optdesc opt_ipv6_hoplimit= { "ipv6-hoplimit","hoplimit",OPT_IPV6_HOPLIMIT,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_HOPLIMIT }; const struct optdesc opt_ipv6_unicast_hops= { "ipv6-unicast-hops","unicast-hops",OPT_IPV6_UNICAST_HOPS,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_UNICAST_HOPS }; +#ifdef IPV6_RECVHOPLIMIT const struct optdesc opt_ipv6_recvhoplimit= { "ipv6-recvhoplimit","recvhoplimit",OPT_IPV6_RECVHOPLIMIT,GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVHOPLIMIT }; +#endif #ifdef IPV6_RECVERR const struct optdesc opt_ipv6_recverr = { "ipv6-recverr", "recverr", OPT_IPV6_RECVERR, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVERR }; #endif +#ifdef IPV6_TCLASS const struct optdesc opt_ipv6_tclass = { "ipv6-tclass", "tclass", OPT_IPV6_TCLASS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_TCLASS }; +#endif +#ifdef IPV6_RECVTCLASS const struct optdesc opt_ipv6_recvtclass = { "ipv6-recvtclass", "recvtclass", OPT_IPV6_RECVTCLASS, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVTCLASS }; +#endif #ifdef IPV6_RECVPATHMTU const struct optdesc opt_ipv6_recvpathmtu = { "ipv6-recvpathmtu", "recvpathmtu", OPT_IPV6_RECVPATHMTU, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_BOOL, OFUNC_SOCKOPT, SOL_IPV6, IPV6_RECVPATHMTU }; #endif @@ -234,11 +248,13 @@ int xiolog_ancillary_ip6(struct cmsghdr *cmsg, int *num, xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #endif +#ifdef IPV6_TCLASS case IPV6_TCLASS: strncpy(typbuff, "IPV6_TCLASS", typlen); strncpy(nambuff, "tclass", namlen); xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; +#endif default: snprintf(typbuff, typlen, "IPV6.%u", cmsg->cmsg_type); strncpy(nambuff, "data", namlen); diff --git a/xioopts.c b/xioopts.c index 9d9e88d..cc69d65 100644 --- a/xioopts.c +++ b/xioopts.c @@ -719,20 +719,34 @@ const struct optname optionnames[] = { IF_IP6 ("ipv6-hopopts", &opt_ipv6_hopopts) IF_IP6 ("ipv6-join-group", &opt_ipv6_join_group) IF_IP6 ("ipv6-pktinfo", &opt_ipv6_pktinfo) +#ifdef IPV6_RECVDSTOPTS IF_IP6 ("ipv6-recvdstopts", &opt_ipv6_recvdstopts) +#endif #ifdef IPV6_RECVERR IF_IP6 ("ipv6-recverr", &opt_ipv6_recverr) #endif +#ifdef IPV6_RECVHOPLIMIT IF_IP6 ("ipv6-recvhoplimit", &opt_ipv6_recvhoplimit) +#endif +#ifdef IPV6_RECVHOPOPTS IF_IP6 ("ipv6-recvhopopts", &opt_ipv6_recvhopopts) +#endif #ifdef IPV6_PATHMTU IF_IP6 ("ipv6-recvpathmtu", &opt_ipv6_recvpathmtu) #endif +#ifdef IPV6_RECVPKTINFO IF_IP6 ("ipv6-recvpktinfo", &opt_ipv6_recvpktinfo) +#endif +#ifdef IPV6_RECVRTHDR IF_IP6 ("ipv6-recvrthdr", &opt_ipv6_recvrthdr) +#endif +#ifdef IPV6_RECVTCLASS IF_IP6 ("ipv6-recvtclass", &opt_ipv6_recvtclass) +#endif IF_IP6 ("ipv6-rthdr", &opt_ipv6_rthdr) +#ifdef IPV6_TCLASS IF_IP6 ("ipv6-tclass", &opt_ipv6_tclass) +#endif IF_IP6 ("ipv6-unicast-hops", &opt_ipv6_unicast_hops) #ifdef IPV6_V6ONLY IF_IP6 ("ipv6-v6only", &opt_ipv6_v6only) @@ -1145,20 +1159,30 @@ const struct optname optionnames[] = { #ifdef IP_RECVDSTADDR IF_IP ("recvdstaddr", &opt_ip_recvdstaddr) #endif +#ifdef IPV6_RECVDSTOPTS IF_IP6 ("recvdstopts", &opt_ipv6_recvdstopts) +#endif #ifdef IP_RECVERR IF_IP ("recverr", &opt_ip_recverr) #endif +#ifdef IPV6_RECVHOPLIMIT IF_IP6 ("recvhoplimit", &opt_ipv6_recvhoplimit) +#endif +#ifdef IPV6_RECVHOPOPTS IF_IP6 ("recvhopopts", &opt_ipv6_recvhopopts) +#endif #ifdef IP_RECVIF IF_IP ("recvif", &opt_ip_recvif) #endif #ifdef IP_RECVOPTS IF_IP ("recvopts", &opt_ip_recvopts) #endif +#ifdef IPV6_RECVPKTINFO IF_IP6 ("recvpktinfo", &opt_ipv6_recvpktinfo) +#endif +#ifdef IPV6_RECVRTHDR IF_IP6 ("recvrthdr", &opt_ipv6_recvrthdr) +#endif #ifdef IP_RECVTOS IF_IP ("recvtos", &opt_ip_recvtos) #endif From 8287a65d1a3785412cf8af44451340a95f3a9cba Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 26 Sep 2008 08:13:19 +0200 Subject: [PATCH 44/75] MacOSX port: issue error when poll gives POLLNVAL --- socat.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/socat.c b/socat.c index 470ad23..c674a3c 100644 --- a/socat.c +++ b/socat.c @@ -929,17 +929,36 @@ int _socat(void) { } if (XIO_READABLE(sock1) && XIO_GETRDFD(sock1) >= 0 && - (fd1in->revents&(POLLIN|POLLHUP|POLLERR))) { + (fd1in->revents /*&(POLLIN|POLLHUP|POLLERR)*/)) { + if (fd1in->revents & POLLNVAL) { + /* this is what we find on Mac OS X when poll()'ing on a device or + named pipe. a read() might imm. return with 0 bytes, resulting + in a loop? */ + Error1("poll(...[%d]: invalid request", fd1in->fd); + return -1; + } mayrd1 = true; } if (XIO_READABLE(sock2) && XIO_GETRDFD(sock2) >= 0 && - (fd2in->revents&(POLLIN|POLLHUP|POLLERR))) { + (fd2in->revents)) { + if (fd2in->revents & POLLNVAL) { + Error1("poll(...[%d]: invalid request", fd2in->fd); + return -1; + } mayrd2 = true; } - if (XIO_GETWRFD(sock1) >= 0 && (fd1out->revents&(POLLOUT|POLLHUP|POLLERR))) { + if (XIO_GETWRFD(sock1) >= 0 && (fd1out->revents)) { + if (fd1out->revents & POLLNVAL) { + Error1("poll(...[%d]: invalid request", fd1out->fd); + return -1; + } maywr1 = true; } - if (XIO_GETWRFD(sock2) >= 0 && (fd2out->revents&(POLLOUT|POLLHUP|POLLERR))) { + if (XIO_GETWRFD(sock2) >= 0 && (fd2out->revents)) { + if (fd2out->revents & POLLNVAL) { + Error1("poll(...[%d]: invalid request", fd2out->fd); + return -1; + } maywr2 = true; } From 91af19a6b72234ae24e65423c12263b875b0af82 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 26 Sep 2008 11:54:08 +0200 Subject: [PATCH 45/75] Cygwin port: IP_RECVOPTS conditional --- xio-ip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xio-ip.c b/xio-ip.c index 1c7a8ab..34d25cc 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -527,7 +527,9 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, #endif #endif /* WITH_IP4 */ case IP_OPTIONS: +#ifdef IP_RECVOPTS case IP_RECVOPTS: +#endif cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgfmt = NULL; break; case IP_TOS: cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgfmt = "%u"; break; From a6699a96b548f2a45b2ee7caa8eac3dcd07ea55e Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 26 Sep 2008 12:30:04 +0200 Subject: [PATCH 46/75] Cygwin port: struct in_pktinfo conditional --- config.h.in | 3 +++ configure.in | 13 +++++++++++++ xio-ip.c | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/config.h.in b/config.h.in index 2965536..9085c8c 100644 --- a/config.h.in +++ b/config.h.in @@ -352,6 +352,9 @@ /* define if you have struct cmsghdr */ #undef HAVE_STRUCT_CMSGHDR +/* define if you have struct in_pktinfo */ +#undef HAVE_STRUCT_IN_PKTINFO + /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #undef HAVE_STRUCT_IP_IP_HL diff --git a/configure.in b/configure.in index 6488ee8..f1ee52e 100644 --- a/configure.in +++ b/configure.in @@ -1113,6 +1113,19 @@ if test $sc_cv_struct_cmsghdr = yes; then fi AC_MSG_RESULT($sc_cv_struct_cmsghdr) +dnl check for struct in_pktinfo +AC_MSG_CHECKING(for struct in_pktinfo) +AC_CACHE_VAL(sc_cv_struct_in_pktinfo, +[AC_TRY_COMPILE([#include +#include +#include ],[struct in_pktinfo s;], +[sc_cv_struct_in_pktinfo=yes], +[sc_cv_struct_in_pktinfo=no])]) +if test $sc_cv_struct_in_pktinfo = yes; then + AC_DEFINE(HAVE_STRUCT_IN_PKTINFO) +fi +AC_MSG_RESULT($sc_cv_struct_in_pktinfo) + dnl check for ip_hl in struct ip AC_MSG_CHECKING(for struct ip.ip_hl) AC_CACHE_VAL(sc_cv_struct_ip_ip_hl, diff --git a/xio-ip.c b/xio-ip.c index 34d25cc..365f066 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -467,7 +467,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); return STAT_OK; #if WITH_IP4 -#ifdef IP_PKTINFO +#if defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO case IP_PKTINFO: { struct in_pktinfo *pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); *num = 3; @@ -481,7 +481,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), scratch3, sizeof(scratch3))); } return STAT_OK; -#endif /* IP_PKTINFO */ +#endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */ #endif /* WITH_IP4 */ #ifdef IP_RECVERR case IP_RECVERR: { From ee504a7badc995742664f3190c49dcd75f643f7b Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 26 Sep 2008 12:30:35 +0200 Subject: [PATCH 47/75] Cygwin port: if_indextoname() conditional --- config.h.in | 3 +++ configure.in | 1 + xio-socket.c | 6 +++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/config.h.in b/config.h.in index 9085c8c..d078190 100644 --- a/config.h.in +++ b/config.h.in @@ -107,6 +107,9 @@ /* Define if you have the memrchr function. */ #undef HAVE_MEMRCHR +/* Define if you have the if_indextoname function. */ +#undef HAVE_IF_INDEXTONAME + /* Define if you have the sigaction function */ #undef HAVE_SIGACTION diff --git a/configure.in b/configure.in index f1ee52e..36644af 100644 --- a/configure.in +++ b/configure.in @@ -672,6 +672,7 @@ AC_FUNC_STRFTIME AC_CHECK_FUNCS(putenv select poll socket strdup strerror strstr strtod strtol) AC_CHECK_FUNCS(strtoul uname getpgid getsid getaddrinfo) AC_CHECK_FUNCS(getipnodebyname setgroups inet_aton memrchr) +AC_CHECK_FUNCS(if_indextoname) AC_CHECK_FUNCS(grantpt unlockpt ptsname) diff --git a/xio-socket.c b/xio-socket.c index 006fe42..41fb523 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1849,7 +1849,7 @@ xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, provide one in parameter ins to avoid creation of a dummy socket. ins must be <0 if it does not specify a socket fd. */ char *xiogetifname(int ind, char *val, int ins) { -#if 0 +#if !HAVE_IF_INDEXTONAME int s; struct ifreq ifr; @@ -1878,9 +1878,9 @@ char *xiogetifname(int ind, char *val, int ins) { if (ins < 0) Close(s); strcpy(val, ifr.ifr_name); return val; -#else /* ! 0 */ +#else /* HAVE_IF_INDEXTONAME */ return if_indextoname(ind, val); -#endif +#endif /* HAVE_IF_INDEXTONAME */ } From 097608e8a98b5d3d8acc13e19501802a0efc3530 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 26 Sep 2008 13:19:49 +0200 Subject: [PATCH 48/75] MacOSX port: detect TABDLY shift problem with autoconf --- configure.in | 6 +++++- xio-termios.c | 10 ++++++++-- xioinitialize.c | 6 ++++-- xioopts.c | 6 ++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/configure.in b/configure.in index 6488ee8..69ce67c 100644 --- a/configure.in +++ b/configure.in @@ -1227,7 +1227,11 @@ AC_CACHE_CHECK(shift offset of $1, $2, if (n==0) {fprintf(stderr,"$1 is 0 (impossible!)\n"); exit(1);} i=0; while (!(n&1)) { n>>=1; ++i; } - fprintf(f, "%u", i); + if (3<= 0 const struct optdesc opt_crdly = { "crdly", NULL, OPT_CRDLY, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_VALUE, 1, CRDLY, CRDLY_SHIFT }; +# endif #endif /* defined(CRDLY) */ #ifdef NLDLY # ifdef NL0 @@ -91,8 +93,10 @@ const struct optdesc opt_tab3 = { "tab3", NULL, OPT_TAB3, GROUP_TERMIOS # ifdef XTABS const struct optdesc opt_xtabs = { "xtabs", NULL, OPT_XTABS, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_FLAG, 1, XTABS, TABDLY }; # endif +# if TABDLY_SHIFT >= 0 const struct optdesc opt_tabdly = { "tabdly", NULL, OPT_TABDLY, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_VALUE, 1, TABDLY, TABDLY_SHIFT }; -#endif +# endif +#endif /* defined(TABDLY) */ #ifdef BSDLY # ifdef BS0 const struct optdesc opt_bs0 = { "bs0", NULL, OPT_BS0, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, BS0, BSDLY }; @@ -197,7 +201,9 @@ const struct optdesc opt_cs5 = { "cs5", NULL, OPT_CS5, GROUP_TERMIOS const struct optdesc opt_cs6 = { "cs6", NULL, OPT_CS6, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS6, CSIZE }; const struct optdesc opt_cs7 = { "cs7", NULL, OPT_CS7, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS7, CSIZE }; const struct optdesc opt_cs8 = { "cs8", NULL, OPT_CS8, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS8, CSIZE }; +#if CSIZE_SHIFT >= 0 const struct optdesc opt_csize = { "csize", NULL, OPT_CSIZE, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_VALUE, 2, CSIZE, CSIZE_SHIFT }; +#endif const struct optdesc opt_cstopb = { "cstopb", NULL, OPT_CSTOPB, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, CSTOPB }; const struct optdesc opt_cread = { "cread", NULL, OPT_CREAD, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, CREAD }; const struct optdesc opt_parenb = { "parenb", NULL, OPT_PARENB, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 2, PARENB }; diff --git a/xioinitialize.c b/xioinitialize.c index d04ad71..15d7d64 100644 --- a/xioinitialize.c +++ b/xioinitialize.c @@ -37,13 +37,15 @@ int xioinitialize(void) { /* some assertions about termios */ #if WITH_TERMIOS -#ifdef CRDLY +#if defined(CRDLY) && CRDLY_SHIFT >= 0 assert(3 << opt_crdly.arg3 == CRDLY); #endif -#ifdef TABDLY +#if defined(TABDLY) && TABDLY_SHIFT >= 0 assert(3 << opt_tabdly.arg3 == TABDLY); #endif +#if CSIZE_SHIFT >= 0 assert(3 << opt_csize.arg3 == CSIZE); +#endif { union { struct termios termarg; diff --git a/xioopts.c b/xioopts.c index cc69d65..259bb45 100644 --- a/xioopts.c +++ b/xioopts.c @@ -316,7 +316,9 @@ const struct optname optionnames[] = { # ifdef CR3 IF_TERMIOS("cr3", &opt_cr3) # endif +# if CRDLY_SHIFT >= 0 IF_TERMIOS("crdly", &opt_crdly) +# endif #endif /* defined(CRDLY) */ IF_TERMIOS("cread", &opt_cread) IF_OPEN ("creat", &opt_o_create) @@ -332,7 +334,9 @@ const struct optname optionnames[] = { IF_TERMIOS("cs6", &opt_cs6) IF_TERMIOS("cs7", &opt_cs7) IF_TERMIOS("cs8", &opt_cs8) +#if CSIZE_SHIFT >= 0 IF_TERMIOS("csize", &opt_csize) +#endif IF_TERMIOS("cstopb", &opt_cstopb) IF_TERMIOS("ctlecho", &opt_echoctl) IF_TERMIOS("ctty", &opt_tiocsctty) @@ -1456,7 +1460,9 @@ const struct optname optionnames[] = { # ifdef TAB3 IF_TERMIOS("tab3", &opt_tab3) # endif +# if TABDLY_SHIFT >= 0 IF_TERMIOS("tabdly", &opt_tabdly) +# endif #endif IF_TERMIOS("tandem", &opt_ixoff) #ifdef TCP_ABORT_THRESHOLD /* HP_UX */ From 2bc9b77bac0cdd205dac9801bdcb707a086a4be4 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 26 Sep 2008 16:58:08 +0200 Subject: [PATCH 49/75] new address options i-pop-all, i-push --- CHANGES | 3 ++ Makefile.in | 4 +-- config.h.in | 1 + doc/socat.yo | 7 +++++ filan.c | 49 +++++++++++++++++++++++++++++++- xio-fd.c | 5 ++++ xio-fd.h | 1 + xio-streams.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ xio-streams.h | 40 ++++++++++++++++++++++++++ xiomodes.h | 1 + xioopts.c | 26 ++++++++++++++++- xioopts.h | 10 +++++-- 12 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 xio-streams.c create mode 100644 xio-streams.h diff --git a/CHANGES b/CHANGES index 7d73860..80ab592 100644 --- a/CHANGES +++ b/CHANGES @@ -54,6 +54,9 @@ new features: new address options ipv6-tclass and ipv6-unicast-hops set the related socket options. + STREAMS (UNIX System V STREAMS) can be configured with the new address + options i-pop-all and i-push + corrections: some raw IP and UNIX datagram modes failed on BSD systems diff --git a/Makefile.in b/Makefile.in index d1c1483..fb6329e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -51,7 +51,7 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ - xio-pty.c xio-openssl.c \ + xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c @FILAN@ @SYCLS@ @SSLCLS@ @@ -69,7 +69,7 @@ HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes. xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ - xio-pty.h xio-openssl.h \ + xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h diff --git a/config.h.in b/config.h.in index 2965536..ea26d95 100644 --- a/config.h.in +++ b/config.h.in @@ -490,6 +490,7 @@ #undef WITH_PTY #undef WITH_EXT2 #undef WITH_OPENSSL +#define WITH_STREAMS 1 #undef WITH_FIPS #undef OPENSSL_FIPS #undef WITH_LIBWRAP diff --git a/doc/socat.yo b/doc/socat.yo index 2153dc1..ef39d84 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -2512,6 +2512,13 @@ label(OPTION_VTDLY)dit(bf(tt(vtdly=))) label(OPTION_WERASE)dit(bf(tt(werase=))) label(OPTION_XCASE)dit(bf(tt(xcase=))) label(OPTION_XTABS)dit(bf(tt(xtabs))) +label(OPTION_I_POP_ALL)dit(bf(tt(i-pop-all))) + With UNIX System V STREAMS, removes all drivers from the stack. +label(OPTION_I_PUSH)dit(bf(tt(i-push=))) + With UNIX System V STREAMS, pushes the driver (module) with the given name + (link(string)(TYPE_STRING)) onto the stack. For example, to make sure that a + character device on Solaris supports termios etc, use the following options: + tt(i-pop-all,i-push=ptem,i-push=ldterm,i-push=ttcompat) enddit() startdit()enddit()nl() diff --git a/filan.c b/filan.c index 0296074..246c9d3 100644 --- a/filan.c +++ b/filan.c @@ -26,7 +26,9 @@ struct sockopt { char *name; }; -/* dirty workaround so we dont get an error on AIX when getting linked with +static int filan_streams_analyze(int fd, FILE *outfile); + +/* dirty workaround so we dont get an error on AIX when being linked with libwrap */ int allow_severity, deny_severity; @@ -353,6 +355,9 @@ int filan_stat( , outfile); } + /* ever heard of POSIX streams? here we handle these */ + filan_streams_analyze(statfd, outfile); + /* now see for type specific infos */ if (statfd >= 0) { /*!indent */ switch (buf->st_mode&S_IFMT) { @@ -408,6 +413,48 @@ int devinfo(int fd) { #endif +/* returns 0 on success (not a stream descriptor, or no module) + returns <0 on failure */ +static int filan_streams_analyze(int fd, FILE *outfile) { +#ifdef I_LIST +# define SL_NMODS 8 /* max number of module names we can store */ + struct str_list modnames; + int i; + + if (!isastream(fd)) { + fprintf(outfile, "\t(no STREAMS modules)"); + return 0; + } +#if 0 /* uncomment for debugging */ + fprintf(outfile, "\tfind=%d", ioctl(fd, I_FIND, "ldterm")); +#endif + modnames.sl_nmods = ioctl(fd, I_LIST, 0); + if (modnames.sl_nmods < 0) { + fprintf(stderr, "ioctl(%d, I_LIST, 0): %s\n", fd, strerror(errno)); + return -1; + } + modnames.sl_modlist = Malloc(modnames.sl_nmods*(sizeof(struct str_mlist))); + if (modnames.sl_modlist == NULL) { + fprintf(stderr, "out of memory\n"); + return -1; + } + if (ioctl(fd, I_LIST, &modnames) < 0) { + fprintf(stderr, "ioctl(%d, I_LIST, %p): %s\n", + fd, &modnames, strerror(errno)); + free(modnames.sl_modlist); + return -1; + } + fprintf(outfile, "\tSTREAMS: "); + for (i = 0; i < modnames.sl_nmods; ++i) { + fprintf(outfile, "\"%s\"", modnames.sl_modlist[i].l_name); + if (i+1 < modnames.sl_nmods) fputc(',', outfile); + } + free(modnames.sl_modlist); +#endif /* defined(I_LIST) */ + return 0; +} + + /* character device analysis */ int cdevan(int fd, FILE *outfile) { int ret; diff --git a/xio-fd.c b/xio-fd.c index 9fc1d57..53d6415 100644 --- a/xio-fd.c +++ b/xio-fd.c @@ -82,3 +82,8 @@ const struct optdesc opt_ioctl_int = { "ioctl-int", NULL, OPT_IOCTL_I const struct optdesc opt_ioctl_intp = { "ioctl-intp", NULL, OPT_IOCTL_INTP, GROUP_FD, PH_FD, TYPE_INT_INTP, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; const struct optdesc opt_ioctl_bin = { "ioctl-bin", NULL, OPT_IOCTL_BIN, GROUP_FD, PH_FD, TYPE_INT_BIN, OFUNC_IOCTL_GENERIC, 0, 0, 0 }; const struct optdesc opt_ioctl_string = { "ioctl-string",NULL, OPT_IOCTL_STRING,GROUP_FD, PH_FD, TYPE_INT_STRING,OFUNC_IOCTL_GENERIC, 0, 0, 0 }; + +/* POSIX STREAMS */ +#define ENABLE_OPTIONS +#include "xio-streams.c" +#undef ENABLE_OPTIONS diff --git a/xio-fd.h b/xio-fd.h index a301b4e..d664212 100644 --- a/xio-fd.h +++ b/xio-fd.h @@ -42,5 +42,6 @@ extern const struct optdesc opt_f_setlk_wr; extern const struct optdesc opt_f_setlkw_wr; extern const struct optdesc opt_cool_write; extern const struct optdesc opt_end_close; +extern const struct optdesc opt_streams_i_push; #endif /* !defined(__xio_fd_h_included) */ diff --git a/xio-streams.c b/xio-streams.c new file mode 100644 index 0000000..910b53e --- /dev/null +++ b/xio-streams.c @@ -0,0 +1,79 @@ +/* source: xio-streams.c */ +/* Copyright Gerhard Rieger 2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +/* this file contains definitions and functions for handling POSIX STREAMS */ + +/* with this source file a new experimental approach is being introduced: + normally when adding a new option at least four existing files have to be + adapted; this is similar for new address types. + + in the future i would like to have a more automatic assembling of socat from + topic oriented source files. this should make integration and control of + contributions more easy. + + all code of a new topic - address and option definitions, open code, option + handing code, ev.parser code, etc. should go into one source file. the + selection of the desired code parts during the compilation is done by + setting cpp defines. + + in the same was all public declarations should go in one header (.h) file. +*/ + +/* do not compile this file directly but include it from other .c files. with + CPP defines you select one part you want to really get included: + + ENABLE_OPTIONS: activate the definition of the address option records + ENABLE_APPLYOPTS: C code that applies the address option passed in opt +*/ + +#ifdef ENABLE_OPTIONS + +#ifdef I_POP +const struct optdesc opt_streams_i_pop_all = { "streams-i-pop-all", "pop-all", OPT_STREAMS_I_POP_ALL, GROUP_FD, PH_FD, TYPE_BOOL, OFUNC_STREAMS_I_POP_ALL, 0, 0 }; +#endif +#ifdef I_PUSH +const struct optdesc opt_streams_i_push = { "streams-i-push", "push", OPT_STREAMS_I_PUSH, GROUP_FD, PH_FD, TYPE_STRING, OFUNC_STREAMS_I_PUSH, 0, 0 }; +#endif + +#elif defined(ENABLE_APPLYOPT) + +#if 0 +void dummy(void) { + if (0) { { ; +#endif +#ifdef I_POP + } else if (opt->desc->func == OFUNC_STREAMS_I_POP_ALL) { + while (Ioctl(fd, I_POP, 0) >= 0) { + Warn2("ioctl(%d, I_POP, 0): %s", fd, strerror(errno)); + } +#endif +#ifdef I_PUSH + } else if (opt->desc->func == OFUNC_STREAMS_I_PUSH) { + if (Ioctl(fd, I_PUSH, opt->value.u_string) < 0) { + Warn3("ioctl(%d, I_PUSH, \"%s\"): %s", + fd, opt->value.u_string, strerror(errno)); + opt->desc = ODESC_ERROR; ++opt; continue; + } +#endif +#if 0 +} } } +#endif + +#else /* !defined(ENABLE_APPLYOPT) */ + +#include "xiosysincludes.h" +#if WITH_STREAMS /* make this address configure dependend */ +#include "xioopen.h" + +#include "xio-fd.h" +#include "xio-socket.h" /* _xioopen_connect() */ +#include "xio-listen.h" +#include "xio-ipapp.h" +#include "xio-openssl.h" + + + +#endif /* WITH_STREAMS */ + +#endif /* !defined(ENABLE_OPTIONS) */ diff --git a/xio-streams.h b/xio-streams.h new file mode 100644 index 0000000..bc1bdbe --- /dev/null +++ b/xio-streams.h @@ -0,0 +1,40 @@ +/* source: xio-streams.h */ +/* Copyright Gerhard Rieger 2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +/* when including this file select one part that you need by defining the + appropriate CPP define: + + (none): standard define, variable, and function declarations + ENABLE_OPTCODE: option codes for use in enum e_optcode + ENABLE_OFUNC: option functions for use in enum e_func +*/ + +#ifdef ENABLE_OPTCODE + +#if 0 +enum { /* make syntax feature of editors cooperative */ +#endif + OPT_STREAMS_I_POP_ALL, /* with POSIX STREAMS */ + OPT_STREAMS_I_PUSH, /* with POSIX STREAMS */ +#if 0 +} ; +#endif + +#elif defined(ENABLE_OFUNC) + +#if 0 +enum { /* make syntax feature of editors cooperative */ +#endif + OFUNC_STREAMS_I_POP_ALL, + OFUNC_STREAMS_I_PUSH, +#if 0 +} ; +#endif + +#else /* normal declarations */ + +extern const struct optdesc opt_streams_i_pop_all; +extern const struct optdesc opt_streams_i_push; + +#endif diff --git a/xiomodes.h b/xiomodes.h index 999c4d4..602eab0 100644 --- a/xiomodes.h +++ b/xiomodes.h @@ -43,5 +43,6 @@ #include "xio-tcpwrap.h" #include "xio-ext2.h" #include "xio-tun.h" +#include "xio-streams.h" #endif /* !defined(__xiomodes_h_included) */ diff --git a/xioopts.c b/xioopts.c index 9d9e88d..ab6de76 100644 --- a/xioopts.c +++ b/xioopts.c @@ -551,6 +551,12 @@ const struct optname optionnames[] = { #endif IF_TERMIOS("hup", &opt_hupcl) IF_TERMIOS("hupcl", &opt_hupcl) +#ifdef I_POP + IF_ANY ("i-pop-all", &opt_streams_i_pop_all) +#endif +#ifdef I_PUSH + IF_ANY ("i-push", &opt_streams_i_push) +#endif IF_TERMIOS("icanon", &opt_icanon) IF_TERMIOS("icrnl", &opt_icrnl) IF_TERMIOS("iexten", &opt_iexten) @@ -1085,6 +1091,9 @@ const struct optname optionnames[] = { IF_IP ("pktopts", &opt_ip_pktoptions) #endif IF_TUN ("pointopoint", &opt_iff_pointopoint) +#ifdef I_POP + IF_ANY ("pop-all", &opt_streams_i_pop_all) +#endif /*IF_IPAPP("port", &opt_port)*/ IF_TUN ("portsel", &opt_iff_portsel) #if HAVE_RESOLV_H @@ -1122,6 +1131,9 @@ const struct optname optionnames[] = { IF_PTY ("pty-intervall", &opt_pty_intervall) IF_PTY ("pty-wait-slave", &opt_pty_wait_slave) #endif /* HAVE_PTY && HAVE_POLL */ +#ifdef I_PUSH + IF_ANY ("push", &opt_streams_i_push) +#endif #ifdef TCP_QUICKACK IF_TCP ("quickack", &opt_tcp_quickack) #endif @@ -1401,6 +1413,12 @@ const struct optname optionnames[] = { IF_TCP ("stdurg", &opt_tcp_stdurg) #endif IF_TERMIOS("stop", &opt_vstop) +#ifdef I_POP + IF_ANY ("streams-i-pop-all", &opt_streams_i_pop_all) +#endif +#ifdef I_PUSH + IF_ANY ("streams-i-push", &opt_streams_i_push) +#endif IF_ANY ("su", &opt_substuser) IF_ANY ("su-d", &opt_substuser_delayed) IF_ANY ("substuser", &opt_substuser) @@ -2797,7 +2815,7 @@ int retropt_bind(struct opt *opts, /* note: not all options can be applied this way (e.g. OFUNC_SPEC with PH_OPEN) implemented are: OFUNC_FCNTL, OFUNC_SOCKOPT (probably not all types), OFUNC_TERMIOS_FLAG, OFUNC_TERMIOS_PATTERN, and some OFUNC_SPEC */ -int applyopts(int fd, struct opt *opts, unsigned int phase) { +int applyopts(int fd, struct opt *opts, enum e_phase phase) { struct opt *opt; opt = opts; while (opt && opt->desc != ODESC_END) { @@ -3574,6 +3592,12 @@ int applyopts(int fd, struct opt *opts, unsigned int phase) { #endif /* WITH_TERMIOS */ +#if WITH_STREAMS +#define ENABLE_APPLYOPT +#include "xio-streams.c" +#undef ENABLE_APPLYOPT +#endif /* WITH_STREAMS */ + } else { /*Error1("applyopts(): function %d not implemented", opt->desc->func);*/ diff --git a/xioopts.h b/xioopts.h index 2a02362..fda6718 100644 --- a/xioopts.h +++ b/xioopts.h @@ -105,7 +105,10 @@ enum e_func { OFUNC_TERMIOS_SPEC, /* termios combined modes */ OFUNC_SIGNAL, /* a signal that should be passed to child process */ OFUNC_RESOLVER, /* a bit position used on _res.options */ - OFUNC_IFFLAG /* interface flag: locical-or a 1bit mask */ + OFUNC_IFFLAG, /* interface flag: locical-or a 1bit mask */ +# define ENABLE_OFUNC +# include "xio-streams.h" /* push a POSIX STREAMS module */ +# undef ENABLE_OFUNC } ; /* for simpler handling of option-to-connection-type relations we define @@ -689,6 +692,9 @@ enum e_optcode { #endif OPT_SOURCEPORT, OPT_STDERR, /* with exec, system */ +# define ENABLE_OPTCODE +# include "xio-streams.h" +# undef ENABLE_OPTCODE OPT_SUBSTUSER, OPT_SUBSTUSER_DELAYED, OPT_SYMBOLIC_LINK, /* with pty */ @@ -899,7 +905,7 @@ extern int retropt_bind(struct opt *opts, int feats, /* TCP etc: 1..address allowed, 3..address and port allowed */ unsigned long res_opts0, unsigned long res_opts1); -extern int applyopts(int fd, struct opt *opts, unsigned int phase); +extern int applyopts(int fd, struct opt *opts, enum e_phase phase); extern int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to); extern int applyopts_flags(struct opt *opts, int group, flags_t *result); From a0435920f644d2a256c0d44997e95bcd63a945a6 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 29 Sep 2008 21:16:07 +0200 Subject: [PATCH 50/75] HP-UX port: continued to make struct ifreq.ifr_index conditional --- xio-socket.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xio-socket.c b/xio-socket.c index 41fb523..6fa4125 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1869,8 +1869,13 @@ char *xiogetifname(int ind, char *val, int ins) { #endif #ifdef SIOCGIFNAME if(Ioctl(s, SIOCGIFNAME, &ifr) < 0) { +#if HAVE_STRUCT_IFREQ_IFR_INDEX + Info3("ioctl(%d, SIOCGIFNAME, {..., ifr_index=%d, ...}: %s", + s, ifr.ifr_index, strerror(errno)); +#elif HAVE_STRUCT_IFREQ_IFR_IFINDEX Info3("ioctl(%d, SIOCGIFNAME, {..., ifr_ifindex=%d, ...}: %s", s, ifr.ifr_ifindex, strerror(errno)); +#endif if (ins < 0) Close(s); return NULL; } From 618170baf3dc7295d157ab0ae891488744868719 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 29 Sep 2008 21:16:41 +0200 Subject: [PATCH 51/75] HP-UX port: unsetenv() might not exist --- config.h.in | 5 ++++- configure.in | 3 +++ sycls.c | 2 ++ sysutils.c | 4 ++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/config.h.in b/config.h.in index 259a942..46d12c6 100644 --- a/config.h.in +++ b/config.h.in @@ -331,7 +331,7 @@ /* Define if you have struct ifreq.ifr_index */ #undef HAVE_STRUCT_IFREQ_IFR_INDEX -/* Define if you have struct ifreq.ifr_ifindex */ +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX /* Define if your struct sockaddr has sa_len */ @@ -364,6 +364,9 @@ /* Define if you have the setenv function */ #undef HAVE_SETENV +/* Define if you have the unsetenv function. not on HP-UX */ +#undef HAVE_UNSETENV + /* Define if you have the flock function */ #undef HAVE_FLOCK diff --git a/configure.in b/configure.in index b84d510..61dd284 100644 --- a/configure.in +++ b/configure.in @@ -1198,6 +1198,9 @@ dnl Search for setenv() AC_CHECK_FUNC(setenv, AC_DEFINE(HAVE_SETENV), AC_CHECK_LIB(isode, setenv, [LIBS="-lisode $LIBS"])) +dnl Search for unsetenv() +AC_CHECK_FUNC(unsetenv, AC_DEFINE(HAVE_UNSETENV)) + dnl Run time checks diff --git a/sycls.c b/sycls.c index e9b004f..fa9f1f9 100644 --- a/sycls.c +++ b/sycls.c @@ -1459,6 +1459,7 @@ int Setenv(const char *name, const char *value, int overwrite) { return result; } +#if HAVE_UNSETENV /* on Linux it returns int but on FreeBSD void. we do not expect many errors, so we take void which works on all systems. */ void Unsetenv(const char *name) { @@ -1470,6 +1471,7 @@ void Unsetenv(const char *name) { errno = _errno; return; } +#endif #if WITH_READLINE diff --git a/sysutils.c b/sysutils.c index ed1a1fa..f9512e7 100644 --- a/sysutils.c +++ b/sysutils.c @@ -550,7 +550,9 @@ int xiosetenv(const char *varname, const char *value, int overwrite) { if (Setenv(envname, value, overwrite) < 0) { Warn3("setenv(\"%s\", \"%s\", 1): %s", envname, value, strerror(errno)); +#if HAVE_UNSETENV Unsetenv(envname); /* dont want to have a wrong value */ +#endif return -1; } return 0; @@ -579,7 +581,9 @@ int xiosetenv2(const char *varname, const char *varname2, const char *value, if (Setenv(envname, value, overwrite) < 0) { Warn3("setenv(\"%s\", \"%s\", 1): %s", envname, value, strerror(errno)); +#if HAVE_UNSETENV Unsetenv(envname); /* dont want to have a wrong value */ +#endif return -1; } return 0; From b0d29f8dc774cc768eb4b6f6abdb1a758a905e93 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 29 Sep 2008 21:18:58 +0200 Subject: [PATCH 52/75] MacOSX port: xiopoll() uses Select(), except when too many fds --- socat.c | 39 ++++++++++++++++++++------------------- sysutils.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- sysutils.h | 2 +- test.sh | 2 ++ xio-socket.c | 9 ++++----- xio-udp.c | 2 +- 6 files changed, 75 insertions(+), 29 deletions(-) diff --git a/socat.c b/socat.c index c674a3c..eb2c2dd 100644 --- a/socat.c +++ b/socat.c @@ -664,7 +664,6 @@ int socat(const char *address1, const char *address2) { */ int childleftdata(xiofile_t *xfd) { struct pollfd in; - int timeout = 0; /* milliseconds */ int retval; /* have to check if a child process died before, but left read data */ @@ -673,6 +672,7 @@ int childleftdata(xiofile_t *xfd) { XIO_RDSTREAM(xfd)->howtoend == END_CLOSE_KILL || XIO_RDSTREAM(xfd)->howtoend == END_SHUTDOWN_KILL) && XIO_RDSTREAM(xfd)->para.exec.pid == 0) { + struct timeval timeout = { 0, 0 }; if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) { in.fd = XIO_GETRDFD(xfd); @@ -680,7 +680,7 @@ int childleftdata(xiofile_t *xfd) { in.revents = 0; } do { - retval = xiopoll(&in, 1, timeout); + retval = xiopoll(&in, 1, &timeout); } while (retval < 0 && errno == EINTR); if (retval < 0) { @@ -767,7 +767,7 @@ int _socat(void) { XIO_GETRDFD(sock2), XIO_GETWRFD(sock2)); while (XIO_RDSTREAM(sock1)->eof <= 1 || XIO_RDSTREAM(sock2)->eof <= 1) { - int timeout; + struct timeval timeout, *to = NULL; Debug6("data loop: sock1->eof=%d, sock2->eof=%d, closing=%d, wasaction=%d, total_to={"F_tv_sec"."F_tv_usec"}", XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock2)->eof, @@ -799,21 +799,21 @@ int _socat(void) { if (polling) { /* there is a ignoreeof poll timeout, use it */ - timeout = 1000*socat_opts.pollintv.tv_sec + - socat_opts.pollintv.tv_usec/1000; /*!!! overflow?*/ + timeout = socat_opts.pollintv; + to = &timeout; } else if (socat_opts.total_timeout.tv_sec != 0 || socat_opts.total_timeout.tv_usec != 0) { /* there might occur a total inactivity timeout */ - timeout = 1000*socat_opts.total_timeout.tv_sec + - socat_opts.total_timeout.tv_usec/1000; + timeout = socat_opts.total_timeout; + to = &timeout; } else { - timeout = -1; /* forever */ + to = NULL; } if (closing>=1) { /* first eof already occurred, start end timer */ - timeout = 1000*socat_opts.closwait.tv_sec + - socat_opts.closwait.tv_usec/1000; + timeout = socat_opts.pollintv; + to = &timeout; closing = 2; } @@ -826,17 +826,18 @@ int _socat(void) { if (closing>=1) { /* first eof already occurred, start end timer */ - timeout = 1000*socat_opts.closwait.tv_sec + - socat_opts.closwait.tv_usec/1000; + timeout = socat_opts.closwait; + to = &timeout; closing = 2; } /* use the ignoreeof timeout if appropriate */ if (polling) { - int ptimeout = 1000*socat_opts.pollintv.tv_sec + - socat_opts.pollintv.tv_usec/1000; - if (closing == 0 || ptimeout < timeout) { - timeout = ptimeout; + if (closing == 0 || + (socat_opts.pollintv.tv_sec < timeout.tv_sec) || + ((socat_opts.pollintv.tv_sec == timeout.tv_sec) && + socat_opts.pollintv.tv_usec < timeout.tv_usec)) { + timeout = socat_opts.pollintv; } } @@ -880,7 +881,7 @@ int _socat(void) { fd2in->fd = -1; } /* frame 0: innermost part of the transfer loop: check FD status */ - retval = xiopoll(fds, 4, timeout); + retval = xiopoll(fds, 4, to); if (retval >= 0 || errno != EINTR) { break; } @@ -947,14 +948,14 @@ int _socat(void) { } mayrd2 = true; } - if (XIO_GETWRFD(sock1) >= 0 && (fd1out->revents)) { + if (XIO_GETWRFD(sock1) >= 0 && fd1out->fd >= 0 && fd1out->revents) { if (fd1out->revents & POLLNVAL) { Error1("poll(...[%d]: invalid request", fd1out->fd); return -1; } maywr1 = true; } - if (XIO_GETWRFD(sock2) >= 0 && (fd2out->revents)) { + if (XIO_GETWRFD(sock2) >= 0 && fd2out->fd >= 0 && fd2out->revents) { if (fd2out->revents & POLLNVAL) { Error1("poll(...[%d]: invalid request", fd2out->fd); return -1; diff --git a/sysutils.c b/sysutils.c index ed1a1fa..bd11f6d 100644 --- a/sysutils.c +++ b/sysutils.c @@ -413,12 +413,56 @@ const char *hstrerror(int err) { /* this function behaves like poll(). It tries to do so even when the poll() system call is not available. */ -int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout) { +int xiopoll(struct pollfd fds[], nfds_t nfds, struct timeval *timeout) { + int i, n = 0; + int result = 0; + + while (true) { /* should be if (), but we want to break */ + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + + FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); + for (i = 0; i < nfds; ++i) { + fds[i].revents = 0; + if (fds[i].fd < 0) { continue; } + if (fds[i].fd > FD_SETSIZE) { break; /* use poll */ } + if (fds[i].events & POLLIN) { + FD_SET(fds[i].fd, &readfds); n = MAX(n, fds[i].fd); } + if (fds[i].events & POLLOUT) { + FD_SET(fds[i].fd, &writefds); n = MAX(n, fds[i].fd); } + } + if (fds[i].fd > FD_SETSIZE) { break; /* use poll */ } + + result = Select(n+1, &readfds, &writefds, &exceptfds, timeout); + if (result < 0) { return result; } + for (i = 0; i < nfds; ++i) { + if (fds[i].fd < 0) { continue; } + if ((fds[i].events & POLLIN) && FD_ISSET(fds[i].fd, &readfds)) { + fds[i].revents |= POLLIN; ++result; + } + if ((fds[i].events & POLLOUT) && FD_ISSET(fds[i].fd, &writefds)) { + fds[i].revents |= POLLOUT; ++result; + } + } + return result; + } #if HAVE_POLL - return Poll(fds, nfds, timeout); + { + int ms = 0; + if (timeout == NULL) { + ms = -1; + } else { + ms = 1000*timeout->tv_sec + timeout->tv_usec/1000; + } + /*! timeout */ + return Poll(fds, nfds, ms); #else /* HAVE_POLL */ - /*!!! wrap around Select() */ + } else { + Error("poll() not available"); + return -1; #endif /* !HAVE_POLL */ + } } diff --git a/sysutils.h b/sysutils.h index f49b96b..3b30b96 100644 --- a/sysutils.h +++ b/sysutils.h @@ -74,7 +74,7 @@ extern int getusergroups(const char *user, gid_t *list, size_t *ngroups); extern const char *hstrerror(int err); #endif -extern int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout); +extern int xiopoll(struct pollfd fds[], nfds_t nfds, struct timeval *timeout); extern int parseport(const char *portname, int proto); diff --git a/test.sh b/test.sh index a534a89..83c8aa9 100755 --- a/test.sh +++ b/test.sh @@ -5697,6 +5697,7 @@ if ! feat=$(testaddrs pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr a-z A-Z) not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else +set -vx SIG="$(signum $signam)" te="$td/test$N.stderr" tpp="$td/test$N.ppid" @@ -5725,6 +5726,7 @@ else numFAIL=$((numFAIL+1)) fi wait +set +vx fi ;; # feat esac N=$((N+1)) diff --git a/xio-socket.c b/xio-socket.c index 006fe42..efe4f16 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -840,18 +840,17 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, if (errno == EINPROGRESS) { if (xfd->para.socket.connect_timeout.tv_sec != 0 || xfd->para.socket.connect_timeout.tv_usec != 0) { - int timeout; + struct timeval timeout; struct pollfd writefd; int result; Info4("connect(%d, %s, "F_Zd"): %s", xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); - timeout = 1000*xfd->para.socket.connect_timeout.tv_sec + - xfd->para.socket.connect_timeout.tv_usec/1000; + timeout = xfd->para.socket.connect_timeout; writefd.fd = xfd->fd; writefd.events = (POLLIN|POLLHUP|POLLERR); - result = Poll(&writefd, 1, timeout); + result = xiopoll(&writefd, 1, &timeout); if (result < 0) { Msg3(level, "poll({%d,POLLIN|POLLHUP|POLLER},,%d): %s", xfd->fd, timeout, strerror(errno)); @@ -1319,7 +1318,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, } readfd.fd = xfd->fd; readfd.events = POLLIN; - if (Poll(&readfd, 1, -1) > 0) { + if (xiopoll(&readfd, 1, NULL) > 0) { break; } diff --git a/xio-udp.c b/xio-udp.c index f507e24..77ffdd6 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -205,7 +205,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff))); readfd.fd = fd->stream.fd; readfd.events = POLLIN|POLLERR; - while (Poll(&readfd, 1, -1) < 0) { + while (xiopoll(&readfd, 1, NULL) < 0) { if (errno != EINTR) break; } From 1dec094b3d302b223488940acdcf8576332f25a9 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Mon, 29 Sep 2008 21:23:07 +0200 Subject: [PATCH 53/75] test.sh options -n, -N: continue tests with number --- test.sh | 852 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 554 insertions(+), 298 deletions(-) diff --git a/test.sh b/test.sh index a534a89..7dfc800 100755 --- a/test.sh +++ b/test.sh @@ -12,10 +12,16 @@ #set -vx val_t=0.1 +NUMCOND=true +#NUMCOND="test \$N -gt 70" while [ "$1" ]; do case "X$1" in X-t?*) val_t="${1#-t}" ;; X-t) shift; val_t="$1" ;; + X-n?*) NUMCOND="test \$N -eq ${1#-t}" ;; + X-n) shift; NUMCOND="test \$N -eq $1" ;; + X-N?*) NUMCOND="test \$N -gt ${1#-t}" ;; + X-N) shift; NUMCOND="test \$N -ge $1" ;; *) break; esac shift @@ -23,6 +29,7 @@ done opt_t="-t $val_t" + #MICROS=100000 case "X$val_t" in X*.???????*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS:0:6}" ;; @@ -1479,6 +1486,7 @@ testecho () { local te="$td/test$N.stderr" local tdiff="$td/test$N.diff" local da="test$N $(date) $RANDOM" + if ! eval $NUMCOND; then :; else #local cmd="$SOCAT $opts $arg1 $arg2" #$ECHO "testing $title (test $N)... \c" $PRINTF "test $F_n %s... " $N "$title" @@ -1506,6 +1514,7 @@ testecho () { cat "$tdiff" numFAIL=$((numFAIL+1)) fi + fi # NUMCOND } # test if call to od and throughput of data works - with graceful shutdown and @@ -1522,6 +1531,7 @@ testod () { local tr="$td/test$N.ref" local tdiff="$td/test$N.diff" local dain="$(date) $RANDOM" + if ! eval $NUMCOND; then :; else echo "$dain" |$OD_C >"$tr" # local daout="$(echo "$dain" |$OD_C)" $PRINTF "test $F_n %s... " $num "$title" @@ -1543,6 +1553,7 @@ testod () { cat "$tdiff" numFAIL=$((numFAIL+1)) fi + fi # NUMCOND } # test if the socat executable has these address types compiled in @@ -2185,7 +2196,8 @@ NAME=EXECPTY case "$TESTS" in *%functions%*|*%exec%*|*%pty%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with pseudo terminal" -if ! testaddrs pty >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -2199,7 +2211,8 @@ NAME=SYSTEMPTY case "$TESTS" in *%functions%*|*%system%*|*%pty%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with pseudo terminal" -if ! testaddrs pty >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -2328,7 +2341,8 @@ NAME=RAWIP4SELF case "$TESTS" in *%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*) TEST="$NAME: simple echo via self receiving raw IPv4 protocol" -if ! feat=$(testaddrs ip4) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs rawip) >/dev/null; then @@ -2347,7 +2361,8 @@ NAME=RAWIPX4SELF case "$TESTS" in *%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*) TEST="$NAME: simple echo via self receiving raw IP protocol, v4 by target" -if ! feat=$(testaddrs ip4) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs rawip) >/dev/null; then @@ -2358,7 +2373,7 @@ elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "ip:127.0.0.1:$IPPROTO" "$opts" -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -2366,7 +2381,8 @@ NAME=RAWIP6SELF case "$TESTS" in *%functions%*|*%ip6%*|*%rawip%*|*%root%*|*%$NAME%*) TEST="$NAME: simple echo via self receiving raw IPv6 protocol" -if ! feat=$(testaddrs ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs rawip) || ! runsip6 >/dev/null; then @@ -2377,7 +2393,7 @@ elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "" "ip6:[::1]:$IPPROTO" "$opts" -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -2385,7 +2401,8 @@ NAME=RAWIPX6SELF case "$TESTS" in *%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%root%*|*%$NAME%*) TEST="$NAME: simple echo via self receiving raw IP protocol, v6 by target" -if ! feat=$(testaddrs ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs rawip) || ! runsip6 >/dev/null; then @@ -2405,7 +2422,8 @@ NAME=TCPSELF case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: echo via self connection of TCP IPv4 socket" -if [ "$UNAME" != Linux ]; then +if ! eval $NUMCOND; then :; +elif [ "$UNAME" != Linux ]; then #printf "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N numCANT=$((numCANT+1)) @@ -2419,6 +2437,7 @@ N=$((N+1)) NAME=UDPSELF +if ! eval $NUMCOND; then :; else case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: echo via self connection of UDP IPv4 socket" @@ -2429,6 +2448,7 @@ else testecho "$N" "$TEST" "" "udp:127.100.0.1:$PORT,sp=$PORT,bind=127.100.0.1" "$opts" fi esac + fi # NUMCOND PORT=$((PORT+1)) N=$((N+1)) @@ -2437,7 +2457,8 @@ NAME=UDP6SELF case "$TESTS" in *%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: echo via self connection of UDP IPv6 socket" -if [ "$UNAME" != Linux ]; then +if ! eval $NUMCOND; then :; +elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs udp ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2453,6 +2474,7 @@ N=$((N+1)) NAME=DUALUDPSELF +if ! eval $NUMCOND; then :; else case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: echo via two unidirectional UDP IPv4 sockets" @@ -2461,6 +2483,7 @@ p1=$PORT p2=$((PORT+1)) testecho "$N" "$TEST" "" "udp:127.0.0.1:$p2,sp=$p1!!udp:127.0.0.1:$p1,sp=$p2" "$opts" esac +fi # NUMCOND PORT=$((PORT+2)) N=$((N+1)) @@ -2471,6 +2494,7 @@ N=$((N+1)) NAME=UNIXSTREAM +if ! eval $NUMCOND; then :; else case "$TESTS" in *%functions%*|*%unix%*|*%$NAME%*) TEST="$NAME: echo via connection to UNIX domain socket" @@ -2503,10 +2527,12 @@ else fi kill $bg 2>/dev/null esac +fi # NUMCOND N=$((N+1)) NAME=TCP4 +if ! eval $NUMCOND; then :; else case "$TESTS" in *%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP V4 socket" @@ -2543,6 +2569,7 @@ kill $pid1 2>/dev/null wait ;; esac PORT=$((PORT+1)) +fi # NUMCOND N=$((N+1)) @@ -2550,7 +2577,8 @@ NAME=TCP6 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP V6 socket" -if ! testaddrs tcp ip6 >/dev/null || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -2593,7 +2621,8 @@ NAME=TCPX4 case "$TESTS" in *%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP socket, v4 by target" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2639,7 +2668,8 @@ NAME=TCPX6 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP socket, v6 by target" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2684,7 +2714,8 @@ NAME=IPV6ONLY0 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: option ipv6-v6only=0 listens on IPv4" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2732,7 +2763,8 @@ NAME=IPV6ONLY1 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: option ipv6-v6only=1 does not listen on IPv4" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2777,7 +2809,8 @@ NAME=ENV_LISTEN_4 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv4 preference on listen" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2825,7 +2858,8 @@ NAME=ENV_LISTEN_6 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv6 preference on listen" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2870,7 +2904,8 @@ NAME=LISTEN_OPTION_4 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: option -4 for IPv4 preference on listen" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2918,7 +2953,8 @@ NAME=LISTEN_OPTION_6 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: option -6 for IPv6 preference on listen" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -2964,7 +3000,8 @@ NAME=LISTEN_PF_IP4 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: pf=4 overrides option -6 on listen" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -3012,7 +3049,8 @@ NAME=LISTEN_PF_IP6 case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: pf=6 overrides option -4 on listen" -if ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -3048,7 +3086,7 @@ else numOK=$((numOK+1)) fi kill $pid 2>/dev/null -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3058,6 +3096,7 @@ NAME=UDP4STREAM case "$TESTS" in *%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%$NAME%*) TEST="$NAME: echo via connection to UDP V4 socket" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -3091,7 +3130,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -3101,7 +3141,8 @@ NAME=UDP6STREAM case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%udp%*|*%$NAME%*) TEST="$NAME: echo via connection to UDP V6 socket" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -3145,6 +3186,7 @@ NAME=GOPENFILE case "$TESTS" in *%functions%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: file opening with gopen" +if ! eval $NUMCOND; then :; else tf1="$td/test$N.1.stdout" tf2="$td/test$N.2.stdout" te="$td/test$N.stderr" @@ -3168,6 +3210,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi +fi # NUMCOND esac N=$((N+1)) @@ -3176,6 +3219,7 @@ NAME=GOPENPIPE case "$TESTS" in *%functions%*|*%gopen%*|*%pipe%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: pipe opening with gopen for reading" +if ! eval $NUMCOND; then :; else tp="$td/pipe$N" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3217,6 +3261,7 @@ else fi fi wait +fi # NUMCOND esac N=$((N+1)) @@ -3225,6 +3270,7 @@ NAME=GOPENUNIXSTREAM case "$TESTS" in *%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%$NAME%*) TEST="$NAME: GOPEN on UNIX stream socket" +if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3262,6 +3308,7 @@ else numOK=$((numOK+1)) fi # !(rc -ne 0) wait +fi # NUMCOND esac N=$((N+1)) @@ -3270,6 +3317,7 @@ NAME=GOPENUNIXDGRAM case "$TESTS" in *%functions%*|*%gopen%*|*%unix%*|*%dgram%*|*%$NAME%*) TEST="$NAME: GOPEN on UNIX datagram socket" +if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3307,6 +3355,7 @@ else fi # !(rc -ne 0) kill "$pids" 2>/dev/null wait +fi ;; # NUMCOND esac N=$((N+1)) @@ -3316,6 +3365,7 @@ NAME=IGNOREEOF case "$TESTS" in *%functions%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file" +if ! eval $NUMCOND; then :; else ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3340,6 +3390,7 @@ else numOK=$((numOK+1)) fi wait +fi ;; # NUMCOND esac N=$((N+1)) set +vx @@ -3349,6 +3400,7 @@ NAME=EXECIGNOREEOF case "$TESTS" in *%functions%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: exec against address with ignoreeof" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" CMD="$SOCAT $opts -lf /dev/null EXEC:$TRUE /dev/null,ignoreeof" @@ -3364,6 +3416,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -3372,7 +3425,8 @@ NAME=FAKEPTY case "$TESTS" in *%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: generation of pty for other processes" -if ! testaddrs pty >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -3408,7 +3462,7 @@ else fi kill $pid 2>/dev/null wait -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -3417,6 +3471,7 @@ NAME=O_TRUNC case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: option o-trunc" +if ! eval $NUMCOND; then :; else ff="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3437,6 +3492,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -3445,6 +3501,7 @@ NAME=FTRUNCATE case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: option ftruncate" +if ! eval $NUMCOND; then :; else ff="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3465,6 +3522,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -3481,6 +3539,7 @@ N=$((N+1)) NAME=CHILDDEFAULT case "$TESTS" in *%functions%*|*%$NAME%*) +if ! eval $NUMCOND; then :; else TEST="$NAME: child process default properties" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3503,6 +3562,7 @@ else $PRINTF "$OK\n" numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -3511,6 +3571,7 @@ NAME=CHILDSETSID case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: child process with setsid" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" CMD="$SOCAT $opts -u exec:$PROCAN,setsid -" @@ -3533,6 +3594,7 @@ else $PRINTF "$OK\n" numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -3541,6 +3603,7 @@ NAME=MAINSETSID case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: main process with setsid" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" CMD="$SOCAT $opts -U -,setsid exec:$PROCAN" @@ -3563,6 +3626,7 @@ else $PRINTF "$OK\n" numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -3571,7 +3635,8 @@ NAME=OPENSSL_TCP4 case "$TESTS" in *%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: openssl connect" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! type openssl >/dev/null 2>&1; then @@ -3610,7 +3675,7 @@ else fi kill $pid 2>/dev/null wait -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3620,7 +3685,8 @@ NAME=OPENSSLLISTEN_TCP4 case "$TESTS" in *%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: openssl listen" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -3654,7 +3720,7 @@ else fi kill $pid 2>/dev/null wait -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3663,7 +3729,8 @@ NAME=OPENSSLLISTEN_TCP6 case "$TESTS" in *%functions%*|*%openssl%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: openssl listen" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -3697,7 +3764,7 @@ else fi kill $pid 2>/dev/null wait -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3709,7 +3776,8 @@ case "$TESTS" in TEST="$NAME: openssl half close" # have an SSL server that executes "$OD_C" and see if EOF on the SSL client # brings the result of od to the client -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -3743,7 +3811,7 @@ else fi kill $pid 2>/dev/null wait -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3753,7 +3821,8 @@ NAME=OPENSSL_SERVERAUTH case "$TESTS" in *%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: openssl server authentication" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -3788,7 +3857,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3797,7 +3866,8 @@ NAME=OPENSSL_CLIENTAUTH case "$TESTS" in *%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: openssl client authentication" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -3832,7 +3902,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3841,7 +3911,8 @@ NAME=OPENSSL_FIPS_BOTHAUTH case "$TESTS" in *%functions%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: OpenSSL+FIPS client and server authentication" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -3879,7 +3950,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3889,7 +3960,8 @@ NAME=SOCKS4CONNECT_TCP4 case "$TESTS" in *%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: socks4 connect over TCP/IPv4" -if ! testaddrs socks4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs socks4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -3923,7 +3995,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3932,7 +4004,8 @@ NAME=SOCKS4CONNECT_TCP6 case "$TESTS" in *%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: socks4 connect over TCP/IPv6" -if ! testaddrs socks4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs socks4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -3966,7 +4039,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -3976,7 +4049,8 @@ NAME=SOCKS4ACONNECT_TCP4 case "$TESTS" in *%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: socks4a connect over TCP/IPv4" -if ! testaddrs socks4a >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs socks4a >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -4010,7 +4084,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -4019,7 +4093,8 @@ NAME=SOCKS4ACONNECT_TCP6 case "$TESTS" in *%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: socks4a connect over TCP/IPv6" -if ! testaddrs socks4a >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs socks4a >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -4053,7 +4128,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -4063,7 +4138,8 @@ NAME=PROXYCONNECT_TCP4 case "$TESTS" in *%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: proxy connect over TCP/IPv4" -if ! testaddrs proxy >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -4098,7 +4174,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -4107,7 +4183,8 @@ NAME=PROXYCONNECT_TCP6 case "$TESTS" in *%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: proxy connect over TCP/IPv6" -if ! testaddrs proxy >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then @@ -4142,7 +4219,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -4152,6 +4229,7 @@ NAME=TCP4NOFORK case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: echo via connection to TCP V4 socket with nofork'ed exec" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -4182,6 +4260,7 @@ else if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -4215,6 +4294,7 @@ N=$((N+1)) #============================================================================== #TEST="$NAME: echo via 'connection' to UDP V4 socket" +#if ! eval $NUMCOND; then :; else #tf="$td/file$N" #tsl=65534 #ts="127.0.0.1:$tsl" @@ -4229,9 +4309,11 @@ N=$((N+1)) # $ECHO "*** test $N $FAILED" # numFAIL=$((numFAIL+1)) #fi +#fi ;; # NUMCOND #N=$((N+1)) #============================================================================== # TEST 4 - simple echo via new file +#if ! eval $NUMCOND; then :; else #N=4 #tf="$td/file$N" #tp="$td/pipe$N" @@ -4245,6 +4327,7 @@ N=$((N+1)) # $ECHO "*** test $N $FAILED" # numFAIL=$((numFAIL+1)) #fi +#fi ;; # NUMCOND #============================================================================== @@ -4252,9 +4335,7 @@ NAME=TOTALTIMEOUT case "$TESTS" in *%functions%*|*%timeout%*|*%$NAME%*) TEST="$NAME: socat inactivity timeout" -if ! true; then - : -else +if ! eval $NUMCOND; then :; else #set -vx tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -4283,7 +4364,7 @@ fi kill $pid 2>/dev/null wait #set +vx -fi # feats +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -4293,9 +4374,7 @@ NAME=IGNOREEOF+TOTALTIMEOUT case "$TESTS" in *%functions%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof and inactivity timeout" -if ! true; then - : -else +if ! eval $NUMCOND; then :; else #set -vx ti="$td/test$N.file" tf="$td/test$N.stdout" @@ -4307,9 +4386,9 @@ printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! # background process id -sleep 1 +psleep 0.5 echo "$da" >>"$ti" -sleep 4 +sleep 3 echo X >>"$ti" sleep 1 kill $bg 2>/dev/null @@ -4325,7 +4404,7 @@ else numOK=$((numOK+1)) fi wait -fi # feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4334,7 +4413,8 @@ NAME=PROXY2SPACES case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: proxy connect accepts status with multiple spaces" -if ! testaddrs proxy >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -4366,7 +4446,7 @@ else fi kill $pid 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -4376,6 +4456,7 @@ NAME=BUG-UNISTDIO case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: for bug with address options on both stdin/out in unidirectional mode" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" ff="$td/file$N" @@ -4398,6 +4479,7 @@ else numCANT=$((numCANT+1)) fi fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -4422,12 +4504,13 @@ NAME=SINGLEEXECOUTPTY case "$TESTS" in *%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: inheritance of stdout to single exec with pty" -if ! testaddrs pty >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1 -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4451,12 +4534,13 @@ NAME=SINGLEEXECINPTYDELAY case "$TESTS" in *%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with pty, with delay" -if ! testaddrs pty >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4464,12 +4548,13 @@ NAME=SINGLEEXECINPTY case "$TESTS" in *%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with pty" -if ! testaddrs pty >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4479,7 +4564,8 @@ NAME=READLINE case "$TESTS" in *%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: readline with password and sigint" -if ! feat=$(testaddrs readline pty); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs readline pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -4571,7 +4657,7 @@ kill $pid 2>/dev/null # necc on OpenBSD wait MICROS=$SAVEMICS TERM="$SAVETERM" -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -4581,6 +4667,7 @@ NAME=GENDERCHANGER case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: TCP4 \"gender changer\"" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -4620,6 +4707,7 @@ else fi kill $pid1 $pid2 $pid3 $pid4 2>/dev/null wait +fi ;; # NUMCOND esac PORT=$((PORT+3)) N=$((N+1)) @@ -4632,7 +4720,8 @@ NAME=OUTBOUNDIN case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot" -if ! feat=$(testaddrs openssl proxy); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs openssl proxy); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -4697,7 +4786,7 @@ else fi kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null wait -fi # feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+5)) N=$((N+1)) @@ -4716,7 +4805,8 @@ NAME=INTRANETRIPPER case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, daemons" -if ! feat=$(testaddrs openssl proxy); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs openssl proxy); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -4808,7 +4898,7 @@ else fi kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null wait -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+5)) N=$((N+1)) @@ -4966,13 +5056,14 @@ NAME=TCP4RANGEBITS case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" -if [ -z "$SECONDADDR" ]; then +if ! eval $NUMCOND; then :; +elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 -fi ;; # $SECONDADDR +fi ;; # $SECONDADDR, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -4981,13 +5072,14 @@ NAME=TCP4RANGEMASK case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" -if [ -z "$SECONDADDR" ]; then +if ! eval $NUMCOND; then :; +elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR:255.255.255.255" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 -fi ;; # $SECONDADDR +fi ;; # $SECONDADDR, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -4997,13 +5089,14 @@ NAME=TCP4RANGEMASKHAIRY case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" -if [ "$UNAME" != Linux ]; then +if ! eval $NUMCOND; then :; +elif [ "$UNAME" != Linux ]; then # we need access to more loopback addresses $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=127.0.0.0:255.255.0.0" "tcp4:127.1.0.0:$PORT" 4 tcp $PORT 0 -fi ;; # Linux +fi ;; # Linux, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -5013,7 +5106,9 @@ NAME=TCP4SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with SOURCEPORT option" +if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -5022,7 +5117,9 @@ NAME=TCP4LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with LOWPORT option" +if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "lowport" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -5031,7 +5128,8 @@ NAME=TCP4WRAPPERS_ADDR case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with TCPWRAP option" -if ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5040,7 +5138,7 @@ hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5049,7 +5147,8 @@ NAME=TCP4WRAPPERS_NAME case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with TCPWRAP option" -if ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5058,7 +5157,7 @@ hd="$td/hosts.deny" $ECHO "socat: $LOCALHOST" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "tcp4:$SECONDADDR:$PORT" 4 tcp $PORT 0 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5068,12 +5167,13 @@ NAME=TCP6RANGE case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with RANGE option" -if ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp6-l:$PORT,reuseaddr,fork,retry=1" "" "range=[::2/128]" "tcp6:[::1]:$PORT" 6 tcp $PORT 0 -fi # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5082,12 +5182,13 @@ NAME=TCP6SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with SOURCEPORT option" -if ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp6-l:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "tcp6:[::1]:$PORT" 6 tcp $PORT 0 -fi # ! feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5096,12 +5197,13 @@ NAME=TCP6LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with LOWPORT option" -if ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "tcp6-l:$PORT,reuseaddr,fork,retry=1" "" "lowport" "tcp6:[::1]:$PORT" 6 tcp $PORT 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5110,7 +5212,8 @@ NAME=TCP6TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with TCPWRAP option" -if ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5119,8 +5222,7 @@ hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "tcp6-l:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "tcp6:[::1]:$PORT" 6 tcp $PORT 0 -fi # ! feat -;; +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5130,8 +5232,10 @@ NAME=UDP4RANGE case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP4-L with RANGE option" +if ! eval $NUMCOND; then :; else #testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -5140,7 +5244,9 @@ NAME=UDP4SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP4-L with SOURCEPORT option" +if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr" "" "sp=$PORT" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -5149,7 +5255,9 @@ NAME=UDP4LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP4-L with LOWPORT option" +if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr" "" "lowport" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -5158,7 +5266,8 @@ NAME=UDP4TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP4-L with TCPWRAP option" -if ! feat=$(testaddrs udp ip4 libwrap) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5167,7 +5276,7 @@ hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "udp4-l:$PORT,reuseaddr,retry=1" "" "tcpwrap-etc=$td" "udp4:127.0.0.1:$PORT" 4 udp $PORT 0 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5177,13 +5286,14 @@ NAME=UDP6RANGE case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP6-L with RANGE option" -if ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else #testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr,fork" "" "range=[::2/128]" "udp6:[::1]:$PORT" 6 udp $PORT 0 testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr" "" "range=[::2/128]" "udp6:[::1]:$PORT" 6 udp $PORT 0 -fi # ! feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5192,12 +5302,13 @@ NAME=UDP6SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP6-L with SOURCEPORT option" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr" "" "sp=$PORT" "udp6:[::1]:$PORT" 6 udp $PORT 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5206,12 +5317,13 @@ NAME=UDP6LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP6-L with LOWPORT option" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr" "" "lowport" "udp6:[::1]:$PORT" 6 udp $PORT 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5220,7 +5332,8 @@ NAME=UDP6TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP6-L with TCPWRAP option" -if ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5229,7 +5342,7 @@ hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "udp6-l:$PORT,reuseaddr" "" "lowport" "udp6:[::1]:$PORT" 6 udp $PORT 0 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5239,13 +5352,14 @@ NAME=OPENSSLTCP4_RANGE case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv4 with RANGE option" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "range=$SECONDADDR/32" "ssl:127.0.0.1:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5254,13 +5368,14 @@ NAME=OPENSSLTCP4_SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of SSL-L with SOURCEPORT option" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "sp=$PORT" "ssl:127.0.0.1:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5269,13 +5384,14 @@ NAME=OPENSSLTCP4_LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of SSL-L with LOWPORT option" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "lowport" "ssl:127.0.0.1:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5284,7 +5400,8 @@ NAME=OPENSSLTCP4_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of SSL-L with TCPWRAP option" -if ! feat=$(testaddrs ip4 tcp libwrap openssl); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 tcp libwrap openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5294,7 +5411,7 @@ hd="$td/hosts.deny" $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "tcpwrap-etc=$td" "ssl:127.0.0.1:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5303,14 +5420,15 @@ NAME=OPENSSLCERTSERVER case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%$NAME%*) TEST="$NAME: security of SSL-L with client certificate" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify,cert=testsrv.crt,key=testsrv.key" "cafile=testcli.crt" "cafile=testsrv.crt" "ssl:127.0.0.1:$PORT,cafile=testsrv.crt,cert=testcli.pem,$SOCAT_EGD" 4 tcp $PORT -1 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5319,14 +5437,15 @@ NAME=OPENSSLCERTCLIENT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%$NAME%*) TEST="$NAME: security of SSL with server certificate" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else gentestcert testsrv gentestcert testcli testserversec "$N" "$TEST" "$opts -s -lu -d" "ssl:$LOCALHOST:$PORT,pf=ip4,fork,retry=2,verify,cert=testcli.pem,$SOCAT_EGD" "cafile=testsrv.crt" "cafile=testcli.crt" "ssl-l:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cafile=testcli.crt,cert=testsrv.crt,key=testsrv.key" 4 tcp "" -1 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5336,7 +5455,8 @@ NAME=OPENSSLTCP6_RANGE case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with RANGE option" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then @@ -5345,7 +5465,7 @@ elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "range=[::2/128]" "ssl:[::1]:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 6 tcp $PORT -1 -fi # ! feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5354,7 +5474,8 @@ NAME=OPENSSLTCP6_SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with SOURCEPORT option" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then @@ -5363,7 +5484,7 @@ elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "sp=$PORT" "ssl:[::1]:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 6 tcp $PORT -1 -fi # ! feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5372,7 +5493,8 @@ NAME=OPENSSLTCP6_LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with LOWPORT option" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then @@ -5381,7 +5503,7 @@ elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then else gentestcert testsrv testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "lowport" "ssl:[::1]:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 6 tcp $PORT -1 -fi # ! feats +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5390,7 +5512,8 @@ NAME=OPENSSLTCP6_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with TCPWRAP option" -if ! feat=$(testaddrs ip6 tcp libwrap openssl) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6 tcp libwrap openssl) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5400,7 +5523,7 @@ hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "ssl-l:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "tcpwrap-etc=$td" "ssl:[::1]:$PORT,cafile=testsrv.crt,$SOCAT_EGD" 6 tcp $PORT -1 -fi # ! feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -5410,7 +5533,8 @@ NAME=OPENSSL_FIPS_SECURITY case "$TESTS" in *%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) TEST="$NAME: OpenSSL restrictions by FIPS" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! testaddrs listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then @@ -5424,7 +5548,7 @@ gentestcert testsrv gentestcert testcli # openssl client accepts a "normal" certificate only when not in fips mode testserversec "$N" "$TEST" "$opts -s" "ssl:$LOCALHOST:$PORT,fork,retry=2,verify,cafile=testsrv.crt" "" "fips" "ssl-l:$PORT,pf=ip4,reuseaddr,cert=testsrv.crt,key=testsrv.key" 4 tcp "" -1 -fi ;; # testaddrs +fi ;; # testaddrs, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -5452,6 +5576,7 @@ NAME=FILANDIR case "$TESTS" in *%filan%*|*%$NAME%*) TEST="$NAME: check type printed for directories" +if ! eval $NUMCOND; then :; else te="$td/test$N.stderr" printf "test $F_n $TEST... " $N type=$($FILAN -f . 2>$te |tail -n 1 |awk '{print($2);}') @@ -5463,6 +5588,7 @@ else cat "$te" numFAIL=$((numFAIL+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -5471,6 +5597,7 @@ NAME=FILANSOCKET case "$TESTS" in *%filan%*|*%$NAME%*) TEST="$NAME: capability to analyze named unix socket" +if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" te1="$td/test$N.stderr1" # socat te2="$td/test$N.stderr2" # filan @@ -5490,7 +5617,7 @@ else fi kill $spid 2>/dev/null wait -;; +fi ;; # NUMCOND esac N=$((N+1)) @@ -5546,6 +5673,7 @@ PTYTYPE=ptmx case "$TESTS" in *%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection" +if ! eval $NUMCOND; then :; else if ! feat=$(testaddrs pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) @@ -5555,6 +5683,7 @@ elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then else testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -5563,7 +5692,8 @@ PTYTYPE=openpty case "$TESTS" in *%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection" -if ! feat=$(testaddrs pty); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then @@ -5571,7 +5701,7 @@ elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then numCANT=$((numCANT+1)) else testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -5580,7 +5710,8 @@ NAME=CONNECTTIMEOUT case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: test the connect-timeout option" -if ! feat=$(testaddrs tcp); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif ! feat=$(testoptions connect-timeout); then @@ -5623,7 +5754,7 @@ else fi fi wait -fi ;; # testaddrs +fi ;; # testaddrs, NUMCOND esac N=$((N+1)) @@ -5632,7 +5763,8 @@ NAME=OPENSSLLISTENDSA case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: openssl listen with DSA certificate" -if ! testaddrs openssl >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5664,7 +5796,7 @@ else fi kill $pid 2>/dev/null wait -fi ;; # testaddrs +fi ;; # testaddrs, NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -5693,7 +5825,8 @@ NAME=EXITCODESIG$signam case "$TESTS" in *%functions%*|*%pty%*|*%$NAME%*) TEST="$NAME: exit status when dying on SIG$signam" -if ! feat=$(testaddrs pty); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr a-z A-Z) not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5725,7 +5858,7 @@ else numFAIL=$((numFAIL+1)) fi wait -fi ;; # feat +fi ;; # NUMCOND, feats esac N=$((N+1)) done @@ -5736,7 +5869,8 @@ NAME=READBYTES case "$TESTS" in *%functions%*|*%$NAME%*) TEST="$NAME: restrict reading from file with bytes option" -if false; then +if ! eval $NUMCOND; then :; +elif false; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -5768,7 +5902,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -5777,9 +5911,7 @@ NAME=UNIXLISTENFORK case "$TESTS" in *%functions%*|*%unix%*|*%listen%*|*%fork%*|*%$NAME%*) TEST="$NAME: UNIX socket keeps listening after child died" -if false; then - : -else +if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -5826,7 +5958,7 @@ else fi # !( $? -ne 0) fi # !(rc -ne 0) wait -fi # true +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -5835,9 +5967,7 @@ NAME=UNIXTOSTREAM case "$TESTS" in *%functions%*|*%unix%*|*%listen%*|*%$NAME%*) TEST="$NAME: generic UNIX client connects to stream socket" -if false; then - : -else +if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -5869,8 +5999,7 @@ else numOK=$((numOK+1)) fi # !(rc -ne 0) wait -fi # true -wait +fi ;; # NUMCOND esac N=$((N+1)) @@ -5879,9 +6008,7 @@ NAME=UNIXTODGRAM case "$TESTS" in *%functions%*|*%unix%*|*%recv%*|*%$NAME%*) TEST="$NAME: generic UNIX client connects to datagram socket" -if false; then - : -else +if ! eval $NUMCOND; then :; else ts1="$td/test$N.socket1" ts2="$td/test$N.socket2" tf="$td/test$N.stdout" @@ -5920,7 +6047,7 @@ else numOK=$((numOK+1)) fi # !(rc -ne 0) wait -fi # true +fi ;; # NUMCOND esac N=$((N+1)) @@ -5969,6 +6096,7 @@ NAME=FULLPARSE case "$TESTS" in *%functions%*|*%parse%*|*%$NAME%*) TEST="$NAME: correctly parse special chars" +if ! eval $NUMCOND; then :; else $PRINTF "test $F_n $TEST... " $N tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -5996,6 +6124,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -6020,7 +6149,8 @@ NAME=TCP6BYTCP4 case "$TESTS" in *%functions%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%$NAME%*) TEST="$NAME: TCP4 mapped into TCP6 address space" -if ! testaddrs tcp ip6 >/dev/null || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6054,7 +6184,7 @@ else numOK=$((numOK+1)) fi kill $pid 2>/dev/null; wait -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6067,6 +6197,7 @@ case "$TESTS" in TEST="$NAME: UDP/IPv4 sendto and recvfrom" # start a UDP4-RECVFROM process that echoes data, and send test data using # UDP4-SENDTO. The sent data should be returned. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -6104,7 +6235,9 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi # NUMCOND + ;; esac PORT=$((PORT+1)) N=$((N+1)) @@ -6114,7 +6247,8 @@ NAME=UDP6DGRAM case "$TESTS" in *%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%$NAME%*) TEST="$NAME: UDP/IPv6 datagram" -if ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6149,7 +6283,7 @@ else if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi numOK=$((numOK+1)) fi -fi ;; # ! feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6159,7 +6293,8 @@ NAME=RAWIP4RECVFROM case "$TESTS" in *%functions%*|*%ip%*|*%ip4%*|*%rawip%*|*%rawip4%*|*%dgram%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv4 datagram" -if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then +if ! eval $NUMCOND; then :; +elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6197,7 +6332,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi # must be root;; +fi ;; # root, NUMCOND esac N=$((N+1)) @@ -6207,7 +6342,8 @@ NAME=RAWIP6RECVFROM case "$TESTS" in *%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%dgram%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv6 datagram by self addressing" -if ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6244,7 +6380,7 @@ else if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi -fi # must be root ;; +fi ;; # root, NUMCOND esac N=$((N+1)) fi #false @@ -6254,6 +6390,7 @@ NAME=UNIXDGRAM case "$TESTS" in *%functions%*|*%unix%*|*%dgram%*|*%$NAME%*) TEST="$NAME: UNIX datagram" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -6284,7 +6421,9 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi # NUMCOND + ;; esac N=$((N+1)) @@ -6293,6 +6432,7 @@ NAME=UDP4RECV case "$TESTS" in *%functions%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 receive" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -6330,7 +6470,9 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi # NUMCOND + ;; esac N=$((N+1)) @@ -6339,7 +6481,8 @@ NAME=UDP6RECV case "$TESTS" in *%functions%*|*%ip6%*|*%dgram%*|*%udp%*|*%udp6%*|*%recv%*|*%$NAME%*) TEST="$NAME: UDP/IPv6 receive" -if ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6377,7 +6520,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # ! feat +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -6386,7 +6529,8 @@ NAME=RAWIP4RECV case "$TESTS" in *%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv4 receive" -if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then +if ! eval $NUMCOND; then :; +elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6424,7 +6568,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi # must be root ;; +fi ;; # NUMCOND, root esac N=$((N+1)) @@ -6433,7 +6577,8 @@ NAME=RAWIP6RECV case "$TESTS" in *%functions%*|*%ip6%*|*%dgram%*|*%rawip%*|*%rawip6%*|*%recv%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv6 receive" -if ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6473,7 +6618,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi # must be root ;; +fi ;; # NUMCOND, root esac N=$((N+1)) @@ -6482,6 +6627,7 @@ NAME=UNIXRECV case "$TESTS" in *%functions%*|*%unix%*|*%dgram%*|*%recv%*|*%$NAME%*) TEST="$NAME: UNIX receive" +if ! eval $NUMCOND; then :; else ts="$td/test$N.socket" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -6513,7 +6659,9 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi # NUMCOND + ;; esac N=$((N+1)) @@ -6522,12 +6670,13 @@ NAME=UDP4RECVFROM_SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECVFROM with SOURCEPORT option" -if ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr" "" "sp=$PORT" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6536,12 +6685,13 @@ NAME=UDP4RECVFROM_LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECVFROM with LOWPORT option" -if ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr" "" "lowport" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6551,7 +6701,9 @@ case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECVFROM with RANGE option" #testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 +if ! eval $NUMCOND; then :; else testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -6560,7 +6712,8 @@ NAME=UDP4RECVFROM_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECVFROM with TCPWRAP option" -if ! feat=$(testaddrs ip4 udp libwrap) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 udp libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6570,7 +6723,7 @@ $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" #testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr,fork" "" "tcpwrap=$d" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 testserversec "$N" "$TEST" "$opts -s" "udp4-recvfrom:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "udp4-sendto:127.0.0.1:$PORT" 4 udp $PORT 0 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6580,7 +6733,8 @@ NAME=UDP4RECV_SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECV with SOURCEPORT option" -if ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6590,7 +6744,7 @@ PORT3=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp4-recv:$PORT1,reuseaddr!!udp4-sendto:127.0.0.1:$PORT2" "" "sp=$PORT3" "udp4-recv:$PORT2!!udp4-sendto:127.0.0.1:$PORT1" 4 udp $PORT1 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6599,7 +6753,8 @@ NAME=UDP4RECV_LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECV with LOWPORT option" -if ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6608,7 +6763,7 @@ PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp4-recv:$PORT1,reuseaddr!!udp4-sendto:127.0.0.1:$PORT2" "" "lowport" "udp4-recv:$PORT2!!udp4-sendto:127.0.0.1:$PORT1" 4 udp $PORT1 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6617,7 +6772,8 @@ NAME=UDP4RECV_RANGE case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECV with RANGE option" -if ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6626,7 +6782,7 @@ PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp4-recv:$PORT1,reuseaddr!!udp4-sendto:127.0.0.1:$PORT2" "" "range=$SECONDADDR/32" "udp4-recv:$PORT2!!udp4-sendto:127.0.0.1:$PORT1" 4 udp $PORT1 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6635,7 +6791,8 @@ NAME=UDP4RECV_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP4-RECV with TCPWRAP option" -if ! feat=$(testaddrs udp ip4 libwrap) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6648,7 +6805,7 @@ $ECHO "ALL: ALL" >"$hd" # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp4-recv:$PORT1,reuseaddr!!udp4-sendto:127.0.0.1:$PORT2" "" "tcpwrap-etc=$td" "udp4-recv:$PORT2!!udp4-sendto:127.0.0.1:$PORT1" 4 udp $PORT1 0 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6658,12 +6815,13 @@ NAME=UDP6RECVFROM_SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECVFROM with SOURCEPORT option" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr" "" "sp=$PORT" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6672,12 +6830,13 @@ NAME=UDP6RECVFROM_LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECVFROM with LOWPORT option" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr" "" "lowport" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6686,13 +6845,14 @@ NAME=UDP6RECVFROM_RANGE case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECVFROM with RANGE option" -if ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else #testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr,fork" "" "range=[::2/128]" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr" "" "range=[::2/128]" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 -fi # ! feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6701,7 +6861,8 @@ NAME=UDP6RECVFROM_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECVFROM with TCPWRAP option" -if ! feat=$(testaddrs udp ip6 libwrap) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6710,7 +6871,7 @@ hd="$td/hosts.deny" $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" testserversec "$N" "$TEST" "$opts -s" "udp6-recvfrom:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "udp6-sendto:[::1]:$PORT" 6 udp $PORT 0 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6720,7 +6881,8 @@ NAME=UDP6RECV_SOURCEPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECV with SOURCEPORT option" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6730,7 +6892,7 @@ PORT3=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp6-recv:$PORT1,reuseaddr!!udp6-sendto:[::1]:$PORT2" "" "sp=$PORT3" "udp6-recv:$PORT2!!udp6-sendto:[::1]:$PORT1" 6 udp $PORT1 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6739,7 +6901,8 @@ NAME=UDP6RECV_LOWPORT case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECV with LOWPORT option" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6748,7 +6911,7 @@ PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp6-recv:$PORT1,reuseaddr!!udp6-sendto:[::1]:$PORT2" "" "lowport" "udp6-recv:$PORT2!!udp6-sendto:[::1]:$PORT1" 6 udp $PORT1 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6757,7 +6920,8 @@ NAME=UDP6RECV_RANGE case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECV with RANGE option" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6766,7 +6930,7 @@ PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp6-recv:$PORT1,reuseaddr!!udp6-sendto:[::1]:$PORT2" "" "range=[::2/128]" "udp6-recv:$PORT2!!udp6-sendto:[::1]:$PORT1" 6 udp $PORT1 0 -fi +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6775,7 +6939,8 @@ NAME=UDP6RECV_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: security of UDP6-RECV with TCPWRAP option" -if ! feat=$(testaddrs udp ip6 libwrap) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -6788,7 +6953,7 @@ PORT2=$PORT # we use the forward channel (PORT1) for testing, and have a backward channel # (PORT2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "udp6-recv:$PORT1,reuseaddr!!udp6-sendto:[::1]:$PORT2" "" "tcpwrap-etc=$td" "udp6-recv:$PORT2!!udp6-sendto:[::1]:$PORT1" 6 udp $PORT1 0 -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -6798,7 +6963,8 @@ NAME=IP4RECVFROM_RANGE case "$TESTS" in *%functions%*|*%security%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP4-RECVFROM with RANGE option" -if ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6807,7 +6973,7 @@ elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then else #testserversec "$N" "$TEST" "$opts -s" "ip4-recvfrom:$PROTO,reuseaddr,fork" "" "range=$SECONDADDR/32" "ip4-sendto:127.0.0.1:$PROTO" 4 ip $PROTO 0 testserversec "$N" "$TEST" "$opts -s" "ip4-recvfrom:$PROTO,reuseaddr!!udp4-sendto:127.0.0.1:$PORT" "" "range=$SECONDADDR/32" "udp4-recv:$PORT!!ip4-sendto:127.0.0.1:$PROTO" 4 ip $PROTO 0 -fi # not feats, not root +fi ;; # NUMCOND, feats, root esac PROTO=$((PROTO+1)) PORT=$((PORT+1)) @@ -6817,7 +6983,8 @@ NAME=IP4RECVFROM_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP4-RECVFROM with TCPWRAP option" -if ! feat=$(testaddrs ip4 rawip libwrap) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 rawip libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6830,7 +6997,8 @@ $ECHO "socat: $SECONDADDR" >"$ha" $ECHO "ALL: ALL" >"$hd" #testserversec "$N" "$TEST" "$opts -s" "ip4-recvfrom:$PROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "ip4-sendto:127.0.0.1:$PROTO" 4 ip $PROTO 0 testserversec "$N" "$TEST" "$opts -s" "ip4-recvfrom:$PROTO,reuseaddr!!udp4-sendto:127.0.0.1:$PORT" "" "tcpwrap-etc=$td" "udp4-recv:$PORT!!ip4-sendto:127.0.0.1:$PROTO" 4 ip $PROTO 0 -fi # not feats, not root +fi # NUMCOND, feats, root + ;; esac PROTO=$((PROTO+1)) PORT=$((PORT+1)) @@ -6841,7 +7009,8 @@ NAME=IP4RECV_RANGE case "$TESTS" in *%functions%*|*%security%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP4-RECV with RANGE option" -if ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6853,7 +7022,7 @@ PROTO2=$PROTO # we use the forward channel (PROTO1) for testing, and have a backward channel # (PROTO2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "ip4-recv:$PROTO1,reuseaddr!!ip4-sendto:127.0.0.1:$PROTO2" "" "range=$SECONDADDR/32" "ip4-recv:$PROTO2!!ip4-sendto:127.0.0.1:$PROTO1" 4 ip $PROTO1 0 -fi # not feats, not root +fi ;; # NUMCOND, feats, root esac PROTO=$((PROTO+1)) N=$((N+1)) @@ -6864,7 +7033,8 @@ NAME=IP4RECV_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP4-RECV with TCPWRAP option" -if ! feat=$(testaddrs ip4 rawip libwrap) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 rawip libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6880,7 +7050,7 @@ $ECHO "ALL: ALL" >"$hd" # we use the forward channel (PROTO1) for testing, and have a backward channel # (PROTO2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "ip4-recv:$PROTO1,reuseaddr!!ip4-sendto:127.0.0.1:$PROTO2" "" "tcpwrap-etc=$td" "ip4-recv:$PROTO2!!ip4-sendto:127.0.0.1:$PROTO1" 4 ip $PROTO1 0 -fi # not feats, not root +fi ;; # NUMCOND, feats, root esac PROTO=$((PROTO+1)) N=$((N+1)) @@ -6890,7 +7060,8 @@ NAME=IP6RECVFROM_RANGE case "$TESTS" in *%functions%*|*%security%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP6-RECVFROM with RANGE option" -if ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6899,7 +7070,7 @@ elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then else #testserversec "$N" "$TEST" "$opts -s" "ip6-recvfrom:$PROTO,reuseaddr,fork" "" "range=[::2/128]" "ip6-sendto:[::1]:$PROTO" 6 ip $PROTO 0 testserversec "$N" "$TEST" "$opts -s" "ip6-recvfrom:$PROTO,reuseaddr!!udp6-sendto:[::1]:$PORT" "" "range=[::2/128]" "udp6-recv:$PORT!!ip6-sendto:[::1]:$PROTO" 6 ip $PROTO 0 -fi # not feats, not root +fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) PORT=$((PORT+1)) @@ -6909,7 +7080,8 @@ NAME=IP6RECVFROM_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP6-RECVFROM with TCPWRAP option" -if ! feat=$(testaddrs ip6 rawip libwrap) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6 rawip libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6922,7 +7094,7 @@ $ECHO "socat: [::2]" >"$ha" $ECHO "ALL: ALL" >"$hd" #testserversec "$N" "$TEST" "$opts -s" "ip6-recvfrom:$PROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "ip6-sendto:[::1]:$PROTO" 6 ip $PROTO 0 testserversec "$N" "$TEST" "$opts -s" "ip6-recvfrom:$PROTO,reuseaddr!!udp6-sendto:[::1]:$PORT" "" "tcpwrap-etc=$td" "udp6-recv:$PORT!!ip6-sendto:[::1]:$PROTO" 6 ip $PROTO 0 -fi # not feats, not root +fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) PORT=$((PORT+1)) @@ -6933,7 +7105,8 @@ NAME=IP6RECV_RANGE case "$TESTS" in *%functions%*|*%security%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP6-RECV with RANGE option" -if ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}raw IP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6945,7 +7118,7 @@ PROTO2=$PROTO # we use the forward channel (PROTO1) for testing, and have a backward channel # (PROTO2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "ip6-recv:$PROTO1,reuseaddr!!ip6-sendto:[::1]:$PROTO2" "" "range=[::2/128]" "ip6-recv:$PROTO2!!ip6-sendto:[::1]:$PROTO1" 6 ip $PROTO1 0 -fi # not feats, not root +fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) @@ -6954,7 +7127,8 @@ NAME=IP6RECV_TCPWRAP case "$TESTS" in *%functions%*|*%security%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*) TEST="$NAME: security of IP6-RECV with TCPWRAP option" -if ! feat=$(testaddrs ip6 rawip libwrap) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6 rawip libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -6970,7 +7144,7 @@ $ECHO "ALL: ALL" >"$hd" # we use the forward channel (PROTO1) for testing, and have a backward channel # (PROTO2) to get the data back, so we get the classical echo behaviour testserversec "$N" "$TEST" "$opts -s" "ip6-recv:$PROTO1,reuseaddr!!ip6-sendto:[::1]:$PROTO2" "" "tcpwrap-etc=$td" "ip6-recv:$PROTO2!!ip6-sendto:[::1]:$PROTO1" 6 ip $PROTO1 0 -fi # not feats, not root +fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) @@ -6984,7 +7158,8 @@ TEST="$NAME: option O_NOATIME on file" # without this option (using touch); one second later read from the first file. # Then we check which file has the later ATIME stamp. For this check we use # "ls -ltu" because it is more portable than "test ... -nt ..." -if ! testoptions o-noatime >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testoptions o-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7021,7 +7196,7 @@ else numOK=$((numOK+1)) fi # wrong time stamps fi # command ok -fi ;; # not feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -7033,7 +7208,8 @@ TEST="$NAME: option O_NOATIME on file descriptor" # without this option (using touch); one second later read from the first file. # Then we check which file has the later ATIME stamp. For this check we use # "ls -ltu" because it is more portable than "test ... -nt ..." -if ! testoptions o-noatime >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testoptions o-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7071,7 +7247,7 @@ else numOK=$((numOK+1)) fi # wrong time stamps fi # command ok -fi ;; # not feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -7083,7 +7259,8 @@ TEST="$NAME: extended file system options using ext2fs noatime option" # without this option (using touch); one second later read from the first file. # Then we check which file has the later ATIME stamp. For this check we use # "ls -ltu" because it is more portable than "test ... -nt ..." -if ! testoptions ext2-noatime >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testoptions ext2-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}ext2-noatime not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7131,7 +7308,7 @@ else fi fi # not impotent fi # can test -fi ;; # not feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -7140,7 +7317,8 @@ NAME=COOLWRITE case "$TESTS" in *%functions%*|*%timeout%*|*%ignoreeof%*|*%coolwrite%*|*%$NAME%*) TEST="$NAME: option cool-write" -if ! testoptions cool-write >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testoptions cool-write >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7170,7 +7348,7 @@ else if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi -fi # testoptions +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -7187,7 +7365,8 @@ TEST="$NAME: option cool-write on bidirectional stdio" # byte. The last write will fail with "broken pipe"; if option coolwrite # has been applied successfully, socat will terminate with 0 (OK), # otherwise with error. -if ! testoptions cool-write >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testoptions cool-write >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7217,7 +7396,7 @@ else if [ -n "$debug" ]; then cat "$te"; fi numOK=$((numOK+1)) fi -fi # testoptions +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -7226,6 +7405,7 @@ NAME=TCP4ENDCLOSE case "$TESTS" in *%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$NAME%*) TEST="$NAME: end-close keeps TCP V4 socket open" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -7263,7 +7443,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2" "${te}3"; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -7273,6 +7454,7 @@ NAME=EXECENDCLOSE case "$TESTS" in *%functions%*|*%exec%*|*%$NAME%*) TEST="$NAME: end-close keeps EXEC child running" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" ts="$td/test$N.sock" @@ -7306,7 +7488,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2"; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -7317,7 +7500,8 @@ NAME=UDP6LISTENBIND case "$TESTS" in *%functions%*|*%bugs%*|*%ip6%*|*%ipapp%*|*%udp%*|*%$NAME%*) TEST="$NAME: UDP6-LISTEN with bind" -if ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7351,7 +7535,7 @@ else if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi -fi ;; # ! testaddrs +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -7363,7 +7547,8 @@ NAME=TCPWRAPPERS_MULTIOPTS case "$TESTS" in *%functions%*|*%bugs%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: use of multiple tcpwrapper enabling options" -if ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7395,7 +7580,7 @@ else if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -7407,7 +7592,8 @@ NAME=TCPWRAPPERS_TCP6ADDR case "$TESTS" in *%functions%*|*%bugs%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) TEST="$NAME: specification of TCP6 address in hosts.allow" -if ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs tcp ip6 libwrap) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7443,7 +7629,7 @@ else if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi -fi ;; # feat +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -7453,7 +7639,8 @@ NAME=UDP4BROADCAST case "$TESTS" in *%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 broadcast" -if [ -z "$BCADDR" ]; then +if ! eval $NUMCOND; then :; +elif [ -z "$BCADDR" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7496,7 +7683,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -7508,7 +7695,8 @@ NAME=IP4BROADCAST case "$TESTS" in *%functions%*|*%rawip%*|*%rawip4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%root%*|*%$NAME%*) TEST="$NAME: raw IPv4 broadcast" -if ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}raw IP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -7555,7 +7743,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # not feats, not root +fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) @@ -7565,11 +7753,12 @@ N=$((N+1)) #case "$TESTS" in #*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%range%*|*%$NAME%*) #TEST="$NAME: security of UDP4-BROADCAST with RANGE option" -#if [ -z "$BCADDR" ]; then +#if ! eval $NUMCOND; then :; +#elif [ -z "$BCADDR" ]; then # $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N #else #testserversec "$N" "$TEST" "$opts -s" "UDP4-BROADCAST:$BCADDR/8:$PORT" "" "range=127.1.0.0:255.255.0.0" "udp4:127.1.0.0:$PORT" 4 udp $PORT 0 -#fi ;; # feats +#fi ;; # NUMCOND, feats #esac #PORT=$((PORT+1)) #N=$((N+1)) @@ -7579,7 +7768,8 @@ NAME=UDP4MULTICAST_UNIDIR case "$TESTS" in *%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 multicast, send only" -if ! feat=$(testaddrs ip4 udp) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 udp) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7616,7 +7806,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # not feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -7624,7 +7814,8 @@ NAME=IP4MULTICAST_UNIDIR case "$TESTS" in *%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*) TEST="$NAME: IPv4 multicast" -if ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -7665,7 +7856,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # not feats, not root +fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) @@ -7675,7 +7866,8 @@ NAME=UDP6MULTICAST_UNIDIR case "$TESTS" in *%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%multicast%*|*%$NAME%*) TEST="$NAME: UDP/IPv6 multicast" -if ! feat=$(testaddrs ip6 udp) || ! runsip6 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip6 udp) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7712,7 +7904,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # not feats +fi ;; # NUMCOND, feats esac N=$((N+1)) fi # false @@ -7721,6 +7913,7 @@ NAME=UDP4MULTICAST_BIDIR case "$TESTS" in *%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*) TEST="$NAME: UDP/IPv4 multicast, with reply" +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -7759,7 +7952,8 @@ else fi if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -7767,7 +7961,8 @@ NAME=IP4MULTICAST_BIDIR case "$TESTS" in *%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*) TEST="$NAME: IPv4 multicast, with reply" -if ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -7812,7 +8007,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # not feats, not root +fi ;; # NUMCOND, feats esac PROTO=$((PROTO+1)) N=$((N+1)) @@ -7825,7 +8020,8 @@ TEST="$NAME: reading data sent through tun interface" #idea: create a TUN interface and send a datagram to one of the addresses of # its virtual network. On the tunnel side, read the packet and compare its last # bytes with the datagram payload -if ! feat=$(testaddrs ip4 tun) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 tun) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -7865,7 +8061,7 @@ else if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi numOK=$((numOK+1)) fi -fi ;; # not feats, not root +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -7879,7 +8075,8 @@ case "$TESTS" in TEST="$NAME: pass data through tun interface using INTERFACE" #idea: create a TUN interface and send a raw packet on the interface side. # It should arrive unmodified on the tunnel side. -if ! feat=$(testaddrs ip4 tun interface) || ! runsip4 >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs ip4 tun interface) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then @@ -7920,7 +8117,7 @@ else if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi numOK=$((numOK+1)) fi -fi ;; # not feats, not root +fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) N=$((N+1)) @@ -7930,7 +8127,8 @@ NAME=ABSTRACTSTREAM case "$TESTS" in *%functions%*|*%unix%*|*%abstract%*|*%connect%*|*%listen%*|*%$NAME%*) TEST="$NAME: abstract UNIX stream socket, listen and connect" -if ! feat=$(testaddrs abstract-unixsocket); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -7973,7 +8171,7 @@ else numOK=$((numOK+1)) fi # !(rc -ne 0) wait -fi ;; # not feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -7982,7 +8180,8 @@ NAME=ABSTRACTDGRAM case "$TESTS" in *%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%$NAME%*) TEST="$NAME: abstract UNIX datagram" -if ! feat=$(testaddrs abstract-unixsocket); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8019,7 +8218,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # not feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -8028,7 +8227,8 @@ NAME=ABSTRACTRECV case "$TESTS" in *%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%recv%*|*%$NAME%*) TEST="$NAME: abstract UNIX datagram receive" -if ! feat=$(testaddrs abstract-unixsocket); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8066,7 +8266,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi ;; # not feats +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -8087,7 +8287,8 @@ TEST="$NAME: socat handles data buffered by openssl" # socat transfer block size; keep the socket connection open and kill the # server process after a short time; if not the whole data block has been # transferred, the test has failed. -if ! feat=$(testaddrs openssl) >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs openssl) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8119,8 +8320,9 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi -wait ;; +wait +fi # NUMCOND, featsesac + ;; esac N=$((N+1)) @@ -8137,7 +8339,8 @@ TEST="$NAME: trigger EOF after that many bytes, even when socket idle" #idea: we deliver that many bytes to socat; the process should terminate then. # we try to transfer data in the other direction then; if transfer succeeds, # the process did not terminate and the bug is still there. -if false; then +if ! eval $NUMCOND; then :; +elif false; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8159,7 +8362,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi +fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -8174,6 +8377,7 @@ TEST="$NAME: exec:...,pty explicitely kills sub process" # for this we have a shell script that generates a file after two seconds; # it should be killed after one second, so if the file was generated the test # has failed +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" ts="$td/test$N.sock" @@ -8209,7 +8413,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -8223,6 +8428,7 @@ TEST="$NAME: echo via connection to TCP V4 socket" # select a tcp entry from /etc/services, have a server listen on the port # number and connect using the service name; with the bug, connection will to a # wrong port +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -8259,7 +8465,8 @@ else fi kill $pid1 2>/dev/null wait -PORT="$_PORT" ;; +PORT="$_PORT" +fi ;; # NUMCOND esac N=$((N+1)) @@ -8284,6 +8491,7 @@ case "$TESTS" in TEST="$NAME: more than FOPEN_MAX FDs in use" # this test opens a number of FDs before socat is invoked. socat will have to # allocate higher FD numbers and thus hang if it cannot handle them. +if ! eval $NUMCOND; then :; else REDIR= #set -vx FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print($3);}') @@ -8302,6 +8510,7 @@ done eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR #set +vx fi # could determine FOPEN_MAX +fi ;; # NUMCOND esac N=$((N+1)) @@ -8316,6 +8525,7 @@ TEST="$NAME: test if UDP4-LISTEN child becomes zombie" # process is forked off. Make some transfer and wait until the -T timeout is # over. Now check for the child process: if it is zombie the test failed. # Correct is that child process terminated +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -8350,7 +8560,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -8366,6 +8577,7 @@ TEST="$NAME: test if UDP4-RECVFROM child becomes zombie" # sub process is forked off. Make some transfer and wait until the -T timeout # is over. Now check for the child process: if it is zombie the test failed. # Correct is that child process terminated +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -8400,7 +8612,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -8416,7 +8629,8 @@ case "$TESTS" in TEST="$NAME: raw IPv4 receive with bind" # idea: start a socat process with ip4-recv:...,bind=... and send it a packet # if the packet passes the test succeeded -if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then +if ! eval $NUMCOND; then :; +elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8454,7 +8668,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi -fi # must be root ;; +fi ;; # NUMCOND, root esac PROTO=$((PROTO+1)) N=$((N+1)) @@ -8470,6 +8684,7 @@ TEST="$NAME: test if UDP4-RECVFROM handles more than one packet" # idea: run a UDP4-RECVFROM process with fork and -T. Send it one packet; # send it a second packet and check if this is processed properly. If yes, the # test succeeded. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -8502,7 +8717,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -8514,6 +8730,7 @@ NAME=EXECSPACES case "$TESTS" in *%functions%*|*%exec%*|*%parse%*|*%$NAME%*) TEST="$NAME: correctly parse exec with consecutive spaces" +if ! eval $NUMCOND; then :; else $PRINTF "test $F_n $TEST... " $N tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8539,6 +8756,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -8552,6 +8770,7 @@ case "$TESTS" in TEST="$NAME: let range drop a packet and see if old socket is closed" # idea: run a UDP4-LISTEN process with range option. Send it one packet from an # address outside range and check if two listening sockets are open then +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -8590,7 +8809,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -8605,6 +8825,7 @@ TEST="$NAME: ignoreeof does not block other direction" # have socat poll in ignoreeof mode. while it waits one second for next check, # we send data in the reverse direction and then the total timeout fires. # it the data has passed, the test succeeded. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -8630,6 +8851,7 @@ else cat "${te}0" numFAIL=$((numFAIL+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -8641,6 +8863,7 @@ case "$TESTS" in TEST="$NAME: escape character triggers EOF" # idea: start socat just echoing input, but apply escape option. send a string # containing the escape character and check if the output is truncated +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -8662,6 +8885,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -8672,6 +8896,7 @@ case "$TESTS" in TEST="$NAME: escape character triggers EOF" # idea: start socat just echoing input, but apply escape option. send a string # containing the escape character and check if the output is truncated +if ! eval $NUMCOND; then :; else ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8693,6 +8918,7 @@ else if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -8711,7 +8937,8 @@ TEST="$NAME: $KEYW log ancillary message $SCM_TYPE $SCM_NAME" # idea: start a socat process with *-RECV:..,... , ev. with ancillary message # enabling option and send it a packet, ev. with some option. check the info log # for the appropriate output. -if [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then +if ! eval $NUMCOND; then :; +elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8777,8 +9004,8 @@ else # option is not supported $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" numCANT=$((numCANT+1)) fi # option is not supported -fi # must be root -;; +fi # NUMCOND, root, feats + ;; esac N=$((N+1)) # @@ -8830,7 +9057,8 @@ TEST="$NAME: $KEYW-LISTEN fills environment variables with socket addresses" # code extracts and prints the SOCAT related environment vars. # outside code then checks if the environment contains the variables correctly # describing the peer and local sockets. -if ! feat=$(testaddrs $FEAT); then +if ! eval $NUMCOND; then :; +elif ! feat=$(testaddrs $FEAT); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo $feat |tr a-z A-Z) not available${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8891,7 +9119,8 @@ else numFAIL=$((numFAIL+1)) fi set +xv -fi ;; # feat +fi # NUMCOND, feats + ;; esac N=$((N+1)) # @@ -8923,7 +9152,8 @@ TEST="$NAME: $KEYW ancillary message brings $SCM_ENVNAME into environment" # message enabling option and send it a packet, ev. with some option. write # the resulting environment to a file and check its contents for the # appropriate variable. -if [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then +if ! eval $NUMCOND; then :; +elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) else @@ -8986,8 +9216,7 @@ else # option is not supported $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" numCANT=$((numCANT+1)) fi # option is not supported -fi # must be root -;; +fi ;; # NUMCOND, feats esac N=$((N+1)) # @@ -9027,6 +9256,7 @@ case "$TESTS" in TEST="$NAME: socket connect with TCP/IPv4" # start a TCP4-LISTEN process that echoes data, and send test data using # SOCKET-CONNECT, selecting TCP/IPv4. The sent data should be returned. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -9065,7 +9295,9 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi # NUMCOND + ;; esac PORT=$((PORT+1)) N=$((N+1)) @@ -9077,6 +9309,7 @@ NAME=SOCKET_CONNECT_TCP6 case "$TESTS" in *%functions%*|*%generic%*|*%tcp6%*|*%socket%*|*%$NAME%*) TEST="$NAME: socket connect with TCP/IPv6" +if ! eval $NUMCOND; then :; else # start a TCP6-LISTEN process that echoes data, and send test data using # SOCKET-CONNECT, selecting TCP/IPv6. The sent data should be returned. tf="$td/test$N.stdout" @@ -9117,7 +9350,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -9129,6 +9363,7 @@ case "$TESTS" in TEST="$NAME: socket connect with UNIX domain" # start a UNIX-LISTEN process that echoes data, and send test data using # SOCKET-CONNECT, selecting UNIX socket. The sent data should be returned. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -9163,7 +9398,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac N=$((N+1)) @@ -9174,6 +9410,7 @@ case "$TESTS" in TEST="$NAME: socket recvfrom with TCP/IPv4" # start a SOCKET-LISTEN process that uses TCP/IPv4 and echoes data, and # send test data using TCP4-CONNECT. The sent data should be returned. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -9214,7 +9451,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -9228,6 +9466,7 @@ case "$TESTS" in TEST="$NAME: socket sendto with UDP/IPv4" # start a UDP4-RECVFROM process that echoes data, and send test data using # SOCKET-SENDTO, selecting UDP/IPv4. The sent data should be returned. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -9266,7 +9505,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -9278,6 +9518,7 @@ case "$TESTS" in TEST="$NAME: socket recvfrom with UDP/IPv4" # start a SOCKET-RECVFROM process that uses UDP/IPv4 and echoes data, and # send test data using UDP4-SENDTO. The sent data should be returned. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -9317,7 +9558,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -9330,6 +9572,7 @@ case "$TESTS" in TEST="$NAME: socket recv with UDP/IPv4" # start a SOCKET-RECV process that uses UPD/IPv4 and writes received data to file, and # send test data using UDP4-SENDTO. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -9370,7 +9613,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -9382,6 +9626,7 @@ case "$TESTS" in TEST="$NAME: socket datagram via UDP/IPv4" # start a UDP4-DATAGRAM process that echoes data, and send test data using # SOCKET-DATAGRAM, selecting UDP/IPv4. The sent data should be returned. +if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -9422,7 +9667,8 @@ else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi numOK=$((numOK+1)) -fi ;; +fi +fi ;; # NUMCOND esac PORT=$((PORT+1)) N=$((N+1)) @@ -9431,14 +9677,15 @@ NAME=SOCKETRANGEMASK case "$TESTS" in *%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%$NAME%*) TEST="$NAME: security of generic socket-listen with RANGE option" -if [ -z "$SECONDADDR" ]; then +if ! eval $NUMCOND; then :; +elif [ -z "$SECONDADDR" ]; then # we need access to more loopback addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N numCANT=$((numCANT+1)) else ts1p=$(printf "%04x" $PORT); testserversec "$N" "$TEST" "$opts -s" "SOCKET-LISTEN:2:6:x${ts1p}x00000000x0000000000000000,reuseaddr,fork,retry=1" "" "range=x0000x7f000000:x0000xffffffff" "SOCKET-CONNECT:2:6:x${ts1p}x${SECONDADDRHEX}x0000000000000000" 4 tcp $PORT 0 -fi ;; # $SECONDADDR +fi ;; # NUMCOND, $SECONDADDR esac PORT=$((PORT+1)) N=$((N+1)) @@ -9457,7 +9704,8 @@ TEST="$NAME: test the ioctl-void option" # process 1 opens it with the TIOCEXCL ioctl; # process 2 opens it too and fails with "device or resource busy" only when the # previous ioctl was successful -if [ -z "$TIOCEXCL" ]; then +if ! eval $NUMCOND; then :; +elif [ -z "$TIOCEXCL" ]; then # we use the numeric value of TIOCEXL which is system dependent $PRINTF "test $F_n $TEST... ${YELLOW}no value of TIOCEXCL${NORMAL}\n" $N numCANT=$((numCANT+1)) @@ -9498,8 +9746,8 @@ else if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi numOK=$((numOK+1)) fi -fi # !Linux - ;; +fi # NUMCOND, TIOCEXCL +;; esac N=$((N+1)) @@ -9521,7 +9769,8 @@ TEST="$NAME: test the setsockopt-int option" # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the # (generically specified) SO_REUSEADDR socket options did not work # process 3 connects to this port; only if it is successful the test is ok -if [ -z "SO_REUSEADDR" ]; then +if ! eval $NUMCOND; then :; +elif [ -z "SO_REUSEADDR" ]; then # we use the numeric value of SO_REUSEADDR which might be system dependent $PRINTF "test $F_n $TEST... ${YELLOW}value of SO_REUSEADDR not known${NORMAL}\n" $N numCANT=$((numCANT+1)) @@ -9570,7 +9819,7 @@ else if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi numOK=$((numOK+1)) fi -fi # !Linux +fi # NUMCOND, SO_REUSEADDR ;; esac PORT=$((PORT+1)) @@ -9582,7 +9831,8 @@ case "$TESTS" in *%functions%*|*%ip4%*|*%ipapp%*|*%sctp%*|*%$NAME%*) TEST="$NAME: echo via connection to SCTP V4 socket" PORT="$((PORT+1))" -if ! testaddrs sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 "$((PORT-1))" >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 "$((PORT-1))" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then @@ -9623,7 +9873,8 @@ else fi kill $pid1 2>/dev/null wait -fi ;; # sctp +fi # NUMCOND, feats + ;; esac PORT=$((PORT+1)) N=$((N+1)) @@ -9633,7 +9884,8 @@ case "$TESTS" in *%functions%*|*%ip6%*|*%ipapp%*|*%sctp%*|*%$NAME%*) TEST="$NAME: echo via connection to SCTP V6 socket" PORT="$((PORT+1))" -if ! testaddrs sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 "$((PORT-1))" >/dev/null; then +if ! eval $NUMCOND; then :; +elif ! testaddrs sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 "$((PORT-1))" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N numCANT=$((numCANT+1)) elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then @@ -9670,7 +9922,8 @@ else numOK=$((numOK+1)) fi kill $pid 2>/dev/null -fi ;; # sctp +fi # NUMCOND, feats + ;; esac PORT=$((PORT+1)) N=$((N+1)) @@ -9706,6 +9959,7 @@ case "$TESTS" in *%functions%*|*%bugs%*|*%socket%*|*%$NAME%*) TEST="$NAME: give a one line description of test" # describe how the test is performed, and what's the success criteria +if ! eval $NUMCOND; then :; else tf="$td/test$N.stout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -9730,5 +9984,7 @@ else cat "${te}1" numFAIL=$((numFAIL+1)) fi +fi # NUMCOND + ;; esac N=$((N+1)) From f82bad1dd8fa422fd73e7ac9b33e16b3e3646956 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 5 Oct 2008 12:56:49 +0200 Subject: [PATCH 54/75] HP-UX: make xiolog_ancillary_socket() cond. by HAVE_STRUCT_CMSGHDR --- xio-socket.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xio-socket.c b/xio-socket.c index 6fa4125..fbfc3b5 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1765,6 +1765,7 @@ int xiocheckpeer(xiosingle_t *xfd, } +#if HAVE_STRUCT_CMSGHDR /* converts the ancillary message in *cmsg into a form useable for further processing. knows the specifics of common message types. returns the number of resulting syntax elements is *num @@ -1841,6 +1842,7 @@ xiolog_ancillary_socket(struct cmsghdr *cmsg, int *num, #endif /* !defined(CMSG_DATA) */ } +#endif /* HAVE_STRUCT_CMSGHDR */ /* return the name of the interface with given index From 75e643ad2d284d0544e3e03ec41451ae28536120 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 10 Oct 2008 06:39:46 +0200 Subject: [PATCH 55/75] socat option -lf did not log to file --- error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/error.c b/error.c index 6284177..551788f 100644 --- a/error.c +++ b/error.c @@ -128,8 +128,8 @@ void diag_set(char what, const char *arg) { } if ((diagopts.logfile = fopen(arg, "a")) == NULL) { Error2("cannot open log file \"%s\": %s", arg, strerror(errno)); - break; } + break; case 's': if (diagopts.logfile != NULL && diagopts.logfile != stderr) { fclose(diagopts.logfile); From b2d618438a5c39e33a88f35437e66c4bc9903ec0 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 12 Oct 2008 12:01:00 +0200 Subject: [PATCH 56/75] made it compile and run on SuSE5.2 --- compat.h | 4 ++++ config.h.in | 6 ++++++ configure.in | 38 ++++++++++++++++++++++++++++++-------- filan.c | 12 +++++++++++- sysutils.c | 26 +++++++++++++++++++------- sysutils.h | 2 +- xio-socket.c | 16 ++++++++++++++-- xio.h | 2 +- xioconfig.h | 4 ++++ xioopts.c | 6 +++++- 10 files changed, 95 insertions(+), 21 deletions(-) diff --git a/compat.h b/compat.h index afd3f3c..5f7c588 100644 --- a/compat.h +++ b/compat.h @@ -602,6 +602,10 @@ # define NETDB_INTERNAL h_NETDB_INTERNAL #endif +#ifndef INET_ADDRSTRLEN +# define INET_ADDRSTRLEN sizeof(struct sockaddr_in) +#endif + #if !HAVE_PROTOTYPE_HSTRERROR /* with MacOSX this is char * */ extern const char *hstrerror(int); diff --git a/config.h.in b/config.h.in index 46d12c6..ad1ed55 100644 --- a/config.h.in +++ b/config.h.in @@ -293,6 +293,12 @@ /* fdset may have component fds_bits or __fds_bits */ #undef HAVE_FDS_BITS +/* Define if you have the sa_family_t */ +#undef HAVE_TYPE_SA_FAMILY_T + +/* define if your struct sigaction has sa_sigaction */ +#undef HAVE_STRUCT_SIGACTION_SA_SIGACTION + /* Define if your struct termios has component c_ispeed */ #undef HAVE_TERMIOS_ISPEED diff --git a/configure.in b/configure.in index 61dd284..035fe21 100644 --- a/configure.in +++ b/configure.in @@ -220,7 +220,7 @@ AC_ARG_ENABLE(rawsocket, [ --disable-genericsocket disable generic socket suppo *) AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes);; esac], [AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes)]) -AC_MSG_CHECKING(whether to include raw network INTERFACE support) +AC_MSG_CHECKING(whether to include raw network interface support) AC_ARG_ENABLE(interface, [ --disable-interface disable network interface support], [case "$enableval" in no) AC_MSG_RESULT(no); WITH_INTERFACE= ;; @@ -231,13 +231,13 @@ if test "$WITH_INTERFACE"; then AC_CHECK_HEADER(netpacket/packet.h, AC_DEFINE(HAVE_NETPACKET_PACKET_H), [WITH_INTERFACE=; - AC_MSG_WARN([include file netpacket/packet.h not found, disabling INTERFACE])]) + AC_MSG_WARN([include file netpacket/packet.h not found, disabling interface])]) fi if test "$WITH_INTERFACE"; then AC_CHECK_HEADER(netinet/if_ether.h, AC_DEFINE(HAVE_NETINET_IF_ETHER_H), [WITH_INTERFACE=; - AC_MSG_WARN([include file netinet/if_ether.h not found, disabling INTERFACE])]) + AC_MSG_WARN([include file netinet/if_ether.h not found, disabling interface])]) fi if test "$WITH_INTERFACE"; then AC_DEFINE(WITH_INTERFACE) @@ -595,13 +595,14 @@ AC_ARG_ENABLE(tun, [ --disable-tun disable TUN/TAP support], esac], [AC_MSG_RESULT(yes); WITH_TUN=1 ]) +# +if ! test "$ac_cv_header_linux_if_tun_h" = 'yes'; then + AC_MSG_WARN(include file linux/if_tun.h not found, disabling TUN) + WITH_TUN= +fi # if test -n "$WITH_TUN"; then - if test `uname` != Linux; then - AC_MSG_NOTICE(only on Linux) - else - AC_DEFINE(WITH_TUN) - fi + AC_DEFINE(WITH_TUN) fi AC_MSG_CHECKING(whether to include system call tracing) @@ -826,6 +827,27 @@ AC_TRY_COMPILE([#include [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_FDS_BITS)], [AC_MSG_RESULT(no);]) +AC_MSG_CHECKING(for sa_family_t) +AC_CACHE_VAL(sc_cv_type_sa_family_t, +[AC_TRY_COMPILE([#include +#include ],[sa_family_t s;], +[sc_cv_type_sa_family_t=yes], +[sc_cv_type_sa_family_t=no])]) +if test $sc_cv_type_sa_family_t = yes; then + AC_DEFINE(HAVE_TYPE_SA_FAMILY_T) +fi +AC_MSG_RESULT($sc_cv_type_sa_family_t) + +AC_MSG_CHECKING(for struct sigaction.sa_sigaction) +AC_CACHE_VAL(sc_cv_struct_sigaction_sa_sigaction, +[AC_TRY_COMPILE([#include ],[struct sigaction s;s.sa_sigaction=0;], +[sc_cv_struct_sigaction_sa_sigaction=yes], +[sc_cv_struct_sigaction_sa_sigaction=no])]) +if test $sc_cv_struct_sigaction_sa_sigaction = yes; then + AC_DEFINE(HAVE_STRUCT_SIGACTION_SA_SIGACTION) +fi +AC_MSG_RESULT($sc_cv_struct_sigaction_sa_sigaction) + ### struct termios .c_ispeed AC_MSG_CHECKING(for termios.c_ispeed) AC_CACHE_VAL(sc_cv_termios_ispeed, diff --git a/filan.c b/filan.c index 246c9d3..6461e47 100644 --- a/filan.c +++ b/filan.c @@ -129,7 +129,17 @@ int filan_fd(int fd, FILE *outfile) { { /* see if data is available */ struct pollfd ufds; ufds.fd = fd; - ufds.events = POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLRDBAND|POLLWRNORM|POLLWRBAND + ufds.events = POLLIN|POLLPRI|POLLOUT +#ifdef POLLRDNORM + |POLLRDNORM +#endif +#ifdef POLLRDBAND + |POLLRDBAND +#endif + |POLLWRNORM +#ifdef POLLWRBAND + |POLLWRBAND +#endif #ifdef POLLMSG |POLLMSG #endif diff --git a/sysutils.c b/sysutils.c index 8e762bd..6b31788 100644 --- a/sysutils.c +++ b/sysutils.c @@ -175,11 +175,20 @@ char *sockaddr_info(const struct sockaddr *sa, socklen_t salen, char *buff, size cp += n, blen -= n; if ((snprintf(cp, blen, "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - sau->soa.sa_data[0], sau->soa.sa_data[1], sau->soa.sa_data[2], - sau->soa.sa_data[3], sau->soa.sa_data[4], sau->soa.sa_data[5], - sau->soa.sa_data[6], sau->soa.sa_data[7], sau->soa.sa_data[8], - sau->soa.sa_data[9], sau->soa.sa_data[10], sau->soa.sa_data[11], - sau->soa.sa_data[12], sau->soa.sa_data[13])) < 0) { + ((unsigned char *)sau->soa.sa_data)[0], + ((unsigned char *)sau->soa.sa_data)[1], + ((unsigned char *)sau->soa.sa_data)[2], + ((unsigned char *)sau->soa.sa_data)[3], + ((unsigned char *)sau->soa.sa_data)[4], + ((unsigned char *)sau->soa.sa_data)[5], + ((unsigned char *)sau->soa.sa_data)[6], + ((unsigned char *)sau->soa.sa_data)[7], + ((unsigned char *)sau->soa.sa_data)[8], + ((unsigned char *)sau->soa.sa_data)[9], + ((unsigned char *)sau->soa.sa_data)[10], + ((unsigned char *)sau->soa.sa_data)[11], + ((unsigned char *)sau->soa.sa_data)[12], + ((unsigned char *)sau->soa.sa_data)[13])) < 0) { Warn("sockaddr_info(): buffer too short"); *buff = '\0'; return buff; @@ -262,6 +271,7 @@ const char *inet_ntop(int pf, const void *binaddr, return NULL; /* errno is valid */ } break; +#if WITH_IP6 case PF_INET6: if ((retlen = snprintf(addrtext, textlen, "%x:%x:%x:%x:%x:%x:%x:%x", @@ -278,6 +288,7 @@ const char *inet_ntop(int pf, const void *binaddr, return NULL; /* errno is valid */ } break; +#endif /* WITH_IP6 */ default: errno = EAFNOSUPPORT; return NULL; @@ -413,7 +424,8 @@ const char *hstrerror(int err) { /* this function behaves like poll(). It tries to do so even when the poll() system call is not available. */ -int xiopoll(struct pollfd fds[], nfds_t nfds, struct timeval *timeout) { +/* note: glibc 5.4 does not know nfds_t */ +int xiopoll(struct pollfd fds[], unsigned long nfds, struct timeval *timeout) { int i, n = 0; int result = 0; @@ -432,7 +444,7 @@ int xiopoll(struct pollfd fds[], nfds_t nfds, struct timeval *timeout) { if (fds[i].events & POLLOUT) { FD_SET(fds[i].fd, &writefds); n = MAX(n, fds[i].fd); } } - if (fds[i].fd > FD_SETSIZE) { break; /* use poll */ } + if (i < nfds) { break; /* use poll */ } result = Select(n+1, &readfds, &writefds, &exceptfds, timeout); if (result < 0) { return result; } diff --git a/sysutils.h b/sysutils.h index 3b30b96..5d72b26 100644 --- a/sysutils.h +++ b/sysutils.h @@ -74,7 +74,7 @@ extern int getusergroups(const char *user, gid_t *list, size_t *ngroups); extern const char *hstrerror(int err); #endif -extern int xiopoll(struct pollfd fds[], nfds_t nfds, struct timeval *timeout); +extern int xiopoll(struct pollfd fds[], unsigned long nfds, struct timeval *timeout); extern int parseport(const char *portname, int proto); diff --git a/xio-socket.c b/xio-socket.c index 94f3363..b385bea 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1104,14 +1104,22 @@ static pid_t xio_waitingfor; /* info from recv loop to signal handler: static bool xio_hashappened; /* info from signal handler to loop: child process has read ("consumed") the packet */ /* this is the signal handler for USR1 and CHLD */ -void xiosigaction_hasread(int signum, siginfo_t *siginfo, void *ucontext) { +void xiosigaction_hasread(int signum +#if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) + , siginfo_t *siginfo, void *ucontext +#endif + ) { pid_t pid; int _errno; int status = 0; bool wassig = false; +#if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) Debug5("xiosigaction_hasread(%d, {%d,%d,%d,"F_pid"}, )", signum, siginfo->si_signo, siginfo->si_errno, siginfo->si_code, siginfo->si_pid); +#else + Debug1("xiosigaction_hasread(%d)", signum); +#endif if (signum == SIGCHLD) { _errno = errno; do { @@ -1146,9 +1154,13 @@ void xiosigaction_hasread(int signum, siginfo_t *siginfo, void *ucontext) { } } while (1); } +#if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) if (xio_waitingfor == siginfo->si_pid) { xio_hashappened = true; } +#else + xio_hashappened = true; +#endif Debug("xiosigaction_hasread() ->"); return; } @@ -1262,7 +1274,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, |SA_NOMASK #endif ; -#if 1 || HAVE_SIGACTION_SASIGACTION +#if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) act.sa_sigaction = xiosigaction_hasread; #else /* Linux 2.0(.33) does not have sigaction.sa_sigaction */ act.sa_handler = xiosighandler_hasread; diff --git a/xio.h b/xio.h index b09c8c3..8bc17ca 100644 --- a/xio.h +++ b/xio.h @@ -335,7 +335,7 @@ union integral { } u_ip_mreq; #endif #if WITH_IP4 - in_addr_t u_ip4addr; + struct in_addr u_ip4addr; #endif } ; diff --git a/xioconfig.h b/xioconfig.h index 7d03be8..03e4859 100644 --- a/xioconfig.h +++ b/xioconfig.h @@ -120,4 +120,8 @@ typedef unsigned int uint32_t; #endif +#ifndef HAVE_TYPE_SA_FAMILY_T + typedef uint16_t sa_family_t; +#endif + #endif /* !defined(__xioconfig_h_included) */ diff --git a/xioopts.c b/xioopts.c index a943182..5b94f24 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1125,6 +1125,9 @@ const struct optname optionnames[] = { #endif IF_TUN ("promisc", &opt_iff_promisc) IF_READLINE("prompt", &opt_prompt) +#ifdef SO_PROTOTYPE + IF_SOCKET ("protocol", &opt_so_prototype) +#endif IF_SOCKET ("protocol-family", &opt_protocol_family) #ifdef SO_PROTOTYPE IF_SOCKET ("prototype", &opt_so_prototype) @@ -1430,6 +1433,7 @@ const struct optname optionnames[] = { IF_SOCKET ("sockopt-string", &opt_setsockopt_string) IF_SOCKS4 ("socksport", &opt_socksport) IF_SOCKS4 ("socksuser", &opt_socksuser) + IF_SOCKET ("socktype", &opt_so_type) IF_IPAPP ("sourceport", &opt_sourceport) IF_IPAPP ("sp", &opt_sourceport) IF_TERMIOS("start", &opt_vstart) @@ -2331,7 +2335,7 @@ int parseopts_table(const char **a, unsigned int groups, struct opt **opts, 0, 0/*!!!*/) != STAT_OK) { opt->desc = ODESC_ERROR; continue; } - opt->value.u_ip4addr = sa.sin_addr.s_addr; + opt->value.u_ip4addr = sa.sin_addr; } break; #endif /* defined(WITH_IP4) */ From fcd73539acf9218120fd007f4921975bbb61dfea Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 12 Oct 2008 12:01:49 +0200 Subject: [PATCH 57/75] do not include sys/timeb.h --- sysincludes.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sysincludes.h b/sysincludes.h index 0377b3a..90bda79 100644 --- a/sysincludes.h +++ b/sysincludes.h @@ -24,7 +24,9 @@ #endif #include /* signal(), SIGPIPE, SIG_IGN */ #include /* struct timeval, strftime() */ +#if 0 #include /* struct timeb */ +#endif #if HAVE_UNISTD_H #include /* select(), read(), write(), stat(), fork() */ #endif From 01f990310e1e0a9719c468138d61db120467acbd Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 12 Oct 2008 12:04:54 +0200 Subject: [PATCH 58/75] more for Darwin; do not test ancillary timestamp with unix domain --- test.sh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/test.sh b/test.sh index 7dfc800..9281e9f 100755 --- a/test.sh +++ b/test.sh @@ -1945,6 +1945,7 @@ waittcp6port () { FreeBSD) l=$(netstat -an |egrep -i 'tcp(6|46) .*[0-9*][:.]'$port' .* listen') ;; NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; + Darwin) l=$(netstat -an |egrep '^tcp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+ +LISTEN' ;; AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; @@ -1974,7 +1975,7 @@ waitudp6port () { FreeBSD) l=$(netstat -an |egrep '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;; NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; - #Darwin) l=$(netstat -an |grep '^udp6.* .*[0-9*]\.'$port' .* \*\.\* ') ;; + Darwin) l=$(netstat -an |egrep '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+' ;; AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;; SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;; #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;; @@ -4388,7 +4389,7 @@ $CMD >"$tf" 2>"$te" & bg=$! # background process id psleep 0.5 echo "$da" >>"$ti" -sleep 3 +sleep 4 echo X >>"$ti" sleep 1 kill $bg 2>/dev/null @@ -5805,7 +5806,7 @@ N=$((N+1)) # derive signal number from signal name # kill -l should provide the info signum () { - if [ ! "$BASH_VERSION" ]; then + if [ ! "$BASH_VERSION" -o -o posix ]; then # we expect: for i in $(POSIXLY_CORRECT=1 kill -l); do echo $i; done |grep -n -i "^$1$" |cut -d: -f1 else @@ -7434,7 +7435,7 @@ if [ $? -ne 0 ]; then echo "$CMD2" cat "${te}1a" "${te}1b" "${te}2" "${te}3" numFAIL=$((numFAIL+1)) -elif ! echo -e "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then +elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" cat "${te}1a" "${te}1b" "${te}2" "${te}3" @@ -7479,7 +7480,7 @@ if [ $? -ne 0 ]; then echo "$CMD2" cat "${te}1a" "${te}1b" "${te}2" numFAIL=$((numFAIL+1)) -elif ! echo -e "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then +elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" cat "${te}1a" "${te}1b" "${te}2" @@ -8926,7 +8927,7 @@ N=$((N+1)) # test: logging of ancillary message while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VALUE do -if [ -z "$PF" ]; then continue; fi +if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi # pf="$(echo $PF |tr A-Z a-z)" proto="$(echo $KEYW |tr A-Z a-z)" @@ -8938,6 +8939,7 @@ TEST="$NAME: $KEYW log ancillary message $SCM_TYPE $SCM_NAME" # enabling option and send it a packet, ev. with some option. check the info log # for the appropriate output. if ! eval $NUMCOND; then :; +#elif [[ "$PF" == "#*" ]]; then : elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N numCANT=$((numCANT+1)) @@ -9036,7 +9038,7 @@ IP6 IP6 [::1] PROTO , so-timestamp SCM_TIMESTAMP IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_PKTINFO dstaddr root [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit root 35 IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass root xaa000000 -UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP timestamp user $(date '+%a %b %e %H:%M:.. %Y') +#UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP timestamp user $(date '+%a %b %e %H:%M:.. %Y') " # this one fails, appearently due to a Linux weakness: # UNIX so-timestamp @@ -9046,7 +9048,7 @@ UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP # connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT, # SOCAT_PEERPORT when applicable while read KEYW FEAT TEST_SOCKADDR TEST_PEERADDR TEST_SOCKPORT TEST_PEERPORT; do -if [ -z "$KEYW" ]; then continue; fi +if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi # test_proto="$(echo $KEYW |tr A-Z a-z)" NAME=${KEYW}LISTENENV @@ -9139,7 +9141,7 @@ UNIX UNIX $td/test\$N.server $td/test\$N.client # test: environment variables from ancillary message while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE do -if [ -z "$PF" ]; then continue; fi +if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi # pf="$(echo $PF |tr A-Z a-z)" proto="$(echo $KEYW |tr A-Z a-z)" @@ -9245,7 +9247,7 @@ IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_DSTADDR root [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT root 35 IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS root xaa000000 -UNIX UNIX $td/test\$N.server - , so-timestamp TIMESTAMP user $(date '+%a %b %e %H:%M:.. %Y') +#UNIX UNIX $td/test\$N.server - , so-timestamp TIMESTAMP user $(date '+%a %b %e %H:%M:.. %Y') " From bc4fefdc50aea8e6ac47e72cdec03cb4d59bf298 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 12 Oct 2008 18:56:01 +0200 Subject: [PATCH 59/75] AIX: cast for hstrerror() --- CHANGES | 7 +++++-- README | 4 ++-- xio-ip4.c | 6 ++++-- xio-proxy.c | 6 ++++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 80ab592..15a7e6d 100644 --- a/CHANGES +++ b/CHANGES @@ -98,8 +98,11 @@ corrections: feature (thanks to Pavan Gadi for reporting this bug) porting: - socat should now build under MacOS X 10.4 (thanks to Camillo Lugaresi for - providing the patch) + socat should now build under MacOS X 10.4 (thanks to Camillo Lugaresi + for providing the patch) + + socat compiles and runs on AIX (thanks to Andi Mather for testing and + patching) further changes: filan -s prefixes output with FD number if more than one FD diff --git a/README b/README index d92eb4a..6bf0463 100644 --- a/README +++ b/README @@ -45,11 +45,11 @@ distributions. platforms --------- -socat 1.6.0 was compiled and more or less successfully tested under the +socat 1.7.0 was compiled and more or less successfully tested under the following operating systems: SuSE Linux 10.1 on x86 -AIX 5.2 on PPC with gcc +AIX 5.3 on PPC with gcc Solaris 9 on Sparc with gcc FreeBSD 6.1 on x86 HP-UX B 11.11 on PA-RISC with gcc diff --git a/xio-ip4.c b/xio-ip4.c index d40796b..076ce1f 100644 --- a/xio-ip4.c +++ b/xio-ip4.c @@ -32,9 +32,10 @@ int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) { netmask_in->s_addr = htonl((0xffffffff << (32-bits))); } else if (delimpos = strchr(rangename1, ':')) { if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) { + /* note: cast is req on AIX: */ Error2("gethostbyname(\"%s\"): %s", delimpos+1, h_errno == NETDB_INTERNAL ? strerror(errno) : - hstrerror(h_errno)); + (char *)hstrerror(h_errno)); return STAT_NORETRY; } netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0]; @@ -47,9 +48,10 @@ int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) { struct hostent *nameaddr; *delimpos = 0; if ((nameaddr = Gethostbyname(rangename1)) == NULL) { + /* note: cast is req on AIX: */ Error2("gethostbyname(\"%s\"): %s", rangename1, h_errno == NETDB_INTERNAL ? strerror(errno) : - hstrerror(h_errno)); + (char *)hstrerror(h_errno)); free(rangename1); return STAT_NORETRY; } diff --git a/xio-proxy.c b/xio-proxy.c index 984933c..622e2c5 100644 --- a/xio-proxy.c +++ b/xio-proxy.c @@ -244,9 +244,11 @@ int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, host = Gethostbyname(targetname); if (host == NULL) { int level = E_WARN; + /* note: cast is req on AIX: */ Msg2(level, "gethostbyname(\"%s\"): %s", targetname, - h_errno == NETDB_INTERNAL ? strerror(errno) : - hstrerror(h_errno)/*0 h_messages[h_errno-1]*/); + h_errno == NETDB_INTERNAL ? strerror(errno) : + (char *)hstrerror(h_errno)/*0 h_messages[h_errno-1]*/); + proxyvars->targetaddr = strdup(targetname); } else { #define LEN 16 /* www.xxx.yyy.zzz\0 */ From 88b1cdc72362ff67faee55c9ec6e5ad4e4130260 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:07:23 +0200 Subject: [PATCH 60/75] added macro Error11() --- error.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/error.h b/error.h index 1ef73a6..385738c 100644 --- a/error.h +++ b/error.h @@ -52,6 +52,7 @@ #define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8) #define Error9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define Error10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) +#define Error11(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #else /* !(WITH_MSGLEVEL >= E_ERROR) */ #define Error(m) #define Error1(m,a1) @@ -64,6 +65,7 @@ #define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8) #define Error9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) #define Error10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) +#define Error11(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) #endif /* !(WITH_MSGLEVEL <= E_ERROR) */ #if WITH_MSGLEVEL <= E_WARN From 32219f51fdd671cc78c26954006f2d6dbb968546 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:13:21 +0200 Subject: [PATCH 61/75] configure.in: corrected typo in HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 035fe21..fc82ae3 100644 --- a/configure.in +++ b/configure.in @@ -1391,7 +1391,7 @@ AC_TYPEOF_COMPONENT([#include ], struct stat64, st_blksize, HAVE_TYP AC_TYPEOF_COMPONENT([#include ], struct stat64, st_blocks, HAVE_TYPEOF_ST64_BLOCKS, sc_cv_type_stat64_stblocks_basic) fi -AC_TYPEOF_COMPONENT([#include ], struct timeval, tv_usec, HAVE_TYPEOF_STRUCT_TIMEVAL_TVUSEC, sc_cv_type_struct_timeval_tvusec) +AC_TYPEOF_COMPONENT([#include ], struct timeval, tv_usec, HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC, sc_cv_type_struct_timeval_tv_usec) AC_TYPEOF_COMPONENT([#include #include From 674166acbd5f80102b1c504b576700df9ee3ff78 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:15:18 +0200 Subject: [PATCH 62/75] socat.c: adapted xiopoll() messages for struct timeval --- socat.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/socat.c b/socat.c index eb2c2dd..eaa5f37 100644 --- a/socat.c +++ b/socat.c @@ -684,8 +684,9 @@ int childleftdata(xiofile_t *xfd) { } while (retval < 0 && errno == EINTR); if (retval < 0) { - Error4("xiopoll({%d,%0o}, 1, %d): %s", - in.fd, in.events, timeout, strerror(errno)); + Error5("xiopoll({%d,%0o}, 1, {"F_tv_sec"."F_tv_usec"}): %s", + in.fd, in.events, timeout.tv_sec, timeout.tv_usec, + strerror(errno)); return -1; } if (retval == 0) { @@ -896,10 +897,10 @@ int _socat(void) { */ if (retval < 0) { - Error10("xiopoll({%d,%0o}{%d,%0o}{%d,%0o}{%d,%0o}, 4, %d): %s", + Error11("xiopoll({%d,%0o}{%d,%0o}{%d,%0o}{%d,%0o}, 4, {"F_tv_sec"."F_tv_usec"}): %s", fds[0].fd, fds[0].events, fds[1].fd, fds[1].events, fds[2].fd, fds[2].events, fds[3].fd, fds[3].events, - timeout, strerror(errno)); + timeout.tv_sec, timeout.tv_usec, strerror(errno)); return -1; } else if (retval == 0) { Info2("poll timed out (no data within %ld.%06ld seconds)", From 01acd2402f70611fac8d33460f3176886cd9f33f Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:15:55 +0200 Subject: [PATCH 63/75] procan-cdefs.c: added output of socket defines --- procan-cdefs.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/procan-cdefs.c b/procan-cdefs.c index d5c1729..f7442f9 100644 --- a/procan-cdefs.c +++ b/procan-cdefs.c @@ -85,15 +85,77 @@ int procan_cdefs(FILE *outfile) { #endif /* socket constants */ +#ifdef PF_UNIX + fprintf(outfile, "#define PF_UNIX %d\n", PF_UNIX); +#elif defined(PF_LOCAL) + fprintf(outfile, "#define PF_LOCAL %d\n", PF_LOCAL); +#endif +#ifdef PF_INET + fprintf(outfile, "#define PF_INET %d\n", PF_INET); +#endif #ifdef PF_INET6 fprintf(outfile, "#define PF_INET6 %d\n", PF_INET6); #endif +#ifdef PF_APPLETALK + fprintf(outfile, "#define PF_APPLETALK %d\n", PF_APPLETALK); +#endif +#ifdef PF_PACKET + fprintf(outfile, "#define PF_PACKET %d\n", PF_PACKET); +#endif +#ifdef SOCK_STREAM + fprintf(outfile, "#define SOCK_STREAM %d\n", SOCK_STREAM); +#endif #ifdef SOCK_DGRAM fprintf(outfile, "#define SOCK_DGRAM %d\n", SOCK_DGRAM); #endif +#ifdef SOCK_RAW + fprintf(outfile, "#define SOCK_RAW %d\n", SOCK_RAW); +#endif +#ifdef SOCK_SEQPACKET + fprintf(outfile, "#define SOCK_SEQPACKET %d\n", SOCK_SEQPACKET); +#endif +#ifdef SOCK_PACKET + fprintf(outfile, "#define SOCK_PACKET %d\n", SOCK_PACKET); +#endif +#ifdef IPPROTO_IP + fprintf(outfile, "#define IPPROTO_IP %d\n", IPPROTO_IP); +#endif +#ifdef IPPROTO_TCP + fprintf(outfile, "#define IPPROTO_TCP %d\n", IPPROTO_TCP); +#endif +#ifdef IPPROTO_UDP + fprintf(outfile, "#define IPPROTO_UDP %d\n", IPPROTO_UDP); +#endif +#ifdef IPPROTO_SCTP + fprintf(outfile, "#define IPPROTO_SCTP %d\n", IPPROTO_SCTP); +#endif +#ifdef IPPROTO_DCCP + fprintf(outfile, "#define IPPROTO_DCCP %d\n", IPPROTO_DCCP); +#endif #ifdef SOL_SOCKET fprintf(outfile, "#define SOL_SOCKET 0x%x\n", SOL_SOCKET); #endif +#ifdef SOL_PACKET + fprintf(outfile, "#define SOL_PACKET 0x%x\n", SOL_PACKET); +#endif +#ifdef SOL_IP + fprintf(outfile, "#define SOL_IP 0x%x\n", SOL_IP); +#endif +#ifdef SOL_IPV6 + fprintf(outfile, "#define SOL_IPV6 0x%x\n", SOL_IPV6); +#endif +#ifdef SOL_TCP + fprintf(outfile, "#define SOL_TCP 0x%x\n", SOL_TCP); +#endif +#ifdef SOL_UDP + fprintf(outfile, "#define SOL_UDP 0x%x\n", SOL_UDP); +#endif +#ifdef SOL_SCTP + fprintf(outfile, "#define SOL_SCTP 0x%x\n", SOL_SCTP); +#endif +#ifdef SOL_DCCP + fprintf(outfile, "#define SOL_DCCP 0x%x\n", SOL_DCCP); +#endif #ifdef SO_REUSEADDR fprintf(outfile, "#define SO_REUSEADDR %d\n", SO_REUSEADDR); #endif From a8ff9481e964cec7eb890731e806fb73cf96407a Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:17:23 +0200 Subject: [PATCH 64/75] xioopts.h: added GROUP_IP_SCTP to GROUP_IPAPP --- xioopts.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xioopts.h b/xioopts.h index fda6718..db61752 100644 --- a/xioopts.h +++ b/xioopts.h @@ -162,7 +162,7 @@ enum e_func { #define GROUP_IP_UDP 0x01000000 #define GROUP_IP_TCP 0x02000000 -#define GROUP_IPAPP (GROUP_IP_UDP|GROUP_IP_TCP) /* true: indicates one of UDP, TCP */ +#define GROUP_IPAPP (GROUP_IP_UDP|GROUP_IP_TCP|GROUP_IP_SCTP) /* true: indicates one of UDP, TCP, SCTP */ #define GROUP_IP_SOCKS4 0x04000000 #define GROUP_OPENSSL 0x08000000 From 29d3f9438b4c4d125c49525216d32b6edd8fff97 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:18:37 +0200 Subject: [PATCH 65/75] xioopts.c: added cast for ip4addr in error message --- xioopts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xioopts.c b/xioopts.c index 5b94f24..a5578ee 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3090,7 +3090,7 @@ int applyopts(int fd, struct opt *opts, enum e_phase phase) { &opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr)) < 0) { Error6("setsockopt(%d, %d, %d, {0x%x}, "F_Zu"): %s", fd, opt->desc->major, opt->desc->minor, - opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr), + *(uint32_t *)&opt->value.u_ip4addr, sizeof(opt->value.u_ip4addr), strerror(errno)); } break; From 180a28b608db444e592c3127c68f61e3b8003c4a Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:23:01 +0200 Subject: [PATCH 66/75] xio-socket.c: adapted xiopoll() messages for struct timeval --- xio-socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xio-socket.c b/xio-socket.c index b385bea..b924f66 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -852,8 +852,8 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen, writefd.events = (POLLIN|POLLHUP|POLLERR); result = xiopoll(&writefd, 1, &timeout); if (result < 0) { - Msg3(level, "poll({%d,POLLIN|POLLHUP|POLLER},,%d): %s", - xfd->fd, timeout, strerror(errno)); + Msg4(level, "xiopoll({%d,POLLIN|POLLHUP|POLLER},,{"F_tv_sec"."F_tv_usec"): %s", + xfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno)); return STAT_RETRYLATER; } if (result == 0) { @@ -1277,7 +1277,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags, #if HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined(SA_SIGINFO) act.sa_sigaction = xiosigaction_hasread; #else /* Linux 2.0(.33) does not have sigaction.sa_sigaction */ - act.sa_handler = xiosighandler_hasread; + act.sa_handler = xiosigaction_hasread; #endif if (Sigaction(SIGUSR1, &act, NULL) < 0) { /*! Linux man does not explicitely say that errno is defined */ From 5753ca66be6a44dfae34176015662db0eb884327 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:56:47 +0200 Subject: [PATCH 67/75] doc/dest-unreach.css: no html tags --- doc/dest-unreach.css | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/doc/dest-unreach.css b/doc/dest-unreach.css index b5dd82f..61a8dac 100644 --- a/doc/dest-unreach.css +++ b/doc/dest-unreach.css @@ -1,15 +1,9 @@ - - -dest-unreach.org stylesheet - - - - - From 45c6d0536adb01e8f0f8a1a38c9974c26b81c88c Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 14 Oct 2008 22:57:51 +0200 Subject: [PATCH 68/75] MacOSX: added missing parentheses; removed outcommented readline data --- test.sh | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/test.sh b/test.sh index 9281e9f..3ff4cfb 100755 --- a/test.sh +++ b/test.sh @@ -1945,7 +1945,7 @@ waittcp6port () { FreeBSD) l=$(netstat -an |egrep -i 'tcp(6|46) .*[0-9*][:.]'$port' .* listen') ;; NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; - Darwin) l=$(netstat -an |egrep '^tcp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+ +LISTEN' ;; + Darwin) l=$(netstat -an |egrep '^tcp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+ +LISTEN') ;; AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; @@ -1975,7 +1975,7 @@ waitudp6port () { FreeBSD) l=$(netstat -an |egrep '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;; NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;; OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; - Darwin) l=$(netstat -an |egrep '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+' ;; + Darwin) l=$(netstat -an |egrep '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;; AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;; SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;; #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;; @@ -4615,18 +4615,6 @@ $ECHO "exit\n\c" usleep $MICROS ) >"$tpi" -#cat >$tr < prog> test 1 -#executing test 1 -#prog> ./readline-test.sh got SIGINT -# test 2 -#executing test 2 -#prog> prog> exit -#EOF cat >$tr < Date: Wed, 15 Oct 2008 22:49:27 +0200 Subject: [PATCH 69/75] V1.7.0.0: platform config files --- Config/Makefile.AIX-5-3 | 195 +++++++++++++ Config/Makefile.Cygwin-1-5-25 | 195 +++++++++++++ Config/Makefile.FreeBSD-6-1 | 66 +++-- Config/Makefile.Linux-2-6-24 | 195 +++++++++++++ Config/Makefile.MacOSX-10-5 | 195 +++++++++++++ Config/Makefile.NetBSD-4-0 | 195 +++++++++++++ Config/Makefile.OpenBSD-4-3 | 195 +++++++++++++ Config/Makefile.SunOS-5-10 | 195 +++++++++++++ Config/config.AIX-5-3.h | 523 ++++++++++++++++++++++++++++++++++ Config/config.Cygwin-1-5-25.h | 522 +++++++++++++++++++++++++++++++++ Config/config.FreeBSD-6-1.h | 47 ++- Config/config.Linux-2-6-24.h | 522 +++++++++++++++++++++++++++++++++ Config/config.MacOSX-10-5.h | 522 +++++++++++++++++++++++++++++++++ Config/config.NetBSD-4-0.h | 522 +++++++++++++++++++++++++++++++++ Config/config.OpenBSD-4-3.h | 522 +++++++++++++++++++++++++++++++++ Config/config.SunOS-5-10.h | 522 +++++++++++++++++++++++++++++++++ 16 files changed, 5104 insertions(+), 29 deletions(-) create mode 100644 Config/Makefile.AIX-5-3 create mode 100644 Config/Makefile.Cygwin-1-5-25 create mode 100644 Config/Makefile.Linux-2-6-24 create mode 100644 Config/Makefile.MacOSX-10-5 create mode 100644 Config/Makefile.NetBSD-4-0 create mode 100644 Config/Makefile.OpenBSD-4-3 create mode 100644 Config/Makefile.SunOS-5-10 create mode 100644 Config/config.AIX-5-3.h create mode 100644 Config/config.Cygwin-1-5-25.h create mode 100644 Config/config.Linux-2-6-24.h create mode 100644 Config/config.MacOSX-10-5.h create mode 100644 Config/config.NetBSD-4-0.h create mode 100644 Config/config.OpenBSD-4-3.h create mode 100644 Config/config.SunOS-5-10.h diff --git a/Config/Makefile.AIX-5-3 b/Config/Makefile.AIX-5-3 new file mode 100644 index 0000000..e07ac40 --- /dev/null +++ b/Config/Makefile.AIX-5-3 @@ -0,0 +1,195 @@ +# source: Makefile.in +# Copyright Gerhard Rieger 2001-2008 +# Published under the GNU General Public License V.2, see file COPYING + +# note: @...@ forms are filled in by configure script + +SHELL = /bin/sh +AR = ar +RANLIB = ranlib + +.SUFFIXES: .c .o + +prefix = /usr/local +exec_prefix = ${prefix} + +BINDEST = ${exec_prefix}/bin + +datarootdir = ${prefix}/share +MANDEST = ${datarootdir}/man + +srcdir = . + + +CC = cc -qlanglvl=extc89 +CCOPTS = $(CCOPT) + +SYSDEFS = +CPPFLAGS = -I. +#0 INCLS = -I. @V_INCL@ +DEFS = -DHAVE_CONFIG_H +LIBS = -lbsd -lssl -lcrypto +LDFLAGS = + +INSTALL = ./install-sh -c + +#OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) + + +#0 CFLAGS = -O $(CCOPTS) $(DEFS) $(INCLS) +CFLAGS = -O $(CCOPTS) $(DEFS) $(CPPFLAGS) +CLIBS = $(LIBS) +#CLIBS = $(LIBS) -lm -lefence +XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ + xiosignal.c xiosigchld.c xioread.c xiowrite.c \ + xiolayer.c xioshutdown.c xioclose.c xioexit.c \ + xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ + xio-gopen.c xio-creat.c xio-file.c xio-named.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-sctp.c xio-rawip.c \ + xio-socks.c xio-proxy.c xio-udp.c \ + xio-rawip.c \ + xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ + xio-pty.c xio-openssl.c xio-streams.c\ + xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c +XIOOBJS = $(XIOSRCS:.c=.o) +UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c +UTLOBJS = $(UTLSRCS:.c=.o) +CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c +OFILES = $(CFILES:.c=.o) +PROGS = socat procan filan + +HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ + xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ + xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-system.h xio-termios.h xio-readline.h \ + xio-pty.h xio-openssl.h xio-streams.h \ + xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h + + +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html +SHFILES = daemon.sh mail.sh ftp.sh readline.sh +TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ + proxy.sh socks4a-echo.sh testcert.conf +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ + Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h + +all: progs doc + +scmclean: gitclean + +gitclean: distclean docclean + rm -f Makefile.bak configure + +doc: doc/socat.1 doc/socat.html + +docclean: + rm -f doc/socat.1 doc/socat.html + +doc/socat.1: doc/socat.yo + yodl2man -o $@ $+ + +doc/socat.html: doc/socat.yo + cd doc; yodl2html -o socat.html socat.yo; cd .. + +progs: $(PROGS) + +depend: $(CFILES) $(HFILES) + makedepend $(SYSDEFS) $(CFILES) + +socat: socat.o libxio.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) + +PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o +procan: $(PROCAN_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) + +filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) + +libxio.a: $(XIOOBJS) $(UTLOBJS) + $(AR) r $@ $(XIOOBJS) $(UTLOBJS) + $(RANLIB) $@ + +doc: doc/xio.help +# + +strip: progs + strip $(PROGS) + +install: progs $(srcdir)/doc/socat.1 + mkdir -p $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) + mkdir -p $(DESTDIR)$(MANDEST)/man1 + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + +uninstall: + rm -f $(DESTDIR)$(BINDEST)/socat + rm -f $(DESTDIR)$(BINDEST)/procan + rm -f $(DESTDIR)$(BINDEST)/filan + rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 + +# make a GNU-zipped tar ball of the source files +dist: socat.tar.gz socat.tar.bz2 + +socat.tar.gz: socat.tar + gzip -9 socat.tar.gz + +socat.tar.bz2: socat.tar + bzip2 -9 socat.tar.bz2 + +VERSION = `sed 's/"//g' VERSION` +TARDIR = socat-$(VERSION) +socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec + if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi + tar cf - $+ |(cd $(TARDIR); tar xf -) + tar cvf socat.tar $(TARDIR) + rm -f $(TARDIR)/COPYING # write protected + rm -r $(TARDIR) + +clean: + rm -f *.o libxio.a socat procan filan \ + socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ + socat.out compile.log test.log + +# remove all files that are generated from the original socat distribution +# note that Makefile is also removed, so you have to start with ./configure +# again +distclean: clean + rm -f config.status config.cache config.log config.h Makefile + rm -rf autom4te.cache + +info: socat + uname -a >socat.out + ./socat -V >>socat.out + ./socat -hh >>socat.out + +# perform some tests on socat +test: progs + ./test.sh + +cert: + # prepare critical files with correct permissions to avoid race cond + >cert.key + >cert.pem + chmod 600 cert.key cert.pem + # generate a private key + openssl genrsa -out cert.key 1024 + # generate a self signed cert + openssl req -new -key cert.key -x509 -days 3653 -out cert.crt + # ...enter fields + # generate the pem file + cat cert.key cert.crt >cert.pem + #echo use cert.pem on requestors side, i.e. with option cert=cert.pem + #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt diff --git a/Config/Makefile.Cygwin-1-5-25 b/Config/Makefile.Cygwin-1-5-25 new file mode 100644 index 0000000..c152950 --- /dev/null +++ b/Config/Makefile.Cygwin-1-5-25 @@ -0,0 +1,195 @@ +# source: Makefile.in +# Copyright Gerhard Rieger 2001-2008 +# Published under the GNU General Public License V.2, see file COPYING + +# note: @...@ forms are filled in by configure script + +SHELL = /bin/sh +AR = ar +RANLIB = ranlib + +.SUFFIXES: .c .o + +prefix = /usr/local +exec_prefix = ${prefix} + +BINDEST = ${exec_prefix}/bin + +datarootdir = ${prefix}/share +MANDEST = ${datarootdir}/man + +srcdir = . + + +CC = gcc +CCOPTS = $(CCOPT) -Wall -Wno-parentheses + +SYSDEFS = +CPPFLAGS = -I. +#0 INCLS = -I. @V_INCL@ +DEFS = -DHAVE_CONFIG_H +LIBS = -lwrap -lutil -lreadline -lssl -lcrypto +LDFLAGS = + +INSTALL = /usr/bin/install -c + +#OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) + + +#0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) +CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) +CLIBS = $(LIBS) +#CLIBS = $(LIBS) -lm -lefence +XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ + xiosignal.c xiosigchld.c xioread.c xiowrite.c \ + xiolayer.c xioshutdown.c xioclose.c xioexit.c \ + xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ + xio-gopen.c xio-creat.c xio-file.c xio-named.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-sctp.c xio-rawip.c \ + xio-socks.c xio-proxy.c xio-udp.c \ + xio-rawip.c \ + xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ + xio-pty.c xio-openssl.c xio-streams.c\ + xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c +XIOOBJS = $(XIOSRCS:.c=.o) +UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c +UTLOBJS = $(UTLSRCS:.c=.o) +CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c +OFILES = $(CFILES:.c=.o) +PROGS = socat procan filan + +HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ + xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ + xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-system.h xio-termios.h xio-readline.h \ + xio-pty.h xio-openssl.h xio-streams.h \ + xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h + + +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html +SHFILES = daemon.sh mail.sh ftp.sh readline.sh +TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ + proxy.sh socks4a-echo.sh testcert.conf +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ + Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h + +all: progs doc + +scmclean: gitclean + +gitclean: distclean docclean + rm -f Makefile.bak configure + +doc: doc/socat.1 doc/socat.html + +docclean: + rm -f doc/socat.1 doc/socat.html + +doc/socat.1: doc/socat.yo + yodl2man -o $@ $+ + +doc/socat.html: doc/socat.yo + cd doc; yodl2html -o socat.html socat.yo; cd .. + +progs: $(PROGS) + +depend: $(CFILES) $(HFILES) + makedepend $(SYSDEFS) $(CFILES) + +socat: socat.o libxio.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) + +PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o +procan: $(PROCAN_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) + +filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) + +libxio.a: $(XIOOBJS) $(UTLOBJS) + $(AR) r $@ $(XIOOBJS) $(UTLOBJS) + $(RANLIB) $@ + +doc: doc/xio.help +# + +strip: progs + strip $(PROGS) + +install: progs $(srcdir)/doc/socat.1 + mkdir -p $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) + mkdir -p $(DESTDIR)$(MANDEST)/man1 + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + +uninstall: + rm -f $(DESTDIR)$(BINDEST)/socat + rm -f $(DESTDIR)$(BINDEST)/procan + rm -f $(DESTDIR)$(BINDEST)/filan + rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 + +# make a GNU-zipped tar ball of the source files +dist: socat.tar.gz socat.tar.bz2 + +socat.tar.gz: socat.tar + gzip -9 socat.tar.gz + +socat.tar.bz2: socat.tar + bzip2 -9 socat.tar.bz2 + +VERSION = `sed 's/"//g' VERSION` +TARDIR = socat-$(VERSION) +socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec + if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi + tar cf - $+ |(cd $(TARDIR); tar xf -) + tar cvf socat.tar $(TARDIR) + rm -f $(TARDIR)/COPYING # write protected + rm -r $(TARDIR) + +clean: + rm -f *.o libxio.a socat procan filan \ + socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ + socat.out compile.log test.log + +# remove all files that are generated from the original socat distribution +# note that Makefile is also removed, so you have to start with ./configure +# again +distclean: clean + rm -f config.status config.cache config.log config.h Makefile + rm -rf autom4te.cache + +info: socat + uname -a >socat.out + ./socat -V >>socat.out + ./socat -hh >>socat.out + +# perform some tests on socat +test: progs + ./test.sh + +cert: + # prepare critical files with correct permissions to avoid race cond + >cert.key + >cert.pem + chmod 600 cert.key cert.pem + # generate a private key + openssl genrsa -out cert.key 1024 + # generate a self signed cert + openssl req -new -key cert.key -x509 -days 3653 -out cert.crt + # ...enter fields + # generate the pem file + cat cert.key cert.crt >cert.pem + #echo use cert.pem on requestors side, i.e. with option cert=cert.pem + #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt diff --git a/Config/Makefile.FreeBSD-6-1 b/Config/Makefile.FreeBSD-6-1 index 0d8faae..2cd0bfe 100644 --- a/Config/Makefile.FreeBSD-6-1 +++ b/Config/Makefile.FreeBSD-6-1 @@ -1,5 +1,5 @@ -# source: Makefile.FreeBSD-6-1 -# Copyright Gerhard Rieger 2001-2006 +# source: Makefile.in +# Copyright Gerhard Rieger 2001-2008 # Published under the GNU General Public License V.2, see file COPYING # note: @...@ forms are filled in by configure script @@ -15,7 +15,8 @@ exec_prefix = ${prefix} BINDEST = ${exec_prefix}/bin -MANDEST = ${prefix}/man +datarootdir = ${prefix}/share +MANDEST = ${datarootdir}/man srcdir = . @@ -27,7 +28,7 @@ SYSDEFS = -D_LONGLONG CPPFLAGS = -I. #0 INCLS = -I. @V_INCL@ DEFS = -DHAVE_CONFIG_H -LIBS = -lwrap -lutil -lreadline -lssl +LIBS = -lwrap -lutil -lreadline -lssl LDFLAGS = INSTALL = /usr/bin/install -c @@ -44,13 +45,16 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ xiolayer.c xioshutdown.c xioclose.c xioexit.c \ xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ xio-gopen.c xio-creat.c xio-file.c xio-named.c \ - xio-socket.c xio-listen.c xio-unix.c xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c xio-socks.c xio-proxy.c xio-udp.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-sctp.c xio-rawip.c \ + xio-socks.c xio-proxy.c xio-udp.c \ xio-rawip.c \ xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ - xio-pty.c xio-openssl.c \ + xio-pty.c xio-openssl.c xio-streams.c\ xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c XIOOBJS = $(XIOSRCS:.c=.o) -UTLSRCS = error.c dalan.c procan.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c +UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c UTLOBJS = $(UTLSRCS:.c=.o) CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c OFILES = $(CFILES:.c=.o) @@ -59,29 +63,43 @@ PROGS = socat procan filan HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ - xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h xio-socket.h \ - xio-listen.h xio-unix.h xio-rawip.h xio-ip.h xio-ip4.h xio-ip6.h \ - xio-ipapp.h xio-tcp.h xio-udp.h xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ xio-system.h xio-termios.h xio-readline.h \ - xio-pty.h xio-openssl.h \ + xio-pty.h xio-openssl.h xio-streams.h \ xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h -DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf -OSFILES = Config/Makefile.Linux-2-6-16 Config/config.Linux-2-6-16.h \ - Config/Makefile.AIX-5-1 Config/config.AIX-5-1.h \ - Config/Makefile.SunOS-5-8 Config/config.SunOS-5-8.h \ - Config/Makefile.HP-UX-B-11-11 Config/config.HP-UX-B-11-11.h \ +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ - Config/Makefile.NetBSD-2-0-2 Config/config.NetBSD-2-0-2.h \ - Config/Makefile.OpenBSD-3-8 Config/config.OpenBSD-3-8.h \ - Config/Makefile.Tru64-5-1B Config/config.Tru64-5-1B.h + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h +all: progs doc -all: progs +scmclean: gitclean + +gitclean: distclean docclean + rm -f Makefile.bak configure + +doc: doc/socat.1 doc/socat.html + +docclean: + rm -f doc/socat.1 doc/socat.html + +doc/socat.1: doc/socat.yo + yodl2man -o $@ $+ + +doc/socat.html: doc/socat.yo + cd doc; yodl2html -o socat.html socat.yo; cd .. progs: $(PROGS) @@ -91,7 +109,7 @@ depend: $(CFILES) $(HFILES) socat: socat.o libxio.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) -PROCAN_OBJS=procan_main.o procan.o hostan.o error.o sycls.o sysutils.o utils.o +PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o procan: $(PROCAN_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) @@ -108,17 +126,17 @@ doc: doc/xio.help strip: progs strip $(PROGS) -install: progs doc/socat.1 +install: progs $(srcdir)/doc/socat.1 mkdir -p $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) mkdir -p $(DESTDIR)$(MANDEST)/man1 - $(INSTALL) -m 644 doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ uninstall: rm -f $(DESTDIR)$(BINDEST)/socat - rm -f $(DESTDIR)$(BINDEST)/procat + rm -f $(DESTDIR)$(BINDEST)/procan rm -f $(DESTDIR)$(BINDEST)/filan rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 diff --git a/Config/Makefile.Linux-2-6-24 b/Config/Makefile.Linux-2-6-24 new file mode 100644 index 0000000..58e0608 --- /dev/null +++ b/Config/Makefile.Linux-2-6-24 @@ -0,0 +1,195 @@ +# source: Makefile.in +# Copyright Gerhard Rieger 2001-2008 +# Published under the GNU General Public License V.2, see file COPYING + +# note: @...@ forms are filled in by configure script + +SHELL = /bin/sh +AR = ar +RANLIB = ranlib + +.SUFFIXES: .c .o + +prefix = /usr/local +exec_prefix = ${prefix} + +BINDEST = ${exec_prefix}/bin + +datarootdir = ${prefix}/share +MANDEST = ${datarootdir}/man + +srcdir = . + + +CC = gcc +CCOPTS = $(CCOPT) -Wall -Wno-parentheses + +SYSDEFS = +CPPFLAGS = -I. +#0 INCLS = -I. @V_INCL@ +DEFS = -DHAVE_CONFIG_H +LIBS = -lwrap -lutil -lreadline -lssl +LDFLAGS = + +INSTALL = /usr/bin/install -c + +#OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) + + +#0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) +CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) +CLIBS = $(LIBS) +#CLIBS = $(LIBS) -lm -lefence +XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ + xiosignal.c xiosigchld.c xioread.c xiowrite.c \ + xiolayer.c xioshutdown.c xioclose.c xioexit.c \ + xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ + xio-gopen.c xio-creat.c xio-file.c xio-named.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-sctp.c xio-rawip.c \ + xio-socks.c xio-proxy.c xio-udp.c \ + xio-rawip.c \ + xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ + xio-pty.c xio-openssl.c xio-streams.c\ + xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c +XIOOBJS = $(XIOSRCS:.c=.o) +UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c +UTLOBJS = $(UTLSRCS:.c=.o) +CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c +OFILES = $(CFILES:.c=.o) +PROGS = socat procan filan + +HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ + xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ + xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-system.h xio-termios.h xio-readline.h \ + xio-pty.h xio-openssl.h xio-streams.h \ + xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h + + +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html +SHFILES = daemon.sh mail.sh ftp.sh readline.sh +TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ + proxy.sh socks4a-echo.sh testcert.conf +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ + Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h + +all: progs doc + +scmclean: gitclean + +gitclean: distclean docclean + rm -f Makefile.bak configure + +doc: doc/socat.1 doc/socat.html + +docclean: + rm -f doc/socat.1 doc/socat.html + +doc/socat.1: doc/socat.yo + yodl2man -o $@ $+ + +doc/socat.html: doc/socat.yo + cd doc; yodl2html -o socat.html socat.yo; cd .. + +progs: $(PROGS) + +depend: $(CFILES) $(HFILES) + makedepend $(SYSDEFS) $(CFILES) + +socat: socat.o libxio.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) + +PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o +procan: $(PROCAN_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) + +filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) + +libxio.a: $(XIOOBJS) $(UTLOBJS) + $(AR) r $@ $(XIOOBJS) $(UTLOBJS) + $(RANLIB) $@ + +doc: doc/xio.help +# + +strip: progs + strip $(PROGS) + +install: progs $(srcdir)/doc/socat.1 + mkdir -p $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) + mkdir -p $(DESTDIR)$(MANDEST)/man1 + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + +uninstall: + rm -f $(DESTDIR)$(BINDEST)/socat + rm -f $(DESTDIR)$(BINDEST)/procan + rm -f $(DESTDIR)$(BINDEST)/filan + rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 + +# make a GNU-zipped tar ball of the source files +dist: socat.tar.gz socat.tar.bz2 + +socat.tar.gz: socat.tar + gzip -9 socat.tar.gz + +socat.tar.bz2: socat.tar + bzip2 -9 socat.tar.bz2 + +VERSION = `sed 's/"//g' VERSION` +TARDIR = socat-$(VERSION) +socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec + if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi + tar cf - $+ |(cd $(TARDIR); tar xf -) + tar cvf socat.tar $(TARDIR) + rm -f $(TARDIR)/COPYING # write protected + rm -r $(TARDIR) + +clean: + rm -f *.o libxio.a socat procan filan \ + socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ + socat.out compile.log test.log + +# remove all files that are generated from the original socat distribution +# note that Makefile is also removed, so you have to start with ./configure +# again +distclean: clean + rm -f config.status config.cache config.log config.h Makefile + rm -rf autom4te.cache + +info: socat + uname -a >socat.out + ./socat -V >>socat.out + ./socat -hh >>socat.out + +# perform some tests on socat +test: progs + ./test.sh + +cert: + # prepare critical files with correct permissions to avoid race cond + >cert.key + >cert.pem + chmod 600 cert.key cert.pem + # generate a private key + openssl genrsa -out cert.key 1024 + # generate a self signed cert + openssl req -new -key cert.key -x509 -days 3653 -out cert.crt + # ...enter fields + # generate the pem file + cat cert.key cert.crt >cert.pem + #echo use cert.pem on requestors side, i.e. with option cert=cert.pem + #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt diff --git a/Config/Makefile.MacOSX-10-5 b/Config/Makefile.MacOSX-10-5 new file mode 100644 index 0000000..43a8f72 --- /dev/null +++ b/Config/Makefile.MacOSX-10-5 @@ -0,0 +1,195 @@ +# source: Makefile.in +# Copyright Gerhard Rieger 2001-2008 +# Published under the GNU General Public License V.2, see file COPYING + +# note: @...@ forms are filled in by configure script + +SHELL = /bin/sh +AR = ar +RANLIB = ranlib + +.SUFFIXES: .c .o + +prefix = /usr/local +exec_prefix = ${prefix} + +BINDEST = ${exec_prefix}/bin + +datarootdir = ${prefix}/share +MANDEST = ${datarootdir}/man + +srcdir = . + + +CC = gcc +CCOPTS = $(CCOPT) -Wall -Wno-parentheses + +SYSDEFS = -D__DYNAMIC__ +CPPFLAGS = -I. -I/usr/local/include +#0 INCLS = -I. @V_INCL@ +DEFS = -DHAVE_CONFIG_H +LIBS = -lwrap -lutil -lresolv -lreadline -lssl -lcrypto +LDFLAGS = + +INSTALL = /usr/bin/install -c + +#OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) + + +#0 CFLAGS = -O -D_GNU_SOURCE -L/usr/local/lib $(CCOPTS) $(DEFS) $(INCLS) +CFLAGS = -O -D_GNU_SOURCE -L/usr/local/lib $(CCOPTS) $(DEFS) $(CPPFLAGS) +CLIBS = $(LIBS) +#CLIBS = $(LIBS) -lm -lefence +XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ + xiosignal.c xiosigchld.c xioread.c xiowrite.c \ + xiolayer.c xioshutdown.c xioclose.c xioexit.c \ + xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ + xio-gopen.c xio-creat.c xio-file.c xio-named.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-sctp.c xio-rawip.c \ + xio-socks.c xio-proxy.c xio-udp.c \ + xio-rawip.c \ + xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ + xio-pty.c xio-openssl.c xio-streams.c\ + xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c +XIOOBJS = $(XIOSRCS:.c=.o) +UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c +UTLOBJS = $(UTLSRCS:.c=.o) +CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c +OFILES = $(CFILES:.c=.o) +PROGS = socat procan filan + +HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ + xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ + xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-system.h xio-termios.h xio-readline.h \ + xio-pty.h xio-openssl.h xio-streams.h \ + xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h + + +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html +SHFILES = daemon.sh mail.sh ftp.sh readline.sh +TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ + proxy.sh socks4a-echo.sh testcert.conf +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ + Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h + +all: progs doc + +scmclean: gitclean + +gitclean: distclean docclean + rm -f Makefile.bak configure + +doc: doc/socat.1 doc/socat.html + +docclean: + rm -f doc/socat.1 doc/socat.html + +doc/socat.1: doc/socat.yo + yodl2man -o $@ $+ + +doc/socat.html: doc/socat.yo + cd doc; yodl2html -o socat.html socat.yo; cd .. + +progs: $(PROGS) + +depend: $(CFILES) $(HFILES) + makedepend $(SYSDEFS) $(CFILES) + +socat: socat.o libxio.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) + +PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o +procan: $(PROCAN_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) + +filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) + +libxio.a: $(XIOOBJS) $(UTLOBJS) + $(AR) r $@ $(XIOOBJS) $(UTLOBJS) + $(RANLIB) $@ + +doc: doc/xio.help +# + +strip: progs + strip $(PROGS) + +install: progs $(srcdir)/doc/socat.1 + mkdir -p $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) + mkdir -p $(DESTDIR)$(MANDEST)/man1 + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + +uninstall: + rm -f $(DESTDIR)$(BINDEST)/socat + rm -f $(DESTDIR)$(BINDEST)/procan + rm -f $(DESTDIR)$(BINDEST)/filan + rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 + +# make a GNU-zipped tar ball of the source files +dist: socat.tar.gz socat.tar.bz2 + +socat.tar.gz: socat.tar + gzip -9 socat.tar.gz + +socat.tar.bz2: socat.tar + bzip2 -9 socat.tar.bz2 + +VERSION = `sed 's/"//g' VERSION` +TARDIR = socat-$(VERSION) +socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec + if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi + tar cf - $+ |(cd $(TARDIR); tar xf -) + tar cvf socat.tar $(TARDIR) + rm -f $(TARDIR)/COPYING # write protected + rm -r $(TARDIR) + +clean: + rm -f *.o libxio.a socat procan filan \ + socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ + socat.out compile.log test.log + +# remove all files that are generated from the original socat distribution +# note that Makefile is also removed, so you have to start with ./configure +# again +distclean: clean + rm -f config.status config.cache config.log config.h Makefile + rm -rf autom4te.cache + +info: socat + uname -a >socat.out + ./socat -V >>socat.out + ./socat -hh >>socat.out + +# perform some tests on socat +test: progs + ./test.sh + +cert: + # prepare critical files with correct permissions to avoid race cond + >cert.key + >cert.pem + chmod 600 cert.key cert.pem + # generate a private key + openssl genrsa -out cert.key 1024 + # generate a self signed cert + openssl req -new -key cert.key -x509 -days 3653 -out cert.crt + # ...enter fields + # generate the pem file + cat cert.key cert.crt >cert.pem + #echo use cert.pem on requestors side, i.e. with option cert=cert.pem + #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt diff --git a/Config/Makefile.NetBSD-4-0 b/Config/Makefile.NetBSD-4-0 new file mode 100644 index 0000000..5f6256a --- /dev/null +++ b/Config/Makefile.NetBSD-4-0 @@ -0,0 +1,195 @@ +# source: Makefile.in +# Copyright Gerhard Rieger 2001-2008 +# Published under the GNU General Public License V.2, see file COPYING + +# note: @...@ forms are filled in by configure script + +SHELL = /bin/sh +AR = ar +RANLIB = ranlib + +.SUFFIXES: .c .o + +prefix = /usr/local +exec_prefix = ${prefix} + +BINDEST = ${exec_prefix}/bin + +datarootdir = ${prefix}/share +MANDEST = ${datarootdir}/man + +srcdir = . + + +CC = gcc +CCOPTS = $(CCOPT) -Wall -Wno-parentheses + +SYSDEFS = +CPPFLAGS = -I. +#0 INCLS = -I. @V_INCL@ +DEFS = -DHAVE_CONFIG_H +LIBS = -lwrap -lutil -lssl +LDFLAGS = + +INSTALL = /usr/bin/install -c + +#OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) + + +#0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) +CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) +CLIBS = $(LIBS) +#CLIBS = $(LIBS) -lm -lefence +XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ + xiosignal.c xiosigchld.c xioread.c xiowrite.c \ + xiolayer.c xioshutdown.c xioclose.c xioexit.c \ + xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ + xio-gopen.c xio-creat.c xio-file.c xio-named.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-sctp.c xio-rawip.c \ + xio-socks.c xio-proxy.c xio-udp.c \ + xio-rawip.c \ + xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ + xio-pty.c xio-openssl.c xio-streams.c\ + xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c +XIOOBJS = $(XIOSRCS:.c=.o) +UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c +UTLOBJS = $(UTLSRCS:.c=.o) +CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c +OFILES = $(CFILES:.c=.o) +PROGS = socat procan filan + +HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ + xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ + xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-system.h xio-termios.h xio-readline.h \ + xio-pty.h xio-openssl.h xio-streams.h \ + xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h + + +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html +SHFILES = daemon.sh mail.sh ftp.sh readline.sh +TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ + proxy.sh socks4a-echo.sh testcert.conf +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ + Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h + +all: progs doc + +scmclean: gitclean + +gitclean: distclean docclean + rm -f Makefile.bak configure + +doc: doc/socat.1 doc/socat.html + +docclean: + rm -f doc/socat.1 doc/socat.html + +doc/socat.1: doc/socat.yo + yodl2man -o $@ $+ + +doc/socat.html: doc/socat.yo + cd doc; yodl2html -o socat.html socat.yo; cd .. + +progs: $(PROGS) + +depend: $(CFILES) $(HFILES) + makedepend $(SYSDEFS) $(CFILES) + +socat: socat.o libxio.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) + +PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o +procan: $(PROCAN_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) + +filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) + +libxio.a: $(XIOOBJS) $(UTLOBJS) + $(AR) r $@ $(XIOOBJS) $(UTLOBJS) + $(RANLIB) $@ + +doc: doc/xio.help +# + +strip: progs + strip $(PROGS) + +install: progs $(srcdir)/doc/socat.1 + mkdir -p $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) + mkdir -p $(DESTDIR)$(MANDEST)/man1 + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + +uninstall: + rm -f $(DESTDIR)$(BINDEST)/socat + rm -f $(DESTDIR)$(BINDEST)/procan + rm -f $(DESTDIR)$(BINDEST)/filan + rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 + +# make a GNU-zipped tar ball of the source files +dist: socat.tar.gz socat.tar.bz2 + +socat.tar.gz: socat.tar + gzip -9 socat.tar.gz + +socat.tar.bz2: socat.tar + bzip2 -9 socat.tar.bz2 + +VERSION = `sed 's/"//g' VERSION` +TARDIR = socat-$(VERSION) +socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec + if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi + tar cf - $+ |(cd $(TARDIR); tar xf -) + tar cvf socat.tar $(TARDIR) + rm -f $(TARDIR)/COPYING # write protected + rm -r $(TARDIR) + +clean: + rm -f *.o libxio.a socat procan filan \ + socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ + socat.out compile.log test.log + +# remove all files that are generated from the original socat distribution +# note that Makefile is also removed, so you have to start with ./configure +# again +distclean: clean + rm -f config.status config.cache config.log config.h Makefile + rm -rf autom4te.cache + +info: socat + uname -a >socat.out + ./socat -V >>socat.out + ./socat -hh >>socat.out + +# perform some tests on socat +test: progs + ./test.sh + +cert: + # prepare critical files with correct permissions to avoid race cond + >cert.key + >cert.pem + chmod 600 cert.key cert.pem + # generate a private key + openssl genrsa -out cert.key 1024 + # generate a self signed cert + openssl req -new -key cert.key -x509 -days 3653 -out cert.crt + # ...enter fields + # generate the pem file + cat cert.key cert.crt >cert.pem + #echo use cert.pem on requestors side, i.e. with option cert=cert.pem + #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt diff --git a/Config/Makefile.OpenBSD-4-3 b/Config/Makefile.OpenBSD-4-3 new file mode 100644 index 0000000..2683fcc --- /dev/null +++ b/Config/Makefile.OpenBSD-4-3 @@ -0,0 +1,195 @@ +# source: Makefile.in +# Copyright Gerhard Rieger 2001-2008 +# Published under the GNU General Public License V.2, see file COPYING + +# note: @...@ forms are filled in by configure script + +SHELL = /bin/sh +AR = ar +RANLIB = ranlib + +.SUFFIXES: .c .o + +prefix = /usr/local +exec_prefix = ${prefix} + +BINDEST = ${exec_prefix}/bin + +datarootdir = ${prefix}/share +MANDEST = ${datarootdir}/man + +srcdir = . + + +CC = gcc +CCOPTS = $(CCOPT) -Wall -Wno-parentheses + +SYSDEFS = -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=5 +CPPFLAGS = -I. +#0 INCLS = -I. @V_INCL@ +DEFS = -DHAVE_CONFIG_H +LIBS = -lwrap -lutil -lreadline -lcurses -lssl -lcrypto +LDFLAGS = + +INSTALL = /usr/bin/install -c + +#OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) + + +#0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) +CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) +CLIBS = $(LIBS) +#CLIBS = $(LIBS) -lm -lefence +XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ + xiosignal.c xiosigchld.c xioread.c xiowrite.c \ + xiolayer.c xioshutdown.c xioclose.c xioexit.c \ + xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ + xio-gopen.c xio-creat.c xio-file.c xio-named.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-sctp.c xio-rawip.c \ + xio-socks.c xio-proxy.c xio-udp.c \ + xio-rawip.c \ + xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ + xio-pty.c xio-openssl.c xio-streams.c\ + xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c +XIOOBJS = $(XIOSRCS:.c=.o) +UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c +UTLOBJS = $(UTLSRCS:.c=.o) +CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c +OFILES = $(CFILES:.c=.o) +PROGS = socat procan filan + +HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ + xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ + xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-system.h xio-termios.h xio-readline.h \ + xio-pty.h xio-openssl.h xio-streams.h \ + xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h + + +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html +SHFILES = daemon.sh mail.sh ftp.sh readline.sh +TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ + proxy.sh socks4a-echo.sh testcert.conf +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ + Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h + +all: progs doc + +scmclean: gitclean + +gitclean: distclean docclean + rm -f Makefile.bak configure + +doc: doc/socat.1 doc/socat.html + +docclean: + rm -f doc/socat.1 doc/socat.html + +doc/socat.1: doc/socat.yo + yodl2man -o $@ $+ + +doc/socat.html: doc/socat.yo + cd doc; yodl2html -o socat.html socat.yo; cd .. + +progs: $(PROGS) + +depend: $(CFILES) $(HFILES) + makedepend $(SYSDEFS) $(CFILES) + +socat: socat.o libxio.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) + +PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o +procan: $(PROCAN_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) + +filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) + +libxio.a: $(XIOOBJS) $(UTLOBJS) + $(AR) r $@ $(XIOOBJS) $(UTLOBJS) + $(RANLIB) $@ + +doc: doc/xio.help +# + +strip: progs + strip $(PROGS) + +install: progs $(srcdir)/doc/socat.1 + mkdir -p $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) + mkdir -p $(DESTDIR)$(MANDEST)/man1 + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + +uninstall: + rm -f $(DESTDIR)$(BINDEST)/socat + rm -f $(DESTDIR)$(BINDEST)/procan + rm -f $(DESTDIR)$(BINDEST)/filan + rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 + +# make a GNU-zipped tar ball of the source files +dist: socat.tar.gz socat.tar.bz2 + +socat.tar.gz: socat.tar + gzip -9 socat.tar.gz + +socat.tar.bz2: socat.tar + bzip2 -9 socat.tar.bz2 + +VERSION = `sed 's/"//g' VERSION` +TARDIR = socat-$(VERSION) +socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec + if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi + tar cf - $+ |(cd $(TARDIR); tar xf -) + tar cvf socat.tar $(TARDIR) + rm -f $(TARDIR)/COPYING # write protected + rm -r $(TARDIR) + +clean: + rm -f *.o libxio.a socat procan filan \ + socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ + socat.out compile.log test.log + +# remove all files that are generated from the original socat distribution +# note that Makefile is also removed, so you have to start with ./configure +# again +distclean: clean + rm -f config.status config.cache config.log config.h Makefile + rm -rf autom4te.cache + +info: socat + uname -a >socat.out + ./socat -V >>socat.out + ./socat -hh >>socat.out + +# perform some tests on socat +test: progs + ./test.sh + +cert: + # prepare critical files with correct permissions to avoid race cond + >cert.key + >cert.pem + chmod 600 cert.key cert.pem + # generate a private key + openssl genrsa -out cert.key 1024 + # generate a self signed cert + openssl req -new -key cert.key -x509 -days 3653 -out cert.crt + # ...enter fields + # generate the pem file + cat cert.key cert.crt >cert.pem + #echo use cert.pem on requestors side, i.e. with option cert=cert.pem + #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt diff --git a/Config/Makefile.SunOS-5-10 b/Config/Makefile.SunOS-5-10 new file mode 100644 index 0000000..d3d5901 --- /dev/null +++ b/Config/Makefile.SunOS-5-10 @@ -0,0 +1,195 @@ +# source: Makefile.in +# Copyright Gerhard Rieger 2001-2008 +# Published under the GNU General Public License V.2, see file COPYING + +# note: @...@ forms are filled in by configure script + +SHELL = /bin/sh +AR = ar +RANLIB = ranlib + +.SUFFIXES: .c .o + +prefix = /usr/local +exec_prefix = ${prefix} + +BINDEST = ${exec_prefix}/bin + +datarootdir = ${prefix}/share +MANDEST = ${datarootdir}/man + +srcdir = . + + +CC = gcc +CCOPTS = $(CCOPT) -Wall -Wno-parentheses + +SYSDEFS = +CPPFLAGS = -I. -I/usr/sfw/include +#0 INCLS = -I. @V_INCL@ +DEFS = -DHAVE_CONFIG_H +LIBS = -lwrap -lrt -lsocket -lnsl -lresolv -lreadline -lcurses -L/usr/sfw/lib -lssl -lcrypto +LDFLAGS = + +INSTALL = ./install-sh -c + +#OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) + + +#0 CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(INCLS) +CFLAGS = -O -D_GNU_SOURCE $(CCOPTS) $(DEFS) $(CPPFLAGS) +CLIBS = $(LIBS) +#CLIBS = $(LIBS) -lm -lefence +XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \ + xiosignal.c xiosigchld.c xioread.c xiowrite.c \ + xiolayer.c xioshutdown.c xioclose.c xioexit.c \ + xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \ + xio-gopen.c xio-creat.c xio-file.c xio-named.c \ + xio-socket.c xio-interface.c xio-listen.c xio-unix.c \ + xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \ + xio-sctp.c xio-rawip.c \ + xio-socks.c xio-proxy.c xio-udp.c \ + xio-rawip.c \ + xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \ + xio-pty.c xio-openssl.c xio-streams.c\ + xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c +XIOOBJS = $(XIOSRCS:.c=.o) +UTLSRCS = error.c dalan.c procan.c procan-cdefs.c hostan.c fdname.c sysutils.c utils.c nestlex.c filan.c sycls.c sslcls.c +UTLOBJS = $(UTLSRCS:.c=.o) +CFILES = $(XIOSRCS) $(UTLSRCS) socat.c procan_main.c filan_main.c +OFILES = $(CFILES:.c=.o) +PROGS = socat procan filan + +HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.h xio.h xioopen.h sysutils.h utils.h nestlex.h compat.h \ + xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \ + xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \ + xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \ + xio-socket.h xio-interface.h xio-listen.h xio-unix.h \ + xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h \ + xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \ + xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \ + xio-system.h xio-termios.h xio-readline.h \ + xio-pty.h xio-openssl.h xio-streams.h \ + xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h + + +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html +SHFILES = daemon.sh mail.sh ftp.sh readline.sh +TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ + proxy.sh socks4a-echo.sh testcert.conf +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ + Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h + +all: progs doc + +scmclean: gitclean + +gitclean: distclean docclean + rm -f Makefile.bak configure + +doc: doc/socat.1 doc/socat.html + +docclean: + rm -f doc/socat.1 doc/socat.html + +doc/socat.1: doc/socat.yo + yodl2man -o $@ $+ + +doc/socat.html: doc/socat.yo + cd doc; yodl2html -o socat.html socat.yo; cd .. + +progs: $(PROGS) + +depend: $(CFILES) $(HFILES) + makedepend $(SYSDEFS) $(CFILES) + +socat: socat.o libxio.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ socat.o libxio.a $(CLIBS) + +PROCAN_OBJS=procan_main.o procan.o procan-cdefs.o hostan.o error.o sycls.o sysutils.o utils.o +procan: $(PROCAN_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PROCAN_OBJS) $(CLIBS) + +filan: filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ filan_main.o filan.o fdname.o error.o sycls.o sysutils.o utils.o $(CLIBS) + +libxio.a: $(XIOOBJS) $(UTLOBJS) + $(AR) r $@ $(XIOOBJS) $(UTLOBJS) + $(RANLIB) $@ + +doc: doc/xio.help +# + +strip: progs + strip $(PROGS) + +install: progs $(srcdir)/doc/socat.1 + mkdir -p $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 socat $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 procan $(DESTDIR)$(BINDEST) + $(INSTALL) -m 755 filan $(DESTDIR)$(BINDEST) + mkdir -p $(DESTDIR)$(MANDEST)/man1 + $(INSTALL) -m 644 $(srcdir)/doc/socat.1 $(DESTDIR)$(MANDEST)/man1/ + +uninstall: + rm -f $(DESTDIR)$(BINDEST)/socat + rm -f $(DESTDIR)$(BINDEST)/procan + rm -f $(DESTDIR)$(BINDEST)/filan + rm -f $(DESTDIR)$(MANDEST)/man1/socat.1 + +# make a GNU-zipped tar ball of the source files +dist: socat.tar.gz socat.tar.bz2 + +socat.tar.gz: socat.tar + gzip -9 socat.tar.gz + +socat.tar.bz2: socat.tar + bzip2 -9 socat.tar.bz2 + +VERSION = `sed 's/"//g' VERSION` +TARDIR = socat-$(VERSION) +socat.tar: configure.in configure Makefile.in config.h.in install-sh VERSION $(CFILES) $(HFILES) $(DOCFILES) $(SHFILES) $(OSFILES) $(TESTFILES) socat.spec + if [ ! -d $(TARDIR) ]; then mkdir $(TARDIR); fi + tar cf - $+ |(cd $(TARDIR); tar xf -) + tar cvf socat.tar $(TARDIR) + rm -f $(TARDIR)/COPYING # write protected + rm -r $(TARDIR) + +clean: + rm -f *.o libxio.a socat procan filan \ + socat.tar socat.tar.Z socat.tar.gz socat.tar.bz2 \ + socat.out compile.log test.log + +# remove all files that are generated from the original socat distribution +# note that Makefile is also removed, so you have to start with ./configure +# again +distclean: clean + rm -f config.status config.cache config.log config.h Makefile + rm -rf autom4te.cache + +info: socat + uname -a >socat.out + ./socat -V >>socat.out + ./socat -hh >>socat.out + +# perform some tests on socat +test: progs + ./test.sh + +cert: + # prepare critical files with correct permissions to avoid race cond + >cert.key + >cert.pem + chmod 600 cert.key cert.pem + # generate a private key + openssl genrsa -out cert.key 1024 + # generate a self signed cert + openssl req -new -key cert.key -x509 -days 3653 -out cert.crt + # ...enter fields + # generate the pem file + cat cert.key cert.crt >cert.pem + #echo use cert.pem on requestors side, i.e. with option cert=cert.pem + #echo use cert.crt on checkers side, i.e. with option cafile=cert.crt diff --git a/Config/config.AIX-5-3.h b/Config/config.AIX-5-3.h new file mode 100644 index 0000000..9c0fec2 --- /dev/null +++ b/Config/config.AIX-5-3.h @@ -0,0 +1,523 @@ +/* config.h. Generated from config.h.in by configure. */ +/* source: config.h.in */ +/* Copyright Gerhard Rieger 2001-2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __config_h_included +#define __config_h_included 1 + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct stat has st_blksize. */ +#define HAVE_ST_BLKSIZE 1 + +/* Define if your struct stat has st_blocks. */ +#define HAVE_ST_BLOCKS 1 + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the poll function. */ +#define HAVE_POLL 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the getpgid function. */ +#define HAVE_GETPGID 1 + +/* Define if you have the getsid function. */ +#define HAVE_GETSID 1 + +/* Define if you have the nanosleep function. */ +#define HAVE_NANOSLEEP 1 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getipnodebyname function. */ +#define HAVE_GETIPNODEBYNAME 1 + +/* Define if you have the setgroups function. */ +#define HAVE_SETGROUPS 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the memrchr function. */ +/* #undef HAVE_MEMRCHR */ + +/* Define if you have the if_indextoname function. */ +#define HAVE_IF_INDEXTONAME 1 + +/* Define if you have the sigaction function */ +#define HAVE_SIGACTION 1 + +/* Define if you have the stat64 function */ +#define HAVE_STAT64 1 + +/* Define if you have the fstat64 function */ +#define HAVE_FSTAT64 1 + +/* Define if you have the lstat64 function */ +#define HAVE_LSTAT64 1 + +/* Define if you have the lseek64 function */ +#define HAVE_LSEEK64 1 + +/* Define if you have the truncate64 function */ +#define HAVE_TRUNCATE64 1 + +/* Define if you have the ftruncate64 function */ +#define HAVE_FTRUNCATE64 1 + +/* Define if you have the strtoll function */ +#define HAVE_STRTOLL 1 + +/* Define if you have the hstrerror function */ +#define HAVE_HSTRERROR 1 + +/* Define if you have the inet_ntop function */ +#define HAVE_INET_NTOP 1 + +/* Define if you have the hstrerror prototype */ +#define HAVE_PROTOTYPE_HSTRERROR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_PTY_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP6_H 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define if you have the header file. */ +#define HAVE_RESOLV_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_DL_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_TYPES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_ERRQUEUE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_IF_TUN_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETPACKET_PACKET_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETINET_IF_ETHER_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ +/* #undef HAVE_UTIL_H */ + +/* Define if you have the header file. (FreeBSD: openpty()) */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define if you have the header file. (stream opts on SunOS)*/ +#define HAVE_SYS_STROPTS_H 1 + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_FS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_EXT2_FS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_READLINE_READLINE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_READLINE_HISTORY_H */ + +/* Define if you have the readline library. */ +/* #undef HAVE_LIBREADLINE */ + +/* Define if you have the m library (-lm). */ +/* #undef HAVE_LIBM */ + +/* Define if you have the floor function */ +/* #undef HAVE_FLOOR */ + +/* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ +/* #undef _XOPEN_EXTENDED_SOURCE */ + +/* fdset may have component fds_bits or __fds_bits */ +#define HAVE_FDS_BITS 1 + +/* Define if you have the sa_family_t */ +#define HAVE_TYPE_SA_FAMILY_T 1 + +/* define if your struct sigaction has sa_sigaction */ +#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 + +/* Define if your struct termios has component c_ispeed */ +/* #undef HAVE_TERMIOS_ISPEED */ + +/* the offset of c_ispeed in struct termios - usable in an speed_t array. + Applies only when HAVE_TERMIOS_ISPEED is set */ +/* #undef ISPEED_OFFSET */ + +/* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ +#ifdef ISPEED_OFFSET +# define OSPEED_OFFSET (ISPEED_OFFSET+1) +#else +/* # undef OSPEED_OFFSET */ +#endif + +/* Define if your termios.h likes _SVID3 defined */ +/* #undef _SVID3 */ + +/* Define if you have struct timespec (e.g. for nanosleep) */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* Define if you have struct linger */ +#define HAVE_STRUCT_LINGER 1 + +/* Define if you have struct ip_mreq */ +#define HAVE_STRUCT_IP_MREQ 1 + +/* Define if you have struct ip_mreqn */ +/* #undef HAVE_STRUCT_IP_MREQN */ + +/* Define if you have struct ipv6_mreq */ +#define HAVE_STRUCT_IPV6_MREQ 1 + +/* Define if you have struct ifreq */ +#define HAVE_STRUCT_IFREQ 1 + +/* Define if you have struct ifreq.ifr_index */ +/* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ + +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ +/* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ + +/* Define if your struct sockaddr has sa_len */ +#define HAVE_STRUCT_SOCKADDR_SALEN 1 + +/* there are several implementations of sockaddr_in6 */ +#define HAVE_IP6_SOCKADDR 0 + +/* Define if you have struct iovec */ +#define HAVE_STRUCT_IOVEC 1 + +/* define if your struct msghdr has msg_control */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 + +/* define if your struct msghdr has msg_controllen */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 + +/* define if your struct msghdr has msg_flag */ +#define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 + +/* define if you have struct cmsghdr */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* define if you have struct in_pktinfo */ +/* #undef HAVE_STRUCT_IN_PKTINFO */ + +/* define if your struct ip has ip_hl; otherwise assume ip_vhl */ +#define HAVE_STRUCT_IP_IP_HL 1 + +/* Define if you have the setenv function */ +#define HAVE_SETENV 1 + +/* Define if you have the unsetenv function. not on HP-UX */ +#define HAVE_UNSETENV 1 + +/* Define if you have the flock function */ +/* #undef HAVE_FLOCK */ +#define HAVE_FLOCK 1 + +/* Define if you have the openpty function */ +/* #undef HAVE_OPENPTY */ + +/* Define if you have the grantpt function */ +#define HAVE_GRANTPT 1 + +/* Define if you have the unlockpt function */ +#define HAVE_UNLOCKPT 1 + +/* Define if you have the ptsname function */ +#define HAVE_PTSNAME 1 + +/* Define if you have the /dev/ptmx pseudo terminal multiplexer */ +/* #undef HAVE_DEV_PTMX */ + +/* Define if you have the /dev/ptc pseudo terminal multiplexer */ +#define HAVE_DEV_PTC 1 + +/* Define if you have the long long type */ +#define HAVE_TYPE_LONGLONG 1 + +/* is socklen_t already typedef'd? */ +#define HAVE_TYPE_SOCKLEN 1 + +/* Define if you have the struct stat64 type */ +#define HAVE_TYPE_STAT64 1 + +/* Define if you have the struct off64_t type */ +#define HAVE_TYPE_OFF64 1 + +/* is sighandler_t already typedef'd? */ +/* #undef HAVE_TYPE_SIGHANDLER */ + +/* is uint8_t already defined? */ +#define HAVE_TYPE_UINT8 1 + +/* is uint16_t already defined? */ +#define HAVE_TYPE_UINT16 1 + +/* is uint32_t already defined? */ +#define HAVE_TYPE_UINT32 1 + +/* is uint64_t already defined? */ +#define HAVE_TYPE_UINT64 1 + +/* Define if you have the printf "Z" modifier */ +/* #undef HAVE_FORMAT_Z */ + +/* Define the shift offset of the CRDLY mask */ +#define CRDLY_SHIFT 8 + +/* Define the shift offset of the TABDLY mask */ +#define TABDLY_SHIFT 10 + +/* Define the shift offset of the CSIZE mask */ +#define CSIZE_SHIFT 4 + +/* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ +/* #undef HAVE_HOSTS_ALLOW_TABLE */ +#if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE +# define HAVE_HOSTS_DENY_TABLE 1 +#else +/* # undef HAVE_HOSTS_DENY_TABLE */ +#endif + +/* 1..short, 3..int, 5..long; 2,4,6..unsigned */ +#define HAVE_BASIC_SIZE_T 0 /* unknown, taking default */ +#define HAVE_BASIC_MODE_T 0 /* unknown, taking default */ +#define HAVE_BASIC_PID_T 0 /* unknown, taking default */ +#define HAVE_BASIC_UID_T 0 /* unknown, taking default */ +#define HAVE_BASIC_GID_T 0 /* unknown, taking default */ +#define HAVE_BASIC_TIME_T 0 /* unknown, taking default */ +#define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ + +#define HAVE_BASIC_SOCKLEN_T 0 /* unknown, taking default */ + +#define HAVE_TYPEOF_ST_DEV 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST_INO 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST_NLINK 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST_SIZE 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST_BLKSIZE 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST_BLOCKS 0 /* unknown, taking default */ + +#define HAVE_TYPEOF_ST64_DEV 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST64_INO 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST64_NLINK 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST64_SIZE 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST64_BLKSIZE 0 /* unknown, taking default */ +#define HAVE_TYPEOF_ST64_BLOCKS 0 /* unknown, taking default */ + +#define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 0 /* unknown, taking default */ + +#define HAVE_TYPEOF_RLIM_MAX 0 /* unknown, taking default */ + +/* Define if you have the /proc filesystem */ +#define HAVE_PROC_DIR 1 + +/* Define if you have the /proc/$$/fd directories */ +#define HAVE_PROC_DIR_FD 1 + +#define WITH_HELP 1 +#define WITH_STDIO 1 +#define WITH_FDNUM 1 +#define WITH_FILE 1 +#define WITH_CREAT 1 +#define WITH_GOPEN 1 +#define WITH_TERMIOS 1 +#define WITH_PIPE 1 +#define WITH_UNIX 1 +/* #undef WITH_ABSTRACT_UNIXSOCKET */ +#define WITH_IP4 1 +#define WITH_IP6 1 +#define WITH_RAWIP 1 +#define WITH_GENERICSOCKET 1 +/* #undef WITH_INTERFACE */ +#define WITH_TCP 1 +#define WITH_UDP 1 +#define WITH_SCTP 1 +#define WITH_LISTEN 1 +#define WITH_SOCKS4 1 +#define WITH_SOCKS4A 1 +#define WITH_PROXY 1 +#define WITH_EXEC 1 +#define WITH_SYSTEM 1 +/* #undef WITH_READLINE */ +/* #undef WITH_TUN */ +#define WITH_PTY 1 +#define WITH_EXT2 1 +#define WITH_OPENSSL 1 +#define WITH_STREAMS 1 +/* #undef WITH_FIPS */ +/* #undef OPENSSL_FIPS */ +/* #undef WITH_LIBWRAP */ +/* #undef HAVE_TCPD_H */ +/* #undef HAVE_LIBWRAP */ + +#define WITH_SYCLS 1 +#define WITH_FILAN 1 +#define WITH_RETRY 1 + +#define WITH_MSGLEVEL 0 + +#endif /* !defined(__config_h_included) */ diff --git a/Config/config.Cygwin-1-5-25.h b/Config/config.Cygwin-1-5-25.h new file mode 100644 index 0000000..096580f --- /dev/null +++ b/Config/config.Cygwin-1-5-25.h @@ -0,0 +1,522 @@ +/* config.h. Generated from config.h.in by configure. */ +/* source: config.h.in */ +/* Copyright Gerhard Rieger 2001-2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __config_h_included +#define __config_h_included 1 + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct stat has st_blksize. */ +#define HAVE_ST_BLKSIZE 1 + +/* Define if your struct stat has st_blocks. */ +#define HAVE_ST_BLOCKS 1 + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the poll function. */ +#define HAVE_POLL 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the getpgid function. */ +#define HAVE_GETPGID 1 + +/* Define if you have the getsid function. */ +#define HAVE_GETSID 1 + +/* Define if you have the nanosleep function. */ +#define HAVE_NANOSLEEP 1 + +/* Define if you have the getaddrinfo function. */ +/* #undef HAVE_GETADDRINFO */ + +/* Define if you have the getipnodebyname function. */ +/* #undef HAVE_GETIPNODEBYNAME */ + +/* Define if you have the setgroups function. */ +#define HAVE_SETGROUPS 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the memrchr function. */ +/* #undef HAVE_MEMRCHR */ + +/* Define if you have the if_indextoname function. */ +/* #undef HAVE_IF_INDEXTONAME */ + +/* Define if you have the sigaction function */ +#define HAVE_SIGACTION 1 + +/* Define if you have the stat64 function */ +/* #undef HAVE_STAT64 */ + +/* Define if you have the fstat64 function */ +/* #undef HAVE_FSTAT64 */ + +/* Define if you have the lstat64 function */ +/* #undef HAVE_LSTAT64 */ + +/* Define if you have the lseek64 function */ +/* #undef HAVE_LSEEK64 */ + +/* Define if you have the truncate64 function */ +/* #undef HAVE_TRUNCATE64 */ + +/* Define if you have the ftruncate64 function */ +/* #undef HAVE_FTRUNCATE64 */ + +/* Define if you have the strtoll function */ +#define HAVE_STRTOLL 1 + +/* Define if you have the hstrerror function */ +#define HAVE_HSTRERROR 1 + +/* Define if you have the inet_ntop function */ +#define HAVE_INET_NTOP 1 + +/* Define if you have the hstrerror prototype */ +#define HAVE_PROTOTYPE_HSTRERROR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the header file. */ +#define HAVE_PTY_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NETINET_IP6_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_ARPA_NAMESER_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_RESOLV_H */ + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NET_IF_DL_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_TYPES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_ERRQUEUE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_IF_TUN_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETPACKET_PACKET_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETINET_IF_ETHER_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ +/* #undef HAVE_UTIL_H */ + +/* Define if you have the header file. (FreeBSD: openpty()) */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define if you have the header file. (stream opts on SunOS)*/ +/* #undef HAVE_SYS_STROPTS_H */ + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_FS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_EXT2_FS_H */ + +/* Define if you have the header file. */ +#define HAVE_READLINE_READLINE_H 1 + +/* Define if you have the header file. */ +#define HAVE_READLINE_HISTORY_H 1 + +/* Define if you have the readline library. */ +#define HAVE_LIBREADLINE 1 + +/* Define if you have the m library (-lm). */ +/* #undef HAVE_LIBM */ + +/* Define if you have the floor function */ +/* #undef HAVE_FLOOR */ + +/* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ +/* #undef _XOPEN_EXTENDED_SOURCE */ + +/* fdset may have component fds_bits or __fds_bits */ +#define HAVE_FDS_BITS 1 + +/* Define if you have the sa_family_t */ +#define HAVE_TYPE_SA_FAMILY_T 1 + +/* define if your struct sigaction has sa_sigaction */ +#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 + +/* Define if your struct termios has component c_ispeed */ +#define HAVE_TERMIOS_ISPEED 1 + +/* the offset of c_ispeed in struct termios - usable in an speed_t array. + Applies only when HAVE_TERMIOS_ISPEED is set */ +#define ISPEED_OFFSET 9 + +/* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ +#ifdef ISPEED_OFFSET +# define OSPEED_OFFSET (ISPEED_OFFSET+1) +#else +/* # undef OSPEED_OFFSET */ +#endif + +/* Define if your termios.h likes _SVID3 defined */ +/* #undef _SVID3 */ + +/* Define if you have struct timespec (e.g. for nanosleep) */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* Define if you have struct linger */ +#define HAVE_STRUCT_LINGER 1 + +/* Define if you have struct ip_mreq */ +#define HAVE_STRUCT_IP_MREQ 1 + +/* Define if you have struct ip_mreqn */ +/* #undef HAVE_STRUCT_IP_MREQN */ + +/* Define if you have struct ipv6_mreq */ +/* #undef HAVE_STRUCT_IPV6_MREQ */ + +/* Define if you have struct ifreq */ +#define HAVE_STRUCT_IFREQ 1 + +/* Define if you have struct ifreq.ifr_index */ +/* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ + +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ +/* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ + +/* Define if your struct sockaddr has sa_len */ +/* #undef HAVE_STRUCT_SOCKADDR_SALEN */ + +/* there are several implementations of sockaddr_in6 */ +/* #undef HAVE_IP6_SOCKADDR */ + +/* Define if you have struct iovec */ +#define HAVE_STRUCT_IOVEC 1 + +/* define if your struct msghdr has msg_control */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 + +/* define if your struct msghdr has msg_controllen */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 + +/* define if your struct msghdr has msg_flag */ +#define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 + +/* define if you have struct cmsghdr */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* define if you have struct in_pktinfo */ +/* #undef HAVE_STRUCT_IN_PKTINFO */ + +/* define if your struct ip has ip_hl; otherwise assume ip_vhl */ +#define HAVE_STRUCT_IP_IP_HL 1 + +/* Define if you have the setenv function */ +#define HAVE_SETENV 1 + +/* Define if you have the unsetenv function. not on HP-UX */ +#define HAVE_UNSETENV 1 + +/* Define if you have the flock function */ +#define HAVE_FLOCK 1 + +/* Define if you have the openpty function */ +#define HAVE_OPENPTY 1 + +/* Define if you have the grantpt function */ +#define HAVE_GRANTPT 1 + +/* Define if you have the unlockpt function */ +#define HAVE_UNLOCKPT 1 + +/* Define if you have the ptsname function */ +#define HAVE_PTSNAME 1 + +/* Define if you have the /dev/ptmx pseudo terminal multiplexer */ +#define HAVE_DEV_PTMX 1 + +/* Define if you have the /dev/ptc pseudo terminal multiplexer */ +/* #undef HAVE_DEV_PTC */ + +/* Define if you have the long long type */ +#define HAVE_TYPE_LONGLONG 1 + +/* is socklen_t already typedef'd? */ +#define HAVE_TYPE_SOCKLEN 1 + +/* Define if you have the struct stat64 type */ +/* #undef HAVE_TYPE_STAT64 */ + +/* Define if you have the struct off64_t type */ +/* #undef HAVE_TYPE_OFF64 */ + +/* is sighandler_t already typedef'd? */ +/* #undef HAVE_TYPE_SIGHANDLER */ + +/* is uint8_t already defined? */ +#define HAVE_TYPE_UINT8 1 + +/* is uint16_t already defined? */ +#define HAVE_TYPE_UINT16 1 + +/* is uint32_t already defined? */ +#define HAVE_TYPE_UINT32 1 + +/* is uint64_t already defined? */ +#define HAVE_TYPE_UINT64 1 + +/* Define if you have the printf "Z" modifier */ +/* #undef HAVE_FORMAT_Z */ + +/* Define the shift offset of the CRDLY mask */ +#define CRDLY_SHIFT 7 + +/* Define the shift offset of the TABDLY mask */ +#define TABDLY_SHIFT 11 + +/* Define the shift offset of the CSIZE mask */ +#define CSIZE_SHIFT 4 + +/* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ +#define HAVE_HOSTS_ALLOW_TABLE 1 +#if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE +# define HAVE_HOSTS_DENY_TABLE 1 +#else +/* # undef HAVE_HOSTS_DENY_TABLE */ +#endif + +/* 1..short, 3..int, 5..long; 2,4,6..unsigned */ +#define HAVE_BASIC_SIZE_T 4 /* unsigned int */ +#define HAVE_BASIC_MODE_T 4 /* unsigned int */ +#define HAVE_BASIC_PID_T 3 /* int */ +#define HAVE_BASIC_UID_T 6 /* unsigned long */ +#define HAVE_BASIC_GID_T 6 /* unsigned long */ +#define HAVE_BASIC_TIME_T 5 /* long */ +#define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ + +#define HAVE_BASIC_SOCKLEN_T 3 /* int */ + +#define HAVE_TYPEOF_ST_DEV 6 /* unsigned long */ +#define HAVE_TYPEOF_ST_INO 8 /* unsigned long long */ +#define HAVE_TYPEOF_ST_NLINK 2 /* unsigned short */ +#define HAVE_TYPEOF_ST_SIZE 7 /* long long */ +#define HAVE_TYPEOF_ST_BLKSIZE 5 /* long */ +#define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ + +/* #undef HAVE_TYPEOF_ST64_DEV */ +/* #undef HAVE_TYPEOF_ST64_INO */ +/* #undef HAVE_TYPEOF_ST64_NLINK */ +/* #undef HAVE_TYPEOF_ST64_SIZE */ +/* #undef HAVE_TYPEOF_ST64_BLKSIZE */ +/* #undef HAVE_TYPEOF_ST64_BLOCKS */ + +#define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ + +#define HAVE_TYPEOF_RLIM_MAX 6 /* unsigned long */ + +/* Define if you have the /proc filesystem */ +#define HAVE_PROC_DIR 1 + +/* Define if you have the /proc/$$/fd directories */ +#define HAVE_PROC_DIR_FD 1 + +#define WITH_HELP 1 +#define WITH_STDIO 1 +#define WITH_FDNUM 1 +#define WITH_FILE 1 +#define WITH_CREAT 1 +#define WITH_GOPEN 1 +#define WITH_TERMIOS 1 +#define WITH_PIPE 1 +#define WITH_UNIX 1 +/* #undef WITH_ABSTRACT_UNIXSOCKET */ +#define WITH_IP4 1 +/* #undef WITH_IP6 */ +#define WITH_RAWIP 1 +#define WITH_GENERICSOCKET 1 +/* #undef WITH_INTERFACE */ +#define WITH_TCP 1 +#define WITH_UDP 1 +/* #undef WITH_SCTP */ +#define WITH_LISTEN 1 +#define WITH_SOCKS4 1 +#define WITH_SOCKS4A 1 +#define WITH_PROXY 1 +#define WITH_EXEC 1 +#define WITH_SYSTEM 1 +#define WITH_READLINE 1 +/* #undef WITH_TUN */ +#define WITH_PTY 1 +#define WITH_EXT2 1 +#define WITH_OPENSSL 1 +#define WITH_STREAMS 1 +/* #undef WITH_FIPS */ +/* #undef OPENSSL_FIPS */ +#define WITH_LIBWRAP 1 +#define HAVE_TCPD_H 1 +#define HAVE_LIBWRAP 1 + +#define WITH_SYCLS 1 +#define WITH_FILAN 1 +#define WITH_RETRY 1 + +#define WITH_MSGLEVEL 0 + +#endif /* !defined(__config_h_included) */ diff --git a/Config/config.FreeBSD-6-1.h b/Config/config.FreeBSD-6-1.h index af45423..aad86e3 100644 --- a/Config/config.FreeBSD-6-1.h +++ b/Config/config.FreeBSD-6-1.h @@ -1,6 +1,6 @@ -/* config.h. Generated by configure. */ -/* source: Config/config.FreeBSD-6-1.h */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* config.h. Generated from config.h.in by configure. */ +/* source: config.h.in */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ #ifndef __config_h_included @@ -108,6 +108,9 @@ /* Define if you have the memrchr function. */ /* #undef HAVE_MEMRCHR */ +/* Define if you have the if_indextoname function. */ +#define HAVE_IF_INDEXTONAME 1 + /* Define if you have the sigaction function */ #define HAVE_SIGACTION 1 @@ -225,9 +228,24 @@ /* Define if you have the header file. */ #define HAVE_NET_IF_H 1 +/* Define if you have the header file. */ +#define HAVE_NET_IF_DL_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_TYPES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_ERRQUEUE_H */ + /* Define if you have the header file. */ /* #undef HAVE_LINUX_IF_TUN_H */ +/* Define if you have the header file. */ +/* #undef HAVE_NETPACKET_PACKET_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETINET_IF_ETHER_H */ + /* Define if you have the header file. */ #define HAVE_SYS_UTSNAME_H 1 @@ -276,6 +294,12 @@ /* fdset may have component fds_bits or __fds_bits */ #define HAVE_FDS_BITS 1 +/* Define if you have the sa_family_t */ +#define HAVE_TYPE_SA_FAMILY_T 1 + +/* define if your struct sigaction has sa_sigaction */ +#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 + /* Define if your struct termios has component c_ispeed */ #define HAVE_TERMIOS_ISPEED 1 @@ -314,7 +338,7 @@ /* Define if you have struct ifreq.ifr_index */ #define HAVE_STRUCT_IFREQ_IFR_INDEX 1 -/* Define if you have struct ifreq.ifr_ifindex */ +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ /* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ /* Define if your struct sockaddr has sa_len */ @@ -335,12 +359,21 @@ /* define if your struct msghdr has msg_flag */ #define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 +/* define if you have struct cmsghdr */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* define if you have struct in_pktinfo */ +/* #undef HAVE_STRUCT_IN_PKTINFO */ + /* define if your struct ip has ip_hl; otherwise assume ip_vhl */ #define HAVE_STRUCT_IP_IP_HL 1 /* Define if you have the setenv function */ #define HAVE_SETENV 1 +/* Define if you have the unsetenv function. not on HP-UX */ +#define HAVE_UNSETENV 1 + /* Define if you have the flock function */ #define HAVE_FLOCK 1 @@ -434,7 +467,7 @@ /* #undef HAVE_TYPEOF_ST64_BLKSIZE */ /* #undef HAVE_TYPEOF_ST64_BLOCKS */ -/* #undef HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC */ +#define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ #define HAVE_TYPEOF_RLIM_MAX 7 /* long long */ @@ -457,8 +490,11 @@ #define WITH_IP4 1 #define WITH_IP6 1 #define WITH_RAWIP 1 +#define WITH_GENERICSOCKET 1 +/* #undef WITH_INTERFACE */ #define WITH_TCP 1 #define WITH_UDP 1 +#define WITH_SCTP 1 #define WITH_LISTEN 1 #define WITH_SOCKS4 1 #define WITH_SOCKS4A 1 @@ -470,6 +506,7 @@ #define WITH_PTY 1 #define WITH_EXT2 1 #define WITH_OPENSSL 1 +#define WITH_STREAMS 1 /* #undef WITH_FIPS */ /* #undef OPENSSL_FIPS */ #define WITH_LIBWRAP 1 diff --git a/Config/config.Linux-2-6-24.h b/Config/config.Linux-2-6-24.h new file mode 100644 index 0000000..94dc9b8 --- /dev/null +++ b/Config/config.Linux-2-6-24.h @@ -0,0 +1,522 @@ +/* config.h. Generated from config.h.in by configure. */ +/* source: config.h.in */ +/* Copyright Gerhard Rieger 2001-2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __config_h_included +#define __config_h_included 1 + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct stat has st_blksize. */ +#define HAVE_ST_BLKSIZE 1 + +/* Define if your struct stat has st_blocks. */ +#define HAVE_ST_BLOCKS 1 + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the poll function. */ +#define HAVE_POLL 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the getpgid function. */ +#define HAVE_GETPGID 1 + +/* Define if you have the getsid function. */ +#define HAVE_GETSID 1 + +/* Define if you have the nanosleep function. */ +#define HAVE_NANOSLEEP 1 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getipnodebyname function. */ +/* #undef HAVE_GETIPNODEBYNAME */ + +/* Define if you have the setgroups function. */ +#define HAVE_SETGROUPS 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the memrchr function. */ +#define HAVE_MEMRCHR 1 + +/* Define if you have the if_indextoname function. */ +#define HAVE_IF_INDEXTONAME 1 + +/* Define if you have the sigaction function */ +#define HAVE_SIGACTION 1 + +/* Define if you have the stat64 function */ +#define HAVE_STAT64 1 + +/* Define if you have the fstat64 function */ +#define HAVE_FSTAT64 1 + +/* Define if you have the lstat64 function */ +#define HAVE_LSTAT64 1 + +/* Define if you have the lseek64 function */ +#define HAVE_LSEEK64 1 + +/* Define if you have the truncate64 function */ +#define HAVE_TRUNCATE64 1 + +/* Define if you have the ftruncate64 function */ +#define HAVE_FTRUNCATE64 1 + +/* Define if you have the strtoll function */ +#define HAVE_STRTOLL 1 + +/* Define if you have the hstrerror function */ +#define HAVE_HSTRERROR 1 + +/* Define if you have the inet_ntop function */ +#define HAVE_INET_NTOP 1 + +/* Define if you have the hstrerror prototype */ +#define HAVE_PROTOTYPE_HSTRERROR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the header file. */ +#define HAVE_PTY_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP6_H 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define if you have the header file. */ +#define HAVE_RESOLV_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NET_IF_DL_H */ + +/* Define if you have the header file. */ +#define HAVE_LINUX_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_ERRQUEUE_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_IF_TUN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETPACKET_PACKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IF_ETHER_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ +/* #undef HAVE_UTIL_H */ + +/* Define if you have the header file. (FreeBSD: openpty()) */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define if you have the header file. (stream opts on SunOS)*/ +#define HAVE_SYS_STROPTS_H 1 + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_FS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_EXT2_FS_H 1 + +/* Define if you have the header file. */ +#define HAVE_READLINE_READLINE_H 1 + +/* Define if you have the header file. */ +#define HAVE_READLINE_HISTORY_H 1 + +/* Define if you have the readline library. */ +#define HAVE_LIBREADLINE 1 + +/* Define if you have the m library (-lm). */ +/* #undef HAVE_LIBM */ + +/* Define if you have the floor function */ +/* #undef HAVE_FLOOR */ + +/* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ +/* #undef _XOPEN_EXTENDED_SOURCE */ + +/* fdset may have component fds_bits or __fds_bits */ +#define HAVE_FDS_BITS 1 + +/* Define if you have the sa_family_t */ +#define HAVE_TYPE_SA_FAMILY_T 1 + +/* define if your struct sigaction has sa_sigaction */ +#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 + +/* Define if your struct termios has component c_ispeed */ +#define HAVE_TERMIOS_ISPEED 1 + +/* the offset of c_ispeed in struct termios - usable in an speed_t array. + Applies only when HAVE_TERMIOS_ISPEED is set */ +#define ISPEED_OFFSET 13 + +/* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ +#ifdef ISPEED_OFFSET +# define OSPEED_OFFSET (ISPEED_OFFSET+1) +#else +/* # undef OSPEED_OFFSET */ +#endif + +/* Define if your termios.h likes _SVID3 defined */ +/* #undef _SVID3 */ + +/* Define if you have struct timespec (e.g. for nanosleep) */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* Define if you have struct linger */ +#define HAVE_STRUCT_LINGER 1 + +/* Define if you have struct ip_mreq */ +#define HAVE_STRUCT_IP_MREQ 1 + +/* Define if you have struct ip_mreqn */ +#define HAVE_STRUCT_IP_MREQN 1 + +/* Define if you have struct ipv6_mreq */ +#define HAVE_STRUCT_IPV6_MREQ 1 + +/* Define if you have struct ifreq */ +#define HAVE_STRUCT_IFREQ 1 + +/* Define if you have struct ifreq.ifr_index */ +/* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ + +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ +#define HAVE_STRUCT_IFREQ_IFR_IFINDEX 1 + +/* Define if your struct sockaddr has sa_len */ +/* #undef HAVE_STRUCT_SOCKADDR_SALEN */ + +/* there are several implementations of sockaddr_in6 */ +#define HAVE_IP6_SOCKADDR 0 + +/* Define if you have struct iovec */ +#define HAVE_STRUCT_IOVEC 1 + +/* define if your struct msghdr has msg_control */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 + +/* define if your struct msghdr has msg_controllen */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 + +/* define if your struct msghdr has msg_flag */ +#define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 + +/* define if you have struct cmsghdr */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* define if you have struct in_pktinfo */ +#define HAVE_STRUCT_IN_PKTINFO 1 + +/* define if your struct ip has ip_hl; otherwise assume ip_vhl */ +#define HAVE_STRUCT_IP_IP_HL 1 + +/* Define if you have the setenv function */ +#define HAVE_SETENV 1 + +/* Define if you have the unsetenv function. not on HP-UX */ +#define HAVE_UNSETENV 1 + +/* Define if you have the flock function */ +#define HAVE_FLOCK 1 + +/* Define if you have the openpty function */ +#define HAVE_OPENPTY 1 + +/* Define if you have the grantpt function */ +#define HAVE_GRANTPT 1 + +/* Define if you have the unlockpt function */ +#define HAVE_UNLOCKPT 1 + +/* Define if you have the ptsname function */ +#define HAVE_PTSNAME 1 + +/* Define if you have the /dev/ptmx pseudo terminal multiplexer */ +#define HAVE_DEV_PTMX 1 + +/* Define if you have the /dev/ptc pseudo terminal multiplexer */ +/* #undef HAVE_DEV_PTC */ + +/* Define if you have the long long type */ +#define HAVE_TYPE_LONGLONG 1 + +/* is socklen_t already typedef'd? */ +#define HAVE_TYPE_SOCKLEN 1 + +/* Define if you have the struct stat64 type */ +#define HAVE_TYPE_STAT64 1 + +/* Define if you have the struct off64_t type */ +#define HAVE_TYPE_OFF64 1 + +/* is sighandler_t already typedef'd? */ +#define HAVE_TYPE_SIGHANDLER 1 + +/* is uint8_t already defined? */ +#define HAVE_TYPE_UINT8 1 + +/* is uint16_t already defined? */ +#define HAVE_TYPE_UINT16 1 + +/* is uint32_t already defined? */ +#define HAVE_TYPE_UINT32 1 + +/* is uint64_t already defined? */ +#define HAVE_TYPE_UINT64 1 + +/* Define if you have the printf "Z" modifier */ +#define HAVE_FORMAT_Z 1 + +/* Define the shift offset of the CRDLY mask */ +#define CRDLY_SHIFT 9 + +/* Define the shift offset of the TABDLY mask */ +#define TABDLY_SHIFT 11 + +/* Define the shift offset of the CSIZE mask */ +#define CSIZE_SHIFT 4 + +/* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ +#define HAVE_HOSTS_ALLOW_TABLE 1 +#if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE +# define HAVE_HOSTS_DENY_TABLE 1 +#else +/* # undef HAVE_HOSTS_DENY_TABLE */ +#endif + +/* 1..short, 3..int, 5..long; 2,4,6..unsigned */ +#define HAVE_BASIC_SIZE_T 4 /* unsigned int */ +#define HAVE_BASIC_MODE_T 4 /* unsigned int */ +#define HAVE_BASIC_PID_T 3 /* int */ +#define HAVE_BASIC_UID_T 4 /* unsigned int */ +#define HAVE_BASIC_GID_T 4 /* unsigned int */ +#define HAVE_BASIC_TIME_T 5 /* long */ +#define HAVE_BASIC_OFF64_T 7 /* long long */ + +#define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ + +#define HAVE_TYPEOF_ST_DEV 8 /* unsigned long long */ +#define HAVE_TYPEOF_ST_INO 6 /* unsigned long */ +#define HAVE_TYPEOF_ST_NLINK 4 /* unsigned int */ +#define HAVE_TYPEOF_ST_SIZE 5 /* long */ +#define HAVE_TYPEOF_ST_BLKSIZE 5 /* long */ +#define HAVE_TYPEOF_ST_BLOCKS 5 /* long */ + +#define HAVE_TYPEOF_ST64_DEV 8 /* unsigned long long */ +#define HAVE_TYPEOF_ST64_INO 8 /* unsigned long long */ +#define HAVE_TYPEOF_ST64_NLINK 4 /* unsigned int */ +#define HAVE_TYPEOF_ST64_SIZE 7 /* long long */ +#define HAVE_TYPEOF_ST64_BLKSIZE 5 /* long */ +#define HAVE_TYPEOF_ST64_BLOCKS 7 /* long long */ + +#define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ + +#define HAVE_TYPEOF_RLIM_MAX 6 /* unsigned long */ + +/* Define if you have the /proc filesystem */ +#define HAVE_PROC_DIR 1 + +/* Define if you have the /proc/$$/fd directories */ +#define HAVE_PROC_DIR_FD 1 + +#define WITH_HELP 1 +#define WITH_STDIO 1 +#define WITH_FDNUM 1 +#define WITH_FILE 1 +#define WITH_CREAT 1 +#define WITH_GOPEN 1 +#define WITH_TERMIOS 1 +#define WITH_PIPE 1 +#define WITH_UNIX 1 +#define WITH_ABSTRACT_UNIXSOCKET 1 +#define WITH_IP4 1 +#define WITH_IP6 1 +#define WITH_RAWIP 1 +#define WITH_GENERICSOCKET 1 +#define WITH_INTERFACE 1 +#define WITH_TCP 1 +#define WITH_UDP 1 +#define WITH_SCTP 1 +#define WITH_LISTEN 1 +#define WITH_SOCKS4 1 +#define WITH_SOCKS4A 1 +#define WITH_PROXY 1 +#define WITH_EXEC 1 +#define WITH_SYSTEM 1 +#define WITH_READLINE 1 +#define WITH_TUN 1 +#define WITH_PTY 1 +#define WITH_EXT2 1 +#define WITH_OPENSSL 1 +#define WITH_STREAMS 1 +/* #undef WITH_FIPS */ +/* #undef OPENSSL_FIPS */ +#define WITH_LIBWRAP 1 +#define HAVE_TCPD_H 1 +#define HAVE_LIBWRAP 1 + +#define WITH_SYCLS 1 +#define WITH_FILAN 1 +#define WITH_RETRY 1 + +#define WITH_MSGLEVEL 0 + +#endif /* !defined(__config_h_included) */ diff --git a/Config/config.MacOSX-10-5.h b/Config/config.MacOSX-10-5.h new file mode 100644 index 0000000..c19ca9e --- /dev/null +++ b/Config/config.MacOSX-10-5.h @@ -0,0 +1,522 @@ +/* config.h. Generated from config.h.in by configure. */ +/* source: config.h.in */ +/* Copyright Gerhard Rieger 2001-2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __config_h_included +#define __config_h_included 1 + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct stat has st_blksize. */ +#define HAVE_ST_BLKSIZE 1 + +/* Define if your struct stat has st_blocks. */ +#define HAVE_ST_BLOCKS 1 + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the poll function. */ +#define HAVE_POLL 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the getpgid function. */ +#define HAVE_GETPGID 1 + +/* Define if you have the getsid function. */ +#define HAVE_GETSID 1 + +/* Define if you have the nanosleep function. */ +#define HAVE_NANOSLEEP 1 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getipnodebyname function. */ +#define HAVE_GETIPNODEBYNAME 1 + +/* Define if you have the setgroups function. */ +#define HAVE_SETGROUPS 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the memrchr function. */ +/* #undef HAVE_MEMRCHR */ + +/* Define if you have the if_indextoname function. */ +#define HAVE_IF_INDEXTONAME 1 + +/* Define if you have the sigaction function */ +#define HAVE_SIGACTION 1 + +/* Define if you have the stat64 function */ +#define HAVE_STAT64 1 + +/* Define if you have the fstat64 function */ +#define HAVE_FSTAT64 1 + +/* Define if you have the lstat64 function */ +#define HAVE_LSTAT64 1 + +/* Define if you have the lseek64 function */ +/* #undef HAVE_LSEEK64 */ + +/* Define if you have the truncate64 function */ +/* #undef HAVE_TRUNCATE64 */ + +/* Define if you have the ftruncate64 function */ +/* #undef HAVE_FTRUNCATE64 */ + +/* Define if you have the strtoll function */ +#define HAVE_STRTOLL 1 + +/* Define if you have the hstrerror function */ +#define HAVE_HSTRERROR 1 + +/* Define if you have the inet_ntop function */ +#define HAVE_INET_NTOP 1 + +/* Define if you have the hstrerror prototype */ +#define HAVE_PROTOTYPE_HSTRERROR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_PTY_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP6_H 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define if you have the header file. */ +#define HAVE_RESOLV_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_DL_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_TYPES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_ERRQUEUE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_IF_TUN_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETPACKET_PACKET_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETINET_IF_ETHER_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ +#define HAVE_UTIL_H 1 + +/* Define if you have the header file. (FreeBSD: openpty()) */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define if you have the header file. (stream opts on SunOS)*/ +/* #undef HAVE_SYS_STROPTS_H */ + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_FS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_EXT2_FS_H */ + +/* Define if you have the header file. */ +#define HAVE_READLINE_READLINE_H 1 + +/* Define if you have the header file. */ +#define HAVE_READLINE_HISTORY_H 1 + +/* Define if you have the readline library. */ +#define HAVE_LIBREADLINE 1 + +/* Define if you have the m library (-lm). */ +/* #undef HAVE_LIBM */ + +/* Define if you have the floor function */ +/* #undef HAVE_FLOOR */ + +/* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ +/* #undef _XOPEN_EXTENDED_SOURCE */ + +/* fdset may have component fds_bits or __fds_bits */ +#define HAVE_FDS_BITS 1 + +/* Define if you have the sa_family_t */ +#define HAVE_TYPE_SA_FAMILY_T 1 + +/* define if your struct sigaction has sa_sigaction */ +#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 + +/* Define if your struct termios has component c_ispeed */ +#define HAVE_TERMIOS_ISPEED 1 + +/* the offset of c_ispeed in struct termios - usable in an speed_t array. + Applies only when HAVE_TERMIOS_ISPEED is set */ +#define ISPEED_OFFSET 9 + +/* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ +#ifdef ISPEED_OFFSET +# define OSPEED_OFFSET (ISPEED_OFFSET+1) +#else +/* # undef OSPEED_OFFSET */ +#endif + +/* Define if your termios.h likes _SVID3 defined */ +/* #undef _SVID3 */ + +/* Define if you have struct timespec (e.g. for nanosleep) */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* Define if you have struct linger */ +#define HAVE_STRUCT_LINGER 1 + +/* Define if you have struct ip_mreq */ +#define HAVE_STRUCT_IP_MREQ 1 + +/* Define if you have struct ip_mreqn */ +/* #undef HAVE_STRUCT_IP_MREQN */ + +/* Define if you have struct ipv6_mreq */ +#define HAVE_STRUCT_IPV6_MREQ 1 + +/* Define if you have struct ifreq */ +#define HAVE_STRUCT_IFREQ 1 + +/* Define if you have struct ifreq.ifr_index */ +/* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ + +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ +/* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ + +/* Define if your struct sockaddr has sa_len */ +#define HAVE_STRUCT_SOCKADDR_SALEN 1 + +/* there are several implementations of sockaddr_in6 */ +#define HAVE_IP6_SOCKADDR 0 + +/* Define if you have struct iovec */ +#define HAVE_STRUCT_IOVEC 1 + +/* define if your struct msghdr has msg_control */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 + +/* define if your struct msghdr has msg_controllen */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 + +/* define if your struct msghdr has msg_flag */ +#define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 + +/* define if you have struct cmsghdr */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* define if you have struct in_pktinfo */ +/* #undef HAVE_STRUCT_IN_PKTINFO */ + +/* define if your struct ip has ip_hl; otherwise assume ip_vhl */ +#define HAVE_STRUCT_IP_IP_HL 1 + +/* Define if you have the setenv function */ +#define HAVE_SETENV 1 + +/* Define if you have the unsetenv function. not on HP-UX */ +#define HAVE_UNSETENV 1 + +/* Define if you have the flock function */ +#define HAVE_FLOCK 1 + +/* Define if you have the openpty function */ +#define HAVE_OPENPTY 1 + +/* Define if you have the grantpt function */ +#define HAVE_GRANTPT 1 + +/* Define if you have the unlockpt function */ +#define HAVE_UNLOCKPT 1 + +/* Define if you have the ptsname function */ +#define HAVE_PTSNAME 1 + +/* Define if you have the /dev/ptmx pseudo terminal multiplexer */ +#define HAVE_DEV_PTMX 1 + +/* Define if you have the /dev/ptc pseudo terminal multiplexer */ +/* #undef HAVE_DEV_PTC */ + +/* Define if you have the long long type */ +#define HAVE_TYPE_LONGLONG 1 + +/* is socklen_t already typedef'd? */ +#define HAVE_TYPE_SOCKLEN 1 + +/* Define if you have the struct stat64 type */ +#define HAVE_TYPE_STAT64 1 + +/* Define if you have the struct off64_t type */ +/* #undef HAVE_TYPE_OFF64 */ + +/* is sighandler_t already typedef'd? */ +/* #undef HAVE_TYPE_SIGHANDLER */ + +/* is uint8_t already defined? */ +#define HAVE_TYPE_UINT8 1 + +/* is uint16_t already defined? */ +#define HAVE_TYPE_UINT16 1 + +/* is uint32_t already defined? */ +#define HAVE_TYPE_UINT32 1 + +/* is uint64_t already defined? */ +#define HAVE_TYPE_UINT64 1 + +/* Define if you have the printf "Z" modifier */ +/* #undef HAVE_FORMAT_Z */ + +/* Define the shift offset of the CRDLY mask */ +#define CRDLY_SHIFT 12 + +/* Define the shift offset of the TABDLY mask */ +#define TABDLY_SHIFT -1 + +/* Define the shift offset of the CSIZE mask */ +#define CSIZE_SHIFT 8 + +/* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ +#define HAVE_HOSTS_ALLOW_TABLE 1 +#if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE +# define HAVE_HOSTS_DENY_TABLE 1 +#else +/* # undef HAVE_HOSTS_DENY_TABLE */ +#endif + +/* 1..short, 3..int, 5..long; 2,4,6..unsigned */ +#define HAVE_BASIC_SIZE_T 6 /* unsigned long */ +#define HAVE_BASIC_MODE_T 2 /* unsigned short */ +#define HAVE_BASIC_PID_T 3 /* int */ +#define HAVE_BASIC_UID_T 4 /* unsigned int */ +#define HAVE_BASIC_GID_T 4 /* unsigned int */ +#define HAVE_BASIC_TIME_T 5 /* long */ +#define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ + +#define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ + +#define HAVE_TYPEOF_ST_DEV 3 /* int */ +#define HAVE_TYPEOF_ST_INO 4 /* unsigned int */ +#define HAVE_TYPEOF_ST_NLINK 2 /* unsigned short */ +#define HAVE_TYPEOF_ST_SIZE 7 /* long long */ +#define HAVE_TYPEOF_ST_BLKSIZE 3 /* int */ +#define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ + +#define HAVE_TYPEOF_ST64_DEV 3 /* int */ +#define HAVE_TYPEOF_ST64_INO 8 /* unsigned long long */ +#define HAVE_TYPEOF_ST64_NLINK 2 /* unsigned short */ +#define HAVE_TYPEOF_ST64_SIZE 7 /* long long */ +#define HAVE_TYPEOF_ST64_BLKSIZE 3 /* int */ +#define HAVE_TYPEOF_ST64_BLOCKS 7 /* long long */ + +#define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 3 /* int */ + +#define HAVE_TYPEOF_RLIM_MAX 8 /* unsigned long long */ + +/* Define if you have the /proc filesystem */ +/* #undef HAVE_PROC_DIR */ + +/* Define if you have the /proc/$$/fd directories */ +/* #undef HAVE_PROC_DIR_FD */ + +#define WITH_HELP 1 +#define WITH_STDIO 1 +#define WITH_FDNUM 1 +#define WITH_FILE 1 +#define WITH_CREAT 1 +#define WITH_GOPEN 1 +#define WITH_TERMIOS 1 +#define WITH_PIPE 1 +#define WITH_UNIX 1 +/* #undef WITH_ABSTRACT_UNIXSOCKET */ +#define WITH_IP4 1 +#define WITH_IP6 1 +#define WITH_RAWIP 1 +#define WITH_GENERICSOCKET 1 +/* #undef WITH_INTERFACE */ +#define WITH_TCP 1 +#define WITH_UDP 1 +/* #undef WITH_SCTP */ +#define WITH_LISTEN 1 +#define WITH_SOCKS4 1 +#define WITH_SOCKS4A 1 +#define WITH_PROXY 1 +#define WITH_EXEC 1 +#define WITH_SYSTEM 1 +#define WITH_READLINE 1 +/* #undef WITH_TUN */ +#define WITH_PTY 1 +#define WITH_EXT2 1 +#define WITH_OPENSSL 1 +#define WITH_STREAMS 1 +/* #undef WITH_FIPS */ +/* #undef OPENSSL_FIPS */ +#define WITH_LIBWRAP 1 +#define HAVE_TCPD_H 1 +#define HAVE_LIBWRAP 1 + +#define WITH_SYCLS 1 +#define WITH_FILAN 1 +#define WITH_RETRY 1 + +#define WITH_MSGLEVEL 0 + +#endif /* !defined(__config_h_included) */ diff --git a/Config/config.NetBSD-4-0.h b/Config/config.NetBSD-4-0.h new file mode 100644 index 0000000..27f18a9 --- /dev/null +++ b/Config/config.NetBSD-4-0.h @@ -0,0 +1,522 @@ +/* config.h. Generated from config.h.in by configure. */ +/* source: config.h.in */ +/* Copyright Gerhard Rieger 2001-2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __config_h_included +#define __config_h_included 1 + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct stat has st_blksize. */ +#define HAVE_ST_BLKSIZE 1 + +/* Define if your struct stat has st_blocks. */ +#define HAVE_ST_BLOCKS 1 + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the poll function. */ +#define HAVE_POLL 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the getpgid function. */ +#define HAVE_GETPGID 1 + +/* Define if you have the getsid function. */ +#define HAVE_GETSID 1 + +/* Define if you have the nanosleep function. */ +#define HAVE_NANOSLEEP 1 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getipnodebyname function. */ +/* #undef HAVE_GETIPNODEBYNAME */ + +/* Define if you have the setgroups function. */ +#define HAVE_SETGROUPS 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the memrchr function. */ +/* #undef HAVE_MEMRCHR */ + +/* Define if you have the if_indextoname function. */ +#define HAVE_IF_INDEXTONAME 1 + +/* Define if you have the sigaction function */ +#define HAVE_SIGACTION 1 + +/* Define if you have the stat64 function */ +/* #undef HAVE_STAT64 */ + +/* Define if you have the fstat64 function */ +/* #undef HAVE_FSTAT64 */ + +/* Define if you have the lstat64 function */ +/* #undef HAVE_LSTAT64 */ + +/* Define if you have the lseek64 function */ +/* #undef HAVE_LSEEK64 */ + +/* Define if you have the truncate64 function */ +/* #undef HAVE_TRUNCATE64 */ + +/* Define if you have the ftruncate64 function */ +/* #undef HAVE_FTRUNCATE64 */ + +/* Define if you have the strtoll function */ +#define HAVE_STRTOLL 1 + +/* Define if you have the hstrerror function */ +#define HAVE_HSTRERROR 1 + +/* Define if you have the inet_ntop function */ +#define HAVE_INET_NTOP 1 + +/* Define if you have the hstrerror prototype */ +#define HAVE_PROTOTYPE_HSTRERROR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_PTY_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP6_H 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define if you have the header file. */ +#define HAVE_RESOLV_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_DL_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_TYPES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_ERRQUEUE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_IF_TUN_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETPACKET_PACKET_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETINET_IF_ETHER_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ +#define HAVE_UTIL_H 1 + +/* Define if you have the header file. (FreeBSD: openpty()) */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define if you have the header file. (stream opts on SunOS)*/ +/* #undef HAVE_SYS_STROPTS_H */ + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_FS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_EXT2_FS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_READLINE_READLINE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_READLINE_HISTORY_H */ + +/* Define if you have the readline library. */ +/* #undef HAVE_LIBREADLINE */ + +/* Define if you have the m library (-lm). */ +/* #undef HAVE_LIBM */ + +/* Define if you have the floor function */ +/* #undef HAVE_FLOOR */ + +/* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ +/* #undef _XOPEN_EXTENDED_SOURCE */ + +/* fdset may have component fds_bits or __fds_bits */ +#define HAVE_FDS_BITS 1 + +/* Define if you have the sa_family_t */ +#define HAVE_TYPE_SA_FAMILY_T 1 + +/* define if your struct sigaction has sa_sigaction */ +#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 + +/* Define if your struct termios has component c_ispeed */ +#define HAVE_TERMIOS_ISPEED 1 + +/* the offset of c_ispeed in struct termios - usable in an speed_t array. + Applies only when HAVE_TERMIOS_ISPEED is set */ +#define ISPEED_OFFSET 9 + +/* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ +#ifdef ISPEED_OFFSET +# define OSPEED_OFFSET (ISPEED_OFFSET+1) +#else +/* # undef OSPEED_OFFSET */ +#endif + +/* Define if your termios.h likes _SVID3 defined */ +/* #undef _SVID3 */ + +/* Define if you have struct timespec (e.g. for nanosleep) */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* Define if you have struct linger */ +#define HAVE_STRUCT_LINGER 1 + +/* Define if you have struct ip_mreq */ +#define HAVE_STRUCT_IP_MREQ 1 + +/* Define if you have struct ip_mreqn */ +/* #undef HAVE_STRUCT_IP_MREQN */ + +/* Define if you have struct ipv6_mreq */ +#define HAVE_STRUCT_IPV6_MREQ 1 + +/* Define if you have struct ifreq */ +#define HAVE_STRUCT_IFREQ 1 + +/* Define if you have struct ifreq.ifr_index */ +/* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ + +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ +/* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ + +/* Define if your struct sockaddr has sa_len */ +#define HAVE_STRUCT_SOCKADDR_SALEN 1 + +/* there are several implementations of sockaddr_in6 */ +#define HAVE_IP6_SOCKADDR 0 + +/* Define if you have struct iovec */ +#define HAVE_STRUCT_IOVEC 1 + +/* define if your struct msghdr has msg_control */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 + +/* define if your struct msghdr has msg_controllen */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 + +/* define if your struct msghdr has msg_flag */ +#define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 + +/* define if you have struct cmsghdr */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* define if you have struct in_pktinfo */ +/* #undef HAVE_STRUCT_IN_PKTINFO */ + +/* define if your struct ip has ip_hl; otherwise assume ip_vhl */ +#define HAVE_STRUCT_IP_IP_HL 1 + +/* Define if you have the setenv function */ +#define HAVE_SETENV 1 + +/* Define if you have the unsetenv function. not on HP-UX */ +#define HAVE_UNSETENV 1 + +/* Define if you have the flock function */ +#define HAVE_FLOCK 1 + +/* Define if you have the openpty function */ +#define HAVE_OPENPTY 1 + +/* Define if you have the grantpt function */ +#define HAVE_GRANTPT 1 + +/* Define if you have the unlockpt function */ +#define HAVE_UNLOCKPT 1 + +/* Define if you have the ptsname function */ +#define HAVE_PTSNAME 1 + +/* Define if you have the /dev/ptmx pseudo terminal multiplexer */ +#define HAVE_DEV_PTMX 1 + +/* Define if you have the /dev/ptc pseudo terminal multiplexer */ +/* #undef HAVE_DEV_PTC */ + +/* Define if you have the long long type */ +#define HAVE_TYPE_LONGLONG 1 + +/* is socklen_t already typedef'd? */ +#define HAVE_TYPE_SOCKLEN 1 + +/* Define if you have the struct stat64 type */ +/* #undef HAVE_TYPE_STAT64 */ + +/* Define if you have the struct off64_t type */ +/* #undef HAVE_TYPE_OFF64 */ + +/* is sighandler_t already typedef'd? */ +/* #undef HAVE_TYPE_SIGHANDLER */ + +/* is uint8_t already defined? */ +#define HAVE_TYPE_UINT8 1 + +/* is uint16_t already defined? */ +#define HAVE_TYPE_UINT16 1 + +/* is uint32_t already defined? */ +#define HAVE_TYPE_UINT32 1 + +/* is uint64_t already defined? */ +#define HAVE_TYPE_UINT64 1 + +/* Define if you have the printf "Z" modifier */ +/* #undef HAVE_FORMAT_Z */ + +/* Define the shift offset of the CRDLY mask */ +#define CRDLY_SHIFT -1 + +/* Define the shift offset of the TABDLY mask */ +#define TABDLY_SHIFT -1 + +/* Define the shift offset of the CSIZE mask */ +#define CSIZE_SHIFT 8 + +/* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ +#define HAVE_HOSTS_ALLOW_TABLE 1 +#if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE +# define HAVE_HOSTS_DENY_TABLE 1 +#else +/* # undef HAVE_HOSTS_DENY_TABLE */ +#endif + +/* 1..short, 3..int, 5..long; 2,4,6..unsigned */ +#define HAVE_BASIC_SIZE_T 4 /* unsigned int */ +#define HAVE_BASIC_MODE_T 4 /* unsigned int */ +#define HAVE_BASIC_PID_T 3 /* int */ +#define HAVE_BASIC_UID_T 4 /* unsigned int */ +#define HAVE_BASIC_GID_T 4 /* unsigned int */ +#define HAVE_BASIC_TIME_T 5 /* long */ +#define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ + +#define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ + +#define HAVE_TYPEOF_ST_DEV 4 /* unsigned int */ +#define HAVE_TYPEOF_ST_INO 8 /* unsigned long long */ +#define HAVE_TYPEOF_ST_NLINK 4 /* unsigned int */ +#define HAVE_TYPEOF_ST_SIZE 7 /* long long */ +#define HAVE_TYPEOF_ST_BLKSIZE 4 /* unsigned int */ +#define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ + +/* #undef HAVE_TYPEOF_ST64_DEV */ +/* #undef HAVE_TYPEOF_ST64_INO */ +/* #undef HAVE_TYPEOF_ST64_NLINK */ +/* #undef HAVE_TYPEOF_ST64_SIZE */ +/* #undef HAVE_TYPEOF_ST64_BLKSIZE */ +/* #undef HAVE_TYPEOF_ST64_BLOCKS */ + +#define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ + +#define HAVE_TYPEOF_RLIM_MAX 7 /* long long */ + +/* Define if you have the /proc filesystem */ +#define HAVE_PROC_DIR 1 + +/* Define if you have the /proc/$$/fd directories */ +/* #undef HAVE_PROC_DIR_FD */ + +#define WITH_HELP 1 +#define WITH_STDIO 1 +#define WITH_FDNUM 1 +#define WITH_FILE 1 +#define WITH_CREAT 1 +#define WITH_GOPEN 1 +#define WITH_TERMIOS 1 +#define WITH_PIPE 1 +#define WITH_UNIX 1 +/* #undef WITH_ABSTRACT_UNIXSOCKET */ +#define WITH_IP4 1 +#define WITH_IP6 1 +#define WITH_RAWIP 1 +#define WITH_GENERICSOCKET 1 +/* #undef WITH_INTERFACE */ +#define WITH_TCP 1 +#define WITH_UDP 1 +/* #undef WITH_SCTP */ +#define WITH_LISTEN 1 +#define WITH_SOCKS4 1 +#define WITH_SOCKS4A 1 +#define WITH_PROXY 1 +#define WITH_EXEC 1 +#define WITH_SYSTEM 1 +/* #undef WITH_READLINE */ +/* #undef WITH_TUN */ +#define WITH_PTY 1 +#define WITH_EXT2 1 +#define WITH_OPENSSL 1 +#define WITH_STREAMS 1 +/* #undef WITH_FIPS */ +/* #undef OPENSSL_FIPS */ +#define WITH_LIBWRAP 1 +#define HAVE_TCPD_H 1 +#define HAVE_LIBWRAP 1 + +#define WITH_SYCLS 1 +#define WITH_FILAN 1 +#define WITH_RETRY 1 + +#define WITH_MSGLEVEL 0 + +#endif /* !defined(__config_h_included) */ diff --git a/Config/config.OpenBSD-4-3.h b/Config/config.OpenBSD-4-3.h new file mode 100644 index 0000000..a3852e1 --- /dev/null +++ b/Config/config.OpenBSD-4-3.h @@ -0,0 +1,522 @@ +/* config.h. Generated from config.h.in by configure. */ +/* source: config.h.in */ +/* Copyright Gerhard Rieger 2001-2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __config_h_included +#define __config_h_included 1 + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct stat has st_blksize. */ +#define HAVE_ST_BLKSIZE 1 + +/* Define if your struct stat has st_blocks. */ +#define HAVE_ST_BLOCKS 1 + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the poll function. */ +#define HAVE_POLL 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the getpgid function. */ +#define HAVE_GETPGID 1 + +/* Define if you have the getsid function. */ +#define HAVE_GETSID 1 + +/* Define if you have the nanosleep function. */ +#define HAVE_NANOSLEEP 1 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getipnodebyname function. */ +/* #undef HAVE_GETIPNODEBYNAME */ + +/* Define if you have the setgroups function. */ +#define HAVE_SETGROUPS 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the memrchr function. */ +#define HAVE_MEMRCHR 1 + +/* Define if you have the if_indextoname function. */ +#define HAVE_IF_INDEXTONAME 1 + +/* Define if you have the sigaction function */ +#define HAVE_SIGACTION 1 + +/* Define if you have the stat64 function */ +/* #undef HAVE_STAT64 */ + +/* Define if you have the fstat64 function */ +/* #undef HAVE_FSTAT64 */ + +/* Define if you have the lstat64 function */ +/* #undef HAVE_LSTAT64 */ + +/* Define if you have the lseek64 function */ +/* #undef HAVE_LSEEK64 */ + +/* Define if you have the truncate64 function */ +/* #undef HAVE_TRUNCATE64 */ + +/* Define if you have the ftruncate64 function */ +/* #undef HAVE_FTRUNCATE64 */ + +/* Define if you have the strtoll function */ +#define HAVE_STRTOLL 1 + +/* Define if you have the hstrerror function */ +#define HAVE_HSTRERROR 1 + +/* Define if you have the inet_ntop function */ +#define HAVE_INET_NTOP 1 + +/* Define if you have the hstrerror prototype */ +#define HAVE_PROTOTYPE_HSTRERROR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_PTY_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP6_H 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define if you have the header file. */ +#define HAVE_RESOLV_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_DL_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_TYPES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_ERRQUEUE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_IF_TUN_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETPACKET_PACKET_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETINET_IF_ETHER_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ +#define HAVE_UTIL_H 1 + +/* Define if you have the header file. (FreeBSD: openpty()) */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define if you have the header file. (stream opts on SunOS)*/ +/* #undef HAVE_SYS_STROPTS_H */ + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_FS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_EXT2_FS_H */ + +/* Define if you have the header file. */ +#define HAVE_READLINE_READLINE_H 1 + +/* Define if you have the header file. */ +#define HAVE_READLINE_HISTORY_H 1 + +/* Define if you have the readline library. */ +#define HAVE_LIBREADLINE 1 + +/* Define if you have the m library (-lm). */ +/* #undef HAVE_LIBM */ + +/* Define if you have the floor function */ +/* #undef HAVE_FLOOR */ + +/* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ +/* #undef _XOPEN_EXTENDED_SOURCE */ + +/* fdset may have component fds_bits or __fds_bits */ +#define HAVE_FDS_BITS 1 + +/* Define if you have the sa_family_t */ +#define HAVE_TYPE_SA_FAMILY_T 1 + +/* define if your struct sigaction has sa_sigaction */ +#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 + +/* Define if your struct termios has component c_ispeed */ +#define HAVE_TERMIOS_ISPEED 1 + +/* the offset of c_ispeed in struct termios - usable in an speed_t array. + Applies only when HAVE_TERMIOS_ISPEED is set */ +#define ISPEED_OFFSET 9 + +/* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ +#ifdef ISPEED_OFFSET +# define OSPEED_OFFSET (ISPEED_OFFSET+1) +#else +/* # undef OSPEED_OFFSET */ +#endif + +/* Define if your termios.h likes _SVID3 defined */ +/* #undef _SVID3 */ + +/* Define if you have struct timespec (e.g. for nanosleep) */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* Define if you have struct linger */ +#define HAVE_STRUCT_LINGER 1 + +/* Define if you have struct ip_mreq */ +#define HAVE_STRUCT_IP_MREQ 1 + +/* Define if you have struct ip_mreqn */ +/* #undef HAVE_STRUCT_IP_MREQN */ + +/* Define if you have struct ipv6_mreq */ +#define HAVE_STRUCT_IPV6_MREQ 1 + +/* Define if you have struct ifreq */ +#define HAVE_STRUCT_IFREQ 1 + +/* Define if you have struct ifreq.ifr_index */ +/* #undef HAVE_STRUCT_IFREQ_IFR_INDEX */ + +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ +/* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ + +/* Define if your struct sockaddr has sa_len */ +#define HAVE_STRUCT_SOCKADDR_SALEN 1 + +/* there are several implementations of sockaddr_in6 */ +#define HAVE_IP6_SOCKADDR 0 + +/* Define if you have struct iovec */ +/* #undef HAVE_STRUCT_IOVEC */ + +/* define if your struct msghdr has msg_control */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROL 1 + +/* define if your struct msghdr has msg_controllen */ +#define HAVE_STRUCT_MSGHDR_MSGCONTROLLEN 1 + +/* define if your struct msghdr has msg_flag */ +#define HAVE_STRUCT_MSGHDR_MSGFLAGS 1 + +/* define if you have struct cmsghdr */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* define if you have struct in_pktinfo */ +/* #undef HAVE_STRUCT_IN_PKTINFO */ + +/* define if your struct ip has ip_hl; otherwise assume ip_vhl */ +#define HAVE_STRUCT_IP_IP_HL 1 + +/* Define if you have the setenv function */ +#define HAVE_SETENV 1 + +/* Define if you have the unsetenv function. not on HP-UX */ +#define HAVE_UNSETENV 1 + +/* Define if you have the flock function */ +#define HAVE_FLOCK 1 + +/* Define if you have the openpty function */ +#define HAVE_OPENPTY 1 + +/* Define if you have the grantpt function */ +/* #undef HAVE_GRANTPT */ + +/* Define if you have the unlockpt function */ +/* #undef HAVE_UNLOCKPT */ + +/* Define if you have the ptsname function */ +/* #undef HAVE_PTSNAME */ + +/* Define if you have the /dev/ptmx pseudo terminal multiplexer */ +/* #undef HAVE_DEV_PTMX */ + +/* Define if you have the /dev/ptc pseudo terminal multiplexer */ +/* #undef HAVE_DEV_PTC */ + +/* Define if you have the long long type */ +#define HAVE_TYPE_LONGLONG 1 + +/* is socklen_t already typedef'd? */ +#define HAVE_TYPE_SOCKLEN 1 + +/* Define if you have the struct stat64 type */ +/* #undef HAVE_TYPE_STAT64 */ + +/* Define if you have the struct off64_t type */ +/* #undef HAVE_TYPE_OFF64 */ + +/* is sighandler_t already typedef'd? */ +/* #undef HAVE_TYPE_SIGHANDLER */ + +/* is uint8_t already defined? */ +#define HAVE_TYPE_UINT8 1 + +/* is uint16_t already defined? */ +#define HAVE_TYPE_UINT16 1 + +/* is uint32_t already defined? */ +#define HAVE_TYPE_UINT32 1 + +/* is uint64_t already defined? */ +#define HAVE_TYPE_UINT64 1 + +/* Define if you have the printf "Z" modifier */ +/* #undef HAVE_FORMAT_Z */ + +/* Define the shift offset of the CRDLY mask */ +#define CRDLY_SHIFT -1 + +/* Define the shift offset of the TABDLY mask */ +#define TABDLY_SHIFT -1 + +/* Define the shift offset of the CSIZE mask */ +#define CSIZE_SHIFT 8 + +/* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ +#define HAVE_HOSTS_ALLOW_TABLE 1 +#if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE +# define HAVE_HOSTS_DENY_TABLE 1 +#else +/* # undef HAVE_HOSTS_DENY_TABLE */ +#endif + +/* 1..short, 3..int, 5..long; 2,4,6..unsigned */ +#define HAVE_BASIC_SIZE_T 6 /* unsigned long */ +#define HAVE_BASIC_MODE_T 4 /* unsigned int */ +#define HAVE_BASIC_PID_T 3 /* int */ +#define HAVE_BASIC_UID_T 4 /* unsigned int */ +#define HAVE_BASIC_GID_T 4 /* unsigned int */ +#define HAVE_BASIC_TIME_T 3 /* int */ +#define HAVE_BASIC_OFF64_T 0 /* unknown, taking default */ + +#define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ + +#define HAVE_TYPEOF_ST_DEV 3 /* int */ +#define HAVE_TYPEOF_ST_INO 4 /* unsigned int */ +#define HAVE_TYPEOF_ST_NLINK 4 /* unsigned int */ +#define HAVE_TYPEOF_ST_SIZE 7 /* long long */ +#define HAVE_TYPEOF_ST_BLKSIZE 4 /* unsigned int */ +#define HAVE_TYPEOF_ST_BLOCKS 7 /* long long */ + +/* #undef HAVE_TYPEOF_ST64_DEV */ +/* #undef HAVE_TYPEOF_ST64_INO */ +/* #undef HAVE_TYPEOF_ST64_NLINK */ +/* #undef HAVE_TYPEOF_ST64_SIZE */ +/* #undef HAVE_TYPEOF_ST64_BLKSIZE */ +/* #undef HAVE_TYPEOF_ST64_BLOCKS */ + +#define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ + +#define HAVE_TYPEOF_RLIM_MAX 8 /* unsigned long long */ + +/* Define if you have the /proc filesystem */ +/* #undef HAVE_PROC_DIR */ + +/* Define if you have the /proc/$$/fd directories */ +/* #undef HAVE_PROC_DIR_FD */ + +#define WITH_HELP 1 +#define WITH_STDIO 1 +#define WITH_FDNUM 1 +#define WITH_FILE 1 +#define WITH_CREAT 1 +#define WITH_GOPEN 1 +#define WITH_TERMIOS 1 +#define WITH_PIPE 1 +#define WITH_UNIX 1 +/* #undef WITH_ABSTRACT_UNIXSOCKET */ +#define WITH_IP4 1 +#define WITH_IP6 1 +#define WITH_RAWIP 1 +#define WITH_GENERICSOCKET 1 +/* #undef WITH_INTERFACE */ +#define WITH_TCP 1 +#define WITH_UDP 1 +/* #undef WITH_SCTP */ +#define WITH_LISTEN 1 +#define WITH_SOCKS4 1 +#define WITH_SOCKS4A 1 +#define WITH_PROXY 1 +#define WITH_EXEC 1 +#define WITH_SYSTEM 1 +#define WITH_READLINE 1 +/* #undef WITH_TUN */ +#define WITH_PTY 1 +#define WITH_EXT2 1 +#define WITH_OPENSSL 1 +#define WITH_STREAMS 1 +/* #undef WITH_FIPS */ +/* #undef OPENSSL_FIPS */ +#define WITH_LIBWRAP 1 +#define HAVE_TCPD_H 1 +#define HAVE_LIBWRAP 1 + +#define WITH_SYCLS 1 +#define WITH_FILAN 1 +#define WITH_RETRY 1 + +#define WITH_MSGLEVEL 0 + +#endif /* !defined(__config_h_included) */ diff --git a/Config/config.SunOS-5-10.h b/Config/config.SunOS-5-10.h new file mode 100644 index 0000000..1745c80 --- /dev/null +++ b/Config/config.SunOS-5-10.h @@ -0,0 +1,522 @@ +/* config.h. Generated from config.h.in by configure. */ +/* source: config.h.in */ +/* Copyright Gerhard Rieger 2001-2008 */ +/* Published under the GNU General Public License V.2, see file COPYING */ + +#ifndef __config_h_included +#define __config_h_included 1 + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct stat has st_blksize. */ +#define HAVE_ST_BLKSIZE 1 + +/* Define if your struct stat has st_blocks. */ +#define HAVE_ST_BLOCKS 1 + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the poll function. */ +#define HAVE_POLL 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the getpgid function. */ +#define HAVE_GETPGID 1 + +/* Define if you have the getsid function. */ +#define HAVE_GETSID 1 + +/* Define if you have the nanosleep function. */ +#define HAVE_NANOSLEEP 1 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getipnodebyname function. */ +#define HAVE_GETIPNODEBYNAME 1 + +/* Define if you have the setgroups function. */ +#define HAVE_SETGROUPS 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the memrchr function. */ +/* #undef HAVE_MEMRCHR */ + +/* Define if you have the if_indextoname function. */ +#define HAVE_IF_INDEXTONAME 1 + +/* Define if you have the sigaction function */ +#define HAVE_SIGACTION 1 + +/* Define if you have the stat64 function */ +#define HAVE_STAT64 1 + +/* Define if you have the fstat64 function */ +#define HAVE_FSTAT64 1 + +/* Define if you have the lstat64 function */ +#define HAVE_LSTAT64 1 + +/* Define if you have the lseek64 function */ +#define HAVE_LSEEK64 1 + +/* Define if you have the truncate64 function */ +#define HAVE_TRUNCATE64 1 + +/* Define if you have the ftruncate64 function */ +#define HAVE_FTRUNCATE64 1 + +/* Define if you have the strtoll function */ +#define HAVE_STRTOLL 1 + +/* Define if you have the hstrerror function */ +#define HAVE_HSTRERROR 1 + +/* Define if you have the inet_ntop function */ +#define HAVE_INET_NTOP 1 + +/* Define if you have the hstrerror prototype */ +#define HAVE_PROTOTYPE_HSTRERROR 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_PTY_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IP6_H 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define if you have the header file. */ +#define HAVE_RESOLV_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_DL_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_TYPES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_ERRQUEUE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_IF_TUN_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETPACKET_PACKET_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NETINET_IF_ETHER_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. (AIX) */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. (NetBSD, OpenBSD: openpty()) */ +/* #undef HAVE_UTIL_H */ + +/* Define if you have the header file. (FreeBSD: openpty()) */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define if you have the header file. (stream opts on SunOS)*/ +#define HAVE_SYS_STROPTS_H 1 + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_FS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_EXT2_FS_H */ + +/* Define if you have the header file. */ +#define HAVE_READLINE_READLINE_H 1 + +/* Define if you have the header file. */ +#define HAVE_READLINE_HISTORY_H 1 + +/* Define if you have the readline library. */ +#define HAVE_LIBREADLINE 1 + +/* Define if you have the m library (-lm). */ +/* #undef HAVE_LIBM */ + +/* Define if you have the floor function */ +/* #undef HAVE_FLOOR */ + +/* some platforms need _XOPEN_EXTENDED_SOURCE to get syslog headers (AIX4.1) */ +/* #undef _XOPEN_EXTENDED_SOURCE */ + +/* fdset may have component fds_bits or __fds_bits */ +#define HAVE_FDS_BITS 1 + +/* Define if you have the sa_family_t */ +#define HAVE_TYPE_SA_FAMILY_T 1 + +/* define if your struct sigaction has sa_sigaction */ +#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1 + +/* Define if your struct termios has component c_ispeed */ +/* #undef HAVE_TERMIOS_ISPEED */ + +/* the offset of c_ispeed in struct termios - usable in an speed_t array. + Applies only when HAVE_TERMIOS_ISPEED is set */ +/* #undef ISPEED_OFFSET */ + +/* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */ +#ifdef ISPEED_OFFSET +# define OSPEED_OFFSET (ISPEED_OFFSET+1) +#else +/* # undef OSPEED_OFFSET */ +#endif + +/* Define if your termios.h likes _SVID3 defined */ +/* #undef _SVID3 */ + +/* Define if you have struct timespec (e.g. for nanosleep) */ +#define HAVE_STRUCT_TIMESPEC 1 + +/* Define if you have struct linger */ +#define HAVE_STRUCT_LINGER 1 + +/* Define if you have struct ip_mreq */ +#define HAVE_STRUCT_IP_MREQ 1 + +/* Define if you have struct ip_mreqn */ +/* #undef HAVE_STRUCT_IP_MREQN */ + +/* Define if you have struct ipv6_mreq */ +#define HAVE_STRUCT_IPV6_MREQ 1 + +/* Define if you have struct ifreq */ +#define HAVE_STRUCT_IFREQ 1 + +/* Define if you have struct ifreq.ifr_index */ +#define HAVE_STRUCT_IFREQ_IFR_INDEX 1 + +/* Define if you have struct ifreq.ifr_ifindex; not on HPUX */ +/* #undef HAVE_STRUCT_IFREQ_IFR_IFINDEX */ + +/* Define if your struct sockaddr has sa_len */ +/* #undef HAVE_STRUCT_SOCKADDR_SALEN */ + +/* there are several implementations of sockaddr_in6 */ +#define HAVE_IP6_SOCKADDR 0 + +/* Define if you have struct iovec */ +#define HAVE_STRUCT_IOVEC 1 + +/* define if your struct msghdr has msg_control */ +/* #undef HAVE_STRUCT_MSGHDR_MSGCONTROL */ + +/* define if your struct msghdr has msg_controllen */ +/* #undef HAVE_STRUCT_MSGHDR_MSGCONTROLLEN */ + +/* define if your struct msghdr has msg_flag */ +/* #undef HAVE_STRUCT_MSGHDR_MSGFLAGS */ + +/* define if you have struct cmsghdr */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* define if you have struct in_pktinfo */ +/* #undef HAVE_STRUCT_IN_PKTINFO */ + +/* define if your struct ip has ip_hl; otherwise assume ip_vhl */ +#define HAVE_STRUCT_IP_IP_HL 1 + +/* Define if you have the setenv function */ +#define HAVE_SETENV 1 + +/* Define if you have the unsetenv function. not on HP-UX */ +#define HAVE_UNSETENV 1 + +/* Define if you have the flock function */ +/* #undef HAVE_FLOCK */ + +/* Define if you have the openpty function */ +/* #undef HAVE_OPENPTY */ + +/* Define if you have the grantpt function */ +#define HAVE_GRANTPT 1 + +/* Define if you have the unlockpt function */ +#define HAVE_UNLOCKPT 1 + +/* Define if you have the ptsname function */ +#define HAVE_PTSNAME 1 + +/* Define if you have the /dev/ptmx pseudo terminal multiplexer */ +#define HAVE_DEV_PTMX 1 + +/* Define if you have the /dev/ptc pseudo terminal multiplexer */ +/* #undef HAVE_DEV_PTC */ + +/* Define if you have the long long type */ +#define HAVE_TYPE_LONGLONG 1 + +/* is socklen_t already typedef'd? */ +#define HAVE_TYPE_SOCKLEN 1 + +/* Define if you have the struct stat64 type */ +#define HAVE_TYPE_STAT64 1 + +/* Define if you have the struct off64_t type */ +#define HAVE_TYPE_OFF64 1 + +/* is sighandler_t already typedef'd? */ +/* #undef HAVE_TYPE_SIGHANDLER */ + +/* is uint8_t already defined? */ +#define HAVE_TYPE_UINT8 1 + +/* is uint16_t already defined? */ +#define HAVE_TYPE_UINT16 1 + +/* is uint32_t already defined? */ +#define HAVE_TYPE_UINT32 1 + +/* is uint64_t already defined? */ +#define HAVE_TYPE_UINT64 1 + +/* Define if you have the printf "Z" modifier */ +/* #undef HAVE_FORMAT_Z */ + +/* Define the shift offset of the CRDLY mask */ +#define CRDLY_SHIFT 9 + +/* Define the shift offset of the TABDLY mask */ +#define TABDLY_SHIFT 11 + +/* Define the shift offset of the CSIZE mask */ +#define CSIZE_SHIFT 4 + +/* Define if you have tcpwrappers (libwrap, tcpd) and it declares hosts_allow_table */ +#define HAVE_HOSTS_ALLOW_TABLE 1 +#if defined(HAVE_HOSTS_ALLOW_TABLE) && HAVE_HOSTS_ALLOW_TABLE +# define HAVE_HOSTS_DENY_TABLE 1 +#else +/* # undef HAVE_HOSTS_DENY_TABLE */ +#endif + +/* 1..short, 3..int, 5..long; 2,4,6..unsigned */ +#define HAVE_BASIC_SIZE_T 4 /* unsigned int */ +#define HAVE_BASIC_MODE_T 6 /* unsigned long */ +#define HAVE_BASIC_PID_T 5 /* long */ +#define HAVE_BASIC_UID_T 5 /* long */ +#define HAVE_BASIC_GID_T 5 /* long */ +#define HAVE_BASIC_TIME_T 5 /* long */ +#define HAVE_BASIC_OFF64_T 7 /* long long */ + +#define HAVE_BASIC_SOCKLEN_T 4 /* unsigned int */ + +#define HAVE_TYPEOF_ST_DEV 6 /* unsigned long */ +#define HAVE_TYPEOF_ST_INO 6 /* unsigned long */ +#define HAVE_TYPEOF_ST_NLINK 6 /* unsigned long */ +#define HAVE_TYPEOF_ST_SIZE 5 /* long */ +#define HAVE_TYPEOF_ST_BLKSIZE 5 /* long */ +#define HAVE_TYPEOF_ST_BLOCKS 5 /* long */ + +#define HAVE_TYPEOF_ST64_DEV 6 /* unsigned long */ +#define HAVE_TYPEOF_ST64_INO 8 /* unsigned long long */ +#define HAVE_TYPEOF_ST64_NLINK 6 /* unsigned long */ +#define HAVE_TYPEOF_ST64_SIZE 7 /* long long */ +#define HAVE_TYPEOF_ST64_BLKSIZE 5 /* long */ +#define HAVE_TYPEOF_ST64_BLOCKS 7 /* long long */ + +#define HAVE_TYPEOF_STRUCT_TIMEVAL_TV_USEC 5 /* long */ + +#define HAVE_TYPEOF_RLIM_MAX 6 /* unsigned long */ + +/* Define if you have the /proc filesystem */ +#define HAVE_PROC_DIR 1 + +/* Define if you have the /proc/$$/fd directories */ +#define HAVE_PROC_DIR_FD 1 + +#define WITH_HELP 1 +#define WITH_STDIO 1 +#define WITH_FDNUM 1 +#define WITH_FILE 1 +#define WITH_CREAT 1 +#define WITH_GOPEN 1 +#define WITH_TERMIOS 1 +#define WITH_PIPE 1 +#define WITH_UNIX 1 +/* #undef WITH_ABSTRACT_UNIXSOCKET */ +#define WITH_IP4 1 +#define WITH_IP6 1 +#define WITH_RAWIP 1 +#define WITH_GENERICSOCKET 1 +/* #undef WITH_INTERFACE */ +#define WITH_TCP 1 +#define WITH_UDP 1 +#define WITH_SCTP 1 +#define WITH_LISTEN 1 +#define WITH_SOCKS4 1 +#define WITH_SOCKS4A 1 +#define WITH_PROXY 1 +#define WITH_EXEC 1 +#define WITH_SYSTEM 1 +#define WITH_READLINE 1 +/* #undef WITH_TUN */ +#define WITH_PTY 1 +#define WITH_EXT2 1 +#define WITH_OPENSSL 1 +#define WITH_STREAMS 1 +/* #undef WITH_FIPS */ +/* #undef OPENSSL_FIPS */ +#define WITH_LIBWRAP 1 +#define HAVE_TCPD_H 1 +#define HAVE_LIBWRAP 1 + +#define WITH_SYCLS 1 +#define WITH_FILAN 1 +#define WITH_RETRY 1 + +#define WITH_MSGLEVEL 0 + +#endif /* !defined(__config_h_included) */ From 102e356db79e993614e9b3f47c874fb6d1e67494 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 15 Oct 2008 22:50:25 +0200 Subject: [PATCH 70/75] prepared code for generic xiocheckrange --- xio-socket.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xio-socket.c b/xio-socket.c index b924f66..a28710f 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1671,6 +1671,8 @@ int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv) { } +/* check if peer address is within permitted range. + return >= 0 if so. */ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) { switch (sa->soa.sa_family) { #if WITH_IP4 @@ -1683,6 +1685,18 @@ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) { return xiocheckrange_ip6(&sa->ip6, range); #endif /* WITH_IP6 */ +#if 0 + case PF_UNSPEC: + { + socklen_t i; + for (i = 0; i < sizeof(sa->soa.sa_data); ++i) { + if ((range->netmask.soa.sa_data[i] & sa->soa.sa_data[i]) != range->netaddr.soa.sa_data[i]) { + return -1; + } + } + return 0; + } +#endif } return -1; } From 74f904fdc9a71b4ad857d277d43d4da2a3d7cf1c Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 15 Oct 2008 22:50:44 +0200 Subject: [PATCH 71/75] corrected copyright year --- xio-gopen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xio-gopen.c b/xio-gopen.c index 7c1497f..a30f61a 100644 --- a/xio-gopen.c +++ b/xio-gopen.c @@ -1,5 +1,5 @@ /* source: xio-gopen.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of generic open type */ From 4a7fee2d3589d59e0c2b1db76e4243bcb477f3e2 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 15 Oct 2008 22:51:18 +0200 Subject: [PATCH 72/75] actualized list of platform config files --- Makefile.in | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index fb6329e..5eaab88 100644 --- a/Makefile.in +++ b/Makefile.in @@ -73,19 +73,18 @@ HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes. xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h -DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html +DOCFILES = README README.FIPS CHANGES FILES EXAMPLES PORTING SECURITY DEVELOPMENT doc/socat.yo doc/socat.1 doc/socat.html doc/xio.help FAQ BUGREPORTS COPYING COPYING.OpenSSL doc/dest-unreach.css doc/socat-openssltunnel.html doc/socat-multicast.html doc/socat-tun.html doc/socat-genericsocket.html SHFILES = daemon.sh mail.sh ftp.sh readline.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh gatherinfo.sh readline-test.sh \ proxy.sh socks4a-echo.sh testcert.conf -OSFILES = Config/Makefile.Linux-2-6-16 Config/config.Linux-2-6-16.h \ - Config/Makefile.AIX-5-1 Config/config.AIX-5-1.h \ - Config/Makefile.SunOS-5-8 Config/config.SunOS-5-8.h \ - Config/Makefile.HP-UX-B-11-11 Config/config.HP-UX-B-11-11.h \ +OSFILES = Config/Makefile.Linux-2-6-24 Config/config.Linux-2-6-24.h \ + Config/Makefile.SunOS-5-10 Config/config.SunOS-5-10.h \ Config/Makefile.FreeBSD-6-1 Config/config.FreeBSD-6-1.h \ - Config/Makefile.NetBSD-2-0-2 Config/config.NetBSD-2-0-2.h \ - Config/Makefile.OpenBSD-3-8 Config/config.OpenBSD-3-8.h \ - Config/Makefile.Tru64-5-1B Config/config.Tru64-5-1B.h - + Config/Makefile.NetBSD-4-0 Config/config.NetBSD-4-0.h \ + Config/Makefile.OpenBSD-4-3 Config/config.OpenBSD-4-3.h \ + Config/Makefile.AIX-5-3 Config/config.AIX-5-3.h \ + Config/Makefile.Cygwin-1-5-25 Config/config.Cygwin-1-5-25.h \ + Config/Makefile.MacOSX-10-5 Config/config.MacOSX-10-5.h all: progs doc From 3a060c1cf34246da0b4ca5113ee08c6b78890501 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 15 Oct 2008 22:52:10 +0200 Subject: [PATCH 73/75] new examples for dumping, usleep, http echo server --- EXAMPLES | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/EXAMPLES b/EXAMPLES index 60ca020..eca34f3 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -37,6 +37,16 @@ $ socat -,raw,echo=0 tcp:172.16.181.130:2023 // replace /bin/login by /bin/bash when using SSL client authentication, can be // run without root then +// this is a cool trick, proposed by Christophe Lohr, to dump communications to +// two files; it would also work for other manipulations (recode, compress...) +// and it might also work with netcat ;-) +$ socat TCP-LISTEN:5555 SYSTEM:'tee l2r | socat - "TCP:remote:5555" | tee r2l' + +/////////////////////////////////////////////////////////////////////////////// +// emergence solution because usleep(1) is not always available +// this will "sleep" for 0.1s +$ socat -T 0.1 pipe pipe + /////////////////////////////////////////////////////////////////////////////// // a very primitive HTTP/1.0 echo server (problems: sends reply headers before // request; hangs if client does not shutdown - HTTP keep-alive) @@ -45,6 +55,11 @@ $ socat -,raw,echo=0 tcp:172.16.181.130:2023 // incoming data back to client $ socat TCP-LISTEN:8000,crlf SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; cat" +// a less primitive HTTP echo server that sends back not only the reqest but +// also server and client address and port. Might have portability issues with +// echo +./socat -T 1 -d -d tcp-l:10081,reuseaddr,fork,crlf system:"echo -e \"\\\"HTTP/1.0 200 OK\\\nDocumentType: text/html\\\n\\\ndate: \$\(date\)
server:\$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT
client: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\\\n
\\\"\"; cat; echo -e \"\\\"\\\n
\\\"\"" + /////////////////////////////////////////////////////////////////////////////// // for communicating with an attached modem, I had reasonable results with // following command line. Required privileges depend on device mode. @@ -292,6 +307,7 @@ $ socat -d -d -d -d - udp-datagram:224.0.0.2:6666,bind=:6666,ip-add-membership=2 // on my Linux system I find in /usr/include/linux/cdrom.h the define: // #define CDROMEJECT 0x5309 /* Ejects the cdrom media */ // the following command makes something like ioctl(fd, CDROMEJECT, NULL) +// (don't care about the read error): $ socat /dev/cdrom,o-nonblock,ioctl-void=0x5309 - // setsockopt(): SO_REUSEADDR From 3d41d1db9d1924aa01ff93b5cbfdd65ff91670ee Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 15 Oct 2008 22:54:12 +0200 Subject: [PATCH 74/75] new examples, corrections eg. for SCTP, some fixes --- doc/socat.yo | 170 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 66 deletions(-) diff --git a/doc/socat.yo b/doc/socat.yo index ef39d84..528d091 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -10,7 +10,7 @@ def(Filan)(0)(bf(Filan)) def(procan)(0)(bf(procan)) def(Procan)(0)(bf(Procan)) -manpage(socat)(1)(Sep 2008)(socat)() +manpage(socat)(1)(Oct 2008)()() whenhtml( label(CONTENTS) @@ -348,6 +348,15 @@ label(ADDRESS_IP_SENDTO)dit(bf(tt(IP-SENDTO::))) link(IP-RECV)(ADDRESS_IP_RECV), link(UDP-SENDTO)(ADDRESS_UDP_SENDTO) link(UNIX-SENDTO)(ADDRESS_UNIX_SENDTO) +label(ADDRESS_INTERFACE)dit(bf(tt(INTERFACE:))) + Communicate with a network connected on an interface using raw packets + including link level data. link()(TYPE_INTERFACE) is the name of + the network interface. Currently only available on Linux. + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) nl() + Useful options: + link(pf)(OPTION_PROTOCOL_FAMILY) + link(type)(OPTION_SO_TYPE)nl() + See also: link(ip-recv)(ADDRESS_IP_RECV) label(ADDRESS_IP4_SENDTO)dit(bf(tt(IP4-SENDTO::))) Like link(IP-SENDTO)(ADDRESS_IP_SENDTO), but always uses IPv4.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4) nl() @@ -541,15 +550,6 @@ label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:))) link(mode)(OPTION_MODE), link(unlink-early)(OPTION_UNLINK_EARLY)nl() See also: link(unnamed pipe)(ADDRESS_UNNAMED_PIPE) -label(ADDRESS_INTERFACE)dit(bf(tt(INTERFACE:))) - Communicate with a network connected on an interface using raw packets - including link level data. link()(TYPE_INTERFACE) is the name of - the network interface. Currently only available on Linux. - Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) nl() - Useful options: - link(pf)(OPTION_PROTOCOL_FAMILY) - link(so-type)(OPTION_SO_TYPE)nl() - See also: link(ip-recv)(ADDRESS_IP_RECV) label(ADDRESS_UNNAMED_PIPE)dit(bf(tt(PIPE))) Creates an unnamed pipe and uses it for reading and writing. It works as an echo, because everything written @@ -621,8 +621,8 @@ label(ADDRESS_SCTP_CONNECT)dit(bf(tt(SCTP-CONNECT::))) link(connect-timeout)(OPTION_CONNECT_TIMEOUT), link(tos)(OPTION_TOS), link(mtudiscover)(OPTION_MTUDISCOVER), - link(mss)(OPTION_MSS), - link(nodelay)(OPTION_NODELAY), + link(sctp-maxseg)(OPTION_SCTP_MAXSEG), + link(sctp-nodelay)(OPTION_SCTP_NODELAY), link(nonblock)(OPTION_NONBLOCK), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY), @@ -654,7 +654,8 @@ label(ADDRESS_SCTP_LISTEN)dit(bf(tt(SCTP-LISTEN:))) link(tcpwrap)(OPTION_TCPWRAPPERS), link(pf)(OPTION_PROTOCOL_FAMILY), link(backlog)(OPTION_BACKLOG), - link(mss)(OPTION_MSS), + link(sctp-maxseg)(OPTION_SCTP_MAXSEG), + link(sctp-nodelay)(OPTION_SCTP_NODELAY), link(su)(OPTION_SUBSTUSER), link(reuseaddr)(OPTION_REUSEADDR), link(retry)(OPTION_RETRY), @@ -707,7 +708,7 @@ label(ADDRESS_SOCKET_DATAGRAM)dit(bf(tt(SOCKET-DATAGRAM:::::::::::< appropriate values. The remote-address must be the link(data)(TYPE_DATA) representation of a sockaddr structure without sa_family and (BSD) sa_len components.nl() - Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) + Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET)nl() Useful options: link(bind)(OPTION_BIND), link(setsockopt-int)(OPTION_SETSOCKOPT_INT), @@ -1946,38 +1947,39 @@ COMMENT( x00 end of option list label(OPTION_MTUDISCOVER)dit(bf(tt(mtudiscover=<0|1|2>))) Takes 0, 1, 2 to never, want, or always use path MTU discover on this socket. -COMMENT(label(OPTION_HRDINCL)dit(bf(tt(hdrincl))) +COMMENT(label(OPTION_HRDINCL)dit(bf(tt(ip-hdrincl))) Tell the raw socket that the application data includes the IP header.) -COMMENT(label(OPTION_IP_MULTICAST_LOOP)dit(bf(tt(multicastloop))) +COMMENT(label(OPTION_IP_MULTICAST_LOOP)dit(bf(tt(ip-multicastloop))) Allow looping back outgoing multicast to the local interface.) -COMMENT(label(OPTION_IP_MULTICAST_TTL)dit(bf(tt(multicastttl))) +COMMENT(label(OPTION_IP_MULTICAST_TTL)dit(bf(tt(ip-multicastttl))) Set the TTL for outgoing multicast packets.) -label(OPTION_IP_PKTINFO)dit(bf(tt(pktinfo))) +label(OPTION_IP_PKTINFO)dit(bf(tt(ip-pktinfo))) Sets the IP_PKTINFO socket option. This enables receiving and logging of - ancillary messages containing destination address and interface (Linux). -COMMENT(label(OPTION_PKTOPTS)dit(bf(tt(pktopts))) + ancillary messages containing destination address and interface (Linux) + (link(example)(EXAMPLE_ANCILLARY)). +COMMENT(label(OPTION_PKTOPTS)dit(bf(tt(ip-pktopts))) Set the IP_PKTOPTIONS socket option.) -label(OPTION_IP_RECVERR)dit(bf(tt(recverr))) +label(OPTION_IP_RECVERR)dit(bf(tt(ip-recverr))) Sets the IP_RECVERR socket option. This enables receiving and logging of ancillary messages containing detailled error information. -label(OPTION_IP_RECVOPTS)dit(bf(tt(recvopts))) +label(OPTION_IP_RECVOPTS)dit(bf(tt(ip-recvopts))) Sets the IP_RECVOPTS socket option. This enables receiving and logging of IP options ancillary messages (Linux, *BSD). -label(OPTION_IP_RECVTOS)dit(bf(tt(recvtos))) +label(OPTION_IP_RECVTOS)dit(bf(tt(ip-recvtos))) Sets the IP_RECVTOS socket option. This enables receiving and logging of TOS (type of service) ancillary messages (Linux). -label(OPTION_IP_RECVTTL)dit(bf(tt(recvttl))) +label(OPTION_IP_RECVTTL)dit(bf(tt(ip-recvttl))) Sets the IP_RECVTTL socket option. This enables receiving and logging of TTL (time to live) ancillary messages (Linux, *BSD). -COMMENT(label(OPTION_RETOPTS)dit(bf(tt(retopts))) +COMMENT(label(OPTION_RETOPTS)dit(bf(tt(ip-retopts))) Set the IP_RETOPTS socket option.) -label(OPTION_IP_RECVDSTADDR)dit(bf(tt(recvdstaddr))) +label(OPTION_IP_RECVDSTADDR)dit(bf(tt(ip-recvdstaddr))) Sets the IP_RECVDSTADDR socket option. This enables receiving and logging of - ancillary messages containing destination address - (*BSD). -label(OPTION_IP_RECVIF)dit(bf(tt(recvif))) + ancillary messages containing destination address (*BSD) + (link(example)(EXAMPLE_ANCILLARY)). +label(OPTION_IP_RECVIF)dit(bf(tt(ip-recvif))) Sets the IP_RECVIF socket option. This enables receiving and logging of - interface ancillary messages (*BSD). + interface ancillary messages (*BSD) (link(example)(EXAMPLE_ANCILLARY)). COMMENT(label(OPTION_ROUTERALERT)dit(bf(tt(routeralert))) Set the IP_ROUTER_ALERT socket option.) label(OPTION_IP_ADD_MEMBERSHIP) @@ -2150,8 +2152,8 @@ startdit()enddit()nl() em(bf(UDP, TCP, and SCTP option groups)) -Here we find options that are related to the network port mechanism and that -thus can be used with UDP, TCP, and SCTP client and server addresses. +Here we find options that are related to the network port mechanism and thus +can be used with UDP, TCP, and SCTP client and server addresses. startdit() label(OPTION_SOURCEPORT)dit(bf(tt(sourceport=))) For outgoing (client) TCP and UDP connections, it sets the source @@ -2834,7 +2836,7 @@ startdit() label(EXAMPLE_ADDRESS_TCP4_CONNECT) dit(bf(tt(socat - TCP4:www.domain.org:80))) -Transfers data between link(STDIO)(ADDRESS_STDIO) (-) and a +transfers data between link(STDIO)(ADDRESS_STDIO) (-) and a link(TCP4)(ADDRESS_TCP4_CONNECT) connection to port 80 of host www.domain.org. This example results in an interactive connection similar to telnet or netcat. The stdin terminal parameters are not changed, so you may @@ -2851,22 +2853,22 @@ mancommand(\.fi) htmlcommand(
socat -d -d READLINE,history=$HOME/.http_history \
TCP4:www.domain.org:www,crnl
) -This is similar to the previous example, but you can edit the current line in a +this is similar to the previous example, but you can edit the current line in a bash like manner (link(READLINE)(ADDRESS_READLINE)) and use the -link(history)(OPTION_HISTORY) file .http_history; socat() -prints messages about progress (link(-d -d)(option_d_d)). The port is specified by service name -(www), and correct network line termination characters (link(crnl)(OPTION_CRNL)) instead of NL -are used. +link(history)(OPTION_HISTORY) file .http_history; socat() prints messages about +progress (link(-d -d)(option_d_d)). The port is specified by service name +(www), and correct network line termination characters +(link(crnl)(OPTION_CRNL)) instead of NL are used. label(EXAMPLE_ADDRESS_TCP4_LISTEN) dit(bf(tt(socat TCP4-LISTEN:www TCP4:www.domain.org:www))) -Installs a simple TCP port forwarder. With +installs a simple TCP port forwarder. With link(TCP4-LISTEN)(ADDRESS_TCP4_LISTEN) it listens on local port "www" until a connection comes in, accepts it, then connects to the remote host -(link(TCP4)(ADDRESS_TCP4_CONNECT)) and starts data transfer. It will not accept a -second connection. +(link(TCP4)(ADDRESS_TCP4_CONNECT)) and starts data transfer. It will not accept +a econd connection. label(EXAMPLE_OPTION_BIND_TCP4) label(EXAMPLE_OPTION_REUSEADDR) @@ -2890,9 +2892,10 @@ arbitrary number of parallel or consecutive connections by link(fork)(OPTION_FORK)'ing a new process after each code(accept()). It provides a little security by link(su)(OPTION_SUBSTUSER)'ing to user -nobody after forking; it only permits connections from the private 10 network (link(range)(OPTION_RANGE)); -due to link(reuseaddr)(OPTION_REUSEADDR), it allows immediate restart after master process's -termination, even if some child sockets are not completely shut down. +nobody after forking; it only permits connections from the private 10 network +(link(range)(OPTION_RANGE)); due to link(reuseaddr)(OPTION_REUSEADDR), it +allows immediate restart after master process's termination, even if some child +sockets are not completely shut down. With link(-lmlocal2)(option_lm), socat logs to stderr until successfully reaching the accept loop. Further logging is directed to syslog with facility local2. @@ -2912,7 +2915,7 @@ mancommand(\.fi) htmlcommand(
socat TCP4-LISTEN:5555,fork,tcpwrap=script \
EXEC:/bin/myscript,chroot=/home/sandbox,su-d=sandbox,pty,stderr
) -A simple server that accepts connections +a simple server that accepts connections (link(TCP4-LISTEN)(ADDRESS_TCP4_LISTEN)) and link(fork)(OPTION_FORK)'s a new child process for each connection; every child acts as single relay. The client must match the rules for daemon process name "script" in @@ -2958,7 +2961,7 @@ label(EXAMPLE_OPTION_ECHO) label(EXAMPLE_OPTION_ESCAPE) dit(bf(tt(socat -,raw,echo=0,escape=0x0f /dev/ttyS0,raw,echo=0,crnl))) -Opens an interactive connection via the serial line, e.g. for talking with a +opens an interactive connection via the serial line, e.g. for talking with a modem. link(raw)(OPTION_RAW) and link(echo)(OPTION_ECHO) set the console's and ttyS0's terminal parameters to practicable values, link(crnl)(OPTION_CRNL) converts to correct newline characters. link(escape)(OPTION_ESCAPE) allows to @@ -2979,7 +2982,7 @@ mancommand(\.fi) htmlcommand(
socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork \
SOCKS4:host.victim.org:127.0.0.1:6000,socksuser=nobody,sourceport=20
) -With link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), socat() opens a listening +with link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN), socat() opens a listening unixdomain() socket file(/tmp/.X11-unix/X1). This path corresponds to local XWindow display :1 on your machine, so XWindow client connections to DISPLAY=:1 are accepted. Socat() then speaks with @@ -2999,7 +3002,7 @@ label(EXAMPLE_option_u) label(EXAMPLE_OPTION_IGNOREEOF) dit(bf(tt(socat -u /tmp/readdata,seek-end=0,ignoreeof -))) -This is an example for unidirectional data transfer +this is an example for unidirectional data transfer (link(-u)(option_u)). Socat() transfers data from file /tmp/readdata (implicit address link(GOPEN)(ADDRESS_GOPEN)), starting at its current end (link(seek-end)(OPTION_SEEK_END)=0 lets socat() start @@ -3038,7 +3041,7 @@ mancommand(\.fi) htmlcommand(
socat -u TCP4-LISTEN:3334,reuseaddr,fork \
OPEN:/tmp/in.log,creat,append
) -Implements a simple network based message collector. +implements a simple network based message collector. For each client connecting to port 3334, a new child process is generated (option link(fork)(OPTION_FORK)). All data sent by the clients are link(append)(OPTION_APPEND)'ed to the file /tmp/in.log. If the file does not exist, socat link(creat)(OPTION_CREAT)'s it. @@ -3048,7 +3051,7 @@ process. COMMENT( dit(bf(tt(socat TCP4-LISTEN:3335,reuseaddr,fork OPEN:/tmp/motd,rdonly))) -Implements a simple network based motd server. +implements a simple network based motd server. For each client connecting to port 3335, a new child process is generated (option link(fork)(OPTION_FORK)). The contents of the file /tmp/motd is sent to each client. @@ -3059,7 +3062,7 @@ process. COMMENT( dit(bf(tt(socat - TCP4-LISTEN:8080,mtudiscover=0,rcvbuf=2048))) -Changes some socket parameters to confuse active OS fingerprinting methods. +changes some socket parameters to confuse active OS fingerprinting methods. link(mtudiscover)(OPTION_MTUDISCOVER)=0 sets the DF (don'ft fragment flag) in the IP packets to 0 and link(rcvbuf)(OPTION_RCVBUF) changes the initial TCP window size. @@ -3068,7 +3071,7 @@ window size. label(EXAMPLE_OPTION_NOECHO) dit(bf(tt(socat READLINE,noecho='[Pp]assword:' EXEC:'ftp ftp.server.com',pty,setsid,ctty))) -Wraps a command line history (link(READLINE)(ADDRESS_READLINE)) around the link(EXEC)(ADDRESS_EXEC)'uted ftp client utility. +wraps a command line history (link(READLINE)(ADDRESS_READLINE)) around the link(EXEC)(ADDRESS_EXEC)'uted ftp client utility. This allows editing and reuse of FTP commands for relatively comfortable browsing through the ftp directory hierarchy. The password is echoed! link(pty)(OPTION_PTY) is required to have ftp issue a prompt. @@ -3082,7 +3085,7 @@ label(EXAMPLE_OPTION_WAITSLAVE) label(EXAMPLE_OPTION_NONBLOCK) (bf(tt(socat PTY,link=$HOME/dev/vmodem0,raw,echo=0,waitslave EXEC:'"ssh modemserver.us.org socat - /dev/ttyS0,nonblock,raw,echo=0"'))) -Generates a pseudo terminal +generates a pseudo terminal device (link(PTY)(ADDRESS_PTY)) on the client that can be reached under the symbolic link(link)(OPTION_SYMBOLIC_LINK) file($HOME/dev/vmodem0). An application that expects a serial line or modem @@ -3180,6 +3183,15 @@ sends a broadcast to the network 192.168.1.0/24 and receives the replies of the timeservers there. Ignores NTP packets from hosts outside this network. +label(EXAMPLE_ADDRESS_GENERIC_CLIENT) +dit(bf(tt(socat - SOCKET-DATAGRAM:2:2:17:x007bxc0a80100x0000000000000000,bind=x007bx00000000x0000000000000000,setsockopt-int=1:6:1,range=x0000xc0a80100x0000000000000000:x0000xffffff00x0000000000000000))) + +is semantically equivalent to the link(previous +example)(EXAMPLE_ADDRESS_UDP4_BROADCAST_CLIENT), but all parameters are +specified in generic form. the value 6 of setsockopt-int is the Linux value for +tt(SO_BROADCAST). + + label(EXAMPLE_ADDRESS_IP4_BROADCAST_CLIENT) dit(bf(tt(socat - IP4-DATAGRAM:255.255.255.255:44,broadcast,range=10.0.0.0/8))) @@ -3216,9 +3228,33 @@ dit(bf(tt(socat PTY,link=/var/run/ppp,raw,echo=0 INTERFACE:hdlc0))) circumvents the problem that pppd requires a serial device and thus might not be able to work on a synchronous line that is represented by a network device. -socat creates a PTY to make pppd happy, binds to the network interface hdlc0, -and can transfer data between both devices. Use pppd on device /var/run/ppp -then. +socat creates a PTY to make pppd happy, binds to the network +link(interface)(ADDRESS_INTERFACE) tt(hdlc0), and can transfer data between +both devices. Use pppd on device tt(/var/run/ppp) then. + + +label(EXAMPLE_HTTPECHO) +dit(bf(tt(socat -T 1 -d -d TCP-L:10081,reuseaddr,fork,crlf SYSTEM:"echo -e \"\\\"HTTP/1.0 200 OK\\\nDocumentType: text/plain\\\n\\\ndate: \$\(date\)\\\nserver:\$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT\\\nclient: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\\\n\\\"\"; cat; echo -e \"\\\"\\\n\\\"\""))) + +creates a simple HTTP echo server: each HTTP client that connects gets a valid +HTTP reply that contains information about the client address and port as it is +seen by the server host, the host address (which might vary on multihomed +servers), and the original client request. + + +label(EXAMPLE_ANCILLARY) +dit(bf(tt(socat -d -d UDP4-RECVFROM:9999,so-broadcast,so-timestamp,ip-pktinfo,ip-recverr,ip-recvopts,ip-recvtos,ip-recvttl!!- SYSTEM:'export; sleep 1' |grep SOCAT))) + +waits for incoming UDP packets on port 9999 and prints the environment +variables provided by socat. On BSD based systems you have to replace +link(tt(ip-pktinfo))(OPTION_IP_PKTINFO) with link(tt(ip-recvdstaddr))(OPTION_IP_RECVDSTADDR),link(tt(ip-recvif))(OPTION_IP_RECVIF). Especially interesting is +SOCAT_IP_DSTADDR: it contains the target address of the packet which may be a +unicast, multicast, or broadcast address. + + +label(EXAMPLE_GENERICSOCKET) +dit(bf(tt())) + enddit() @@ -3290,7 +3326,7 @@ dit(bf(SOCAT_FORK_WAIT) (input)) Specifies the time (seconds) to sleep the parent and child processes after successful fork(). Useful for debugging. dit(bf(SOCAT_VERSION) (output)) Socat sets this variable to its version string, -e.g. tt("1.6.1.0") for released versions or e.g. tt("1.6.0.1+envvar") for +e.g. tt("1.7.0.0") for released versions or e.g. tt("1.6.0.1+envvar") for temporary versions; can be used in scripts invoked by socat. dit(bf(SOCAT_PID) (output)) Socat sets this variable to its process id. In case @@ -3305,16 +3341,18 @@ dit(bf(SOCAT_PEERADDR) (output)) With passive socket addresses (all LISTEN and RECVFROM addresses), this variable is set to a string describing the peers socket address. Port information is not included. -dit(bf(SOCAT_PEERPORT) (output)) With appropriate passive socket addresses (TCP -and UDP - LISTEN and RECVFROM), this variable is set to a string containing the +dit(bf(SOCAT_PEERPORT) (output)) With appropriate passive socket addresses +(TCP, UDP, and SCTP - LISTEN and RECVFROM), this variable is set to a string containing the number of the peer port. dit(bf(SOCAT_SOCKADDR) (output)) With all LISTEN addresses, this variable is set to a string describing the local socket address. Port information is not -included. +included link(example)(EXAMPLE_HTTPECHO) -dit(bf(SOCAT_SOCKPORT) (output)) With TCP-LISTEN and UDP-LISTEN addresses, this -variable is set to the local port. +dit(bf(SOCAT_SOCKPORT) (output)) With link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), +link(UDP-LISTEN)(ADDRESS_UDP_LISTEN), and +link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN) addresses, this variable is set to the +local port. dit(bf(SOCAT_TIMESTAMP) (output)) With all RECVFROM addresses where address option link(so-timestamp)(OPTION_SO_TIMESTAMP) is applied, socat sets this @@ -3410,7 +3448,7 @@ standard specifications available on the Internet for free. label(VERSION) manpagesection(VERSION) -This man page describes version 1.6.0 of socat(). +This man page describes version 1.7.0 of socat(). label(BUGS) From 4645166fcdd4639e8454712f6d28f449f6d5ae4d Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 15 Oct 2008 22:54:47 +0200 Subject: [PATCH 75/75] version 1.7.0.0 --- CHANGES | 49 ++++++++++++++++++++++++++++++------------------- README | 25 ++++++++++++------------- VERSION | 2 +- socat.spec | 4 ++-- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/CHANGES b/CHANGES index 15a7e6d..4fe6ee3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,11 +1,13 @@ +####################### V 1.7.0.0: + new features: new address types SCTP-CONNECT and SCTP-LISTEN implement SCTP stream mode for IPv4 and IPv6; new address options sctp-maxseg and - sctp-nodelay (suggested by David A. Madore; thanks to Jonathan Brennan + sctp-nodelay (suggested by David A. Madore; thanks to Jonathan Brannan for providing an initial patch) - new address "interface" for transparent network interface handling + new address "INTERFACE" for transparent network interface handling (suggested by Stuart Nicholson) added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN, @@ -17,14 +19,14 @@ new features: ioctl-bin for generic ioctl() calls. added address options setsockopt-int, setsockopt-bin, and - setsockopt-string + setsockopt-string for generic setsockopt() calls - so-type now only affect the socket() and socketpair() calls, not the - name resolution. so-type and so-prototype can be applied to all socket - based addresses. + option so-type now only affects the socket() and socketpair() calls, + not the name resolution. so-type and so-prototype can now be applied to + all socket based addresses. new address option "escape" allows to break a socat instance even when - raw terminal mode prevents ^C etc. + raw terminal mode prevents ^C etc. (feature suggested by Guido Trotter) socat sets environment variables SOCAT_VERSION, SOCAT_PID, SOCAT_PPID for use in executed scripts @@ -40,22 +42,22 @@ new features: socat provides the contents of ancillary messages received on RECVFROM addresses in appropriate environment variables: - SOCAT_IP_PKTINFO_DSTADDR, SOCAT_IP_PKTINFO_IF, SOCAT_IP_PKTINFO_LOCADDR - (not on BSD); SOCAT_IP_RECVDSTADDR, SOCAT_IP_RECVIF (BSD); - SOCAT_SCM_TIMESTAMP, SOCAT_IP_OPTIONS, SOCAT_IP_TOS, SOCAT_IP_TTL, - SOCAT_IPV6_HOPLIMIT, SOCAT_IPV6_TCLASS, SOCAT_IPV6_PKTINFO_DSTADDR + SOCAT_TIMESTAMP, SOCAT_IP_DSTADDR, SOCAT_IP_IF, SOCAT_IP_LOCADDR, + SOCAT_IP_OPTIONS, SOCAT_IP_TOS, SOCAT_IP_TTL, SOCAT_IPV6_DSTADDR, + SOCAT_IPV6_HOPLIMIT, SOCAT_IPV6_TCLASS the following address options were added to enable ancillary messages: - so-timestamp, ip-pktinfo, ip-recvdstaddr, ip-recverr, ip-recvif, - ip-recvopts, ip-recvtos, ip-recvttl, ipv6-recvdstopts, ipv6-recverr, - ipv6-recvhoplimit, ipv6-recvhopopts, ipv6-recvpathmtu, + so-timestamp, ip-pktinfo (not BSD), ip-recvdstaddr (BSD), ip-recverr, + ip-recvif (BSD), ip-recvopts, ip-recvtos, ip-recvttl, ipv6-recvdstopts, + ipv6-recverr, ipv6-recvhoplimit, ipv6-recvhopopts, ipv6-recvpathmtu, ipv6-recvpktinfo, ipv6-recvrthdr, ipv6-recvtclass new address options ipv6-tclass and ipv6-unicast-hops set the related socket options. STREAMS (UNIX System V STREAMS) can be configured with the new address - options i-pop-all and i-push + options i-pop-all and i-push (thanks to Michal Rysavy for providing a + patch) corrections: some raw IP and UNIX datagram modes failed on BSD systems @@ -73,6 +75,7 @@ corrections: packet. test: UDP4RECVFROM_FORK corrected a few mistakes that caused compiler warnings on 64bit hosts + (thanks to Jonathan Brannan e.a. for providing a patch) EXEC and SYSTEM with stderr injected socat messages into the data stream. test: EXECSTDERRLOG @@ -94,15 +97,23 @@ corrections: replaced the select() calls by poll() to cleanly fix the problems with many file descriptors already open + socat option -lf did not log to file but to stderr + socat did not compile on Solaris when configured without termios feature (thanks to Pavan Gadi for reporting this bug) porting: - socat should now build under MacOS X 10.4 (thanks to Camillo Lugaresi - for providing the patch) + socat compiles and runs on AIX with gcc (thanks to Andi Mather for his + help) - socat compiles and runs on AIX (thanks to Andi Mather for testing and - patching) + socat compiles and runs on Cygwin (thanks to Jan Just Keijser for his + help) + + socat compiles and runs on HP-UX with gcc (thanks to Michal Rysavy for + his help) + + socat compiles and runs on MacOS X (thanks to Camillo Lugaresi for his + help) further changes: filan -s prefixes output with FD number if more than one FD diff --git a/README b/README index 6bf0463..f92849d 100644 --- a/README +++ b/README @@ -48,25 +48,24 @@ platforms socat 1.7.0 was compiled and more or less successfully tested under the following operating systems: -SuSE Linux 10.1 on x86 -AIX 5.3 on PPC with gcc -Solaris 9 on Sparc with gcc +Debian lenny/sid on x86, kernel 2.6.24 FreeBSD 6.1 on x86 -HP-UX B 11.11 on PA-RISC with gcc +NetBSD4.0 on x86 +OpenBSD 4.3 on x86 +OpenSolaris 10 on x86 with gcc +Mac OS X 10.5.5 on iMac G5, with libreadline +HP-UX 11.23 +AIX 5.3 on 64bit Power4 with gcc +Cygwin 1.5.25 on i686 tests on Tru64 can no longer be performed because HP testdrive has taken down these hosts. -tests on Mac OS X can no longer be performed because the Sourceforge -compilefarm was discontinued. - -tests on NetBSD and OpenBSD can no longer be performed for the above reasons. - Some versions of socat have been reported to successfully compile under older Linux versions back to RedHat 2.1 (kernel 1.2.13, gcc 2.7.0), under AIX 4.1 and 4.3, SunOS 5.7-5.8, FreeBSD 4.2 - 4.9, MacOS X 10.1, Cygwin, Solaris 8 on x86, -OSR 5.0.6, NetBSD 1.6.1 and 2.0.2, OpenBSD 3.4 and 3.8, Tru64 5.1B, and Mac OS -X 10.1-10.2. +OSR 5.0.6, NetBSD 1.6.1 and 2.0.2, OpenBSD 3.4 and 3.8, Tru64 5.1B, Mac OS X +10.1-10.2, and HP-UX 11 It might well compile and run under other UNIX like operating systems. @@ -76,7 +75,7 @@ install Get the tarball and extract it: gtar xzf socat.tar.gz - cd socat-1.6.0.1 + cd socat-1.7.0.0 ./configure make su @@ -197,7 +196,7 @@ msghdr but disables struct cmsghdr. Please contact socat development if you know a solution. Shutting down the write channel of a UNIX domain socket does not seem to -trigger an EOF on the other socket. This makes problems with the exec and +trigger an EOF on the peer socket. This makes problems with the exec and system addresses. This OS provides the type "long long", but not the strtoll() function to read diff --git a/VERSION b/VERSION index f3bc8c2..bd51149 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.7.0-rc0" +"1.7.0.0" diff --git a/socat.spec b/socat.spec index b3a6561..370c246 100644 --- a/socat.spec +++ b/socat.spec @@ -1,6 +1,6 @@ -%define majorver 1.6 -%define minorver 0.1 +%define majorver 1.7 +%define minorver 0.0 Summary: socat - multipurpose relay Name: socat