mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Interface flags now defined with INTERFACE, inherited by TUN
This commit is contained in:
parent
8c9b185890
commit
47af17dbf2
16 changed files with 312 additions and 142 deletions
3
CHANGES
3
CHANGES
|
@ -83,6 +83,9 @@ Corrections:
|
||||||
Now Socat handles EPIPE and ECONNRESET as errors to indicate possible
|
Now Socat handles EPIPE and ECONNRESET as errors to indicate possible
|
||||||
failure of data transfer.
|
failure of data transfer.
|
||||||
|
|
||||||
|
INTERFACE addresses did not accept options of INTERFACE group (for
|
||||||
|
historical reasons they were only available with TUN addresses).
|
||||||
|
|
||||||
Coding:
|
Coding:
|
||||||
Introduced groups_t instead of uint32_t, for more flexibility.
|
Introduced groups_t instead of uint32_t, for more flexibility.
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,7 @@ AC_ARG_ENABLE(genericsocket, [ --disable-genericsocket disable generic socket s
|
||||||
*) AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes);;
|
*) AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes);;
|
||||||
esac],
|
esac],
|
||||||
[AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes)])
|
[AC_DEFINE(WITH_GENERICSOCKET) AC_MSG_RESULT(yes)])
|
||||||
|
|
||||||
AC_MSG_CHECKING(whether to include generic network interface support)
|
AC_MSG_CHECKING(whether to include generic network interface support)
|
||||||
AC_ARG_ENABLE(interface, [ --disable-interface disable network interface support],
|
AC_ARG_ENABLE(interface, [ --disable-interface disable network interface support],
|
||||||
[case "$enableval" in
|
[case "$enableval" in
|
||||||
|
|
48
doc/socat.yo
48
doc/socat.yo
|
@ -1084,7 +1084,7 @@ label(ADDRESS_TUN)dit(bf(tt(TUN[:<if-addr>/<bits>])))
|
||||||
Note: If you intend to transfer packets between two Socat "wire sides" you
|
Note: If you intend to transfer packets between two Socat "wire sides" you
|
||||||
need a protocol that keeps packet boundaries, e.g.UDP; TCP might work with
|
need a protocol that keeps packet boundaries, e.g.UDP; TCP might work with
|
||||||
option link(nodelay)(OPTION_TCP_NODELAY).nl()
|
option link(nodelay)(OPTION_TCP_NODELAY).nl()
|
||||||
Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN),link(TUN)(GROUP_TUN) nl()
|
Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN),link(TUN)(GROUP_INTERFACE) nl()
|
||||||
Useful options:
|
Useful options:
|
||||||
link(iff-up)(OPTION_IFF_UP),
|
link(iff-up)(OPTION_IFF_UP),
|
||||||
link(tun-device)(OPTION_TUN_DEVICE),
|
link(tun-device)(OPTION_TUN_DEVICE),
|
||||||
|
@ -3002,27 +3002,11 @@ enddit()
|
||||||
startdit()enddit()nl()
|
startdit()enddit()nl()
|
||||||
|
|
||||||
|
|
||||||
label(GROUP_TUN)em(bf(TUN option group))
|
label(GROUP_INTERFACE)em(bf(INTERFACE option group))
|
||||||
|
|
||||||
Options that control Linux TUN/TAP interface device addresses.
|
Options that control Linux INTERFACE addresses.
|
||||||
|
|
||||||
startdit()
|
startdit()
|
||||||
label(OPTION_TUN_DEVICE)dit(bf(tt(tun-device=<device-file>)))
|
|
||||||
Instructs socat to take another path for the TUN clone device. Default is
|
|
||||||
tt(/dev/net/tun).
|
|
||||||
label(OPTION_TUN_NAME)dit(bf(tt(tun-name=<if-name>)))
|
|
||||||
Gives the resulting network interface a specific name instead of the system
|
|
||||||
generated (tun0, tun1, etc.)
|
|
||||||
label(OPTION_TUN_TYPE)dit(bf(tt(tun-type=[tun|tap])))
|
|
||||||
Sets the type of the TUN device; use this option to generate a TAP
|
|
||||||
device. See the Linux docu for the difference between these types.
|
|
||||||
When you try to establish a tunnel between two TUN devices, their types
|
|
||||||
should be the same.
|
|
||||||
label(OPTION_IFF_NO_PI)dit(bf(tt(iff-no-pi)))
|
|
||||||
Sets the IFF_NO_PI flag which controls if the device includes additional
|
|
||||||
packet information in the tunnel.
|
|
||||||
When you try to establish a tunnel between two TUN devices, these flags
|
|
||||||
should have the same values.
|
|
||||||
label(OPTION_IFF_UP)dit(bf(tt(iff-up)))
|
label(OPTION_IFF_UP)dit(bf(tt(iff-up)))
|
||||||
Sets the TUN network interface status UP. Strongly recommended.
|
Sets the TUN network interface status UP. Strongly recommended.
|
||||||
label(OPTION_IFF_BROADCAST)dit(bf(tt(iff-broadcast)))
|
label(OPTION_IFF_BROADCAST)dit(bf(tt(iff-broadcast)))
|
||||||
|
@ -3060,6 +3044,32 @@ enddit()
|
||||||
startdit()enddit()nl()
|
startdit()enddit()nl()
|
||||||
|
|
||||||
|
|
||||||
|
label(GROUP_TUN)em(bf(TUN option group))
|
||||||
|
|
||||||
|
Options that control Linux TUN/TAP interface device addresses.
|
||||||
|
|
||||||
|
startdit()
|
||||||
|
label(OPTION_TUN_DEVICE)dit(bf(tt(tun-device=<device-file>)))
|
||||||
|
Instructs socat to take another path for the TUN clone device. Default is
|
||||||
|
tt(/dev/net/tun).
|
||||||
|
label(OPTION_TUN_NAME)dit(bf(tt(tun-name=<if-name>)))
|
||||||
|
Gives the resulting network interface a specific name instead of the system
|
||||||
|
generated (tun0, tun1, etc.)
|
||||||
|
label(OPTION_TUN_TYPE)dit(bf(tt(tun-type=[tun|tap])))
|
||||||
|
Sets the type of the TUN device; use this option to generate a TAP
|
||||||
|
device. See the Linux docu for the difference between these types.
|
||||||
|
When you try to establish a tunnel between two TUN devices, their types
|
||||||
|
should be the same.
|
||||||
|
label(OPTION_IFF_NO_PI)dit(bf(tt(iff-no-pi)))
|
||||||
|
Sets the IFF_NO_PI flag which controls if the device includes additional
|
||||||
|
packet information in the tunnel.
|
||||||
|
When you try to establish a tunnel between two TUN devices, these flags
|
||||||
|
should have the same values.
|
||||||
|
enddit()
|
||||||
|
|
||||||
|
startdit()enddit()nl()
|
||||||
|
|
||||||
|
|
||||||
label(VALUES)
|
label(VALUES)
|
||||||
manpagesection(DATA VALUES)
|
manpagesection(DATA VALUES)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
#ifndef __sysincludes_h_included
|
#ifndef __sysincludes_h_included
|
||||||
#define __sysincludes_h_included 1
|
#define __sysincludes_h_included 1
|
||||||
|
|
||||||
|
/* Sorry for this... */
|
||||||
|
#if defined(__sun) || defined(__sun__) || defined(__SunOS)
|
||||||
|
# define BSD_COMP 1 /* for SIOCGIFFLAGS */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stddef.h> /* ptrdiff_t */
|
#include <stddef.h> /* ptrdiff_t */
|
||||||
#if HAVE_STDBOOL_H
|
#if HAVE_STDBOOL_H
|
||||||
#include <stdbool.h> /* bool, true, false */
|
#include <stdbool.h> /* bool, true, false */
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "sysutils.h"
|
#include "sysutils.h"
|
||||||
|
|
||||||
|
#if _WITH_INTERFACE
|
||||||
|
const int one = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Substitute for Write():
|
/* Substitute for Write():
|
||||||
Try to write all bytes before returning; this handles EINTR,
|
Try to write all bytes before returning; this handles EINTR,
|
||||||
EAGAIN/EWOULDBLOCK, and partial write situations. The drawback is that this
|
EAGAIN/EWOULDBLOCK, and partial write situations. The drawback is that this
|
||||||
|
|
|
@ -43,6 +43,10 @@ struct xiorange {
|
||||||
} ;
|
} ;
|
||||||
#endif /* _WITH_SOCKET */
|
#endif /* _WITH_SOCKET */
|
||||||
|
|
||||||
|
#if _WITH_INTERFACE
|
||||||
|
extern const int one;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern ssize_t writefull(int fd, const void *buff, size_t bytes);
|
extern ssize_t writefull(int fd, const void *buff, size_t bytes);
|
||||||
|
|
||||||
#if _WITH_SOCKET
|
#if _WITH_SOCKET
|
||||||
|
|
40
test.sh
40
test.sh
|
@ -8395,34 +8395,42 @@ tl="$td/test$N.lock"
|
||||||
da="$(date) $RANDOM"
|
da="$(date) $RANDOM"
|
||||||
TUNNET=10.255.255
|
TUNNET=10.255.255
|
||||||
TUNNAME=tun9
|
TUNNAME=tun9
|
||||||
CMD1="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME echo"
|
CMD0="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME PIPE"
|
||||||
CMD="$TRACE $SOCAT $opts - INTERFACE:$TUNNAME"
|
CMD1="$TRACE $SOCAT $opts - INTERFACE:$TUNNAME"
|
||||||
printf "test $F_n $TEST... " $N
|
printf "test $F_n $TEST... " $N
|
||||||
$CMD1 2>"${te}1" &
|
$CMD0 2>"${te}1" &
|
||||||
pid1="$!"
|
pid0="$!"
|
||||||
#waitinterface "$TUNNAME"
|
#waitinterface "$TUNNAME"
|
||||||
sleep 1
|
usleep $MICROS
|
||||||
echo "$da" |$CMD >"$tf" 2>"${te}"
|
{ echo "$da"; usleep $MICROS ; } |$CMD1 >"$tf" 2>"${te}"
|
||||||
kill $pid1 2>/dev/null
|
rc1=$?
|
||||||
|
usleep $MICROS
|
||||||
|
kill $pid0 2>/dev/null
|
||||||
wait
|
wait
|
||||||
if [ $? -ne 0 ]; then
|
if [ "$rc1" -ne 0 ]; then
|
||||||
$PRINTF "$FAILED: $TRACE $SOCAT:\n"
|
$PRINTF "$FAILED (rc1=$rc1):\n"
|
||||||
echo "$CMD &"
|
echo "$CMD0 &"
|
||||||
|
cat "${te}0" >&2
|
||||||
echo "$CMD1"
|
echo "$CMD1"
|
||||||
cat "${te}" "${te}1"
|
cat "${te}1" >&2
|
||||||
numFAIL=$((numFAIL+1))
|
numFAIL=$((numFAIL+1))
|
||||||
listFAIL="$listFAIL $N"
|
listFAIL="$listFAIL $N"
|
||||||
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||||
$PRINTF "$FAILED\n"
|
$PRINTF "$FAILED (diff)\n"
|
||||||
echo "$CMD &"
|
echo "$CMD0 &"
|
||||||
|
cat "${te}0" >&2
|
||||||
echo "$CMD1"
|
echo "$CMD1"
|
||||||
|
cat "${te}1" >&2
|
||||||
|
echo "// diff:"
|
||||||
cat "$tdiff"
|
cat "$tdiff"
|
||||||
cat "${te}" "${te}1"
|
|
||||||
numFAIL=$((numFAIL+1))
|
numFAIL=$((numFAIL+1))
|
||||||
listFAIL="$listFAIL $N"
|
listFAIL="$listFAIL $N"
|
||||||
else
|
else
|
||||||
$PRINTF "$OK\n"
|
$PRINTF "$OK\n"
|
||||||
if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi
|
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||||
|
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||||
|
if [ "$VERBOSE" ]; then echo "$CMD1"; fi
|
||||||
|
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||||
numOK=$((numOK+1))
|
numOK=$((numOK+1))
|
||||||
fi
|
fi
|
||||||
fi ;; # NUMCOND, feats
|
fi ;; # NUMCOND, feats
|
||||||
|
@ -13720,7 +13728,7 @@ elif [ $rc1 -ne 0 ]; then
|
||||||
cat "${te}1" >&2
|
cat "${te}1" >&2
|
||||||
numFAIL=$((numFAIL+1))
|
numFAIL=$((numFAIL+1))
|
||||||
listFAIL="$listFAIL $N"
|
listFAIL="$listFAIL $N"
|
||||||
elif echo "$da" |diff - ${tf}1 >${tfdiff}$N; then
|
elif echo "$da" |diff - ${tf}1 >${tdiff}$N; then
|
||||||
$PRINTF "$OK\n"
|
$PRINTF "$OK\n"
|
||||||
numOK=$((numOK+1))
|
numOK=$((numOK+1))
|
||||||
else
|
else
|
||||||
|
|
135
xio-interface.c
135
xio-interface.c
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include "xiosysincludes.h"
|
#include "xiosysincludes.h"
|
||||||
|
|
||||||
#if WITH_INTERFACE
|
#if _WITH_INTERFACE
|
||||||
|
|
||||||
#include "xioopen.h"
|
#include "xioopen.h"
|
||||||
#include "xio-socket.h"
|
#include "xio-socket.h"
|
||||||
|
@ -19,7 +19,39 @@ int xioopen_interface(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups, int pf,
|
int xioflags, xiofile_t *xfd, groups_t groups, int pf,
|
||||||
int dummy2, int dummy3);
|
int dummy2, int dummy3);
|
||||||
|
|
||||||
const struct addrdesc xioaddr_interface= { "INTERFACE", 3, xioopen_interface, GROUP_FD|GROUP_SOCKET, PF_PACKET, 0, 0 HELP(":<interface>") };
|
/*0 const struct optdesc opt_interface_addr = { "interface-addr", "address", OPT_INTERFACE_ADDR, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/
|
||||||
|
/*0 const struct optdesc opt_interface_netmask = { "interface-netmask", "netmask", OPT_INTERFACE_NETMASK, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/
|
||||||
|
const struct optdesc opt_iff_up = { "iff-up", "up", OPT_IFF_UP, GROUP_INTERFACE, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_UP };
|
||||||
|
const struct optdesc opt_iff_broadcast = { "iff-broadcast", NULL, OPT_IFF_BROADCAST, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_BROADCAST };
|
||||||
|
const struct optdesc opt_iff_debug = { "iff-debug" , NULL, OPT_IFF_DEBUG, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_DEBUG };
|
||||||
|
const struct optdesc opt_iff_loopback = { "iff-loopback" , "loopback", OPT_IFF_LOOPBACK, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_LOOPBACK };
|
||||||
|
const struct optdesc opt_iff_pointopoint = { "iff-pointopoint", "pointopoint",OPT_IFF_POINTOPOINT, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_POINTOPOINT };
|
||||||
|
const struct optdesc opt_iff_notrailers = { "iff-notrailers", "notrailers", OPT_IFF_NOTRAILERS, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_NOTRAILERS };
|
||||||
|
const struct optdesc opt_iff_running = { "iff-running", "running", OPT_IFF_RUNNING, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_RUNNING };
|
||||||
|
const struct optdesc opt_iff_noarp = { "iff-noarp", "noarp", OPT_IFF_NOARP, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_NOARP };
|
||||||
|
const struct optdesc opt_iff_promisc = { "iff-promisc", "promisc", OPT_IFF_PROMISC, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_PROMISC };
|
||||||
|
const struct optdesc opt_iff_allmulti = { "iff-allmulti", "allmulti", OPT_IFF_ALLMULTI, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_ALLMULTI };
|
||||||
|
#ifdef IFF_MASTER
|
||||||
|
const struct optdesc opt_iff_master = { "iff-master", "master", OPT_IFF_MASTER, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_MASTER };
|
||||||
|
#endif
|
||||||
|
#ifdef IFF_SLAVE
|
||||||
|
const struct optdesc opt_iff_slave = { "iff-slave", "slave", OPT_IFF_SLAVE, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_SLAVE };
|
||||||
|
#endif
|
||||||
|
const struct optdesc opt_iff_multicast = { "iff-multicast", NULL, OPT_IFF_MULTICAST, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_MULTICAST };
|
||||||
|
#ifdef IFF_PORTSEL
|
||||||
|
const struct optdesc opt_iff_portsel = { "iff-portsel", "portsel", OPT_IFF_PORTSEL, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_PORTSEL };
|
||||||
|
#endif
|
||||||
|
#ifdef IFF_AUTOMEDIA
|
||||||
|
const struct optdesc opt_iff_automedia = { "iff-automedia", "automedia", OPT_IFF_AUTOMEDIA, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_AUTOMEDIA };
|
||||||
|
#endif
|
||||||
|
/*const struct optdesc opt_iff_dynamic = { "iff-dynamic", "dynamic", OPT_IFF_DYNAMIC, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(short), IFF_DYNAMIC };*/
|
||||||
|
#if LATER
|
||||||
|
const struct optdesc opt_route = { "route", NULL, OPT_ROUTE, GROUP_INTERFACE, PH_INIT, TYPE_STRING, OFUNC_SPEC };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WITH_INTERFACE
|
||||||
|
const struct addrdesc xioaddr_interface = { "INTERFACE", 3, xioopen_interface, GROUP_FD|GROUP_SOCKET|GROUP_INTERFACE, PF_PACKET, 0, 0 HELP(":<interface>") };
|
||||||
|
#endif /* WITH_INTERFACE */
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -34,13 +66,14 @@ int _xioopen_interface(const char *ifname,
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
char *bindstring = NULL;
|
char *bindstring = NULL;
|
||||||
struct sockaddr_ll sall = { 0 };
|
struct sockaddr_ll sall = { 0 };
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (ifindex(ifname, &ifidx, -1) < 0) {
|
if (ifindex(ifname, &ifidx, -1) < 0) {
|
||||||
Error1("unknown interface \"%s\"", ifname);
|
Error1("unknown interface \"%s\"", ifname);
|
||||||
ifidx = 0; /* desparate attempt to continue */
|
ifidx = 0; /* desparate attempt to continue */
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_INTERFACE;
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
|
@ -67,9 +100,25 @@ int _xioopen_interface(const char *ifname,
|
||||||
needbind = true;
|
needbind = true;
|
||||||
xfd->peersa = (union sockaddr_union)us;
|
xfd->peersa = (union sockaddr_union)us;
|
||||||
|
|
||||||
return
|
rc =
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups, pf, socktype, 0, 0);
|
opts, xioflags, xfd, groups, pf, socktype, 0, 0);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
strncpy(xfd->para.interface.name, ifname, IFNAMSIZ);
|
||||||
|
_xiointerface_get_iff(xfd->fd, ifname, &xfd->para.interface.save_iff);
|
||||||
|
_xiointerface_apply_iff(xfd->fd, ifname, xfd->para.interface.iff_opts);
|
||||||
|
|
||||||
|
#ifdef PACKET_IGNORE_OUTGOING
|
||||||
|
/* Raw socket may even provide packets that are outbound - we are not
|
||||||
|
interested in these and disable this "feature" in kernel if possible */
|
||||||
|
if (Setsockopt(xfd->fd, SOL_PACKET, PACKET_IGNORE_OUTGOING, &one, sizeof(one)) < 0) {
|
||||||
|
Warn2("setsockopt(%d, SOL_PACKET, PACKET_IGNORE_OUTGOING, {1}): %s",
|
||||||
|
xfd->fd, strerror(errno));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -102,4 +151,80 @@ int xioopen_interface(int argc, const char *argv[], struct opt *opts,
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WITH_INTERFACE */
|
|
||||||
|
/* Retrieves the interface flags related to sockfd */
|
||||||
|
int _xiointerface_get_iff(
|
||||||
|
int sockfd,
|
||||||
|
const char *name,
|
||||||
|
short *save_iff)
|
||||||
|
{
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||||
|
if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||||
|
Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s",
|
||||||
|
sockfd, ifr.ifr_name, strerror(errno));
|
||||||
|
}
|
||||||
|
*save_iff = ifr.ifr_flags;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Applies the interface flags to the socket FD.
|
||||||
|
Used by INTERFACE and TUN
|
||||||
|
*/
|
||||||
|
int _xiointerface_set_iff(
|
||||||
|
int sockfd,
|
||||||
|
const char *name,
|
||||||
|
short new_iff)
|
||||||
|
{
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||||
|
if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||||
|
Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s",
|
||||||
|
sockfd, ifr.ifr_name, strerror(errno));
|
||||||
|
}
|
||||||
|
ifr.ifr_flags = new_iff;
|
||||||
|
if (Ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
|
||||||
|
Error4("ioctl(%d, SIOCSIFFLAGS, {\"%s\", %hd}: %s",
|
||||||
|
sockfd, ifr.ifr_name, ifr.ifr_flags, strerror(errno));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Applies the interface flags to the socket FD
|
||||||
|
Used by INTERFACE and TUN
|
||||||
|
*/
|
||||||
|
int _xiointerface_apply_iff(
|
||||||
|
int sockfd,
|
||||||
|
const char *name,
|
||||||
|
short iff_opts[2])
|
||||||
|
{
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||||
|
if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||||
|
Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s",
|
||||||
|
sockfd, ifr.ifr_name, strerror(errno));
|
||||||
|
}
|
||||||
|
Debug2("\"%s\": system set flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags);
|
||||||
|
ifr.ifr_flags |= iff_opts[0];
|
||||||
|
ifr.ifr_flags &= ~iff_opts[1];
|
||||||
|
Debug2("\"%s\": xio merged flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags);
|
||||||
|
if (Ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
|
||||||
|
Error4("ioctl(%d, SIOCSIFFLAGS, {\"%s\", %hd}: %s",
|
||||||
|
sockfd, ifr.ifr_name, ifr.ifr_flags, strerror(errno));
|
||||||
|
}
|
||||||
|
ifr.ifr_flags = 0;
|
||||||
|
if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||||
|
Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s",
|
||||||
|
sockfd, ifr.ifr_name, strerror(errno));
|
||||||
|
}
|
||||||
|
Debug2("\"%s\": resulting flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _WITH_INTERFACE */
|
||||||
|
|
|
@ -7,4 +7,29 @@
|
||||||
|
|
||||||
extern const struct addrdesc xioaddr_interface;
|
extern const struct addrdesc xioaddr_interface;
|
||||||
|
|
||||||
|
extern const struct optdesc opt_interface_addr;
|
||||||
|
extern const struct optdesc opt_interface_netmask;
|
||||||
|
extern const struct optdesc opt_iff_up;
|
||||||
|
extern const struct optdesc opt_iff_broadcast;
|
||||||
|
extern const struct optdesc opt_iff_debug;
|
||||||
|
extern const struct optdesc opt_iff_loopback;
|
||||||
|
extern const struct optdesc opt_iff_pointopoint;
|
||||||
|
extern const struct optdesc opt_iff_notrailers;
|
||||||
|
extern const struct optdesc opt_iff_running;
|
||||||
|
extern const struct optdesc opt_iff_noarp;
|
||||||
|
extern const struct optdesc opt_iff_promisc;
|
||||||
|
extern const struct optdesc opt_iff_allmulti;
|
||||||
|
extern const struct optdesc opt_iff_master;
|
||||||
|
extern const struct optdesc opt_iff_slave;
|
||||||
|
extern const struct optdesc opt_iff_multicast;
|
||||||
|
extern const struct optdesc opt_iff_portsel;
|
||||||
|
extern const struct optdesc opt_iff_automedia;
|
||||||
|
/*extern const struct optdesc opt_iff_dynamic;*/
|
||||||
|
|
||||||
|
extern int xiolog_ancillary_packet(struct single *sfd, struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen);
|
||||||
|
|
||||||
|
extern int _xiointerface_get_iff(int sockfd, const char *name, short *save_iff);
|
||||||
|
extern int _xiointerface_set_iff(int sockfd, const char *name, short new_iff);
|
||||||
|
extern int _xiointerface_apply_iff(int sockfd, const char *name, short iff_opts[2]);
|
||||||
|
|
||||||
#endif /* !defined(__xio_interface_h_included) */
|
#endif /* !defined(__xio_interface_h_included) */
|
||||||
|
|
|
@ -1055,6 +1055,7 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(xfd, opts);
|
||||||
applyopts_single(xfd, opts, PH_PASTSOCKET);
|
applyopts_single(xfd, opts, PH_PASTSOCKET);
|
||||||
applyopts(xfd->fd, opts, PH_PASTSOCKET);
|
applyopts(xfd->fd, opts, PH_PASTSOCKET);
|
||||||
|
applyopts_single(xfd, opts, PH_FD);
|
||||||
applyopts(xfd->fd, opts, PH_FD);
|
applyopts(xfd->fd, opts, PH_FD);
|
||||||
|
|
||||||
applyopts_cloexec(xfd->fd, opts);
|
applyopts_cloexec(xfd->fd, opts);
|
||||||
|
|
53
xio-tun.c
53
xio-tun.c
|
@ -11,40 +11,21 @@
|
||||||
#include "xio-named.h"
|
#include "xio-named.h"
|
||||||
#include "xio-socket.h"
|
#include "xio-socket.h"
|
||||||
#include "xio-ip.h"
|
#include "xio-ip.h"
|
||||||
|
#include "xio-interface.h"
|
||||||
|
|
||||||
#include "xio-tun.h"
|
#include "xio-tun.h"
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
|
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
|
||||||
|
|
||||||
/****** TUN addresses ******/
|
/****** TUN options ******/
|
||||||
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_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 };
|
const struct optdesc opt_tun_name = { "tun-name", NULL, OPT_TUN_NAME, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };
|
||||||
const struct optdesc opt_tun_type = { "tun-type", NULL, OPT_TUN_TYPE, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };
|
const struct optdesc opt_tun_type = { "tun-type", NULL, OPT_TUN_TYPE, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };
|
||||||
const struct optdesc opt_iff_no_pi = { "iff-no-pi", "no-pi", OPT_IFF_NO_PI, GROUP_TUN, PH_FD, TYPE_BOOL, OFUNC_SPEC };
|
const struct optdesc opt_iff_no_pi = { "iff-no-pi", "no-pi", OPT_IFF_NO_PI, GROUP_TUN, PH_FD, TYPE_BOOL, OFUNC_SPEC };
|
||||||
/*0 const struct optdesc opt_interface_addr = { "interface-addr", "address", OPT_INTERFACE_ADDR, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/
|
|
||||||
/*0 const struct optdesc opt_interface_netmask = { "interface-netmask", "netmask", OPT_INTERFACE_NETMASK, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/
|
|
||||||
const struct optdesc opt_iff_up = { "iff-up", "up", OPT_IFF_UP, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_UP };
|
|
||||||
const struct optdesc opt_iff_broadcast = { "iff-broadcast", NULL, OPT_IFF_BROADCAST, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_BROADCAST };
|
|
||||||
const struct optdesc opt_iff_debug = { "iff-debug" , NULL, OPT_IFF_DEBUG, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_DEBUG };
|
|
||||||
const struct optdesc opt_iff_loopback = { "iff-loopback" , "loopback", OPT_IFF_LOOPBACK, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_LOOPBACK };
|
|
||||||
const struct optdesc opt_iff_pointopoint = { "iff-pointopoint", "pointopoint",OPT_IFF_POINTOPOINT, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_POINTOPOINT };
|
|
||||||
const struct optdesc opt_iff_notrailers = { "iff-notrailers", "notrailers", OPT_IFF_NOTRAILERS, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_NOTRAILERS };
|
|
||||||
const struct optdesc opt_iff_running = { "iff-running", "running", OPT_IFF_RUNNING, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_RUNNING };
|
|
||||||
const struct optdesc opt_iff_noarp = { "iff-noarp", "noarp", OPT_IFF_NOARP, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_NOARP };
|
|
||||||
const struct optdesc opt_iff_promisc = { "iff-promisc", "promisc", OPT_IFF_PROMISC, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_PROMISC };
|
|
||||||
const struct optdesc opt_iff_allmulti = { "iff-allmulti", "allmulti", OPT_IFF_ALLMULTI, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_ALLMULTI };
|
|
||||||
const struct optdesc opt_iff_master = { "iff-master", "master", OPT_IFF_MASTER, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_MASTER };
|
|
||||||
const struct optdesc opt_iff_slave = { "iff-slave", "slave", OPT_IFF_SLAVE, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_SLAVE };
|
|
||||||
const struct optdesc opt_iff_multicast = { "iff-multicast", NULL, OPT_IFF_MULTICAST, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_MULTICAST };
|
|
||||||
const struct optdesc opt_iff_portsel = { "iff-portsel", "portsel", OPT_IFF_PORTSEL, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_PORTSEL };
|
|
||||||
const struct optdesc opt_iff_automedia = { "iff-automedia", "automedia", OPT_IFF_AUTOMEDIA, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(para.tun.iff_opts), IFF_AUTOMEDIA };
|
|
||||||
/*const struct optdesc opt_iff_dynamic = { "iff-dynamic", "dynamic", OPT_IFF_DYNAMIC, GROUP_INTERFACE, PH_FD, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.tun.iff_opts), XIO_SIZEOF(short), IFF_DYNAMIC };*/
|
|
||||||
#if LATER
|
|
||||||
const struct optdesc opt_route = { "route", NULL, OPT_ROUTE, GROUP_INTERFACE, PH_INIT, TYPE_STRING, OFUNC_SPEC };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const struct addrdesc xioaddr_tun = { "TUN", 3, xioopen_tun, GROUP_FD|GROUP_CHR|GROUP_NAMED|GROUP_OPEN|GROUP_TUN, 0, 0, 0 HELP("[:<ip-addr>/<bits>]") };
|
/****** TUN addresses ******/
|
||||||
|
const struct addrdesc xioaddr_tun = { "TUN", 3, xioopen_tun, GROUP_FD|GROUP_CHR|GROUP_OPEN|GROUP_TUN, 0, 0, 0 HELP("[:<ip-addr>/<bits>]") };
|
||||||
/* "if-name"=tun3
|
/* "if-name"=tun3
|
||||||
// "route"=address/netmask
|
// "route"=address/netmask
|
||||||
// "ip6-route"=address/netmask
|
// "ip6-route"=address/netmask
|
||||||
|
@ -103,7 +84,7 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
xfd->stream.fd = result;
|
xfd->stream.fd = result;
|
||||||
|
|
||||||
/* prepare configuration of the new network interface */
|
/* prepare configuration of the new network interface */
|
||||||
memset(&ifr, 0,sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
|
||||||
if (retropt_string(opts, OPT_TUN_NAME, &tunname) == 0) {
|
if (retropt_string(opts, OPT_TUN_NAME, &tunname) == 0) {
|
||||||
strncpy(ifr.ifr_name, tunname, IFNAMSIZ); /* ok */
|
strncpy(ifr.ifr_name, tunname, IFNAMSIZ); /* ok */
|
||||||
|
@ -136,6 +117,7 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
xfd->stream.fd, ifr.ifr_name, strerror(errno));
|
xfd->stream.fd, ifr.ifr_name, strerror(errno));
|
||||||
Close(xfd->stream.fd);
|
Close(xfd->stream.fd);
|
||||||
}
|
}
|
||||||
|
Notice1("TUN: new device \"%s\"", ifr.ifr_name);
|
||||||
|
|
||||||
/*===================== setting interface properties =====================*/
|
/*===================== setting interface properties =====================*/
|
||||||
|
|
||||||
|
@ -174,29 +156,8 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
|
||||||
/*--------------------- setting interface flags --------------------------*/
|
/*--------------------- setting interface flags --------------------------*/
|
||||||
applyopts_single(&xfd->stream, opts, PH_FD);
|
applyopts_single(&xfd->stream, opts, PH_FD);
|
||||||
|
|
||||||
if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
_xiointerface_apply_iff(sockfd, ifr.ifr_name, xfd->stream.para.interface.iff_opts);
|
||||||
Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s",
|
|
||||||
sockfd, ifr.ifr_name, strerror(errno));
|
|
||||||
}
|
|
||||||
Debug2("\"%s\": system set flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags);
|
|
||||||
ifr.ifr_flags |= xfd->stream.para.tun.iff_opts[0];
|
|
||||||
ifr.ifr_flags &= ~xfd->stream.para.tun.iff_opts[1];
|
|
||||||
Debug2("\"%s\": xio merged flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags);
|
|
||||||
if (Ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
|
|
||||||
Error4("ioctl(%d, SIOCSIFFLAGS, {\"%s\", %hd}: %s",
|
|
||||||
sockfd, ifr.ifr_name, ifr.ifr_flags, strerror(errno));
|
|
||||||
}
|
|
||||||
ifr.ifr_flags = 0;
|
|
||||||
if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
|
||||||
Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s",
|
|
||||||
sockfd, ifr.ifr_name, strerror(errno));
|
|
||||||
}
|
|
||||||
Debug2("\"%s\": resulting flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags);
|
|
||||||
|
|
||||||
|
|
||||||
#if LATER
|
|
||||||
applyopts_named(tundevice, opts, PH_FD);
|
|
||||||
#endif
|
|
||||||
applyopts(xfd->stream.fd, opts, PH_FD);
|
applyopts(xfd->stream.fd, opts, PH_FD);
|
||||||
applyopts_cloexec(xfd->stream.fd, opts);
|
applyopts_cloexec(xfd->stream.fd, opts);
|
||||||
|
|
||||||
|
|
18
xio-tun.h
18
xio-tun.h
|
@ -9,24 +9,6 @@ extern const struct optdesc opt_tun_device;
|
||||||
extern const struct optdesc opt_tun_name;
|
extern const struct optdesc opt_tun_name;
|
||||||
extern const struct optdesc opt_tun_type;
|
extern const struct optdesc opt_tun_type;
|
||||||
extern const struct optdesc opt_iff_no_pi;
|
extern const struct optdesc opt_iff_no_pi;
|
||||||
extern const struct optdesc opt_interface_addr;
|
|
||||||
extern const struct optdesc opt_interface_netmask;
|
|
||||||
extern const struct optdesc opt_iff_up;
|
|
||||||
extern const struct optdesc opt_iff_broadcast;
|
|
||||||
extern const struct optdesc opt_iff_debug;
|
|
||||||
extern const struct optdesc opt_iff_loopback;
|
|
||||||
extern const struct optdesc opt_iff_pointopoint;
|
|
||||||
extern const struct optdesc opt_iff_notrailers;
|
|
||||||
extern const struct optdesc opt_iff_running;
|
|
||||||
extern const struct optdesc opt_iff_noarp;
|
|
||||||
extern const struct optdesc opt_iff_promisc;
|
|
||||||
extern const struct optdesc opt_iff_allmulti;
|
|
||||||
extern const struct optdesc opt_iff_master;
|
|
||||||
extern const struct optdesc opt_iff_slave;
|
|
||||||
extern const struct optdesc opt_iff_multicast;
|
|
||||||
extern const struct optdesc opt_iff_portsel;
|
|
||||||
extern const struct optdesc opt_iff_automedia;
|
|
||||||
/*extern const struct optdesc opt_iff_dynamic;*/
|
|
||||||
|
|
||||||
extern const struct addrdesc xioaddr_tun;
|
extern const struct addrdesc xioaddr_tun;
|
||||||
|
|
||||||
|
|
11
xio.h
11
xio.h
|
@ -192,7 +192,8 @@ typedef struct single {
|
||||||
END_SHUTDOWN, /* shutdown() */
|
END_SHUTDOWN, /* shutdown() */
|
||||||
END_KILL, /* has subprocess */
|
END_KILL, /* has subprocess */
|
||||||
END_CLOSE_KILL, /* first close fd, then kill subprocess */
|
END_CLOSE_KILL, /* first close fd, then kill subprocess */
|
||||||
END_SHUTDOWN_KILL /* first shutdown fd, then kill subprocess */
|
END_SHUTDOWN_KILL,/* first shutdown fd, then kill subprocess */
|
||||||
|
END_INTERFACE /* restore interface flags, then close fd */
|
||||||
} howtoend;
|
} howtoend;
|
||||||
#if _WITH_SOCKET
|
#if _WITH_SOCKET
|
||||||
union sockaddr_union peersa;
|
union sockaddr_union peersa;
|
||||||
|
@ -276,11 +277,13 @@ typedef struct single {
|
||||||
#endif
|
#endif
|
||||||
} openssl;
|
} openssl;
|
||||||
#endif /* WITH_OPENSSL */
|
#endif /* WITH_OPENSSL */
|
||||||
#if WITH_TUN
|
#if _WITH_INTERFACE
|
||||||
struct {
|
struct {
|
||||||
|
char name[IFNAMSIZ]; /* name of interface */
|
||||||
|
short save_iff; /* for restoring old settings on exit */
|
||||||
short iff_opts[2]; /* ifr flags, using OFUNC_OFFSET_MASKS */
|
short iff_opts[2]; /* ifr flags, using OFUNC_OFFSET_MASKS */
|
||||||
} tun;
|
} interface;
|
||||||
#endif /* WITH_TUN */
|
#endif /* _WITH_INTERFACE */
|
||||||
} para;
|
} para;
|
||||||
#if WITH_STATS
|
#if WITH_STATS
|
||||||
unsigned long long blocks_read;
|
unsigned long long blocks_read;
|
||||||
|
|
10
xioclose.c
10
xioclose.c
|
@ -10,6 +10,7 @@
|
||||||
#include "xiolockfile.h"
|
#include "xiolockfile.h"
|
||||||
|
|
||||||
#include "xio-termios.h"
|
#include "xio-termios.h"
|
||||||
|
#include "xio-interface.h"
|
||||||
|
|
||||||
|
|
||||||
/* close the xio fd; must be valid and "simple" (not dual) */
|
/* close the xio fd; must be valid and "simple" (not dual) */
|
||||||
|
@ -77,6 +78,15 @@ int xioclose1(struct single *pipe) {
|
||||||
Info3("shutdown(%d, %d): %s", pipe->fd, 2, strerror(errno)); }
|
Info3("shutdown(%d, %d): %s", pipe->fd, 2, strerror(errno)); }
|
||||||
break;
|
break;
|
||||||
#endif /* _WITH_SOCKET */
|
#endif /* _WITH_SOCKET */
|
||||||
|
#if WITH_INTERFACE
|
||||||
|
case END_INTERFACE:
|
||||||
|
{
|
||||||
|
_xiointerface_set_iff(pipe->fd, pipe->para.interface.name, pipe->para.interface.save_iff);
|
||||||
|
if (Close(pipe->fd) < 0) {
|
||||||
|
Info2("close(%d): %s", pipe->fd, strerror(errno)); } break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* WITH_INTERFACE */
|
||||||
case END_NONE: default: break;
|
case END_NONE: default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
xioconfig.h
12
xioconfig.h
|
@ -67,7 +67,13 @@
|
||||||
# undef WITH_LIBWRAP
|
# undef WITH_LIBWRAP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WITH_GENERICSOCKET || WITH_TUN
|
#if WITH_INTERFACE || WITH_TUN
|
||||||
|
# define _WITH_INTERFACE 1
|
||||||
|
#else
|
||||||
|
# define _WITH_INTERFACE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WITH_GENERICSOCKET || _WITH_INTERFACE
|
||||||
# define _WITH_SOCKET 1
|
# define _WITH_SOCKET 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -79,11 +85,11 @@
|
||||||
# define _WITH_IP6 1
|
# define _WITH_IP6 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WITH_NAMED || WITH_TUN
|
#if WITH_NAMED
|
||||||
# define _WITH_NAMED 1
|
# define _WITH_NAMED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WITH_FILE || WITH_TUN
|
#if WITH_FILE
|
||||||
# define _WITH_FILE 1
|
# define _WITH_FILE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
82
xioopts.c
82
xioopts.c
|
@ -125,6 +125,12 @@ bool xioopts_ignoregroups;
|
||||||
# define IF_OPENSSL(a,b)
|
# define IF_OPENSSL(a,b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WITH_INTERFACE
|
||||||
|
# define IF_INTERFACE(a,b) {a,b},
|
||||||
|
#else
|
||||||
|
# define IF_INTERFACE(a,b)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WITH_TUN
|
#if WITH_TUN
|
||||||
# define IF_TUN(a,b) {a,b},
|
# define IF_TUN(a,b) {a,b},
|
||||||
#else
|
#else
|
||||||
|
@ -167,7 +173,7 @@ const struct optname optionnames[] = {
|
||||||
#if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
|
#if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
|
||||||
IF_IP ("add-source-membership", &opt_ip_add_source_membership)
|
IF_IP ("add-source-membership", &opt_ip_add_source_membership)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("allmulti", &opt_iff_allmulti)
|
IF_INTERFACE("allmulti", &opt_iff_allmulti)
|
||||||
#if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
|
#if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
|
||||||
IF_IPAPP ("allow-table", &opt_tcpwrap_hosts_allow_table)
|
IF_IPAPP ("allow-table", &opt_tcpwrap_hosts_allow_table)
|
||||||
#endif
|
#endif
|
||||||
|
@ -185,7 +191,9 @@ const struct optname optionnames[] = {
|
||||||
#ifdef IPV6_AUTHHDR
|
#ifdef IPV6_AUTHHDR
|
||||||
IF_IP6 ("authhdr", &opt_ipv6_authhdr)
|
IF_IP6 ("authhdr", &opt_ipv6_authhdr)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("automedia", &opt_iff_automedia)
|
#ifdef IFF_AUTOMEDIA
|
||||||
|
IF_INTERFACE("automedia", &opt_iff_automedia)
|
||||||
|
#endif
|
||||||
#ifdef CBAUD
|
#ifdef CBAUD
|
||||||
IF_TERMIOS("b0", &opt_b0)
|
IF_TERMIOS("b0", &opt_b0)
|
||||||
#ifdef B1000000
|
#ifdef B1000000
|
||||||
|
@ -629,23 +637,31 @@ const struct optname optionnames[] = {
|
||||||
#ifdef SO_BINDTODEVICE
|
#ifdef SO_BINDTODEVICE
|
||||||
IF_SOCKET ("if", &opt_so_bindtodevice)
|
IF_SOCKET ("if", &opt_so_bindtodevice)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("iff-allmulti", &opt_iff_allmulti)
|
IF_INTERFACE("iff-allmulti", &opt_iff_allmulti)
|
||||||
IF_TUN ("iff-automedia", &opt_iff_automedia)
|
#ifdef IFF_AUTOMEDIA
|
||||||
IF_TUN ("iff-broadcast", &opt_iff_broadcast)
|
IF_INTERFACE("iff-automedia", &opt_iff_automedia)
|
||||||
IF_TUN ("iff-debug", &opt_iff_debug)
|
#endif
|
||||||
/*IF_TUN ("iff-dynamic", &opt_iff_dynamic)*/
|
IF_INTERFACE("iff-broadcast", &opt_iff_broadcast)
|
||||||
IF_TUN ("iff-loopback", &opt_iff_loopback)
|
IF_INTERFACE("iff-debug", &opt_iff_debug)
|
||||||
IF_TUN ("iff-master", &opt_iff_master)
|
/*IF_INTERFACE("iff-dynamic", &opt_iff_dynamic)*/
|
||||||
IF_TUN ("iff-multicast", &opt_iff_multicast)
|
IF_INTERFACE("iff-loopback", &opt_iff_loopback)
|
||||||
|
#ifdef IFF_MASTER
|
||||||
|
IF_INTERFACE("iff-master", &opt_iff_master)
|
||||||
|
#endif
|
||||||
|
IF_INTERFACE("iff-multicast", &opt_iff_multicast)
|
||||||
IF_TUN ("iff-no-pi", &opt_iff_no_pi)
|
IF_TUN ("iff-no-pi", &opt_iff_no_pi)
|
||||||
IF_TUN ("iff-noarp", &opt_iff_noarp)
|
IF_INTERFACE("iff-noarp", &opt_iff_noarp)
|
||||||
IF_TUN ("iff-notrailers", &opt_iff_notrailers)
|
IF_INTERFACE("iff-notrailers", &opt_iff_notrailers)
|
||||||
IF_TUN ("iff-pointopoint", &opt_iff_pointopoint)
|
IF_INTERFACE("iff-pointopoint", &opt_iff_pointopoint)
|
||||||
IF_TUN ("iff-portsel", &opt_iff_portsel)
|
#ifdef IFF_PORTSEL
|
||||||
IF_TUN ("iff-promisc", &opt_iff_promisc)
|
IF_INTERFACE("iff-portsel", &opt_iff_portsel)
|
||||||
IF_TUN ("iff-running", &opt_iff_running)
|
#endif
|
||||||
IF_TUN ("iff-slave", &opt_iff_slave)
|
IF_INTERFACE("iff-promisc", &opt_iff_promisc)
|
||||||
IF_TUN ("iff-up", &opt_iff_up)
|
IF_INTERFACE("iff-running", &opt_iff_running)
|
||||||
|
#ifdef IFF_SLAVE
|
||||||
|
IF_INTERFACE("iff-slave", &opt_iff_slave)
|
||||||
|
#endif
|
||||||
|
IF_INTERFACE("iff-up", &opt_iff_up)
|
||||||
IF_TERMIOS("ignbrk", &opt_ignbrk)
|
IF_TERMIOS("ignbrk", &opt_ignbrk)
|
||||||
IF_TERMIOS("igncr", &opt_igncr)
|
IF_TERMIOS("igncr", &opt_igncr)
|
||||||
/* you might need to terminate socat manually if you use this option: */
|
/* you might need to terminate socat manually if you use this option: */
|
||||||
|
@ -914,7 +930,7 @@ const struct optname optionnames[] = {
|
||||||
IF_ANY ("lockw", &opt_flock_ex_nb) /* BSD, fallback */
|
IF_ANY ("lockw", &opt_flock_ex_nb) /* BSD, fallback */
|
||||||
#endif
|
#endif
|
||||||
IF_EXEC ("login", &opt_dash)
|
IF_EXEC ("login", &opt_dash)
|
||||||
IF_TUN ("loopback", &opt_iff_loopback)
|
IF_INTERFACE("loopback", &opt_iff_loopback)
|
||||||
IF_IPAPP ("lowport", &opt_lowport)
|
IF_IPAPP ("lowport", &opt_lowport)
|
||||||
#if HAVE_LSEEK64
|
#if HAVE_LSEEK64
|
||||||
IF_ANY ("lseek", &opt_lseek64_set)
|
IF_ANY ("lseek", &opt_lseek64_set)
|
||||||
|
@ -931,7 +947,9 @@ const struct optname optionnames[] = {
|
||||||
IF_ANY ("lseek64-end", &opt_lseek64_end)
|
IF_ANY ("lseek64-end", &opt_lseek64_end)
|
||||||
IF_ANY ("lseek64-set", &opt_lseek64_set)
|
IF_ANY ("lseek64-set", &opt_lseek64_set)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("master", &opt_iff_master)
|
#ifdef IFF_MASTER
|
||||||
|
IF_INTERFACE("master", &opt_iff_master)
|
||||||
|
#endif
|
||||||
IF_LISTEN ("max-children", &opt_max_children)
|
IF_LISTEN ("max-children", &opt_max_children)
|
||||||
#if HAVE_SSL_set_max_proto_version || defined(SSL_set_max_proto_version)
|
#if HAVE_SSL_set_max_proto_version || defined(SSL_set_max_proto_version)
|
||||||
IF_OPENSSL("max-version", &opt_openssl_max_proto_version)
|
IF_OPENSSL("max-version", &opt_openssl_max_proto_version)
|
||||||
|
@ -971,7 +989,7 @@ const struct optname optionnames[] = {
|
||||||
#ifdef IP_MTU_DISCOVER
|
#ifdef IP_MTU_DISCOVER
|
||||||
IF_IP ("mtudiscover", &opt_ip_mtu_discover)
|
IF_IP ("mtudiscover", &opt_ip_mtu_discover)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("multicast", &opt_iff_multicast)
|
IF_INTERFACE("multicast", &opt_iff_multicast)
|
||||||
IF_IP ("multicast-if", &opt_ip_multicast_if)
|
IF_IP ("multicast-if", &opt_ip_multicast_if)
|
||||||
IF_IP ("multicast-loop", &opt_ip_multicast_loop)
|
IF_IP ("multicast-loop", &opt_ip_multicast_loop)
|
||||||
IF_IP ("multicast-ttl", &opt_ip_multicast_ttl)
|
IF_IP ("multicast-ttl", &opt_ip_multicast_ttl)
|
||||||
|
@ -999,7 +1017,7 @@ const struct optname optionnames[] = {
|
||||||
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
||||||
IF_OPENSSL("no-sni", &opt_openssl_no_sni)
|
IF_OPENSSL("no-sni", &opt_openssl_no_sni)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("noarp", &opt_iff_noarp)
|
IF_INTERFACE("noarp", &opt_iff_noarp)
|
||||||
#ifdef O_NOATIME
|
#ifdef O_NOATIME
|
||||||
IF_OPEN ("noatime", &opt_o_noatime)
|
IF_OPEN ("noatime", &opt_o_noatime)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1038,7 +1056,7 @@ const struct optname optionnames[] = {
|
||||||
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
||||||
IF_OPENSSL("nosni", &opt_openssl_no_sni)
|
IF_OPENSSL("nosni", &opt_openssl_no_sni)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("notrailers", &opt_iff_notrailers)
|
IF_INTERFACE("notrailers", &opt_iff_notrailers)
|
||||||
#ifdef O_NSHARE
|
#ifdef O_NSHARE
|
||||||
IF_OPEN ("nshare", &opt_o_nshare)
|
IF_OPEN ("nshare", &opt_o_nshare)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1251,12 +1269,14 @@ const struct optname optionnames[] = {
|
||||||
IF_IP ("pktoptions", &opt_ip_pktoptions)
|
IF_IP ("pktoptions", &opt_ip_pktoptions)
|
||||||
IF_IP ("pktopts", &opt_ip_pktoptions)
|
IF_IP ("pktopts", &opt_ip_pktoptions)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("pointopoint", &opt_iff_pointopoint)
|
IF_INTERFACE("pointopoint", &opt_iff_pointopoint)
|
||||||
#ifdef I_POP
|
#ifdef I_POP
|
||||||
IF_ANY ("pop-all", &opt_streams_i_pop_all)
|
IF_ANY ("pop-all", &opt_streams_i_pop_all)
|
||||||
#endif
|
#endif
|
||||||
/*IF_IPAPP("port", &opt_port)*/
|
/*IF_IPAPP("port", &opt_port)*/
|
||||||
IF_TUN ("portsel", &opt_iff_portsel)
|
#ifdef IFF_PORTSEL
|
||||||
|
IF_INTERFACE("portsel", &opt_iff_portsel)
|
||||||
|
#endif
|
||||||
#if HAVE_RESOLV_H && WITH_RES_PRIMARY
|
#if HAVE_RESOLV_H && WITH_RES_PRIMARY
|
||||||
IF_IP ("primary", &opt_res_primary)
|
IF_IP ("primary", &opt_res_primary)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1266,7 +1286,7 @@ const struct optname optionnames[] = {
|
||||||
#ifdef O_PRIV
|
#ifdef O_PRIV
|
||||||
IF_OPEN ("priv", &opt_o_priv)
|
IF_OPEN ("priv", &opt_o_priv)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("promisc", &opt_iff_promisc)
|
IF_INTERFACE("promisc", &opt_iff_promisc)
|
||||||
IF_READLINE("prompt", &opt_prompt)
|
IF_READLINE("prompt", &opt_prompt)
|
||||||
#ifdef SO_PROTOTYPE
|
#ifdef SO_PROTOTYPE
|
||||||
IF_SOCKET ("protocol", &opt_so_prototype)
|
IF_SOCKET ("protocol", &opt_so_prototype)
|
||||||
|
@ -1401,7 +1421,7 @@ const struct optname optionnames[] = {
|
||||||
#ifdef IPV6_RTHDR
|
#ifdef IPV6_RTHDR
|
||||||
IF_IP6 ("rthdr", &opt_ipv6_rthdr)
|
IF_IP6 ("rthdr", &opt_ipv6_rthdr)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("running", &opt_iff_running)
|
IF_INTERFACE("running", &opt_iff_running)
|
||||||
#ifdef TCP_SACK_DISABLE
|
#ifdef TCP_SACK_DISABLE
|
||||||
IF_TCP ("sack-disable", &opt_tcp_sack_disable)
|
IF_TCP ("sack-disable", &opt_tcp_sack_disable)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1484,7 +1504,9 @@ const struct optname optionnames[] = {
|
||||||
IF_SOCKET ("siocspgrp", &opt_siocspgrp)
|
IF_SOCKET ("siocspgrp", &opt_siocspgrp)
|
||||||
#endif
|
#endif
|
||||||
IF_PTY ("sitout-eio", &opt_sitout_eio)
|
IF_PTY ("sitout-eio", &opt_sitout_eio)
|
||||||
IF_TUN ("slave", &opt_iff_slave)
|
#ifdef IFF_SLAVE
|
||||||
|
IF_INTERFACE("slave", &opt_iff_slave)
|
||||||
|
#endif
|
||||||
IF_SOCKET ("sndbuf", &opt_so_sndbuf)
|
IF_SOCKET ("sndbuf", &opt_so_sndbuf)
|
||||||
IF_SOCKET ("sndbuf-late", &opt_so_sndbuf_late)
|
IF_SOCKET ("sndbuf-late", &opt_so_sndbuf_late)
|
||||||
#ifdef SO_SNDLOWAT
|
#ifdef SO_SNDLOWAT
|
||||||
|
@ -1797,7 +1819,7 @@ const struct optname optionnames[] = {
|
||||||
#if WITH_FS && defined(FS_UNRM_FL)
|
#if WITH_FS && defined(FS_UNRM_FL)
|
||||||
IF_ANY ("unrm", &opt_fs_unrm)
|
IF_ANY ("unrm", &opt_fs_unrm)
|
||||||
#endif
|
#endif
|
||||||
IF_TUN ("up", &opt_iff_up)
|
IF_INTERFACE("up", &opt_iff_up)
|
||||||
#ifdef SO_USE_IFBUFS
|
#ifdef SO_USE_IFBUFS
|
||||||
IF_SOCKET ("use-ifbufs", &opt_so_use_ifbufs)
|
IF_SOCKET ("use-ifbufs", &opt_so_use_ifbufs)
|
||||||
IF_SOCKET ("useifbufs", &opt_so_use_ifbufs)
|
IF_SOCKET ("useifbufs", &opt_so_use_ifbufs)
|
||||||
|
@ -3745,7 +3767,7 @@ int applyopts(int fd, struct opt *opts, enum e_phase phase) {
|
||||||
/*Error1("applyopts(): function %d not implemented",
|
/*Error1("applyopts(): function %d not implemented",
|
||||||
opt->desc->func);*/
|
opt->desc->func);*/
|
||||||
if (opt->desc->func != OFUNC_EXT && opt->desc->func != OFUNC_SIGNAL) {
|
if (opt->desc->func != OFUNC_EXT && opt->desc->func != OFUNC_SIGNAL) {
|
||||||
Error1("applyopts(): option \"%s\" does not apply",
|
Error1("applyopts(): internal error: option \"%s\" does not apply",
|
||||||
opt->desc->defname);
|
opt->desc->defname);
|
||||||
opt->desc = ODESC_ERROR;
|
opt->desc = ODESC_ERROR;
|
||||||
++opt;
|
++opt;
|
||||||
|
|
Loading…
Reference in a new issue