- 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/
我正在使用 OUTFILE 命令,但由于权限问题和安全风险,我想将 shell 的输出转储到文件中,但出现了一些错误。我试过的 #This is a simple shell to connect t
我刚刚开始学习 Java,我想克服在尝试为这个“问题”创建 Java 程序时出现的障碍。这是我必须创建一个程序来解决的问题: Tandy 喜欢分发糖果,但只有 n 颗糖果。对于她给第 i 个糖果的人,
你好,我想知道我是否可以得到一些帮助来解决我在 C++ 中打印出 vector 内容的问题 我试图以特定顺序在一个或两个函数调用中输出一个类的所有变量。但是我在遍历 vector 时收到一个奇怪的错误
我正在将 intellij (2019.1.1) 用于 java gradle (5.4.1) 项目,并使用 lombok (1.18.6) 来自动生成代码。 Intellij 将生成的源放在 out
编辑:在与 guest271314 交流后,我意识到问题的措辞(在我的问题正文中)可能具有误导性。我保留了旧版本并更好地改写了新版本 背景: 从远程服务器获取 JSON 时,响应 header 包含一
我的问题可能有点令人困惑。我遇到的问题是我正在使用来自 Java 的 StoredProcedureCall 调用过程,例如: StoredProcedureCall call = new Store
在我使用的一些IDL中,我注意到在方法中标记返回值有2个约定-[in, out]和[out, retval]。 当存在多个返回值时,似乎使用了[in, out],例如: HRESULT MyMetho
当我查看 gar -h 的帮助输出时,它告诉我: [...] gar: supported targets: elf64-x86-64 elf32-i386 a.out-i386-linux [...
我想循环遍历一个列表,并以 HTML 格式打印其中的一部分,以代码格式打印其中的一部分。所以更准确地说:我想产生与这相同的输出 1 is a great number 2 is a great
我有下面的tekton管道,并尝试在Google Cloud上运行。集群角色绑定。集群角色。该服务帐户具有以下权限。。例外。不确定需要为服务帐户设置什么权限。
当尝试从 make 过滤非常长的输出以获取特定警告或错误消息时,第一个想法是这样的: $ make | grep -i 'warning: someone set up us the bomb' 然而
我正在创建一个抽象工具类,该类对另一组外部类(不受我控制)进行操作。外部类在某些接口(interface)点概念上相似,但访问它们相似属性的语法不同。它们还具有不同的语法来应用工具操作的结果。我创建了
这个问题已经有答案了: What do numbers starting with 0 mean in python? (9 个回答) 已关闭 7 年前。 在我的代码中使用按位与运算符 (&) 时,我
我写了这段代码来解析输入文件中的行输入格式:电影 ID 可以有多个条目,所以我们应该计算平均值输出:**没有重复(这是问题所在) import re f = open("ratings2.txt",
我需要处理超过 1000 万个光谱数据集。数据结构如下:大约有 1000 个 .fits(.fits 是某种数据存储格式)文件,每个文件包含大约 600-1000 个光谱,其中每个光谱中有大约 450
我编写了一个简单的 C 程序,它读取一个文件并生成一个包含每个单词及其出现频率的表格。 该程序有效,我已经能够在 Linux 上运行的终端中获得显示的输出,但是,我不确定如何获得生成的显示以生成包含词
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
1.普通的输出: print(str)#str是任意一个字符串,数字··· 2.格式化输出: ?
我无法让 logstash 正常工作。 Basic logstash Example作品。但后来我与 Advanced Pipeline Example 作斗争.也许这也可能是 Elasticsear
这是我想要做的: 我想让用户给我的程序一些声音数据(通过麦克风输入),然后保持 250 毫秒,然后通过扬声器输出。 我已经使用 Java Sound API 做到了这一点。问题是它有点慢。从发出声音到
我是一名优秀的程序员,十分优秀!