1//
2// ICMPv4PacketImpl.h
3//
4// Library: Net
5// Package: ICMP
6// Module: ICMPv4PacketImpl
7//
8// Definition of the ICMPv4PacketImpl class.
9//
10// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Net_ICMPv4PacketImpl_INCLUDED
18#define Net_ICMPv4PacketImpl_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/Net/Socket.h"
23#include "Poco/Net/ICMPPacketImpl.h"
24#include <cstddef>
25
26
27namespace Poco {
28namespace Net {
29
30
31class Net_API ICMPv4PacketImpl : public ICMPPacketImpl
32 /// This class implements the ICMPv4 packet.
33 /// Parts are based on the original ICMP code by
34 /// Mike Muuss
35 /// U. S. Army Ballistic Research Laboratory
36 /// December, 1983
37{
38public:
39 // ICMPv4 header
40 struct Header
41 {
42 Poco::UInt8 type; // ICMP packet type
43 Poco::UInt8 code; // Type sub code
44 Poco::UInt16 checksum;
45 Poco::UInt16 id;
46 Poco::UInt16 seq;
47 };
48
49 // compile-time shield against misalignment
50#if POCO_OS != POCO_OS_ANDROID
51 poco_static_assert (offsetof(Header, code) == 0x01);
52 poco_static_assert (offsetof(Header, checksum) == 0x02);
53 poco_static_assert (offsetof(Header, id) == 0x04);
54 poco_static_assert (offsetof(Header, seq) == 0x06);
55#endif
56
57 enum MessageType
58 {
59 ECHO_REPLY,
60 ICMP_1,
61 ICMP_2,
62 DESTINATION_UNREACHABLE,
63 SOURCE_QUENCH,
64 REDIRECT,
65 ICMP_6,
66 ICMP_7,
67 ECHO_REQUEST,
68 ICMP_9,
69 ICMP_10,
70 TIME_EXCEEDED,
71 PARAMETER_PROBLEM,
72 TIMESTAMP_REQUEST,
73 TIMESTAMP_REPLY,
74 INFORMATION_REQUEST,
75 INFORMATION_REPLY,
76 MESSAGE_TYPE_UNKNOWN, // non-standard default, must remain last but one
77 MESSAGE_TYPE_LENGTH // length indicator, must remain last
78 };
79
80 enum DestinationUnreachableCode
81 {
82 NET_UNREACHABLE,
83 HOST_UNREACHABLE,
84 PROTOCOL_UNREACHABLE,
85 PORT_UNREACHABLE,
86 FRAGMENTATION_NEEDED_AND_DF_SET,
87 SOURCE_ROUTE_FAILED,
88 DESTINATION_UNREACHABLE_UNKNOWN, // non-standard default, must remain last but one
89 DESTINATION_UNREACHABLE_LENGTH // length indicator, must remain last
90 };
91
92 enum RedirectMessageCode
93 {
94 REDIRECT_NETWORK,
95 REDIRECT_HOST,
96 REDIRECT_SERVICE_NETWORK,
97 REDIRECT_SERVICE_HOST,
98 REDIRECT_MESSAGE_UNKNOWN, // non-standard default, must remain last but one
99 REDIRECT_MESSAGE_LENGTH // length indicator, must remain last
100 };
101
102 enum TimeExceededCode
103 {
104 TIME_TO_LIVE,
105 FRAGMENT_REASSEMBLY,
106 TIME_EXCEEDED_UNKNOWN, // non-standard default, must remain last but one
107 TIME_EXCEEDED_LENGTH // length indicator, must remain last
108 };
109
110 enum ParameterProblemCode
111 {
112 POINTER_INDICATES_THE_ERROR,
113 PARAMETER_PROBLEM_UNKNOWN, // non-standard default, must remain last but one
114 PARAMETER_PROBLEM_LENGTH // length indicator, must remain last
115 };
116
117 ICMPv4PacketImpl(int dataSize = 48);
118 /// Constructor. Creates an ICMPv4PacketImpl.
119
120 ~ICMPv4PacketImpl();
121 /// Destructor.
122
123 int packetSize() const;
124 /// Returns the total length of packet (header + data);
125
126 struct timeval time(Poco::UInt8* buffer = 0, int length = 0) const;
127 /// Returns current epoch time if either buffer or length are equal to zero.
128 /// Otherwise, it extracts the time value from the supplied buffer.
129 ///
130 /// Buffer includes IP header, ICMP header and data.
131
132 bool validReplyID(Poco::UInt8* buffer, int length) const;
133 /// Returns true if the extracted id is recognized
134 /// (i.e. equals the process id).
135 ///
136 /// Buffer includes IP header, ICMP header and data.
137
138 virtual std::string errorDescription(Poco::UInt8* buffer, int length, int& type, int& code);
139 /// Returns error description string.
140 /// If supplied buffer contains ICMPv4 echo reply packet, an
141 /// empty string is returned indicating the absence of error.
142 /// If type and code of the error can be determined, they are
143 /// assigned to the type and code respectively.
144 ///
145 /// Buffer includes IP header, ICMP header and data.
146
147 virtual std::string typeDescription(int typeId);
148 /// Returns the description of the packet type.
149
150 static const Poco::UInt16 MAX_PACKET_SIZE;
151 static const std::string MESSAGE_TYPE[MESSAGE_TYPE_LENGTH];
152 static const Poco::UInt8 DESTINATION_UNREACHABLE_TYPE; // 3
153 static const Poco::UInt8 SOURCE_QUENCH_TYPE; // 4
154 static const Poco::UInt8 REDIRECT_MESSAGE_TYPE; // 5
155 static const Poco::UInt8 TIME_EXCEEDED_TYPE; // 11
156 static const Poco::UInt8 PARAMETER_PROBLEM_TYPE; // 12
157
158private:
159 void initPacket();
160 Header* header(Poco::UInt8* buffer, int length) const;
161 Poco::UInt8* data(Poco::UInt8* buffer, int length) const;
162
163 static const std::string DESTINATION_UNREACHABLE_CODE[DESTINATION_UNREACHABLE_LENGTH];
164 static const std::string REDIRECT_MESSAGE_CODE[REDIRECT_MESSAGE_LENGTH];
165 static const std::string TIME_EXCEEDED_CODE[TIME_EXCEEDED_LENGTH];
166 static const std::string PARAMETER_PROBLEM_CODE[PARAMETER_PROBLEM_LENGTH];
167
168 Poco::UInt16 _seq;
169};
170
171
172} } // namespace Poco::Net
173
174
175#endif // Net_ICMPv4PacketImpl_INCLUDED
176