1#include "CPktCmn.h"
2/*
3Copyright (c) 2015-2015 Cisco Systems, Inc.
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9    http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16*/
17
18
19
20#define TouchCacheLine(a)
21
22uint16_t pkt_InetChecksum(uint8_t* data ,
23                        uint16_t len, uint8_t* data2 , uint16_t len2){
24
25    TouchCacheLine(data2);
26    TouchCacheLine(data2+32);
27    TouchCacheLine(data2+64);
28
29    int sum = 0;
30    while(len>1){
31        TouchCacheLine(data+96); //three lines ahead !
32        sum += PKT_NTOHS(*((uint16_t*)data));
33        data += 2;
34        len -= 2;
35    }
36
37    while(len2>1){
38        TouchCacheLine(data2+96); //three lines ahead !
39        sum += PKT_NTOHS(*((uint16_t*)data2));
40        data2 += 2;
41        len2 -= 2;
42    }
43
44    if(len2){
45        sum += (PKT_NTOHS(*((uint16_t*)data2)) & 0xff00);
46    }
47
48    while(sum >> 16){
49        sum = (sum & 0xffff) + (sum >> 16);
50    }
51
52    return PKT_NTOHS((uint16_t)(~sum));
53}
54
55uint16_t pkt_InetChecksum(uint8_t* data , uint16_t len){
56
57    int sum = 0;
58    while(len>1){
59        TouchCacheLine(data+96); //three line ahead !
60        sum += PKT_NTOHS(*((uint16_t*)data));
61        data += 2;
62        len -= 2;
63    }
64
65    if(len){
66        sum += (PKT_NTOHS(*((uint16_t*)data)) & 0xff00);
67    }
68
69    while(sum >> 16){
70        sum = (sum & 0xffff) + (sum >> 16);
71    }
72
73    return PKT_NTOHS((uint16_t)(~sum));
74}
75
76uint16_t pkt_UpdateInetChecksum(uint16_t csFieldFromPacket, uint16_t oldVal, uint16_t newVal){
77    uint32_t newCS;
78    newCS = (uint16_t)(~PKT_NTOHS(csFieldFromPacket));
79    newCS += (uint16_t)(~PKT_NTOHS(oldVal));
80    newCS += (uint16_t)PKT_NTOHS(newVal);
81    while(newCS >> 16){
82        newCS = (newCS & 0xffff) + (newCS >> 16);
83    }
84    return PKT_NTOHS((uint16_t)(~newCS));
85}
86
87uint16_t pkt_SubtractInetChecksum(uint16_t checksum, uint16_t csToSubtract){
88    uint32_t newCS;
89    newCS = (uint16_t)(~PKT_NTOHS(checksum));
90
91    // since the cs is already in ~ format in the packet, there is no need
92    // to negate it for subtraction in 1's complement.
93    newCS += (uint16_t)PKT_NTOHS(csToSubtract);
94
95    while(newCS >> 16){
96        newCS = (newCS & 0xffff) + (newCS >> 16);
97    }
98    return PKT_NTOHS((uint16_t)(~newCS));
99}
100
101uint16_t pkt_AddInetChecksum(uint16_t checksum, uint16_t csToAdd){
102    uint32_t newCS;
103    newCS = (uint16_t)(~PKT_NTOHS(checksum));
104
105    // since the cs is already in ~ format in the packet, there is a need
106    // to negate it for addition in 1's complement.
107    newCS += (uint16_t)PKT_NTOHS(~csToAdd);
108
109    while(newCS >> 16){
110        newCS = (newCS & 0xffff) + (newCS >> 16);
111    }
112    return PKT_NTOHS((uint16_t)(~newCS));
113}
114
115
116extern "C" void pkt_ChecksumTest(){
117
118    uint16_t cs;
119    uint8_t data[5] = {0xcd,0x7a,0x55,0x55,0xa1};
120
121    cs = pkt_InetChecksum((uint8_t*)data,5);
122    printf("CS = 0x%04x: ",cs);
123    if(cs == 0x2F3C){
124        printf("CS func with odd len OK.\n");
125    }else{
126        printf("ERROR: CS func produced wrong value with odd number of bytes.\n");
127    }
128
129    cs = pkt_InetChecksum((uint8_t*)data,4);
130    printf("CS = 0x%04x: ",cs);
131    if(cs == 0x2FDD){
132        printf("CS func with even len OK.\n");
133    }else{
134        printf("ERROR: CS func produced wrong value with even number of bytes.\n");
135    }
136
137    cs = pkt_UpdateInetChecksum(cs,0x5555,0x8532);
138    printf("CS = 0x%04x: ",cs);
139    if(cs == 0x0000){
140        printf("Update CS func OK.\n");
141    }else{
142        printf("ERROR: Update CS func produced wrong value.\n");
143    }
144
145}
146