⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nath323alg.c

📁 VXWORKS NAT 部分源代码3 有兴趣朋友可以参考下
💻 C
📖 第 1 页 / 共 3 页
字号:
                		ip_addr = READ_ALIGN_SAFE32(data);
				ip_addr = ntohl (ip_addr);

				/* look for G's H245Address match */
				if (ip_addr == bind_info.remote_addr)
				{
                    			port = READ_ALIGN_SAFE16(data + sizeof (IP_ADDRESS));
					port = ntohs (port);

					nat_printf(NAT_PRINTF_TRACE, "H225 ALG: H245Address from remote host found\n");
					nat_printf(NAT_PRINTF_DATA, 
						"H225 ALG: Global host's H245Address is: ip = %x, port = %x\n", 
						ip_addr, port);

					/* register H.245 ALG to NAT */
					if (natRegisterAlg (nat_p, port, H245Alg, &h323Alg[H245Alg]) != OK)
					{
						nat_printf(NAT_PRINTF_ERROR, 
							"natH225Packet: Failed to register H245 ALG with remote H.245 port\n");
						return (FALSE);
					}
				}
				data++;
			}
		}
		else	/* session started by G */
		{
			/* search for L's transport address in the H225 payload.
			   If found, translate it to its real transport address.
			*/
			nat_printf(NAT_PRINTF_TRACE, 
				"H225 ALG: inbound packet, inbound session. Translate global transport to its local transport\n");

			while ((data + IP_PORT_LENGTH) <= (data_start + data_length))
			{
                		ip_addr = READ_ALIGN_SAFE32(data);
				ip_addr = ntohl (ip_addr);

				/* look for L's translated address match */
				if (ip_addr == bind_info.global_addr)
				{				
                    			port = READ_ALIGN_SAFE16(data + sizeof (IP_ADDRESS));
					port = ntohs (port);

					nat_printf(NAT_PRINTF_DATA, 
						"H225 ALG: global ip match found in H.225 payload, ip = %x, port = %x\n", ip_addr, port);

					if (port == bind_info.global_transport)
					{	/* replace with L's real transport address */
						ip_data = (IP_ADDRESS *) data;
						transport.ip_addr = htonl (bind_info.local_addr);
						port_data = (USHORT *) (data + sizeof(IP_ADDRESS));
						checksum = tcp_packet->tcp_header.checksum;
						if (nat_p->type == NAT_TYPE_NAPT)
						{
							transport.port = htons (bind_info.local_transport);
							natAdjustChecksum((BYTE *)ip_data, &transport, NAT_BIND_NAPT, &checksum);
						}
						else
						{
							transport.port = READ_ALIGN_SAFE16(port_data);
							natAdjustChecksum((BYTE *)ip_data, &transport, NAT_BIND_BASIC, &checksum);
						}

						tcp_packet->tcp_header.checksum = checksum;
                        			WRITE_ALIGN_SAFE32(ip_data, transport.ip_addr);
                        			WRITE_ALIGN_SAFE16(port_data, transport.port);
						
						data += IP_PORT_LENGTH;

						nat_printf(NAT_PRINTF_DATA, 
							"H225 ALG: After translation, local ip = %x, port = %x\n", 
							ntohl(READ_ALIGN_SAFE32(ip_data)), ntohs(READ_ALIGN_SAFE16(port_data)));
					}
					else	/* port != bind_info.global_transport */
					{
						data++;
					}
				}
				else	/* ip_addr != bind_info.global_addr */
				{
					data++;
				}
			}	/* while */
		}	/* else (session started by G) */
	}	/* else (inbound packet) */

	return (TRUE);
}

