blob: bb53eba534236b4131c28141b3fefa2936712da9 [file] [log] [blame]
Rusty Eddy1da61a22015-09-01 00:48:58 +00001/*
2 * Copyright 2015 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 */
16package org.onlab.packet;
17
18import java.nio.ByteBuffer;
19
20public class IGMPQuery extends IGMPGroup {
21
22 // Bits and bytes after the group address
23 private byte resv = 0;
24 private boolean sbit = false;
25 private byte qrv = 2;
26 private byte qqic = 0x7d;
27
28 /**
29 * Create IGMP Query message.
30 *
31 * @param gaddr initiaze with a group address.
32 * @param auxInfo auxillary info.
33 */
34 public IGMPQuery(IpAddress gaddr, int auxInfo) {
35 super(gaddr, auxInfo);
36 }
37
38 /**
39 * Create IGMP Query message.
40 */
41 public IGMPQuery() {
42 super();
43 }
44
45 /**
46 * Is the S flag set? Telling adjacent routers to suppress normal timer updates.
47 *
48 * @return true if the flag is set, false otherwise
49 */
50 public boolean isSbit() {
51 return sbit;
52 }
53
54 /**
55 * Set the S flag. Default is false.
56 *
57 * @param sbit true or false
58 */
59 public void setSbit(boolean sbit) {
60 this.sbit = sbit;
61 }
62
63 /**
64 * Get the Querier Robustness Variable.
65 *
Ray Milkey9b36d812015-09-09 15:24:54 -070066 * @return querier robustness value
Rusty Eddy1da61a22015-09-01 00:48:58 +000067 */
68 public byte getQrv() {
69 return qrv;
70 }
71
72 /**
73 * Set the Querier Robustness Variable. Default is 2.
74 *
Ray Milkey9b36d812015-09-09 15:24:54 -070075 * @param qrv new querier robustness value
Rusty Eddy1da61a22015-09-01 00:48:58 +000076 */
77 public void setQrv(byte qrv) {
78 this.qrv = qrv;
79 }
80
81 /**
82 * Get the reserved field. Should be zero, but ignored regardless of it's value.
83 *
84 * @return the reserved field.
85 */
86 public byte getResv() {
87 return resv;
88 }
89
90 /**
91 * Set the reserved field. Should be 0 and ignored by receivers.
92 *
93 * @param resv the reserved field.
94 */
95 public void setResv(byte resv) {
96 this.resv = resv;
97 }
98
99 /**
100 * Serialize this IGMPQuery.
101 *
102 * @param bb the ByteBuffer to write into, positioned at the next spot to be written to.
103 * @return the serialized message
104 */
105 @Override
106 public byte[] serialize(ByteBuffer bb) {
107
108 bb.put(gaddr.toOctets());
109 byte fld = (byte) (0x7 & qrv);
110 bb.put(fld);
111 bb.put(qqic);
112 bb.putShort((short) sources.size());
113 for (IpAddress ipaddr : sources) {
114 bb.put(ipaddr.toOctets());
115 }
116 return bb.array();
117 }
118
119 /**
120 * Deserialize the IGMP Query group structure.
121 *
122 * @param bb ByteBuffer pointing at the IGMP Query group address
123 * @return the IGMP Group object
124 */
125 public IGMPGroup deserialize(ByteBuffer bb) throws DeserializationException {
126
127 gaddr = Ip4Address.valueOf(bb.getInt());
128 byte fld = bb.get();
129
130 // Just ignore the reserved bits
131 resv = 0;
132 this.sbit = ((fld & 0x8) == 0x8);
133 qrv = (byte) (fld & 0x7);
134
135 // QQIC field
136 qqic = bb.get();
137
138 // Get the number of sources.
139 short nsrcs = bb.getShort();
140
141 // Do a sanity check on the amount of space we have in our buffer.
142 int lengthNeeded = (Ip4Address.BYTE_LENGTH * nsrcs);
143 PacketUtils.checkHeaderLength(bb.remaining(), lengthNeeded);
144
145 for (; nsrcs > 0; nsrcs--) {
146 Ip4Address ipaddr = Ip4Address.valueOf(bb.getInt());
147 this.sources.add(ipaddr);
148 }
149 return this;
150 }
151
152 /*
153 * (non-Javadoc)
154 *
155 * @see java.lang.Object#equals()
156 */
157 public boolean equals(Object obj) {
158 if (this == obj) {
159 return true;
160 }
161 if (!(obj instanceof IGMPQuery)) {
162 return false;
163 }
164 IGMPQuery other = (IGMPQuery) obj;
165
166 if (this.sbit != other.sbit) {
167 return false;
168 }
169 if (this.qrv != other.qrv) {
170 return false;
171 }
172 if (this.qqic != other.qqic) {
173 return false;
174 }
175 if (this.sources.size() != other.sources.size()) {
176 return false;
177 }
178
179 // TODO: make these tolerant of order
180 if (!this.sources.equals(other.sources)) {
181 return false;
182 }
183
184 return true;
185 }
186
187 /*
188 * (non-Javadoc)
189 *
190 * @see java.lang.Object#hashCode()
191 */
192 @Override
193 public int hashCode() {
194 final int prime = 2521;
195 int result = super.hashCode();
196 result = prime * result + this.gaddr.hashCode();
197 result = prime * result + this.qqic;
198 result = prime * result + this.qrv;
199 result = prime * result + this.sources.hashCode();
200 return result;
201 }
Ray Milkey9b36d812015-09-09 15:24:54 -0700202}