Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
LIBALIAS(3)		    Library Functions Manual		   LIBALIAS(3)

NAME
       libalias	 --  packet  aliasing library for masquerading and network ad-
       dress translation

SYNOPSIS
       #include	<sys/types.h>
       #include	<netinet/in.h>
       #include	<alias.h>

       Function	prototypes are given in	the main body of the text.

DESCRIPTION
       The libalias library is a collection of functions for aliasing and  de-
       aliasing	 of  IP	packets, intended for masquerading and network address
       translation (NAT).

INTRODUCTION
       This library is a moderately portable set of functions designed to  as-
       sist in the process of IP masquerading and network address translation.
       Outgoing	 packets  from	a local	network	with unregistered IP addresses
       can be aliased to appear	as if they came	from an	accessible IP address.
       Incoming	packets	are then de-aliased so that they are sent to the  cor-
       rect machine on the local network.

       A  certain  amount of flexibility is built into the packet aliasing en-
       gine.  In the simplest mode of operation, a many-to-one address mapping
       takes place between the local network and  the  packet  aliasing	 host.
       This is known as	IP masquerading.  In addition, one-to-one mappings be-
       tween  local  and  public  addresses  can also be implemented, which is
       known as	static NAT.  In	between	these extremes,	 different  groups  of
       private addresses can be	linked to different public addresses, compris-
       ing  several  distinct  many-to-one mappings.  Also, a given public ad-
       dress and port can be statically	redirected to a	private	address/port.

