]> git.llucax.com Git - z.facultad/66.09/etherled.git/blob - pruebas/c/checksum.c
Adapto ejemplo básico que andaba a SDCC y funciona correctamente.
[z.facultad/66.09/etherled.git] / pruebas / c / checksum.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4
5 typedef unsigned char  u8;
6 typedef unsigned short u16;
7
8 /**
9  * Función para calcular checksum.
10  *
11  * Para verificar un checksum, hay que poner los datos con checksum incluído y
12  * la suma final debe dar 0.
13  *
14  * Al aplicar el checksum al paquete IP, hay que hacerlo a TODA la cabecera,
15  * incluyendo el src y dst y el checksum mismo (se toma todo 0 al checksum a la
16  * hora de calcularlo).
17  *
18  * @param buf array con palabritas de 16 bits.
19  * @param len tamaño del array (en cantidad de elementos).
20  */
21 u16 chksum(u16* buf, u8 len)
22 {
23         u16 sum = 0;
24         u8 i = -1;
25         while (++i < len)
26         {
27                 /* suma de complemento a 1 */
28                 sum += buf[i];
29                 if (sum < buf[i]) ++sum; /* corrección de carry (hubo OV) */
30         }
31         return ~sum;
32 }
33
34 /**
35  * Función para convertir un string en un array de palabras de 16 bits.
36  */
37 u8 strtou16(char* buf, u8 len, u16* ret)
38 {
39         u8 i;
40         for (i = 0; i < len; i += 4)
41         {
42                 char tmp[5] = { buf[i], buf[i+1], buf[i+2], buf[i+3], '\0' };
43                 ret[i/4] = strtoul(tmp, NULL, 16);
44         }
45         return len/4;
46 }
47
48 int main(int argc, char* argv[])
49 {
50         u16 buf[256];
51         u8 len;
52         if (argc < 2)
53         {
54                 fprintf(stderr, "Uso: %s string_hexa_con_tamaño_multiplo_de_4\n", argv[0]);
55                 return 1;
56         }
57         len = strtou16(argv[1], strlen(argv[1]), buf);
58         printf("%hX\n", chksum(buf, len));
59         return 0;
60 }
61