-
2019-07-27 11:19:04
我们知道IPv4的报头的长度一般为20bytes,而checksum的长度为16bits(2bytes)。下面我用一个例子来讲解计算过程:
假设某个IPv4数据包报头为:E3 4F 23 96 44 27 99 F3 [00 00],注意,用中括号括起来的就是checksum
- checksum的初始值自动被设置为0
- 然后,以16bit为单位,两两相加,对于该例子,即为:E34F + 2396 + 4427 + 99F3 = 1E4FF
- 若计算结果大于0xFFFF,则将,高16位加到低16位上,对于该例子,即为,0xE4FF + 0x0001 = E500
- 然后,将该值取反,即为~(E500)=1AFF
此时,发送包已经计算完毕,下面,我们再来计算接收方的信息
- 若数据包正常,那么,它的报头应该是这样 ,E3 4F 23 96 44 27 99 F3 1A FF
- 此时,前18bytes的内容不变,等于E500,然后,将E500与刚刚计算的校验和1AFF相加
- 若计算结果为FFFF,那么,该数据包正常,没有错误
更多相关内容 -
IPv4头部校验和的反码算法 (2002年)
2021-05-20 05:02:01给出了正整数反码加法和补码加法间关系的2个定理。在此基础上,给出了IPv4头部校验和2个反码算法。 -
ipv4和ipv6的校验
2021-06-03 14:58:38最近在搞一个ipv6的,需要对它进行校验,原来是只由ipv4,现在需要改为,即支持v4又要支持v6,话不多说,上菜! ipv4的校验:最近在搞一个ipv6的,需要对它进行校验,原来是只由ipv4,现在需要改为,即支持v4又要支持v6,话不多说,上菜!
ipv4的校验:
var ipv4 = new RegExp(/^([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])(\.(\d|[1-9](\d)?|1\d{2}|2[0-4]\d|25[0-5])){3}$/);
同时校验ipv4和ipv6:(网上搜的,但是有用!)
var ipv4v6 = new RegExp(/^([\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^::([\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:):([\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){2}:([\da-fA-F]{1,4}:){0,2}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){3}:([\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}$|^:((:[\da-fA-F]{1,4}){1,6}|:)$|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)$|^([\da-fA-F]{1,4}:){2}((:[\da-fA-F]{1,4}){1,4}|:)$|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,4}){1,3}|:)$|^([\da-fA-F]{1,4}:){4}((:[\da-fA-F]{1,4}){1,2}|:)$|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?$|^([\da-fA-F]{1,4}:){6}:$/);
-
[wireshark]IP头校验和错误的解决方案
2020-05-11 15:03:59Wireshark测试的时候发现了好多的包都被标记为 Bad Tcp 把包打开仔细查看后发现只有一...其中的 “IPv4硬件校验和”即对应了这两个选项,它的可选项有“Rx & Tx 开启、Rx开启、Tx开启和关闭”四个。 默认的配置往往转载自多篇文章。
出现该问题的原因:
Wireshark测试的时候发现了好多的包都被标记为 Bad Tcp
把包打开仔细查看后发现只有一个问题就是:header checksum == 0x0000
查阅了大量资料后发现原来是网卡的自动计算校验和在作怪。
网卡驱动的高级配置中,一般有两项叫做Rx Checksum Offload和Tx Checksum Offload
以win7为例,可以看下图所示:
其中的 “IPv4硬件校验和”即对应了这两个选项,它的可选项有“Rx & Tx 开启、Rx开启、Tx开启和关闭”四个。默认的配置往往是 Rx & Tx 开启。它表示网卡会帮应用进行计算ip头的checksum字段,这样一来,操作系统的ip协议栈无须进行额外的checksum运算,它只需封装好ip 数据报后甩给网卡即可。
甩给网卡的原始ip报文的checksum字段值,原则上是无意义的,即随机的,但是根据windows上的表现来看,这个值一直 是固定0x0000。
猜测一下Wireshark的抓包原理,大概是利用Pcap提供的某种机制,把发给网卡的数据给截获了一份,这样一来,如果操作系统协议栈中出来的ip包的checksum尚未被正确设置,Wireshark完全不知道该数据还会被网卡进行修正,于是它就报错了。
至此,如何使得Wireshark不再抱怨ip头校验错误,最直接的方法是直接选择关闭“IPv4硬件校验和”选项即可。
但是坚决不能这样做,这样会使系统的性能降低,上网变慢。 我们直接在wireshark软件中关闭ip头的校验即可!修改方案:
edit -> preferences -> protocols -> IPv4 -> validate the IPv4 checksum if possible
把对勾去掉即可,这才是正确的解决方法!
-
Linux -- IPV4、IP、TCP、UDP数据报头的格式以及校验和算法
2019-09-09 18:12:05一、以下各个头文件所在的位置为 Ubuntu下目录/usr/include/linux/ Fedora下目录 /usr/src/kernels/2.6.35.6-45.fc14.i686/include/linux/ 二、ip头部的结构体定义如下 #include <linux/ip.h> struct ...一、以下各个头文件所在的位置为
Ubuntu下目录/usr/include/linux/
Fedora下目录 /usr/src/kernels/2.6.35.6-45.fc14.i686/include/linux/
二、ip头部的结构体定义如下
#include <linux/ip.h> struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else #error "Please fix <asm/byteorder.h>" #endif __u8 tos; __be16 tot_len; __be16 id; __be16 frag_off; __u8 ttl; __u8 protocol; __sum16 check; __be32 saddr; __be32 daddr; /*The options start here. */ };
结构体成员对应的结构如下图所示。
下面主要说明几个字段:
iphdr->ihl:首部长度(4bit),首部长度指的是IP头部占32 bit(4字节)字的数目(也就是IP头部包含多少个4字节),包括任何选项。由于它是一个4比特字段, 因此首部最长为60个字节。
iphdr->check:IP首部检验和字段(16位,2字节),只计算IP头部的的所有字段的校验和,它不对首部后面的数据进行计算。
发送方:计算一份数据报的IP头部检验和,则需要首先把此检验和字段置为0。然后对首部中每个16 bit(2字节)进行二进制反码求和(整个首部看成是由一串16 bit的字组成),然后结果存在此检验和字段中。
接受方:当收到一份IP数据报后,对首部中每个16 bit(2字节)进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该为全1。如果结果不是全1(即检验和错误),那么IP就丢弃收到的数据报。但是不生成差错报文,由上层去发现丢失的数据报并进行重传。
iphdr->tot_len:总长度字段(16位)是指整个IP数据报的长度(包含后面的协议头和数据),以字节为单位。
利用首部长度字段和总长度字段,就可以知道 IP数据报中数据内容的起始位置和长度。由于该字段长16比特,所以IP数据报最长可达65535字节,总长度字段是IP首部中必要的内容,因为一些数据链路(如以太网)需要填充一些数据以达到最小长度。尽管以太网的最小帧长为46字节,但是IP数据可能会更短。如果没有总长度字段,那么IP层就不知道46字节中有多少是IP数据报的内容。
三、tcp头部的结构体定义如下
#include <linux/tcp.h> struct tcphdr { __be16 source; __be16 dest; __be32 seq; __be32 ack_seq; #if defined(__LITTLE_ENDIAN_BITFIELD) __u16 res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; #elif defined(__BIG_ENDIAN_BITFIELD) __u16 doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1; #else #error "Adjust your <asm/byteorder.h> defines" #endif __be16 window; __sum16 check; __be16 urg_ptr; };
结构体成员对应的结构如下图所示。
tcphdr->doff:TCP头部长度,指明了在TCP头部包含多少个32位的字。
此信息是必须的,因为options域的长度是可变的,所以整个TCP头部的长度也是变化的。从技术上讲,这个域实际上指明了数据部分在段内部的其起始地址(以32位字作为单位进行计量),因为这个数值正好是按字为单位的TCP头部的长度,所以,二者的效果是等同的。
tcphdr->check:检验和,覆盖了整个的TCP报文段(包含后面的数据),这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证。
四、udp头部的结构体定义如下
struct udphdr { __be16 source; __be16 dest; __be16 len; __sum16 check; };
udp协议很简单,其数据报由udp首部和用户数据两部分组成,其中首部只有8字节。
1、源端口号(Source Port):长度为16位(2字节),指明发送数据的进程的端口号。
2、目的端口号(Destination Port):长度为16位(2字节),指明目的主机接收数据的进程的端口号。
3、长度(Data Length):长度为16位(2字节),该字段值为udp报头和数据两部分的总字节数。
4、检验和(Checksum):长度为16位(2字节),udp检验和是udp报头和udp数据的所有数据的检验和。对报文中每个16 bit(2字节)进行二进制反码的求和。由发送端计算和存储,由接收端校验。
5、数据
五、Ip头和tcp头udp头的数据校验和的算法函数
char setIpCheck(struct iphdr* iphdrp) { iphdrp->check = 0; iphdrp->check = htons(checksum(0, (u_int8_t *)iphdrp, iphdrp->ihl << 2)); return iphdrp->check == 0 ? -1 : 0; } char setTcpCheck(struct iphdr* iphdrp) { struct tcphdr *tcphdrp = (struct tcphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2)); tcphdrp->check = 0; size_t tcplen = ntohs(iphdrp->tot_len) - (iphdrp->ihl<<2); u_int32_t cksum = 0; cksum += ntohs((iphdrp->saddr >> 16) & 0x0000ffff); cksum += ntohs(iphdrp->saddr & 0x0000ffff); cksum += ntohs((iphdrp->daddr >> 16) & 0x0000ffff); cksum += ntohs(iphdrp->daddr & 0x0000ffff); cksum += iphdrp->protocol & 0x00ff; cksum += tcplen; tcphdrp->check = htons(checksum(cksum, (u_int8_t*)tcphdrp, tcplen)); return tcphdrp->check == 0 ? -1 : 0; } char setUdpCheck(struct iphdr* iphdrp) { struct udphdr *udphdrp = (struct udphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2)); udphdrp->check = 0; size_t udplen = ntohs(iphdrp->tot_len) - (iphdrp->ihl<<2); u_int32_t cksum = 0; cksum += ntohs((iphdrp->saddr >> 16) & 0x0000ffff); cksum += ntohs(iphdrp->saddr & 0x0000ffff); cksum += ntohs((iphdrp->daddr >> 16) & 0x0000ffff); cksum += ntohs(iphdrp->daddr & 0x0000ffff); cksum += iphdrp->protocol & 0x00ff; cksum += udplen; udphdrp->check = htons(checksum(cksum, (u_int8_t*)udphdrp, udplen)); return udphdrp->check == 0 ? -1 : 0; } static u_int16_t checksum(u_int32_t init, u_int8_t *addr, size_t count) { /* Compute Internet Checksum for "count" bytes * beginning at location "addr". */ u_int32_t sum = init; while( count > 1 ) { /* This is the inner loop */ sum += ntohs(* (u_int16_t*) addr); addr += 2; count -= 2; } /* Add left-over byte, if any */ if( count > 0 ) sum += ntohs(( *(u_int8_t *) addr )); /* Fold 32-bit sum to 16 bits */ while (sum>>16) sum = (sum & 0xffff) + (sum >> 16); return (u_int16_t)~sum; }
-
IPv4协议首部结构分析及校验位算法实现
2020-04-04 01:34:31IPv4协议首部校验位算法实现IPv4与Ipv6的首部区别IPv4 数据包结构C算法实现Java算法实现 ...Ipv4协议包含首部校验和字段等信息, 导致路由转发时需要进行重新计算, 增加了延时成本, 在IPv6中取消了对应的校验和字段. ... -
IPv4头部结构
2021-06-10 08:22:154位版本号:IPv4协议值固定为4。 4位头部长度:标识头部最多有多少个4字节(32位(bit))。4位最大值是15,即最大可表示有15个4字节(60个字节,减去基本的20字节,也说明了为什么选项最多40字节)。 8位服务类型... -
JS常用正则表达式超全集(密码强度校验,金额校验,IE版本,IPv4,IPv6校验)
2021-01-21 11:09:07有时候正则表达式可以大大提高我们的开发效率呢 比如这段校验基本日期格式的javascript代码: ...密码的强度必须包含大小写字母和数字的组合,不能使用特殊符号,长度在8-10之间: ^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]) -
TCP/IP卷一:26---Internet协议之(IPv4、IPv6数据报,Internet校验和)
2019-07-19 09:28:40所有TCP、 UDP、 ICMP和IGMP数据都通过IP数 据报传输 IP的可靠性 IP提供了一种尽力而为、无连接的数据报交付服务。“尽力而为”的含义是不保 证IP数据报能成功到达目的地 虽然IP不是简单丢弃所有不必要流量,但它... -
ipv4报文头部详解
2021-01-22 15:18:46ipv4报文头详解ipv4报文头各字段解释分片详解 ipv4报文头 Type of Service 在部分资料中又称为DS Field 各字段解释 版本(Version) 该字段规定了 IP协议的版本,值为4。长度为4位。 Internet 报头长度(Internet ... -
[Scapy]Scapy IPv4/IPv6 UDP Checksum 校验和计算方法
2022-03-08 21:21:34Scapy IPv4/IPv6 UDP校验和计算方法 -
IPv4头部和IPv6头部
2018-07-23 17:25:22IPv4: IPv4数据报。...头部校验和有助于确保头部字段被正确发送到目的地。 IPv6: IPv6头部大小固定(40字节),并包含128位源地址和目的地址。下一个头部字段能用于说明IPv6头部之后其他扩... -
JS IPV4和IPV6混合正则校验
2020-08-13 11:31:32IPV4和IPV6混合正则校验 const ipReg = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4... -
分析IPV4头结构
2020-11-09 21:42:26(4)8位服务类型(Type Of Sevevice,TOS)包括一个3位的优先权字段(现在已经被忽略),4位的TOS字段和1位保留字段(必须置0)。4位的TOS字段分别表示,:最小时延,最大吞吐量,最高可靠性,和最小费用,其中最多... -
分析比较IPV4报文头部和IPV6报文头部的区别
2020-02-25 22:43:51版本(Version):长度4bit,IP协议的版本号,分为IPV4和IPV6。IPV4值为0100 头部长度(Header Length):长度4bit,IPV4的头部总长度。当报文头部中无Opthion字段时,报文头部总长度为20字节。 区分服务... -
ipv4和ipv6的 udp/tcp CRC校验和算法
2016-11-30 14:30:24ipv4和ipv6下udp/tcp层协议的CRC校验和算法详解 -
IPV4地址的合法性校验及IPV4地址和无符号整型之间相互转换
2018-08-12 08:31:03将无符号整数转成IP地址 #include &lt;iostream&gt;...using namespace std;...void ipv4_to_str(char* ... //输出格式为A.B.C.D. sprintf_s(addr_str, 20, "%d.%d.%d.%d", (ipv4_... -
IPV4和IPV6正则表达式的深入讲解
2021-01-18 15:29:40IPV4正则表达式 Ipv4地址分为ABCDE五大类,其中ABC类是普通ip地址,D类是组播地址,E类保留,作为研究之用。 范围分别为: A: 1.0.0.1 ―一126.155.255.255 内网地址范围:10.0.0.0 一一10-255.255.255 B: ... -
2.2.1 IPv6和IPv4基本头部格式
2021-05-23 03:20:222.2 IPv6报文2.2.1 IPv6和IPv4基本头部格式根据IPv4报文中存在的问题,IPv6报文头格式与IPv4相比进行了一些改动。IPv6头部结构遵循以下新规则:基本头部的固定长度:IPv6的基本报文头...去除头部校验和:由于变化的T... -
IPv4基础知识
2020-09-25 22:39:58IPv4地址包含网络号和主机号。 网络号:唯一的标识了一条物理链路或逻辑链路,对于该链路相连的所有设备来说网络号部分是共同的。 主机号:唯一标识了该链路上连接的具体设备。 1.按照主机数量分类 ... -
PHP校验IPV4和IPV6格式正确性
2021-03-23 08:17:08使用filter_var函数,该函数还能校验URL,EMAIL等,可查看PHP手册IPV4return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;IPV6return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG... -
IPv4检验和计算
2017-06-06 19:10:00IPv4检验和计算 IP分组中的检验和仅覆盖首部,而不管数据,首部被划分为16位的段,把所有段相加,结果取反,塞进首部检验和里 在目的主机中,首部划分为16位,相加,结果肯定是16个1,然后取反,结果为0.如下 ... -
IPv4和IPv6的数据报结构头部详解
2020-03-23 20:30:43Intemet校验和是一个16位的数字和,它能以相当高的概率确定接收的消息或其中的部分内容是否与发送的相匹配。注意,Intemet校验和算法与常见的循环冗余校验(CRC)[PB61]不同,后者提供了更强的保护功能。 CRC不记得的... -
ipv4
2021-01-12 06:48:10摘要 腾兴网为您分享:互助作业,期货开户云app,360加密软件,火知了,17app,中望cad2009,唐诗三百首早教,魔力秀...ipv4和ipv6都是常有的地址,用户在日常上网中需要用到,有小伙伴想知道ipv4和ipv6的地址位数,是... -
IPv4报文头部分析
2020-03-28 14:48:31IPV4报文如下所示: 翻译版本如图: 各段主要内容如下: ...(2)头部长度:(4 bit),确定ip报文的长度,ipv4报头单位是32bit,在这里,4位二进制表示为0101,即换算为 (5*32bit)/8 = 20 字节,故... -
ipv4、tcp、udp数据报头的格式以及校验和算法
2019-10-02 15:04:27一、以下各个头文件所在的位置为 Ubuntu下目录/usr/include/linux/ Fedora下目录 /usr/src/kernels/2.6.35.6-45.fc14.i686/include/linux/ 二、ip头部的结构体定义如下 1 #include <linux/ip.h> 2 ... -
IPv4、TCP和UDP的校验和计算
2009-09-23 16:16:00分组头的校验和(checksum)算法是16位累加和后的反码,TCP和UDP数据报头也使用相同的校验算法,但参与运算的数据与IP分组头不一样。 IPv4分组头的结构如下所示: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6... -
以太帧IP校验和和UDP校验和计算及相关问题总结
2021-08-19 17:39:36以太帧IP校验和和UDP校验和计算及相关问题总结以太帧IP校验和和UDP校验和计算及相关问题总结一 以太帧IP校验和计算二 以太帧IP校验和计算三 wireshark抓包可以抓到,但是网络调试助手netassist没有返回是什么原因 ... -
IP协议 IPV4头部结构
2019-11-04 14:46:2316位头部校验和:发送端填充,接收端使用CRC检测IP数据报的头部(仅仅检测头部,不关心数据部分)在传输的过程中是否有损坏. 32位的源端IP地址和目的端IP地址用来标识数据报额发送端和接收端,一般这两个数值是...