INITIALIZATION AND CONTROL
       One special function, LibAliasInit(), must always be called before  any
       packet  handling	 may  be  performed, and the returned instance pointer
       must  be	 passed	 to  all   the	 other	 functions.    Normally,   the
       LibAliasSetAddress()  function is called	afterwards, to set the default
       aliasing	address.  In addition, the operating mode of the packet	alias-
       ing engine can be customized by calling LibAliasSetMode().

       struct libalias * LibAliasInit(struct libalias *)

	     This function is used to initialize internal data structures.
	     When called the first time, a NULL	pointer	should be passed as an
	     argument.	The following mode bits	are always set after calling
	     LibAliasInit().  See the description of LibAliasSetMode() below
	     for the meaning of	these mode bits.

		   PKT_ALIAS_SAME_PORTS
		   PKT_ALIAS_USE_SOCKETS
		   PKT_ALIAS_RESET_ON_ADDR_CHANGE

	     This function will	always return the packet aliasing engine to
	     the same initial state.  The LibAliasSetAddress() function	is
	     normally called afterwards, and any desired changes from the de-
	     fault mode	bits listed above require a call to LibAliasSetMode().

	     It	is mandatory that this function	be called at the beginning of
	     a program prior to	any packet handling.

       void LibAliasUninit(struct libalias *)

	     This function has no return value and is used to clear any	re-
	     sources attached to internal data structures.

	     This function should be called when a program stops using the
	     aliasing engine; amongst other things, it clears out any firewall
	     holes.  To	provide	backwards compatibility	and extra security, it
	     is	added to the atexit(3) chain by	LibAliasInit().

       void LibAliasSetAddress(struct libalias *, struct in_addr addr)

	     This function sets	the source address to which outgoing packets
	     from the local area network are aliased.  All outgoing packets
	     are re-mapped to this address unless overridden by	a static ad-
	     dress mapping established by LibAliasRedirectAddr().  If this
	     function has not been called, and no static rules match, an out-
	     going packet retains its source address.

	     If	the PKT_ALIAS_RESET_ON_ADDR_CHANGE mode	bit is set (the	de-
	     fault mode	of operation), then the	internal aliasing link tables
	     will be reset any time the	aliasing address changes.  This	is
	     useful for	interfaces such	as ppp(8), where the IP	address	may or
	     may not change on successive dial-up attempts.

	     If	the PKT_ALIAS_RESET_ON_ADDR_CHANGE mode	bit is set to zero,
	     this function can also be used to dynamically change the aliasing
	     address on	a packet-to-packet basis (it is	a low overhead call).

	     It	is mandatory that this function	be called prior	to any packet
	     handling.

       unsigned	int LibAliasSetMode(struct libalias  *,	 unsigned  int	flags,
       unsigned	int mask)

	     This function sets	or clears mode bits according to the value of
	     flags.  Only bits marked in mask are affected.  The following
	     mode bits are defined in <alias.h>:

	     PKT_ALIAS_LOG
		     Enables logging into /var/log/alias.log.  Each time an
		     aliasing link is created or deleted, the log file is ap-
		     pended to with the	current	number of ICMP,	TCP and	UDP
		     links.  Mainly useful for debugging when the log file is
		     viewed continuously with tail(1).

	     PKT_ALIAS_DENY_INCOMING
		     If	this mode bit is set, all incoming packets associated
		     with new TCP connections or new UDP transactions will be
		     marked for	being ignored (LibAliasIn() returns
		     PKT_ALIAS_IGNORED code) by	the calling program.  Response
		     packets to	connections or transactions initiated from the
		     packet aliasing host or local network will	be unaffected.
		     This mode bit is useful for implementing a	one-way	fire-
		     wall.

	     PKT_ALIAS_SAME_PORTS
		     If	this mode bit is set, the packet-aliasing engine will
		     attempt to	leave the alias	port numbers unchanged from
		     the actual	local port numbers.  This can be done as long
		     as	the quintuple (proto, alias addr, alias	port, remote
		     addr, remote port)	is unique.  If a conflict exists, a
		     new aliasing port number is chosen	even if	this mode bit
		     is	set.

	     PKT_ALIAS_USE_SOCKETS
		     This bit should be	set when the packet aliasing host
		     originates	network	traffic	as well	as forwards it.	 When
		     the packet	aliasing host is waiting for a connection from
		     an	unknown	host address or	unknown	port number (e.g. an
		     FTP data connection), this	mode bit specifies that	a
		     socket be allocated as a place holder to prevent port
		     conflicts.	 Once a	connection is established, usually
		     within a minute or	so, the	socket is closed.

	     PKT_ALIAS_UNREGISTERED_ONLY
		     If	this mode bit is set, traffic on the local network
		     which does	not originate from unregistered	address	spaces
		     will be ignored.  Standard	Class A, B and C unregistered
		     addresses are:

		     10.0.0.0	  ->  10.255.255.255   (Class A	subnet)
		     172.16.0.0	  ->  172.31.255.255   (Class B	subnets)
		     192.168.0.0  ->  192.168.255.255  (Class C	subnets)

		     This option is useful in the case that the	packet alias-
		     ing host has both registered and unregistered subnets on
		     different interfaces.  The	registered subnet is fully ac-
		     cessible to the outside world, so traffic from it does
		     not need to be passed through the packet aliasing engine.

	     PKT_ALIAS_UNREGISTERED_CGN
		     Like PKT_ALIAS_UNREGISTERED_ONLY, but includes the	RFC
		     6598 (Carrier Grade NAT) subnet as	follows:

		     100.64.0.0	  ->  100.127.255.255  (RFC 6598 subnet)

	     PKT_ALIAS_RESET_ON_ADDR_CHANGE
		     When this mode bit	is set and LibAliasSetAddress()	is
		     called to change the aliasing address, the	internal link
		     table of the packet aliasing engine will be cleared.
		     This operating mode is useful for ppp(8) links where the
		     interface address can sometimes change or remain the same
		     between dial-up attempts.	If this	mode bit is not	set,
		     the link table will never be reset	in the event of	an ad-
		     dress change.

	     PKT_ALIAS_PUNCH_FW
		     This option makes libalias	"punch holes" in an
		     ipfirewall(4) - based firewall for	FTP/IRC	DCC connec-
		     tions.  The holes punched are bound by from/to IP address
		     and port; it will not be possible to use a	hole for an-
		     other connection.	A hole is removed when the connection
		     that uses it dies.	 To cater to unexpected	death of a
		     program using libalias (e.g. kill -9), changing the state
		     of	the flag will clear the	entire firewall	range allo-
		     cated for holes.  This clearing will also happen on the
		     initial call to LibAliasSetFWBase(), which	must happen
		     prior to setting this flag.

	     PKT_ALIAS_REVERSE
		     This option makes libalias	reverse	the way	it handles in-
		     coming and	outgoing packets, allowing it to be fed	with
		     data that passes through the internal interface rather
		     than the external one.

	     PKT_ALIAS_PROXY_ONLY
		     This option tells libalias	to obey	transparent proxy
		     rules only.  Normal packet	aliasing is not	performed.
		     See LibAliasProxyRule() below for details.

	     PKT_ALIAS_SKIP_GLOBAL
		     This option is used by ipfw_nat only.  Specifying it as a
		     flag to LibAliasSetMode() has no effect.  See section
		     "NETWORK ADDRESS TRANSLATION" in ipfw(8) for more de-
		     tails.

       void  LibAliasSetFWBase(struct  libalias	*, unsigned int	base, unsigned
       int num)

	     Set the firewall range allocated for punching firewall holes
	     (with the PKT_ALIAS_PUNCH_FW flag).  The range is cleared for all
	     rules on initialization.

       void LibAliasSkinnyPort(struct libalias *, unsigned int port)

	     Set the TCP port used by the Skinny Station protocol.  Skinny is
	     used by Cisco IP phones to	communicate with Cisco Call Managers
	     to	set up voice over IP calls.  If	this is	not set, Skinny	alias-
	     ing will not be done.  The	typical	port used by Skinny is 2000.

