merged fixes from 0.8.6.1 (errornous skip of FPGA load)
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
#include "bas_printf.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define DBG_FECBD
|
||||
//#define DBG_FECBD
|
||||
#ifdef DBG_FECBD
|
||||
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
|
||||
#else
|
||||
@@ -62,94 +62,94 @@ static int iRxbd;
|
||||
*/
|
||||
void fecbd_init(uint8_t ch)
|
||||
{
|
||||
NBUF *nbuf;
|
||||
int i;
|
||||
NBUF *nbuf;
|
||||
int i;
|
||||
|
||||
dbg("\r\n");
|
||||
|
||||
/*
|
||||
* Align Buffer Descriptors to 4-byte boundary
|
||||
*/
|
||||
RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC);
|
||||
TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD));
|
||||
/*
|
||||
* Align Buffer Descriptors to 4-byte boundary
|
||||
*/
|
||||
RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC);
|
||||
TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD));
|
||||
|
||||
dbg("initialise RX buffer descriptor ring\r\n");
|
||||
|
||||
/*
|
||||
* Initialize the Rx Buffer Descriptor ring
|
||||
*/
|
||||
for (i = 0; i < NRXBD; ++i)
|
||||
{
|
||||
/* Grab a network buffer from the free list */
|
||||
nbuf = nbuf_alloc();
|
||||
if (nbuf == NULL)
|
||||
{
|
||||
/*
|
||||
* Initialize the Rx Buffer Descriptor ring
|
||||
*/
|
||||
for (i = 0; i < NRXBD; ++i)
|
||||
{
|
||||
/* Grab a network buffer from the free list */
|
||||
nbuf = nbuf_alloc();
|
||||
if (nbuf == NULL)
|
||||
{
|
||||
dbg("could not allocate network buffer\r\n");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize the BD */
|
||||
RxBD(ch,i).status = RX_BD_E | RX_BD_INTERRUPT;
|
||||
RxBD(ch,i).length = RX_BUF_SZ;
|
||||
RxBD(ch,i).data = nbuf->data;
|
||||
/* Initialize the BD */
|
||||
RxBD(ch,i).status = RX_BD_E | RX_BD_INTERRUPT;
|
||||
RxBD(ch,i).length = RX_BUF_SZ;
|
||||
RxBD(ch,i).data = nbuf->data;
|
||||
|
||||
/* Add the network buffer to the Rx queue */
|
||||
nbuf_add(NBUF_RX_RING, nbuf);
|
||||
}
|
||||
/* Add the network buffer to the Rx queue */
|
||||
nbuf_add(NBUF_RX_RING, nbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the WRAP bit on the last one
|
||||
*/
|
||||
RxBD(ch, i - 1).status |= RX_BD_W;
|
||||
/*
|
||||
* Set the WRAP bit on the last one
|
||||
*/
|
||||
RxBD(ch, i - 1).status |= RX_BD_W;
|
||||
|
||||
dbg("initialise TX buffer descriptor ring\r\n");
|
||||
|
||||
/*
|
||||
* Initialize the Tx Buffer Descriptor ring
|
||||
*/
|
||||
for (i = 0; i < NTXBD; ++i)
|
||||
{
|
||||
TxBD(ch, i).status = TX_BD_INTERRUPT;
|
||||
TxBD(ch, i).length = 0;
|
||||
TxBD(ch, i).data = NULL;
|
||||
}
|
||||
/*
|
||||
* Initialize the Tx Buffer Descriptor ring
|
||||
*/
|
||||
for (i = 0; i < NTXBD; ++i)
|
||||
{
|
||||
TxBD(ch, i).status = TX_BD_INTERRUPT;
|
||||
TxBD(ch, i).length = 0;
|
||||
TxBD(ch, i).data = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the WRAP bit on the last one
|
||||
*/
|
||||
TxBD(ch, i - 1).status |= TX_BD_W;
|
||||
/*
|
||||
* Set the WRAP bit on the last one
|
||||
*/
|
||||
TxBD(ch, i - 1).status |= TX_BD_W;
|
||||
|
||||
/*
|
||||
* Initialize the buffer descriptor indexes
|
||||
*/
|
||||
iTxbd_new = iTxbd_old = iRxbd = 0;
|
||||
/*
|
||||
* Initialize the buffer descriptor indexes
|
||||
*/
|
||||
iTxbd_new = iTxbd_old = iRxbd = 0;
|
||||
}
|
||||
|
||||
void fecbd_dump(uint8_t ch)
|
||||
{
|
||||
#ifdef DBG_FECBD
|
||||
int i;
|
||||
int i;
|
||||
|
||||
xprintf("\n------------ FEC%d BDs -----------\n",ch);
|
||||
xprintf("RxBD Ring\n");
|
||||
for (i = 0; i < NRXBD; i++)
|
||||
{
|
||||
xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
|
||||
i, &RxBD(ch, i),
|
||||
RxBD(ch, i).status,
|
||||
RxBD(ch, i).length,
|
||||
RxBD(ch, i).data);
|
||||
}
|
||||
xprintf("TxBD Ring\n");
|
||||
for (i = 0; i < NTXBD; i++)
|
||||
{
|
||||
xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
|
||||
i, &TxBD(ch, i),
|
||||
TxBD(ch, i).status,
|
||||
TxBD(ch, i).length,
|
||||
TxBD(ch, i).data);
|
||||
}
|
||||
xprintf("--------------------------------\n\n");
|
||||
xprintf("\n------------ FEC%d BDs -----------\n",ch);
|
||||
xprintf("RxBD Ring\n");
|
||||
for (i = 0; i < NRXBD; i++)
|
||||
{
|
||||
xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
|
||||
i, &RxBD(ch, i),
|
||||
RxBD(ch, i).status,
|
||||
RxBD(ch, i).length,
|
||||
RxBD(ch, i).data);
|
||||
}
|
||||
xprintf("TxBD Ring\n");
|
||||
for (i = 0; i < NTXBD; i++)
|
||||
{
|
||||
xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
|
||||
i, &TxBD(ch, i),
|
||||
TxBD(ch, i).status,
|
||||
TxBD(ch, i).length,
|
||||
TxBD(ch, i).data);
|
||||
}
|
||||
xprintf("--------------------------------\n\n");
|
||||
#endif /* DBG_FECBD */
|
||||
}
|
||||
|
||||
@@ -165,28 +165,28 @@ void fecbd_dump(uint8_t ch)
|
||||
*/
|
||||
uint32_t fecbd_get_start(uint8_t ch, uint8_t direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case Rx:
|
||||
return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD));
|
||||
case Tx:
|
||||
default:
|
||||
return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD));
|
||||
}
|
||||
switch (direction)
|
||||
{
|
||||
case Rx:
|
||||
return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD));
|
||||
case Tx:
|
||||
default:
|
||||
return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD));
|
||||
}
|
||||
}
|
||||
|
||||
FECBD *fecbd_rx_alloc(uint8_t ch)
|
||||
{
|
||||
int i = iRxbd;
|
||||
int i = iRxbd;
|
||||
|
||||
/* Check to see if the ring of BDs is full */
|
||||
if (RxBD(ch, i).status & RX_BD_E)
|
||||
return NULL;
|
||||
/* Check to see if the ring of BDs is full */
|
||||
if (RxBD(ch, i).status & RX_BD_E)
|
||||
return NULL;
|
||||
|
||||
/* Increment the circular index */
|
||||
iRxbd = (uint8_t)((iRxbd + 1) % NRXBD);
|
||||
/* Increment the circular index */
|
||||
iRxbd = (uint8_t)((iRxbd + 1) % NRXBD);
|
||||
|
||||
return &RxBD(ch, i);
|
||||
return &RxBD(ch, i);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -201,16 +201,16 @@ FECBD *fecbd_rx_alloc(uint8_t ch)
|
||||
*/
|
||||
FECBD *fecbd_tx_alloc(uint8_t ch)
|
||||
{
|
||||
int i = iTxbd_new;
|
||||
int i = iTxbd_new;
|
||||
|
||||
/* Check to see if the ring of BDs is full */
|
||||
if (TxBD(ch, i).status & TX_BD_R)
|
||||
return NULL;
|
||||
/* Check to see if the ring of BDs is full */
|
||||
if (TxBD(ch, i).status & TX_BD_R)
|
||||
return NULL;
|
||||
|
||||
/* Increment the circular index */
|
||||
iTxbd_new = (uint8_t)((iTxbd_new + 1) % NTXBD);
|
||||
/* Increment the circular index */
|
||||
iTxbd_new = (uint8_t)((iTxbd_new + 1) % NTXBD);
|
||||
|
||||
return &TxBD(ch, i);
|
||||
return &TxBD(ch, i);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -226,14 +226,14 @@ FECBD *fecbd_tx_alloc(uint8_t ch)
|
||||
*/
|
||||
FECBD *fecbd_tx_free(uint8_t ch)
|
||||
{
|
||||
int i = iTxbd_old;
|
||||
int i = iTxbd_old;
|
||||
|
||||
/* Check to see if the ring of BDs is empty */
|
||||
if ((TxBD(ch, i).data == NULL) || (TxBD(ch, i).status & TX_BD_R))
|
||||
return NULL;
|
||||
/* Check to see if the ring of BDs is empty */
|
||||
if ((TxBD(ch, i).data == NULL) || (TxBD(ch, i).status & TX_BD_R))
|
||||
return NULL;
|
||||
|
||||
/* Increment the circular index */
|
||||
iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD);
|
||||
/* Increment the circular index */
|
||||
iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD);
|
||||
|
||||
return &TxBD(ch, i);
|
||||
return &TxBD(ch, i);
|
||||
}
|
||||
|
||||
451
BaS_gcc/net/ip.c
451
BaS_gcc/net/ip.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* File: ip.c
|
||||
* File: ip.c
|
||||
* Purpose: Internet Protcol device driver
|
||||
*
|
||||
* Notes:
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "bas_string.h"
|
||||
|
||||
|
||||
#define IP_DEBUG
|
||||
//#define IP_DEBUG
|
||||
#if defined(IP_DEBUG)
|
||||
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
|
||||
#else
|
||||
@@ -21,300 +21,297 @@
|
||||
|
||||
void ip_init(IP_INFO *info, IP_ADDR_P myip, IP_ADDR_P gateway, IP_ADDR_P netmask)
|
||||
{
|
||||
int index;
|
||||
int index;
|
||||
|
||||
for (index = 0; index < sizeof(IP_ADDR); index++)
|
||||
{
|
||||
info->myip[index] = myip[index];
|
||||
info->gateway[index] = gateway[index];
|
||||
info->netmask[index] = netmask[index];
|
||||
info->broadcast[index] = 0xFF;
|
||||
}
|
||||
for (index = 0; index < sizeof(IP_ADDR); index++)
|
||||
{
|
||||
info->myip[index] = myip[index];
|
||||
info->gateway[index] = gateway[index];
|
||||
info->netmask[index] = netmask[index];
|
||||
info->broadcast[index] = 0xFF;
|
||||
}
|
||||
|
||||
info->rx = 0;
|
||||
info->rx_unsup = 0;
|
||||
info->tx = 0;
|
||||
info->err = 0;
|
||||
info->rx = 0;
|
||||
info->rx_unsup = 0;
|
||||
info->tx = 0;
|
||||
info->err = 0;
|
||||
}
|
||||
|
||||
uint8_t *ip_get_myip(IP_INFO *info)
|
||||
{
|
||||
if (info != 0)
|
||||
{
|
||||
return (uint8_t *) &info->myip[0];
|
||||
}
|
||||
dbg("info is NULL!\n\t");
|
||||
return 0;
|
||||
if (info != 0)
|
||||
{
|
||||
return (uint8_t *) &info->myip[0];
|
||||
}
|
||||
dbg("info is NULL!\n\t");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ip_addr_compare(IP_ADDR_P addr1, IP_ADDR_P addr2)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||
{
|
||||
if (addr1[i] != addr2[i])
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||
{
|
||||
if (addr1[i] != addr2[i])
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t *ip_resolve_route(NIF *nif, IP_ADDR_P destip)
|
||||
{
|
||||
/*
|
||||
* This function determines whether or not an outgoing IP
|
||||
* packet needs to be transmitted on the local net or sent
|
||||
* to the router for transmission.
|
||||
*/
|
||||
IP_INFO *info;
|
||||
IP_ADDR mask, result;
|
||||
IP_ADDR bc = { 255, 255, 255, 255 };
|
||||
int i;
|
||||
/*
|
||||
* This function determines whether or not an outgoing IP
|
||||
* packet needs to be transmitted on the local net or sent
|
||||
* to the router for transmission.
|
||||
*/
|
||||
IP_INFO *info;
|
||||
IP_ADDR mask, result;
|
||||
IP_ADDR bc = { 255, 255, 255, 255 };
|
||||
int i;
|
||||
|
||||
info = nif_get_protocol_info(nif, ETH_FRM_IP);
|
||||
info = nif_get_protocol_info(nif, ETH_FRM_IP);
|
||||
|
||||
if (memcmp(destip, bc, 4) == 0)
|
||||
{
|
||||
dbg("destip is broadcast address, no gateway needed\r\n");
|
||||
return destip;
|
||||
}
|
||||
if (memcmp(destip, bc, 4) == 0)
|
||||
{
|
||||
dbg("destip is broadcast address, no gateway needed\r\n");
|
||||
return destip;
|
||||
}
|
||||
|
||||
/* create mask for local IP */
|
||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||
{
|
||||
mask[i] = info->myip[i] & info->netmask[i];
|
||||
}
|
||||
/* create mask for local IP */
|
||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||
{
|
||||
mask[i] = info->myip[i] & info->netmask[i];
|
||||
}
|
||||
|
||||
/* apply mask to the destination IP */
|
||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||
{
|
||||
result[i] = mask[i] & destip[i];
|
||||
}
|
||||
/* apply mask to the destination IP */
|
||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||
{
|
||||
result[i] = mask[i] & destip[i];
|
||||
}
|
||||
|
||||
/* See if destination IP is local or not */
|
||||
if (ip_addr_compare(mask, result))
|
||||
{
|
||||
/* The destination IP is on the local net */
|
||||
return arp_resolve(nif, ETH_FRM_IP, destip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The destination IP is not on the local net */
|
||||
return arp_resolve(nif, ETH_FRM_IP, info->gateway);
|
||||
}
|
||||
/* See if destination IP is local or not */
|
||||
if (ip_addr_compare(mask, result))
|
||||
{
|
||||
/* The destination IP is on the local net */
|
||||
return arp_resolve(nif, ETH_FRM_IP, destip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The destination IP is not on the local net */
|
||||
return arp_resolve(nif, ETH_FRM_IP, info->gateway);
|
||||
}
|
||||
}
|
||||
|
||||
int ip_send(NIF *nif, uint8_t *dest, uint8_t *src, uint8_t protocol, NBUF *pNbuf)
|
||||
{
|
||||
/*
|
||||
* This function assembles an IP datagram and passes it
|
||||
* onto the hardware to be sent over the network.
|
||||
*/
|
||||
uint8_t *route;
|
||||
ip_frame_hdr *ipframe;
|
||||
/*
|
||||
* This function assembles an IP datagram and passes it
|
||||
* onto the hardware to be sent over the network.
|
||||
*/
|
||||
uint8_t *route;
|
||||
ip_frame_hdr *ipframe;
|
||||
|
||||
/*
|
||||
* Construct the IP header
|
||||
*/
|
||||
ipframe = (ip_frame_hdr*) &pNbuf->data[IP_HDR_OFFSET];
|
||||
/*
|
||||
* Construct the IP header
|
||||
*/
|
||||
ipframe = (ip_frame_hdr*) &pNbuf->data[IP_HDR_OFFSET];
|
||||
|
||||
/* IP version 4, Internet Header Length of 5 32-bit words */
|
||||
ipframe->version_ihl = 0x45;
|
||||
/* IP version 4, Internet Header Length of 5 32-bit words */
|
||||
ipframe->version_ihl = 0x45;
|
||||
|
||||
/* Type of Service == 0, normal and routine */
|
||||
ipframe->service_type = 0x00;
|
||||
/* Type of Service == 0, normal and routine */
|
||||
ipframe->service_type = 0x00;
|
||||
|
||||
/* Total length of data */
|
||||
ipframe->total_length = (uint16_t) (pNbuf->length + IP_HDR_SIZE);
|
||||
/* Total length of data */
|
||||
ipframe->total_length = (uint16_t) (pNbuf->length + IP_HDR_SIZE);
|
||||
|
||||
/* User defined identification */
|
||||
ipframe->identification = 0x0000;
|
||||
/* User defined identification */
|
||||
ipframe->identification = 0x0000;
|
||||
|
||||
/* Fragment Flags and Offset -- Don't fragment, last frag */
|
||||
ipframe->flags_frag_offset = 0x0000;
|
||||
/* Fragment Flags and Offset -- Don't fragment, last frag */
|
||||
ipframe->flags_frag_offset = 0x0000;
|
||||
|
||||
/* Time To Live */
|
||||
ipframe->ttl = 0xFF;
|
||||
/* Time To Live */
|
||||
ipframe->ttl = 0xFF;
|
||||
|
||||
/* Protocol */
|
||||
ipframe->protocol = protocol;
|
||||
/* Protocol */
|
||||
ipframe->protocol = protocol;
|
||||
|
||||
/* Checksum, computed later, zeroed for computation */
|
||||
ipframe->checksum = 0x0000;
|
||||
/* Checksum, computed later, zeroed for computation */
|
||||
ipframe->checksum = 0x0000;
|
||||
|
||||
/* source IP address */
|
||||
ipframe->source_addr[0] = src[0];
|
||||
ipframe->source_addr[1] = src[1];
|
||||
ipframe->source_addr[2] = src[2];
|
||||
ipframe->source_addr[3] = src[3];
|
||||
/* source IP address */
|
||||
ipframe->source_addr[0] = src[0];
|
||||
ipframe->source_addr[1] = src[1];
|
||||
ipframe->source_addr[2] = src[2];
|
||||
ipframe->source_addr[3] = src[3];
|
||||
|
||||
/* dest IP address */
|
||||
ipframe->dest_addr[0] = dest[0];
|
||||
ipframe->dest_addr[1] = dest[1];
|
||||
ipframe->dest_addr[2] = dest[2];
|
||||
ipframe->dest_addr[3] = dest[3];
|
||||
/* dest IP address */
|
||||
ipframe->dest_addr[0] = dest[0];
|
||||
ipframe->dest_addr[1] = dest[1];
|
||||
ipframe->dest_addr[2] = dest[2];
|
||||
ipframe->dest_addr[3] = dest[3];
|
||||
|
||||
/* Compute checksum */
|
||||
ipframe->checksum = ip_chksum((uint16_t *) ipframe, IP_HDR_SIZE);
|
||||
/* Compute checksum */
|
||||
ipframe->checksum = ip_chksum((uint16_t *) ipframe, IP_HDR_SIZE);
|
||||
|
||||
/* Increment the packet length by the size of the IP header */
|
||||
pNbuf->length += IP_HDR_SIZE;
|
||||
/* Increment the packet length by the size of the IP header */
|
||||
pNbuf->length += IP_HDR_SIZE;
|
||||
|
||||
/*
|
||||
* Determine the hardware address of the recipient
|
||||
*/
|
||||
IP_ADDR bc = { 255, 255, 255, 255};
|
||||
if (memcmp(bc, dest, 4) != 0)
|
||||
{
|
||||
route = ip_resolve_route(nif, dest);
|
||||
if (route == NULL)
|
||||
{
|
||||
dbg("Unable to locate %d.%d.%d.%d\r\n",
|
||||
dest[0], dest[1], dest[2], dest[3]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
route = bc;
|
||||
dbg("route = broadcast\r\n");
|
||||
dbg("nif = %p\r\n", nif);
|
||||
dbg("nif->send = %p\r\n", nif->send);
|
||||
}
|
||||
/*
|
||||
* Determine the hardware address of the recipient
|
||||
*/
|
||||
IP_ADDR bc = { 255, 255, 255, 255};
|
||||
if (memcmp(bc, dest, 4) != 0)
|
||||
{
|
||||
route = ip_resolve_route(nif, dest);
|
||||
if (route == NULL)
|
||||
{
|
||||
dbg("Unable to locate %d.%d.%d.%d\r\n",
|
||||
dest[0], dest[1], dest[2], dest[3]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
route = bc;
|
||||
dbg("route = broadcast\r\n");
|
||||
dbg("nif = %p\r\n", nif);
|
||||
dbg("nif->send = %p\r\n", nif->send);
|
||||
}
|
||||
|
||||
return nif->send(nif, route, &nif->hwa[0], ETH_FRM_IP, pNbuf);
|
||||
return nif->send(nif, route, &nif->hwa[0], ETH_FRM_IP, pNbuf);
|
||||
}
|
||||
|
||||
#if defined(DEBUG_PRINT)
|
||||
void dump_ip_frame(ip_frame_hdr *ipframe)
|
||||
{
|
||||
xprintf("Version: %02X\n", ((ipframe->version_ihl & 0x00f0) >> 4));
|
||||
xprintf("IHL: %02X\n", ipframe->version_ihl & 0x000f);
|
||||
xprintf("Service: %02X\n", ipframe->service_type);
|
||||
xprintf("Length: %04X\n", ipframe->total_length);
|
||||
xprintf("Ident: %04X\n", ipframe->identification);
|
||||
xprintf("Flags: %02X\n", ((ipframe->flags_frag_offset & 0xC000) >> 14));
|
||||
xprintf("Frag: %04X\n", ipframe->flags_frag_offset & 0x3FFF);
|
||||
xprintf("TTL: %02X\n", ipframe->ttl);
|
||||
xprintf("Protocol: %02X\n", ipframe->protocol);
|
||||
xprintf("Chksum: %04X\n", ipframe->checksum);
|
||||
xprintf("Source : %d.%d.%d.%d\n",
|
||||
ipframe->source_addr[0],
|
||||
ipframe->source_addr[1],
|
||||
ipframe->source_addr[2],
|
||||
ipframe->source_addr[3]);
|
||||
xprintf("Dest : %d.%d.%d.%d\n",
|
||||
ipframe->dest_addr[0],
|
||||
ipframe->dest_addr[1],
|
||||
ipframe->dest_addr[2],
|
||||
ipframe->dest_addr[3]);
|
||||
xprintf("Options: %08X\n", ipframe->options);
|
||||
xprintf("Version: %02X\n", ((ipframe->version_ihl & 0x00f0) >> 4));
|
||||
xprintf("IHL: %02X\n", ipframe->version_ihl & 0x000f);
|
||||
xprintf("Service: %02X\n", ipframe->service_type);
|
||||
xprintf("Length: %04X\n", ipframe->total_length);
|
||||
xprintf("Ident: %04X\n", ipframe->identification);
|
||||
xprintf("Flags: %02X\n", ((ipframe->flags_frag_offset & 0xC000) >> 14));
|
||||
xprintf("Frag: %04X\n", ipframe->flags_frag_offset & 0x3FFF);
|
||||
xprintf("TTL: %02X\n", ipframe->ttl);
|
||||
xprintf("Protocol: %02X\n", ipframe->protocol);
|
||||
xprintf("Chksum: %04X\n", ipframe->checksum);
|
||||
xprintf("Source : %d.%d.%d.%d\n",
|
||||
ipframe->source_addr[0],
|
||||
ipframe->source_addr[1],
|
||||
ipframe->source_addr[2],
|
||||
ipframe->source_addr[3]);
|
||||
xprintf("Dest : %d.%d.%d.%d\n",
|
||||
ipframe->dest_addr[0],
|
||||
ipframe->dest_addr[1],
|
||||
ipframe->dest_addr[2],
|
||||
ipframe->dest_addr[3]);
|
||||
xprintf("Options: %08X\n", ipframe->options);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
uint16_t ip_chksum(uint16_t *data, int num)
|
||||
{
|
||||
int chksum, ichksum;
|
||||
uint16_t temp;
|
||||
int chksum, ichksum;
|
||||
uint16_t temp;
|
||||
|
||||
chksum = 0;
|
||||
num = num >> 1; /* from bytes to words */
|
||||
for (; num; num--, data++)
|
||||
{
|
||||
temp = *data;
|
||||
ichksum = chksum + temp;
|
||||
ichksum = ichksum & 0x0000FFFF;
|
||||
if ((ichksum < temp) || (ichksum < chksum))
|
||||
{
|
||||
ichksum += 1;
|
||||
ichksum = ichksum & 0x0000FFFF;
|
||||
}
|
||||
chksum = ichksum;
|
||||
}
|
||||
return (uint16_t) ~chksum;
|
||||
chksum = 0;
|
||||
num = num >> 1; /* from bytes to words */
|
||||
for (; num; num--, data++)
|
||||
{
|
||||
temp = *data;
|
||||
ichksum = chksum + temp;
|
||||
ichksum = ichksum & 0x0000FFFF;
|
||||
if ((ichksum < temp) || (ichksum < chksum))
|
||||
{
|
||||
ichksum += 1;
|
||||
ichksum = ichksum & 0x0000FFFF;
|
||||
}
|
||||
chksum = ichksum;
|
||||
}
|
||||
return (uint16_t) ~chksum;
|
||||
}
|
||||
|
||||
static int validate_ip_hdr(NIF *nif, ip_frame_hdr *ipframe)
|
||||
{
|
||||
int index, chksum;
|
||||
IP_INFO *info;
|
||||
int index, chksum;
|
||||
IP_INFO *info;
|
||||
|
||||
/*
|
||||
* Check the IP Version
|
||||
*/
|
||||
if (IP_VERSION(ipframe) != 4)
|
||||
return 0;
|
||||
/*
|
||||
* Check the IP Version
|
||||
*/
|
||||
if (IP_VERSION(ipframe) != 4)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Check Internet Header Length
|
||||
*/
|
||||
if (IP_IHL(ipframe) < 5)
|
||||
return 0;
|
||||
/*
|
||||
* Check Internet Header Length
|
||||
*/
|
||||
if (IP_IHL(ipframe) < 5)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Check the destination IP address
|
||||
*/
|
||||
info = nif_get_protocol_info(nif,ETH_FRM_IP);
|
||||
for (index = 0; index < sizeof(IP_ADDR); index++)
|
||||
if (info->myip[index] != ipframe->dest_addr[index])
|
||||
return 0;
|
||||
/*
|
||||
* Check the destination IP address
|
||||
*/
|
||||
info = nif_get_protocol_info(nif,ETH_FRM_IP);
|
||||
for (index = 0; index < sizeof(IP_ADDR); index++)
|
||||
if (info->myip[index] != ipframe->dest_addr[index])
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Check the checksum
|
||||
*/
|
||||
chksum = (int)((uint16_t) IP_CHKSUM(ipframe));
|
||||
IP_CHKSUM(ipframe) = 0;
|
||||
/*
|
||||
* Check the checksum
|
||||
*/
|
||||
chksum = (int)((uint16_t) IP_CHKSUM(ipframe));
|
||||
IP_CHKSUM(ipframe) = 0;
|
||||
|
||||
if (ip_chksum((uint16_t *) ipframe, IP_IHL(ipframe) * 4) != chksum)
|
||||
return 0;
|
||||
if (ip_chksum((uint16_t *) ipframe, IP_IHL(ipframe) * 4) != chksum)
|
||||
return 0;
|
||||
|
||||
IP_CHKSUM(ipframe) = (uint16_t) chksum;
|
||||
IP_CHKSUM(ipframe) = (uint16_t) chksum;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ip_handler(NIF *nif, NBUF *pNbuf)
|
||||
{
|
||||
/*
|
||||
* IP packet handler
|
||||
*/
|
||||
ip_frame_hdr *ipframe;
|
||||
/*
|
||||
* IP packet handler
|
||||
*/
|
||||
ip_frame_hdr *ipframe;
|
||||
|
||||
dbg("packet received\r\n");
|
||||
dbg("packet received\r\n");
|
||||
|
||||
ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset];
|
||||
ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset];
|
||||
|
||||
/*
|
||||
* Verify valid IP header and destination IP
|
||||
*/
|
||||
if (!validate_ip_hdr(nif, ipframe))
|
||||
{
|
||||
dbg("not a valid IP packet!\r\n");
|
||||
/*
|
||||
* Verify valid IP header and destination IP
|
||||
*/
|
||||
if (!validate_ip_hdr(nif, ipframe))
|
||||
{
|
||||
dbg("not a valid IP packet!\r\n");
|
||||
|
||||
nbuf_free(pNbuf);
|
||||
return;
|
||||
}
|
||||
nbuf_free(pNbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
pNbuf->offset += (IP_IHL(ipframe) * 4);
|
||||
pNbuf->length = (uint16_t)(IP_LENGTH(ipframe) - (IP_IHL(ipframe) * 4));
|
||||
|
||||
/*
|
||||
* Call the appriopriate handler
|
||||
*/
|
||||
switch (IP_PROTOCOL(ipframe))
|
||||
{
|
||||
case IP_PROTO_ICMP:
|
||||
// FIXME: icmp_handler(nif, pNbuf);
|
||||
break;
|
||||
case IP_PROTO_UDP:
|
||||
udp_handler(nif,pNbuf);
|
||||
break;
|
||||
default:
|
||||
dbg("no protocol handler registered for protocol %d\r\n",
|
||||
__FUNCTION__, IP_PROTOCOL(ipframe));
|
||||
nbuf_free(pNbuf);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
/*
|
||||
* Call the appriopriate handler
|
||||
*/
|
||||
switch (IP_PROTOCOL(ipframe))
|
||||
{
|
||||
case IP_PROTO_ICMP:
|
||||
// FIXME: icmp_handler(nif, pNbuf);
|
||||
break;
|
||||
case IP_PROTO_UDP:
|
||||
udp_handler(nif,pNbuf);
|
||||
break;
|
||||
default:
|
||||
dbg("no protocol handler registered for protocol %d\r\n",
|
||||
__FUNCTION__, IP_PROTOCOL(ipframe));
|
||||
nbuf_free(pNbuf);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t port;
|
||||
void (*handler)(NIF *, NBUF *);
|
||||
uint16_t port;
|
||||
void (*handler)(NIF *, NBUF *);
|
||||
} UDP_BOUND_PORT;
|
||||
|
||||
#define UDP_MAX_PORTS (5) /* plenty for this implementation */
|
||||
@@ -34,151 +34,151 @@ static uint16_t udp_port;
|
||||
|
||||
void udp_init(void)
|
||||
{
|
||||
int index;
|
||||
int index;
|
||||
|
||||
for (index = 0; index < UDP_MAX_PORTS; ++index)
|
||||
{
|
||||
udp_port_table[index].port = 0;
|
||||
udp_port_table[index].handler = 0;
|
||||
}
|
||||
for (index = 0; index < UDP_MAX_PORTS; ++index)
|
||||
{
|
||||
udp_port_table[index].port = 0;
|
||||
udp_port_table[index].handler = 0;
|
||||
}
|
||||
|
||||
udp_port = DEFAULT_UDP_PORT; /* next free port */
|
||||
udp_port = DEFAULT_UDP_PORT; /* next free port */
|
||||
}
|
||||
|
||||
void udp_prime_port(uint16_t init_port)
|
||||
{
|
||||
udp_port = init_port;
|
||||
udp_port = init_port;
|
||||
}
|
||||
|
||||
void udp_bind_port(uint16_t port, void (*handler)(NIF *, NBUF *))
|
||||
{
|
||||
int index;
|
||||
int index;
|
||||
|
||||
for (index = 0; index < UDP_MAX_PORTS; ++index)
|
||||
{
|
||||
if (udp_port_table[index].port == 0)
|
||||
{
|
||||
udp_port_table[index].port = port;
|
||||
udp_port_table[index].handler = handler;
|
||||
for (index = 0; index < UDP_MAX_PORTS; ++index)
|
||||
{
|
||||
if (udp_port_table[index].port == 0)
|
||||
{
|
||||
udp_port_table[index].port = port;
|
||||
udp_port_table[index].handler = handler;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void udp_free_port(uint16_t port)
|
||||
{
|
||||
int index;
|
||||
int index;
|
||||
|
||||
for (index = 0; index < UDP_MAX_PORTS; ++index)
|
||||
{
|
||||
if (udp_port_table[index].port == port)
|
||||
{
|
||||
udp_port_table[index].port = 0;
|
||||
for (index = 0; index < UDP_MAX_PORTS; ++index)
|
||||
{
|
||||
if (udp_port_table[index].port == port)
|
||||
{
|
||||
udp_port_table[index].port = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *udp_port_handler(uint16_t port)
|
||||
{
|
||||
int index;
|
||||
int index;
|
||||
|
||||
for (index = 0; index < UDP_MAX_PORTS; ++index)
|
||||
{
|
||||
if (udp_port_table[index].port == port)
|
||||
{
|
||||
return (void *) udp_port_table[index].handler;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
for (index = 0; index < UDP_MAX_PORTS; ++index)
|
||||
{
|
||||
if (udp_port_table[index].port == port)
|
||||
{
|
||||
return (void *) udp_port_table[index].handler;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t udp_obtain_free_port(void)
|
||||
{
|
||||
uint16_t port;
|
||||
uint16_t port;
|
||||
|
||||
port = udp_port;
|
||||
if (--udp_port <= 255)
|
||||
udp_port = DEFAULT_UDP_PORT;
|
||||
port = udp_port;
|
||||
if (--udp_port <= 255)
|
||||
udp_port = DEFAULT_UDP_PORT;
|
||||
|
||||
return port;
|
||||
return port;
|
||||
}
|
||||
|
||||
int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf)
|
||||
{
|
||||
uint8_t *myip;
|
||||
uint8_t *myip;
|
||||
|
||||
if (nif == NULL)
|
||||
{
|
||||
if (nif == NULL)
|
||||
{
|
||||
dbg("nif is NULL\r\n");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function takes data, creates a UDP frame from it and
|
||||
* passes it onto the IP layer
|
||||
*/
|
||||
udp_frame_hdr *udpframe;
|
||||
/*
|
||||
* This function takes data, creates a UDP frame from it and
|
||||
* passes it onto the IP layer
|
||||
*/
|
||||
udp_frame_hdr *udpframe;
|
||||
|
||||
udpframe = (udp_frame_hdr *) &pNbuf->data[UDP_HDR_OFFSET];
|
||||
udpframe = (udp_frame_hdr *) &pNbuf->data[UDP_HDR_OFFSET];
|
||||
|
||||
/* Set UDP source port */
|
||||
udpframe->src_port = (uint16_t) sport;
|
||||
/* Set UDP source port */
|
||||
udpframe->src_port = (uint16_t) sport;
|
||||
|
||||
/* Set UDP destination port */
|
||||
udpframe->dest_port = (uint16_t) dport;
|
||||
/* Set UDP destination port */
|
||||
udpframe->dest_port = (uint16_t) dport;
|
||||
|
||||
/* Set length */
|
||||
udpframe->length = (uint16_t) (pNbuf->length + UDP_HDR_SIZE);
|
||||
/* Set length */
|
||||
udpframe->length = (uint16_t) (pNbuf->length + UDP_HDR_SIZE);
|
||||
|
||||
/* No checksum calcualation needed */
|
||||
udpframe->chksum = (uint16_t) 0;
|
||||
/* No checksum calcualation needed */
|
||||
udpframe->chksum = (uint16_t) 0;
|
||||
|
||||
/* Add the length of the UDP packet to the total length of the packet */
|
||||
pNbuf->length += 8;
|
||||
/* Add the length of the UDP packet to the total length of the packet */
|
||||
pNbuf->length += 8;
|
||||
|
||||
myip = ip_get_myip(nif_get_protocol_info(nif, ETH_FRM_IP));
|
||||
myip = ip_get_myip(nif_get_protocol_info(nif, ETH_FRM_IP));
|
||||
|
||||
dbg("sent UDP request to %d.%d.%d.%d from %d.%d.%d.%d\r\n",
|
||||
dest[0], dest[1], dest[2], dest[3],
|
||||
myip[0], myip[1], myip[2], myip[3]);
|
||||
dest[0], dest[1], dest[2], dest[3],
|
||||
myip[0], myip[1], myip[2], myip[3]);
|
||||
|
||||
return (ip_send(nif, dest, myip, IP_PROTO_UDP, pNbuf));
|
||||
return (ip_send(nif, dest, myip, IP_PROTO_UDP, pNbuf));
|
||||
|
||||
}
|
||||
|
||||
void udp_handler(NIF *nif, NBUF *pNbuf)
|
||||
{
|
||||
/*
|
||||
* This function handles incoming UDP packets
|
||||
*/
|
||||
udp_frame_hdr *udpframe;
|
||||
void (*handler)(NIF *, NBUF *);
|
||||
/*
|
||||
* This function handles incoming UDP packets
|
||||
*/
|
||||
udp_frame_hdr *udpframe;
|
||||
void (*handler)(NIF *, NBUF *);
|
||||
|
||||
udpframe = (udp_frame_hdr *) &pNbuf->data[pNbuf->offset];
|
||||
udpframe = (udp_frame_hdr *) &pNbuf->data[pNbuf->offset];
|
||||
|
||||
dbg("packet received\r\n",);
|
||||
|
||||
/*
|
||||
* Adjust the length and valid data offset of the packet we are
|
||||
* passing on
|
||||
*/
|
||||
pNbuf->length -= UDP_HDR_SIZE;
|
||||
pNbuf->offset += UDP_HDR_SIZE;
|
||||
/*
|
||||
* Adjust the length and valid data offset of the packet we are
|
||||
* passing on
|
||||
*/
|
||||
pNbuf->length -= UDP_HDR_SIZE;
|
||||
pNbuf->offset += UDP_HDR_SIZE;
|
||||
|
||||
/*
|
||||
* Traverse the list of bound ports to see if there is a higher
|
||||
* level protocol to pass the packet on to
|
||||
*/
|
||||
if ((handler = (void(*)(NIF*, NBUF*)) udp_port_handler(UDP_DEST(udpframe))) != NULL)
|
||||
handler(nif, pNbuf);
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Traverse the list of bound ports to see if there is a higher
|
||||
* level protocol to pass the packet on to
|
||||
*/
|
||||
if ((handler = (void(*)(NIF*, NBUF*)) udp_port_handler(UDP_DEST(udpframe))) != NULL)
|
||||
handler(nif, pNbuf);
|
||||
else
|
||||
{
|
||||
dbg("received UDP packet for non-supported port\n");
|
||||
nbuf_free(pNbuf);
|
||||
}
|
||||
nbuf_free(pNbuf);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user