func ParseMultiIEs(b []byte) ([]*IE, error) {
	var ies []*IE
	for {
		if len(b) == 0 {
			break
		}
		i, err := Parse(b)
		if err != nil {
			return nil, err
		}
		ies = append(ies, i)
		b = b[i.MarshalLen():]
	}
	return ies, nil
}
ParseMultiIEs decodes multiple IEs at a time.
This is easy and useful but slower than decoding one by one.
When you don't know the number of IEs, this is the only way to decode them.
See benchmarks in diameter_test.go for the detail.
package ie
import (
	"encoding/binary"
	"io"
	"github.com/wmnsk/go-pfcp/internal/logger"
	"github.com/wmnsk/go-pfcp/internal/utils"
)
const (
	_                                                                uint16 = 0
	CreatePDR                                                        uint16 = 1
	PDI                                                              uint16 = 2
	CreateFAR                                                        uint16 = 3
	ForwardingParameters                                             uint16 = 4
	DuplicatingParameters                                            uint16 = 5
	CreateURR                                                        uint16 = 6
	CreateQER                                                        uint16 = 7
	CreatedPDR                                                       uint16 = 8
	UpdatePDR                                                        uint16 = 9
	UpdateFAR                                                        uint16 = 10
	UpdateForwardingParameters                                       uint16 = 11
	UpdateBARWithinSessionReportResponse                             uint16 = 12
	UpdateURR                                                        uint16 = 13
	UpdateQER                                                        uint16 = 14
	RemovePDR                                                        uint16 = 15
	RemoveFAR                                                        uint16 = 16
	RemoveURR                                                        uint16 = 17
	RemoveQER                                                        uint16 = 18
	Cause                                                            uint16 = 19
	SourceInterface                                                  uint16 = 20
	FTEID                                                            uint16 = 21
	NetworkInstance                                                  uint16 = 22
	SDFFilter                                                        uint16 = 23
	ApplicationID                                                    uint16 = 24
	GateStatus                                                       uint16 = 25
	MBR                                                              uint16 = 26
	GBR                                                              uint16 = 27
	QERCorrelationID                                                 uint16 = 28
	Precedence                                                       uint16 = 29
	TransportLevelMarking                                            uint16 = 30
	VolumeThreshold                                                  uint16 = 31
	TimeThreshold                                                    uint16 = 32
	MonitoringTime                                                   uint16 = 33
	SubsequentVolumeThreshold                                        uint16 = 34
	SubsequentTimeThreshold                                          uint16 = 35
	InactivityDetectionTime                                          uint16 = 36
	ReportingTriggers                                                uint16 = 37
	RedirectInformation                                              uint16 = 38
	ReportType                                                       uint16 = 39
	OffendingIE                                                      uint16 = 40
	ForwardingPolicy                                                 uint16 = 41
	DestinationInterface                                             uint16 = 42
	UPFunctionFeatures                                               uint16 = 43
	ApplyAction                                                      uint16 = 44
	DownlinkDataServiceInformation                                   uint16 = 45
	DownlinkDataNotificationDelay                                    uint16 = 46
	DLBufferingDuration                                              uint16 = 47
	DLBufferingSuggestedPacketCount                                  uint16 = 48
	PFCPSMReqFlags                                                   uint16 = 49
	PFCPSRRspFlags                                                   uint16 = 50
	LoadControlInformation                                           uint16 = 51
	SequenceNumber                                                   uint16 = 52
	Metric                                                           uint16 = 53
	OverloadControlInformation                                       uint16 = 54
	Timer                                                            uint16 = 55
	PDRID                                                            uint16 = 56
	FSEID                                                            uint16 = 57
	ApplicationIDsPFDs                                               uint16 = 58
	PFDContext                                                       uint16 = 59
	NodeID                                                           uint16 = 60
	PFDContents                                                      uint16 = 61
	MeasurementMethod                                                uint16 = 62
	UsageReportTrigger                                               uint16 = 63
	MeasurementPeriod                                                uint16 = 64
	FQCSID                                                           uint16 = 65
	VolumeMeasurement                                                uint16 = 66
	DurationMeasurement                                              uint16 = 67
	ApplicationDetectionInformation                                  uint16 = 68
	TimeOfFirstPacket                                                uint16 = 69
	TimeOfLastPacket                                                 uint16 = 70
	QuotaHoldingTime                                                 uint16 = 71
	DroppedDLTrafficThreshold                                        uint16 = 72
	VolumeQuota                                                      uint16 = 73
	TimeQuota                                                        uint16 = 74
	StartTime                                                        uint16 = 75
	EndTime                                                          uint16 = 76
	QueryURR                                                         uint16 = 77
	UsageReportWithinSessionModificationResponse                     uint16 = 78
	UsageReportWithinSessionDeletionResponse                         uint16 = 79
	UsageReportWithinSessionReportRequest                            uint16 = 80
	URRID                                                            uint16 = 81
	LinkedURRID                                                      uint16 = 82
	DownlinkDataReport                                               uint16 = 83
	OuterHeaderCreation                                              uint16 = 84
	CreateBAR                                                        uint16 = 85
	UpdateBARWithinSessionModificationRequest                        uint16 = 86
	RemoveBAR                                                        uint16 = 87
	BARID                                                            uint16 = 88
	CPFunctionFeatures                                               uint16 = 89
	UsageInformation                                                 uint16 = 90
	ApplicationInstanceID                                            uint16 = 91
	FlowInformation                                                  uint16 = 92
	UEIPAddress                                                      uint16 = 93
	PacketRate                                                       uint16 = 94
	OuterHeaderRemoval                                               uint16 = 95
	RecoveryTimeStamp                                                uint16 = 96
	DLFlowLevelMarking                                               uint16 = 97
	HeaderEnrichment                                                 uint16 = 98
	ErrorIndicationReport                                            uint16 = 99
	MeasurementInformation                                           uint16 = 100
	NodeReportType                                                   uint16 = 101
	UserPlanePathFailureReport                                       uint16 = 102
	RemoteGTPUPeer                                                   uint16 = 103
	URSEQN                                                           uint16 = 104
	UpdateDuplicatingParameters                                      uint16 = 105
	ActivatePredefinedRules                                          uint16 = 106
	DeactivatePredefinedRules                                        uint16 = 107
	FARID                                                            uint16 = 108
	QERID                                                            uint16 = 109
	OCIFlags                                                         uint16 = 110
	PFCPAssociationReleaseRequest                                    uint16 = 111
	GracefulReleasePeriod                                            uint16 = 112
	PDNType                                                          uint16 = 113
	FailedRuleID                                                     uint16 = 114
	TimeQuotaMechanism                                               uint16 = 115
	UserPlaneIPResourceInformation                                   uint16 = 116
	UserPlaneInactivityTimer                                         uint16 = 117
	AggregatedURRs                                                   uint16 = 118
	Multiplier                                                       uint16 = 119
	AggregatedURRID                                                  uint16 = 120
	SubsequentVolumeQuota                                            uint16 = 121
	SubsequentTimeQuota                                              uint16 = 122
	RQI                                                              uint16 = 123
	QFI                                                              uint16 = 124
	QueryURRReference                                                uint16 = 125
	AdditionalUsageReportsInformation                                uint16 = 126
	CreateTrafficEndpoint                                            uint16 = 127
	CreatedTrafficEndpoint                                           uint16 = 128
	UpdateTrafficEndpoint                                            uint16 = 129
	RemoveTrafficEndpoint                                            uint16 = 130
	TrafficEndpointID                                                uint16 = 131
	EthernetPacketFilter                                             uint16 = 132
	MACAddress                                                       uint16 = 133
	CTAG                                                             uint16 = 134
	STAG                                                             uint16 = 135
	Ethertype                                                        uint16 = 136
	Proxying                                                         uint16 = 137
	EthernetFilterID                                                 uint16 = 138
	EthernetFilterProperties                                         uint16 = 139
	SuggestedBufferingPacketsCount                                   uint16 = 140
	UserID                                                           uint16 = 141
	EthernetPDUSessionInformation                                    uint16 = 142
	EthernetTrafficInformation                                       uint16 = 143
	MACAddressesDetected                                             uint16 = 144
	MACAddressesRemoved                                              uint16 = 145
	EthernetInactivityTimer                                          uint16 = 146
	AdditionalMonitoringTime                                         uint16 = 147
	EventQuota                                                       uint16 = 148
	EventThreshold                                                   uint16 = 149
	SubsequentEventQuota                                             uint16 = 150
	SubsequentEventThreshold                                         uint16 = 151
	TraceInformation                                                 uint16 = 152
	FramedRoute                                                      uint16 = 153
	FramedRouting                                                    uint16 = 154
	FramedIPv6Route                                                  uint16 = 155
	EventTimeStamp                                                   uint16 = 156
	AveragingWindow                                                  uint16 = 157
	PagingPolicyIndicator                                            uint16 = 158
	APNDNN                                                           uint16 = 159
	TGPPInterfaceType                                                uint16 = 160
	PFCPSRReqFlags                                                   uint16 = 161
	PFCPAUReqFlags                                                   uint16 = 162
	ActivationTime                                                   uint16 = 163
	DeactivationTime                                                 uint16 = 164
	CreateMAR                                                        uint16 = 165
	TGPPAccessForwardingActionInformation                            uint16 = 166
	NonTGPPAccessForwardingActionInformation                         uint16 = 167
	RemoveMAR                                                        uint16 = 168
	UpdateMAR                                                        uint16 = 169
	MARID                                                            uint16 = 170
	SteeringFunctionality                                            uint16 = 171
	SteeringMode                                                     uint16 = 172
	Weight                                                           uint16 = 173
	Priority                                                         uint16 = 174
	UpdateTGPPAccessForwardingActionInformation                      uint16 = 175
	UpdateNonTGPPAccessForwardingActionInformation                   uint16 = 176
	UEIPAddressPoolIdentity                                          uint16 = 177
	AlternativeSMFIPAddress                                          uint16 = 178
	PacketReplicationAndDetectionCarryOnInformation                  uint16 = 179
	SMFSetID                                                         uint16 = 180
	QuotaValidityTime                                                uint16 = 181
	NumberOfReports                                                  uint16 = 182
	PFCPSessionRetentionInformation                                  uint16 = 183
	PFCPASRspFlags                                                   uint16 = 184
	CPPFCPEntityIPAddress                                            uint16 = 185
	PFCPSEReqFlags                                                   uint16 = 186
	UserPlanePathRecoveryReport                                      uint16 = 187
	IPMulticastAddressingInfo                                        uint16 = 188
	JoinIPMulticastInformationWithinUsageReport                      uint16 = 189
	LeaveIPMulticastInformationWithinUsageReport                     uint16 = 190
	IPMulticastAddress                                               uint16 = 191
	SourceIPAddress                                                  uint16 = 192
	PacketRateStatus                                                 uint16 = 193
	CreateBridgeInfoForTSC                                           uint16 = 194
	CreatedBridgeInfoForTSC                                          uint16 = 195
	DSTTPortNumber                                                   uint16 = 196
	NWTTPortNumber                                                   uint16 = 197
	TSNBridgeID                                                      uint16 = 198
	TSCManagementInformationWithinSessionModificationRequest         uint16 = 199
	TSCManagementInformationWithinSessionModificationResponse        uint16 = 200
	TSCManagementInformationWithinSessionReportRequest               uint16 = 201
	PortManagementInformationForTSCWithinSessionModificationRequest  uint16 = 199  
	PortManagementInformationForTSCWithinSessionModificationResponse uint16 = 200  
	PortManagementInformationForTSCWithinSessionReportRequest        uint16 = 201  
	PortManagementInformationContainer                               uint16 = 202
	ClockDriftControlInformation                                     uint16 = 203
	RequestedClockDriftInformation                                   uint16 = 204
	ClockDriftReport                                                 uint16 = 205
	TSNTimeDomainNumber                                              uint16 = 206
	TimeOffsetThreshold                                              uint16 = 207
	CumulativeRateRatioThreshold                                     uint16 = 208
	TimeOffsetMeasurement                                            uint16 = 209
	CumulativeRateRatioMeasurement                                   uint16 = 210
	RemoveSRR                                                        uint16 = 211
	CreateSRR                                                        uint16 = 212
	UpdateSRR                                                        uint16 = 213
	SessionReport                                                    uint16 = 214
	SRRID                                                            uint16 = 215
	AccessAvailabilityControlInformation                             uint16 = 216
	RequestedAccessAvailabilityInformation                           uint16 = 217
	AccessAvailabilityReport                                         uint16 = 218
	AccessAvailabilityInformation                                    uint16 = 219
	ProvideATSSSControlInformation                                   uint16 = 220
	ATSSSControlParameters                                           uint16 = 221
	MPTCPControlInformation                                          uint16 = 222
	ATSSSLLControlInformation                                        uint16 = 223
	PMFControlInformation                                            uint16 = 224
	MPTCPParameters                                                  uint16 = 225
	ATSSSLLParameters                                                uint16 = 226
	PMFParameters                                                    uint16 = 227
	MPTCPAddressInformation                                          uint16 = 228
	UELinkSpecificIPAddress                                          uint16 = 229
	PMFAddressInformation                                            uint16 = 230
	ATSSSLLInformation                                               uint16 = 231
	DataNetworkAccessIdentifier                                      uint16 = 232
	UEIPAddressPoolInformation                                       uint16 = 233
	AveragePacketDelay                                               uint16 = 234
	MinimumPacketDelay                                               uint16 = 235
	MaximumPacketDelay                                               uint16 = 236
	QoSReportTrigger                                                 uint16 = 237
	GTPUPathQoSControlInformation                                    uint16 = 238
	GTPUPathQoSReport                                                uint16 = 239
	QoSInformationInGTPUPathQoSReport                                uint16 = 240
	GTPUPathInterfaceType                                            uint16 = 241
	QoSMonitoringPerQoSFlowControlInformation                        uint16 = 242
	RequestedQoSMonitoring                                           uint16 = 243
	ReportingFrequency                                               uint16 = 244
	PacketDelayThresholds                                            uint16 = 245
	MinimumWaitTime                                                  uint16 = 246
	QoSMonitoringReport                                              uint16 = 247
	QoSMonitoringMeasurement                                         uint16 = 248
	MTEDTControlInformation                                          uint16 = 249
	DLDataPacketsSize                                                uint16 = 250
	QERControlIndications                                            uint16 = 251
	PacketRateStatusReport                                           uint16 = 252
	NFInstanceID                                                     uint16 = 253
	EthernetContextInformation                                       uint16 = 254
	RedundantTransmissionParameters                                  uint16 = 255
	UpdatedPDR                                                       uint16 = 256
	SNSSAI                                                           uint16 = 257
	IPVersion                                                        uint16 = 258
	PFCPASReqFlags                                                   uint16 = 259
	DataStatus                                                       uint16 = 260
	ProvideRDSConfigurationInformation                               uint16 = 261
	RDSConfigurationInformation                                      uint16 = 262
	QueryPacketRateStatusWithinSessionModificationRequest            uint16 = 263
	PacketRateStatusReportWithinSessionModificationResponse          uint16 = 264
	MPTCPApplicableIndication                                        uint16 = 265
	BridgeManagementInformationContainer                             uint16 = 266
	UEIPAddressUsageInformation                                      uint16 = 267
	NumberOfUEIPAddresses                                            uint16 = 268
	ValidityTimer                                                    uint16 = 269
	RedundantTransmissionForwardingParameters                        uint16 = 270
	TransportDelayReporting                                          uint16 = 271
)
type IE struct {
	Type         uint16
	Length       uint16
	EnterpriseID uint16
	Payload      []byte
	ChildIEs     []*IE
}
func New(itype uint16, data []byte) *IE {
	i := &IE{
		Type:    itype,
		Payload: data,
	}
	i.SetLength()
	return i
}
func NewVendorSpecificIE(itype, eid uint16, data []byte) *IE {
	i := &IE{
		Type:         itype,
		EnterpriseID: eid,
		Payload:      data,
	}
	i.SetLength()
	return i
}
func NewGroupedIE(itype uint16, ies ...*IE) *IE {
	return newGroupedIE(itype, 0, ies...)
}
func NewVendorSpecificGroupedIE(itype, eid uint16, ies ...*IE) *IE {
	return newGroupedIE(itype, eid, ies...)
}
func Parse(b []byte) (*IE, error) {
	i := &IE{}
	if err := i.UnmarshalBinary(b); err != nil {
		return nil, err
	}
	return i, nil
}
func (i *IE) UnmarshalBinary(b []byte) error {
	l := len(b)
	if l < 4 {
		return io.ErrUnexpectedEOF
	}
	i.Type = binary.BigEndian.Uint16(b[0:2])
	i.Length = binary.BigEndian.Uint16(b[2:4])
	offset := 4
	end := int(i.Length)
	if i.IsVendorSpecific() && l >= 6 {
		i.EnterpriseID = binary.BigEndian.Uint16(b[4:6])
		offset += 2
		end -= 2
	}
	if l <= offset {
		return nil
	}
	i.Payload = b[offset : offset+end]
	if i.IsGrouped() {
		var err error
		i.ChildIEs, err = ParseMultiIEs(i.Payload)
		if err != nil {
			return err
		}
	}
	return nil
}
func (i *IE) Marshal() ([]byte, error) {
	b := make([]byte, i.MarshalLen())
	if err := i.MarshalTo(b); err != nil {
		return nil, err
	}
	return b, nil
}
func (i *IE) MarshalTo(b []byte) error {
	l := len(b)
	if l < 4 {
		return ErrInvalidLength
	}
	binary.BigEndian.PutUint16(b[:2], i.Type)
	binary.BigEndian.PutUint16(b[2:4], i.Length)
	offset := 4
	if i.IsVendorSpecific() && l >= 6 {
		binary.BigEndian.PutUint16(b[4:6], i.EnterpriseID)
		offset += 2
	}
	if i.IsGrouped() {
		for _, ie := range i.ChildIEs {
			if err := ie.MarshalTo(b[offset:]); err != nil {
				return err
			}
			offset += ie.MarshalLen()
		}
		return nil
	}
	copy(b[offset:i.MarshalLen()], i.Payload)
	return nil
}
func (i *IE) MarshalLen() int {
	l := 4
	if i.IsVendorSpecific() {
		l += 2
	}
	if i.IsGrouped() {
		for _, ie := range i.ChildIEs {
			l += ie.MarshalLen()
		}
		return l
	}
	return l + len(i.Payload)
}
func (i *IE) SetLength() {
	l := 0
	if i.IsVendorSpecific() {
		l += 2
	}
	i.Length = uint16(l + len(i.Payload))
}
func (i *IE) IsVendorSpecific() bool {
	return i.Type&0x8000 != 0
}
var groupedMap = map[uint16]bool{
	CreatePDR:                            true,
	PDI:                                  true,
	CreateFAR:                            true,
	ForwardingParameters:                 true,
	DuplicatingParameters:                true,
	CreateURR:                            true,
	CreateQER:                            true,
	CreatedPDR:                           true,
	UpdatePDR:                            true,
	UpdateFAR:                            true,
	UpdateForwardingParameters:           true,
	UpdateBARWithinSessionReportResponse: true,
	UpdateURR:                            true,
	UpdateQER:                            true,
	RemovePDR:                            true,
	RemoveFAR:                            true,
	RemoveURR:                            true,
	RemoveQER:                            true,
	LoadControlInformation:               true,
	OverloadControlInformation:           true,
	ApplicationIDsPFDs:                   true,
	PFDContext:                           true,
	ApplicationDetectionInformation:      true,
	QueryURR:                             true,
	UsageReportWithinSessionModificationResponse: true,
	UsageReportWithinSessionDeletionResponse:     true,
	UsageReportWithinSessionReportRequest:        true,
	DownlinkDataReport:                           true,
	CreateBAR:                                    true,
	UpdateBARWithinSessionModificationRequest:    true,
	RemoveBAR:                                                 true,
	ErrorIndicationReport:                                     true,
	UserPlanePathFailureReport:                                true,
	UpdateDuplicatingParameters:                               true,
	AggregatedURRs:                                            true,
	CreateTrafficEndpoint:                                     true,
	CreatedTrafficEndpoint:                                    true,
	UpdateTrafficEndpoint:                                     true,
	RemoveTrafficEndpoint:                                     true,
	EthernetPacketFilter:                                      true,
	EthernetTrafficInformation:                                true,
	AdditionalMonitoringTime:                                  true,
	CreateMAR:                                                 true,
	TGPPAccessForwardingActionInformation:                     true,
	NonTGPPAccessForwardingActionInformation:                  true,
	RemoveMAR:                                                 true,
	UpdateMAR:                                                 true,
	UpdateTGPPAccessForwardingActionInformation:               true,
	UpdateNonTGPPAccessForwardingActionInformation:            true,
	PFCPSessionRetentionInformation:                           true,
	UserPlanePathRecoveryReport:                               true,
	IPMulticastAddressingInfo:                                 true,
	JoinIPMulticastInformationWithinUsageReport:               true,
	LeaveIPMulticastInformationWithinUsageReport:              true,
	CreatedBridgeInfoForTSC:                                   true,
	TSCManagementInformationWithinSessionModificationRequest:  true,
	TSCManagementInformationWithinSessionModificationResponse: true,
	TSCManagementInformationWithinSessionReportRequest:        true,
	ClockDriftControlInformation:                              true,
	ClockDriftReport:                                          true,
	RemoveSRR:                                                 true,
	CreateSRR:                                                 true,
	UpdateSRR:                                                 true,
	SessionReport:                                             true,
	AccessAvailabilityControlInformation:                      true,
	AccessAvailabilityReport:                                  true,
	ProvideATSSSControlInformation:                            true,
	ATSSSControlParameters:                                    true,
	MPTCPParameters:                                           true,
	ATSSSLLParameters:                                         true,
	PMFParameters:                                             true,
	UEIPAddressPoolInformation:                                true,
	GTPUPathQoSControlInformation:                             true,
	GTPUPathQoSReport:                                         true,
	QoSInformationInGTPUPathQoSReport:                         true,
	QoSMonitoringPerQoSFlowControlInformation:                 true,
	QoSMonitoringReport:                                       true,
	PacketRateStatusReport:                                    true,
	EthernetContextInformation:                                true,
	RedundantTransmissionParameters:                           true,
	UpdatedPDR:                                                true,
	ProvideRDSConfigurationInformation:                        true,
	QueryPacketRateStatusWithinSessionModificationRequest:     true,
	PacketRateStatusReportWithinSessionModificationResponse:   true,
	UEIPAddressUsageInformation:                               true,
	RedundantTransmissionForwardingParameters:                 true,
	TransportDelayReporting:                                   true,
}
func (i *IE) IsGrouped() bool {
	_, ok := groupedMap[i.Type]
	return ok
}
func (i *IE) Add(ies ...*IE) {
	if !i.IsGrouped() {
		return
	}
	i.Payload = nil
	i.ChildIEs = append(i.ChildIEs, ies...)
	for _, ie := range i.ChildIEs {
		serialized, err := ie.Marshal()
		if err != nil {
			continue
		}
		i.Payload = append(i.Payload, serialized...)
	}
	i.SetLength()
}
func (i *IE) Remove(typ uint16) {
	if !i.IsGrouped() {
		return
	}
	i.Payload = nil
	newChildren := make([]*IE, len(i.ChildIEs))
	idx := 0
	for _, ie := range i.ChildIEs {
		if ie.Type == typ {
			newChildren = newChildren[:len(newChildren)-1]
			continue
		}
		newChildren[idx] = ie
		idx++
		serialized, err := ie.Marshal()
		if err != nil {
			continue
		}
		i.Payload = append(i.Payload, serialized...)
	}
	i.ChildIEs = newChildren
	i.SetLength()
}
func (i *IE) FindByType(typ uint16) (*IE, error) {
	if !i.IsGrouped() {
		return nil, ErrInvalidType
	}
	for _, ie := range i.ChildIEs {
		if ie.Type == typ {
			return ie, nil
		}
	}
	return nil, ErrIENotFound
}