📄 ipsec_io.c
字号:
#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) { #ifdef INCLUDE_COUNTERS_NETWORK_INTERFACE updateNetworkInterfaceCounters (OUTBOUND, pp_memory_buffer, pp_ip_header, EXPLICIT_BYPASS_COUNT, NOT_USED); #endif spdIncrementPolicyCounters (sptr_policy, ((struct ip *) *pp_ip_header)->ip_len - header_length); return (return_value); } if (mode != TUNNEL) return (OK); destIPAddr = getDestAddrFromTrafficInfo (p_traffic_info, wrn_inet_family); srcIPAddr = getSrcAddrFromTrafficInfo (p_traffic_info, wrn_inet_family); if (NEITHER_OF (protocol, TRANSPORT_PROTO_ESP, TRANSPORT_PROTO_AH)) return (OK); /* Come here only if proto is not one of ESP, AH, i.e., ipsec applied at least once */ if (isSameIP (destIPAddr, p_tunnel_end_point)) { if (IS_IP_MINE (srcIPAddr)) return (OK); } return_value = ipsecApplyPolicy (direction, p_traffic_info, sptr_policy, pSABundle, net_interface, pp_memory_buffer, pp_ip_header, header_length, flags); return (return_value); }/********************************************************************************* ipsecOutput - Process outbound packets** This routine serves as the IP stack hook and entry point for outbound packets* that are to be processed by IPsec.** RETURNS: OK if the packet is BYPASSed or returned to the IP stack;* ERROR if the packet is dropped or TUNNELED by IPsec. The ERROR return* code indicates that the packet should not or TUNNE, or EHOSTUNREACH** SEE ALSO:** NOMANUAL*/STATUS ipsecOutput ( struct mbuf ** m, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct sockaddr_in *dst, struct in_ifaddr *ia ) { 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; NET_IF *net_interface; struct ip *p_ip_header; struct ifnet *p_m_ifnet; STATUS return_value; struct ifnet *ifp; int s; if (ipsec_global_class.ipsec_enabled == FALSE) return (OK); p_ip_header = mtod (*m, struct ip *); wrSecTrace(TRACE_IPSEC_OUT, L1, "\n"); wrSecTrace(TRACE_IPSEC_OUT, L1, "************** OUTPUT PROCESSING STARTING ***************\n"); wrSecTraceIPHeader( TRACE_IPSEC_OUT, L2, "OUTBOUND IP Packet", p_ip_header ); wrSecTraceBuffer( TRACE_IPSEC_OUT, L3, "OUTBOUND IP PACKET", p_ip_header, p_ip_header->ip_len, 16 ); if (((struct mbuf *) *m)->m_flags & M_SECURE_PKT) ((struct mbuf *) *m)->m_flags = (((struct mbuf *) *m)->m_flags ^ M_SECURE_PKT); /* increment global output packet count */ ++ipsec_global_class.ipsecOutputCount; PARAMETER_NOT_USED (opt); PARAMETER_NOT_USED (ro); PARAMETER_NOT_USED (imo); PARAMETER_NOT_USED (dst); ifp = ia->ia_ifp; if (ifp == NULL) { wrSecTrace(TRACE_IPSEC_OUT, L1, "Field ifp in struct in_ifaddr* ia is not initialized, dropping packet and returning ERROR\n"); WRN_M_FREEM (*m); /* Drop the IP Packet*/ /* increment global output dropped packet count due to invalid packet */ ++ipsec_global_class.ipsecOutputCountDropped; return (ERROR); } /* ** Save the m ifp. The ifp should be the outbound interface */ p_m_ifnet = ((struct mbuf *) *m)->m_pkthdr.rcvif; ((struct mbuf *) *m)->m_pkthdr.rcvif = ifp; if (ipsecGetNetIf (OUTBOUND, *m, p_ip_header, &net_interface) == FALSE) { ((struct mbuf *) *m)->m_pkthdr.rcvif = p_m_ifnet; return (OK); } wrSecTrace( TRACE_IPSEC_OUT, L1, "Creating OUTBOUND Traffic info...\n" ); return_value = ipsecCreateTrafficInfo (&p_traffic_info, &v4_traffic_info, &v6_traffic_info, net_interface, m, &p_ip_header, (p_ip_header->ip_hl << 2), flags); { wrSecTraceTrafficInfo( TRACE_IPSEC_OUT, L1, OUTBOUND, p_traffic_info ); /* ** --- Lookup security policy */ spdGetCachedPolicyTraffic( OUTBOUND, p_traffic_info, &sptr_policy, &pSABundle ); return_value = ipsecProcessInsecurePacket (OUTBOUND, p_traffic_info, sptr_policy, pSABundle, net_interface, m, &p_ip_header, (p_ip_header->ip_hl << 2),flags); wrSecTrace( TRACE_IPSEC_OUT, L1, "ipsecProcessInsecurePacket() returned %u...\n", return_value ); if (return_value == ERROR) { /* increment global output dropped packet */ ++ipsec_global_class.ipsecOutputCountDropped; } else if (return_value == EMSGSIZE) { /* pass this error value to ip_output. */ } else if (return_value != OK) /* packet is tunneled or queued */ { return_value = ERROR; } else { return_value = ipsecProcessSecurePacket (OUTBOUND, p_traffic_info, sptr_policy, pSABundle, net_interface, m, &p_ip_header, (p_ip_header->ip_hl << 2),flags); wrSecTrace( TRACE_IPSEC_OUT, L1, "ipsecProcessSecurePacket() returned %u...\n", return_value ); if (return_value == ERROR) { /* increment global output dropped packet due to ipsecProcessSecurePacket */ ++ipsec_global_class.ipsecOutputCountDropped; } else if (return_value == EMSGSIZE) { /* pass this error value to ip_output. */ } else if (return_value != OK) /* packet is tunneled or queued */ { return_value = ERROR; } #ifdef INCLUDE_COUNTERS_NETWORK_INTERFACE else /* return_value == OK */ { /* possible output packet count */ /* increment PACKET_COUNT and BYTE_COUNT since they go hand in hand */ updateNetworkInterfaceCounters (OUTBOUND, m, &p_ip_header, PACKET_COUNT, p_ip_header->ip_len - (p_ip_header->ip_hl << 2)); } #endif } } /* we need to check return_value before modifying mbuf since it * got freed in case of ERROR return value. */ if (return_value != ERROR) ((struct mbuf *) *m)->m_pkthdr.rcvif = p_m_ifnet; wrSecTrace(TRACE_IPSEC_OUT, L1,"ipsecOutput() hook returning '%d'\n", return_value); wrSecTrace(TRACE_IPSEC_OUT, L1,"************** OUTPUT PROCESSING ENDING *****************\n"); return (return_value);}/****************************************************************************** * * ipsecInProcessPlainTextPacket - filters incoming plain text packets before * ipsec processing * * This function checks incoming plain text packets to determine if they should * dropped or bypassed. A packet will be bypassed under the following * conditions: * - There is an SA bundle associated with the packet and the bundle * processing indicator is BYPASS. This will only occur if an MKM SA * (with processing indicator BYPASS) has been created. * - There is not an SA bundle and the security policy associated with the * packet is BYPASS. This will occur if there is an SPD BYPASS policy or * if the default policy is BYPASS. * - The packet has already been secured by IPsec. (the M_SECURE_PKT bit is * set in the mbuf). * * A packet will be discarded under the following conditions: * - There is an SA bundle associated with the packet and the bundle * processing indicator is DISCARD. This will only occur if an MKM SA * (with processing indicator DISCARD) has been created. * - There is not an SA bundle and the security policy associated with the * packet is DISCARD. This will occur if there is an SPD DISCARD policy or * if the default policy is DISCARD * - There is not an SA bundle and the security policy associated with the * packet is APPLY. This will occur if a protection suite does not * currently exist for the associated policy. * * NOMANUAL * * RETURNS: OK or ERROR if the packet is discarded*/LOCAL STATUS ipsecInProcessPlainTextPacket ( SECURITY_POLICY *sptr_policy, struct mbuf **pp_memory_buffer, struct ip **pp_ip_header, int header_length, VI_NETWORK_TRAFFIC_INFO *p_traffic_info ) { #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) WRSEC_INET_FAMILY wrn_inet_family = p_traffic_info->type; #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */ SPD_PROCESSING_INDICATOR security_check = sptr_policy ? sptr_policy->processing_indicator:NOT_VALID; STATUS return_value = ERROR; SA_BUNDLE *pSABundle; /* IP Packet has been secured by ipsec */ if (((struct mbuf *) *pp_memory_buffer)->m_flags & M_SECURE_PKT) return (OK); pSABundle = sadbGetSABundle (INBOUND, p_traffic_info, FALSE); if (pSABundle != NULL) { if (pSABundle->security_processing_indicator == BYPASS) { /* only MKM would have a sa_bundle processing indicator set to BYPASS so we should not need to count this bypass */ return_value = OK; } else { /* since the packet is not ipsec'ed and since there is a sa_bundle the packet should be secure thus drop it. */ /* probably want to log this error insecure packet arrived on secure interface */ /* drop the packet*/ WRN_M_FREEM (*pp_memory_buffer); } } else { if ((security_check == APPLY) || (security_check == DISCARD)) { if (security_check == DISCARD) { #ifdef INCLUDE_COUNTERS_NETWORK_INTERFACE updateNetworkInterfaceCounters (INBOUND, 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); } else { #ifdef INCLUDE_COUNTERS_NETWORK_INTERFACE updateNetworkInterfaceCounters (INBOUND, pp_memory_buffer, pp_ip_header, NO_PS_DISCARD_COUNT, NOT_USED); #endif #ifdef INCLUDE_LOGGING_SPD_PACKET_DISCARD if (ipsecLoggerIsLogEventEnabled (SPD_PACKET_DISCARD)) { ipsecEventLogFromNetworkTrafficInfo (p_traffic_info, NULL, SPD_PACKET_DISCARD, NO_PROTECTION_SUITE); } #endif /* INCLUDE_LOGGING_SPD_PACKET_DISCARD */ } WRN_M_FREEM (*pp_memory_buffer); /* drop the packet*/ } else if (security_check == BYPASS) { /* do not need to count since packet will be counted as a bypass in ipsecProcessSecurePacket */ /* security_check == BYPASS */ return_value = OK; } else /* else if (security_check == NOT_VALID) */ { if (spdGetDefaultPI (p_traffic_info->type, INBOUND, &security_check) == TRUE) { if (security_check == BYPASS) { /* should increment bypass count based on the default policy indicator */ return_value = OK; } else /* if (security_check == DISCARD) */ { #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) if (wrn_inet_family == WRSEC_PF_INET6) if (ipsecIsIcmp6Message (*pp_memory_buffer)) return (OK); #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */ /* increment discard counts based on the default policy indicator */ #ifdef INCLUDE_COUNTERS_NETWORK_INTERFACE updateNetworkInterfaceCounters (INBOUND, pp_memory_buffer, pp_ip_header, NO_POLICY_DISCARD_COUNT, NOT_USED); #endif #ifdef INCLUDE_LOGGING_SPD_PACKET_DISCARD if (ipsecLoggerIsLogEventEnabled (SPD_PACKET_DISCARD)) { ipsecEventLogFromNetworkTrafficInfo (p_traffic_info, NULL, SPD_PACKET_DISCARD, NO_POLICY); } #endif /* INCLUDE_LOGGING_SPD_PACKET_DISCARD */ WRN_M_FREEM (*pp_memory_buffer); /* drop the packet*/ } } else { /* increment bypass based on a PI */ #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) if (wrn_inet_family == WRSEC_PF_INET6) if (ipsecIsIcmp6Message (*pp_memory_buffer)) return (OK); #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */ WRN_M_FREEM (*pp_memory_buffer); /* drop the packet*/ } } } return (return_value); }/******************************************************************************* ipsec_get_attached_network_interface - checks if interface is ipsec enabled* * This function searches the ipsec interface containers for the one on which* we received the packet based on ip address in packet ( source address* incase of outbound packet, destination address incase of inbound packet )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -