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

📄 ipsec_icmp_pmtu.c

📁 ipsec PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 4 页
字号:
        /* save this destination, if we later find that original packet was          * not tunnelled then we need this destination (us).         */        WRSEC_INET4_SET_STRUCT_A_WITH_IN_ADDR_B((*(WRSEC_INET4_ADDR *)pmtu_message->destination_address), ip1->ip_dst)        /* Check if we are the destination address */        if (ipsec_find_network_interface_based_on_ip_address (pmtu_message->destination_address) == NULL)            {            /* We are not the destination  for this packet,             * so we will not do any pmtu processing              */            ipsecPmtuMessageDelete (pmtu_message);            ipsecSAInfoDestroy (sa_info);            return (OK);            }        offset = ip1->ip_hl << 2;        total_packet_length = m->m_pkthdr.len;        if (m->m_len < total_packet_length)            {            if ((*pp_m = m_pullup (m, total_packet_length)) == NULL)                {                ipsecPmtuMessageDelete (pmtu_message);                ipsecSAInfoDestroy (sa_info);                WRN_M_FREEM (m); /* drop the packet*/				wrSecTrace( TRACE_ALL, L1, "PACKET DROPPED!! 'function::%s'\n", __FUNCTION__);                return (ERROR);                }            }        icmp4 = (struct icmp *) ((UCHAR *)ip1 + (ip1->ip_hl << 2));        offset += ICMP_MINLEN;        ip2 = (struct ip *) ((UCHAR *)icmp4 + ICMP_MINLEN);        complete_packet_len = ntohs (ip2->ip_len);        pmtu_message->pmtu = ntohs (icmp4->icmp_nextmtu) - packetBufReservedHeaderSizeGet();        WRSEC_INET4_SET_STRUCT_A_WITH_IN_ADDR_B((*(WRSEC_INET4_ADDR *)sa_info->tunnel_endpoint), ip2->ip_dst)        offset += ip2->ip_hl << 2;        complete_packet_len -= ip2->ip_hl << 2;        next_protocol = ip2->ip_p;        }    #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)    else if (((struct ip *)ip)->ip_v == IP_V6)        {        struct icmp6_hdr *icmp6;        struct ip6_hdr *ip6_hdr2;        struct ip6_hdr *ip6_hdr1;        BOOL loop_continue = TRUE;        UCHAR *p_extn_header;        int ip6hdr2_len;        USHORT fragment_offset;        /* initialize pmtu_mesage */        ipsecPmtuMessageCreate (pmtu_message, WRSEC_AF_INET6);        ipsecPmtuSaInfoCreate (sa_info, WRSEC_AF_INET6);        ip6_hdr1 = (struct ip6_hdr *)ip;        WRSEC_INET6_SET_STRUCT_A_WITH_IN6_ADDR_B((*(WRSEC_INET6_ADDR *)pmtu_message->destination_address),                                               ip6_hdr1->ip6_dst)        offset = ipsecIpv6HdrLenGet (m, NULL);        /* Check if we are the destination address */        if (ipsec_find_network_interface_based_on_ip_address (pmtu_message->destination_address) == NULL)            {            /* We are not the destination  for this packet,             * so we will not do any pmtu processing              */            ipsecPmtuMessageDelete (pmtu_message);            ipsecSAInfoDestroy (sa_info);            return (OK);            }        total_packet_length = m->m_pkthdr.len;        if (m->m_len < total_packet_length)            {            if ((*pp_m = m_pullup (m, total_packet_length)) == 0)                {                ipsecPmtuMessageDelete (pmtu_message);                ipsecSAInfoDestroy (sa_info);                WRN_M_FREEM (m); /* drop the packet*/				wrSecTrace( TRACE_ALL, L1, "PACKET DROPPED!! 'function::%s'\n", __FUNCTION__);                return (ERROR);                }            }        icmp6 = (struct icmp6_hdr *) ((UCHAR *)ip6_hdr1 + offset);        offset += ICMP6_MINLEN;        ip6_hdr2 = (struct ip6_hdr *) ((UCHAR *)icmp6 + ICMP6_MINLEN);        ip6hdr2_len = sizeof (struct ip6_hdr);        complete_packet_len = ntohs (ip6_hdr2->ip6_plen);        next_protocol = ip6_hdr2->ip6_nxt;        pmtu_message->pmtu = ntohl (icmp6->icmp6_mtu) - packetBufReservedHeaderSizeGet();        WRSEC_INET6_SET_STRUCT_A_WITH_IN6_ADDR_B((*(WRSEC_INET6_ADDR *)sa_info->tunnel_endpoint),                                               ip6_hdr2->ip6_dst)        offset += ip6hdr2_len;        while (loop_continue)            {            p_extn_header = (UCHAR *)ip + offset;            switch (next_protocol)                {                case IPPROTO_HOPOPTS:                case IPPROTO_DSTOPTS:                case IPPROTO_ROUTING:                    /* The length feild in the case of routing ,hop by                             * hop ,destination extension headers is the header                            * length in 8-octet units,not counting the first 8                            * octets.                            */                    offset += 8 + 8 * (* (p_extn_header + 1));                    break;                case IPPROTO_FRAGMENT:                    /* The Length of the fragment header is 8 bytes */                    offset += 8;                    /* check if fragment offset is zero. */                    fragment_offset = *(p_extn_header + 2) << 5;                    fragment_offset |= *(p_extn_header + 3) >> 3;                    if (fragment_offset)                        {                        loop_continue = FALSE;                        }                    break;                default:                    loop_continue = FALSE;                }            if (loop_continue)                {                next_protocol = * (p_extn_header);                }            }        }    #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */    if (next_protocol == TRANSPORT_PROTO_AH)        {        UCHAR *ah_header;        /*         * IP1  ICMP IP2 AH/AH+ESP [IP3*] TCP* /UDP* /OTHERS*          * (*:may be encrypted)             */        ah_header = (UCHAR *)ip + offset;        status = ipsecPmtuAhMessageProcess (ah_header,    (total_packet_length - offset), complete_packet_len,                                            pmtu_message, sa_info);        }    else if (next_protocol == TRANSPORT_PROTO_ESP)        {        UCHAR *esp_header;        /*         * IP1  ICMP IP2 ESP [IP3*] TCP* /UDP* /OTHERS*          * (*:may be encrypted)             */        esp_header = (UCHAR *)ip + offset;        status = ipsecPmtuEspMessageProcess (esp_header,   (total_packet_length - offset), complete_packet_len,                                             pmtu_message, sa_info);        }    else        {        ipsecPmtuMessageDelete (pmtu_message);        ipsecSAInfoDestroy (sa_info);        return (OK);        }    if (status == OK)        {        /* We have found the destinataion. */        if (pmtu_message->transport == TRUE)            {            status = (ipsecPmtuTransportMessageProcess (m, pmtu_message));            }        else            {            status = ipsecPmtuForwardPmtuMessage (m, pmtu_message);            }        }    else        {        WRN_M_FREEM (m);		wrSecTrace( TRACE_ALL, L1, "PACKET DROPPED!! 'function::%s'\n", __FUNCTION__);        status = ERROR;        }    /* store PMTU information in the database */    if (ipsecPmtuStorePmtuInfo (pmtu_message, sa_info) == ERROR)        {        status = ERROR;        }    ipsecPmtuMessageDelete (pmtu_message);    ipsecSAInfoDestroy (sa_info);    return (status);    }/****************************************************************************** * ipsecPmtuStorePmtuInfo - stores the PMTU information in the database. *  * NOMANUAL * RETURNS : OK if the info has been stored or else ERROR. */LOCAL STATUS ipsecPmtuStorePmtuInfo    (    IPSEC_PMTU_MESSAGE *pmtu_message,    SA_BUNDLE_INFO *sa_info    )    {    UINT age;    if (sa_info->p_sa_bundle == NULL)        {        sa_info->p_sa_bundle = ipsecPmtuSaBundleFind (sa_info);        if (sa_info->p_sa_bundle == NULL)            {            return (ERROR);            }        }    age = ipsecPmtuAgeGet (sa_info->p_sa_bundle->p_reflected_address);    sa_info->p_sa_bundle->pmtu_age = age;    sa_info->p_sa_bundle->pmtu = pmtu_message->pmtu;    return (OK);    }/****************************************************************************** * ipsecPmtuAhMessageProcess - removes the ah header from the packet. *                     *  This function removes the ah header from the packet and bypasses it to the *  the upper layers if ah was applied to the packet in transport mode.In case *  of tunnel it removes the ah header and tunnel header.If the next header is *  a esp header then the packet is sent for furthur esp processing. * * NOMANUAL * * RETURNS : * OK : if the packet is to be bypassed to the upper layers or if all  *      the information necessary to send the PMTU message has been *      stored in IPSEC_PMTU_MESSAGE. * ERROR : if all the pmtu information could not be found . */LOCAL STATUS ipsecPmtuAhMessageProcess    (    UCHAR *bptr_ah_hdr, /* pointer to ah header */    int data_len,      /* pmtu payload length */    UINT complete_packet_len, /* packet length of original                                             packet */    IPSEC_PMTU_MESSAGE *pmtu_message, /* structure to store                                         pmtu info */    SA_BUNDLE_INFO *sa_info /* information to retrive SA from                                        database */    )    {    UCHAR next_protocol;    UCHAR *p_spi;    STATUS status;    USHORT ipsec_headers_length;    USHORT ah_header_len;    status = OK;    ipsec_headers_length = 0;    next_protocol = *bptr_ah_hdr;    /* The payoad length field provides the length of the      * authentication header in 32 bit words,not counting      * the first 8 octets.     */    ah_header_len = *(bptr_ah_hdr + 1) * 4 + 8;    p_spi = bptr_ah_hdr + 4;    sa_info->protocol = TRANSPORT_PROTO_AH;    sa_info->spi = wrSecDeserializeULong (&p_spi);    data_len -= ah_header_len;    complete_packet_len -= ah_header_len;    if (data_len <= 0)        {        sa_info->p_sa_bundle = ipsecPmtuSaBundleFind (sa_info);        if (sa_info->p_sa_bundle == NULL)            {            return (ERROR);            }        if (sa_info->p_sa_bundle->mode == TRANSPORT)            {            pmtu_message->transport = TRUE;            }        /* We dont have enough data to find the source of the original         * packet. Lets try to find from SA Bundle);         */        return ipsecPmtuDestinationFind (pmtu_message, sa_info->p_sa_bundle);        }    if (next_protocol == TRANSPORT_PROTO_ESP)        {        status = ipsecPmtuEspMessageProcess (bptr_ah_hdr + ah_header_len, data_len, complete_packet_len, pmtu_message,                                             sa_info);        }    else if ((next_protocol == TRANSPORT_PORTO_IP_IN_IP_IPV4) || (next_protocol == TRANSPORT_PROTO_IP_IN_IP_IPV6))        {        status = ipsecPmtuTunnelMessageProcess ((struct ip *) (bptr_ah_hdr + ah_header_len), data_len, pmtu_message,                                                sa_info);        }    else        {        UCHAR *data = bptr_ah_hdr + ah_header_len;        pmtu_message->ip_nxt_protocol = next_protocol;        pmtu_message->transport = TRUE;        status = ipsecPmtuDataCopy (pmtu_message, data, data_len);        }    return (status);    }/****************************************************************************** * ipsecPmtuEspMessageProcess - removes the esp header and decrypts packet. * * This function removes the esp header from the packet.If esp has been * applied in transport mode to the packet,then the packet is decrypted only * if we get the complete packet as the icmp pmtu payload.This is because, we * will not be having access to the next header field if we do not have the * esp trailer.  In case of tunnel mode is packet is always decrypted and sent * for furthur processing. * * RETURNS : * OK : if a pmtu message has been filled with all the information necessary  *      to send the PMTU message. *       * ERROR : if the sa bundle could not be found or if packet could not be * decrypted or if all the pmtu information could not be found. */LOCAL STATUS ipsecPmtuEspMessageProcess    (    UCHAR *bptr_esp_hdr, /* pointer to esp header */    int data_len,       /* pmtu payload length */    UINT complete_packet_len, /* packet length of the orginal                                             packet */    IPSEC_PMTU_MESSAGE *pmtu_message, /* structure to store pmtu info */    SA_BUNDLE_INFO *sa_info           /* info to retrieve sa from sadb */    )    {    UCHAR *bptr_decrypted_data;    SA_BUNDLE *p_sa_bundle;    USHORT decrypted_data_len;    UINT pad_len;    UCHAR next_header;    STATUS status;    status = OK;    if (sa_info->protocol != TRANSPORT_PROTO_AH)        {        UCHAR *p_spi = bptr_esp_hdr;        sa_info->spi = wrSecDeserializeULong ((UCHAR ** )&p_spi);        sa_info->protocol = TRANSPORT_PROTO_ESP;        }    p_sa_bundle = ipsecPmtuSaBundleFind (sa_info);    if (p_sa_bundle == NULL)        {        status = ERROR;        return (status);        }    sa_info->p_sa_bundle = p_sa_bundle;

⌨️ 快捷键说明

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