构造协议报文、自定制协议方法

来源:互联网 发布:守望先锋数据查询关闭 编辑:程序博客网 时间:2024/06/03 14:22

最近在做嵌入式产品开发,需要构造报文、定制协议,以满足通信的需求,下面转发来自互联网上的“构造ip和icmp报文”文章,

 

以使通过该文章,可以总结出构造协议的一般方法!


出处:《Linux 编程技术详解》

//在<netinet/ip.h>中可以查看IP包头结构struct iphdr
//在<netinet/ip_icmp.h>中可以查看ICMP包头结构struct icmphdr
struct iphdr * ip_header;//IP包头
struct icmphdr * icmp_header;//ICMP包头

char * buffer;
unsigned short buffer_size;

//申请内存空间,并填写包头信息
buffer_size=sizeof(struct iphdr)+ sizeof(struct icmphdr)+ sizeof(struct timeval);
buffer=(char *)malloc(buffer_size);
 
memset(buffer, 0, sizeof(buffer));//初始化内存空间

//IP包头为20B
ip_header=(struct iphdr *)buffer;//很巧妙哦
ip_header->ihl=5;//IP包头长度为20字节,以4字节为单位,
ip_header->version=4;//版本:IPv4
ip_header->tos=0;//服务类型
ip_header->tos_len=htons(buffer_size);//IP包长度
ip_header->id=rand();//标识
ip_header->ttl=64;//生存周期
ip_header->frag_off=0x40;//分片偏移位
ip_header->protocol=IPPROTO_ICMP;//协议类型
ip_header->check=0;//IP包的校验值,由系统自动填写,不用管
ip_header->daddr=inet_addr("172.18.132.242");//目标IP地址
ip_header->saddr=0;//源IP地址,由系统自动填写,不用管

//ICMP包头为8B
icmp_header=(struct icmphdr *)(ip_header+1);//很巧妙哦
icmp_header->type=ICMP_ECHO;//消息类型
icmp_header->code=0;//编码,当前未使用
icmp_header->un.echo.id=htons(6000);//发送ICMP包的本地端口号
icmp_header->un.echo.sequence=0;

//据上,此时时间戳数据段的起始地址为buffer[28](ping程序数据段中需要携带时间戳信息,该信息用于计算ICMP数据包返回时的时间)
struct timeval * tp=(struct timeval *)&buffer[28];//很巧妙哦
gettimeofday(tp,NULL);

//ICMP报文含有校验字段,用于校验ICMP报文是否有效
//在校验时,ICMP数据包段的所有数据按16位进行分组,并累加;最后一次累加时,如果位数不够,补零累加;如果出现进位,则将16位高位加到16位低位上
icmp_header->checksum=cal_cksum((const u_short *)icmp_header, sizeof(struct icmphdr)+sizeof(struct timeval), 0);//计算ICMP报文的校验值(这个函数是书中的)

 

原创粉丝点击