2009-09-26 50 views
18

La estructura cabecera UDP definido en /usr/include/netinet/udp.h es el siguientecálculo de suma de comprobación UDP

struct udphdr 
{ 
    u_int16_t source; 
    u_int16_t dest; 
    u_int16_t len; 
    u_int16_t check; 
}; 

¿Qué valor se almacena en el campo de comprobación de la cabecera? ¿Cómo verificar si la suma de comprobación es correcta? Quise decir en qué datos se computa la suma de comprobación? (¿Es solo el encabezado udp o el encabezado udp más la carga útil que lo sigue?)

Gracias.

Respuesta

27

La suma de comprobación UDP se realiza sobre toda la carga útil, y los demás campos en la cabecera, y algunos campos de la cabecera IP. Se construye un pseudo-encabezado a partir del encabezado IP para realizar el cálculo (que se realiza sobre este pseudo-encabezado, el encabezado UDP y la carga útil). La razón por la que se incluye el pseudo-encabezado es para atrapar paquetes que se han enrutado a la dirección IP incorrecta.

Básicamente, en el extremo de recepción, todas las palabras de 16 bits de los encabezados más el área de datos se suman (envuelve a 16 bits) y el resultado se compara con 0xffff.

En el lado del envío, es un poco más complejo. La suma de un complemento se realiza en todos los valores de 16 bits, luego el complemento de uno (es decir, invertir todos los bits) se toma de ese valor para poblar el campo de suma de comprobación (con la condición adicional de que una suma de comprobación calculada de cero se cambiará a todos uno-bits).

La suma de un complemento es no solo la suma de todos los valores de complemento uno. Es un poco más complejo.

Básicamente, tiene un acumulador de 16 bits en ejecución que comienza en cero y agrega cada valor de 16 bits a eso. Cada vez que una de esas adiciones genera un acarreo, el valor se ajusta y usted agrega uno al valor nuevamente. Esto efectivamente toma el bit de acarreo de la adición de 16 bits y lo agrega al valor.


Como acotación al margen, y esto es pura conjetura de mi parte, pero esto probablemente se podría hacer de manera eficiente mediante el uso de la ADC (añadidos con acarreo) de instrucciones en lugar de ADD (sorprendentemente, añadir), o cualesquiera instrucciones equivalentes estaban disponibles en su CPU en ese momento.

Si no hubiera ningún acarreo, ADC simplemente agregaría el bit cero del acarreo. En los días cuando esto estaba hecho (y sí, lamentablemente, yo soy ese viejo), la memoria era mucho más una limitación que la velocidad, no tanto el caso hoy en día, por lo que salvar algunos bytes en su código podría elevar que el nivel de semi-dios-emperador-de-la-universo :-)


Tenga en cuenta que usted nunca tuvo que preocuparse de llevar a la segunda vez (o un acarreo de dos con el siguiente ADC si está utilizando ese método mencionado en el párrafo anterior) ya que los dos valores más grandes de 16 bits, cuando se suman, producen (truncado desde 0x1fffe) 0xfffe - agregar uno a eso nunca causará otro acarreo.

Una vez calculada la suma del complemento de una calculada, tiene sus bits invertidos y se inserta en el paquete, esto hará que el cálculo en el extremo receptor produzca 0xffff, suponiendo que no haya errores en la transmisión, por supuesto.

Vale la pena señalar que la carga útil siempre está acolchada para garantizar que haya un número integral de palabras de 16 bits. Si tenía acolchado, el campo de longitud le indica la longitud real.

RFC768 es la especificación que detalla esto.

+0

Gracias por eso. Estaba un poco confundido acerca de la parte del Pseudo-Encabezado ... pero luego el RFC despejó el aire. – Deepak

+1

"Todas las palabras de 16 bits de los encabezados (donde la suma de comprobación UDP es cero) se agregan y el complemento de uno (es decir, invertir todos los bits) es lo que se pone en el campo de suma de comprobación". No, lo que dice el RFC llevaría a "Todos los complementos de uno (es decir, invertir todos los bits) de las palabras de 16 bits de los encabezados (donde la suma de control UDP es cero) se agregan y el complemento de eso es lo que se pone en el campo de suma de comprobación ". De lo contrario, respuesta perfecta +1. – Joren

+1

Esto no es correcto. "La suma de un complemento" no significa tomar el complemento de cada palabra y sumarlas. Significa que agrega las palabras juntas, y cuando se produce un bit de acarreo, agrega 1 a la suma en ejecución. Ver http://mathforum.org/library/drmath/view/54379.html. –

1

Un agradable y fácil de entender ejemplo de cálculo de suma de comprobación UDP se realiza por Gerd Hoffmann .

Puede Google de "net-checksum.c Gerd Hoffmann" o buscar en el archivo aquí:

https://gist.github.com/fxlv/81209bbd150abfeaceb1f85ff076c9f3

Puede utilizar la función net_checksum_tcpudp, alimentar la longitud de carga útil de UDP, proto, src y dst IPs y luego la carga útil UDP en sí misma y hará lo correcto.

Al final tiene que llamar al htons() en la suma de comprobación y está listo.

Cuestiones relacionadas