• 8530阅读
  • 4回复

请问QT中如何设置网卡混杂模式QSocket?QTcpSocket?QAbastractSocket?。。。 [复制链接]

上一主题 下一主题
离线ruger
 
只看楼主 倒序阅读 楼主  发表于: 2008-11-04
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
请问QT中如何设置网卡混杂模式QSocket?QTcpSocket?QAbastractSocket?。。。
QT对网络的支持坊腐不怎么样?而且版本3.3,4.2,4.3,4.4,4.5的区别都很多
让人不爽啊~~
[ 此贴被ruger在2008-11-04 18:00重新编辑 ]
离线ruger
只看该作者 1楼 发表于: 2008-11-04
如果不行,就只能用C/libpcap了
离线ruger
只看该作者 2楼 发表于: 2008-11-04
#include "csniffer.h"
#include "cerror.h"
#define __YASIN_WAS_HERE_FOR_NET_BPF__
#ifndef WIN32
#include <pcap.h>
#endif
#include "cmainslots.h"
#define ETH_HW_ADDR_LEN 6
#define DEFAULT_DEVICE "lo"
//#define DEFAULT_DEVICE "vmnet1"
#ifndef __WORKING_FOR_THE_FORM
//#include "sniffdata.h"
#endif
//CSniffer * CSniffer::thisSniffer=0;
CMainSlots *CSniffer::snifferSocket = 0;
CSniffer::CSniffer(const int _verbose,
                                    const char *host,
                                    const char *port,
                                    const char *f,
                                    const char *interf,
                                    const int max,
                                    const short int prom,
                                    const unsigned short snaplen,
                                    void (*callback) (u_char * args,
                                                                       
const struct pcap_pkthdr * header,
                                                                       
const u_char *
                                                                       
packet)):maxPacketNumber(max),
promisc(prom), snap_len(snaplen), packet_handler(callback),
verbose(_verbose)
{
#ifdef _POINTER_DEBUG_
    Q_CHECK_PTR(packet_handler);
    //  Q_CHECK_PTR(f);
#endif
    _debug(QString("CSniffer::CSniffer() created"), 2);
    if (!f)
    {
        /* filter is not set */
        filter = new char[1];

        filter[0] = '\0';
    }
    else
    {
        filter = new char[strlen(f) + 1];
    }

#ifdef _POINTER_DEBUG_
    Q_CHECK_PTR(filter);
#endif
    capture_interface = new char[strlen(interf) + 1];

#ifdef _POINTER_DEBUG_
    Q_CHECK_PTR(capture_interface);
#endif
    strcpy(filter, f);
    strcpy((char *) capture_interface, interf);
    //  thisSniffer=this;
    if (_verbose & 2 || _verbose & 8)
    {
        CSniffer::snifferSocket = new CMainSlots(NULL);
        CSniffer::snifferSocket->sock_connect(QString::QString(host),
atoi(port) + 1);
    }
}

CSniffer::~CSniffer()
{
    delete[]filter;
    delete[]capture_interface;
    /*!
      close the handler
    */
    if (handle)
        pcap_close(handle);
    _debug(QString("CSniffer::CSniffer() destroyed"), 2);
}

/*!
  Read property of string filter.
*/
char    *CSniffer::getfilter()
{
    return filter;
}

/*!
  Read property of char* capture_interface.
*/
const char *CSniffer::getinterface() const
{
    return capture_interface;
}

/*!
  Read property of short int promisc.
*/
const short int &CSniffer::getpromisc() const
{
    return promisc;
}

/*!
  Read property of int maxPacketNumber.
*/
const int &CSniffer::getmaxPacketNumber() const
{
    return maxPacketNumber;
}

/*!
  No descriptions
*/
void CSniffer::stopSniffing()
{
    goonSniffing = 0;
}

/*!
  No descriptions
*/
int CSniffer::isRunning() const
{
    return goonSniffing;
}

