Вот написал процедуру перерасчёта контрольной суммы пакета. Когда пакет приходит то я меняю IP адреса и необходим перерасчёт контрольной суммы. Но почемуто в сниффере отображается что контрольная сумма не верна. Помогите... Может где-то в коде ошибка... На вход: Указатель на пришедший пакет. Без заголовка ether Размер всего пакета. Процедура должна пересчитать контрольную сумму у IP,TCP,ICMP,UDP пакета... Код (Text): RebuildChecksum proc PackBuff: DWORD, PackLen: DWORD LOCAL PPacket : DWORD LOCAL PLenght : DWORD LOCAL POther : DWORD LOCAL srcip : DWORD LOCAL dstip : DWORD LOCAL Chksum : WORD LOCAL IPpacket[sizeof ip_hdr] : BYTE LOCAL Ptype : BYTE mov eax, [PackBuff] add eax, sizeof ip_hdr mov [POther],eax sub eax, sizeof pseudo_hdr mov [PPacket], eax mov eax, [PackLen] sub eax, sizeof ip_hdr ; Длина пакета без IP заголовка add eax, sizeof pseudo_hdr mov [PLenght], eax mov esi, [PackBuff] mov eax, (ip_hdr ptr [esi]).ip_src mov [srcip], eax mov eax, (ip_hdr ptr [esi]).ip_dest mov [dstip], eax invoke ChkSumm, esi, sizeof ip_hdr ; Считаем контрольную сумму IP пакета mov (ip_hdr ptr [esi]).ip_cksum, ax mov ecx, sizeof ip_hdr lea edi, IPpacket rep movsb ; Сохраняем IP пакет ; Проверяем какому протоколу мы будем вычислять контрольную сумму mov edi, [PackBuff] mov al, (ip_hdr ptr [edi]).ip_p .if al == IPPROTO_TCP mov [Ptype], IPPROTO_TCP .endif .if al == IPPROTO_ICMP mov [Ptype], IPPROTO_ICMP .endif .if al == IPPROTO_UDP mov [Ptype], IPPROTO_UDP .endif invoke RtlZeroMemory, [PPacket], sizeof pseudo_hdr mov edi, [PPacket] mov eax, [srcip] mov (pseudo_hdr ptr [edi]).src_addr, eax mov eax, [dstip] mov (pseudo_hdr ptr [edi]).dst_addr, eax mov byte ptr al, [Ptype] mov (pseudo_hdr ptr [edi]).protocol, al ;IPPROTO_? mov eax,[PLenght] sub eax, sizeof pseudo_hdr ; Длина пакета без псевдо заголовка invoke htons, eax mov (pseudo_hdr ptr [edi]).len,ax invoke ChkSumm, [PPacket], [PLenght] ; Считаем контрольную сумму пакета mov [Chksum],ax mov edi, [PackBuff] lea esi, IPpacket mov ecx, sizeof ip_hdr rep movsb mov byte ptr al, [Ptype] .if al == IPPROTO_TCP mov word ptr ax,[Chksum] mov edi,[POther] mov (tcp_hdr ptr [edi]).tcp_cksum,ax .endif .if al == IPPROTO_ICMP mov word ptr ax,[Chksum] mov edi,[POther] mov (icmp_hdr ptr [edi]).icmp_cksum,ax .endif .if al == IPPROTO_UDP mov word ptr ax,[Chksum] mov edi,[POther] mov (udp_hdr ptr [edi]).udp_cksum,ax .endif ret RebuildChecksum endp Процедура расчёта контрольной суммы верна... Вот на всяк случай... Код (Text): ChkSumm proc pData:dword, SzData:dword LOCAL tmpVal : dword mov tmpVal, 0 @@: cmp SzData, 1 jle @f mov eax, pData xor ecx, ecx mov cx, [eax] mov edx, tmpVal add edx, ecx mov tmpVal, edx mov eax, pData add eax, 2 mov pData, eax mov ecx, SzData sub ecx, 2 mov SzData, ecx jmp @b @@: cmp SzData, 0 jz @f mov edx, pData xor eax, eax mov al, [edx] mov ecx, tmpVal add ecx, eax mov tmpVal, ecx @@: mov edx, tmpVal shr edx, 10h mov eax, tmpVal and eax, 0FFFFh add edx, eax mov tmpVal, edx mov ecx, tmpVal shr ecx, 10h mov edx, tmpVal add edx, ecx mov tmpVal, edx mov eax, tmpVal not eax ret ChkSumm endp
Что-то я не вижу обнуления ячеек с контрольной суммой перед её расчётом. Еще не совсем понятно зачем так часто использовать tmpVal, когда можно всё сделать в регистрах(смотреть самый первый вариант): http://www.wasm.ru/forum/viewtopic.php?id=16048