]> git.ipfire.org Git - thirdparty/squid.git/blob - src/snmp/Pdu.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / snmp / Pdu.cc
1 /*
2 * Copyright (C) 1996-2015 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 "ipc/TypedMsgHdr.h"
14 #include "snmp/Pdu.h"
15 #include "snmp/Var.h"
16 #include "snmp_core.h"
17 #include "tools.h"
18
19 #include <algorithm>
20
21 Snmp::Pdu::Pdu()
22 {
23 init();
24 }
25
26 Snmp::Pdu::Pdu(const Pdu& pdu)
27 {
28 init();
29 assign(pdu);
30 }
31
32 Snmp::Pdu::~Pdu()
33 {
34 clear();
35 }
36
37 Snmp::Pdu&
38 Snmp::Pdu::operator = (const Pdu& pdu)
39 {
40 clear();
41 assign(pdu);
42 return *this;
43 }
44
45 void
46 Snmp::Pdu::init()
47 {
48 memset(this, 0, sizeof(*this));
49 errstat = SNMP_DEFAULT_ERRSTAT;
50 errindex = SNMP_DEFAULT_ERRINDEX;
51 }
52
53 void
54 Snmp::Pdu::aggregate(const Pdu& pdu)
55 {
56 Must(varCount() == pdu.varCount());
57 ++aggrCount;
58 for (variable_list* p_aggr = variables, *p_var = pdu.variables; p_var != NULL;
59 p_aggr = p_aggr->next_variable, p_var = p_var->next_variable) {
60 Must(p_aggr != NULL);
61 Var& aggr = static_cast<Var&>(*p_aggr);
62 Var& var = static_cast<Var&>(*p_var);
63 if (aggr.isNull()) {
64 aggr.setName(var.getName());
65 aggr.copyValue(var);
66 } else {
67 switch (snmpAggrType(aggr.name, aggr.name_length)) {
68 case atSum:
69 case atAverage:
70 // The mean-average division is done later
71 // when the Snmp::Pdu::fixAggregate() called
72 aggr += var;
73 break;
74 case atMax:
75 if (var > aggr)
76 aggr.copyValue(var);
77 break;
78 case atMin:
79 if (var < aggr)
80 aggr.copyValue(var);
81 break;
82 default:
83 break;
84 }
85 }
86 }
87 }
88
89 void
90 Snmp::Pdu::clear()
91 {
92 clearSystemOid();
93 clearVars();
94 init();
95 }
96
97 void
98 Snmp::Pdu::assign(const Pdu& pdu)
99 {
100 command = pdu.command;
101 address.sin_addr.s_addr = pdu.address.sin_addr.s_addr;
102 reqid = pdu.reqid;
103 errstat = pdu.errstat;
104 errindex = pdu.errindex;
105 non_repeaters = pdu.non_repeaters;
106 max_repetitions = pdu.max_repetitions;
107 agent_addr.sin_addr.s_addr = pdu.agent_addr.sin_addr.s_addr;
108 trap_type = pdu.trap_type;
109 specific_type = pdu.specific_type;
110 time = pdu.time;
111 aggrCount = pdu.aggrCount;
112 setSystemOid(pdu.getSystemOid());
113 setVars(pdu.variables);
114 }
115
116 void
117 Snmp::Pdu::clearVars()
118 {
119 variable_list* var = variables;
120 while (var != NULL) {
121 variable_list* tmp = var;
122 var = var->next_variable;
123 snmp_var_free(tmp);
124 }
125 variables = NULL;
126 }
127
128 void
129 Snmp::Pdu::setVars(variable_list* vars)
130 {
131 clearVars();
132 for (variable_list** p_var = &variables; vars != NULL;
133 vars = vars->next_variable, p_var = &(*p_var)->next_variable) {
134 *p_var = new Var(static_cast<Var&>(*vars));
135 }
136 }
137
138 void
139 Snmp::Pdu::clearSystemOid()
140 {
141 if (enterprise != NULL) {
142 xfree(enterprise);
143 enterprise = NULL;
144 }
145 enterprise_length = 0;
146 }
147
148 Range<const oid*>
149 Snmp::Pdu::getSystemOid() const
150 {
151 return Range<const oid*>(enterprise, enterprise + enterprise_length);
152 }
153
154 void
155 Snmp::Pdu::setSystemOid(const Range<const oid*>& systemOid)
156 {
157 clearSystemOid();
158 if (systemOid.start != NULL && systemOid.size() != 0) {
159 enterprise_length = systemOid.size();
160 enterprise = static_cast<oid*>(xmalloc(enterprise_length * sizeof(oid)));
161 std::copy(systemOid.start, systemOid.end, enterprise);
162 }
163 }
164
165 void
166 Snmp::Pdu::pack(Ipc::TypedMsgHdr& msg) const
167 {
168 msg.putPod(command);
169 msg.putPod(address);
170 msg.putPod(reqid);
171 msg.putPod(errstat);
172 msg.putPod(errindex);
173 msg.putPod(non_repeaters);
174 msg.putPod(max_repetitions);
175 msg.putInt(enterprise_length);
176 if (enterprise_length > 0) {
177 Must(enterprise != NULL);
178 msg.putFixed(enterprise, enterprise_length * sizeof(oid));
179 }
180 msg.putPod(agent_addr);
181 msg.putPod(trap_type);
182 msg.putPod(specific_type);
183 msg.putPod(time);
184 msg.putInt(varCount());
185 for (variable_list* var = variables; var != NULL; var = var->next_variable)
186 static_cast<Var*>(var)->pack(msg);
187 }
188
189 void
190 Snmp::Pdu::unpack(const Ipc::TypedMsgHdr& msg)
191 {
192 clear();
193 msg.getPod(command);
194 msg.getPod(address);
195 msg.getPod(reqid);
196 msg.getPod(errstat);
197 msg.getPod(errindex);
198 msg.getPod(non_repeaters);
199 msg.getPod(max_repetitions);
200 enterprise_length = msg.getInt();
201 if (enterprise_length > 0) {
202 enterprise = static_cast<oid*>(xmalloc(enterprise_length * sizeof(oid)));
203 msg.getFixed(enterprise, enterprise_length * sizeof(oid));
204 }
205 msg.getPod(agent_addr);
206 msg.getPod(trap_type);
207 msg.getPod(specific_type);
208 msg.getPod(time);
209 int count = msg.getInt();
210 for (variable_list** p_var = &variables; count > 0;
211 p_var = &(*p_var)->next_variable, --count) {
212 Var* var = new Var();
213 var->unpack(msg);
214 *p_var = var;
215 }
216 }
217
218 int
219 Snmp::Pdu::varCount() const
220 {
221 int count = 0;
222 for (variable_list* var = variables; var != NULL; var = var->next_variable)
223 ++count;
224 return count;
225 }
226
227 void
228 Snmp::Pdu::fixAggregate()
229 {
230 if (aggrCount < 2)
231 return;
232 for (variable_list* p_aggr = variables; p_aggr != NULL; p_aggr = p_aggr->next_variable) {
233 Var& aggr = static_cast<Var&>(*p_aggr);
234 if (snmpAggrType(aggr.name, aggr.name_length) == atAverage) {
235 aggr /= aggrCount;
236 }
237 }
238 aggrCount = 0;
239 }
240