source: nscp/include/nrpe/nrpepacket.hpp @ 1e0bbec

0.4.00.4.10.4.2
Last change on this file since 1e0bbec was 1e0bbec, checked in by Michael Medin <michael@…>, 4 years ago

Semi-working NRPEClient (debian boost is broken so need to recompile it myself before I can finish it off) But "should almost work" (from CLI)

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21#pragma once
22
23#include <types.hpp>
24
25
26class NRPEPacket {
27public:
28        static const short unknownPacket = 0;
29        static const short queryPacket = 1;
30        static const short responsePacket = 2;
31        static const short version2 = 2;
32
33        class NRPEPacketException {
34                std::wstring error_;
35        public:
36                NRPEPacketException(std::wstring error) : error_(error) {}
37                std::wstring getMessage() {
38                        return error_;
39                }
40        };
41
42private:
43        typedef struct packet {
44                int16_t   packet_version;
45                int16_t   packet_type;
46                u_int32_t crc32_value;
47                int16_t   result_code;
48                char      buffer[];
49        } packet;
50        std::wstring payload_;
51        short type_;
52        short version_;
53        NSCAPI::nagiosReturn result_;
54        unsigned int crc32_;
55        unsigned int calculatedCRC32_;
56        char *tmpBuffer;
57        unsigned int buffer_length_;
58public:
59        NRPEPacket(unsigned int buffer_length) : tmpBuffer(NULL), buffer_length_(buffer_length) {};
60        NRPEPacket(const char *buffer, unsigned int length, unsigned int buffer_length) : tmpBuffer(NULL), buffer_length_(buffer_length) {
61                readFrom(buffer, length);
62        };
63        NRPEPacket(short type, short version, NSCAPI::nagiosReturn result, std::wstring payLoad, unsigned int buffer_length)
64                : tmpBuffer(NULL)
65                ,type_(type)
66                ,version_(version)
67                ,result_(result)
68                ,payload_(payLoad)
69                ,buffer_length_(buffer_length)
70        {
71        }
72        NRPEPacket()
73                : tmpBuffer(NULL)
74                ,type_(unknownPacket)
75                ,version_(version2)
76                ,result_(0)
77                ,buffer_length_(0)
78        {
79        }
80        NRPEPacket(const NRPEPacket &other) : tmpBuffer(NULL) {
81                payload_ = other.payload_;
82                type_ = other.type_;
83                version_ = other.version_;
84                result_ = other.result_;
85                crc32_ = other.crc32_;
86                calculatedCRC32_ = other.calculatedCRC32_;
87                buffer_length_ = other.buffer_length_;
88        }
89        NRPEPacket& operator=(NRPEPacket const& other) {
90                tmpBuffer=NULL;
91                payload_ = other.payload_;
92                type_ = other.type_;
93                version_ = other.version_;
94                result_ = other.result_;
95                crc32_ = other.crc32_;
96                calculatedCRC32_ = other.calculatedCRC32_;
97                buffer_length_ = other.buffer_length_;
98                return *this;
99        }
100
101        ~NRPEPacket() {
102                delete [] tmpBuffer;
103        }
104        static NRPEPacket make_request(std::wstring payload, unsigned int buffer_length) {
105                return NRPEPacket(queryPacket, version2, -1, payload, buffer_length);
106        }
107
108        const char* getBuffer() {
109                delete [] tmpBuffer;
110                tmpBuffer = new char[getBufferLength()+1];
111                //TODO readd this ZeroMemory(tmpBuffer, getBufferLength()+1);
112                packet *p = reinterpret_cast<packet*>(tmpBuffer);
113                p->result_code = htons(NSCHelper::nagios2int(result_));
114                p->packet_type = htons(type_);
115                p->packet_version = htons(version_);
116                if (payload_.length() >= buffer_length_-1)
117                        throw NRPEPacketException(_T("To much data cant create return packet (truncate datat)"));
118                //ZeroMemory(p->buffer, buffer_length_-1);
119                strncpy(p->buffer, to_string(payload_).c_str(), payload_.length());
120                p->buffer[payload_.length()] = 0;
121                p->crc32_value = 0;
122                p->crc32_value = htonl(calculate_crc32(tmpBuffer, getBufferLength()));
123                return tmpBuffer;
124        }
125
126        void readFrom(const char *buffer, unsigned int length) {
127                if (buffer == NULL)
128                        throw NRPEPacketException(_T("No buffer."));
129                if (length != getBufferLength())
130                        throw NRPEPacketException(_T("Invalid length: ") + strEx::itos(length) + _T(" != ") + strEx::itos(getBufferLength()));
131                const packet *p = reinterpret_cast<const packet*>(buffer);
132                type_ = ntohs(p->packet_type);
133                if ((type_ != queryPacket)&&(type_ != responsePacket))
134                        throw NRPEPacketException(_T("Invalid packet type."));
135                version_ = ntohs(p->packet_version);
136                if (version_ != version2)
137                        throw NRPEPacketException(_T("Invalid packet version."));
138                crc32_ = ntohl(p->crc32_value);
139                // Verify CRC32
140                // @todo Fix this, currently we need a const buffer so we cannot change the CRC to 0.
141                char * tb = new char[getBufferLength()+1];
142                memcpy(tb, buffer, getBufferLength());
143                packet *p2 = reinterpret_cast<packet*>(tb);
144                p2->crc32_value = 0;
145                calculatedCRC32_ = calculate_crc32(tb, getBufferLength());
146                delete [] tb;
147                if (crc32_ != calculatedCRC32_)
148                        throw NRPEPacketException(_T("Invalid checksum in NRPE packet!"));
149                // Verify CRC32 end
150                result_ = NSCHelper::int2nagios(ntohs(p->result_code));
151                payload_ = strEx::string_to_wstring(std::string(p->buffer));
152        }
153
154        unsigned short getVersion() const { return version_; }
155        unsigned short getType() const { return type_; }
156        unsigned short getResult() const { return result_; }
157        std::wstring getPayload() const { return payload_; }
158        bool verifyCRC() { return calculatedCRC32_ == crc32_; }
159        unsigned int getBufferLength() const { return getBufferLength(buffer_length_); }
160        static unsigned int getBufferLength(unsigned int buffer_length) { return sizeof(packet)+buffer_length*sizeof(char); }
161        unsigned int getInternalBufferLength() const { return buffer_length_; }
162
163
164        std::wstring toString() {
165                std::wstringstream ss;
166                ss << _T("type: ") << type_;
167                ss << _T(", version: ") << version_;
168                ss << _T(", result: ") << result_;
169                ss << _T(", payload: ") << payload_;
170                return ss.str();
171        }
172
173};
174
175
176
177
Note: See TracBrowser for help on using the repository browser.