I am trying to modify the ICMP boost_asio implementation to print ICMP response and request packets. In the example code I am trying to print the response/reply buffer using below code:
void StartReceive()
{
gSocket.async_receive_from(gReply.prepare(65536), gReceiver,
[&](const error_code& error, size_t length)
{
gReply.commit(length);
ipv4_header ipv4Hdr;
icmp_header icmpHdr;
std::string body(BODY.size(), 0);
std::istream is(&gReply);
char c;
c = is.get();
while (is)
{
std::cout << std::hex << c;
c = is.get();
}
I tried other methods also to print the buffer from std::istream reply, but it is printing garbage values. I will appreciate if someone can help in printing the buffer in hex format eg:
45 00 00 54 89 4c 00 00 40 01 fe af 0b 0b 0b 02 2c d5 af cb 08 00 e7 f7 44 4a 2a 95 62 c5 12 b2 00 0c 40 a2 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37
Thanks
ostream
prints chars as characters, not integers, so std::hex
format manipulator does nothing. Instead print as an (unsigned) integer, e.g.:
#include <boost/asio.hpp>
#include <iomanip>
#include <iostream>
#include <fstream>
int main()
{
boost::asio::streambuf gReply;
std::ostream(&gReply) << std::ifstream("main.cpp").rdbuf();
std::istream is(&gReply);
is >> std::noskipws;
std::cout << std::hex << std::showbase << std::setfill('0');
int col = 0;
for(unsigned char c; is >> c;)
{
std::cout << std::setw(4) << static_cast<int>(c) << ' ';
if (0 == (++col % 16))
std::cout << '\n';
}
}
Prints its own source in hex:
0x23 0x69 0x6e 0x63 0x6c 0x75 0x64 0x65 0x20 0x3c 0x62 0x6f 0x6f 0x73 0x74 0x2f
0x61 0x73 0x69 0x6f 0x2e 0x68 0x70 0x70 0x3e 00xa 0x23 0x69 0x6e 0x63 0x6c 0x75
0x64 0x65 0x20 0x3c 0x69 0x6f 0x6d 0x61 0x6e 0x69 0x70 0x3e 00xa 0x23 0x69 0x6e
0x63 0x6c 0x75 0x64 0x65 0x20 0x3c 0x69 0x6f 0x73 0x74 0x72 0x65 0x61 0x6d 0x3e
00xa 0x23 0x69 0x6e 0x63 0x6c 0x75 0x64 0x65 0x20 0x3c 0x66 0x73 0x74 0x72 0x65
0x61 0x6d 0x3e 00xa 00xa 0x69 0x6e 0x74 0x20 0x6d 0x61 0x69 0x6e 0x28 0x29 00xa
0x7b 00xa 0x20 0x20 0x20 0x20 0x62 0x6f 0x6f 0x73 0x74 0x3a 0x3a 0x61 0x73 0x69
0x6f 0x3a 0x3a 0x73 0x74 0x72 0x65 0x61 0x6d 0x62 0x75 0x66 0x20 0x67 0x52 0x65
0x70 0x6c 0x79 0x3b 00xa 00xa 0x20 0x20 0x20 0x20 0x73 0x74 0x64 0x3a 0x3a 0x6f
0x73 0x74 0x72 0x65 0x61 0x6d 0x28 0x26 0x67 0x52 0x65 0x70 0x6c 0x79 0x29 0x20
0x3c 0x3c 0x20 0x73 0x74 0x64 0x3a 0x3a 0x69 0x66 0x73 0x74 0x72 0x65 0x61 0x6d
0x28 0x22 0x6d 0x61 0x69 0x6e 0x2e 0x63 0x70 0x70 0x22 0x29 0x2e 0x72 0x64 0x62
0x75 0x66 0x28 0x29 0x3b 00xa 00xa 0x20 0x20 0x20 0x20 0x73 0x74 0x64 0x3a 0x3a
0x69 0x73 0x74 0x72 0x65 0x61 0x6d 0x20 0x69 0x73 0x28 0x26 0x67 0x52 0x65 0x70
0x6c 0x79 0x29 0x3b 00xa 0x20 0x20 0x20 0x20 0x69 0x73 0x20 0x3e 0x3e 0x20 0x73
0x74 0x64 0x3a 0x3a 0x6e 0x6f 0x73 0x6b 0x69 0x70 0x77 0x73 0x3b 00xa 00xa 0x20
0x20 0x20 0x20 0x73 0x74 0x64 0x3a 0x3a 0x63 0x6f 0x75 0x74 0x20 0x3c 0x3c 0x20
0x73 0x74 0x64 0x3a 0x3a 0x68 0x65 0x78 0x20 0x3c 0x3c 0x20 0x73 0x74 0x64 0x3a
0x3a 0x73 0x68 0x6f 0x77 0x62 0x61 0x73 0x65 0x20 0x3c 0x3c 0x20 0x20 0x73 0x74
0x64 0x3a 0x3a 0x73 0x65 0x74 0x66 0x69 0x6c 0x6c 0x28 0x27 0x30 0x27 0x29 0x3b
00xa 0x20 0x20 0x20 0x20 0x69 0x6e 0x74 0x20 0x63 0x6f 0x6c 0x20 0x3d 0x20 0x30
0x3b 00xa 0x20 0x20 0x20 0x20 0x66 0x6f 0x72 0x28 0x75 0x6e 0x73 0x69 0x67 0x6e
0x65 0x64 0x20 0x63 0x68 0x61 0x72 0x20 0x63 0x3b 0x20 0x69 0x73 0x20 0x3e 0x3e
0x20 0x63 0x3b 0x29 00xa 0x20 0x20 0x20 0x20 0x7b 00xa 0x20 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x73 0x74 0x64 0x3a 0x3a 0x63 0x6f 0x75 0x74 0x20 0x3c 0x3c 0x20
0x73 0x74 0x64 0x3a 0x3a 0x73 0x65 0x74 0x77 0x28 0x34 0x29 0x20 0x3c 0x3c 0x20
0x73 0x74 0x61 0x74 0x69 0x63 0x5f 0x63 0x61 0x73 0x74 0x3c 0x69 0x6e 0x74 0x3e
0x28 0x63 0x29 0x20 0x3c 0x3c 0x20 0x27 0x20 0x27 0x3b 00xa 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x20 0x69 0x66 0x20 0x28 0x30 0x20 0x3d 0x3d 0x20 0x28 0x2b 0x2b
0x63 0x6f 0x6c 0x20 0x25 0x20 0x31 0x36 0x29 0x29 00xa 0x20 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x73 0x74 0x64 0x3a 0x3a 0x63 0x6f 0x75 0x74
0x20 0x3c 0x3c 0x20 0x27 0x5c 0x6e 0x27 0x3b 00xa 0x20 0x20 0x20 0x20 0x7d 00xa
0x7d 00xa
There is no need to use istream
on streambuf
here:
gReply.commit(boost::asio::buffer_copy(
gReply.prepare(64),
boost::asio::buffer(std::string_view("Hello world!"))));
std::cout << std::hex << std::showbase << std::setfill('0');
int col = 0;
for(auto it = buffers_begin(gReply.data()),
end = buffers_end(gReply.data());
it != end;
++it)
{
unsigned char c = *it;
std::cout << std::setw(4) << static_cast<int>(c) << ' ';
if (0 == (++col % 16))
std::cout << '\n';
}
Prints
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x77 0x6f 0x72 0x6c 0x64 0x21
Note that you can use other (dynamic) buffers instead of streambuf
making things easier for this kind of use case:
#include <boost/asio.hpp>
#include <iomanip>
#include <iostream>
int main()
{
std::vector<unsigned char> reply;
auto rbuf = boost::asio::dynamic_buffer(reply);
rbuf.commit(boost::asio::buffer_copy(
rbuf.prepare(64),
boost::asio::buffer(std::string_view("Hello world!"))));
std::cout << std::hex << std::showbase << std::setfill('0');
for(int col = 0; int ic : reply)
std::cout << std::setw(4) << ic << (++col % 16 ? ' ' : '\n');
}
Prints, again:
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x77 0x6f 0x72 0x6c 0x64 0x21