blob: 80c1ea4872852298ded18008c57dd5986f0f2acc [file] [log] [blame]
karthik1977be465a12024-02-20 11:32:37 +05301/*
2 * Copyright 2023-present Open Networking Foundation
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
17package org.onosproject.sflow.impl;
18
19import java.util.LinkedList;
20import java.util.List;
karthik19774bb1ec02024-02-20 22:26:15 +053021import com.google.common.base.MoreObjects;
22import java.util.Objects;
karthik1977be465a12024-02-20 11:32:37 +053023
24import org.onosproject.sflow.SflowSample;
25import org.onlab.packet.Deserializer;
26import org.onlab.packet.BasePacket;
27
28import static com.google.common.base.Preconditions.checkState;
29
30/**
31 * The sFlow Datagram structure permits multiple samples to be included in each
32 * datagram, the sFlow Agent must not wait for a buffer to fill with samples
33 * before sending the sFlow Datagram. sFlow is intended to provide timely
34 * information on traffic
35 * Ref: (A) https://www.ietf.org/rfc/rfc3176.txt
36 * (B) https://sflow.org/sflow_version_5.txt
37 * The Packet Header format is specified as:
38 * <p>
39 * 0 1 2 3
40 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * | sFlow Version Number |
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * | Agent IP Version |
45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 * | Agent IP Address |
47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * | SubAgent ID |
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 * | Sequence Number |
51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 * | System Up Time |
53 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 * | Number of Samples |
55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 * | Sample Data Headers |
57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 */
59
60public final class SflowPacket extends BasePacket {
61
62 private int version; //current supported version is 5
63 private int agentIpVersion; // current supported version 1=v4, 2=v6
64 private String agentAddress; // sflow agent IP address
65 private int subAgentID; //sflow implemented on distributed device
66 private int seqNumber; // To overcome spoofed attacks of spoofed sflow dgrams
67 private int sysUptime; // Milliseconds since device last booted
68 private int numberOfSamples; // number of samplings
69 private List<SflowSample> sFlowsample; // List of sampling data headers
70
71 private SflowPacket(Builder builder) {
72 this.version = builder.version;
73 this.agentIpVersion = builder.agentIpVersion;
74 this.agentAddress = builder.agentAddress;
75 this.subAgentID = builder.subAgentID;
76 this.seqNumber = builder.seqNumber;
77 this.sysUptime = builder.sysUptime;
78 this.numberOfSamples = builder.numberOfSamples;
79 this.sFlowsample = builder.sflowSample;
80 }
81
82
83 /**
84 * Returns Version of Flow entry ; Supported Version 2,4,5.
85 *
86 * @return version number
87 */
88 public int getVersion() {
89 return version;
90 }
91
92 /**
93 * Returns The address type of the address associated with this agent.
94 * Supported Version IPv4
95 *
96 * @return version number
97 */
98 public int getAgentIpVersion() {
99 return agentIpVersion;
100 }
101
102 /**
103 * Returns The IP address associated with this agent ; Supported Version IPv4.
104 * The IP address associated with this agent. In the case of a multi-homed
105 * agent, this should be the loopback address of the agent. The sFlowAgent
106 * address must provide SNMP connectivity to the agent. The address should be an
107 * invariant that does not change as interfaces are reconfigured, enabled,
108 * disabled, added or removed. A manager should be able to use the
109 * sFlowAgentAddress as a unique key that will identify this agent over extended
110 * periods of time so that a history can be maintained.
111 *
112 * @return IP Address
113 */
114 public String getAgentAddress() {
115 return agentAddress;
116 }
117
118 /**
119 * Returns : The sub-agent field is used when an sFlow agent is implemented on a.
120 * distributed architecture and where it is impractical to bring the samples to
121 * a single point for transmission.
122 *
123 * @return IP Address of subAgent
124 */
125 public int getSubAgentID() {
126 return subAgentID;
127 }
128
129 /**
130 * Returns Sequence number of flow entry . Incremented with each flow sample.
131 * generated by this source_id
132 *
133 * @return sequence number
134 */
135 public int getSeqNumber() {
136 return seqNumber;
137 }
138
139 /**
140 * Returns time in milliseconds since this device was first booted.
141 *
142 * @return system up time
143 **/
144 public int getSysUptime() {
145 return sysUptime;
146 }
147
148 /**
149 * Returns number of samplings generated in sFlow datagram.
150 *
151 * @return Number of samplings
152 **/
153
154 public int getNumberSample() {
155 return numberOfSamples;
156 }
157
158 /**
159 * Returns number of samplings generated in sFlow datagram. An sFlow Datagram.
160 * contains lists of Packet Flow Records and counter records. The format of each
161 * Packet Flow Record is identified by a data_format value. The data_format name
162 * space is extensible, allowing for the addition of standard record types as
163 * well as vendor specific extensions.
164 *
165 * @return List of Sample data Headers
166 **/
167 public List<SflowSample> getSampleDataHeaders() {
168 return sFlowsample;
169 }
170
171 /**
172 * Deserializer function for sFlow packets.
173 *
174 * @return deserializer function
175 */
176 public static Deserializer<SflowPacket> deserializer() {
177 return (data, offset, length) -> null;
178 }
179
180 @Override
181 public byte[] serialize() {
182 throw new UnsupportedOperationException("Not supported yet.");
183 }
184
karthik19774bb1ec02024-02-20 22:26:15 +0530185 @Override
186 public int hashCode() {
187 int hash = 3;
188 hash = 59 * hash + this.version;
189 hash = 59 * hash + this.agentIpVersion;
190 hash = 59 * hash + this.seqNumber;
191 hash = 59 * hash + this.subAgentID;
192 hash = 59 * hash + this.sysUptime;
193 hash = 59 * hash + this.numberOfSamples;
194 hash = 59 * hash + Objects.hashCode(this.agentAddress);
195 hash = 59 * hash + Objects.hashCode(this.sFlowsample);
196 return hash;
197 }
198
199 @Override
200 public boolean equals(Object obj) {
201 if (this == obj) {
202 return true;
203 }
204 if (obj == null) {
205 return false;
206 }
207 if (getClass() != obj.getClass()) {
208 return false;
209 }
210 final SflowPacket other = (SflowPacket) obj;
211 if (this.version != other.version) {
212 return false;
213 }
214 if (this.agentIpVersion != other.agentIpVersion) {
215 return false;
216 }
217 if (this.seqNumber != other.seqNumber) {
218 return false;
219 }
220 if (this.subAgentID != other.subAgentID) {
221 return false;
222 }
223 if (this.sysUptime != other.sysUptime) {
224 return false;
225 }
226 if (this.numberOfSamples != other.numberOfSamples) {
227 return false;
228 }
229 return Objects.equals(this.agentAddress, other.agentAddress);
230 }
231
232 @Override
233 public String toString() {
234 return MoreObjects.toStringHelper(getClass())
235 .add("version", version)
236 .add("agentIpVersion", agentIpVersion)
237 .add("seqNumber", seqNumber)
238 .add("subAgentID", subAgentID)
239 .add("sysUptime", sysUptime)
240 .add("numberOfSamples", numberOfSamples)
241 .add("agentAddress", agentAddress)
242 .toString();
243 }
244
karthik1977be465a12024-02-20 11:32:37 +0530245 /**
246 * Builder for sFlow packet.
247 */
248 private static class Builder {
249 private int version;
250 private int agentIpVersion;
251 private String agentAddress;
252 private int subAgentID;
253 private int seqNumber;
254 private int sysUptime;
255 private int numberOfSamples;
256 private List<SflowSample> sflowSample = new LinkedList<>();
257
258 /**
259 * Setter sFlow Version of Flow entry ; Supported Version 2,4,5.
260 *
261 * @param version number.
262 * @return this class builder.
263 */
264 public Builder version(int version) {
265 this.version = version;
266 return this;
267 }
268
269 /**
270 * Setter for The address type of the address associated with this agent.
271 *
272 * @param agent ip version.
273 * @return this class builder.
274 */
275 public Builder agentIpVersion(int agentIpVersion) {
276 this.agentIpVersion = agentIpVersion;
277 return this;
278 }
279
280 /**
281 * Setter The IP address associated with this agent.
282 *
283 * @param IP Address.
284 * @return this class builder.
285 */
286 public Builder agentAddress(String agentAddress) {
287 this.agentAddress = agentAddress;
288 return this;
289 }
290
291 /**
292 * Setter for time in milliseconds since this device was first booted.
293 *
294 * @param agent id.
295 * @return this class builder.
296 */
297 public Builder subAgentID(int subAgentID) {
298 this.subAgentID = subAgentID;
299 return this;
300 }
301
302 /**
303 * Setter for number of samplings generated in sFlow datagram.
304 *
305 * @param Number of samplings.
306 * @return this class builder.
307 */
308 public Builder numberOfSamples(int numberOfSamples) {
309 this.numberOfSamples = numberOfSamples;
310 return this;
311 }
312
313 /**
314 * Setter for time in milliseconds since this device was first booted.
315 *
316 * @param sysUptime system up time.
317 * @return this class builder.
318 */
319 public Builder sysUptime(int sysUptime) {
320 this.sysUptime = sysUptime;
321 return this;
322 }
323
324 /**
325 * Returns Sequence number of flow entry . Incremented with each flow sampling.
326 * generated by this source_id
327 *
328 * @param sequence number.
329 * @return this class builder.
330 */
331 public Builder seqNumber(int seqNumber) {
332 this.seqNumber = seqNumber;
333 return this;
334 }
335
336 /**
337 * Setter for list of samplings.
338 *
339 * @param sflowSample list of samplings.
340 * @return this class builder.
341 */
342 public Builder sflowSample(SflowSample sflowSample) {
343 this.sflowSample.add(sflowSample);
344 return this;
345 }
346
347
348 /**
349 * Checks arguments for sFlow packet.
350 */
351 private void checkArguments() {
352 checkState(version != 0, "Invalid Version.");
353 checkState(agentIpVersion != 0, "Invalid ipVersionAgent.");
354 checkState(subAgentID != 0, "Invalid subAgentID.");
355 checkState(seqNumber != 0, "Invalid SeqNumber.");
356 checkState(sysUptime != 0, "Invalid sysUptime.");
357 }
358
359 /**
360 * Builds sFlow packet.
361 *
362 * @return sflowpacket.
363 */
364 public SflowPacket build() {
365 checkArguments();
366 return new SflowPacket(this);
367 }
368
369 }
370}