ReactOS  0.4.15-dev-1397-g19779b3
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 }
IPv6Header v6
Definition: sw-offload.c:55
IPv4Header v4
Definition: sw-offload.c:56
static __inline USHORT CalculateIpv6PseudoHeaderChecksum(IPv6Header *pIpHeader, USHORT headerAndPayloadLen)
Definition: sw-offload.c:316
GLuint res
Definition: glext.h:9613
static __inline USHORT CalculateIpv4PseudoHeaderChecksum(IPv4Header *pIpHeader, USHORT headerAndPayloadLen)
Definition: sw-offload.c:302

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 {
304  tIPv4PseudoHeader ipph;
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 __inline USHORT CheckSumCalculator(ULONG val, PVOID buffer, ULONG len)
Definition: sw-offload.c:96
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
unsigned short USHORT
Definition: pedump.c:61
static __inline USHORT swap_short(USHORT us)

Referenced by CalculateIpPseudoHeaderChecksum().

◆ CalculateIpv6PseudoHeaderChecksum()

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

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

317 {
318  tIPv6PseudoHeader ipph;
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_src_address
Definition: sw-offload.c:49
IPV6_ADDRESS ipph_dest
Definition: sw-offload.c:78
static __inline USHORT CheckSumCalculator(ULONG val, PVOID buffer, ULONG len)
Definition: sw-offload.c:96
IPV6_ADDRESS ip6_dst_address
Definition: sw-offload.c:50
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
UCHAR ip6_next_header
Definition: sw-offload.c:47
IPV6_ADDRESS ipph_src
Definition: sw-offload.c:77
unsigned short USHORT
Definition: pedump.c:61
static __inline USHORT swap_short(USHORT us)

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 }
static __inline USHORT CheckSumCalculator(ULONG val, PVOID buffer, ULONG len)
Definition: sw-offload.c:96

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 }
static __inline USHORT CheckSumCalculator(ULONG val, PVOID buffer, ULONG len)
Definition: sw-offload.c:96

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
unsigned char * PUCHAR
Definition: retypes.h:3
GLuint buffer
Definition: glext.h:5915
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
unsigned short * PUSHORT
Definition: retypes.h:2

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 }
GLuint res
Definition: glext.h:9613

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 }
GLuint res
Definition: glext.h:9613

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 }
GLuint res
Definition: glext.h:9613

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
IPv6Header v6
Definition: sw-offload.c:55
IPv4Header v4
Definition: sw-offload.c:56
GLenum GLsizei len
Definition: glext.h:6722
#define IP_HEADER_LENGTH(pHeader)
Definition: sw-offload.c:91
unsigned short USHORT
Definition: pedump.c:61
static __inline USHORT swap_short(USHORT us)
GLuint res
Definition: glext.h:9613

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  {
576  if(flags & pcrTcpV4Checksum)
577  {
579  }
580  }
581  else /* UDP */
582  {
583  if (flags & pcrUdpV4Checksum)
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  {
596  if(flags & pcrTcpV6Checksum)
597  {
599  }
600  }
601  else /* UDP */
602  {
603  if (flags & pcrUdpV6Checksum)
604  {
606  }
607  }
608  }
609  }
610  PrintOutParsingResult(res, 1, caller);
611  return res;
612 }
GLuint buffer
Definition: glext.h:5915
static __inline tTcpIpPacketParsingResult VerifyUdpChecksum(IPHeader *pIpHeader, ULONG len, tTcpIpPacketParsingResult known, ULONG whatToFix)
Definition: sw-offload.c:473
GLsizeiptr size
Definition: glext.h:5919
static __inline VOID PrintOutParsingResult(tTcpIpPacketParsingResult res, int level, LPCSTR procname)
Definition: sw-offload.c:552
GLbitfield flags
Definition: glext.h:7161
static __inline tTcpIpPacketParsingResult QualifyIpPacket(IPHeader *pIpHeader, ULONG len)
Definition: sw-offload.c:159
static __inline tTcpIpPacketParsingResult VerifyTcpChecksum(IPHeader *pIpHeader, ULONG len, tTcpIpPacketParsingResult known, ULONG whatToFix)
Definition: sw-offload.c:408
GLuint res
Definition: glext.h:9613
static __inline tTcpIpPacketParsingResult VerifyIpChecksum(IPv4Header *pIpHeader, tTcpIpPacketParsingResult known, BOOLEAN bFix)
Definition: sw-offload.c:364

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 }
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
static __inline VOID PrintOutParsingResult(tTcpIpPacketParsingResult res, int level, LPCSTR procname)
Definition: sw-offload.c:552
static __inline tTcpIpPacketParsingResult QualifyIpPacket(IPHeader *pIpHeader, ULONG len)
Definition: sw-offload.c:159
GLuint res
Definition: glext.h:9613

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,
559  GetIPCSCase(res),
560  res.fixedIpCS ? "(fixed)" : "",
561  GetXxpCSCase(res),
562  res.fixedXxpCS ? "(fixed)" : ""));
563 }
GLint level
Definition: gl.h:1546
static LPCSTR __inline GetPacketCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:529
static LPCSTR __inline GetXxpCSCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:546
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
static LPCSTR __inline GetIPCSCase(tTcpIpPacketParsingResult res)
Definition: sw-offload.c:540
GLuint res
Definition: glext.h:9613

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 }
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
#define TCP_HEADER_LENGTH(pHeader)
Definition: sw-offload.c:92
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
struct _tagTCPHeader TCPHeader
GLenum GLsizei len
Definition: glext.h:6722
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1

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 }
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
struct _tagUDPHeader UDPHeader
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
GLenum GLsizei len
Definition: glext.h:6722
unsigned short USHORT
Definition: pedump.c:61
static __inline USHORT swap_short(USHORT us)
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1

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 }
USHORT ip6_payload_len
Definition: sw-offload.c:46
#define TRUE
Definition: types.h:120
#define PROTOCOL_TCP
Definition: sw-offload.c:87
unsigned char * PUCHAR
Definition: retypes.h:3
IPv6Header v6
Definition: sw-offload.c:55
static __inline tTcpIpPacketParsingResult ProcessTCPHeader(tTcpIpPacketParsingResult _res, PVOID pIpHeader, ULONG len, USHORT ipHeaderSize)
Definition: sw-offload.c:117
struct _tagIPv4Header IPv4Header
UCHAR ip6ext_hdr_len
Definition: sw-offload.c:62
#define FALSE
Definition: types.h:117
#define __fallthrough
Definition: sal.h:2886
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
unsigned char BOOLEAN
IPv4Header v4
Definition: sw-offload.c:56
static __inline tTcpIpPacketParsingResult ProcessUDPHeader(tTcpIpPacketParsingResult _res, PVOID pIpHeader, ULONG len, USHORT ipHeaderSize)
Definition: sw-offload.c:140
unsigned char UCHAR
Definition: xmlstorage.h:181
GLenum GLsizei len
Definition: glext.h:6722
UCHAR ip6_next_header
Definition: sw-offload.c:47
unsigned short USHORT
Definition: pedump.c:61
static __inline USHORT swap_short(USHORT us)
UCHAR ip6ext_next_header
Definition: sw-offload.c:61
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
#define PROTOCOL_UDP
Definition: sw-offload.c:88
#define __FUNCTION__
Definition: types.h:112
#define MAX_SUPPORTED_IPV6_HEADERS
Definition: sw-offload.c:37

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 __inline VOID CalculateIpChecksum(IPv4Header *pIpHeader)
Definition: sw-offload.c:110
static __inline BOOLEAN CompareNetCheckSumOnEndSystem(USHORT computedChecksum, USHORT arrivedChecksum)
Definition: sw-offload.c:347
unsigned short USHORT
Definition: pedump.c:61
GLuint res
Definition: glext.h:9613
static BOOL bFix
Definition: dispmode.c:75

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 }
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
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
GLenum GLsizei len
Definition: glext.h:6722
static __inline BOOLEAN CompareNetCheckSumOnEndSystem(USHORT computedChecksum, USHORT arrivedChecksum)
Definition: sw-offload.c:347
unsigned short USHORT
Definition: pedump.c:61
static __inline USHORT CalculateIpPseudoHeaderChecksum(IPHeader *pIpHeader, tTcpIpPacketParsingResult res, USHORT headerAndPayloadLen)
Definition: sw-offload.c:335
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1

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 }
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
static __inline USHORT GetXxpHeaderAndPayloadLen(IPHeader *pIpHeader, tTcpIpPacketParsingResult res)
Definition: sw-offload.c:286
GLenum GLsizei len
Definition: glext.h:6722
static __inline BOOLEAN CompareNetCheckSumOnEndSystem(USHORT computedChecksum, USHORT arrivedChecksum)
Definition: sw-offload.c:347
unsigned short USHORT
Definition: pedump.c:61
static __inline USHORT CalculateIpPseudoHeaderChecksum(IPHeader *pIpHeader, tTcpIpPacketParsingResult res, USHORT headerAndPayloadLen)
Definition: sw-offload.c:335
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
static VOID CalculateUdpChecksumGivenPseudoCS(UDPHeader *pUdpHeader, ULONG udpLength)
Definition: sw-offload.c:387

Referenced by ParaNdis_CheckSumVerify().