ReactOS 0.4.16-dev-297-gc569aee
sw-offload.c File Reference
#include "ndis56common.h"
#include <sal.h>
Include dependency graph for sw-offload.c:

Go to the source code of this file.

Classes

struct  _tagIPv6Header
 
union  IPHeader
 
struct  _tagIPv6ExtHeader
 
struct  _tagIPv4PseudoHeader
 
struct  _tagIPv6PseudoHeader
 

Macros

#define MAX_SUPPORTED_IPV6_HEADERS   (256 - 4)
 
#define PROTOCOL_TCP   6
 
#define PROTOCOL_UDP   17
 
#define IP_HEADER_LENGTH(pHeader)   (((pHeader)->ip_verlen & 0x0F) << 2)
 
#define TCP_HEADER_LENGTH(pHeader)   ((pHeader->tcp_flags & 0xF0) >> 2)
 

Typedefs

typedef ULONG IPV6_ADDRESS[4]
 
typedef struct _tagIPv6Header IPv6Header
 
typedef struct _tagIPv6ExtHeader IPv6ExtHeader
 
typedef struct _tagIPv4PseudoHeader tIPv4PseudoHeader
 
typedef struct _tagIPv6PseudoHeader tIPv6PseudoHeader
 

Functions

static __inline USHORT CheckSumCalculator (ULONG val, PVOID buffer, ULONG len)
 
static __inline VOID CalculateIpChecksum (IPv4Header *pIpHeader)
 
static __inline tTcpIpPacketParsingResult ProcessTCPHeader (tTcpIpPacketParsingResult _res, PVOID pIpHeader, ULONG len, USHORT ipHeaderSize)
 
static __inline tTcpIpPacketParsingResult ProcessUDPHeader (tTcpIpPacketParsingResult _res, PVOID pIpHeader, ULONG len, USHORT ipHeaderSize)
 
static __inline tTcpIpPacketParsingResult QualifyIpPacket (IPHeader *pIpHeader, ULONG len)
 
static __inline USHORT GetXxpHeaderAndPayloadLen (IPHeader *pIpHeader, tTcpIpPacketParsingResult res)
 
static __inline USHORT CalculateIpv4PseudoHeaderChecksum (IPv4Header *pIpHeader, USHORT headerAndPayloadLen)
 
static __inline USHORT CalculateIpv6PseudoHeaderChecksum (IPv6Header *pIpHeader, USHORT headerAndPayloadLen)
 
static __inline USHORT CalculateIpPseudoHeaderChecksum (IPHeader *pIpHeader, tTcpIpPacketParsingResult res, USHORT headerAndPayloadLen)
 
static __inline BOOLEAN CompareNetCheckSumOnEndSystem (USHORT computedChecksum, USHORT arrivedChecksum)
 
static __inline tTcpIpPacketParsingResult VerifyIpChecksum (IPv4Header *pIpHeader, tTcpIpPacketParsingResult known, BOOLEAN bFix)
 
static VOID CalculateUdpChecksumGivenPseudoCS (UDPHeader *pUdpHeader, ULONG udpLength)
 
static __inline VOID CalculateTcpChecksumGivenPseudoCS (TCPHeader *pTcpHeader, ULONG tcpLength)
 
static __inline tTcpIpPacketParsingResult VerifyTcpChecksum (IPHeader *pIpHeader, ULONG len, tTcpIpPacketParsingResult known, ULONG whatToFix)
 
static __inline tTcpIpPacketParsingResult VerifyUdpChecksum (IPHeader *pIpHeader, ULONG len, tTcpIpPacketParsingResult known, ULONG whatToFix)
 
static LPCSTR __inline GetPacketCase (tTcpIpPacketParsingResult res)
 
static LPCSTR __inline GetIPCSCase (tTcpIpPacketParsingResult res)
 
static LPCSTR __inline GetXxpCSCase (tTcpIpPacketParsingResult res)
 
