La estocada final al TCP checksum

Iniciado por Kaxperday, 3 Enero 2016, 19:17 PM

0 Miembros y 1 Visitante están viendo este tema.

Kaxperday

Bueno tras ponerme esta mañana conseguí hacer el tcp segment len la parte más dificil aunque da mucho asco en su conjunto:

Código (cpp) [Seleccionar]

//sumo todo el payload tcp
for (int i = 54; i < _tamaño - 1; i++){
if (i + 1 == _tamaño) break;
sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
i++;
}

if ((_tamaño - 1) % 2 == 0){
sumanda = (u_short)_datos[_tamaño - 1];
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
}


Pero me falla la parte donde se suman los datos tcp, el payload, tengo que ir de 16 bits en 16 bits. Cambia si es par o impar y en eso estoy, a ver si alguien lo ve a simple vista, no se que ponia tambien que lei de rellenar con ceros.

Igual sumo dos veces el ultimo byte.. ya lo he depurado mentalmente y no enuentro manera no estoy muy freso, una hand pls, QUE YA LO TENGO CASI!!! TRAS MEEEESSES AÑOS LUSTROS.

Edito: sumar del byte 54 hasta el final sea par o impar sin repetir bytes claro y de 16 bits en 16 bits (u_short).

Ejemplos de comparacion final de tcp checksum verdadero y el mio calculado, respectivamente:


3d10== 1506 3d24
de5e== 190 de72
7527== 396 753b
6fae== 397 79c2
f0c9== 397 fadd
dabd== 396 dad1
9e96== 397 a8aa
f5d== 397 ff21
8c62== 1478 8c76
283e== 309 3252


Lo primero es el checksum verdadero, lo segundo es el tamaño del paquete (notese que si es par con sumar 14 al checksum nuestro ya tendriamos el verdadero siempre) sin embargo cuando es impar se va mas de resultado.

Creo que me falta el padding que no se ni lo que es, pero ya buscaré, este otro codigo que encontré hace tiempo, y está haciendo lo mismo sumar cabecera y datos de 16 en 16, en el ultimo paso no se que hace ni porque eso del padding, pero en ello estoy.

Código (cpp) [Seleccionar]
 
// Calculate the sum                                            //
        sum = 0;
        while (len > 1)
{
                sum += *buf++;
                if (sum & 0x80000000)
                        sum = (sum & 0xFFFF) + (sum >> 16);
                len -= 2;
        }

        if (len & 1)
                // Add the padding if the packet lenght is odd          //
                sum += *((uint8_t *)buf);


Edito: HAHAHAH AMIGOS, mucho google traductor ya decia yo que era porque era par o impar, "odd" en ingles es impar, en ese caso "add the padding" que no se que es, pero bueno jajaja poco a poco descifrando. (inverse enginnering) #esduroderoer

Ok se refiere a que si es impar ponga ceros en el final y bien esto ya lo hice, puse ceros delante y detrás del ultimo byte, es decir si terminaba en 0x12 0x14 0x 30 y era impar he probado a dejar 0x3000 y 0x0030 y el resultado malo tambien ojj, bueno ya casi lo tengo, caerá esta semana.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

MAFUS

Que significado tienen las variables?

Kaxperday

#2
Wow buena pregunta :""DDD yo es que ya me lo se de memoria de tanto verlo.


u_short sumando = 0, sumanda = 0;
bitset<17> controlador;


El controlador controla el acarreo de bit esta bien, _datos[] es el vector de bytes que recibo del paquete, y _tamaño el tamaño del mismo.

Me encuentro sumando el payload, que no siempre debería de ir así pero si el header len tcp es de 20 bytes empezaría en el byte 54 como tengo en el code y de ahí tira hasta el final sumando de 16 bits en 16bits, pero algo hago mal con el ultimo byte y cuando es impar.

Casi lo tengogg: izquierda checksum real, derecha calculado.


6543==6543
4dcb==4dcb
646==646
91c6==91c6
1bf==1bf
3922==3922
37ab==37ab
9069==9069
b262==b262
e928==e928
d76e==d76e
7d==7d
3eb5==3e3d
a84b==a77e
2313==2313
7dea==7dea
1dcb==1d50
6479==6479
506e==506e
5410==539c

Código (cpp) [Seleccionar]

//sumo todo el payload tcp
for (int i = 54; i < _tamaño; i++){
if (i + 1 > _tamaño - 1){
sumanda = (u_short)_datos[_tamaño - 1];
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
}
sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
i++;
}
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

MAFUS

A ver, desconozco el algoritmo de esto, pero veo una cosa que no me cuadra:
En la última iteración, cuándo i valga _tamano - 1, en la linea 10, cuando accedes a _datis [i +  1] ¿no estás fuera del array?

Kaxperday

#4
Cita de: MAFUS en  3 Enero 2016, 21:52 PM
A ver, desconozco el algoritmo de esto, pero veo una cosa que no me cuadra:
En la última iteración, cuándo i valga _tamano - 1, en la linea 10, cuando accedes a _datis [i +  1] ¿no estás fuera del array?

Se me olvido llamar al break.. :/, pero no cambia nada con ni sin break.

Hay algo que no comprendo que es porque cuando es par el checksum que calculo es 20 unidades mas pequeño que el original, y cuando es impar varia mucho de uno a otro. En los pares estoy olvidandome de sumar 20 y en los impares algo hago mal que va más alla que eso supongo.

Eso de odd, de que si son impares hay que añadir padding o no se que, simplemente sería quesumamos los bytes de par en par, y si el ultimo no tiene pareja lo sumamos por separado y salimos del bucle que es lo que hago, ¿NO?.

Código (cpp) [Seleccionar]

//sumo todo el payload tcp
for (int i = 54; i < _tamaño; i++){
if (i + 1 == _tamaño){//se desborda entonces copiamos solo el ultimo, pero estará ya copiado??
sumanda = (u_short)_datos[_tamaño - 1];
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
break;
}
sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
sumando++;
i++;
}

Saludos.

Bueno bueno, parece que tuve que ir a pedir ayuda al extranjero, aunque no espero ni respuesta, los guiris van de listos pero me parece que npi.

http://stackoverflow.com/questions/34582015/tcp-checksum-3-0-version

Ya esta disponible la nueva versión tcp checsum de kaxperday 3.0, más cerca del checksum real que nunca, delicatesse 3.0.

A ver si para la 4.0 ya la tenemos!!!

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.