2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 49 SNMP Interface */
12 #include "base/TextException.h"
14 #include "CommCalls.h"
17 #include "snmp/Forwarder.h"
18 #include "snmp/Request.h"
19 #include "snmp/Response.h"
20 #include "snmp_core.h"
22 CBDATA_NAMESPACED_CLASS_INIT(Snmp
, Forwarder
);
24 Snmp::Forwarder::Forwarder(const Pdu
& aPdu
, const Session
& aSession
, int aFd
,
25 const Ip::Address
& anAddress
):
26 Ipc::Forwarder(new Request(KidIdentifier
, Ipc::RequestId(), aPdu
, aSession
, aFd
, anAddress
), 2),
29 debugs(49, 5, "FD " << aFd
);
31 closer
= asyncCall(49, 5, "Snmp::Forwarder::noteCommClosed",
32 CommCbMemFunT
<Forwarder
, CommCloseCbParams
>(this, &Forwarder::noteCommClosed
));
33 comm_add_close_handler(fd
, closer
);
36 /// removes our cleanup handler of the client connection socket
38 Snmp::Forwarder::swanSong()
41 if (closer
!= nullptr) {
42 comm_remove_close_handler(fd
, closer
);
47 Ipc::Forwarder::swanSong();
50 /// called when the client socket gets closed by some external force
52 Snmp::Forwarder::noteCommClosed(const CommCloseCbParams
& params
)
54 debugs(49, 5, MYNAME
);
55 Must(fd
== params
.fd
);
58 mustStop("commClosed");
62 Snmp::Forwarder::handleTimeout()
64 sendError(SNMP_ERR_RESOURCEUNAVAILABLE
);
65 Ipc::Forwarder::handleTimeout();
69 Snmp::Forwarder::handleException(const std::exception
& e
)
71 debugs(49, 3, e
.what());
72 sendError(SNMP_ERR_GENERR
);
73 Ipc::Forwarder::handleException(e
);
76 /// send error SNMP response
78 Snmp::Forwarder::sendError(int error
)
80 debugs(49, 3, MYNAME
);
83 return; // client gone
85 Snmp::Request
& req
= static_cast<Snmp::Request
&>(*request
);
86 req
.pdu
.command
= SNMP_PDU_RESPONSE
;
87 req
.pdu
.errstat
= error
;
88 u_char buffer
[SNMP_REQUEST_SIZE
];
89 int len
= sizeof(buffer
);
90 snmp_build(&req
.session
, &req
.pdu
, buffer
, &len
);
91 comm_udp_sendto(fd
, req
.address
, buffer
, len
);
95 Snmp::SendResponse(const Ipc::RequestId requestId
, const Pdu
&pdu
)
97 debugs(49, 5, MYNAME
);
98 // snmpAgentResponse() can modify arg
100 Snmp::Response
response(requestId
);
101 snmp_pdu
* response_pdu
= nullptr;
103 response_pdu
= snmpAgentResponse(&tmp
);
104 Must(response_pdu
!= nullptr);
105 response
.pdu
= static_cast<Pdu
&>(*response_pdu
);
106 snmp_free_pdu(response_pdu
);
107 } catch (const std::exception
& e
) {
108 debugs(49, DBG_CRITICAL
, e
.what());
109 response
.pdu
.command
= SNMP_PDU_RESPONSE
;
110 response
.pdu
.errstat
= SNMP_ERR_GENERR
;
112 Ipc::TypedMsgHdr message
;
113 response
.pack(message
);
114 Ipc::SendMessage(Ipc::Port::CoordinatorAddr(), message
);