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