一、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

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

ip校验和及udp校验和的计算方法相关推荐

  1. IP ICMP TCP UDP 校验和

    首先,IP.ICMP.UDP和TCP报文头部都有校验和字段,大小都是16bit,算法也基本一样: 在发送数据时,为了计算数据包的校验和.应该按如下步骤: (1)把校验和字段置为0: (2)把需校验的数 ...

  2. IP头中的校验和计算方法介绍

    校验和的作用   按照协议的规定,报文到达每一层,首先验证校验和是否正确,丢弃掉不正确的报文,再才会进行后续操作.  那么校验和是怎么计算的呢?  校验和的计算方法(以 IP 首部中的校验和为例) 方 ...

  3. UDP头部结构,UDP校验和计算

    Udp:用户数据报协议 特点: 1.无连接,传输数据时不需要建立链接 2.尽最大努力传输,不可靠 3.面向报文的,接收到应用程序的数据时,只往数据前面加一个UDP头部就传给网络层,收到网络层传来的UD ...

  4. 利用Python计算UDP校验和

    UDP 检验和提供了差错检测的功能.这是基于端到端原则实现的.但是 UDP 的检验和并不提供差错回复的能力. 一.UDP结构 二.UDP校验和计算方法  计算校验和的过程很关键,主要分为以下几个步骤: ...

  5. UDP校验和(checksum)原理

    目录 1.校验和原理 1.1 校验和计算 1.2 校验和验证 2.UDP校验和原理 2.1 UDP校验数据范围 2.2 发送方UDP校验和计算 2.3 接收方UDP校验和验证 3.UDP伪首部 4.U ...

  6. 有关UDP校验和、循环冗余检测(CRC)的计算

    UDP校验和的计算 1.理论 UDP检验和提供了差错检型功能.这就是说,检验和用于确定当UDP报文段从源到达目的地移动时,其中的比特是否发生了改变(例如,由于链路中的噪声干扰或者存储在路由器中时引入问 ...

  7. TCP/IP协议与UDP协议的区别

    首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信! TCP/IP协议是一个协议簇.里面 ...

  8. ESP8266(4)WIFI与IP/端口与UDP/TCP

    ESP8266(4)WIFI与IP/端口与UDP/TCP 网络结构 WIFI IP/端口 IPv4 UDP/TCP 用户数据报协议UDP 传输控制协议TCP 网络结构 参照FPGA的的以太网通信 传送 ...

  9. linux计算校验和 c语言,校验和计算

    My own code //MGQ 2012-02-22 inline static unsigned short checksum(unsigned short *buffer,int size) ...

最新文章

  1. 【引用】JS刷新当前页面
  2. 成功解决ERROR: Could not install packages due to an EnvironmentError: [Errno 28] No space left on device
  3. Python之区块链简单记账本实现
  4. mysql online ddl
  5. [pytorch、学习] - 5.6 深度卷积神经网络(AlexNet)
  6. QuickBI助你成为分析师-邮件定时推送
  7. C和汇编混合编程----实现浮点数的加减乘除
  8. linux加密框架 crypto 算法管理 - 算法查找接口 crypto_find_alg
  9. 看完这篇还不会kafka,我跪榴莲!
  10. 鸿蒙系统暗黑2,暗黑破坏神2为什么被称为神作!看看装备强化系统就知道有多完美...
  11. DataGrid中的超级链接列使用注意点
  12. 微信域名屏蔽检测方法 微信域名检测接口的机制
  13. STM32建好的工程为啥下载不进去程序
  14. c++ const
  15. Java设计模式笔记--------工厂模式------抽象工厂模式
  16. 看爬b站《工作细胞》一万条评论看伙伴们在讨论什么
  17. ChatGPT套壳网站汇总-5月22日更新
  18. 笔记本加装SSD重装系统win10引导始终指向原系统的问题终极解决方法
  19. java调用银联支付接口开发,银联在线Java接口开发
  20. 【算法】求非空子集的三种思路

热门文章

  1. ShardingCore 如何呈现“完美”分表
  2. .NET 6 Preview 6 正式发布: 关注网络开发
  3. ML.NET Cookbook:(7)如何训练回归模型?
  4. C# 使用 CancellationTokenSource 终止线程
  5. 技术分享 | jaeger链路日志实现
  6. 打造跨平台.NET Core后台服务
  7. AspNetCore 启动地址配置详解
  8. .Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换
  9. asp.net core 自定义 Policy 替换 AllowAnonymous 的行为
  10. 一文带你了解华为云DevCloud为何能全面领跑中国DevOps云服务市场