1 package org.openflow.codec.protocol;
3 import java.util.Arrays;
5 import org.openflow.codec.io.IDataBuffer;
6 import org.openflow.codec.util.U16;
7 import org.openflow.codec.util.U8;
10 * Represents an ofp_packet_in
12 * @author David Erickson (daviderickson@cs.stanford.edu) - Feb 8, 2010
15 public class OFPPacketIn extends OFPMessage {
16 public static int MINIMUM_LENGTH = 32;
17 public static int MINIMUM_LENGTH_WITHOUT_MATCH = MINIMUM_LENGTH - 8;
19 public enum OFPacketInReason {
20 NO_MATCH, ACTION, INVALID_TTL
23 protected int bufferId;
24 protected short totalLength;
25 protected OFPacketInReason reason;
26 protected byte tableId;
27 protected long cookie;
28 protected OFPMatch match;
29 protected byte[] packetData;
31 public OFPPacketIn() {
33 this.type = OFPType.PACKET_IN;
34 this.length = U16.t(MINIMUM_LENGTH);
42 public int getBufferId() {
51 public OFPPacketIn setBufferId(int bufferId) {
52 this.bufferId = bufferId;
57 * Returns the packet data
61 public byte[] getPacketData() {
62 return this.packetData;
66 * Sets the packet data, and updates the length of this message
70 public OFPPacketIn setPacketData(byte[] packetData) {
71 this.packetData = packetData;
76 private void updateLength() {
77 short matchLength = (null == match) ? 0 : match.getLengthWithPadding();
78 int packetDataLength = (null == packetData) ? 0 : packetData.length;
79 int len = OFPPacketIn.MINIMUM_LENGTH_WITHOUT_MATCH + matchLength + packetDataLength;
80 this.length = (short) len;
88 public OFPacketInReason getReason() {
97 public OFPPacketIn setReason(OFPacketInReason reason) {
107 public byte getTableId() {
116 public void setTableId(byte tableId) {
117 this.tableId = tableId;
125 public long getCookie() {
134 public void setCookie(long cookie) {
135 this.cookie = cookie;
143 public OFPMatch getMatch() {
152 public void setMatch(OFPMatch match) {
162 public short getTotalLength() {
163 return this.totalLength;
171 public OFPPacketIn setTotalLength(short totalLength) {
172 this.totalLength = totalLength;
177 public void readFrom(IDataBuffer data) {
178 super.readFrom(data);
179 this.bufferId = data.getInt();
180 this.totalLength = data.getShort();
181 this.reason = OFPacketInReason.values()[U8.f(data.get())];
182 this.tableId = data.get();
183 this.cookie = data.getLong();
184 this.match = new OFPMatch();
185 match.readFrom(data);
186 // TBD - how to handle the padding here
187 data.getShort(); // pad
188 this.packetData = new byte[getLengthU() - OFPPacketIn.MINIMUM_LENGTH_WITHOUT_MATCH
189 - match.getLengthWithPadding()];
190 data.get(this.packetData);
194 public void writeTo(IDataBuffer data) {
196 data.putInt(bufferId);
197 data.putShort(totalLength);
198 data.put((byte) reason.ordinal());
200 data.putLong(cookie);
204 data.putShort((short) 0); // pad
205 data.put(this.packetData);
209 public int hashCode() {
210 final int prime = 283;
211 int result = super.hashCode();
212 result = prime * result + bufferId;
213 result = prime * result + tableId;
214 result = prime * result + (int) (cookie ^ (cookie >>> 32));
215 result = prime * result + ((null == match) ? 0 : match.hashCode());
216 result = prime * result + Arrays.hashCode(packetData);
217 result = prime * result + ((reason == null) ? 0 : reason.hashCode());
218 result = prime * result + totalLength;
223 public boolean equals(Object obj) {
227 if (!super.equals(obj)) {
230 if (!(obj instanceof OFPPacketIn)) {
233 OFPPacketIn other = (OFPPacketIn) obj;
234 if (bufferId != other.bufferId) {
237 if (tableId != other.tableId) {
241 if (other.match != null) {
244 } else if (!match.equals(other.match)) {
247 if (!Arrays.equals(packetData, other.packetData)) {
250 if (reason == null) {
251 if (other.reason != null) {
254 } else if (!reason.equals(other.reason)) {
257 if (totalLength != other.totalLength) {