static __inline VOID PrintOutParsingResult (tTcpIpPacketParsingResult res, int level, LPCSTR procname)
 
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify (PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
 
tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket (PVOID buffer, ULONG size, LPCSTR caller)
 

Macro Definition Documentation

◆ IP_HEADER_LENGTH

#define IP_HEADER_LENGTH (   pHeader)    (((pHeader)->ip_verlen & 0x0F) << 2)

Definition at line 91 of file sw-offload.c.

◆ MAX_SUPPORTED_IPV6_HEADERS

#define MAX_SUPPORTED_IPV6_HEADERS   (256 - 4)

Definition at line 37 of file sw-offload.c.

◆ PROTOCOL_TCP

#define PROTOCOL_TCP   6

Definition at line 87 of file sw-offload.c.

◆ PROTOCOL_UDP

#define PROTOCOL_UDP   17

Definition at line 88 of file sw-offload.c.

◆ TCP_HEADER_LENGTH

#define TCP_HEADER_LENGTH (   pHeader)    ((pHeader->tcp_flags & 0xF0) >> 2)

Definition at line 92 of file sw-offload.c.

Typedef Documentation

◆ IPV6_ADDRESS

typedef ULONG IPV6_ADDRESS[4]

Definition at line 39 of file sw-offload.c.

◆ IPv6ExtHeader

◆ IPv6Header

◆ tIPv4PseudoHeader

◆ tIPv6PseudoHeader

Function Documentation

◆ CalculateIpChecksum()

static __inline VOID CalculateIpChecksum ( IPv4Header pIpHeader)
static

Definition at line 110 of file sw-offload.c.

111{
112 pIpHeader->ip_xsum = 0;
113 pIpHeader->ip_xsum = CheckSumCalculator(0, pIpHeader, IP_HEADER_LENGTH(pIpHeader));
114}
static __inline USHORT CheckSumCalculator(ULONG val, PVOID buffer, ULONG len)
Definition: sw-offload.c:96
#define IP_HEADER_LENGTH(pHeader)
Definition: sw-offload.c:91

Referenced by VerifyIpChecksum().

◆ CalculateIpPseudoHeaderChecksum()

static __inline USHORT CalculateIpPseudoHeaderChecksum ( IPHeader pIpHeader,
tTcpIpPacketParsingResult  res,
USHORT  headerAndPayloadLen 
)
static

Definition at line 335 of file sw-offload.c.

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}
GLuint res
Definition: glext.h:9613
@ ppresIPV4
Definition: ndis56common.h:826
@ ppresIPV6
Definition: ndis56common.h:827
static __inline USHORT CalculateIpv4PseudoHeaderChecksum(IPv4Header *pIpHeader, USHORT headerAndPayloadLen)
Definition: sw-offload.c:302
static __inline USHORT CalculateIpv6PseudoHeaderChecksum(IPv6Header *pIpHeader, USHORT headerAndPayloadLen)
Definition: sw-offload.c:316
IPv6Header v6
Definition: sw-offload.c:55
IPv4Header v4
Definition: sw-offload.c:56

Referenced by VerifyTcpChecksum(), and VerifyUdpChecksum().

◆ CalculateIpv4PseudoHeaderChecksum()

static __inline USHORT CalculateIpv4PseudoHeaderChecksum ( IPv4Header pIpHeader,
USHORT  headerAndPayloadLen 
)
static

Definition at line 302 of file sw-offload.c.

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}
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
static __inline USHORT swap_short(USHORT us)
unsigned short USHORT
Definition: pedump.c:61

Referenced by CalculateIpPseudoHeaderChecksum().

◆ CalculateIpv6PseudoHeaderChecksum()

static __inline USHORT CalculateIpv6PseudoHeaderChecksum ( IPv6Header pIpHeader,
USHORT  headerAndPayloadLen 
)
static

Definition at line 316 of file sw-offload.c.

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}
IPV6_ADDRESS ip6_dst_address
Definition: sw-offload.c:50
UCHAR ip6_next_header
Definition: sw-offload.c:47
IPV6_ADDRESS ip6_src_address
Definition: sw-offload.c:49
IPV6_ADDRESS ipph_src
Definition: sw-offload.c:77
IPV6_ADDRESS ipph_dest
Definition: sw-offload.c:78

Referenced by CalculateIpPseudoHeaderChecksum().

◆ CalculateTcpChecksumGivenPseudoCS()

static __inline VOID CalculateTcpChecksumGivenPseudoCS ( TCPHeader pTcpHeader,
ULONG  tcpLength 
)
static

Definition at line 396 of file sw-offload.c.

397{
398 pTcpHeader->tcp_xsum = CheckSumCalculator(0, pTcpHeader, tcpLength);
399}

Referenced by VerifyTcpChecksum().

◆ CalculateUdpChecksumGivenPseudoCS()

static VOID CalculateUdpChecksumGivenPseudoCS ( UDPHeader pUdpHeader,
ULONG  udpLength 
)
static

Definition at line 387 of file sw-offload.c.

388{
389 pUdpHeader->udp_xsum = CheckSumCalculator(0, pUdpHeader, udpLength);
390}

Referenced by VerifyUdpChecksum().

◆ CheckSumCalculator()

static __inline USHORT CheckSumCalculator ( ULONG  val,
PVOID  buffer,
ULONG  len 
)
static

