数据包收发c语言程序,在C程序中发送ICMP数据包

数据包收发c语言程序,在C程序中发送ICMP数据包我正在尝试用 C 创建一个 ICMPping 测试程序 但是在成功发送数据包时遇到了困难 sendto 函数返回字节数和所有内容但实际上没有发送数据包 我已经在目标计算机上使用 WireShark 验证了这一点 主机上的常规 ping 工作正常 但在 WireShark 中显示 这是我的代码 include include include include include include include

我正在尝试用C创建一个ICMP ping测试程序,但是在成功发送数据包时遇到了困难. sendto函数返回字节数和所有内容但实际上没有发送数据包.我已经在目标计算机上使用WireShark验证了这一点.主机上的常规ping工作正常,但在WireShark中显示.

这是我的代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

unsigned short cksum(unsigned short *addr, int len);

int main(int argc, char *argv[])

{

int sock;

char send_buf[400], recv_buf[400], src_name[256], src_ip[15], dst_ip[15];

struct ip *ip = (struct ip *)send_buf;

struct icmp *icmp = (struct icmp *)(ip + 1);

struct hostent *src_hp, *dst_hp;

struct sockaddr_in src, dst;

struct timeval t;

int on;

int num = 10;

int failed_count = 0;

int bytes_sent, bytes_recv;

int dst_addr_len;

int result;

fd_set socks;

/* Initialize variables */

on = 1;

memset(send_buf, 0, sizeof(send_buf));

/* Check for valid args */

if(argc < 2)

{

printf(“\nUsage: %s \n”, argv[0]);

printf(“- dst_server is the target\n”);

exit(EXIT_FAILURE);

}

/* Check for root access */

if (getuid() != 0)

{

fprintf(stderr, “%s: This program requires root privileges!\n”, argv[0]);

exit(EXIT_FAILURE);

}

/* Get source IP address */

if(gethostname(src_name, sizeof(src_name)) < 0)

{

perror(“gethostname() error”);

exit(EXIT_FAILURE);

}

else

{

if((src_hp = gethostbyname(src_name)) == NULL)

{

fprintf(stderr, “%s: Can’t resolve, unknown source.\n”, src_name);

exit(EXIT_FAILURE);

}

else

ip->ip_src = (*(struct in_addr *)src_hp->h_addr);

}

/* Get destination IP address */

if((dst_hp = gethostbyname(argv[1])) == NULL)

{

if((ip->ip_dst.s_addr = inet_addr(argv[1])) == -1)

{

fprintf(stderr, “%s: Can’t resolve, unknown destination.\n”, argv[1]);

exit(EXIT_FAILURE);

}

}

else

{

ip->ip_dst = (*(struct in_addr *)dst_hp->h_addr);

dst.sin_addr = (*(struct in_addr *)dst_hp->h_addr);

}

sprintf(src_ip, “%s”, inet_ntoa(ip->ip_src));

sprintf(dst_ip, “%s”, inet_ntoa(ip->ip_dst));

printf(“Source IP: ‘%s’ — Destination IP: ‘%s’\n”, src_ip, dst_ip);

/* Create RAW socket */

if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)

{

perror(“socket() error”);

/* If something wrong, just exit */

exit(EXIT_FAILURE);

}

/* Socket options, tell the kernel we provide the IP structure */

if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)

{

perror(“setsockopt() for IP_HDRINCL error”);

exit(EXIT_FAILURE);

}

/* IP structure, check the ip.h */

ip->ip_v = 4;

ip->ip_hl = 5;

ip->ip_tos = 0;

ip->ip_len = htons(sizeof(send_buf));

ip->ip_id = htons(321);

ip->ip_off = htons(0);

ip->ip_ttl = 255;

ip->ip_p = IPPROTO_ICMP;

ip->ip_sum = 0;

/* ICMP structure, check ip_icmp.h */

icmp->icmp_type = ICMP_ECHO;

icmp->icmp_code = 0;

icmp->icmp_id = 123;

icmp->icmp_seq = 0;

/* Set up destination address family */

dst.sin_family = AF_INET;

/* Loop based on the packet number */

for(int i = 1; i <= num; i++)