/**************************************************************************
Function:	natH323Event

Description:
This callback function is called by NAT upon the H.245 termination.
The function frees the static UDP binds (RTP and RTCP logical channels)
as well as the T1.120 TCP bind created during the H.245 session.
**************************************************************************/
void natH245Event(u_long nat_id, u_long agent_id, 
				  NAT_AGENT_EVENT event, NAT_EVENT_INFO *event_info) 
{
	NAT_STATUS	status;
	int			i;

	if (nat_instance[0].id != nat_id)
	{
		printf("natH245Event: Invalid nat id\n");
		return;
	}

	if (agent_id != h323Alg[H245Alg].id)	
	{	/* return if event not generated from H.245 TCP packet */
		nat_printf(NAT_PRINTF_ERROR, "natH245Event: not H245Alg\n");	/* tk */
		return;
	}

	if (event != NAT_BIND_TERMINATION)
	{
		nat_printf(NAT_PRINTF_ERROR, "natH245Event: Call not for bind termination!\n");

		return;
	}

	/* now delete all the UDP logical channels opened by H.245 */
	for (i=0; i<MAX_LOGICAL_CHANNELS; i++)
	{
		if (logical_channel_bind[i] != 0)
		{
			status = natFreeBind (nat_id, agent_id, logical_channel_bind[i]);

			if (status != NAT_OK)
			{
				nat_printf(NAT_PRINTF_ERROR,
					"natH245Event: natFreeBind returned error status = %d, bind id = %x\n", 
					status, logical_channel_bind[i]);
			}
			else
			{
				logical_channel_bind[i] = 0;
			}
		}
	}
}

/**************************************************************************
Function:	natH323Init

Description:
This function is called when the H.323 ALG component is included in the
NAT components.  It is called after the completion of NAT initialization.
This does the following:
- Query the NAT service
- Set up agent descriptor to describe the characteristics of the ALG
- Include the callback function natH323Packet to process the H.225 packets
- Register the ALG to NAT

The semaphore natInitSync is used to prevent the race condition between
the NAT initialization and the initializations of other agents when
included.
**************************************************************************/
STATUS natH323Init(u_short h323_port)
{
	NAT_STATUS	status;
	int			i;
	
	semTake (natInitSync, WAIT_FOREVER);    /* wait for event */

	nat_printf(NAT_PRINTF_INIT, "H323 initialization: port = %u\n", h323_port);
		
	memset(&nat_instance[0], 0, sizeof(NAT_ID_INFO));

	status = natGetID(&nat_instance[0]);	/* query the NAT service */

	if (status != NAT_OK)
	{
		printf("natH323: natGetID failed with error %d\n", status);
		semGive (natInitSync);
		return(ERROR);
	}

	/* Register H225 ALG to NAT */
	if (natRegisterAlg (&nat_instance[0], h323_port, H225Alg, &h323Alg[H225Alg]) != OK)
	{
		printf("natH323: Failed to register H225 ALG\n");
		semGive (natInitSync);
		return (ERROR);
	}

	printf("H323 ALG registered with NAT\n");

	for (i=0; i<MAX_LOGICAL_CHANNELS; i++)
	{
		logical_channel_bind[i] = 0;
	}

	semGive (natInitSync);

	return(OK);
}


STATUS natH323end(void)
{
	
	semTake (natInitSync, WAIT_FOREVER);    /* wait for event */


	/* unregister H245 ALG to NAT */
	if((natUnregisterAgent(nat_instance[0].id,h323Alg[H245Alg].id)) != OK)
	{
		printf("natH323: Failed to unregister H225 ALG\n");
		semGive (natInitSync);
		return (ERROR);
	}
	/* unregister H225 ALG to NAT */
	if((natUnregisterAgent(nat_instance[0].id,h323Alg[H225Alg].id)) != OK)
	{
		printf("natH323: Failed to unregister H225 ALG\n");
		semGive (natInitSync);
		return (ERROR);
	}

	semGive (natInitSync);

	return(OK);
}

