From f47db663cb3ae4d2fc391bb3acf9d0c2b38a41b7 Mon Sep 17 00:00:00 2001 From: Apple Date: Sat, 14 Jul 2007 01:12:38 +0000 Subject: [PATCH] network_cmds-245.19.tar.gz --- alias/alias_db.c | 117 ++++++++++++-- natd.tproj/natd.c | 272 ++++++++++++++++++--------------- tftpd.tproj/Makefile.postamble | 3 +- 3 files changed, 252 insertions(+), 140 deletions(-) diff --git a/alias/alias_db.c b/alias/alias_db.c index 9d6b996..f6088dd 100644 --- a/alias/alias_db.c +++ b/alias/alias_db.c @@ -169,6 +169,7 @@ #include #include #include +#include #include #include @@ -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; isrc_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; isrc_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; + } + } + +} diff --git a/natd.tproj/natd.c b/natd.tproj/natd.c index a04d99f..043b370 100644 --- a/natd.tproj/natd.c +++ b/natd.tproj/natd.c @@ -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; iversion > 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. */ diff --git a/tftpd.tproj/Makefile.postamble b/tftpd.tproj/Makefile.postamble index f5423b9..0505ae0 100644 --- a/tftpd.tproj/Makefile.postamble +++ b/tftpd.tproj/Makefile.postamble @@ -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" -- 2.45.2