/******************************************************************************/
// @copyright   Copyright Notification
//   No part may be reproduced except as authorized by written permission.
//   The copyright and the foregoing restriction extend to reproduction in all media.
//   (c) 2023, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC).
//   All rights reserved.
// @version: IWD_23wk37
// $Date: 2019-11-16 12:44:38 +0100 (Sat, 16 Nov 2019) $
// $Rev: 26175 $
/******************************************************************************/

module LoopbackIP_PacketFilterTest {

  import from CommonDefs all;
  import from CommonIP all;
  import from LoopbackIP all;

  //----------------------------------------------------------------------------
  /*
   * @desc      Common function to create IPv4 or IPv6 datagram
   * @param     p_IpTypeIsIPv4
   * @param     p_Protocol
   * @param     p_IPv4_SourceAddr
   * @param     p_IPv4_DestAddr
   * @param     p_IPv6_SourceAddr
   * @param     p_IPv6_DestAddr
   * @param     p_IPv6_FlowLabel
   * @param     p_SourcePort
   * @param     p_DestPort
   * @param     p_IPSecSPI
   * @param     p_TOS_TC
   * @return    octetstring
   * @status    APPROVED (LTE, NBIOT, NR5GC, UTRAN)
   */
  function f_PacketFilterTest_CreateDatagram(boolean p_IpTypeIsIPv4,
                                             UInt8_Type p_Protocol,
                                             charstring p_IPv4_SourceAddr,
                                             charstring p_IPv4_DestAddr,
                                             charstring p_IPv6_SourceAddr,
                                             charstring p_IPv6_DestAddr,
                                             UInt20_Type p_IPv6_FlowLabel,
                                             UInt16_Type p_SourcePort,
                                             UInt16_Type p_DestPort,
                                             O4_Type p_IPSecSPI,
                                             O1_Type p_TOS_TC) return octetstring
  {
    var octetstring v_IpPacket;
    var octetstring v_IPPayload;

    if (p_IpTypeIsIPv4) {
      select (p_Protocol) {
        case (tsc_IP_Protocol_UDP) {
          v_IPPayload := f_IPv4UdpDatagram_Create(p_IPv4_SourceAddr, p_IPv4_DestAddr, p_SourcePort, p_DestPort, tsc_IP_AnyData);
        }
        case (tsc_IP_Protocol_TCP) {
          v_IPPayload := f_IPv4TcpDatagram_Create(p_IPv4_SourceAddr, p_IPv4_DestAddr, p_SourcePort, p_DestPort, tsc_IP_AnyData);
        }
        case (tsc_IP_Protocol_IPSec) {
          v_IPPayload := f_IPSecESPDatagram_Create(p_Protocol,
                                                   p_IPSecSPI,
                                                   f_IPv4UdpDatagram_Create(p_IPv4_SourceAddr, p_IPv4_DestAddr, p_SourcePort, p_DestPort, tsc_IP_AnyData));
        }
      }
      v_IpPacket := f_IPv4Packet_Create(-, p_TOS_TC, p_Protocol, p_IPv4_SourceAddr, p_IPv4_DestAddr, v_IPPayload);
    }
    else {
      select (p_Protocol) {
        case (tsc_IP_Protocol_UDP) {
          v_IPPayload := f_IPv6UdpDatagram_Create(p_IPv6_SourceAddr, p_IPv6_DestAddr, p_SourcePort, p_DestPort, tsc_IP_AnyData);
        }
        case (tsc_IP_Protocol_TCP) {
          v_IPPayload := f_IPv6TcpDatagram_Create(p_IPv6_SourceAddr, p_IPv6_DestAddr, p_SourcePort, p_DestPort, tsc_IP_AnyData);
        }
        case (tsc_IP_Protocol_IPSec) {
          v_IPPayload := f_IPSecESPDatagram_Create(p_Protocol,
                                                   p_IPSecSPI,
                                                   f_IPv6UdpDatagram_Create(p_IPv6_SourceAddr, p_IPv6_DestAddr, p_SourcePort, p_DestPort, tsc_IP_AnyData));
        }
      }
      v_IpPacket := f_IPv6Packet_Create(p_TOS_TC, p_IPv6_FlowLabel, p_Protocol, -, p_IPv6_SourceAddr, p_IPv6_DestAddr, v_IPPayload);

    }
    return v_IpPacket;
  }

