ReactOS 0.4.16-dev-334-g4d9f67c
sw-offload.c
Go to the documentation of this file.
1/*
2 * This file contains SW Implementation of checksum computation for IP,TCP,UDP
3 *
4 * Copyright (c) 2008-2017 Red Hat, Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met :
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and / or other materials provided with the distribution.
14 * 3. Neither the names of the copyright holders nor the names of their contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29#include "ndis56common.h"
30
31#ifdef WPP_EVENT_TRACING
32#include "sw-offload.tmh"
33#endif
34#include <sal.h>
35
36// till IP header size is 8 bit
37#define MAX_SUPPORTED_IPV6_HEADERS (256 - 4)
38
40
41// IPv6 Header RFC 2460 (40 bytes)
42typedef struct _tagIPv6Header {
43 UCHAR ip6_ver_tc; // traffic class(low nibble), version (high nibble)
44 UCHAR ip6_tc_fl; // traffic class(high nibble), flow label
45 USHORT ip6_fl; // flow label, the rest
46 USHORT ip6_payload_len; // length of following headers and payload
47 UCHAR ip6_next_header; // next header type
48 UCHAR ip6_hoplimit; // hop limit
52
53typedef union
54{
57} IPHeader;
58
59// IPv6 Header RFC 2460 (n*8 bytes)
60typedef struct _tagIPv6ExtHeader {
61 UCHAR ip6ext_next_header; // next header type
62 UCHAR ip6ext_hdr_len; // length of this header in 8 bytes unit, not including first 8 bytes
65
66// IP Pseudo Header RFC 768
67typedef struct _tagIPv4PseudoHeader {
68 ULONG ipph_src; // Source address
69 ULONG ipph_dest; // Destination address
71 UCHAR ipph_protocol; // TCP/UDP
72 USHORT ipph_length; // TCP/UDP length
74
75// IPv6 Pseudo Header RFC 2460
76typedef struct _tagIPv6PseudoHeader {
77 IPV6_ADDRESS ipph_src; // Source address
78 IPV6_ADDRESS ipph_dest; // Destination address
79 ULONG ipph_length; // TCP/UDP length
80 UCHAR z1; // 0
81 UCHAR z2; // 0
82 UCHAR z3; // 0
83 UCHAR ipph_protocol; // TCP/UDP
85
86
87#define PROTOCOL_TCP 6
88#define PROTOCOL_UDP 17
89
90
91#define IP_HEADER_LENGTH(pHeader) (((pHeader)->ip_verlen & 0x0F) << 2)
92#define TCP_HEADER_LENGTH(pHeader) ((pHeader->tcp_flags & 0xF0) >> 2)
93
94
95
97{
98 PUSHORT pus = (PUSHORT)buffer;
99 ULONG count = len >> 1;
100 while (count--) val += *pus++;
101 if (len & 1) val += (USHORT)*(PUCHAR)pus;
102 val = (((val >> 16) | (val << 16)) + val) >> 16;
103 return (USHORT)~val;
104}
105
106
107/******************************************
108 IP header checksum calculator
109*******************************************/
110static __inline VOID CalculateIpChecksum(IPv4Header *pIpHeader)
111{
112 pIpHeader->ip_xsum = 0;
113 pIpHeader->ip_xsum = CheckSumCalculator(0, pIpHeader, IP_HEADER_LENGTH(pIpHeader));
114}
115
116static __inline tTcpIpPacketParsingResult
118{
119 ULONG tcpipDataAt;
121 tcpipDataAt = ipHeaderSize + sizeof(TCPHeader);
123 res.TcpUdp = ppresIsTCP;
124
125 if (len >= tcpipDataAt)
126 {
127 TCPHeader *pTcpHeader = (TCPHeader *)RtlOffsetToPointer(pIpHeader, ipHeaderSize);
128 res.xxpStatus = ppresXxpKnown;
129 tcpipDataAt = ipHeaderSize + TCP_HEADER_LENGTH(pTcpHeader);
130 res.XxpIpHeaderSize = tcpipDataAt;
131 }
132 else
133 {
134 DPrintf(2, ("tcp: %d < min headers %d", len, tcpipDataAt));
135 }
136 return res;
137}
138
139static __inline tTcpIpPacketParsingResult
141{
143 ULONG udpDataStart = ipHeaderSize + sizeof(UDPHeader);
145 res.TcpUdp = ppresIsUDP;
146 res.XxpIpHeaderSize = udpDataStart;
147 if (len >= udpDataStart)
148 {
149 UDPHeader *pUdpHeader = (UDPHeader *)RtlOffsetToPointer(pIpHeader, ipHeaderSize);
150 USHORT datagramLength = swap_short(pUdpHeader->udp_length);
151 res.xxpStatus = ppresXxpKnown;
152 // may be full or not, but the datagram length is known
153 DPrintf(2, ("udp: len %d, datagramLength %d", len, datagramLength));
154 }
155 return res;
156}
157
158static __inline tTcpIpPacketParsingResult
160{
162 UCHAR ver_len = pIpHeader->v4.ip_verlen;
163 UCHAR ip_version = (ver_len & 0xF0) >> 4;
164 USHORT ipHeaderSize = 0;
165 USHORT fullLength = 0;
166 res.value = 0;
167
168 if (ip_version == 4)
169 {
170 ipHeaderSize = (ver_len & 0xF) << 2;
171 fullLength = swap_short(pIpHeader->v4.ip_length);
172 DPrintf(3, ("ip_version %d, ipHeaderSize %d, protocol %d, iplen %d",
173 ip_version, ipHeaderSize, pIpHeader->v4.ip_protocol, fullLength));
174 res.ipStatus = (ipHeaderSize >= sizeof(IPv4Header)) ? ppresIPV4 : ppresNotIP;
175 if (len < ipHeaderSize) res.ipCheckSum = ppresIPTooShort;
176 if (fullLength) {}
177 else
178 {
179 DPrintf(2, ("ip v.%d, iplen %d", ip_version, fullLength));
180 }
181 }
182 else if (ip_version == 6)
183 {
184 UCHAR nextHeader = pIpHeader->v6.ip6_next_header;
185 BOOLEAN bParsingDone = FALSE;
186 ipHeaderSize = sizeof(pIpHeader->v6);
187 res.ipStatus = ppresIPV6;
188 res.ipCheckSum = ppresCSOK;
189 fullLength = swap_short(pIpHeader->v6.ip6_payload_len);
190 fullLength += ipHeaderSize;
191 while (nextHeader != 59)
192 {
193 IPv6ExtHeader *pExt;
194 switch (nextHeader)
195 {
196 case PROTOCOL_TCP:
197 bParsingDone = TRUE;
198 res.xxpStatus = ppresXxpKnown;
199 res.TcpUdp = ppresIsTCP;
200 res.xxpFull = len >= fullLength ? 1 : 0;
201 res = ProcessTCPHeader(res, pIpHeader, len, ipHeaderSize);
202 break;
203 case PROTOCOL_UDP:
204 bParsingDone = TRUE;
205 res.xxpStatus = ppresXxpKnown;
206 res.TcpUdp = ppresIsUDP;
207 res.xxpFull = len >= fullLength ? 1 : 0;
208 res = ProcessUDPHeader(res, pIpHeader, len, ipHeaderSize);
209 break;
210 //existing extended headers
211 case 0:
213 case 60:
215 case 43:
217 case 44:
219 case 51:
221 case 50:
223 case 135:
224 if (len >= ((ULONG)ipHeaderSize + 8))
225 {
226 pExt = (IPv6ExtHeader *)((PUCHAR)pIpHeader + ipHeaderSize);
227 nextHeader = pExt->ip6ext_next_header;
228 ipHeaderSize += 8;
229 ipHeaderSize += pExt->ip6ext_hdr_len * 8;
230 }
231 else
232 {
233 DPrintf(0, ("[%s] ERROR: Break in the middle of ext. headers(len %d, hdr > %d)", __FUNCTION__, len, ipHeaderSize));
234 res.ipStatus = ppresNotIP;
235 bParsingDone = TRUE;
236 }
237 break;
238 //any other protocol
239 default:
240 res.xxpStatus = ppresXxpOther;
241 bParsingDone = TRUE;
242 break;
243 }
244 if (bParsingDone)
245 break;
246 }
247 if (ipHeaderSize <= MAX_SUPPORTED_IPV6_HEADERS)
248 {
249 DPrintf(3, ("ip_version %d, ipHeaderSize %d, protocol %d, iplen %d",
250 ip_version, ipHeaderSize, nextHeader, fullLength));
251 res.ipHeaderSize = ipHeaderSize;
252 }
253 else
254 {
255 DPrintf(0, ("[%s] ERROR: IP chain is too large (%d)", __FUNCTION__, ipHeaderSize));
256 res.ipStatus = ppresNotIP;
257 }
258 }
259
260 if (res.ipStatus == ppresIPV4)
261 {
262 res.ipHeaderSize = ipHeaderSize;
263 res.xxpFull = len >= fullLength ? 1 : 0;
264 // bit "more fragments" or fragment offset mean the packet is fragmented
265 res.IsFragment = (pIpHeader->v4.ip_offset & ~0xC0) != 0;
266 switch (pIpHeader->v4.ip_protocol)
267 {
268 case PROTOCOL_TCP:
269 {
270 res = ProcessTCPHeader(res, pIpHeader, len, ipHeaderSize);
271 }
272 break;
273 case PROTOCOL_UDP:
274 {
275 res = ProcessUDPHeader(res, pIpHeader, len, ipHeaderSize);
276 }
277 break;
278 default:
279 res.xxpStatus = ppresXxpOther;
280 break;
281 }
282 }
283 return res;
284}
285
287{
288 if (res.ipStatus == ppresIPV4)
289 {
290 USHORT headerLength = IP_HEADER_LENGTH(&pIpHeader->v4);
291 USHORT len = swap_short(pIpHeader->v4.ip_length);
292 return len - headerLength;
293 }
294 if (res.ipStatus == ppresIPV6)
295 {
296 USHORT fullLength = swap_short(pIpHeader->v6.ip6_payload_len);
297 return fullLength + sizeof(pIpHeader->v6) - (USHORT)res.ipHeaderSize;
298 }
299 return 0;
300}
301
302static __inline USHORT CalculateIpv4PseudoHeaderChecksum(IPv4Header *pIpHeader, USHORT headerAndPayloadLen)
303{
306 ipph.ipph_src = pIpHeader->ip_src;
307 ipph.ipph_dest = pIpHeader->ip_dest;
308 ipph.ipph_zero = 0;
309 ipph.ipph_protocol = pIpHeader->ip_protocol;
310 ipph.ipph_length = swap_short(headerAndPayloadLen);
311 checksum = CheckSumCalculator(0, &ipph, sizeof(ipph));
312 return ~checksum;
313}
314
315
316static __inline USHORT CalculateIpv6PseudoHeaderChecksum(IPv6Header *pIpHeader, USHORT headerAndPayloadLen)
317{
320 ipph.ipph_src[0] = pIpHeader->ip6_src_address[0];
321 ipph.ipph_src[1] = pIpHeader->ip6_src_address[1];
322 ipph.ipph_src[2] = pIpHeader->ip6_src_address[2];
323 ipph.ipph_src[3] = pIpHeader->ip6_src_address[3];
324 ipph.ipph_dest[0] = pIpHeader->ip6_dst_address[0];
325 ipph.ipph_dest[1] = pIpHeader->ip6_dst_address[1];
326 ipph.ipph_dest[2] = pIpHeader->ip6_dst_address[2];
327 ipph.ipph_dest[3] = pIpHeader->ip6_dst_address[3];
328 ipph.z1 = ipph.z2 = ipph.z3 = 0;
329 ipph.ipph_protocol = pIpHeader->ip6_next_header;
330 ipph.ipph_length = swap_short(headerAndPayloadLen);
331 checksum = CheckSumCalculator(0, &ipph, sizeof(ipph));
332 return ~checksum;
333}
334
337 USHORT headerAndPayloadLen)
338{
339 if (res.ipStatus == ppresIPV4)
340 return CalculateIpv4PseudoHeaderChecksum(&pIpHeader->v4, headerAndPayloadLen);
341 if (res.ipStatus == ppresIPV6)
342 return CalculateIpv6PseudoHeaderChecksum(&pIpHeader->v6, headerAndPayloadLen);
343 return 0;
344}
345
346static __inline BOOLEAN
347CompareNetCheckSumOnEndSystem(USHORT computedChecksum, USHORT arrivedChecksum)
348{
349 //According to RFC 1624 sec. 3
350 //Checksum verification mechanism should treat 0xFFFF
351 //checksum value from received packet as 0x0000
352 if(arrivedChecksum == 0xFFFF)
353 arrivedChecksum = 0;
354
355 return computedChecksum == arrivedChecksum;
356}
357
358/******************************************
359 Calculates IP header checksum calculator
360 it can be already calculated
361 the header must be complete!
362*******************************************/
363static __inline tTcpIpPacketParsingResult
365 IPv4Header *pIpHeader,
368{
370 if (res.ipCheckSum != ppresIPTooShort)
371 {
372 USHORT saved = pIpHeader->ip_xsum;
373 CalculateIpChecksum(pIpHeader);
374 res.ipCheckSum = CompareNetCheckSumOnEndSystem(pIpHeader->ip_xsum, saved) ? ppresCSOK : ppresCSBad;
375 if (!bFix)
376 pIpHeader->ip_xsum = saved;
377 else
378 res.fixedIpCS = res.ipCheckSum == ppresCSBad;
379 }
380 return res;
381}
382
383/*********************************************
384Calculates UDP checksum, assuming the checksum field
385is initialized with pseudoheader checksum
386**********************************************/
388{
389 pUdpHeader->udp_xsum = CheckSumCalculator(0, pUdpHeader, udpLength);
390}
391
392/*********************************************
393Calculates TCP checksum, assuming the checksum field
394is initialized with pseudoheader checksum
395**********************************************/
396static __inline VOID CalculateTcpChecksumGivenPseudoCS(TCPHeader *pTcpHeader, ULONG tcpLength)
397{
398 pTcpHeader->tcp_xsum = CheckSumCalculator(0, pTcpHeader, tcpLength);
399}
400
401/************************************************
402Checks (and fix if required) the TCP checksum
403sets flags in result structure according to verification
404TcpPseudoOK if valid pseudo CS was found
405TcpOK if valid TCP checksum was found
406************************************************/
407static __inline tTcpIpPacketParsingResult
409{
410 USHORT phcs;
412 TCPHeader *pTcpHeader = (TCPHeader *)RtlOffsetToPointer(pIpHeader, res.ipHeaderSize);
413 USHORT saved = pTcpHeader->tcp_xsum;
414 USHORT xxpHeaderAndPayloadLen = GetXxpHeaderAndPayloadLen(pIpHeader, res);
415 if (len >= res.ipHeaderSize)
416 {
417 phcs = CalculateIpPseudoHeaderChecksum(pIpHeader, res, xxpHeaderAndPayloadLen);
418 res.xxpCheckSum = CompareNetCheckSumOnEndSystem(phcs, saved) ? ppresPCSOK : ppresCSBad;
419 if (res.xxpCheckSum != ppresPCSOK || whatToFix)
420 {
421 if (whatToFix & pcrFixPHChecksum)
422 {
423 if (len >= (ULONG)(res.ipHeaderSize + sizeof(*pTcpHeader)))
424 {
425 pTcpHeader->tcp_xsum = phcs;
426 res.fixedXxpCS = res.xxpCheckSum != ppresPCSOK;
427 }
428 else
429 res.xxpStatus = ppresXxpIncomplete;
430 }
431 else if (res.xxpFull)
432 {
433 //USHORT ipFullLength = swap_short(pIpHeader->v4.ip_length);
434 pTcpHeader->tcp_xsum = phcs;
435 CalculateTcpChecksumGivenPseudoCS(pTcpHeader, xxpHeaderAndPayloadLen);
436 if (CompareNetCheckSumOnEndSystem(pTcpHeader->tcp_xsum, saved))
437 res.xxpCheckSum = ppresCSOK;
438
439 if (!(whatToFix & pcrFixXxpChecksum))
440 pTcpHeader->tcp_xsum = saved;
441 else
442 res.fixedXxpCS =
443 res.xxpCheckSum == ppresCSBad || res.xxpCheckSum == ppresPCSOK;
444 }
445 else if (whatToFix)
446 {
447 res.xxpStatus = ppresXxpIncomplete;
448 }
449 }
450 else if (res.xxpFull)
451 {
452 // we have correct PHCS and we do not need to fix anything
453 // there is a very small chance that it is also good TCP CS
454 // in such rare case we give a priority to TCP CS
455 CalculateTcpChecksumGivenPseudoCS(pTcpHeader, xxpHeaderAndPayloadLen);
456 if (CompareNetCheckSumOnEndSystem(pTcpHeader->tcp_xsum, saved))
457 res.xxpCheckSum = ppresCSOK;
458 pTcpHeader->tcp_xsum = saved;
459 }
460 }
461 else
462 res.ipCheckSum = ppresIPTooShort;
463 return res;
464}
465
466/************************************************
467Checks (and fix if required) the UDP checksum
468sets flags in result structure according to verification
469UdpPseudoOK if valid pseudo CS was found
470UdpOK if valid UDP checksum was found
471************************************************/
472static __inline tTcpIpPacketParsingResult
474{
475 USHORT phcs;
477 UDPHeader *pUdpHeader = (UDPHeader *)RtlOffsetToPointer(pIpHeader, res.ipHeaderSize);
478 USHORT saved = pUdpHeader->udp_xsum;
479 USHORT xxpHeaderAndPayloadLen = GetXxpHeaderAndPayloadLen(pIpHeader, res);
480 if (len >= res.ipHeaderSize)
481 {
482 phcs = CalculateIpPseudoHeaderChecksum(pIpHeader, res, xxpHeaderAndPayloadLen);
483 res.xxpCheckSum = CompareNetCheckSumOnEndSystem(phcs, saved) ? ppresPCSOK : ppresCSBad;
484 if (whatToFix & pcrFixPHChecksum)
485 {
486 if (len >= (ULONG)(res.ipHeaderSize + sizeof(UDPHeader)))
487 {
488 pUdpHeader->udp_xsum = phcs;
489 res.fixedXxpCS = res.xxpCheckSum != ppresPCSOK;
490 }
491 else
492 res.xxpStatus = ppresXxpIncomplete;
493 }
494 else if (res.xxpCheckSum != ppresPCSOK || (whatToFix & pcrFixXxpChecksum))
495 {
496 if (res.xxpFull)
497 {
498 pUdpHeader->udp_xsum = phcs;
499 CalculateUdpChecksumGivenPseudoCS(pUdpHeader, xxpHeaderAndPayloadLen);
500 if (CompareNetCheckSumOnEndSystem(pUdpHeader->udp_xsum, saved))
501 res.xxpCheckSum = ppresCSOK;
502
503 if (!(whatToFix & pcrFixXxpChecksum))
504 pUdpHeader->udp_xsum = saved;
505 else
506 res.fixedXxpCS =
507 res.xxpCheckSum == ppresCSBad || res.xxpCheckSum == ppresPCSOK;
508 }
509 else
510 res.xxpCheckSum = ppresXxpIncomplete;
511 }
512 else if (res.xxpFull)
513 {
514 // we have correct PHCS and we do not need to fix anything
515 // there is a very small chance that it is also good UDP CS
516 // in such rare case we give a priority to UDP CS
517 CalculateUdpChecksumGivenPseudoCS(pUdpHeader, xxpHeaderAndPayloadLen);
518 if (CompareNetCheckSumOnEndSystem(pUdpHeader->udp_xsum, saved))
519 res.xxpCheckSum = ppresCSOK;
520 pUdpHeader->udp_xsum = saved;
521 }
522 }
523 else
524 res.ipCheckSum = ppresIPTooShort;
525
526 return res;
527}
528
530{
531 static const char *const IPCaseName[4] = { "not tested", "Non-IP", "IPv4", "IPv6" };
532 if (res.xxpStatus == ppresXxpKnown) return res.TcpUdp == ppresIsTCP ?
533 (res.ipStatus == ppresIPV4 ? "TCPv4" : "TCPv6") :
534 (res.ipStatus == ppresIPV4 ? "UDPv4" : "UDPv6");
535 if (res.xxpStatus == ppresXxpIncomplete) return res.TcpUdp == ppresIsTCP ? "Incomplete TCP" : "Incomplete UDP";
536 if (res.xxpStatus == ppresXxpOther) return "IP";
537 return IPCaseName[res.ipStatus];
538}
539
541{
542 static const char *const CSCaseName[4] = { "not tested", "(too short)", "OK", "Bad" };
543 return CSCaseName[res.ipCheckSum];
544}
545
547{
548 static const char *const CSCaseName[4] = { "-", "PCS", "CS", "Bad" };
549 return CSCaseName[res.xxpCheckSum];
550}
551
554 int level,
555 LPCSTR procname)
556{
557 DPrintf(level, ("[%s] %s packet IPCS %s%s, checksum %s%s", procname,
560 res.fixedIpCS ? "(fixed)" : "",
562 res.fixedXxpCS ? "(fixed)" : ""));
563}
564
566{
568 if (res.ipStatus == ppresIPV4)
569 {
570 if (flags & pcrIpChecksum)
572 if(res.xxpStatus == ppresXxpKnown)
573 {
574 if (res.TcpUdp == ppresIsTCP) /* TCP */
575 {
577 {
579 }
580 }
581 else /* UDP */
582 {
584 {
586 }
587 }
588 }
589 }
590 else if (res.ipStatus == ppresIPV6)
591 {
592 if(res.xxpStatus == ppresXxpKnown)
593 {
594 if (res.TcpUdp == ppresIsTCP) /* TCP */
595 {
597 {
599 }
600 }
601 else /* UDP */
602 {
604 {
606 }
607 }
608 }
609 }
610 PrintOutParsingResult(res, 1, caller);
611 return res;
612}
613
615{
617 PrintOutParsingResult(res, 1, caller);
618 return res;
619}
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
#define __FUNCTION__
Definition: types.h:116
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
struct _tagTCPHeader TCPHeader
struct _tagUDPHeader UDPHeader
struct _tagIPv4Header IPv4Header
static __inline USHORT swap_short(USHORT us)
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
static BOOL bFix
Definition: dispmode.c:75
@ pcrUdpV4Checksum
Definition: ndis56common.h:867
@ pcrFixPHChecksum
Definition: ndis56common.h:876
@ pcrTcpV4Checksum
Definition: ndis56common.h:866
@ pcrFixUdpV6Checksum
Definition: ndis56common.h:880
@ pcrIpChecksum
Definition: ndis56common.h:865
@ pcrTcpV6Checksum
Definition: ndis56common.h:868
@ pcrFixTcpV4Checksum
Definition: ndis56common.h:877
@ pcrFixIPChecksum
Definition: ndis56common.h:875
@ pcrFixXxpChecksum
Definition: ndis56common.h:881
@ pcrFixTcpV6Checksum
Definition: ndis56common.h:879
@ pcrUdpV6Checksum
Definition: ndis56common.h:869
@ pcrFixUdpV4Checksum
Definition: ndis56common.h:878
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
@ ppresIPTooShort
Definition: ndis56common.h:828
@ ppresCSBad
Definition: ndis56common.h:831
@ ppresIsTCP
Definition: ndis56common.h:835
@ ppresPCSOK
Definition: ndis56common.h:829
@ ppresIsUDP
Definition: ndis56common.h:836
@ ppresIPV4
Definition: ndis56common.h:826
@ ppresXxpKnown
Definition: ndis56common.h:833
@ ppresNotIP
Definition: ndis56common.h:825
@ ppresXxpOther
Definition: ndis56common.h:832
@ ppresCSOK
Definition: ndis56common.h:830
@ ppresXxpIncomplete
Definition: ndis56common.h:834
@ ppresIPV6
Definition: ndis56common.h:827
unsigned short USHORT
Definition: pedump.c:61
#define __fallthrough
Definition: sal_old.h:314
UCHAR ip6ext_next_header
Definition: sw-offload.c:61
UCHAR ip6ext_hdr_len
Definition: sw-offload.c:62
IPV6_ADDRESS ip6_dst_address
Definition: sw-offload.c:50
UCHAR ip6_next_header
Definition: sw-offload.c:47
USHORT ip6_fl
Definition: sw-offload.c:45
UCHAR ip6_ver_tc
Definition: sw-offload.c:43
UCHAR ip6_tc_fl
Definition: sw-offload.c:44
IPV6_ADDRESS ip6_src_address
Definition: sw-offload.c:49
UCHAR ip6_hoplimit
Definition: sw-offload.c:48
USHORT ip6_payload_len
Definition: sw-offload.c:46
IPV6_ADDRESS ipph_src
Definition: sw-offload.c:77
IPV6_ADDRESS ipph_dest
Definition: sw-offload.c:78
static __inline tTcpIpPacketParsingResult ProcessUDPHeader(tTcpIpPacketParsingResult _res, PVOID pIpHeader, ULONG len, USHORT ipHeaderSize)
Definition: sw-offload.c:140
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify(PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
Definition: sw-offload.c:565
struct _tagIPv4PseudoHeader tIPv4PseudoHeader
static __inline tTcpIpPacketParsingResult ProcessTCPHeader(tTcpIpPacketParsingResult _res, PVOID pIpHeader, ULONG len, USHORT ipHeaderSize)
Definition: sw-offload.c:117
tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket(PVOID buffer, ULONG size, LPCSTR caller)
Definition: sw-offload.c:614
static __inline USHORT CalculateIpv4PseudoHeaderChecksum(IPv4Header *pIpHeader, USHORT headerAndPayloadLen)
Definition: sw-offload.c:302
ULONG IPV6_ADDRESS[4]
Definition: sw-offload.c:39
static VOID CalculateUdpChecksumGivenPseudoCS(UDPHeader *pUdpHeader, ULONG udpLength)
Definition: sw-offload.c:387
static LPCSTR __inline GetIPCSCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:540
static __inline USHORT GetXxpHeaderAndPayloadLen(IPHeader *pIpHeader, tTcpIpPacketParsingResult res)
Definition: sw-offload.c:286
struct _tagIPv6PseudoHeader tIPv6PseudoHeader
static LPCSTR __inline GetPacketCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:529
struct _tagIPv6ExtHeader IPv6ExtHeader
static __inline VOID CalculateTcpChecksumGivenPseudoCS(TCPHeader *pTcpHeader, ULONG tcpLength)
Definition: sw-offload.c:396
#define PROTOCOL_UDP
Definition: sw-offload.c:88
struct _tagIPv6Header IPv6Header
#define MAX_SUPPORTED_IPV6_HEADERS
Definition: sw-offload.c:37
static __inline USHORT CheckSumCalculator(ULONG val, PVOID buffer, ULONG len)
Definition: sw-offload.c:96
static __inline tTcpIpPacketParsingResult VerifyIpChecksum(IPv4Header *pIpHeader, tTcpIpPacketParsingResult known, BOOLEAN bFix)
Definition: sw-offload.c:364
#define TCP_HEADER_LENGTH(pHeader)
Definition: sw-offload.c:92
#define PROTOCOL_TCP
Definition: sw-offload.c:87
static __inline tTcpIpPacketParsingResult VerifyTcpChecksum(IPHeader *pIpHeader, ULONG len, tTcpIpPacketParsingResult known, ULONG whatToFix)
Definition: sw-offload.c:408
static __inline tTcpIpPacketParsingResult VerifyUdpChecksum(IPHeader *pIpHeader, ULONG len, tTcpIpPacketParsingResult known, ULONG whatToFix)
Definition: sw-offload.c:473
static __inline tTcpIpPacketParsingResult QualifyIpPacket(IPHeader *pIpHeader, ULONG len)
Definition: sw-offload.c:159
static __inline USHORT CalculateIpv6PseudoHeaderChecksum(IPv6Header *pIpHeader, USHORT headerAndPayloadLen)
Definition: sw-offload.c:316
static __inline BOOLEAN CompareNetCheckSumOnEndSystem(USHORT computedChecksum, USHORT arrivedChecksum)
Definition: sw-offload.c:347
#define IP_HEADER_LENGTH(pHeader)
Definition: sw-offload.c:91
static __inline USHORT CalculateIpPseudoHeaderChecksum(IPHeader *pIpHeader, tTcpIpPacketParsingResult res, USHORT headerAndPayloadLen)
Definition: sw-offload.c:335
static LPCSTR __inline GetXxpCSCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:546
static __inline VOID PrintOutParsingResult(tTcpIpPacketParsingResult res, int level, LPCSTR procname)
Definition: sw-offload.c:552
static __inline VOID CalculateIpChecksum(IPv4Header *pIpHeader)
Definition: sw-offload.c:110
uint16_t * PUSHORT
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
IPv6Header v6
Definition: sw-offload.c:55
IPv4Header v4
Definition: sw-offload.c:56
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned char UCHAR
Definition: xmlstorage.h:181