parent
507fe729a1
commit
37ce2656ec
167
sbin/ipfw/ipfw.8
167
sbin/ipfw/ipfw.8
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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>
|
||||
|
@ -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? */
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
2665
sys/netinet/libalias/alias_sctp.c
Normal file
2665
sys/netinet/libalias/alias_sctp.c
Normal file
File diff suppressed because it is too large
Load Diff
201
sys/netinet/libalias/alias_sctp.h
Normal file
201
sys/netinet/libalias/alias_sctp.h
Normal 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
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user