📄 nat_initialize.c
字号:
/* nat_initialize.c */
/* Copyright 2000-2004 Wind River Systems, Inc. */
/* @format.tab-size 4, @format.use-tabs true, @format.new-line lf */
/*
modification history
--------------------
01k,24mar04,zhu fix a bug in natFilterHooksDelete
01j,19sep03,zhu Created NAT filter hook add and delete functions.
01i,16jun03,myz Use new fragment translation initialization.
01h,09may03,myz removed NAT_OUTPUT_FILTER, now handled by natIcmpErrorHook
01g,02may03,vks added error check for muxBind call that sets NAT output
filter
01f,01may03,zhu removed DMZ and renamed SPR69698_PATCH to NAT_OUTPUT_FILTER
01e,29apr03,myz Add error return check on last mod and fixed a diab warning
01d,25apr03,myz use NAT timer facility to call the nat_timer function
01c,24apr03,zhu updated copyright
01b,21apr03,myz replaced swap(_long) with the ntohs(l) and htons(l) macros,
removed RWOS dispatcher creation, no longer needed.
01a,16apr03,zhu added DMZ support
040903 vks updated Copyright info
040803 vks added bind_list initialization - part of rw_container removal
092502 vvv modified fragment list to use lstLib instead of rw_container;
added semaphore for fragment lists (SPR #79675)
092402 vvv replaced references to rw_container with direct linked list
access to improve performance
092302 vvv unconditionally include check for SPR #65740
092302 vvv added check for global_address_pool_size (SPR #80490)
112601 tk Fix SPR65740: ARP problem with Basic-NAT.
092801 tk Fix SPR69698: Register a special hook to handle outgoing icmp error packet
generated by IP stack. This workaround was not included in NAT 1.1 FCS.
091001 tk Set maximum static IP entries differently for NAPT and Basic-NAT.
090501 tk Skip initializing TCP and UDP static entries when in Basic-NAT.
082301 tk Add calls to registerStaticEntryToTranslationList() to register TCP/UDP static
entries to NAT's translation list and bind list.
081001 tk Fix bugs in nat_setup_static_entries.
071101 tk Modify nat_setup_static_entries() to call natSetBind to bind static IP entries.
Create ipListLock, agentListLock, and bindListLock semaphores.
062701 tk Fix Basic NAT starting global address problem when using interface global address
and mask instead of from the config file. Checking of the global address/mask
was done before the they are initialized to the interface address/mask.
053001 tk Modified nat_printf to return immediately if printf and logging are disabled to
speed up performance.
052501 tk Fix SPR#67128: Add feature to configure the starting global address in Basic NAT.
Default always starts from IP (address & mask + 1) as before. Also, add
static_entry parameter in NAT_IP_ADDRESS_ENTRY so natShow will show the static
IP entries even when they are below the configured starting address.
050901 tk Fix SPR#67127: console displays "set NAT Plugging Event" after initialization.
Now, it displays the message only if NAT Printf Initialization is enabled.
Fix Basic NAT problem to avoid assigning global address that is equal to the
NAT global interface address.
042101 tk Remove the line to reset translation timer to 0 in nat_initialize.
Add temporary work around to allow tester to set the starting available IP in
global address pool when testing basic NAT.
030901 tk Fix synchronization problem with NAT initialization.
*/
#define GLOBAL_FILE
#include <stdio.h> /* vprintf() prototype location under Tornado */
#include <string.h>
#include <stdarg.h>
#include "nat.h"
#include "nat_api.h"
/* VxWorks specific headers */
#include <ifLib.h>
#include <logLib.h> /* logMsg prototype */
#include <tickLib.h> /* tickGet() prototype */
#include <sysLib.h> /* sysClkRateGet() prototype */
#include <etherLib.h>
#include "netinet/ip.h"
/* external functions */
extern FUNCPTR _func_fwPreinputHook; /* FW preinput hook */
extern FUNCPTR _func_fwOutputHook; /* FW output hook */
#if 0
extern FUNCPTR _func_fwNatPreinputHook; /* NAT preinput hook */
extern FUNCPTR _func_fwNatOutputHook; /* NAT output hook */
extern FUNCPTR _func_fwNatHook; /* NAT filter hook */
#endif
extern void natIcmpErrorHookAdd (void);
/* Function to register static TCP/UDP entry to its translation list */
STATUS registerStaticEntryToTranslationList (
NAT_PORT_STATIC_ENTRY *staticEntry,
u_short protocol);
/* NAT filter hook */
STATUS natFilterHooksAdd (FUNCPTR, FUNCPTR);
void natFilterHooksDelete (void);
/************************************************************************/
static void initialize_global_address_pool (IP_ADDRESS address,
NAT_IP_ADDRESS_ENTRY *sptr_address_entry, ULONG table_size);
static enum TEST nat_setup_static_entries (NAT_IP_STATIC_ENTRY *sptr_static_entry,
NAT_IP_ADDRESS_ENTRY* sptr_address_entry, ULONG table_size,
IP_TRANSLATION_HEADER *sptr_ip_translation_list);
void nat_add_local_interfaces_to_passthru_list (void);
/************************add by zbb*********************************************/
struct portcheck *portchecktable=NULL;
NAT_CURRENCY_TRANSLATION_ENTRY natTabArray[MAX_NAT_ENTRYS];
NAT_CURRENCY_TRANSLATION_ENTRY * natEntryFree;
OUTPORTMAP out_port_map[UPPER_EPHEMERAL_PORT_VALUE];
INMAPHASH in_map_hash[MAX_IN_ENTRY];
NATSTAT natStats;
void nat_entrys_initailize()
{
int looper;
for(looper=0;looper < UPPER_EPHEMERAL_PORT_VALUE; looper++)
{
out_port_map[looper].next_entrys_link=NULL;
out_port_map[looper].next_algs_entrys_link=NULL;
}
for(looper=0;looper<MAX_IN_ENTRY;looper++)
{
in_map_hash[looper].inmap = NULL;
}
for(looper=0;looper< MAX_NAT_ENTRYS-1;looper++)
{
natTabArray[looper].next_entrys_link=&natTabArray[looper+1];
}
natTabArray[looper].next_entrys_link=NULL;
natEntryFree=&natTabArray[0];
}
/************************************************************************/
STATUS nat_initialize ()
{
char addr_str[32];
char mask_str[32];
STATUS status;
USHORT index;
struct ifnet* port_if;
struct ifaddr* ifaddr;
struct sockaddr_in* inaddr;
void * natTimerId;
unsigned char eHdr[6];
struct in_addr iaddr;
nat_printf(NAT_PRINTF_INIT, "nat_initialize\n");
if (nat.enabled != true)
{
nat_printf(NAT_PRINTF_ERROR, "nat.enabled == FALSE\n");
return (ERROR);
}
/*
* we create the semaphores that will provide mutually exclusive
* access to the translation lists.
*/
spoofingPortLock = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE);
udpListLock = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE);
tcpListLock = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE);
ipListLock = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE);
bindListLock = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE);
agentListLock = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE);
natentrylock=semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE);
/*
natentrylock=semBCreate (SEM_Q_PRIORITY,SEM_FULL);
nattimerlock=semBCreate (SEM_Q_PRIORITY,SEM_FULL);
*/
if ( (udpListLock == NULL) ||
(tcpListLock == NULL) ||
(ipListLock == NULL) ||
(spoofingPortLock == NULL) ||
(bindListLock == NULL) ||
(agentListLock == NULL) ||(natentrylock==NULL))
return (ERROR);
nat.tcp_state_table = &nat_tcp_state_table[0];
nat.natg.ip_translation_list.sptr_forward_link = NULL;
nat.natg.ip_translation_list.sptr_backward_link = NULL;
nat.current_port_spoofing_number = LOWER_EPHEMERAL_PORT_VALUE;
nat.nats.icmp_default_entry.icmp_identifier = 0x0000;
nat.nats.icmp_default_entry.spoofed_icmp_identifier = 0x0000;
nat.agent_info = NULL;
lstInit(&nat.bind_list);
lstInit (&nat.passthru_list);
lstInit(&nat.agent_list);
/* Basic NAT (NATG) address pool configuration */
if (nat.natg.global_address_pool_size > 0)
{
if (nat.natg.global_address_pool_size > 24) /* 24-bit address pool maximum */
{
nat_printf(NAT_PRINTF_ERROR,
"Invalid global_address_pool_size (in bits): %d\n",
nat.natg.global_address_pool_size);
return(ERROR);
}
/* Convert from bit-width to absolute size */
nat.natg.global_address_pool_size = 1 << nat.natg.global_address_pool_size;
/* Allocate NATG Local Address Use Table (dynamically) */
nat.natg.global_address_pool = malloc (
sizeof(NAT_IP_ADDRESS_ENTRY) * nat.natg.global_address_pool_size);
if (nat.natg.global_address_pool == NULL)
{
nat_printf(NAT_PRINTF_ERROR,
"Failure to allocate memory for global_address_pool\n");
return(ERROR);
}
}
else
{
nat_printf (NAT_PRINTF_ERROR,
"Invalid global_address_pool_size (in bits): %d\n",
nat.natg.global_address_pool_size);
return (ERROR);
}
for (index = 0x0000; index < NUMBER_OF_IP_PORTS; ++index)
{
unsigned char * pStr;
/* convert the string to all lower case letters */
pStr = (unsigned char *)nat.port[index].type_string;
while (*pStr != (unsigned char)(ULONG)NULL)
{
*pStr = tolower(*pStr);
pStr++;
}
/* Set the interface/port 'type' (LOCAL or GLOBAL) */
if (strstr (nat.port[index].type_string, "global") != NULL)
{
nat.port[index].type = NAT_GLOBAL_PORT;
nat.global_port_number = index;
}
else
{
nat.port[index].type = NAT_LOCAL_PORT;
}
/* Dynamically attached inteface? */
nat.port[index].ifunit = ifunit(nat.port[index].ifname);
if(nat.port[index].ifunit == NULL)
{
nat_printf(NAT_PRINTF_ERROR,"WARNING: "
"Interface (%s) for port %d not found (dynamically attached?)\n"
,nat.port[index].ifname, index);
}
else /* statically attached interface */
{
nat_printf(NAT_PRINTF_INIT,"Interface (%s) for port %d attached"
,nat.port[index].ifname, index);
if (nat.port[index].address == 0) /* dynamic address */
{
/* Search for IP address */
port_if = nat.port[index].ifunit;
for (ifaddr = port_if->if_addrlist; ifaddr != NULL; ifaddr = ifaddr->ifa_next)
{
if(ifaddr->ifa_addr->sa_family == AF_INET)
break;
}
if (ifaddr == NULL) /* IP Address not found */
{
nat_printf(NAT_PRINTF_ERROR,"Address for interface on port %d (%s) "
"not found\n"
,index, nat.port[index].ifname);
return(ERROR);
}
nat_printf(NAT_PRINTF_INIT,"Address/mask for interface on port %d (%s) "
"detected\n",index, nat.port[index].ifname);
inaddr = (struct sockaddr_in*) ifaddr->ifa_addr;
nat.port[index].address = ntohl(inaddr->sin_addr.s_addr);
inaddr = (struct sockaddr_in*) ifaddr->ifa_netmask;
nat.port[index].mask = ntohl(inaddr->sin_addr.s_addr);
}
}
/* Initialization output */
iaddr.s_addr = htonl(nat.port[index].address);
inet_ntoa_b(iaddr,addr_str);
iaddr.s_addr = htonl(nat.port[index].mask);
inet_ntoa_b(iaddr,mask_str);
nat_printf(NAT_PRINTF_INIT
,"Address/mask for interface on port %d (%s): %s/%s\n"
,index, nat.port[index].ifname, addr_str, mask_str);
/* Automatically set global IP address based on address of global interface */
if (nat.port[index].type == NAT_GLOBAL_PORT && nat.global_address == 0)
{
nat.global_address = nat.port[index].address;
nat.global_address_mask = nat.port[index].mask;
iaddr.s_addr = htonl(nat.global_address);
inet_ntoa_b(iaddr,addr_str);
iaddr.s_addr = htonl(nat.global_address_mask);
inet_ntoa_b(iaddr,mask_str);
nat_printf(NAT_PRINTF_INIT
,"Global address/mask set to that of port %d: %s/%s\n", index, addr_str, mask_str);
}
/* Patch to fix SPR #65740 to map basic NAT global address to the ARP table */
if (etherAddrResolve(nat.port[index].ifunit, addr_str, (char *)eHdr, 2, 5) == OK)
{
sprintf(nat.etherAddr, "%x:%x:%x:%x:%x:%x",
eHdr[0], eHdr[1], eHdr[2], eHdr[3], eHdr[4], eHdr[5]);
nat_printf(NAT_PRINTF_INIT,"Global port's mac address = %s\n", nat.etherAddr);
}
else
{
nat_printf(NAT_PRINTF_ERROR, "Can't get global port's mac address\n");
}
}
/* NAT fragment handling module initialization */
nat.pFragTranResrc = natFragTranModuleInit();
/* Check for the validity of starting global address for Basic NAT if configured */
if ((nat.global_address & nat.global_address_mask) ==
(nat.starting_global_address & nat.global_address_mask))
{
nat.natg.global_address_index_start = (ULONG)
(nat.starting_global_address & ~nat.global_address_mask);
}
else /* if configured starting address is invalid, ignore it */
{
nat.natg.global_address_index_start = 0;
}
nat_printf(NAT_PRINTF_INIT, "Basic NAT starting global index = %d\n",
nat.natg.global_address_index_start);
initialize_global_address_pool (
nat.global_address & nat.global_address_mask,
nat.natg.global_address_pool,
nat.natg.global_address_pool_size);
if (nat_setup_static_entries (&nat.static_entries[0], nat.natg.global_address_pool,
nat.natg.global_address_pool_size,
&nat.natg.ip_translation_list) == FAIL)
{
return (ERROR);
}
/* Set TCP/UDP translation global ports */
if (nat.single_global_address_enabled == TRUE)
{
nat_entrys_initailize();
for (index=0; index<sizeof(nat.tcp_static_entries)/sizeof(nat.tcp_static_entries[0]); index++)
{
if (nat.tcp_static_entries[index].local_address == 0)
{
continue; /* End of list */
}
/* Global server port defaults to local port if not specified (0) */
if(nat.tcp_static_entries[index].global_port_number == 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -