📄 natalgapi.c
字号:
/* natAlgApi.c - WIND NET NAT Application Gateway (ALG) programming interface *//* WIND NET NAT Application Level Gateway (ALG) Application Programming Interface *//* Copyright 2000-2003 Wind River Systems, Inc. *//* @format.tab-size 4, @format.use-tabs true, @format.new-line lf *//*modification history--------------------01c,29aug03,zhu updated the format for refgen01b,13aug03,zhu fixed natSetBind memory leak01a,23apr03,zhu enhanced natBindShow041103 vks removed #ifdef'd out code under natFreeSession, natSetSession and natFreeBundle 040903 vks updated Copyright info032603 vks replaced rw_container with lstLib (for bind_list)111302 vvv added semGive on error in natSetBind (SPR #79394)092402 vvv replaced references to rw_container with direct linked list access to improve performance101901 tk Fix data type to avoid warning in T3 compiler.100301 tk Remove semaphore calls. They have been moved to nat_api.c.092101 tk Modify natGetTransportBind() to check for remote address and port or just remote address.080701 tk Modified natSetBind for H.323 protocol support.070201 tk Enhance natSetBind, natFreeBind, natGetAddrBind, natGetTransportBind, and natBindShow. Now natSetBind/ natFreeBind actually create/delete an entry to/from the protocol translation list in the NAT core in addition to adding/deleting the entry in its own bind list.060501 tk Add a static function match_nat_agent().060401 tk Add a new API function natUnregisterAgent().*//*DESCRIPTION This library supplies an API for integrating a new ALG with WIND NET NAT. See also the timer API supplied by 'natInit'. SEE ALSO 'natInit'*/#include <stdio.h> /* printf */#include "nat.h"#include "nat_api.h"/*#define ALG_DEBUG*//*****************************************************************************This utility function is called by the API functions to verify for thethe validity of the external agent (i.e. if it is a registered agent)*****************************************************************************/static NAT_STATUS match_nat_agent(u_long nat_id, u_long agent_id){ NAT_CLASS *nat_p; NAT_AGENT_INFO* agent_info; if (agent_id == 0) { return (NAT_OK); /* agent is NAT */ } nat_p = (NAT_CLASS *) nat_id; semTake(agentListLock, WAIT_FOREVER); agent_info = (NAT_AGENT_INFO *) lstFirst(&nat.agent_list); while (agent_info != NULL) { if (agent_info->id == agent_id) { semGive (agentListLock); return (NAT_OK); } agent_info = (NAT_AGENT_INFO *) lstNext((NODE*) agent_info); } semGive(agentListLock); return (NAT_INVALID_AGENT_ID);}/****************************************************************************//****************************************************************************//* Initial entry point for an external NAT agent (ALG, Back-up NAT, etc) *//****************************************************************************//*****************************************************************************Function: natGetIDDescription:This function is called by the external agent to obtain the NAT service identifier and its type. The external agent is responsible for allocating the NAT_ID_INFO data structure and pass its pointer as the argument to this function. NAT fills in the structure including the NAT ID.*****************************************************************************/ /******************************************************************************* * natGetID - get a NAT service identifier* * The external agent calls this external agent to obtain the NAT service * identifier and its type. The external agent is responsible for allocating * the NAT_ID_INFO data structure and passing its pointer as the argument to * this routine. NAT fills in the structure including the NAT ID. * * Currently, WIND NET NAT supports only a single instance of NAT. The * supported types are NAPT or Basic NAT (see RFC 2663 for explanations of * the different flavors of NAT).* * RETURNS* * NAT_OK, if successful; or NAT_INVALID_ARG_PTR, if <id_info> is NULL.* */NAT_STATUS natGetID ( NAT_ID_INFO* id_info /* Output area for NAT service information. */ ){ if (id_info == NULL) { return(NAT_INVALID_ARG_PTR); } id_info->id = (u_long)&nat; /* A global variable that may go away some day */ id_info->enabled = nat.enabled; id_info->type = 0; if(nat.single_global_address_enabled == TRUE) { id_info->type |= NAT_TYPE_NAPT; } else { id_info->type |= NAT_TYPE_BASIC; } return(NAT_OK);}/*****************************************************************************Function: natRegisterAgentDescription:This function is called by the external agent to register with the NAT service. The external agent allocates the NAT_AGENT_INFO storage and fill in the agent's information before passing it to the function. Upon successful completion of this function, NAT will assign and return the agent ID (i.e. handle) in the NAT_AGENT_INFO data structure.*****************************************************************************/ /******************************************************************************* * natRegisterAgent - register external agent with NAT service* * The external agent calls this routine to register with the NAT service. * Before calling this function, the external agent allocates the * NAT_AGENT_INFO structure and fills in the agent's information before passing * it to the routine. Typical agent information includes the following:* \ml* \m -* agent type (currently it can only be ALG)* \m -* whether the agent chooses to translate addresses in the IP and TCP/UDP * headers as well as in the payload (no NAT translation), or only in the * payload (post-NAT translation)* \m -* agent's port number* \m -* callback functions* \me * Upon successful completion of this routine, NAT assigns and returns the * agent ID (the handle) in the NAT_AGENT_INFO data structure. * * RETURNS* * \is* \i NAT_OK * Success.* \i NAT_INVALID_NAT_ID* Invalid NAT ID.* \i NAT_INVALID_ARG_PTR* Invalid pointer to agent information.* \i NAT_UNSUPPORTED_AGENT_TYPE* Requested agent type not is supported.* \i NAT_SYSTEM_ERROR* Cannot allocate storage for the new agent. * \ie**/NAT_STATUS natRegisterAgent ( u_long nat_id, /* NAT service ID, from a natGetID() call. */ NAT_AGENT_INFO* agent_info /* Pointer to agent information. */ ){ NAT_CLASS* nat_p; NAT_AGENT_INFO* new_agent_info; if (nat_id == 0) { return(NAT_INVALID_NAT_ID); } nat_p = (NAT_CLASS*) nat_id; if (agent_info == NULL) { return(NAT_INVALID_ARG_PTR); } if (agent_info->type != NAT_AGENT_TYPE_ALG) { return(NAT_UNSUPPORTED_AGENT_TYPE); } new_agent_info = (NAT_AGENT_INFO*) malloc (sizeof (NAT_AGENT_INFO)); if (new_agent_info == NULL) { return(NAT_SYSTEM_ERROR); } agent_info->id = (u_long)new_agent_info; /* Use item pointer for ID */ memcpy(new_agent_info, agent_info, sizeof(NAT_AGENT_INFO)); semTake (agentListLock, WAIT_FOREVER); lstAdd (&nat.agent_list, (NODE*) new_agent_info); semGive (agentListLock); return(NAT_OK); }/*****************************************************************************Function: natUnregisterAgentDescription:This function is called by the external agent to deregister itself from the NAT service.*****************************************************************************//******************************************************************************* * natUnregisterAgent - deregister an external agent for the NAT service* * The external agent calls this routine to deregister itself from NAT service.** RETURNS* * \is* \i NAT_OK* Success.* \i NAT_INVALID_NAT_ID* Invalid NAT ID.* \i NAT_INVALID_AGENT_ID* Invalid agent ID.* \i NAT_SYSTEM_ERROR* Memory allocation error.* \ie*/NAT_STATUS natUnregisterAgent ( u_long nat_id, /* NAT service ID, from a natGetId() call. */ u_long agent_id /* Agent ID, from a natRegisterAgent() call. */ ){ NAT_CLASS* nat_p; NAT_AGENT_INFO* agent_info; nat_p = (NAT_CLASS *) nat_id; if (nat_p != &nat) /* for now, support only one instance */ { return(NAT_INVALID_NAT_ID); } semTake (agentListLock, WAIT_FOREVER); agent_info = (NAT_AGENT_INFO *) lstFirst(&nat.agent_list); while (agent_info != NULL) { if (agent_info->id == agent_id) { lstDelete (&nat.agent_list, (NODE *) agent_info); semGive (agentListLock); free (agent_info); return (NAT_OK); } agent_info = (NAT_AGENT_INFO *) lstNext((NODE *) agent_info); } semGive (agentListLock); return (NAT_INVALID_AGENT_ID);}/*****************************************************************************Function: natSetBindDescription:This function is called by the external agent to create a new address bind or set certain parameters of an existing bind. The bind can be an address bind or transport bind. The caller is expected to fill in the NAT_BIND_INFO structure. A new bind request is made by setting the bind ID (in NAT_BIND_INFO) to 0. A non-zero bind ID would be interpreted to mean that the agent is attempting to set some existing bind parameters.If the caller requests for a bind creation, and NAT is successful in creating a new bind, the function will fill the NAT_BIND_INFO structure with the newly assigned bind ID. If the request is for setting some bind parameters and the bind ID is valid, it will replace the NAT bind information with the new one.NOTE:Currently, only new bind creation is supported. For request to set existingbind parameters, the input bind parameters will be copied to the existing bindentry, but will have no effect on NAT.*****************************************************************************//******************************************************************************* * natSetBind - create address bind or set parameters of existing bind* * The external agent calls this routine to create an address bind or to set * parameters in an existing bind. The bind can be either an address bind or * a transport bind. The caller is expected to fill in the NAT_BIND_INFO * structure. A new bind request is made by setting the bind ID (in * NAT_BIND_INFO) to 0. A non-zero bind ID is interpreted to mean that the * agent is attempting to set some existing bind parameters.* * If the caller requests a bind creation, and NAT is successful in creating * a bind, the routine fills the NAT_BIND_INFO structure with the * newly assigned bind ID. If the request is for setting some bind parameters * and the bind ID is valid, it replaces the existing bind's parameters with * the new parameters.* * When creating a bind, NAT allocates its own bind descriptor and registers * it in its bind-descriptor list. Therefore, it is important that the * external agent fills in all of the requisite parameters in the * bind-descriptor prior to passing it to NAT through this routine. NAT then * copies these parameters to its own bind descriptor and creates the TCP or * UDP control block for this bind based on the given parameters. * * For a detailed description of each of the members defined in the * NAT_BIND_INFO structure, see the description provided in the <WIND NET * NAT User's Guide>. * * 'Note:' Currently, only bind creation is supported. Setting the parameters * in an existing bind is prohibited. When a non-zero bind ID is detected, * this routine returns NAT_UNSUPPORTED_FEATURE (defined in natAlgApi.h). For * the ALG, it is not clear what bind parameters may need modification. * Incorrectly modified parameters could cause the unexpected disconnection * of a session, as well as memory leaks. For this reason, WIND NET NAT ALG * API does not support this feature until its purpose is better understood.* * RETURNS* \is* \i NAT_OK * Success.* \i NAT_INVALID_NAT_ID* Invalid NAT ID.* \i NAT_INVALID_AGENT_ID* Invalid NAT agent ID.* \i NAT_INVALID_ARG_PTR* Invalid pointer to bind information.* \i NAT_BIND_MAKE_FAILED* Cannot create a bind.* \i NAT_SYSTEM_ERROR* Memory allocation error.* \i NAT_UNSUPPORTED_FEATURE* Unsupported feature.* \ie**/NAT_STATUS natSetBind ( u_long nat_id, /* NAT service ID, from a natGetID() call. */ u_long agent_id, /* Agent ID, from a netRegisterAgent() call. */ NAT_BIND_INFO* bind_info /* Pointer to bind information. */ ){ NAT_CLASS* nat_p; NAT_BIND_INFO* new_bind_info; NAT_STATUS status; BOOL static_flag; u_short local_port_number, global_port_number, remote_port_number; IP_ADDRESS local_address, global_address, remote_address; TCP_TRANSLATION_ENTRY *tcp_translation_entry; UDP_TRANSLATION_ENTRY *udp_translation_entry; IP_TRANSLATION_ENTRY *ip_translation_entry; nat_p = (NAT_CLASS *) nat_id; if (nat_p != &nat) { return(NAT_INVALID_NAT_ID); } if ((status = match_nat_agent(nat_id, agent_id)) != NAT_OK) { return(status); } if (bind_info == NULL) { return(NAT_INVALID_ARG_PTR); } semTake(bindListLock, WAIT_FOREVER); static_flag = bind_info->static_entry; local_address = (IP_ADDRESS) bind_info->local_addr; local_port_number = bind_info->local_transport; global_address = (IP_ADDRESS) bind_info->global_addr; global_port_number = bind_info->global_transport; remote_address = (IP_ADDRESS) bind_info->remote_addr; remote_port_number = bind_info->remote_transport; /* for a new bind request, must create an entry in the respective NAT translation list, create a new bind entry and fill in the bind information. */ if (bind_info->id == 0) /* New bind request */ { new_bind_info = (NAT_BIND_INFO*) malloc (sizeof (NAT_BIND_INFO)); if (new_bind_info == NULL) { semGive (bindListLock); return(NAT_SYSTEM_ERROR); } bind_info->id = (u_long)new_bind_info; /* Use item pointer for ID */ bind_info->agent_id = agent_id; /* create a new bind in the NAT translation list */ if (bind_info->type == NAT_BIND_NAPT) { switch (bind_info->protocol) { case IPPROTO_TCP:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -