]> git.saurik.com Git - apple/network_cmds.git/commitdiff
network_cmds-245.19.tar.gz mac-os-x-10411ppc mac-os-x-10411x86 v245.19
authorApple <opensource@apple.com>
Sat, 14 Jul 2007 01:12:38 +0000 (01:12 +0000)
committerApple <opensource@apple.com>
Sat, 14 Jul 2007 01:12:38 +0000 (01:12 +0000)
alias/alias_db.c
natd.tproj/natd.c
tftpd.tproj/Makefile.postamble

index 9d6b99609a771314a698557134915118b9f07757..f6088dd6009dd63aaa64032af4f3cc4b40dd2b88 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <syslog.h>
 
 #include <sys/queue.h>
 #include <sys/socket.h>
@@ -596,6 +597,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
@@ -605,6 +607,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)
 {
@@ -613,6 +654,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
@@ -1957,16 +2001,18 @@ FindAliasPortOut(struct in_addr src_addr, struct in_addr dst_addr, u_short src_p
         link_type = LINK_TCP;
         break;
     default:
-        return NULL;
+        return 0;
         break;
     }
 
 #ifdef DEBUG
        {
-               int icount;
+               int icount = 0;
                
-               printf("PORTMAP::srcaddr = 0x%x.%d, dstaddr = 0x%x.%d link_type = %d, lifetime = %d\n", 
-                       src_addr.s_addr, src_port, dst_addr.s_addr, pub_port, link_type, lifetime);
+               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++)
                {
@@ -1974,11 +2020,19 @@ FindAliasPortOut(struct in_addr src_addr, struct in_addr dst_addr, u_short src_p
                        while (link != NULL)
                        {
                                struct alias_link *link_next;
-
-                               printf("PORTMAP:: linksrcaddr = 0x%x.%d, linkdstaddr = 0x%x.%d, aliasaddr=0x%x.%d, linktype = %d\n", 
-                                       link->src_addr.s_addr,link->src_port,link->dst_addr.s_addr,link->dst_port, link->alias_addr.s_addr,link->alias_port, 
-                                       link->link_type);
-
+                               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",
+                                       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;
@@ -2004,20 +2058,22 @@ FindAliasPortOut(struct in_addr src_addr, struct in_addr dst_addr, u_short src_p
        {   
         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);        
+               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 */
-               if ( !pub_port )
-                       pub_port = GET_ALIAS_PORT;
         link = AddLink(src_addr, dst_addr, alias_addr,
-                       src_port, 0, pub_port,
+                       src_port, 0, GET_ALIAS_EPHEMERAL_PORT,
                        link_type);
-               if ( link != NULL )
+               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 )
        {
@@ -3001,3 +3057,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;
+               }
+       }
+       
+}
index a04d99f5eea2cdc1d1867c6ffc3de88a10b0e0aa..043b370e79b54419b8fa62efd788281e415cd308 100644 (file)
@@ -111,6 +111,7 @@ static void SetAliasAddressFromIfName (const char *ifName);
 static void    InitiateShutdown (int);
 static void    Shutdown (int);
 static void    RefreshAddr (int);
+static void    HandleInfo (int);
 static void    ParseOption (const char* option, const char* parms);
 static void    ReadConfigFile (const char* fileName);
 static void    SetupPortRedirect (const char* parms);
@@ -152,6 +153,7 @@ static      int                     packetDirection;
 static  int                    dropIgnoredIncoming;
 static  int                    logDropped;
 static int                     logFacility;
+static int                     dumpinfo;
 
 #define        NATPORTMAP              1
 
@@ -173,47 +175,50 @@ static    int                     logFacility;
 #define OUTOFRESOURCES                 4
 #define UNSUPPORTEDOPCODE              5
 #define MAXRETRY        10
-#define TIMER_RATE      250
+#define TIMER_RATE      250000
 
 #define FAILED                                 -1
 
-typedef struct  stdportmaprequest{
-               char                    version;
-               unsigned char   opcode;
-               unsigned short  result;
-               char                    data[4];
-       }stdportmaprequest;
-
-typedef struct  publicaddrreply{
-               char                    version;
-               unsigned char   opcode;
-               unsigned short  result;
-               unsigned int    epoch;
-               struct in_addr  addr;
-       }publicaddrreply;
-typedef struct  publicportreq{
-               char                    version;
-               unsigned char   opcode;
-               unsigned short  result;
-               unsigned short  privateport;
-               unsigned short  publicport;
-               int                             lifetime;               /* in second */
-       }publicportreq;
-typedef struct  publicportreply{
-                char                    version;
-                unsigned char   opcode;
-                unsigned short  result;
-                unsigned int    epoch;
-                unsigned short  privateport;
-                unsigned short  publicport;
-                int             lifetime;               /* in second */
-        }publicportreply;
-typedef struct  stderrreply{
-               char                    version;
-               unsigned char   opcode;
-               unsigned short  result;
-               unsigned int    epoch;
-       }stderrreply;
+typedef struct  stdportmaprequest {
+       char                    version;
+       unsigned char   opcode;
+       unsigned short  result;
+       char                    data[4];
+} stdportmaprequest;
+
+typedef struct  publicaddrreply {
+       char                    version;
+       unsigned char   opcode;
+       unsigned short  result;
+       unsigned int    epoch;
+       struct in_addr  addr;
+ } publicaddrreply;
+
+typedef struct  publicportreq {
+       char                    version;
+       unsigned char   opcode;
+       unsigned short  result;
+       unsigned short  privateport;
+       unsigned short  publicport;
+       int                             lifetime;               /* in second */
+} publicportreq;
+
+typedef struct  publicportreply {
+       char                    version;
+       unsigned char   opcode;
+       unsigned short  result;
+       unsigned int    epoch;
+       unsigned short  privateport;
+       unsigned short  publicport;
+       int             lifetime;               /* in second */
+} publicportreply;
+
+typedef struct  stderrreply {
+       char                    version;
+       unsigned char   opcode;
+       unsigned short  result;
+       unsigned int    epoch;
+} stderrreply;
 
 
 static int             enable_natportmap = 0; 
@@ -232,7 +237,7 @@ static  double              secdivisor;
 static void            HandlePortMap( int fd );
 static void            SendPortMapResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, unsigned char origopcode, unsigned short result);
 static void            SendPublicAddress( int fd, struct sockaddr_in *clientaddr, int clientaddrlen );
-static void            SendPublicPortResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, publicportreq *reply, int  publicport);
+static void            SendPublicPortResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, publicportreq *reply, u_short publicport, int result);
 static void            Doubletime( struct timeval *tvp);
 static void            Stoptimer();
 static void            Natdtimer();
