From 0cfe39a4134b2865e3d3549c5f12eeb86d7018a2 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 26 Jul 2024 09:48:17 +0200 Subject: [PATCH] Fixed IP-SENDTO with option pf with protocol name --- CHANGES | 5 +++++ test.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ xio-ip.c | 12 ++++++----- xio-progcall.c | 9 ++++---- xio-rawip.c | 2 +- xio-socket.c | 6 ++---- xio-socketpair.c | 3 ++- 7 files changed, 75 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index fbe3618..74add19 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,11 @@ Corrections: did not work. Thanks to Linus Luessing for reporting this bug. + Up to version 1.8.0.0 IP-SENDTO and option pf (protocol-family) with + protocol name (vs.numeric argument) failed with message: + E retropts_int(): trailing garbage in numerical arg of option "protocol-family" + Test: IP_SENDTO_PF + Features: Total inactivity timeout option -T 0 now means 0.0 seconds; up to version 1.8.0.0 it meant no total inactivity timeout. diff --git a/test.sh b/test.sh index 315ab00..163afa0 100755 --- a/test.sh +++ b/test.sh @@ -19862,6 +19862,59 @@ esac N=$((N+1)) +# Test for a bug (up to 1.8.0.0) with IP-SENDTO and option pf (protocol-family) +# with protocol name (vs.numeric) +NAME=IP_SENDTO_PF +case "$TESTS" in +*%$N%*|*%functions%*|*%root%*|*%bugs%*|*%socket%*|*%ip4%*|*%rawip%*|*%gopen%*|*%$NAME%*) +TEST="$NAME: test IP-SENDTO with option pf with protocol name" +# Invoke Socat with address IP-SENDTO with option pf=ip4 +# When this works the test succeeded; when an error (in particular: +# E retropts_int(): trailing garbage in numerical arg of option "protocol-family") +# occurs, the test fails +if ! eval $NUMCOND; then : +# Remove unneeded checks, adapt lists of the remaining ones +elif ! cond=$(checkconds \ + "" \ + "root" \ + "" \ + "IP4 RAWIP GOPEN" \ + "GOPEN IP-SENDTO" \ + "pf" \ + "ip4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" + namesCANT="$namesCANT $NAME" +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + CMD0="$TRACE $SOCAT $opts -u /dev/null IP-SENDTO:127.0.0.1:254,pf=ip4" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" + rc0=$? + if [ "$rc0" -ne 0 ]; then + $PRINTF "$FAILED (rc0=$rc0)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" + namesFAIL="$namesFAIL $NAME" + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + numOK=$((numOK+1)) + listOK="$listOK $N" + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + # end of common tests ################################################################################## diff --git a/xio-ip.c b/xio-ip.c index dfccbbd..14364f1 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -132,15 +132,17 @@ int xioinit_ip( char ipv) { if (*pf == PF_UNSPEC) { +#if WITH_IP4 && WITH_IP6 switch (ipv) { - case '0': *pf = PF_UNSPEC; break; -#if WITH_IP4 case '4': *pf = PF_INET; break; -#endif -#if WITH_IP6 case '6': *pf = PF_INET6; break; -#endif + default: break; /* includes \0 */ } +#elif WITH_IP6 + *pf = PF_INET6; +#else + *pf = PF_INET; +#endif } return 0; } diff --git a/xio-progcall.c b/xio-progcall.c index 202c554..f980ef9 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -56,7 +56,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ struct opt *popts = NULL; /* parent options */ struct opt *copts; /* child options */ int numleft; - int d, sv[2], rdpip[2], wrpip[2]; + int sv[2], rdpip[2], wrpip[2]; int rw = (xioflags & XIO_ACCMODE); bool usepipes = false; #if HAVE_PTY @@ -355,10 +355,11 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ /* end withfork, use_pipes */ } else { /* withfork, socketpair */ + int pf; - d = AF_UNIX; - retropt_int(opts, OPT_PROTOCOL_FAMILY, &d); - result = xiosocketpair(opts, d, SOCK_STREAM, 0, sv); + pf = AF_UNIX; + retropt_socket_pf(opts, &pf); + result = xiosocketpair(opts, pf, SOCK_STREAM, 0, sv); if (result < 0) { return -1; } diff --git a/xio-rawip.c b/xio-rawip.c index e4d3812..3b4fd44 100644 --- a/xio-rawip.c +++ b/xio-rawip.c @@ -108,7 +108,7 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname, if (sfd->howtoend == END_UNSPEC) sfd->howtoend = END_SHUTDOWN; - retropt_int(opts, OPT_PROTOCOL_FAMILY, pf); + retropt_socket_pf(opts, pf); if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; applyopts(sfd, -1, opts, PH_INIT); diff --git a/xio-socket.c b/xio-socket.c index ce69b73..5a7782f 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1460,15 +1460,13 @@ int retropt_socket_pf(struct opt *opts, int *pf) { } else if (!strcasecmp("inet", pfname) || !strcasecmp("inet4", pfname) || !strcasecmp("ip4", pfname) || - !strcasecmp("ipv4", pfname) || - !strcasecmp("2", pfname)) { + !strcasecmp("ipv4", pfname)) { *pf = PF_INET; #endif /* WITH_IP4 */ #if WITH_IP6 } else if (!strcasecmp("inet6", pfname) || !strcasecmp("ip6", pfname) || - !strcasecmp("ipv6", pfname) || - !strcasecmp("10", pfname)) { + !strcasecmp("ipv6", pfname)) { *pf = PF_INET6; #endif /* WITH_IP6 */ } else { diff --git a/xio-socketpair.c b/xio-socketpair.c index f9b3977..0da0c99 100644 --- a/xio-socketpair.c +++ b/xio-socketpair.c @@ -7,6 +7,7 @@ #include "xiosysincludes.h" #include "xioopen.h" +#include "xio-socket.h" #include "xio-named.h" #include "xio-socketpair.h" @@ -44,7 +45,7 @@ static int xioopen_socketpair( sfd->para.bipipe.socktype = SOCK_DGRAM; if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; applyopts(sfd, -1, opts, PH_INIT); - retropt_int(opts, OPT_PROTOCOL_FAMILY, &pf); + retropt_socket_pf(opts, &pf); retropt_int(opts, OPT_SO_TYPE, &sfd->para.bipipe.socktype); retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);