/** Tamaño del frame */
byte netdev_len;
-/// Datos persistentes del módulo
-static union // Unión porque nunca se usan ambos juntos
+// Próximo frame a obtener
+static struct
{
- byte send_len; ///> Tamaño del frame que será enviado
- byte next_pkt; ///> Próximo frame a obtener
+ byte next_buf;
+ byte curr_buf;
+ byte curr_off;
}
-persistent;
-
-/// Estructura de la cabecera del buffer de la placa de red.
-struct buf_hdr_t
-{
- byte status; ///> Estado del frame recibido
- byte next; ///> Offset del próximo frame
- uint16 len; ///> Tamaño del frame
-};
+recv_state;
+/// Tamaño de la cabecera de los buffers de la placa de red
+#define BUF_HDR_SIZE 4
/// Cambia de página sin modificar los demás bits del CR
#define SELECT_REG_PAGE(page) \
}
-/** Comienza el envío de un nuevo frame
- * @param len Tamaño del frame a enviar
- */
+/** Comienza el envío de un nuevo frame */
void netdev_send_start()
{
- persistent.send_len = 0;
- // Wait until pending transmit operation completes.
- while(read_reg(CR) & TXP) continue;
-
// Set remote DMA start address registers to indicate where to load packet.
write_reg(RSAR0, 0u);
write_reg(RSAR1, TX_PAGE_START);
+}
+
+/** Finaliza el envío del frame
+ * @precond netdev_send_start() debe haber sido ejecutada
+ * @precond se copiaron datos al dispositivo para enviar
+ * @param len Cantidad de bytes a transmitir
+ */
+void netdev_send_end(byte len)
+{
+ // Set transmit page start to indicate packet start.
+ write_reg(TPSR, TX_PAGE_START);
+
+ // Ethernet packets must be > 60 bytes, otherwise are rejected as runts.
+ if (len < MIN_PACKET_LEN)
+ len = MIN_PACKET_LEN;
+
+ // Set transmit byte count registers to indicate packet length.
+ write_reg(TBCR0, len);
+ write_reg(TBCR1, 0u);
+
+ // Issue command for RTL8019AS to transmit packet from it's local buffer.
+ write_reg(CR, START | TXP);
+
+ // Wait until pending transmit operation completes.
+ while(read_reg(CR) & TXP) continue;
+}
+void netdev_write_start(byte len)
+{
// Set remote DMA byte count registers to indicate length of packet load.
- write_reg(RBCR0, MAX_PACKET_LEN); // Tamaño máximo en principio
+ write_reg(RBCR0, len); // Tamaño máximo en principio
write_reg(RBCR1, 0u);
// Initiate DMA transfer of uip_buf & uip_appdata buffers to RTL8019AS.
* @precond netdev_send_start() debe haber sido ejecutada
* @param b Byte a enviar
*/
-void netdev_send_byte(byte b)
+void netdev_write_byte(byte b)
{
- persistent.send_len++;
write_reg(RDMA, b);
}
* @precond netdev_send_start() debe haber sido ejecutada
* @param w Word a enviar
*/
-void netdev_send_word(uint16 w)
+void netdev_write_word(uint16 w)
{
- persistent.send_len += 2;
write_reg(RDMA, HIGH(w));
write_reg(RDMA, LOW(w));
}
-/** Finaliza el envío del frame
- * @precond netdev_send_start() debe haber sido ejecutada
- */
-void netdev_send_end()
+void netdev_write_end()
{
// Abort/ complete DMA operation.
ABORT_DMA(START);
-
- // Set transmit page start to indicate packet start.
- write_reg(TPSR, TX_PAGE_START);
-
- // Ethernet packets must be > 60 bytes, otherwise are rejected as runts.
- if (persistent.send_len < MIN_PACKET_LEN)
- {
- persistent.send_len = MIN_PACKET_LEN;
- }
-
- // Set transmit byte count registers to indicate packet length.
- write_reg(TBCR0, LOW(persistent.send_len));
- write_reg(TBCR1, 0u);
-
- // Issue command for RTL8019AS to transmit packet from it's local buffer.
- write_reg(CR, START | TXP);
}
/** Comienza la lectura de un nuevo frame
- * @precond netdev_recv_start() debe haber sido ejecutada
+ * @return Cantidad de bytes a recibir
*/
-void netdev_recv_start()
+byte netdev_recv_start()
{
- // Limpio tamaño del frame
- netdev_len = 0;
-
// Check if the rx buffer has overflowed.
if (read_reg(ISR) & OVW)
{
printb(read_reg(ISR), 0x01);
printb(read_reg(BNRY), 0x02);
printb(current, 0x04);
+ ledsb(0x00, 0x00);
reset();
}
- return;
+ return 0;
}
// Check if there is a packet in the rx buffer.
else if (read_reg(ISR) & PRX)
{
- struct buf_hdr_t buf_hdr;
+ byte status;
+ byte len;
byte current;
- byte bnry;
// Retrieve packet header. (status, next_ptr, length_l, length_h)
- // Set remote DMA start address registers to packet header.
- bnry = read_reg(BNRY) + 1;
- if (bnry >= RX_PAGE_STOP)
- bnry = RX_PAGE_START;
- write_reg(RSAR0, 0u);
- write_reg(RSAR1, bnry);
+ // Obtiene el buffer a leer actualmente
+ recv_state.curr_buf = read_reg(BNRY) + 1;
+ if (recv_state.curr_buf >= RX_PAGE_STOP)
+ recv_state.curr_buf = RX_PAGE_START;
// Select RTL8019AS register page 1.
SELECT_REG_PAGE(1);
SELECT_REG_PAGE(0);
// Check if last packet has been removed from rx buffer.
- if(bnry == current)
+ if(recv_state.curr_buf == current)
{
// Clear packet received interrupt flag.
write_reg(ISR, PRX | RXE);
- return;
+ return 0;
}
// Set remote DMA byte count registers to packet header length.
- write_reg(RBCR0, sizeof(struct buf_hdr_t));
- write_reg(RBCR1, 0x00);
-
- // Clear remote DMA complete interrupt status register bit.
- write_reg(ISR, RDC);
-
- // Initiate DMA transfer of packet header.
- write_reg(CR, READ);
+ recv_state.curr_off = 0;
+ netdev_read_start(BUF_HDR_SIZE);
// Packet status.
- buf_hdr.status = read_reg(RDMA);
+ status = netdev_read_byte();
// Save next packet pointer.
- buf_hdr.next = read_reg(RDMA);
-
- // Indicamos cual es el próximo paquete para cuando termine
- // FIXME poner más lindo para que consuma menos memoria
- persistent.next_pkt = buf_hdr.next - 1;
+ recv_state.next_buf = netdev_read_byte() - 1;
// Retrieve packet data length and subtract CRC bytes.
- buf_hdr.len = read_reg(RDMA) - sizeof(struct buf_hdr_t);
+ len = netdev_read_byte() - BUF_HDR_SIZE;
// Si es muy grande, muy chico o hubo error, lo descartamos
- if ((buf_hdr.len < MIN_PACKET_LEN) || (buf_hdr.len > MAX_PACKET_LEN)
- || ((buf_hdr.status & 0x0F) != RXSOK)
- || read_reg(RDMA)) // Parte alta del tamaño
+ if ((len < MIN_PACKET_LEN) || (len > MAX_PACKET_LEN)
+ || ((status & 0x0F) != RXSOK)
+ || netdev_read_byte()) // Parte alta del tamaño
{
// Terminamos DMA y pasamos al próximo frame
- ABORT_DMA(START);
- write_reg(BNRY, persistent.next_pkt);
- return;
+ netdev_read_end();
+ write_reg(BNRY, recv_state.next_buf);
+ return 0;
}
// Abort/ complete DMA operation.
- ABORT_DMA(START);
+ netdev_read_end();
- // Todo OK, empezamos a recibir así que ponemos bien el tamaño del frame
- netdev_len = buf_hdr.len;
+ return len;
+ }
- // Set remote DMA start address registers to packet data.
- write_reg(RSAR0, sizeof(struct buf_hdr_t));
- write_reg(RSAR1, bnry);
+ return 0;
+}
- // Set remote DMA byte count registers to packet data length.
- write_reg(RBCR0, buf_hdr.len);
- write_reg(RBCR1, 0u);
+/** Finaliza la recepción del frame
+ * @precond netdev_recv_start() debe haber sido ejecutada
+ */
+void netdev_recv_end()
+{
+ // Pasa el próximo frame
+ write_reg(BNRY, recv_state.next_buf);
+}
- // Initiate DMA transfer of packet data.
- write_reg(CR, READ);
- }
+void netdev_read_start(byte len)
+{
+ // Set remote DMA start address registers to packet data.
+ write_reg(RSAR0, recv_state.curr_off);
+ write_reg(RSAR1, recv_state.curr_buf);
+ recv_state.curr_off += len;
+
+ // Set remote DMA byte count registers to packet data length.
+ write_reg(RBCR0, len);
+ write_reg(RBCR1, 0);
+
+ // Initiate DMA transfer of packet data.
+ write_reg(CR, READ);
}
/** Lee un byte del buffer de la placa de red
* @precond netdev_recv_start() debe haber sido ejecutada
*/
-byte netdev_recv_byte()
+byte netdev_read_byte()
{
return read_reg(RDMA);
}
/** Lee un word del buffer de la placa de red
* @precond netdev_recv_start() debe haber sido ejecutada
*/
-uint16 netdev_recv_word()
+uint16 netdev_read_word()
{
- uint16 w = netdev_recv_byte() << 8;
- return w + netdev_recv_byte();
+ uint16 w = read_reg(RDMA) << 8;
+ return w + read_reg(RDMA);
}
/** Finaliza la lectura del frame
* @precond netdev_recv_start() debe haber sido ejecutada
*/
-void netdev_recv_end()
+void netdev_read_end()
{
- // Termina de leer bytes de padding (si hay)
- netdev_len += sizeof(struct buf_hdr_t);
- if (read_reg(CRDA0) < netdev_len)
- {
- netdev_len -= read_reg(CRDA0) - 1; // El puntero está adelantado en 1
- while (netdev_len--)
- {
- //printb(read_reg(CRDA0), netdev_len);
- netdev_recv_byte();
- }
- }
// Completa DMA
ABORT_DMA(START);
- // Pasa el próximo frame
- write_reg(BNRY, persistent.next_pkt);
}
sbit NICE = CTRL_PORT^2; // A7, usado para activar placa de red
#endif
-// Configuración de paǵinas de buffers
-#define TX_PAGE_START 0x40 // 0x4000 Tx buffer: 6 * 256 = 1536 bytes
-#define RX_PAGE_START 0x46 // 0x4600 Rx buffer: 26 * 256 = 6656 bytes
-#define RX_PAGE_STOP 0x60 // 0x6000
-
// Límites de tamaño de paquete
#define MIN_PACKET_LEN 60u // Mínimo permitido por 802.3
#define MAX_PACKET_LEN 128u // Mínimo permitido por nuestra escasa memoria =)
+// Configuración de paǵinas de buffers
+#define TX_PAGE_START 0x40 // 0x4000 Tx buffer: 256 bytes (usamos 128)
+#define RX_PAGE_START 0x46 // 0x4600 Rx buffer: 31 * 256 = 7936 bytes
+#define RX_PAGE_STOP 0x60 // 0x6000
+
// Register base address
#define REG_BASE 0x0000 // Hardwired to 0x0300
{
/* variable para iterar */
byte i;
+ netdev_read_start(ETH_HEADER_SIZE);
/* descarto MAC de destino, acepto broadcasts */
for (i = 0; i < ETH_ADDR_SIZE; ++i)
- netdev_recv_byte();
+ netdev_read_byte();
/* obtenemos MAC de origen */
for (i = 0; i < ETH_ADDR_SIZE; ++i)
- eth_addr_remote[i] = netdev_recv_byte();
+ eth_addr_remote[i] = netdev_read_byte();
/* obtenemos tipo de protocolo transportado por el frame, (sólo
* aceptamos IP y ARP) */
- switch (netdev_recv_word())
+ switch (netdev_read_word())
{
case IP:
eth_proto = ETH_IP;
eth_proto = ETH_ARP;
break;
default:
+ netdev_read_end();
return false; /* drop */
}
+ netdev_read_end();
return true;
}
{
/* variable para iterar */
byte i;
+ netdev_write_start(ETH_HEADER_SIZE);
/* mandamos como MAC de destino la remota */
for (i = 0; i < ETH_ADDR_SIZE; ++i)
- netdev_send_byte(eth_addr_remote[i]);
+ netdev_write_byte(eth_addr_remote[i]);
/* y como fuente la nuestra */
for (i = 0; i < ETH_ADDR_SIZE; ++i)
- netdev_send_byte(eth_addr_local[i]);
+ netdev_write_byte(eth_addr_local[i]);
/* escribimos el tipo de paquete que transporta el frame */
- netdev_send_word((eth_proto == ETH_IP) ? IP : ARP);
+ netdev_write_word((eth_proto == ETH_IP) ? IP : ARP);
+ netdev_write_end();
}
/** Tamaño de dirección MAC (en bytes) */
#define ETH_ADDR_SIZE 6
+/** Tamaño de cabecera ethernet */
+#define ETH_HEADER_SIZE 14
+
/** Tipos de frame ethernet */
typedef enum { ETH_IP, ETH_ARP } eth_proto_t;
// vim: set et sw=4 sts=4 :
#include "netdev.h"
+#include "debug.h"
#include "ip.h"
/** protocolos soportados */
{
/* variables utilitarias (iterar y/o buffer) */
byte h, l;
+ bit ok = true;
+ netdev_read_start(IP_HEADER_SIZE);
/* reseteamos checksum */
checksum = 0;
/* versión y tamaño de cabecera vienen en el 1er byte */
- h = netdev_recv_byte();
+ h = netdev_read_byte();
/* sólo soportamos versión 4 */
if ((h >> 4) != 4)
- return false; /* drop */
+ ok = false;
/* tamaño de cabecera */
if ((h & 0x0F) != 5) /* no aceptamos opciones raras =) */
- return false; /* drop */
+ ok = false;
/* ignoramos el TOS y vamos calculando checksum */
- sum(WORD(h, netdev_recv_byte()));
+ sum(WORD(h, netdev_read_byte()));
/* obtenemos tamaño del paquete */
- if (h = netdev_recv_byte()) /* tiene más de 255 bytes (no lo soportamos) */
- return false; /* drop */
- ip_packet_len = netdev_recv_byte(); /* hasta 255 bytes tienen los nuestros */
+ if (h = netdev_read_byte()) /* tiene más de 255 bytes (no lo soportamos) */
+ ok = false;
+ ip_packet_len = netdev_read_byte(); /* hasta 255 bytes tienen los nuestros */
/* vamos calculando checksum */
sum(WORD(h, ip_packet_len));
/* ignoramos identificación (2 bytes) y vamos calculando checksum */
- sum(netdev_recv_word());
+ sum(netdev_read_word());
/* si tiene prendido el bit de MF (More Fragments, bit 5 del byte, bit 2
* de los flags de la cabecera) o si tiene un offset de fragmento (bits
* del 4 al 0 y todos los bits del byte siguiente), dropeamos (no
* soportamos fragmentación) */
- h = netdev_recv_byte();
- l = netdev_recv_byte();
+ h = netdev_read_byte();
+ l = netdev_read_byte();
if ((h & 0x3F) || l)
- return false; /* drop */
+ ok = false;
/* seguimos calculando checksum */
sum(WORD(h, l));
/* no le damos bola al TTL (no le vamos a hacer lío si ya llegó hasta
* acá el pobre =) */
- h = netdev_recv_byte();
+ h = netdev_read_byte();
/* protocolo (sólo soportamos UDP e ICMP) */
- l = netdev_recv_byte();
+ l = netdev_read_byte();
switch (l)
{
case ICMP:
ip_proto = IP_UDP;
break;
default:
- return false; /* drop */
+ ok = false;
}
/* sigo calculando checksum */
sum(WORD(h, l));
/* obtenemos checksum y seguimos el cálculo */
- sum(netdev_recv_word());
+ sum(netdev_read_word());
/* obtenemos IP de origen (mientras seguimos calculando el checksum) */
for (l = 0; l < IP_ADDR_SIZE; ++l)
{
- ip_addr_remote[l] = netdev_recv_byte();
+ ip_addr_remote[l] = netdev_read_byte();
if (l % 2)
sum(WORD(h, ip_addr_remote[l]));
else
// TODO si soportamos DHCP hay que aceptar broadcasts!
for (l = 0; l < IP_ADDR_SIZE; ++l)
{
- if (ip_addr_local[l] != netdev_recv_byte())
- return false; /* drop (no es para nosotros) */
+ if (ip_addr_local[l] != netdev_read_byte())
+ ok = false;
if (l % 2)
sum(WORD(h, ip_addr_local[l]));
else
}
/* verificamos checksum */
if ((uint16)~checksum)
- return false; /* checksum malo, drop */
- return true;
+ ok = false;
+ netdev_read_end();
+ return ok;
}
void ip_write_packet_header()
static uint16 id;
/* reseteamos checksum */
checksum = 0;
+ netdev_write_start(IP_HEADER_SIZE);
/* versión (4) y tamaño de cabecera (5 words de 4 bytes = 20 bytes) */
- netdev_send_byte(h = 0x45);
+ netdev_write_byte(h = 0x45);
/* TOS (0xc0 = Internetwork Control, 0x00 = normal) */
l = (ip_proto == IP_ICMP) ? 0xc0 : 0x00;
- netdev_send_byte(l);
+ netdev_write_byte(l);
sum(WORD(h, l)); /* actualizamos checksum */
/* escribimos tamaño del paquete */
- netdev_send_byte(h = 0x00); /* nunca vamos a mandar algo de más de 255 bytes */
- netdev_send_byte(ip_packet_len);
+ netdev_write_byte(h = 0x00); /* nunca vamos a mandar algo de más de 255 bytes */
+ netdev_write_byte(ip_packet_len);
sum(WORD(h, ip_packet_len)); /* actualizamos checksum */
/* identificación (sirve para reensamblar paquetes) */
- netdev_send_word(id);
+ netdev_write_word(++id);
sum(id); /* actualizamos checksum */
/* pedimos que no se fragmente */
- netdev_send_byte(h = 0x40); /* Don't Fragment (DF) = 1 */
- netdev_send_byte(l = 0x00); /* offset de fragmento = 0 */
+ netdev_write_byte(h = 0x40); /* Don't Fragment (DF) = 1 */
+ netdev_write_byte(l = 0x00); /* offset de fragmento = 0 */
sum(WORD(h, l)); /* actualizamos checksum */
/* TTL de 64 saltos porque está de moda */
- netdev_send_byte(h = 0x40);
+ netdev_write_byte(h = 0x40);
/* protocolo (sólo soportamos UDP e ICMP) */
l = (ip_proto == IP_ICMP) ? ICMP : UDP;
- netdev_send_byte(l);
+ netdev_write_byte(l);
sum(WORD(h, l)); /* actualizamos checksum */
/* checksum: antes de poder escribir el checksum hay que terminar de
* calcularlo según las direcciones IP de origen y destino, así que eso
else
h = ip_addr_remote[l];
/* ahora sí grabamos el checksum */
- netdev_send_word(~checksum);
+ netdev_write_word(~checksum);
/* ahora sí, continuamos poniendo las direcciones */
/* ponemos como dirección IP de origen la nuestra */
for (l = 0; l < IP_ADDR_SIZE; ++l)
- netdev_send_byte(ip_addr_local[l]);
+ netdev_write_byte(ip_addr_local[l]);
/* IP de destino, la remota */
for (l = 0; l < IP_ADDR_SIZE; ++l)
- netdev_send_byte(ip_addr_remote[l]);
+ netdev_write_byte(ip_addr_remote[l]);
+ netdev_write_end();
}
/** Tamaño de dirección IP (en bytes) */
#define IP_ADDR_SIZE 4
+/** Tamaño de cabecera IP (en bytes) */
+#define IP_HEADER_SIZE 20
+
/** Tipos de paquete IP */
typedef enum { IP_UDP, IP_ICMP } ip_proto_t;
ip_addr_local[3] = 100;
// Inicializo puerto UDP
- udp_port_local = 9000;
+ udp_port_local = 9876;
while (1) // Forever
{
- byte i;
- netdev_recv_start();
- printb(netdev_len, 0x1);
- if (!netdev_len) // no recibimos nada (válido)
+ byte buf[64]; //XXX
+ byte i; //XXX
+
+ if (!netdev_recv_start()) // no recibimos nada (válido)
continue; // Probamos de nuevo
// Tenemos algo!
// Vemos que protocolo transporta
switch (eth_proto)
{
- case ETH_ARP: // FIXME, implementar ARP!
+ case ETH_ARP: // TODO: implementar ARP!
goto drop; // Tiramos el paquete
case ETH_IP:
// Vemos que protocolo transporta
switch (ip_proto)
{
- case IP_ICMP: // FIXME, implementar ICMP!
+ case IP_ICMP: // TODO: implementar ICMP!
goto drop; // Tiramos el paquete
case IP_UDP:
if (!udp_read_dgram_header()) // No es un buen header
goto drop; // Tiramos el paquete
- printb(udp_dgram_len, 0x40);
+ //printb(udp_dgram_len, 0x40);
+ // TODO
// Nuestro protocolo, por ahora un simple echo!
- for (i = 8; i < udp_dgram_len; ++i) // 8 por la cabecera UDP
- {
- printb(netdev_recv_byte(), 0x00);
- }
-drop:
+ netdev_read_start(udp_dgram_len-UDP_HEADER_SIZE);
+ for (i = 0; i < udp_dgram_len-UDP_HEADER_SIZE; ++i)
+ buf[i] = netdev_read_byte();
+ netdev_read_end();
netdev_recv_end();
+
+ // Respuesta
+ netdev_send_start();
+ eth_write_frame_header();
+ ip_write_packet_header();
+ udp_write_dgram_header();
+ netdev_write_start(udp_dgram_len-UDP_HEADER_SIZE);
+ for (i = 0; i < udp_dgram_len-UDP_HEADER_SIZE; ++i)
+ netdev_write_byte(buf[i]);
+ netdev_write_end();
+ netdev_send_end(ETH_HEADER_SIZE+IP_HEADER_SIZE+udp_dgram_len);
}
}
+ continue;
+drop:
+ netdev_recv_end();
}
}
*/
bool netdev_init();
-/** Comienza el envío de un nuevo frame
- * @param len Tamaño del frame a enviar
- */
+/** Comienza el envío de un nuevo frame */
void netdev_send_start();
-/** Escribe un byte al buffer de la placa de red para ser enviado
+/** Finaliza el envío del frame
* @precond netdev_send_start() debe haber sido ejecutada
+ * @precond se copiaron datos al dispositivo para enviar
+ * @param len Cantidad de bytes a transmitir
+ */
+void netdev_send_end(byte len);
+
+/** Comienza una transferencia al dispositivo de red
+ * @param len Cantidad de bytes a escribir
+ */
+void netdev_write_start(byte len);
+
+/** Escribe un byte al buffer de la placa de red para ser enviado
+ * @precond netdev_write_start() debe haber sido ejecutada
* @param b Byte a enviar
*/
-void netdev_send_byte(byte b);
+void netdev_write_byte(byte b);
/** Escribe un word al buffer de la placa de red para ser enviado
- * @precond netdev_send_start() debe haber sido ejecutada
+ * @precond netdev_write_start() debe haber sido ejecutada
* @param w Word a enviar
*/
-void netdev_send_word(uint16 w);
+void netdev_write_word(uint16 w);
-/** Finaliza el envío del frame
- * @precond netdev_send_start() debe haber sido ejecutada
+/** Finaliza una transferencia al dispositivo de red
+ * @precond netdev_write_start() fue llamada y se ecribió la cantidad de bytes
+ * en ella especificada
*/
-void netdev_send_end();
+void netdev_write_end();
-/** Comienza la lectura de un nuevo frame
- * @postcond Deja en netdev_len el tamaño del frame recibido
+/** Comienza la recepción de un nuevo frame
+ * @return Cantidad de bytes a recibir
*/
-void netdev_recv_start();
+byte netdev_recv_start();
+
+/** Finaliza la lectura del frame
+ * @precond netdev_recv_start() debe haber sido ejecutada
+ */
+void netdev_recv_end();
+
+/** Comienza a leer bytes del dispositivo de red
+ * @param len Cantidad de bytes a leer
+ */
+void netdev_read_start(byte len);
/** Lee un byte del buffer de la placa de red
* @precond netdev_recv_start() debe haber sido ejecutada
*/
-byte netdev_recv_byte();
+byte netdev_read_byte();
/** Lee un word del buffer de la placa de red
* @precond netdev_recv_start() debe haber sido ejecutada
*/
-uint16 netdev_recv_word();
+uint16 netdev_read_word();
/** Finaliza la lectura del frame
* @precond netdev_recv_start() debe haber sido ejecutada
*/
-void netdev_recv_end();
+void netdev_read_end();
#endif // _NETDEV_H_
bool udp_read_dgram_header()
{
byte tmp;
+ bit ok = true;
+ netdev_read_start(UDP_HEADER_SIZE);
/* reseteamos checksum */
checksum = 0;
/* el UDP tiene un checksum que incluye parte de la cabecera IP */
sum(ip_packet_len - 20);
/* de ahora en más todos los datos del checksum corresponden a UDP */
/* puerto origen (remoto) */
- udp_port_remote = netdev_recv_word();
+ udp_port_remote = netdev_read_word();
/* agregamos puerto de origen al checksum */
sum(udp_port_remote);
/* sólo aceptamos datagramas a nuestro puerto */
- if (netdev_recv_word() != udp_port_local)
- return false; /* drop */
+ if (netdev_read_word() != udp_port_local)
+ ok = false; /* drop */
/* agregamos puerto de destino al checksum */
sum(udp_port_local);
/* tamaño del datagrama */
- if (tmp = netdev_recv_byte()) /* no soportamos más de 255 bytes */
- return false; /* drop */
- udp_dgram_len = netdev_recv_byte(); /* parte baja */
+ if (tmp = netdev_read_byte()) /* no soportamos más de 255 bytes */
+ ok = false; /* drop */
+ udp_dgram_len = netdev_read_byte(); /* parte baja */
if (udp_dgram_len < 8) /* no puede ser más chico que sus cabeceras */
- return false; /* drop */
+ ok = false; /* drop */
/* agregamos tamaño al checksum */
sum(WORD(tmp, udp_dgram_len));
/* agregamos checksum al checksum */
- sum(netdev_recv_word());
+ sum(netdev_read_word());
/* falta agregar el cuerpo del mensaje para verificar la suma
* esto debe hacerlo el protocolo que sigue para poder seguir obteniendo
* los datos de la placa de red byte a byte */
+ netdev_read_end();
return true;
}
uint16 udp_read_word()
{
- uint16 w = netdev_recv_word();
+ uint16 w = netdev_read_word();
sum(w);
return w;
}
void udp_write_dgram_header()
{
+ netdev_write_start(UDP_HEADER_SIZE);
/* reseteamos checksum */
checksum = 0;
/* el UDP tiene un checksum que incluye parte de la cabecera IP */
/* tamaño del paquete UDP (IP sin las cabeceras, que son 20 bytes) */
sum(ip_packet_len - 20); // FIXME
/* puerto origen */
- netdev_send_word(udp_port_local);
+ netdev_write_word(udp_port_local);
sum(udp_port_local);
/* puerto destino */
- netdev_send_word(udp_port_remote);
+ netdev_write_word(udp_port_remote);
sum(udp_port_remote);
/* tamaño del datagrama */
- netdev_send_byte(0x00); /* parte alta en 0 porque no soportamos más de 255 */
- netdev_send_byte(udp_dgram_len);
+ netdev_write_byte(0x00); /* parte alta en 0 porque no soportamos más de 255 */
+ netdev_write_byte(udp_dgram_len);
sum(WORD(0x00, udp_dgram_len));
/* indicamos que no se usa checksum */
- netdev_send_word(0x0000);
+ netdev_write_word(0x0000);
sum(0x0000);
+ netdev_write_end();
}
void udp_write_word(uint16 w)
{
sum(w);
- netdev_send_word(w);
+ netdev_write_word(w);
}
void udp_write_checksum()
* </pre>
*/
+/** Tamaño de la cabecera UDP */
+#define UDP_HEADER_SIZE 8
+
/** Puerto UDP nuestro */
extern uint16 udp_port_local;