@@ -445,6 +450,7 @@ int main (int argc, char** argv)
        siginterrupt(SIGHUP, 1);
        signal (SIGTERM, InitiateShutdown);
        signal (SIGHUP, RefreshAddr);
+       signal (SIGINFO, HandleInfo);
 /*
  * Set alias address if it has been given.
  */
@@ -535,9 +541,13 @@ int main (int argc, char** argv)
                            NULL,
                            NULL) == -1) {
 
-                       if (errno == EINTR)
+                       if (errno == EINTR) {
+                               if (dumpinfo) {
+                                       DumpInfo();
+                                       dumpinfo = 0;
+                               }
                                continue;
-
+                       }
                        Quit ("Select failed.");
                }
 
@@ -633,8 +643,8 @@ static void DoAliasing (int fd, int direction)
        int                     bytes;
        int                     origBytes;
        int                     status;
-       int                     addrSize;
-       struct ip*              ip;
+       socklen_t       addrSize;
+       struct ip*      ip;
 
        if (assignAliasAddr) {
 
@@ -925,7 +935,7 @@ static void SendPublicAddress( int fd, struct sockaddr_in *clientaddr, int clien
        reply.opcode = SERVERREPLYOP + PUBLICADDRREQ;
        reply.result = SUCCESS;
        reply.addr = lastassignaliasAddr;
-        reply.epoch = getuptime();
+       reply.epoch = getuptime();
 
        bytes = sendto (fd, (void*)&reply, sizeof(reply), 0, (struct sockaddr*)clientaddr, clientaddrlen);
        if ( bytes != sizeof(reply) )
@@ -935,24 +945,29 @@ static void SendPublicAddress( int fd, struct sockaddr_in *clientaddr, int clien
 /* SendPublicPortResponse */
 /* response for portmap request and portmap removal request */
 /* publicport <= 0 means error */
-static void SendPublicPortResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, publicportreq *req, int  publicport)
+static void SendPublicPortResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, publicportreq *req, u_short publicport, int result)
 {
 
        int                             bytes;
        publicportreply                 reply;
        
+       bzero(&reply, sizeof(publicportreply));
        reply.version = NATPMVERSION;
        reply.opcode = SERVERREPLYOP + req->opcode;
-       if ( publicport <= 0)
+       if (result)
                /* error in port mapping */
                reply.result = OUTOFRESOURCES;
        else
                reply.result = SUCCESS;
-        reply.epoch = getuptime();
+       
+       reply.epoch = getuptime();
+
+       reply.privateport = req->privateport;
 
-       if ( req->lifetime ){                   /* not delete mapping */
-               reply.privateport = req->privateport;
+       /* adding or renewing a mapping */
+       if ( req->lifetime ) {
                reply.publicport = publicport;
+               reply.lifetime = req->lifetime;
        }
        bytes = sendto (fd, (void*)&reply, sizeof(publicportreply), 0, (struct sockaddr*)clientaddr, clientaddrlen);
        if ( bytes != sizeof(publicportreply) )
@@ -1013,23 +1028,18 @@ static void SendPortMapMulti()
 /* double the time value */
 static void Doubletime( struct timeval *tvp)
 {
-
-        if ( tvp->tv_sec )
-                tvp->tv_sec *= 2;
-        if ( tvp->tv_usec )
-                tvp->tv_usec *= 2;
-        if (tvp->tv_usec >= 1000000) {
-               tvp->tv_sec += tvp->tv_usec / 1000000;
-               tvp->tv_usec = tvp->tv_usec % 1000000;
-        }
+       
+       timeradd(tvp, tvp, tvp);
+       
 }
 
 /* stop running natd timer */
 static void Stoptimer()
 {
-        itval.it_value.tv_usec = 0;
-        if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0)
-                printf( "setitimer err: %d\n", errno);
+       itval.it_value.tv_sec = 0;
+       itval.it_value.tv_usec = 0;
+       if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0)
+               printf( "setitimer err: %d\n", errno);
 }
 
 /* natdtimer */
@@ -1043,7 +1053,8 @@ static void Natdtimer()
        
        if ( numoftries < MAXRETRY ){
                Doubletime( &itval.it_value);
-               itval.it_interval = itval.it_value;
+               itval.it_interval.tv_sec = 0;
+               itval.it_interval.tv_usec = 0;
                if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0)
                                printf( "setitimer err: %d\n", errno);
        }