Definition at line 96 of file sw-offload.c.

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}
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
uint16_t * PUSHORT
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59

Referenced by CalculateIpChecksum(), CalculateIpv4PseudoHeaderChecksum(), CalculateIpv6PseudoHeaderChecksum(), CalculateTcpChecksumGivenPseudoCS(), and CalculateUdpChecksumGivenPseudoCS().

◆ CompareNetCheckSumOnEndSystem()

static __inline BOOLEAN CompareNetCheckSumOnEndSystem ( USHORT  computedChecksum,
USHORT  arrivedChecksum 
)
static

Definition at line 347 of file sw-offload.c.

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}

Referenced by VerifyIpChecksum(), VerifyTcpChecksum(), and VerifyUdpChecksum().

◆ GetIPCSCase()

static LPCSTR __inline GetIPCSCase ( tTcpIpPacketParsingResult  res)
static

Definition at line 540 of file sw-offload.c.

541{
542 static const char *const CSCaseName[4] = { "not tested", "(too short)", "OK", "Bad" };
543 return CSCaseName[res.ipCheckSum];
544}

Referenced by PrintOutParsingResult().

◆ GetPacketCase()

static LPCSTR __inline GetPacketCase ( tTcpIpPacketParsingResult  res)
static

Definition at line 529 of file sw-offload.c.

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}
@ ppresIsTCP
Definition: ndis56common.h:835
@ ppresXxpKnown
Definition: ndis56common.h:833
@ ppresXxpOther
Definition: ndis56common.h:832
@ ppresXxpIncomplete
Definition: ndis56common.h:834

Referenced by PrintOutParsingResult().

◆ GetXxpCSCase()

static LPCSTR __inline GetXxpCSCase ( tTcpIpPacketParsingResult  res)
static

Definition at line 546 of file sw-offload.c.

547{
548 static const char *const CSCaseName[4] = { "-", "PCS", "CS", "Bad" };
549 return CSCaseName[res.xxpCheckSum];
550}

Referenced by PrintOutParsingResult().

◆ GetXxpHeaderAndPayloadLen()

static __inline USHORT GetXxpHeaderAndPayloadLen ( IPHeader pIpHeader,
tTcpIpPacketParsingResult  res 
)
static

Definition at line 286 of file sw-offload.c.

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}
USHORT ip6_payload_len
Definition: sw-offload.c:46

Referenced by VerifyTcpChecksum(), and VerifyUdpChecksum().

◆ ParaNdis_CheckSumVerify()

tTcpIpPacketParsingResult ParaNdis_CheckSumVerify ( PVOID  buffer,
ULONG  size,
ULONG  flags,
LPCSTR  caller 
)

Definition at line 565 of file sw-offload.c.

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}
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
@ 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
@ pcrFixTcpV6Checksum
Definition: ndis56common.h:879
@ pcrUdpV6Checksum
Definition: ndis56common.h:869
@ pcrFixUdpV4Checksum
Definition: ndis56common.h:878
static __inline tTcpIpPacketParsingResult VerifyIpChecksum(IPv4Header *pIpHeader, tTcpIpPacketParsingResult known, BOOLEAN bFix)
Definition: sw-offload.c:364
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 VOID PrintOutParsingResult(tTcpIpPacketParsingResult res, int level, LPCSTR procname)
Definition: sw-offload.c:552

Referenced by ParaNdis_CheckRxChecksum(), ParaNdis_DoCopyPacketData(), ParaNdis_DoSubmitPacket(), ParaNdis_PacketMapper(), and PrepareSendEntry().

◆ ParaNdis_ReviewIPPacket()

tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket ( PVOID  buffer,
ULONG  size,
LPCSTR  caller 
)

Definition at line 614 of file sw-offload.c.

615{
617 PrintOutParsingResult(res, 1, caller);
618 return res;
619}

Referenced by QueryTcpHeaderOffset().

◆ PrintOutParsingResult()

static __inline VOID PrintOutParsingResult ( tTcpIpPacketParsingResult  res,
int  level,
LPCSTR  procname 
)
static

Definition at line 552 of file sw-offload.c.

556{
557 DPrintf(level, ("[%s] %s packet IPCS %s%s, checksum %s%s", procname,
560 res.fixedIpCS ? "(fixed)" : "",
562 res.fixedXxpCS ? "(fixed)" : ""));
563}
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
GLint level
Definition: gl.h:1546
static LPCSTR __inline GetIPCSCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:540
static LPCSTR __inline GetPacketCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:529
static LPCSTR __inline GetXxpCSCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:546

Referenced by ParaNdis_CheckSumVerify(), and ParaNdis_ReviewIPPacket().

