Loading ttcn3/EtsiLibrary/LibIpv6/LibCommonRfcs/LibIpv6_Interface_Functions.ttcn +116 −138 Original line number Diff line number Diff line Loading @@ -69,12 +69,13 @@ group rfc2460Root_Functions { return FncRetCode { var FncRetCode v_ret := e_success; var UInt8 i, j; var Ipv6Address v_homeAddress := c_16ZeroBytes; var UInt8 v_nrOfTunnelHdr := 0; var UInt8 v_authHdrIndex := 0; var UInt8 v_spi := 0; var Ipv6Address v_pseudoSrcAddr := c_16ZeroBytes; var Ipv6Address v_pseudoDstAddr := c_16ZeroBytes; var boolean v_loop := true; var Ipv6Packet v_pseudoIpv6Packet; var Ipv6Packet v_innerIpv6Packet; var Ipv6Packet v_tempIpv6Packet; var Ipv6Packet v_activeIpv6Packet := p_ipv6Packet; v_pseudoDstAddr := v_activeIpv6Packet.ipv6Hdr.destinationAddress; Loading @@ -85,10 +86,19 @@ group rfc2460Root_Functions { v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); } // Browse the differents extension headers and search for specific fields to be computed if (ispresent(v_activeIpv6Packet.extHdrList)) { for (i:=0; i<sizeof(v_activeIpv6Packet.extHdrList) and v_loop ;i:=i+1) { for (i:=0; v_loop and i<sizeof(v_activeIpv6Packet.extHdrList) ;i:=i+1) { // Authentication Header has to be processed only when all the other fields are correct // Only the first auth header will be processed if (ischosen(v_activeIpv6Packet.extHdrList[i].authHeader) and v_authHdrIndex == 0) { // Remember to process this auth header later v_authHdrIndex := i; } // Process Home Address Destination Option, non-recursive // Change the pseudo-source address if (ischosen(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader)) { for (j:=0; j<sizeof(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader.destOptionList);j:=j+1) { if (ischosen(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader.destOptionList[j].homeAddressOption)) { Loading @@ -96,13 +106,18 @@ group rfc2460Root_Functions { } } } // Proccess Routing Header Type 2, non-recursive // Change the pseudo-destination address else if (ischosen(v_activeIpv6Packet.extHdrList[i].routingHeader) and (v_activeIpv6Packet.extHdrList[i].routingHeader.routingType == c_routeHdrType2)) { if (ischosen(v_activeIpv6Packet.extHdrList[i].routingHeader.routingHeaderData.rtHdrDataHomeAddress)) { v_pseudoDstAddr := v_activeIpv6Packet.extHdrList[i].routingHeader.routingHeaderData.rtHdrDataHomeAddress; } } // Process Mobile Header, non-recursive // Compute Mip header length and checksum, and some other mip specific fields // Update global packet's payload length else if (ischosen(v_activeIpv6Packet.extHdrList[i].mobileHeader)) { v_ret := f_setMobileHeader( v_activeIpv6Packet.ipv6Hdr.sourceAddress, v_activeIpv6Packet.ipv6Hdr.destinationAddress, Loading @@ -113,42 +128,51 @@ group rfc2460Root_Functions { // update packet payloadLen v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); } // Process Tunneled Header, recursive // Recursively process the tunneled packet. // Outter packet has to be updated once the recursion call returns else if (ischosen(v_activeIpv6Packet.extHdrList[i].tunneledIpv6)) { v_nrOfTunnelHdr := v_nrOfTunnelHdr + 1; //Build original packet v_pseudoIpv6Packet.ipv6Hdr := v_activeIpv6Packet.extHdrList[i].tunneledIpv6; // extract inner packet v_innerIpv6Packet.ipv6Hdr := v_activeIpv6Packet.extHdrList[i].tunneledIpv6; for (j:=0; (i+j+1)<sizeof(v_activeIpv6Packet.extHdrList) ;j:=j+1) { v_pseudoIpv6Packet.extHdrList[j] := v_activeIpv6Packet.extHdrList[i+1]; v_innerIpv6Packet.extHdrList[j] := v_activeIpv6Packet.extHdrList[i+1]; } if (ispresent(v_activeIpv6Packet.ipv6Payload)) { v_pseudoIpv6Packet.ipv6Payload := v_activeIpv6Packet.ipv6Payload; v_innerIpv6Packet.ipv6Payload := v_activeIpv6Packet.ipv6Payload; } v_pseudoIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_pseudoIpv6Packet); // recursive call, original packet can still contain other headers f_setExtensionHeaders( v_pseudoIpv6Packet ); //Update the original packet v_pseudoIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_pseudoIpv6Packet); // recursive call, inner packet can still contain other headers f_setExtensionHeaders( v_innerIpv6Packet ); // include recursion results v_activeIpv6Packet.extHdrList[i].tunneledIpv6.payloadLength := v_pseudoIpv6Packet.ipv6Hdr.payloadLength; if (ispresent(v_pseudoIpv6Packet.extHdrList)) { for (j:=0; j<sizeof(v_pseudoIpv6Packet.extHdrList) ;j:=j+1) { v_activeIpv6Packet.extHdrList[i+1] := v_pseudoIpv6Packet.extHdrList[j]; // include recursion results into the active packet v_activeIpv6Packet.extHdrList[i].tunneledIpv6.payloadLength := v_innerIpv6Packet.ipv6Hdr.payloadLength; if (ispresent(v_innerIpv6Packet.extHdrList)) { for (j:=0; j<sizeof(v_innerIpv6Packet.extHdrList) ;j:=j+1) { v_activeIpv6Packet.extHdrList[i+1] := v_innerIpv6Packet.extHdrList[j]; } } if (ispresent(v_pseudoIpv6Packet.ipv6Payload)) { v_activeIpv6Packet.ipv6Payload := v_pseudoIpv6Packet.ipv6Payload; if (ispresent(v_innerIpv6Packet.ipv6Payload)) { v_activeIpv6Packet.ipv6Payload := v_innerIpv6Packet.ipv6Payload; } // Update the active packet v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); // Stop processing extension headers : // the remaining extension headers belong to the inner packet, // and have already been processed by the recursive call v_loop := false; } // Process ESP Header, recursive // Build the orignal, ESP-less, inner packet and process it recursively // Active packet has to be updated once the recursion call returns else if (ischosen(v_activeIpv6Packet.extHdrList[i].espHeader)) { //set IV // set IV if needed. // Payload length may change. if (vc_sad[v_activeIpv6Packet.extHdrList[i].espHeader.spi].espEncryptionAlgo == e_encr_null) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.iv := omit; } Loading @@ -156,26 +180,33 @@ group rfc2460Root_Functions { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.iv := int2oct(128, f_getEncryptionIvLen(vc_sad[v_activeIpv6Packet.extHdrList[i].espHeader.spi].espEncryptionAlgo)); } //Update the original packet v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); v_ret := f_getOriginalIpv6Packet( v_activeIpv6Packet, v_activeIpv6Packet.extHdrList[i].espHeader, v_pseudoIpv6Packet); v_pseudoIpv6Packet.ipv6Hdr.destinationAddress := v_pseudoDstAddr; v_pseudoIpv6Packet.ipv6Hdr.sourceAddress := v_pseudoSrcAddr; v_innerIpv6Packet); v_innerIpv6Packet.ipv6Hdr.destinationAddress := v_pseudoDstAddr; v_innerIpv6Packet.ipv6Hdr.sourceAddress := v_pseudoSrcAddr; if (v_ret == e_success) { f_setExtensionHeaders( v_pseudoIpv6Packet ); // include recursion results if (ispresent(v_pseudoIpv6Packet.extHdrList)) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.espIpDatagram.extHdrList := v_pseudoIpv6Packet.extHdrList // recursive call, inner packet can still contain other headers f_setExtensionHeaders( v_innerIpv6Packet ); // include recursion results into the active packet if (ispresent(v_innerIpv6Packet.extHdrList)) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.espIpDatagram.extHdrList := v_innerIpv6Packet.extHdrList } if (ispresent(v_pseudoIpv6Packet.ipv6Payload)) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.espIpDatagram.ipv6Payload := v_pseudoIpv6Packet.ipv6Payload; if (ispresent(v_innerIpv6Packet.ipv6Payload)) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.espIpDatagram.ipv6Payload := v_innerIpv6Packet.ipv6Payload; } // Update the active packet v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); // Stop processing extension headers : // the remaining extension headers belong to the inner packet, // and have already been processed by the recursive call v_loop := false; } } Loading @@ -185,6 +216,8 @@ group rfc2460Root_Functions { // all extension headers have been processed // Is there still a payload to be processed and which has not been already processed in a recursive call? if (v_loop==true and ispresent(v_activeIpv6Packet.ipv6Payload)) { // IKE message specific processing if(ischosen(v_activeIpv6Packet.ipv6Payload.ikeMsg)) { if(v_activeIpv6Packet.ipv6Payload.ikeMsg.msgLength == 0) { //calc payloadLen of UDP msg Loading @@ -193,113 +226,58 @@ group rfc2460Root_Functions { + lengthof(fx_ikePayloadListToOct(v_activeIpv6Packet.ipv6Payload.ikeMsg.payloadList)); } } v_ret := f_calcIpv6PayloadChecksum(v_pseudoSrcAddr, v_pseudoDstAddr, v_activeIpv6Packet.ipv6Payload); } v_ret := f_setAuthHeader (v_activeIpv6Packet); p_ipv6Packet := v_activeIpv6Packet; return v_ret; }//end f_setExtensionHeaders /* * @desc This goes through the extension header list and looks for * Authentication Header to compute ICV. * Only 1 Authentication Header is processed * @param p_srcAddr Source Address of IPv6 packet * @param p_dstAddr Dst Address of IPv6 packet * @param p_extHdrList Extension Header List * @return execution status */ function f_setAuthHeader( inout Ipv6Packet p_ipv6Packet) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret := e_success; var UInt8 i, j; var boolean v_loop := true; var Ipv6Packet v_pseudoIpv6Packet; var Ipv6Packet v_activeIpv6Packet := p_ipv6Packet; if (ispresent(v_activeIpv6Packet.extHdrList)) { for (i:=0; i<sizeof(v_activeIpv6Packet.extHdrList) and v_loop ;i:=i+1) { // Process Home Address Destination Option, predictable field if (ischosen(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader)) { for (j:=0; j<sizeof(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader.destOptionList);j:=j+1) { if (ischosen(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader.destOptionList[j].homeAddressOption)) { //TODO } } } // Proccess Routing Header Type 2, predictable field else if (ischosen(v_activeIpv6Packet.extHdrList[i].routingHeader) and (v_activeIpv6Packet.extHdrList[i].routingHeader.routingType == c_routeHdrType2)) { if (ischosen(v_activeIpv6Packet.extHdrList[i].routingHeader.routingHeaderData.rtHdrDataHomeAddress)) { //TODO } } // Process Tunneled Header, recursive else if (ischosen(v_activeIpv6Packet.extHdrList[i].tunneledIpv6)) { //Build original packet v_pseudoIpv6Packet.ipv6Hdr := v_activeIpv6Packet.extHdrList[i].tunneledIpv6; for (j:=0; (i+j+1)<sizeof(v_activeIpv6Packet.extHdrList) ;j:=j+1) { v_pseudoIpv6Packet.extHdrList[j] := v_activeIpv6Packet.extHdrList[i+1]; } if (ispresent(v_activeIpv6Packet.ipv6Payload)) { v_pseudoIpv6Packet.ipv6Payload := v_activeIpv6Packet.ipv6Payload; // Compute payload checksum (Icmpv6, UDP, ...) v_ret := f_calcIpv6PayloadChecksum(v_pseudoSrcAddr, v_pseudoDstAddr, v_activeIpv6Packet.ipv6Payload); } // recursive call, original packet can still contain Auth header f_setAuthHeader( v_pseudoIpv6Packet ); v_loop := false; } // Process Authentication Header Header else if (ischosen(v_activeIpv6Packet.extHdrList[i].authHeader)) { // Proccess Authentication, non-recursive // Compute ICV and ICV-Padding if ( v_authHdrIndex<sizeof(v_activeIpv6Packet.extHdrList) and ischosen(v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader)) { //Set Dummy ICV of correct length if (vc_sad[c_saOut].icvLen == 0) { p_ipv6Packet.extHdrList[i].authHeader.icv := omit; v_spi := v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.securityParametersIndex; if (vc_sad[v_spi].icvLen == 0) { v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icv := omit; } else { p_ipv6Packet.extHdrList[i].authHeader.icv := int2oct(0, vc_sad[c_saOut].icvLen); v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icv := int2oct(0, vc_sad[v_spi].icvLen); } // Check ICV padding if (vc_sad[c_saOut].icvPadLen == 0) { p_ipv6Packet.extHdrList[i].authHeader.icvPadding := omit; if (vc_sad[v_spi].icvPadLen == 0) { v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icvPadding := omit; } else { p_ipv6Packet.extHdrList[i].authHeader.icvPadding := int2oct(0, vc_sad[c_saOut].icvPadLen); v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icvPadding := int2oct(0, vc_sad[v_spi].icvPadLen); } // Update AuthHeader payloadLen p_ipv6Packet.extHdrList[i].authHeader.payloadLen := (12 + vc_sad[c_saOut].icvLen + vc_sad[c_saOut].icvPadLen) / 4 - 2; v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.payloadLen := (12 + vc_sad[v_spi].icvLen + vc_sad[v_spi].icvPadLen) / 4 - 2; //Update IPv6 payload based on the calculated ICV + padding p_ipv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (p_ipv6Packet); v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (p_ipv6Packet); //compute icv if (vc_sad[v_spi].icvLen != 0) { // work on a temporary copy in order to be able to zero mutable fields v_tempIpv6Packet := v_activeIpv6Packet; v_activeIpv6Packet := p_ipv6Packet; //zero mutable fields v_activeIpv6Packet.ipv6Hdr.flowLabel := 0; v_activeIpv6Packet.ipv6Hdr.hopLimit := 0; v_tempIpv6Packet.ipv6Hdr.flowLabel := 0; v_tempIpv6Packet.ipv6Hdr.hopLimit := 0; //compute icv if (vc_sad[c_saOut].icvLen != 0) { p_ipv6Packet.extHdrList[i].authHeader.icv := fx_mac( vc_sad[c_saOut].ahIntegrityAlgo , vc_sad[c_saOut].ahIntegrityKey, fx_encodeMessage(v_activeIpv6Packet)); // Compute ICV v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icv := fx_mac( vc_sad[v_spi].ahIntegrityAlgo , vc_sad[v_spi].ahIntegrityKey, fx_encodeMessage(v_tempIpv6Packet)); } v_loop := false; } }//end for } return v_ret; p_ipv6Packet := v_activeIpv6Packet; }//end f_setAuthHeader return v_ret; }//end f_setExtensionHeaders }//end group extHdrFns Loading Loading
ttcn3/EtsiLibrary/LibIpv6/LibCommonRfcs/LibIpv6_Interface_Functions.ttcn +116 −138 Original line number Diff line number Diff line Loading @@ -69,12 +69,13 @@ group rfc2460Root_Functions { return FncRetCode { var FncRetCode v_ret := e_success; var UInt8 i, j; var Ipv6Address v_homeAddress := c_16ZeroBytes; var UInt8 v_nrOfTunnelHdr := 0; var UInt8 v_authHdrIndex := 0; var UInt8 v_spi := 0; var Ipv6Address v_pseudoSrcAddr := c_16ZeroBytes; var Ipv6Address v_pseudoDstAddr := c_16ZeroBytes; var boolean v_loop := true; var Ipv6Packet v_pseudoIpv6Packet; var Ipv6Packet v_innerIpv6Packet; var Ipv6Packet v_tempIpv6Packet; var Ipv6Packet v_activeIpv6Packet := p_ipv6Packet; v_pseudoDstAddr := v_activeIpv6Packet.ipv6Hdr.destinationAddress; Loading @@ -85,10 +86,19 @@ group rfc2460Root_Functions { v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); } // Browse the differents extension headers and search for specific fields to be computed if (ispresent(v_activeIpv6Packet.extHdrList)) { for (i:=0; i<sizeof(v_activeIpv6Packet.extHdrList) and v_loop ;i:=i+1) { for (i:=0; v_loop and i<sizeof(v_activeIpv6Packet.extHdrList) ;i:=i+1) { // Authentication Header has to be processed only when all the other fields are correct // Only the first auth header will be processed if (ischosen(v_activeIpv6Packet.extHdrList[i].authHeader) and v_authHdrIndex == 0) { // Remember to process this auth header later v_authHdrIndex := i; } // Process Home Address Destination Option, non-recursive // Change the pseudo-source address if (ischosen(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader)) { for (j:=0; j<sizeof(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader.destOptionList);j:=j+1) { if (ischosen(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader.destOptionList[j].homeAddressOption)) { Loading @@ -96,13 +106,18 @@ group rfc2460Root_Functions { } } } // Proccess Routing Header Type 2, non-recursive // Change the pseudo-destination address else if (ischosen(v_activeIpv6Packet.extHdrList[i].routingHeader) and (v_activeIpv6Packet.extHdrList[i].routingHeader.routingType == c_routeHdrType2)) { if (ischosen(v_activeIpv6Packet.extHdrList[i].routingHeader.routingHeaderData.rtHdrDataHomeAddress)) { v_pseudoDstAddr := v_activeIpv6Packet.extHdrList[i].routingHeader.routingHeaderData.rtHdrDataHomeAddress; } } // Process Mobile Header, non-recursive // Compute Mip header length and checksum, and some other mip specific fields // Update global packet's payload length else if (ischosen(v_activeIpv6Packet.extHdrList[i].mobileHeader)) { v_ret := f_setMobileHeader( v_activeIpv6Packet.ipv6Hdr.sourceAddress, v_activeIpv6Packet.ipv6Hdr.destinationAddress, Loading @@ -113,42 +128,51 @@ group rfc2460Root_Functions { // update packet payloadLen v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); } // Process Tunneled Header, recursive // Recursively process the tunneled packet. // Outter packet has to be updated once the recursion call returns else if (ischosen(v_activeIpv6Packet.extHdrList[i].tunneledIpv6)) { v_nrOfTunnelHdr := v_nrOfTunnelHdr + 1; //Build original packet v_pseudoIpv6Packet.ipv6Hdr := v_activeIpv6Packet.extHdrList[i].tunneledIpv6; // extract inner packet v_innerIpv6Packet.ipv6Hdr := v_activeIpv6Packet.extHdrList[i].tunneledIpv6; for (j:=0; (i+j+1)<sizeof(v_activeIpv6Packet.extHdrList) ;j:=j+1) { v_pseudoIpv6Packet.extHdrList[j] := v_activeIpv6Packet.extHdrList[i+1]; v_innerIpv6Packet.extHdrList[j] := v_activeIpv6Packet.extHdrList[i+1]; } if (ispresent(v_activeIpv6Packet.ipv6Payload)) { v_pseudoIpv6Packet.ipv6Payload := v_activeIpv6Packet.ipv6Payload; v_innerIpv6Packet.ipv6Payload := v_activeIpv6Packet.ipv6Payload; } v_pseudoIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_pseudoIpv6Packet); // recursive call, original packet can still contain other headers f_setExtensionHeaders( v_pseudoIpv6Packet ); //Update the original packet v_pseudoIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_pseudoIpv6Packet); // recursive call, inner packet can still contain other headers f_setExtensionHeaders( v_innerIpv6Packet ); // include recursion results v_activeIpv6Packet.extHdrList[i].tunneledIpv6.payloadLength := v_pseudoIpv6Packet.ipv6Hdr.payloadLength; if (ispresent(v_pseudoIpv6Packet.extHdrList)) { for (j:=0; j<sizeof(v_pseudoIpv6Packet.extHdrList) ;j:=j+1) { v_activeIpv6Packet.extHdrList[i+1] := v_pseudoIpv6Packet.extHdrList[j]; // include recursion results into the active packet v_activeIpv6Packet.extHdrList[i].tunneledIpv6.payloadLength := v_innerIpv6Packet.ipv6Hdr.payloadLength; if (ispresent(v_innerIpv6Packet.extHdrList)) { for (j:=0; j<sizeof(v_innerIpv6Packet.extHdrList) ;j:=j+1) { v_activeIpv6Packet.extHdrList[i+1] := v_innerIpv6Packet.extHdrList[j]; } } if (ispresent(v_pseudoIpv6Packet.ipv6Payload)) { v_activeIpv6Packet.ipv6Payload := v_pseudoIpv6Packet.ipv6Payload; if (ispresent(v_innerIpv6Packet.ipv6Payload)) { v_activeIpv6Packet.ipv6Payload := v_innerIpv6Packet.ipv6Payload; } // Update the active packet v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); // Stop processing extension headers : // the remaining extension headers belong to the inner packet, // and have already been processed by the recursive call v_loop := false; } // Process ESP Header, recursive // Build the orignal, ESP-less, inner packet and process it recursively // Active packet has to be updated once the recursion call returns else if (ischosen(v_activeIpv6Packet.extHdrList[i].espHeader)) { //set IV // set IV if needed. // Payload length may change. if (vc_sad[v_activeIpv6Packet.extHdrList[i].espHeader.spi].espEncryptionAlgo == e_encr_null) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.iv := omit; } Loading @@ -156,26 +180,33 @@ group rfc2460Root_Functions { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.iv := int2oct(128, f_getEncryptionIvLen(vc_sad[v_activeIpv6Packet.extHdrList[i].espHeader.spi].espEncryptionAlgo)); } //Update the original packet v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); v_ret := f_getOriginalIpv6Packet( v_activeIpv6Packet, v_activeIpv6Packet.extHdrList[i].espHeader, v_pseudoIpv6Packet); v_pseudoIpv6Packet.ipv6Hdr.destinationAddress := v_pseudoDstAddr; v_pseudoIpv6Packet.ipv6Hdr.sourceAddress := v_pseudoSrcAddr; v_innerIpv6Packet); v_innerIpv6Packet.ipv6Hdr.destinationAddress := v_pseudoDstAddr; v_innerIpv6Packet.ipv6Hdr.sourceAddress := v_pseudoSrcAddr; if (v_ret == e_success) { f_setExtensionHeaders( v_pseudoIpv6Packet ); // include recursion results if (ispresent(v_pseudoIpv6Packet.extHdrList)) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.espIpDatagram.extHdrList := v_pseudoIpv6Packet.extHdrList // recursive call, inner packet can still contain other headers f_setExtensionHeaders( v_innerIpv6Packet ); // include recursion results into the active packet if (ispresent(v_innerIpv6Packet.extHdrList)) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.espIpDatagram.extHdrList := v_innerIpv6Packet.extHdrList } if (ispresent(v_pseudoIpv6Packet.ipv6Payload)) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.espIpDatagram.ipv6Payload := v_pseudoIpv6Packet.ipv6Payload; if (ispresent(v_innerIpv6Packet.ipv6Payload)) { v_activeIpv6Packet.extHdrList[i].espHeader.espPayload.espIpDatagram.ipv6Payload := v_innerIpv6Packet.ipv6Payload; } // Update the active packet v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (v_activeIpv6Packet); // Stop processing extension headers : // the remaining extension headers belong to the inner packet, // and have already been processed by the recursive call v_loop := false; } } Loading @@ -185,6 +216,8 @@ group rfc2460Root_Functions { // all extension headers have been processed // Is there still a payload to be processed and which has not been already processed in a recursive call? if (v_loop==true and ispresent(v_activeIpv6Packet.ipv6Payload)) { // IKE message specific processing if(ischosen(v_activeIpv6Packet.ipv6Payload.ikeMsg)) { if(v_activeIpv6Packet.ipv6Payload.ikeMsg.msgLength == 0) { //calc payloadLen of UDP msg Loading @@ -193,113 +226,58 @@ group rfc2460Root_Functions { + lengthof(fx_ikePayloadListToOct(v_activeIpv6Packet.ipv6Payload.ikeMsg.payloadList)); } } v_ret := f_calcIpv6PayloadChecksum(v_pseudoSrcAddr, v_pseudoDstAddr, v_activeIpv6Packet.ipv6Payload); } v_ret := f_setAuthHeader (v_activeIpv6Packet); p_ipv6Packet := v_activeIpv6Packet; return v_ret; }//end f_setExtensionHeaders /* * @desc This goes through the extension header list and looks for * Authentication Header to compute ICV. * Only 1 Authentication Header is processed * @param p_srcAddr Source Address of IPv6 packet * @param p_dstAddr Dst Address of IPv6 packet * @param p_extHdrList Extension Header List * @return execution status */ function f_setAuthHeader( inout Ipv6Packet p_ipv6Packet) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret := e_success; var UInt8 i, j; var boolean v_loop := true; var Ipv6Packet v_pseudoIpv6Packet; var Ipv6Packet v_activeIpv6Packet := p_ipv6Packet; if (ispresent(v_activeIpv6Packet.extHdrList)) { for (i:=0; i<sizeof(v_activeIpv6Packet.extHdrList) and v_loop ;i:=i+1) { // Process Home Address Destination Option, predictable field if (ischosen(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader)) { for (j:=0; j<sizeof(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader.destOptionList);j:=j+1) { if (ischosen(v_activeIpv6Packet.extHdrList[i].destinationOptionHeader.destOptionList[j].homeAddressOption)) { //TODO } } } // Proccess Routing Header Type 2, predictable field else if (ischosen(v_activeIpv6Packet.extHdrList[i].routingHeader) and (v_activeIpv6Packet.extHdrList[i].routingHeader.routingType == c_routeHdrType2)) { if (ischosen(v_activeIpv6Packet.extHdrList[i].routingHeader.routingHeaderData.rtHdrDataHomeAddress)) { //TODO } } // Process Tunneled Header, recursive else if (ischosen(v_activeIpv6Packet.extHdrList[i].tunneledIpv6)) { //Build original packet v_pseudoIpv6Packet.ipv6Hdr := v_activeIpv6Packet.extHdrList[i].tunneledIpv6; for (j:=0; (i+j+1)<sizeof(v_activeIpv6Packet.extHdrList) ;j:=j+1) { v_pseudoIpv6Packet.extHdrList[j] := v_activeIpv6Packet.extHdrList[i+1]; } if (ispresent(v_activeIpv6Packet.ipv6Payload)) { v_pseudoIpv6Packet.ipv6Payload := v_activeIpv6Packet.ipv6Payload; // Compute payload checksum (Icmpv6, UDP, ...) v_ret := f_calcIpv6PayloadChecksum(v_pseudoSrcAddr, v_pseudoDstAddr, v_activeIpv6Packet.ipv6Payload); } // recursive call, original packet can still contain Auth header f_setAuthHeader( v_pseudoIpv6Packet ); v_loop := false; } // Process Authentication Header Header else if (ischosen(v_activeIpv6Packet.extHdrList[i].authHeader)) { // Proccess Authentication, non-recursive // Compute ICV and ICV-Padding if ( v_authHdrIndex<sizeof(v_activeIpv6Packet.extHdrList) and ischosen(v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader)) { //Set Dummy ICV of correct length if (vc_sad[c_saOut].icvLen == 0) { p_ipv6Packet.extHdrList[i].authHeader.icv := omit; v_spi := v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.securityParametersIndex; if (vc_sad[v_spi].icvLen == 0) { v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icv := omit; } else { p_ipv6Packet.extHdrList[i].authHeader.icv := int2oct(0, vc_sad[c_saOut].icvLen); v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icv := int2oct(0, vc_sad[v_spi].icvLen); } // Check ICV padding if (vc_sad[c_saOut].icvPadLen == 0) { p_ipv6Packet.extHdrList[i].authHeader.icvPadding := omit; if (vc_sad[v_spi].icvPadLen == 0) { v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icvPadding := omit; } else { p_ipv6Packet.extHdrList[i].authHeader.icvPadding := int2oct(0, vc_sad[c_saOut].icvPadLen); v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icvPadding := int2oct(0, vc_sad[v_spi].icvPadLen); } // Update AuthHeader payloadLen p_ipv6Packet.extHdrList[i].authHeader.payloadLen := (12 + vc_sad[c_saOut].icvLen + vc_sad[c_saOut].icvPadLen) / 4 - 2; v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.payloadLen := (12 + vc_sad[v_spi].icvLen + vc_sad[v_spi].icvPadLen) / 4 - 2; //Update IPv6 payload based on the calculated ICV + padding p_ipv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (p_ipv6Packet); v_activeIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (p_ipv6Packet); //compute icv if (vc_sad[v_spi].icvLen != 0) { // work on a temporary copy in order to be able to zero mutable fields v_tempIpv6Packet := v_activeIpv6Packet; v_activeIpv6Packet := p_ipv6Packet; //zero mutable fields v_activeIpv6Packet.ipv6Hdr.flowLabel := 0; v_activeIpv6Packet.ipv6Hdr.hopLimit := 0; v_tempIpv6Packet.ipv6Hdr.flowLabel := 0; v_tempIpv6Packet.ipv6Hdr.hopLimit := 0; //compute icv if (vc_sad[c_saOut].icvLen != 0) { p_ipv6Packet.extHdrList[i].authHeader.icv := fx_mac( vc_sad[c_saOut].ahIntegrityAlgo , vc_sad[c_saOut].ahIntegrityKey, fx_encodeMessage(v_activeIpv6Packet)); // Compute ICV v_activeIpv6Packet.extHdrList[v_authHdrIndex].authHeader.icv := fx_mac( vc_sad[v_spi].ahIntegrityAlgo , vc_sad[v_spi].ahIntegrityKey, fx_encodeMessage(v_tempIpv6Packet)); } v_loop := false; } }//end for } return v_ret; p_ipv6Packet := v_activeIpv6Packet; }//end f_setAuthHeader return v_ret; }//end f_setExtensionHeaders }//end group extHdrFns Loading