@@ -1070,7 +1081,7 @@ static void NotifyPublicAddress()
        itval.it_value.tv_sec = 0;
        itval.it_value.tv_usec = TIMER_RATE;
        itval.it_interval.tv_sec = 0;
-       itval.it_interval.tv_usec = TIMER_RATE;
+       itval.it_interval.tv_usec = 0;
        if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0)
                        printf( "setitimer err: %d\n", errno);
 
@@ -1082,26 +1093,33 @@ void DoPortMapping( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, p
 {
        u_char          proto = IPPROTO_TCP;
        int             aliasport;
+       struct in_addr inany = { INADDR_ANY };
        
        if ( req->opcode == MAPUDPREQ)
                proto = IPPROTO_UDP;
        if ( req->lifetime == 0)
        {
                /* remove port mapping */
-               if ( !FindAliasPortOut(  clientaddr->sin_addr, lastassignaliasAddr, req->privateport, req->publicport, proto, req->lifetime, 0))
+               if ( !FindAliasPortOut(  clientaddr->sin_addr, inany , req->privateport, req->publicport, proto, req->lifetime, 0))
                        /* FindAliasPortOut returns no error, port successfully removed, return no error response to client */
-                       SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, 1 );
+                       SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, 0, 0 );
                else
                        /* deleting port fails, return error */
-                       SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, -1 );
+                       SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, 0, -1 );
        }
        else 
        {
                /* look for port mapping - public port is ignored in this case */
                /* create port mapping - map provided public port to private port if public port is not 0 */
-               aliasport = FindAliasPortOut(  clientaddr->sin_addr, lastassignaliasAddr, req->privateport, req->publicport, proto, req->lifetime, 1);
+               aliasport = FindAliasPortOut(  clientaddr->sin_addr, 
+                       inany, /* lastassignaliasAddr */
+                       req->privateport, 
+                       0, 
+                       proto, 
+                       req->lifetime, 
+                       1);
                /* aliasport should be non zero if mapping is successfully, else -1 is returned, alias port shouldn't be zero???? */
-               SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, aliasport );
+               SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, aliasport, 0 );
                        
        }
 }
