aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/Makefile2
-rw-r--r--etc/libalias.conf8
-rw-r--r--lib/libalias/Makefile39
-rw-r--r--lib/libalias/libalias/Makefile13
-rw-r--r--lib/libalias/modules/Makefile7
-rw-r--r--lib/libalias/modules/Makefile.inc7
-rw-r--r--lib/libalias/modules/cuseeme/Makefile6
-rw-r--r--lib/libalias/modules/dummy/Makefile6
-rw-r--r--lib/libalias/modules/ftp/Makefile6
-rw-r--r--lib/libalias/modules/irc/Makefile6
-rw-r--r--lib/libalias/modules/nbt/Makefile6
-rw-r--r--lib/libalias/modules/pptp/Makefile6
-rw-r--r--lib/libalias/modules/skinny/Makefile6
-rw-r--r--lib/libalias/modules/smedia/Makefile6
-rw-r--r--sbin/natd/natd.c3
-rw-r--r--sys/conf/files9
-rw-r--r--sys/modules/libalias/Makefile32
-rw-r--r--sys/modules/libalias/libalias/Makefile8
-rw-r--r--sys/modules/libalias/modules/Makefile7
-rw-r--r--sys/modules/libalias/modules/Makefile.inc3
-rw-r--r--sys/modules/libalias/modules/cuseeme/Makefile6
-rw-r--r--sys/modules/libalias/modules/dummy/Makefile6
-rw-r--r--sys/modules/libalias/modules/ftp/Makefile6
-rw-r--r--sys/modules/libalias/modules/irc/Makefile6
-rw-r--r--sys/modules/libalias/modules/modules.inc11
-rw-r--r--sys/modules/libalias/modules/nbt/Makefile6
-rw-r--r--sys/modules/libalias/modules/pptp/Makefile6
-rw-r--r--sys/modules/libalias/modules/skinny/Makefile6
-rw-r--r--sys/modules/libalias/modules/smedia/Makefile6
-rw-r--r--sys/netinet/libalias/alias.c291
-rw-r--r--sys/netinet/libalias/alias.h14
-rw-r--r--sys/netinet/libalias/alias_cuseeme.c99
-rw-r--r--sys/netinet/libalias/alias_db.c149
-rw-r--r--sys/netinet/libalias/alias_dummy.c153
-rw-r--r--sys/netinet/libalias/alias_ftp.c82
-rw-r--r--sys/netinet/libalias/alias_irc.c83
-rw-r--r--sys/netinet/libalias/alias_local.h64
-rw-r--r--sys/netinet/libalias/alias_mod.c284
-rw-r--r--sys/netinet/libalias/alias_mod.h157
-rw-r--r--sys/netinet/libalias/alias_nbt.c138
-rw-r--r--sys/netinet/libalias/alias_old.c1
-rw-r--r--sys/netinet/libalias/alias_pptp.c193
-rw-r--r--sys/netinet/libalias/alias_proxy.c12
-rw-r--r--sys/netinet/libalias/alias_skinny.c80
-rw-r--r--sys/netinet/libalias/alias_smedia.c88
-rw-r--r--sys/netinet/libalias/alias_util.c1
-rw-r--r--sys/netinet/libalias/libalias.3429
47 files changed, 2245 insertions, 318 deletions
diff --git a/etc/Makefile b/etc/Makefile
index 1e386a3da758..5f985178eec6 100644
--- a/etc/Makefile
+++ b/etc/Makefile
@@ -12,7 +12,7 @@ BIN1= amd.map apmd.conf auth.conf \
dhclient.conf disktab fbtab freebsd-update.conf \
ftpusers gettytab group \
hosts hosts.allow hosts.equiv hosts.lpd \
- inetd.conf login.access login.conf mac.conf motd \
+ inetd.conf libalias.conf login.access login.conf mac.conf motd \
netconfig network.subr networks newsyslog.conf nsswitch.conf \
portsnap.conf pf.conf pf.os phones profile protocols \
rc rc.bsdextended rc.firewall rc.firewall6 rc.initdiskless \
diff --git a/etc/libalias.conf b/etc/libalias.conf
new file mode 100644
index 000000000000..dfe37abca71a
--- /dev/null
+++ b/etc/libalias.conf
@@ -0,0 +1,8 @@
+# $FreeBSD$
+/usr/lib/libalias_cuseeme.so
+/usr/lib/libalias_ftp.so
+/usr/lib/libalias_irc.so
+/usr/lib/libalias_nbt.so
+/usr/lib/libalias_pptp.so
+/usr/lib/libalias_skinny.so
+/usr/lib/libalias_smedia.so
diff --git a/lib/libalias/Makefile b/lib/libalias/Makefile
index 465216a9c1c3..1b5ec952e2d5 100644
--- a/lib/libalias/Makefile
+++ b/lib/libalias/Makefile
@@ -1,16 +1,29 @@
+# Copyright 2006 Paolo Pisati <piso@FreeBSD.org>
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$
-.PATH: ${.CURDIR}/../../sys/netinet/libalias
+SUBDIR= libalias modules
-LIB= alias
-SHLIBDIR?= /lib
-SHLIB_MAJOR= 5
-MAN= libalias.3
-SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
- alias_nbt.c alias_pptp.c alias_proxy.c alias_skinny.c alias_smedia.c \
- alias_util.c alias_old.c
-INCS= alias.h
-WARNS?= 6
-NO_WERROR=
-
-.include <bsd.lib.mk>
+.include <bsd.subdir.mk>
diff --git a/lib/libalias/libalias/Makefile b/lib/libalias/libalias/Makefile
new file mode 100644
index 000000000000..29a234dee369
--- /dev/null
+++ b/lib/libalias/libalias/Makefile
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../sys/netinet/libalias
+
+LIB= alias
+SHLIBDIR?= /lib
+SHLIB_MAJOR= 5
+MAN= libalias.3
+SRCS= alias.c alias_db.c alias_proxy.c alias_util.c alias_old.c alias_mod.c
+INCS= alias.h
+WARNS?= 6
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/modules/Makefile b/lib/libalias/modules/Makefile
new file mode 100644
index 000000000000..e4aa76724816
--- /dev/null
+++ b/lib/libalias/modules/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.include "../../../sys/modules/libalias/modules/modules.inc"
+
+SUBDIR= ${MODULES}
+
+.include <bsd.subdir.mk>
diff --git a/lib/libalias/modules/Makefile.inc b/lib/libalias/modules/Makefile.inc
new file mode 100644
index 000000000000..df92be4e5a39
--- /dev/null
+++ b/lib/libalias/modules/Makefile.inc
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../sys/netinet/libalias
+
+SHLIBDIR?= /lib
+SHLIB_MAJOR= 4
+WARNS?= 1
diff --git a/lib/libalias/modules/cuseeme/Makefile b/lib/libalias/modules/cuseeme/Makefile
new file mode 100644
index 000000000000..482ce93a76ca
--- /dev/null
+++ b/lib/libalias/modules/cuseeme/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= alias_cuseeme
+SRCS= alias_cuseeme.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/modules/dummy/Makefile b/lib/libalias/modules/dummy/Makefile
new file mode 100644
index 000000000000..a79ca855ea61
--- /dev/null
+++ b/lib/libalias/modules/dummy/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= alias_dummy
+SRCS= alias_dummy.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/modules/ftp/Makefile b/lib/libalias/modules/ftp/Makefile
new file mode 100644
index 000000000000..4865fa2ef536
--- /dev/null
+++ b/lib/libalias/modules/ftp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= alias_ftp
+SRCS= alias_ftp.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/modules/irc/Makefile b/lib/libalias/modules/irc/Makefile
new file mode 100644
index 000000000000..98f4e853605f
--- /dev/null
+++ b/lib/libalias/modules/irc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= alias_irc
+SRCS= alias_irc.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/modules/nbt/Makefile b/lib/libalias/modules/nbt/Makefile
new file mode 100644
index 000000000000..c26b5d90a669
--- /dev/null
+++ b/lib/libalias/modules/nbt/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= alias_nbt
+SRCS= alias_nbt.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/modules/pptp/Makefile b/lib/libalias/modules/pptp/Makefile
new file mode 100644
index 000000000000..69d8e617a1f1
--- /dev/null
+++ b/lib/libalias/modules/pptp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= alias_pptp
+SRCS= alias_pptp.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/modules/skinny/Makefile b/lib/libalias/modules/skinny/Makefile
new file mode 100644
index 000000000000..f554e9cec4fd
--- /dev/null
+++ b/lib/libalias/modules/skinny/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= alias_skinny
+SRCS= alias_skinny.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libalias/modules/smedia/Makefile b/lib/libalias/modules/smedia/Makefile
new file mode 100644
index 000000000000..56c4ddd2a29b
--- /dev/null
+++ b/lib/libalias/modules/smedia/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= alias_smedia
+SRCS= alias_smedia.c
+
+.include <bsd.lib.mk>
diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c
index e7c3600a1726..c0fb05facc9c 100644
--- a/sbin/natd/natd.c
+++ b/sbin/natd/natd.c
@@ -970,7 +970,8 @@ void Warn (const char* msg)
static void RefreshAddr (int sig __unused)
{
- if (mip->ifName)
+ LibAliasRefreshModules();
+ if (mip != NULL && mip->ifName != NULL)
mip->assignAliasAddr = 1;
}
diff --git a/sys/conf/files b/sys/conf/files
index 64e67bc10d32..40f291def7e0 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1744,16 +1744,11 @@ netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
netinet/libalias/alias.c optional libalias
-netinet/libalias/alias_cuseeme.c optional libalias
netinet/libalias/alias_db.c optional libalias
-netinet/libalias/alias_ftp.c optional libalias
-netinet/libalias/alias_irc.c optional libalias
-netinet/libalias/alias_nbt.c optional libalias
-netinet/libalias/alias_pptp.c optional libalias
netinet/libalias/alias_proxy.c optional libalias
-netinet/libalias/alias_skinny.c optional libalias
-netinet/libalias/alias_smedia.c optional libalias
netinet/libalias/alias_util.c optional libalias
+netinet/libalias/alias_old.c optional libalias
+netinet/libalias/alias_mod.c optional libalias
netinet6/ah_aesxcbcmac.c optional ipsec
netinet6/ah_core.c optional ipsec
netinet6/ah_input.c optional ipsec
diff --git a/sys/modules/libalias/Makefile b/sys/modules/libalias/Makefile
index 6a2255e5de48..c8b7dd58e774 100644
--- a/sys/modules/libalias/Makefile
+++ b/sys/modules/libalias/Makefile
@@ -1,33 +1,5 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../netinet/libalias
+SUBDIR= libalias modules
-KMOD= libalias
-SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
- alias_nbt.c alias_pptp.c alias_proxy.c alias_skinny.c alias_smedia.c \
- alias_util.c
-INCS= alias.h
-
-EXPORT_SYMS= LibAliasInit \
- LibAliasUninit \
- LibAliasSetAddress \
- LibAliasSetMode \
- LibAliasSkinnyPort \
- LibAliasIn \
- LibAliasOut \
- LibAliasRedirectPort \
- LibAliasRedirectAddr \
- LibAliasAddServer \
- LibAliasRedirectDynamic \
- LibAliasRedirectDelete \
- LibAliasProxyRule \
- LibAliasRedirectProto \
- LibAliasSaveFragment \
- LibAliasGetFragment \
- LibAliasFragmentIn \
- LibAliasSetTarget \
- LibAliasCheckNewLink \
- LibAliasInternetChecksum \
- LibAliasUnaliasOut
-
-.include <bsd.kmod.mk>
+.include <bsd.subdir.mk>
diff --git a/sys/modules/libalias/libalias/Makefile b/sys/modules/libalias/libalias/Makefile
new file mode 100644
index 000000000000..f5b480c72cab
--- /dev/null
+++ b/sys/modules/libalias/libalias/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../netinet/libalias
+
+KMOD= libalias
+SRCS= alias.c alias_db.c alias_proxy.c alias_util.c alias_old.c alias_mod.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/libalias/modules/Makefile b/sys/modules/libalias/modules/Makefile
new file mode 100644
index 000000000000..828e40faae78
--- /dev/null
+++ b/sys/modules/libalias/modules/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.include "modules.inc"
+
+SUBDIR= ${MODULES}
+
+.include <bsd.subdir.mk>
diff --git a/sys/modules/libalias/modules/Makefile.inc b/sys/modules/libalias/modules/Makefile.inc
new file mode 100644
index 000000000000..78391c597b86
--- /dev/null
+++ b/sys/modules/libalias/modules/Makefile.inc
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../netinet/libalias
diff --git a/sys/modules/libalias/modules/cuseeme/Makefile b/sys/modules/libalias/modules/cuseeme/Makefile
new file mode 100644
index 000000000000..dfb5a83d2790
--- /dev/null
+++ b/sys/modules/libalias/modules/cuseeme/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= alias_cuseeme
+SRCS= alias_cuseeme.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/libalias/modules/dummy/Makefile b/sys/modules/libalias/modules/dummy/Makefile
new file mode 100644
index 000000000000..ded455a8dfe7
--- /dev/null
+++ b/sys/modules/libalias/modules/dummy/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= alias_dummy
+SRCS= alias_dummy.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/libalias/modules/ftp/Makefile b/sys/modules/libalias/modules/ftp/Makefile
new file mode 100644
index 000000000000..07e700b40956
--- /dev/null
+++ b/sys/modules/libalias/modules/ftp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= alias_ftp
+SRCS= alias_ftp.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/libalias/modules/irc/Makefile b/sys/modules/libalias/modules/irc/Makefile
new file mode 100644
index 000000000000..b6e330d9e1b8
--- /dev/null
+++ b/sys/modules/libalias/modules/irc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= alias_irc
+SRCS= alias_irc.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/libalias/modules/modules.inc b/sys/modules/libalias/modules/modules.inc
new file mode 100644
index 000000000000..9582ab53828c
--- /dev/null
+++ b/sys/modules/libalias/modules/modules.inc
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+MODULES =
+MODULES += cuseeme
+MODULES += dummy
+MODULES += ftp
+MODULES += irc
+MODULES += nbt
+MODULES += pptp
+MODULES += skinny
+MODULES += smedia
diff --git a/sys/modules/libalias/modules/nbt/Makefile b/sys/modules/libalias/modules/nbt/Makefile
new file mode 100644
index 000000000000..6d6dd8728b6a
--- /dev/null
+++ b/sys/modules/libalias/modules/nbt/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= alias_nbt
+SRCS= alias_nbt.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/libalias/modules/pptp/Makefile b/sys/modules/libalias/modules/pptp/Makefile
new file mode 100644
index 000000000000..748f356e9fa7
--- /dev/null
+++ b/sys/modules/libalias/modules/pptp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= alias_pptp
+SRCS= alias_pptp.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/libalias/modules/skinny/Makefile b/sys/modules/libalias/modules/skinny/Makefile
new file mode 100644
index 000000000000..8560f5ed131f
--- /dev/null
+++ b/sys/modules/libalias/modules/skinny/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= alias_skinny
+SRCS= alias_skinny.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/libalias/modules/smedia/Makefile b/sys/modules/libalias/modules/smedia/Makefile
new file mode 100644
index 000000000000..245a63e8cfec
--- /dev/null
+++ b/sys/modules/libalias/modules/smedia/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= alias_smedia
+SRCS= alias_smedia.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c
index aa2bed937dab..0120c1988b80 100644
--- a/sys/netinet/libalias/alias.c
+++ b/sys/netinet/libalias/alias.c
@@ -115,7 +115,11 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#else
#include <sys/types.h>
+#include <stdlib.h>
#include <stdio.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <string.h>
#endif
#include <netinet/in_systm.h>
@@ -128,22 +132,14 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
#else
+#include <err.h>
#include "alias.h"
#include "alias_local.h"
+#include "alias_mod.h"
#endif
-#define NETBIOS_NS_PORT_NUMBER 137
-#define NETBIOS_DGM_PORT_NUMBER 138
-#define FTP_CONTROL_PORT_NUMBER 21
-#define IRC_CONTROL_PORT_NUMBER_1 6667
-#define IRC_CONTROL_PORT_NUMBER_2 6668
-#define CUSEEME_PORT_NUMBER 7648
-#define RTSP_CONTROL_PORT_NUMBER_1 554
-#define RTSP_CONTROL_PORT_NUMBER_2 7070
-#define TFTP_PORT_NUMBER 69
-#define PPTP_CONTROL_PORT_NUMBER 1723
-
static __inline int
twowords(void *p)
{
@@ -725,24 +721,24 @@ UdpAliasIn(struct libalias *la, struct ip *pip)
struct in_addr original_address;
u_short alias_port;
int accumulate;
- int r = 0;
+ int r = 0, error;
+ struct alias_data ad = {
+ .lnk = lnk,
+ .oaddr = &original_address,
+ .aaddr = &alias_address,
+ .aport = &alias_port,
+ .sport = &ud->uh_sport,
+ .dport = &ud->uh_dport,
+ .maxpktsize = 0
+ };
alias_address = GetAliasAddress(lnk);
original_address = GetOriginalAddress(lnk);
alias_port = ud->uh_dport;
ud->uh_dport = GetOriginalPort(lnk);
-/* Special processing for IP encoding protocols */
- if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
- AliasHandleCUSeeMeIn(la, pip, original_address);
-/* If NETBIOS Datagram, It should be alias address in UDP Data, too */
- else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
- || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER)
- r = AliasHandleUdpNbt(la, pip, lnk, &original_address, ud->uh_dport);
- else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
- || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER)
- r = AliasHandleUdpNbtNS(la, pip, lnk, &alias_address, &alias_port,
- &original_address, &ud->uh_dport);
+ /* Walk out chain. */
+ error = find_handler(IN, UDP, la, pip, &ad);
/* If UDP checksum is not zero, then adjust since destination port */
/* is being unaliased and destination address is being altered. */
@@ -774,6 +770,7 @@ UdpAliasOut(struct libalias *la, struct ip *pip, int create)
{
struct udphdr *ud;
struct alias_link *lnk;
+ int error;
/* Return if proxy-only mode is enabled */
if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
@@ -787,29 +784,21 @@ UdpAliasOut(struct libalias *la, struct ip *pip, int create)
if (lnk != NULL) {
u_short alias_port;
struct in_addr alias_address;
+ struct alias_data ad = {
+ .lnk = lnk,
+ .oaddr = NULL,
+ .aaddr = &alias_address,
+ .aport = &alias_port,
+ .sport = &ud->uh_sport,
+ .dport = &ud->uh_dport,
+ .maxpktsize = 0
+ };
alias_address = GetAliasAddress(lnk);
alias_port = GetAliasPort(lnk);
-/* Special processing for IP encoding protocols */
- if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
- AliasHandleCUSeeMeOut(la, pip, lnk);
-/* If NETBIOS Datagram, It should be alias address in UDP Data, too */
- else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
- || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER)
- AliasHandleUdpNbt(la, pip, lnk, &alias_address, alias_port);
- else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
- || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER)
- AliasHandleUdpNbtNS(la, pip, lnk, &pip->ip_src, &ud->uh_sport,
- &alias_address, &alias_port);
-/*
- * We don't know in advance what TID the TFTP server will choose,
- * so we create a wilcard link (destination port is unspecified)
- * that will match any TID from a given destination.
- */
- else if (ntohs(ud->uh_dport) == TFTP_PORT_NUMBER)
- FindRtspOut(la, pip->ip_src, pip->ip_dst,
- ud->uh_sport, alias_port, IPPROTO_UDP);
+ /* Walk out chain. */
+ error = find_handler(OUT, UDP, la, pip, &ad);
/* If UDP checksum is not zero, adjust since source port is */
/* being aliased and source address is being altered */
@@ -855,15 +844,26 @@ TcpAliasIn(struct libalias *la, struct ip *pip)
struct in_addr proxy_address;
u_short alias_port;
u_short proxy_port;
- int accumulate;
+ int accumulate, error;
+
+ /*
+ * The init of MANY vars is a bit below, but aliashandlepptpin
+ * seems to need the destination port that came within the
+ * packet and not the original one looks below [*].
+ */
+
+ struct alias_data ad = {
+ .lnk = lnk,
+ .oaddr = NULL,
+ .aaddr = NULL,
+ .aport = NULL,
+ .sport = &tc->th_sport,
+ .dport = &tc->th_dport,
+ .maxpktsize = 0
+ };
-/* Special processing for IP encoding protocols */
- if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
- || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
- AliasHandlePptpIn(la, pip, lnk);
- else if (la->skinnyPort != 0 && (ntohs(tc->th_dport) == la->skinnyPort
- || ntohs(tc->th_sport) == la->skinnyPort))
- AliasHandleSkinny(la, pip, lnk);
+ /* Walk out chain. */
+ error = find_handler(IN, TCP, la, pip, &ad);
alias_address = GetAliasAddress(lnk);
original_address = GetOriginalAddress(lnk);
@@ -872,6 +872,28 @@ TcpAliasIn(struct libalias *la, struct ip *pip)
tc->th_dport = GetOriginalPort(lnk);
proxy_port = GetProxyPort(lnk);
+ /*
+ * Look above, if anyone is going to add find_handler AFTER
+ * this aliashandlepptpin/point, please redo alias_data too.
+ * Uncommenting the piece here below should be enough.
+ */
+#if 0
+ struct alias_data ad = {
+ .lnk = lnk,
+ .oaddr = &original_address,
+ .aaddr = &alias_address,
+ .aport = &alias_port,
+ .sport = &ud->uh_sport,
+ .dport = &ud->uh_dport,
+ .maxpktsize = 0
+ };
+
+ /* Walk out chain. */
+ error = find_handler(la, pip, &ad);
+ if (error == EHDNOF)
+ printf("Protocol handler not found\n");
+#endif
+
/* Adjust TCP checksum since destination port is being unaliased */
/* and destination port is being altered. */
accumulate = alias_port;
@@ -926,7 +948,7 @@ TcpAliasIn(struct libalias *la, struct ip *pip)
static int
TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create)
{
- int proxy_type;
+ int proxy_type, error;
u_short dest_port;
u_short proxy_server_port;
struct in_addr dest_address;
@@ -973,6 +995,15 @@ TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create)
u_short alias_port;
struct in_addr alias_address;
int accumulate;
+ struct alias_data ad = {
+ .lnk = lnk,
+ .oaddr = NULL,
+ .aaddr = &alias_address,
+ .aport = &alias_port,
+ .sport = &tc->th_sport,
+ .dport = &tc->th_dport,
+ .maxpktsize = maxpacketsize
+ };
/* Save original destination address, if this is a proxy packet.
Also modify packet to include destination encoding. This may
@@ -989,25 +1020,9 @@ TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create)
/* Monitor TCP connection state */
TcpMonitorOut(pip, lnk);
-
-/* Special processing for IP encoding protocols */
- if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER
- || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER)
- AliasHandleFtpOut(la, pip, lnk, maxpacketsize);
- else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1
- || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2)
- AliasHandleIrcOut(la, pip, lnk, maxpacketsize);
- else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1
- || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1
- || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2
- || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2)
- AliasHandleRtspOut(la, pip, lnk, maxpacketsize);
- else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
- || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
- AliasHandlePptpOut(la, pip, lnk);
- else if (la->skinnyPort != 0 && (ntohs(tc->th_sport) == la->skinnyPort
- || ntohs(tc->th_dport) == la->skinnyPort))
- AliasHandleSkinny(la, pip, lnk);
+
+ /* Walk out chain. */
+ error = find_handler(OUT, TCP, la, pip, &ad);
/* Adjust TCP checksum since source port is being aliased */
/* and source address is being altered */
@@ -1208,13 +1223,26 @@ LibAliasIn(struct libalias *la, char *ptr, int maxpacketsize)
case IPPROTO_TCP:
iresult = TcpAliasIn(la, pip);
break;
- case IPPROTO_GRE:
- if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY ||
- AliasHandlePptpGreIn(la, pip) == 0)
+ case IPPROTO_GRE: {
+ int error;
+ struct alias_data ad = {
+ .lnk = NULL,
+ .oaddr = NULL,
+ .aaddr = NULL,
+ .aport = NULL,
+ .sport = NULL,
+ .dport = NULL,
+ .maxpktsize = 0
+ };
+
+ /* Walk out chain. */
+ error = find_handler(IN, IP, la, pip, &ad);
+ if (error == 0)
iresult = PKT_ALIAS_OK;
else
iresult = ProtoAliasIn(la, pip);
- break;
+ }
+ break;
default:
iresult = ProtoAliasIn(la, pip);
break;
@@ -1321,12 +1349,25 @@ LibAliasOutTry(struct libalias *la, char *ptr, /* valid IP packet */
case IPPROTO_TCP:
iresult = TcpAliasOut(la, pip, maxpacketsize, create);
break;
- case IPPROTO_GRE:
- if (AliasHandlePptpGreOut(la, pip) == 0)
- iresult = PKT_ALIAS_OK;
- else
- iresult = ProtoAliasOut(la, pip, create);
- break;
+ case IPPROTO_GRE: {
+ int error;
+ struct alias_data ad = {
+ .lnk = NULL,
+ .oaddr = NULL,
+ .aaddr = NULL,
+ .aport = NULL,
+ .sport = NULL,
+ .dport = NULL,
+ .maxpktsize = 0
+ };
+ /* Walk out chain. */
+ error = find_handler(OUT, IP, la, pip, &ad);
+ if (error == 0)
+ iresult = PKT_ALIAS_OK;
+ else
+ iresult = ProtoAliasOut(la, pip, create);
+ }
+ break;
default:
iresult = ProtoAliasOut(la, pip, create);
break;
@@ -1443,3 +1484,93 @@ LibAliasUnaliasOut(struct libalias *la, char *ptr, /* valid IP packet */
return (iresult);
}
+
+#ifndef _KERNEL
+
+int
+LibAliasRefreshModules(void)
+{
+ char buf[256], conf[] = "/etc/libalias.conf";
+ FILE *fd;
+ int len;
+
+ fd = fopen(conf, "r");
+ if (fd == NULL)
+ err(1, "fopen(%s)", conf);
+
+ LibAliasUnLoadAllModule();
+
+ for (;;) {
+ fgets(buf, 256, fd);
+ if feof(fd)
+ break;
+ len = strlen(buf);
+ if (len > 1) {
+ buf[len - 1] = '\0';
+ printf("Loading %s\n", buf);
+ LibAliasLoadModule(buf);
+ }
+ }
+ return (0);
+}
+
+int
+LibAliasLoadModule(char *path)
+{
+ struct dll *t;
+ void *handle;
+ struct proto_handler *m;
+ const char *error;
+ moduledata_t *p;
+
+ handle = dlopen (path, RTLD_LAZY);
+ if (!handle) {
+ fputs (dlerror(), stderr);
+ return (EINVAL);
+ }
+
+ p = dlsym(handle, "alias_mod");
+ if ((error = dlerror()) != NULL) {
+ fputs(error, stderr);
+ return (EINVAL);
+ }
+
+ t = malloc(sizeof(struct dll));
+ if (t == NULL)
+ return (ENOMEM);
+ strncpy(t->name, p->name, DLL_LEN);
+ t->handle = handle;
+ if (attach_dll(t) == EEXIST) {
+ free(t);
+ fputs("dll conflict", stderr);
+ return (EEXIST);
+ }
+
+ m = dlsym(t->handle, "handlers");
+ if ((error = dlerror()) != NULL) {
+ fputs(error, stderr);
+ return (EINVAL);
+ }
+
+ LibAliasAttachHandlers(m);
+ return (0);
+}
+
+int
+LibAliasUnLoadAllModule(void)
+{
+ struct dll *t;
+ struct proto_handler *p;
+
+ /* Unload all modules then reload everything. */
+ while ((p = first_handler()) != NULL) {
+ detach_handler(p);
+ }
+ while ((t = walk_dll_chain()) != NULL) {
+ dlclose(t->handle);
+ free(t);
+ }
+ return (1);
+}
+
+#endif
diff --git a/sys/netinet/libalias/alias.h b/sys/netinet/libalias/alias.h
index 2c509435a58e..4a809f406530 100644
--- a/sys/netinet/libalias/alias.h
+++ b/sys/netinet/libalias/alias.h
@@ -28,7 +28,7 @@
* $FreeBSD$
*/
-/*-
+/*
* Alias.h defines the outside world interfaces for the packet aliasing
* software.
*
@@ -39,12 +39,16 @@
#ifndef _ALIAS_H_
#define _ALIAS_H_
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#define LIBALIAS_BUF_SIZE 128
#ifdef _KERNEL
/*
* The kernel version of libalias does not support these features.
*/
#define NO_FW_PUNCH
-#define NO_LOGGING
#define NO_USE_SOCKETS
#endif
@@ -180,6 +184,10 @@ void LibAliasSetTarget(struct libalias *, struct in_addr _target_addr);
/* Transparent proxying routines. */
int LibAliasProxyRule(struct libalias *, const char *_cmd);
+/* Module handling API */
+int LibAliasLoadModule(char *);
+int LibAliasUnLoadAllModule(void);
+int LibAliasRefreshModules(void);
/*
* Mode flags and other constants.
@@ -192,9 +200,7 @@ int LibAliasProxyRule(struct libalias *, const char *_cmd);
* If PKT_ALIAS_LOG is set, a message will be printed to /var/log/alias.log
* every time a link is created or deleted. This is useful for debugging.
*/
-#ifndef NO_LOGGING
#define PKT_ALIAS_LOG 0x01
-#endif
/*
* If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g. to ftp,
diff --git a/sys/netinet/libalias/alias_cuseeme.c b/sys/netinet/libalias/alias_cuseeme.c
index 171a6f966a71..f25594201bd3 100644
--- a/sys/netinet/libalias/alias_cuseeme.c
+++ b/sys/netinet/libalias/alias_cuseeme.c
@@ -31,7 +31,10 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
#else
+#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
#endif
@@ -44,8 +47,100 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
#else
#include "alias_local.h"
+#include "alias_mod.h"
+#endif
+
+#define CUSEEME_PORT_NUMBER 7648
+
+static void
+AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip,
+ struct alias_link *lnk);
+
+static void
+AliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip,
+ struct in_addr original_addr);
+
+static int
+fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ah->dport == NULL || ah->oaddr == NULL)
+ return (-1);
+ if (ntohs(*ah->dport) == CUSEEME_PORT_NUMBER)
+ return (0);
+ return (-1);
+}
+
+static int
+protohandlerin(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleCUSeeMeIn(la, pip, *ah->oaddr);
+ return (0);
+}
+
+static int
+protohandlerout(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleCUSeeMeOut(la, pip, ah->lnk);
+ return (0);
+}
+
+/* Kernel module definition. */
+struct proto_handler handlers[] = {
+ {
+ .pri = 120,
+ .dir = OUT,
+ .proto = UDP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandlerout
+ },
+ {
+ .pri = 120,
+ .dir = IN,
+ .proto = UDP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandlerin
+ },
+ { EOH }
+};
+
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ LibAliasAttachHandlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ LibAliasDetachHandlers(handlers);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+#ifdef _KERNEL
+static
+#endif
+moduledata_t
+alias_mod = {
+ "alias_cuseeme", mod_handler, NULL
+};
+
+#ifdef _KERNEL
+DECLARE_MODULE(alias_cuseeme, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
+MODULE_VERSION(alias_cuseeme, 1);
+MODULE_DEPEND(alias_cuseeme, libalias, 1, 1, 1);
#endif
/* CU-SeeMe Data Header */
@@ -77,7 +172,7 @@ struct client_info {
* counts etc */
};
-void
+static void
AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, struct alias_link *lnk)
{
struct udphdr *ud = ip_next(pip);
@@ -100,7 +195,7 @@ AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, struct alias_link *ln
}
}
-void
+static void
AliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip, struct in_addr original_addr)
{
struct in_addr alias_addr;
diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index 281d5f54fcbf..1061c74f0057 100644
--- a/sys/netinet/libalias/alias_db.c
+++ b/sys/netinet/libalias/alias_db.c
@@ -143,40 +143,32 @@ __FBSDID("$FreeBSD$");
*/
#ifdef _KERNEL
+#include <machine/stdarg.h>
#include <sys/param.h>
-#else
-#include <sys/types.h>
-#endif
-
-#include <sys/errno.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#ifdef _KERNEL
-#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/malloc.h>
#include <sys/module.h>
-#else
+#include <sys/syslog.h>
+#else
+#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
+#include <sys/errno.h>
+#include <sys/time.h>
#include <unistd.h>
-#include <arpa/inet.h>
#endif
-/* BSD network include files */
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
+#include <sys/socket.h>
#include <netinet/tcp.h>
#ifdef _KERNEL
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
+#include <net/if.h>
#else
#include "alias.h"
#include "alias_local.h"
+#include "alias_mod.h"
#endif
static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead);
@@ -358,10 +350,12 @@ alias_mod_handler(module_t mod, int type, void *data)
switch (type) {
case MOD_LOAD:
error = 0;
+ handler_chain_init();
break;
case MOD_QUIESCE:
case MOD_UNLOAD:
- finishoff();
+ handler_chain_destroy();
+ finishoff();
error = 0;
break;
default:
@@ -409,12 +403,10 @@ static void ClearFWHole(struct alias_link *);
#endif
-#ifndef NO_LOGGING
/* Log file control */
static void ShowAliasStats(struct libalias *);
-static void InitPacketAliasLog(struct libalias *);
+static int InitPacketAliasLog(struct libalias *);
static void UninitPacketAliasLog(struct libalias *);
-#endif
static u_int
StartPointIn(struct in_addr alias_addr,
@@ -462,37 +454,55 @@ SeqDiff(u_long x, u_long y)
return (ntohl(y) - ntohl(x));
}
+#ifdef _KERNEL
+
+static void
+AliasLog(char *str, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(str, LIBALIAS_BUF_SIZE, format, ap);
+ log(LOG_SECURITY | LOG_INFO, "%s\n", str);
+ va_end(ap);
+}
+#else
+static void
+AliasLog(FILE *stream, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stream, format, ap);
+ va_end(ap);
+ fflush(stream);
+}
+#endif
-#ifndef NO_LOGGING
static void
ShowAliasStats(struct libalias *la)
{
/* Used for debugging */
-
- if (la->monitorFile) {
- fprintf(la->monitorFile,
- "icmp=%d, udp=%d, tcp=%d, pptp=%d, proto=%d, frag_id=%d frag_ptr=%d",
- la->icmpLinkCount,
- la->udpLinkCount,
- la->tcpLinkCount,
- la->pptpLinkCount,
- la->protoLinkCount,
- la->fragmentIdLinkCount,
- la->fragmentPtrLinkCount);
-
- fprintf(la->monitorFile, " / tot=%d (sock=%d)\n",
- la->icmpLinkCount + la->udpLinkCount
- + la->tcpLinkCount
- + la->pptpLinkCount
- + la->protoLinkCount
- + la->fragmentIdLinkCount
- + la->fragmentPtrLinkCount,
- la->sockCount);
-
- fflush(la->monitorFile);
+ if (la->logDesc) {
+ int tot = la->icmpLinkCount + la->udpLinkCount +
+ la->tcpLinkCount + la->pptpLinkCount +
+ la->protoLinkCount + la->fragmentIdLinkCount +
+ la->fragmentPtrLinkCount;
+
+ AliasLog(la->logDesc,
+ "icmp=%u, udp=%u, tcp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u",
+ la->icmpLinkCount,
+ la->udpLinkCount,
+ la->tcpLinkCount,
+ la->pptpLinkCount,
+ la->protoLinkCount,
+ la->fragmentIdLinkCount,
+ la->fragmentPtrLinkCount, tot);
+#ifndef _KERNEL
+ AliasLog(la->logDesc, " (sock=%u)\n", la->sockCount);
+#endif
}
}
-#endif
/* Internal routines for finding, deleting and adding links
@@ -929,12 +939,10 @@ DeleteLink(struct alias_link *lnk)
/* Free memory */
free(lnk);
-#ifndef NO_LOGGING
/* Write statistics, if logging enabled */
if (la->packetAliasMode & PKT_ALIAS_LOG) {
ShowAliasStats(la);
}
-#endif
}
@@ -1072,11 +1080,9 @@ AddLink(struct libalias *la, struct in_addr src_addr,
fprintf(stderr, "malloc() call failed.\n");
#endif
}
-#ifndef NO_LOGGING
if (la->packetAliasMode & PKT_ALIAS_LOG) {
ShowAliasStats(la);
}
-#endif
return (lnk);
}
@@ -2203,30 +2209,40 @@ HouseKeeping(struct libalias *la)
}
}
-#ifndef NO_LOGGING
/* Init the log file and enable logging */
-static void
+static int
InitPacketAliasLog(struct libalias *la)
{
- if ((~la->packetAliasMode & PKT_ALIAS_LOG)
- && (la->monitorFile = fopen("/var/log/alias.log", "w"))) {
+ if (~la->packetAliasMode & PKT_ALIAS_LOG) {
+#ifdef _KERNEL
+ if ((la->logDesc = malloc(LIBALIAS_BUF_SIZE)))
+ ;
+#else
+ if ((la->logDesc = fopen("/var/log/alias.log", "w")))
+ fprintf(la->logDesc, "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
+#endif
+ else
+ return (ENOMEM); /* log initialization failed */
la->packetAliasMode |= PKT_ALIAS_LOG;
- fprintf(la->monitorFile,
- "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
}
+
+ return (1);
}
/* Close the log-file and disable logging. */
static void
UninitPacketAliasLog(struct libalias *la)
{
- if (la->monitorFile) {
- fclose(la->monitorFile);
- la->monitorFile = NULL;
- }
+ if (la->logDesc) {
+#ifdef _KERNEL
+ free(la->logDesc);
+#else
+ fclose(la->logDesc);
+#endif
+ la->logDesc = NULL;
+ }
la->packetAliasMode &= ~PKT_ALIAS_LOG;
}
-#endif
/* Outside world interfaces
@@ -2489,6 +2505,9 @@ LibAliasInit(struct libalias *la)
#ifndef NO_FW_PUNCH
la->fireWallFD = -1;
#endif
+#ifndef _KERNEL
+ LibAliasRefreshModules();
+#endif
return (la);
}
@@ -2498,9 +2517,7 @@ LibAliasUninit(struct libalias *la)
la->deleteAllLinks = 1;
CleanupAliasData(la);
la->deleteAllLinks = 0;
-#ifndef NO_LOGGING
UninitPacketAliasLog(la);
-#endif
#ifndef NO_FW_PUNCH
UninitPunchFW(la);
#endif
@@ -2517,16 +2534,16 @@ LibAliasSetMode(
* do a probe for flag values) */
)
{
-#ifndef NO_LOGGING
/* Enable logging? */
if (flags & mask & PKT_ALIAS_LOG) {
- InitPacketAliasLog(la); /* Do the enable */
+ /* Do the enable */
+ if (InitPacketAliasLog(la) == ENOMEM)
+ return (-1);
} else
/* _Disable_ logging? */
if (~flags & mask & PKT_ALIAS_LOG) {
UninitPacketAliasLog(la);
}
-#endif
#ifndef NO_FW_PUNCH
/* Start punching holes in the firewall? */
if (flags & mask & PKT_ALIAS_PUNCH_FW) {
diff --git a/sys/netinet/libalias/alias_dummy.c b/sys/netinet/libalias/alias_dummy.c
new file mode 100644
index 000000000000..fc6a0f98459b
--- /dev/null
+++ b/sys/netinet/libalias/alias_dummy.c
@@ -0,0 +1,153 @@
+/*-
+ * Copyright (c) 2005 Paolo Pisati <piso@FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$");
+
+/*
+ * Alias_dummy is just an empty skeleton used to demostrate how to write
+ * a module for libalias, that will run unalterated in userland or in
+ * kernel land.
+ */
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#else
+#include <errno.h>
+#include <sys/types.h>
+#include <stdio.h>
+#endif
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+
+#ifdef _KERNEL
+#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
+#else
+#include "alias_local.h"
+#include "alias_mod.h"
+#endif
+
+static void
+AliasHandleDummy(struct libalias *la, struct ip *ip, struct alias_data *ah);
+
+static int
+fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ /*
+ * Check here all the data that will be used later, if any field
+ * is empy/NULL, return a -1 value.
+ */
+ if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
+ ah->maxpktsize == 0)
+ return (-1);
+ /*
+ * Fingerprint the incoming packet, if it matches any conditions
+ * return an OK value.
+ */
+ if (ntohs(*ah->dport) == 123
+ || ntohs(*ah->sport) == 456)
+ return (0); /* I know how to handle it. */
+ return (-1); /* I don't recognize this packet. */
+}
+
+/*
+ * Wrap in this general purpose function, the real function used to alias the
+ * packets.
+ */
+
+static int
+protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleDummy(la, pip, ah);
+ return (0);
+}
+
+/*
+ * NOTA BENE: the next variable MUST NOT be renamed in any case if you want
+ * your module to work in userland, cause it's used to find and use all
+ * the protocol handlers present in every module.
+ * So WATCH OUT, your module needs this variables and it needs it with
+ * ITS EXACT NAME: handlers.
+ */
+
+struct proto_handler handlers [] = {
+ {
+ .pri = 666,
+ .dir = IN|OUT,
+ .proto = UDP|TCP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandler
+ },
+ { EOH }
+};
+
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ LibAliasAttachHandlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ LibAliasDetachHandlers(handlers);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+#ifdef _KERNEL
+static
+#endif
+moduledata_t alias_mod = {
+ "alias_dummy", mod_handler, NULL
+};
+
+#ifdef _KERNEL
+DECLARE_MODULE(alias_dummy, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
+MODULE_VERSION(alias_dummy, 1);
+MODULE_DEPEND(alias_dummy, libalias, 1, 1, 1);
+#endif
+
+static void
+AliasHandleDummy(struct libalias *la, struct ip *ip, struct alias_data *ah)
+{
+ ; /* Dummy. */
+}
+
diff --git a/sys/netinet/libalias/alias_ftp.c b/sys/netinet/libalias/alias_ftp.c
index d91e1cde018f..6016f1b3c19a 100644
--- a/sys/netinet/libalias/alias_ftp.c
+++ b/sys/netinet/libalias/alias_ftp.c
@@ -72,12 +72,13 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <sys/param.h>
#include <sys/ctype.h>
-#include <sys/libkern.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
#else
+#include <errno.h>
#include <sys/types.h>
-#include <ctype.h>
#include <stdio.h>
-#include <string.h>
#endif
#include <netinet/in_systm.h>
@@ -88,8 +89,81 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
#else
#include "alias_local.h"
+#include "alias_mod.h"
+#endif
+
+#define FTP_CONTROL_PORT_NUMBER 21
+
+static void
+AliasHandleFtpOut(struct libalias *, struct ip *, struct alias_link *,
+ int maxpacketsize);
+
+static int
+fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
+ ah->maxpktsize == 0)
+ return (-1);
+ if (ntohs(*ah->dport) == FTP_CONTROL_PORT_NUMBER
+ || ntohs(*ah->sport) == FTP_CONTROL_PORT_NUMBER)
+ return (0);
+ return (-1);
+}
+
+static int
+protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleFtpOut(la, pip, ah->lnk, ah->maxpktsize);
+ return (0);
+}
+
+struct proto_handler handlers[] = {
+ {
+ .pri = 80,
+ .dir = OUT,
+ .proto = TCP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandler
+ },
+ { EOH }
+};
+
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ LibAliasAttachHandlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ LibAliasDetachHandlers(handlers);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+#ifdef _KERNEL
+static
+#endif
+moduledata_t alias_mod = {
+ "alias_ftp", mod_handler, NULL
+};
+
+#ifdef _KERNEL
+DECLARE_MODULE(alias_ftp, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
+MODULE_VERSION(alias_ftp, 1);
+MODULE_DEPEND(alias_ftp, libalias, 1, 1, 1);
#endif
#define FTP_CONTROL_PORT_NUMBER 21
@@ -112,7 +186,7 @@ static int ParseFtp227Reply(struct libalias *la, char *, int);
static int ParseFtp229Reply(struct libalias *la, char *, int);
static void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int);
-void
+static void
AliasHandleFtpOut(
struct libalias *la,
struct ip *pip, /* IP packet to examine/patch */
diff --git a/sys/netinet/libalias/alias_irc.c b/sys/netinet/libalias/alias_irc.c
index defdb561384e..e9a8d09e5861 100644
--- a/sys/netinet/libalias/alias_irc.c
+++ b/sys/netinet/libalias/alias_irc.c
@@ -50,14 +50,15 @@ __FBSDID("$FreeBSD$");
/* Includes */
#ifdef _KERNEL
#include <sys/param.h>
-#include <sys/libkern.h>
#include <sys/ctype.h>
#include <sys/limits.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
#else
+#include <errno.h>
#include <sys/types.h>
-#include <ctype.h>
#include <stdio.h>
-#include <string.h>
#include <limits.h>
#endif
@@ -69,15 +70,89 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
#else
#include "alias_local.h"
+#include "alias_mod.h"
#endif
+#define IRC_CONTROL_PORT_NUMBER_1 6667
+#define IRC_CONTROL_PORT_NUMBER_2 6668
+
/* Local defines */
#define DBprintf(a)
+static void
+AliasHandleIrcOut(struct libalias *, struct ip *, struct alias_link *,
+ int maxpacketsize);
+
+static int
+fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ah->dport == NULL || ah->dport == NULL || ah->lnk == NULL ||
+ ah->maxpktsize == 0)
+ return (-1);
+ if (ntohs(*ah->dport) == IRC_CONTROL_PORT_NUMBER_1
+ || ntohs(*ah->dport) == IRC_CONTROL_PORT_NUMBER_2)
+ return (0);
+ return (-1);
+}
+
+static int
+protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleIrcOut(la, pip, ah->lnk, ah->maxpktsize);
+ return (0);
+}
+
+struct proto_handler handlers[] = {
+ {
+ .pri = 90,
+ .dir = OUT,
+ .proto = TCP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandler
+ },
+ { EOH }
+};
+
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ LibAliasAttachHandlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ LibAliasDetachHandlers(handlers);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+#ifdef _KERNEL
+static
+#endif
+moduledata_t alias_mod = {
+ "alias_irc", mod_handler, NULL
+};
+
+/* Kernel module definition. */
+#ifdef _KERNEL
+DECLARE_MODULE(alias_irc, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
+MODULE_VERSION(alias_irc, 1);
+MODULE_DEPEND(alias_irc, libalias, 1, 1, 1);
+#endif
-void
+static void
AliasHandleIrcOut(struct libalias *la,
struct ip *pip, /* IP packet to examine */
struct alias_link *lnk, /* Which link are we on? */
diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h
index 4dc2e0a95742..1dc50c8c7c45 100644
--- a/sys/netinet/libalias/alias_local.h
+++ b/sys/netinet/libalias/alias_local.h
@@ -46,18 +46,13 @@
#ifndef _ALIAS_LOCAL_H_
#define _ALIAS_LOCAL_H_
-#include <sys/queue.h>
-
-/* Use kernel allocator. */
-#if defined(_KERNEL) && defined(_SYS_MALLOC_H_)
-MALLOC_DECLARE(M_ALIAS);
-#define malloc(x) malloc(x, M_ALIAS, M_NOWAIT|M_ZERO)
-#define calloc(x, n) malloc(x*n)
-#define free(x) free(x, M_ALIAS)
-#endif
+#include <sys/types.h>
+#include <sys/sysctl.h>
-/* XXX: LibAliasSetTarget() uses this constant. */
#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/lock.h>
+/* XXX: LibAliasSetTarget() uses this constant. */
#define INADDR_NONE 0xffffffff
#endif
@@ -116,10 +111,14 @@ struct libalias {
int deleteAllLinks; /* If equal to zero, DeleteLink() */
/* will not remove permanent links */
-#ifndef NO_LOGGING
- FILE *monitorFile; /* File descriptor for link */
+
+ /* log descriptor */
+#ifdef _KERNEL
+ char *logDesc;
+#else
+ FILE *logDesc;
#endif
- /* statistics monitoring file */
+ /* statistics monitoring */
int newDefaultLink; /* Indicates if a new aliasing */
/* link has been created after a */
@@ -296,43 +295,6 @@ void HouseKeeping(struct libalias *);
/* Tcp specfic routines */
/* lint -save -library Suppress flexelint warnings */
-/* FTP routines */
-void
-AliasHandleFtpOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk,
- int _maxpacketsize);
-
-/* IRC routines */
-void
-AliasHandleIrcOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk,
- int _maxsize);
-
-/* RTSP routines */
-void
-AliasHandleRtspOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk,
- int _maxpacketsize);
-
-/* PPTP routines */
-void AliasHandlePptpOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk);
-void AliasHandlePptpIn(struct libalias *la, struct ip *_pip, struct alias_link *_lnk);
-int AliasHandlePptpGreOut(struct libalias *la, struct ip *_pip);
-int AliasHandlePptpGreIn(struct libalias *la, struct ip *_pip);
-
-/* NetBIOS routines */
-int
-AliasHandleUdpNbt(struct libalias *la, struct ip *_pip, struct alias_link *_lnk,
- struct in_addr *_alias_address, u_short _alias_port);
-int
-AliasHandleUdpNbtNS(struct libalias *la, struct ip *_pip, struct alias_link *_lnk,
- struct in_addr *_alias_address, u_short * _alias_port,
- struct in_addr *_original_address, u_short * _original_port);
-
-/* CUSeeMe routines */
-void AliasHandleCUSeeMeOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk);
-void AliasHandleCUSeeMeIn(struct libalias *la, struct ip *_pip, struct in_addr _original_addr);
-
-/* Skinny routines */
-void AliasHandleSkinny(struct libalias *la, struct ip *_pip, struct alias_link *_lnk);
-
/* Transparent proxy routines */
int
ProxyCheck(struct libalias *la, struct ip *_pip, struct in_addr *_proxy_server_addr,
@@ -373,6 +335,4 @@ udp_next(struct udphdr *udphdr)
}
#endif
-/*lint -restore */
-
#endif /* !_ALIAS_LOCAL_H_ */
diff --git a/sys/netinet/libalias/alias_mod.c b/sys/netinet/libalias/alias_mod.c
new file mode 100644
index 000000000000..71192e981249
--- /dev/null
+++ b/sys/netinet/libalias/alias_mod.c
@@ -0,0 +1,284 @@
+/*-
+ * Copyright (c) 2005 Paolo Pisati <piso@FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+__FBSDID("$FreeBSD$");
+
+
+#ifdef _KERNEL
+#include <sys/libkern.h>
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#else
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <errno.h>
+#endif
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#ifdef _KERNEL
+#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
+#else
+#include "alias_local.h"
+#include "alias_mod.h"
+#endif
+
+/* Protocol and userland module handlers chains. */
+LIST_HEAD(handler_chain, proto_handler) handler_chain = LIST_HEAD_INITIALIZER(foo);
+#ifdef _KERNEL
+struct rwlock handler_rw;
+#endif
+SLIST_HEAD(dll_chain, dll) dll_chain = SLIST_HEAD_INITIALIZER(foo);
+
+#ifdef _KERNEL
+
+#define LIBALIAS_LOCK_INIT() \
+ rw_init(&handler_rw, "Libalias_modules_rwlock")
+#define LIBALIAS_LOCK_DESTROY() rw_destroy(&handler_rw)
+#define LIBALIAS_WLOCK_ASSERT() \
+ rw_assert(&handler_rw, RA_WLOCKED)
+
+static __inline void
+LIBALIAS_RLOCK(void)
+{
+ rw_rlock(&handler_rw);
+}
+
+static __inline void
+LIBALIAS_RUNLOCK(void)
+{
+ rw_runlock(&handler_rw);
+}
+
+static __inline void
+LIBALIAS_WLOCK(void)
+{
+ rw_wlock(&handler_rw);
+}
+
+static __inline void
+LIBALIAS_WUNLOCK(void)
+{
+ rw_wunlock(&handler_rw);
+}
+
+static void
+_handler_chain_init(void)
+{
+
+ if (!rw_initialized(&handler_rw))
+ LIBALIAS_LOCK_INIT();
+}
+
+static void
+_handler_chain_destroy(void)
+{
+
+ if (rw_initialized(&handler_rw))
+ LIBALIAS_LOCK_DESTROY();
+}
+
+#else
+#define LIBALIAS_LOCK_INIT() ;
+#define LIBALIAS_LOCK_DESTROY() ;
+#define LIBALIAS_WLOCK_ASSERT() ;
+#define LIBALIAS_RLOCK() ;
+#define LIBALIAS_RUNLOCK() ;
+#define LIBALIAS_WLOCK() ;
+#define LIBALIAS_WUNLOCK() ;
+#define _handler_chain_init() ;
+#define _handler_chain_destroy() ;
+#endif
+
+void
+handler_chain_init(void)
+{
+ _handler_chain_init();
+}
+
+void
+handler_chain_destroy(void)
+{
+ _handler_chain_destroy();
+}
+
+static int
+_attach_handler(struct proto_handler *p)
+{
+ struct proto_handler *b = NULL;
+
+ LIBALIAS_WLOCK_ASSERT();
+ LIST_FOREACH(b, &handler_chain, entries) {
+ if ((b->pri == p->pri) &&
+ (b->dir == p->dir) &&
+ (b->proto == p->proto))
+ return (EEXIST); /* Priority conflict. */
+ if (b->pri > p->pri) {
+ LIST_INSERT_BEFORE(b, p, entries);
+ return (0);
+ }
+ }
+ /* End of list or found right position, inserts here. */
+ if (b)
+ LIST_INSERT_AFTER(b, p, entries);
+ else
+ LIST_INSERT_HEAD(&handler_chain, p, entries);
+ return (0);
+}
+
+static int
+_detach_handler(struct proto_handler *p)
+{
+ struct proto_handler *b, *b_tmp;;
+
+ LIBALIAS_WLOCK_ASSERT();
+ LIST_FOREACH_SAFE(b, &handler_chain, entries, b_tmp) {
+ if (b == p) {
+ LIST_REMOVE(b, entries);
+ return (0);
+ }
+ }
+ return (ENOENT); /* Handler not found. */
+}
+
+int
+LibAliasAttachHandlers(struct proto_handler *_p)
+{
+ int i, error = -1;
+
+ LIBALIAS_WLOCK();
+ for (i=0; 1; i++) {
+ if (*((int *)&_p[i]) == EOH)
+ break;
+ error = _attach_handler(&_p[i]);
+ if (error != 0)
+ break;
+ }
+ LIBALIAS_WUNLOCK();
+ return (error);
+}
+
+int
+LibAliasDetachHandlers(struct proto_handler *_p)
+{
+ int i, error = -1;
+
+ LIBALIAS_WLOCK();
+ for (i=0; 1; i++) {
+ if (*((int *)&_p[i]) == EOH)
+ break;
+ error = _detach_handler(&_p[i]);
+ if (error != 0)
+ break;
+ }
+ LIBALIAS_WUNLOCK();
+ return (error);
+}
+
+int
+detach_handler(struct proto_handler *_p)
+{
+ int error = -1;
+
+ LIBALIAS_WLOCK();
+ error = _detach_handler(_p);
+ LIBALIAS_WUNLOCK();
+ return (error);
+}
+
+int
+find_handler(int8_t dir, int8_t proto, struct libalias *la, struct ip *pip,
+ struct alias_data *ad)
+{
+ struct proto_handler *p;
+ int error = ENOENT;
+
+ LIBALIAS_RLOCK();
+
+ LIST_FOREACH(p, &handler_chain, entries) {
+ if ((p->dir & dir) && (p->proto & proto))
+ if (p->fingerprint(la, pip, ad) == 0) {
+ error = p->protohandler(la, pip, ad);
+ break;
+ }
+ }
+ LIBALIAS_RUNLOCK();
+ return (error);
+}
+
+struct proto_handler *
+first_handler(void)
+{
+
+ return (LIST_FIRST(&handler_chain));
+}
+
+/* Dll manipulation code - this code is not thread safe... */
+
+int
+attach_dll(struct dll *p)
+{
+ struct dll *b;
+
+ SLIST_FOREACH(b, &dll_chain, next) {
+ if (!strncmp(b->name, p->name, DLL_LEN))
+ return (EEXIST); /* Dll name conflict. */
+ }
+ SLIST_INSERT_HEAD(&dll_chain, p, next);
+ return (0);
+}
+
+void *
+detach_dll(char *p)
+{
+ struct dll *b = NULL, *b_tmp;
+ void *error = NULL;
+
+ SLIST_FOREACH_SAFE(b, &dll_chain, next, b_tmp)
+ if (!strncmp(b->name, p, DLL_LEN)) {
+ SLIST_REMOVE(&dll_chain, b, dll, next);
+ error = b;
+ break;
+ }
+ return (error);
+}
+
+struct dll *
+walk_dll_chain(void)
+{
+ struct dll *t;
+
+ t = SLIST_FIRST(&dll_chain);
+ if (t == NULL)
+ return (NULL);
+ SLIST_REMOVE_HEAD(&dll_chain, next);
+ return (t);
+}
diff --git a/sys/netinet/libalias/alias_mod.h b/sys/netinet/libalias/alias_mod.h
new file mode 100644
index 000000000000..5e193e97eb5e
--- /dev/null
+++ b/sys/netinet/libalias/alias_mod.h
@@ -0,0 +1,157 @@
+/*-
+ * Copyright (c) 2005 Paolo Pisati <piso@FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$
+ */
+
+/*
+ * Alias_mod.h defines the outside world interfaces for the packet aliasing
+ * modular framework
+ */
+
+#ifndef _ALIAS_MOD_H_
+#define _ALIAS_MOD_H_
+
+#ifdef _KERNEL
+MALLOC_DECLARE(M_ALIAS);
+
+/* Use kernel allocator. */
+#if defined(_SYS_MALLOC_H_)
+#define malloc(x) malloc(x, M_ALIAS, M_NOWAIT|M_ZERO)
+#define calloc(x, n) malloc(x*n)
+#define free(x) free(x, M_ALIAS)
+#endif
+#endif
+
+/* Protocol handlers struct & function. */
+
+/* Packet flow direction. */
+#define IN 1
+#define OUT 2
+
+/* Working protocol. */
+#define IP 1
+#define TCP 2
+#define UDP 4
+
+/*
+ * Data passed to protocol handler module, it must be filled
+ * right before calling find_handler() to determine which
+ * module is elegible to be called.
+ */
+
+struct alias_data {
+ struct alias_link *lnk;
+ struct in_addr *oaddr; /* Original address. */
+ struct in_addr *aaddr; /* Alias address. */
+ uint16_t *aport; /* Alias port. */
+ uint16_t *sport, *dport; /* Source & destination port */
+ uint16_t maxpktsize; /* Max packet size. */
+};
+
+/*
+ * This structure contains all the information necessary to make
+ * a protocol handler correctly work.
+ */
+
+struct proto_handler {
+ u_int pri; /* Handler priority. */
+ int16_t dir; /* Flow direction. */
+ uint8_t proto; /* Working protocol. */
+ int (*fingerprint)(struct libalias *la, /* Fingerprint * function. */
+ struct ip *pip, struct alias_data *ah);
+ int (*protohandler)(struct libalias *la, /* Aliasing * function. */
+ struct ip *pip, struct alias_data *ah);
+ LIST_ENTRY(proto_handler) entries;
+};
+
+
+/*
+ * Used only in userland when libalias needs to keep track of all
+ * module loaded. In kernel land (kld mode) we don't need to care
+ * care about libalias modules cause it's kld to do it for us.
+ */
+
+#define DLL_LEN 32
+struct dll {
+ char name[DLL_LEN]; /* Name of module. */
+ void *handle; /*
+ * Ptr to shared obj obtained through
+ * dlopen() - use this ptr to get access
+ * to any symbols from a loaded module
+ * via dlsym().
+ */
+ SLIST_ENTRY(dll) next;
+};
+
+/* Functions used with protocol handlers. */
+
+void handler_chain_init(void);
+void handler_chain_destroy(void);
+int LibAliasAttachHandlers(struct proto_handler *);
+int LibAliasDetachHandlers(struct proto_handler *);
+int detach_handler(struct proto_handler *);
+int find_handler(int8_t, int8_t, struct libalias *,
+ struct ip *, struct alias_data *);
+struct proto_handler *first_handler(void);
+
+/* Functions used with dll module. */
+
+void dll_chain_init(void);
+void dll_chain_destroy(void);
+int attach_dll(struct dll *);
+void *detach_dll(char *);
+struct dll *walk_dll_chain(void);
+
+/* End of handlers. */
+#define EOH -1
+
+/*
+ * Some defines borrowed from sys/module.h used to compile a kld
+ * in userland as a shared lib.
+ */
+
+#ifndef _KERNEL
+typedef enum modeventtype {
+ MOD_LOAD,
+ MOD_UNLOAD,
+ MOD_SHUTDOWN,
+ MOD_QUIESCE
+} modeventtype_t;
+
+typedef struct module *module_t;
+typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *);
+
+/*
+ * Struct for registering modules statically via SYSINIT.
+ */
+typedef struct moduledata {
+ const char *name; /* module name */
+ modeventhand_t evhand; /* event handler */
+ void *priv; /* extra data */
+} moduledata_t;
+#endif
+
+#endif /* !_ALIAS_MOD_H_ */
diff --git a/sys/netinet/libalias/alias_nbt.c b/sys/netinet/libalias/alias_nbt.c
index 303cf3f9cb05..0d17870fa7ee 100644
--- a/sys/netinet/libalias/alias_nbt.c
+++ b/sys/netinet/libalias/alias_nbt.c
@@ -43,27 +43,147 @@ __FBSDID("$FreeBSD$");
/* Includes */
#ifdef _KERNEL
#include <sys/param.h>
-#include <sys/ctype.h>
-#include <sys/libkern.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
#else
+#include <errno.h>
#include <sys/types.h>
-#include <ctype.h>
#include <stdio.h>
-#include <string.h>
-#include <arpa/inet.h>
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
-#include <netinet/tcp.h>
#ifdef _KERNEL
-#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
#else
#include "alias_local.h"
+#include "alias_mod.h"
+#endif
+
+#define NETBIOS_NS_PORT_NUMBER 137
+#define NETBIOS_DGM_PORT_NUMBER 138
+
+static int
+AliasHandleUdpNbt(struct libalias *, struct ip *, struct alias_link *,
+ struct in_addr *, u_short);
+
+static int
+AliasHandleUdpNbtNS(struct libalias *, struct ip *, struct alias_link *,
+ struct in_addr *, u_short *, struct in_addr *, u_short *);
+static int
+fingerprint1(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
+ ah->aaddr == NULL || ah->aport == NULL)
+ return (-1);
+ if (ntohs(*ah->dport) == NETBIOS_DGM_PORT_NUMBER
+ || ntohs(*ah->sport) == NETBIOS_DGM_PORT_NUMBER)
+ return (0);
+ return (-1);
+}
+
+static int
+protohandler1(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleUdpNbt(la, pip, ah->lnk, ah->aaddr, *ah->aport);
+ return (0);
+}
+
+static int
+fingerprint2(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
+ ah->aaddr == NULL || ah->aport == NULL)
+ return (-1);
+ if (ntohs(*ah->dport) == NETBIOS_NS_PORT_NUMBER
+ || ntohs(*ah->sport) == NETBIOS_NS_PORT_NUMBER)
+ return (0);
+ return (-1);
+}
+
+static int
+protohandler2in(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleUdpNbtNS(la, pip, ah->lnk, ah->aaddr, ah->aport,
+ ah->oaddr, ah->dport);
+ return (0);
+}
+
+static int
+protohandler2out(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleUdpNbtNS(la, pip, ah->lnk, &pip->ip_src, ah->sport,
+ ah->aaddr, ah->aport);
+ return (0);
+}
+
+/* Kernel module definition. */
+struct proto_handler handlers[] = {
+ {
+ .pri = 130,
+ .dir = IN|OUT,
+ .proto = UDP,
+ .fingerprint = &fingerprint1,
+ .protohandler = &protohandler1
+ },
+ {
+ .pri = 140,
+ .dir = IN,
+ .proto = UDP,
+ .fingerprint = &fingerprint2,
+ .protohandler = &protohandler2in
+ },
+ {
+ .pri = 140,
+ .dir = OUT,
+ .proto = UDP,
+ .fingerprint = &fingerprint2,
+ .protohandler = &protohandler2out
+ },
+ { EOH }
+};
+
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ LibAliasAttachHandlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ LibAliasDetachHandlers(handlers);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+#ifdef _KERNEL
+static
+#endif
+moduledata_t alias_mod = {
+ "alias_nbt", mod_handler, NULL
+};
+
+#ifdef _KERNEL
+DECLARE_MODULE(alias_nbt, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
+MODULE_VERSION(alias_nbt, 1);
+MODULE_DEPEND(alias_nbt, libalias, 1, 1, 1);
#endif
typedef struct {
@@ -212,7 +332,7 @@ AliasHandleName(u_char * p, char *pmax)
#define DGM_POSITIVE_RES 0x15
#define DGM_NEGATIVE_RES 0x16
-int
+static int
AliasHandleUdpNbt(
struct libalias *la,
struct ip *pip, /* IP packet to examine/patch */
@@ -640,7 +760,7 @@ AliasHandleResource(
return ((u_char *) q);
}
-int
+static int
AliasHandleUdpNbtNS(
struct libalias *la,
struct ip *pip, /* IP packet to examine/patch */
diff --git a/sys/netinet/libalias/alias_old.c b/sys/netinet/libalias/alias_old.c
index e885fdc6f934..528f6be39fd1 100644
--- a/sys/netinet/libalias/alias_old.c
+++ b/sys/netinet/libalias/alias_old.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <sys/param.h>
+#include <sys/proc.h>
#else
#include <sys/types.h>
#include <stdlib.h>
diff --git a/sys/netinet/libalias/alias_pptp.c b/sys/netinet/libalias/alias_pptp.c
index 0ce69a4718ce..b4fd9d0d438a 100644
--- a/sys/netinet/libalias/alias_pptp.c
+++ b/sys/netinet/libalias/alias_pptp.c
@@ -39,6 +39,169 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+/* Includes */
+#ifdef _KERNEL
+#include <sys/param.h>
+#include <sys/limits.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#else
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <stdio.h>
+#endif
+
+#include <netinet/tcp.h>
+
+#ifdef _KERNEL
+#include <netinet/libalias/alias.h>
+#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
+#else
+#include "alias.h"
+#include "alias_local.h"
+#include "alias_mod.h"
+#endif
+
+#define PPTP_CONTROL_PORT_NUMBER 1723
+
+static void
+AliasHandlePptpOut(struct libalias *, struct ip *, struct alias_link *);
+
+static void
+AliasHandlePptpIn(struct libalias *, struct ip *, struct alias_link *);
+
+static int
+AliasHandlePptpGreOut(struct libalias *, struct ip *);
+
+static int
+AliasHandlePptpGreIn(struct libalias *, struct ip *);
+
+static int
+fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL)
+ return (-1);
+ if (ntohs(*ah->dport) == PPTP_CONTROL_PORT_NUMBER
+ || ntohs(*ah->sport) == PPTP_CONTROL_PORT_NUMBER)
+ return (0);
+ return (-1);
+}
+
+static int
+fingerprintgre(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ return (0);
+}
+
+static int
+protohandlerin(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandlePptpIn(la, pip, ah->lnk);
+ return (0);
+}
+
+static int
+protohandlerout(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandlePptpOut(la, pip, ah->lnk);
+ return (0);
+}
+
+static int
+protohandlergrein(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY ||
+ AliasHandlePptpGreIn(la, pip) == 0)
+ return (0);
+ return (-1);
+}
+
+static int
+protohandlergreout(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (AliasHandlePptpGreOut(la, pip) == 0)
+ return (0);
+ return (-1);
+}
+
+/* Kernel module definition. */
+struct proto_handler handlers[] = {
+ {
+ .pri = 200,
+ .dir = IN,
+ .proto = TCP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandlerin
+ },
+ {
+ .pri = 210,
+ .dir = OUT,
+ .proto = TCP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandlerout
+ },
+/*
+ * WATCH OUT!!! these 2 handlers NEED a priority of INT_MAX (highest possible)
+ * cause they will ALWAYS process packets, so they must be the last one
+ * in chain: look fingerprintgre() above.
+ */
+ {
+ .pri = INT_MAX,
+ .dir = IN,
+ .proto = IP,
+ .fingerprint = &fingerprintgre,
+ .protohandler = &protohandlergrein
+ },
+ {
+ .pri = INT_MAX,
+ .dir = OUT,
+ .proto = IP,
+ .fingerprint = &fingerprintgre,
+ .protohandler = &protohandlergreout
+ },
+ { EOH }
+};
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ LibAliasAttachHandlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ LibAliasDetachHandlers(handlers);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+#ifdef _KERNEL
+static
+#endif
+moduledata_t alias_mod = {
+ "alias_pptp", mod_handler, NULL
+};
+
+#ifdef _KERNEL
+DECLARE_MODULE(alias_pptp, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
+MODULE_VERSION(alias_pptp, 1);
+MODULE_DEPEND(alias_pptp, libalias, 1, 1, 1);
+#endif
+
/*
Alias_pptp.c performs special processing for PPTP sessions under TCP.
Specifically, watch PPTP control messages and alias the Call ID or the
@@ -65,26 +228,6 @@ __FBSDID("$FreeBSD$");
*/
-/* Includes */
-#ifdef _KERNEL
-#include <sys/param.h>
-#else
-#include <sys/types.h>
-#include <stdio.h>
-#endif
-
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#ifdef _KERNEL
-#include <netinet/libalias/alias.h>
-#include <netinet/libalias/alias_local.h>
-#else
-#include "alias_local.h"
-#endif
-
/*
* PPTP definitions
*/
@@ -153,7 +296,7 @@ typedef struct pptpCallIds *PptpCallId;
static PptpCallId AliasVerifyPptp(struct ip *, u_int16_t *);
-void
+static void
AliasHandlePptpOut(struct libalias *la,
struct ip *pip, /* IP packet to examine/patch */
struct alias_link *lnk)
@@ -225,7 +368,7 @@ AliasHandlePptpOut(struct libalias *la,
}
}
-void
+static void
AliasHandlePptpIn(struct libalias *la,
struct ip *pip, /* IP packet to examine/patch */
struct alias_link *lnk)
@@ -328,8 +471,7 @@ AliasVerifyPptp(struct ip *pip, u_int16_t * ptype)
return (PptpCallId) (hptr + 1);
}
-
-int
+static int
AliasHandlePptpGreOut(struct libalias *la, struct ip *pip)
{
GreHdr *gr;
@@ -353,8 +495,7 @@ AliasHandlePptpGreOut(struct libalias *la, struct ip *pip)
return (0);
}
-
-int
+static int
AliasHandlePptpGreIn(struct libalias *la, struct ip *pip)
{
GreHdr *gr;
diff --git a/sys/netinet/libalias/alias_proxy.c b/sys/netinet/libalias/alias_proxy.c
index f683ba095240..699e421e1920 100644
--- a/sys/netinet/libalias/alias_proxy.c
+++ b/sys/netinet/libalias/alias_proxy.c
@@ -58,30 +58,24 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/ctype.h>
#include <sys/libkern.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
#include <sys/limits.h>
#else
#include <sys/types.h>
-#include <sys/socket.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <netdb.h>
-#include <arpa/inet.h>
+#include <string.h>
#endif
-/* BSD IPV4 includes */
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
#include <netinet/tcp.h>
#ifdef _KERNEL
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
#else
+#include <arpa/inet.h>
#include "alias.h" /* Public API functions for libalias */
#include "alias_local.h" /* Functions used by alias*.c */
#endif
diff --git a/sys/netinet/libalias/alias_skinny.c b/sys/netinet/libalias/alias_skinny.c
index f109f74c4d65..91307aceab71 100644
--- a/sys/netinet/libalias/alias_skinny.c
+++ b/sys/netinet/libalias/alias_skinny.c
@@ -32,26 +32,92 @@
#ifdef _KERNEL
#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
#else
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <errno.h>
#include <stdio.h>
-#include <string.h>
#include <unistd.h>
-#include <arpa/inet.h>
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
-#include <netinet/udp.h>
#ifdef _KERNEL
-#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
#else
#include "alias_local.h"
+#include "alias_mod.h"
+#endif
+
+static void
+AliasHandleSkinny(struct libalias *, struct ip *, struct alias_link *);
+
+static int
+fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL)
+ return (-1);
+ if (la->skinnyPort != 0 && (ntohs(*ah->sport) == la->skinnyPort ||
+ ntohs(*ah->dport) == la->skinnyPort))
+ return (0);
+ return (-1);
+}
+
+static int
+protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ AliasHandleSkinny(la, pip, ah->lnk);
+ return (0);
+}
+
+struct proto_handler handlers[] = {
+ {
+ .pri = 110,
+ .dir = IN|OUT,
+ .proto = TCP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandler
+ },
+ { EOH }
+};
+
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ LibAliasAttachHandlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ LibAliasDetachHandlers(handlers);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+#ifdef _KERNEL
+static
+#endif
+moduledata_t alias_mod = {
+ "alias_skinny", mod_handler, NULL
+};
+
+#ifdef _KERNEL
+DECLARE_MODULE(alias_skinny, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
+MODULE_VERSION(alias_skinny, 1);
+MODULE_DEPEND(alias_skinny, libalias, 1, 1, 1);
#endif
/*
@@ -233,7 +299,7 @@ alias_skinny_opnrcvch_ack(struct libalias *la, struct OpenReceiveChannelAck *opn
return (0);
}
-void
+static void
AliasHandleSkinny(struct libalias *la, struct ip *pip, struct alias_link *lnk)
{
size_t hlen, tlen, dlen;
diff --git a/sys/netinet/libalias/alias_smedia.c b/sys/netinet/libalias/alias_smedia.c
index c314a65f770d..58f844b3d818 100644
--- a/sys/netinet/libalias/alias_smedia.c
+++ b/sys/netinet/libalias/alias_smedia.c
@@ -100,8 +100,11 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <sys/param.h>
-#include <sys/libkern.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
#else
+#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
@@ -111,13 +114,92 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
-#include <netinet/udp.h>
#ifdef _KERNEL
#include <netinet/libalias/alias.h>
#include <netinet/libalias/alias_local.h>
+#include <netinet/libalias/alias_mod.h>
#else
#include "alias_local.h"
+#include "alias_mod.h"
+#endif
+
+#define RTSP_CONTROL_PORT_NUMBER_1 554
+#define RTSP_CONTROL_PORT_NUMBER_2 7070
+#define TFTP_PORT_NUMBER 69
+
+static void
+AliasHandleRtspOut(struct libalias *, struct ip *, struct alias_link *,
+ int maxpacketsize);
+static int
+fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
+ ah->maxpktsize == 0)
+ return (-1);
+ if (ntohs(*ah->dport) == RTSP_CONTROL_PORT_NUMBER_1
+ || ntohs(*ah->sport) == RTSP_CONTROL_PORT_NUMBER_1
+ || ntohs(*ah->dport) == RTSP_CONTROL_PORT_NUMBER_2
+ || ntohs(*ah->sport) == RTSP_CONTROL_PORT_NUMBER_2
+ || ntohs(*ah->dport) == TFTP_PORT_NUMBER)
+ return (0);
+ return (-1);
+}
+
+static int
+protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+ if (ntohs(*ah->dport) == TFTP_PORT_NUMBER)
+ FindRtspOut(la, pip->ip_src, pip->ip_dst,
+ *ah->sport, *ah->aport, IPPROTO_UDP);
+ else AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpktsize);
+ return (0);
+}
+
+struct proto_handler handlers[] = {
+ {
+ .pri = 100,
+ .dir = OUT,
+ .proto = TCP|UDP,
+ .fingerprint = &fingerprint,
+ .protohandler = &protohandler
+ },
+ { EOH }
+};
+
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ LibAliasAttachHandlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ LibAliasDetachHandlers(handlers);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+#ifdef _KERNEL
+static
+#endif
+moduledata_t alias_mod = {
+ "alias_smedia", mod_handler, NULL
+};
+
+#ifdef _KERNEL
+DECLARE_MODULE(alias_smedia, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
+MODULE_VERSION(alias_smedia, 1);
+MODULE_DEPEND(alias_smedia, libalias, 1, 1, 1);
#endif
#define RTSP_CONTROL_PORT_NUMBER_1 554
@@ -392,7 +474,7 @@ alias_pna_out(struct libalias *la, struct ip *pip,
return (0);
}
-void
+static void
AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk, int maxpacketsize)
{
int hlen, tlen, dlen;
diff --git a/sys/netinet/libalias/alias_util.c b/sys/netinet/libalias/alias_util.c
index dc70bc12667e..4cdbaf8c1076 100644
--- a/sys/netinet/libalias/alias_util.c
+++ b/sys/netinet/libalias/alias_util.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#ifdef _KERNEL
#include <sys/param.h>
+#include <sys/proc.h>
#else
#include <sys/types.h>
#include <stdio.h>
diff --git a/sys/netinet/libalias/libalias.3 b/sys/netinet/libalias/libalias.3
index 4605e766f6aa..55a0c3ea3773 100644
--- a/sys/netinet/libalias/libalias.3
+++ b/sys/netinet/libalias/libalias.3
@@ -893,6 +893,9 @@ added support for PPTP and RTSP.
added support for RTSP/PNA.
.An Ruslan Ermilov Aq ru@FreeBSD.org
added support for PPTP and LSNAT as well as general hacking.
+.An Paolo Pisati Aq piso@FreeBSD.org
+made the library modular, moving support for all
+protocols (except for IP, TCP and UDP) to external modules.
.Sh ACKNOWLEDGMENTS
Listed below, in approximate chronological order, are individuals who
have provided valuable comments and/or debugging assistance.
@@ -1011,3 +1014,429 @@ If this results in a conflict, then port numbers are randomly chosen until
a unique aliasing link can be established.
In an alternate operating mode, the first choice of an aliasing port is also
random and unrelated to the local port number.
+.Sh MODULAR ARCHITECTURE (AND Xr ipfw 4 Sh SUPPORT)
+One of the latest improvements to
+.Nm libalias was to make its support
+for new protocols independent from the rest of the library, giving it
+the ability to load/unload at run-time support for new protocols.
+To achieve this feature, all the code for protocol handling was moved
+to a series of modules outside of the main library.
+These modules are compiled from the same sources but works in a
+different ways, depending on whether they are compiled to work inside a kernel
+or as part of the userland library.
+.Ss LIBALIAS MODULES IN KERNEL LAND
+When compiled to be parts of a kernel,
+.Nm libalias
+modules are plain simple KLDs:
+.Pp
+.Bl -item -compact
+.It
+.Pa /boot/kernel/alias_cuseeme.ko
+.It
+.Pa /boot/kernel/alias_dummy.ko
+.It
+.Pa /boot/kernel/alias_ftp.ko
+.It
+.Pa /boot/kernel/alias_irc.ko
+.It
+.Pa /boot/kernel/alias_nbt.ko
+.It
+.Pa /boot/kernel/alias_pptp.ko
+.It
+.Pa /boot/kernel/alias_skinny.ko
+.It
+.Pa /boot/kernel/alias_smedia.ko
+.El
+.Pp
+To add support for new protocol just kldload its module, for example:
+.Pp
+.Dl "kldload alias_ftp
+.Pp
+and when you don't need it anymore, you can unload it:
+.Pp
+.Dl "kldunload alias_ftp
+.Ss LIBALIAS MODULES IN USERLAND
+Due to the differences between kernel and userland (no kld mechanism,
+many different address spaces, etc etc), we had to change a bit how to
+handle modules loading/tracking/unloading in userland.
+.Pp
+While compiled for a userland
+.Nm libalias
+all the modules are plain libraries:
+.Pp
+.Bl -item -compact
+.It
+.Pa /usr/lib/libalias_cuseeme.a
+.It
+.Pa /usr/lib/libalias_cuseeme.so -> /lib/libalias_cuseeme.so.4
+.It
+.Pa /usr/lib/libalias_cuseeme_p.a
+.It
+.Pa /usr/lib/libalias_dummy.a
+.It
+.Pa /usr/lib/libalias_dummy.so -> /lib/libalias_dummy.so.4
+.It
+.Pa /usr/lib/libalias_dummy_p.a
+.It
+.Pa /usr/lib/libalias_ftp.a
+.It
+.Pa /usr/lib/libalias_ftp.so -> /lib/libalias_ftp.so.4
+.It
+.Pa /usr/lib/libalias_ftp_p.a
+.It
+.Pa /usr/lib/libalias_irc.a
+.It
+.Pa /usr/lib/libalias_irc.so -> /lib/libalias_irc.so.4
+.It
+.Pa /usr/lib/libalias_irc_p.a
+.It
+.Pa /usr/lib/libalias_nbt.a
+.It
+.Pa /usr/lib/libalias_nbt.so -> /lib/libalias_nbt.so.4
+.It
+.Pa /usr/lib/libalias_nbt_p.a
+.It
+.Pa /usr/lib/libalias_pptp.a
+.It
+.Pa /usr/lib/libalias_pptp.so -> /lib/libalias_pptp.so.4
+.It
+.Pa /usr/lib/libalias_pptp_p.a
+.It
+.Pa /usr/lib/libalias_skinny.a
+.It
+.Pa /usr/lib/libalias_skinny.so -> /lib/libalias_skinny.so.4
+.It
+.Pa /usr/lib/libalias_skinny_p.a
+.It
+.Pa /usr/lib/libalias_smedia.a
+.It
+.Pa /usr/lib/libalias_smedia.so -> /lib/libalias_smedia.so.4
+.It
+.Pa /usr/lib/libalias_smedia_p.a
+.El
+.Pp
+To take advantage of modules, an application must be
+patched to handle SIGHUP signal and call LibAliasRefreshModules()
+whenever it receives that signal (see below for details).
+.Pp
+If you have correctly installed
+.Nm libalias
+in /etc you should
+find a file called libalias.conf with the following contents (or
+similar):
+.Pp
+.Bl -item -compact
+.It
+.Pa /usr/lib/libalias_cuseeme.so
+.It
+.Pa /usr/lib/libalias_ftp.so
+.It
+.Pa /usr/lib/libalias_irc.so
+.It
+.Pa /usr/lib/libalias_nbt.so
+.It
+.Pa /usr/lib/libalias_pptp.so
+.It
+.Pa /usr/lib/libalias_skinny.so
+.It
+.Pa /usr/lib/libalias_smedia.so
+.El
+.Pp
+this file contains the paths to the modules that
+.Nm libalias
+will load.
+To load/unload a new module just add its path to libalias.conf and
+send a SIGHUP signal to the application that needs the new module:
+.Pp
+.Dl "kill -HUP <process pid>
+.Ss MODULAR ARCHITECURE: HOW IT WORKS
+The modular architecture of
+.Nm libalias
+work (almost) the same when it's
+running inside kernel or in userland. From alias_mod.c:
+.Bd -literal
+/* protocol and userland module handlers chains */
+struct chain handler_chain, dll_chain;
+
+handler_chain keep tracks of all the protocol handlers loaded, while
+ddl_chain takes care of userland modules loaded.
+
+handler_chain is composed of struct proto_handler entries:
+
+struct proto_handler {
+
+ /* handler priority */
+ int pri;
+ /* flow direction */
+ int16_t dir;
+ /* working protocol */
+ int16_t proto;
+ /* fingerprint * function */
+ int (*fingerprint)(struct libalias *la,
+ struct ip *pip, struct alias_data *ah);
+ /* aliasing * function */
+ int (*protohandler)(struct libalias *la,
+ struct ip *pip, struct alias_data *ah);
+ struct proto_handler *next;
+};
+.Ed
+.Pp
+where:
+.Pp
+pri is the priority assigned to a protocol handler, lower
+is better.
+.Pp
+dir is the direction of packets: ingoing or outgoing.
+.Pp
+proto says at which protocol this packet belongs: IP, TCP or UDP
+.Pp
+fingerprint points to the fingerprint function while protohandler points
+to the protocol handler function.
+.Pp
+The fingerprint function has the double of scope of checking if the
+incoming packet is sound and if it belongs to any categories that this
+module can handle.
+.Pp
+The protocol handler function is the function that actually manipulates
+the packet to make
+.Nm libalias
+correctly nat it.
+.Pp
+When a packet enters
+.Nm libalias
+, if it meets a module hook,
+handler_chain is searched to see if there's an handler that match
+this type of packet (it checks protocol and direction of packet), then if
+more then one handler is found, it starts with the module with
+a lower priority number: it calls fingerprints and read the result.
+.Pp
+If the result value is equal to OK, then it calls the protocol handler
+of this handler and return, else it skip to the fingerprint function
+of the next eligible module, till the end of handler_chain
+.Pp
+Inside
+.Nm libalias
+the module hook looks like this:
+.Bd -literal
+ struct alias_data ad = {
+ lnk,
+ &original_address,
+ &alias_address,
+ &alias_port,
+ &ud->uh_sport, /* original source port */
+ &ud->uh_dport, /* original dest port */
+ 256 /* maxpacketsize */
+ };
+
+ ...
+
+ /* walk out chain */
+ err = find_handler(IN, UDP, la, pip, &ad);
+.Ed
+all data useful to a module are gathered together in a alias_data
+structure, then find_handler is called.
+find_handler is the function responsible of walking out the handler
+chain, it receives as input parameters:
+.Pp
+IN: direction
+.Pp
+UDP: working protocol
+.Pp
+la: pointer to this instance of libalias
+.Pp
+pip: pointer to a struct ip
+.Pp
+ad: pointer to struct alias_data (see above)
+.Pp
+in this case, find_handler will search only for modules registered for
+supporting INcoming UDP packets.
+.Pp
+As i said earlier,
+.Nm libalias
+in userland is a bit different, cause we
+have to take care of module handling too (avoiding duplicate load of
+module, avoiding module with same name, etc etc) so dll_chain was
+introduced.
+.Pp
+dll_chain contains a list of all userland
+.Nm libalias
+modules loaded.
+.Pp
+When an application calls LibAliasRefreshModules(),
+.Nm libalias
+first unload all the loaded modules, then reload all the modules listed in
+/etc/libalias.conf: for every module loaded, a new entry to dll_chain
+is added.
+.Pp
+dll_chain is composed of struct dll entries:
+.Bd -literal
+struct dll {
+ /* name of module */
+ char name[DLL_LEN];
+ /*
+ * ptr to shared obj obtained through
+ * dlopen() - use this ptr to get access
+ * to any symbols from a loaded module
+ * via dlsym()
+ */
+ void *handle;
+ struct dll *next;
+};
+.Ed
+name is the name of the module
+.Pp
+handle is a pointer to the module obtained through dlopen()
+.Pp
+Whenever a module is loaded in userland, an entry is added to
+dll_chain, than every protocol handler present in that module
+is resolved and registered in handler_chain.
+.Ss HOW TO WRITE A MODULE FOR LIBALIAS
+There's a module (called alias_dummy.[ch]) in
+.Nm libalias
+that can be used as a skeleton for future work, here we analyse some parts of that
+module.
+From alias_dummy.c:
+.Bd -literal
+struct proto_handler handlers [] = {{666, IN|OUT, UDP|TCP,
+ &fingerprint, &protohandler}};
+.Ed
+.Pp
+The variable 'handlers' is the 'most important thing' in your module,
+cause it describes the handlers present and let the outside world use
+it in an opaque way.
+.Pp
+It must ALWAYS be present in every module, and it MUST retain
+the name 'handlers', else if you'll try to load
+this module in userland, it will complain about missing symbols: for
+more info about module load/unload, please refer to
+LibAliasRefreshModules, LibAliasLoadModule and LibAliasUnloadModule in
+alias.c
+.Pp
+handlers[] contains all the proto_handler structures present in a
+module.
+.Bd -literal
+static int
+mod_handler(module_t mod, int type, void *data)
+{
+ int error;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = 0;
+ attach_handlers(handlers);
+ break;
+ case MOD_UNLOAD:
+ error = 0;
+ detach_handlers(handlers;
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+.Ed
+When running as kld, mod_handler register/deregister the module using
+attach_handlers/detach_handlers respectively.
+.Pp
+Every module must contain at least 2 functions: one fingerprint
+function and a protocol handler function.
+.Bd -literal
+#ifdef _KERNEL
+static
+#endif
+int
+fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+{
+
+...
+}
+
+#ifdef _KERNEL
+static
+#endif
+int
+protohandler(struct libalias *la, struct ip *pip,
+ struct alias_data *ah)
+{
+
+...
+}
+.Ed
+and they must accept exactly these input parameters.
+.Ss PATCHING AN APPLICATION FOR USERLAND LIBALIAS MODULES
+If you have any application that uses
+.Nm libalias
+and you want to add it
+support for modules, then follow this simple 5 steps
+procedure.
+.Bd -ragged -offset indent
+.An -split
+.An 1) first, figure out which file is the main file of your program
+.An (let's call it main.c)
+.An 2) add this to the header section of main,c, if not already
+.An present:
+.Pp
+.An #include <signal.h>
+.Pp
+.An 3) and this just after the header section:
+.Pp
+.An static void signal_handler(int);
+.Pp
+.An 4) add this line in the init function of you program or, if it
+.An doesn't have any init function, put it in main():
+.Pp
+.An signal(SIGHUP, signal_handler);
+.Pp
+.An 5) and place this function somewhere in main.c:
+.Pp
+.An static void
+.An signal_handler(int sig)
+.An {
+.Pp
+.An LibAliasRefreshModules();
+.An }
+.Pp
+.An else, if your program already trap SIGHUP signal, just add a call
+.An to LibAliasRefreshModules() in the function serving that signal.
+.Pp
+.An For example, to patch natd to use libalias modules, just add
+.An the following line to RefreshAddr (int sig __unused):
+.Pp
+.An LibAliasRefreshModules()
+.Pp
+.An recompile and you are done.
+.Ed
+.Ss LOGGING SUPPORT IN KERNEL LAND
+.Pp
+While working as kld,
+.Nm libalias
+now have log support that
+happens on a buffer allocated inside struct libalias(from alias_local.h):
+.Bd -literal
+struct libalias {
+ ...
+
+ /* log descriptor */
+#ifdef KERNEL_LOG
+ char *logDesc; /*
+ * ptr to an auto-malloced
+ * memory buffer when libalias
+ * works as kld
+ */
+#else
+ FILE *logDesc; /*
+ * ptr to /var/log/alias.log
+ * when libalias runs as a
+ * userland lib
+ */
+#endif
+
+...
+}
+.Ed
+so all the applications using
+.Nm libalias
+, will be able to handle their
+own logs, if they want, accessing logDesc.
+Moreover, every change to log buffer is automatically added to syslog
+with facilities security and info.