弄了两天,终于搞定了!把最简单的icmp报文发送实现了。本程序在linux环境编写,使用原始套接字。

实现步骤:

1、得到protocol实体(protoent,声明于);

2、初始化地址结构(sockaddr_in,声明于);

3、创建套接字(socket(),声明于,参数声明于);

4、更改socket选项,更改发送缓冲区大小(setsockopt(),声明于);

5、发送报文(sendto(),声明于);

6、关闭socket描述符(close(),声明于);

代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

typedef unsigned char byte;

typedef unsigned long ulong;

typedef unsigned short ushort;

const char* proto_name

="icmp";

const char* ip_str

="10.14.4.167";

#define SEND_BUFF1024

#define CK_NULL(___ent,___str)({\

if(___ent==NULL)printf(___str);\

})

#define PRT_ADDR_TEST(___addr)({\

printf("direction ip is:%d.%d.%d.%d\r\n",\

(___addr&0x000000ff), \

(___addr&0x0000ff00)>>8,\

(___addr&0x00ff0000)>>16,\

(___addr&0xff000000)>>24\

);\

})

byte

send_buffer[SEND_BUFF];

// declare function

ushort

icmp_cal_cksum(byte*,int);

void

icmp_create(){

struct icmp* icmph=

(struct icmp*)send_buffer;

int pid,

i,

data_len;

pid=getuid();

data_len=SEND_BUFF-8;// send_length sub icmp header_length

icmph->icmp_type=ICMP_ECHO;

icmph->icmp_code=0;

icmph->icmp_cksum=0;

icmph->icmp_seq=0;

icmph->icmp_id=pid;

for(i=0;i

icmph->icmp_data[i]=i;

icmph->icmp_cksum=icmp_cal_cksum((byte*)icmph,data_len);

}

ushort

icmp_cal_cksum(byte* _data,int _data_len){

int sum=0;

int odd=_data_len&0x01;

ushort* value=(ushort*)_data;

while(_data_len& 0xfffe){

sum+=*(ushort*)_data;

_data+=2;

_data_len-=2;

}

if(odd){

ushort tmp=((*_data)<<8)&0xff00;

sum+=tmp;

}

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

sum+=(sum>>16);

return ~sum;

}

int

main(int argc,char** argv){

// socket fd

int sockfd;

// return err code

int err_code;

// send data length

int snd_len;

// long addr

ulong addr_l;

// protocol entity

struct protoent* protocol;

// socket send buffer length

int send_buff=SEND_BUFF;

// protocol socket address

struct sockaddr_in dest_addr;

// get protocol entity

protocol=getprotobyname(proto_name);

CK_NULL(protocol,"error! cannot get protocol entity!!!\r\n");

// convert ip str to u_long

addr_l=inet_addr(ip_str);

if(addr_l==INADDR_NONE){

printf("error! cannot convert ip str to long addr!!!\r\n");

return -1;

}

addr_l=htonl(addr_l);

PRT_ADDR_TEST(addr_l);

// set memory 0

bzero((char*)&dest_addr,sizeof(dest_addr));

// full sockaddr_in struct

memcpy((char*)&dest_addr.sin_addr,&addr_l,sizeof(addr_l));

sockfd=socket(AF_INET,SOCK_RAW,protocol->p_proto);

if(sockfd<0){

printf("error!cannot create sockfd!\r\n");

return -1;

}

err_code=setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&send_buff,sizeof(send_buff));

icmp_create();

snd_len=sendto(sockfd,send_buffer,send_buff,0,(struct sockaddr*)&dest_addr,sizeof(dest_addr));

if(snd_len

printf("error!send data length is not enougth!\r\n");

return -1;

}

printf("data has sended length=%d\r\n",snd_len);

close(sockfd);

return 0;

}

注:创建原始套接字时应使用管理员权限,否则会创建失败!好像也有代码中获取权限的方法,但我没有去查相关资料。

