/* * -------------------------------------------------------------------------- * FixSegmentHeader * * Fix IP length, IP checksum, TCP sequence number and TCP checksum * in the segment. * -------------------------------------------------------------------------- */ static NDIS_STATUS FixSegmentHeader(PNET_BUFFER nb, UINT16 segmentSize, UINT32 seqNumber) { EthHdr *dstEth; IPHdr *dstIP; TCPHdr *dstTCP; PMDL mdl; PUINT8 bufferStart; mdl = NET_BUFFER_FIRST_MDL(nb); bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(mdl, LowPagePriority); if (!bufferStart) { return NDIS_STATUS_RESOURCES; } dstEth = (EthHdr *)(bufferStart + NET_BUFFER_CURRENT_MDL_OFFSET(nb)); ASSERT((INT)MmGetMdlByteCount(mdl) - NET_BUFFER_CURRENT_MDL_OFFSET(nb) >= sizeof(EthHdr) + sizeof(IPHdr) + sizeof(TCPHdr)); dstIP = (IPHdr *)((PCHAR)dstEth + sizeof *dstEth); dstTCP = (TCPHdr *)((PCHAR)dstIP + dstIP->ihl * 4); ASSERT((INT)MmGetMdlByteCount(mdl) - NET_BUFFER_CURRENT_MDL_OFFSET(nb) >= sizeof(EthHdr) + dstIP->ihl * 4 + TCP_HDR_LEN(dstTCP)); /* Fix IP length and checksum */ ASSERT(dstIP->protocol == IPPROTO_TCP); dstIP->tot_len = htons(segmentSize + dstIP->ihl * 4 + TCP_HDR_LEN(dstTCP)); dstIP->check = 0; dstIP->check = IPChecksum((UINT8 *)dstIP, dstIP->ihl * 4, 0); /* Fix TCP checksum */ dstTCP->seq = htonl(seqNumber); dstTCP->check = IPPseudoChecksum((UINT32 *)&dstIP->saddr, (UINT32 *)&dstIP->daddr, IPPROTO_TCP, segmentSize + TCP_HDR_LEN(dstTCP)); dstTCP->check = CalculateChecksumNB(nb, (UINT16)(NET_BUFFER_DATA_LENGTH(nb) - sizeof *dstEth - dstIP->ihl * 4), sizeof *dstEth + dstIP->ihl * 4); return STATUS_SUCCESS; }
/* *---------------------------------------------------------------------------- * OvsCalculateUDPChecksum * Calculate UDP checksum *---------------------------------------------------------------------------- */ static __inline NDIS_STATUS OvsCalculateUDPChecksum(PNET_BUFFER_LIST curNbl, PNET_BUFFER curNb, IPHdr *ipHdr, UDPHdr *udpHdr, UINT32 packetLength) { NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo; UINT16 checkSum; csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl, TcpIpChecksumNetBufferListInfo); /* Next check if UDP checksum has been calculated. */ if (!csumInfo.Receive.UdpChecksumSucceeded) { UINT32 l4Payload; checkSum = udpHdr->check; l4Payload = packetLength - sizeof(EthHdr) - ipHdr->ihl * 4; udpHdr->check = 0; udpHdr->check = IPPseudoChecksum((UINT32 *)&ipHdr->saddr, (UINT32 *)&ipHdr->daddr, IPPROTO_UDP, (UINT16)l4Payload); udpHdr->check = CalculateChecksumNB(curNb, (UINT16)l4Payload, sizeof(EthHdr) + ipHdr->ihl * 4); if (checkSum != udpHdr->check) { OVS_LOG_TRACE("UDP checksum incorrect."); return NDIS_STATUS_INVALID_PACKET; } } csumInfo.Receive.UdpChecksumSucceeded = 1; NET_BUFFER_LIST_INFO(curNbl, TcpIpChecksumNetBufferListInfo) = csumInfo.Value; return NDIS_STATUS_SUCCESS; }