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