📄 ipsec_io.c
字号:
* NOMANUAL* * RETURNS: TRUE if network interface is found, FALSE otherwise*/LOCAL BOOL ipsecGetNetIf ( TRAFFIC_DIRECTION direction, struct mbuf *p_memory_buffer, struct ip *sptr_ip_header, NET_IF **net_interface ) { IPSEC_NETWORK_INTERFACE *p_ipsec_network_interface = (IPSEC_NETWORK_INTERFACE*)NULL; BOOL status; int s; s = splnet (); status = ipsec_get_attached_network_interface (direction, p_memory_buffer, sptr_ip_header, &p_ipsec_network_interface); if (p_ipsec_network_interface != NULL) { *net_interface = p_ipsec_network_interface->net_interface; if (direction == INBOUND ) { /* these packets were not counted in ipsecFilterHook */ /* interface input packet count */ ++p_ipsec_network_interface->packets_rx_on_ipsec_port; } else { /* increment interface output packet count */ ++p_ipsec_network_interface->packets_tx_on_ipsec_port; } } splx (s); return( status );}/******************************************************************************** ipsecCreateTrafficInfo - Create IPsec traffic info structure.** This function will create an IPsec traffic info struct at the start of each* stack hook/** RETURNS: none** SEE ALSO:** NOMANUAL*/LOCAL STATUS ipsecCreateTrafficInfo ( VI_NETWORK_TRAFFIC_INFO **p_p_traffic_info, V4_NETWORK_TRAFFIC_INFO *p_v4_traffic_info, V6_NETWORK_TRAFFIC_INFO *p_v6_traffic_info, NET_IF *net_interface, struct mbuf ** pp_memory_buffer, struct ip ** pp_ip_header, int header_length, int flags ){ *p_p_traffic_info = NULL; if (((struct ip *) *pp_ip_header)->ip_v == 4) { WRN_INIT_V4_NETWORK_TRAFFIC_INFO((p_v4_traffic_info)) *p_p_traffic_info = (VI_NETWORK_TRAFFIC_INFO *)p_v4_traffic_info; } else if (((struct ip *) *pp_ip_header)->ip_v == 6) { WRN_INIT_V6_NETWORK_TRAFFIC_INFO((p_v6_traffic_info)) *p_p_traffic_info = (VI_NETWORK_TRAFFIC_INFO *)p_v6_traffic_info; } else { ipsec_printf (IPSEC_ERROR_PRINTF, "IPsec: Invalid IP Header format\n"); return (ERROR); } /* build traffic info */ if (ipsec_build_traffic_info (pp_memory_buffer, pp_ip_header, header_length, net_interface, *p_p_traffic_info, flags) == FALSE) { /* Drop the IP Packet */ WRN_M_FREEM (*pp_memory_buffer); wrSecTrace( TRACE_ALL, L1, "PACKET DROPPED!! 'function::%s'\n", __FUNCTION__); *p_p_traffic_info = NULL; } return( *p_p_traffic_info ? OK:ERROR);}/******************************************************************************** ipsecInput - This function is called by IP if ipsec is enabled.** This function will create a message suitable to be processed by IPsec and pass* the packet to IPsec module.** RETURNS: none** SEE ALSO:** NOMANUAL*/STATUS ipsecInput ( struct mbuf ** m, int hlen, struct ip ** ip ) { V4_NETWORK_TRAFFIC_INFO v4_traffic_info; V6_NETWORK_TRAFFIC_INFO v6_traffic_info; VI_NETWORK_TRAFFIC_INFO *p_traffic_info = NULL; SECURITY_POLICY* sptr_policy = NULL; SA_BUNDLE *pSABundle = (SA_BUNDLE*)NULL; STATUS return_value; NET_IF *net_interface; int s, flags = 0; int nxt_hdr = (int)NULL; if (ipsec_global_class.ipsec_enabled == FALSE) return (OK); wrSecTrace(TRACE_IPSEC_IN, L1, "\n"); wrSecTrace(TRACE_IPSEC_IN, L1, "************** INPUT PROCESSING STARTING ***************\n"); wrSecTraceIPHeader( TRACE_IPSEC_IN, L2, "INBOUND IP Packet", *ip ); if (((struct mbuf *) *m)->m_flags & M_SECURE_PKT) { ((struct mbuf *) *m)->m_flags = (((struct mbuf *) *m)->m_flags ^ M_SECURE_PKT); if (((struct ip *) *ip)->ip_v == 4) { nxt_hdr = ((struct ip *) *ip)->ip_p; } #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) else if (((struct ip *) *ip)->ip_v == 6) { nxt_hdr = ((struct ip6_hdr *) *ip)->ip6_nxt; } #endif /* defined (__IPV6_STACK__) */ if ((nxt_hdr != TRANSPORT_PROTO_ESP) && (nxt_hdr != TRANSPORT_PROTO_AH)) { return (OK); } } /* increment global input packet count */ ++ipsec_global_class.ipsecInputCount; /* ** --- Check if IPSEC is attached to this interface. If not, treat the packet as a BYPASSS */ wrSecTrace( TRACE_IPSEC_IN, L1, "Getting INBOUND Network interface...\n" ); if (ipsecGetNetIf (INBOUND, *m, *ip, &net_interface) == FALSE) return (OK); return_value = ipsecCreateTrafficInfo (&p_traffic_info, &v4_traffic_info, &v6_traffic_info, net_interface, m, ip, hlen, flags); if (return_value == OK) { /* ** --- Apply security policy */ wrSecTraceTrafficInfo( TRACE_IPSEC_IN, L1, INBOUND, p_traffic_info ); spdGetCachedPolicyTraffic( INBOUND, p_traffic_info, &sptr_policy, &pSABundle); return_value = ipsecApplyPolicy (INBOUND, p_traffic_info, sptr_policy, pSABundle, net_interface, m, ip, hlen, flags); } /* ** --- Check return status */ if (return_value == ERROR) { /* increment global input packet count for dropped packets */ ++ipsec_global_class.ipsecInputCountDropped; } else if (return_value != OK) /* packet is de-capsulated or queued */ { #ifdef INCLUDE_COUNTERS_NETWORK_INTERFACE if (return_value == TUNNELED) { /* increment PACKET_COUNT and BYTE_COUNT since they go hand in hand */ updateNetworkInterfaceCounters (INBOUND, m, ip, PACKET_COUNT, (*ip)->ip_len - hlen); } #endif return_value = ERROR; } else /* return == OK */ { /* possible input packet count */ #ifdef INCLUDE_COUNTERS_NETWORK_INTERFACE /* increment PACKET_COUNT and BYTE_COUNT since they go hand in hand */ updateNetworkInterfaceCounters (INBOUND, m, ip, PACKET_COUNT, (*ip)->ip_len - hlen); #endif } if (return_value != ERROR) { /* Drop all packets which still have AH or ESP as next header */ (*ip) = mtod ((*m), struct ip *); if (((struct ip *) *ip)->ip_v == 4) { nxt_hdr = ((struct ip *) *ip)->ip_p; } #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) else if (((struct ip *) *ip)->ip_v == 6) { nxt_hdr = ((struct ip6_hdr *) *ip)->ip6_nxt; } #endif /* #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */ if (nxt_hdr == TRANSPORT_PROTO_AH || nxt_hdr == TRANSPORT_PROTO_ESP) { /* increment global input packet count for dropped packets due next header being AH/ESP */ ++ipsec_global_class.ipsecInputCountDropped; return_value = ERROR; WRN_M_FREEM (*m); /* Drop the IP Packet*/ } } wrSecTrace(TRACE_IPSEC_IN, L1, "ipsecInput() hook returning '%d'\n", return_value); wrSecTrace(TRACE_IPSEC_IN, L1, "************** INPUT PROCESSING ENDING *****************\n"); return (return_value); }/******************************************************************************** ipsecOutProcessInsecurePacket : Process an unsecured outbound packet.* * This routine performs initial processing on outbound packets, under the * assumption that they have not been secured. Packets processed here will* either have an IPsec APPLY policy associated with them or no known policy * (a BYPASS or DISCARD policy will be handled prior to this routine being* called). * If the packet is secured (AH or ESP protocol), then we hand the packet to* ipsecOutProcessSecurePacket for further processing. Otherwise, we need to* apply the appropriate policy. This is done in ipsecApplyPolicy().** RETURNS: OK if the packet will be BYPASSed;* ERROR if the packet is dropped;* EMSGSIZE if packet size > mtu;* TUNNELED if the packet has been tunneled;* QUEUED if the packet has been queued (IPSEC_QUEUEING enabled).*/LOCAL int ipsecProcessInsecurePacket ( TRAFFIC_DIRECTION direction, VI_NETWORK_TRAFFIC_INFO *p_traffic_info, SECURITY_POLICY *sptr_policy, SA_BUNDLE *pSABundle, NET_IF *net_interface, struct mbuf ** pp_memory_buffer, struct ip ** pp_ip_header, int header_length, int flags ) { WRSEC_INET_FAMILY wrn_inet_family = p_traffic_info->type; SPD_PROCESSING_INDICATOR security_check = sptr_policy ? sptr_policy->processing_indicator:NOT_VALID; STATUS return_value = OK; int protocol = TRAFFIC_INFO_PROTOCOL_GET(p_traffic_info); if (security_check == DISCARD) { /* have discard policy but may or may not have a sa_bundle */ #ifdef INCLUDE_COUNTERS_NETWORK_INTERFACE updateNetworkInterfaceCounters (OUTBOUND, pp_memory_buffer, pp_ip_header, EXPLICIT_DISCARD_COUNT, NOT_USED); #endif #ifdef INCLUDE_LOGGING_SPD_PACKET_DISCARD if (ipsecLoggerIsLogEventEnabled (SPD_PACKET_DISCARD)) { ipsecEventLogFromNetworkTrafficInfo (p_traffic_info, NULL, SPD_PACKET_DISCARD, EXPLICIT_DISCARD_POLICY); } #endif /* INCLUDE_LOGGING_SPD_PACKET_DISCARD */ spdIncrementPolicyCounters (sptr_policy, ((struct ip *) *pp_ip_header)->ip_len - header_length); /* Drop the IP Packet */ WRN_M_FREEM (*pp_memory_buffer); return (ERROR); } else if (security_check == BYPASS) { /* do not increment counts here since they will be incremented later in processSecurePacket */ return (OK); } if (ONE_OF (protocol, TRANSPORT_PROTO_ESP, TRANSPORT_PROTO_AH)) { return_value = ipsecProcessSecurePacket (direction, p_traffic_info, sptr_policy, pSABundle, net_interface, pp_memory_buffer, pp_ip_header, header_length, flags); return (return_value); } return_value = ipsecApplyPolicy (direction, p_traffic_info, sptr_policy, pSABundle, net_interface, pp_memory_buffer, pp_ip_header, header_length, flags); return (return_value); }/******************************************************************************** ipsecOutProcessSecurePacket : Process a secured outbound packet.** This routine performs processing on outbound packets that have already been* secured (that is, the protocol is AH or ESP). The policy associated with the* packet is examined and IPsec processing will be applied if the packet* needs to be tunneled. Typically, this will occur if we receive a packet that* was secured elsewhere, but needs to be resecured over a tunnel.* The packet will be bypassed under the following conditions:* (a) The packet is not secured (AH or ESP). This should NOT happen.* (b) There is not a tunnel policy associated with the packet.* (c) The packet is traveling from this node to the tunnel endpoint.* For the case where the tunnel policy is to be applied, this is handled* by ipsecApplyPolicy(). This will normally result in the packet being discarded* if there is no SA Bundle, or processing of the packet using the SA bundle* specifications.* RETURNS: OK, if the packet will be BYPASSED;* ERROR if the packet will be DISCARDED or processing fails;* TUNNELED if the packet has been TUNNELED;* EMSGSIZE if packet size > mtu.*/LOCAL int ipsecProcessSecurePacket ( TRAFFIC_DIRECTION direction, VI_NETWORK_TRAFFIC_INFO *p_traffic_info, SECURITY_POLICY *sptr_policy, SA_BUNDLE *pSABundle, NET_IF *net_interface, struct mbuf ** pp_memory_buffer, struct ip ** pp_ip_header, int header_length, int flags ) { WRSEC_INET_FAMILY wrn_inet_family = p_traffic_info->type; SPD_PROCESSING_INDICATOR security_check = sptr_policy ? sptr_policy->processing_indicator:NOT_VALID; ENCAPSULATION_MODE_VALUE mode = ENCAPSULATION_MODE_VALUE_RESERVED; STATUS return_value = OK; WRSEC_INET_ADDR *p_tunnel_end_point = NULL; int protocol = TRAFFIC_INFO_PROTOCOL_GET(p_traffic_info); WRSEC_INET_ADDR *destIPAddr; WRSEC_INET_ADDR *srcIPAddr; /* ** --- For apply policies, mode will be either TUNNEL or TRANSPORT */ if (security_check == APPLY) { mode = ((IPSEC_SECURITY_POLICY *)sptr_policy)->encapsulation_mode; if (mode == TUNNEL) p_tunnel_end_point = ((IPSEC_SECURITY_POLICY *)sptr_policy)->p_tunnel_endpoint; } if (security_check == DISCARD) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -