blob: a7e7680b607a618e34ffad405e89110377f8c257 [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
Charles M.C. Chan5c0b4762015-01-10 18:38:37 +080086 int payloadLength = 0;
87 if (payloadData != null) {
88 payloadLength = payloadData.length;
89 }
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080090
91 final byte[] data = new byte[HEADER_LENGTH + payloadLength];
92 final ByteBuffer bb = ByteBuffer.wrap(data);
93
94 bb.putInt(0);
95 bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080096 bb.put(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
97
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080098 if (payloadData != null) {
99 bb.put(payloadData);
100 }
101
102 return data;
103 }
104
105 @Override
106 public IPacket deserialize(byte[] data, int offset, int length) {
107 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
108
109 bb.getInt();
110 bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800111 bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800112
113 this.payload = new Data();
114 this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
115 - bb.position());
116 this.payload.setParent(this);
117
118 return this;
119 }
120
121 /*
122 * (non-Javadoc)
123 *
124 * @see java.lang.Object#hashCode()
125 */
126 @Override
127 public int hashCode() {
128 final int prime = 5807;
129 int result = super.hashCode();
130 ByteBuffer bb;
131 bb = ByteBuffer.wrap(this.targetAddress);
132 for (int i = 0; i < 4; i++) {
133 result = prime * result + bb.getInt();
134 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800135 bb = ByteBuffer.wrap(this.destinationAddress);
136 for (int i = 0; i < 4; i++) {
137 result = prime * result + bb.getInt();
138 }
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800139 return result;
140 }
141
142 /*
143 * (non-Javadoc)
144 *
145 * @see java.lang.Object#equals(java.lang.Object)
146 */
147 @Override
148 public boolean equals(final Object obj) {
149 if (this == obj) {
150 return true;
151 }
152 if (!super.equals(obj)) {
153 return false;
154 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800155 if (!(obj instanceof Redirect)) {
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800156 return false;
157 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800158 final Redirect other = (Redirect) obj;
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800159 if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
160 return false;
161 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800162 if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) {
163 return false;
164 }
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800165 return true;
166 }
167}