Контрольная сумма для заголовка IPv4

190
22 января 2019, 07:00

Был задан такой вопрос, но я вроде как приблизился к решению вопроса о своей задаче. В интернете найден мной такой метод:

        public static ushort ComputeHeaderIpChecksum(byte[] header, int length) {
        ushort word16;
        long sum = 0;
        for (int i = 0; i < length; i += 2) {
            word16 = (ushort)(((header[i] << 8) & 0xFF00) + (header[i + 1] & 0xFF));
            sum += word16;
        }
        while ((sum >> 16) != 0) {
            sum = (sum & 0xFFFF) + (sum >> 16);
        }
        return (ushort)~sum;
    }

Но он не работает как должно, да и к тому же я не понимаю метода вычисления контрольной суммы. С английским у меня не очень хорошо, дабы такие статьи почитать в интернете на другом языке. Пакет собирается таким образом:

            foreach (byte array in MacAddressDestination) {
            Packet[i++] = array;
        }
        foreach (byte array in MacAddressSource) {
            Packet[i++] = array;
        }
        Packet[i++] = 0x08; //IPv4
        Packet[i++] = 0x00; //Type IPv4
        Packet[i++] = 0x45; //IP Version
        Packet[i++] = 0x00; //Тип Сервиса //0x41
        Packet[i++] = 0x00; //Total lenght
        Packet[i++] = 0x3c; //Total lenght
        Packet[i++] = 0x50; //Идентификатор
        Packet[i++] = 0x73; //Идентификатор
        Packet[i++] = 0x00; //Флаг
        Packet[i++] = 0x00; //Флаг
        Packet[i++] = 0x80; //TTL
        Packet[i++] = 0x01; //ICMP Protocol 
        //Packet[i++] = 0x35; //Header checksum (Правильная сумма, какая должна получится)
        //Packet[i++] = 0x8d; //Header checksum
        Packet[i++] = 0x00; //Header checksum
        Packet[i++] = 0x00; //Header checksum
        foreach (byte array in ipS) { //IP адрес источника
            Packet[i++] = array;
        }
        foreach (byte array in ipD) { //IP адрес доставки
            Packet[i++] = array;
        }
        ushort ipHeadChecksum = ComputeHeaderIpChecksum(Packet, 33);//Применение метода
        Packet[24] = (byte)ipHeadChecksum;
        Packet[25] = (byte)(ipHeadChecksum >> 8);

Скорее всего ошибка у меня в применении этого метода

Answer 1

Ваш код собирает не IP-датаграмму, а Ethernet-фрейм. Соответственно IPv4-заголовок находится не с начала. Судя по всему, нужны такие изменения:

public static ushort ComputeHeaderIpChecksum(byte[] header, int start, int length) {
    long sum = 0;
    for (int i = 0; i < length; i += 2) {
        ushort word16 = (ushort)((header[start + i] << 8) + header[start + i + 1]);
        sum += word16;
    }
    while ((sum >> 16) != 0) {
        sum = (sum & 0xFFFF) + (sum >> 16);
    }
    return (ushort)~sum;
}

И ваш код:

foreach (byte array in MacAddressDestination) {
    Packet[i++] = array;
}
foreach (byte array in MacAddressSource) {
    Packet[i++] = array;
}
Packet[i++] = 0x08; //IPv4
Packet[i++] = 0x00; //Type IPv4
var datagramStart = i; // здесь начинается IPv4-датаграмма
Packet[i++] = 0x45; //IP Version
Packet[i++] = 0x00; //Тип Сервиса //0x41
Packet[i++] = 0x00; //Total lenght
Packet[i++] = 0x3c; //Total lenght
Packet[i++] = 0x50; //Идентификатор
Packet[i++] = 0x73; //Идентификатор
Packet[i++] = 0x00; //Флаг
Packet[i++] = 0x00; //Флаг
Packet[i++] = 0x80; //TTL
Packet[i++] = 0x01; //ICMP Protocol
var checksumStart = i; // здесь начинается контрольная сумма
//Packet[i++] = 0x35; //Header checksum (Правильная сумма, какая должна получится)
//Packet[i++] = 0x8d; //Header checksum
Packet[i++] = 0x00; //Header checksum
Packet[i++] = 0x00; //Header checksum
foreach (byte array in ipS) { //IP адрес источника
    Packet[i++] = array;
}
foreach (byte array in ipD) { //IP адрес доставки
    Packet[i++] = array;
}
ushort ipHeadChecksum = ComputeHeaderIpChecksum(Packet, datagramStart, 20);
Packet[checksumStart] = (byte)(ipHeadChecksum >> 8);
Packet[checksumStart + 1] = (byte)ipHeadChecksum;
READ ALSO
WPF: добавить элемент в ObservableCollection&lt;T&gt; через IEnumerable

WPF: добавить элемент в ObservableCollection<T> через IEnumerable

Такая дилемма: у меня есть эдакий "ItemsSource" в моем элементе управленияDependencyProperty типа IEnumerable

162
Поворот оружия в сторону Touch на Unity

Поворот оружия в сторону Touch на Unity

Каким образом сделать, так чтобы оружие моего персонажа дулом было повернуто в сторону моего пальца (тача) и следило за ним, когда вожу по экрану

160