2 * Copyright (c) 2015 Cable Television Laboratories, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.pcmm.gates.impl;
11 import com.google.common.primitives.Bytes;
12 import org.pcmm.gates.IExtendedClassifier;
13 import org.umu.cops.stack.COPSMsgParser;
15 import java.net.Inet4Address;
16 import java.net.InetAddress;
17 import java.net.UnknownHostException;
18 import java.util.ArrayList;
19 import java.util.List;
22 * Implementation of the IExtendedClassifier interface
24 public class ExtendedClassifier extends Classifier implements IExtendedClassifier {
27 * IPv4 (for this class) and IPv6 (for extended IPv6Classifier) mask. When the address is zero, the mask is
28 * irrelevant else only packets with source IP address 'pkt.ip-src'
29 * will match if (pkt.ip-src AND classifier.ipmask-src) == classifier.ip-src.
31 protected final InetAddress srcMask;
34 * IPv4 (for this class) and IPv6 (for extended IPv6Classifier) mask. When the address is zero, the mask is
35 * irrelevant else only packets with source IP address 'pkt.ip-dst'
36 * will match if (pkt.ip-dst AND classifier.ipmask-dst) == classifier.ip-dst.
38 protected final InetAddress dstMask;
41 * Source Port End specifies the high-end TCP/UDP source port value. See super srcPort for low-end value.
43 protected final short srcPortEnd;
46 * Destination Port End specifies the high-end TCP/UDP source port value. See super dstPort for low-end value.
48 protected final short dstPortEnd;
51 * The classifiers identifier
53 protected final short classifierId;
56 * Enumeration of the activation state
58 protected final ActivationState activationState;
63 protected final Action action;
67 * @param protocol - the protocol being sent through the gate
68 * @param tosOverwrite - ENABLE/DISABLE
69 * @param tosMask - the mask
70 * @param srcAddress - the source IP
71 * @param dstAddress - the destination IP
72 * @param srcPortBegin - the source begin port
73 * @param dstPortBegin - the destination begin port
74 * @param priority - the priority value
75 * @param srcMask - the source IP mask
76 * @param dstMask - the destination IP mask
77 * @param srcPortEnd - the source start port
78 * @param dstPortEnd - the destination end port
79 * @param classifierId - the classifier identifier
80 * @param activationState - denotes the activation state
81 * @param action - the action
83 public ExtendedClassifier(final Protocol protocol, final byte tosOverwrite, final byte tosMask,
84 final Inet4Address srcAddress, final Inet4Address dstAddress, final short srcPortBegin,
85 final short dstPortBegin, final byte priority, final Inet4Address srcMask,
86 final Inet4Address dstMask, final short srcPortEnd, final short dstPortEnd,
87 final short classifierId, final ActivationState activationState, final Action action) {
88 super(IExtendedClassifier.STYPE, protocol, tosOverwrite, tosMask, srcAddress, dstAddress, srcPortBegin,
89 dstPortBegin, priority);
90 if (srcMask == null) throw new IllegalArgumentException("Source IP Mask cannot be null");
91 if (dstMask == null) throw new IllegalArgumentException("Destination IP Mask cannot be null");
92 if (activationState == null) throw new IllegalArgumentException("Activation state must not be null");
93 if (action == null) throw new IllegalArgumentException("Action must not be null");
94 this.srcMask = srcMask;
95 this.dstMask = dstMask;
96 this.srcPortEnd = srcPortEnd;
97 this.dstPortEnd = dstPortEnd;
98 this.classifierId = classifierId;
99 this.activationState = activationState;
100 this.action = action;
104 * Constructor for IPv6Classifier subclass
105 * @param sType - the type of classifier
106 * @param srcAddress - the source IP
107 * @param dstAddress - the destination IP
108 * @param srcPortBegin - the source begin port
109 * @param dstPortBegin - the destination begin port
110 * @param priority - the priority value
111 * @param srcPortEnd - the source start port
112 * @param dstPortEnd - the destination end port
113 * @param classifierId - the classifier identifier
114 * @param activationState - denotes the activation state
115 * @param action - the action
117 protected ExtendedClassifier(final byte sType, final InetAddress srcAddress, final InetAddress dstAddress,
118 final short srcPortBegin, final short dstPortBegin, final byte priority,
119 final short srcPortEnd, final short dstPortEnd, final short classifierId,
120 final ActivationState activationState, final Action action) {
121 super(sType, null, (byte)0, (byte)0, srcAddress, dstAddress, srcPortBegin, dstPortBegin, priority);
122 if (activationState == null) throw new IllegalArgumentException("Activation state must not be null");
123 if (action == null) throw new IllegalArgumentException("Action must not be null");
126 this.srcPortEnd = srcPortEnd;
127 this.dstPortEnd = dstPortEnd;
128 this.classifierId = classifierId;
129 this.activationState = activationState;
130 this.action = action;
134 public InetAddress getIPSourceMask() {
139 public InetAddress getIPDestinationMask() {
144 public short getSourcePortStart() {
145 return super.getSourcePort();
149 public short getSourcePortEnd() {
154 public short getDestinationPortStart() {
155 return super.getDestinationPort();
159 public short getDestinationPortEnd() {
164 public short getClassifierID() {
169 public ActivationState getActivationState() {
170 return activationState;
174 public Action getAction() {
179 protected byte[] getBytes() {
180 final List<Byte> byteList = new ArrayList<>(Bytes.asList(COPSMsgParser.shortToBytes(protocol.getValue())));
181 byteList.add(tosOverwrite);
182 byteList.add(tosMask);
183 byteList.addAll(Bytes.asList(srcAddress.getAddress()));
184 byteList.addAll(Bytes.asList(srcMask.getAddress()));
185 byteList.addAll(Bytes.asList(dstAddress.getAddress()));
186 byteList.addAll(Bytes.asList(dstMask.getAddress()));
187 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPort)));
188 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPortEnd)));
189 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPort)));
190 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPortEnd)));
191 byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(classifierId)));
192 byteList.add(priority);
193 byteList.add(activationState.getValue());
194 byteList.add(action.getByte());
197 byteList.addAll(Bytes.asList((byte) 0, (byte) 0, (byte) 0));
199 return Bytes.toArray(byteList);
203 public boolean equals(final Object o) {
207 if (!(o instanceof ExtendedClassifier)) {
210 if (!super.equals(o)) {
213 final ExtendedClassifier that = (ExtendedClassifier) o;
214 return srcPortEnd == that.srcPortEnd && dstPortEnd == that.dstPortEnd && classifierId == that.classifierId &&
215 activationState == that.activationState && action == that.action &&
216 !(srcMask != null ? !srcMask.equals(that.srcMask) : that.srcMask != null) &&
217 !(dstMask != null ? !dstMask.equals(that.dstMask) : that.dstMask != null);
221 public int hashCode() {
222 int result = super.hashCode();
223 result = 31 * result + (srcMask != null ? srcMask.hashCode() : 0);
224 result = 31 * result + (dstMask != null ? dstMask.hashCode() : 0);
225 result = 31 * result + (int) srcPortEnd;
226 result = 31 * result + (int) dstPortEnd;
227 result = 31 * result + (int) classifierId;
228 result = 31 * result + (int) activationState.getValue();
229 result = 31 * result + (int) action.getByte();
234 * Returns a ExtendedClassifier object from a byte array
235 * @param data - the data to parse
236 * @return - the object or null if cannot be parsed
237 * TODO - make me more robust as exceptions can be swallowed here.
239 public static ExtendedClassifier parse(final byte[] data) {
240 final List<Byte> bytes = new ArrayList<>(Bytes.asList(data));
243 return new ExtendedClassifier(Protocol.valueOf(COPSMsgParser.bytesToShort(data[0], data[1])),
245 (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(4, 8))),
246 (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(8, 12))),
247 COPSMsgParser.bytesToShort(data[20], data[21]), COPSMsgParser.bytesToShort(data[24], data[25]),
248 data[30], (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(12, 16))),
249 (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(16, 20))),
250 COPSMsgParser.bytesToShort(data[22], data[23]), COPSMsgParser.bytesToShort(data[26], data[27]),
251 COPSMsgParser.bytesToShort(data[28], data[29]), ActivationState.valueOf(data[31]),
252 Action.getFromByte(data[32]));
253 } catch (UnknownHostException e) {