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