UDP校验

来源:互联网 发布:mac合并单元格快捷键 编辑:程序博客网 时间:2024/06/12 04:53

UDP结构由首部和数据两部分组成。

        首部由8个字节。包括:

1.源端口号,两个字节

2.目的端口号,两个字节

3.长度,两个字节。UDP用户数据包的总长度。以字节为单位。

4.检验和,两个字节。用来检验UPD伪首部、数据部分、首部。和IP分组首部校验方法一样。

     其中伪首部:又称伪包头,是指在TCP分段或者UDP数据格式中,在数据包首部前面增加源地址、目的地址、IP组的协议字段、TCP或UDP数据的总长度等共12个字节,协议类型就一个字节,需要补充一个字节0x0.

次伪首部是一个临时结构,它既不向下也不向上传递,仅仅为了保证可以校验套接字的正确性。


        伪首部+UDP首部+数据 一起计算校验和。

具体方法如下:

1.按每16位求和得出一个32位的数。

2.如果这个32位的数,高16位不为0,则高16位加上低16再得到一个32位的数。

3.重复第二步,直到高16位为0.,之后将低16位取反,得到校验和。

       感谢http://blog.chinaunix.net/uid-20753106-id-3987608.html作者的算法,在此仅做个记录:

#include <stdio.h>#include <unistd.h>#include <arpa/inet.h>typedef struct {    int srcIp;    int dstIp;    short udp_len;    char rsv;    char protocol;    unsigned short src_port;    unsigned short dst_port;    unsigned short len;    unsigned short check_sum;    char data[2];} UDPHDR;char arr[100] = {0xc0, 0xa8, 0xd1, 0x80, 0xc0, 0xa8, 0xd1, 0x01, 0x00, 0x0a, 0x00, 0x11, 0x13, 0x88, 0x13, 0x88, 0x00, 0x0a, 0x00, 0x00, 0x61, 0x66};unsigned short check_sum(unsigned short *a, int len);int main(){    short b = 0;    UDPHDR udphdr = {0};    udphdr.srcIp = inet_addr("192.168.209.128");    udphdr.dstIp = inet_addr("192.168.209.1");    udphdr.udp_len = htons(10);    udphdr.protocol = 0x11;    udphdr.rsv = 0;    udphdr.src_port = htons(5000);    udphdr.dst_port = htons(5000);    udphdr.len = htons(10);    udphdr.check_sum = 0;    udphdr.data[0] = 0x61;    udphdr.data[1] = 0x66;    b = check_sum((short *)&udphdr, 22);    printf("[test ...] b = %04x\n", b & 0xffff);    b = check_sum((short *)arr, 22);    printf("[test arr] b = %04x\n", b & 0xffff);    return 0;}unsigned short check_sum(unsigned short *a, int len){    unsigned int sum = 0;    while (len > 1) {        sum += *a++;        len -= 2;    }    if (len) {        sum += *(unsigned char *)a;    }    while (sum >> 16) {        sum = (sum >> 16) + (sum & 0xffff);    }    return (unsigned short)(~sum);}

以上是作者抓的数据包,仅作参考。

   校验原理:

接收方进行校验时,也是对每16位(2字节)进行二进制反码求和。接收方计算校验和时的首部与发送方计算校验和时的首部相比,多了一个发送方计算出来的校验和的反码。因此,如果首部在传输过程中没有发生差错,那么接收方计算的结果应该为全一。 

  

0 0
原创粉丝点击