@@ -1110,69 +1128,70 @@ void DoPortMapping( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, p
 /* handle all packets sent to NATPORTMAP port  */
 static void HandlePortMap( int fd )
 {
-#define                MAXBUFFERSIZE           100
-
-        struct sockaddr_in     clientaddr;
-        int                    clientaddrlen;
-               unsigned char           buffer[MAXBUFFERSIZE];
-               int                                                     bytes;
-               unsigned short                          result = SUCCESS;
-               struct stdportmaprequest        *req;
-
-        clientaddrlen = sizeof( clientaddr );
-        bytes = recvfrom( fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&clientaddr, &clientaddrlen);
-        if ( bytes == -1 )
-        {
-                printf( "Read NATPM port error\n");
-                return;
-        }
-        req = (struct stdportmaprequest*)buffer;
+       #define         MAXBUFFERSIZE           100
+       
+       struct sockaddr_in                      clientaddr;
+       socklen_t                                       clientaddrlen;
+       unsigned char                           buffer[MAXBUFFERSIZE];
+       int                                                     bytes;
+       unsigned short                          result = SUCCESS;
+       struct stdportmaprequest        *req;
+       
+       clientaddrlen = sizeof( clientaddr );
+       bytes = recvfrom( fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&clientaddr, &clientaddrlen);
+       if ( bytes == -1 )
+       {
+               printf( "Read NATPM port error\n");
+               return;
+       }
+       req = (struct stdportmaprequest*)buffer;
+       
+       #ifdef DEBUG
+       {
+               int i;
                
-#ifdef DEBUG
+               printf("HandlePortMap from %s:%u length= %d: ", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, bytes);
+               for ( i = 0; i<bytes; i++)
                {
-                       int i;
-                       
-                       for ( i = 0; i<bytes; i++)
-                       {
-                               printf("%d", buffer[i]);
-                       }
-                       printf("\n");
+                       printf("%02x", buffer[i]);
                }
-#endif                 
-               /* check client version */
-               if ( req->version > NATPMVERSION )
-                       result = NOTSUPPORTEDVERSION;
-               else if ( !enable_natportmap )
-                       /* natd wasn't launched with portmapping enabled */
-                       result = NOTAUTHORIZED;
-                       
-               if ( result )
+               printf("\n");
+       }
+       #endif                  
+       /* check client version */
+       if ( req->version > NATPMVERSION )
+               result = NOTSUPPORTEDVERSION;
+       else if ( !enable_natportmap )
+               /* natd wasn't launched with portmapping enabled */
+               result = NOTAUTHORIZED;
+               
+       if ( result )
+       {
+               SendPortMapResponse( fd, &clientaddr, clientaddrlen, req->opcode, result );
+               return;
+       }
+               
+       switch ( req->opcode )
+       {
+               case PUBLICADDRREQ:
                {
-                       SendPortMapResponse( fd, &clientaddr, clientaddrlen, req->opcode, result );
-                       return;
+                       SendPublicAddress(fd, &clientaddr, clientaddrlen);
+                       break;
                }
-                       
-               switch ( req->opcode )
+               
+               case MAPUDPREQ:
+               case MAPTCPREQ:
+               case MAPUDPTCPREQ:
                {
-                       case PUBLICADDRREQ:
-                       {
-                               SendPublicAddress(fd, &clientaddr, clientaddrlen);
-                               break;
-                       }
-                       
-                       case MAPUDPREQ:
-                       case MAPTCPREQ:
-                       case MAPUDPTCPREQ:
-                       {
-                               DoPortMapping( fd, &clientaddr, clientaddrlen, (publicportreq*)req);
-                               break;
-                       }
-                       
-                       
-                       default:
-                               SendPortMapResponse( fd, &clientaddr, clientaddrlen, req->opcode, UNSUPPORTEDOPCODE );
+                       DoPortMapping( fd, &clientaddr, clientaddrlen, (publicportreq*)req);
+                       break;
                }
-                       
+               
+               
+               default:
+                       SendPortMapResponse( fd, &clientaddr, clientaddrlen, req->opcode, UNSUPPORTEDOPCODE );
+       }
+               
 }
 
 
@@ -1387,6 +1406,11 @@ static void Shutdown (int sig)
        running = 0;
 }
 
+static void HandleInfo (int sig)
+{
+       dumpinfo++;
+}
+
 /* 
  * Different options recognized by this program.
  */
index f5423b9f2569fcc27268aeba479c0bd6f7222fbc..0505ae054353f2b6eca7c4a6547b795c8280f2ca 100644 (file)
@@ -115,5 +115,4 @@ after_install:
        mkdir -p "$(DSTROOT)/System/Library/LaunchDaemons"
        cp tftp.plist "$(DSTROOT)/System/Library/LaunchDaemons/"
        cp tftp.plist-SERVER "$(DSTROOT)/System/Library/LaunchDaemons/"
-       mkdir -p "$(DSTROOT)/private/tftpboot/private"
-       ln -s / "$(DSTROOT)/private/tftpboot/private/tftpboot"
+       mkdir -p "$(DSTROOT)/private/tftpboot"