-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathudp_checksum.c
More file actions
118 lines (100 loc) · 2.85 KB
/
Copy pathudp_checksum.c
File metadata and controls
118 lines (100 loc) · 2.85 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* File name: udp_checksum.c
*
* Date: July, 21, 2021
*
* Author: Keting Chen
*
* Description:
* This module does UDP datagram checksum justification and calculation.
*
**/
#include <stdio.h>
#include <udp_head.h>
extern int DEBUG;
/*
* This function helps justify the UDP datagram checksum.
*
* param void *udpData: the received UDP datagram
* param int len: the length of the UDP datagram
*
* return: 1 for checksum correct, 0 otherwise.
*
*/
int udp_checksum_justify (void *udpData, int len) {
unsigned short *data;
unsigned int sum = 0;
unsigned int ret = 0;
data = udpData;
/* The algorithm is similar to that in ipv4_checksum.c,
* but different due to UDP length
*/
for (int i = 0; i < len / 2; ++i) {
data[i] = (data[i] << 8) | (data[i] >> 8);
sum += data[i];
if (sum >> 16 != 0) {
sum += sum >> 16;
sum = sum & 0xffff;
}
data[i] = (data[i] << 8) | (data[i] >> 8);
}
/* when len is odd, we have to process the last byte individually */
if (len % 2 != 0) {
unsigned char *dtOdd = udpData;
// use char to gain the last one byte number
unsigned int temp = dtOdd[len - 1];
// assume there's another zero byte after the last byte
temp = temp << 8;
sum += temp;
if (sum >> 16 != 0) {
sum += sum >> 16;
sum = sum & 0xffff;
}
}
ret = ~sum & 0xffff;
if (DEBUG) {
printf("OK: udp_checksum_justify()\n line %d: justification complete.\n", __LINE__ - 1);
}
return (ret == 0) ? 1 : 0;
}
/*
* This function helps calculate the UDP datagram checksum.
*
* param void *udpData: the received UDP datagram
* param int len: the length of the UDP datagram
*
* return: unsigned int checksum.
*
*/
unsigned int udp_checksum_calculate (void *udpData, int len) {
unsigned short *data;
unsigned int sum = 0;
unsigned int ret = 0;
data = udpData;
/* The algorithm is similar to that in udp_checksum_justify() */
for (int i = 0; i < len / 2; ++i) {
data[i] = (data[i] << 8) | (data[i] >> 8);
sum += data[i];
if (sum >> 16 != 0) {
sum += sum >> 16;
sum = sum & 0xffff;
}
data[i] = (data[i] << 8) | (data[i] >> 8);
}
// len is odd
if (len % 2 != 0) {
unsigned char *dtOdd = udpData;
unsigned int temp = dtOdd[len - 1];
temp = temp << 8;
sum += temp;
if (sum >> 16 != 0) {
sum += sum >> 16;
sum = sum & 0xffff;
}
}
ret = ~sum & 0xffff;
if (DEBUG) {
printf("OK: udp_checksum_calculate()\n line %d: calculation complete.\n", __LINE__ - 1);
}
return ret;
}