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
104
105
106
107
108
109
110
111
112 | // Copyright (C) 2023-2024 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Kea Hooks Basic
// Commercial End User License Agreement v2.0. See COPYING file in the premium/
// directory.
#include <config.h>
#include <icmp_msg.h><--- Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <util/io.h>
#include <exceptions/exceptions.h>
#include <netinet/ip_icmp.h><--- Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <iostream><--- Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results.
using namespace isc;
using namespace isc::asiolink;
using namespace isc::util;
namespace isc {
namespace ping_check {
ICMPMsg::ICMPMsg()
: source_(IOAddress::IPV4_ZERO_ADDRESS()),
destination_(IOAddress::IPV4_ZERO_ADDRESS()),
msg_type_(0), code_(0), check_sum_(0), id_(0), sequence_(0),
payload_(0) {
}
ICMPMsgPtr
ICMPMsg::unpack(const uint8_t* wire_data, size_t length) {
ICMPMsgPtr msg(new ICMPMsg());
if (length < sizeof(struct ip)) {
isc_throw(BadValue,
"ICMPMsg::unpack - truncated ip header, length: "
<< length);
}
// Find the IP header length...
struct ip* ip_header = (struct ip*)(wire_data);<--- C-style pointer casting [+]C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected.
auto hlen = (ip_header->ip_hl << 2);
// Make sure we received enough data.
if (length < (hlen + sizeof(struct icmp))) {
isc_throw(BadValue, "ICMPMsg::truncated packet? length: "
<< length << ", hlen: " << hlen);
}
// Grab the source and destination addresses.
msg->setSource(IOAddress(ntohl(ip_header->ip_src.s_addr)));
msg->setDestination(IOAddress(ntohl(ip_header->ip_dst.s_addr)));
// Get the message type.
struct icmp* reply = (struct icmp*)(wire_data + hlen);<--- C-style pointer casting [+]C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected.
msg->setType(reply->icmp_type);
msg->setCode(reply->icmp_code);
msg->setChecksum(ntohs(reply->icmp_cksum));
msg->setId(ntohs(reply->icmp_hun.ih_idseq.icd_id));
msg->setSequence(ntohs(reply->icmp_hun.ih_idseq.icd_seq));
auto payload_len = length - hlen - ICMP_HEADER_SIZE;
msg->setPayload((const uint8_t*)(&reply->icmp_dun), payload_len);<--- C-style pointer casting [+]C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected.
return (msg);
}
ICMPPtr
ICMPMsg::pack() const {
ICMPPtr outbound(new struct icmp());
memset(outbound.get(), 0x00, sizeof(struct icmp));
outbound->icmp_type = msg_type_;
outbound->icmp_id = htons(id_);
outbound->icmp_seq = htons(sequence_);
/// @todo copy in payload - not needed for ECHO REQUEST
outbound->icmp_cksum = htons(~calcChecksum((const uint8_t*)(outbound.get()), sizeof(struct icmp)));<--- C-style pointer casting [+]C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected.
return (outbound);
}
void
ICMPMsg::setPayload(const uint8_t* data, size_t length) {
payload_.insert(payload_.end(), data, data + length);
}
uint32_t
ICMPMsg::calcChecksum(const uint8_t* buf, size_t length) {
uint32_t sum = 0;
/* Checksum all the pairs of bytes first... */
size_t i;
for (i = 0; i < (length & ~1U); i += 2) {
sum += static_cast<uint32_t>(readUint16(buf + i, sizeof(uint16_t)));
/* Add carry. */
if (sum > 0xFFFF) {
sum -= 0xFFFF;
}
}
/* If there's a single byte left over, checksum it, too. Network
byte order is big-endian, so the remaining byte is the high byte. */
if (i < length) {
sum += buf[i] << 8;
/* Add carry. */
if (sum > 0xFFFF) {
sum -= 0xFFFF;
}
}
return (sum);
}
} // end of namespace ping_check
} // end of namespace isc
|