PACKET HANDLING
       The packet handling functions are used to modify	 incoming  (remote  to
       local)  and outgoing (local to remote) packets.	The calling program is
       responsible for receiving and sending packets via network interfaces.

       Along with LibAliasInit() and LibAliasSetAddress(), the two packet han-
       dling functions,	LibAliasIn() and LibAliasOut(),	comprise  the  minimal
       set of functions	needed for a basic IP masquerading implementation.

       int LibAliasIn(struct libalias *, void *buffer, int maxpacketsize)

	     An	incoming packet	coming from a remote machine to	the local net-
	     work is de-aliased	by this	function.  The IP packet is pointed to
	     by	buffer,	and maxpacketsize indicates the	size of	the data
	     structure containing the packet and should	be at least as large
	     as	the actual packet size.

	     Return codes:

	     PKT_ALIAS_OK
		     The packet	aliasing process was successful.

	     PKT_ALIAS_IGNORED
		     The packet	was ignored and	not de-aliased.	 This can hap-
		     pen if the	protocol is unrecognized, as for an ICMP mes-
		     sage type that is not handled, or if incoming packets for
		     new connections are being ignored (if the
		     PKT_ALIAS_DENY_INCOMING mode bit was set using
		     LibAliasSetMode()).

	     PKT_ALIAS_UNRESOLVED_FRAGMENT
		     This is returned when a fragment cannot be	resolved be-
		     cause the header fragment has not been sent yet.  In this
		     situation,	fragments must be saved	with
		     LibAliasSaveFragment() until a header fragment is found.

	     PKT_ALIAS_FOUND_HEADER_FRAGMENT
		     The packet	aliasing process was successful, and a header
		     fragment was found.  This is a signal to retrieve any un-
		     resolved fragments	with LibAliasGetFragment() and de-
		     alias them	with LibAliasFragmentIn().

	     PKT_ALIAS_ERROR
		     An	internal error within the packet aliasing engine oc-
		     curred.

       int LibAliasOut(struct libalias *, void *buffer,	int maxpacketsize)

	     An	outgoing packet	coming from the	local network to a remote ma-
	     chine is aliased by this function.	 The IP	packet is pointed to
	     by	buffer,	and maxpacketsize indicates the	maximum	packet size
	     permissible should	the packet length be changed.  IP encoding
	     protocols place address and port information in the encapsulated
	     data stream which has to be modified and can account for changes
	     in	packet length.	Well known examples of such protocols are FTP
	     and IRC DCC.

	     Return codes:

	     PKT_ALIAS_OK
		     The packet	aliasing process was successful.

	     PKT_ALIAS_IGNORED
		     The packet	was ignored and	not aliased.  This can happen
		     if	the protocol is	unrecognized, or possibly an ICMP mes-
		     sage type is not handled.

	     PKT_ALIAS_ERROR
		     An	internal error within the packet aliasing engine oc-
		     curred.

