Я уже некоторое время работаю над этим, но не могу получить правильное значение контрольной суммы. Здесь мой метод принимает 3-байтовые массивы. Первый содержит байты IPv4Header, второй — байты TCPHeader и, наконец, полезную нагрузку. Я уже проверил, что эти байты верны, и пытаюсь использовать перекрестные ссылки по мере продвижения, но после стольких попыток мне все время не удается. Я также не нашел ни одного руководства с реальным кодом, который бы делал это из байтового массива.
public ushort ComputeChecksum(byte[] ipv4Header, byte[] tcpHeader, byte[] payload)
{
int pseudoHeaderLength = 12; // Pseudo-header is 12 bytes
int totalLength = pseudoHeaderLength + tcpHeader.Length + payload.Length;
byte[] pseudoHeaderAndTcpSegment = new byte[totalLength];
// Copy Source IP address (4 bytes)
Array.Copy(ipv4Header, 12, pseudoHeaderAndTcpSegment, 0, 4);
Console.WriteLine("Claculate TCP CheckSum length:" + totalLength);
Console.WriteLine((BitConverter.ToString(pseudoHeaderAndTcpSegment).Replace("-", " ") + ", "));
Console.WriteLine("");
// Copy Destination IP address (4 bytes)
Array.Copy(ipv4Header, 16, pseudoHeaderAndTcpSegment, 4, 4);
Console.WriteLine((BitConverter.ToString(pseudoHeaderAndTcpSegment).Replace("-", " ") + ", "));
Console.WriteLine("");
// TCP length (2 bytes)
int tcpLength = tcpHeader.Length + payload.Length;
pseudoHeaderAndTcpSegment[8] = (byte)((tcpLength >> 8) & 0xFF);
pseudoHeaderAndTcpSegment[9] = (byte)(tcpLength & 0xFF);
Console.WriteLine((BitConverter.ToString(pseudoHeaderAndTcpSegment).Replace("-", " ") + ", "));
Console.WriteLine("");
// Protocol (1 byte)
pseudoHeaderAndTcpSegment[10] = ipv4Header[9];
Console.WriteLine((BitConverter.ToString(pseudoHeaderAndTcpSegment).Replace("-", " ") + ", ") + " Protocol:" + ipv4Header[9]); // ipv4Header[9] prints 6 like it should
Console.WriteLine("");
// Zero byte (1 byte)
pseudoHeaderAndTcpSegment[11] = 0;
Console.WriteLine((BitConverter.ToString(pseudoHeaderAndTcpSegment).Replace("-", " ") + ", "));
Console.WriteLine("");
// Copy TCP header
Array.Copy(tcpHeader, 0, pseudoHeaderAndTcpSegment, 12, tcpHeader.Length);
// Copy payload
Array.Copy(payload, 0, pseudoHeaderAndTcpSegment, 12 + tcpHeader.Length, payload.Length);
Console.WriteLine((BitConverter.ToString(pseudoHeaderAndTcpSegment).Replace("-", " ") + ", "));
Console.WriteLine("");
return ComputeChecksum(pseudoHeaderAndTcpSegment);
}
private static ushort ComputeChecksum(byte[] data)
{
long sum = 0;
int length = data.Length;
int index = 0;
while (length > 1)
{
sum += (ushort)(((data[index] 0)
{
sum += (ushort)((data[index] > 16) != 0)
{
sum = (sum & 0xFFFF) + (sum >> 16);
}
// Return one's complement of the result
return (ushort)~sum;
}
Печатаемые байты кажутся правильными, и я прочитал эту статью «Вычисление контрольной суммы TCP», в которой мне говорилось, что мне следует использовать IP-адрес источника, IP-адрес назначения, длину сегмента, протокол. , фиксированные 8 бит, за которыми следуют заголовок TCP и полезная нагрузка. Итак, я думаю, что мой порядок правильный, хотя я не уверен, правильно ли я выполнил фиксированные 8 бит и часть длины. Я также не уверен, правильно ли я вычисляю фактический 2-байтовый ответ, используя дополнение. Любые исправления будут очень признательны, спасибо!
Я уже некоторое время работаю над этим, но не могу получить правильное значение контрольной суммы. Здесь мой метод принимает 3-байтовые массивы. Первый содержит байты IPv4Header, второй — байты TCPHeader и, наконец, полезную нагрузку. Я уже проверил, что эти байты верны, и пытаюсь использовать перекрестные ссылки по мере продвижения, но после стольких попыток мне все время не удается. Я также не нашел ни одного руководства с реальным кодом, который бы делал это из байтового массива. [code]public ushort ComputeChecksum(byte[] ipv4Header, byte[] tcpHeader, byte[] payload) { int pseudoHeaderLength = 12; // Pseudo-header is 12 bytes int totalLength = pseudoHeaderLength + tcpHeader.Length + payload.Length;
byte[] pseudoHeaderAndTcpSegment = new byte[totalLength];
private static ushort ComputeChecksum(byte[] data) { long sum = 0; int length = data.Length; int index = 0;
while (length > 1) { sum += (ushort)(((data[index] 0) { sum += (ushort)((data[index] > 16) != 0) { sum = (sum & 0xFFFF) + (sum >> 16); }
// Return one's complement of the result return (ushort)~sum; } [/code] Печатаемые байты кажутся правильными, и я прочитал эту статью «Вычисление контрольной суммы TCP», в которой мне говорилось, что мне следует использовать IP-адрес источника, IP-адрес назначения, длину сегмента, протокол. , фиксированные 8 бит, за которыми следуют заголовок TCP и полезная нагрузка. Итак, я думаю, что мой порядок правильный, хотя я не уверен, правильно ли я выполнил фиксированные 8 бит и часть длины. Я также не уверен, правильно ли я вычисляю фактический 2-байтовый ответ, используя дополнение. Любые исправления будут очень признательны, спасибо!
Недавно я задал аналогичный вопрос, но отметил его как решенный, так как думал, что нашел ответ, хотя на самом деле мой код работал только в определенных случаях, пропуская при этом большую часть случаев. В любом случае я использую WinDivert для...
У меня есть устройство, использующее модифицированный протокол Modbus. Устройство отправляет сообщения на последовательный порт RPi3. Сообщение имеет длину 14 байт и начинается с байта синхронизации, за которым следуют 11 байтов данных, а затем два...
Мне дали этот код Delphi:
unit lib_CRC;
interface uses SysUtils;
function CalculateCRC(Text: String): String;
implementation{ CRC Code generation routines }
Мне дали этот код Delphi:
unit lib_CRC;
interface uses SysUtils;
function CalculateCRC(Text: String): String;
implementation{ CRC Code generation routines }