网络通讯中的checksum算法

本文探讨了网络通讯中checksum算法的重要性,通过Debian系统抓包工具验证ICMP网络包的checksum原理。实验内容包括理解checksum算法,使用wireshark抓包并分析ICMP请求与回复包的checksum值,以及实现ping功能时checksum的验证。
摘要由CSDN通过智能技术生成

网络通讯中的checksum算法

一、实验目的和任务

  1. 本实验要求复习Debian系统抓包工具的使用。
  2. 本实验要求理解checksum算法原理和实现方法。
    二、实验设备介绍
    1.软件需求: win7操作系统,VMware workstation,ubuntu12 [配置交叉编译环境]。
    2.硬件需求: PC内存大于1G,硬盘空间大于20G;smart210开发板。
    三、注意事项和要求
    1.启动Debian系统,并设置正确网络IP地址。
    2.分析checksum字段与数据包的关系。
    3.请抓包结果截图放入实验报告中。
    四、实验内容和步骤

4.1较验字段checksum介绍

checksum意思是较验和,就是将一段已有长度的数据按照某种整数类型(通常是16位无符号整数)进行累加(进位部分再继续加到低位),累加后的结果再取反以用于校验。具有校验合的数据包再次进行校验后结果则为0,因为这种运算硬件或软件设计简单,要校验的数据长度可以在较大范围变化,对数据的校验提供较高的可靠性保证,适用场合很广。理论上checksum并不是100%保证数据是可靠的。
下面是一个具体的checksum数据计算过程;在这里插入图片描述

4.2 Debian中捕获网络包来验证ICMP网络包中checksum算法原理

打开Debian虚拟机,打开一个终端,使用su命令,密码:333333更换为root账号,终端输入wireshark命令启动抓包程序,点击Options按钮打开抓包选项,输入icmp为抓包过滤选项,点击Start按钮开始抓包。再启动一个终端窗口,输入ping -c 3 www.baidu.com命令,执行ping命令,网络将产生ICMP的request请求包和ICMP的reply包。在这里插入图片描述
在这里插入图片描述
抓包成功后得到下面的内容,一个ICMP请求包,一个完整的网络包是以太网头+IP头+ICMP包。选中ICMP部分,将ICMP包内容拷贝到文本文件中。在这里插入图片描述
IP包头部分:
4500 0054 0000 4000 4001 b6e8 c0a8 031a 0ed7 b127
其中b6e8是checksum

ICMP请求包:
0800 5424 3a0f 0001 33f6 245a 2278 0400 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021
2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637
其中5424是checksum在这里插入图片描述
ICMP回复包:
0000 5c24 3a0f 0001 33f6 245a 2278 0400 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021
2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637
其中5c24是checksum

4.3checksum算法设计与验证

<参考网址:http://blog.csdn.net/zjli321/article/details/74908451>
checksum较验是将原始数据每16位一组,进行带进位的累加,全部数据累结果超出16位则将进位部分再进行一次16位累加,累加后结果取反后作为最后的结果。在这里插入图片描述
下面是计算checksum的例子算法代码。

//063.c checksum算法
#include "stdio.h"
unsigned short csum(unsigned short *addr, int count);
unsigned char data[] = 
{
   
    0x45,0x00,0x00,0x3c,
    0xe0,0x8a,0x00,0x00,
    0x40,0x01,0x00,0x00,//0x18,0xdd
    0xc0,0xa8,0x00,0x08,
    0xc0,0xa8,0x00,0x01
};
int main(void)
{
   
    printf("the check sum is 0x%x\n",csum((unsigned short *)data,sizeof(data)));
    return 0;
}

unsigned short csum(unsigned short *addr, int count)
{
   
    /* Compute Internet Checksum for "count" bytes
    * beginning at location "addr".
    */
    long sum = 0;
unsigned short tmp = 0;
//将原始数据取成16位数,加运算时以32位数相加,这样可以保留进位 
    while( count > 1 ) 
    {
   
        /* This is the inner loop */
        sum += (long)(* ((unsigned short *)addr++));
        count -= 2;
    }
    
    /* Add left-over byte, if any */
    if( count > 0 )
    {
   
        sum += * (unsigned char *) addr;//??
    }
/* Fold 32-bit sum to 16 bits */
//将高16位部分再加到低16位上
    while (sum>>16)
    {
   
        sum = (sum & 0xffff) + (sum >> 16);
    }    
    return ~sum;
}

请根据实验机器抓包内容,对IP头和ICMP头的数据,修改以上程序,验证checksum字段的计算过程,即查看程序对IP头部分运长输出是否为0xe8b6,进一步验证ICMP的checksum值。

4.4 Ping功能的实现

进一步验证checksum字段在实际网络协议中的应用。

/*064.c   ping.c*/ 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h> /*bzero*/
#include <netdb.h>
#include <pthread.h>
/*保存已经发送包的状态值*/
typedef struct pingm_pakcet{
   
	struct timeval tv_begin;	/*发送的时间*/
	struct timeval tv_end;		/*接收到的时间*/
	short seq;					/*序列号*/
	int flag;		/*1,表示已经发送但没有接收到回应包0,表示接收到回应包*/
}pingm_pakcet;
//用数组来记录每个ICMP包
static pingm_pakcet pingpacket[128];
static pingm_pakcet *icmp_findpacket(int seq);
static unsigned short icmp_cksum(unsigned char *data,  
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值