Summer of Code 2005: improve libalias - part 1 of 2
With the first part of my previous Summer of Code work, we get: -made libalias modular: -support for 'particular' protocols (like ftp/irc/etcetc) is no more hardcoded inside libalias, but it's available through external modules loadable at runtime -modules are available both in kernel (/boot/kernel/alias_*.ko) and user land (/lib/libalias_*) -protocols/applications modularized are: cuseeme, ftp, irc, nbt, pptp, skinny and smedia -added logging support for kernel side -cleanup After a buildworld, do a 'mergemaster -i' to install the file libalias.conf in /etc or manually copy it. During startup (and after every HUP signal) user land applications running the new libalias will try to read a file in /etc called libalias.conf: that file contains the list of modules to load. User land applications affected by this commit are ppp and natd: if libalias.conf is present in /etc you won't notice any difference. The only kernel land bit affected by this commit is ng_nat: if you are using ng_nat, and it doesn't correctly handle ftp/irc/etcetc sessions anymore, remember to kldload the correspondent module (i.e. kldload alias_ftp). General information and details about the inner working are available in the libalias man page under the section 'MODULAR ARCHITECTURE (AND ipfw(4) SUPPORT)'. NOTA BENE: this commit affects _ONLY_ libalias, ipfw in-kernel nat support will be part of the next libalias-related commit. Approved by: glebius Reviewed by: glebius, ru
This commit is contained in:
parent
e502090edb
commit
5582e56d9d
@ -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 \
|
||||
|
8
etc/libalias.conf
Normal file
8
etc/libalias.conf
Normal file
@ -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
|
@ -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>
|
||||
|
13
lib/libalias/libalias/Makefile
Normal file
13
lib/libalias/libalias/Makefile
Normal file
@ -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>
|
7
lib/libalias/modules/Makefile
Normal file
7
lib/libalias/modules/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include "../../../sys/modules/libalias/modules/modules.inc"
|
||||
|
||||
SUBDIR= ${MODULES}
|
||||
|
||||
.include <bsd.subdir.mk>
|
7
lib/libalias/modules/Makefile.inc
Normal file
7
lib/libalias/modules/Makefile.inc
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../sys/netinet/libalias
|
||||
|
||||
SHLIBDIR?= /lib
|
||||
SHLIB_MAJOR= 4
|
||||
WARNS?= 1
|
6
lib/libalias/modules/cuseeme/Makefile
Normal file
6
lib/libalias/modules/cuseeme/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= alias_cuseeme
|
||||
SRCS= alias_cuseeme.c
|
||||
|
||||
.include <bsd.lib.mk>
|
6
lib/libalias/modules/dummy/Makefile
Normal file
6
lib/libalias/modules/dummy/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= alias_dummy
|
||||
SRCS= alias_dummy.c
|
||||
|
||||
.include <bsd.lib.mk>
|
6
lib/libalias/modules/ftp/Makefile
Normal file
6
lib/libalias/modules/ftp/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= alias_ftp
|
||||
SRCS= alias_ftp.c
|
||||
|
||||
.include <bsd.lib.mk>
|
6
lib/libalias/modules/irc/Makefile
Normal file
6
lib/libalias/modules/irc/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= alias_irc
|
||||
SRCS= alias_irc.c
|
||||
|
||||
.include <bsd.lib.mk>
|
6
lib/libalias/modules/nbt/Makefile
Normal file
6
lib/libalias/modules/nbt/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= alias_nbt
|
||||
SRCS= alias_nbt.c
|
||||
|
||||
.include <bsd.lib.mk>
|
6
lib/libalias/modules/pptp/Makefile
Normal file
6
lib/libalias/modules/pptp/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= alias_pptp
|
||||
SRCS= alias_pptp.c
|
||||
|
||||
.include <bsd.lib.mk>
|
6
lib/libalias/modules/skinny/Makefile
Normal file
6
lib/libalias/modules/skinny/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= alias_skinny
|
||||
SRCS= alias_skinny.c
|
||||
|
||||
.include <bsd.lib.mk>
|
6
lib/libalias/modules/smedia/Makefile
Normal file
6
lib/libalias/modules/smedia/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= alias_smedia
|
||||
SRCS= alias_smedia.c
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
8
sys/modules/libalias/libalias/Makefile
Normal file
8
sys/modules/libalias/libalias/Makefile
Normal file
@ -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>
|
7
sys/modules/libalias/modules/Makefile
Normal file
7
sys/modules/libalias/modules/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include "modules.inc"
|
||||
|
||||
SUBDIR= ${MODULES}
|
||||
|
||||
.include <bsd.subdir.mk>
|
3
sys/modules/libalias/modules/Makefile.inc
Normal file
3
sys/modules/libalias/modules/Makefile.inc
Normal file
@ -0,0 +1,3 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../netinet/libalias
|
6
sys/modules/libalias/modules/cuseeme/Makefile
Normal file
6
sys/modules/libalias/modules/cuseeme/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= alias_cuseeme
|
||||
SRCS= alias_cuseeme.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
6
sys/modules/libalias/modules/dummy/Makefile
Normal file
6
sys/modules/libalias/modules/dummy/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= alias_dummy
|
||||
SRCS= alias_dummy.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
6
sys/modules/libalias/modules/ftp/Makefile
Normal file
6
sys/modules/libalias/modules/ftp/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= alias_ftp
|
||||
SRCS= alias_ftp.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
6
sys/modules/libalias/modules/irc/Makefile
Normal file
6
sys/modules/libalias/modules/irc/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= alias_irc
|
||||
SRCS= alias_irc.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
11
sys/modules/libalias/modules/modules.inc
Normal file
11
sys/modules/libalias/modules/modules.inc
Normal file
@ -0,0 +1,11 @@
|
||||
# $FreeBSD$
|
||||
|
||||
MODULES =
|
||||
MODULES += cuseeme
|
||||
MODULES += dummy
|
||||
MODULES += ftp
|
||||
MODULES += irc
|
||||
MODULES += nbt
|
||||
MODULES += pptp
|
||||
MODULES += skinny
|
||||
MODULES += smedia
|
6
sys/modules/libalias/modules/nbt/Makefile
Normal file
6
sys/modules/libalias/modules/nbt/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= alias_nbt
|
||||
SRCS= alias_nbt.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
6
sys/modules/libalias/modules/pptp/Makefile
Normal file
6
sys/modules/libalias/modules/pptp/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= alias_pptp
|
||||
SRCS= alias_pptp.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
6
sys/modules/libalias/modules/skinny/Makefile
Normal file
6
sys/modules/libalias/modules/skinny/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= alias_skinny
|
||||
SRCS= alias_skinny.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
6
sys/modules/libalias/modules/smedia/Makefile
Normal file
6
sys/modules/libalias/modules/smedia/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= alias_smedia
|
||||
SRCS= alias_smedia.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -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;
|
||||
|
||||
/* 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);
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
|
||||
/* 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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
@ -2488,6 +2504,9 @@ LibAliasInit(struct libalias *la)
|
||||
| PKT_ALIAS_RESET_ON_ADDR_CHANGE;
|
||||
#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) {
|
||||
|
153
sys/netinet/libalias/alias_dummy.c
Normal file
153
sys/netinet/libalias/alias_dummy.c
Normal file
@ -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. */
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
void
|
||||
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
|
||||
|
||||
static void
|
||||
AliasHandleIrcOut(struct libalias *la,
|
||||
struct ip *pip, /* IP packet to examine */
|
||||
struct alias_link *lnk, /* Which link are we on? */
|
||||
|
@ -46,18 +46,13 @@
|
||||
#ifndef _ALIAS_LOCAL_H_
|
||||
#define _ALIAS_LOCAL_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.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
|
||||
|
||||
/* 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_ */
|
||||
|
284
sys/netinet/libalias/alias_mod.c
Normal file
284
sys/netinet/libalias/alias_mod.c
Normal file
@ -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);
|
||||
}
|
157
sys/netinet/libalias/alias_mod.h
Normal file
157
sys/netinet/libalias/alias_mod.h
Normal file
@ -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_ */
|
@ -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 */
|
||||
|
@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user