blob: 511b5c756f713582d680d906e422bba577e640e4 [file] [log] [blame]
Yi Tsengca34e1d2017-07-18 16:16:25 -07001/*
2 * Copyright 2017-present 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
18package org.onlab.packet.dhcp;
19
20import org.onlab.packet.DHCP6;
21import org.onlab.packet.Data;
22import org.onlab.packet.DeserializationException;
23import org.onlab.packet.Deserializer;
24import org.onlab.packet.IPacket;
25import org.onlab.packet.Ip6Address;
26
27import java.nio.ByteBuffer;
28import java.util.Objects;
29
30/**
31 * IA Address option for DHCPv6.
32 * Based on RFC-3315.
33 */
34public final class Dhcp6IaAddressOption extends Dhcp6Option {
35 public static final int DEFAULT_LEN = 24;
36
37 private Ip6Address ip6Address;
38 private int preferredLifetime;
39 private int validLifetime;
40 private IPacket options;
41
42 @Override
43 public short getCode() {
44 return DHCP6.OptionCode.IAADDR.value();
45 }
46
47 @Override
48 public short getLength() {
49 return (short) (options == null ? DEFAULT_LEN : DEFAULT_LEN + options.serialize().length);
50 }
51
52 /**
53 * Sets IPv6 address.
54 *
55 * @param ip6Address the IPv6 address
56 */
57 public void setIp6Address(Ip6Address ip6Address) {
58 this.ip6Address = ip6Address;
59 }
60
61 /**
62 * Sets preferred lifetime.
63 *
64 * @param preferredLifetime the preferred lifetime
65 */
66 public void setPreferredLifetime(int preferredLifetime) {
67 this.preferredLifetime = preferredLifetime;
68 }
69
70 /**
71 * Sets valid lifetime.
72 *
73 * @param validLifetime the valid lifetime
74 */
75 public void setValidLifetime(int validLifetime) {
76 this.validLifetime = validLifetime;
77 }
78
79 /**
80 * Sets options data.
81 *
82 * @param options the options data
83 */
84 public void setOptions(IPacket options) {
85 this.options = options;
86 }
87
88 /**
89 * Gets IPv6 address.
90 *
91 * @return the IPv6 address
92 */
93 public Ip6Address getIp6Address() {
94 return ip6Address;
95 }
96
97 /**
98 * Gets preferred lifetime.
99 *
100 * @return the preferred lifetime
101 */
102 public int getPreferredLifetime() {
103 return preferredLifetime;
104 }
105
106 /**
107 * Gets valid lifetime.
108 *
109 * @return the valid lifetime
110 */
111 public int getValidLifetime() {
112 return validLifetime;
113 }
114
115 /**
116 * Gets options of IA Address option.
117 *
118 * @return the options data
119 */
120 public IPacket getOptions() {
121 return options;
122 }
123
124 public static Deserializer<Dhcp6Option> deserializer() {
125 return (data, offset, length) -> {
126 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
127 Dhcp6Option dhcp6Option =
128 Dhcp6Option.deserializer().deserialize(data, offset, length);
129 iaAddressOption.setPayload(dhcp6Option.getPayload());
130 if (dhcp6Option.getLength() < DEFAULT_LEN) {
131 throw new DeserializationException("Invalid length of IA address option");
132 }
133 ByteBuffer bb = ByteBuffer.wrap(dhcp6Option.getData());
134 byte[] ipv6Addr = new byte[16];
135 bb.get(ipv6Addr);
136 iaAddressOption.ip6Address = Ip6Address.valueOf(ipv6Addr);
137 iaAddressOption.preferredLifetime = bb.getInt();
138 iaAddressOption.validLifetime = bb.getInt();
139
140 // options length of IA Address option
141 int optionsLen = dhcp6Option.getLength() - DEFAULT_LEN;
142 if (optionsLen > 0) {
143 byte[] optionsData = new byte[optionsLen];
144 bb.get(optionsData);
145 iaAddressOption.options =
146 Data.deserializer().deserialize(optionsData, 0, optionsLen);
147 }
148 return iaAddressOption;
149 };
150 }
151
152 @Override
153 public byte[] serialize() {
154 int payloadLen = options == null ? DEFAULT_LEN : DEFAULT_LEN + options.serialize().length;
155 ByteBuffer bb = ByteBuffer.allocate(payloadLen + Dhcp6Option.DEFAULT_LEN);
156 bb.putShort(DHCP6.OptionCode.IAADDR.value());
157 bb.putShort((short) payloadLen);
158 bb.put(ip6Address.toOctets());
159 bb.putInt(preferredLifetime);
160 bb.putInt(validLifetime);
161 if (options != null) {
162 bb.put(options.serialize());
163 }
164 return bb.array();
165 }
166
167 @Override
168 public int hashCode() {
169 return Objects.hash(super.hashCode(), ip6Address, preferredLifetime,
170 validLifetime, options);
171 }
172
173 @Override
174 public boolean equals(Object obj) {
175 if (this == obj) {
176 return true;
177 }
178 if (obj == null) {
179 return false;
180 }
181 if (!(obj instanceof Dhcp6IaAddressOption)) {
182 return false;
183 }
184 final Dhcp6IaAddressOption other = (Dhcp6IaAddressOption) obj;
185
186 return Objects.equals(getCode(), other.getCode()) &&
187 Objects.equals(getLength(), other.getLength()) &&
188 Objects.equals(ip6Address, other.ip6Address) &&
189 Objects.equals(preferredLifetime, other.preferredLifetime) &&
190 Objects.equals(validLifetime, other.validLifetime) &&
191 Objects.equals(options, other.options);
192 }
193
194 @Override
195 public String toString() {
196 return getToStringHelper()
197 .add("ip6Address", ip6Address)
198 .add("preferredLifetime", preferredLifetime)
199 .add("validLifetime", validLifetime)
200 .add("options", options)
201 .toString();
202 }
203}