1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-28 16:43:09 +00:00

Various mdoc and grammar fixes.

Approved by: glebius
Reviewed by: glebius, ru
This commit is contained in:
Paolo Pisati 2006-10-08 13:53:45 +00:00
parent 706a23745a
commit f3d9aab351
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=163127

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 04, 2006
.Dd October 1, 2006
.Dt LIBALIAS 3
.Os
.Sh NAME
@ -1016,259 +1016,217 @@ 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
.Nm
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.
the ability to load/unload support for new protocols at run-time.
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
These modules are compiled from the same sources but work in
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:
When compiled for the kernel,
.Nm
modules are plain KLDs recognizable with the "alias_" prefix.
.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
To add support for a new protocol, load the corresponding module.
For example:
.Pp
To add support for new protocol just kldload its module, for example:
.Dl "kldload alias_ftp"
.Pp
.Dl "kldload alias_ftp
When support for a protocol is no longer needed, its module can be unloaded:
.Pp
and when you don't need it anymore, you can unload it:
.Pp
.Dl "kldunload alias_ftp
.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.
Due to the differences between kernel and userland (no KLD mechanism,
many different address spaces, etc.), we had to change a bit how to
handle module loading/tracking/unloading in userland.
.Pp
While compiled for a userland
.Nm libalias
all the modules are plain libraries:
.Nm ,
all the modules are plain libraries, residing in /usr/lib, and recognizable with the "libalias_" prefix.
.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
There is a configuration file,
.Pa /etc/libalias.conf ,
with the following contents (by default):
.Bd -literal -offset indent
/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
.Ed
.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
This file contains the paths to the modules that
.Nm
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:
To load/unload a new module, just add its path to
.Pa libalias.conf
and call LibAliasRefreshModules from the program.
In case the application provides an HUP signal handler, add a call to LibAliasRefreshModules inside the handler, and everytime you want to refresh the loaded modules, send it the
.Dv SIGHUP
signal:
.Pp
.Dl "kill -HUP <process pid>
.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:
.Nm
works similar whether it is running inside the
kernel or in userland.
From
.Pa alias_mod.c :
.Bd -literal
/* Protocol and userland module handlers chains. */
LIST_HEAD(handler_chain, proto_handler) handler_chain \&...
\&...
SLIST_HEAD(dll_chain, dll) dll_chain \&...
.Ed
.Pp
.Va handler_chain
keep tracks of all the protocol handlers loaded, while
.Va ddl_chain
takes care of userland modules loaded.
.Pp
.Va handler_chain
is composed of
.Vt "struct proto_handler"
entries:
.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,
u_int pri;
int16_t dir;
uint8_t proto;
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;
int (*protohandler)(struct libalias *la,
struct ip *pip, struct alias_data *ah);
LIST_ENTRY(proto_handler) entries;
};
.Ed
.Pp
where:
.Pp
pri is the priority assigned to a protocol handler, lower
.Bl -inset
.It Va 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
.It Va dir
is the direction of packets: ingoing or outgoing.
.It Va proto
says at which protocol this packet belongs: IP, TCP or UDP.
.It Va fingerprint
points to the fingerprint function while protohandler points
to the protocol handler function.
.El
.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
The
.Va fingerprint
function has the double of scope of checking if the
incoming packet is found and if it belongs to any categories that this
module can handle.
.Pp
The protocol handler function is the function that actually manipulates
The
.Va protohandler
function actually manipulates
the packet to make
.Nm libalias
correctly nat it.
.Nm
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.
.Nm ,
if it meets a module hook,
.Va handler_chain
is searched to see if there is an handler that matches
this type of a packet (it checks protocol and direction of packet), then if
more than one handler is found, it starts with the module with
the lowest priority number: it calls the
.Va fingerprint
function and interprets 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
If the result value is equal to 0 then it calls the protocol handler
of this handler and returns.
Otherwise, it proceeds to the next eligible module until the
.Va handler_chain
is exhausted.
.Pp
Inside
.Nm libalias
.Nm ,
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 */
};
.Bd -literal -offset indent
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);
/* 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
.Pp
All data useful to a module are gathered together in an
.Vt alias_data
structure, then
.Fn find_handler
is called.
The
.Fn find_handler
function is responsible for walking out the handler
chain, it receives as input parameters:
.Bl -tag -width indent
.It Fa IN
direction
.It Fa UDP
working protocol
.It Fa la
pointer to this instance of libalias
.It Fa pip
pointer to a
.Vt "struct ip"
.It Fa ad
pointer to
.Vt "struct alias_data"
(see above)
.El
.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
In this case,
.Fn 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.
As was mentioned earlier,
.Nm
in userland is a bit different, cause
care has to be taken of module handling too (avoiding duplicate load of
module, avoiding module with same name, etc.) so
.Va dll_chain
was introduced.
.Pp
dll_chain contains a list of all userland
.Nm libalias
.Va dll_chain
contains a list of all userland
.Nm
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
When an application calls
.Fn LibAliasRefreshModules ,
.Nm
first unloads all the loaded modules, then reloads all the modules listed in
.Pa /etc/libalias.conf :
for every module loaded, a new entry to
.Va dll_chain
is added.
.Pp
dll_chain is composed of struct dll entries:
.Va dll_chain
is composed of
.Vt "struct dll"
entries:
.Bd -literal
struct dll {
/* name of module */
@ -1276,44 +1234,64 @@ struct dll {
/*
* ptr to shared obj obtained through
* dlopen() - use this ptr to get access
* to any symbols from a loaded module
* 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
};
.Ed
.Bl -inset
.It Va name
is the name of the module
.It Va handle
is a pointer to the module obtained through
.Xr dlopen 3
.El
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.
.Va dll_chain ,
then every protocol handler present in that module
is resolved and registered in
.Va handler_chain .
.Ss HOW TO WRITE A MODULE FOR LIBALIAS
There's a module (called alias_dummy.[ch]) in
.Nm libalias
There is a module (called
.Pa alias_dummy.[ch] )
in
.Nm
that can be used as a skeleton for future work, here we analyse some parts of that
module.
From alias_dummy.c:
From
.Pa 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
The variable
.Va handlers
is the
.Dq "most important thing"
in a module
cause it describes the handlers present and lets 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
the name
.Va handlers ,
otherwise attempting to load a module in userland will fail and
complain about missing symbols: for more information about module
load/unload, please refer to
.Fn LibAliasRefreshModules ,
.Fn LibAliasLoadModule
and
.Fn LibAliasUnloadModule
in
.Pa alias.c .
.Pp
handlers[] contains all the proto_handler structures present in a
module.
.Va handlers
contains all the
.Vt proto_handler
structures present in a module.
.Bd -literal
static int
mod_handler(module_t mod, int type, void *data)
@ -1335,8 +1313,13 @@ mod_handler(module_t mod, int type, void *data)
return (error);
}
.Ed
When running as kld, mod_handler register/deregister the module using
attach_handlers/detach_handlers respectively.
When running as KLD,
.Fn mod_handler
register/deregister the module using
.Fn attach_handlers
and
.Fn detach_handlers ,
respectively.
.Pp
Every module must contain at least 2 functions: one fingerprint
function and a protocol handler function.
@ -1348,7 +1331,7 @@ int
fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
{
...
\&...
}
#ifdef _KERNEL
@ -1359,59 +1342,73 @@ 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:
To add module support into an application that uses
.Nm ,
the following simple steps can be followed.
.Bl -enum
.It
Find the main file of an application
(let us call it
.Pa main.c ) .
.It
Add this to the header section of
.Pa main.c ,
if not already present:
.Pp
.An #include <signal.h>
.Dl "#include <signal.h>"
.Pp
.An 3) and this just after the header section:
and this just after the header section:
.Pp
.An static void signal_handler(int);
.Dl "static void signal_handler(int);"
.It
Add the following line to the init function of an application or,
if it does not have any init function, put it in
.Fn main :
.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():
.Dl "signal(SIGHUP, signal_handler);"
.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.
and place the
.Fn signal_handler
function somewhere in
.Pa main.c :
.Bd -literal -offset indent
static void
signal_handler(int sig)
{
LibAliasRefreshModules();
}
.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):
Otherwise, if an application already traps the
.Dv SIGHUP
signal, just add a call to
.Fn LibAliasRefreshModules
in the signal handler function.
.El
For example, to patch
.Xr natd 8
to use
.Nm
modules, just add the following line to
.Fn RefreshAddr "int sig __unused" :
.Pp
.Dl "LibAliasRefreshModules()"
.Pp
recompile and you are done.
.Ss LOGGING SUPPORT IN KERNEL LAND
When working as KLD,
.Nm
now has log support that
happens on a buffer allocated inside
.Vt "struct libalias"
(from
.Pa alias_local.h ) :
.Bd -literal
struct libalias {
...
@ -1431,12 +1428,18 @@ struct libalias {
*/
#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.
so all applications using
.Nm
will be able to handle their
own logs, if they want, accessing
.Va logDesc .
Moreover, every change to a log buffer is automatically added to
.Xr syslog 3
with the
.Dv LOG_SECURITY
facility and the
.Dv LOG_INFO
level.