我正在使用一个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);
}