446 lines
20 KiB
Plaintext
446 lines
20 KiB
Plaintext
/******************************************************************************/
|
|
// @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.
|
|
// Trademark 2012, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC).
|
|
// All rights reserved.
|
|
// @version: 36.523-3v10.1.0
|
|
// $Date: 2012-09-03 00:32:42 +0200 (Mon, 03 Sep 2012) $
|
|
// $Rev: 7245 $
|
|
/******************************************************************************/
|
|
|
|
module CommonIP {
|
|
|
|
import from CommonDefs all;
|
|
import from Parameters all;
|
|
|
|
const UInt8_Type tsc_IP_Protocol_ICMP := 1; /* @status APPROVED */
|
|
|
|
const UInt8_Type tsc_IP_Protocol_UDP := 17; /* @status APPROVED */
|
|
|
|
const UInt8_Type tsc_ICMP_Type_EchoReply := 0; /* @status APPROVED */
|
|
|
|
const UInt8_Type tsc_IP_Protocol_TCP := 6; /* @status APPROVED */
|
|
|
|
const UInt8_Type tsc_IP_Protocol_IPSec := 50; /* @status APPROVED */
|
|
|
|
const integer tsc_IMS_PortNumber_5060 := 5060; /* @status APPROVED */
|
|
|
|
const octetstring tsc_IP_AnyData := '00112233445566778899AABBCCDDEEFF'O; /* @status APPROVED */
|
|
|
|
function fl_LoopbackModeB_IPv4IPv6Address(boolean p_UseIPv4,
|
|
charstring p_IPv4Addr,
|
|
charstring p_IPv6Addr) return charstring
|
|
{
|
|
if (p_UseIPv4) { return p_IPv4Addr; }
|
|
else { return p_IPv6Addr; }
|
|
}
|
|
|
|
function f_LoopbackModeB_IP_Address_UE(boolean p_UseIPv4 := pc_IPv4,
|
|
PDN_Index_Type p_PdnIndex := PDN_1) return charstring
|
|
{
|
|
var charstring v_IPAddr := "";
|
|
select (p_PdnIndex) {
|
|
case (PDN_1) { v_IPAddr := fl_LoopbackModeB_IPv4IPv6Address(p_UseIPv4, px_IPv4_Address1_UE, px_IPv6_Address1_UE); }
|
|
case (PDN_2) { v_IPAddr := fl_LoopbackModeB_IPv4IPv6Address(p_UseIPv4, px_IPv4_Address2_UE, px_IPv6_Address2_UE); }
|
|
}
|
|
return v_IPAddr;
|
|
}
|
|
|
|
function f_LoopbackModeB_IP_Address_NW(boolean p_UseIPv4 := pc_IPv4,
|
|
PDN_Index_Type p_PdnIndex := PDN_1) return charstring
|
|
{
|
|
var charstring v_IPAddr := "";
|
|
select (p_PdnIndex) {
|
|
case (PDN_1) { v_IPAddr := fl_LoopbackModeB_IPv4IPv6Address(p_UseIPv4, px_IPv4_Address1_NW, px_IPv6_Address1_NW); }
|
|
case (PDN_2) { v_IPAddr := fl_LoopbackModeB_IPv4IPv6Address(p_UseIPv4, px_IPv4_Address2_NW, px_IPv6_Address2_NW); }
|
|
}
|
|
return v_IPAddr;
|
|
}
|
|
|
|
function f_IpAddressIsIPv4(charstring p_IpAddress) return boolean
|
|
{
|
|
var template charstring v_Pattern := pattern "[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+";
|
|
return match(p_IpAddress, v_Pattern);
|
|
};
|
|
|
|
function f_IpAddressIsIPv6(charstring p_IpAddress) return boolean
|
|
{
|
|
var Char1List_Type v_SplitCharList := {":"};
|
|
var CharStringList_Type v_FieldList := f_StringSplit(p_IpAddress, v_SplitCharList);
|
|
var integer v_FieldCnt := lengthof(v_FieldList);
|
|
var charstring v_Field;
|
|
var charstring v_Pattern;
|
|
var integer v_FieldLength;
|
|
var integer i;
|
|
|
|
if ((v_FieldCnt == 1) or (v_FieldCnt > 8)) { return false; }
|
|
|
|
for (i:=0; i<v_FieldCnt; i:=i+1) {
|
|
v_Field := v_FieldList[i];
|
|
v_FieldLength := lengthof(v_Field);
|
|
v_Pattern := "[0-9a-f]#(" & int2str(v_FieldLength) & ")";
|
|
|
|
if (v_FieldLength > 4) { return false; }
|
|
if (not match(v_Field, pattern v_Pattern)) { return false; }
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function f_Convert_IPv4Addr2OctString(charstring p_IPv4AddrChar) return O4_Type
|
|
{
|
|
var Char1List_Type v_SplitCharList := {"."};
|
|
var CharStringList_Type v_FieldList := f_StringSplit(p_IPv4AddrChar, v_SplitCharList);
|
|
var octetstring v_IPv4AddrOct := ''O;
|
|
var integer v_FieldCnt := lengthof(v_FieldList);
|
|
var integer v_IntVal;
|
|
var integer i;
|
|
|
|
if (v_FieldCnt != 4) {
|
|
FatalError(__FILE__, __LINE__, "invalid IP Address");
|
|
}
|
|
for (i:=0; i<v_FieldCnt; i:=i+1) {
|
|
v_IntVal := str2int(v_FieldList[i]);
|
|
v_IPv4AddrOct := v_IPv4AddrOct & int2oct(v_IntVal, 1);
|
|
}
|
|
return v_IPv4AddrOct;
|
|
}
|
|
|
|
function f_Convert_IPv6Addr2OctString(charstring p_IPv6AddrChar) return O16_Type
|
|
{
|
|
var Char1List_Type v_SplitCharList := {":"};
|
|
var CharStringList_Type v_FieldList := f_StringSplit(p_IPv6AddrChar, v_SplitCharList);
|
|
var octetstring v_IPv6AddrOct := ''O;
|
|
var integer v_FieldCnt := lengthof(v_FieldList);
|
|
var boolean v_EmptyBlocksExpanded := false; /* set to true when "::" has been expanded => subsequent empty fields will just be replaced by '0000' */
|
|
var charstring v_Field;
|
|
var integer v_NoOfEmptyBlocks;
|
|
var integer i;
|
|
var integer k;
|
|
|
|
if (v_FieldCnt > 8) {
|
|
FatalError(__FILE__, __LINE__, "invalid IP Address");
|
|
}
|
|
for (i:=0; i<v_FieldCnt; i:=i+1) {
|
|
v_Field := v_FieldList[i];
|
|
select (lengthof(v_Field)) {
|
|
case (0) { // empty block
|
|
if (not v_EmptyBlocksExpanded) { /* e.g. for "2001:0ba0::" we have two empty blocks at the end of the address but only one of them shall be expanded; @sic R5s110645 change 5 sic@ */
|
|
v_EmptyBlocksExpanded := true;
|
|
v_NoOfEmptyBlocks := 8 - (v_FieldCnt - 1); /* "-1" because one empty block is already contained in v_FieldCnt */
|
|
for (k:=0; k < v_NoOfEmptyBlocks; k:=k+1) {
|
|
v_IPv6AddrOct := v_IPv6AddrOct & '0000'O;
|
|
}
|
|
} else { /* "::" has already been expanded */
|
|
v_IPv6AddrOct := v_IPv6AddrOct & '0000'O;
|
|
}
|
|
}
|
|
case (1) {
|
|
v_IPv6AddrOct := v_IPv6AddrOct & str2oct("000" & v_Field);
|
|
}
|
|
case (2) {
|
|
v_IPv6AddrOct := v_IPv6AddrOct & str2oct("00" & v_Field);
|
|
}
|
|
case (3) {
|
|
v_IPv6AddrOct := v_IPv6AddrOct & str2oct("0" & v_Field);
|
|
}
|
|
case (4) {
|
|
v_IPv6AddrOct := v_IPv6AddrOct & str2oct(v_Field);
|
|
|
|
}
|
|
case else {
|
|
FatalError(__FILE__, __LINE__, "invalid IP Address");
|
|
}
|
|
}
|
|
}
|
|
return v_IPv6AddrOct;
|
|
}
|
|
|
|
function f_Convert_OctString2IPv6Addr(O16_Type p_IPv6AddrOct) return charstring
|
|
{ /* @sic R5s110603 change 2 sic@ */
|
|
var charstring v_IPv6Addr := "";
|
|
var integer v_AddrLength := lengthof(p_IPv6AddrOct);
|
|
var integer i := 0;
|
|
|
|
while (i < v_AddrLength) {
|
|
v_IPv6Addr := v_IPv6Addr & oct2str(substr(p_IPv6AddrOct, i, 2));
|
|
i:=i+2;
|
|
if (i < v_AddrLength) {
|
|
v_IPv6Addr := v_IPv6Addr & ":";
|
|
}
|
|
}
|
|
return v_IPv6Addr;
|
|
}
|
|
|
|
function f_IpChecksum(octetstring p_OctetString) return O2_Type
|
|
{ /* calculate header checksum; within the given octetstring the header checksum shall be set to '0000'O */
|
|
var integer i;
|
|
var octetstring v_Word;
|
|
var integer v_DataLength := lengthof(p_OctetString);
|
|
var integer v_Sum := 0;
|
|
|
|
if (v_DataLength mod 2 != 0) {
|
|
p_OctetString := p_OctetString & '00'O;
|
|
}
|
|
|
|
// accumulate all words of the IP header
|
|
for (i:=0; i < v_DataLength; i := i+2) {
|
|
v_Word := p_OctetString[i] & p_OctetString[i+1];
|
|
v_Sum := v_Sum + oct2int(v_Word);
|
|
}
|
|
// deal with the
|
|
while (v_Sum > tsc_UInt16Max) {
|
|
v_Sum := (v_Sum mod (tsc_UInt16Max+1)) + (v_Sum / (tsc_UInt16Max+1));
|
|
}
|
|
// get complement
|
|
v_Sum := tsc_UInt16Max - v_Sum;
|
|
return int2oct(v_Sum, 2);
|
|
}
|
|
|
|
function f_IPv4Packet_Create(O2_Type p_Identification := '6d7d'O, // Identification; random value (can be used to generate different packets
|
|
O1_Type p_TOS := '00'O, // Differentiated services (RFC 2474), Explicit Congestion Notification (ECN, RFC 3168), former TOS (RFC 791)
|
|
UInt8_Type p_Protocol,
|
|
charstring p_SourceAddr,
|
|
charstring p_DestAddr,
|
|
octetstring p_IPPayload)
|
|
return octetstring
|
|
{
|
|
var integer v_TotalLength := lengthof(p_IPPayload) + 20; // 20 bytes IP header
|
|
var O4_Type v_SourceAddrStr := f_Convert_IPv4Addr2OctString(p_SourceAddr);
|
|
var O4_Type v_DestAddrStr := f_Convert_IPv4Addr2OctString(p_DestAddr);
|
|
var octetstring v_OctetString;
|
|
|
|
// IP header
|
|
v_OctetString := '45'O; // version and header length
|
|
v_OctetString := v_OctetString & p_TOS;
|
|
v_OctetString := v_OctetString & int2oct(v_TotalLength, 2);
|
|
v_OctetString := v_OctetString & p_Identification;
|
|
v_OctetString := v_OctetString & '0000'O; // flags (3 bits; typically 0 for UDP) and fragment offset (13 bits; typically 0 for UDP)
|
|
v_OctetString := v_OctetString & '80'O; // Time to live (random value)
|
|
v_OctetString := v_OctetString & int2oct(p_Protocol, 1);
|
|
v_OctetString := v_OctetString & f_IpChecksum(v_OctetString & '0000'O & v_SourceAddrStr & v_DestAddrStr);
|
|
v_OctetString := v_OctetString & v_SourceAddrStr;
|
|
v_OctetString := v_OctetString & v_DestAddrStr;
|
|
v_OctetString := v_OctetString & p_IPPayload;
|
|
|
|
return v_OctetString;
|
|
}
|
|
|
|
function f_IPv6Packet_Create(O1_Type p_TrafficClass := '00'O,
|
|
UInt20_Type p_FlowLabel := 0,
|
|
UInt8_Type p_Protocol,
|
|
charstring p_SourceAddr,
|
|
charstring p_DestAddr,
|
|
octetstring p_IPPayload)
|
|
return octetstring
|
|
{
|
|
var hexstring v_Version := '6'H;
|
|
var hexstring v_TrafficClass := oct2hex (p_TrafficClass);
|
|
var hexstring v_FlowLabel := int2hex (p_FlowLabel, 5);
|
|
var O16_Type v_SourceAddrStr := f_Convert_IPv6Addr2OctString(p_SourceAddr);
|
|
var O16_Type v_DestAddrStr := f_Convert_IPv6Addr2OctString(p_DestAddr);
|
|
var octetstring v_OctetString;
|
|
|
|
// IP header
|
|
v_OctetString := hex2oct(v_Version & v_TrafficClass & v_FlowLabel); // Version, Traffic Class and Flow Label to be revised
|
|
v_OctetString := v_OctetString & int2oct (lengthof(p_IPPayload), 2); // Payload Length
|
|
v_OctetString := v_OctetString & int2oct(p_Protocol, 1); // Next header
|
|
v_OctetString := v_OctetString & '40'O; // Hop Limit
|
|
v_OctetString := v_OctetString & v_SourceAddrStr;
|
|
v_OctetString := v_OctetString & v_DestAddrStr;
|
|
v_OctetString := v_OctetString & p_IPPayload;
|
|
return v_OctetString;
|
|
}
|
|
|
|
function f_IPv4UdpDatagram_Create(charstring p_SourceAddr,
|
|
charstring p_DestAddr,
|
|
UInt16_Type p_SourcePort,
|
|
UInt16_Type p_DestPort,
|
|
octetstring p_UdpPayload)
|
|
return octetstring
|
|
{ /* @desc create UDP datagram */
|
|
var integer v_UdpDatagramLength := lengthof(p_UdpPayload) + 8; // 8 bytes UDP header
|
|
// Pseudo Header:
|
|
var O4_Type v_SourceAddrStr := f_Convert_IPv4Addr2OctString(p_SourceAddr);
|
|
var O4_Type v_DestAddrStr := f_Convert_IPv4Addr2OctString(p_DestAddr);
|
|
var O2_Type v_LengthStr := int2oct(v_UdpDatagramLength, 2);
|
|
var O1_Type v_Protocol := '11'O; // UDP
|
|
var octetstring v_PseudoHeader := v_SourceAddrStr & v_DestAddrStr &'00'O & v_Protocol & v_LengthStr;
|
|
var O2_Type v_ChecksumDummy := '0000'O;
|
|
var octetstring v_OctetString := ''O;
|
|
|
|
v_OctetString := v_OctetString & int2oct(p_SourcePort, 2);
|
|
v_OctetString := v_OctetString & int2oct(p_DestPort, 2);
|
|
v_OctetString := v_OctetString & v_LengthStr;
|
|
v_OctetString := v_OctetString & f_IpChecksum(v_PseudoHeader & v_OctetString & v_ChecksumDummy & p_UdpPayload); /* Note: the UDP checksum can also be '0000'O what means "no chcksum"; but that is not the usual case */
|
|
v_OctetString := v_OctetString & p_UdpPayload;
|
|
|
|
return v_OctetString;
|
|
}
|
|
|
|
function f_IPv6UdpDatagram_Create(charstring p_SourceAddr,
|
|
charstring p_DestAddr,
|
|
UInt16_Type p_SourcePort,
|
|
UInt16_Type p_DestPort,
|
|
octetstring p_UdpPayload)
|
|
return octetstring
|
|
{
|
|
var integer v_UdpDatagramLength := lengthof(p_UdpPayload) + 8; // 8 bytes UDP header
|
|
var O16_Type v_SourceAddrStr := f_Convert_IPv6Addr2OctString(p_SourceAddr);
|
|
var O16_Type v_DestAddrStr := f_Convert_IPv6Addr2OctString(p_DestAddr);
|
|
var O4_Type v_LengthStr := int2oct(v_UdpDatagramLength, 4); // RFC 2460 clause 8.1
|
|
var octetstring v_PseudoHeader;
|
|
var octetstring v_OctetString;
|
|
|
|
// Prepare the pseudo header, see RFC 2460 and illustration in Wikipedia
|
|
v_PseudoHeader := v_SourceAddrStr & v_DestAddrStr & v_LengthStr;
|
|
v_PseudoHeader := v_PseudoHeader & v_LengthStr; // UDP length
|
|
v_PseudoHeader := v_PseudoHeader & '000000'O & '11'O; // Zeros and Next header (= Protocol)
|
|
v_PseudoHeader := v_PseudoHeader & int2oct(p_SourcePort, 2) & int2oct(p_DestPort, 2) & int2oct(v_UdpDatagramLength, 2) & '0000'O;
|
|
v_PseudoHeader := v_PseudoHeader & p_UdpPayload;
|
|
|
|
// Now set the UDP packet
|
|
v_OctetString := int2oct(p_SourcePort, 2);
|
|
v_OctetString := v_OctetString & int2oct(p_DestPort, 2);
|
|
v_OctetString := v_OctetString & int2oct(v_UdpDatagramLength, 2);
|
|
v_OctetString := v_OctetString & f_IpChecksum(v_PseudoHeader);
|
|
v_OctetString := v_OctetString & p_UdpPayload;
|
|
|
|
return v_OctetString;
|
|
}
|
|
|
|
function f_IPv4TcpDatagram_Create(charstring p_SourceAddr,
|
|
charstring p_DestAddr,
|
|
UInt16_Type p_SourcePort,
|
|
UInt16_Type p_DestPort,
|
|
octetstring p_TcpPayload)
|
|
return octetstring
|
|
{
|
|
var integer v_TcpDatagramLength := lengthof(p_TcpPayload) + 20; // 20 bytes TCP header
|
|
// Pseudo Header:
|
|
var O4_Type v_SourceAddrStr := f_Convert_IPv4Addr2OctString(p_SourceAddr);
|
|
var O4_Type v_DestAddrStr := f_Convert_IPv4Addr2OctString(p_DestAddr);
|
|
var O2_Type v_LengthStr := int2oct(v_TcpDatagramLength, 2);
|
|
var O1_Type v_Protocol := int2oct(tsc_IP_Protocol_TCP, 1);
|
|
var octetstring v_PseudoHeader := v_SourceAddrStr & v_DestAddrStr &'00'O & v_Protocol & v_LengthStr;
|
|
var O2_Type v_ChecksumDummy := '0000'O;
|
|
var octetstring v_UrgPointer := '0000'O;
|
|
var octetstring v_OctetString := ''O;
|
|
|
|
v_OctetString := v_OctetString & int2oct(p_SourcePort, 2);
|
|
v_OctetString := v_OctetString & int2oct(p_DestPort, 2);
|
|
v_OctetString := v_OctetString & int2oct(0, 4); // Sequence Number
|
|
v_OctetString := v_OctetString & int2oct(0, 4); // Acknowledgment Number
|
|
v_OctetString := v_OctetString & '5011'O; // 4bits HeaderLen/6bits Reserved/URG/ACK/PSH/RST/SYN/FIN
|
|
v_OctetString := v_OctetString & int2oct(256, 4); // How to set the windows size?
|
|
v_OctetString := v_OctetString & f_IpChecksum(v_PseudoHeader & v_OctetString & v_ChecksumDummy & v_UrgPointer & p_TcpPayload); /* Note: the TCP checksum can also be '0000'O what means "no chcksum"; but that is not the usual case */
|
|
v_OctetString := v_OctetString & v_UrgPointer;
|
|
v_OctetString := v_OctetString & p_TcpPayload;
|
|
|
|
return v_OctetString;
|
|
}
|
|
|
|
function f_IPv6TcpDatagram_Create(charstring p_SourceAddr,
|
|
charstring p_DestAddr,
|
|
UInt16_Type p_SourcePort,
|
|
UInt16_Type p_DestPort,
|
|
octetstring p_TcpPayload)
|
|
return octetstring
|
|
{ /* @sic R5s110645 change 4: IPv6 address instead of IPv4 sic@ */
|
|
var integer v_TcpDatagramLength := lengthof(p_TcpPayload) + 20; // 20 bytes TCP header
|
|
// Pseudo Header:
|
|
var O16_Type v_SourceAddrStr := f_Convert_IPv6Addr2OctString(p_SourceAddr);
|
|
var O16_Type v_DestAddrStr := f_Convert_IPv6Addr2OctString(p_DestAddr);
|
|
var O4_Type v_LengthStr := int2oct(v_TcpDatagramLength, 4); // 2460 clause 8.1
|
|
var O1_Type v_Protocol := int2oct(tsc_IP_Protocol_TCP, 1);
|
|
var octetstring v_PseudoHeader;
|
|
var O2_Type v_ChecksumDummy := '0000'O;
|
|
var octetstring v_UrgPointer := '0000'O;
|
|
var octetstring v_OctetString := ''O;
|
|
|
|
// Prepare the pseudo header, see RFC 2460 and illustration in Wikipedia
|
|
v_PseudoHeader := v_SourceAddrStr & v_DestAddrStr & v_LengthStr;
|
|
v_PseudoHeader := v_PseudoHeader & '000000'O & v_Protocol; // Zeros and Next header (= Protocol)
|
|
|
|
v_OctetString := v_OctetString & int2oct(p_SourcePort, 2);
|
|
v_OctetString := v_OctetString & int2oct(p_DestPort, 2);
|
|
v_OctetString := v_OctetString & int2oct(0, 4); // Sequence Number
|
|
v_OctetString := v_OctetString & int2oct(0, 4); // Acknowledgment Number
|
|
v_OctetString := v_OctetString & '5011'O; // 4bits HeaderLen/6bits Reserved/URG/ACK/PSH/RST/SYN/FIN
|
|
v_OctetString := v_OctetString & int2oct(256, 4); // How to set the windows size?
|
|
v_OctetString := v_OctetString & f_IpChecksum(v_PseudoHeader & v_OctetString & v_ChecksumDummy & v_UrgPointer & p_TcpPayload); /* Note: the TCP checksum can also be '0000'O what means "no chcksum"; but that is not the usual case */
|
|
v_OctetString := v_OctetString & v_UrgPointer;
|
|
v_OctetString := v_OctetString & p_TcpPayload;
|
|
|
|
return v_OctetString;
|
|
}
|
|
|
|
function fl_IcmpDatagram_Create(UInt8_Type p_IcmpType,
|
|
O2_Type p_SequenceNumber,
|
|
octetstring p_Data)
|
|
return octetstring
|
|
{ /* @desc create ICMP datagram */
|
|
var O2_Type v_ChecksumDummy := '0000'O;
|
|
var O2_Type v_Id := '0001'O;
|
|
var octetstring v_OctetString := ''O;
|
|
|
|
v_OctetString := v_OctetString & int2oct(p_IcmpType, 1); // Type
|
|
v_OctetString := v_OctetString & '00'O; // Code
|
|
v_OctetString := v_OctetString & f_IpChecksum(v_OctetString & v_ChecksumDummy & v_Id & p_Data);
|
|
v_OctetString := v_OctetString & v_Id;
|
|
v_OctetString := v_OctetString & p_SequenceNumber;
|
|
v_OctetString := v_OctetString & p_Data;
|
|
|
|
return v_OctetString;
|
|
}
|
|
|
|
function f_IcmpEchoReply(integer p_SequenceNumber) return octetstring
|
|
{
|
|
var O2_Type v_IcmpSequenceNumber := int2oct(p_SequenceNumber, 2);
|
|
var octetstring v_IcmpPayload := ''O;
|
|
var integer i;
|
|
|
|
for (i:=0; i<p_SequenceNumber; i:=i+1) {
|
|
v_IcmpPayload := v_IcmpPayload & tsc_IP_AnyData;
|
|
}
|
|
return fl_IcmpDatagram_Create(tsc_ICMP_Type_EchoReply, v_IcmpSequenceNumber, v_IcmpPayload);
|
|
}
|
|
|
|
function f_IPv4IPv6_IcmpEchoReply(charstring p_SourceAddr,
|
|
charstring p_DestAddr := "",
|
|
integer p_SequenceNumber := 1) return octetstring
|
|
{
|
|
var charstring v_DestAddr:= p_DestAddr;
|
|
var octetstring v_Payload := f_IcmpEchoReply(p_SequenceNumber);
|
|
var UInt8_Type v_Protocol := tsc_IP_Protocol_ICMP;
|
|
var octetstring v_IpPacket;
|
|
|
|
if (v_DestAddr == "") { v_DestAddr := p_SourceAddr; }
|
|
|
|
if (f_IpAddressIsIPv4(p_SourceAddr)) {
|
|
v_IpPacket := f_IPv4Packet_Create('10'O & int2oct(p_SequenceNumber, 1), -, v_Protocol, p_SourceAddr, p_DestAddr, v_Payload);
|
|
} else {
|
|
v_IpPacket := f_IPv6Packet_Create(-, -, v_Protocol, p_SourceAddr, v_DestAddr, v_Payload);
|
|
}
|
|
return v_IpPacket;
|
|
}
|
|
|
|
function f_IPv4IPv6_AnyUdpPacket(charstring p_SourceAddr,
|
|
charstring p_DestAddr,
|
|
UInt16_Type p_SourcePort,
|
|
UInt16_Type p_DestPort) return octetstring
|
|
{
|
|
var UInt8_Type v_Protocol := tsc_IP_Protocol_UDP;
|
|
var octetstring v_Payload := tsc_IP_AnyData;
|
|
var octetstring v_IpPacket;
|
|
|
|
if (f_IpAddressIsIPv4(p_SourceAddr)) {
|
|
v_IpPacket := f_IPv4Packet_Create(-, -, v_Protocol, p_SourceAddr, p_DestAddr, f_IPv4UdpDatagram_Create(p_SourceAddr, p_DestAddr, p_SourcePort, p_DestPort, v_Payload));
|
|
} else {
|
|
v_IpPacket := f_IPv6Packet_Create(-, -, v_Protocol, p_SourceAddr, p_DestAddr, f_IPv6UdpDatagram_Create(p_SourceAddr, p_DestAddr, p_SourcePort, p_DestPort, v_Payload));
|
|
}
|
|
return v_IpPacket;
|
|
}
|
|
|
|
}
|