ip校验和及udp校验和的计算方法

一、ip校验和的计算: 
计算方法: 
1. ip包头(共20个字节)按照每16个bit作为一个值依次进行相加 
2. 将计算结果的进位加到低16位上 
3. 将结果取反 
ip包头的内存内容 
eg: 
45 00 00 20 0F B8 00 00 
80 11 00 00 C0 A8 0A 9F 
C0 A8 0A C7

将 0x4500 0x0020 0x0FB8 0x0000 0x8011 0x0000 0xC0A8 0x0A9F 0xC0A8 0x0AC7 依次相加 所得结果为0x26B9F 然后将 0x0002 + 0x6B9F = 0x6BA1 
然后将 0x6BA1 取反得 0x945E

要注意两点:

1 在给ip_header计算校验和之前   首先把ip_header的checksum字段置为0
2 计算得到checksum之后   赋值时要转换为网络字节序:ip_header.checksum = htons(checksum); struct ip_header  //小端模式__LITTLE_ENDIAN  
{   unsigned char ihl:4;       //ip   header   length      unsigned char version:4;   //version     u_char        tos;         //type   of   service     u_short       tot_len;     //total   length     u_short       id;          //identification     u_short       frag_off;    //fragment   offset     u_char        ttl;         //time   to   live     u_char        protocol;    //protocol   type     u_short       check;       //check   sum     u_int         saddr;       //source   address     u_int         daddr;       //destination   address     
};  

