2 * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
5 package org.pcmm.gates.impl;
7 import com.google.common.primitives.Bytes;
8 import org.pcmm.gates.IExtendedClassifier;
9 import org.umu.cops.stack.COPSMsgParser;
11 import java.net.Inet4Address;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
15 import java.util.List;
18 * Implementation of the IExtendedClassifier interface
20 public class ExtendedClassifier extends Classifier implements IExtendedClassifier {
23 * IPv4 (for this class) and IPv6 (for extended IPv6Classifier) mask. When the address is zero, the mask is
24 * irrelevant else only packets with source IP address 'pkt.ip-src'
25 * will match if (pkt.ip-src AND classifier.ipmask-src) == classifier.ip-src.
27 protected final InetAddress srcMask;
30 * IPv4 (for this class) and IPv6 (for extended IPv6Classifier) mask. When the address is zero, the mask is
31 * irrelevant else only packets with source IP address 'pkt.ip-dst'
32 * will match if (pkt.ip-dst AND classifier.ipmask-dst) == classifier.ip-dst.
34 protected final InetAddress dstMask;
37 * Source Port End specifies the high-end TCP/UDP source port value. See super srcPort for low-end value.
39 protected final short srcPortEnd;
42 * Destination Port End specifies the high-end TCP/UDP source port value. See super dstPort for low-end value.
44 protected final short dstPortEnd;
47 * The classifiers identifier
49 protected final short classifierId;
52 * Enumeration of the activation state
54 protected final ActivationState activationState;
59 protected final Action action;
63 * @param protocol - the protocol being sent through the gate
64 * @param tosOverwrite - ENABLE/DISABLE
65 * @param tosMask - the mask
66 * @param srcAddress - the source IP
67 * @param dstAddress - the destination IP
68 * @param srcPortBegin - the source begin port
69 * @param dstPortBegin - the destination begin port
70 * @param priority - the priority value
71 * @param srcMask - the source IP mask
72 * @param dstMask - the destination IP mask
73 * @param srcPortEnd - the source start port
74 * @param dstPortEnd - the destination end port
75 * @param classifierId - the classifier identifier
76 * @param activationState - denotes the activation state
77 * @param action - the action
79 public ExtendedClassifier(final Protocol protocol, final byte tosOverwrite, final byte tosMask,
80 final Inet4Address srcAddress, final Inet4Address dstAddress, final short srcPortBegin,
81 final short dstPortBegin, final byte priority, final Inet4Address srcMask,
82 final Inet4Address dstMask, final short srcPortEnd, final short dstPortEnd,
83 final short classifierId, final ActivationState activationState, final Action action) {
84 super(IExtendedClassifier.STYPE, protocol, tosOverwrite, tosMask, srcAddress, dstAddress, srcPortBegin,
85 dstPortBegin, priority);
86 if (srcMask == null) throw new IllegalArgumentException("Source IP Mask cannot be null");
87 if (dstMask == null) throw new IllegalArgumentException("Destination IP Mask cannot be null");
88 if (activationState == null) throw new IllegalArgumentException("Activation state must not be null");
89 if (action == null) throw new IllegalArgumentException("Action must not be null");
90 this.srcMask = srcMask;
91 this.dstMask = dstMask;
92 this.srcPortEnd = srcPortEnd;
93 this.dstPortEnd = dstPortEnd;
94 this.classifierId = classifierId;
95 this.activationState = activationState;
100 * Constructor for IPv6Classifier subclass
101 * @param sType - the type of classifier
102 * @param srcAddress - the source IP
103 * @param dstAddress - the destination IP
104 * @param srcPortBegin - the source begin port
105 * @param dstPortBegin - the destination begin port
106 * @param priority - the priority value
107 * @param srcPortEnd - the source start port
108 * @param dstPortEnd - the destination end port
109 * @param classifierId - the classifier identifier
110 * @param activationState - denotes the activation state
111 * @param action - the action
113 protected ExtendedClassifier(final byte sType, final InetAddress srcAddress, final InetAddress dstAddress,
114 final short srcPortBegin, final short dstPortBegin, final byte priority,
115 final short srcPortEnd, final short dstPortEnd, final short classifierId,
116 final ActivationState activationState, final Action action) {
117 super(sType, null, (byte)0, (byte)0, srcAddress, dstAddress, srcPortBegin, dstPortBegin, priority);
118 if (activationState == null) throw new IllegalArgumentException("Activation state must not be null");
119 if (action == null) throw new IllegalArgumentException("Action must not be null");
122 this.srcPortEnd = srcPortEnd;
123 this.dstPortEnd = dstPortEnd;
124 this.classifierId = classifierId;
125 this.activationState = activationState;
126 this.action = action;
130 public InetAddress getIPSourceMask() {
135 public InetAddress getIPDestinationMask() {
140 public short getSourcePortStart() {
141 return super.getSourcePort();
145 public short getSourcePortEnd() {
150 public short getDestinationPortStart() {
151 return super.getDestinationPort();
155 public short getDestinationPortEnd() {
160 public short getClassifierID() {
165 public ActivationState getActivationState() {
166 return activationState;
170 public Action getAction() {
175 protected byte[] getBytes() {
176 final List<Byte> byteList = new ArrayList<>(Bytes.asList(COPSMsgParser.shortToBytes(protocol.getValue())));
177 byteList.add(tosOverwrite);
178 byteList.add(tosMask);
179 byteList.addAll(Bytes.asList(srcAddress.getAddress()));
180 byteList.addAll(Bytes.asList(srcMask.getAddress()));
181 byteList.addAll(Bytes.asList(dstAddress.getAddress()));
182 byteList.addAll(Bytes.asList(dstMask.getAddress()));
183 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPort)));
184 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPortEnd)));
185 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPort)));
186 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPortEnd)));
187 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(classifierId)));
188 byteList.add(priority);
189 byteList.add(activationState.getValue());
190 byteList.add(action.getByte());
193 byteList.addAll(Bytes.asList((byte) 0, (byte) 0, (byte) 0));
195 return Bytes.toArray(byteList);
199 public boolean equals(final Object o) {
203 if (!(o instanceof ExtendedClassifier)) {
206 if (!super.equals(o)) {
209 final ExtendedClassifier that = (ExtendedClassifier) o;
210 return srcPortEnd == that.srcPortEnd && dstPortEnd == that.dstPortEnd && classifierId == that.classifierId &&
211 activationState == that.activationState && action == that.action &&
212 !(srcMask != null ? !srcMask.equals(that.srcMask) : that.srcMask != null) &&
213 !(dstMask != null ? !dstMask.equals(that.dstMask) : that.dstMask != null);
217 public int hashCode() {
218 int result = super.hashCode();
219 result = 31 * result + (srcMask != null ? srcMask.hashCode() : 0);
220 result = 31 * result + (dstMask != null ? dstMask.hashCode() : 0);
221 result = 31 * result + (int) srcPortEnd;
222 result = 31 * result + (int) dstPortEnd;
223 result = 31 * result + (int) classifierId;
224 result = 31 * result + (int) activationState.getValue();
225 result = 31 * result + (int) action.getByte();
230 * Returns a ExtendedClassifier object from a byte array
231 * @param data - the data to parse
232 * @return - the object or null if cannot be parsed
233 * TODO - make me more robust as exceptions can be swallowed here.
235 public static ExtendedClassifier parse(final byte[] data) {
236 final List<Byte> bytes = new ArrayList<>(Bytes.asList(data));
239 return new ExtendedClassifier(Protocol.valueOf(COPSMsgParser.bytesToShort(data[0], data[1])),
241 (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(4, 8))),
242 (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(8, 12))),
243 COPSMsgParser.bytesToShort(data[20], data[21]), COPSMsgParser.bytesToShort(data[24], data[25]),
244 data[30], (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(12, 16))),
245 (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(16, 20))),
246 COPSMsgParser.bytesToShort(data[22], data[23]), COPSMsgParser.bytesToShort(data[26], data[27]),
247 COPSMsgParser.bytesToShort(data[28], data[29]), ActivationState.valueOf(data[31]),
248 Action.getFromByte(data[32]));
249 } catch (UnknownHostException e) {