Renove faith(4) and faithd(8) from base. It looks like industry
have chosen different (and more traditional) stateless/statuful NAT64 as translation mechanism. Last non-trivial commits to both faith(4) and faithd(8) happened more than 12 years ago, so I assume it is time to drop RFC3142 in FreeBSD. No objections from: net@
This commit is contained in:
parent
48a9d8f214
commit
603eaf792b
@ -38,6 +38,12 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20141109: faith/faithd removal
|
||||
OLD_FILES+=etc/rc.d/faith
|
||||
OLD_FILES+=usr/share/man/man4/faith.4.gz
|
||||
OLD_FILES+=usr/share/man/man4/if_faith.4.gz
|
||||
OLD_FILES+=usr/sbin/faithd
|
||||
OLD_FILES+=usr/share/man/man8/faithd.8.gz
|
||||
# 20141102: postrandom obsoleted by new /dev/random code
|
||||
OLD_FILES+=etc/rc.d/postrandom
|
||||
# 20141031: initrandom obsoleted by new /dev/random code
|
||||
|
4
UPDATING
4
UPDATING
@ -31,6 +31,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
|
||||
disable the most expensive debugging functionality run
|
||||
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
||||
|
||||
20141109:
|
||||
faith(4) and faithd(8) has been removed from base system. It
|
||||
has been obsolete for a very long time.
|
||||
|
||||
20141104:
|
||||
vt(4), the new console driver, is enabled by default. It brings
|
||||
support for Unicode and double-width characters, as well as
|
||||
|
@ -514,9 +514,6 @@ stf_interface_ipv4plen="0" # Prefix length for 6to4 IPv4 addr,
|
||||
stf_interface_ipv6_ifid="0:0:0:1" # IPv6 interface id for stf0.
|
||||
# If you like, you can set "AUTO" for this.
|
||||
stf_interface_ipv6_slaid="0000" # IPv6 Site Level Aggregator for stf0
|
||||
ipv6_faith_prefix="NO" # Set faith prefix to enable a FAITH
|
||||
# IPv6-to-IPv4 TCP translator. You also need
|
||||
# faithd(8) setup.
|
||||
ipv6_ipv4mapping="NO" # Set to "YES" to enable IPv4 mapped IPv6 addr
|
||||
# communication. (like ::ffff:a.b.c.d)
|
||||
ipv6_ipfilter_rules="/etc/ipf6.rules" # rules definition file for ipfilter,
|
||||
|
@ -372,7 +372,6 @@ dhcpif()
|
||||
case $1 in
|
||||
lo[0-9]*|\
|
||||
stf[0-9]*|\
|
||||
faith[0-9]*|\
|
||||
lp[0-9]*|\
|
||||
sl[0-9]*)
|
||||
return 1
|
||||
@ -591,7 +590,6 @@ ipv6_autoconfif()
|
||||
case $_if in
|
||||
lo[0-9]*|\
|
||||
stf[0-9]*|\
|
||||
faith[0-9]*|\
|
||||
lp[0-9]*|\
|
||||
sl[0-9]*)
|
||||
return 1
|
||||
|
@ -42,7 +42,6 @@ FILES= DAEMON \
|
||||
dhclient \
|
||||
dmesg \
|
||||
dumpon \
|
||||
faith \
|
||||
fsck \
|
||||
ftpd \
|
||||
gbde \
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
# PROVIDE: NETWORKING NETWORK
|
||||
# REQUIRE: netif netoptions routing ppp ipfw stf faith
|
||||
# REQUIRE: netif netoptions routing ppp ipfw stf
|
||||
# REQUIRE: defaultroute routed mrouted route6d mroute6d resolv bridge
|
||||
# REQUIRE: static_arp static_ndp local_unbound
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#
|
||||
|
||||
# PROVIDE: bridge
|
||||
# REQUIRE: netif faith ppp stf
|
||||
# REQUIRE: netif ppp stf
|
||||
# KEYWORD: nojail
|
||||
|
||||
. /etc/rc.subr
|
||||
|
@ -6,7 +6,7 @@
|
||||
#
|
||||
|
||||
# PROVIDE: defaultroute
|
||||
# REQUIRE: devd faith netif stf
|
||||
# REQUIRE: devd netif stf
|
||||
# KEYWORD: nojail
|
||||
|
||||
. /etc/rc.subr
|
||||
|
@ -1,75 +0,0 @@
|
||||
#!/bin/sh
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# PROVIDE: faith
|
||||
# REQUIRE: netif
|
||||
# KEYWORD: nojail
|
||||
|
||||
. /etc/rc.subr
|
||||
. /etc/network.subr
|
||||
|
||||
name="faith"
|
||||
start_cmd="faith_up"
|
||||
stop_cmd="faith_down"
|
||||
|
||||
faith_up()
|
||||
{
|
||||
case ${ipv6_faith_prefix} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
echo "Configuring IPv6-to-IPv4 TCP relay capturing interface:" \
|
||||
" faith0."
|
||||
${SYSCTL} net.inet6.ip6.keepfaith=1
|
||||
ifconfig faith0 create >/dev/null 2>&1
|
||||
ifconfig faith0 up
|
||||
for prefix in ${ipv6_faith_prefix}; do
|
||||
prefixlen=`expr "${prefix}" : ".*/\(.*\)"`
|
||||
case ${prefixlen} in
|
||||
'')
|
||||
prefixlen=96
|
||||
;;
|
||||
*)
|
||||
prefix=`expr "${prefix}" : \
|
||||
"\(.*\)/${prefixlen}"`
|
||||
;;
|
||||
esac
|
||||
route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1
|
||||
route change -inet6 ${prefix} -prefixlen ${prefixlen} \
|
||||
-ifp faith0
|
||||
done
|
||||
check_startmsgs && ifconfig faith0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
faith_down()
|
||||
{
|
||||
echo "Removing IPv6-to-IPv4 TCP relay capturing interface: faith0."
|
||||
ifconfig faith0 destroy
|
||||
${SYSCTL} net.inet6.ip6.keepfaith=0
|
||||
|
||||
case ${ipv6_faith_prefix} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
for prefix in ${ipv6_faith_prefix}; do
|
||||
prefixlen=`expr "${prefix}" : ".*/\(.*\)"`
|
||||
case ${prefixlen} in
|
||||
'')
|
||||
prefixlen=96
|
||||
;;
|
||||
*)
|
||||
prefix=`expr "${prefix}" : \
|
||||
"\(.*\)/${prefixlen}"`
|
||||
;;
|
||||
esac
|
||||
route delete -inet6 ${prefix} -prefixlen ${prefixlen}
|
||||
done
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$1"
|
@ -6,7 +6,7 @@
|
||||
#
|
||||
|
||||
# PROVIDE: routing
|
||||
# REQUIRE: faith netif ppp stf
|
||||
# REQUIRE: netif ppp stf
|
||||
# KEYWORD: nojailvnet
|
||||
|
||||
. /etc/rc.subr
|
||||
@ -245,7 +245,7 @@ static_inet6()
|
||||
[Nn][Oo][Nn][Ee])
|
||||
return
|
||||
;;
|
||||
lo0|faith[0-9]*)
|
||||
lo0)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
@ -30,8 +30,6 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
|
||||
*
|
||||
* Issues to be discussed:
|
||||
* - Return values. There are nonstandard return values defined and used
|
||||
* in the source code. This is because RFC2553 is silent about which error
|
||||
@ -101,10 +99,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include "nscache.h"
|
||||
#endif
|
||||
|
||||
#if defined(__KAME__) && defined(INET6)
|
||||
# define FAITH
|
||||
#endif
|
||||
|
||||
#define ANY 0
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
@ -1316,47 +1310,6 @@ get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
|
||||
{
|
||||
char *p;
|
||||
struct addrinfo *ai;
|
||||
#ifdef FAITH
|
||||
struct in6_addr faith_prefix;
|
||||
char *fp_str;
|
||||
int translate = 0;
|
||||
#endif
|
||||
|
||||
#ifdef FAITH
|
||||
/*
|
||||
* Transfrom an IPv4 addr into a special IPv6 addr format for
|
||||
* IPv6->IPv4 translation gateway. (only TCP is supported now)
|
||||
*
|
||||
* +-----------------------------------+------------+
|
||||
* | faith prefix part (12 bytes) | embedded |
|
||||
* | | IPv4 addr part (4 bytes)
|
||||
* +-----------------------------------+------------+
|
||||
*
|
||||
* faith prefix part is specified as ascii IPv6 addr format
|
||||
* in environmental variable GAI.
|
||||
* For FAITH to work correctly, routing to faith prefix must be
|
||||
* setup toward a machine where a FAITH daemon operates.
|
||||
* Also, the machine must enable some mechanizm
|
||||
* (e.g. faith interface hack) to divert those packet with
|
||||
* faith prefixed destination addr to user-land FAITH daemon.
|
||||
*/
|
||||
fp_str = getenv("GAI");
|
||||
if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 &&
|
||||
afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) {
|
||||
u_int32_t v4a;
|
||||
u_int8_t v4a_top;
|
||||
|
||||
memcpy(&v4a, addr, sizeof v4a);
|
||||
v4a_top = v4a >> IN_CLASSA_NSHIFT;
|
||||
if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) &&
|
||||
v4a_top != 0 && v4a != IN_LOOPBACKNET) {
|
||||
afd = &afdl[N_INET6];
|
||||
memcpy(&faith_prefix.s6_addr[12], addr,
|
||||
sizeof(struct in_addr));
|
||||
translate = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
|
||||
+ (afd->a_socklen));
|
||||
@ -1370,11 +1323,6 @@ get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
|
||||
ai->ai_addrlen = afd->a_socklen;
|
||||
ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
|
||||
p = (char *)(void *)(ai->ai_addr);
|
||||
#ifdef FAITH
|
||||
if (translate == 1)
|
||||
memcpy(p + afd->a_off, &faith_prefix, (size_t)afd->a_addrlen);
|
||||
else
|
||||
#endif
|
||||
memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
|
||||
return ai;
|
||||
}
|
||||
|
@ -414,7 +414,6 @@ getnameinfo_link(const struct sockaddr *sa, socklen_t salen,
|
||||
/*
|
||||
* The following have zero-length addresses.
|
||||
* IFT_ATM (net/if_atmsubr.c)
|
||||
* IFT_FAITH (net/if_faith.c)
|
||||
* IFT_GIF (net/if_gif.c)
|
||||
* IFT_LOOP (net/if_loop.c)
|
||||
* IFT_PPP (net/if_ppp.c, net/if_spppsubr.c)
|
||||
|
@ -109,7 +109,6 @@ device tun # Packet tunnel.
|
||||
device pty # Pseudo-ttys (telnet etc)
|
||||
device md # Memory "disks"
|
||||
#device gif 4 # IPv6 and IPv4 tunneling
|
||||
#device faith 1 # IPv6-to-IPv4 relaying (translation)
|
||||
device tap
|
||||
|
||||
#options DEVICE_POLLING
|
||||
|
@ -114,7 +114,6 @@ device tun # Packet tunnel.
|
||||
device pty # Pseudo-ttys (telnet etc)
|
||||
device md # Memory "disks"
|
||||
#device gif 4 # IPv6 and IPv4 tunneling
|
||||
#device faith 1 # IPv6-to-IPv4 relaying (translation)
|
||||
device tap
|
||||
|
||||
#options VIMAGE # soner or later we may want to test this
|
||||
|
@ -132,7 +132,6 @@ MAN= aac.4 \
|
||||
et.4 \
|
||||
eventtimers.4 \
|
||||
exca.4 \
|
||||
faith.4 \
|
||||
fatm.4 \
|
||||
fd.4 \
|
||||
fdc.4 \
|
||||
@ -637,7 +636,6 @@ MLINKS+=en.4 if_en.4
|
||||
MLINKS+=enc.4 if_enc.4
|
||||
MLINKS+=epair.4 if_epair.4
|
||||
MLINKS+=et.4 if_et.4
|
||||
MLINKS+=faith.4 if_faith.4
|
||||
MLINKS+=fatm.4 if_fatm.4
|
||||
MLINKS+=fd.4 stderr.4 \
|
||||
fd.4 stdin.4 \
|
||||
|
@ -1,133 +0,0 @@
|
||||
.\" $KAME: faith.4,v 1.9 2001/04/27 17:26:35 itojun Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the project nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 23, 2012
|
||||
.Dt FAITH 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm faith
|
||||
.Nd IPv6-to-IPv4 TCP relay capturing interface
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device faith"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
interface captures IPv6 TCP traffic,
|
||||
for implementing userland IPv6-to-IPv4 TCP relay
|
||||
like
|
||||
.Xr faithd 8 .
|
||||
.Pp
|
||||
Each
|
||||
.Nm
|
||||
interface is created at runtime using interface cloning.
|
||||
This is
|
||||
most easily done with the
|
||||
.Xr ifconfig 8
|
||||
.Cm create
|
||||
command or using the
|
||||
.Va cloned_interfaces
|
||||
variable in
|
||||
.Xr rc.conf 5 .
|
||||
.Pp
|
||||
Special action will be taken when IPv6 TCP traffic is seen on a router,
|
||||
and the default routing table suggests to route it to the
|
||||
.Nm
|
||||
interface.
|
||||
In this case, the packet will be accepted by the router,
|
||||
regardless of the list of IPv6 interface addresses assigned to the router.
|
||||
The packet will be captured by an IPv6 TCP socket, if it has the
|
||||
.Dv IN6P_FAITH
|
||||
flag turned on and matching address/port pairs.
|
||||
As a result,
|
||||
.Nm
|
||||
will let you capture IPv6 TCP traffic to some specific destination addresses.
|
||||
Userland programs, such as
|
||||
.Xr faithd 8
|
||||
can use this behavior to relay IPv6 TCP traffic to IPv4 TCP traffic.
|
||||
The program can accept some specific IPv6 TCP traffic, perform
|
||||
.Xr getsockname 2
|
||||
to get the IPv6 destination address specified by the client,
|
||||
and perform application-specific address mapping to relay IPv6 TCP to IPv4 TCP.
|
||||
.Pp
|
||||
The
|
||||
.Dv IN6P_FAITH
|
||||
flag on a IPv6 TCP socket can be set by using
|
||||
.Xr setsockopt 2 ,
|
||||
with level
|
||||
.Dv IPPROTO_IPV6
|
||||
and optname
|
||||
.Dv IPv6_FAITH .
|
||||
.Pp
|
||||
To handle error reports by ICMPv6, some ICMPv6 packets routed to an
|
||||
.Nm
|
||||
interface will be delivered to IPv6 TCP, as well.
|
||||
.Pp
|
||||
To understand how
|
||||
.Nm
|
||||
can be used, take a look at the source code of
|
||||
.Xr faithd 8 .
|
||||
.Pp
|
||||
As the
|
||||
.Nm
|
||||
interface implements potentially dangerous operations,
|
||||
great care must be taken when configuring it.
|
||||
To avoid possible misuse, the
|
||||
.Xr sysctl 8
|
||||
variable
|
||||
.Li net.inet6.ip6.keepfaith
|
||||
must be set to
|
||||
.Li 1
|
||||
prior to using the interface.
|
||||
When
|
||||
.Li net.inet6.ip6.keepfaith
|
||||
is
|
||||
.Li 0 ,
|
||||
no packets will be captured by the
|
||||
.Nm
|
||||
interface.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
interface is intended to be used on routers, not on hosts.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr inet 4 ,
|
||||
.Xr inet6 4 ,
|
||||
.Xr faithd 8
|
||||
.Rs
|
||||
.%A Jun-ichiro itojun Hagino
|
||||
.%A Kazu Yamamoto
|
||||
.%T "An IPv6-to-IPv4 transport relay translator"
|
||||
.%O RFC3142
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The FAITH IPv6-to-IPv4 TCP relay translator first appeared in the
|
||||
WIDE hydrangea IPv6 stack.
|
@ -241,17 +241,6 @@ Defaults to off.
|
||||
Boolean: the default value of a per-interface flag to
|
||||
enable/disable performing automatic link-local address configuration.
|
||||
Defaults to on.
|
||||
.It Dv IPV6CTL_KEEPFAITH
|
||||
.Pq ip6.keepfaith
|
||||
Boolean: enable/disable
|
||||
.Dq FAITH
|
||||
TCP relay IPv6-to-IPv4 translator code in the kernel.
|
||||
Refer
|
||||
.Xr faith 4
|
||||
and
|
||||
.Xr faithd 8
|
||||
for detail.
|
||||
Defaults to off.
|
||||
.It Dv IPV6CTL_LOG_INTERVAL
|
||||
.Pq ip6.log_interval
|
||||
Integer: default interval between
|
||||
|
@ -393,10 +393,6 @@ For wildcard sockets, this can restrict connections to IPv6 only.
|
||||
.\".Ox
|
||||
.\"IPv6 sockets are always IPv6-only, so the socket option is read-only
|
||||
.\"(not modifiable).
|
||||
.It Dv IPV6_FAITH Fa "int *"
|
||||
Get or set the status of whether
|
||||
.Xr faith 4
|
||||
connections can be made to this socket.
|
||||
.It Dv IPV6_USE_MIN_MTU Fa "int *"
|
||||
Get or set whether the minimal IPv6 maximum transmission unit (MTU) size
|
||||
will be used to avoid fragmentation from occurring for subsequent
|
||||
|
@ -2948,15 +2948,6 @@ This can be set to
|
||||
.Pq Vt str
|
||||
IPv6 Site Level Aggregator for
|
||||
.Xr stf 4 .
|
||||
.It Va ipv6_faith_prefix
|
||||
.Pq Vt str
|
||||
If not set to
|
||||
.Dq Li NO ,
|
||||
this is the faith prefix to enable a FAITH IPv6-to-IPv4 TCP
|
||||
translator.
|
||||
You also need
|
||||
.Xr faithd 8
|
||||
setup.
|
||||
.It Va ipv6_ipv4mapping
|
||||
.Pq Vt bool
|
||||
If set to
|
||||
|
@ -310,7 +310,6 @@ device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
device firmware # firmware assist module
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
|
@ -143,7 +143,6 @@ device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
#device firmware # firmware assist module
|
||||
|
||||
# SCSI peripherals
|
||||
|
@ -54,7 +54,6 @@ options FDT_DTB_STATIC
|
||||
|
||||
# Misc pseudo devices
|
||||
device bpf # Required for DHCP
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
device firmware # firmware(9) required for USB wlan
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device loop # Network loopback
|
||||
|
@ -57,7 +57,6 @@ options FDT_DTB_STATIC
|
||||
|
||||
# Misc pseudo devices
|
||||
device bpf # Required for DHCP
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
device firmware # firmware(9) required for USB wlan
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device loop # Network loopback
|
||||
|
@ -104,7 +104,6 @@ device ether # Ethernet support
|
||||
#device tun # Packet tunnel.
|
||||
#device md # Memory "disks"
|
||||
#device gif # IPv6 and IPv4 tunneling
|
||||
#device faith # IPv6-to-IPv4 relaying (translation)
|
||||
#device firmware # firmware assist module
|
||||
|
||||
# Serial (COM) ports
|
||||
|
@ -136,7 +136,6 @@ device ether # Ethernet support
|
||||
#device tun # Packet tunnel.
|
||||
#device md # Memory "disks"
|
||||
#device gif # IPv6 and IPv4 tunneling
|
||||
#device faith # IPv6-to-IPv4 relaying (translation)
|
||||
#device firmware # firmware assist module
|
||||
|
||||
# SCSI peripherals
|
||||
|
@ -92,7 +92,6 @@ device ether # Ethernet support
|
||||
#device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
#device gif # IPv6 and IPv4 tunneling
|
||||
#device faith # IPv6-to-IPv4 relaying (translation)
|
||||
#device firmware # firmware assist module
|
||||
|
||||
# Ethernet
|
||||
|
@ -75,7 +75,6 @@ device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
#device gif # IPv6 and IPv4 tunneling
|
||||
#device faith # IPv6-to-IPv4 relaying (translation)
|
||||
#device firmware # firmware assist module
|
||||
device ether # Ethernet support
|
||||
device miibus # Required for ethernet
|
||||
|
@ -146,7 +146,6 @@ device ether # Ethernet support
|
||||
#device tun # Packet tunnel.
|
||||
#device md # Memory "disks"
|
||||
#device gif # IPv6 and IPv4 tunneling
|
||||
#device faith # IPv6-to-IPv4 relaying (translation)
|
||||
#device firmware # firmware assist module
|
||||
|
||||
# SCSI peripherals
|
||||
|
@ -254,7 +254,6 @@ if_disc_load="NO" # Discard device
|
||||
if_ef_load="NO" # pseudo-device providing support for multiple
|
||||
# ethernet frame types
|
||||
if_epair_load="NO" # Virtual b-t-b Ethernet-like interface pair
|
||||
if_faith_load="NO" # IPv6-to-IPv4 TCP relay capturing interface
|
||||
if_gif_load="NO" # generic tunnel interface
|
||||
if_gre_load="NO" # encapsulating network device
|
||||
if_stf_load="NO" # 6to4 tunnel interface
|
||||
|
@ -890,10 +890,7 @@ device gre
|
||||
device me
|
||||
options XBONEHACK
|
||||
|
||||
# The `faith' device captures packets sent to it and diverts them
|
||||
# to the IPv4/IPv6 translation daemon.
|
||||
# The `stf' device implements 6to4 encapsulation.
|
||||
device faith
|
||||
device stf
|
||||
|
||||
# The pf packet filter consists of three devices:
|
||||
|
@ -3229,7 +3229,6 @@ net/if_edsc.c optional edsc
|
||||
net/if_enc.c optional enc ipsec inet | enc ipsec inet6
|
||||
net/if_epair.c optional epair
|
||||
net/if_ethersubr.c optional ether
|
||||
net/if_faith.c optional faith
|
||||
net/if_fddisubr.c optional fddi
|
||||
net/if_fwsubr.c optional fwip
|
||||
net/if_gif.c optional gif inet | gif inet6 | \
|
||||
|
@ -318,7 +318,6 @@ device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
device firmware # firmware assist module
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
|
@ -66,7 +66,6 @@ device ether # Ethernet support
|
||||
#device tun # Packet tunnel.
|
||||
#device md # Memory "disks"
|
||||
#device gif # IPv6 and IPv4 tunneling
|
||||
#device faith # IPv6-to-IPv4 relaying (translation)
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
# Be aware of the administrative consequences of enabling this!
|
||||
|
@ -82,7 +82,6 @@ device ether # Ethernet support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
|
||||
# Wireless cards
|
||||
options IEEE80211_SUPPORT_MESH
|
||||
|
@ -55,7 +55,6 @@ device ether # Ethernet support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
# Be aware of the administrative consequences of enabling this!
|
||||
|
@ -53,7 +53,6 @@ device ether # Ethernet support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
# Be aware of the administrative consequences of enabling this!
|
||||
|
@ -261,7 +261,6 @@ device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
device firmware # firmware assist module
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
|
@ -197,7 +197,6 @@
|
||||
./etc/rc.d/dmesg
|
||||
./etc/rc.d/dumpon
|
||||
./etc/rc.d/encswap
|
||||
./etc/rc.d/faith
|
||||
./etc/rc.d/fsck
|
||||
./etc/rc.d/ftp-proxy
|
||||
./etc/rc.d/ftpd
|
||||
|
@ -145,7 +145,6 @@ SUBDIR= \
|
||||
if_disc \
|
||||
if_edsc \
|
||||
if_epair \
|
||||
if_faith \
|
||||
${_if_gif} \
|
||||
${_if_gre} \
|
||||
${_if_me} \
|
||||
|
@ -1,8 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../net
|
||||
|
||||
KMOD= if_faith
|
||||
SRCS= if_faith.c opt_inet.h opt_inet6.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -1,331 +0,0 @@
|
||||
/* $KAME: if_faith.c,v 1.23 2001/12/17 13:55:29 sumikawa Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* derived from
|
||||
* @(#)if_loop.c 8.1 (Berkeley) 6/10/93
|
||||
* Id: if_loop.c,v 1.22 1996/06/19 16:24:10 wollman Exp
|
||||
*/
|
||||
|
||||
/*
|
||||
* Loopback interface driver for protocol testing and timing.
|
||||
*/
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_clone.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/vnet.h>
|
||||
|
||||
#ifdef INET
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
#ifndef INET
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#endif
|
||||
|
||||
struct faith_softc {
|
||||
struct ifnet *sc_ifp;
|
||||
};
|
||||
|
||||
static int faithioctl(struct ifnet *, u_long, caddr_t);
|
||||
static int faithoutput(struct ifnet *, struct mbuf *, const struct sockaddr *,
|
||||
struct route *);
|
||||
#ifdef INET6
|
||||
static int faithprefix(struct in6_addr *);
|
||||
#endif
|
||||
|
||||
static int faithmodevent(module_t, int, void *);
|
||||
|
||||
static const char faithname[] = "faith";
|
||||
static MALLOC_DEFINE(M_FAITH, faithname, "Firewall Assisted Tunnel Interface");
|
||||
|
||||
static int faith_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void faith_clone_destroy(struct ifnet *);
|
||||
static struct if_clone *faith_cloner;
|
||||
|
||||
#define FAITHMTU 1500
|
||||
|
||||
static int
|
||||
faithmodevent(mod, type, data)
|
||||
module_t mod;
|
||||
int type;
|
||||
void *data;
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
faith_cloner = if_clone_simple(faithname, faith_clone_create,
|
||||
faith_clone_destroy, 0);
|
||||
#ifdef INET6
|
||||
faithprefix_p = faithprefix;
|
||||
#endif
|
||||
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
#ifdef INET6
|
||||
faithprefix_p = NULL;
|
||||
#endif
|
||||
|
||||
if_clone_detach(faith_cloner);
|
||||
break;
|
||||
default:
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static moduledata_t faith_mod = {
|
||||
"if_faith",
|
||||
faithmodevent,
|
||||
0
|
||||
};
|
||||
|
||||
DECLARE_MODULE(if_faith, faith_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
|
||||
MODULE_VERSION(if_faith, 1);
|
||||
|
||||
static int
|
||||
faith_clone_create(ifc, unit, params)
|
||||
struct if_clone *ifc;
|
||||
int unit;
|
||||
caddr_t params;
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct faith_softc *sc;
|
||||
|
||||
sc = malloc(sizeof(struct faith_softc), M_FAITH, M_WAITOK | M_ZERO);
|
||||
ifp = sc->sc_ifp = if_alloc(IFT_FAITH);
|
||||
if (ifp == NULL) {
|
||||
free(sc, M_FAITH);
|
||||
return (ENOSPC);
|
||||
}
|
||||
|
||||
ifp->if_softc = sc;
|
||||
if_initname(sc->sc_ifp, faithname, unit);
|
||||
|
||||
ifp->if_mtu = FAITHMTU;
|
||||
/* Change to BROADCAST experimentaly to announce its prefix. */
|
||||
ifp->if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST;
|
||||
ifp->if_ioctl = faithioctl;
|
||||
ifp->if_output = faithoutput;
|
||||
ifp->if_hdrlen = 0;
|
||||
ifp->if_addrlen = 0;
|
||||
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||
if_attach(ifp);
|
||||
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
faith_clone_destroy(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct faith_softc *sc = ifp->if_softc;
|
||||
|
||||
bpfdetach(ifp);
|
||||
if_detach(ifp);
|
||||
if_free(ifp);
|
||||
free(sc, M_FAITH);
|
||||
}
|
||||
|
||||
static int
|
||||
faithoutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
||||
struct route *ro)
|
||||
{
|
||||
int isr;
|
||||
u_int32_t af;
|
||||
struct rtentry *rt = NULL;
|
||||
|
||||
M_ASSERTPKTHDR(m);
|
||||
|
||||
if (ro != NULL)
|
||||
rt = ro->ro_rt;
|
||||
/* BPF writes need to be handled specially. */
|
||||
if (dst->sa_family == AF_UNSPEC)
|
||||
bcopy(dst->sa_data, &af, sizeof(af));
|
||||
else
|
||||
af = dst->sa_family;
|
||||
|
||||
if (bpf_peers_present(ifp->if_bpf))
|
||||
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m);
|
||||
|
||||
if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
|
||||
m_freem(m);
|
||||
return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
|
||||
rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
|
||||
}
|
||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
|
||||
if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
isr = NETISR_IP;
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
isr = NETISR_IPV6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
m_freem(m);
|
||||
return EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
/* XXX do we need more sanity checks? */
|
||||
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
|
||||
if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
|
||||
netisr_dispatch(isr, m);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process an ioctl request.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
faithioctl(ifp, cmd, data)
|
||||
struct ifnet *ifp;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
int error = 0;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case SIOCSIFADDR:
|
||||
ifp->if_flags |= IFF_UP;
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
|
||||
/*
|
||||
* Everything else is done at a higher level.
|
||||
*/
|
||||
break;
|
||||
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
if (ifr == 0) {
|
||||
error = EAFNOSUPPORT; /* XXX */
|
||||
break;
|
||||
}
|
||||
switch (ifr->ifr_addr.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
error = EAFNOSUPPORT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef SIOCSIFMTU
|
||||
case SIOCSIFMTU:
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SIOCSIFFLAGS:
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
/*
|
||||
* XXX could be slow
|
||||
* XXX could be layer violation to call sys/net from sys/netinet6
|
||||
*/
|
||||
static int
|
||||
faithprefix(in6)
|
||||
struct in6_addr *in6;
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct sockaddr_in6 sin6;
|
||||
int ret;
|
||||
|
||||
if (V_ip6_keepfaith == 0)
|
||||
return 0;
|
||||
|
||||
bzero(&sin6, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
sin6.sin6_addr = *in6;
|
||||
rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL, RT_DEFAULT_FIB);
|
||||
if (rt && rt->rt_ifp && rt->rt_ifp->if_type == IFT_FAITH &&
|
||||
(rt->rt_ifp->if_flags & IFF_UP) != 0)
|
||||
ret = 1;
|
||||
else
|
||||
ret = 0;
|
||||
if (rt)
|
||||
RTFREE_LOCKED(rt);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
@ -246,7 +246,6 @@
|
||||
/* not based on IANA assignments */
|
||||
#define IFT_GIF 0xf0
|
||||
#define IFT_PVC 0xf1
|
||||
#define IFT_FAITH 0xf2
|
||||
#define IFT_ENC 0xf4
|
||||
#define IFT_PFLOG 0xf6
|
||||
#define IFT_PFSYNC 0xf7
|
||||
|
@ -428,8 +428,7 @@ __END_DECLS
|
||||
#define IP_RECVIF 20 /* bool; receive reception if w/dgram */
|
||||
/* for IPSEC */
|
||||
#define IP_IPSEC_POLICY 21 /* int; set/get security policy */
|
||||
#define IP_FAITH 22 /* bool; accept FAITH'ed connections */
|
||||
|
||||
/* unused; was IP_FAITH */
|
||||
#define IP_ONESBCAST 23 /* bool: send all-ones broadcast */
|
||||
#define IP_BINDANY 24 /* bool: allow bind to any address */
|
||||
#define IP_BINDMULTI 25 /* bool: allow multiple listeners on a tuple */
|
||||
@ -630,7 +629,7 @@ int getsourcefilter(int, uint32_t, struct sockaddr *, socklen_t,
|
||||
#define IPCTL_STATS 12 /* ipstat structure */
|
||||
#define IPCTL_ACCEPTSOURCEROUTE 13 /* may accept source routed packets */
|
||||
#define IPCTL_FASTFORWARDING 14 /* use fast IP forwarding code */
|
||||
#define IPCTL_KEEPFAITH 15 /* FAITH IPv4->IPv6 translater ctl */
|
||||
/* 15, unused, was: IPCTL_KEEPFAITH */
|
||||
#define IPCTL_GIF_TTL 16 /* default TTL for gif encap packet */
|
||||
|
||||
#endif /* __BSD_VISIBLE */
|
||||
|
@ -1645,11 +1645,6 @@ in_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup,
|
||||
inp->inp_lport != lport)
|
||||
continue;
|
||||
|
||||
/* XXX inp locking */
|
||||
if (ifp && ifp->if_type == IFT_FAITH &&
|
||||
(inp->inp_flags & INP_FAITH) == 0)
|
||||
continue;
|
||||
|
||||
injail = prison_flag(inp->inp_cred, PR_IP4);
|
||||
if (injail) {
|
||||
if (prison_check_ip4(inp->inp_cred,
|
||||
@ -1724,11 +1719,6 @@ in_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup,
|
||||
inp->inp_lport != lport)
|
||||
continue;
|
||||
|
||||
/* XXX inp locking */
|
||||
if (ifp && ifp->if_type == IFT_FAITH &&
|
||||
(inp->inp_flags & INP_FAITH) == 0)
|
||||
continue;
|
||||
|
||||
injail = prison_flag(inp->inp_cred, PR_IP4);
|
||||
if (injail) {
|
||||
if (prison_check_ip4(inp->inp_cred,
|
||||
@ -1869,11 +1859,6 @@ in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
||||
inp->inp_lport != lport)
|
||||
continue;
|
||||
|
||||
/* XXX inp locking */
|
||||
if (ifp && ifp->if_type == IFT_FAITH &&
|
||||
(inp->inp_flags & INP_FAITH) == 0)
|
||||
continue;
|
||||
|
||||
injail = prison_flag(inp->inp_cred, PR_IP4);
|
||||
if (injail) {
|
||||
if (prison_check_ip4(inp->inp_cred,
|
||||
@ -2468,10 +2453,6 @@ db_print_inpflags(int inp_flags)
|
||||
db_printf("%sINP_MTUDISC", comma ? ", " : "");
|
||||
comma = 1;
|
||||
}
|
||||
if (inp_flags & INP_FAITH) {
|
||||
db_printf("%sINP_FAITH", comma ? ", " : "");
|
||||
comma = 1;
|
||||
}
|
||||
if (inp_flags & INP_RECVTTL) {
|
||||
db_printf("%sINP_RECVTTL", comma ? ", " : "");
|
||||
comma = 1;
|
||||
|
@ -511,7 +511,7 @@ short inp_so_options(const struct inpcb *inp);
|
||||
#define INP_ANONPORT 0x00000040 /* port chosen for user */
|
||||
#define INP_RECVIF 0x00000080 /* receive incoming interface */
|
||||
#define INP_MTUDISC 0x00000100 /* user can do MTU discovery */
|
||||
#define INP_FAITH 0x00000200 /* accept FAITH'ed connections */
|
||||
/* 0x000200 unused: was INP_FAITH */
|
||||
#define INP_RECVTTL 0x00000400 /* receive incoming IP TTL */
|
||||
#define INP_DONTFRAG 0x00000800 /* don't fragment packet */
|
||||
#define INP_BINDANY 0x00001000 /* allow bind to any address */
|
||||
|
@ -410,19 +410,6 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
|
||||
m->m_len += hlen;
|
||||
m->m_data -= hlen;
|
||||
|
||||
if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
|
||||
/*
|
||||
* Deliver very specific ICMP type only.
|
||||
*/
|
||||
switch (icp->icmp_type) {
|
||||
case ICMP_UNREACH:
|
||||
case ICMP_TIMXCEED:
|
||||
break;
|
||||
default:
|
||||
goto freeit;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ICMPPRINTFS
|
||||
if (icmpprintfs)
|
||||
printf("icmp_input, type %d code %d\n", icp->icmp_type,
|
||||
|
@ -104,12 +104,6 @@ SYSCTL_INT(_net_inet_ip, IPCTL_SENDREDIRECTS, redirect, CTLFLAG_VNET | CTLFLAG_R
|
||||
&VNET_NAME(ipsendredirects), 0,
|
||||
"Enable sending IP redirects");
|
||||
|
||||
static VNET_DEFINE(int, ip_keepfaith);
|
||||
#define V_ip_keepfaith VNET(ip_keepfaith)
|
||||
SYSCTL_INT(_net_inet_ip, IPCTL_KEEPFAITH, keepfaith, CTLFLAG_VNET | CTLFLAG_RW,
|
||||
&VNET_NAME(ip_keepfaith), 0,
|
||||
"Enable packet capture for FAITH IPv4->IPv6 translater daemon");
|
||||
|
||||
static VNET_DEFINE(int, ip_sendsourcequench);
|
||||
#define V_ip_sendsourcequench VNET(ip_sendsourcequench)
|
||||
SYSCTL_INT(_net_inet_ip, OID_AUTO, sendsourcequench, CTLFLAG_VNET | CTLFLAG_RW,
|
||||
@ -752,18 +746,6 @@ ip_input(struct mbuf *m)
|
||||
if (ip->ip_dst.s_addr == INADDR_ANY)
|
||||
goto ours;
|
||||
|
||||
/*
|
||||
* FAITH(Firewall Aided Internet Translator)
|
||||
*/
|
||||
if (ifp && ifp->if_type == IFT_FAITH) {
|
||||
if (V_ip_keepfaith) {
|
||||
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_ICMP)
|
||||
goto ours;
|
||||
}
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not for us; forward if possible and desirable.
|
||||
*/
|
||||
|
@ -991,7 +991,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
case IP_RECVDSTADDR:
|
||||
case IP_RECVTTL:
|
||||
case IP_RECVIF:
|
||||
case IP_FAITH:
|
||||
case IP_ONESBCAST:
|
||||
case IP_DONTFRAG:
|
||||
case IP_RECVTOS:
|
||||
@ -1058,10 +1057,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
OPTSET(INP_RECVIF);
|
||||
break;
|
||||
|
||||
case IP_FAITH:
|
||||
OPTSET(INP_FAITH);
|
||||
break;
|
||||
|
||||
case IP_ONESBCAST:
|
||||
OPTSET(INP_ONESBCAST);
|
||||
break;
|
||||
@ -1200,7 +1195,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
case IP_RECVTTL:
|
||||
case IP_RECVIF:
|
||||
case IP_PORTRANGE:
|
||||
case IP_FAITH:
|
||||
case IP_ONESBCAST:
|
||||
case IP_DONTFRAG:
|
||||
case IP_BINDANY:
|
||||
@ -1259,10 +1253,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
optval = 0;
|
||||
break;
|
||||
|
||||
case IP_FAITH:
|
||||
optval = OPTBIT(INP_FAITH);
|
||||
break;
|
||||
|
||||
case IP_ONESBCAST:
|
||||
optval = OPTBIT(INP_ONESBCAST);
|
||||
break;
|
||||
|
@ -482,22 +482,6 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
goto freeit;
|
||||
}
|
||||
|
||||
if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) {
|
||||
/*
|
||||
* Deliver very specific ICMP6 type only.
|
||||
* This is important to deliver TOOBIG. Otherwise PMTUD
|
||||
* will not work.
|
||||
*/
|
||||
switch (icmp6->icmp6_type) {
|
||||
case ICMP6_DST_UNREACH:
|
||||
case ICMP6_PACKET_TOO_BIG:
|
||||
case ICMP6_TIME_EXCEEDED:
|
||||
break;
|
||||
default:
|
||||
goto freeit;
|
||||
}
|
||||
}
|
||||
|
||||
ICMP6STAT_INC(icp6s_inhist[icmp6->icmp6_type]);
|
||||
icmp6_ifstat_inc(ifp, ifs6_in_msg);
|
||||
if (icmp6->icmp6_type < ICMP6_INFOMSG_MASK)
|
||||
|
@ -137,8 +137,6 @@ static int in6_notify_ifa(struct ifnet *, struct in6_ifaddr *,
|
||||
struct in6_aliasreq *, int);
|
||||
static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *);
|
||||
|
||||
int (*faithprefix_p)(struct in6_addr *);
|
||||
|
||||
static int in6_validate_ifra(struct ifnet *, struct in6_aliasreq *,
|
||||
struct in6_ifaddr *, int);
|
||||
static struct in6_ifaddr *in6_alloc_ifa(struct ifnet *,
|
||||
@ -1948,34 +1946,20 @@ in6if_do_dad(struct ifnet *ifp)
|
||||
if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)
|
||||
return (0);
|
||||
|
||||
switch (ifp->if_type) {
|
||||
#ifdef IFT_DUMMY
|
||||
case IFT_DUMMY:
|
||||
#endif
|
||||
case IFT_FAITH:
|
||||
/*
|
||||
* These interfaces do not have the IFF_LOOPBACK flag,
|
||||
* but loop packets back. We do not have to do DAD on such
|
||||
* interfaces. We should even omit it, because loop-backed
|
||||
* NS would confuse the DAD procedure.
|
||||
*/
|
||||
/*
|
||||
* Our DAD routine requires the interface up and running.
|
||||
* However, some interfaces can be up before the RUNNING
|
||||
* status. Additionaly, users may try to assign addresses
|
||||
* before the interface becomes up (or running).
|
||||
* We simply skip DAD in such a case as a work around.
|
||||
* XXX: we should rather mark "tentative" on such addresses,
|
||||
* and do DAD after the interface becomes ready.
|
||||
*/
|
||||
if (!((ifp->if_flags & IFF_UP) &&
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
|
||||
return (0);
|
||||
default:
|
||||
/*
|
||||
* Our DAD routine requires the interface up and running.
|
||||
* However, some interfaces can be up before the RUNNING
|
||||
* status. Additionaly, users may try to assign addresses
|
||||
* before the interface becomes up (or running).
|
||||
* We simply skip DAD in such a case as a work around.
|
||||
* XXX: we should rather mark "tentative" on such addresses,
|
||||
* and do DAD after the interface becomes ready.
|
||||
*/
|
||||
if (!((ifp->if_flags & IFF_UP) &&
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -424,8 +424,7 @@ struct route_in6 {
|
||||
#define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */
|
||||
#endif /* IPSEC */
|
||||
|
||||
#define IPV6_FAITH 29 /* bool; accept FAITH'ed connections */
|
||||
|
||||
/* 29; unused; was IPV6_FAITH */
|
||||
#if 1 /* IPV6FIREWALL */
|
||||
#define IPV6_FW_ADD 30 /* add a firewall rule to chain */
|
||||
#define IPV6_FW_DEL 31 /* delete a firewall rule from chain */
|
||||
@ -580,7 +579,7 @@ struct ip6_mtuinfo {
|
||||
#define IPV6CTL_SOURCECHECK 10 /* verify source route and intf */
|
||||
#define IPV6CTL_SOURCECHECK_LOGINT 11 /* minimume logging interval */
|
||||
#define IPV6CTL_ACCEPT_RTADV 12
|
||||
#define IPV6CTL_KEEPFAITH 13
|
||||
/* 13; unused; was: IPV6CTL_KEEPFAITH */
|
||||
#define IPV6CTL_LOG_INTERVAL 14
|
||||
#define IPV6CTL_HDRNESTLIMIT 15
|
||||
#define IPV6CTL_DAD_COUNT 16
|
||||
@ -669,7 +668,6 @@ extern void addrsel_policy_init(void);
|
||||
#define sin6tosa(sin6) ((struct sockaddr *)(sin6))
|
||||
#define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa))
|
||||
|
||||
extern int (*faithprefix_p)(struct in6_addr *);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifndef _SIZE_T_DECLARED
|
||||
|
@ -870,12 +870,6 @@ in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup,
|
||||
struct inpcbhead *head;
|
||||
struct inpcb *inp, *tmpinp;
|
||||
u_short fport = fport_arg, lport = lport_arg;
|
||||
int faith;
|
||||
|
||||
if (faithprefix_p != NULL)
|
||||
faith = (*faithprefix_p)(laddr);
|
||||
else
|
||||
faith = 0;
|
||||
|
||||
/*
|
||||
* First look for an exact match.
|
||||
@ -935,10 +929,6 @@ in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* XXX inp locking */
|
||||
if (faith && (inp->inp_flags & INP_FAITH) == 0)
|
||||
continue;
|
||||
|
||||
injail = prison_flag(inp->inp_cred, PR_IP6);
|
||||
if (injail) {
|
||||
if (prison_check_ip6(inp->inp_cred,
|
||||
@ -1001,10 +991,6 @@ in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* XXX inp locking */
|
||||
if (faith && (inp->inp_flags & INP_FAITH) == 0)
|
||||
continue;
|
||||
|
||||
injail = prison_flag(inp->inp_cred, PR_IP6);
|
||||
if (injail) {
|
||||
if (prison_check_ip6(inp->inp_cred,
|
||||
@ -1069,18 +1055,12 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
||||
struct inpcbhead *head;
|
||||
struct inpcb *inp, *tmpinp;
|
||||
u_short fport = fport_arg, lport = lport_arg;
|
||||
int faith;
|
||||
|
||||
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
||||
("%s: invalid lookup flags %d", __func__, lookupflags));
|
||||
|
||||
INP_HASH_LOCK_ASSERT(pcbinfo);
|
||||
|
||||
if (faithprefix_p != NULL)
|
||||
faith = (*faithprefix_p)(laddr);
|
||||
else
|
||||
faith = 0;
|
||||
|
||||
/*
|
||||
* First look for an exact match.
|
||||
*/
|
||||
@ -1137,10 +1117,6 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* XXX inp locking */
|
||||
if (faith && (inp->inp_flags & INP_FAITH) == 0)
|
||||
continue;
|
||||
|
||||
injail = prison_flag(inp->inp_cred, PR_IP6);
|
||||
if (injail) {
|
||||
if (prison_check_ip6(inp->inp_cred,
|
||||
|
@ -434,7 +434,6 @@ VNET_DEFINE(int, ip6_rr_prune) = 5; /* router renumbering prefix
|
||||
VNET_DEFINE(int, ip6_mcast_pmtu) = 0; /* enable pMTU discovery for multicast? */
|
||||
VNET_DEFINE(int, ip6_v6only) = 1;
|
||||
|
||||
VNET_DEFINE(int, ip6_keepfaith) = 0;
|
||||
VNET_DEFINE(time_t, ip6_log_time) = (time_t)0L;
|
||||
#ifdef IPSTEALTH
|
||||
VNET_DEFINE(int, ip6stealth) = 0;
|
||||
@ -543,8 +542,6 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RFC6204W3, rfc6204w3,
|
||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_rfc6204w3), 0,
|
||||
"Accept the default router list from ICMPv6 RA messages even "
|
||||
"when packet forwarding enabled.");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_KEEPFAITH, keepfaith,
|
||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_keepfaith), 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_LOG_INTERVAL, log_interval,
|
||||
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_log_interval), 0, "");
|
||||
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_HDRNESTLIMIT, hdrnestlimit,
|
||||
|
@ -1408,7 +1408,6 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
/* FALLTHROUGH */
|
||||
case IPV6_UNICAST_HOPS:
|
||||
case IPV6_HOPLIMIT:
|
||||
case IPV6_FAITH:
|
||||
|
||||
case IPV6_RECVPKTINFO:
|
||||
case IPV6_RECVHOPLIMIT:
|
||||
@ -1552,10 +1551,6 @@ do { \
|
||||
OPTSET(IN6P_RTHDR);
|
||||
break;
|
||||
|
||||
case IPV6_FAITH:
|
||||
OPTSET(INP_FAITH);
|
||||
break;
|
||||
|
||||
case IPV6_RECVPATHMTU:
|
||||
/*
|
||||
* We ignore this option for TCP
|
||||
@ -1823,7 +1818,6 @@ do { \
|
||||
case IPV6_RECVRTHDR:
|
||||
case IPV6_RECVPATHMTU:
|
||||
|
||||
case IPV6_FAITH:
|
||||
case IPV6_V6ONLY:
|
||||
case IPV6_PORTRANGE:
|
||||
case IPV6_RECVTCLASS:
|
||||
@ -1868,10 +1862,6 @@ do { \
|
||||
optval = OPTBIT(IN6P_MTU);
|
||||
break;
|
||||
|
||||
case IPV6_FAITH:
|
||||
optval = OPTBIT(INP_FAITH);
|
||||
break;
|
||||
|
||||
case IPV6_V6ONLY:
|
||||
optval = OPTBIT(IN6P_IPV6_V6ONLY);
|
||||
break;
|
||||
|
@ -296,7 +296,6 @@ VNET_DECLARE(int, ip6_norbit_raif); /* Disable R-bit in NA on RA
|
||||
* receiving IF. */
|
||||
VNET_DECLARE(int, ip6_rfc6204w3); /* Accept defroute from RA even when
|
||||
forwarding enabled */
|
||||
VNET_DECLARE(int, ip6_keepfaith); /* Firewall Aided Internet Translator */
|
||||
VNET_DECLARE(int, ip6_log_interval);
|
||||
VNET_DECLARE(time_t, ip6_log_time);
|
||||
VNET_DECLARE(int, ip6_hdrnestlimit); /* upper limit of # of extension
|
||||
@ -310,7 +309,6 @@ VNET_DECLARE(int, ip6_dad_count); /* DupAddrDetectionTransmits */
|
||||
#define V_ip6_no_radr VNET(ip6_no_radr)
|
||||
#define V_ip6_norbit_raif VNET(ip6_norbit_raif)
|
||||
#define V_ip6_rfc6204w3 VNET(ip6_rfc6204w3)
|
||||
#define V_ip6_keepfaith VNET(ip6_keepfaith)
|
||||
#define V_ip6_log_interval VNET(ip6_log_interval)
|
||||
#define V_ip6_log_time VNET(ip6_log_time)
|
||||
#define V_ip6_hdrnestlimit VNET(ip6_hdrnestlimit)
|
||||
|
@ -169,12 +169,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
|
||||
|
||||
RIP6STAT_INC(rip6s_ipackets);
|
||||
|
||||
if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) {
|
||||
/* XXX Send icmp6 host/port unreach? */
|
||||
m_freem(m);
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
|
||||
init_sin6(&fromsa, m); /* general init */
|
||||
|
||||
ifp = m->m_pkthdr.rcvif;
|
||||
|
@ -149,10 +149,6 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
|
||||
if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
|
||||
goto out;
|
||||
}
|
||||
if (faithprefix_p != NULL && (*faithprefix_p) (&dst.sin6_addr)) {
|
||||
/* XXX send icmp6 host/port unreach? */
|
||||
goto out;
|
||||
}
|
||||
length = ntohs(ip6->ip6_plen) + iphlen;
|
||||
/* Validate mbuf chain length with IP payload length. */
|
||||
if (SCTP_HEADER_LEN(m) != length) {
|
||||
|
@ -208,12 +208,6 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
ifp = m->m_pkthdr.rcvif;
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) {
|
||||
/* XXX send icmp6 host/port unreach? */
|
||||
m_freem(m);
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
|
||||
#ifndef PULLDOWN_TEST
|
||||
IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
|
@ -231,7 +231,6 @@ device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
device firmware # firmware assist module
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
|
@ -154,7 +154,6 @@ device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device ofwd # Open Firmware disks
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying/(translation)
|
||||
device firmware # firmware assist module
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
|
@ -157,7 +157,6 @@ device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device ofwd # Open Firmware disks
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying/(translation)
|
||||
device firmware # firmware assist module
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
|
@ -77,7 +77,6 @@ device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying/(translation)
|
||||
device firmware # firmware assist module
|
||||
|
||||
|
||||
|
@ -225,7 +225,6 @@ device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
device firmware # firmware assist module
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
|
@ -1954,7 +1954,6 @@ OLD_FILES+=usr/share/man/man3/iconvlist.3.gz
|
||||
.if ${MK_INET6} == no
|
||||
OLD_FILES+=sbin/ping6
|
||||
OLD_FILES+=sbin/rtsol
|
||||
OLD_FILES+=usr/sbin/faithd
|
||||
OLD_FILES+=usr/sbin/ip6addrctl
|
||||
OLD_FILES+=usr/sbin/mld6query
|
||||
OLD_FILES+=usr/sbin/ndp
|
||||
|
@ -71,7 +71,6 @@ device tun
|
||||
device pty
|
||||
device md
|
||||
device gif
|
||||
device faith
|
||||
device firmware
|
||||
device bpf
|
||||
device uhci
|
||||
|
@ -69,7 +69,6 @@ device tun
|
||||
device pty
|
||||
device md
|
||||
device gif
|
||||
device faith
|
||||
device firmware
|
||||
device bpf
|
||||
device uhci
|
||||
|
@ -1311,14 +1311,6 @@ net.inet.ip.intr_queue_drops
|
||||
---
|
||||
net.inet.ip.intr_queue_maxlen
|
||||
|
||||
---
|
||||
net.inet.ip.keepfaith
|
||||
bool
|
||||
|
||||
This is used in conjunction with
|
||||
.Xr faithd 8
|
||||
to control the FAITH IPv6/v4 translator daemon.
|
||||
|
||||
---
|
||||
net.inet.ip.maxfragpackets
|
||||
|
||||
|
@ -148,7 +148,6 @@ device tun # Packet tunnel.
|
||||
device pty # Pseudo-ttys (telnet etc)
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
# Be aware of the administrative consequences of enabling this!
|
||||
|
@ -138,7 +138,6 @@ device tun # Packet tunnel.
|
||||
device pty # Pseudo-ttys (telnet etc)
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
# Be aware of the administrative consequences of enabling this!
|
||||
|
@ -110,7 +110,6 @@ device tun # Packet tunnel.
|
||||
device pty # Pseudo-ttys (telnet etc)
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
# Be aware of the administrative consequences of enabling this!
|
||||
|
@ -160,7 +160,6 @@ SUBDIR+= gpioctl
|
||||
.endif
|
||||
|
||||
.if ${MK_INET6} != "no"
|
||||
SUBDIR+= faithd
|
||||
SUBDIR+= ip6addrctl
|
||||
SUBDIR+= mld6query
|
||||
SUBDIR+= ndp
|
||||
|
@ -82,7 +82,7 @@ f_dialog_menu_netdev()
|
||||
f_struct "$dev" get name if || continue
|
||||
# Skip unsavory interfaces
|
||||
case "$if" in
|
||||
lo[0-9]*|ppp[0-9]*|sl[0-9]*|faith[0-9]*) continue ;;
|
||||
lo[0-9]*|ppp[0-9]*|sl[0-9]*) continue ;;
|
||||
esac
|
||||
iflist="$iflist $if"
|
||||
done
|
||||
|
@ -1,25 +0,0 @@
|
||||
# Copyright (c) 1996 WIDE Project. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modifications, are permitted provided that the above copyright notice
|
||||
# and this paragraph are duplicated in all such forms and that any
|
||||
# documentation, advertising materials, and other materials related to
|
||||
# such distribution and use acknowledge that the software was developed
|
||||
# by the WIDE Project, Japan. The name of the Project may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
|
||||
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= faithd
|
||||
MAN= faithd.8
|
||||
SRCS= faithd.c tcp.c ftp.c prefix.c
|
||||
|
||||
CFLAGS+= -DHAVE_POLL_H
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,148 +0,0 @@
|
||||
Configuring FAITH IPv6-to-IPv4 TCP relay
|
||||
|
||||
Kazu Yamamoto and Jun-ichiro itojun Hagino
|
||||
$KAME: README,v 1.10 2003/01/06 21:40:33 sumikawa Exp $
|
||||
$FreeBSD$
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
FAITH is an IPv6-to-IPv4 TCP relay. It performs tcp relay just as some of
|
||||
firewall-oriented gateway does, but between IPv6 and IPv4 with address
|
||||
translation.
|
||||
TCP connections has to be made from IPv6 node to IPv4 node. FAITH will
|
||||
not relay connections for the opposite direction.
|
||||
To perform relays, FAITH daemon needs to be executed on a router between
|
||||
your local IPv6 site and outside IPv4 network. The daemon needs to be
|
||||
invoked per each TCP services (TCP port number).
|
||||
|
||||
IPv4 node "dest" = 123.4.5.6
|
||||
|
|
||||
[[[[ outside IPv4 ocean ]]]]
|
||||
|
|
||||
node that runs FAITH-daemon (usually a router)
|
||||
|
|
||||
==+=====+===+==== IPv6, or IPv4/v6 network in your site ^
|
||||
| | | connection
|
||||
clients IPv6 node "src" |
|
||||
|
||||
You will have to allocate an IPv6 address prefix to map IPv4 addresses into.
|
||||
The following description uses 3ffe:0501:ffff:0000:: as example.
|
||||
Please use a prefix which belongs to your site.
|
||||
FAITH will make it possible to make an IPv6 TCP connection From IPv6 node
|
||||
"src", toward IPv4 node "dest", by specifying FAITH-mapped address
|
||||
3ffe:0501:ffff:0000::123.4.5.6
|
||||
(which is, 3ffe:0501:ffff:0000:0000:0000:7b04:0506).
|
||||
The address mapping can be performed by hand:-), by special nameserver on
|
||||
the network, or by special resolver on the source node.
|
||||
|
||||
|
||||
Setup
|
||||
=====
|
||||
|
||||
The following example assumes:
|
||||
- You have assigned 3ffe:0501:ffff:0000:: as FAITH adderss prefix.
|
||||
- You are willing to provide IPv6-to IPv4 TCP relay for telnet.
|
||||
|
||||
<<On the translating router on which faithd runs>>
|
||||
|
||||
(1) If you have IPv6 TCP server for the "telnet" service, i.e. telnetd via
|
||||
inet6d, disable that daemon. Comment out the line from "inet6d.conf"
|
||||
and send the HUP signal to "inet6d".
|
||||
|
||||
(2) Execute sysctl as root to enable FAITH support in the kernel.
|
||||
|
||||
# sysctl net.inet6.ip6.keepfaith=1
|
||||
|
||||
(3) Route packets toward FAITH prefix into "faith0" interface.
|
||||
|
||||
# ifconfig faith0 up
|
||||
# route add -inet6 3ffe:0501:ffff:0000:: -prefixlen 64 ::1
|
||||
# route change -inet6 3ffe:0501:ffff:0000:: -prefixlen 64 -ifp faith0
|
||||
|
||||
(4) Execute "faithd" by root as follows:
|
||||
|
||||
# faithd telnet /usr/libexec/telnetd telnetd
|
||||
|
||||
1st argument is a service name you are willing to provide TCP relay.
|
||||
(it can be specified either by number "23" or by string "telnet")
|
||||
2nd argument is a path name for local IPv6 TCP server. If there is a
|
||||
connection toward the router itself, this program will be invoked.
|
||||
3rd and the following arguments are arguments for the local IPv6 TCP
|
||||
server. (3rd argument is typically the program name without its path.)
|
||||
|
||||
More examples:
|
||||
|
||||
# faithd ftpd /usr/libexec/ftpd ftpd -l
|
||||
# faithd sshd
|
||||
|
||||
If inetd(8) on your platform have special support for faithd, it is possible
|
||||
to setup faithd services via inetd(8). Consult manpage for details.
|
||||
|
||||
|
||||
<<Routing>>
|
||||
|
||||
(4) Make sure that packets whose destinations match the prefix can
|
||||
reach from the IPv6 host to the translating router.
|
||||
|
||||
<<On the IPv6 host>>
|
||||
|
||||
There are two ways to translate IPv4 address to IPv6 address:
|
||||
(a) Faked by DNS
|
||||
(b) Faked by /etc/hosts.
|
||||
|
||||
(5.a) Install "newbie" and set up FAITH mode. See kit/ports/newbie.
|
||||
|
||||
(5.b) Add an entry into /etc/hosts so that you can resolve hostname into
|
||||
faked IPv6 addrss. For example, add the following line for www.netbsd.org:
|
||||
|
||||
3ffe:0501:ffff:0000::140.160.140.252 www.netbsd.org
|
||||
|
||||
<<On the translating router on which faithd runs.>>
|
||||
|
||||
(6) To see if "faithd" works, watch "/var/log/daemon". Note: please
|
||||
setup "/etc/syslog.conf" so that LOG_DAEMON messages are to be stored
|
||||
in "/var/log/daemon".
|
||||
|
||||
<e.g.>
|
||||
daemon.* /var/log/daemon
|
||||
|
||||
|
||||
Access control
|
||||
==============
|
||||
|
||||
Since faithd implements TCP relaying service, it is critical to implement
|
||||
proper access control to cope with malicious use. Bad guy may try to
|
||||
use your relay router to circumvent access controls, or may try to
|
||||
abuse your network (like sending SPAMs from IPv4 address that belong to you).
|
||||
Install IPv6 packet filter directives that would reject traffic from
|
||||
unwanted source. If you are using inetd-based setup, you may be able to
|
||||
use access control mechanisms in inetd.
|
||||
|
||||
|
||||
Advanced configuration
|
||||
======================
|
||||
|
||||
If you would like to restrict IPv4 destination for translation, you may
|
||||
want to do the following:
|
||||
|
||||
# route add -inet6 3ffe:0501:ffff:0000::123.0.0.0 -prefixlen 104 ::1
|
||||
# route change -inet6 3ffe:0501:ffff:0000::123.0.0.0 -prefixlen 104 \
|
||||
-ifp faith0
|
||||
|
||||
By this way, you can restrict IPv4 destination to 123.0.0.0/8.
|
||||
You may also want to reject packets toward 3ffe:0501:ffff:0000::/64 which
|
||||
is not in 3ffe:0501:ffff:0000::123.0.0.0/104. This will be left as excerside
|
||||
for the reader.
|
||||
|
||||
By doing this, you will be able to provide your IPv4 web server to outside
|
||||
IPv6 customers, without risks of unwanted open relays.
|
||||
|
||||
[[[[ IPv6 network outside ]]]] |
|
||||
| | connection
|
||||
node that runs FAITH-daemon (usually a router) v
|
||||
|
|
||||
========+======== IPv4/v6 network in your site
|
||||
| (123.0.0.0/8)
|
||||
IPv4 web server
|
@ -1,404 +0,0 @@
|
||||
.\" $KAME: faithd.8,v 1.37 2002/05/09 14:21:23 itojun Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the project nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 2, 2011
|
||||
.Dt FAITHD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm faithd
|
||||
.Nd FAITH IPv6/v4 translator daemon
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl dp
|
||||
.Op Fl f Ar configfile
|
||||
.Ar service
|
||||
.Op Ar serverpath Op Ar serverargs
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility provides IPv6-to-IPv4 TCP relaying.
|
||||
It can only be used on an IPv4/v6 dual stack router.
|
||||
.Pp
|
||||
When
|
||||
.Nm
|
||||
receives
|
||||
.Tn TCPv6
|
||||
traffic, it will relay the
|
||||
.Tn TCPv6
|
||||
traffic to
|
||||
.Tn TCPv4 .
|
||||
The destination for the relayed
|
||||
.Tn TCPv4
|
||||
connection will be determined by the last 4 octets of the original
|
||||
.Tn IPv6
|
||||
destination.
|
||||
For example, if
|
||||
.Li 3ffe:0501:4819:ffff::
|
||||
is reserved for
|
||||
.Nm ,
|
||||
and the
|
||||
.Tn TCPv6
|
||||
destination address is
|
||||
.Li 3ffe:0501:4819:ffff::0a01:0101 ,
|
||||
the traffic will be relayed to IPv4 destination
|
||||
.Li 10.1.1.1 .
|
||||
.Pp
|
||||
To use the
|
||||
.Nm
|
||||
translation service,
|
||||
an IPv6 address prefix must be reserved for mapping IPv4 addresses into.
|
||||
The kernel must be properly configured to route all the TCP connections
|
||||
toward the reserved IPv6 address prefix into the
|
||||
.Xr faith 4
|
||||
pseudo interface, using the
|
||||
.Xr route 8
|
||||
command.
|
||||
Also,
|
||||
.Xr sysctl 8
|
||||
should be used to configure
|
||||
.Dv net.inet6.ip6.keepfaith
|
||||
to
|
||||
.Dv 1 .
|
||||
.Pp
|
||||
The router must be configured to capture all the TCP traffic
|
||||
for the reserved
|
||||
.Tn IPv6
|
||||
address prefix, by using
|
||||
.Xr route 8
|
||||
and
|
||||
.Xr sysctl 8
|
||||
commands.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility needs special name-to-address translation logic, so that
|
||||
hostnames get resolved into the special
|
||||
.Tn IPv6
|
||||
address prefix.
|
||||
For small-scale installations, use
|
||||
.Xr hosts 5 ;
|
||||
For large-scale installations, it is useful to have
|
||||
a DNS server with special address translation support.
|
||||
An implementation called
|
||||
.Nm totd
|
||||
is available at
|
||||
.Pa http://www.vermicelli.pasta.cs.uit.no/software/totd.html .
|
||||
Make sure you do not propagate translated DNS records over to normal
|
||||
DNS, as it can cause severe problems.
|
||||
.Ss Daemon mode
|
||||
When
|
||||
.Nm
|
||||
is invoked as a standalone program,
|
||||
.Nm
|
||||
will daemonize itself.
|
||||
The
|
||||
.Nm
|
||||
utility will listen to
|
||||
.Tn TCPv6
|
||||
port
|
||||
.Ar service .
|
||||
If
|
||||
.Tn TCPv6
|
||||
traffic to port
|
||||
.Ar service
|
||||
is found, it relays the connection.
|
||||
.Pp
|
||||
Since
|
||||
.Nm
|
||||
listens to TCP port
|
||||
.Ar service ,
|
||||
it is not possible to run local TCP daemons for port
|
||||
.Ar service
|
||||
on the router, using
|
||||
.Xr inetd 8
|
||||
or other standard mechanisms.
|
||||
By specifying
|
||||
.Ar serverpath
|
||||
to
|
||||
.Nm ,
|
||||
you can run local daemons on the router.
|
||||
The
|
||||
.Nm
|
||||
utility will invoke a local daemon at
|
||||
.Ar serverpath
|
||||
if the destination address is a local interface address,
|
||||
and will perform translation to IPv4 TCP in other cases.
|
||||
You can also specify
|
||||
.Ar serverargs
|
||||
for the arguments for the local daemon.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl d
|
||||
Debugging information will be generated using
|
||||
.Xr syslog 3 .
|
||||
.It Fl f Ar configfile
|
||||
Specify a configuration file for access control.
|
||||
See below.
|
||||
.It Fl p
|
||||
Use privileged TCP port number as source port,
|
||||
for IPv4 TCP connection toward final destination.
|
||||
For relaying
|
||||
.Xr ftp 1 ,
|
||||
this flag is not necessary as special program code is supplied.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility will relay both normal and out-of-band TCP data.
|
||||
It is capable of emulating TCP half close as well.
|
||||
The
|
||||
.Nm
|
||||
utility includes special support for protocols used by
|
||||
.Xr ftp 1 .
|
||||
When translating the FTP protocol,
|
||||
.Nm
|
||||
translates network level addresses in
|
||||
.Li PORT/LPRT/EPRT
|
||||
and
|
||||
.Li PASV/LPSV/EPSV
|
||||
commands.
|
||||
.Pp
|
||||
Inactive sessions will be disconnected in 30 minutes,
|
||||
to prevent stale sessions from chewing up resources.
|
||||
This may be inappropriate for some services
|
||||
(should this be configurable?).
|
||||
.Ss inetd mode
|
||||
When
|
||||
.Nm
|
||||
is invoked via
|
||||
.Xr inetd 8 ,
|
||||
.Nm
|
||||
will handle connections passed from standard input.
|
||||
If the connection endpoint is in the reserved IPv6 address prefix,
|
||||
.Nm
|
||||
will relay the connection.
|
||||
Otherwise,
|
||||
.Nm
|
||||
will invoke a service-specific daemon like
|
||||
.Xr telnetd 8 ,
|
||||
by using the command argument passed from
|
||||
.Xr inetd 8 .
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility determines operation mode by the local TCP port number,
|
||||
and enables special protocol handling whenever necessary/possible.
|
||||
For example, if
|
||||
.Nm
|
||||
is invoked via
|
||||
.Xr inetd 8
|
||||
on the FTP port, it will operate as an FTP relay.
|
||||
.Pp
|
||||
The operation mode requires special support for
|
||||
.Nm
|
||||
in
|
||||
.Xr inetd 8 .
|
||||
.Ss Access control
|
||||
To prevent malicious access,
|
||||
.Nm
|
||||
implements simple address-based access control.
|
||||
With
|
||||
.Pa /etc/faithd.conf
|
||||
(or
|
||||
.Ar configfile
|
||||
specified by
|
||||
.Fl f ) ,
|
||||
.Nm
|
||||
will avoid relaying unwanted traffic.
|
||||
The
|
||||
.Pa faithd.conf
|
||||
configuration file contains directives of the following format:
|
||||
.Bl -bullet
|
||||
.It
|
||||
.Ar src Ns / Ns Ar slen Cm deny Ar dst Ns / Ns Ar dlen
|
||||
.Pp
|
||||
If the source address of a query matches
|
||||
.Ar src Ns / Ns Ar slen ,
|
||||
and the translated destination address matches
|
||||
.Ar dst Ns / Ns Ar dlen ,
|
||||
deny the connection.
|
||||
.It
|
||||
.Ar src Ns / Ns Ar slen Cm permit Ar dst Ns / Ns Ar dlen
|
||||
.Pp
|
||||
If the source address of a query matches
|
||||
.Ar src Ns / Ns Ar slen ,
|
||||
and the translated destination address matches
|
||||
.Ar dst Ns / Ns Ar dlen ,
|
||||
permit the connection.
|
||||
.El
|
||||
.Pp
|
||||
The directives are evaluated in sequence,
|
||||
and the first matching entry will be effective.
|
||||
If there is no match
|
||||
(if we reach the end of the ruleset)
|
||||
the traffic will be denied.
|
||||
.Pp
|
||||
With inetd mode,
|
||||
traffic may be filtered by using access control functionality in
|
||||
.Xr inetd 8 .
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
utility exits with
|
||||
.Dv EXIT_SUCCESS
|
||||
.Pq 0
|
||||
on success, and
|
||||
.Dv EXIT_FAILURE
|
||||
.Pq 1
|
||||
on error.
|
||||
.Sh EXAMPLES
|
||||
Before invoking
|
||||
.Nm ,
|
||||
the
|
||||
.Xr faith 4
|
||||
interface has to be configured properly.
|
||||
.Bd -literal -offset indent
|
||||
# sysctl net.inet6.ip6.accept_rtadv=0
|
||||
# sysctl net.inet6.ip6.forwarding=1
|
||||
# sysctl net.inet6.ip6.keepfaith=1
|
||||
# ifconfig faith0 up
|
||||
# route add -inet6 3ffe:501:4819:ffff:: -prefixlen 96 ::1
|
||||
# route change -inet6 3ffe:501:4819:ffff:: -prefixlen 96 -ifp faith0
|
||||
.Ed
|
||||
.Ss Daemon mode samples
|
||||
To translate
|
||||
.Li telnet
|
||||
service, and provide no local telnet service, invoke
|
||||
.Nm
|
||||
as follows:
|
||||
.Bd -literal -offset indent
|
||||
# faithd telnet
|
||||
.Ed
|
||||
.Pp
|
||||
If you would like to provide local telnet service via
|
||||
.Xr telnetd 8
|
||||
on
|
||||
.Pa /usr/libexec/telnetd ,
|
||||
use the following command line:
|
||||
.Bd -literal -offset indent
|
||||
# faithd telnet /usr/libexec/telnetd telnetd
|
||||
.Ed
|
||||
.Pp
|
||||
If you would like to pass extra arguments to the local daemon:
|
||||
.Bd -literal -offset indent
|
||||
# faithd ftp /usr/libexec/ftpd ftpd -l
|
||||
.Ed
|
||||
.Pp
|
||||
Here are some other examples.
|
||||
You may need
|
||||
.Fl p
|
||||
if the service checks the source port range.
|
||||
.Bd -literal -offset indent
|
||||
# faithd ssh
|
||||
# faithd telnet /usr/libexec/telnetd telnetd
|
||||
.Ed
|
||||
.Ss inetd mode samples
|
||||
Add the following lines into
|
||||
.Xr inetd.conf 5 .
|
||||
Syntax may vary depending upon your operating system.
|
||||
.Bd -literal -offset indent
|
||||
telnet stream tcp6/faith nowait root faithd telnetd
|
||||
ftp stream tcp6/faith nowait root faithd ftpd -l
|
||||
ssh stream tcp6/faith nowait root faithd /usr/sbin/sshd -i
|
||||
.Ed
|
||||
.Pp
|
||||
.Xr inetd 8
|
||||
will open listening sockets with kernel TCP relay support enabled.
|
||||
Whenever a connection comes in,
|
||||
.Nm
|
||||
will be invoked by
|
||||
.Xr inetd 8 .
|
||||
If the connection endpoint is in the reserved IPv6 address prefix.
|
||||
The
|
||||
.Nm
|
||||
utility will relay the connection.
|
||||
Otherwise,
|
||||
.Nm
|
||||
will invoke service-specific daemon like
|
||||
.Xr telnetd 8 .
|
||||
.Ss Access control samples
|
||||
The following illustrates a simple
|
||||
.Pa faithd.conf
|
||||
setting.
|
||||
.Bd -literal -offset indent
|
||||
# permit anyone from 3ffe:501:ffff::/48 to use the translator,
|
||||
# to connect to the following IPv4 destinations:
|
||||
# - any location except 10.0.0.0/8 and 127.0.0.0/8.
|
||||
# Permit no other connections.
|
||||
#
|
||||
3ffe:501:ffff::/48 deny 10.0.0.0/8
|
||||
3ffe:501:ffff::/48 deny 127.0.0.0/8
|
||||
3ffe:501:ffff::/48 permit 0.0.0.0/0
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr faith 4 ,
|
||||
.Xr route 8 ,
|
||||
.Xr sysctl 8
|
||||
.Rs
|
||||
.%A Jun-ichiro itojun Hagino
|
||||
.%A Kazu Yamamoto
|
||||
.%T "An IPv6-to-IPv4 transport relay translator"
|
||||
.%B RFC3142
|
||||
.%U http://tools.ietf.org/html/rfc3142
|
||||
.%D June 2001
|
||||
.Re
|
||||
.\"
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in the WIDE Hydrangea IPv6 protocol stack kit.
|
||||
.\"
|
||||
.Pp
|
||||
IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack
|
||||
was initially integrated into
|
||||
.Fx 4.0 .
|
||||
.Sh SECURITY CONSIDERATIONS
|
||||
It is very insecure to use IP-address based authentication, for connections relayed by
|
||||
.Nm ,
|
||||
and any other TCP relaying services.
|
||||
.Pp
|
||||
Administrators are advised to limit accesses to
|
||||
.Nm
|
||||
using
|
||||
.Pa faithd.conf ,
|
||||
or by using IPv6 packet filters, to protect the
|
||||
.Nm
|
||||
service from malicious parties, and to avoid theft of service/bandwidth.
|
||||
IPv6 destination addresses can be limited by
|
||||
carefully configuring routing entries that point to
|
||||
.Xr faith 4 ,
|
||||
using
|
||||
.Xr route 8 .
|
||||
The IPv6 source address needs to be filtered using packet filters.
|
||||
The documents listed in
|
||||
.Sx SEE ALSO
|
||||
have more information on this topic.
|
@ -1,908 +0,0 @@
|
||||
/* $KAME: faithd.c,v 1.67 2003/10/16 05:26:21 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* User level translator from IPv6 to IPv4.
|
||||
*
|
||||
* Usage: faithd [<port> <progpath> <arg1(progname)> <arg2> ...]
|
||||
* e.g. faithd telnet /usr/libexec/telnetd telnetd
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <libutil.h>
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <net/if_types.h>
|
||||
#ifdef IFT_FAITH
|
||||
# define USE_ROUTE
|
||||
# include <net/if.h>
|
||||
# include <net/route.h>
|
||||
# include <net/if_dl.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include "faithd.h"
|
||||
#include "prefix.h"
|
||||
|
||||
char *serverpath = NULL;
|
||||
char *serverarg[MAXARGV + 1];
|
||||
static char *faithdname = NULL;
|
||||
char logname[BUFSIZ];
|
||||
char procname[BUFSIZ];
|
||||
|
||||
struct myaddrs {
|
||||
struct myaddrs *next;
|
||||
struct sockaddr *addr;
|
||||
};
|
||||
struct myaddrs *myaddrs = NULL;
|
||||
|
||||
static const char *service;
|
||||
#ifdef USE_ROUTE
|
||||
static int sockfd = 0;
|
||||
#endif
|
||||
int dflag = 0;
|
||||
static int pflag = 0;
|
||||
static int inetd = 0;
|
||||
static char *configfile = NULL;
|
||||
|
||||
int main(int, char **);
|
||||
static int inetd_main(int, char **);
|
||||
static int daemon_main(int, char **);
|
||||
static void play_service(int);
|
||||
static void play_child(int, struct sockaddr *);
|
||||
static int faith_prefix(struct sockaddr *);
|
||||
static int map6to4(struct sockaddr_in6 *, struct sockaddr_in *);
|
||||
static void sig_child(int);
|
||||
static void sig_terminate(int);
|
||||
static void start_daemon(void);
|
||||
static void exit_stderr(const char *, ...)
|
||||
__attribute__((__format__(__printf__, 1, 2)));
|
||||
static void grab_myaddrs(void);
|
||||
static void free_myaddrs(void);
|
||||
static void update_myaddrs(void);
|
||||
static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/*
|
||||
* Initializing stuff
|
||||
*/
|
||||
|
||||
faithdname = strrchr(argv[0], '/');
|
||||
if (faithdname)
|
||||
faithdname++;
|
||||
else
|
||||
faithdname = argv[0];
|
||||
|
||||
if (strcmp(faithdname, "faithd") != 0) {
|
||||
inetd = 1;
|
||||
return inetd_main(argc, argv);
|
||||
} else
|
||||
return daemon_main(argc, argv);
|
||||
}
|
||||
|
||||
static int
|
||||
inetd_main(int argc, char **argv)
|
||||
{
|
||||
char path[MAXPATHLEN];
|
||||
struct sockaddr_storage me;
|
||||
struct sockaddr_storage from;
|
||||
socklen_t melen, fromlen;
|
||||
int i;
|
||||
int error;
|
||||
const int on = 1;
|
||||
char sbuf[NI_MAXSERV], snum[NI_MAXSERV];
|
||||
|
||||
if (config_load(configfile) < 0 && configfile) {
|
||||
exit_failure("could not load config file");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (strrchr(argv[0], '/') == NULL)
|
||||
snprintf(path, sizeof(path), "%s/%s", DEFAULT_DIR, argv[0]);
|
||||
else
|
||||
snprintf(path, sizeof(path), "%s", argv[0]);
|
||||
|
||||
#ifdef USE_ROUTE
|
||||
grab_myaddrs();
|
||||
|
||||
sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC);
|
||||
if (sockfd < 0) {
|
||||
exit_failure("socket(PF_ROUTE): %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
|
||||
melen = sizeof(me);
|
||||
if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0) {
|
||||
exit_failure("getsockname: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
fromlen = sizeof(from);
|
||||
if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0) {
|
||||
exit_failure("getpeername: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0,
|
||||
sbuf, sizeof(sbuf), NI_NUMERICHOST) == 0)
|
||||
service = sbuf;
|
||||
else
|
||||
service = DEFAULT_PORT_NAME;
|
||||
if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0,
|
||||
snum, sizeof(snum), NI_NUMERICHOST) != 0)
|
||||
snprintf(snum, sizeof(snum), "?");
|
||||
|
||||
snprintf(logname, sizeof(logname), "faithd %s", snum);
|
||||
snprintf(procname, sizeof(procname), "accepting port %s", snum);
|
||||
openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
|
||||
|
||||
if (argc >= MAXARGV) {
|
||||
exit_failure("too many arguments");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
serverarg[0] = serverpath = path;
|
||||
for (i = 1; i < argc; i++)
|
||||
serverarg[i] = argv[i];
|
||||
serverarg[i] = NULL;
|
||||
|
||||
error = setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &on,
|
||||
sizeof(on));
|
||||
if (error < 0) {
|
||||
exit_failure("setsockopt(SO_OOBINLINE): %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
play_child(STDIN_FILENO, (struct sockaddr *)&from);
|
||||
exit_failure("should not reach here");
|
||||
return 0; /*dummy!*/
|
||||
}
|
||||
|
||||
static int
|
||||
daemon_main(int argc, char **argv)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
int s_wld, error, i, serverargc, on = 1;
|
||||
int family = AF_INET6;
|
||||
int c;
|
||||
|
||||
while ((c = getopt(argc, argv, "df:p")) != -1) {
|
||||
switch (c) {
|
||||
case 'd':
|
||||
dflag++;
|
||||
break;
|
||||
case 'f':
|
||||
configfile = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
pflag++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (config_load(configfile) < 0 && configfile) {
|
||||
exit_failure("could not load config file");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_ROUTE
|
||||
grab_myaddrs();
|
||||
#endif
|
||||
|
||||
switch (argc) {
|
||||
case 0:
|
||||
usage();
|
||||
/*NOTREACHED*/
|
||||
default:
|
||||
serverargc = argc - NUMARG;
|
||||
if (serverargc >= MAXARGV)
|
||||
exit_stderr("too many arguments");
|
||||
|
||||
serverpath = strdup(argv[NUMPRG]);
|
||||
if (!serverpath)
|
||||
exit_stderr("not enough core");
|
||||
for (i = 0; i < serverargc; i++) {
|
||||
serverarg[i] = strdup(argv[i + NUMARG]);
|
||||
if (!serverarg[i])
|
||||
exit_stderr("not enough core");
|
||||
}
|
||||
serverarg[i] = NULL;
|
||||
/* fall throuth */
|
||||
case 1: /* no local service */
|
||||
service = argv[NUMPRT];
|
||||
break;
|
||||
}
|
||||
|
||||
start_daemon();
|
||||
|
||||
/*
|
||||
* Opening wild card socket for this service.
|
||||
*/
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP; /* SCTP? */
|
||||
error = getaddrinfo(NULL, service, &hints, &res);
|
||||
if (error)
|
||||
exit_failure("getaddrinfo: %s", gai_strerror(error));
|
||||
|
||||
s_wld = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (s_wld == -1)
|
||||
exit_failure("socket: %s", strerror(errno));
|
||||
|
||||
#ifdef IPV6_FAITH
|
||||
if (res->ai_family == AF_INET6) {
|
||||
error = setsockopt(s_wld, IPPROTO_IPV6, IPV6_FAITH, &on, sizeof(on));
|
||||
if (error == -1)
|
||||
exit_failure("setsockopt(IPV6_FAITH): %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
error = setsockopt(s_wld, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
if (error == -1)
|
||||
exit_failure("setsockopt(SO_REUSEADDR): %s", strerror(errno));
|
||||
|
||||
error = setsockopt(s_wld, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));
|
||||
if (error == -1)
|
||||
exit_failure("setsockopt(SO_OOBINLINE): %s", strerror(errno));
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
error = setsockopt(s_wld, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
|
||||
if (error == -1)
|
||||
exit_failure("setsockopt(IPV6_V6ONLY): %s", strerror(errno));
|
||||
#endif
|
||||
|
||||
error = bind(s_wld, (struct sockaddr *)res->ai_addr, res->ai_addrlen);
|
||||
if (error == -1)
|
||||
exit_failure("bind: %s", strerror(errno));
|
||||
|
||||
error = listen(s_wld, 5);
|
||||
if (error == -1)
|
||||
exit_failure("listen: %s", strerror(errno));
|
||||
|
||||
#ifdef USE_ROUTE
|
||||
sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC);
|
||||
if (sockfd < 0) {
|
||||
exit_failure("socket(PF_ROUTE): %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Everything is OK.
|
||||
*/
|
||||
|
||||
snprintf(logname, sizeof(logname), "faithd %s", service);
|
||||
snprintf(procname, sizeof(procname), "accepting port %s", service);
|
||||
openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
|
||||
syslog(LOG_INFO, "Starting faith daemon for %s port", service);
|
||||
|
||||
play_service(s_wld);
|
||||
/* NOTREACHED */
|
||||
exit(1); /*pacify gcc*/
|
||||
}
|
||||
|
||||
static void
|
||||
play_service(int s_wld)
|
||||
{
|
||||
struct sockaddr_storage srcaddr;
|
||||
socklen_t len;
|
||||
int s_src;
|
||||
pid_t child_pid;
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd pfd[2];
|
||||
#else
|
||||
fd_set rfds;
|
||||
int maxfd;
|
||||
#endif
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Wait, accept, fork, faith....
|
||||
*/
|
||||
again:
|
||||
setproctitle("%s", procname);
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
pfd[0].fd = s_wld;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = -1;
|
||||
pfd[1].revents = 0;
|
||||
#else
|
||||
FD_ZERO(&rfds);
|
||||
if (s_wld >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_SET(s_wld, &rfds);
|
||||
maxfd = s_wld;
|
||||
#endif
|
||||
#ifdef USE_ROUTE
|
||||
if (sockfd) {
|
||||
#ifdef HAVE_POLL_H
|
||||
pfd[1].fd = sockfd;
|
||||
pfd[1].events = POLLIN;
|
||||
#else
|
||||
if (sockfd >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_SET(sockfd, &rfds);
|
||||
maxfd = (maxfd < sockfd) ? sockfd : maxfd;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
error = poll(pfd, sizeof(pfd)/sizeof(pfd[0]), INFTIM);
|
||||
#else
|
||||
error = select(maxfd + 1, &rfds, NULL, NULL, NULL);
|
||||
#endif
|
||||
if (error < 0) {
|
||||
if (errno == EINTR)
|
||||
goto again;
|
||||
exit_failure("select: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
#ifdef USE_ROUTE
|
||||
#ifdef HAVE_POLL_H
|
||||
if (pfd[1].revents & POLLIN)
|
||||
#else
|
||||
if (FD_ISSET(sockfd, &rfds))
|
||||
#endif
|
||||
{
|
||||
update_myaddrs();
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_POLL_H
|
||||
if (pfd[0].revents & POLLIN)
|
||||
#else
|
||||
if (FD_ISSET(s_wld, &rfds))
|
||||
#endif
|
||||
{
|
||||
len = sizeof(srcaddr);
|
||||
s_src = accept(s_wld, (struct sockaddr *)&srcaddr, &len);
|
||||
if (s_src < 0) {
|
||||
if (errno == ECONNABORTED)
|
||||
goto again;
|
||||
exit_failure("socket: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (srcaddr.ss_family == AF_INET6 &&
|
||||
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&srcaddr)->sin6_addr)) {
|
||||
close(s_src);
|
||||
syslog(LOG_ERR, "connection from IPv4 mapped address?");
|
||||
goto again;
|
||||
}
|
||||
|
||||
child_pid = fork();
|
||||
|
||||
if (child_pid == 0) {
|
||||
/* child process */
|
||||
close(s_wld);
|
||||
closelog();
|
||||
openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
|
||||
play_child(s_src, (struct sockaddr *)&srcaddr);
|
||||
exit_failure("should never reach here");
|
||||
/*NOTREACHED*/
|
||||
} else {
|
||||
/* parent process */
|
||||
close(s_src);
|
||||
if (child_pid == -1)
|
||||
syslog(LOG_ERR, "can't fork");
|
||||
}
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
|
||||
static void
|
||||
play_child(int s_src, struct sockaddr *srcaddr)
|
||||
{
|
||||
struct sockaddr_storage dstaddr6;
|
||||
struct sockaddr_storage dstaddr4;
|
||||
char src[NI_MAXHOST];
|
||||
char dst6[NI_MAXHOST];
|
||||
char dst4[NI_MAXHOST];
|
||||
socklen_t len = sizeof(dstaddr6);
|
||||
int s_dst, error, hport, nresvport, on = 1;
|
||||
struct timeval tv;
|
||||
struct sockaddr *sa4;
|
||||
const struct config *conf;
|
||||
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
getnameinfo(srcaddr, srcaddr->sa_len,
|
||||
src, sizeof(src), NULL, 0, NI_NUMERICHOST);
|
||||
syslog(LOG_INFO, "accepted a client from %s", src);
|
||||
|
||||
error = getsockname(s_src, (struct sockaddr *)&dstaddr6, &len);
|
||||
if (error == -1) {
|
||||
exit_failure("getsockname: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
getnameinfo((struct sockaddr *)&dstaddr6, len,
|
||||
dst6, sizeof(dst6), NULL, 0, NI_NUMERICHOST);
|
||||
syslog(LOG_INFO, "the client is connecting to %s", dst6);
|
||||
|
||||
if (!faith_prefix((struct sockaddr *)&dstaddr6)) {
|
||||
if (serverpath) {
|
||||
/*
|
||||
* Local service
|
||||
*/
|
||||
syslog(LOG_INFO, "executing local %s", serverpath);
|
||||
if (!inetd) {
|
||||
dup2(s_src, 0);
|
||||
close(s_src);
|
||||
dup2(0, 1);
|
||||
dup2(0, 2);
|
||||
}
|
||||
execv(serverpath, serverarg);
|
||||
syslog(LOG_ERR, "execv %s: %s", serverpath,
|
||||
strerror(errno));
|
||||
_exit(EXIT_FAILURE);
|
||||
} else {
|
||||
close(s_src);
|
||||
exit_success("no local service for %s", service);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Act as a translator
|
||||
*/
|
||||
|
||||
switch (((struct sockaddr *)&dstaddr6)->sa_family) {
|
||||
case AF_INET6:
|
||||
if (!map6to4((struct sockaddr_in6 *)&dstaddr6,
|
||||
(struct sockaddr_in *)&dstaddr4)) {
|
||||
close(s_src);
|
||||
exit_failure("map6to4 failed");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
syslog(LOG_INFO, "translating from v6 to v4");
|
||||
break;
|
||||
default:
|
||||
close(s_src);
|
||||
exit_failure("family not supported");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
sa4 = (struct sockaddr *)&dstaddr4;
|
||||
getnameinfo(sa4, sa4->sa_len,
|
||||
dst4, sizeof(dst4), NULL, 0, NI_NUMERICHOST);
|
||||
|
||||
conf = config_match(srcaddr, sa4);
|
||||
if (!conf || !conf->permit) {
|
||||
close(s_src);
|
||||
if (conf) {
|
||||
exit_failure("translation to %s not permitted for %s",
|
||||
dst4, prefix_string(&conf->match));
|
||||
/*NOTREACHED*/
|
||||
} else {
|
||||
exit_failure("translation to %s not permitted", dst4);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "the translator is connecting to %s", dst4);
|
||||
|
||||
setproctitle("port %s, %s -> %s", service, src, dst4);
|
||||
|
||||
if (sa4->sa_family == AF_INET6)
|
||||
hport = ntohs(((struct sockaddr_in6 *)&dstaddr4)->sin6_port);
|
||||
else /* AF_INET */
|
||||
hport = ntohs(((struct sockaddr_in *)&dstaddr4)->sin_port);
|
||||
|
||||
if (pflag)
|
||||
s_dst = rresvport_af(&nresvport, sa4->sa_family);
|
||||
else
|
||||
s_dst = socket(sa4->sa_family, SOCK_STREAM, 0);
|
||||
if (s_dst < 0) {
|
||||
exit_failure("socket: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (conf->src.a.ss_family) {
|
||||
if (bind(s_dst, (const struct sockaddr *)&conf->src.a,
|
||||
conf->src.a.ss_len) < 0) {
|
||||
exit_failure("bind: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
error = setsockopt(s_dst, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));
|
||||
if (error < 0) {
|
||||
exit_failure("setsockopt(SO_OOBINLINE): %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
error = setsockopt(s_src, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
if (error < 0) {
|
||||
exit_failure("setsockopt(SO_SNDTIMEO): %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
error = setsockopt(s_dst, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
if (error < 0) {
|
||||
exit_failure("setsockopt(SO_SNDTIMEO): %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
error = connect(s_dst, sa4, sa4->sa_len);
|
||||
if (error < 0) {
|
||||
exit_failure("connect: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
switch (hport) {
|
||||
case FTP_PORT:
|
||||
ftp_relay(s_src, s_dst);
|
||||
break;
|
||||
default:
|
||||
tcp_relay(s_src, s_dst, service);
|
||||
break;
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* 0: non faith, 1: faith */
|
||||
static int
|
||||
faith_prefix(struct sockaddr *dst)
|
||||
{
|
||||
#ifndef USE_ROUTE
|
||||
int mib[4], size;
|
||||
struct in6_addr faith_prefix;
|
||||
struct sockaddr_in6 *dst6 = (struct sockaddr_in *)dst;
|
||||
|
||||
if (dst->sa_family != AF_INET6)
|
||||
return 0;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_INET6;
|
||||
mib[2] = IPPROTO_IPV6;
|
||||
mib[3] = IPV6CTL_FAITH_PREFIX;
|
||||
size = sizeof(struct in6_addr);
|
||||
if (sysctl(mib, 4, &faith_prefix, &size, NULL, 0) < 0) {
|
||||
exit_failure("sysctl: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (memcmp(dst, &faith_prefix,
|
||||
sizeof(struct in6_addr) - sizeof(struct in_addr) == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
struct myaddrs *p;
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sockaddr_in *sin4;
|
||||
struct sockaddr_in6 *dst6;
|
||||
struct sockaddr_in *dst4;
|
||||
struct sockaddr_in dstmap;
|
||||
|
||||
dst6 = (struct sockaddr_in6 *)dst;
|
||||
if (dst->sa_family == AF_INET6
|
||||
&& IN6_IS_ADDR_V4MAPPED(&dst6->sin6_addr)) {
|
||||
/* ugly... */
|
||||
memset(&dstmap, 0, sizeof(dstmap));
|
||||
dstmap.sin_family = AF_INET;
|
||||
dstmap.sin_len = sizeof(dstmap);
|
||||
memcpy(&dstmap.sin_addr, &dst6->sin6_addr.s6_addr[12],
|
||||
sizeof(dstmap.sin_addr));
|
||||
dst = (struct sockaddr *)&dstmap;
|
||||
}
|
||||
|
||||
dst6 = (struct sockaddr_in6 *)dst;
|
||||
dst4 = (struct sockaddr_in *)dst;
|
||||
|
||||
for (p = myaddrs; p; p = p->next) {
|
||||
sin6 = (struct sockaddr_in6 *)p->addr;
|
||||
sin4 = (struct sockaddr_in *)p->addr;
|
||||
|
||||
if (p->addr->sa_len != dst->sa_len
|
||||
|| p->addr->sa_family != dst->sa_family)
|
||||
continue;
|
||||
|
||||
switch (dst->sa_family) {
|
||||
case AF_INET6:
|
||||
if (sin6->sin6_scope_id == dst6->sin6_scope_id
|
||||
&& IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &dst6->sin6_addr))
|
||||
return 0;
|
||||
break;
|
||||
case AF_INET:
|
||||
if (sin4->sin_addr.s_addr == dst4->sin_addr.s_addr)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 0: non faith, 1: faith */
|
||||
static int
|
||||
map6to4(struct sockaddr_in6 *dst6, struct sockaddr_in *dst4)
|
||||
{
|
||||
memset(dst4, 0, sizeof(*dst4));
|
||||
dst4->sin_len = sizeof(*dst4);
|
||||
dst4->sin_family = AF_INET;
|
||||
dst4->sin_port = dst6->sin6_port;
|
||||
memcpy(&dst4->sin_addr, &dst6->sin6_addr.s6_addr[12],
|
||||
sizeof(dst4->sin_addr));
|
||||
|
||||
if (dst4->sin_addr.s_addr == INADDR_ANY
|
||||
|| dst4->sin_addr.s_addr == INADDR_BROADCAST
|
||||
|| IN_MULTICAST(ntohl(dst4->sin_addr.s_addr)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sig_child(int sig __unused)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0)
|
||||
if (WEXITSTATUS(status))
|
||||
syslog(LOG_WARNING, "child %ld exit status 0x%x",
|
||||
(long)pid, status);
|
||||
}
|
||||
|
||||
void
|
||||
sig_terminate(int sig __unused)
|
||||
{
|
||||
syslog(LOG_INFO, "Terminating faith daemon");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
start_daemon(void)
|
||||
{
|
||||
#ifdef SA_NOCLDWAIT
|
||||
struct sigaction sa;
|
||||
#endif
|
||||
|
||||
if (daemon(0, 0) == -1)
|
||||
exit_stderr("daemon: %s", strerror(errno));
|
||||
|
||||
#ifdef SA_NOCLDWAIT
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = sig_child;
|
||||
sa.sa_flags = SA_NOCLDWAIT;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaction(SIGCHLD, &sa, (struct sigaction *)0);
|
||||
#else
|
||||
if (signal(SIGCHLD, sig_child) == SIG_ERR) {
|
||||
exit_failure("signal CHLD: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
|
||||
if (signal(SIGTERM, sig_terminate) == SIG_ERR) {
|
||||
exit_failure("signal TERM: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
exit_stderr(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void
|
||||
exit_failure(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
syslog(LOG_ERR, "%s", buf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void
|
||||
exit_success(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
syslog(LOG_INFO, "%s", buf);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef USE_ROUTE
|
||||
static void
|
||||
grab_myaddrs(void)
|
||||
{
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct myaddrs *p;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
if (getifaddrs(&ifap) != 0) {
|
||||
exit_failure("getifaddrs");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
switch (ifa->ifa_addr->sa_family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
p = (struct myaddrs *)malloc(sizeof(struct myaddrs) +
|
||||
ifa->ifa_addr->sa_len);
|
||||
if (!p) {
|
||||
exit_failure("not enough core");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
memcpy(p + 1, ifa->ifa_addr, ifa->ifa_addr->sa_len);
|
||||
p->next = myaddrs;
|
||||
p->addr = (struct sockaddr *)(p + 1);
|
||||
#ifdef __KAME__
|
||||
if (ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
sin6 = (struct sockaddr_in6 *)p->addr;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)
|
||||
|| IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
|
||||
sin6->sin6_scope_id =
|
||||
ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
|
||||
sin6->sin6_addr.s6_addr[2] = 0;
|
||||
sin6->sin6_addr.s6_addr[3] = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
myaddrs = p;
|
||||
if (dflag) {
|
||||
char hbuf[NI_MAXHOST];
|
||||
getnameinfo(p->addr, p->addr->sa_len,
|
||||
hbuf, sizeof(hbuf), NULL, 0,
|
||||
NI_NUMERICHOST);
|
||||
syslog(LOG_INFO, "my interface: %s %s", hbuf,
|
||||
ifa->ifa_name);
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(ifap);
|
||||
}
|
||||
|
||||
static void
|
||||
free_myaddrs(void)
|
||||
{
|
||||
struct myaddrs *p, *q;
|
||||
|
||||
p = myaddrs;
|
||||
while (p) {
|
||||
q = p->next;
|
||||
free(p);
|
||||
p = q;
|
||||
}
|
||||
myaddrs = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
update_myaddrs(void)
|
||||
{
|
||||
char msg[BUFSIZ];
|
||||
int len;
|
||||
struct rt_msghdr *rtm;
|
||||
|
||||
len = read(sockfd, msg, sizeof(msg));
|
||||
if (len < 0) {
|
||||
syslog(LOG_ERR, "read(PF_ROUTE) failed");
|
||||
return;
|
||||
}
|
||||
rtm = (struct rt_msghdr *)msg;
|
||||
if (len < 4 || len < rtm->rtm_msglen) {
|
||||
syslog(LOG_ERR, "read(PF_ROUTE) short read");
|
||||
return;
|
||||
}
|
||||
if (rtm->rtm_version != RTM_VERSION) {
|
||||
syslog(LOG_ERR, "routing socket version mismatch");
|
||||
close(sockfd);
|
||||
sockfd = 0;
|
||||
return;
|
||||
}
|
||||
switch (rtm->rtm_type) {
|
||||
case RTM_NEWADDR:
|
||||
case RTM_DELADDR:
|
||||
case RTM_IFINFO:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
/* XXX more filters here? */
|
||||
|
||||
syslog(LOG_INFO, "update interface address list");
|
||||
free_myaddrs();
|
||||
grab_myaddrs();
|
||||
}
|
||||
#endif /*USE_ROUTE*/
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-dp] [-f conf] service [serverpath [serverargs]]\n",
|
||||
faithdname);
|
||||
exit(0);
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/* $KAME: faithd.h,v 1.9 2002/05/09 09:41:24 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
extern char logname[];
|
||||
extern int dflag;
|
||||
|
||||
extern void tcp_relay(int, int, const char *);
|
||||
extern void ftp_relay(int, int);
|
||||
extern int ftp_active(int, int, int *, int *);
|
||||
extern int ftp_passive(int, int, int *, int *);
|
||||
extern void exit_success(const char *, ...)
|
||||
__attribute__((__format__(__printf__, 1, 2)));
|
||||
extern void exit_failure(const char *, ...)
|
||||
__attribute__((__format__(__printf__, 1, 2)));
|
||||
|
||||
#define DEFAULT_PORT_NAME "telnet"
|
||||
#define DEFAULT_DIR "/usr/libexec"
|
||||
#define DEFAULT_NAME "telnetd"
|
||||
#define DEFAULT_PATH (DEFAULT_DIR "/" DEFAULT_NAME)
|
||||
|
||||
#define FTP_PORT 21
|
||||
#define RLOGIN_PORT 513
|
||||
#define RSH_PORT 514
|
||||
|
||||
#define RETURN_SUCCESS 0
|
||||
#define RETURN_FAILURE 1
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
#define MSS 2048
|
||||
#define MAXARGV 20
|
||||
|
||||
#define NUMPRT 0
|
||||
#define NUMPRG 1
|
||||
#define NUMARG 2
|
||||
|
||||
#define UC(b) (((int)b)&0xff)
|
||||
|
||||
#define FAITH_TIMEOUT (30 * 60) /*second*/
|
File diff suppressed because it is too large
Load Diff
@ -1,345 +0,0 @@
|
||||
/* $KAME: prefix.c,v 1.13 2003/09/02 22:50:17 itojun Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) ((size_t)(u_long)(&((type *)0)->member))
|
||||
#endif
|
||||
|
||||
#include "faithd.h"
|
||||
#include "prefix.h"
|
||||
|
||||
static int prefix_set(const char *, struct prefix *, int);
|
||||
static struct config *config_load1(const char *);
|
||||
#if 0
|
||||
static void config_show1(const struct config *);
|
||||
static void config_show(void);
|
||||
#endif
|
||||
|
||||
struct config *config_list = NULL;
|
||||
const int niflags = NI_NUMERICHOST;
|
||||
|
||||
static int
|
||||
prefix_set(const char *s, struct prefix *prefix, int slash)
|
||||
{
|
||||
char *p = NULL, *q, *r;
|
||||
struct addrinfo hints, *res = NULL;
|
||||
int max;
|
||||
|
||||
p = strdup(s);
|
||||
if (!p)
|
||||
goto fail;
|
||||
q = strchr(p, '/');
|
||||
if (q) {
|
||||
if (!slash)
|
||||
goto fail;
|
||||
*q++ = '\0';
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
if (getaddrinfo(p, "0", &hints, &res))
|
||||
goto fail;
|
||||
if (res->ai_next || res->ai_addrlen > sizeof(prefix->a))
|
||||
goto fail;
|
||||
memcpy(&prefix->a, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
switch (prefix->a.ss_family) {
|
||||
case AF_INET:
|
||||
max = 32;
|
||||
break;
|
||||
case AF_INET6:
|
||||
max = 128;
|
||||
break;
|
||||
default:
|
||||
max = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (q) {
|
||||
r = NULL;
|
||||
prefix->l = (int)strtoul(q, &r, 10);
|
||||
if (!*q || *r)
|
||||
goto fail;
|
||||
if (prefix->l < 0 || prefix->l > max)
|
||||
goto fail;
|
||||
} else
|
||||
prefix->l = max;
|
||||
|
||||
if (p)
|
||||
free(p);
|
||||
if (res)
|
||||
freeaddrinfo(res);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (p)
|
||||
free(p);
|
||||
if (res)
|
||||
freeaddrinfo(res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *
|
||||
prefix_string(const struct prefix *prefix)
|
||||
{
|
||||
static char buf[NI_MAXHOST + 20];
|
||||
char hbuf[NI_MAXHOST];
|
||||
|
||||
if (getnameinfo((const struct sockaddr *)&prefix->a, prefix->a.ss_len,
|
||||
hbuf, sizeof(hbuf), NULL, 0, niflags))
|
||||
return NULL;
|
||||
snprintf(buf, sizeof(buf), "%s/%d", hbuf, prefix->l);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
prefix_match(const struct prefix *prefix, const struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_storage a, b;
|
||||
char *pa, *pb;
|
||||
int off, l;
|
||||
|
||||
if (prefix->a.ss_family != sa->sa_family ||
|
||||
prefix->a.ss_len != sa->sa_len)
|
||||
return 0;
|
||||
|
||||
if (prefix->a.ss_len > sizeof(a) || sa->sa_len > sizeof(b))
|
||||
return 0;
|
||||
|
||||
switch (prefix->a.ss_family) {
|
||||
case AF_INET:
|
||||
off = offsetof(struct sockaddr_in, sin_addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
off = offsetof(struct sockaddr_in6, sin6_addr);
|
||||
break;
|
||||
default:
|
||||
if (memcmp(&prefix->a, sa, prefix->a.ss_len) != 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(&a, &prefix->a, prefix->a.ss_len);
|
||||
memcpy(&b, sa, sa->sa_len);
|
||||
l = prefix->l / 8 + (prefix->l % 8 ? 1 : 0);
|
||||
|
||||
/* overrun check */
|
||||
if (off + l > a.ss_len)
|
||||
return 0;
|
||||
|
||||
pa = ((char *)&a) + off;
|
||||
pb = ((char *)&b) + off;
|
||||
if (prefix->l % 8) {
|
||||
pa[prefix->l / 8] &= 0xff00 >> (prefix->l % 8);
|
||||
pb[prefix->l / 8] &= 0xff00 >> (prefix->l % 8);
|
||||
}
|
||||
if (memcmp(pa, pb, l) != 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* prefix/prefixlen permit/deny prefix/prefixlen [srcaddr]
|
||||
* 3ffe::/16 permit 10.0.0.0/8 10.1.1.1
|
||||
*/
|
||||
static struct config *
|
||||
config_load1(const char *line)
|
||||
{
|
||||
struct config *conf;
|
||||
char buf[BUFSIZ];
|
||||
char *p;
|
||||
char *token[4];
|
||||
int i;
|
||||
|
||||
if (strlen(line) + 1 > sizeof(buf))
|
||||
return NULL;
|
||||
strlcpy(buf, line, sizeof(buf));
|
||||
|
||||
p = strchr(buf, '\n');
|
||||
if (!p)
|
||||
return NULL;
|
||||
*p = '\0';
|
||||
p = strchr(buf, '#');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
if (strlen(buf) == 0)
|
||||
return NULL;
|
||||
|
||||
p = buf;
|
||||
memset(token, 0, sizeof(token));
|
||||
for (i = 0; i < sizeof(token) / sizeof(token[0]); i++) {
|
||||
token[i] = strtok(p, "\t ");
|
||||
p = NULL;
|
||||
if (token[i] == NULL)
|
||||
break;
|
||||
}
|
||||
/* extra tokens? */
|
||||
if (strtok(p, "\t ") != NULL)
|
||||
return NULL;
|
||||
/* insufficient tokens */
|
||||
switch (i) {
|
||||
case 3:
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conf = (struct config *)malloc(sizeof(*conf));
|
||||
if (conf == NULL)
|
||||
return NULL;
|
||||
memset(conf, 0, sizeof(*conf));
|
||||
|
||||
if (strcasecmp(token[1], "permit") == 0)
|
||||
conf->permit = 1;
|
||||
else if (strcasecmp(token[1], "deny") == 0)
|
||||
conf->permit = 0;
|
||||
else {
|
||||
/* invalid keyword is considered as "deny" */
|
||||
conf->permit = 0;
|
||||
}
|
||||
|
||||
if (prefix_set(token[0], &conf->match, 1) < 0)
|
||||
goto fail;
|
||||
if (prefix_set(token[2], &conf->dest, 1) < 0)
|
||||
goto fail;
|
||||
if (token[3]) {
|
||||
if (prefix_set(token[3], &conf->src, 0) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return conf;
|
||||
|
||||
fail:
|
||||
free(conf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
config_load(const char *configfile)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[BUFSIZ];
|
||||
struct config *conf, *p;
|
||||
struct config sentinel;
|
||||
|
||||
config_list = NULL;
|
||||
|
||||
if (!configfile)
|
||||
configfile = _PATH_PREFIX_CONF;
|
||||
fp = fopen(configfile, "r");
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
|
||||
p = &sentinel;
|
||||
sentinel.next = NULL;
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
conf = config_load1(buf);
|
||||
if (conf) {
|
||||
p->next = conf;
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
config_list = sentinel.next;
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
config_show1(const struct config *conf)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = prefix_string(&conf->match);
|
||||
printf("%s", p ? p : "?");
|
||||
|
||||
if (conf->permit)
|
||||
printf(" permit");
|
||||
else
|
||||
printf(" deny");
|
||||
|
||||
p = prefix_string(&conf->dest);
|
||||
printf(" %s", p ? p : "?");
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
config_show()
|
||||
{
|
||||
struct config *conf;
|
||||
|
||||
for (conf = config_list; conf; conf = conf->next)
|
||||
config_show1(conf);
|
||||
}
|
||||
#endif
|
||||
|
||||
const struct config *
|
||||
config_match(struct sockaddr *sa1, struct sockaddr *sa2)
|
||||
{
|
||||
static struct config conf;
|
||||
const struct config *p;
|
||||
|
||||
if (sa1->sa_len > sizeof(conf.match.a) ||
|
||||
sa2->sa_len > sizeof(conf.dest.a))
|
||||
return NULL;
|
||||
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
if (!config_list) {
|
||||
conf.permit = 1;
|
||||
memcpy(&conf.match.a, sa1, sa1->sa_len);
|
||||
memcpy(&conf.dest.a, sa2, sa2->sa_len);
|
||||
return &conf;
|
||||
}
|
||||
|
||||
for (p = config_list; p; p = p->next)
|
||||
if (prefix_match(&p->match, sa1) && prefix_match(&p->dest, sa2))
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/* $KAME: prefix.h,v 1.4 2001/09/05 03:04:21 itojun Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
struct prefix {
|
||||
struct sockaddr_storage a;
|
||||
int l;
|
||||
};
|
||||
|
||||
struct config {
|
||||
struct config *next;
|
||||
|
||||
int permit;
|
||||
struct prefix match;
|
||||
struct prefix dest;
|
||||
struct prefix src; /* src to use for outgoing connection */
|
||||
};
|
||||
|
||||
#define _PATH_PREFIX_CONF "/etc/faithd.conf"
|
||||
|
||||
extern const char *prefix_string(const struct prefix *);
|
||||
extern int prefix_match(const struct prefix *, const struct sockaddr *);
|
||||
extern int config_load(const char *);
|
||||
extern const struct config *config_match(struct sockaddr *, struct sockaddr *);
|
@ -1,324 +0,0 @@
|
||||
/* $KAME: tcp.c,v 1.13 2003/09/02 22:49:21 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "faithd.h"
|
||||
|
||||
static char tcpbuf[16*1024];
|
||||
/* bigger than MSS and may be lesser than window size */
|
||||
static int tblen, tboff, oob_exists;
|
||||
static fd_set readfds, writefds, exceptfds;
|
||||
static char atmark_buf[2];
|
||||
static pid_t cpid = (pid_t)0;
|
||||
static pid_t ppid = (pid_t)0;
|
||||
volatile time_t child_lastactive = (time_t)0;
|
||||
static time_t parent_lastactive = (time_t)0;
|
||||
|
||||
static void sig_ctimeout(int);
|
||||
static void sig_child(int);
|
||||
static void notify_inactive(void);
|
||||
static void notify_active(void);
|
||||
static void send_data(int, int, const char *, int);
|
||||
static void relay(int, int, const char *, int);
|
||||
|
||||
/*
|
||||
* Inactivity timer:
|
||||
* - child side (ppid != 0) will send SIGUSR1 to parent every (FAITH_TIMEOUT/4)
|
||||
* second if traffic is active. if traffic is inactive, don't send SIGUSR1.
|
||||
* - parent side (ppid == 0) will check the last SIGUSR1 it have seen.
|
||||
*/
|
||||
static void
|
||||
sig_ctimeout(int sig __unused)
|
||||
{
|
||||
/* parent side: record notification from the child */
|
||||
if (dflag)
|
||||
syslog(LOG_DEBUG, "activity timer from child");
|
||||
child_lastactive = time(NULL);
|
||||
}
|
||||
|
||||
/* parent will terminate if child dies. */
|
||||
static void
|
||||
sig_child(int sig __unused)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
pid = wait3(&status, WNOHANG, (struct rusage *)0);
|
||||
if (pid > 0 && WEXITSTATUS(status))
|
||||
syslog(LOG_WARNING, "child %ld exit status 0x%x",
|
||||
(long)pid, status);
|
||||
exit_success("terminate connection due to child termination");
|
||||
}
|
||||
|
||||
static void
|
||||
notify_inactive()
|
||||
{
|
||||
time_t t;
|
||||
|
||||
/* only on parent side... */
|
||||
if (ppid)
|
||||
return;
|
||||
|
||||
/* parent side should check for timeout. */
|
||||
t = time(NULL);
|
||||
if (dflag) {
|
||||
syslog(LOG_DEBUG, "parent side %sactive, child side %sactive",
|
||||
(FAITH_TIMEOUT < t - parent_lastactive) ? "in" : "",
|
||||
(FAITH_TIMEOUT < t - child_lastactive) ? "in" : "");
|
||||
}
|
||||
|
||||
if (FAITH_TIMEOUT < t - child_lastactive
|
||||
&& FAITH_TIMEOUT < t - parent_lastactive) {
|
||||
/* both side timeouted */
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
kill(cpid, SIGTERM);
|
||||
wait(NULL);
|
||||
exit_failure("connection timeout");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
notify_active()
|
||||
{
|
||||
if (ppid) {
|
||||
/* child side: notify parent of active traffic */
|
||||
time_t t;
|
||||
t = time(NULL);
|
||||
if (FAITH_TIMEOUT / 4 < t - child_lastactive) {
|
||||
if (kill(ppid, SIGUSR1) < 0) {
|
||||
exit_failure("terminate connection due to parent termination");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
child_lastactive = t;
|
||||
}
|
||||
} else {
|
||||
/* parent side */
|
||||
parent_lastactive = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
send_data(int s_rcv, int s_snd, const char *service __unused, int direction)
|
||||
{
|
||||
int cc;
|
||||
|
||||
if (oob_exists) {
|
||||
cc = send(s_snd, atmark_buf, 1, MSG_OOB);
|
||||
if (cc == -1)
|
||||
goto retry_or_err;
|
||||
oob_exists = 0;
|
||||
if (s_rcv >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_SET(s_rcv, &exceptfds);
|
||||
}
|
||||
|
||||
for (; tboff < tblen; tboff += cc) {
|
||||
cc = write(s_snd, tcpbuf + tboff, tblen - tboff);
|
||||
if (cc < 0)
|
||||
goto retry_or_err;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (tblen) {
|
||||
if (tblen >= sizeof(tcpbuf))
|
||||
tblen = sizeof(tcpbuf) - 1;
|
||||
tcpbuf[tblen] = '\0';
|
||||
syslog(LOG_DEBUG, "from %s (%dbytes): %s",
|
||||
direction == 1 ? "client" : "server", tblen, tcpbuf);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
tblen = 0; tboff = 0;
|
||||
if (s_snd >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_CLR(s_snd, &writefds);
|
||||
if (s_rcv >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_SET(s_rcv, &readfds);
|
||||
return;
|
||||
retry_or_err:
|
||||
if (errno != EAGAIN)
|
||||
exit_failure("writing relay data failed: %s", strerror(errno));
|
||||
if (s_snd >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_SET(s_snd, &writefds);
|
||||
}
|
||||
|
||||
static void
|
||||
relay(int s_rcv, int s_snd, const char *service, int direction)
|
||||
{
|
||||
int atmark, error, maxfd;
|
||||
struct timeval tv;
|
||||
fd_set oreadfds, owritefds, oexceptfds;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
FD_ZERO(&exceptfds);
|
||||
fcntl(s_snd, F_SETFD, O_NONBLOCK);
|
||||
oreadfds = readfds; owritefds = writefds; oexceptfds = exceptfds;
|
||||
if (s_rcv >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_SET(s_rcv, &readfds);
|
||||
FD_SET(s_rcv, &exceptfds);
|
||||
oob_exists = 0;
|
||||
maxfd = (s_rcv > s_snd) ? s_rcv : s_snd;
|
||||
|
||||
for (;;) {
|
||||
tv.tv_sec = FAITH_TIMEOUT / 4;
|
||||
tv.tv_usec = 0;
|
||||
oreadfds = readfds;
|
||||
owritefds = writefds;
|
||||
oexceptfds = exceptfds;
|
||||
error = select(maxfd + 1, &readfds, &writefds, &exceptfds, &tv);
|
||||
if (error == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
exit_failure("select: %s", strerror(errno));
|
||||
} else if (error == 0) {
|
||||
readfds = oreadfds;
|
||||
writefds = owritefds;
|
||||
exceptfds = oexceptfds;
|
||||
notify_inactive();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* activity notification */
|
||||
notify_active();
|
||||
|
||||
if (FD_ISSET(s_rcv, &exceptfds)) {
|
||||
error = ioctl(s_rcv, SIOCATMARK, &atmark);
|
||||
if (error != -1 && atmark == 1) {
|
||||
int cc;
|
||||
oob_read_retry:
|
||||
cc = read(s_rcv, atmark_buf, 1);
|
||||
if (cc == 1) {
|
||||
if (s_rcv >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_CLR(s_rcv, &exceptfds);
|
||||
if (s_snd >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_SET(s_snd, &writefds);
|
||||
oob_exists = 1;
|
||||
} else if (cc == -1) {
|
||||
if (errno == EINTR)
|
||||
goto oob_read_retry;
|
||||
exit_failure("reading oob data failed"
|
||||
": %s",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FD_ISSET(s_rcv, &readfds)) {
|
||||
relaydata_read_retry:
|
||||
tblen = read(s_rcv, tcpbuf, sizeof(tcpbuf));
|
||||
tboff = 0;
|
||||
|
||||
switch (tblen) {
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
goto relaydata_read_retry;
|
||||
exit_failure("reading relay data failed: %s",
|
||||
strerror(errno));
|
||||
/* NOTREACHED */
|
||||
case 0:
|
||||
/* to close opposite-direction relay process */
|
||||
shutdown(s_snd, 0);
|
||||
|
||||
close(s_rcv);
|
||||
close(s_snd);
|
||||
exit_success("terminating %s relay", service);
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
if (s_rcv >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_CLR(s_rcv, &readfds);
|
||||
if (s_snd >= FD_SETSIZE)
|
||||
exit_failure("descriptor too big");
|
||||
FD_SET(s_snd, &writefds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (FD_ISSET(s_snd, &writefds))
|
||||
send_data(s_rcv, s_snd, service, direction);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tcp_relay(int s_src, int s_dst, const char *service)
|
||||
{
|
||||
syslog(LOG_INFO, "starting %s relay", service);
|
||||
|
||||
child_lastactive = parent_lastactive = time(NULL);
|
||||
|
||||
cpid = fork();
|
||||
switch (cpid) {
|
||||
case -1:
|
||||
exit_failure("tcp_relay: can't fork grand child: %s",
|
||||
strerror(errno));
|
||||
/* NOTREACHED */
|
||||
case 0:
|
||||
/* child process: relay going traffic */
|
||||
ppid = getppid();
|
||||
/* this is child so reopen log */
|
||||
closelog();
|
||||
openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
|
||||
relay(s_src, s_dst, service, 1);
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
/* parent process: relay coming traffic */
|
||||
ppid = (pid_t)0;
|
||||
signal(SIGUSR1, sig_ctimeout);
|
||||
signal(SIGCHLD, sig_child);
|
||||
relay(s_dst, s_src, service, 0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
@ -1,312 +0,0 @@
|
||||
# faithd, ruby version. requires v6-enabled ruby.
|
||||
#
|
||||
# highly experimental (not working right at all) and very limited
|
||||
# functionality.
|
||||
#
|
||||
# $Id: faithd.rb,v 1.1.2.4 1999/05/10 17:06:30 itojun Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
require "socket"
|
||||
require "thread"
|
||||
|
||||
# XXX should be derived from system headers
|
||||
IPPROTO_IPV6 = 41
|
||||
IPV6_FAITH = 29
|
||||
DEBUG = true
|
||||
DEBUG_LOOPBACK = true
|
||||
|
||||
# TODO: OOB data handling
|
||||
def tcpcopy(s1, s2, m)
|
||||
STDERR.print "tcpcopy #{s1} #{s2}\n" if DEBUG
|
||||
buf = ""
|
||||
while TRUE
|
||||
begin
|
||||
buf = s1.sysread(100)
|
||||
s2.syswrite(buf)
|
||||
rescue EOFError
|
||||
break
|
||||
rescue IOError
|
||||
break
|
||||
end
|
||||
end
|
||||
STDERR.print "tcpcopy #{s1} #{s2} finished\n" if DEBUG
|
||||
s1.shutdown(0)
|
||||
s2.shutdown(1)
|
||||
end
|
||||
|
||||
def relay_ftp_passiveconn(s6, s4, dport6, dport4)
|
||||
Thread.start do
|
||||
d6 = TCPserver.open("::", dport6).accept
|
||||
d4 = TCPsocket.open(s4.getpeer[3], dport4)
|
||||
t = []
|
||||
t[0] = Thread.start do
|
||||
tcpcopy(d6, d4)
|
||||
end
|
||||
t[1] = Thread.start do
|
||||
tcpcopy(d4, d6)
|
||||
end
|
||||
for i in t
|
||||
i.join
|
||||
end
|
||||
d4.close
|
||||
d6.close
|
||||
end
|
||||
end
|
||||
|
||||
def ftp_parse_2428(line)
|
||||
if (line[0] != line[line.length - 1])
|
||||
return nil
|
||||
end
|
||||
t = line.split(line[0 .. 0]) # as string
|
||||
if (t.size != 4 || t[1] !~ /^[12]$/ || t[3] !~ /^\d+$/)
|
||||
return nil
|
||||
end
|
||||
return t[1 .. 3]
|
||||
end
|
||||
|
||||
def relay_ftp_command(s6, s4, state)
|
||||
STDERR.print "relay_ftp_command start\n" if DEBUG
|
||||
while TRUE
|
||||
begin
|
||||
STDERR.print "s6.gets\n" if DEBUG
|
||||
line = s6.gets
|
||||
STDERR.print "line is #{line}\n" if DEBUG
|
||||
if line == nil
|
||||
return nil
|
||||
end
|
||||
|
||||
# translate then copy
|
||||
STDERR.print "line is #{line}\n" if DEBUG
|
||||
if (line =~ /^EPSV\r\n/i)
|
||||
STDERR.print "EPSV -> PASV\n" if DEBUG
|
||||
line = "PASV\n"
|
||||
state = "EPSV"
|
||||
elsif (line =~ /^EPRT\s+(.+)\r\n/i)
|
||||
t = ftp_parse_2428($1)
|
||||
if t == nil
|
||||
s6.puts "501 illegal parameter to EPRT\r\n"
|
||||
next
|
||||
end
|
||||
|
||||
# some tricks should be here
|
||||
s6.puts "501 illegal parameter to EPRT\r\n"
|
||||
next
|
||||
end
|
||||
STDERR.print "fail: send #{line} as is\n" if DEBUG
|
||||
s4.puts(line)
|
||||
break
|
||||
rescue EOFError
|
||||
return nil
|
||||
rescue IOError
|
||||
return nil
|
||||
end
|
||||
end
|
||||
STDERR.print "relay_ftp_command finish\n" if DEBUG
|
||||
return state
|
||||
end
|
||||
|
||||
def relay_ftp_status(s4, s6, state)
|
||||
STDERR.print "relay_ftp_status start\n" if DEBUG
|
||||
while TRUE
|
||||
begin
|
||||
line = s4.gets
|
||||
if line == nil
|
||||
return nil
|
||||
end
|
||||
|
||||
# translate then copy
|
||||
s6.puts(line)
|
||||
|
||||
next if line =~ /^\d\d\d-/
|
||||
next if line !~ /^\d/
|
||||
|
||||
# special post-processing
|
||||
case line
|
||||
when /^221 / # result to QUIT
|
||||
s4.shutdown(0)
|
||||
s6.shutdown(1)
|
||||
end
|
||||
|
||||
break if (line =~ /^\d\d\d /)
|
||||
rescue EOFError
|
||||
return nil
|
||||
rescue IOError
|
||||
return nil
|
||||
end
|
||||
end
|
||||
STDERR.print "relay_ftp_status finish\n" if DEBUG
|
||||
return state
|
||||
end
|
||||
|
||||
def relay_ftp(sock, name)
|
||||
STDERR.print "relay_ftp(#{sock}, #{name})\n" if DEBUG
|
||||
while TRUE
|
||||
STDERR.print "relay_ftp(#{sock}, #{name}) accepting\n" if DEBUG
|
||||
s = sock.accept
|
||||
STDERR.print "relay_ftp(#{sock}, #{name}) accepted #{s}\n" if DEBUG
|
||||
Thread.start do
|
||||
threads = []
|
||||
STDERR.print "accepted #{s} -> #{Thread.current}\n" if DEBUG
|
||||
s6 = s
|
||||
dest6 = s.addr[3]
|
||||
if !DEBUG_LOOPBACK
|
||||
t = s.getsockname.unpack("x8 x12 C4")
|
||||
dest4 = "#{t[0]}.#{t[1]}.#{t[2]}.#{t[3]}"
|
||||
port4 = s.addr[1]
|
||||
else
|
||||
dest4 = "127.0.0.1"
|
||||
port4 = "ftp"
|
||||
end
|
||||
if DEBUG
|
||||
STDERR.print "IPv6 dest: #{dest6} IPv4 dest: #{dest4}\n" if DEBUG
|
||||
end
|
||||
STDERR.print "connect to #{dest4} #{port4}\n" if DEBUG
|
||||
s4 = TCPsocket.open(dest4, port4)
|
||||
STDERR.print "connected to #{dest4} #{port4}, #{s4.addr[1]}\n" if DEBUG
|
||||
state = 0
|
||||
while TRUE
|
||||
# translate status line
|
||||
state = relay_ftp_status(s4, s6, state)
|
||||
break if state == nil
|
||||
# translate command line
|
||||
state = relay_ftp_command(s6, s4, state)
|
||||
break if state == nil
|
||||
end
|
||||
STDERR.print "relay_ftp(#{sock}, #{name}) closing s4\n" if DEBUG
|
||||
s4.close
|
||||
STDERR.print "relay_ftp(#{sock}, #{name}) closing s6\n" if DEBUG
|
||||
s6.close
|
||||
STDERR.print "relay_ftp(#{sock}, #{name}) done\n" if DEBUG
|
||||
end
|
||||
end
|
||||
STDERR.print "relay_ftp(#{sock}, #{name}) finished\n" if DEBUG
|
||||
end
|
||||
|
||||
def relay_tcp(sock, name)
|
||||
STDERR.print "relay_tcp(#{sock}, #{name})\n" if DEBUG
|
||||
while TRUE
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) accepting\n" if DEBUG
|
||||
s = sock.accept
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) accepted #{s}\n" if DEBUG
|
||||
Thread.start do
|
||||
threads = []
|
||||
STDERR.print "accepted #{s} -> #{Thread.current}\n" if DEBUG
|
||||
s6 = s
|
||||
dest6 = s.addr[3]
|
||||
if !DEBUG_LOOPBACK
|
||||
t = s.getsockname.unpack("x8 x12 C4")
|
||||
dest4 = "#{t[0]}.#{t[1]}.#{t[2]}.#{t[3]}"
|
||||
port4 = s.addr[1]
|
||||
else
|
||||
dest4 = "127.0.0.1"
|
||||
port4 = "telnet"
|
||||
end
|
||||
if DEBUG
|
||||
STDERR.print "IPv6 dest: #{dest6} IPv4 dest: #{dest4}\n" if DEBUG
|
||||
end
|
||||
STDERR.print "connect to #{dest4} #{port4}\n" if DEBUG
|
||||
s4 = TCPsocket.open(dest4, port4)
|
||||
STDERR.print "connected to #{dest4} #{port4}, #{s4.addr[1]}\n" if DEBUG
|
||||
[0, 1].each do |i|
|
||||
threads[i] = Thread.start do
|
||||
if (i == 0)
|
||||
tcpcopy(s6, s4)
|
||||
else
|
||||
tcpcopy(s4, s6)
|
||||
end
|
||||
end
|
||||
end
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) wait\n" if DEBUG
|
||||
for i in threads
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) wait #{i}\n" if DEBUG
|
||||
i.join
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) wait #{i} done\n" if DEBUG
|
||||
end
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) closing s4\n" if DEBUG
|
||||
s4.close
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) closing s6\n" if DEBUG
|
||||
s6.close
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) done\n" if DEBUG
|
||||
end
|
||||
end
|
||||
STDERR.print "relay_tcp(#{sock}, #{name}) finished\n" if DEBUG
|
||||
end
|
||||
|
||||
def usage()
|
||||
STDERR.print "usage: #{$0} [-f] port...\n"
|
||||
end
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
||||
$mode = "tcp"
|
||||
|
||||
while ARGV[0] =~ /^-/ do
|
||||
case ARGV[0]
|
||||
when /^-f/
|
||||
$mode = "ftp"
|
||||
else
|
||||
usage()
|
||||
exit 0
|
||||
end
|
||||
ARGV.shift
|
||||
end
|
||||
|
||||
if ARGV.length == 0
|
||||
usage()
|
||||
exit 1
|
||||
end
|
||||
|
||||
ftpport = Socket.getservbyname("ftp")
|
||||
|
||||
res = []
|
||||
for port in ARGV
|
||||
t = Socket.getaddrinfo(nil, port, Socket::PF_INET6, Socket::SOCK_STREAM,
|
||||
nil, Socket::AI_PASSIVE)
|
||||
if (t.size <= 0)
|
||||
STDERR.print "FATAL: getaddrinfo failed (port=#{port})\n"
|
||||
exit 1
|
||||
end
|
||||
res += t
|
||||
end
|
||||
|
||||
sockpool = []
|
||||
names = []
|
||||
listenthreads = []
|
||||
|
||||
res.each do |i|
|
||||
s = TCPserver.new(i[3], i[1])
|
||||
n = Socket.getnameinfo(s.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV).join(" port ")
|
||||
if i[6] == IPPROTO_IPV6
|
||||
s.setsockopt(i[6], IPV6_FAITH, 1)
|
||||
end
|
||||
s.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
|
||||
sockpool.push s
|
||||
names.push n
|
||||
end
|
||||
|
||||
if DEBUG
|
||||
(0 .. sockpool.size - 1).each do |i|
|
||||
STDERR.print "listen[#{i}]: #{sockpool[i]} #{names[i]}\n" if DEBUG
|
||||
end
|
||||
end
|
||||
|
||||
(0 .. sockpool.size - 1).each do |i|
|
||||
listenthreads[i] = Thread.start do
|
||||
if DEBUG
|
||||
STDERR.print "listen[#{i}]: thread #{Thread.current}\n" if DEBUG
|
||||
end
|
||||
STDERR.print "listen[#{i}]: thread #{Thread.current}\n" if DEBUG
|
||||
case $mode
|
||||
when "tcp"
|
||||
relay_tcp(sockpool[i], names[i])
|
||||
when "ftp"
|
||||
relay_ftp(sockpool[i], names[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i in listenthreads
|
||||
i.join
|
||||
end
|
||||
|
||||
exit 0
|
@ -69,7 +69,7 @@ __FBSDID("$FreeBSD$");
|
||||
* or name a tcpmux service
|
||||
* or specify a unix domain socket
|
||||
* socket type stream/dgram/raw/rdm/seqpacket
|
||||
* protocol tcp[4][6][/faith], udp[4][6], unix
|
||||
* protocol tcp[4][6], udp[4][6], unix
|
||||
* wait/nowait single-threaded/multi-threaded
|
||||
* user[:group][/login-class] user/group/login-class to run daemon as
|
||||
* server program full path name
|
||||
@ -1305,14 +1305,6 @@ setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
|
||||
syslog(LOG_ERR, "setsockopt (IPV6_V6ONLY): %m");
|
||||
}
|
||||
#undef turnon
|
||||
#ifdef IPV6_FAITH
|
||||
if (sep->se_type == FAITH_TYPE) {
|
||||
if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, &on,
|
||||
sizeof(on)) < 0) {
|
||||
syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef IPSEC
|
||||
ipsecsetup(sep);
|
||||
#endif
|
||||
@ -1744,15 +1736,15 @@ getconfigent(void)
|
||||
arg = sskip(&cp);
|
||||
if (strncmp(arg, "tcp", 3) == 0) {
|
||||
sep->se_proto = newstr(strsep(&arg, "/"));
|
||||
if (arg != NULL) {
|
||||
if (strcmp(arg, "faith") == 0)
|
||||
sep->se_type = FAITH_TYPE;
|
||||
if (arg != NULL && (strcmp(arg, "faith") == 0)) {
|
||||
syslog(LOG_ERR, "faith has been deprecated");
|
||||
goto more;
|
||||
}
|
||||
} else {
|
||||
if (sep->se_type == NORM_TYPE &&
|
||||
strncmp(arg, "faith/", 6) == 0) {
|
||||
arg += 6;
|
||||
sep->se_type = FAITH_TYPE;
|
||||
syslog(LOG_ERR, "faith has been deprecated");
|
||||
goto more;
|
||||
}
|
||||
sep->se_proto = newstr(arg);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user