]> git.ipfire.org Git - thirdparty/squid.git/blob - src/snmp/Var.cc
4140309a7059532a64eb2355d74f01fd0d78c16c
[thirdparty/squid.git] / src / snmp / Var.cc
1 /*
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 /* DEBUG: section 49 SNMP Interface */
10
11 #include "squid.h"
12 #include "base/TextException.h"
13 #include "Debug.h"
14 #include "ipc/TypedMsgHdr.h"
15 #include "snmp/Var.h"
16 #include "tools.h"
17
18 #include <algorithm>
19
20 Snmp::Var::Var()
21 {
22 init();
23 }
24
25 Snmp::Var::Var(const Var& var)
26 {
27 init();
28 assign(var);
29 }
30
31 Snmp::Var::~Var()
32 {
33 clear();
34 }
35
36 Snmp::Var&
37 Snmp::Var::operator = (const Var& var)
38 {
39 clear();
40 assign(var);
41 return *this;
42 }
43
44 void
45 Snmp::Var::init()
46 {
47 memset(static_cast<variable_list *>(this), 0, sizeof(variable_list));
48 }
49
50 Snmp::Var&
51 Snmp::Var::operator += (const Var& var)
52 {
53 switch (type) {
54 case SMI_INTEGER:
55 setInt(asInt() + var.asInt());
56 break;
57 case SMI_GAUGE32:
58 setGauge(asGauge() + var.asGauge());
59 break;
60 case SMI_COUNTER32:
61 setCounter(asCounter() + var.asCounter());
62 break;
63 case SMI_COUNTER64:
64 setCounter64(asCounter64() + var.asCounter64());
65 break;
66 case SMI_TIMETICKS:
67 setTimeTicks(asTimeTicks() + var.asTimeTicks());
68 break;
69 default:
70 debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
71 throw TexcHere("Unsupported type");
72 break;
73 }
74 return *this;
75 }
76
77 Snmp::Var&
78 Snmp::Var::operator /= (int num)
79 {
80 Must(num != 0);
81 switch (type) {
82 case SMI_INTEGER:
83 setInt(asInt() / num);
84 break;
85 case SMI_GAUGE32:
86 setGauge(asGauge() / num);
87 break;
88 case SMI_COUNTER32:
89 setCounter(asCounter() / num);
90 break;
91 case SMI_COUNTER64:
92 setCounter64(asCounter64() / num);
93 break;
94 case SMI_TIMETICKS:
95 setTimeTicks(asTimeTicks() / num);
96 break;
97 default:
98 debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
99 throw TexcHere("Unsupported type");
100 break;
101 }
102 return *this;
103 }
104
105 bool
106 Snmp::Var::operator < (const Var& var) const
107 {
108 switch (type) {
109 case SMI_INTEGER:
110 return asInt() < var.asInt();
111 case SMI_GAUGE32:
112 return asGauge() < var.asGauge();
113 case SMI_COUNTER32:
114 return asCounter() < var.asCounter();
115 case SMI_COUNTER64:
116 return asCounter64() < var.asCounter64();
117 case SMI_TIMETICKS:
118 return asTimeTicks() < var.asTimeTicks();
119 default:
120 debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
121 throw TexcHere("Unsupported type");
122 break;
123 }
124 return false; // unreachable
125 }
126
127 bool
128 Snmp::Var::operator > (const Var& var) const
129 {
130 switch (type) {
131 case SMI_INTEGER:
132 return asInt() > var.asInt();
133 case SMI_GAUGE32:
134 return asGauge() > var.asGauge();
135 case SMI_COUNTER32:
136 return asCounter() > var.asCounter();
137 case SMI_COUNTER64:
138 return asCounter64() > var.asCounter64();
139 case SMI_TIMETICKS:
140 return asTimeTicks() > var.asTimeTicks();
141 default:
142 debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
143 throw TexcHere("Unsupported type");
144 break;
145 }
146 return false; // unreachable
147 }
148
149 void
150 Snmp::Var::assign(const Var& var)
151 {
152 setName(var.getName());
153 copyValue(var);
154 }
155
156 void
157 Snmp::Var::clearName()
158 {
159 xfree(name);
160 name = nullptr;
161 name_length = 0;
162 }
163
164 Range<const oid*>
165 Snmp::Var::getName() const
166 {
167 return Range<const oid*>(name, name + name_length);
168 }
169
170 void
171 Snmp::Var::setName(const Range<const oid*>& aName)
172 {
173 clearName();
174 if (aName.start != NULL && aName.size() != 0) {
175 name_length = aName.size();
176 name = static_cast<oid*>(xmalloc(name_length * sizeof(oid)));
177 std::copy(aName.start, aName.end, name);
178 }
179 }
180
181 void
182 Snmp::Var::clearValue()
183 {
184 xfree(val.string);
185 val.string = nullptr;
186 val_len = 0;
187 type = 0;
188 }
189
190 bool
191 Snmp::Var::isNull() const
192 {
193 return type == SMI_NULLOBJ;
194 }
195
196 int
197 Snmp::Var::asInt() const
198 {
199 Must(type == SMI_INTEGER);
200 Must(val.integer != NULL && val_len == sizeof(int));
201 return *val.integer;
202 }
203
204 unsigned int
205 Snmp::Var::asGauge() const
206 {
207 Must(type == SMI_GAUGE32);
208 Must(val.integer != NULL && val_len == 4);
209 return *reinterpret_cast<unsigned int*>(val.integer);
210 }
211
212 int
213 Snmp::Var::asCounter() const
214 {
215 Must(type == SMI_COUNTER32);
216 Must(val.integer != NULL && val_len == 4);
217 return *reinterpret_cast<int*>(val.integer);
218 }
219
220 long long int
221 Snmp::Var::asCounter64() const
222 {
223 Must(type == SMI_COUNTER64);
224 Must(val.integer != NULL && val_len == 8);
225 return *reinterpret_cast<long long int*>(val.integer);
226 }
227
228 unsigned int
229 Snmp::Var::asTimeTicks() const
230 {
231 Must(type == SMI_TIMETICKS);
232 Must(val.integer != NULL && val_len == sizeof(unsigned int));
233 return *reinterpret_cast<unsigned int*>(val.integer);
234 }
235
236 Range<const oid*>
237 Snmp::Var::asObject() const
238 {
239 Must(type == SMI_OBJID);
240 Must(val_len % sizeof(oid) == 0);
241 int length = val_len / sizeof(oid);
242 Must(val.objid != NULL && length > 0);
243 return Range<const oid*>(val.objid, val.objid + length);
244 }
245
246 Range<const u_char*>
247 Snmp::Var::asString() const
248 {
249 Must(type == SMI_STRING);
250 Must(val.string != NULL && val_len > 0);
251 return Range<const u_char*>(val.string, val.string + val_len);
252 }
253
254 void
255 Snmp::Var::setInt(int value)
256 {
257 setValue(&value, sizeof(value), SMI_INTEGER);
258 }
259
260 void
261 Snmp::Var::setCounter(int value)
262 {
263 setValue(&value, sizeof(value), SMI_COUNTER32);
264 }
265
266 void
267 Snmp::Var::setGauge(unsigned int value)
268 {
269 setValue(&value, sizeof(value), SMI_GAUGE32);
270 }
271
272 void
273 Snmp::Var::setString(const Range<const u_char*>& string)
274 {
275 setValue(string.start, string.size(), SMI_STRING);
276 }
277
278 void
279 Snmp::Var::setObject(const Range<const oid*>& object)
280 {
281 setValue(object.start, object.size() * sizeof(oid), SMI_OBJID);
282 }
283
284 void
285 Snmp::Var::setCounter64(long long int counter)
286 {
287 setValue(&counter, sizeof(counter), SMI_COUNTER64);
288 }
289
290 void
291 Snmp::Var::setTimeTicks(unsigned int ticks)
292 {
293 setValue(&ticks, sizeof(ticks), SMI_TIMETICKS);
294 }
295
296 void
297 Snmp::Var::copyValue(const Var& var)
298 {
299 setValue(var.val.string, var.val_len, var.type);
300 }
301
302 void
303 Snmp::Var::setValue(const void* value, int length, int aType)
304 {
305 clearValue();
306 if (value != NULL) {
307 Must(length > 0 && aType > 0);
308 val.string = static_cast<u_char*>(xmalloc(length));
309 memcpy(val.string, value, length);
310 }
311 val_len = length;
312 type = aType;
313 }
314
315 void
316 Snmp::Var::clear()
317 {
318 clearName();
319 clearValue();
320 init();
321 }
322
323 void
324 Snmp::Var::pack(Ipc::TypedMsgHdr& msg) const
325 {
326 msg.putInt(name_length);
327 if (name_length > 0) {
328 Must(name != NULL);
329 msg.putFixed(name, name_length * sizeof(oid));
330 }
331 msg.putPod(type);
332 msg.putPod(val_len);
333 if (val_len > 0) {
334 Must(val.string != NULL);
335 msg.putFixed(val.string, val_len);
336 }
337 }
338
339 void
340 Snmp::Var::unpack(const Ipc::TypedMsgHdr& msg)
341 {
342 clearName();
343 clearValue();
344 name_length = msg.getInt();
345 Must(name_length >= 0);
346 if (name_length > 0) {
347 name = static_cast<oid*>(xmalloc(name_length * sizeof(oid)));
348 msg.getFixed(name, name_length * sizeof(oid));
349 }
350 msg.getPod(type);
351 val_len = msg.getInt();
352 Must(val_len >= 0);
353 if (val_len > 0) {
354 val.string = static_cast<u_char*>(xmalloc(val_len));
355 msg.getFixed(val.string, val_len);
356 }
357 }
358