Bump to odlparent 3.1.0 and yangtools 2.0.3
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / gates / impl / ExtendedClassifier.java
1 /*
2  * Copyright (c) 2015 Cable Television Laboratories, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.pcmm.gates.impl;
10
11 import com.google.common.primitives.Bytes;
12 import org.pcmm.gates.IExtendedClassifier;
13 import org.umu.cops.stack.COPSMsgParser;
14
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;
20
21 /**
22  * Implementation of the IExtendedClassifier interface
23  */
24 public class ExtendedClassifier extends Classifier implements IExtendedClassifier {
25
26     /**
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.
30      */
31     protected final InetAddress srcMask;
32
33     /**
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.
37      */
38     protected final InetAddress dstMask;
39
40     /**
41      * Source Port End specifies the high-end TCP/UDP source port value. See super srcPort for low-end value.
42      */
43     protected final short srcPortEnd;
44
45     /**
46      * Destination Port End specifies the high-end TCP/UDP source port value. See super dstPort for low-end value.
47      */
48     protected final short dstPortEnd;
49
50     /**
51      * The classifiers identifier
52      */
53     protected final short classifierId;
54
55     /**
56      * Enumeration of the activation state
57      */
58     protected final ActivationState activationState;
59
60     /**
61      * The action value
62      */
63     protected final Action action;
64
65     /**
66      * Constructor
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
82      */
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;
101     }
102
103     /**
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
116      */
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");
124         this.srcMask = null;
125         this.dstMask = null;
126         this.srcPortEnd = srcPortEnd;
127         this.dstPortEnd = dstPortEnd;
128         this.classifierId = classifierId;
129         this.activationState = activationState;
130         this.action = action;
131     }
132
133     @Override
134     public InetAddress getIPSourceMask() {
135         return srcMask;
136     }
137
138     @Override
139     public InetAddress getIPDestinationMask() {
140         return dstMask;
141     }
142
143     @Override
144     public short getSourcePortStart() {
145         return super.getSourcePort();
146     }
147
148     @Override
149     public short getSourcePortEnd() {
150         return srcPortEnd;
151     }
152
153     @Override
154     public short getDestinationPortStart() {
155         return super.getDestinationPort();
156     }
157
158     @Override
159     public short getDestinationPortEnd() {
160         return dstPortEnd;
161     }
162
163     @Override
164     public short getClassifierID() {
165         return classifierId;
166     }
167
168     @Override
169     public ActivationState getActivationState() {
170         return activationState;
171     }
172
173     @Override
174     public Action getAction() {
175         return action;
176     }
177
178     @Override
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());
195
196         // reserved padding
197         byteList.addAll(Bytes.asList((byte) 0, (byte) 0, (byte) 0));
198
199         return Bytes.toArray(byteList);
200     }
201
202     @Override
203     public boolean equals(final Object o) {
204         if (this == o) {
205             return true;
206         }
207         if (!(o instanceof ExtendedClassifier)) {
208             return false;
209         }
210         if (!super.equals(o)) {
211             return false;
212         }
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);
218     }
219
220     @Override
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();
230         return result;
231     }
232
233     /**
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.
238      */
239     public static ExtendedClassifier parse(final byte[] data) {
240         final List<Byte> bytes = new ArrayList<>(Bytes.asList(data));
241
242         try {
243             return new ExtendedClassifier(Protocol.valueOf(COPSMsgParser.bytesToShort(data[0], data[1])),
244                     data[2], data[3],
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) {
254             return null;
255         }
256     }
257
258 }