// 计算ip数据包的checksum
// 将20个字节的ip数据包每16位组成一个字  依次相加  设所得结果为 0x34ACE
// 将 进位的3与 0x4ACE相加   得  0x4AD1
// 将 0x4AD1取反得到checksum
u_short get_ip_checksum(char* ip_hdr)
{char* ptr_data = ip_hdr; u_long  tmp = 0; u_long  sum = 0; for (int i=0; i<20; i+=2){tmp += (u_char)ptr_data[i] << 8; tmp += (u_char)ptr_data[i+1]; sum += tmp; tmp = 0; }u_short lWord = sum & 0x0000FFFF; u_short hWord = sum >> 16; u_short checksum = lWord + hWord; checksum = ~checksum; return checksum; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

二、udp校验和


// udp的checksum计算是用到的结构体
// udp中, 参与计算checksum的数据包括三部分: 亚头部 + UDP头部 + 数据部分
// 亚头部: 4 byte源ip地址 + 4 byte目的ip地址 + 0x00 + 1 byte协议 + UDP 长度(2byte)(udp包头长度+数据长度)
// UDP包头: 2 byte源端口 + 2 byte目的端口 + 2 byte UDP包长(此处是udp包头自带的值不用变) + 0x0000 (checksum)
// 数据部分
// 计算方法同get_ip_checksum一样
typedef struct udp_check_subhdr         // udp计算checksum时的 亚头部: 4 byte源ip地址 + 4 byte目的ip地址 + 0x00 + 1 byte协议 + UDP 长度(2byte)
{u_long   src_ip; u_long   dst_ip; char     mbz;           // must be zerochar     protocol; u_short  len;           // 这里的长度是指  udp packet中  udp头部和数据部分的总长度
} udp_check_subhdr;// pudp_pkt: udp的整个packet
// pkt_len: 整个packet的长度(以太网数据帧头 ip头 udp头)
u_short get_udp_checksum(char* pudp_pkt, int pkt_len) 
{ether_header *eth_hdr = (ether_header *)pudp_pkt; ip_header    *ip_hdr  = (ip_header*)( pudp_pkt+sizeof(ether_header) ); udphdr       *udp_hdr = (udphdr*)( (char*)ip_hdr+sizeof(ip_header) ); u_short udp_part_len = pkt_len-sizeof(ether_header)-sizeof(ip_header);    // 亚包头中的len: =udp包头长度+数据长度(udp包总长度-ethernet包头长度-ip包头长度); udp_check_subhdr udp_subhdr; udp_subhdr.protocol = ip_hdr->protocol; udp_subhdr.dst_ip = ip_hdr->daddr; udp_subhdr.src_ip = ip_hdr->saddr; udp_subhdr.mbz = 0x00; udp_subhdr.len = htons(udp_part_len); int subhdr_len = sizeof(udp_check_subhdr); int buf_size = udp_part_len + subhdr_len;         // 亚包头 + udp包头 + 数据部分的总长度if (pkt_len < buf_size)return 0; u_char* buffer = (u_char*)malloc(buf_size); memset(buffer, 0x00, buf_size); memcpy(buffer, (char*)&udp_subhdr, subhdr_len); memcpy(buffer + subhdr_len, (char*)udp_hdr, udp_part_len); unsigned char* ptr_data = buffer; u_long  tmp = 0; u_long  sum = 0; for (int i=0; i<buf_size; i+=2){tmp += (u_char)ptr_data[i] << 8; tmp += (u_char)ptr_data[i+1]; sum += tmp; tmp = 0; }u_short lWord = sum & 0x0000FFFF; u_short hWord = sum >> 16; u_short checksum = lWord + hWord; checksum = ~checksum; return checksum;  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

最后: ip校验和还有udp校验和的查看是在接收端查看的,从源端查看是没有计算的值(ip校验和是0x00 udp校验和不清楚什么意义) 用pcap发送自定义数据包时 调用pcap_sendpacket时是直接发送定义好的数据包 就是将定义好的包直接通过网卡发送 不会经过电脑上的ip层和链路层 所以 校验和要自己计算

从两个网页处学到计算方法: 
http://www.360doc.com/content/12/0511/15/621500_210332306.shtml 
http://blog.csdn.net/maeom/article/details/6065203

*注: 仅作为笔记之用 如有错误或不妥之处还望指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291755.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Blog.Core开源】网关统一集成下游服务文档

一般看到公众号更新&#xff0c;就是大概率要开始上班了&#x1f602;上回书咱们说到了《【Blog.Core开源】快速预览Admin界面效果》&#xff0c;这样我们就可以专注于后端开发&#xff0c;而且也能快速的实现效果的预览。那今天我们继续来往下走&#xff0c;说一说网关相关的内…

android4.3 截屏功能的尝试与失败分析

1.背景 上一篇讲了在源码中捕获到了android手机的截屏函数&#xff08;同时按下电源键与音量减&#xff0c;详情http://blog.csdn.net/buptgshengod/article/details/19911909&#xff09;&#xff0c;经过一周的研究还是没有在手机上实现系统截屏功能&#xff0c;总结下尝试的…

numpy方法总结

2019独角兽企业重金招聘Python工程师标准>>> 一、数组方法 创建数组&#xff1a;arange()创建一维数组&#xff1b;array()创建一维或多维数组&#xff0c;其参数是类似于数组的对象&#xff0c;如列表等 反过来转换则可以使用numpy.ndarray.tolist()函数&#xff0…

一些移动端开发的细节记录

好久不来写东西了,最近太忙,给自己搞的很累,对自己选择的道路有些不自信了. 决定干够半年后,大概四月中旬,会离职休息两三个月,去几个喜欢的地方看看,锻炼打球减肥,再把最近想要做过的项目整理一下,编写一些自己的插件和库,把之前积累的一些书过一下. 对前端的热爱没有丝毫改变…

阿里云离线数据仓库

阿里云离线数据仓库第1章 数据仓库概念第2章 项目需求及架构设计2.1 项目需求分析2.2 阿里云技术框架2.2.1 技术选型2.2.2 系统数据流程设计第3章 数据生成模块3.1 埋点数据基本格式3.2 事件日志数据3.2.1 商品列表页&#xff08;loading&#xff09;3.2.2 商品曝光&#xff08…

C++之extern和string的find函数和substr函数和data()函数使用总结

1、extern使用总结 网上看的例子,特么没有一个看懂的,为什么会用到这个extern呢?因为有一个cpp文件需要另外一个cpp文件的里面的值,第一反应想到的是static,因为java 里面如果在变量前面加了static,一切就好说了,class.成员变量,然后特么我也去找c++里面的static…

技术分享 | 混合云模式下SaaS端前端最佳实践

导读&#xff1a;集成开放平台采用的是混合云部署架构&#xff0c;包含两个大的组件&#xff0c;管理控制台和引擎。管理控制台是SaaS的&#xff0c;部署在公有云&#xff0c;按租户隔离。引擎部署在客户私有云。一套SaaS版的管理控制台如何适配不同客户的引擎&#xff0c;本文…

统计素数个数

10:判决素数个数总时间限制:1000ms 内存限制:65536kB描述 输入两个整数X和Y&#xff0c;输出两者之间的素数个数&#xff08;包括X和Y&#xff09;。输入 两个整数X和Y&#xff08;1 < X,Y < 105&#xff09;。输出 输出一个整数&#xff0c;表示X&#xff0c;…

记一则Hadoop DataNode OOM故障,以及解决方案

一、故障症状最近公司一个集群跑大任务时&#xff0c;datanode日志报DataXceiveServer: Exiting due to:java.lang.OutOfMemoryError: unable to create new native thread异常&#xff0c;然后计算节点上的DataNode直接挂掉。DataNode异常日志截图如下&#xff1a;2014-03-06 …

阿里云实时数据仓库

阿里云实时数据仓库——学习笔记 课程目标 学习搭建一个实时数据仓库&#xff0c;掌握数据采集、存储、计算、输出、展示等整个业务流程。整个实时数据仓库系统是在阿里云架构上搭建&#xff0c;掌握并学会运用各个服务组件&#xff0c;及各个组件之间如何联动。前置知识要求&…

[转]svn常用命令

谢谢原作者:http://blog.sina.com.cn/s/blog_963453200101eiuq.html 1、检出svn co http://路径(目录或文件的全路径) [本地目录全路径] --username 用户名 --password 密码svn co svn://路径(目录或文件的全路径) [本地目录全路径] --username 用户名 --password 密码…

手动挡五个档位示意图_汽车档位越多越好?听听专业回答

如今的汽车市场百花齐放&#xff0c;汽车厂商们也不断在研发过程中寻找不同的突破口&#xff0c;其中汽车变速器的档位变化就是众多汽车品牌当做噱头的重点&#xff0c;不知从什么时候开始&#xff0c;自动变速箱档位数量变多成为了深受汽车品牌喜爱的突破点&#xff0c;渐渐的…

常用排序-基数排序,计数排序

基数排序 将整数每个位数分别比较&#xff0c;先找出最长位&#xff0c;针对每个位&#xff08;个位&#xff0c;十位…&#xff09;利用桶的思想&#xff0c;将每个位的元素个数统计&#xff0c;倒序读入temp[10]列表中&#xff0c; 时间复杂度O(d(nK)),k是10进制&#xff0c;…

Android之用netcfg命令获取手机虚拟网卡tun0的信息

1、在终端输入下面命令 adb shell adb netcfg 2、展示结果 3、使用总结 我们得到手机 tun0 地址为10.1.102.11 然后在vpn后台&#xff0c;我们先找到是哪个tun&#xff0c;我们可以使用ip route命令ip route show table2 这个允许结果就是 地址 哪个tun比如我们得到是tun2 然…

C# 基于事件的异步模式

点击蓝字 关注我们开工大吉EventBasedAsyncPattern 方法使用了基于事件的异步模式。这个模式定义了一个带有 “Async” 后缀的方法。示例代码再次使用了WebClient 类。对于同步方法DownloadString&#xff0c;WebClient类提供了一个异步变体方法 DownloadStringAsync。当请求完…

Tomcat 下 Memcached 集群与 Terracotta 集群比较

总结&#xff1a;Terracotta 集群配置要比Memcached 集群简单&#xff0c;但Terracotta 集群启动的速度要比Memcached 集群慢&#xff0c;性能Terracotta 集群要比Memcached 集群好。但性能都好不过weblogic单机的性能&#xff01;&#xff01; Terracotta 集群效果图如下&…

POJ 2887 Big String

Big StringTime Limit: 1000MS Memory Limit: 131072KTotal Submissions: 7053 Accepted: 1684Description You are given a string and supposed to do some string manipulations.Input The first line of the input contains the initial string. You can assume that it …

MySQL For RedHat Linux(源码安装,附安装包)

准备工作在http://pan.baidu.com/s/1GsS3s下载安装包 Mysql.zip把相应的包放在 /opt 目录下 解压mysql.tar.gz 检测系统是否安装MySQL1、执行 #rpm -qa | grep -i mysql如果出现&#xff1a;[rootlocalhost Mysql]# rpm -qa|grep -i mysql [rootlocalhost Mysql]# 则未安装MySQ…

IDEA简单配置教程

IDEA简单配置教程 ——做好前期配置工作&#xff0c;后期少走弯路。 创建模块(Module) 设置(Settings) 设置主题 窗体及菜单字体及大小 设置编辑区主题 通过插件(plugins)更换主题 设置鼠标滚轮修改字体大小 设置鼠标悬浮提示 设置自动导包功能 显示行号和方法间的分隔符 忽略…

Android之解决打补丁包后移动端为什么不升级,升级之后出现“应用未安装“,以及更新成功之后反复更新问题

1、打补丁包后移动端为什么不升级,而且PC端和移动端访问同一个url得到的xml文件内容不一致 不升级是因为补丁包文件搞错了,虽然改了文件内容, pc端访问同一个url得到的xml文件内容不一致,是以为服务端集群导致。 总结: 1)、给客户打补丁包之前一定要到客户后台把相关文件…