PORT AND ADDRESS REDIRECTION
       The  functions  described  in  this section allow machines on the local
       network to be accessible	in some	degree	to  new	 incoming  connections
       from the	external network.  Individual ports can	be re-mapped or	static
       network address translations can	be designated.

       struct	  alias_link	 *     LibAliasRedirectPort(struct libalias *,
       struct in_addr local_addr,			   u_short local_port,
       struct in_addr remote_addr,			  u_short remote_port,
       struct in_addr alias_addr, u_short alias_port, u_char proto)

	     This function specifies that traffic from a given remote ad-
	     dress/port	to an alias address/port be redirected to a specified
	     local address/port.  The parameter	proto can be either
	     IPPROTO_TCP or IPPROTO_UDP, as defined in <netinet/in.h>.

	     If	local_addr or alias_addr is zero, this indicates that the
	     packet aliasing address as	established by LibAliasSetAddress() is
	     to	be used.  Even if LibAliasSetAddress() is called to change the
	     address after LibAliasRedirectPort() is called, a zero reference
	     will track	this change.

	     If	the link is further set	up to operate with load	sharing, then
	     local_addr	and local_port are ignored, and	are selected dynami-
	     cally from	the server pool, as described in LibAliasAddServer()
	     below.

	     If	remote_addr is zero, this indicates to redirect	packets	from
	     any remote	address.  Likewise, if remote_port is zero, this indi-
	     cates to redirect packets originating from	any remote port	num-
	     ber.  The remote port specification will almost always be zero,
	     but non-zero remote addresses can sometimes be useful for fire-
	     walling.  If two calls to LibAliasRedirectPort() overlap in their
	     address/port specifications, then the most	recent call will have
	     precedence.

	     This function returns a pointer which can subsequently be used by
	     LibAliasRedirectDelete().	If NULL	is returned, then the function
	     call did not complete successfully.

	     All port numbers should be	in network address byte	order, so it
	     is	necessary to use htons(3) to convert these parameters from in-
	     ternally readable numbers to network byte order.  Addresses are
	     also in network byte order, which is implicit in the use of the
	     struct in_addr data type.

       struct	  alias_link	 *     LibAliasRedirectAddr(struct libalias *,
       struct in_addr local_addr, struct in_addr alias_addr)

	     This function designates that all incoming	traffic	to alias_addr
	     be	redirected to local_addr.  Similarly, all outgoing traffic
	     from local_addr is	aliased	to alias_addr.

	     If	local_addr or alias_addr is zero, this indicates that the
	     packet aliasing address as	established by LibAliasSetAddress() is
	     to	be used.  Even if LibAliasSetAddress() is called to change the
	     address after LibAliasRedirectAddr() is called, a zero reference
	     will track	this change.

	     If	the link is further set	up to operate with load	sharing, then
	     the local_addr argument is	ignored, and is	selected dynamically
	     from the server pool, as described	in LibAliasAddServer() below.

	     If	subsequent calls to LibAliasRedirectAddr() use the same	alias-
	     ing address, all new incoming traffic to this aliasing address
	     will be redirected	to the local address made in the last function
	     call.  New	traffic	generated by any of the	local machines,	desig-
	     nated in the several function calls, will be aliased to the same
	     address.  Consider	the following example:

	     LibAliasRedirectAddr(la, inet_aton("192.168.0.2"),
				     inet_aton("141.221.254.101"));
	     LibAliasRedirectAddr(la, inet_aton("192.168.0.3"),
				     inet_aton("141.221.254.101"));
	     LibAliasRedirectAddr(la, inet_aton("192.168.0.4"),
				     inet_aton("141.221.254.101"));

	     Any outgoing connections such as telnet(1)	or ftp(1) from
	     192.168.0.2, 192.168.0.3 and 192.168.0.4 will appear to come from
	     141.221.254.101.  Any incoming connections	to 141.221.254.101
	     will be directed to 192.168.0.4.

	     Any calls to LibAliasRedirectPort() will have precedence over ad-
	     dress mappings designated by LibAliasRedirectAddr().

	     This function returns a pointer which can subsequently be used by
	     LibAliasRedirectDelete().	If NULL	is returned, then the function
	     call did not complete successfully.

       int    LibAliasAddServer(struct libalias	*,    struct alias_link	*link,
       struct in_addr addr, u_short port)

	     This function sets	the link up for	Load Sharing using IP Network
	     Address Translation (RFC 2391, LSNAT).  LSNAT operates as fol-
	     lows.  A client attempts to access	a server by using the server
	     virtual address.  The LSNAT router	transparently redirects	the
	     request to	one of the hosts in the	server pool, using a real-time
	     load sharing algorithm.  Multiple sessions	may be initiated from
	     the same client, and each session could be	directed to a differ-
	     ent host based on the load	balance	across server pool hosts when
	     the sessions are initiated.  If load sharing is desired for just
	     a few specific services, the configuration	on LSNAT could be de-
	     fined to restrict load sharing to just the	services desired.

	     Currently,	only the simplest selection algorithm is implemented,
	     where a host is selected on a round-robin basis only, without re-
	     gard to load on the host.

	     First, the	link is	created	by either LibAliasRedirectPort() or
	     LibAliasRedirectAddr().  Then, LibAliasAddServer()	is called mul-
	     tiple times to add	entries	to the link's server pool.

	     For links created with LibAliasRedirectAddr(), the	port argument
	     is	ignored	and could have any value, e.g. htons(~0).

	     This function returns 0 on	success, -1 otherwise.

       int LibAliasRedirectDynamic(struct libalias *, struct alias_link	*link)

	     This function marks the specified static redirect rule entered by
	     LibAliasRedirectPort() as dynamic.	 This can be used to e.g. dy-
	     namically redirect	a single TCP connection, after which the rule
	     is	removed.  Only fully specified links can be made dynamic.
	     (See the "STATIC AND DYNAMIC LINKS" and "PARTIALLY	SPECIFIED
	     ALIASING LINKS" sections below for	a definition of	static vs. dy-
	     namic, and	partially vs. fully specified links.)

	     This function returns 0 on	success, -1 otherwise.

       void LibAliasRedirectDelete(struct libalias *, struct alias_link	*link)

	     This function will	delete a specific static redirect rule entered
	     by	LibAliasRedirectPort() or LibAliasRedirectAddr().  The parame-
	     ter link is the pointer returned by either	of the redirection
	     functions.	 If an invalid pointer is passed to
	     LibAliasRedirectDelete(), then a program crash or unpredictable
	     operation could result, so	care is	needed when using this func-
	     tion.

       int LibAliasProxyRule(struct libalias *,	const char *cmd)

	     The passed	cmd string consists of one or more pairs of words.
	     The first word in each pair is a token and	the second is the
	     value that	should be applied for that token.  Tokens and their
	     argument types are	as follows:

	     type encode_ip_hdr	| encode_tcp_stream | no_encode
		     In	order to support transparent proxying, it is necessary
		     to	somehow	pass the original address and port information
		     into the new destination server.  If encode_ip_hdr	is
		     specified,	the original destination address and port are
		     passed as an extra	IP option.  If encode_tcp_stream is
		     specified,	the original destination address and port are
		     passed as the first piece of data in the TCP stream in
		     the format	"DEST IP port".

	     port portnum
		     Only packets with the destination port portnum are	prox-
		     ied.

	     server host[:portnum]
		     This specifies the	host and portnum that the data is to
		     be	redirected to.	host must be an	IP address rather than
		     a DNS host	name.  If portnum is not specified, the	desti-
		     nation port number	is not changed.

		     The server	specification is mandatory unless the delete
		     command is	being used.

	     rule index
		     Normally, each call to LibAliasProxyRule()	inserts	the
		     next rule at the start of a linear	list of	rules.	If an
		     index is specified, the new rule will be checked after
		     all rules with lower indices.  Calls to
		     LibAliasProxyRule() that do not specify a rule are	as-
		     signed rule 0.

	     delete index
		     This token	and its	argument MUST NOT be used with any
		     other tokens.  When used, all existing rules with the
		     given index are deleted.

	     proto tcp | udp
		     If	specified, only	packets	of the given protocol type are
		     matched.

	     src IP[/bits]
		     If	specified, only	packets	with a source address matching
		     the given IP are matched.	If bits	is also	specified,
		     then the first bits bits of IP are	taken as a network
		     specification, and	all IP addresses from that network
		     will be matched.

	     dst IP[/bits]
		     If	specified, only	packets	with a destination address
		     matching the given	IP are matched.	 If bits is also spec-
		     ified, then the first bits	bits of	IP are taken as	a net-
		     work specification, and all IP addresses from that	net-
		     work will be matched.

	     This function is usually used to redirect outgoing	connections
	     for internal machines that	are not	permitted certain types	of in-
	     ternet access, or to restrict access to certain external ma-
	     chines.

       struct	 alias_link	*     LibAliasRedirectProto(struct libalias *,
       struct in_addr local_addr,		   struct in_addr remote_addr,
       struct in_addr alias_addr, u_char proto)

	     This function specifies that any IP packet	with protocol number
	     of	proto from a given remote address to an	alias address will be
	     redirected	to a specified local address.

	     If	local_addr or alias_addr is zero, this indicates that the
	     packet aliasing address as	established by LibAliasSetAddress() is
	     to	be used.  Even if LibAliasSetAddress() is called to change the
	     address after LibAliasRedirectProto() is called, a	zero reference
	     will track	this change.

	     If	remote_addr is zero, this indicates to redirect	packets	from
	     any remote	address.  Non-zero remote addresses can	sometimes be
	     useful for	firewalling.

	     If	two calls to LibAliasRedirectProto() overlap in	their address
	     specifications, then the most recent call will have precedence.

	     This function returns a pointer which can subsequently be used by
	     LibAliasRedirectDelete().	If NULL	is returned, then the function
	     call did not complete successfully.

