/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "pingsender.h" #include "logger.h" namespace { Logger logger("PingSender"); } quint16 PingSender::inetChecksum(const void* data, size_t len) { int nleft, sum; quint16* w; union { quint16 us; quint8 uc[2]; } last; quint16 answer; nleft = static_cast(len); sum = 0; w = (quint16*)data; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { last.uc[0] = *(quint8*)w; last.uc[1] = 0; sum += last.us; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return (answer); }