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

📄 ipsec_icmp_pmtu.c

📁 ipsec PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 4 页
字号:
            bcopy ((const char *)pmtu_message->data, (char *)p_transport, (int)pmtu_message->datalength);            icmp_len += pmtu_message->datalength;            }        m->m_len = icmp_len;        m->m_data = (char *)icmp4;        icmp4->icmp_type = ICMP_UNREACH;        icmp4->icmp_code = ICMP_UNREACH_NEEDFRAG;        icmp4->icmp_void = 0;        icmp4->icmp_nextmtu = htons (pmtu_message->pmtu);        icmp4->icmp_cksum = 0;        icmp4->icmp_cksum = in_cksum (m, icmp_len);        m->m_data -= MINIMUM_IP_V4_HEADER_LENGTH;        m->m_len = icmp_len + MINIMUM_IP_V4_HEADER_LENGTH;        m->m_pkthdr.len = m->m_len;        m->m_pkthdr.rcvif = (struct ifnet *)p_network_interface->sptr_ifnet;        m->m_flags |= M_PKTHDR;        s = splnet ();        sptr_ifnet = ipsec_get_ifnet_handle (pmtu_message->destination_address);        splx (s);        if (sptr_ifnet != NULL)            {            /* pmtu message destined to us,bypass it to upper layers */            ip4->ip_len = icmp_len;            #if STACK_NAME == STACK_NAME_V4_V6            icmp_input (m, MINIMUM_IP_V4_HEADER_LENGTH, IPPROTO_ICMP);            #else            icmp_input (m, MINIMUM_IP_V4_HEADER_LENGTH);            #endif /* STACK_NAME == STACK_NAME_V4_V6 */            m_freem (m_source);            return (ERROR);            }        ip4->ip_len = icmp_len + MINIMUM_IP_V4_HEADER_LENGTH;        bzero ((char *)&ro, sizeof (struct route));        (void)ip_output (m, NULL, &ro, 0, NULL);        m_freem (m_source);        }    #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)    else if (pmtu_message->family == WRSEC_AF_INET6)        {        struct ip6_hdr *ip6hdr;        struct icmp6_hdr *icmp6;        struct ifnet *outif;        int ip6hdr_len;        outif = NULL;        /* 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 ip6_hdr) + 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 = ICMP6_MINLEN + pmtu_message->datalength + (MINIMUM_IP_V6_HEADER_LENGTH);        MGET1 (m, mblk_size, M_WAIT, m_source->m_type);        if (m == NULL)            {            /* Store the PMTU Message */            WRN_M_FREEM (m_source);			wrSecTrace( TRACE_ALL, L1, "PACKET DROPPED!! 'function::%s'\n", __FUNCTION__);            return (ERROR);            }        ip6hdr = mtod (m, struct ip6_hdr *);        ip6hdr_len = MINIMUM_IP_V6_HEADER_LENGTH;        ip6hdr->ip6_flow = 0x00;        ip6hdr->ip6_vfc = IPV6_VERSION;        ip6hdr->ip6_hlim = IPV6_DEFHLIM;        ip6hdr->ip6_nxt = IPPROTO_ICMPV6;        WRSEC_INET6_SET_IN6_ADDR_A_WITH_STRUCT_B(ip6hdr->ip6_dst,                                               (*(WRSEC_INET6_ADDR *)pmtu_message->destination_address))        p_network_interface = ipsecFindNetworkInterfaceBasedOnIfnet (m_source->m_pkthdr.rcvif, WRSEC_AF_INET6);        if (p_network_interface == NULL)            {            return (ERROR);            }        WRSEC_INET6_SET_IN6_ADDR_A_WITH_STRUCT_B (            ip6hdr->ip6_src, (* ((WRSEC_INET6_ADDR *)p_network_interface->p_address)));        icmp_len = ICMP6_MINLEN;        if (pmtu_message->data != NULL)            {            UCHAR *p_transport = (UCHAR *)ip6hdr + MINIMUM_IP_V6_HEADER_LENGTH + ICMP6_MINLEN;            bcopy ((const char *)pmtu_message->data, (char *)p_transport, (int)pmtu_message->datalength);            icmp_len += pmtu_message->datalength;            }        icmp6 = (struct icmp6_hdr *) ((UCHAR *)ip6hdr + MINIMUM_IP_V6_HEADER_LENGTH);        icmp6->icmp6_type = ICMP6_PACKET_TOO_BIG;        icmp6->icmp6_code = 0;        icmp6->icmp6_mtu = 0;        icmp6->icmp6_mtu = htonl (pmtu_message->pmtu);        ip6hdr->ip6_plen = icmp_len;        m->m_len = icmp_len + ip6hdr_len;        m->m_pkthdr.len = m->m_len;        icmp6->icmp6_cksum = 0;        icmp6->icmp6_cksum = in6_cksum (m, IPPROTO_ICMPV6, ip6hdr_len, ip6hdr->ip6_plen);        m->m_pkthdr.rcvif = (struct ifnet *)p_network_interface->sptr_ifnet;        m->m_flags |= M_PKTHDR;        s = splnet ();        sptr_ifnet = ipsec_get_ifnet_handle (pmtu_message->destination_address);        splx (s);        if (sptr_ifnet != NULL)            {            /* pmtu message destined to us,bypass it to upper layers */            icmp6_input (&m, &ip6hdr_len, IPPROTO_ICMPV6);            m_freem (m_source);            return (ERROR);            }        ip6_output (m, NULL, NULL, 0, NULL, &outif);        m_freem (m_source);        }    #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */    return (ERROR);    }/****************************************************************************** * ipsecPmtuMessageCreate - creates the pmtu message information. * * NOMANUAL * * RETURNS : N/A */LOCAL void ipsecPmtuMessageCreate    (    IPSEC_PMTU_MESSAGE *pmtu_message, /* pmtu message */    WRSEC_INET_ADDR_FAMILY type         /* family type */    )    {    pmtu_message->family = type;    pmtu_message->transport = FALSE;    pmtu_message->data = NULL;    pmtu_message->datalength = 0;    pmtu_message->pmtu = 0;    pmtu_message->ip_nxt_protocol = 0;    pmtu_message->destination_address = wrSecInetAddrCreate(type);    }/****************************************************************************** * ipsecPmtuSaInfoCreate - creates the SA information. * * NOMANUAL * * RETURNS : N/A */LOCAL void ipsecPmtuSaInfoCreate    (    SA_BUNDLE_INFO *sa_info,  /* sa information */    WRSEC_INET_ADDR_FAMILY type /* family type */    )    {    sa_info->p_sa_bundle = NULL;    sa_info->spi = 0;    sa_info->protocol = 0;    sa_info->tunnel_endpoint = wrSecInetAddrCreate(type);    }/****************************************************************************** * ipsecPmtuMessageDelete - destroys the pmtu message information. * * * NOMANUAL * * RETURNS : N/A */LOCAL void ipsecPmtuMessageDelete    (    IPSEC_PMTU_MESSAGE *pmtu_message /* pmtu info */    )    {    if (pmtu_message->destination_address != NULL)        {        wrSecFree (pmtu_message->destination_address);        pmtu_message->destination_address = NULL;        }    if (pmtu_message->data != NULL)        {        wrSecFree (pmtu_message->data);        pmtu_message->data = NULL;        }    }/****************************************************************************** * ipsecSAInfoDestroy - destroys the SA information. * * NOMANUAL * * RETURNS : N/A */LOCAL void ipsecSAInfoDestroy    (    SA_BUNDLE_INFO *sa_info /* sa info */    )    {    if (sa_info->tunnel_endpoint != NULL)        {        wrSecFree (sa_info->tunnel_endpoint);        sa_info->tunnel_endpoint = NULL;        }    }/****************************************************************************** * ipsecPmtuSaBundleFind - finds an outbound sa with the with sa info  *                provided. * * NOMANUAL * RETURNS : pointer to the SA bundle or  NULL. */LOCAL SA_BUNDLE *ipsecPmtuSaBundleFind    (    SA_BUNDLE_INFO *sa_info /* info to retrieve sa bundle */    )    {    SA_BUNDLE *p_sa_bundle;    WRSEC_HASH_TABLE hashtable;    p_sa_bundle = NULL;    if (sa_info->protocol == TRANSPORT_PROTO_AH)        {        hashtable = sadb.p_ob_ah_sa_bundles;        }    else if (sa_info->protocol == TRANSPORT_PROTO_ESP)        {        hashtable = sadb.p_ob_esp_sa_bundles;        }    else        {        return NULL;   /* This should not happen */        }    p_sa_bundle = sadb_get_sa_from_ob_spi_container (sa_info->spi, hashtable, sa_info->tunnel_endpoint);    return (p_sa_bundle);    }/****************************************************************************** * ipsecPmtuSendPmtuMessage - sends a pmtu message back to the peer. * * This function sends a pmtu message back to the originator of the packet. *  * NOMANUAL  * RETUNRS : N/A. */void ipsecPmtuSendPmtuMessage    (    struct mbuf *m,       /* pmtu packet to be sent */    SA_BUNDLE *p_SAbundle /* bundle contianing PMTU info */    )    {    struct ip *ip;    IPSEC_PMTU_MESSAGE ipsec_pmtu_message;    IPSEC_PMTU_MESSAGE *pmtu_message = &ipsec_pmtu_message;    ip = mtod (m, struct ip *);    if (((struct ip *)ip)->ip_v == IP_V4)        {        /* initialize pmtu_mesage */        ipsecPmtuMessageCreate (pmtu_message, WRSEC_AF_INET4);        WRSEC_INET4_SET_STRUCT_A_WITH_IN_ADDR_B((*(WRSEC_INET4_ADDR *)pmtu_message->destination_address), ip->ip_src)        if (ip->ip_len > IPSEC_PMTU_MESSAGE_LENGTH)            {            pmtu_message->datalength = IPSEC_PMTU_MESSAGE_LENGTH;            }        else            {            pmtu_message->datalength = ip->ip_len;            }        ip->ip_len = htons(ip->ip_len);   /* FIXME: VXWORKS_6_X compile error */                pmtu_message->pmtu = p_SAbundle->pmtu;        if (ipsecPmtuDataCopy (pmtu_message, (UCHAR *)ip, pmtu_message->datalength) == ERROR)            {            ipsec_printf (IPSEC_ERROR_PRINTF, "IPSEC:PMTU:Tunnel:Unable to allocate memory\n");            return;            }        ipsecPmtuForwardPmtuMessage (m, pmtu_message);        ipsecPmtuMessageDelete (pmtu_message);        }    #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)    else if (((struct ip *)ip)->ip_v == IP_V6)        {        int ip6_hdrlen;        struct ip6_hdr *ip6 = mtod (m, struct ip6_hdr *);        ipsecPmtuMessageCreate (pmtu_message, WRSEC_AF_INET6);        ip6_hdrlen = ipsecIpv6HdrLenGet (m, NULL);        WRSEC_INET6_SET_STRUCT_A_WITH_IN6_ADDR_B((*(WRSEC_INET6_ADDR *)pmtu_message->destination_address),                                               ip6->ip6_src)        if ((ntohs (ip6->ip6_plen) + ip6_hdrlen) > IPSEC_PMTU_MESSAGE_LENGTH)            {            pmtu_message->datalength = IPSEC_PMTU_MESSAGE_LENGTH;            }        else            {            pmtu_message->datalength = ntohs (ip6->ip6_plen) + ip6_hdrlen;            }        pmtu_message->pmtu = p_SAbundle->pmtu;        if (ipsecPmtuDataCopy (pmtu_message, (UCHAR *)ip6, pmtu_message->datalength) == ERROR)            {            ipsec_printf (IPSEC_ERROR_PRINTF, "IPSEC:PMTU:Tunnel:Unable to allocate memory\n");            return;            }        ipsecPmtuForwardPmtuMessage (m, pmtu_message);        ipsecPmtuMessageDelete (pmtu_message);        }    #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */    }/****************************************************************************** * ipsecPmtuIsPacketBiggerThanPmtu - checks if the packet length is * bigger * than the PMTU stored in * the SA. * * This funciton checks if the packet length is bigger than the PMTU stored * in the SA. *  * NOMANUAL * RETUNRS : ERROR if the packet is bigger than the pmtu stored in the SA  *           else OK. */STATUS ipsecPmtuIsPacketBiggerThanPmtu    (    struct mbuf *m,      /* packet whose length is to be chacked */    SA_BUNDLE *pSABundle /* SA contining PMTU info */    )    {    STATUS status;    struct ip *ip;    UINT packetLength;    status = OK;    packetLength = 0;    ip = mtod (m, struct ip *);    if (((struct ip *)ip)->ip_v == IP_V4)        {        packetLength = ip->ip_len;        }    #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)    else if (((struct ip *)ip)->ip_v == IP_V6)        {        struct ip6_hdr *ip6 = mtod (m, struct ip6_hdr *);        packetLength = (ntohs (ip6->ip6_plen) + sizeof (struct ip6_hdr));        }    #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */    if (packetLength >= pSABundle->pmtu)        {        status = ERROR;        }    return (status);    }/******************************************************************************/

⌨️ 快捷键说明

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