如何解码包数据,包分析
Posted
技术标签:
【中文标题】如何解码包数据,包分析【英文标题】:how to decode packet data, packet analysis 【发布时间】:2012-07-09 09:59:12 【问题描述】:我的项目需要帮助。我不擅长这个。这是我的服务器接收器。此编码是为物理 PC 完成的。基本上物理PC中的这种编码是从虚拟接收器接收数据包。有用。但不知何故,我在解码数据包信息时遇到了问题,我对此一无所知。
#define HAVE_REMOTE
#define MAX_BUF_SIZE 1024
#define snprintf _snprintf
#define ETH_ALEN 6
#define IP_ALEN 4
#define ARP_REQUEST 1
#define ARP_REPLY 2
#include <stdlib.h>
#include <stdio.h>
#include <winsock2.h>
#include <pcap.h>
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Ws2_32.lib")
// A sample of the select() return value
int recvfromTimeOutUDP(SOCKET socket, long sec, long usec)
// Setup timeval variable
struct timeval timeout;
struct fd_set fds;
timeout.tv_sec = sec;
timeout.tv_usec = usec;
// Setup fd_set structure
FD_ZERO(&fds);
FD_SET(socket, &fds);
// Return value:
// -1: error occurred
// 0: timed out
// > 0: data ready to be read
return select(0, &fds, 0, 0, &timeout);
int main(int argc, char **argv)
WSADATA wsaData;
SOCKET ReceivingSocket;
SOCKADDR_IN ReceiverAddr;
int Port = 5150;
char ReceiveBuf[6000];
int BufLength = 6000;
SOCKADDR_IN SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);
int ByteReceived = 5, SelectTiming, ErrorCode;
char ch = 'Y';
// Initialize Winsock version 2.2
if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
printf("Server: WSAStartup failed with error %ld\n", WSAGetLastError());
return -1;
else
printf("Server: The Winsock DLL status is %s.\n", wsaData.szSystemStatus);
// Create a new socket to receive datagrams on.
ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ReceivingSocket == INVALID_SOCKET)
printf("Server: Error at socket(): %ld\n", WSAGetLastError());
// Clean up
WSACleanup();
// Exit with error
return -1;
else
printf("Server: socket() is OK!\n");
// Set up a SOCKADDR_IN structure that will tell bind that we
// want to receive datagrams from all interfaces using port 5150.
// The IPv4 family
ReceiverAddr.sin_family = AF_INET;
// Port no. 5150
ReceiverAddr.sin_port = htons(Port);
// From all interface (0.0.0.0)
ReceiverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// Associate the address information with the socket using bind.
// At this point you can receive datagrams on your bound socket.
if (bind(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)) == SOCKET_ERROR)
printf("Server: bind() failed! Error: %ld.\n", WSAGetLastError());
// Close the socket
closesocket(ReceivingSocket);
// Do the clean up
WSACleanup();
// and exit with error
return -1;
else
printf("Server: bind() is OK!\n");
// Some info on the receiver side...
getsockname(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, (int *)sizeof(ReceiverAddr));
printf("Server: Receiving IP(s) used: %s\n", inet_ntoa(ReceiverAddr.sin_addr));
printf("Server: Receiving port used: %d\n", htons(ReceiverAddr.sin_port));
printf("Server: I\'m ready to receive a datagram...\n");
SelectTiming = recvfromTimeOutUDP(ReceivingSocket, 100, 0);
switch (SelectTiming)
case 0:
// Timed out, do whatever you want to handle this situation
printf("Server: Timeout while waiting for client!...\n");
break;
case -1:
// Error occurred, maybe we should display an error message?
// Need more tweaking here and the recvfromTimeOutUDP()...
printf("Server: Some error encountered with code number: %ld\n", WSAGetLastError());
break;
default:
while (1)
// Call recvfrom() to get it then display the received data...
ByteReceived = recvfrom(ReceivingSocket, ReceiveBuf, BufLength,
0, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
if ( ByteReceived > 0 )
printf("\n\nServer: Total Bytes received: %d\n", ByteReceived);
printf("Server: The data is \"%s\"\n", ReceiveBuf);
else if ( ByteReceived <= 0 )
printf("Server: Connection closed with error code: %ld\n",
WSAGetLastError());
else
printf("Server: recvfrom() failed with error code: %d\n",
WSAGetLastError());
// Some info on the sender side
getpeername(ReceivingSocket, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
printf("Server: Sending IP used: %s\n", inet_ntoa(SenderAddr.sin_addr));
printf("Server: Sending port used: %d\n", htons(SenderAddr.sin_port));
printf("TIME -", ReceiveBuf);
// When your application is finished receiving datagrams close the socket.
printf("Server: Finished receiving. Closing the listening socket...\n");
if (closesocket(ReceivingSocket) != 0)
printf("Server: closesocket() failed! Error code: %ld\n", WSAGetLastError());
else
printf("Server: closesocket() is OK...\n");
// When your application is finished call WSACleanup.
printf("Server: Cleaning up...\n");
if(WSACleanup() != 0)
printf("Server: WSACleanup() failed! Error code: %ld\n", WSAGetLastError());
else
printf("Server: WSACleanup() is OK\n");
// Back to the system
// system("PAUSE");
return 0;
以下是我在物理 PC 中的 CLI 中获取的示例。我相信这是从虚拟接收器接收到的数据包。我很困惑如何将其解码为
时间|发件人 Mac 地址|目标 Mac 地址|数据包长度|以太类型|Src IP 地址|目的IP地址
Server: Total Bytes received: 4000
Server: The data is "Time : 10:32:24.759385
0050568214540064403a1c000800450000285aeb40007f06b0c4ac10a40bac10f3f3c0990d3d740222860176142f5010054e40620000000000000000"
Server: Sending IP used: 172.16.243.243
Server: Sending port used: 59079
Server: Total Bytes received: 4000
Server: The data is "Time : 10:32:24.759385
0050568214540064403a1c000800450000285aeb40007f06b0c4ac10a40bac10f3f3c0990d3d740222860176142f5010054e40620000000000000000"
Server: Sending IP used: 172.16.243.243
Server: Sending port used: 59080
如何解码数据包信息分析?
解码,类似这样。
时间|发件人 Mac 地址|目标 Mac 地址|数据包长度|以太类型|Src IP 地址|目的IP地址
【问题讨论】:
好像不知道收到的数据报格式? @ciphor ya.. 是新手。谢谢,将阅读有关数据报的信息。 【参考方案1】:您大概将数据写入字节缓冲区以便发送。接收它时,您只需要以与写入数据相同的方式从接收缓冲区中读回数据。我们只能看到您的接收代码,因此我们只能猜测您发送的内容,但假设您将 4 x 4 字节整数写入 char 缓冲区,然后通过套接字发送。接收代码将需要执行类似的操作
int iData1 = 0;
int iData2 = 0;
int iData3 = 0;
int iData4 = 0;
char* szIt = ReceiveBuff; // set a pointer to start of receive buffer
memcpy(&iData1,szIt,sizeof(int); // memcpy first item
szIt += sizeof(int); // point to location in buffer of next item
memcpy(&iData2,szIt,sizeof(int); // memcpy second....
szIt += sizeof(int);
// Now do the rest of the data items until you have read
// everything in the packet
等下一个项目。如果您有不同的类型,那么您需要将指针增加这些类型的大小。还有其他方法可以做同样的事情,但这会奏效。执行此操作时需要考虑的一件非常重要的事情是您发送和接收的机器的一致性。您可以强制您的数据写入 big endean,以便客户端知道并且可以处理它本身是否是 little endean。
重要的是您发送的数据的顺序以及在客户端以相同的方式解释您的字节缓冲区。
希望对你有帮助
【讨论】:
嘿!感谢您的提示!我尝试但它没有工作。它没有收到缓冲区。您有任何示例或此类网站。非常感谢。 如果您没有收到缓冲区,听起来问题可能出在您的客户端代码中。以上是关于如何解码包数据,包分析的主要内容,如果未能解决你的问题,请参考以下文章