LibIpv6_Interface_Functions.ttcn 24.8 KB
Newer Older
/*
 *	@author 	STF 276
 *  @version 	$Id$
 *	@desc		This module specifies functions definitions
 *              based on the IPv6 meta message type.  
 *  
 */
 module LibIpv6_Interface_Functions {

	//LibCommon
	import from LibCommon_BasicTypesAndValues all;
	import from LibCommon_DataStrings all;
	import from LibCommon_VerdictControl { type FncRetCode };
	//LibIpv6
	import from LibIpv6_Interface_TypesAndValues all;
	import from LibIpv6_Interface_Templates all;
	import from LibIpv6_ModuleParameters all;
	import from LibIpv6_ExternalFunctions all;
	import from LibIpv6_CommonRfcs_Functions all;
	import from LibIpv6_CommonRfcs_TypesAndValues all;
	
group rfc2460Root_Functions {
	
	group ipv6Packets {	

	/*
	 * @desc 	This sends a General IPv6 packet
	 *			from an IPv6 node to any NUT.
	 *			A General IPv6 packet is used in the case where only Extension headers
	 *			need to be sent.
	 * @remark  Time limit is defined by module parameter PX_TAC (see comp type)
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendGeneralIpv6(template Ipv6Packet p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var Ipv6Packet v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendGeneralIpv6: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendGeneralIpv6

	group extHdrFns {

	/*
	 * @desc 	This goes through the extension header list and calculates length, checksum
	 *			and other specific functions of the different extension headers
	 * @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_setExtensionHeaders(	inout ExtensionHeaderList p_extHdrList,
									in Ipv6Address p_srcAddr,
									in Ipv6Address p_dstAddr,
									in Ipv6Packet p_ipv6Packet)
	runs on LibIpv6Node
	return FncRetCode {
		var FncRetCode v_ret := e_success;
		var UInt8 i;
		var Ipv6Address v_homeAddress := c_16ZeroBytes;
		var UInt8 v_nrOfTunnelHdr := 0;
berge's avatar
berge committed
		var Ipv6Address v_pseudoSrcAddr := c_16ZeroBytes;
		var Ipv6Address v_pseudoDstAddr := c_16ZeroBytes;

		for (i:=0; i<sizeof(p_extHdrList);i:=i+1) {
			if (ischosen(p_extHdrList[i].mobileHeader)) {
berge's avatar
berge committed
				if (f_isPresentHomeAddressOption(p_extHdrList, v_homeAddress) == e_success) {//used in all packets that are sent to registered CN
					v_pseudoSrcAddr := v_homeAddress;
					v_pseudoDstAddr := p_dstAddr;
				}
				else if (f_isPresentRoutingHeaderType2(p_extHdrList, v_homeAddress) == e_success) {
berge's avatar
berge committed
					v_pseudoSrcAddr := p_srcAddr;					
					v_pseudoDstAddr := v_homeAddress;
				}
				else {
berge's avatar
berge committed
					v_pseudoSrcAddr := p_srcAddr;					
					v_pseudoDstAddr := p_dstAddr;
berge's avatar
berge committed
				
				v_ret := f_setMobileHeader(	p_srcAddr,
											p_dstAddr,
											v_pseudoSrcAddr,					
											v_pseudoDstAddr,
											p_extHdrList[i].mobileHeader);
			}
			else if (ischosen(p_extHdrList[i].tunneledIpv6)) {
				v_nrOfTunnelHdr := v_nrOfTunnelHdr + 1;
				p_extHdrList[i].tunneledIpv6.payloadLength := fx_tunnelledPayloadLength(p_ipv6Packet, v_nrOfTunnelHdr);
berge's avatar
berge committed
				
				// Tunneled header is the active packet
				p_srcAddr := p_extHdrList[i].tunneledIpv6.sourceAddress;
				p_dstAddr := p_extHdrList[i].tunneledIpv6.destinationAddress;

			}
		/*	else if (ischosen(p_extHdrList[i].)) {
			}  */
		}//end for

berge's avatar
berge committed
		return v_ret;
	}//end f_setExtensionHeaders
		
	}//end group extHdrFns


    } //end group ipv6Packets
	
}//end group rfc2460Root_Functions