  //----------------------------------------------------------------------------
  /*
   * @desc      Establish IP packets used in test case 10.9.1
   * @param     p_IpTypeIsIPv4
   * @param     p_Index
   * @return    octetstring
   * @status    APPROVED (LTE, UTRAN)
   */
  function f_PacketFilterTest_CreateDatagram_10_9_1(boolean p_IpTypeIsIPv4,
                                                    integer p_Index) return octetstring
  {
    var charstring v_IPv4_SourceAddr := "192.168.0.1";
    var charstring v_IPv4_DestAddr   := "172.168.8.1";
    var charstring v_IPv6_SourceAddr := "fe80::1:1";
    var charstring v_IPv6_DestAddr   := "2001:0ba0::0001:0001"; // @sic R5s110645 sic@
    var UInt20_Type v_IPv6_FlowLabel := 10;
    var UInt16_Type v_SourcePort;
    var UInt16_Type v_DestPort;
    var O1_Type v_TOS_TC;
    var UInt8_Type v_Protocol;
    var O4_Type v_IPSecSPI := '0F80F000'O; // @sic R5s110645 sic@
          
    select (p_Index) { // Index is packet number per prose
      case (1) {
        v_Protocol   := tsc_IP_Protocol_UDP;
        v_SourcePort := 60001;
        v_DestPort   := 60350;
        v_TOS_TC     := 'A9'O;
      }
      case (2) {
        v_Protocol   := tsc_IP_Protocol_UDP;
        v_SourcePort := 60001;
        v_DestPort   := 60350;
        v_TOS_TC     := 'A9'O;
        v_IPv4_DestAddr   := "172.168.9.1"; // modified wrt base IP packet #1
        v_IPv6_DestAddr   := "2001:0bb0::0001:0001"; // modified wrt base IP packet #1 @sic R5s110645 sic@
      }
      case (3) {
        v_Protocol   := tsc_IP_Protocol_TCP; // modified wrt base IP packet #1
        v_SourcePort := 60001;
        v_DestPort   := 60350;
        v_TOS_TC     := 'A9'O;
      }
      case (4) {
        v_Protocol   := tsc_IP_Protocol_UDP;
        v_SourcePort := 60002; // modified wrt base IP packet #1
        v_DestPort   := 60350;
        v_TOS_TC     := 'A9'O;
      }
      case (5) {
        v_Protocol   := tsc_IP_Protocol_UDP;
        v_SourcePort := 60101; // modified wrt base IP packet #1
        v_DestPort   := 60350;
        v_TOS_TC     := 'A9'O;
      }
      case (6) {
        v_Protocol   := tsc_IP_Protocol_UDP;
        v_SourcePort := 60001;
        v_DestPort   := 60351; // modified wrt base IP packet #1
        v_TOS_TC     := 'A9'O;
      }
      case (7) {
        v_Protocol   := tsc_IP_Protocol_UDP;
        v_SourcePort := 60001;
        v_DestPort   := 60451; // modified wrt base IP packet #1
        v_TOS_TC     := 'A9'O;
      }
      case (8) {
        v_Protocol   := tsc_IP_Protocol_UDP;
        v_SourcePort := 60001;
        v_DestPort   := 60350;
        v_TOS_TC     := 'E9'O; // modified wrt base IP packet #1
      }
      case (9) {
        v_Protocol   := tsc_IP_Protocol_IPSec;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'A2'O;
      }
      case (10) {
        v_Protocol   := tsc_IP_Protocol_IPSec;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'A2'O;
        v_IPv4_DestAddr   := "172.168.9.1"; // modified wrt base IP packet #9
        v_IPv6_DestAddr   := "2001:0bb0::0001:0001"; // modified wrt base IP packet #9 @sic R5s110645 sic@
      }
      case (11) {
        v_Protocol   := tsc_IP_Protocol_TCP;  // modified wrt base IP packet #9
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'A2'O;
      }
      case (12) {
        v_Protocol   := tsc_IP_Protocol_IPSec;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'A2'O;
        v_IPSecSPI    := 'F90F0000'O;  // modified wrt base IP packet #9
      }
      case (13) {
        v_Protocol   := tsc_IP_Protocol_IPSec;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'E9'O;  // modified wrt base IP packet #9
      }
      case (14) {
        v_Protocol   := tsc_IP_Protocol_TCP;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'B3'O;
        v_IPv6_FlowLabel := 5;
        
        if (p_IpTypeIsIPv4) {
          FatalError(__FILE__, __LINE__, "packet id 14 is not for IPv4");
        }
      }
      case (15) {
        v_Protocol   := tsc_IP_Protocol_TCP;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'B3'O;
        v_IPv6_FlowLabel := 5;
        v_IPv6_DestAddr   := "2001:0bb0::0001:0001"; // modified wrt base IP packet #14 @sic R5s110645 sic@

        if (p_IpTypeIsIPv4) {
          FatalError(__FILE__, __LINE__, "packet id 15 is not for IPv4");
        }
      }
      case (16) {
        v_Protocol   := tsc_IP_Protocol_TCP;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'E9'O;  // modified wrt base IP packet #14
        v_IPv6_FlowLabel := 5;
        
        if (p_IpTypeIsIPv4) {
          FatalError(__FILE__, __LINE__, "packet id 16 is not for IPv4");
        }
      }
      case (17) {
        v_Protocol   := tsc_IP_Protocol_TCP;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'B3'O;
        v_IPv6_FlowLabel := 10;  // modified wrt base IP packet #14
        
        if (p_IpTypeIsIPv4) {
          FatalError(__FILE__, __LINE__, "packet id 17 is not for IPv4");
        }
      }
      case (18) {
        v_Protocol   := tsc_IP_Protocol_TCP;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'AA'O;
      }
      case (19) {
        v_Protocol   := tsc_IP_Protocol_TCP;
        v_SourcePort := 60101;
        v_DestPort   := 60451;
        v_TOS_TC     := 'AA'O;
        v_IPv4_DestAddr   := "172.168.9.1"; // modified wrt base IP packet #18 @sic R5s110604 sic@
        v_IPv6_DestAddr   := "2001:0ba1::0001:0001"; // modified wrt base IP packet #18 @sic R5s110645 sic@
      }
      case else {
        // out of supported range
        FatalError(__FILE__, __LINE__, "unsupported packet id");
      }
    }
    return f_PacketFilterTest_CreateDatagram(p_IpTypeIsIPv4,
                                             v_Protocol,
                                             v_IPv4_SourceAddr,
                                             v_IPv4_DestAddr,
                                             v_IPv6_SourceAddr,
                                             v_IPv6_DestAddr,
                                             v_IPv6_FlowLabel,
                                             v_SourcePort,
                                             v_DestPort,
                                             v_IPSecSPI,
                                             v_TOS_TC);
  }

}
