From owner-svn-src-user@FreeBSD.ORG Sun Dec 28 17:16:33 2008 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 24B261065673; Sun, 28 Dec 2008 17:16:33 +0000 (UTC) (envelope-from piso@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 10E828FC08; Sun, 28 Dec 2008 17:16:33 +0000 (UTC) (envelope-from piso@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mBSHGWNH018989; Sun, 28 Dec 2008 17:16:32 GMT (envelope-from piso@svn.freebsd.org) Received: (from piso@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mBSHGWg8018977; Sun, 28 Dec 2008 17:16:32 GMT (envelope-from piso@svn.freebsd.org) Message-Id: <200812281716.mBSHGWg8018977@svn.freebsd.org> From: Paolo Pisati Date: Sun, 28 Dec 2008 17:16:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r186543 - in user/piso: sbin/ipfw share/man/man8 sys/modules/libalias/libalias sys/netinet sys/netinet/libalias X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 28 Dec 2008 17:16:33 -0000 Author: piso Date: Sun Dec 28 17:16:32 2008 New Revision: 186543 URL: http://svn.freebsd.org/changeset/base/186543 Log: Import sctp nat support in ipfw obtained from CAIA - http://caia.swin.edu.au. Added: user/piso/share/man/man8/alias_sctp.8 (contents, props changed) user/piso/sys/netinet/libalias/alias_sctp.c (contents, props changed) user/piso/sys/netinet/libalias/alias_sctp.h (contents, props changed) Modified: user/piso/sbin/ipfw/ipfw2.c user/piso/share/man/man8/Makefile user/piso/sys/modules/libalias/libalias/Makefile user/piso/sys/netinet/ip_fw_nat.c user/piso/sys/netinet/libalias/alias.c user/piso/sys/netinet/libalias/alias.h user/piso/sys/netinet/libalias/alias_db.c user/piso/sys/netinet/libalias/alias_local.h Modified: user/piso/sbin/ipfw/ipfw2.c ============================================================================== --- user/piso/sbin/ipfw/ipfw2.c Sun Dec 28 14:37:09 2008 (r186542) +++ user/piso/sbin/ipfw/ipfw2.c Sun Dec 28 17:16:32 2008 (r186543) @@ -48,6 +48,7 @@ #include #define IPFW_INTERNAL /* Access to protected structures in ip_fw.h. */ +#define _ALIAS_SCTP /*Using alias_sctp*/ #include #include @@ -3504,7 +3505,13 @@ StrToProto (const char* str) if (!strcmp (str, "udp")) return IPPROTO_UDP; +#ifdef _ALIAS_SCTP /*Using alias_sctp*/ + if (!strcmp (str, "sctp")) + return IPPROTO_SCTP; + errx (EX_DATAERR, "unknown protocol %s. Expected sctp, tcp or udp", str); +#else errx (EX_DATAERR, "unknown protocol %s. Expected tcp or udp", str); +#endif } static int @@ -3680,13 +3687,29 @@ setup_redir_port(char *spool_buf, int le strncpy(tmp_spool_buf, *av, strlen(*av)+1); lsnat = 1; } else { - if (StrToAddrAndPortRange (*av, &r->laddr, protoName, +#ifdef _ALIAS_SCTP /*Using alias_sctp*/ + /* + * 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 { +#endif /*Using alias_sctp*/ + if (StrToAddrAndPortRange (*av, &r->laddr, protoName, &portRange) != 0) errx(EX_DATAERR, "redirect_port:" "invalid local port range"); r->lport = GETLOPORT(portRange); numLocalPorts = GETNUMPORTS(portRange); +#ifdef _ALIAS_SCTP /*Using alias_sctp*/ + } +#endif /*Using alias_sctp*/ } INC_ARGCV(); @@ -3710,6 +3733,12 @@ setup_redir_port(char *spool_buf, int le } r->pport = GETLOPORT(portRange); +#ifdef _ALIAS_SCTP /*Using alias_sctp*/ + if (r->proto == IPPROTO_SCTP) { /* so the logic below still works */ + numLocalPorts = GETNUMPORTS(portRange); + r->lport = r->pport; + } +#endif /*Using alias_sctp*/ r->pport_cnt = GETNUMPORTS(portRange); INC_ARGCV(); @@ -3765,6 +3794,22 @@ setup_redir_port(char *spool_buf, int le goto nospace; len -= SOF_SPOOL; space += SOF_SPOOL; + +#ifdef _ALIAS_SCTP /*Using alias_sctp*/ + /* + * 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 { +#endif /*Using alias_sctp*/ if (StrToAddrAndPortRange(sep, &tmp->addr, protoName, &portRange) != 0) errx(EX_DATAERR, "redirect_port:" @@ -3773,6 +3818,9 @@ setup_redir_port(char *spool_buf, int le errx(EX_DATAERR, "redirect_port: local port" "must be single in this context"); tmp->port = GETLOPORT(portRange); +#ifdef _ALIAS_SCTP /*Using alias_sctp*/ + } +#endif /*Using alias_sctp*/ r->spool_cnt++; /* Point to the next possible cfg_spool. */ spool_buf = &spool_buf[SOF_SPOOL]; Modified: user/piso/share/man/man8/Makefile ============================================================================== --- user/piso/share/man/man8/Makefile Sun Dec 28 14:37:09 2008 (r186542) +++ user/piso/share/man/man8/Makefile Sun Dec 28 17:16:32 2008 (r186543) @@ -13,7 +13,8 @@ MAN= adding_user.8 \ rc.subr.8 \ rescue.8 \ sticky.8 \ - yp.8 + yp.8 \ + alias_sctp.8 MLINKS= rc.8 rc.atm.8 \ rc.8 rc.d.8 \ Added: user/piso/share/man/man8/alias_sctp.8 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/piso/share/man/man8/alias_sctp.8 Sun Dec 28 17:16:32 2008 (r186543) @@ -0,0 +1,241 @@ +.\" * Copyright (c) 2008, Centre for Advanced Internet Architectures +.\" * Swinburne University of Technology, Melbourne, Australia +.\" * (CRICOS number 00111D). +.\" * +.\" * 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 and 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. +.\" * +.\" * +.\" * +.\" * All rights reserved. +.\" * +.\" * Redistribution and use in source and binary forms, with or without +.\" * modification, are permitted provided that the following conditions +.\" * are met: +.\" * 1. Redistributions of source code must retain the above copyright +.\" * notice, this list of conditions and the following disclaimer. +.\" * 2. Redistributions in binary form must reproduce the above copyright +.\" * notice, this list of conditions and the following disclaimer in the +.\" * documentation and/or other materials provided with the distribution. +.\" * 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. +.TH ALIAS_SCTP 8 "30 September 08" "version 0.2" +.SH NAME +alias_sctp - SCTP NAT functionality for libalias in FreeBSD +.SH SYNOPSIS +.B alias_sctp \- libalias enhancements to support SCTP NAT +.PP +.B ipfw \- Extensions to user-land tool to configure SCTP NAT +.PP +.B sysctl net.inet.ip.alias.sctp.* \- sysctl interface to alias_sctp +./"=========================================================================" +.SH DESCRIPTION +.B alias_sctp +is a kernel space addition to libalias that implements NAT for SCTP within the +.B ipfw2 +framework for FreeBSD. The +.B alias_sctp +implementation is based on the details provided in Internet Draft xxxxx and our +own ideas discovered during implementation. +.B alias_sctp +is a dynamically configurable NAT module that supports the following functionality: +.IP o +Optional support for tracking of Global IP Addresses (see Internet Draft xxxx) +.IP o +Dynamically configurable timeouts for various states within the NAT +.IP o +Dynamically configurable packet parsing limits (to protect against DoS attacks) +.IP o +Per port/IP-address forwarding of incoming associations +.IP o +Dynamically configurable hash table size and logging details +.IP o +NAT configured via user-land +.B ipfw +tool +.IP o +NAT statistics available via +.B ipfw +user-land command +./"=========================================================================" +.SH USING alias_sctp +.SS Configuring alias_sctp via ipfw +.B Alias_sctp +can be configured in a simillar manner to TCP through the ipfw command line tool +(see ipfw(8)). The main difference in configuring SCTP NAT rules, is that +.B alias_sctp +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: +.IP +.B ipfw nat +inst# +.B config if +nic +.B redirect_port sctp +ip-addr [,addr-list] {port | port-port] [,ports]} +./"=========================================================================" +.SH "sysctl" INTERFACE +Most +.B alias_sctp +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 NAT instances. Default values are also listed below. + +.SS net.inet.ip.alias.sctp.hashtable_size (Default = 2003) +Size of hash tables used for NAT lookups (100 < prime_number > 1000001) +This value sets the hash table size for any _future_ created NAT +instance and therefore must be set prior to creating a NAT instance (ie +ipfw nat 100 config ...). +.PP +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. + +.SS net.inet.ip.alias.sctp.error_on_ootb (Default = 1) +Defines when the 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 NAT AND is not an INIT or ASCONF-AddIP packet: +.PP +.IP "0 \-" +ErrorM is never sent in response to OOTB packets +.IP "1 \-" +ErrorM is only sent to OOTB packets received on the local side +.IP "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 NAT is tracking global IP addresses +.IP "3 \-" +ErrorM is sent in response to all OOTB packets on both the local and global side +(DoS risk) +.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 NAT. If tracking 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 NAT will respond to all OOTB global packets (a DoS risk). + +.SS net.inet.ip.alias.sctp.accept_global_ootb_addip (Default = 0) +Defines how the NAT responds to receipt of global OOTB ASCONF-AddIP: +.PP +.IP "0 \-" +No response (unless a partially matching association exists - +ports and vtags match but global address does not) +.IP "1 \-" +NAT will accept and process all OOTB global AddIP messages. +.PP +Option 1 should never be selected as this forms a security risk. An attacker can +establish multiple fake associations by sending AddIP messages. + +.SS net.inet.ip.alias.sctp.initialising_chunk_proc_limit (Default = 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. + +.SS net.inet.ip.alias.sctp.chunk_proc_limit (Default = 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 >= +(initialising_chunk_proc_limit). As for the previous parameter, 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. + +.SS net.inet.ip.alias.sctp.param_proc_limit (Default = 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. + +.SS net.inet.ip.alias.sctp.track_global_addresses (Default = 0) +Enables/disables global IP address tracking within the NAT and places an +upper limit on the number of addresses tracked for each association: +.PP +.IP "0 \-" +Global tracking is disabled +.IP ">1 \-" +Enables tracking, the maximum number of addresses tracked for each +association is limited to this value +.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 NAT at a cost +of increased processing load, memory usage, complexity, and possible NAT state +problems in complex networks with multiple NATs. We recommend not tracking +global IP addresses, this will still result in a fully functional NAT. + +.SS net.inet.ip.alias.sctp.init_timer (Default = 15) +Timeout value (s) while waiting for (INIT-ACK|AddIP-ACK). +This value cannot be 0. + +.SS net.inet.ip.alias.sctp.up_timer (Default = 300) +Timeout value (s) to keep an association up with no traffic. +This value cannot be 0. + +.SS net.inet.ip.alias.sctp.shutdown_time (Default = 15) +Timeout value (s) while waiting for SHUTDOWN-COMPLETE. +This value cannot be 0. + +.SS net.inet.ip.alias.sctp.holddown_time (Default = 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. This +net.inet.ip.alias.sctp.log_level (Default = 0) Level of detail in the system log +messages (0 \- minimal, 1 \- event, 2 \- info, 3 \- detail, 4 \- debug, 5 \- max +debug) +.PP +May be a good option in high loss environments. + +.SH "SEE ALSO" +.BR ipfw (8), +.BR libalias (8), +.BR sysctl (8) +.SH AUTHOR +.B alias_sctp +has been developed and released by: + +The Centre for Advanced Internet Architectures (CAIA), Swinburne University, +Melbourne, Australia. +.IP +.I http://www.caia.swin.edu.au +.LP +The primary developers and maintainers of +.B alias_sctp +are David Hayes and Jason But. + +.B alias_sctp +can be downloaded from its website: +.IP +.I http://www.caia.swin.edu.au/urp/SONATA +.LP +This site contains the latest updates and further information on how to use and +.B alias_sctp Modified: user/piso/sys/modules/libalias/libalias/Makefile ============================================================================== --- user/piso/sys/modules/libalias/libalias/Makefile Sun Dec 28 14:37:09 2008 (r186542) +++ user/piso/sys/modules/libalias/libalias/Makefile Sun Dec 28 17:16:32 2008 (r186543) @@ -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 Modified: user/piso/sys/netinet/ip_fw_nat.c ============================================================================== --- user/piso/sys/netinet/ip_fw_nat.c Sun Dec 28 14:37:09 2008 (r186542) +++ user/piso/sys/netinet/ip_fw_nat.c Sun Dec 28 17:16:32 2008 (r186543) @@ -326,6 +326,12 @@ ipfw_nat(struct ip_fw_args *args, struct else retval = LibAliasOut(t->lib, c, mcl->m_len + M_TRAILINGSPACE(mcl)); +#ifdef _ALIAS_SCTP + if (retval == PKT_ALIAS_RESPOND) { + m->m_flags |= M_SKIP_FIREWALL; + retval = PKT_ALIAS_OK; + } +#endif if (retval != PKT_ALIAS_OK && retval != PKT_ALIAS_FOUND_HEADER_FRAGMENT) { /* XXX - should i add some logging? */ @@ -401,6 +407,7 @@ ipfw_nat(struct ip_fw_args *args, struct } args->m = mcl; + return (IP_FW_NAT); } Modified: user/piso/sys/netinet/libalias/alias.c ============================================================================== --- user/piso/sys/netinet/libalias/alias.c Sun Dec 28 14:37:09 2008 (r186542) +++ user/piso/sys/netinet/libalias/alias.c Sun Dec 28 17:16:32 2008 (r186543) @@ -111,10 +111,18 @@ __FBSDID("$FreeBSD$"); See HISTORY file for additional revisions. */ +/** + * Modifications to add sctp functionality by David A. Hayes + * $Id: alias.c 122 2008-06-25 06:50:47Z dhayes $ + * All are inclosed in #ifdef _ALIAS_SCTP + * + */ + #ifdef _KERNEL #include #include #include +#include #else #include #include @@ -136,11 +144,28 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef _ALIAS_SCTP +#include +#endif #else #include #include "alias.h" #include "alias_local.h" #include "alias_mod.h" +#ifdef _ALIAS_SCTP +#include "alias_sctp.h" +#endif +#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 @@ -1335,6 +1360,11 @@ LibAliasInLocked(struct libalias *la, ch case IPPROTO_TCP: iresult = TcpAliasIn(la, pip); break; +#ifdef _ALIAS_SCTP + case IPPROTO_SCTP: + iresult = SctpAlias(la, pip, SN_TO_LOCAL); + break; +#endif case IPPROTO_GRE: { int error; struct alias_data ad = { @@ -1477,10 +1507,15 @@ LibAliasOutLocked(struct libalias *la, c 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 _ALIAS_SCTP + case IPPROTO_SCTP: + iresult = SctpAlias(la, pip, SN_TO_GLOBAL); + break; +#endif + case IPPROTO_GRE: { int error; struct alias_data ad = { .lnk = NULL, Modified: user/piso/sys/netinet/libalias/alias.h ============================================================================== --- user/piso/sys/netinet/libalias/alias.h Sun Dec 28 14:37:09 2008 (r186542) +++ user/piso/sys/netinet/libalias/alias.h Sun Dec 28 17:16:32 2008 (r186543) @@ -36,6 +36,13 @@ * distribution. */ +/** + * Modifications to add sctp functionality by David A. Hayes + * $Id: alias.h 122 2008-06-25 06:50:47Z dhayes $ + * All are inclosed in #ifdef _ALIAS_SCTP + * + */ + #ifndef _ALIAS_H_ #define _ALIAS_H_ @@ -45,6 +52,11 @@ #define LIBALIAS_BUF_SIZE 128 #ifdef _KERNEL + +#ifndef _ALIAS_SCTP +#define _ALIAS_SCTP //if ALIAS_SCTP code is to be included +#endif + /* * The kernel version of libalias does not support these features. */ Modified: user/piso/sys/netinet/libalias/alias_db.c ============================================================================== --- user/piso/sys/netinet/libalias/alias_db.c Sun Dec 28 14:37:09 2008 (r186542) +++ user/piso/sys/netinet/libalias/alias_db.c Sun Dec 28 17:16:32 2008 (r186543) @@ -141,6 +141,13 @@ __FBSDID("$FreeBSD$"); See HISTORY file for additional revisions. */ +/** + * Modifications to add sctp functionality by David A. Hayes + * $Id: alias_db.c 177 2008-07-14 04:33:47Z dhayes $ + * All are inclosed in #ifdef _ALIAS_SCTP + * + */ + #ifdef _KERNEL #include @@ -166,6 +173,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef _ALIAS_SCTP +#include +#endif #include #else #include "alias.h" @@ -373,6 +383,7 @@ static moduledata_t alias_mod = { }; DECLARE_MODULE(alias, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + #endif /* Internal utility routines (used only in alias_db.c) @@ -410,6 +421,10 @@ static void ClearFWHole(struct alias_lin static void ShowAliasStats(struct libalias *); static int InitPacketAliasLog(struct libalias *); static void UninitPacketAliasLog(struct libalias *); +#ifdef _ALIAS_SCTP +struct in_addr FindSctpRedirectAddress(struct libalias *la, struct sctp_nat_msg *sm); +void SctpShowAliasStats(struct libalias *la); +#endif static u_int StartPointIn(struct in_addr alias_addr, @@ -489,15 +504,25 @@ ShowAliasStats(struct libalias *la) /* Used for debugging */ if (la->logDesc) { int tot = la->icmpLinkCount + la->udpLinkCount + +#ifdef _ALIAS_SCTP + (la->sctpLinkCount>>1) + /* sctp counts half associations */ +#endif la->tcpLinkCount + la->pptpLinkCount + la->protoLinkCount + la->fragmentIdLinkCount + la->fragmentPtrLinkCount; AliasLog(la->logDesc, +#ifdef _ALIAS_SCTP + "icmp=%u, udp=%u, tcp=%u, sctp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u", +#else "icmp=%u, udp=%u, tcp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u", +#endif la->icmpLinkCount, la->udpLinkCount, la->tcpLinkCount, +#ifdef _ALIAS_SCTP + la->sctpLinkCount>>1, /* sctp counts half associations */ +#endif la->pptpLinkCount, la->protoLinkCount, la->fragmentIdLinkCount, @@ -508,6 +533,13 @@ ShowAliasStats(struct libalias *la) } } +#ifdef _ALIAS_SCTP +void SctpShowAliasStats(struct libalias *la) +{ + ShowAliasStats(la); +} +#endif + /* Internal routines for finding, deleting and adding links Port Allocation: @@ -971,6 +1003,10 @@ AddLink(struct libalias *la, struct in_a case LINK_TCP: lnk->expire_time = TCP_EXPIRE_INITIAL; break; +#ifdef _ALIAS_SCTP + case LINK_SCTP: /* treat like LINK_ADDR */ + break; +#endif case LINK_PPTP: lnk->flags |= LINK_PERMANENT; /* no timeout. */ break; @@ -1031,6 +1067,10 @@ AddLink(struct libalias *la, struct in_a return (NULL); } break; +#ifdef _ALIAS_SCTP + case LINK_SCTP: /* treat like LINK_ADDR */ + break; +#endif case LINK_PPTP: la->pptpLinkCount++; break; @@ -1277,11 +1317,17 @@ _FindLinkIn(struct libalias *la, struct src_addr = lnk->src_addr; src_port = lnk->src_port; } - - lnk = ReLink(lnk, - src_addr, dst_addr, alias_addr, - src_port, dst_port, alias_port, - link_type); +#ifdef _ALIAS_SCTP + if(link_type == LINK_SCTP) { + lnk->src_addr = src_addr; + lnk->src_port = src_port; + return(lnk); + } +#endif + lnk = ReLink(lnk, + src_addr, dst_addr, alias_addr, + src_port, dst_port, alias_port, + link_type); } return (lnk); } @@ -2277,10 +2323,15 @@ LibAliasRedirectPort(struct libalias *la case IPPROTO_TCP: link_type = LINK_TCP; break; +#ifdef _ALIAS_SCTP + case IPPROTO_SCTP: + link_type = LINK_SCTP; + break; +#endif 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 +2547,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 _ALIAS_SCTP + AliasSctpInit(la);//*** +#endif LIBALIAS_LOCK_INIT(la); LIBALIAS_LOCK(la); } else { @@ -2503,6 +2557,10 @@ LibAliasInit(struct libalias *la) la->deleteAllLinks = 1; CleanupAliasData(la); la->deleteAllLinks = 0; +#ifdef _ALIAS_SCTP + AliasSctpTerm(la); + AliasSctpInit(la); +#endif } la->aliasAddress.s_addr = INADDR_ANY; @@ -2511,6 +2569,9 @@ LibAliasInit(struct libalias *la) la->icmpLinkCount = 0; la->udpLinkCount = 0; la->tcpLinkCount = 0; +#ifdef _ALIAS_SCTP + la->sctpLinkCount = 0; +#endif la->pptpLinkCount = 0; la->protoLinkCount = 0; la->fragmentIdLinkCount = 0; @@ -2539,6 +2600,9 @@ LibAliasUninit(struct libalias *la) { LIBALIAS_LOCK(la); +#ifdef _ALIAS_SCTP + AliasSctpTerm(la); +#endif la->deleteAllLinks = 1; CleanupAliasData(la); la->deleteAllLinks = 0; @@ -2879,3 +2943,39 @@ LibAliasSetSkinnyPort(struct libalias *l la->skinnyPort = port; LIBALIAS_UNLOCK(la); } +#ifdef _ALIAS_SCTP +/** + * @brief Find the address to redirect incoming packets + * + * The function is located in alias_db.c due to calls to static functions + * + * + * @param la pointer to the libalias instance + * @param sm pointer to the incoming message + * + * @return address to redirect an incoming INIT to + */ +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 */ + } +} +#endif Modified: user/piso/sys/netinet/libalias/alias_local.h ============================================================================== --- user/piso/sys/netinet/libalias/alias_local.h Sun Dec 28 14:37:09 2008 (r186542) +++ user/piso/sys/netinet/libalias/alias_local.h Sun Dec 28 17:16:32 2008 (r186543) @@ -42,6 +42,12 @@ * * */ +/** + * Modifications to add sctp functionality by David A. Hayes + * $Id: alias_local.h 122 2008-06-25 06:50:47Z dhayes $ + * All are inclosed in #ifdef _ALIAS_SCTP + * + */ #ifndef _ALIAS_LOCAL_H_ #define _ALIAS_LOCAL_H_ @@ -50,6 +56,16 @@ #include #ifdef _KERNEL +/* if alias_sctp is not required, #define _ALIAS_SCTP should be commented out */ +#ifndef _ALIAS_SCTP +#define _ALIAS_SCTP +#endif +#ifdef _ALIAS_SCTP +#include +#endif +#endif + +#ifdef _KERNEL #include #include #include @@ -147,6 +163,32 @@ struct libalias { struct in_addr true_addr; /* in network byte order. */ u_short true_port; /* in host byte order. */ + /* + * + *alias_sctp code + */ +#ifdef _ALIAS_SCTP + /*counts associations that have progressed to UP and not yet removed */ + int sctpLinkCount; + /*Timing queue for keeping track of association timeouts */ + struct sctp_nat_timer sctpNatTimer; + + /* Size of hash table used in this instance*/ + u_int sctpNatTableSize; +/** + * @brief Local look up table + * + * lookup table of sctp_nat_assoc sorted by l_vtag/l_port + */ + LIST_HEAD(sctpNatTableL, sctp_nat_assoc) *sctpTableLocal; +/** + * @brief Global look up table + * + * lookup table of sctp_nat_assoc sorted by g_vtag/g_port + */ + LIST_HEAD(sctpNatTableG, sctp_nat_assoc) *sctpTableGlobal; +#endif + #ifdef _KERNEL /* * avoid races in libalias: every public function has to use it. @@ -198,6 +240,22 @@ struct libalias { /* Prototypes */ + /* + * + *alias_sctp code + */ +#ifdef _ALIAS_SCTP +/* + * SctpFunction prototypes + * + */ +void AliasSctpInit(struct libalias *la); +void AliasSctpTerm(struct libalias *la); + +int SctpAlias(struct libalias *la, struct ip *ip, int direction); +//int SctpAliasOut(struct libalias *la, struct ip *ip); +#endif + /* * We do not calculate TCP checksums when libalias is a kernel * module, since it has no idea about checksum offloading. Added: user/piso/sys/netinet/libalias/alias_sctp.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/piso/sys/netinet/libalias/alias_sctp.c Sun Dec 28 17:16:32 2008 (r186543) @@ -0,0 +1,2687 @@ +//* $Id$ */ +//#ifndef lint +//static char vcid[] = "$Id$"; +//#endif /* lint */ +/** + * @file alias_sctp.c + * Copyright (c) 2008, Centre for Advanced Internet Architectures + * Swinburne University of Technology, Melbourne, Australia + * (CRICOS number 00111D). + * + * 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 and 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. + * + * + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 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. + * + */ +/** @mainpage + * Alias_sctp is part of the SONATA (http://caia.swin.edu.au/urp/sonata) project + * to develop and release a BSD licensed implementation of a Network Address + * Translation (NAT) module that supports the Stream Control Transmission + * Protocol (SCTP). + * + * Traditional address and port number look ups are inadequate for SCTP's + * operation due to both processing requirements and issues with multi-homing. + * Alias_sctp integrates with FreeBSD's ipfw/libalias NAT system. + * + * Version 0.2 features include: + * - Support for global multi-homing + * - Support for ASCONF modification from Internet Draft + * (draft-stewart-behave-sctpnat-04, R. Stewart and M. Tuexen, "Stream control + * transmission protocol (SCTP) network address translation," Jul. 2008) to + * provide support for multi-homed privately addressed hosts + * - Support for forwarding of T-flagged packets + * - Generation and delivery of AbortM/ErrorM packets upon detection of NAT + * collisions + * - Per-port forwarding rules + * - Dynamically controllable logging and statistics + * - Dynamic management of timers + * - Dynamic control of hash-table size + */ + +#ifdef _KERNEL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +#include "alias_sctp.h" +#include +#include "alias.h" +#include "alias_local.h" +#include +#include +#endif //#ifdef _KERNEL + +/* ---------------------------------------------------------------------- + * FUNCTION PROTOTYPES + * ---------------------------------------------------------------------- + */ +/* Packet Parsing Functions */ +static int sctp_PktParser(struct libalias *la, int direction, struct ip *pip, + struct sctp_nat_msg *sm, struct sctp_nat_assoc **passoc); +static int GetAsconfVtags(struct libalias *la, struct sctp_nat_msg *sm, + uint32_t *l_vtag, uint32_t *g_vtag, int direction); +static int IsASCONFack(struct libalias *la, struct sctp_nat_msg *sm, int direction); + +static void AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction); +static int Add_Global_Address_to_List(struct sctp_nat_assoc *assoc, struct sctp_GlobalAddress *G_addr); +static void RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction); +static int IsADDorDEL(struct libalias *la, struct sctp_nat_msg *sm, int direction); + +/* State Machine Functions */ +static int ProcessSctpMsg(struct libalias *la, int direction, \ + struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc); + +static int ID_process(struct libalias *la, int direction,\ + struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); +static int INi_process(struct libalias *la, int direction,\ + struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); +static int INa_process(struct libalias *la, int direction,\ + struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); +static int UP_process(struct libalias *la, int direction,\ + struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); +static int CL_process(struct libalias *la, int direction,\ + struct sctp_nat_assoc *assoc, struct sctp_nat_msg *sm); +static void TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm,\ + struct sctp_nat_assoc *assoc, int sndrply, int direction); + +/* Hash Table Functions */ +static struct sctp_nat_assoc* +FindSctpLocal(struct libalias *la, struct in_addr l_addr, struct in_addr g_addr, uint32_t l_vtag, uint16_t l_port, uint16_t g_port); +static struct sctp_nat_assoc* +FindSctpGlobal(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t g_port, uint16_t l_port, int *partial_match); +static struct sctp_nat_assoc* +FindSctpGlobalClash(struct libalias *la, struct sctp_nat_assoc *Cassoc); +static struct sctp_nat_assoc* +FindSctpLocalT(struct libalias *la, struct in_addr g_addr, uint32_t l_vtag, uint16_t g_port, uint16_t l_port); +static struct sctp_nat_assoc* +FindSctpGlobalT(struct libalias *la, struct in_addr g_addr, uint32_t g_vtag, uint16_t l_port, uint16_t g_port); + +static int AddSctpAssocLocal(struct libalias *la, struct sctp_nat_assoc *assoc, struct in_addr g_addr); +static int AddSctpAssocGlobal(struct libalias *la, struct sctp_nat_assoc *assoc); +static void RmSctpAssoc(struct libalias *la, struct sctp_nat_assoc *assoc); +static void freeGlobalAddressList(struct sctp_nat_assoc *assoc); + +/* Timer Queue Functions */ +static void sctp_AddTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc); +static void sctp_RmTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc); +static void sctp_ResetTimeOut(struct libalias *la, struct sctp_nat_assoc *assoc, int newexp); +void sctp_CheckTimers(struct libalias *la); + + +/* Logging Functions */ +static void logsctperror(char* errormsg, uint32_t vtag, int error, int direction); +static void logsctpparse(int direction, struct sctp_nat_msg *sm); +static void logsctpassoc(struct sctp_nat_assoc *assoc, char *s); +static void logTimerQ(struct libalias *la); +static void logSctpGlobal(struct libalias *la); +static void logSctpLocal(struct libalias *la); +#ifdef _KERNEL +static void SctpAliasLog(const char *format, ...); +#endif + +/** @defgroup external External code changes and modifications + * + * Some changes have been made to files external to alias_sctp.(c|h). These + * changes are primarily due to code needing to call static functions within + * those files or to perform extra functionality that can only be performed + * within these files. + */ +/** @ingroup external + * @brief Log current statistics for the libalias instance + * + * This function is defined in alias_db.c, since it calls static functions in + * this file *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***