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