]> git.saurik.com Git - apple/network_cmds.git/blobdiff - alias/alias_db.c
network_cmds-457.tar.gz
[apple/network_cmds.git] / alias / alias_db.c
index 8c8c70817c74ece3da24de4edd23e5bf42ae85b6..81dfff9142f197130c2cf0bee0f7a02adb9a752f 100644 (file)
@@ -3,22 +3,19 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
  * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <syslog.h>
 
 #include <sys/queue.h>
 #include <sys/socket.h>
@@ -275,8 +273,8 @@ static int iChatAVHack = 1;
 
 struct ack_data_record     /* used to save changes to ACK/sequence numbers */
 {
-    u_long ack_old;
-    u_long ack_new;
+    __uint32_t ack_old;
+    __uint32_t ack_new;
     int delta;
     int active;
 };
@@ -450,9 +448,11 @@ static u_int StartPointIn(struct in_addr, u_short, int);
 static u_int StartPointOut(struct in_addr, struct in_addr,
                            u_short, u_short, int);
 
-static int SeqDiff(u_long, u_long);
+static int SeqDiff(__uint32_t, __uint32_t);
 
+#ifndef        DEBUG
 static void ShowAliasStats(void);
+#endif
 
 #ifndef NO_FW_PUNCH
 /* Firewall control */
@@ -499,7 +499,7 @@ StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
 
 
 static int
-SeqDiff(u_long x, u_long y)
+SeqDiff(__uint32_t x, __uint32_t y)
 {
 /* Return the difference between two TCP sequence numbers */
 
@@ -512,6 +512,7 @@ SeqDiff(u_long x, u_long y)
 }
 
 
+#ifndef        DEBUG
 static void
 ShowAliasStats(void)
 {
@@ -540,6 +541,7 @@ ShowAliasStats(void)
       fflush(monitorFile);
    }
 }
+#endif
 
 
 
@@ -599,6 +601,7 @@ FindLinkIn(struct in_addr, struct in_addr, u_short, u_short, int, int);
 #define GET_NEW_PORT_MAX_ATTEMPTS       20
 
 #define GET_ALIAS_PORT                  -1
+#define GET_ALIAS_EPHEMERAL_PORT        -2
 #define GET_ALIAS_ID        GET_ALIAS_PORT
 
 #define FIND_EVEN_ALIAS_BASE             1
@@ -608,6 +611,45 @@ FindLinkIn(struct in_addr, struct in_addr, u_short, u_short, int, int);
    another link concurrently.  This is because GetNewPort() looks for
    unused triplets: (dest addr, dest port, alias port). */
 