group rfc3775Mipv6_ExtHdrFunctions {

	/*
	 * @desc 	This goes through the Mip header and calculates length, checksum
	 *			and other specific functions of the different messages.
	 *			This function is used when sending messages.
	 * @param 	p_msg ExtensionHeaderList to be treated	
	 * @return 	execution status 
	*/
berge's avatar
berge committed
	function f_setMobileHeader(	in Ipv6Address p_srcAddr,
								in Ipv6Address p_dstAddr,
								in Ipv6Address p_pseudoSrcAddr, 
								in Ipv6Address p_pseudoDstAddr, 	
								inout MobileHeader p_mobileHeader)
	runs on LibIpv6Node
	return FncRetCode {
		var MobileHeader v_mobileHeader := valueof(p_mobileHeader);
		var Ipv6Address v_homeAddress := c_16ZeroBytes ;

		//if (ischosen(p_mobileHeader.mobileMessage.homeTestInit)) {
			//calc homeInitCookie
			//p_mobileHeader.mobileMessage.homeTestInit.homeInitCookie := f_createInitCookie();
		//else if (ischosen(p_mobileHeader.mobileMessage.homeTest)) {//CNSimu sends this message
		//else if (ischosen(p_mobileHeader.mobileMessage.careOfTestInit) and (PX_TEST_IPSEC == true)) {
		//SMU TODO
		//}
		//else if (ischosen(p_mobileHeader.mobileMessage.careOfTest) and (PX_TEST_IPSEC == true)) {
		//SMU TODO
		//}
		if (ischosen(p_mobileHeader.mobileMessage.bindingUpdateMsg)) {//Authorization data is only needed for BU sent to CN=IUT
			var UInt8 v_position := 0;
			//Concept of including bindingAuthentication
			// specifiy on template level all options
			// 1) if authenticator == c_20ZeroBytes then value is calculated in f_setMobileHeader
			// 2) if authenticator != c_20ZeroBytes then no value is calculated in f_setMobileHeader,
			//     because it's assumed that the correct value was set on template level
			// 3) same applies to nonceIndex etc

			// TODO Check this 
			if (f_isPresentNonceIndices(p_mobileHeader.mobileMessage.bindingUpdateMsg, v_position) == e_success) {
				if(vc_mobileSec.mnSimuParams.receivedHomeNonceIndex != c_uInt16Zero
					and vc_mobileSec.mnSimuParams.receivedCareOfNonceIndex != c_uInt16Zero) {
						p_mobileHeader.mobileMessage.bindingUpdateMsg.mobileOptions[v_position].mobileOptNonceIndices.homeNonceIndex
						:= vc_mobileSec.mnSimuParams.receivedHomeNonceIndex;
						p_mobileHeader.mobileMessage.bindingUpdateMsg.mobileOptions[v_position].mobileOptNonceIndices.careOfNonceIndex
						:= vc_mobileSec.mnSimuParams.receivedCareOfNonceIndex;
					log("f_setMobileHeader: Error: NonceIndices included in Binding Update, but mnSimuParams.receivedCareOfNonceIndex/receivedHomeNonceIndex not initialized");
					return e_error;	
				}
			}	
			if (f_isPresentBindingAuthorizationDataOption(p_mobileHeader.mobileMessage.bindingUpdateMsg, v_position) == e_success) {
				if(vc_mobileSec.mnSimuParams.receivedHomeKeygenToken != c_64ZeroBits
					and vc_mobileSec.mnSimuParams.receivedCareOfKeygenToken != c_64ZeroBits) {
				
						if (p_mobileHeader.mobileMessage.bindingUpdateMsg.lifeTime != 0) {
							vc_mobileSec.mnSimuParams.kbm := fx_mac(		e_sha1, c_1ZeroByte,
																			bit2oct(vc_mobileSec.mnSimuParams.receivedHomeKeygenToken)
																			& bit2oct(vc_mobileSec.mnSimuParams.receivedCareOfKeygenToken));
						}
						else {
							vc_mobileSec.mnSimuParams.kbm := fx_mac(		e_sha1, c_1ZeroByte,
																			bit2oct(vc_mobileSec.mnSimuParams.receivedHomeKeygenToken));	
						}
berge's avatar
berge committed
											
						//set Authenticator option with dummy Authenticator
						p_mobileHeader.mobileMessage.bindingUpdateMsg.mobileOptions[v_position].mobileBindingAuthorizationData := {
														mobileOptType := 5,
														mobileOptLen := 12,
														authenticator := c_12ZeroBytes}
																		
						//calculate the mipHeaderLength over the dummy Authenticator
						p_mobileHeader.headerLen := fx_mipHeaderLength(p_mobileHeader) ;
						
						//set Authenticator to omit in order to calc the authenticator
						p_mobileHeader.mobileMessage.bindingUpdateMsg.mobileOptions[v_position].mobileBindingAuthorizationData.authenticator := omit;
berge's avatar
berge committed
						p_mobileHeader.mobileMessage.bindingUpdateMsg.mobileOptions[v_position].mobileBindingAuthorizationData.authenticator 
								 := fx_mac(	e_hmac_sha1_96, vc_mobileSec.mnSimuParams.kbm,
berge's avatar
berge committed
																		p_srcAddr //careOfaddr 
																		& p_dstAddr //cnAddr
					log("f_setMobileHeader: Error: BindingAuthorizationDataOption included in Binding Update, but receivedHomeKeygenToken/receivedCareOfKeygenToken not initialized");
					return e_error;	
				}
	//	else if (ischosen(p_mobileHeader.mobileMessage.bindingAck) and (PX_TEST_IPSEC == true)) {
		//SMU TODO
		//}
		
		// modified by AMB to easily send packets with wrong mobileHdrLen
		if (p_mobileHeader.headerLen == c_1ZeroByte ) {
			p_mobileHeader.headerLen := fx_mipHeaderLength(p_mobileHeader);
		}
		// modified by PK to easily send packets with wrong checksum
		//set mipChecksum to zero
		//p_mobileHeader.checksum := c_2ZeroBytes;  
berge's avatar
berge committed
		//calc mipChecksum only when its set to c_2ZeroBytes
		// do no calc mipChecksum , but use the checksum from the template
		if (p_mobileHeader.checksum == c_2ZeroBytes) {
berge's avatar
berge committed
			p_mobileHeader.checksum := fx_mipHeaderChecksum ( 	p_pseudoSrcAddr, 
																p_pseudoDstAddr, 
																p_mobileHeader);
berge's avatar
berge committed
		}
berge's avatar
berge committed
	function f_checkAuthenticator (	in Ipv6Address p_srcAddr,
									in Ipv6Address p_dstAddr,
									in MobileHeader p_mobileHeader,
									in octetstring p_receivedAuthenticator)
	runs on LibIpv6Node 
	return FncRetCode {
		var UInt8 v_position := 0;
		var octetstring v_computedAuthenticator;
		
		if (f_isPresentBindingAuthorizationDataOption(p_mobileHeader.mobileMessage.bindingUpdateMsg, v_position) == e_success) {
				
			p_mobileHeader.checksum := c_2ZeroBytes;			
				
berge's avatar
berge committed
			if (p_mobileHeader.mobileMessage.bindingUpdateMsg.lifeTime != 0) {
				vc_mobileSec.cnSimuParams.kbm := fx_mac(		e_sha1, c_1ZeroByte,
																bit2oct(vc_mobileSec.cnSimuParams.homeKeygenToken)
																& bit2oct(vc_mobileSec.cnSimuParams.careOfKeygenToken));
			}
			else {
				vc_mobileSec.cnSimuParams.kbm := fx_mac(		e_sha1, c_1ZeroByte,
																bit2oct(vc_mobileSec.cnSimuParams.homeKeygenToken));	
			}
									
			//set Authenticator option with dummy Authenticator
			p_mobileHeader.mobileMessage.bindingUpdateMsg.mobileOptions[v_position].mobileBindingAuthorizationData := {
											mobileOptType := 5,
											mobileOptLen := 12,
											authenticator := c_12ZeroBytes}
																
			//calculate the mipHeaderLength over the dummy Authenticator
			p_mobileHeader.headerLen := fx_mipHeaderLength(p_mobileHeader) ;
				
			//set Authenticator to omit in order to calc the authenticator
			p_mobileHeader.mobileMessage.bindingUpdateMsg.mobileOptions[v_position].mobileBindingAuthorizationData.authenticator := omit;
		
			v_computedAuthenticator := fx_mac(	e_hmac_sha1_96, vc_mobileSec.cnSimuParams.kbm,
												p_srcAddr //careOfaddr 
												& p_dstAddr //cnAddr
												& fx_mipHdrToOct(p_mobileHeader) );
												
			if (p_receivedAuthenticator != v_computedAuthenticator) {
				return e_error;
			}
			
			return e_success;	
		}
		else {
			log("f_checkAuthenticator: Error: This packet does not contain any Binding Update");
			return e_error;
		}
	} //end function f_checkAuthenticator


		/*
	 * @desc 	This goes through the BindingUpdate and
	 *			checks if a NonceIndicesOption is present.
	 * @param 	p_bindingUpdate Binding Update to be treated
	 * @param 	v_position Position of the NonceIndicesOption in the MobileOptionList
	 * @return 	execution status 
	*/
mullers's avatar
mullers committed
	function f_isPresentNonceIndices(	in BindingUpdateMsg p_bindingUpdate,
														inout UInt8 v_position)
	runs on LibIpv6Node
	return FncRetCode {
		var FncRetCode v_ret := e_error;
		var UInt8 i;

		//select ext hdrs that need special calculation
		for (i:=0; i<sizeof(p_bindingUpdate.mobileOptions) and (v_ret != e_success); i:=i+1) {
			if (ischosen(p_bindingUpdate.mobileOptions[i].mobileOptNonceIndices)) {
					v_position := i;
					v_ret := e_success;
				}
		}
		return v_ret;
	}//end function f_isPresentNonceIndices

	/*
	 * @desc 	This goes through the BindingUpdate and
	 *			checks if a AuthorizationDataOption is present.
	 * @param 	p_bindingUpdate Binding Update to be treated
	 * @param 	v_position Position of the AuthorizationDataOption in the MobileOptionList
	 * @return 	execution status 
	*/
mullers's avatar
mullers committed
	function f_isPresentBindingAuthorizationDataOption(	in BindingUpdateMsg p_bindingUpdate,
														inout UInt8 v_position)
	runs on LibIpv6Node
	return FncRetCode {
		var FncRetCode v_ret := e_error;
		var UInt8 i;

		//select ext hdrs that need special calculation
		for (i:=0; i<sizeof(p_bindingUpdate.mobileOptions) and (v_ret != e_success); i:=i+1) {
			if (ischosen(p_bindingUpdate.mobileOptions[i].mobileBindingAuthorizationData)) {
					v_position := i;
					v_ret := e_success;
				}
		}
		return v_ret;
	}//end function f_isPresentBindingAuthorizationDataOption
mullers's avatar
mullers committed

	/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - Binding Update
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendBU(template BindingUpdate p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var BindingUpdate v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendBU: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendBU

	/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - Binding Acknowledgement
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendBA(template BindingAcknowledgement p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var BindingAcknowledgement v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendBA: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendBA

	/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - Binding Error
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendBE(template BindingError p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var BindingError v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendBE: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendBE

	/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - Binding Refresh Request
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendBR(template BindingRefreshRequest p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var BindingRefreshRequest v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendBR: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendBR

	/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - Home Test
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendHot(template HomeTest p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var HomeTest v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendHot: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendHot

		/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - Home Test Init
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendHoti(template HomeTestInit p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var HomeTestInit v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendHoti: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendHoti

	/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - CareOfTestInit
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendCoti(template CareOfTestInit p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var CareOfTestInit v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendCoti: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendCoti

		/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - CareOfTest
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendCot(template CareOfTest p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var CareOfTest v_ipPkt;
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendCoti: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendCot

			/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - Fast Nbr Adv
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendFastNbrAdv(template FastNeighborAdvertisement p_msg)
mullers's avatar
mullers committed
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
mullers's avatar
mullers committed
		v_ipPkt := valueof(p_msg);
		//set extensionHeaders
		if (ispresent(v_ipPkt.extHdrList)) {
			if(f_setExtensionHeaders(	v_ipPkt.extHdrList,
										v_ipPkt.ipv6Hdr.sourceAddress,
										v_ipPkt.ipv6Hdr.destinationAddress,
										v_ipPkt) != e_success) {
				log(" **** f_sendFastNbrAdv: Error when calculating length of extension headers ****");
				return e_error;
			}
		}
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendFastNbrAdv

	



	
}//end group rfc3775Mipv6_ExtHdrFunctions


group rfc4303Esp_ExtHdrFunctions {
	
mullers's avatar
mullers committed
	function f_init_ipSecParams()
	runs on LibIpv6Node {
		
mullers's avatar
mullers committed
		var FncRetCode v_ret := e_error;

		vc_sad[0] := {
mullers's avatar
mullers committed
			spi := 0/*f_createSpi()*/,
mullers's avatar
mullers committed
			seqNr := c_uInt32Zero,
			// AH Integrity
			ahIntegrityAlgo := PX_INTEGRITY_ALGO,
mullers's avatar
mullers committed
			ahIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			// ESP encryption
			espEncryptionAlgo := PX_ENCRYPTION_ALGO,
mullers's avatar
mullers committed
			espEncryptionKey := PX_ESP_ENCR_KEY/*f_createSecretKey()*/,
			// ESP integrity
			espIntegrityAlgo := PX_INTEGRITY_ALGO,
mullers's avatar
mullers committed
			espIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			// Combined mode
			espCombinedModeAlgo := PX_COMBINED_MODE_ALGO,
mullers's avatar
mullers committed
			espCombinedModeKey := PX_COMBINED_MODE_KEY/*f_createSecretKey()*/,
			// Protocol mode
			ipSecProtocolMode := PX_IP_SEC_PROTOCOL_MODE
		}
mullers's avatar
mullers committed

		//TODO chose in function of PX_SPI the SAD to be used for testing
		v_ret := fx_setSecurityParameters(vc_sad[0]);
		if (v_ret != e_success) {log("fx_setSecurityParameters: Error when settign security parameters");}
mullers's avatar
mullers committed
	}//end f_init_ipSecParams


	/*
	 * @desc 	This generates Security Parameters Index
	 * @return 	Security Parameters Index
	*/
	function f_createSpi()
	runs on LibIpv6Node
	return UInt32 {
		var Oct4 v_spi := int2oct(float2int(int2float(20000-5000)*rnd())+5000, 4);

		return oct2int(v_spi);
	}//end f_createSpi

	/*
	 * @desc 	This generates a secret key
	 * @return 	Secret key
	*/
	function f_createSecretKey()
	runs on LibIpv6Node
	return octetstring {
		var Oct20 v_key := int2oct(float2int(int2float(20000-5000)*rnd())+5000, 20);

		return v_key;
	}//end f_createSecretKey

mullers's avatar
mullers committed
//	function f_buildEspExtHdr(	
//			in Sa p_sa,
//			in PlaintextData p_plaintextData,
//			out ExtensionHeader p_extensionHeader)
//	runs on LibIpv6Node
//	return FncRetCode {
//		// Variables
//		var EncryptResult v_encryptResult;
///		var IntegrityResult v_integrityResult;
//		var FncRetCode v_ret := e_error;
//		var octetstring v_padding := c_1ZeroByte;
//TODO check this
/*
		// Encrypt espPayloadData
		v_ret := fx_encrypt(	p_sa.ipSecProtocolMode,
								p_sa.espEncryptionAlgo,
								p_sa.espEncryptionKey,
								p_plaintextData,
								v_encryptResult);
		if ( v_ret != e_success ) {return v_ret;}
	
		// Fill EspExtHdr
		var EspHeader v_espHdr := valueof(m_espHdr_dummy);
		// Header
		v_espHdr.securityParametersIndex := p_sa.securityParametersIndex;
		v_espHdr.sequenceNumber := p_sa.sequenceNumber;
		// Payload
		if (ispresent(v_encryptResult.iv)) {
			v_espHdr.iv := v_encryptResult.iv;
		}
		// Encrypted payload is assigend for integrity calculation.
		// Afterwards plaintext will be assigned
		v_espHdr.espPayloadData.ciphertextData := v_encryptResult.ciphertextData;
		if (ispresent(v_encryptResult.tfcPadding)) {
			v_espHdr.tfcPadding := v_encryptResult.tfcPadding;
		}
		// Byte Align
		v_ret := fx_byteAlignEspHeader(4, v_espHdr, v_padding);
		if ( v_ret != e_success ) {return v_ret;}

		if (v_padding != c_1ZeroByte) {
			v_espHdr.padding := v_padding;
			v_espHdr.padLength := lengthof(v_padding);
		}

		// Integrity
		v_ret := fx_macEspHdr(	p_sa.espIntegrityAlgo,
									p_sa.espIntegrityKey,
									v_espHdr,
									v_integrityResult);
		if ( v_ret != e_success ) {return v_ret;}
		if (ispresent(v_integrityResult.icv)) {
			v_espHdr.icv := v_integrityResult.icv;
		}

		// Assign Plaintext EspPayload
		v_espHdr.espPayloadData.plaintextData := p_plaintextData;
		p_extensionHeader := {espHeader := v_espHdr};
mullers's avatar
mullers committed
*/
//		return e_success;
mullers's avatar
mullers committed
//	}//end function f_buildEspExtHdr	
	
}//end group rfc4303Esp_ExtHdrFunctions

	
} // end module LibIpv6_Interface_Functions