/* * @author STF 276 * @version $Id$ * @desc This module specifies common ICMP messages * interchanges (= operations) for an Ipv6 test component * Functions do not set a test component verdict but instead * use the function return value instead to notify the function * caller about the success of the operation. * */ module LibIpv6_Rfc2463Icmpv6_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_Functions all; import from LibIpv6_Interface_Templates all; import from LibIpv6_CommonRfcs_TypesAndValues all; import from LibIpv6_CommonRfcs_Functions all; import from LibIpv6_ModuleParameters all ; import from LibIpv6_ExternalFunctions all; import from LibIpv6_Rfc2463Icmpv6_Templates all; import from LibIpv6_Rfc2463Icmpv6_TypesAndValues all; /* * @desc This sends an ICMPv6 echo request from an IPv6 node to * any NUT. Prior it modifies IPv6 packet payload length * and ICMPv6 checksum to their correct values using external * functions. * @remark The template passed in must NOT contain any matching expressions! * @param p_echoRequest Ipv6 packet value or template with echo request to be sent * @return execution status */ function f_sendEchoRequest (in template EchoRequest p_echoRequest) runs on LibIpv6Node return FncRetCode { var EchoRequest v_ipPkt; v_ipPkt := valueof(p_echoRequest); if(f_setExtensionHeaders( v_ipPkt ) != e_success) { log(" **** f_sendEchoRequest: Error when calculating length of extension headers ****"); return e_error; } //send ipPort.send(v_ipPkt); return e_success; }//end f_sendEchoRequest /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any NUT. * Prior it modifies IPv6 packet payload length and ICMPv6 checksum * to their correct values using external functions * @remark The template passed in must NOT contain any matching expressions! * @param p_echoReply Ipv6 packet value or template with echo reply to be sent * @return execution status */ function f_sendEchoReply (in template EchoReply p_echoReply) runs on LibIpv6Node return FncRetCode { var EchoReply v_ipPkt; v_ipPkt := valueof(p_echoReply); if(f_setExtensionHeaders( v_ipPkt ) != e_success) { log(" **** f_sendEchoReply: Error when calculating length of extension headers ****"); return e_error; } //send ipPort.send(v_ipPkt); return e_success; }//end f_sendEchoReply /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any NUT, * and waits for any ICMP packet for a fixed amount of time. * @remark Time limit is defined by module parameter PX_TAC (see comp type) * @param p_hops Number of hops to be used in IPv6 header * @param p_llaAddrTn Local link address of testing node which calls this function * @param p_llaAddrNut Local link address of node under test * @param p_ipPkt ICMPv6 packet which has been received * @return execution status */ function f_getIpPktAfterEchoReq( in UInt8 p_hops, in template Ipv6Address p_llaAddrTn, in template Ipv6Address p_llaAddrNut, out Ipv6Packet p_ipPkt) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret; v_ret := f_sendEchoRequest ( m_echoRequest_noExtHdr_noData_hop ( p_llaAddrTn, p_llaAddrNut, p_hops, c_defId, c_defSeqNo ) ); if ( v_ret != e_success ) {return v_ret;} tc_ac.start; alt { [] ipPort.receive(mw_ipPkt) -> value p_ipPkt { tc_ac.stop; return e_success; } [] tc_ac.timeout{ return e_timeout; } } // end alt } // end f_getIcmpAfterEchoReq /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any NUT, * and waits for a Time Exceeded message for a fixed amount of time. * @remark Time limit is defined by module parameter PX_TAC (see comp type) * @param p_hops Number of hops to be used in IPv6 header * @param p_llaAddrTn Local link address of testing node which calls this function * @param p_llaAddrNut Local link address of node under test * @param p_llaAddrRut Local link address of router under test * @return execution status */ function f_getTimeExceededAfterEchoReq( in UInt8 p_hops, in template Ipv6Address p_llaAddrTn, in template Ipv6Address p_llaAddrNut, in template Ipv6Address p_llaAddrRut) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret; v_ret := f_sendEchoRequest ( m_echoRequest_noExtHdr_noData_hop ( p_llaAddrTn, p_llaAddrNut, p_hops, c_defId, c_defSeqNo ) ); if ( v_ret != e_success ) {return v_ret;} tc_ac.start; alt { [] ipPort.receive(mw_timeExceeded_noExtHdr ( p_llaAddrRut, p_llaAddrTn, c_icmpCode0 )) { tc_ac.stop; return e_success; } [] tc_ac.timeout{ return e_timeout; } } // end alt } // end f_getTimeExceedAfterEchoReq /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any NUT, * and waits for a Packet Too Big message for a fixed amount of time. * @remark Time limit is defined by module parameter PX_TAC (see comp type) * @param p_echoRequest Template of the Echo Request to be sent * @param p_packetTooBig Template of the Packet Too Big message that is expected * @return execution status */ function f_getPacketTooBigAfterEchoReq ( template EchoRequest p_echoRequest, template PacketTooBig p_packetTooBig ) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret; v_ret := f_sendEchoRequest ( p_echoRequest ); if ( v_ret != e_success ) {return v_ret;} tc_ac.start; alt { [] ipPort.receive ( p_packetTooBig ) { tc_ac.stop; return e_success; } [] tc_ac.timeout{ return e_timeout; } } // end alt } // end f_getPacketTooBigAfterEchoReq /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any NUT, * and waits for a Destination Unreachable message for a fixed amount of time. * @remark Time limit is defined by module parameter PX_TAC (see comp type) * @param p_echoRequest Template of the Echo Request to be sent * @param p_destUnreachable Template of the Packet Too Big message that is expected * @return execution status */ function f_getDestinationUnreachableAfterEchoReq ( template EchoRequest p_echoRequest, template DestinationUnreachable p_destUnreachable ) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret; v_ret := f_sendEchoRequest ( p_echoRequest ); if ( v_ret != e_success ) {return v_ret;} tc_ac.start; alt { [] ipPort.receive ( p_destUnreachable ) { tc_ac.stop; return e_success; } [] tc_ac.timeout{ return e_timeout; } } // end alt } // end f_getDestinationUnreachableAfterEchoReq /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any * NUT, and waits for a echo reply for a fixed amount of time. * This function can be used to verify that the NUT is * up and running. * @remark Time limit is defined by module parameter PX_TAC (see comp type) * @param p_llaAddrTn Local link address of testing node which calls this function * @param p_llaAddrNut Local link address of node under test * @param p_identifier Idenitifier to be used in ICMPv6 echo request * @param p_seqNo Sequence number to be used in ICMPv6 echo request * @param p_icmpPkt IPv6 packet which has been received * @return execution status */ function f_echoProcUp( in template Ipv6Address p_llaAddrTn, in template Ipv6Address p_llaAddrNut, in UInt16 p_identifier, in UInt16 p_seqNo, out EchoReply p_icmpPkt) runs on LibIpv6Node return FncRetCode { var EchoReply v_echoRep; var FncRetCode v_ret; v_ret := f_sendEchoRequest( m_echoRequest_noExtHdr_noData( p_llaAddrTn, p_llaAddrNut, p_identifier, p_seqNo )); if ( v_ret != e_success ) {return v_ret;} tc_ac.start; alt { [] ipPort.receive(mw_echoReply ( p_llaAddrNut, p_llaAddrTn )) -> value v_echoRep { p_icmpPkt := v_echoRep ; tc_ac.stop; return e_success; } [] tc_ac.timeout{ return e_timeout; } } // end alt } // end f_echoProcUp /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any NUT, * and waits for a echo reply for a fixed amount of time. * @remark Time limit is defined by module parameter PX_TAC (see comp type) * @param p_llaAddrTn Local link address of testing node which calls this function * @param p_llaAddrNut Local link address of node under test * @param p_identifier Idenitifier to be used in ICMPv6 echo request * @param p_seqNo Sequence number to be used in ICMPv6 echo request * @param p_echoRequest Received Echo Request * @return execution status */ function f_replyToEchoRequest(in template Ipv6Address p_llaAddrTn, in template Ipv6Address p_llaAddrNut, in UInt16 p_identifier, in UInt16 p_seqNo, out EchoRequest p_echoRequest) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret := e_error; tc_ac.start; alt { [] ipPort.receive(mw_echoRequest ( p_llaAddrNut, p_llaAddrTn )) -> value p_echoRequest { tc_ac.stop; v_ret := e_success; } [] tc_ac.timeout{ return e_timeout; } } // end alt v_ret := f_sendEchoReply( m_echoReply_noExtHdr_data( p_llaAddrTn, p_llaAddrNut, p_identifier, p_seqNo, p_echoRequest.ipv6Payload.echoRequestMsg.data )); return v_ret ; } // end f_replyToEchoRequest /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any * NUT, and does not a reply wihtin a given time limit. * This function can be used to verify that the NUT is NOT * up and running. * @remark Time limit is defined by module parameter PX_TNOAC (see comp type) * @param p_llaAddrTn Local link address of testing node which calls this function * @param p_llaAddrNut Local link address of node under test * @return execution status */ function f_echoProcDown( template Ipv6Address p_llaAddrTn, template Ipv6Address p_llaAddrNut) runs on LibIpv6Node return FncRetCode { // var EchoReply v_echoReply; // if ( f_echoProcUp( p_llaAddrTn, p_llaAddrNut, c_defId, c_defSeqNo, v_echoReply) == e_timeout ) { // // that means no echo reply was received - this is what we want here // return e_success; // } else { // return e_error; // } var EchoReply v_echoRep; var FncRetCode v_ret; v_ret := f_sendEchoRequest( m_echoRequest_noExtHdr_noData( p_llaAddrTn, p_llaAddrNut, c_defId, c_defSeqNo )); if ( v_ret != e_success ) {return v_ret;} tc_noAc.start; alt { [] ipPort.receive(mw_echoReply ( p_llaAddrNut, p_llaAddrTn )) -> value v_echoRep { tc_noAc.stop; return e_error; } [] tc_noAc.timeout{ return e_success; } } // end alt }//end f_echoProcDown /* * @desc This sends an ICMPv6 echo request from an IPv6 node to * any NUT. Prior it modifies IPv6 packet payload length * and ICMPv6 checksum to their correct values using external * functions. * @remark The template passed in must NOT contain any matching expressions! * @param p_echoRequest Ipv6 packet value or template with echo request to be sent * @param p_payloadLength Length of the IPv6 payload to be sent * @return execution status */ function f_sendEchoRequest_noCalcPayloadLength (in template EchoRequest p_echoRequest, UInt16 p_payloadLength ) runs on LibIpv6Node return FncRetCode { var EchoRequest v_ipPkt; v_ipPkt := valueof(p_echoRequest); //set payload length v_ipPkt.ipv6Hdr.payloadLength := p_payloadLength; if(f_setExtensionHeaders( v_ipPkt ) != e_success) { log(" **** f_sendEchoRequest_noCalcPayloadLength: Error when calculating length of extension headers ****"); return e_error; } //send ipPort.send(v_ipPkt); return e_success; }//end f_sendEchoRequest_noCalcPayloadLength /* * @desc This sends an ICMPv6 echo request from an IPv6 node to * any NUT. Prior it modifies IPv6 packet payload length * and ICMPv6 checksum to their correct values using external * functions. Waits for a Parameter Problem message. * @param p_echoRequest Ipv6 packet value or template with echo request to be sent (must not contains wildcards) * @param p_parameterProblem Parameter Problem message we are waiting for. * @return execution status */ function f_getParameterProblemAfterEchoReq_ignoreEchoReply ( in template EchoRequest p_echoRequest, in template ParameterProblem p_parameterProblem ) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret; var boolean v_ppReceived := false; v_ret := f_sendEchoRequest ( p_echoRequest ); if ( v_ret != e_success ) { return v_ret; } tc_ac.start; alt { [] ipPort.receive ( p_parameterProblem ) { v_ppReceived := true; repeat; } [] ipPort.receive ( ParameterProblem:? ) { log("**** f_getParameterProblemAfterEchoReq_ignoreEchoReply: ERROR: Template mismatch **** "); v_ret := e_error; } [] ipPort.receive(mw_echoReply ( p_echoRequest.ipv6Hdr.destinationAddress, p_echoRequest.ipv6Hdr.sourceAddress ) ) { tc_ac.stop; log("**** f_getParameterProblemAfterEchoReq_ignoreEchoReply: ERROR: An Echo Reply was received, HUT did not discard our Echo Request **** "); v_ret := e_error; } [v_ppReceived==false] tc_ac.timeout{ v_ret := e_timeout; } [v_ppReceived==true] tc_ac.timeout{ v_ret := e_success; } } // end alt return v_ret; }//end f_getParameterProblemAfterEchoReq_ignoreEchoReply /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any * NUT, and waits for a echo reply for a fixed amount of time. * This function can be used to verify that the NUT is * up and running. Neighbor detection is handled here, rather than in * a default. Might be useful if NUT must perform neighbor detection. * @remark Time limit is defined by module parameter PX_TAC (see comp type) * @param p_llaAddrTn Local link address of testing node which calls this function * @param p_llaAddrNut Local link address of node under test * @return execution status */ function f_echoProcUp_withHopL255Len1280( in template Ipv6Address p_llaAddrTn, in template Ipv6Address p_llaAddrNut) runs on LibIpv6Node return FncRetCode { var FncRetCode v_ret; v_ret := f_sendEchoRequest ( m_echoRequest_noExtHdr_data_hop ( p_llaAddrTn, p_llaAddrNut, c_hopLimit255, c_defId, c_defSeqNo, c_1280ZeroBytes ) ); if ( v_ret == e_success ) { tc_ac.start; alt { [] ipPort.receive ( mw_echoReply_noExtHdr_data_hop ( p_llaAddrNut, p_llaAddrTn, c_hopLimit255, c_1280ZeroBytes ) ) { tc_ac.stop; return e_success; } [] tc_ac.timeout{ return e_timeout; } } // end alt } // End If return v_ret; } // End function f_echoProcUp_withHopL255Len1280 /* * @desc This sends other ICMPv6 packet from an IPv6 node to * any IUT. Prior it modifies IPv6 packet payload length * and ICMPv6 checksum to their correct values using external * functions. * @remark The template passed in must NOT contain any matching expressions! * @param p_otherIcmpv6 Ipv6 packet value or template with the ICMPv6 packet to be sent * @return execution status */ function f_sendOtherIcmpv6 (in template OtherIcmpv6 p_otherIcmpv6) runs on LibIpv6Node return FncRetCode { var OtherIcmpv6 v_ipPkt; v_ipPkt := valueof(p_otherIcmpv6); //set Extension Header if(f_setExtensionHeaders( v_ipPkt ) != e_success) { log(" **** f_sendOtherIcmpv6: Error when calculating length of extension headers ****"); return e_error; } //send ipPort.send(v_ipPkt); return e_success; } // end f_sendOtherIcmpv6 /* * @desc This sends an ICMPv6 Destination Unreachable message to * any IUT. Prior it modifies IPv6 packet payload length * and ICMPv6 checksum to their correct values using external * functions. * @remark The template passed in must NOT contain any matching expressions! * @param p_destUnreachable Ipv6 packet value or template with the Destination * Unreachable message to be sent * @return execution status */ function f_sendDestUnreachable (in template DestinationUnreachable p_destUnreachable ) runs on LibIpv6Node return FncRetCode { var DestinationUnreachable v_ipPkt; v_ipPkt := valueof(p_destUnreachable); //set Extension Header if(f_setExtensionHeaders( v_ipPkt ) != e_success) { log(" **** f_sendDestUnreachable: Error when calculating length of extension headers ****"); return e_error; } //send ipPort.send(v_ipPkt); return e_success; } // end f_sendDestUnreachable /* * @desc This sends an ICMPv6 Packet Too Big message to * any IUT. Prior it modifies IPv6 packet payload length * and ICMPv6 checksum to their correct values using external * functions. * @remark The template passed in must NOT contain any matching expressions! * @param p_packetTooBig Ipv6 packet value or template with the Packet * Too Big message to be sent * @return execution status */ function f_sendPacketTooBig (in template PacketTooBig p_packetTooBig ) runs on LibIpv6Node return FncRetCode { var PacketTooBig v_ipPkt; v_ipPkt := valueof(p_packetTooBig); //set Extension Header if(f_setExtensionHeaders( v_ipPkt ) != e_success) { log(" **** f_sendPacketTooBig: Error when calculating length of extension headers ****"); return e_error; } //send ipPort.send(v_ipPkt); return e_success; } // end f_sendPacketTooBig /* * @desc This sends an ICMPv6 Packet Too Big message to * any IUT. Prior it modifies IPv6 packet payload length * and ICMPv6 checksum to their correct values using external * functions. * @remark The template passed in must NOT contain any matching expressions! * @param p_timeExceeded Ipv6 packet value or template with the Time * Exceeded message to be sent * @return execution status */ function f_sendTimeExceeded (in template TimeExceeded p_timeExceeded ) runs on LibIpv6Node return FncRetCode { var TimeExceeded v_ipPkt; v_ipPkt := valueof(p_timeExceeded); //set Extension Header if(f_setExtensionHeaders( v_ipPkt ) != e_success) { log(" **** f_sendTimeExceeded: Error when calculating length of extension headers ****"); return e_error; } //send ipPort.send(v_ipPkt); return e_success; } // end f_sendTimeExceeded /* * @desc This sends an ICMPv6 Packet Too Big message to * any IUT. Prior it modifies IPv6 packet payload length * and ICMPv6 checksum to their correct values using external * functions. * @remark The template passed in must NOT contain any matching expressions! * @param p_parameterProblem Ipv6 packet value or template with the Parameter * Problem message to be sent * @return execution status */ function f_sendParameterProblem (in template ParameterProblem p_parameterProblem ) runs on LibIpv6Node return FncRetCode { var ParameterProblem v_ipPkt; v_ipPkt := valueof(p_parameterProblem); //set Extension Header if(f_setExtensionHeaders( v_ipPkt ) != e_success) { log(" **** f_sendParameterProblem: Error when calculating length of extension headers ****"); return e_error; } //send ipPort.send(v_ipPkt); return e_success; } // end f_sendParameterProblem /* * @desc This sends an ICMPv6 echo request from an IPv6 node to any * NUT, and waits for a echo reply for a fixed amount of time. * This function can be used to verify that the NUT is * up and running. * @remark Time limit is defined by module parameter PX_TAC (see comp type) * @param p_glaA Global address of tunnel entry point ( testing node 1) * @param p_glaB Global address of tunnel exit point (IUT) * @param p_glaC Src Global address of tunneled packet ( MN Home Address) * @param p_glaD Dst Global address of tunneled packet ( testing node 2) * @param p_identifier Idenitifier to be used in ICMPv6 echo request * @param p_seqNo Sequence number to be used in ICMPv6 echo request * @param p_icmpPkt IPv6 packet which has been received * @return execution status */ function f_echoProc_tunneled( in template Ipv6Address p_glaA, in template Ipv6Address p_glaB, in template Ipv6Address p_glaC, in template Ipv6Address p_glaD, in UInt16 p_identifier, in UInt16 p_seqNo, out EchoReply p_icmpPkt) runs on LibIpv6Node return FncRetCode { var EchoReply v_echoRep; var FncRetCode v_ret; v_ret := f_sendEchoRequest( m_echoRequest_extHdr_data ( c_tunneledIpHdr, m_extHdrList_1Elem ( m_extHdr_tunneledHeader ( c_icmpHdr, p_glaC, p_glaD)), p_glaA, p_glaB, c_defId, c_defSeqNo, c_8ZeroBytes )); if ( v_ret != e_success ) {return v_ret;} tc_ac.start; alt { [] ipPort.receive(mw_echoReply_extHdr_data ( p_glaB, p_glaA, c_tunneledIpHdr, m_extHdrList_1Elem ( mw_extHdr_tunneledHeader ( c_icmpHdr, p_glaD, p_glaC )), c_defId, c_defSeqNo, c_8ZeroBytes)) -> value v_echoRep { p_icmpPkt := v_echoRep ; tc_ac.stop; return e_success; } [] tc_ac.timeout{ return e_timeout; } } // end alt } // end f_echoProc_tunneled } // end module LibIpv6_Rfc2463Icmpv6_Functions