{

/* Header checksums */

icmp->icmp_cksum = 0;

ip->ip_sum = cksum((unsigned short *)send_buf, ip->ip_hl);

icmp->icmp_cksum = cksum((unsigned short *)icmp, sizeof(send_buf) – sizeof(struct icmp));

/* Get destination address length */

dst_addr_len = sizeof(dst);

/* Set listening timeout */

t.tv_sec = 5;

t.tv_usec = 0;

/* Set socket listening descriptors */

FD_ZERO(&socks);

FD_SET(sock, &socks);

/* Send packet */

if((bytes_sent = sendto(sock, send_buf, sizeof(send_buf), 0, (struct sockaddr *)&dst, dst_addr_len)) < 0)

{

perror(“sendto() error”);

failed_count++;

printf(“Failed to send packet.\n”);

fflush(stdout);

}

else

{

printf(“Sent %d byte packet… “, bytes_sent);

fflush(stdout);

/* Listen for the response or timeout */

if((result = select(sock + 1, &socks, NULL, NULL, &t)) < 0)

{

perror(“select() error”);

failed_count++;

printf(“Error receiving packet!\n”);

}

else if (result > 0)

{

printf(“Waiting for packet… “);

fflush(stdout);

if((bytes_recv = recvfrom(sock, recv_buf, sizeof(ip) + sizeof(icmp) + sizeof(recv_buf), 0, (struct sockaddr *)&dst, (socklen_t *)&dst_addr_len)) < 0)

{

perror(“recvfrom() error”);

failed_count++;

fflush(stdout);

}

else

printf(“Received %d byte packet!\n”, bytes_recv);

}

else

{

printf(“Failed to receive packet!\n”);

failed_count++;

}

fflush(stdout);

icmp->icmp_seq++;

}

}

/* Display success rate */

printf(“Ping test completed with %d%% success rate.\n”, (((num – failed_count) / num) * 100));

/* close socket */

close(sock);

return 0;

}

/* One’s Complement checksum algorithm */

unsigned short cksum(unsigned short *addr, int len)

{

int nleft = len;

int sum = 0;

unsigned short *w = addr;

unsigned short answer = 0;

while (nleft > 1)

{

sum += *w++;

nleft -= 2;

}

if (nleft == 1)

{

*(unsigned char *)(&answer) = *(unsigned char *)w;

sum += answer;

}

sum = (sum >> 16) + (sum & 0xffff);

sum += (sum >> 16);

answer = ~sum;

return (answer);

}

对我做错了什么的想法?校验和还好吗?两者都使用0可以吗?

编辑:好的,所以我设法得到正确发送的数据包,感谢下面的人!目标计算机将发回回信回复.但是,现在,我的程序没有收到答复. select()函数总是超时.我已经更新了上面的代码.

编辑2:好吧,我已经开始工作了!我需要将套接字协议设置为IPPROTO_ICMP而不是IPPROTO_RAW,它工作得很好!再次感谢你们的评论!真有帮助!看起来我只能将一个答案标记为正确,但你们都帮助解决这个问题. ?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221958.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午4:53
下一篇 2026年3月17日 下午4:54


相关推荐

  • 整合Flex和Java—配置篇

    整合Flex和Java—配置篇作为一个 Java 程序员学习 Flex 关心的就是怎样将 Flex 和 Java 进行结合交互 带着 Java 程序员的思维 一开始学习 Flex 并没有按部就班的学习 Flex 的基础知识 而是想搞清楚 Flex 到底怎样和 Java 交互的 经过了一个周末的研究 终于初见成果 下面就重要的讲解三种配置的两个 http bbs airia cn FLEX thread 72 1 1 aspx

    2026年3月26日
    2
  • Mac PyCharm 打不开处理

    Mac PyCharm 打不开处理1 第一步 先输入 cd Applications PyCharm app Contents MacOS2 第二步 查看无法打开 pycharm 的原因 需要输入 c pycharm3 第三步 下面就是展示的分析日志 其中许多小伙伴都找不到网上说的这个地址 cd Users 用户名 Library Preferences PyCharm2019 1 其实地址不是这个 而是 Users liuxiaoming Library ApplicationS JetBrain

    2025年6月28日
    13
  • 神秘模型 Nano Banana

    神秘模型 Nano Banana

    2026年3月13日
    3
  • Nacos整合SpringCloud(配置中心、注册中心)[通俗易懂]

    Nacos整合SpringCloud(配置中心、注册中心)[通俗易懂]1.什么是Nacos?Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。2.Nacos配置中心整合2.1启动NacosServer并添加配置1.下载地址:直接下载:NacosServer下载页源码构建:Github项目页面2.启动Linux/Unix/Mac操作系统,执行命令shstartup.sh-ms…

    2022年6月6日
    54
  • java中ReentrantLock类的tryLock和tryLock的例子和用法

    java中ReentrantLock类的tryLock和tryLock的例子和用法ReentrantLock类的tryLock和tryLock(时间)马克-to-win:tryLock的方法就是试一下,如果能得到锁,就返回真,如果当时得不到,马上就返回假,绝不等。tryLock(时间)的用法就是在规定的时间内设法得到锁。如果在规定的时间内最终不能得到锁,就返回假。注意,这个方法是可以被打断的,打断后的处理方法和上面的例子lockInterruptibly的处理一样。…

    2022年10月8日
    4
  • java.util.Map——Map集合的常用方法「建议收藏」

    java.util.Map——Map集合的常用方法「建议收藏」Java技术交流群:817997079,欢迎“有志之士”的加入。开发中最常用的就是List集合和Map集合,Map集合是基于java核心类——java.util中的;Map集合用于储存元素对,Map储存的是一对键值(key和value),是通过key映射到它的value;下面介绍的是Map集合的一些经常用到的方法以及代码示例。1.map.size();方法作用:获取map集合类的大小(m…

    2022年5月7日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号