如何在需要时阻止套接字接收数据?

时间:2018-02-21 05:51:37

标签: sockets winsock raw-sockets

我正在使用一个mp3链接嗅探项目,我用一个简单的原始套接字方法成功地嗅探了链接。问题是这个项目需要下载链接,所以我首先想到的是当你不想嗅闻时停止套接字接收原始数据,然后选择存储的链接,但我不会知道如何在程序运行时停止套接字。欢迎任何帮助向我展示这个问题的重点,甚至是一种处理它的新方法。

编辑:这是我的代码:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define callerr {cout << "Error: " << WSAGetLastError() << endl; system("pause"); return 0;}
#define failerr {cout << "Failed.\n"; system("pause"); return;}
#define SIO_RCVALL _WSAIOW(IOC_VENDOR, 1)

#include <WinSock2.h>
#include <iostream>
#include <iphlpapi.h>
#include <sstream>
#include <vector>

using namespace std;

struct ip_addr
{
    u_char byte1;
    u_char byte2;
    u_char byte3;
    u_char byte4;
};

struct ip_hdr
{
    unsigned char ip_header_len : 4;
    unsigned char ip_version : 4;
    unsigned char ip_tos;
    unsigned short ip_total_length;
    unsigned short ip_id;
    unsigned char ip_frag_offset : 5;
    unsigned char ip_more_fragment : 1;
    unsigned char ip_dont_fragment : 1;
    unsigned char ip_reserved_zero : 1;
    unsigned char ip_frag_offset1;
    unsigned char ip_ttl;
    unsigned char ip_protocol;
    unsigned short ip_checksum;
    unsigned int ip_srcaddr;
    unsigned int ip_destaddr;
};

struct tcp_hdr
{
    unsigned short source_port;
    unsigned short dest_port;
    unsigned int sequence;
    unsigned int acknowledge;
    unsigned char ns : 1;
    unsigned char reserved_part1 : 3;
    unsigned char data_offset : 4;
    unsigned char fin : 1;
    unsigned char syn : 1;
    unsigned char rst : 1;
    unsigned char psh : 1;
    unsigned char ack : 1;
    unsigned char urg : 1;
    unsigned char ecn : 1;
    unsigned char cwr : 1;
    unsigned short window;
    unsigned short checksum;
    unsigned short urgent_pointer;
};

sockaddr_in source, dest;
PIP_ADAPTER_ADDRESSES adapter(NULL), i;
u_long bs = 65536;
ip_hdr *ih;
tcp_hdr *th;
vector <char*> url;

void getUrl(char *tmp, char *tmp1)
{
    int i = 0;
    char *t = strstr(tmp, "Host: ");
    t += 6;
    while (*t != 13)
    {
        tmp1[i] = *t;
        ++t;
        ++i;
    }
    t = strstr(tmp, "GET ");
    t += 4;
    while (*t != ' ')
    {
        tmp1[i] = *t;
        ++t;
        ++i;
    }
    tmp1[i] = 0;
    url.push_back(tmp1);

    cout << "Url: " << tmp1 << endl;
}

void processPacket(char *buff, int size, SOCKET capture)
{
    ih = (ip_hdr*)buff;
    if (ih->ip_protocol == 6)
    {
        th = (tcp_hdr*)(buff + ih->ip_header_len * 4);
        char *data = (char*)((char*)th + th->data_offset * 4);
        int len = ntohs(ih->ip_total_length) - ih->ip_header_len * 4 - th->data_offset * 4;
        data[len] = 0;
        char tmp[65536], tmp1[65536];
        for (int i = 0; i <= len; ++i) tmp[i] = data[i];
        if (strstr(tmp, "GET ") != 0 and strstr(tmp, ".mp3 ")) getUrl(tmp, tmp1);
    }
}

void capturePacket(SOCKET capture)
{
    char *buff = (char*)malloc(bs); //Kich thuoc toi da cua mot packet
    int res;

    if (!buff) failerr;

    do
    {
        res = recvfrom(capture, buff, bs, 0, 0, 0);
        if (res > 0) processPacket(buff, res, capture);
        else failerr;
    } while (res > 0);

    free(buff);
}

int main()
{
    adapter = (PIP_ADAPTER_ADDRESSES)malloc(bs);
    SOCKET capture;
    int inum = 0, id, j, in, set = 1;
    WSAData wsa;

    cout << "Initializing Winsock... ";
    if (WSAStartup(MAKEWORD(2, 2), &wsa)) callerr;
    cout << "Succesfully initialized.\n\nSearching interface list... ";

    if (GetAdaptersAddresses(2, 0, NULL, adapter, &bs) != ERROR_SUCCESS) callerr;
    cout << "Interface list: \n";
    for (i = adapter; i; i = i->Next)
    {
        wcout << ++inum << ": " << i->FriendlyName << ", IPv4 address: ";
        sockaddr_in *tmp = reinterpret_cast<sockaddr_in*>(i->FirstUnicastAddress->Address.lpSockaddr);
        cout << inet_ntoa(tmp->sin_addr) << endl;
    }

    do
    {
        cout << "\nEnter interface number: "; cin >> id;
        if (id < 1 or id > inum) cout << "Invalid number.";
    } while (id < 1 or id > inum);
    for (i = adapter, j = 0; j < id - 1; ++j, i = i->Next);


    sockaddr_in *tmp = reinterpret_cast<sockaddr_in*>(i->FirstUnicastAddress->Address.lpSockaddr);
    memset(&dest, 0, sizeof(dest));
    memcpy(&dest.sin_addr.s_addr, &tmp->sin_addr.S_un, sizeof(dest.sin_addr.s_addr));
    dest.sin_family = AF_INET;
    dest.sin_port = 0;

    cout << "\nInitializing RAW socket... ";
    capture = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    if (capture == INVALID_SOCKET) callerr;
    cout << "Successfully initialized.\nBinding socket to localhost port 0... ";

    if (bind(capture, (sockaddr *)&dest, sizeof(dest)) == SOCKET_ERROR) callerr;
    cout << "Successfully binded.\nSetting socket... ";


    if (WSAIoctl(capture, SIO_RCVALL, &set, sizeof(set), 0, 0, (PDWORD) &in, 0, 0) == SOCKET_ERROR) callerr;
    cout << "Successfully set-up.\n\nStarting TCP packet capturing. \n";

    capturePacket(capture);
}

0 个答案:

没有答案