]>
Commit | Line | Data |
---|---|---|
51ea0904 | 1 | /* |
51ea0904 CT |
2 | * DEBUG: section 49 SNMP Interface |
3 | * | |
4 | */ | |
5 | ||
f7f3304a | 6 | #include "squid.h" |
51ea0904 CT |
7 | #include "base/TextException.h" |
8 | #include "CommCalls.h" | |
1b76e6c1 | 9 | #include "comm.h" |
582c2af2 | 10 | #include "globals.h" |
51ea0904 CT |
11 | #include "ipc/Port.h" |
12 | #include "snmp_core.h" | |
d6e3ad20 CT |
13 | #include "snmp/Forwarder.h" |
14 | #include "snmp/Request.h" | |
15 | #include "snmp/Response.h" | |
51ea0904 | 16 | |
51ea0904 CT |
17 | CBDATA_NAMESPACED_CLASS_INIT(Snmp, Forwarder); |
18 | ||
51ea0904 CT |
19 | Snmp::Forwarder::Forwarder(const Pdu& aPdu, const Session& aSession, int aFd, |
20 | const Ip::Address& anAddress): | |
21 | Ipc::Forwarder(new Request(KidIdentifier, 0, aPdu, aSession, aFd, anAddress), 2), | |
22 | fd(aFd) | |
23 | { | |
24 | debugs(49, 5, HERE << "FD " << aFd); | |
25 | Must(fd >= 0); | |
933a6aed | 26 | closer = asyncCall(49, 5, "Snmp::Forwarder::noteCommClosed", |
51ea0904 CT |
27 | CommCbMemFunT<Forwarder, CommCloseCbParams>(this, &Forwarder::noteCommClosed)); |
28 | comm_add_close_handler(fd, closer); | |
29 | } | |
30 | ||
31 | /// removes our cleanup handler of the client connection socket | |
32 | void | |
33 | Snmp::Forwarder::cleanup() | |
34 | { | |
35 | if (fd >= 0) { | |
36 | if (closer != NULL) { | |
37 | comm_remove_close_handler(fd, closer); | |
38 | closer = NULL; | |
39 | } | |
40 | fd = -1; | |
41 | } | |
42 | } | |
43 | ||
44 | /// called when the client socket gets closed by some external force | |
45 | void | |
46 | Snmp::Forwarder::noteCommClosed(const CommCloseCbParams& params) | |
47 | { | |
48 | debugs(49, 5, HERE); | |
49 | Must(fd == params.fd); | |
50 | fd = -1; | |
51 | mustStop("commClosed"); | |
52 | } | |
53 | ||
54 | void | |
55 | Snmp::Forwarder::handleTimeout() | |
56 | { | |
57 | sendError(SNMP_ERR_RESOURCEUNAVAILABLE); | |
58 | Ipc::Forwarder::handleTimeout(); | |
59 | } | |
60 | ||
61 | void | |
62 | Snmp::Forwarder::handleException(const std::exception& e) | |
63 | { | |
64 | debugs(49, 3, HERE << e.what()); | |
65 | if (fd >= 0) | |
66 | sendError(SNMP_ERR_GENERR); | |
67 | Ipc::Forwarder::handleException(e); | |
68 | } | |
69 | ||
70 | /// send error SNMP response | |
71 | void | |
72 | Snmp::Forwarder::sendError(int error) | |
73 | { | |
74 | debugs(49, 3, HERE); | |
75 | Snmp::Request& req = static_cast<Snmp::Request&>(*request); | |
76 | req.pdu.command = SNMP_PDU_RESPONSE; | |
77 | req.pdu.errstat = error; | |
78 | u_char buffer[SNMP_REQUEST_SIZE]; | |
79 | int len = sizeof(buffer); | |
80 | snmp_build(&req.session, &req.pdu, buffer, &len); | |
81 | comm_udp_sendto(fd, req.address, buffer, len); | |
82 | } | |
83 | ||
84 | void | |
85 | Snmp::SendResponse(unsigned int requestId, const Pdu& pdu) | |
86 | { | |
87 | debugs(49, 5, HERE); | |
88 | // snmpAgentResponse() can modify arg | |
89 | Pdu tmp = pdu; | |
90 | Snmp::Response response(requestId); | |
91 | snmp_pdu* response_pdu = NULL; | |
92 | try { | |
93 | response_pdu = snmpAgentResponse(&tmp); | |
94 | Must(response_pdu != NULL); | |
95 | response.pdu = static_cast<Pdu&>(*response_pdu); | |
96 | snmp_free_pdu(response_pdu); | |
97 | } catch (const std::exception& e) { | |
98 | debugs(49, DBG_CRITICAL, HERE << e.what()); | |
99 | response.pdu.command = SNMP_PDU_RESPONSE; | |
100 | response.pdu.errstat = SNMP_ERR_GENERR; | |
101 | } | |
102 | Ipc::TypedMsgHdr message; | |
103 | response.pack(message); | |
104 | Ipc::SendMessage(Ipc::coordinatorAddr, message); | |
105 | } |