/**************************************************************************
Function:	natRegisterAlg

Description:
This function registers the given ALG type with NAT.  In H.323 protocol,
we need to worry only the H.225 call signaling and H.245 call control ALGs.
**************************************************************************/
static STATUS natRegisterAlg (
		NAT_ID_INFO *nat_id, 
		u_short port, 
		H323AlgType alg,
		NAT_AGENT_INFO *agent_info_p)
{
	NAT_STATUS		status;

	memset(agent_info_p, 0, sizeof(NAT_AGENT_INFO));

	agent_info_p->type = NAT_AGENT_TYPE_ALG;
	agent_info_p->flags = NAT_FLAG_POST_XLAT;
	agent_info_p->session_tag.protocol = IPPROTO_TCP;

	switch (alg)
	{
		case H225Alg:
			agent_info_p->session_tag.transport = port;
			agent_info_p->packet_callback = natH225Packet;		/* packet callback */			
			sprintf(agent_info_p->desc, "%.*s", 
					(int)sizeof(agent_info_p->desc)-1, h225_alg_desc);
			sprintf(agent_info_p->name, "%.*s", 
					(int)(sizeof(agent_info_p->name)-1), h225_alg_name);
			break;

		case H245Alg:
			agent_info_p->session_tag.transport = port;
			agent_info_p->packet_callback = natH245Packet;		/* packet callback */
			agent_info_p->event_callback = natH245Event;		/* event callback */
			sprintf(agent_info_p->desc, "%.*s", 
					(int)sizeof(agent_info_p->desc)-1, h245_alg_desc);
			sprintf(agent_info_p->name, "%.*s", 
					(int)(sizeof(agent_info_p->name)-1), h245_alg_name);
			break;

		default:
			printf("unknown H323 ALG\n");
			return (ERROR);
	}

	status = natRegisterAgent(nat_id->id, agent_info_p);	/* register the ALG */

	if (status != NAT_OK)
	{
		return (ERROR);
	}

	return (OK);
}

/**************************************************************************
Function:	natAdjustChecksum

Description:
This function adjusts the TCP checksum for changing the IP address and port
number.  Different methods must be used depending on whether the data to
be replaced start at even or odd address.If at even address, do the checksum 
adjustment normally.  If at odd address, back-up to the nearest smaller 
even address and do the checksum adjustment starting from there.  This 
extra step must be done because checksum is calculated by adding 2 bytes 
at a time
**************************************************************************/
static void natAdjustChecksum(
	BYTE		*data,
	TRANSPORT_ADDR	*new_transport,
	NAT_BIND_TYPE	nat_type,
	USHORT		*checksum)
{
	BYTE	*old_byte_p, *new_byte_p;
	BYTE	old_data[IP_PORT_LENGTH], new_data[IP_PORT_LENGTH];	
	int		i;

	if (((ULONG)data) % 2)	/* odd address */
	{
		/* go to the nearest lower even address and adjust checksum for 6 bytes,
		   note this includes: 
		   1 byte before IP address + IP address (4 bytes) + first byte of port
		*/
		old_byte_p = (BYTE *) data;
		old_byte_p--;
		new_data[0] = *old_byte_p;	/* byte before IP */
		for (i=0; i<IP_PORT_LENGTH; i++)
		{
			old_data[i] = *old_byte_p++;
		}					
		new_byte_p = (BYTE *) &new_transport->ip_addr;
		for (i=1; i<(IP_PORT_LENGTH-1); i++)
		{
			new_data[i] = *new_byte_p++;
		}
		
		new_byte_p = (BYTE *) &new_transport->port;
		new_data[i] = *new_byte_p++;

		checksum_fixup ((BYTE *) checksum,
						old_data, IP_PORT_LENGTH,
						new_data, IP_PORT_LENGTH);

		/* for NAPT, we still need to account for the change in the last
		   byte of the port number.  Adjust checksum for 2 bytes:
				1 byte of 2nd byte of port + 1 byte after port
		*/
		if (nat_type == NAT_BIND_NAPT)
		{
			old_data[0] = *old_byte_p++;	/* old port */
			old_data[1] = *old_byte_p;
			new_data[0] = *new_byte_p;		/* translated port */
			new_data[1] = *old_byte_p;

			checksum_fixup ((BYTE *) checksum,
							old_data, (USHORT) 2,
							new_data, (USHORT) 2);
		}
					
	}
	else	/* even address */
	{	
		checksum_fixup ((BYTE *) checksum,
						(BYTE *) data, sizeof(IP_ADDRESS),
						(BYTE *) &new_transport->ip_addr, sizeof(IP_ADDRESS));

		if (nat_type == NAT_BIND_NAPT)
		{
			checksum_fixup ((BYTE *) checksum,
							(BYTE *) (data + sizeof(IP_ADDRESS)), sizeof(USHORT),
							(BYTE *) &new_transport->port, sizeof(USHORT));
		}
	}
}
		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -