I am writing a packet sniffer in C++ utilizing streams instead of printf()
to store and create output. The problem I've run into is that recvfrom()
seems to fail and return -1
when I have two or more statements that generate output using a stream.
If I comment one of the two output generating statements, the program runs fine. Through trial and error, I've found that by removing the std::setw()
from the std::cout
statement, it will work correctly and display both the packet and the "beef" message.
Any ideas or help would be much appreciated as I am at a loss and considering reverting back to using printf()
since it never had this problem (and is faster than a stream). I admit, this is really the first time I have ever used ostringstream
and I may be using it incorrectly.
My simplified source code:
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <linux/if_packet.h>
std::string BufferInHex( unsigned char * buffer, int length )
{
std::ostringstream out;
for( int i = 0; i < length; i ++ ) {
if( i % 16 == 0 && i != 0 ) {
out << "\n";
}
else if( i % 8 == 0 && i != 0 ) {
out << " ";
}
out << std::hex;
out << std::setfill('0') << std::setw(2) << static_cast<unsigned>(buffer[i]) << " ";
out << std::dec;
}
return out.str();
}
int main( void )
{
struct sockaddr_ll saddr = {0};
socklen_t saddr_size = sizeof(saddr);
unsigned char packet[1500] = {0};
int sockFd = socket( AF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
if( sockFd < 0 ) {
std::cerr << "Error creating socket!\n";
return 1;
}
int data_size = recvfrom( sockFd, packet, sizeof( packet ), 0, (struct sockaddr*)&saddr, &saddr_size );
if( data_size == -1 ) {
std::cerr << "Error in recvfrom()\n";
return 2;
}
std::cout << std::hex;
std::cout << std::setw( 8 ) << ntohs( 0xADDE ) << "\n";
std::cout << std::dec;
std::cout << BufferInHex( packet, data_size ) << "\n";
return 0;
}
It is being compiled with g++ on Centos 6.4 kernel 2.6.32 using the following command:
g++ sniff.cpp -o sniff -Wall
Thanks for any ideas or help,
Jeremiah