blob: 3c39df5ab8f226da4d3ced313ce1d799c2533d70 [file] [log] [blame]
Rusty Eddy1da61a22015-09-01 00:48:58 +00001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Rusty Eddy1da61a22015-09-01 00:48:58 +00003 *
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
Ray Milkey0bb1e102016-11-10 14:51:27 -0800124 * @throws DeserializationException on serializer error
Rusty Eddy1da61a22015-09-01 00:48:58 +0000125 */
126 public IGMPGroup deserialize(ByteBuffer bb) throws DeserializationException {
127
128 gaddr = Ip4Address.valueOf(bb.getInt());
129 byte fld = bb.get();
130
131 // Just ignore the reserved bits
132 resv = 0;
133 this.sbit = ((fld & 0x8) == 0x8);
134 qrv = (byte) (fld & 0x7);
135
136 // QQIC field
137 qqic = bb.get();
138
139 // Get the number of sources.
140 short nsrcs = bb.getShort();
141
142 // Do a sanity check on the amount of space we have in our buffer.
143 int lengthNeeded = (Ip4Address.BYTE_LENGTH * nsrcs);
144 PacketUtils.checkHeaderLength(bb.remaining(), lengthNeeded);
145
146 for (; nsrcs > 0; nsrcs--) {
147 Ip4Address ipaddr = Ip4Address.valueOf(bb.getInt());
148 this.sources.add(ipaddr);
149 }
150 return this;
151 }
152
153 /*
154 * (non-Javadoc)
155 *
156 * @see java.lang.Object#equals()
157 */
158 public boolean equals(Object obj) {
159 if (this == obj) {
160 return true;
161 }
162 if (!(obj instanceof IGMPQuery)) {
163 return false;
164 }
165 IGMPQuery other = (IGMPQuery) obj;
166
167 if (this.sbit != other.sbit) {
168 return false;
169 }
170 if (this.qrv != other.qrv) {
171 return false;
172 }
173 if (this.qqic != other.qqic) {
174 return false;
175 }
176 if (this.sources.size() != other.sources.size()) {
177 return false;
178 }
179
180 // TODO: make these tolerant of order
181 if (!this.sources.equals(other.sources)) {
182 return false;
183 }
184
185 return true;
186 }
187
188 /*
189 * (non-Javadoc)
190 *
191 * @see java.lang.Object#hashCode()
192 */
193 @Override
194 public int hashCode() {
195 final int prime = 2521;
196 int result = super.hashCode();
197 result = prime * result + this.gaddr.hashCode();
198 result = prime * result + this.qqic;
199 result = prime * result + this.qrv;
200 result = prime * result + this.sources.hashCode();
201 return result;
202 }
Ray Milkey9b36d812015-09-09 15:24:54 -0700203}