FRAGMENT HANDLING
       The functions in	this section are used to deal with incoming fragments.

       Outgoing	fragments are handled within LibAliasOut() by changing the ad-
       dress	according    to	   any	  applicable	mapping	    set	    by
       LibAliasRedirectAddr(),	 or   the  default  aliasing  address  set  by
       LibAliasSetAddress().

       Incoming	fragments are handled in one of	two ways.  If the header of  a
       fragmented  IP  packet has already been seen, then all subsequent frag-
       ments will be re-mapped in the same manner  the	header	fragment  was.
       Fragments  which	 arrive	before the header are saved and	then retrieved
       once the	header fragment	has been resolved.

       int LibAliasSaveFragment(struct libalias	*, void	*ptr)

	     When LibAliasIn() returns PKT_ALIAS_UNRESOLVED_FRAGMENT, this
	     function can be used to save the pointer to the unresolved	frag-
	     ment.

	     It	is implicitly assumed that ptr points to a block of memory al-
	     located by	malloc(3).  If the fragment is never resolved, the
	     packet aliasing engine will automatically free the	memory after a
	     timeout period.  [Eventually this function	should be modified so
	     that a callback function for freeing memory is passed as an argu-
	     ment.]

	     This function returns PKT_ALIAS_OK	if it was successful and
	     PKT_ALIAS_ERROR if	there was an error.

       void * LibAliasGetFragment(struct libalias *, void *buffer)

	     This function can be used to retrieve fragment pointers saved by
	     LibAliasSaveFragment().  The IP header fragment pointed to	by
	     buffer is the header fragment indicated when LibAliasIn() returns
	     PKT_ALIAS_FOUND_HEADER_FRAGMENT.  Once a fragment pointer is re-
	     trieved, it becomes the calling program's responsibility to free
	     the dynamically allocated memory for the fragment.

	     The LibAliasGetFragment() function	can be called sequentially un-
	     til there are no more fragments available,	at which time it re-
	     turns NULL.

       void  LibAliasFragmentIn(struct	libalias   *,	void   *header,	  void
       *fragment)

	     When a fragment is	retrieved with LibAliasGetFragment(), it can
	     then be de-aliased	with a call to LibAliasFragmentIn().  The
	     header argument is	the pointer to a header	fragment used as a
	     template, and fragment is the pointer to the packet to be de-
	     aliased.

