Я пишу анализатор пакетов в C ++, используя потоки вместо printf()
хранить и создавать выходные данные. Проблема, с которой я столкнулся, заключается в том, что recvfrom()
кажется провалиться и вернуться -1
когда у меня есть два или более операторов, которые генерируют вывод с использованием потока.
Если я прокомментирую один из двух операторов генерации вывода, программа будет работать нормально. Методом проб и ошибок я обнаружил, что, удалив std::setw()
от std::cout
Заявление, он будет работать правильно и отображать как пакет, так и сообщение «beef».
Любые идеи или помощь будут высоко ценится, так как я в растерянности и думаю вернуться к использованию printf()
так как никогда не было этой проблемы (и быстрее, чем поток). Я признаю, это действительно первый раз, когда я использовал ostringstream
и я могу использовать это неправильно.
Мой упрощенный исходный код:
#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;
}
Он компилируется с g ++ в ядре Centos 6.4 2.6.32 с помощью следующей команды:
g++ sniff.cpp -o sniff -Wall
Спасибо за любые идеи или помощь,
Иеремия
Задача ещё не решена.
Других решений пока нет …