void CSniffer::sniff()
{
    goonSniffing = 1;
    /*!
      The device to sniff on
    */
    /*!
      Error string
    */
    char errbuf[PCAP_ERRBUF_SIZE];

    /*!
      The compiled filter
    */
    struct bpf_program filter;

    /*!
      Our netmask
    */
    bpf_u_int32 mask;

    /*!
      Our IP
    */
    bpf_u_int32 net;

    //  const struct pcap_pkthdr header;    /*! The header that pcap
gives us */
    if (!capture_interface)
        /*!
          Define the device
        */
        capture_interface = pcap_lookupdev(errbuf);
    /*!
      Find the properties for the device
    */
    if (pcap_lookupnet(capture_interface, &net, &mask, errbuf)==-1)
    {
        CError::handle_exit_codes(_STACK_SNIFFER_LOOKUPNET_ERROR_,
QString(errbuf));
    }
    /*!
      Open the session in promiscuous mode
    */
    handle = pcap_open_live(capture_interface, snap_len, promisc, 1000,
errbuf);
    if (!handle)
    {
        qDebug("Sniffer failed to open the capture_interface");
        QString error = errbuf;

        if (error.find("Operation not permitted") > -1)
        {
            CError::handle_exit_codes(_STACK_SNIFFER_PERRMISSION_ERROR_,
QString(errbuf));
        }
        else
        {
            CError::handle_exit_codes(_STACK_SNIFFER_UNKWNOWN_ERROR_,
QString(errbuf));
        }
    }
    /*!
      Compile and apply the filter
    */
    if (pcap_compile(handle, &filter, getfilter(), 0, net) < 0)
    {
        CError::handle_exit_codes(_STACK_SNIFFER_FILTER_ERROR_,
QString(pcap_geterr(handle)));
    }
    if (pcap_setfilter(handle, &filter) < 0)
    {
        CError::handle_exit_codes(_STACK_SNIFFER_FILTER_ERROR_,
QString(pcap_geterr(handle)));
    }
    if (pcap_loop(handle, maxPacketNumber, (packet_handler), NULL) < 0)
    {
        CError::handle_exit_codes(_STACK_SNIFFER_THREAD_ERROR_,
QString(pcap_geterr(handle)));
    }
    pcap_close(handle);
    CError::handle_exit_codes(_STACK_SUCCESS_);
}

void CSniffer::run()
{
    sniff();
}

HEADER is:
#ifndef CSNIFFER_H
#define CSNIFFER_H
#include "defaults.h"
#include "cmainslots.h"
#include <stdio.h>
#define __YASIN_WAS_HERE_FOR_NET_BPF__
#ifndef WIN32
#include <pcap.h>
#endif
#ifdef _QTHREAD_SUPPORT_
#include <qthread.h>
#else
#include "cthread.h"
#endif
/*!
  @short This class is the main sniffing class.
  It opens a read socket and sniffs.    According to its output
formats, passes the packet to next steps.
  @author Yasin Yilmaz
*/
class    CSniffer
#ifdef _QTHREAD_SUPPORT_
:        public QThread
#else
:        public CThread
#endif
{
public:
    CSniffer(const int _verbose,
                    const char *host,
                    const char *port,
                    const char *f,
                    const char *interf,
                    const int max,
                    const short int prom,
                    const unsigned short snaplen,
                    void (*callback) (u_char * args,
                                                        const struct
pcap_pkthdr * header, const u_char * packet));
              virtual ~ CSniffer();
    virtual void run();
    /*!
      Read property of string filter.
    */
    virtual char *getfilter();
    /*!
      Read property of char* interface.
    */
    virtual const char *getinterface() const;
    /*!
      Read property of short int promisc.
    */
    virtual const short int &getpromisc() const;
    /*!
      Read property of int maxPacketNumber.
    */
    virtual const int &getmaxPacketNumber() const;
    void      stopSniffing();
    int      isRunning() const;
    void      setNonBlocking();
    void      setBlocking();
    static CMainSlots *snifferSocket;
    //  static CSniffer* thisSniffer;
private:                                                // Private
attributes
    //  inline static void handle_ip_packets_burst(u_char * args,const
struct pcap_pkthdr *header,const u_char * packet);
    //  inline static void handle_ip_packets_file(u_char * args,const
struct pcap_pkthdr *header,const u_char * packet);
    //  inline static void handle_ip_packets_no_gui(u_char * args,const
struct pcap_pkthdr *header,const u_char * packet);
    //  inline static void handle_ip_packets_with_gui(u_char *
args,const struct pcap_pkthdr *header,const u_char * packet);
    char    *filter;
    const int maxPacketNumber;
    const short int promisc;
    inline void sniff();
    const unsigned int snap_len;
    /*!
      Session handle
    */
    pcap_t  *handle;
    /*!
      The interface to listen on...
    */
    char    *capture_interface;
    int      goonSniffing;
    /*!
      Pointer to function to handle captured packets. This pointer is
passed to pcap library calls.
    */
    void      (*packet_handler) (u_char * args,
                                                            const
struct pcap_pkthdr * header, const u_char * packet);
    /*!
      This variable holds the error code of the sniffer.
    */
    int      ErrorCode;
    const int verbose;
};
#endif
离线sbtree
只看该作者 3楼 发表于: 2008-11-04
网卡混杂模式???
才疏学浅,不理解楼主的概念
windows 7 + VC++2008 + Qt4.5.2
离线ruger
只看该作者 4楼 发表于: 2008-11-04
引用第3楼sbtree于2008-11-04 17:08发表的  :
网卡混杂模式???
才疏学浅,不理解楼主的概念

混杂模式:promiscuous mode;    promiscuous;
在混杂模式下,网卡可以捕捉通过该网卡的所有数据包,无论是否应该接收或者转发,通常sniffer都要将网卡设置为混杂模式来捕捉数据包

刚才看了国外2004年的一个帖子,说应该用libpcap来解决这个问题,楼上也是这个思路,功能简单的话应该不用这么复杂..
快速回复
限100 字节
 
上一个 下一个