MISCELLANEOUS FUNCTIONS
       struct alias_link * AddLink(struct libalias *, struct in_addr src_addr,
       struct  in_addr	dst_addr, struct in_addr alias_addr, u_short src_port,
       u_short dst_port, int alias_param, int link_type)

	     This function adds	new state to the instance hash table.  The
	     dst_address and/or	dst_port may be	given as zero, which intro-
	     duces some	dynamic	character into the link, since LibAliasSetAd-
	     dress can change the address that is used.	 However, in the cur-
	     rent implementation, such links can only be used for inbound (ext
	     ->	int) traffic.

       void LibAliasSetTarget(struct libalias *, struct	in_addr	addr)

	     When an incoming packet not associated with any pre-existing
	     aliasing link arrives at the host machine,	it will	be sent	to the
	     address indicated by a call to LibAliasSetTarget().

	     If	this function is called	with an	INADDR_NONE address argument,
	     then all new incoming packets go to the address set by
	     LibAliasSetAddress().

	     If	this function is not called, or	is called with an INADDR_ANY
	     address argument, then all	new incoming packets go	to the address
	     specified in the packet.  This allows external machines to	talk
	     directly to internal machines if they can route packets to	the
	     machine in	question.

       u_short LibAliasInternetChecksum(struct libalias	 *,  u_short  *buffer,
       int nbytes)

	     This is a utility function	that does not seem to be available
	     elsewhere and is included as a convenience.  It computes the in-
	     ternet checksum, which is used in both IP and protocol-specific
	     headers (TCP, UDP,	ICMP).

	     The buffer	argument points	to the data block to be	checksummed,
	     and nbytes	is the number of bytes.	 The 16-bit checksum field
	     should be zeroed before computing the checksum.

	     Checksums can also	be verified by operating on a block of data
	     including its checksum.  If the checksum is valid,
	     LibAliasInternetChecksum()	will return zero.

       int   LibAliasUnaliasOut(struct	 libalias   *,	 void	*buffer,   int
       maxpacketsize)

	     An	outgoing packet, which has already been	aliased, has its pri-
	     vate address/port information restored by this function.  The IP
	     packet is pointed to by buffer, and maxpacketsize is provided for
	     error checking purposes.  This function can be used if an al-
	     ready-aliased packet needs	to have	its original IP	header re-
	     stored for	further	processing (e.g. logging).

CONCEPTUAL BACKGROUND
       This section is intended	for those  who	are  planning  to  modify  the
       source  code or want to create somewhat esoteric	applications using the
       packet aliasing functions.

       The conceptual framework	under which the	packet aliasing	 engine	 oper-
       ates  is	 described  here.  Central to the discussion is	the idea of an
       aliasing	link which describes  the  relationship	 for  a	 given	packet
       transaction  between the	local machine, aliased identity	and remote ma-
       chine.  It is discussed how such	links come into	existence and are  de-
       stroyed.

   ALIASING LINKS
       There  is a notion of an	aliasing link, which is	a 7-tuple describing a
       specific	translation:

	     (local addr, local	port, alias addr, alias	port,
	      remote addr, remote port,	protocol)

       Outgoing	packets	have the local address and port	number	replaced  with
       the  alias  address  and	port number.  Incoming packets undergo the re-
       verse process.  The packet aliasing engine attempts  to	match  packets
       against	an internal table of aliasing links to determine how to	modify
       a given IP packet.  Both	the IP header and protocol  dependent  headers
       are  modified  as necessary.  Aliasing links are	created	and deleted as
       necessary according to network traffic.

       Protocols can be	TCP, UDP or even ICMP in certain circumstances.	 (Some
       types of	ICMP packets can be aliased according to sequence or ID	number
       which acts as an	equivalent port	number for identifying how  individual
       packets should be handled.)

       Each aliasing link must have a unique combination of the	following five
       quantities: alias address/port, remote address/port and protocol.  This
       ensures	that  several  machines	 on a local network can	share the same
       aliasing	IP address.  In	cases where conflicts might arise, the	alias-
       ing port	is chosen so that uniqueness is	maintained.

   STATIC AND DYNAMIC LINKS
       Aliasing	 links	can either be static or	dynamic.  Static links persist
       indefinitely and	represent fixed	rules for translating IP packets.  Dy-
       namic links come	into existence for a specific TCP  connection  or  UDP
       transaction or ICMP ECHO	sequence.  For the case	of TCP,	the connection
       can  be	monitored  to  see when	the associated aliasing	link should be
       deleted.	 Aliasing links	for UDP	transactions (and ICMP ECHO and	 TIME-
       STAMP requests) work on a simple	timeout	rule.  When no activity	is ob-
       served  on  a dynamic link for a	certain	amount of time it is automati-
       cally deleted.  Timeout rules also apply	to TCP	connections  which  do
       not open	or close properly.

   PARTIALLY SPECIFIED ALIASING	LINKS
       Aliasing	 links can be partially	specified, meaning that	the remote ad-
       dress and/or remote port	are unknown.  In  this	case,  when  a	packet
       matching	 the  incomplete specification is found, a fully specified dy-
       namic link is created.  If the original partially specified link	is dy-
       namic, it will be deleted after the fully specified  link  is  created,
       otherwise it will persist.

       For instance, a partially specified link	might be

	     (192.168.0.4, 23, 204.228.203.215,	8066, 0, 0, tcp)

       The  zeros  denote  unspecified	components  for	the remote address and
       port.  If this link were	static it would	have the effect	of redirecting
       all incoming traffic from port 8066 of 204.228.203.215 to port 23 (tel-
       net) of machine 192.168.0.4 on the local	network.  Each individual tel-
       net connection would initiate the creation of a distinct	dynamic	link.

   DYNAMIC LINK	CREATION
       In addition to aliasing links, there are	also address mappings that can
       be stored within	the internal data table	of the packet aliasing	mecha-
       nism.

	     (local addr, alias	addr)

       Address mappings	are searched when creating new dynamic links.

       All  outgoing packets from the local network automatically create a dy-
       namic link if they do not match an  already  existing  fully  specified
       link.   If  an address mapping exists for the outgoing packet, this de-
       termines	the alias address to be	used.  If no mapping  exists,  then  a
       default	address,  usually  the address of the packet aliasing host, is
       used.  If necessary, this default address can be	changed	 as  often  as
       each individual packet arrives.

       The  aliasing  port number is determined	such that the new dynamic link
       does not	conflict with any existing links.  In  the  default  operating
       mode,  the  packet  aliasing  engine  attempts to set the aliasing port
       equal to	the local port number.	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.

