Commit 967f5b36 authored by berge's avatar berge
Browse files

Changed f_setExtensionHeader(), added some comments.

Removed f_setAuthHeader().
parent a4730941
Loading
Loading
Loading
Loading
+116 −138
Original line number Diff line number Diff line
@@ -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;
@@ -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)) {
@@ -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,
@@ -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; 
					}
@@ -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;
					}
				}
@@ -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
@@ -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