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 = 4096;
37const UInt16 ICMPPacketImpl::MAX_SEQ_VALUE = 65535;
38
39
40ICMPPacketImpl::ICMPPacketImpl(int dataSize):
41 _seq(0),
42 _pPacket(new UInt8[MAX_PACKET_SIZE]),
43 _dataSize(dataSize)
44{
45 if (_dataSize > MAX_PACKET_SIZE)
46 throw InvalidArgumentException("Packet size must be <= " + NumberFormatter::format(MAX_PACKET_SIZE));
47}
48
49
50ICMPPacketImpl::~ICMPPacketImpl()
51{
52 delete [] _pPacket;
53}
54
55
56void ICMPPacketImpl::setDataSize(int dataSize)
57{
58 _dataSize = dataSize;
59 initPacket();
60}
61
62
63int ICMPPacketImpl::getDataSize() const
64{
65 return _dataSize;
66}
67
68
69const Poco::UInt8* ICMPPacketImpl::packet(bool init)
70{
71 if (init) initPacket();
72 return _pPacket;
73}
74
75
76unsigned short ICMPPacketImpl::checksum(UInt16 *addr, Int32 len)
77{
78 Int32 nleft = len;
79 UInt16* w = addr;
80 UInt16 answer;
81 Int32 sum = 0;
82
83 while (nleft > 1)
84 {
85 sum += *w++;
86 nleft -= sizeof(UInt16);
87 }
88
89 if (nleft == 1)
90 {
91 UInt16 u = 0;
92 *(UInt8*) (&u) = *(UInt8*) w;
93 sum += u;
94 }
95
96 sum = (sum >> 16) + (sum & 0xffff);
97 sum += (sum >> 16);
98 answer = ~sum;
99 return answer;
100}
101
102
103} } // namespace Poco::Net
104