尝试计算IP头校验和

时间:2015-02-15 16:32:42

标签: c# ip packet checksum

我尝试编写一个使用this示例计算IP Header Checksum的函数。

首先我有我的IP头字节:

byte[] arr = { 
                 69, 0, 0, 60, 28, 70, 64, 0, 64, 6,
                 0, 0, 172, 16, 10, 99, 172, 16, 10, 12
             };

这里我添加所有字节对:

public static ushort[] AddPairs(byte[] arr)
{
    List<ushort> pairs = new List<ushort>();
    for (int i = 0; i < arr.Length; i += 2)
    {
        byte b1 = arr[i];
        byte b2 = arr[i + 1];
        ushort add = (ushort)((arr[i] << 8) + arr[i + 1]);
        pairs.Add(add);
    }

    return pairs.ToArray();
}

在这里我需要计算校验和:

public static void ComputeHeaderIpChecksum(byte[] arr)
{
    ushort[] pairs = AddPairs(arr);
    ushort result;
    ushort tmp = 0;


    for (int i = 0; i < pairs.Length; i++)
    {
        result = (ushort)(pairs[i] + pairs[i + 1]);
        tmp = result;
    }
}

首先在添加2个值后,如何在没有进位的情况下检查这是否有效ushort? 我有点被困在这里,不知道接下来该做什么,并乐意为你提供帮助。

1 个答案:

答案 0 :(得分:0)

来自微芯片的校验和的C代码

WORD CalcIPChecksum(BYTE *buffer, WORD count)
{

    // wordval = CalcIPChecksum(&pEEPROMbuf[0x0800 + 6], 51);
    WORD    i;
    WORD    *val;
    union
    {
        WORD    w[2];
        DWORD   dw;
    } sum;

    i = count >> 1;
    val = (WORD *)buffer;
    //unsigned char temp;
    // Calculate the sum of all words
    sum.dw = 0L;
    while(i--)
    {
        //temp = *val;
        sum.dw += (DWORD)*val++;
    }
    // Add in the sum of the remaining byte, if present


    if (count & 0x1)
    { 
        DWORD temp = (DWORD)*(BYTE *)val;

        sum.dw += temp;


    }
    // Do an end-around carry (one's complement arrithmetic)
    sum.dw = sum.w[0] + sum.w[1];

    // Do another end-around carry in case if the prior add
    // caused a carry out
    sum.w[0] += sum.w[1];
    WORD answer = ~sum.w[0];
    // Return the resulting checksum
    return ;
}

c#中的相同功能

private UInt16 CalcIPChecksum(byte[] buffer, ushort count,int offset)
{
    ushort i =0;
    byte[] val = StatMethods.memcpy(ref buffer, offset, count);// get_byte_arr(buffer, count, offset);
                                                               // public static byte[] memcpy(ref byte[] ar, int startposition, int offset)

    UInt32 sum_dw = 0;
    i = (ushort)(count >> 1);
    sum_dw = 0;
    int j = 0;
    while (i > 0)
    {
       UInt16 restored = BitConverter.ToUInt16(val, j);
       sum_dw += restored;
        String s = sum_dw.ToString("X");
       System.Diagnostics.Debug.WriteLine("Number: "+i+" -- "+"value:" + s);
       j += 2;
       i--;

    }

    var aa = count & 0x1;

    if (Convert.ToBoolean(aa))
    {
        byte restored = val[j];

        sum_dw += (byte)restored;


    }
    byte[] sum_wb = BitConverter.GetBytes(sum_dw);

    UInt16 sum_w0 = (UInt16)((UInt16)sum_wb[0] + (UInt32)(sum_wb[1]<<8));
    UInt16 sum_w1 = (UInt16)((UInt16)sum_wb[2] + (UInt32)(sum_wb[3] << 8));

    sum_dw = (UInt32)sum_w0 + (UInt32 )sum_w1; 

    sum_wb = BitConverter.GetBytes(sum_dw);

    sum_w0 = (UInt16)((UInt16)sum_wb[0] + (UInt32)(sum_wb[1] << 8));
    sum_w1 = (UInt16)((UInt16)sum_wb[2] + (UInt32)(sum_wb[3] << 8));

    sum_w0 += sum_w1;



    var reverse = ~(sum_w0);
    UInt16 ans = (UInt16)(~(sum_w0));
    System.Diagnostics.Debug.WriteLine("Asnwer: "+reverse);

    return (UInt16)reverse;

}

希望有所帮助