- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我使用原始套接字编写了一个简单的数据包接收器,但我得到了奇怪的输出,例如:
Received packet: size: 124, type: PACKET_HOST (0)
Sender info: Name: n003-000-000-000.static.ge.com, IP: 3.0.0.0
Data:
74 2f 68 3c d1 9f 00 37 b7 d1 5a a7 08 00 45 00 00 6e 00 00 40
00 40 11 b6 e9 c0 a8 01 01 c0 a8 01 44 00 35 94 08 00 5a 3b aa
e1 78 81 80 00 01 00 01 00 00 00 00 01 30 01 30 01 30 01 33 07
69 6e 2d 61 64 64 72 04 61 72 70 61 00 00 0c 00 01 c0 0c 00 0c
00 01 00 00 65 95 00 20 10 6e 30 30 33 2d 30 30 30 2d 30 30 30
2d 30 30 30 06 73 74 61 74 69 63 02 67 65 03 63 6f 6d 00
当我浏览互联网时,数据包变大了,但主机名和地址保持不变或几乎相同。
谁能帮我找出问题所在?
代码如下:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <linux/if_ether.h>
#include <netdb.h>
#include <linux/if_packet.h>
#include <netinet/ether.h>
#define PACKET_SIZE 1 << 16
void usage();
void packetTypeToStr(int type, char *str);
int main(int argc, char **argv) {
const char *iface_name;
if (argc == 2) {
iface_name = argv[1];
} else if (argc > 2) {
usage();
return 1;
} else {
iface_name = "wlan0";
}
// Opening socket in raw mode
int socketFileDesc = 0;
if ((socketFileDesc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
perror("socket");
return errno;
}
printf("Opened raw socket\n");
// Acquiring the index of the interface
struct ifreq iface;
memset(&iface, 0, sizeof(struct ifreq));
strncpy(iface.ifr_name, iface_name, strlen(iface_name) + 1);
if (ioctl(socketFileDesc, SIOCGIFINDEX, &iface) < 0) {
perror("SIOCGIFINDEX");
usage();
close(socketFileDesc);
return errno;
}
int index = iface.ifr_ifindex;
printf("Index of the interface %s: %d\n", iface_name, index);
// Acquiring the mac address of the interface
struct ifreq iface_mac;
memset(&iface_mac, 0, sizeof(struct ifreq));
strncpy(iface_mac.ifr_name, iface_name, strlen(iface_name) + 1);
if (ioctl(socketFileDesc, SIOCGIFHWADDR, &iface_mac) < 0) {
perror("SIOCGIFHWADDR");
usage();
close(socketFileDesc);
return errno;
}
printf("MAC address of the interface %s: %s\n", iface_name, ether_ntoa((struct ether_addr*)iface_mac.ifr_hwaddr.sa_data));
// Setting interface in promiscuous mode
struct ifreq iface_options;
memset(&iface_options, 0, sizeof(struct ifreq));
strncpy(iface_options.ifr_name, iface_name, strlen(iface_name) + 1);
if (ioctl(socketFileDesc, SIOCGIFFLAGS, &iface_options) < 0) {
perror("SIOCGIFFLAGS");
close(socketFileDesc);
return errno;
}
iface_options.ifr_flags |= IFF_PROMISC;
if (ioctl(socketFileDesc, SIOCSIFFLAGS, &iface_options) < 0) {
perror("SIOCGIFFLAGS");
close(socketFileDesc);
return errno;
}
printf("Interface %s set in promiscuous mode\n", iface_name);
// Binding socket to the interface
struct sockaddr_ll socketAddress;
memset(&socketAddress, 0, sizeof(socketAddress));
socketAddress.sll_family = AF_PACKET;
socketAddress.sll_protocol = htons(ETH_P_ALL);
socketAddress.sll_ifindex = index;
if (bind(socketFileDesc, (struct sockaddr *) &socketAddress, sizeof(socketAddress)) < 0) {
perror("bind");
close(socketFileDesc);
return errno;
}
printf("Socket bound to the interface: %s\nWaiting for packets...\n", iface_name);
// Receiving packets in a loop
while (1) {
ssize_t n = 0;
uint8_t packet[PACKET_SIZE];
bzero(packet, sizeof(packet));
struct sockaddr_in address;
socklen_t length = sizeof(address);
if ((n = recvfrom(socketFileDesc, packet, sizeof(packet), 0, (struct sockaddr *) &address, &length)) < 0) {
perror("recvfrom");
close(socketFileDesc);
return errno;
}
// Null-terminated data
if (n > 0)
packet[n - 1] = '\0';
else
continue;
// IP address
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(address.sin_addr), ip, length);
// Host name
struct hostent *host = gethostbyaddr(&(address.sin_addr), length, AF_INET);
if (host == NULL) {
herror("gethostbyaddr");
return h_errno;
}
const char *hostName = host->h_name;
// Packet type
char packetType[BUFSIZ];
int type = ((struct sockaddr_ll *) &address)->sll_pkttype;
packetTypeToStr(type, packetType);
// Printing info and data
printf("\n\nReceived packet: size: %li, type: %s\n"
"Sender info: Name: %s, IP: %s\n",
n, packetType, hostName, ip);
printf("Data:\n");
int i = 0;
for (; i < n; ++i)
printf("%02x ", packet[i]);
}
return 0;
}
最佳答案
由于您正在接收原始数据包 recvfrom()
无法返回 IP 地址,因为数据通常可能不是互联网数据包。例如,它可能只是一个任意的以太网数据包,它是从一些根本没有 TCP/IP 堆栈的设备发送的。可能 recvfrom()
将传递的 sockaddr 指针视为 struct sockaddr_ll *
并返回物理层地址。
您可以尝试通过解析接收到的数据包来获取正确的IP地址。如果它真的是 IP 数据包 - 它将包含所有 header ,以及源地址和目标地址。
关于c - C中的原始套接字数据包接收器,奇怪的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38266787/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!