Add SCTP NAT support.

Submitted by: CAIA (http://caia.swin.edu.au)
This commit is contained in:
Paolo Pisati 2009-02-07 18:49:42 +00:00
parent 507fe729a1
commit 37ce2656ec
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=188294
11 changed files with 3212 additions and 23 deletions

View File

@ -2183,17 +2183,173 @@ Redirect and LSNAT support follow closely the syntax used in
See Section
.Sx EXAMPLES
for some examples on how to do redirect and lsnat.
.Sh SCTP NAT SUPPORT
Sctp nat can be configured in a simillar manner to TCP through the
ipfw command line tool
.Xr ipfw 8
, the main difference is that
.Nm sctp nat
does not do port
translation. Since the local and global side ports will be the same,
there is no need to specify both. Ports are redirected as follows:
.Bd -ragged -offset indent
.Bk -words
.Cm nat
.Ar nat_number
.Cm config if
.Ar nic
.Cm redirect_port sctp
.Ar ip_address [,addr_list] {[port | port-port] [,ports]}
.Ek
.Ed
.Pp
.
Most
.B sctp nat
configuration can be done in real-time through the
.B sysctl(8)
interface. All may be changed dynamically, though the hash_table size will only
change for new
.Nm nat
instances. See
.Sx SYSCTL VARIABLES
for more info.
.Sh SYSCTL VARIABLES
A set of
.Xr sysctl 8
variables controls the behaviour of the firewall and
associated modules
.Pq Nm dummynet , bridge .
.Pq Nm dummynet , bridge , sctp nat .
These are shown below together with their default value
(but always check with the
.Xr sysctl 8
command what value is actually in use) and meaning:
.Bl -tag -width indent
.It Va net.inet.ip.alias.sctp.accept_global_ootb_addip: No 0
Defines how the
.Nm nat
responds to receipt of global OOTB ASCONF-AddIP:
.Bl -tag -width indent
.It Cm 0
No response (unless a partially matching association exists -
ports and vtags match but global address does not)
.It Cm 1
.Nm nat
will accept and process all OOTB global AddIP messages.
.El
.Pp
Option 1 should never be selected as this forms a security risk. An attacker can
establish multiple fake associations by sending AddIP messages.
.It Va net.inet.ip.alias.sctp.chunk_proc_limit: No 5
Defines the maximum number of chunks in an SCTP packet that will be parsed for a
packet that matches an existing association. This value is enforced to be greater or equal
than
.Cm net.inet.ip.alias.sctp.initialising_chunk_proc_limit .
A high value is
a DoS risk yet setting too low a value may result in important control chunks in
the packet not being located and parsed.
.It Va net.inet.ip.alias.sctp.error_on_ootb: No 1
Defines when the
.Nm nat
responds to any Out-of-the-Blue (OOTB) packets with ErrorM
packets. An OOTB packet is a packet that arrives with no existing association
registered in the
.Nm nat
and is not an INIT or ASCONF-AddIP packet:
.Bl -tag -width indent
.It Cm 0
ErrorM is never sent in response to OOTB packets.
.It Cm 1
ErrorM is only sent to OOTB packets received on the local side.
.It Cm 2
ErrorM is sent to the local side and on the global side ONLY if there is a
partial match (ports and vtags match but the source global IP does not). This
value is only useful if the
.Nm nat
is tracking global IP addresses.
.It Cm 3
ErrorM is sent in response to all OOTB packets on both the local and global side
(DoS risk).
.El
.Pp
At the moment the default is 0, since the ErrorM packet is not yet
supported by most SCTP stacks. When it is supported, and if not tracking
global addresses, we recommend setting this value to 1 to allow
multi-homed local hosts to function with the
.Nm nat .
To track global addresses, we recommend setting this value to 2 to
allow global hosts to be informed when they need to (re)send an
ASCONF-AddIP. Value 3 should never be chosen (except for debugging) as
the
.Nm nat
will respond to all OOTB global packets (a DoS risk).
.It Va net.inet.ip.alias.sctp.hashtable_size: No 2003
Size of hash tables used for
.Nm nat
lookups (100 < prime_number > 1000001)
This value sets the
.Nm hash table
size for any future created
.Nm nat
instance and therefore must be set prior to creating a
.Nm nat
instance.
The table sizes my be changed to suit specific needs. If there will be few
concurrent associations, and memory is scarce, you may make these smaller. If
there will be many thousands (or millions) of concurrent associations, you
should make these larger. A prime number is best for the table size. The sysctl
update function will adjust your input value to the next highest prime number.
.It Va net.inet.ip.alias.sctp.holddown_time: No 0
Hold association in table for this many seconds after receiving a
SHUTDOWN-COMPLETE. This allows endpoints to correct shutdown gracefully if a
shutdown_complete is lost and retransmissions are required.
.It Va net.inet.ip.alias.sctp.init_timer: No 15
Timeout value while waiting for (INIT-ACK|AddIP-ACK).
This value cannot be 0.
.It Va net.inet.ip.alias.sctp.initialising_chunk_proc_limit: No 2
Defines the maximum number of chunks in an SCTP packet that will be parsed when
no existing association exists that matches that packet. Ideally this packet
will only be an INIT or ASCONF-AddIP packet. A higher value may become a DoS
risk as malformed packets can consume processing resources.
.It Va net.inet.ip.alias.sctp.param_proc_limit: No 25
Defines the maximum number of parameters within a chunk that will be parsed in a
packet. As for other similar sysctl variables, larger values pose a DoS risk.
.It Va net.inet.ip.alias.sctp.log_level: No 0
Level of detail in the system log messages (0 \- minimal, 1 \- event,
2 \- info, 3 \- detail, 4 \- debug, 5 \- max debug). May be a good
option in high loss environments.
.It Va net.inet.ip.alias.sctp.shutdown_time: No 15
Timeout value while waiting for SHUTDOWN-COMPLETE.
This value cannot be 0.
.It Va net.inet.ip.alias.sctp.track_global_addresses: No 0
Enables/disables global IP address tracking within the
.Nm nat
and places an
upper limit on the number of addresses tracked for each association:
.Bl -tag -width indent
.It Cm 0
Global tracking is disabled
.It Cm >1
Enables tracking, the maximum number of addresses tracked for each
association is limited to this value
.El
.Pp
This variable is fully dynamic, the new value will be adopted for all newly
arriving associations, existing association are treated as they were previously.
Global tracking will decrease the number of collisions within the
.Nm nat
at a cost
of increased processing load, memory usage, complexity, and possible
.Nm nat
state
problems in complex networks with multiple
.Nm nats .
We recommend not tracking
global IP addresses, this will still result in a fully functional
.Nm nat .
.It Va net.inet.ip.alias.sctp.up_timer: No 300
Timeout value to keep an association up with no traffic.
This value cannot be 0.
.It Va net.inet.ip.dummynet.expire : No 1
Lazily delete dynamic pipes/queue once they have no pending traffic.
You can disable this by setting the variable to 0, in which case
@ -2718,6 +2874,15 @@ as part of a Summer of Code 2005 project.
Work on
.Nm dummynet
traffic shaper supported by Akamba Corp.
.Pp
Sctp
.Nm nat
support has been developed by
.An The Centre for Advanced Internet Architectures (CAIA) Aq http://www.caia.swin.edu.au .
The primary developers and maintainers are David Hayes and Jason But.
For further information visit:
.Aq http://www.caia.swin.edu.au/urp/SONATA
.
.Sh BUGS
The syntax has grown over the years and sometimes it might be confusing.
Unfortunately, backward compatibility prevents cleaning up mistakes

View File

@ -257,7 +257,9 @@ StrToProto (const char* str)
if (!strcmp (str, "udp"))
return IPPROTO_UDP;
errx (EX_DATAERR, "unknown protocol %s. Expected tcp or udp", str);
if (!strcmp (str, "sctp"))
return IPPROTO_SCTP;
errx (EX_DATAERR, "unknown protocol %s. Expected sctp, tcp or udp", str);
}
static int
@ -433,13 +435,27 @@ setup_redir_port(char *spool_buf, int len,
strncpy(tmp_spool_buf, *av, strlen(*av)+1);
lsnat = 1;
} else {
if (StrToAddrAndPortRange (*av, &r->laddr, protoName,
&portRange) != 0)
errx(EX_DATAERR, "redirect_port:"
"invalid local port range");
/*
* The sctp nat does not allow the port numbers to be mapped to
* new port numbers. Therefore, no ports are to be specified
* in the target port field.
*/
if (r->proto == IPPROTO_SCTP) {
if (strchr (*av, ':'))
errx(EX_DATAERR, "redirect_port:"
"port numbers do not change in sctp, so do not "
"specify them as part of the target");
else
StrToAddr(*av, &r->laddr);
} else {
if (StrToAddrAndPortRange (*av, &r->laddr, protoName,
&portRange) != 0)
errx(EX_DATAERR, "redirect_port:"
"invalid local port range");
r->lport = GETLOPORT(portRange);
numLocalPorts = GETNUMPORTS(portRange);
r->lport = GETLOPORT(portRange);
numLocalPorts = GETNUMPORTS(portRange);
}
}
INC_ARGCV();
@ -463,6 +479,10 @@ setup_redir_port(char *spool_buf, int len,
}
r->pport = GETLOPORT(portRange);
if (r->proto == IPPROTO_SCTP) { /* so the logic below still works */
numLocalPorts = GETNUMPORTS(portRange);
r->lport = r->pport;
}
r->pport_cnt = GETNUMPORTS(portRange);
INC_ARGCV();
@ -518,14 +538,31 @@ setup_redir_port(char *spool_buf, int len,
goto nospace;
len -= SOF_SPOOL;
space += SOF_SPOOL;
if (StrToAddrAndPortRange(sep, &tmp->addr, protoName,
&portRange) != 0)
errx(EX_DATAERR, "redirect_port:"
"invalid local port range");
if (GETNUMPORTS(portRange) != 1)
errx(EX_DATAERR, "redirect_port: local port"
"must be single in this context");
tmp->port = GETLOPORT(portRange);
/*
* The sctp nat does not allow the port numbers to be mapped to new port numbers
* Therefore, no ports are to be specified in the target port field
*/
if (r->proto == IPPROTO_SCTP) {
if (strchr (sep, ':')) {
errx(EX_DATAERR, "redirect_port:"
"port numbers do not change in "
"sctp, so do not specify them as "
"part of the target");
} else {
StrToAddr(sep, &tmp->addr);
tmp->port = r->pport;
}
} else {
if (StrToAddrAndPortRange(sep, &tmp->addr,
protoName, &portRange) != 0)
errx(EX_DATAERR, "redirect_port:"
"invalid local port range");
if (GETNUMPORTS(portRange) != 1)
errx(EX_DATAERR, "redirect_port: "
"local port must be single in "
"this context");
tmp->port = GETLOPORT(portRange);
}
r->spool_cnt++;
/* Point to the next possible cfg_spool. */
spool_buf = &spool_buf[SOF_SPOOL];

View File

@ -3,6 +3,6 @@
.PATH: ${.CURDIR}/../../../netinet/libalias
KMOD= libalias
SRCS= alias.c alias_db.c alias_proxy.c alias_util.c alias_mod.c
SRCS= alias.c alias_db.c alias_proxy.c alias_util.c alias_mod.c alias_sctp.c
.include <bsd.kmod.mk>

View File

@ -326,6 +326,10 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
else
retval = LibAliasOut(t->lib, c,
mcl->m_len + M_TRAILINGSPACE(mcl));
if (retval == PKT_ALIAS_RESPOND) {
m->m_flags |= M_SKIP_FIREWALL;
retval = PKT_ALIAS_OK;
}
if (retval != PKT_ALIAS_OK &&
retval != PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
/* XXX - should i add some logging? */

View File

@ -115,6 +115,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/sysctl.h>
#else
#include <sys/types.h>
#include <stdlib.h>
@ -143,6 +144,17 @@ __FBSDID("$FreeBSD$");
#include "alias_mod.h"
#endif
/*
* Define libalias SYSCTL Node
*/
#ifdef SYSCTL_NODE
SYSCTL_DECL(_net_inet);
SYSCTL_DECL(_net_inet_ip);
SYSCTL_NODE(_net_inet_ip, OID_AUTO, alias, CTLFLAG_RW, NULL, "Libalias sysctl API");
#endif
static __inline int
twowords(void *p)
{
@ -1335,6 +1347,11 @@ LibAliasInLocked(struct libalias *la, char *ptr, int maxpacketsize)
case IPPROTO_TCP:
iresult = TcpAliasIn(la, pip);
break;
#ifdef _KERNEL
case IPPROTO_SCTP:
iresult = SctpAlias(la, pip, SN_TO_LOCAL);
break;
#endif
case IPPROTO_GRE: {
int error;
struct alias_data ad = {
@ -1477,10 +1494,15 @@ LibAliasOutLocked(struct libalias *la, char *ptr, /* valid IP packet */
case IPPROTO_UDP:
iresult = UdpAliasOut(la, pip, maxpacketsize, create);
break;
case IPPROTO_TCP:
case IPPROTO_TCP:
iresult = TcpAliasOut(la, pip, maxpacketsize, create);
break;
case IPPROTO_GRE: {
#ifdef _KERNEL
case IPPROTO_SCTP:
iresult = SctpAlias(la, pip, SN_TO_GLOBAL);
break;
#endif
case IPPROTO_GRE: {
int error;
struct alias_data ad = {
.lnk = NULL,

View File

@ -411,6 +411,8 @@ static void ShowAliasStats(struct libalias *);
static int InitPacketAliasLog(struct libalias *);
static void UninitPacketAliasLog(struct libalias *);
void SctpShowAliasStats(struct libalias *la);
static u_int
StartPointIn(struct in_addr alias_addr,
u_short alias_port,
@ -489,15 +491,17 @@ ShowAliasStats(struct libalias *la)
/* Used for debugging */
if (la->logDesc) {
int tot = la->icmpLinkCount + la->udpLinkCount +
(la->sctpLinkCount>>1) + /* sctp counts half associations */
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",
"icmp=%u, udp=%u, tcp=%u, sctp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u",
la->icmpLinkCount,
la->udpLinkCount,
la->tcpLinkCount,
la->sctpLinkCount>>1, /* sctp counts half associations */
la->pptpLinkCount,
la->protoLinkCount,
la->fragmentIdLinkCount,
@ -508,6 +512,13 @@ ShowAliasStats(struct libalias *la)
}
}
void SctpShowAliasStats(struct libalias *la)
{
ShowAliasStats(la);
}
/* Internal routines for finding, deleting and adding links
Port Allocation:
@ -1278,6 +1289,11 @@ _FindLinkIn(struct libalias *la, struct in_addr dst_addr,
src_port = lnk->src_port;
}
if (link_type == LINK_SCTP) {
lnk->src_addr = src_addr;
lnk->src_port = src_port;
return(lnk);
}
lnk = ReLink(lnk,
src_addr, dst_addr, alias_addr,
src_port, dst_port, alias_port,
@ -2277,10 +2293,13 @@ LibAliasRedirectPort(struct libalias *la, struct in_addr src_addr, u_short src_p
case IPPROTO_TCP:
link_type = LINK_TCP;
break;
case IPPROTO_SCTP:
link_type = LINK_SCTP;
break;
default:
#ifdef LIBALIAS_DEBUG
fprintf(stderr, "PacketAliasRedirectPort(): ");
fprintf(stderr, "only TCP and UDP protocols allowed\n");
fprintf(stderr, "only SCTP, TCP and UDP protocols allowed\n");
#endif
lnk = NULL;
goto getout;
@ -2496,6 +2515,9 @@ LibAliasInit(struct libalias *la)
LIST_INIT(&la->linkTableOut[i]);
for (i = 0; i < LINK_TABLE_IN_SIZE; i++)
LIST_INIT(&la->linkTableIn[i]);
#ifdef _KERNEL
AliasSctpInit(la);
#endif
LIBALIAS_LOCK_INIT(la);
LIBALIAS_LOCK(la);
} else {
@ -2503,6 +2525,10 @@ LibAliasInit(struct libalias *la)
la->deleteAllLinks = 1;
CleanupAliasData(la);
la->deleteAllLinks = 0;
#ifdef _KERNEL
AliasSctpTerm(la);
AliasSctpInit(la);
#endif
}
la->aliasAddress.s_addr = INADDR_ANY;
@ -2511,6 +2537,7 @@ LibAliasInit(struct libalias *la)
la->icmpLinkCount = 0;
la->udpLinkCount = 0;
la->tcpLinkCount = 0;
la->sctpLinkCount = 0;
la->pptpLinkCount = 0;
la->protoLinkCount = 0;
la->fragmentIdLinkCount = 0;
@ -2539,6 +2566,9 @@ LibAliasUninit(struct libalias *la)
{
LIBALIAS_LOCK(la);
#ifdef _KERNEL
AliasSctpTerm(la);
#endif
la->deleteAllLinks = 1;
CleanupAliasData(la);
la->deleteAllLinks = 0;
@ -2879,3 +2909,30 @@ LibAliasSetSkinnyPort(struct libalias *la, unsigned int port)
la->skinnyPort = port;
LIBALIAS_UNLOCK(la);
}
/*
* Find the address to redirect incoming packets
*/
struct in_addr
FindSctpRedirectAddress(struct libalias *la, struct sctp_nat_msg *sm)
{
struct alias_link *lnk;
struct in_addr redir;
LIBALIAS_LOCK_ASSERT(la);
lnk = FindLinkIn(la, sm->ip_hdr->ip_src, sm->ip_hdr->ip_dst,
sm->sctp_hdr->dest_port,sm->sctp_hdr->dest_port, LINK_SCTP, 1);
if (lnk != NULL) {
return(lnk->src_addr); /* port redirect */
} else {
redir = FindOriginalAddress(la,sm->ip_hdr->ip_dst);
if (redir.s_addr == la->aliasAddress.s_addr ||
redir.s_addr == la->targetAddress.s_addr) { /* No address found */
lnk = FindLinkIn(la, sm->ip_hdr->ip_src, sm->ip_hdr->ip_dst,
NO_DEST_PORT, 0, LINK_SCTP, 1);
if (lnk != NULL)
return(lnk->src_addr); /* redirect proto */
}
return(redir); /* address redirect */
}
}

View File

@ -57,6 +57,10 @@
/* XXX: LibAliasSetTarget() uses this constant. */
#define INADDR_NONE 0xffffffff
#include <netinet/libalias/alias_sctp.h>
#else
#include "alias_sctp.h"
#endif
/* Sizes of input and output link tables */
@ -147,7 +151,29 @@ struct libalias {
struct in_addr true_addr; /* in network byte order. */
u_short true_port; /* in host byte order. */
/*
* sctp code support
*/
/* counts associations that have progressed to UP and not yet removed */
int sctpLinkCount;
#ifdef _KERNEL
/* timing queue for keeping track of association timeouts */
struct sctp_nat_timer sctpNatTimer;
/* size of hash table used in this instance */
u_int sctpNatTableSize;
/*
* local look up table sorted by l_vtag/l_port
*/
LIST_HEAD(sctpNatTableL, sctp_nat_assoc) *sctpTableLocal;
/*
* global look up table sorted by g_vtag/g_port
*/
LIST_HEAD(sctpNatTableG, sctp_nat_assoc) *sctpTableGlobal;
/*
* avoid races in libalias: every public function has to use it.
*/
@ -198,6 +224,14 @@ struct libalias {
/* Prototypes */
/*
* SctpFunction prototypes
*
*/
void AliasSctpInit(struct libalias *la);
void AliasSctpTerm(struct libalias *la);
int SctpAlias(struct libalias *la, struct ip *ip, int direction);
/*
* We do not calculate TCP checksums when libalias is a kernel
* module, since it has no idea about checksum offloading.
@ -264,6 +298,8 @@ struct in_addr
FindOriginalAddress(struct libalias *la, struct in_addr _alias_addr);
struct in_addr
FindAliasAddress(struct libalias *la, struct in_addr _original_addr);
struct in_addr
FindSctpRedirectAddress(struct libalias *la, struct sctp_nat_msg *sm);
/* External data access/modification */
int

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,201 @@
/**
* @file alias_sctp.h
* Copyright (c) 2008, Centre for Advanced Internet Architectures
* Swinburne University of Technology, Melbourne, Australia
* (CRICOS number 00111D).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The names of the authors, the "Centre for Advanced Internet Architectures"
* and "Swinburne University of Technology" may not be used to endorse
* or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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.
*
* Alias_sctp forms part of the libalias kernel module to handle
* Network Address Translation (NAT) for the SCTP protocol.
*
* This software was developed by David A. Hayes
* with leadership and advice from Jason But
*
* The design is outlined in CAIA technical report number 080618A
* (D. Hayes and J. But, "Alias_sctp Version 0.1: SCTP NAT implementation in IPFW")
*
* Development is part of the CAIA SONATA project,
* proposed by Jason But and Grenville Armitage:
* http://caia.swin.edu.au/urp/sonata/
*
*
* This project has been made possible in part by a grant from
* the Cisco University Research Program Fund at Community
* Foundation Silicon Valley.
*
*/
/* $FreeBSD$ */
#ifndef _ALIAS_SCTP_H_
#define _ALIAS_SCTP_H_
#include <sys/param.h>
#ifdef _KERNEL
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/uio.h>
#include <sys/socketvar.h>
#include <sys/syslog.h>
#endif // #ifdef _KERNEL
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
/**
* These are defined in sctp_os_bsd.h, but it can't be included due to its local file
* inclusion, so I'm defining them here.
*
*/
#include <machine/cpufunc.h>
#include <machine/cpu.h>
/* The packed define for 64 bit platforms */
#ifndef SCTP_PACKED
#define SCTP_PACKED __attribute__((packed))
#endif //#ifndef SCTP_PACKED
#ifndef SCTP_UNUSED
#define SCTP_UNUSED __attribute__((unused))
#endif //#ifndef SCTP_UNUSED
#include <netinet/sctp.h>
//#include <netinet/sctp_os_bsd.h> --might be needed later for mbuf stuff
#include <netinet/sctp_header.h>
#ifndef _KERNEL
#include <stdlib.h>
#include <stdio.h>
#include <curses.h>
#endif //#ifdef _KERNEL
#define LINK_SCTP IPPROTO_SCTP
#define SN_TO_LOCAL 0 /**< packet traveling from global to local */
#define SN_TO_GLOBAL 1 /**< packet traveling from local to global */
#define SN_TO_NODIR 99 /**< used where direction is not important */
#define SN_NAT_PKT 0x0000 /**< Network Address Translate packet */
#define SN_DROP_PKT 0x0001 /**< drop packet (don't forward it) */
#define SN_PROCESSING_ERROR 0x0003 /**< Packet processing error */
#define SN_REPLY_ABORT 0x0010 /**< Reply with ABORT to sender (don't forward it) */
#define SN_SEND_ABORT 0x0020 /**< Send ABORT to destination */
#define SN_TX_ABORT 0x0030 /**< mask for transmitting abort */
#define SN_REFLECT_ERROR 0x0100 /**< Reply with ERROR to sender on OOTB packet Tbit set */
#define SN_REPLY_ERROR 0x0200 /**< Reply with ERROR to sender on ASCONF clash */
#define SN_TX_ERROR 0x0300 /**< mask for transmitting error */
#define PKT_ALIAS_RESPOND 0x1000 /**< Signal to libalias that there is a response packet to send */
/*
* Data structures
*/
/**
* @brief sctp association information
*
* Structure that contains information about a particular sctp association
* currently under Network Address Translation.
* Information is stored in network byte order (as is libalias)***
*/
struct sctp_nat_assoc {
uint32_t l_vtag; /**< local side verification tag */
uint16_t l_port; /**< local side port number */
uint32_t g_vtag; /**< global side verification tag */
uint16_t g_port; /**< global side port number */
struct in_addr l_addr; /**< local ip address */
struct in_addr a_addr; /**< alias ip address */
int state; /**< current state of NAT association */
int TableRegister; /**< stores which look up tables association is registered in */
int exp; /**< timer expiration in seconds from uptime */
int exp_loc; /**< current location in timer_Q */
int num_Gaddr; /**< number of global IP addresses in the list */
LIST_HEAD(sctpGlobalAddresshead,sctp_GlobalAddress) Gaddr; /**< List of global addresses */
LIST_ENTRY (sctp_nat_assoc) list_L; /**< Linked list of pointers for Local table*/
LIST_ENTRY (sctp_nat_assoc) list_G; /**< Linked list of pointers for Global table */
LIST_ENTRY (sctp_nat_assoc) timer_Q; /**< Linked list of pointers for timer Q */
//Using libalias locking
};
struct sctp_GlobalAddress {
struct in_addr g_addr;
LIST_ENTRY (sctp_GlobalAddress) list_Gaddr; /**< Linked list of pointers for Global table */
};
/**
* @brief SCTP chunk of interest
*
* The only chunks whose contents are of any interest are the INIT and ASCONF_AddIP
*/
union sctpChunkOfInt {
struct sctp_init *Init; /**< Pointer to Init Chunk */
struct sctp_init_ack *InitAck; /**< Pointer to Init Chunk */
struct sctp_paramhdr *Asconf; /**< Pointer to ASCONF chunk */
};
/**
* @brief SCTP message
*
* Structure containing the relevant information from the SCTP message
*/
struct sctp_nat_msg {
uint16_t msg; /**< one of the key messages defined above */
#ifdef INET6
// struct ip6_hdr *ip_hdr; /**< pointer to ip packet header */ /*no inet6 support yet*/
#else
struct ip *ip_hdr; /**< pointer to ip packet header */
#endif //#ifdef INET6
struct sctphdr *sctp_hdr; /**< pointer to sctp common header */
union sctpChunkOfInt sctpchnk; /**< union of pointers to the chunk of interest */
int chunk_length; /**< length of chunk of interest */
};
/**
* @brief sctp nat timer queue structure
*
*/
struct sctp_nat_timer {
int loc_time; /**< time in seconds for the current location in the queue */
int cur_loc; /**< index of the current location in the circular queue */
LIST_HEAD(sctpTimerQ,sctp_nat_assoc) *TimerQ; /**< List of associations at this position in the timer Q */
};
#endif //#ifndef _ALIAS_SCTP_H

View File

@ -599,7 +599,7 @@ sctp_crc32c_sb8_64_bit(uint32_t crc,
*
* none
*/
static uint32_t
uint32_t
update_crc32(uint32_t crc32c,
unsigned char *buffer,
unsigned int length)
@ -697,7 +697,7 @@ old_update_crc32(uint32_t crc32c,
}
static uint32_t
uint32_t
sctp_finalize_crc32(uint32_t crc32c)
{
uint32_t result;

View File

@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$");
#if defined(_KERNEL) || defined(__Userspace__)
uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
void sctp_delayed_cksum(struct mbuf *);
uint32_t update_crc32(uint32_t, unsigned char *, unsigned int);
uint32_t sctp_finalize_crc32(uint32_t);
#endif /* _KERNEL */