]> git.ipfire.org Git - thirdparty/squid.git/blob - src/snmp/Var.cc
Merged from trunk
[thirdparty/squid.git] / src / snmp / Var.cc
1 /*
2 * DEBUG: section 49 SNMP Interface
3 *
4 */
5
6 #include "squid.h"
7 #include "base/TextException.h"
8 #include "Debug.h"
9 #include "ipc/TypedMsgHdr.h"
10 #include "snmp/Var.h"
11 #include "tools.h"
12 #if HAVE_ALGORITHM
13 #include <algorithm>
14 #endif
15
16 Snmp::Var::Var()
17 {
18 init();
19 }
20
21 Snmp::Var::Var(const Var& var)
22 {
23 init();
24 assign(var);
25 }
26
27 Snmp::Var::~Var()
28 {
29 clear();
30 }
31
32 Snmp::Var&
33 Snmp::Var::operator = (const Var& var)
34 {
35 clear();
36 assign(var);
37 return *this;
38 }
39
40 void
41 Snmp::Var::init()
42 {
43 xmemset(this, 0, sizeof(*this));
44 }
45
46 Snmp::Var&
47 Snmp::Var::operator += (const Var& var)
48 {
49 switch (type) {
50 case SMI_INTEGER:
51 setInt(asInt() + var.asInt());
52 break;
53 case SMI_GAUGE32:
54 setGauge(asGauge() + var.asGauge());
55 break;
56 case SMI_COUNTER32:
57 setCounter(asCounter() + var.asCounter());
58 break;
59 case SMI_COUNTER64:
60 setCounter64(asCounter64() + var.asCounter64());
61 break;
62 case SMI_TIMETICKS:
63 setTimeTicks(asTimeTicks() + var.asTimeTicks());
64 break;
65 default:
66 debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
67 throw TexcHere("Unsupported type");
68 break;
69 }
70 return *this;
71 }
72
73 Snmp::Var&
74 Snmp::Var::operator /= (int num)
75 {
76 Must(num != 0);
77 switch (type) {
78 case SMI_INTEGER:
79 setInt(asInt() / num);
80 break;
81 case SMI_GAUGE32:
82 setGauge(asGauge() / num);
83 break;
84 case SMI_COUNTER32:
85 setCounter(asCounter() / num);
86 break;
87 case SMI_COUNTER64:
88 setCounter64(asCounter64() / num);
89 break;
90 case SMI_TIMETICKS:
91 setTimeTicks(asTimeTicks() / num);
92 break;
93 default:
94 debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
95 throw TexcHere("Unsupported type");
96 break;
97 }
98 return *this;
99 }
100
101 bool
102 Snmp::Var::operator < (const Var& var) const
103 {
104 switch (type) {
105 case SMI_INTEGER:
106 return asInt() < var.asInt();
107 case SMI_GAUGE32:
108 return asGauge() < var.asGauge();
109 case SMI_COUNTER32:
110 return asCounter() < var.asCounter();
111 case SMI_COUNTER64:
112 return asCounter64() < var.asCounter64();
113 case SMI_TIMETICKS:
114 return asTimeTicks() < var.asTimeTicks();
115 default:
116 debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
117 throw TexcHere("Unsupported type");
118 break;
119 }
120 return false; // unreachable
121 }
122
123 bool
124 Snmp::Var::operator > (const Var& var) const
125 {
126 switch (type) {
127 case SMI_INTEGER:
128 return asInt() > var.asInt();
129 case SMI_GAUGE32:
130 return asGauge() > var.asGauge();
131 case SMI_COUNTER32:
132 return asCounter() > var.asCounter();
133 case SMI_COUNTER64:
134 return asCounter64() > var.asCounter64();
135 case SMI_TIMETICKS:
136 return asTimeTicks() > var.asTimeTicks();
137 default:
138 debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
139 throw TexcHere("Unsupported type");
140 break;
141 }
142 return false; // unreachable
143 }
144
145 void
146 Snmp::Var::assign(const Var& var)
147 {
148 setName(var.getName());
149 copyValue(var);
150 }
151
152 void
153 Snmp::Var::clearName()
154 {
155 if (name != NULL) {
156 xfree(name);
157 name = NULL;
158 }
159 name_length = 0;
160 }
161
162 Range<const oid*>
163 Snmp::Var::getName() const
164 {
165 return Range<const oid*>(name, name + name_length);
166 }
167
168 void
169 Snmp::Var::setName(const Range<const oid*>& aName)
170 {
171 clearName();
172 if (aName.start != NULL && aName.size() != 0) {
173 name_length = aName.size();
174 name = static_cast<oid*>(xmalloc(name_length * sizeof(oid)));
175 std::copy(aName.start, aName.end, name);
176 }
177 }
178
179 void
180 Snmp::Var::clearValue()
181 {
182 if (val.string != NULL) {
183 xfree(val.string);
184 val.string = NULL;
185 }
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 }