TcpMonitorIn() -- These routines monitor TCP connections, and
TcpMonitorOut() delete a link when a connection is closed.
+ DoMSSClamp() -- Clamps the MSS of the given TCP header to the
+ value in packetAliasMSS.
+
These routines look for SYN, FIN and RST flags to determine when TCP
connections open and close. When a TCP connection closes, the data
structure containing packet aliasing information is deleted after
static void TcpMonitorOut(struct ip *, struct alias_link *);
+static u_short packetAliasMSS;
+
+void PacketAliasClampMSS(u_short mss)
+{
+ packetAliasMSS = mss;
+}
+
+static void DoMSSClamp(struct tcphdr *tc)
+{
+ u_char *option = (u_char *) tc + sizeof(*tc);
+ u_char *optionEnd = option + ((tc->th_off << 2) - sizeof(*tc));
+
+ while (optionEnd > option)
+ {
+ switch (option[0])
+ {
+ case TCPOPT_EOL:
+ option = optionEnd;
+ break;
+
+ case TCPOPT_NOP:
+ ++option;
+ break;
+
+ case TCPOPT_MAXSEG:
+ if (option[1] == 4)
+ {
+ u_short *mssPtr = (u_short *) option + 1;
+ u_short mssVal = ntohs(*mssPtr);
+
+ if (packetAliasMSS < mssVal)
+ {
+ int accumulate = mssVal;
+ accumulate -= packetAliasMSS;
+ *mssPtr = htons(packetAliasMSS);
+ ADJUST_CHECKSUM(accumulate, tc->th_sum);
+ }
+
+ option = optionEnd;
+ }
+ break;
+
+ default:
+ option += option[1];
+ break;
+ }
+ }
+}
+
static void
TcpMonitorIn(struct ip *pip, struct alias_link *link)
{
if (tc->th_flags & TH_RST)
SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
else if (tc->th_flags & TH_SYN)
+ {
SetStateIn(link, ALIAS_TCP_STATE_CONNECTED);
+
+ if (packetAliasMSS)
+ DoMSSClamp(tc);
+ }
break;
case ALIAS_TCP_STATE_CONNECTED:
if (tc->th_flags & (TH_FIN | TH_RST))
if (tc->th_flags & TH_RST)
SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
else if (tc->th_flags & TH_SYN)
+ {
SetStateOut(link, ALIAS_TCP_STATE_CONNECTED);
+
+ if (packetAliasMSS)
+ DoMSSClamp(tc);
+ }
break;
case ALIAS_TCP_STATE_CONNECTED:
if (tc->th_flags & (TH_FIN | TH_RST))
PacketAliasSetFWBase(unsigned int, unsigned int);
#endif
+ extern void
+ PacketAliasClampMSS(u_short mss);
+
/* Packet Handling */
extern int
PacketAliasIn(char *, int maxpacketsize);
.\" manual page [] for natd 1.4
-.\" $Id: natd.8,v 1.4 2002/05/10 00:51:01 mscopp Exp $
+.\" $Id: natd.8,v 1.4.32.1 2003/03/11 00:59:15 mscopp Exp $
.Dd June 27, 2000
.Os Darwin
.Dt NATD 8
.Op Fl log_denied
.Op Fl log_facility Ar facility_name
.Op Fl punch_fw Ar firewall_range
+.Op Fl clamp_mss
.Ek
.Sh DESCRIPTION
This program provides a Network Address Translation facility for use
.Ar basenumber
will be used for punching firewall holes.
The range will be cleared for all rules on startup.
+.It Fl clamp_mss Xo
+.Xc
+This option enables MSS clamping. The MSS value is derived from the
+MTU of the interface specified in the
+.Fl interface
+option.
.El
.Sh RUNNING NATD
The following steps are necessary before attempting to run
static u_short inOutPort;
static struct in_addr aliasAddr;
static int dynamicMode;
+static int clampMSS;
static int ifMTU;
static int aliasOverhead;
static int icmpSock;
if (aliasAddr.s_addr == INADDR_NONE && ifName == NULL)
errx (1, "aliasing address not given");
- if (aliasAddr.s_addr != INADDR_NONE && ifName != NULL)
- errx (1, "both alias address and interface "
- "name are not allowed");
/*
* Check that valid port number is known.
*/
strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) {
ifIndex = ifm->ifm_index;
ifMTU = ifm->ifm_data.ifi_mtu;
+ if (clampMSS)
+ PacketAliasClampMSS(ifMTU - sizeof(struct tcphdr) - sizeof(struct ip));
break;
}
}
/*
* Get interface address.
*/
+ if (aliasAddr.s_addr == INADDR_NONE) {
sin = NULL;
while (next < lim) {
ifam = (struct ifa_msghdr *)next;
PacketAliasSetAddress(sin->sin_addr);
syslog(LOG_INFO, "Aliasing to %s, mtu %d bytes",
inet_ntoa(sin->sin_addr), ifMTU);
+ }
free(buf);
}
RedirectAddress,
ConfigFile,
DynamicMode,
+ ClampMSS,
ProxyRule,
LogDenied,
LogFacility,
"dynamic",
NULL },
+ { ClampMSS,
+ 0,
+ YesNo,
+ "[yes|no]",
+ "enable TCP MSS clamping",
+ "clamp_mss",
+ NULL },
+
{ InPort,
0,
Service,
dynamicMode = yesNoValue;
break;
+ case ClampMSS:
+ clampMSS = yesNoValue;
+ break;
+
case InPort:
inPort = uNumValue;
break;
/*
- * $Source: /cvs/Darwin/src/live/network_cmds/rlogin.tproj/krcmd.c,v $
+ * $Source: /cvs/root/network_cmds/rlogin.tproj/krcmd.c,v $
* $Header: /mit/kerberos/ucb/mit/kcmd/RCS/krcmd.c,v 5.1
* 89/07/25 15:38:44 kfall Exp Locker: kfall $
* static char *rcsid_kcmd_c =
/*
- * $Source: /cvs/Darwin/src/live/network_cmds/rsh.tproj/rsh.c,v $
- * $Header: /cvs/Darwin/src/live/network_cmds/rsh.tproj/rsh.c,v 1.1.1.1 1999/05/02 03:58:17 wsanchez Exp $
+ * $Source: /cvs/root/network_cmds/rsh.tproj/rsh.c,v $
+ * $Header: /cvs/root/network_cmds/rsh.tproj/rsh.c,v 1.1.1.1 1999/05/02 03:58:17 wsanchez Exp $
*/
#include <sys/types.h>