I'm trying to figure out how to calculate the Internet Checksum in Java and its causing me no end of pain. (I'm horrible at bit manipulation.) I found a version in C# Calculate an Internet (aka IP, aka RFC791) checksum in C#. However my attempt at converting it to Java does not see to produce the correct results. Can anyone see what I'm doing wrong? I suspect a data type issue.
public long getValue() {
    byte[] buf = { (byte) 0xed, 0x2A, 0x44, 0x10, 0x03, 0x30};
    int length = buf.length;
    int i = 0;
    long sum = 0;
    long data = 0;
    while (length > 1) {
        data = 0;
        data = (((buf[i]) << 8) | ((buf[i + 1]) & 0xFF));
        sum += data;
        if ((sum & 0xFFFF0000) > 0) {
            sum = sum & 0xFFFF;
            sum += 1;
        }
        i += 2;
        length -= 2;
    }
    if (length > 0) {
        sum += (buf[i] << 8);
        // sum += buffer[i];
        if ((sum & 0xFFFF0000) > 0) {
            sum = sum & 0xFFFF;
            sum += 1;
        }
    }
    sum = ~sum;
    sum = sum & 0xFFFF;
    return sum;
}
 
                        
Edited to apply comments from @Andy, @EJP, @RD et al and adding extra test cases just to be sure.
I've used a combination of @Andys answer (correctly identifying the location of the problem) and updated the code to include the unit tests provided in the linked answer along with a verified message checksum additional test case.
First the implementation
Then the unit test in JUnit4