◆ ProcessTCPHeader()

static __inline tTcpIpPacketParsingResult ProcessTCPHeader ( tTcpIpPacketParsingResult  _res,
PVOID  pIpHeader,
ULONG  len,
USHORT  ipHeaderSize 
)
static

Definition at line 117 of file sw-offload.c.

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}
struct _tagTCPHeader TCPHeader
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
#define TCP_HEADER_LENGTH(pHeader)
Definition: sw-offload.c:92

Referenced by QualifyIpPacket().

◆ ProcessUDPHeader()

static __inline tTcpIpPacketParsingResult ProcessUDPHeader ( tTcpIpPacketParsingResult  _res,
PVOID  pIpHeader,
ULONG  len,
USHORT  ipHeaderSize 
)
static

Definition at line 140 of file sw-offload.c.

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}
struct _tagUDPHeader UDPHeader
@ ppresIsUDP
Definition: ndis56common.h:836

Referenced by QualifyIpPacket().

◆ QualifyIpPacket()

static __inline tTcpIpPacketParsingResult QualifyIpPacket ( IPHeader pIpHeader,
ULONG  len 
)
static

Definition at line 159 of file sw-offload.c.

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}
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define __FUNCTION__
Definition: types.h:116
struct _tagIPv4Header IPv4Header
@ ppresIPTooShort
Definition: ndis56common.h:828
@ ppresNotIP
Definition: ndis56common.h:825
@ ppresCSOK
Definition: ndis56common.h:830
#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
static __inline tTcpIpPacketParsingResult ProcessUDPHeader(tTcpIpPacketParsingResult _res, PVOID pIpHeader, ULONG len, USHORT ipHeaderSize)
Definition: sw-offload.c:140
static __inline tTcpIpPacketParsingResult ProcessTCPHeader(tTcpIpPacketParsingResult _res, PVOID pIpHeader, ULONG len, USHORT ipHeaderSize)
Definition: sw-offload.c:117
#define PROTOCOL_UDP
Definition: sw-offload.c:88
#define MAX_SUPPORTED_IPV6_HEADERS
Definition: sw-offload.c:37
#define PROTOCOL_TCP
Definition: sw-offload.c:87
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by ParaNdis_CheckSumVerify(), and ParaNdis_ReviewIPPacket().

◆ VerifyIpChecksum()

static __inline tTcpIpPacketParsingResult VerifyIpChecksum ( IPv4Header pIpHeader,
tTcpIpPacketParsingResult  known,
BOOLEAN  bFix 
)
static

Definition at line 364 of file sw-offload.c.

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}
static BOOL bFix
Definition: dispmode.c:75
@ ppresCSBad
Definition: ndis56common.h:831
static __inline BOOLEAN CompareNetCheckSumOnEndSystem(USHORT computedChecksum, USHORT arrivedChecksum)
Definition: sw-offload.c:347
static __inline VOID CalculateIpChecksum(IPv4Header *pIpHeader)
Definition: sw-offload.c:110

Referenced by ParaNdis_CheckSumVerify().

◆ VerifyTcpChecksum()

static __inline tTcpIpPacketParsingResult VerifyTcpChecksum ( IPHeader pIpHeader,
ULONG  len,
tTcpIpPacketParsingResult  known,
ULONG  whatToFix 
)
static

Definition at line 408 of file sw-offload.c.

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}
@ pcrFixXxpChecksum
Definition: ndis56common.h:881
@ ppresPCSOK
Definition: ndis56common.h:829
static __inline USHORT GetXxpHeaderAndPayloadLen(IPHeader *pIpHeader, tTcpIpPacketParsingResult res)
Definition: sw-offload.c:286
static __inline VOID CalculateTcpChecksumGivenPseudoCS(TCPHeader *pTcpHeader, ULONG tcpLength)
Definition: sw-offload.c:396
static __inline USHORT CalculateIpPseudoHeaderChecksum(IPHeader *pIpHeader, tTcpIpPacketParsingResult res, USHORT headerAndPayloadLen)
Definition: sw-offload.c:335

Referenced by ParaNdis_CheckSumVerify().

◆ VerifyUdpChecksum()

static __inline tTcpIpPacketParsingResult VerifyUdpChecksum ( IPHeader pIpHeader,
ULONG  len,
tTcpIpPacketParsingResult  known,
ULONG  whatToFix 
)
static

Definition at line 473 of file sw-offload.c.

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}
static VOID CalculateUdpChecksumGivenPseudoCS(UDPHeader *pUdpHeader, ULONG udpLength)
Definition: sw-offload.c:387

Referenced by ParaNdis_CheckSumVerify().