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

📄 ipsec_icmp_pmtu.c

📁 ipsec PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (p_sa_bundle->mode == TRANSPORT)        {        /* In case of transport, we need full original packet to get          * access to next header field in esp header.         */        pmtu_message->transport = TRUE;        if (data_len != complete_packet_len)            {            return (ERROR);            }        }    if (ipsec_decrypt_esp_message ((SA_BUNDLE *)p_sa_bundle->reflected_sa, bptr_esp_hdr, data_len, &bptr_decrypted_data,                                   &decrypted_data_len,                    &pad_len,     &next_header) == FALSE)        {        return (ERROR);        }    data_len = decrypted_data_len;    if (p_sa_bundle->mode == TRANSPORT)        {        pmtu_message->ip_nxt_protocol = next_header;        data_len = data_len - pad_len - 2 * sizeof (UCHAR);        status = ipsecPmtuDataCopy (pmtu_message, bptr_decrypted_data, data_len);        }    else        {        status = ipsecPmtuTunnelMessageProcess ((struct ip *)bptr_decrypted_data, data_len, pmtu_message, sa_info);        }    return (status);    }/****************************************************************************** * ipsecPmtuTunnelMessageProcess - removes the tunnel headers * * This function populates the pmtu message with PMTU payload data and the * destination address of the host to which the PMTU message has to be sent * * NOMANUAL * * RETURNS : OK or ERROR if the destination address could not be found. */LOCAL STATUS ipsecPmtuTunnelMessageProcess    (    struct ip *ip,                    /* ip header */    UINT data_len,                    /* remaining pmtu payload */    IPSEC_PMTU_MESSAGE *pmtu_message, /* structure to store pmtu info*/    SA_BUNDLE_INFO *sa_info           /* info to retrieve sa from sadb */    )    {    if (ip->ip_v == IP_V4)        {        if (data_len < MINIMUM_IP_V4_HEADER_LENGTH)            {            if (sa_info->p_sa_bundle == NULL)                {                sa_info->p_sa_bundle = ipsecPmtuSaBundleFind (sa_info);                }            if (sa_info->p_sa_bundle == NULL)                {                return (ERROR);                }            else                {                return (ipsecPmtuDestinationFind (pmtu_message, sa_info->p_sa_bundle));                }            }        WRSEC_INET4_SET_STRUCT_A_WITH_IN_ADDR_B ((*(WRSEC_INET4_ADDR *)pmtu_message->destination_address), ip->ip_src);        }    #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)    else if (ip->ip_v == IP_V6)        {        struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;        if (data_len < MINIMUM_IP_V6_HEADER_LENGTH)            {            if (sa_info->p_sa_bundle == NULL)                {                sa_info->p_sa_bundle = ipsecPmtuSaBundleFind (sa_info);                }            if (sa_info->p_sa_bundle == NULL)                {                return (ERROR);                }            else                {                return (ipsecPmtuDestinationFind (pmtu_message, sa_info->p_sa_bundle));                }            }        WRSEC_INET6_SET_STRUCT_A_WITH_IN6_ADDR_B ((*(WRSEC_INET6_ADDR *)pmtu_message->destination_address), ip6->ip6_src);        }    #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */    else        {        ipsec_printf (IPSEC_ERROR_PRINTF, "IPSEC:PMTU:Tunnel:only IPv4 and IPv6 address are supported\n");        return (ERROR);        }    return ipsecPmtuDataCopy (pmtu_message, (UCHAR *)ip, data_len);    }/****************************************************************************** * ipsecPmtuTransportMessageProcess - bypasses the packet to the upper layers. * * This function recalculates the icmp(6) checksum and bypasses the packet * to the upper layers. *  * NOMANUAL * * RETURNS: OK always * */LOCAL STATUS ipsecPmtuTransportMessageProcess    (    struct mbuf *m,                  /* pointer to mbuf */    IPSEC_PMTU_MESSAGE *pmtu_message /* contains pmtu info */    )    {    STATUS status;    UCHAR *p_transport;    int hlen, ip2len;    status = OK;    hlen = ip2len = 0;    p_transport = NULL;    if (pmtu_message->family == WRSEC_AF_INET4)        {        struct icmp *icmp4;        struct ip *ip1, *ip2;        ip1 = NULL;        icmp4 = NULL;        ip1 = mtod (m, struct ip *);        hlen = ip1->ip_hl << 2;        icmp4 = (struct icmp *) ((UCHAR *)ip1 + hlen);        ip2 = (struct ip *) ((UCHAR *)icmp4 + ICMP_MINLEN);        ip2len = ip2->ip_hl << 2;        p_transport = (UCHAR *)ip2 + ip2len;        /*          * For the error advice packets we must first insure that the         * packet is large enough to contain the returned ip header.         */        if (pmtu_message->datalength < (sizeof (struct ip) + MIN_TRANSPORT_HDR_LEN))            {            /* Store the PMTU Message */            return (OK);            }        bcopy ((const char *)pmtu_message->data, (char *)p_transport, (int)pmtu_message->datalength);        ip2->ip_p = pmtu_message->ip_nxt_protocol;        ip2->ip_len = ip2len + pmtu_message->datalength;        ip2->ip_len = htons (ip2->ip_len);        ip1->ip_len = ICMP_MINLEN + ip2->ip_len;        m->m_len = ip1->ip_len;        m->m_data = (char *)icmp4;        m->m_pkthdr.len = m->m_len;        icmp4->icmp_nextmtu = htons (pmtu_message->pmtu);        icmp4->icmp_cksum = 0;        icmp4->icmp_cksum = in_cksum (m, (ICMP_MINLEN + ip2->ip_len));        m->m_data = (char *)ip1;        m->m_len = ip1->ip_len + hlen;        m->m_pkthdr.len = m->m_len;        m->m_pkthdr.rcvif = (struct ifnet *)0;        }    #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)    else if (pmtu_message->family == WRSEC_AF_INET6)        {        struct ip6_hdr *ip6_hdr1, *ip6_hdr2;        struct icmp6_hdr *icmp6;        ip6_hdr1 = mtod (m, struct ip6_hdr *);        hlen = ipsecIpv6HdrLenGet (NULL, ip6_hdr1);        ip6_hdr2 = (struct ip6_hdr *) ((char *)ip6_hdr1 + hlen + ICMP6_MINLEN);        ip2len = ipsecIpv6HdrLenGet (NULL, ip6_hdr2);        p_transport = (UCHAR *)ip6_hdr2 + ip2len;        if (pmtu_message->datalength < (sizeof (struct ip6_hdr) + MIN_TRANSPORT_HDR_LEN))            {            /* Store the PMTU Message */            return (OK);            }        bcopy ((const char *)pmtu_message->data, (char *)p_transport, (int)pmtu_message->datalength);        ip6_hdr2->ip6_nxt = pmtu_message->ip_nxt_protocol;        ip6_hdr2->ip6_plen = pmtu_message->datalength;        ip6_hdr1->ip6_plen = ICMP6_MINLEN + ip2len + ip6_hdr2->ip6_plen;        ip6_hdr2->ip6_plen = htons (ip6_hdr2->ip6_plen);        icmp6 = (struct icmp6_hdr *) ((char *)ip6_hdr1 + hlen);        m->m_len = ip6_hdr1->ip6_plen + hlen;        m->m_pkthdr.len = m->m_len;        icmp6->icmp6_mtu = htonl (pmtu_message->pmtu);        icmp6->icmp6_cksum = 0;        icmp6->icmp6_cksum = in6_cksum (m, IPPROTO_ICMPV6, hlen, ip6_hdr1->ip6_plen);        ip6_hdr1->ip6_plen = htons (ip6_hdr1->ip6_plen);        m->m_pkthdr.rcvif = (struct ifnet *)0;        return (status);        }    #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */    return (status);    }/****************************************************************************** * ipsecPmtuDataCopy - stores the PMTU payload in the PMTU message. * * NOMANUAL     * RETUNRNS : OK or ERROR if the data pointer is not set. */LOCAL STATUS ipsecPmtuDataCopy    (    IPSEC_PMTU_MESSAGE *pmtu_message, /* structure to store pmtu payload */    UCHAR *data,                       /* pmtu data to store */    UINT data_len                     /* length of  pmtu data */    )    {    pmtu_message->data = (UCHAR *)wrSecCalloc (1, data_len);    if (pmtu_message->data == NULL)        {        return (ERROR);        }    pmtu_message->datalength = data_len;    memcpy (pmtu_message->data, data, data_len);    return (OK);    }/******************************************************************************  * ipsecPmtuDestinationFind - finds the destination to which the PMTU * message has to be sent. * * This function finds the destination to which the PMTU message has to be * sent.  This is called in case where the PMTU message received by the * gateway does not contain information regarding the originator of the * packet(i.e which caused the PMTU to be generated). * * NOMANUAL * * RETURNS : OK if the destination has been found else ERROR. */LOCAL STATUS ipsecPmtuDestinationFind    (    IPSEC_PMTU_MESSAGE *pmtu_message, /* structure to store dest address */    SA_BUNDLE *p_sa_bundle            /* outbound sa bundle */    )    {    WRSEC_INET_ADDR *p_source;    p_source = sadb_get_source_address ((SA_BUNDLE *)p_sa_bundle->reflected_sa);    if (p_source == NULL)        {        return (ERROR);        }    if (p_source->type == WRSEC_AF_INET4)        {        WRSEC_INET4_ASSIGN_B_TO_A (((WRSEC_INET4_ADDR *)pmtu_message->destination_address), ((WRSEC_INET4_ADDR *)p_source));        }    #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)    else if (p_source->type == WRSEC_AF_INET6)        {        WRSEC_INET6_ASSIGN_B_TO_A (((WRSEC_INET6_ADDR *)pmtu_message->destination_address), ((WRSEC_INET6_ADDR *)p_source));        }    #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */    else        {        return (ERROR);        }    return (OK);    }/****************************************************************************** * ipsecPmtuForwardPmtuMessage - forward the pmtu message. * * This function is called after tunnel processing to forward the PMTU message * that the gateway  has received on behalf of other hosts whose policies  * have been configured in its SADB. * * NOMANUAL *  * RETURNS : ERROR if the packet has been forwarded. */LOCAL STATUS ipsecPmtuForwardPmtuMessage    (    struct mbuf *m_source,           /* packet to forward */    IPSEC_PMTU_MESSAGE *pmtu_message /* info to make pmtu packet */    )    {    STATUS status;    USHORT icmp_len;    int hlen, s;    struct ifnet *sptr_ifnet = NULL;    UINT mblk_size;    struct mbuf *m;    IPSEC_NETWORK_INTERFACE *p_network_interface;    status = OK;    if (pmtu_message->family == WRSEC_AF_INET4)        {        struct ip *orig_ip;        struct ip *ip4;        struct icmp *icmp4;        struct route ro;        icmp4 = NULL;        orig_ip = NULL;        orig_ip = mtod (m_source, struct ip *);        hlen = orig_ip->ip_hl << 2;        /* The pmtu payload should contain the full original ip header plus          * 8 bytes of upper layer protocol ( UDP/TCP)         */        if (pmtu_message->datalength < (sizeof (struct ip) + MIN_TRANSPORT_HDR_LEN))            {            /* Store the PMTU Message */            WRN_M_FREEM (m_source);			wrSecTrace( TRACE_ALL, L1, "PACKET DROPPED!! 'function::%s'\n", __FUNCTION__);            return (ERROR);            }        mblk_size = ICMP_MINLEN + pmtu_message->datalength + (MINIMUM_IP_V4_HEADER_LENGTH);        #if STACK_NAME == STACK_NAME_V4_V6        MGET1 (m, mblk_size, M_WAIT, m_source->m_type);        #else        m = m_getclr (M_WAIT, m_source->m_type, mblk_size, TRUE);        #endif /* STACK_NAME == STACK_NAME_V4_V6 */        if (m == NULL)            {            /* Store the PMTU Message */            WRN_M_FREEM (m_source);			wrSecTrace( TRACE_ALL, L1, "PACKET DROPPED!! 'function::%s'\n", __FUNCTION__);            return (ERROR);            }        ip4 = mtod (m, struct ip *);        ip4->ip_v = IPVERSION;        ip4->ip_hl = MINIMUM_IP_V4_HEADER_LENGTH >> 2;        ip4->ip_p = TRANSPORT_PROTO_ICMP;        ip4->ip_off = 0;        ip4->ip_ttl = IPDEFTTL;        p_network_interface = ipsecFindNetworkInterfaceBasedOnIfnet (m_source->m_pkthdr.rcvif, WRSEC_AF_INET4);        if (p_network_interface == NULL)            {            return (ERROR);            }        WRSEC_INET4_SET_IN_ADDR_A_WITH_STRUCT_B(ip4->ip_src,                                              (*(WRSEC_INET4_ADDR *) (p_network_interface->p_address)))        WRSEC_INET4_SET_IN_ADDR_A_WITH_STRUCT_B(ip4->ip_dst,                                              (*(WRSEC_INET4_ADDR *)pmtu_message->destination_address))        icmp4 = (struct icmp *) ((UCHAR *)ip4 + MINIMUM_IP_V4_HEADER_LENGTH);        icmp_len = ICMP_MINLEN;        if (pmtu_message->data != NULL)            {            UCHAR *p_transport = (UCHAR *)icmp4 + ICMP_MINLEN;

⌨️ 快捷键说明

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