How to Calculate IP/TCP/UDP Checksum
来源:互联网 发布:下载cdr软件 编辑:程序博客网 时间:2024/05/30 04:51
ref: http://www.roman10.net/2011/11/27/how-to-calculate-iptcpudp-checksumpart-2-implementation/IP Header Checksum Calculation Implementation
To calculate the IP checksum, one can use the code below,
/* set ip checksum of a given ip header*/void compute_ip_checksum(struct iphdr* iphdrp){ iphdrp->check = 0; iphdrp->check = compute_checksum((unsigned short*)iphdrp, iphdrp->ihl<<2);}/* Compute checksum for count bytes starting at addr, using one's complement of one's complement sum*/static unsigned short compute_checksum(unsigned short *addr, unsigned int count) { register unsigned long sum = 0; while (count > 1) { sum += * addr++; count -= 2; } //if any bytes left, pad the bytes and add if(count > 0) { sum += ((*addr)&htons(0xFF00)); } //Fold sum to 16 bits: add carrier to result while (sum>>16) { sum = (sum & 0xffff) + (sum >> 16); } //one's complement sum = ~sum; return ((unsigned short)sum);}The method compute_ip_checksum initialize the checksum field of IP header to zeros. Then calls a method compute_checksum. The mothod compute_checksum accepts the computation data and computation length as two input parameters. It sum up all 16-bit words, if there’s odd number of bytes, it adds a padding byte. After summing up all words, it folds the sum to 16 bits by adding the carrier to the results. At last, it takes the one’s complement of sum and cast it to 16-bit unsigned short type.
Note that the data structure iphdr and tcphdr and udphdr are Linux data structures representing IP header, TCP header and UDP header respectively. You may want to Google for more information in order to understand the code.
TCP Header Checksum Calculation Implementation
To calculate the TCP checksum, you can use the code below,
/* set tcp checksum: given IP header and tcp segment */void compute_tcp_checksum(struct iphdr *pIph, unsigned short *ipPayload) { register unsigned long sum = 0; unsigned short tcpLen = ntohs(pIph->tot_len) - (pIph->ihl<<2); struct tcphdr *tcphdrp = (struct tcphdr*)(ipPayload); //add the pseudo header //the source ip sum += (pIph->saddr>>16)&0xFFFF; sum += (pIph->saddr)&0xFFFF; //the dest ip sum += (pIph->daddr>>16)&0xFFFF; sum += (pIph->daddr)&0xFFFF; //protocol and reserved: 6 sum += htons(IPPROTO_TCP); //the length sum += htons(tcpLen); //add the IP payload //initialize checksum to 0 tcphdrp->check = 0; while (tcpLen > 1) { sum += * ipPayload++; tcpLen -= 2; } //if any bytes left, pad the bytes and add if(tcpLen > 0) { //printf("+++++++++++padding, %dn", tcpLen); sum += ((*ipPayload)&htons(0xFF00)); } //Fold 32-bit sum to 16 bits: add carrier to result while (sum>>16) { sum = (sum & 0xffff) + (sum >> 16); } sum = ~sum; //set computation result tcphdrp->check = (unsigned short)sum;}The method compute_ip_checksum initialize the checksum field of IP header to zeros. Then calls a method compute_checksum. The mothod compute_checksum accepts the computation data and computation length as two input parameters. It sum up all 16-bit words, if there’s odd number of bytes, it adds a padding byte. After summing up all words, it folds the sum to 16 bits by adding the carrier to the results. At last, it takes the one’s complement of sum and cast it to 16-bit unsigned short type.description of the algorithm.
Note that the data structure iphdr and tcphdr and udphdr are Linux data structures representing IP header, TCP header and UDP header respectively. You may want to Google for more information in order to understand the code.
TCP Header Checksum Calculation Implementation
To calculate the TCP checksum, you can use the code below,
/* set tcp checksum: given IP header and tcp segment */void compute_tcp_checksum(struct iphdr *pIph, unsigned short *ipPayload) { register unsigned long sum = 0; unsigned short tcpLen = ntohs(pIph->tot_len) - (pIph->ihl<<2); struct tcphdr *tcphdrp = (struct tcphdr*)(ipPayload); //add the pseudo header //the source ip sum += (pIph->saddr>>16)&0xFFFF; sum += (pIph->saddr)&0xFFFF; //the dest ip sum += (pIph->daddr>>16)&0xFFFF; sum += (pIph->daddr)&0xFFFF; //protocol and reserved: 6 sum += htons(IPPROTO_TCP); //the length sum += htons(tcpLen); //add the IP payload //initialize checksum to 0 tcphdrp->check = 0; while (tcpLen > 1) { sum += * ipPayload++; tcpLen -= 2; } //if any bytes left, pad the bytes and add if(tcpLen > 0) { //printf("+++++++++++padding, %dn", tcpLen); sum += ((*ipPayload)&htons(0xFF00)); } //Fold 32-bit sum to 16 bits: add carrier to result while (sum>>16) { sum = (sum & 0xffff) + (sum >> 16); } sum = ~sum; //set computation result tcphdrp->check = (unsigned short)sum;}The mothod sums the pseudo TCP header first, then the IP payload, which is the TCP segment. It also pads the last byte if there’re odd number of bytes. For detailed description of the algorithm.
UDP Header Checksum Calculation Implementation
To calculate the UDP checksum, one can follow the code below,
/* set tcp checksum: given IP header and UDP datagram */void compute_udp_checksum(struct iphdr *pIph, unsigned short *ipPayload) { register unsigned long sum = 0; struct udphdr *udphdrp = (struct udphdr*)(ipPayload); unsigned short udpLen = htons(udphdrp->len); //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~udp len=%dn", udpLen); //add the pseudo header //printf("add pseudo headern"); //the source ip sum += (pIph->saddr>>16)&0xFFFF; sum += (pIph->saddr)&0xFFFF; //the dest ip sum += (pIph->daddr>>16)&0xFFFF; sum += (pIph->daddr)&0xFFFF; //protocol and reserved: 17 sum += htons(IPPROTO_UDP); //the length sum += udphdrp->len; //add the IP payload //printf("add ip payloadn"); //initialize checksum to 0 udphdrp->check = 0; while (udpLen > 1) { sum += * ipPayload++; udpLen -= 2; } //if any bytes left, pad the bytes and add if(udpLen > 0) { //printf("+++++++++++++++padding: %dn", udpLen); sum += ((*ipPayload)&htons(0xFF00)); } //Fold sum to 16 bits: add carrier to result //printf("add carriern"); while (sum>>16) { sum = (sum & 0xffff) + (sum >> 16); } //printf("one's complementn"); sum = ~sum; //set computation result udphdrp->check = ((unsigned short)sum == 0x0000)?0xFFFF:(unsigned short)sum;The code is similar to TCP checksum computation. Except that when the checksum is compted as all 0s, we set them to 1s. As 0x0000 is already reserved for indicating that the checksum is not computed. Also please refer to part 1 for detailed description of the algorithm.
- How to Calculate IP/TCP/UDP Checksum
- How to Calculate IP/TCP/UDP Checksum–Part 3 Usage Example and Validation
- How to Calculate IP Header Checksum (With an Example)
- IP/TCP/UDP checksum
- TCP/IP Illustrated 笔记 UDP Checksum
- IP/TCP/UDP中Checksum的计算
- 计算ICMP,IP,UDP,TCP报头部分中的checksum
- DPDK 使用网卡ip/tcp/udp checksum offload
- TCP/IP checksum 简析
- TCP/IP checksum 简析
- how to calculate ANOVA
- ip,udp的checksum算法
- How To: Network / TCP / UDP Tuning
- How to calculate t distributions
- How to troubleshoot TCP/IP connectivity
- 如何计算UDP/TCP检验和checksum
- 如何计算UDP/TCP检验和checksum
- 计算UDP/TCP检验和checksum
- bat文件语法
- java Object 对象的的wait()、notify()、notifyAll()介绍
- JPush相关总结
- C#多线程
- 数据结构之栈的实现
- How to Calculate IP/TCP/UDP Checksum
- Eclipse配置svn 并从svn上面下载项目(将eclipse上面项目添加到svn上)
- omam138/upp/fpga
- Nginx配置性能深度优化
- HTML标签
- ASP.NET MVC 此安装不支持该项目类型解决方法
- 【OpenCV】OpenCV3的第二天——光流法(Optial Flow)运动目标检测
- 细思极恐!带指纹解锁的手机更安全吗?
- 2009秋季学期 Linux 辅导班