X-Git-Url: https://git.saurik.com/apple/network_cmds.git/blobdiff_plain/07f470571f6fc2709bdcf62fad0e6c4c1bf4e1b9..fdfd5971fdda9c24d576337643161018a5281167:/alias/alias_db.c?ds=inline diff --git a/alias/alias_db.c b/alias/alias_db.c index 8c8c708..81dfff9 100644 --- a/alias/alias_db.c +++ b/alias/alias_db.c @@ -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@ */ @@ -172,6 +169,7 @@ #include #include #include +#include #include #include @@ -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; 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)); + + 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; 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; + } + } + +}