1//
2// ICMPPacketImpl.cpp
3//
4// Library: Net
5// Package: ICMP
6// Module: ICMPPacketImpl
7//
8// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/Net/ICMPPacketImpl.h"
16#include "Poco/Net/NetException.h"
17#include "Poco/Timestamp.h"
18#include "Poco/Timespan.h"
19#include "Poco/NumberFormatter.h"
20#include <sstream>
21
22
23using Poco::InvalidArgumentException;
24using Poco::Timestamp;
25using Poco::Timespan;
26using Poco::NumberFormatter;
27using Poco::UInt8;
28using Poco::UInt16;
29using Poco::Int32;
30
31
32namespace Poco {
33namespace Net {
34
35
36const UInt16 ICMPPacketImpl::MAX_PACKET_SIZE = 65535;
37const UInt16 ICMPPacketImpl::MAX_PAYLOAD_SIZE = 65507;
38const UInt16 ICMPPacketImpl::MAX_SEQ_VALUE = 65535;
39
40
41ICMPPacketImpl::ICMPPacketImpl(int dataSize):
42 _seq(0),
43 _pPacket(new UInt8[MAX_PACKET_SIZE]),
44 _dataSize(dataSize)
45{
46 if (_dataSize > MAX_PACKET_SIZE)
47 throw InvalidArgumentException("Packet size must be <= " + NumberFormatter::format(MAX_PACKET_SIZE));
48}
49
50
51ICMPPacketImpl::~ICMPPacketImpl()
52{
53 delete [] _pPacket;
54}
55
56
57void ICMPPacketImpl::setDataSize(int dataSize)
58{
59 _dataSize = dataSize;
60 initPacket();
61}
62
63
64int ICMPPacketImpl::getDataSize() const
65{
66 return _dataSize;
67}
68
69
70const Poco::UInt8* ICMPPacketImpl::packet(bool init)
71{
72 if (init) initPacket();
73 return _pPacket;
74}
75
76
77unsigned short ICMPPacketImpl::checksum(UInt16 *addr, Int32 len)
78{
79 Int32 nleft = len;
80 UInt16* w = addr;
81 UInt16 answer;
82 Int32 sum = 0;
83
84 while (nleft > 1)
85 {
86 sum += *w++;
87 nleft -= sizeof(UInt16);
88 }
89
90 if (nleft == 1)
91 {
92 UInt16 u = 0;
93 *(UInt8*) (&u) = *(UInt8*) w;
94 sum += u;
95 }
96
97 sum = (sum >> 16) + (sum & 0xffff);
98 sum += (sum >> 16);
99 answer = static_cast<UInt16>(~sum);
100 return answer;
101}
102
103
104} } // namespace Poco::Net
105