📄 ipsec_ipv6_utilities.c
字号:
/* ipsec_ipv6_utilities.c - utlity routines for getting ipv6 header info *//******************************************************************************//* Copyright 2000-2001 Wind River Systems, Inc. *//******************************************************************************//*modification history--------------------02b,12may05,??? Added return value to fix compiler warning02a,11nov04,msa Removed dead code.01i,08jul04,jfb Rebased from ipsec-nortel_fuzzy_bunny_slippers-int.cg01h,12jun03,rparkhil added support for STACK_NAME01g,25Apr03,sam(teamf1) added missing function header.01f,24apr03,sam(teamf1) code cleanup.01f,05mar03,mhb(teamf1) added break in the switch in ipsec_ipv6_extns_get_fragment_header.01e,13jan03,mhb(teamf1) fixed DIAB compilation error.01d,10jan03,mhb(teamf1) added the function ipsecIpv6ExtnsFragmentHdrGet01c,07Jan03,mhb(teamf1) changed vxworks.h to vxWorks.h in includes for Solaris build01b,11nov02,mhb(teamf1) fixed endian related bugs.01a,7Sep02,rks(teamf1) written *//*DESCRIPTIONThis file has the utility routines for traversing the ipv6 packet and getting the lengths of the headers,pointers to the headers and protocol types of theheaders following the ipv6 header.*//* include files */#include "vxWorks.h"#include <netinet/in.h>#include "ipsecP.h"#include "ipsec_print_routines.h"#if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)#include "ipsec_ipv6_utilities.h"LOCAL UCHAR *mbufDataPtrAtOffset ( struct mbuf *m, int offset );/******************************************************************************* mbufDataPtrAtOffset - sets the mbuf data and length pointer to the offset* specified.* This routine sets the mbuf data and length pointer to the offset specified.** NOMANUAL** RETURNS : byte pointer to the offset in the mbuf data.*/LOCAL UCHAR *mbufDataPtrAtOffset ( struct mbuf *m, /* pointer to mbuf */ int offset /* offset */ ) { while (m) { if (offset >= m->m_len) { m = m->m_next; offset -= m->m_len; } else return ((UCHAR *)m->m_data + offset); } ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: offset outside of mbuf in \func mbufDataPtrAtOffset\n"); return NULL; }/******************************************************************************* ipsecIpv6HdrLenGet - gets the total length of the ipv6 header. * * This routine gets the length of the extension header (prior to* AH,ESP,Transport protocol headers). The hdrlen calculation is required by* build_traffic_info function to pull ip+tcp header into a single mbuf. * * NOMANUAL** RETURNS : ipv6 header length.*/int ipsecIpv6HdrLenGet ( struct mbuf *m, /* pointer to mbuf */ struct ip6_hdr *ip6 /* ipv6 header */ ) { char *p_nxt_hdr; int nxt_hdr; int ip6_hlen; int ip6_hlen_max; int ext_hlen; int hdr_len_calculation_done; if (ip6 == NULL) { ip6 = (struct ip6_hdr *)m->m_data; } ip6_hlen = sizeof (struct ip6_hdr); nxt_hdr = ip6->ip6_nxt; p_nxt_hdr = (char *)(ip6)+ip6_hlen; ip6_hlen_max = sizeof (struct ip6_hdr) + ntohs (ip6->ip6_plen); hdr_len_calculation_done = 0; while ((!hdr_len_calculation_done) && ip6_hlen < ip6_hlen_max) { switch (nxt_hdr) { case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: case IPPROTO_ROUTING: if (m != NULL) { nxt_hdr = *(mbufDataPtrAtOffset (m, ip6_hlen)); /* 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. */ ext_hlen = (8 + ((*(mbufDataPtrAtOffset (m, ip6_hlen + 1))) * 8)); } else { nxt_hdr = *(p_nxt_hdr); ext_hlen = 8 + (*(p_nxt_hdr + 1)) * 8; } break; case IPPROTO_FRAGMENT: /* The Length of the fragment header is 8 bytes */ ext_hlen = 8; hdr_len_calculation_done = 1; break; case IPPROTO_AH: case IPPROTO_ESP: default: ext_hlen = 0; hdr_len_calculation_done = 1; } p_nxt_hdr += ext_hlen; ip6_hlen += ext_hlen; } return ip6_hlen; }/******************************************************************************* ipsecIpv6ExtnHdrLenGet - gets the length of the ipv6 extension headers.** Gets the length of the ipv6 extension headers.** NOMANUAL** RETURNS : length of the extension headers.**/int ipsecIpv6ExtnHdrLenGet ( struct ip6_hdr *ip6 /* ipv6 header */ ) { char *p_nxt_hdr; int nxt_hdr; int ip6_hlen; int ip6_hlen_max; int ext_hlen; int hdr_len_calculation_done; UCHAR second_dst_opt = 0; nxt_hdr = ip6->ip6_nxt; p_nxt_hdr = (char *)(ip6)+sizeof (struct ip6_hdr); ip6_hlen_max = sizeof (struct ip6_hdr) + ntohs (ip6->ip6_plen); hdr_len_calculation_done = 0; ip6_hlen = 0; while ((!hdr_len_calculation_done) && ip6_hlen < ip6_hlen_max) { switch (nxt_hdr) { case IPPROTO_DSTOPTS: if (second_dst_opt) { ext_hlen = 0; hdr_len_calculation_done = 1; break; } second_dst_opt = 1; case IPPROTO_HOPOPTS: case IPPROTO_ROUTING: nxt_hdr = *(p_nxt_hdr); /* 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. */ ext_hlen = (8 + (*(p_nxt_hdr + 1)) * 8); break; case IPPROTO_FRAGMENT: /* The Length of the fragment header is 8 bytes */ ext_hlen = 8; hdr_len_calculation_done = 1; break; case IPPROTO_AH: case IPPROTO_ESP: default: ext_hlen = 0; hdr_len_calculation_done = 1; break; } p_nxt_hdr += ext_hlen; ip6_hlen += ext_hlen; } return ip6_hlen; }/******************************************************************************* ipsecIpv6ExtnsNextHdrSet - This sets the next header field of the extension * header.* The next header field of the extension header is set to the next_hdr value* which is sent as the third argument.* * NOMANUAL * * RETURNS : N/A*/void ipsecIpv6ExtnsNextHdrSet ( UCHAR first_hdr, UCHAR *p_extn_hdr, UCHAR next_hdr, USHORT extns_tot_len ) { USHORT ext_hlen = 0; USHORT len = 0; UCHAR nxt_hdr = first_hdr; /* find last extension header */ while (1) { switch (nxt_hdr) { 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. */ ext_hlen = (8 + (*(p_extn_hdr + 1)) * 8); break; case IPPROTO_FRAGMENT: /* The Length of the fragment header is 8 bytes */ ext_hlen = 8; break; case IPPROTO_AH: case IPPROTO_ESP: default: ipsec_printf (IPSEC_WARNING_PRINTF, "IPSEC: Unexpected extension header !!\n"); return; } len += ext_hlen; if (len >= extns_tot_len) { break; } nxt_hdr = *(p_extn_hdr); p_extn_hdr += ext_hlen; } *(p_extn_hdr) = next_hdr; }/******************************************************************************* ipsecIpv6ExtnsTransportProtocolFind - gets the transport protocol from * the packet. ** This function iterates through all the extension headers and finds the * transport protocol from the last extension header.** NOMANUAL** RETURNS : N/A*/int ipsecIpv6ExtnsTransportProtocolFind ( UCHAR first_hdr, UCHAR *p_extns ) { USHORT ext_hlen = 0; UCHAR nxt_hdr = first_hdr; /* find last extension header */ while (1) { switch (nxt_hdr) { 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. */ ext_hlen = (8 + (*(p_extns + 1)) * 8); break; case IPPROTO_FRAGMENT: /* The Length of the fragment header is 8 bytes */ ext_hlen = 8; break; case IPPROTO_AH: case IPPROTO_ESP: default: return nxt_hdr; } nxt_hdr = *(p_extns); p_extns += ext_hlen; } /* code is not expected to reach here */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -