数据包嗅探器只检测发送的数据包
Packet sniffer only detects sent packets
我一直在开发一个数据包嗅探器,只是为了好玩/教育,它进展得很顺利。我遇到的问题是,recvfrom()
中出现的唯一数据包是SENT数据包,即以我的IP作为源IP的数据包,而不是我的WAN IP,而是我的LAN IP(如果有意义的话)。我试着修复它,花了几个小时阅读我能找到的所有东西,但对我来说似乎没有解决方案。我100%肯定我写的代码没有检测到所有的数据包,因为wireshark检测到更多的数据包(传入和传出),很明显,我的电脑不仅仅有传出流量。
packetsize = recvfrom(sniffer , Buffer , 65536 , 0 , (SOCKADDR *)&SenderAddr , &SenderAddrSize);
for (int x = 12; x < 16; x++)
{
printf("%c ",Buffer[x]);
}
std::cout << "n";
iphdr = (IPV4_HDR *)Buffer;
memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iphdr->ip_srcaddr;
std::cout << inet_ntoa(source.sin_addr) << "nn";
这就是一切失败的地方(还有更多的代码,但并不重要),结构都定义正确,所以没有错误(否则我不可能在每个数据包中一遍又一遍地获得相同的IP地址)。此外,我的网络中还有另一个不存在的IP显示为源IP,偶尔源IP是0.0.0.0,我都觉得很奇怪。
缓冲区被声明为
char *Buffer = (char *)malloc(65536);
所以它是有符号的char,我不知道如何从这些值中手动"提取"标头的单独部分。
我希望任何人都能向我解释,recvfrom实际上没有丢失数据包,我做错了什么。此外,我想知道如何解释recvfrom
的输出,即将有符号转换为无符号,或者其他方式?
我希望我把我的问题说清楚了,提前谢谢。
编辑我的代码中更大的一块
int main()
{
SOCKET sniffer;
struct in_addr addr;
int in;
char hostname[100];
struct hostent *local;
WSADATA wsa;
// Initialise Winsock
printf("nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
{
printf("WSAStartup() failed.n");
getchar();
return 1;
}
printf("Initialised");
// Create a RAW Socket
printf("nCreating RAW Socket....");
sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sniffer == INVALID_SOCKET)
{
printf("Failed to create raw socket.n");
printf("WSA throws error code %dn",WSAGetLastError());
printf("Run as admin to fixn");
getchar();
return 1;
}
printf("Created.");
// Retrieve the local hostname
if (gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR)
{
printf("WSA throws error code %dn",WSAGetLastError());
getchar();
return 1;
}
printf("nHost name : %s n",hostname);
bool retry = true;
signed int maxnumber = -1;
do
{
// Retrieve the available IPs of the local host
local = gethostbyname(hostname);
printf("nAvailable Network Interfaces n");
if (local == NULL)
{
printf("WSA throws error code %d.n",WSAGetLastError());
getchar();
return 1;
}
// Available interfaces
for (i = 0; local->h_addr_list[i] != 0; i++) // h_addr_list is null terminated
{
// local is hostent struct in which information about the host is stored
// in_addr represents an IPv4 internet address. inet_ntoa: in_addr to string (ip adress)
memmove(&addr, local->h_addr_list[i], sizeof(struct in_addr));
//memmove(destination, source, number of bytes to copy)
printf("Interface Number : %d Address : %sn", i, inet_ntoa(addr));
maxnumber = i;
printf("n");
}
// Choose interface
if (maxnumber > 0)
{
printf("Enter the interface number you would like to sniff : ");
scanf("%d",&in);
printf(" in: %d | maxnumber: %d n", in, maxnumber);
if (in <= maxnumber)
{
retry = false;
} else {
printf("Interface number %d with adress %d does not exist nn", in, local->h_addr_list[in]);
}
}
else
{
printf("Only one interface available");
in = 0;
retry = false;
}
} while (retry);
self = addr;
CreateFolder(self);
memset(&dest, 0, sizeof(dest));
memcpy(&dest.sin_addr.s_addr,local->h_addr_list[in],sizeof(dest.sin_addr.s_addr));
dest.sin_family = AF_INET;
dest.sin_port = htons(source.sin_port);//=0;
printf("nBinding socket to local system and port 0 ...");
if (bind(sniffer,(struct sockaddr *)&dest,sizeof(dest)) == SOCKET_ERROR)
{
printf("bind(%s) failed.n", inet_ntoa(addr));
getchar();
return 1;
}
printf("Binding successful");
j=1;
unsigned long nbytesret;
printf("nSetting socket to sniff...");
if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, &nbytesret , 0 , 0) == SOCKET_ERROR)
{
printf("WSAIoctl() failed.n");
getchar();
return 1;
}
printf("Socket setn");
printf("Press enter to startn");
getchar();
printf("Packet Capture Statistics...n");
StartSniffing(sniffer);
printf("Ending sniffer, press enter to exit n");
getchar();
closesocket(sniffer);
WSACleanup();
return 0;
}
void StartSniffing(SOCKET sniffer)
{
char *Buffer = (char *)malloc(65536);
int packetsize;
if (Buffer == NULL)
{
printf("malloc() failed.n");
getchar();
return;
}
do
{
packetsize = recvfrom(sniffer , Buffer , 65536 , 0 , (SOCKADDR *)&SenderAddr , &SenderAddrSize);
if(packetsize > 0)
{
ProcessPacket(Buffer, packetsize);
}
else
{
printf( "recvfrom() failed.n");
getchar();
}
}
while (packetsize > 0);
free(Buffer);
}
要以无符号形式从缓冲区读取,请使用类似的reinterpret_cast
来获得无符号指针:
unsigned char *uBuffer = reinterpret_cast<unsigned char *>(Buffer);
相关文章:
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 发送固定大小的 UDP 数据包
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 在 c++ 中解析数据包数据的最佳方法是什么?
- 接受函数在发送数据包时等待
- 如何在 omnet++ 中发送自定义数据包?
- 数据包访问实践
- 在C++中创建一个简单的数据包路由器,如何跟踪"客户端"?
- 德拉吉诺 LG01-S 收到异常数据包并停止工作
- 将数据包从C++服务器发送到NodeJs服务器时出现MessagePack解码错误
- 使用C++将UDP数据包存储在Structure中
- FFmpeg av_read_frame从音频流返回数据包
- 为什么操作系统正在更改我的数据包的指定传出端口
- 是否可以将多个结构作为一个数据包存储在一个函数中,然后传递给其他函数并在那里提取?
- recvfrom 只收到几个数据包,之后它进入等待状态
- 如果我在 Windows 中编程我的深度数据包检测程序,我会错过什么主要的事情
- C 程序检测物理链路状态和数据包丢失
- 数据包嗅探器只检测发送的数据包
- Wireshark 未检测到发送的任何数据包。 发送返回 0