|  | 
| 1 | 1 | package com.sipgate.udpproxy.udp.payload.gtpv2.ie; | 
| 2 | 2 | 
 | 
| 3 | 3 | import com.sipgate.udpproxy.udp.payload.gtpv2.ie.decoder.BitHelper; | 
| 4 |  | -import com.sipgate.udpproxy.udp.payload.gtpv2.ie.decoder.IpV4V6; | 
|  | 4 | +import com.sipgate.udpproxy.udp.payload.gtpv2.ie.tft.GenericPacketFilterComponent; | 
|  | 5 | + | 
|  | 6 | +import java.util.ArrayList; | 
|  | 7 | +import java.util.List; | 
| 5 | 8 | 
 | 
| 6 | 9 | public class EpsBearerLevelTrafficFlowTemplate extends InformationElement { | 
| 7 | 10 | 	public EpsBearerLevelTrafficFlowTemplate(final byte type, final byte spare, final byte instance, final byte[] payload) { | 
| @@ -35,6 +38,28 @@ public EpsBearerLevelTrafficFlowTemplate setNumberOfPacketFilters(final int numb | 
| 35 | 38 | 		return this; | 
| 36 | 39 | 	} | 
| 37 | 40 | 
 | 
|  | 41 | +	public List<PacketFilter> getPacketFilters() { | 
|  | 42 | +		final var packetFilters = new ArrayList<PacketFilter>(); | 
|  | 43 | +		int offset = 1; | 
|  | 44 | +		for (int i = 0; i < getNumberOfPacketFilters(); i++) { | 
|  | 45 | +			final byte[] packetFilterRaw = new byte[payload[offset + 2] + 3]; | 
|  | 46 | +			System.arraycopy(payload, offset, packetFilterRaw, 0, packetFilterRaw.length); | 
|  | 47 | +			final var packetFilter = new PacketFilter(packetFilterRaw); | 
|  | 48 | +			packetFilters.add(packetFilter); | 
|  | 49 | +			offset += packetFilter.getPacketFilterLength() + 3; | 
|  | 50 | +		} | 
|  | 51 | +		return packetFilters; | 
|  | 52 | +	} | 
|  | 53 | + | 
|  | 54 | +	@Override | 
|  | 55 | +	public String toString() { | 
|  | 56 | +		return "EpsBearerLevelTrafficFlowTemplate{" + | 
|  | 57 | +				"tftOperationCode=" + getTftOperationCodeEnum() + | 
|  | 58 | +				", numberOfPacketFilters=" + getNumberOfPacketFilters() + | 
|  | 59 | +				", packetFilters=" + getPacketFilters() + | 
|  | 60 | +				'}'; | 
|  | 61 | +	} | 
|  | 62 | + | 
| 38 | 63 | 	public enum TftOperationCode { | 
| 39 | 64 | 		IGNORE_THIS_IE(0), | 
| 40 | 65 | 		CREATE_NEW_TFT(1), | 
| @@ -118,91 +143,41 @@ public PacketFilter setPacketFilterLength(final int packetFilterLength) { | 
| 118 | 143 | 			return this; | 
| 119 | 144 | 		} | 
| 120 | 145 | 
 | 
| 121 |  | -		public PacketFilterComponentType getPacketFilterComponentType() { | 
| 122 |  | -			return PacketFilterComponentType.fromCode(BitHelper.toInt(payload[3])); | 
| 123 |  | -		} | 
| 124 |  | - | 
| 125 |  | -		public PacketFilter setPacketFilterComponentType(final PacketFilterComponentType packetFilterComponentType) { | 
| 126 |  | -			payload[3] = (byte) packetFilterComponentType.getCode(); | 
| 127 |  | -			// TODO: set length and re-init payload array based on length | 
| 128 |  | -			return this; | 
| 129 |  | -		} | 
| 130 |  | - | 
| 131 |  | -		public String getIpv4RemoteAddress() { | 
| 132 |  | -			if (getPacketFilterComponentType() != PacketFilterComponentType.IPV4_REMOTE_ADDRESS) { | 
| 133 |  | -				throw new IllegalStateException("Packet filter component type is not IPV4_REMOTE_ADDRESS"); | 
| 134 |  | -			} | 
| 135 |  | - | 
| 136 |  | -			final byte[] ipv4Address = new byte[4]; | 
| 137 |  | -			System.arraycopy(payload, 4, ipv4Address, 0, 4); | 
| 138 |  | - | 
| 139 |  | -			return IpV4V6.decodeV4(ipv4Address); | 
| 140 |  | -		} | 
| 141 |  | - | 
| 142 |  | -		public String getIpv4RemoteAddressMask() { | 
| 143 |  | -			if (getPacketFilterComponentType() != PacketFilterComponentType.IPV4_REMOTE_ADDRESS) { | 
| 144 |  | -				throw new IllegalStateException("Packet filter component type is not IPV4_REMOTE_ADDRESS"); | 
|  | 146 | +		public List<GenericPacketFilterComponent> getPacketFilterComponents() { | 
|  | 147 | +			final var components = new ArrayList<GenericPacketFilterComponent>(); | 
|  | 148 | +			int offset = 3; | 
|  | 149 | +			while (offset < payload.length) { | 
|  | 150 | +				final var componentType = GenericPacketFilterComponent.PacketFilterComponentType.fromCode(payload[offset]); | 
|  | 151 | +				if (componentType == null) { | 
|  | 152 | +					throw new IllegalArgumentException("Unknown packet filter component type: " + payload[offset]); | 
|  | 153 | +				} | 
|  | 154 | +				final var componentLength = componentType.getValueLength() + 1; | 
|  | 155 | +				final var componentPayload = new byte[componentLength]; | 
|  | 156 | +				try { | 
|  | 157 | +					System.arraycopy(payload, offset, componentPayload, 0, componentLength); | 
|  | 158 | +				} catch (final ArrayIndexOutOfBoundsException e) { | 
|  | 159 | +					throw new IllegalArgumentException("Packet filter component length is invalid! Indicated length: " + componentLength + ", actual length: " + (payload.length - offset)); | 
|  | 160 | +				} | 
|  | 161 | +				System.arraycopy(payload, offset, componentPayload, 0, componentLength); | 
|  | 162 | +				final var component = GenericPacketFilterComponent.fromBytes(componentPayload); | 
|  | 163 | +				components.add(component); | 
|  | 164 | +				offset += componentLength; | 
| 145 | 165 | 			} | 
| 146 | 166 | 
 | 
| 147 |  | -			final byte[] ipv4AddressMask = new byte[4]; | 
| 148 |  | -			System.arraycopy(payload, 8, ipv4AddressMask, 0, 4); | 
| 149 |  | - | 
| 150 |  | -			return IpV4V6.decodeV4(ipv4AddressMask); | 
|  | 167 | +			return components; | 
| 151 | 168 | 		} | 
| 152 | 169 | 
 | 
| 153 |  | -		public PacketFilter setIpv4RemoteAddress(final String ipv4RemoteAddress) { | 
| 154 |  | -			if (getPacketFilterComponentType() != PacketFilterComponentType.IPV4_REMOTE_ADDRESS) { | 
| 155 |  | -				throw new IllegalStateException("Packet filter component type is not IPV4_REMOTE_ADDRESS"); | 
| 156 |  | -			} | 
| 157 |  | - | 
| 158 |  | -			final byte[] ipv4Address = IpV4V6.encodeV4(ipv4RemoteAddress); | 
| 159 |  | -			System.arraycopy(ipv4Address, 0, payload, 4, 4); | 
| 160 |  | - | 
| 161 |  | -			return this; | 
|  | 170 | +		@Override | 
|  | 171 | +		public String toString() { | 
|  | 172 | +			return "PacketFilter{" + | 
|  | 173 | +					"packetFilterIdentifier=" + getPacketFilterIdentifier() + | 
|  | 174 | +					", packetFilterDirection=" + getPacketFilterDirection() + | 
|  | 175 | +					", packetFilterEvaluationPrecedence=" + getPacketFilterEvaluationPrecedence() + | 
|  | 176 | +					", packetFilterLength=" + getPacketFilterLength() + | 
|  | 177 | +					", packetFilterComponents=" + getPacketFilterComponents() + | 
|  | 178 | +					'}'; | 
| 162 | 179 | 		} | 
| 163 | 180 | 
 | 
| 164 |  | -		public enum PacketFilterComponentType { | 
| 165 |  | -			IPV4_REMOTE_ADDRESS(16), | 
| 166 |  | -			IPV4_LOCAL_ADDRESS(17), | 
| 167 |  | -			IPV6_REMOTE_ADDRESS(32), | 
| 168 |  | -			IPV6_REMOTE_ADDRESS_PREFIX_LENGTH(33), | 
| 169 |  | -			IPV6_LOCAL_ADDRESS_PREFIX_LENGTH(35), | 
| 170 |  | -			PROTOCOL_IDENTIFIER_NEXT_HEADER(48), | 
| 171 |  | -			SINGLE_LOCAL_PORT(64), | 
| 172 |  | -			LOCAL_PORT_RANGE(65), | 
| 173 |  | -			SINGLE_REMOTE_PORT(80), | 
| 174 |  | -			REMOTE_PORT_RANGE(81), | 
| 175 |  | -			SECURITY_PARAMETER_INDEX(96), | 
| 176 |  | -			TYPE_OF_SERVICE_TRAFFIC_CLASS(112), | 
| 177 |  | -			FLOW_LABEL(128), | 
| 178 |  | -			DESTINATION_MAC_ADDRESS(129), | 
| 179 |  | -			SOURCE_MAC_ADDRESS(130), | 
| 180 |  | -			IEE_802_1Q_C_TAG_VID(131), | 
| 181 |  | -			IEE_802_1Q_S_TAG_VID(132), | 
| 182 |  | -			IEE_802_1Q_C_TAG_PCP(133), | 
| 183 |  | -			IEE_802_1Q_S_TAG_PCP(134), | 
| 184 |  | -			ETHERTYPE(135), | 
| 185 |  | -			; | 
| 186 |  | - | 
| 187 |  | -			private final int code; | 
| 188 |  | - | 
| 189 |  | -			PacketFilterComponentType(final int code) { | 
| 190 |  | -				this.code = code; | 
| 191 |  | -			} | 
| 192 |  | - | 
| 193 |  | -			public int getCode() { | 
| 194 |  | -				return code; | 
| 195 |  | -			} | 
| 196 |  | - | 
| 197 |  | -			public static PacketFilterComponentType fromCode(final int code) { | 
| 198 |  | -				for (final var packetFilterComponentType : values()) { | 
| 199 |  | -					if (packetFilterComponentType.getCode() == code) { | 
| 200 |  | -						return packetFilterComponentType; | 
| 201 |  | -					} | 
| 202 |  | -				} | 
| 203 |  | -				return null; | 
| 204 |  | -			} | 
| 205 |  | -		} | 
| 206 | 181 | 	} | 
| 207 | 182 | 
 | 
| 208 | 183 | } | 
0 commit comments