0

我正在为网关(又名路由器)编写代码,在运行 Debian 7.1 的 Linux 设备上使用 boost、C++、Codeblocks。我遇到了一个烦人的 boost 绑定错误,我根本无法弄清楚问题是什么。在开始创建线程之前,我已经能够打印出 MAC Header

这是我的代码:

#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, &eth0socket, eth0);
    eth1socket = CreateAndBindSocket(ETH_P_ALL, &eth1socket, eth1);

    boost::thread eth0recvthread(RecvThread, &eth0socket); //instantiate thread in main

    char ch;
    cin.get(ch);

    eth0recvthread.interrupt();
    eth0recvthread.join();

    return 0;
}

现在我正在尝试创建一个线程来侦听其中一个套接字并(现在)打印以太网帧的 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 ===|

Tbh 我不知道出了什么问题,但是我对 C++ 和 Boost 还是很陌生。

套接字的创建和绑定工作得很好,因为它们已经过测试,但是线程函数 RecvThread() 是让我失败的那个。

如果有人对我做错了什么有一些想法(很可能是指针 (*) 或地址 (&) 搞砸了一切),我将非常感激!

提前致谢!

4

0 回答 0