locked
TCP Checksum RRS feed

  • Question

  •    I wrote a WFP callout, modify TCP header`s remote port (80 => other port) and reinjected to send path, in FWPM_LAYER_OUTBOUND_TRANSPORT_V4 layer,

    when modify remote port, i re-calculate TCP header`s checksum, calculate is OK, View to be sent through the packet capture tool packet checksum is 0xffff, if I do not re-calculate the checksum data is no problem, (In addition, my analysis indicates the packet`s checksum is alway 0), the callout is OOB modify type, and check offload was close.

       Whether in FWPM_LAYER_OUTBOUND_TRANSPORT_V4 layer modify data must modify the checksum?

         May I ask why, thank you

    NTSTATUS ProcessModifyIndicate(PTRANSPORT_INDICATE Indicate)
    {
    	NTSTATUS Status = STATUS_SUCCESS;
    
    	PVOID Storage = NULL;
    
    	if (NULL == Indicate)
    	{
    		return STATUS_INVALID_PARAMETER;
    	}
    
    	do 
    	{
    		ULONG Length = 0;
    
    		USHORT Checksum = 0;
    
    		PSEUDO_HEADER Pseudo = {0};
    
    		PTCP_HEADER Header = NULL;
    
    		PNET_BUFFER Buffer = NET_BUFFER_LIST_FIRST_NB(Indicate->Common.Clone);
    
    		NDIS_TCP_IP_CHECKSUM_PACKET_INFO Offload = {0};
    
    		Length = NET_BUFFER_DATA_LENGTH(Buffer);
    
    		Storage = ExAllocatePoolWithTag(NonPagedPool, NET_BUFFER_DATA_LENGTH(Buffer), MODIFY_TAG);
    		if (NULL == Storage)
    		{
    			Status = STATUS_INSUFFICIENT_RESOURCES;
    			break;
    		}
    
    		Header = (PTCP_HEADER)NdisGetDataBuffer(Buffer, NET_BUFFER_DATA_LENGTH(Buffer), Storage, sizeof(USHORT), 0);
    		if (NULL == Header)
    		{
    			break;
    		}
    
    		SET_TCP_REMOTE(Header, MODIFY_REMOTE_PORT == GET_TCP_REMOTE(Header) ? MODIFY_REDIRECT_PORT : MODIFY_REMOTE_PORT);
    
    		SET_TCP_CHECKSUM(Header, 0);
    
    		SET_PSEUDO_LOCAL(&Pseudo, Indicate->Local);
    		SET_PSEUDO_REMOTE(&Pseudo, Indicate->Remote);
    		SET_PSEUDO_PROTOCOL(&Pseudo, Indicate->Protocol);
    		SET_PSEUDO_LENGTH(&Pseudo, NET_BUFFER_DATA_LENGTH(Buffer));
    
    		Checksum = CalculateTransportChecksum((PUSHORT)Header, &Pseudo);
    
    		Offload.Value = (ULONG)NET_BUFFER_LIST_INFO(Indicate->Common.Clone, TcpIpChecksumNetBufferListInfo);
    
    		if ((PVOID)Header == Storage)
    		{
    			Header = (PTCP_HEADER)NdisGetDataBuffer(Buffer, sizeof(TCP_HEADER), NULL, sizeof(USHORT), 0);
    			if (NULL == Header)
    			{
    				Status = STATUS_INSUFFICIENT_RESOURCES;
    				break;
    			}
    
    			SET_TCP_REMOTE(Header, MODIFY_REMOTE_PORT == GET_TCP_REMOTE(Header) ? MODIFY_REDIRECT_PORT : MODIFY_REMOTE_PORT);
    		}
    
    		SET_TCP_CHECKSUM(Header, Checksum);
    	}
    	while (FALSE);
    
    	if (NULL != Storage)
    	{
    		ExFreePoolWithTag(Storage, MODIFY_TAG);
    		Storage = NULL;
    	}
    
    	return Status;
    }

     
    Thursday, October 25, 2012 11:20 AM

All replies