Reply To: UDP checksum recalculation

Home Forums Discussions Support UDP checksum recalculation Reply To: UDP checksum recalculation

#6063
Kon
Participant

    VOID
    RecalculateUDPChecksum (
    PINTERMEDIATE_BUFFER pPacket
    )
    {
    udphdr_ptr pUdpHeader = NULL;
    unsigned short word16, padd = 0;
    unsigned int i, sum = 0;
    PUCHAR buff;
    DWORD dwUdpLen;

    iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];

    // Sanity check
    if (pIpHeader->ip_p == IPPROTO_UDP)
    {
    pUdpHeader = (udphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
    }
    else
    return;

    dwUdpLen = ntohs(pIpHeader->ip_len) – pIpHeader->ip_hl*4;//pPacket->m_Length – ((PUCHAR)(pTcpHeader) – pPacket->m_IBuffer);

    if ( (dwUdpLen/2)*2 != dwUdpLen )
    {
    padd=1;
    pPacket->m_IBuffer[dwUdpLen + pIpHeader->ip_hl*4 + sizeof(ether_header)] = 0;
    }

    buff = (PUCHAR)pUdpHeader;
    pUdpHeader->th_sum = 0;

    // make 16 bit words out of every two adjacent 8 bit words and
    // calculate the sum of all 16 vit words
    for (i=0; i< dwUdpLen+padd; i=i+2){
    word16 =((buff<<8)&0xFF00)+(buff[i+1]&0xFF);
    sum = sum + (unsigned long)word16;
    }

    // add the TCP pseudo header which contains:
    // the IP source and destination addresses,

    sum = sum + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w2);
    sum = sum + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w2);

    // the protocol number and the length of the TCP packet
    sum = sum + IPPROTO_UDP + (unsigned short)dwUdpLen;

    // keep only the last 16 bits of the 32 bit calculated sum and add the carries
    while (sum>>16)
    sum = (sum & 0xFFFF)+(sum >> 16);

    // Take the one’s complement of sum
    sum = ~sum;

    pUdpHeader->th_sum = ntohs((unsigned short)sum);
    }