- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
总结:原始套接字中的sendto api报告没有错误,但wireshark抓包中未发送ICMP数据包。
我是原始套接字编程新手,正在尝试从头开始创建 ICMP ping 数据包。我成功创建了一个 ping 程序,如下所示:https://www.geeksforgeeks.org/ping-in-c/但现在我希望自己构建以太网 header ,即从头开始构建所有数据包 header 。我确实按照以下方式编写了程序:https://opensourceforu.com/2015/03/a-guide-to-using-raw-sockets/但是当我运行它并使用 tcpdump 捕获数据包传输并使用 Wireshark 分析它时,我发现没有发送 ICMP 数据包,尽管根据我的编程逻辑,我的数据包已成功发送(因为 sendto api 没有报告任何错误)。我附上了代码,我们将非常感谢任何帮助。
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/ip_icmp.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#define PING_PKT_S 64
#define PORT_NO 0
#define PING_SLEEP_RATE 1000000
#define RECV_TIMEOUT 1
int pingloop=1;
struct ping_pkt
{
struct ethhdr eth;
struct ip ip;
struct icmphdr hdr;
char msg[PING_PKT_S-sizeof(struct icmphdr)];
}g_pckt;
typedef struct ping_ctx{
int tos;
int ttl;
char srcIP[200];
char dstIP[200];
int r_sock;
}ping_ctx;
unsigned short checksum(void *b, int len)
{
unsigned short *buf = b;
unsigned int sum=0;
unsigned short result;
for ( sum = 0; len > 1; len -= 2 )
sum += *buf++;
if ( len == 1 )
sum += *(unsigned char*)buf;
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
result = ~sum;
return result;
}
void intHandler(int dummy)
{
pingloop=0;
}
void fill_ip_h(struct ip *ip, ping_ctx* ctx)
{
ip->ip_src.s_addr = inet_addr(ctx->srcIP);
ip->ip_dst.s_addr = inet_addr(ctx->dstIP);
ip->ip_v = 4;
ip->ip_hl = sizeof*ip >> 2;
ip->ip_tos = (unsigned char)(ctx->tos);
ip->ip_len = htons(sizeof(g_pckt));
ip->ip_id = htons(4321);
ip->ip_off = htons(0);
ip->ip_ttl = (unsigned char)(ctx->ttl);
ip->ip_p = 1;
ip->ip_sum = 0; /* Let kernel fills in */
}
void fill_icmp_h(struct icmphdr* hdr,int *msg_count)
{
hdr->type = ICMP_ECHO;
hdr->un.echo.id = 1;
hdr->un.echo.sequence = (*msg_count)++;
}
void fill_data(unsigned char * data)
{
memset(data, 'J', PING_PKT_S-sizeof(struct icmphdr));
}
void fill_eth(struct ethhdr* eth){
eth->h_source[0] = 0x08;
eth->h_source[1] = 0x00;
eth->h_source[2] = 0x27;
eth->h_source[3] = 0xe8;
eth->h_source[4] = 0xb5;
eth->h_source[5] = 0x12;
eth->h_dest[0] = 0x08;
eth->h_dest[1] = 0x00;
eth->h_dest[2] = 0x27;
eth->h_dest[3] = 0xe8;
eth->h_dest[4] = 0xb5;
eth->h_dest[5] = 0x12;
eth->h_proto = htons(ETH_P_IP);
}
void send_ping(ping_ctx* ctx)
{
int msg_count=0, i, addr_len, pkt_sent=1,
msg_received_count=0,on =1;
struct sockaddr_ll remote_addr;
struct ip *ip = NULL;
struct icmphdr* icmph = NULL;
unsigned char* data = NULL;
struct ethhdr* eth = NULL;
struct sockaddr_ll r_addr;
struct timespec time_start, time_end, tfs, tfe;
long double rtt_msec=0, total_msec=0;
struct timeval tv_out;
/*Set params*/
char *to = ctx->dstIP;
char *from = ctx->srcIP;
int ping_sockfd = ctx->r_sock;
int ttl = ctx->ttl;
int tos =ctx->tos;
/*Timer Settings*/
tv_out.tv_sec = RECV_TIMEOUT;
tv_out.tv_usec = 0;
clock_gettime(CLOCK_MONOTONIC, &tfs);
//GET INTERFACE INDEX FOR INTERFACE enp0s3
/*struct ifreq ifr;
size_t if_name_len = strlen(if_name);
if(if_name_len<sizeof(ifr.ifr_name)){
memcpy(ifr.ifr_name,if_name,if_name_len);
ifr.ifr_name[if_name_len]=0;
}
else{
die("Interface name is too long");
}
memset(&ifr,0,sizeof(ifr));
strncpy(ifr.ifr_name,enp0s3,IFNAMSIZ-1);
int fd = socket(AF_UNIX,SOCK_DGRAM,0);
if(fd==-1)
printf("Error opening socket");
if(ioctl(fd,SIOCGIFINDEX,&ifr)==-1){
printf("Error getting index name");
}*/
//int ifindex = ifr.ifr_ifindex;
int ifindex = if_nametoindex("enp0s3");
printf("The interface number is : %d \n",ifindex);
remote_addr.sll_ifindex = ifindex;
remote_addr.sll_halen = ETH_ALEN;
remote_addr.sll_addr[0] = 0x08;
remote_addr.sll_addr[1] = 0x00;
remote_addr.sll_addr[2] = 0x27;
remote_addr.sll_addr[3] = 0xe8;
remote_addr.sll_addr[4] = 0xb5;
remote_addr.sll_addr[5] = 0x12;
if(setsockopt(ping_sockfd, SOL_SOCKET, SO_RCVTIMEO,
(const char*)&tv_out, sizeof tv_out) < 0)
{
printf("Setting socket options failed for SO_RCVTIMEO\n");
return;
}
/*if(setsockopt(ping_sockfd, IPPROTO_RAW, IP_HDRINCL, &on, sizeof(on)) < 0)
{
printf("Setting socket options failed for IP_HDRINCL");
return;
}*/
while(pingloop)
{
pkt_sent=1;
memset(&g_pckt, 0, sizeof(g_pckt));
/*ETHERNET Header*/
eth = (struct ethhdr *)&g_pckt;
fill_eth(eth);
/*IP Header*/
ip = (struct ip *)(eth + 1);
fill_ip_h(ip, ctx);
/*ICMP Header*/
icmph = (struct icmphdr*)(ip + 1);
fill_icmp_h(icmph, &msg_count);
/*Data*/
data = (unsigned char *)(icmph + 1);
fill_data(data);
/*ICMP Checksum*/
icmph->checksum = checksum(icmph, PING_PKT_S);
usleep(PING_SLEEP_RATE);
/*TX*/
clock_gettime(CLOCK_MONOTONIC, &time_start);
if ( sendto(ping_sockfd, &g_pckt, sizeof(g_pckt), 0,
(struct sockaddr*) &remote_addr,
sizeof(remote_addr)) <= 0)
{
printf("\nPacket Sending Failed!\n");
pkt_sent=0;
}
/*RX*/
/*addr_len=sizeof(r_addr);
if ( recvfrom(ping_sockfd, icmph, PING_PKT_S, 0,
(struct sockaddr*)&r_addr, &addr_len) <= 0
&& msg_count>1)
{
printf("\nPacket receive failed!\n");
} */
else
{
clock_gettime(CLOCK_MONOTONIC, &time_end);
double timeElapsed = ((double)(time_end.tv_nsec -
time_start.tv_nsec))/1000000.0;
rtt_msec = (time_end.tv_sec-
time_start.tv_sec) * 1000.0
+ timeElapsed;
// if packet was not sent, don't receive
if(pkt_sent)
{
if(!(g_pckt.hdr.type ==69 && g_pckt.hdr.code==0))
{
printf("Error..Packet received with ICMP"
"type %d code %d\n",
g_pckt.hdr.type, g_pckt.hdr.code);
}
else
{
printf("%d bytes Received reply from %s: icmp_seq=:%d ttl=%d time=%Lf ms\n",PING_PKT_S, ctx->dstIP, msg_count, ctx->ttl, rtt_msec);
msg_received_count++;
}
}
}
}
clock_gettime(CLOCK_MONOTONIC, &tfe);
double timeElapsed = ((double)(tfe.tv_nsec -
tfs.tv_nsec))/1000000.0;
total_msec = (tfe.tv_sec-tfs.tv_sec)*1000.0+
timeElapsed ;
printf("\n%d packets sent, %d packets received, %f percent "
"packet loss. Total time: %Lf ms.\n\n",
msg_count, msg_received_count,
((msg_count - msg_received_count)/msg_count) * 100.0,
total_msec);
}
int main(int argc, char *argv[])
{
ping_ctx ctx = {0};
if(argc!=3)
{
printf("sudo ./myping 10.117.157.6 10.39.51.117\n");
return 0;
}
signal(SIGINT, intHandler);
ctx.r_sock = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
if(ctx.r_sock <0)
{
printf("\nSocket file descriptor not received\n");
return 0;
}
ctx.tos = 0;
ctx.ttl = 64;
strncpy(ctx.dstIP, argv[1],strlen(argv[1]));
strncpy(ctx.srcIP, argv[2],strlen(argv[2]));
send_ping(&ctx);
return 0;
}
当使用tcpdump捕获数据包并在wireshark中打开捕获时,看不到ICMP数据包。
最佳答案
您的以太网 header 有一些错误填写。我运行你的程序并使用wireshark捕获一些错误的包。您的程序可以发送数据包,但这与 ICMP 协议(protocol)不匹配。因此,如果您使用过滤器 ICMP ,则不会捕获任何内容。以太网 header 存在一些错误,导致后续协议(protocol)(ICMP)无法解析。
//Wireshark capture packet like below
Linux cooked capture
Packet type: Send by us (4)
Link-layer address type: 1
Link-layer address length: 6
Source: PcsCompu_e8:b5:12(08:00:27:e8:b5:12)
Unused: 0000
Protocol: Unknown (0xd370)
关于c - 为什么打开wireshark抓包后没有发送ICMP ping请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53919669/
我开始学习 Oracle JavaSE 认证考试。 我创建了一个 IntelliJ Idea 项目来处理我的训练源代码。我想尽量减少 IntelliJ Idea 的帮助。 我只想使用:颜色语法、终端选
默认情况下,.DPR 和 .DPROJ 的文件扩展名描述是相同的,因此在资源管理器中打开具有相同基本名称的项目文件时,两个文件描述都会列为“Delphi 项目文件”,这提供了一个选择开发人员 - 要打
我目前正在从 android 网站了解 Navigation Drawer,我正在使用他们的示例 http://developer.android.com/training/implementing-
我需要帮助。 我在 A3:A500 列中有单词和数字 我需要改变他们的名字。 如果单元格包含单词“previ”,则如果单元格是数字,则将字母“p”放入新列中。如果它是一个词,那么不要放“p” ...就
我正在尝试编写一些 VBA,它允许按钮添加一个空行,保持相同的格式,就在 SUM 公式所在的行上方。 到目前为止,我实现了创建一个空行,但我不知道如何实现代码以让该新行继承相同的格式样式(包括边框和格
我在共享网络驱动器上有两个工作簿: 工作簿 A(表) 工作簿 B(数据透视表 - 连接到源工作簿 A) 我正在尝试,当打开 Workbook B 时,运行宏并执行以下操作: 取消保护工作簿 B 上的某
我正在开发一个需要在在线/离线模式下进行测试的应用程序,所以我想知道是否有任何方法可以打开/关闭 iPad 模拟器的互联网连接(不关闭我的 MAC 的互联网服务)。请帮忙 最佳答案 不,模拟器使用与您
我需要对目录的所有文件执行我的脚本(搜索)。以下是有效的方法。我只是问哪个最好。 (我需要格式的文件名:parsedchpt31_4.txt) 全局: my $parse_corpus; #(for
在我的代码中,我想有条件地执行一些操作: #ifdef DEBUG NSLog(@"I'm in debug mode"); #endif 我已配置“项目”->“编辑项目设置”->“构建”选项卡,以便
我编写了一个小程序来比较笔记本电脑的性能。为了使程序CPU更加密集,我用一些多线程代码(通过Parallel API实现)实现了Rabin-Karp模式匹配算法。 我注意到,当在关闭编译器优化标志的情
使用以下代码来关闭模态并打开第二个模态。总是遇到同样的问题可以关闭一个但不能打开第二个,或者如果我更改顺序我可以打开一个但不能关闭另一个。 (我想我已经尝试过101版本了)。如果有人能帮忙的话。
blue sky 默认情况下,当指针悬停时显示标题。 是否可以切换它,例如: $('#button').on('click', function(){ if (something) {turn
我正在编写一个简单的宏,它将打开、保存和关闭一个 Excel 文件(例如 myworkbook.xlsx),但我无法执行此操作。我的文件 myworkbook.xlsx 位于以下位置: C:\User
我正在加载两个 geoJson 层 - 出于测试目的,两个层都是相同的数据,但是是从两个不同的 json 文件中提取的。当我在图层 Controller 中打开和关闭图层时,图层的绘制顺序会发生变化。
我在我的设置 Activity 中发现,当用户单击 ToggleButton 时,它应该在整个应用程序中静音,但它不起作用。我在教程类中放入的 SoundPool onClick 按钮声音仍在 onC
我有一部双卡手机。如果我想打开飞行模式,两个 SIM 卡都会发生这种情况。 是否可以通过编程方式仅对一张SIM卡进行操作(用户可以选择两者之一)?我看到了here上的帖子,他们一直工作到 API 16
我目前正在开发一个带有一些 pipe() 和重定向的 C shell 程序。 我使用 dup2() stdout 和 stderr (1 & 2) 重定向。 当我用 int fd = open("te
Jquery: 有没有办法捕获浏览器打开“打开/另存为”对话框时触发的事件? Open/Save dialog example http://qpack.orcanos.com/helpcenter/
我知道你可以用 window.close 关闭 window.open 但还有其他方法吗?我有一个打开 facebook 连接的弹出窗口,我想在用户连接到 facebook 时关闭弹出窗口,然后刷新父
我搜索一个事件,如果不存在,则搜索一种方法来了解屏幕是否关闭(电源选项 - 控制面板 - 关闭显示设置)。 这些解决方案都不适合我。 所以要么我在某个地方错了,要么就是不合适。 How to get
我是一名优秀的程序员,十分优秀!