📄 nat_filter_hook.c
字号:
/* nat_filter_hook.c *//* Copyright 2000-2003 Wind River Systems, Inc. *//* @format.tab-size 4, @format.use-tabs true, @format.new-line lf *//*modification history--------------------01d,09may03,myz removed SERVICES_ADDON loopback handling, now handled by the natIcmpErrorHook.01c,05may03,zhu removed the fix for loopback interface, because it causes a ping problem for local interface01b,01may03,zhu removed DMZ01a,10apr03,zhu A few changes: 1. replace expensive sprintf 2. process ICMP error message from loopback interface 3. update static entried when dynamic global address changes102001 tk On dynamic global address, refresh netmask as well.081701 tk Add #define SHOW_PACKET_DISCARDED to show "packet discarded" trace.053001 tk Add conditional if statement around nat_printf in nat_filter_hook to speed up performance. Also, change debug message variables from local to static reduce overhead cost of stack allocation and de- allocation upon entering nat_filter_hook().*//*#define SHOW_PACKET_DISCARDED*/#include "nat.h"/* VxWorks specific headers */#include <inetLib.h>#include <net/mbuf.h> /* struct mbuf and struct ifnet definitions */#include <netinet/in.h> #include <netinet/ip.h> /* struct ip definition */#include <stdio.h> /* sprintf() prototype */#include <nat_api.h>/* static variables for debug messages */static char src[INET_ADDR_LEN];static char dst[INET_ADDR_LEN];static char str[64];static char output[128];static char* ip_proto_desc(ushort proto){ static char proto_desc[32]; switch(proto) { case IPPROTO_IP: return("IP"); case IPPROTO_ICMP: return("ICMP"); case IPPROTO_IGMP: return("IGMP"); case IPPROTO_GGP: return("GGP"); case IPPROTO_TCP: return("TCP"); case IPPROTO_EGP: return("EGP"); case IPPROTO_PUP: return("PUP"); case IPPROTO_UDP: return("UDP"); case IPPROTO_IDP: return("IDP"); case IPPROTO_TP: return("TP"); case IPPROTO_EON: return("EON"); case IPPROTO_OSPF: return("OSPF"); case IPPROTO_ENCAP: return("ENCAP"); } sprintf(proto_desc,"proto(%02X)",proto); return(proto_desc);}BOOL nat_filter_hook (struct ifnet* pIf, struct mbuf** pPtrMbuf, struct ip** pPtrIpHdr, int ipHdrLen){ int i; int port_number; char ifname[32]; USHORT org_length; IP_PACKET* p_packet; M_BLK* pBlock; struct ifnet* global_if; struct ifaddr* ifaddr; IP_ADDRESS inAddr, inMask; IP_ADDRESS last_global_address = nat.global_address; if (nat.enabled == FALSE) { nat_printf(NAT_PRINTF_ERROR, "nat_filter_hook: not enabled\n"); return (FALSE); } if (pIf == NULL) { nat_printf(NAT_PRINTF_ERROR, "nat_filter_hook: NULL interface pointer\n"); return (FALSE); } if (pPtrIpHdr == NULL || *pPtrIpHdr == NULL) { nat_printf(NAT_PRINTF_ERROR, "nat_filter_hook: NULL IP header pointer\n"); return (FALSE); } if (pPtrMbuf == NULL || *pPtrMbuf == NULL) { nat_printf(NAT_PRINTF_ERROR, "nat_filter_hook: NULL Mbuf pointer\n"); return (FALSE); } i = 0; while (pIf->if_name[i]) { ifname[i] = pIf->if_name[i++]; } ifname[i++] = '0' + pIf->if_unit; ifname[i++] = 0; /* tk - add the if conditional statement to speed up performance */ if (nat.logging_enabled == true || nat.printing_enabled == true) { /* Debug output */ sprintf(output,"nat_filter_hook: if(%s) ",ifname); inet_ntoa_b((*pPtrIpHdr)->ip_src, src); inet_ntoa_b((*pPtrIpHdr)->ip_dst, dst); sprintf(str, "%s src: %s dst: %s\n", ip_proto_desc((*pPtrIpHdr)->ip_p), src, dst); strcat(output,str); nat_printf(NAT_PRINTF_DATA, output); } /* Find port for this interface */ for (port_number = 0; port_number < sizeof(nat.port)/sizeof(nat.port[0]); port_number++) { if (nat.port[port_number].ifunit==pIf || (nat.port[port_number].ifunit==NULL /* dynamically attached interface */ && strcmp(nat.port[port_number].ifname,ifname)==0)) { break; } } if (port_number >= sizeof(nat.port)/sizeof(nat.port[0])) { nat_printf(NAT_PRINTF_ERROR, "nat_filter_hook: port for interface (%s) not found\n" ,ifname); return (FALSE); } if (nat.port[port_number].enabled == FALSE) { nat_printf(NAT_PRINTF_ERROR, "nat_filter_hook: port %d not enabled\n",port_number); return (FALSE); } /* Dynamic Global Address? */ if (nat.dynamic_global_address == TRUE || nat.port[nat.global_port_number].ifunit == NULL) { global_if = nat.port[nat.global_port_number].ifunit; if(global_if == NULL) { global_if = ifunit(nat.port[nat.global_port_number].ifname); } if (global_if != NULL) /* Interface Attached, Get Current Address */ { /* Search for IP address */ for (ifaddr = global_if->if_addrlist; ifaddr != NULL; ifaddr = ifaddr->ifa_next) { if(ifaddr->ifa_addr->sa_family == AF_INET) break; } if (ifaddr != NULL) /* IP Address found */ { inAddr = ntohl(((struct sockaddr_in*) ifaddr->ifa_addr)->sin_addr.s_addr); inMask = ntohl(((struct sockaddr_in*) ifaddr->ifa_netmask)->sin_addr.s_addr); nat.port[nat.global_port_number].address = inAddr; nat.port[nat.global_port_number].mask = inMask; nat_printf(NAT_PRINTF_TRACE, "nat_filter_hook: dynamic global interface addr: %08lX, mask: %08lX", inAddr, inMask); nat.global_address = inAddr; nat.global_address_mask = inMask; } } } /* * Fix up for static entries used to forward certain ports to local machine. * When the global address changes, we have to update the static entries and * ICMP default address. */ if(last_global_address != nat.global_address) { NAT_PORT_STATIC_ENTRY entry; char addrString[18]; struct in_addr iaddr; int i; /* Update static TCP entries using IP of global interface. */ for(i = 0; i < MAXIMUM_NUMBER_OF_TCP_STATIC_ENTRIES; i++) { entry = nat.tcp_static_entries[i]; if(!entry.local_address && !entry.local_port_number && !entry.global_port_number) continue; if(entry.local_address == last_global_address) { iaddr.s_addr = entry.local_address; inet_ntoa_b(iaddr, addrString); natTcpStaticDelete(addrString, entry.local_port_number, entry.global_port_number); iaddr.s_addr = nat.global_address; inet_ntoa_b(iaddr, addrString); natTcpStaticAdd(addrString, entry.local_port_number, entry.global_port_number); } } /* Update static UDP entries using IP of global interface. */ for(i = 0; i < MAXIMUM_NUMBER_OF_UDP_STATIC_ENTRIES; i++) { entry = nat.udp_static_entries[i]; if(!entry.local_address && !entry.local_port_number && !entry.global_port_number) continue; if(entry.local_address == last_global_address) { iaddr.s_addr = entry.local_address; inet_ntoa_b(iaddr, addrString); natUdpStaticDelete(addrString, entry.local_port_number, entry.global_port_number); iaddr.s_addr = nat.global_address; inet_ntoa_b(iaddr, addrString); natUdpStaticAdd(addrString, entry.local_port_number, entry.global_port_number); } } /* Update the default ICMP address if it matches the old global address. */ if(nat.nats.icmp_default_entry.local_address == last_global_address) nat.nats.icmp_default_entry.local_address = nat.global_address; last_global_address = nat.global_address; } p_packet = (IP_PACKET *) *pPtrIpHdr; /* *pPtrIpHdr == *pPtrMbuf->mBlkHdr.mData */ pBlock = *pPtrMbuf; org_length = p_packet->header.total_length; if (nat_rx (port_number, pBlock) == PASS) { pBlock->mBlkHdr.mLen = (USHORT) (pBlock->mBlkHdr.mLen + (p_packet->header.total_length - org_length)); return (FALSE); /* not filtered, normal processing should take place */ }#ifdef SHOW_PACKET_DISCARDED nat_printf(NAT_PRINTF_TRACE, "nat_filter_hook: packet discarded\n");#endif netMblkClChainFree(*pPtrMbuf); return (TRUE); /* filtered, no futher action should be taken with this packet */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -