LibIpv6_Interface_Functions.ttcn 43.3 KB
Newer Older
	 *			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(f_setExtensionHeaders(	v_ipPkt ) != e_success) {
			log(" **** f_sendCoti: Error when calculating length of extension headers ****");
			return e_error;
		}

		//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)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var FastNeighborAdvertisement v_ipPkt;
		v_ipPkt := valueof(p_msg);

		//set extensionHeaders
		if(f_setExtensionHeaders(	v_ipPkt ) != e_success) {
			log(" **** f_sendFastNbrAdv: Error when calculating length of extension headers ****");
			return e_error;
		}

		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendFastNbrAdv

}//end group rfc3775Mipv6_ExtHdrFunctions


group rfc4303Esp_ExtHdrFunctions {
	
	/*
	 * @desc 	Rebuild original packet from an ESP packet (removes ESP encapsulation)
	 * @param 	p_ipv6Packet complete packet containing ESP Header to be processed
	 * @param   p_espHeader ESP Header to be processed
	 * @param   p_originalIpv6Packet retrieved original packet 
	 * @return 	execution status 
	*/
	function f_getOriginalIpv6Packet(	in Ipv6Packet p_ipv6Packet,
										in EspHeader p_espHeader,
										out Ipv6Packet p_originalIpv6Packet)
	runs on LibIpv6Node
	return FncRetCode {
		var UInt8 i;
		var boolean v_loop := true;

		if (not(ispresent(p_espHeader.espPayload.espIpDatagram.extHdrList))
			and not(ispresent(p_espHeader.espPayload.espIpDatagram.ipv6Payload))) {
				log("**** f_getOriginalIpv6Packet: EspHeader.espPayload.espIpDatagram received that does neither contain extHdrList not ipv6Payload => EspHeader is not constructed correctly ****")	;			
				return e_error;
		}

		//Build original packet
		p_originalIpv6Packet.ipv6Hdr := p_ipv6Packet.ipv6Hdr;
		p_originalIpv6Packet.ipv6Hdr.nextHeader := p_espHeader.nextHeader;
		
		if (ispresent(p_espHeader.espPayload.espIpDatagram.extHdrList)) {
			p_originalIpv6Packet.extHdrList := p_espHeader.espPayload.espIpDatagram.extHdrList;
		}
		if (ispresent(p_espHeader.espPayload.espIpDatagram.ipv6Payload)) {
			p_originalIpv6Packet.ipv6Payload := p_espHeader.espPayload.espIpDatagram.ipv6Payload;
		}

		// is a tunneledIpv6Hdr in the extHdrList? If yes, then it becomes the Ipv6Hdr of the original packet
		if (ispresent(p_espHeader.espPayload.espIpDatagram.extHdrList)) {
			for (i:=0; i<sizeof(p_espHeader.espPayload.espIpDatagram.extHdrList) and v_loop ;i:=i+1) {
				if (ischosen(p_espHeader.espPayload.espIpDatagram.extHdrList[i].tunneledIpv6)) {
					p_originalIpv6Packet.ipv6Hdr := p_espHeader.espPayload.espIpDatagram.extHdrList[i].tunneledIpv6;
					v_loop := false;
				}
				else {
					p_originalIpv6Packet.extHdrList[i] := p_espHeader.espPayload.espIpDatagram.extHdrList[i];	
				}
			}
		}

		p_originalIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (p_originalIpv6Packet);

		return e_success;

	}//end f_getOriginalIpv6Packet
	
	/*
	 * @desc 	
	 *			This function is used to retrieve the index
	 *          within the SecurityAssociationList corresponding
	 *          to the given SPI.
	 *
	 * @param 	p_sad SecurityAssociationList to be treated	
	 * @param   p_spi SPI used to search for the list index
	 * @param   p_idx Index of the SA corresponding to p_spi
	 * @return 	execution status 
	*/
	function f_getSaBySpi(in Sad p_sad, in integer p_spi, out integer p_idx) 
	return FncRetCode {
		var integer i := 0;
		for (i:=0; i<sizeof(p_sad); i:=i+1) {
			if (p_sad[i].spi == p_spi) {
				p_idx := i;
				return e_success;
			}
		}
		log("**** f_getSaBySpi: Could not find SPI! ****")	;			
		
		return e_error;
	}
	
}//end group rfc4303Esp_ExtHdrFunctions

group rfc791RootFns {
	
	/*
	 * @desc  	This sends an ICMPv4 packet from an dual stack IPv4/IPv6 node to 
	 *          any NUT. Prior it modifies
	 *			IPv6 packet payload length and ICMPv6 checksum
	 *			IPv4 packet payload length (totalLength field in IPv4 header) and ICMPv4 checksum
	 *			to their correct values using external functions.
	 * @remark  The template passed in must NOT contain any matching expressions!
	 * @param 	p_ipv4Packet Ipv4 packet value or template with echo request to be sent
	 * @return 	execution status
	*/
	function f_sendIpv4Packet (in template Ipv4Packet p_ipv4Packet) 
	runs on LibIpv6Node
	return FncRetCode {
		var Ipv4Packet v_ipPkt;
		v_ipPkt := valueof(p_ipv4Packet);

		if (ispresent(v_ipPkt.ipv4Payload)) {
			//Build IPv6 Packet
		 	if(ischosen(v_ipPkt.ipv4Payload.ipv6Packet)) {
				if(f_setExtensionHeaders(v_ipPkt.ipv4Payload.ipv6Packet) != e_success) {
					log(" **** f_sendIpv4Packet: Error when building IPv6Packet ****");
					return e_error;
				}
			}
			else if(ischosen(v_ipPkt.ipv4Payload.ipv4EchoRequestMsg)) {
				v_ipPkt.ipv4Payload.ipv4EchoRequestMsg.checksum := fx_calcIpv4PayloadChecksum (
					v_ipPkt.ipv4Payload
				);
			}
			else if(ischosen(v_ipPkt.ipv4Payload.ipv4EchoReplyMsg)) {
				v_ipPkt.ipv4Payload.ipv4EchoReplyMsg.checksum := fx_calcIpv4PayloadChecksum (
					v_ipPkt.ipv4Payload
				);
			}
		}

		//Build IPv4 Packet
		//IHL is set in templates
		// Update the total length					
		v_ipPkt.ipv4Hdr.totalLength := fx_ipv4PacketTotalLength (v_ipPkt);

		// Compute header checksum (HCS)
		v_ipPkt.ipv4Hdr.hcs := fx_calcIpv4Hcs (
			v_ipPkt.ipv4Hdr
		);
		
		//send
		ipv4Port.send(v_ipPkt);
	
		return e_success;
	
	}//end f_sendIpv4Packet
	
}//end rfc791RootFns

	
} // end module LibIpv6_Interface_Functions