MODULAR	ARCHITECTURE (AND ipfw(4) SUPPORT)
       One  of the latest improvements to libalias was to make its support for
       new protocols independent from the rest of the library, giving  it  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  com-
       piled  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.

   LIBALIAS MODULES IN KERNEL LAND
       When compiled for the kernel, libalias modules are plain	KLDs recogniz-
       able with the alias_ prefix.

       To  add support for a new protocol, load	the corresponding module.  For
       example:

	     kldload alias_ftp

       When support for	a protocol is no longer	needed,	its module can be  un-
       loaded:

	     kldunload alias_ftp

   LIBALIAS MODULES 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.

       While  compiled	for a userland libalias, all the modules are plain li-
       braries,	residing in /usr/lib, and recognizable with the	libalias_ pre-
       fix.

       There is	a configuration	file, /etc/libalias.conf, with	the  following
       contents	(by default):

	     /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

       This  file  contains  the paths to the modules that libalias will load.
       To load/unload a	new module, just add its  path	to  libalias.conf  and
       call  LibAliasRefreshModules()  from the	program.  In case the applica-
       tion   provides	 a   SIGHUP   signal   handler,	  add	a   call    to
       LibAliasRefreshModules()	inside the handler, and	every time you want to
       refresh the loaded modules, send	it the SIGHUP signal:

	     kill -HUP <process_pid>

   MODULAR ARCHITECURE:	HOW IT WORKS
       The  modular  architecture of libalias works similar whether it is run-
       ning inside the kernel or in userland.  From alias_mod.c:

       /* Protocol and userland	module handlers	chains.	*/
       LIST_HEAD(handler_chain,	proto_handler) handler_chain ...
       ...
       SLIST_HEAD(dll_chain, dll) dll_chain ...

       handler_chain keeps track of all	the protocol  handlers	loaded,	 while
       ddl_chain tracks	which userland modules are loaded.

       handler_chain is	composed of struct proto_handler entries:

       struct proto_handler {
	       u_int pri;
	       int16_t dir;
	       uint8_t proto;
	       int (*fingerprint)(struct libalias *la,
			struct ip *pip,	struct alias_data *ah);
	       int (*protohandler)(struct libalias *la,
			struct ip *pip,	struct alias_data *ah);
	       TAILQ_ENTRY(proto_handler) link;
       };

       where:

       pri  is	the priority assigned to a protocol handler; lower priority is
       better.

       dir is the direction of packets:	ingoing	or outgoing.

       proto indicates to which	protocol this packet belongs: IP, TCP or UDP.

       fingerprint points  to  the  fingerprint	 function  while  protohandler
       points to the protocol handler function.

       The  fingerprint	function has the dual role of checking if the incoming
       packet is found,	and if it belongs to any categories that  this	module
       can handle.

       The  protohandler  function  actually  manipulates  the	packet to make
       libalias	correctly NAT it.

       When a packet enters libalias, if it meets a module hook, 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 fingerprint function and	interprets the
       result.

       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	handler_chain is exhausted.

       Inside libalias,	the module hook	looks like this:

	     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);

       All  data  useful  to  a	 module	are gathered together in an alias_data
       structure, then find_handler() is called.  The find_handler()  function
       is  responsible for walking the handler chain; it receives as input pa-
       rameters:

       IN      direction

       UDP     working protocol

       la      pointer to this instance	of libalias

       pip     pointer to a struct ip

       ad      pointer to struct alias_data (see above)

       In this case, find_handler() will search	only  for  modules  registered
       for supporting INcoming UDP packets.

       As  was	mentioned earlier, libalias in userland	is a bit different, as
       care must be taken in module handling as	well (avoiding duplicate  load
       of modules, avoiding modules with same name, etc.) so dll_chain was in-
       troduced.

       dll_chain contains a list of all	userland libalias modules loaded.

       When  an	application calls LibAliasRefreshModules(), libalias first un-
       loads all the loaded modules, then reloads all the  modules  listed  in
       /etc/libalias.conf:  for	 every	module loaded, a new entry is added to
       dll_chain.

       dll_chain is composed of	struct dll entries:

       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;
       };

       name is the name	of the module.

       handle is a pointer to the module obtained through dlopen(3).
       Whenever	a  module  is  loaded  in  userland,  an  entry	 is  added  to
       dll_chain,  then	 every	protocol handler present in that module	is re-
       solved and registered in	handler_chain.

   HOW TO WRITE	A MODULE FOR LIBALIAS
       There is	a module (called alias_dummy.[ch]) in  libalias	 that  can  be
       used as a skeleton for future work.  Here we analyse some parts of that
       module.	From alias_dummy.c:

       struct proto_handler handlers[] = {
	   {
	       .pri = 666,
	       .dir = IN|OUT,
	       .proto =	UDP|TCP,
	       .fingerprint = fingerprint,
	       .protohandler= protohandler,
	   },
	   { EOH }
       };

       The  variable  handlers is the "most important thing" in	a module since
       it describes the	handlers present and lets the outside world use	it  in
       an opaque way.

       It  must	ALWAYS be present in every module, and it MUST retain the name
       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	     LibAliasRefreshModules(),
       LibAliasLoadModule() and	LibAliasUnloadModule() in alias.c.

       handlers	contains all the proto_handler structures present in a module.

       static int
       mod_handler(module_t mod, int type, void	*data)
       {
	       int error;

	       switch (type) {
	       case MOD_LOAD:
		       error = LibAliasAttachHandlers(handlers);
		       break;
	       case MOD_UNLOAD:
		       error = LibAliasDetachHandlers(handlers);
		       break;
	       default:
		       error = EINVAL;
	       }
	       return (error);
       }
       When running as KLD, mod_handler() registers/deregisters	the module us-
       ing   LibAliasAttachHandlers()  and  LibAliasDetachHandlers(),  respec-
       tively.

       Every module must contain at least 2 functions: one  fingerprint	 func-
       tion and	a protocol handler function.

       #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)
       {

       ...
       }
       and they	must accept exactly these input	parameters.

   PATCHING AN APPLICATION FOR USERLAND	LIBALIAS MODULES
       To  add module support into an application that uses libalias, the fol-
       lowing simple steps can be followed.

       1.   Find the main file of an application (let us call it main.c).

       2.   Add	this to	the header section of main.c, if not already present:

		  #include <signal.h>

	    and	this just after	the header section:

		  static void signal_handler(int);

       3.   Add	the following line to the init function	of an application  or,
	    if it does not have	any init function, put it in main():

		  signal(SIGHUP, signal_handler);

	    and	place the signal_handler() function somewhere in main.c:

		  static void
		  signal_handler(int sig)
		  {

			  LibAliasRefreshModules();
		  }

	    Otherwise, if an application already traps the SIGHUP signal, just
	    add	a call to LibAliasRefreshModules() in the signal handler func-
	    tion.
       For  example,  to  patch	 natd(8) to use	libalias modules, just add the
       following line to RefreshAddr(int sig __unused):

	     LibAliasRefreshModules()

       recompile and you are done.

   LOGGING SUPPORT IN KERNEL LAND
       When working as KLD, libalias now has log support  that	happens	 on  a
       buffer allocated	inside struct libalias (from alias_local.h):

       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

	       ...
       }
       so  all	applications  using  libalias will be able to handle their own
       logs, if	they want, accessing logDesc.  Moreover, every change to a log
       buffer is automatically added to	syslog(3) with the LOG_SECURITY	facil-
       ity and the LOG_INFO level.

