1 // vim: set et sw=4 sts=4 :
10 uint16 udp_port_remote;
14 /* para calcular checksum */
15 static uint16 checksum;
16 static byte byte_count;
17 static byte last_byte;
19 /* agrega un word al checksum calculado */
20 static void sum(uint16 w)
23 if (checksum < w) /* corrección de carry (hubo OV) */
27 bool udp_read_dgram_header()
31 netdev_read_start(UDP_HEADER_SIZE);
32 /* reseteamos checksum */
35 /* el UDP tiene un checksum que incluye parte de la cabecera IP */
37 sum(WORD(ip_addr_remote[0], ip_addr_remote[1]));
38 sum(WORD(ip_addr_remote[2], ip_addr_remote[3]));
40 sum(WORD(ip_addr_local[0], ip_addr_local[1]));
41 sum(WORD(ip_addr_local[2], ip_addr_local[3]));
42 /* protocolo expresado en 16 bits (0x11 es UDP) */
44 /* tamaño del paquete UDP (sin las cabeceras que son 20 bytes) */
45 sum(ip_packet_len - 20);
46 /* de ahora en más todos los datos del checksum corresponden a UDP */
47 /* puerto origen (remoto) */
48 udp_port_remote = netdev_read_word();
49 /* agregamos puerto de origen al checksum */
51 /* sólo aceptamos datagramas a nuestro puerto */
52 if (netdev_read_word() != udp_port_local)
53 ok = false; /* drop */
54 /* agregamos puerto de destino al checksum */
56 /* tamaño del datagrama */
57 if (tmp = netdev_read_byte()) /* no soportamos más de 255 bytes */
58 ok = false; /* drop */
59 udp_dgram_len = netdev_read_byte(); /* parte baja */
60 if (udp_dgram_len < 8) /* no puede ser más chico que sus cabeceras */
61 ok = false; /* drop */
62 /* agregamos tamaño al checksum */
63 sum(WORD(tmp, udp_dgram_len));
64 /* agregamos checksum al checksum */
65 sum(netdev_read_word());
66 /* falta agregar el cuerpo del mensaje para verificar la suma
67 * esto debe hacerlo el protocolo que sigue para poder seguir obteniendo
68 * los datos de la placa de red byte a byte */
76 if (byte_count % 2) // impar, tengo 2, sumo
78 b = netdev_read_byte();
79 sum(WORD(last_byte, b));
81 else // par, guardo para sumar cuando tenga 2
83 b = netdev_read_byte();
90 bool udp_checksum_ok()
92 // Verifico si falta sumar algo (UDP debe sumar de a un word)
93 if (byte_count == (udp_dgram_len - UDP_HEADER_SIZE))
94 sum(WORD(last_byte, 0x00)); // Relleno el byte que falta con 0x00
95 return !(uint16)~checksum;
98 void udp_write_dgram_header()
100 netdev_write_start(UDP_HEADER_SIZE);
101 /* reseteamos checksum */
104 /* el UDP tiene un checksum que incluye parte de la cabecera IP */
106 sum(WORD(ip_addr_remote[0], ip_addr_remote[1]));
107 sum(WORD(ip_addr_remote[2], ip_addr_remote[3]));
109 sum(WORD(ip_addr_local[0], ip_addr_local[1]));
110 sum(WORD(ip_addr_local[2], ip_addr_local[3]));
111 /* protocolo expresado en 16 bits (0x11 es UDP) */
113 /* tamaño del paquete UDP (IP sin las cabeceras, que son 20 bytes) */
114 sum(ip_packet_len - 20); // FIXME
116 netdev_write_word(udp_port_local);
119 netdev_write_word(udp_port_remote);
120 sum(udp_port_remote);
121 /* tamaño del datagrama */
122 netdev_write_byte(0x00); /* parte alta en 0 porque no soportamos más de 255 */
123 netdev_write_byte(udp_dgram_len);
124 sum(WORD(0x00, udp_dgram_len));
125 /* indicamos que no se usa checksum */
126 netdev_write_word(0x0000);
131 void udp_write_byte(byte b)
133 if (byte_count % 2) // impar, tengo 2, sumo
135 netdev_write_byte(b);
136 sum(WORD(last_byte, b));
138 else // par, guardo para sumar cuando tenga 2
140 netdev_write_byte(b);
146 void udp_write_checksum(byte offset)
148 // Verifico si falta sumar algo (UDP debe sumar de a un word)
149 if (byte_count == (udp_dgram_len - UDP_HEADER_SIZE))
150 sum(WORD(last_byte, 0x00)); // Relleno el byte que falta con 0x00
151 // Escribo checksum en el buffer de la placa de red
152 netdev_write_start_at(offset + 6, 2); // 6 bytes de offset hasta el checksum
153 netdev_write_word((uint16)~checksum); // Guardo checksum