+static int
+GetEphemeralPort(struct alias_link *link)
+{
+       int i;
+       
+       /* Port number search */
+       for (i=0; i < GET_NEW_PORT_MAX_ATTEMPTS; i++)
+       {
+               struct sockaddr_in sock_addr;
+               socklen_t salen;
+               u_short port_net;
+               struct alias_link *search_result;
+       
+               if (GetSocket(0, &link->sockfd, link->link_type) == 0)
+                       return -1;
+               salen = sizeof(struct sockaddr_in);
+               if (getsockname(link->sockfd, (struct sockaddr *)&sock_addr, &salen) == -1)
+                       return -1;
+               port_net = sock_addr.sin_port;
+       
+               search_result = FindLinkIn(link->dst_addr, link->alias_addr,
+                                                                  link->dst_port, port_net,
+                                                                  link->link_type, 0);
+       
+               if (search_result == NULL) {
+                       link->alias_port = port_net;
+                       return(0);
+               }
+               close(link->sockfd);
+               link->sockfd = -1;
+       }
+       #ifdef DEBUG
+       fprintf(stderr, "PacketAlias/GetEphemeralPort(): ");
+       fprintf(stderr, "could not find free port\n");
+       #endif
+       
+       return(-1);
+}
+
 static int
 GetNewPort(struct alias_link *link, int alias_port_param)
 {
@@ -616,6 +658,9 @@ GetNewPort(struct alias_link *link, int alias_port_param)
     u_short port_sys;
     u_short port_net;
 
+       if (alias_port_param == GET_ALIAS_EPHEMERAL_PORT)
+               return GetEphemeralPort(link);
+
 /*
    Description of alias_port_param for GetNewPort().  When
    this parameter is zero or positive, it precisely specifies
@@ -625,7 +670,6 @@ GetNewPort(struct alias_link *link, int alias_port_param)
    When this parameter is GET_ALIAS_PORT, it indicates to get a randomly
    selected port number.
 */
     if (alias_port_param == GET_ALIAS_PORT)
     {
         /*
@@ -711,7 +755,6 @@ GetNewPort(struct alias_link *link, int alias_port_param)
         port_sys += ALIAS_PORT_BASE;
         port_net = htons(port_sys);
     }
-
 #ifdef DEBUG
     fprintf(stderr, "PacketAlias/GetnewPort(): ");
     fprintf(stderr, "could not find free port\n");
@@ -1115,7 +1158,6 @@ AddLink(struct in_addr  src_addr,
             free(link);
             return(NULL);
         }
-
     /* Link-type dependent initialization */
         switch(link_type)
         {
@@ -1942,6 +1984,115 @@ FindAliasAddress(struct in_addr original_addr)
     }
 }
 
+/* FindAliasPortOut */
+/* external routine for NatPortMap */
+/* return alias port for the src_addr,dst_addr,src_port and proto */
+/* if one doesn't existed, create a mapping with providing pub_port if it's not 0 */
+/* delete mapping if addmapping is not true */
+int
+FindAliasPortOut(struct in_addr src_addr, struct in_addr dst_addr, u_short src_port, u_short pub_port, u_char proto, int lifetime, char addmapping)
+{
+    u_int i;
+    struct alias_link *link;
+    int link_type;
+
+    switch (proto)
+    {
+    case IPPROTO_UDP:
+        link_type = LINK_UDP;
+        break;
+    case IPPROTO_TCP:
+        link_type = LINK_TCP;
+        break;
+    default:
+        return 0;
+        break;
+    }
+
+#ifdef DEBUG
+       {
+               int icount = 0;
+               
+               printf("FindAliasPortOut:: srcaddr= %s:%u, ", 
+                       inet_ntoa(src_addr), ntohs(src_port));
+               printf("dstadd= %s:%u link_type= %d, lifetime= %d\n", 
+                       inet_ntoa(dst_addr), ntohs(pub_port), link_type, lifetime);
+                       
+               for (i=0; i<LINK_TABLE_OUT_SIZE; i++)
+               {
+                       link = LIST_FIRST(&linkTableOut[i]);
+                       while (link != NULL)
+                       {
+                               struct alias_link *link_next;
+                               char src_str[32], dst_str[32], alias_str[32];
+       
+                               snprintf(src_str, sizeof(src_str), "%s:%u",
+                                       inet_ntoa(link->src_addr), ntohs(link->src_port));
+                               snprintf(dst_str, sizeof(dst_str), "%s:%u",
+                                       inet_ntoa(link->dst_addr), ntohs(link->dst_port));
+                               snprintf(alias_str, sizeof(alias_str), "%s:%u",
+                                       inet_ntoa(link->alias_addr), ntohs(link->alias_port));
+       
+                               printf(" linkTableOut[%d:%d] src= %s dst= %s alias= %s flags= 0x%x linktype= %d ts= %d exp= %d fd= %d\n",
+                                       i, icount, src_str, dst_str, alias_str, 
+                                       link->flags, link->link_type, link->timestamp, link->expire_time, link->sockfd);
+       
+                               link_next = LIST_NEXT(link, list_out);
+                               icount++;
+                               link = link_next;
+                       }
+               }
+               
+       }
+#endif
+
+    i = StartPointOut(src_addr, dst_addr, src_port, 0, link_type);
+#ifdef DEBUG
+       printf("PORTMAP::StartPointOut returns %d\n", i);
+#endif
+    LIST_FOREACH(link, &linkTableOut[i], list_out)
+       {
+               if (link->src_addr.s_addr == src_addr.s_addr &&
+                       link->dst_addr.s_addr == dst_addr.s_addr &&
+                       link->src_port == src_port && link->link_type == link_type)
+                       break;
+       }
+
+       if ( link == NULL && addmapping)
+       {   
+        struct in_addr alias_addr;
+#ifdef DEBUG
+               printf("PORTMAP:: cannot find mapping, adding mapping private port =%d, public port = %d\n",
+                       src_port, pub_port);    
+#endif
+               /* address/port in not in list, create new mapping */
+               
+        alias_addr = FindAliasAddress(src_addr);
+               /* create new mapping */
+        link = AddLink(src_addr, dst_addr, alias_addr,
+                       src_port, 0, GET_ALIAS_EPHEMERAL_PORT,
+                       link_type);
+               if ( link != NULL ) {
+                       /* link was create, set new lifetime */
+                       SetExpire(link, lifetime);
+                       /* Prevent link deletion when incoming connection arrive */
+                       link->flags |= LINK_CONE;
+               }
+       }
+       if ( link )
+       {
+               if ( addmapping )
+                       return( GetAliasPort(link));
+               else
+               {
+                       SetExpire(link, 0);                             /* delete mapping */
+                       return 0;
+               }       
+       }
+       
+       return -1;
+}
+
 
 /* External routines for getting or changing link data
    (external to alias_db.c, but internal to alias*.c)
@@ -2164,7 +2315,7 @@ packet size was altered is searched.
     int i;
     struct tcphdr *tc;
     int delta, ack_diff_min;
-    u_long ack;
+    __uint32_t ack;
 
     tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
     ack      = tc->th_ack;
@@ -2215,7 +2366,7 @@ packet size was altered is searched.
     int i;
     struct tcphdr *tc;
     int delta, seq_diff_min;
-    u_long seq;
+    __uint32_t seq;
 
     tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
     seq = tc->th_seq;
@@ -2910,3 +3061,36 @@ PacketAliasSetFWBase(unsigned int base, unsigned int num) {
     fireWallNumNums = num;
 #endif
 }
+
+void
+DumpInfo(void)
+{
+       int i, icount = 0;
+       struct alias_link *link;
+       
+       for (i=0; i<LINK_TABLE_OUT_SIZE; i++)
+       {
+               link = LIST_FIRST(&linkTableOut[i]);
+               while (link != NULL)
+               {
+                       struct alias_link *link_next;
+                       char src_str[32], dst_str[32], alias_str[32];
+
+                       snprintf(src_str, sizeof(src_str), "%s:%u",
+                               inet_ntoa(link->src_addr), ntohs(link->src_port));
+                       snprintf(dst_str, sizeof(dst_str), "%s:%u",
+                               inet_ntoa(link->dst_addr), ntohs(link->dst_port));
+                       snprintf(alias_str, sizeof(alias_str), "%s:%u",
+                               inet_ntoa(link->alias_addr), ntohs(link->alias_port));
+
+                       syslog(LOG_ERR, " linkTableOut[%d:%d] src= %s dst= %s alias= %s flags= 0x%x linktype= %d ts= %d exp= %d fd= %d",
+                               i, icount, src_str, dst_str, alias_str, 
+                               link->flags, link->link_type, link->timestamp, link->expire_time, link->sockfd);
+
+                       link_next = LIST_NEXT(link, list_out);
+                       icount++;
+                       link = link_next;
+               }
+       }
+       
+}