source: nscp/include/nrpe/nrpepacket.hpp @ 7f9c823

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

First attempt at serious boostification.
NOTICE! This is NOT a complete edition, it build and runs but many features are disabled and/or broken.
But we have working, sockets and mutexes and conversion functions from boost inside now and more to come...
Also started to build with CMake since it works better then boost.build

  • Property mode set to 100644
File size: 6.2 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
24typedef short int16_t;
25typedef unsigned long u_int32_t;
26
27class NRPEPacket {
28public:
29        static const short unknownPacket = 0;
30        static const short queryPacket = 1;
31        static const short responsePacket = 2;
32        static const short version2 = 2;
33
34        class NRPEPacketException {
35                std::wstring error_;
36        public:
37                NRPEPacketException(std::wstring error) : error_(error) {}
38                std::wstring getMessage() {
39                        return error_;
40                }
41        };
42
43private:
44        typedef struct packet {
45                int16_t   packet_version;
46                int16_t   packet_type;
47                u_int32_t crc32_value;
48                int16_t   result_code;
49                char      buffer[];
50        } packet;
51        std::wstring payload_;
52        short type_;
53        short version_;
54        NSCAPI::nagiosReturn result_;
55        unsigned int crc32_;
56        unsigned int calculatedCRC32_;
57        char *tmpBuffer;
58        unsigned int buffer_length_;
59public:
60        NRPEPacket(unsigned int buffer_length) : tmpBuffer(NULL), buffer_length_(buffer_length) {};
61        NRPEPacket(const char *buffer, unsigned int length, unsigned int buffer_length) : tmpBuffer(NULL), buffer_length_(buffer_length) {
62                readFrom(buffer, length);
63        };
64        NRPEPacket(short type, short version, NSCAPI::nagiosReturn result, std::wstring payLoad, unsigned int buffer_length)
65                : tmpBuffer(NULL)
66                ,type_(type)
67                ,version_(version)
68                ,result_(result)
69                ,payload_(payLoad)
70                ,buffer_length_(buffer_length)
71        {
72        }
73        NRPEPacket()
74                : tmpBuffer(NULL)
75                ,type_(unknownPacket)
76                ,version_(version2)
77                ,result_(0)
78                ,buffer_length_(0)
79        {
80        }
81        NRPEPacket(NRPEPacket &other) : tmpBuffer(NULL) {
82                payload_ = other.payload_;
83                type_ = other.type_;
84                version_ = other.version_;
85                result_ = other.result_;
86                crc32_ = other.crc32_;
87                calculatedCRC32_ = other.calculatedCRC32_;
88                buffer_length_ = other.buffer_length_;
89        }
90        ~NRPEPacket() {
91                delete [] tmpBuffer;
92        }
93        static NRPEPacket make_request(std::wstring payload, unsigned int buffer_length) {
94                return NRPEPacket(queryPacket, version2, -1, payload, buffer_length);
95        }
96
97        const char* getBuffer() {
98                delete [] tmpBuffer;
99                tmpBuffer = new char[getBufferLength()+1];
100                ZeroMemory(tmpBuffer, getBufferLength()+1);
101                packet *p = reinterpret_cast<packet*>(tmpBuffer);
102                p->result_code = htons(NSCHelper::nagios2int(result_));
103                p->packet_type = htons(type_);
104                p->packet_version = htons(version_);
105                if (payload_.length() >= buffer_length_-1)
106                        throw NRPEPacketException(_T("To much data cant create return packet (truncate datat)"));
107                //ZeroMemory(p->buffer, buffer_length_-1);
108                strncpy_s(p->buffer, buffer_length_-1, strEx::wstring_to_string(payload_).c_str(), payload_.length());
109                p->buffer[payload_.length()] = 0;
110                p->crc32_value = 0;
111                p->crc32_value = htonl(calculate_crc32(tmpBuffer, getBufferLength()));
112                return tmpBuffer;
113        }
114
115        void readFrom(const char *buffer, unsigned int length) {
116                if (buffer == NULL)
117                        throw NRPEPacketException(_T("No buffer."));
118                if (length != getBufferLength())
119                        throw NRPEPacketException(_T("Invalid length: ") + strEx::itos(length) + _T(" != ") + strEx::itos(getBufferLength()));
120                const packet *p = reinterpret_cast<const packet*>(buffer);
121                type_ = ntohs(p->packet_type);
122                if ((type_ != queryPacket)&&(type_ != responsePacket))
123                        throw NRPEPacketException(_T("Invalid packet type."));
124                version_ = ntohs(p->packet_version);
125                if (version_ != version2)
126                        throw NRPEPacketException(_T("Invalid packet version."));
127                crc32_ = ntohl(p->crc32_value);
128                // Verify CRC32
129                // @todo Fix this, currently we need a const buffer so we cannot change the CRC to 0.
130                char * tb = new char[getBufferLength()+1];
131                memcpy(tb, buffer, getBufferLength());
132                packet *p2 = reinterpret_cast<packet*>(tb);
133                p2->crc32_value = 0;
134                calculatedCRC32_ = calculate_crc32(tb, getBufferLength());
135                delete [] tb;
136                if (crc32_ != calculatedCRC32_)
137                        throw NRPEPacketException(_T("Invalid checksum in NRPE packet!"));
138                // Verify CRC32 end
139                result_ = NSCHelper::int2nagios(ntohs(p->result_code));
140                payload_ = strEx::string_to_wstring(std::string(p->buffer));
141        }
142
143        unsigned short getVersion() const { return version_; }
144        unsigned short getType() const { return type_; }
145        unsigned short getResult() const { return result_; }
146        std::wstring getPayload() const { return payload_; }
147        bool verifyCRC() { return calculatedCRC32_ == crc32_; }
148        unsigned int getBufferLength() const { return getBufferLength(buffer_length_); }
149        static unsigned int getBufferLength(unsigned int buffer_length) { return sizeof(packet)+buffer_length*sizeof(char); }
150        unsigned int getInternalBufferLength() const { return buffer_length_; }
151
152
153        std::wstring toString() {
154                std::wstringstream ss;
155                ss << _T("type: ") << type_;
156                ss << _T(", version: ") << version_;
157                ss << _T(", result: ") << result_;
158                ss << _T(", payload: ") << payload_;
159                return ss.str();
160        }
161
162};
163
164
165
166
Note: See TracBrowser for help on using the repository browser.