linux看请求报文发送的ip,Linux C 实现最简单的ICMP_ECHO请求报文发送相关推荐

  1. linux 看不到htaccess文件夹,linux:.htaccess文件使用教程

    1.1 什么是.htaccess文件 从本指南中,你将可以学习到有关.htaccess文件及其功能的知识,并用以优化你的网站.尽管.htaccess只是一个文件,但它可以更改服务器的设置,允许你做许多 ...

  2. linux用cat查看本机ip,linux sh 如何根据出口网关来获取本机出口ip

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 测试机器:华为P7-L07 安卓测试环境:EMUI 3.1 安卓5.1.1(版本号:P7-L07C01B851,基带版本:23.600.06.00.00, ...

  3. Linux网卡改为动态过去IP,Linux修改网卡ens33为eth0以及centos7下修改动态IP为静态IP地址...

    修改网卡ens33为eth0 在使用RHEL和Centos7,发现网卡名称变成了EnoX,挺不习惯.现更改回旧名称eth0看着顺眼. 1.备份/etc/sysconfig/grub文件 cp /etc ...

  4. linux udp广播转发到所有ip,linux – 所有接口上的UDP广播

    首先,你应该考虑广播过时,特别是INADDR_BROADCAST(255.255.255.255).您的问题突出显示广播不合适的原因之一.它应该与IPv4一起死亡(希望).请注意,IPv6甚至不具有广 ...

  5. linux查看上次重启日志和ip,Linux實時查看日志,訪問前10IP 和相關命令

    本文介紹Linux下tail命令的使用方法. linux tail命令用途是依照要求將指定的文件的最后部分輸出到標准設備,通常是終端,通俗講來,就是把某個檔案文件的最后幾行顯示到終端上,假設該檔案有更 ...

  6. deep linux 看视频卡,在Deepin 20等Linux系统下用Chrome看虎牙直播经常卡的处理

    有时候在Deepin 20等Linux系统下用谷歌Chrome浏览器看虎牙直播会卡,而且是经常性的,而同样的操作在Windows系统下就不会,所用的依然还是Chrome浏览器.通常情况下看网站直播视频 ...

  7. Linux系统如何配置64个IP,Linux系统配置IP

    Linux版本centos7 64位系统 一,DHCP分配IP地址 自动获取IP: # dhclient 二,设置静态IP 查看网卡名称: # ip add 或 # ifconfig 编辑网卡配置文件 ...

  8. linux看不到进程管理,关于Linux下进程的详解【进程查看与管理】

    关于Linux下进程的详解[进程查看与管理] 一.关于进程 进程: 已经启动的可执行程序的运行实力 进程的组成:一个进程包含内核中的一部分地址空间和一系列数据结构.其中地址空间是内核标记的一部分内存以 ...

  9. linux看目录用的哪个磁盘,linux查看目录大小及硬盘大小

    linux查看目录大小及硬盘大小的命令: # du -ks   ---in all # du -k     ---every last du和df命令都被用于获得文件系统大小的信息:df用于报告文件系 ...

最新文章

  1. 云计算开发技术,Python自动化运维开发实战三部分
  2. ubuntu 21.04创建桌面快捷方式的方法
  3. java param request_使用@RequestParam将请求参数绑定至方法参数
  4. log4j与commons-logging,slf4j的关系
  5. 带哨兵节点的链_关于链表中哨兵结点问题的深入剖析
  6. UOJ59 WC2013 小Q运动季
  7. 如何使用视频转换器将ogg格式转换为MP3格式
  8. java gui构建机制_java-从构造函数构建GUI. [设计决策]
  9. final关键字的用法
  10. RocketMQ消息消费源码分析
  11. 消息队列常见的使用场景
  12. 【C语言】输出一个菱形
  13. python里面fabs什么意思_介绍Python中的fabs()方法的使用
  14. 高中的班花貌美如花,我与一众兄弟将其“共享”了!
  15. 孩子用什么样的灯对眼睛没有伤害呢?2023这样的灯光更护眼
  16. php中md5加密函数怎么用,PHP加密函数—md5()函数加密实例用法
  17. 利用selenium实现淘宝双十一抢购商品
  18. Tensorflow基础4:run()函数
  19. 三.ffmpeg 集成av1
  20. 使用pyecharts绘制中国历代都城的分布图

热门文章

  1. 谷歌推出理解神经网络的新方法SVCCA | NIPS论文+代码
  2. Objc Runtime在项目中该怎么用
  3. 什么是语义化的HTML?有何意义?为什么要做到语义化?
  4. 移动应用程序框架Kendo UI Mobile发布R2 2016 SP2
  5. unity, destroy gameObject destroy all children
  6. 利用钩子技术控制进程创建(附源代码)
  7. FGMap学习之--快速入门
  8. Java学习笔记——面向对象 1
  9. Vue2.0史上最全入坑教程(中)—— 脚手架代码详解
  10. android UI 标签