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.
Gracias por eso. Estaba un poco confundido acerca de la parte del Pseudo-Encabezado ... pero luego el RFC despejó el aire. – Deepak
"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
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. –