es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El cálculo del checksum de IP da valores muy extraños. ¿Es la suma de todas las palabras en iphdr y luego se toma su complemento? ¿Qué me estoy perdiendo?

Entonces, esta función hasta ahora simplemente realiza la suma de cada palabra en el objeto struct iphdr después de establecer el checksum en 0 y complementarlo. Pero algo está mal con esto, ya que el campo checksum de mis paquetes IP recibidos es completamente diferente. Lo que calculo me está dando un valor negativo.

Entonces, esta es mi función de checksum que simplemente hace lo siguiente:

“`c++
uint16_t ip_checksum(void* vdata,size_t length) {
// Cast the data pointer to one that can be indexed.
char* data=(char)vdata;
uint32_t acc=0;
// Handle complete 16-bit blocks.
for (size_t i=0;i+1<length;i+=2) {=”” uint16_t=”” word;=”” memcpy(&word,data+i,2);=”” acc+=”ntohs(word);” *if=”” (acc=””>0xffff) {
acc-=0xffff;
}
/
}
return (~acc);
}


Entonces, este bucle simplemente opera en cada palabra de 16 bits del puntero de objeto recibido y realiza la suma, almacenándola en la variable acc. Luego lo complemento con `~`. ```c++ return (~acc);

Básicamente eso es exactamente lo que se indica en internet para calcularlo si entendí correctamente. Pero cuando hago esto:

c++
printf("checksum = %d\n",ntohs(iph->check));
iph->check=0;
int16_t i=ip_checksum(iph,sizeof(iph));
printf("------------------------------------------>%d\n",(i));

imprime valores completamente diferentes de checksum en los dos printf anteriores. Así que me gustaría saber qué estoy haciendo mal.</length;i+=2)>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Problema con el cálculo del checksum de IP

    La función compartida anteriormente está diseñada para calcular el checksum de IP para el objeto iphdr recibido. La función primero inicializa un acumulador acc en 0, y luego añade cada palabra de 16 bits del objeto a acc. Finalmente, la función devuelve el complemento de acc.

    Sin embargo, el checksum calculado parece ser completamente diferente al que se encuentra en el paquete IP recibido. Además, el valor calculado es negativo en algunos casos.

    Podría haber varios problemas con el código que podrían llevar al cálculo incorrecto del checksum. Algunos posibles problemas se discuten a continuación.

    Problemas de orden de bytes (endianness)

    Un problema potencial con el código podría estar relacionado con el orden de bytes (endianness). El código asume que los datos recibidos están en orden big-endian, y los convierte al orden de bytes del host utilizando la función ntohs().

    Sin embargo, si el paquete recibido está en orden little-endian, la función ntohs() no podrá convertir los datos correctamente. Esto podría llevar a un cálculo incorrecto del checksum.

    Para solucionar este problema, el código podría verificar el orden de bytes del sistema huésped y convertir los datos en consecuencia. Alternativamente, el cálculo del checksum de IP se podría realizar utilizando una función de biblioteca que maneje automáticamente el orden de bytes.

    Manejo del campo de checksum

    Otro problema con el código podría estar relacionado con el manejo del campo de checksum en el objeto iphdr. El código establece el valor del checksum en 0 antes de calcularlo, lo cual es el enfoque correcto.

    Sin embargo, luego el código imprime el valor del checksum original utilizando printf("checksum = %d\n",ntohs(iph->check));. Esto podría llevar a confusión, ya que el valor impreso no coincidiría con el valor calculado.

    En cambio, el código debería imprimir directamente el valor calculado, sin extraer el valor original del objeto iphdr.

    Complemento del checksum

    El código toma el complemento del valor del acumulador utilizando el operador ~. Este es el enfoque correcto para complementar el valor.

    Sin embargo, luego el código devuelve el valor complementado como un entero sin signo de 16 bits. Esto podría llevar a problemas si el valor complementado es negativo.

    Para solucionar este problema, el código podría utilizar un entero con signo de 16 bits para almacenar el valor complementado. Esto aseguraría que los valores negativos se manejen correctamente.

    Conclusión

    Podría haber varios problemas con el código que llevan a un cálculo incorrecto del checksum. Los problemas discutidos anteriormente son algunos de los más comunes que podrían llevar a tales problemas. Al abordar estos problemas, el código podría modificarse para calcular el checksum de IP correcto para el objeto iphdr recibido.

Comments are closed.