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