Debian 7.1 を実行している Linux デバイスでブースト、C++、コードブロックを使用して、ゲートウェイ (別名ルーター) のコードを書いています。迷惑なブースト バインド エラーに悩まされており、何が問題なのかわかりません。スレッドの作成を開始する前に、MAC ヘッダーを印刷できました。
これが私のコードです:
#include <errno.h>
#include <sys/ioctl.h>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <iostream>
#include <features.h>
#include <stdlib.h>
using namespace std;
int CreateRawSocket(int protocol_to_sniff)
{
int s;
if((s = socket(AF_PACKET, SOCK_RAW, htons(protocol_to_sniff))) == -1)
{
perror("Error creating raw socket");
exit(-1);
}
return s;
}
int BindRawSocketToInterface(char *device, int raw, int protocol)
{
struct sockaddr_ll sll;
struct ifreq ifr;
bzero(&sll, sizeof(sll));
bzero(&ifr, sizeof(ifr));
strncpy((char *)ifr.ifr_name, device, IFNAMSIZ);
if((ioctl(raw, SIOCGIFINDEX, &ifr)) == -1)
{
printf("Error getting interface index!\n");
exit(-1);
}
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(protocol);
if((bind(raw, (struct sockaddr *)&sll, sizeof(sll))) == -1)
{
perror("Error binding raw socket to interface\n");
exit(-1);
}
return 1;
}
int rawpacket_recv(int s, unsigned char *packet, int length)
{
int to_recv = 0;
to_recv = read(s, packet, length);
if(to_recv == -1)
{
perror("Error receiving packet");
exit(-1);
}
return to_recv;
}
int PrintPacketMACHdr(unsigned char *eth_packet)
{
unsigned char *ethhead;
int j;
ethhead = eth_packet;
printf("---Start of Ethernet header---");
printf("\nDestination address:\n");
for(j = 0; j < 6; j++)
{
printf("%02x:", *(ethhead+j)); //destination address (0 to 6 bit)
}
printf("\nSource address:\n");
for(j = 6; j < 12; j++)
{
printf("%02x:", *(ethhead+j)); //source address
}
printf("\nEther protocol number:\n");
for(j = 12; j < 14; j++)
{
printf("%02x", *(ethhead+j)); //protocol number
}
printf("\n---End of Ethernet header---\n");
if(*(ethhead + 12) == 8 && *(ethhead + 13) == 0)
{
return 1; //IP packet
}
if(*(ethhead + 12) == 8 && *(ethhead + 13) == 6)
{
return 2; //ARP packet
}
return 0;
}
int CreateAndBindSocket(int protocol_to_sniff, int *socket, char *interface)
{
int ethSocket = *socket; //eth1recv;
ethSocket = CreateRawSocket(protocol_to_sniff);
BindRawSocketToInterface(interface, ethSocket, ETH_P_ALL);
return ethSocket;
}
void RecvThread(int *socket) //thread function for receiving packets
{
int counter;
unsigned char *eth_buffer;
int eth_receiver;
int eth_socket = *socket
eth_buffer = (unsigned char *)malloc(ETH_P_ALL);
eth_receiver = rawpacket_recv(eth_socket, eth_buffer, ETH_P_ALL);
for(;;)
{
cout << "thread iteration " << ++counter << " Press Enter to stop" << endl;
try
{
//Sleep and check for interrupt();
//boost::this_thread::sleep(boost::posix_time::milliseconds(500));
usleep(50000);
PrintPacketMACHdr(eth_buffer);
}
catch(boost::thread_interrupted&)
{
cout << "Thread is stopped" << endl;
return;
}
}
}
int main(int argc, char **argv)
{
int eth0socket, eth1socket;
char eth0[] = "eth0";
char eth1[] = "eth1";
eth0socket = CreateAndBindSocket(ETH_P_ALL, ð0socket, eth0);
eth1socket = CreateAndBindSocket(ETH_P_ALL, ð1socket, eth1);
boost::thread eth0recvthread(RecvThread, ð0socket); //instantiate thread in main
char ch;
cin.get(ch);
eth0recvthread.interrupt();
eth0recvthread.join();
return 0;
}
現在、ソケットの 1 つをリッスンし、(今のところ) イーサネット フレームの MAC ヘッダーを出力するスレッドを作成しようとしています。後で、パケットをある種の配列に保存してから、この配列内のパケットを処理する別のスレッドを作成する必要があります。しかし、見出しにあるように、ブースト エラーが発生します。
/home/thomas/Workspace/minisniffer/main.cpp||In function ‘void RecvThread(int)’:|
/home/thomas/Workspace/minisniffer/main.cpp|181|warning: variable ‘eth_receiver’ set but not used [-Wunused-but-set-variable]|
../../../../usr/local/boost_1_54_0/boost/bind/bind_template.hpp|20| required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()() [with R = void; F = void (*)(int); L = boost::_bi::list1<boost::_bi::value<int*> >; boost::_bi::bind_t<R, F, L>::result_type = void]’|
../../../../usr/local/boost_1_54_0/boost/thread/detail/thread.hpp|117| required from ‘void boost::detail::thread_data<F>::run() [with F = boost::_bi::bind_t<void, void (*)(int), boost::_bi::list1<boost::_bi::value<int*> > >]’|
/home/thomas/Workspace/minisniffer/main.cpp|306| required from here|
../../../../usr/local/boost_1_54_0/boost/bind/bind.hpp|253|error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]|
../../../../usr/local/boost_1_54_0/boost/system/error_code.hpp|222|warning: ‘boost::system::posix_category’ defined but not used [-Wunused-variable]|
../../../../usr/local/boost_1_54_0/boost/system/error_code.hpp|223|warning: ‘boost::system::errno_ecat’ defined but not used [-Wunused-variable]|
../../../../usr/local/boost_1_54_0/boost/system/error_code.hpp|224|warning: ‘boost::system::native_ecat’ defined but not used [-Wunused-variable]|
||=== Build finished: 4 errors, 4 warnings ===|
何が失敗しているのかわかりませんが、C ++とBoostにはかなり慣れていません。
ソケットの作成とバインディングは、すでにテストされているため問題なく機能しますが、スレッド関数 RecvThread() は失敗するものです。
誰かが私が間違っていることについて何らかの考えを持っている場合 (すべてを台無しにしているポインター (*) またはアドレス (&) である可能性が高い)、私はとても感謝しています!!
前もって感謝します!