AUTHORS
       Charles Mott <cm@linktel.net>, versions 1.0 - 1.8, 2.0 -	2.4.
       Eivind Eklund <eivind@FreeBSD.org>, versions 1.8b, 1.9 and 2.5.	 Added
       IRC  DCC	 support as well as contributing a number of architectural im-
       provements; added the firewall bypass for FTP/IRC DCC.
       Erik Salander <erik@whistle.com>	added support for PPTP and RTSP.
       Junichi Satoh <junichi@junichi.org> added support for RTSP/PNA.
       Ruslan Ermilov <ru@FreeBSD.org> added support for  PPTP	and  LSNAT  as
       well as general hacking.
       Gleb Smirnoff <glebius@FreeBSD.org> ported the library to kernel	space.
       Paolo  Pisati  <piso@FreeBSD.org> made the library modular, moving sup-
       port for	all protocols (except for IP, TCP and UDP)  to	external  mod-
       ules.

ACKNOWLEDGEMENTS
       Listed  below,  in approximate chronological order, are individuals who
       have provided valuable comments and/or debugging	assistance.

	     Gary Roberts
	     Tom Torrance
	     Reto Burkhalter
	     Martin Renters
	     Brian Somers
	     Paul Traina
	     Ari Suutari
	     Dave Remien
	     J.	Fortes
	     Andrzej Bialecki
	     Gordon Burditt

FreeBSD	13.2			 May 31, 2021			   LIBALIAS(3)

NAME | SYNOPSIS | DESCRIPTION | INTRODUCTION | INITIALIZATION AND CONTROL | PACKET HANDLING | PORT AND ADDRESS REDIRECTION | FRAGMENT HANDLING | MISCELLANEOUS FUNCTIONS | CONCEPTUAL BACKGROUND | AUTHORS | ACKNOWLEDGEMENTS

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=libalias&manpath=FreeBSD+14.0-RELEASE+and+Ports>

home | help