]> git.saurik.com Git - apple/network_cmds.git/blobdiff - alias/alias.c
network_cmds-328.tar.gz
[apple/network_cmds.git] / alias / alias.c
index fffcae238162f6d7fa9d05d3812a36f8fa0bc74c..668dbe1c9df846ca3f6676b85b9c02a7c25a0157 100644 (file)
     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
@@ -176,6 +179,72 @@ static void TcpMonitorIn(struct ip *, struct alias_link *);
 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));
+
+#define TEST_5618045 0
+#if TEST_5618045
+       if ((ntohs(tc->th_dport) == 8080 || ntohs(tc->th_sport) == 8080) && tc->th_off > 5) {
+               option[0] = 0xF4;
+               option[1] = 0;
+       }
+#endif
+
+    while (optionEnd > option)
+    {
+        /* Bounds checking to avoid infinite loops */
+        if (option[0] == TCPOPT_EOL)
+            break;
+        
+        if (option[0] == TCPOPT_NOP) {
+            ++option;
+            continue;
+        } else {
+            if (optionEnd - option < 2)
+                break;
+            if (option[1] < 2 || option + option[1] >= optionEnd)
+                break;
+       }
+
+        switch (option[0])
+        {
+            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;
+                        int accnetorder = 0 ;
+                        
+                        accumulate -= packetAliasMSS;
+                        *mssPtr = htons(packetAliasMSS);
+                        accnetorder = htons(accumulate);
+                        ADJUST_CHECKSUM(accnetorder, tc->th_sum);
+                    }
+
+                    option = optionEnd;
+                }
+                break;
+
+            default:
+                option += option[1];
+                break;
+        }
+    }
+}
+
 static void
 TcpMonitorIn(struct ip *pip, struct alias_link *link)
 {
@@ -189,7 +258,12 @@ 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))
@@ -211,7 +285,12 @@ TcpMonitorOut(struct ip *pip, struct alias_link *link)
             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))
@@ -1408,7 +1487,7 @@ PacketAliasOut(char *ptr,           /* valid IP packet */
     addr_save = GetDefaultAliasAddress();
     if (packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY)
     {
-        u_long addr;
+        in_addr_t addr;
         int iclass;
 
         iclass = 0;