blob: 2c9450b687afa9d5f254a27787fccd5533ed8f93 [file] [log] [blame]
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080019package org.onlab.packet.ndp;
20
21import org.onlab.packet.BasePacket;
22import org.onlab.packet.Data;
23import org.onlab.packet.IPacket;
24import org.onlab.packet.Ip6Address;
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080025
26import java.nio.ByteBuffer;
27import java.util.Arrays;
28
29/**
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080030 * Implements ICMPv6 Redirect packet format. (RFC 4861)
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080031 */
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080032public class Redirect extends BasePacket {
33 public static final byte HEADER_LENGTH = 36; // bytes
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080034
35 protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080036 protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH];
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080037
38 /**
39 * Gets target address.
40 *
41 * @return the target IPv6 address
42 */
43 public byte[] getTargetAddress() {
44 return this.targetAddress;
45 }
46
47 /**
48 * Sets target address.
49 *
50 * @param targetAddress the target IPv6 address to set
51 * @return this
52 */
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080053 public Redirect setTargetAddress(final byte[] targetAddress) {
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080054 this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
55 return this;
56 }
57
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080058 /**
59 * Gets destination address.
60 *
61 * @return the destination IPv6 address
62 */
63 public byte[] getDestinationAddress() {
64 return this.destinationAddress;
65 }
66
67 /**
68 * Sets destination address.
69 *
70 * @param destinationAddress the destination IPv6 address to set
71 * @return this
72 */
73 public Redirect setDestinationAddress(final byte[] destinationAddress) {
74 this.destinationAddress = Arrays.copyOfRange(destinationAddress, 0, Ip6Address.BYTE_LENGTH);
75 return this;
76 }
77
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080078 @Override
79 public byte[] serialize() {
80 byte[] payloadData = null;
81 if (this.payload != null) {
82 this.payload.setParent(this);
83 payloadData = this.payload.serialize();
84 }
85
86 int payloadLength = payloadData == null ? 0 : (short) payloadData.length;
87
88 final byte[] data = new byte[HEADER_LENGTH + payloadLength];
89 final ByteBuffer bb = ByteBuffer.wrap(data);
90
91 bb.putInt(0);
92 bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080093 bb.put(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
94
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080095 if (payloadData != null) {
96 bb.put(payloadData);
97 }
98
99 return data;
100 }
101
102 @Override
103 public IPacket deserialize(byte[] data, int offset, int length) {
104 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
105
106 bb.getInt();
107 bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800108 bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800109
110 this.payload = new Data();
111 this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
112 - bb.position());
113 this.payload.setParent(this);
114
115 return this;
116 }
117
118 /*
119 * (non-Javadoc)
120 *
121 * @see java.lang.Object#hashCode()
122 */
123 @Override
124 public int hashCode() {
125 final int prime = 5807;
126 int result = super.hashCode();
127 ByteBuffer bb;
128 bb = ByteBuffer.wrap(this.targetAddress);
129 for (int i = 0; i < 4; i++) {
130 result = prime * result + bb.getInt();
131 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800132 bb = ByteBuffer.wrap(this.destinationAddress);
133 for (int i = 0; i < 4; i++) {
134 result = prime * result + bb.getInt();
135 }
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800136 return result;
137 }
138
139 /*
140 * (non-Javadoc)
141 *
142 * @see java.lang.Object#equals(java.lang.Object)
143 */
144 @Override
145 public boolean equals(final Object obj) {
146 if (this == obj) {
147 return true;
148 }
149 if (!super.equals(obj)) {
150 return false;
151 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800152 if (!(obj instanceof Redirect)) {
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800153 return false;
154 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800155 final Redirect other = (Redirect) obj;
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800156 if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
157 return false;
158 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800159 if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) {
160 return false;
161 }
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800162 return true;
163 }
164}