mirror of
https://github.com/apache/nuttx.git
synced 2026-09-22 14:41:29 +08:00
Add basic structure to support multiple network interfaces
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@343 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -1391,9 +1391,6 @@ The system can be re-made subsequently by just typing <code>make</code>.
|
||||
<li>
|
||||
<code>CONFIG_NET_LLH_LEN</code>: The link level header length
|
||||
</li>
|
||||
<li>
|
||||
<code>CONFIG_NET_EXTERNAL_BUFFER</code>: Incoming packet buffer (uip_buf) is defined externally
|
||||
</li>
|
||||
<li>
|
||||
<code>CONFIG_NET_FWCACHE_SIZE</code>: number of packets to remember when looking for duplicates
|
||||
</li>
|
||||
|
||||
+31
-30
@@ -55,7 +55,7 @@
|
||||
* Private Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define BUF ((struct uip_eth_hdr *)g_sim_dev.d_buf)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@@ -75,8 +75,9 @@ struct timer
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct timer periodic_timer;
|
||||
static struct timer arp_timer;
|
||||
static struct timer g_periodic_timer;
|
||||
static struct timer g_arp_timer;
|
||||
static struct uip_driver_s g_sim_dev;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@@ -106,82 +107,82 @@ void uipdriver_loop(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
uip_len = tapdev_read((unsigned char*)uip_buf, UIP_BUFSIZE);
|
||||
if (uip_len > 0)
|
||||
g_sim_dev.d_len = tapdev_read((unsigned char*)g_sim_dev.d_buf, UIP_BUFSIZE);
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
if (BUF->type == htons(UIP_ETHTYPE_IP))
|
||||
{
|
||||
uip_arp_ipin();
|
||||
uip_input();
|
||||
uip_input(&g_sim_dev);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* uip_len is set to a value > 0.
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (uip_len > 0)
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
tapdev_send((char*)uip_buf, uip_len);
|
||||
uip_arp_out(&g_sim_dev);
|
||||
tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
|
||||
}
|
||||
}
|
||||
else if (BUF->type == htons(UIP_ETHTYPE_ARP))
|
||||
{
|
||||
uip_arp_arpin();
|
||||
uip_arp_arpin(&g_sim_dev);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* uip_len is set to a value > 0.
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (uip_len > 0)
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
tapdev_send((char*)uip_buf, uip_len);
|
||||
tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (timer_expired(&periodic_timer))
|
||||
else if (timer_expired(&g_periodic_timer))
|
||||
{
|
||||
timer_reset(&periodic_timer);
|
||||
timer_reset(&g_periodic_timer);
|
||||
for(i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
uip_tcppoll(i);
|
||||
uip_tcppoll(&g_sim_dev,i);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* uip_len is set to a value > 0.
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (uip_len > 0)
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
tapdev_send((char*)uip_buf, uip_len);
|
||||
uip_arp_out(&g_sim_dev);
|
||||
tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
for(i = 0; i < UIP_UDP_CONNS; i++)
|
||||
{
|
||||
uip_udppoll(i);
|
||||
uip_udppoll(&g_sim_dev,i);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* uip_len is set to a value > 0.
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (uip_len > 0)
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
tapdev_send((char*)uip_buf, uip_len);
|
||||
uip_arp_out(&g_sim_dev);
|
||||
tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
/* Call the ARP timer function every 10 seconds. */
|
||||
|
||||
if (timer_expired(&arp_timer))
|
||||
if (timer_expired(&g_arp_timer))
|
||||
{
|
||||
timer_reset(&arp_timer);
|
||||
timer_reset(&g_arp_timer);
|
||||
uip_arp_timer();
|
||||
}
|
||||
}
|
||||
@@ -189,8 +190,8 @@ void uipdriver_loop(void)
|
||||
|
||||
int uipdriver_init(void)
|
||||
{
|
||||
timer_set(&periodic_timer, 500);
|
||||
timer_set(&arp_timer, 10000 );
|
||||
timer_set(&g_periodic_timer, 500);
|
||||
timer_set(&g_arp_timer, 10000 );
|
||||
|
||||
tapdev_init();
|
||||
uip_init();
|
||||
|
||||
@@ -229,8 +229,6 @@ defconfig -- This is a configuration file similar to the Linux
|
||||
CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
CONFIG_NET_BROADCAST - Broadcast support
|
||||
CONFIG_NET_LLH_LEN - The link level header length
|
||||
CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf)
|
||||
is defined externally
|
||||
CONFIG_NET_FWCACHE_SIZE - number of packets to remember when
|
||||
looking for duplicates
|
||||
|
||||
|
||||
@@ -268,7 +268,6 @@ CONFIG_PREALLOC_TIMERS=8
|
||||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
@@ -287,7 +286,6 @@ CONFIG_NET_STATISTICS=y
|
||||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
||||
@@ -257,7 +257,6 @@ CONFIG_PREALLOC_TIMERS=8
|
||||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
@@ -276,7 +275,6 @@ CONFIG_NET_STATISTICS=y
|
||||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
||||
@@ -281,7 +281,6 @@ CONFIG_PREALLOC_TIMERS=8
|
||||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
@@ -300,7 +299,6 @@ CONFIG_NET_STATISTICS=y
|
||||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
||||
@@ -266,7 +266,6 @@ CONFIG_PREALLOC_TIMERS=8
|
||||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
@@ -285,7 +284,6 @@ CONFIG_NET_STATISTICS=y
|
||||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
||||
@@ -254,7 +254,6 @@ CONFIG_PREALLOC_TIMERS=0
|
||||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
@@ -273,7 +272,6 @@ CONFIG_NET_STATISTICS=y
|
||||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
||||
@@ -228,7 +228,6 @@ CONFIG_FS_FAT=y
|
||||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
@@ -247,7 +246,6 @@ CONFIG_NET_STATISTICS=y
|
||||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
||||
+120
-54
@@ -63,16 +63,96 @@
|
||||
* the macrose defined in this file.
|
||||
*/
|
||||
|
||||
#define UIP_DATA 1 /* Tells uIP that there is incoming data in the uip_buf buffer. The
|
||||
* length of the data is stored in the global variable uip_len. */
|
||||
#define UIP_DATA 1 /* Tells uIP that there is incoming data in the d_buf buffer. The
|
||||
* length of the data is stored in the field d_len. */
|
||||
#define UIP_TIMER 2 /* Tells uIP that the periodic timer has fired. */
|
||||
#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should be polled. */
|
||||
#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram should be constructed in the
|
||||
* uip_buf buffer. */
|
||||
#ifdef CONFIG_NET_UDP
|
||||
* d_buf buffer. */
|
||||
#ifdef CONFIG_NET_UDP
|
||||
# define UIP_UDP_TIMER 5
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure collects information that is specific to a specific network
|
||||
* interface driver. If the hardware platform supports only a single instance
|
||||
* of this structure.
|
||||
*/
|
||||
|
||||
struct uip_driver_s
|
||||
{
|
||||
/* The uIP packet buffer.
|
||||
*
|
||||
* The d_buf array is used to hold incoming and outgoing
|
||||
* packets. The device driver should place incoming data into this
|
||||
* buffer. When sending data, the device driver should read the link
|
||||
* level headers and the TCP/IP headers from this buffer. The size of
|
||||
* the link level headers is configured by the UIP_LLH_LEN define.
|
||||
*
|
||||
* Note: The application data need not be placed in this buffer, so
|
||||
* the device driver must read it from the place pointed to by the
|
||||
* d_appdata pointer as illustrated by the following example:
|
||||
*
|
||||
* void
|
||||
* devicedriver_send(void)
|
||||
* {
|
||||
* hwsend(&dev->d_buf[0], UIP_LLH_LEN);
|
||||
* if(dev->d_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
|
||||
* hwsend(&dev->d_buf[UIP_LLH_LEN], dev->d_len - UIP_LLH_LEN);
|
||||
* } else {
|
||||
* hwsend(&dev->d_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
|
||||
* hwsend(dev->d_appdata, dev->d_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
uint8 d_buf[UIP_BUFSIZE + 2];
|
||||
|
||||
/* d_appdata points to the location where application data can be read from
|
||||
* or written into a packet.
|
||||
*/
|
||||
|
||||
uint8 *d_appdata;
|
||||
|
||||
/* This is a pointer into d_buf where a user application may append
|
||||
* data to be sent.
|
||||
*/
|
||||
|
||||
uint8 *d_snddata;
|
||||
|
||||
/* The length of the packet in the d_buf buffer.
|
||||
*
|
||||
* Holds the length of the packet in the d_buf buffer.
|
||||
*
|
||||
* When the network device driver calls the uIP input function,
|
||||
* d_len should be set to the length of the packet in the d_buf
|
||||
* buffer.
|
||||
*
|
||||
* When sending packets, the device driver should use the contents of
|
||||
* the d_len variable to determine the length of the outgoing
|
||||
* packet.
|
||||
*/
|
||||
|
||||
uint16 d_len;
|
||||
|
||||
/* When d_buf contains outgoing xmit data, xmtlen is nonzero and represents
|
||||
* the amount of appllcation data after d_snddata
|
||||
*/
|
||||
|
||||
uint16 d_sndlen;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pulblic Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* uIP device driver functions
|
||||
*
|
||||
* These functions are used by a network device driver for interacting
|
||||
@@ -82,21 +162,21 @@
|
||||
*
|
||||
* This function should be called when the device driver has received
|
||||
* a packet from the network. The packet from the device driver must
|
||||
* be present in the uip_buf buffer, and the length of the packet
|
||||
* should be placed in the uip_len variable.
|
||||
* be present in the d_buf buffer, and the length of the packet
|
||||
* should be placed in the d_len field.
|
||||
*
|
||||
* When the function returns, there may be an outbound packet placed
|
||||
* in the uip_buf packet buffer. If so, the uip_len variable is set to
|
||||
* in the d_buf packet buffer. If so, the d_len field is set to
|
||||
* the length of the packet. If no packet is to be sent out, the
|
||||
* uip_len variable is set to 0.
|
||||
* d_len field is set to 0.
|
||||
*
|
||||
* The usual way of calling the function is presented by the source
|
||||
* code below.
|
||||
*
|
||||
* uip_len = devicedriver_poll();
|
||||
* if(uip_len > 0) {
|
||||
* dev->d_len = devicedriver_poll();
|
||||
* if(dev->d_len > 0) {
|
||||
* uip_input();
|
||||
* if(uip_len > 0) {
|
||||
* if(dev->d_len > 0) {
|
||||
* devicedriver_send();
|
||||
* }
|
||||
* }
|
||||
@@ -106,25 +186,25 @@
|
||||
* Ethernet, you will need to call the uIP ARP code before calling
|
||||
* this function:
|
||||
*
|
||||
* #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
* uip_len = ethernet_devicedrver_poll();
|
||||
* if(uip_len > 0) {
|
||||
* #define BUF ((struct uip_eth_hdr *)&dev->d_buf[0])
|
||||
* dev->d_len = ethernet_devicedrver_poll();
|
||||
* if(dev->d_len > 0) {
|
||||
* if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
|
||||
* uip_arp_ipin();
|
||||
* uip_input();
|
||||
* if(uip_len > 0) {
|
||||
* if(dev->d_len > 0) {
|
||||
* uip_arp_out();
|
||||
* ethernet_devicedriver_send();
|
||||
* }
|
||||
* } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
|
||||
* uip_arp_arpin();
|
||||
* if(uip_len > 0) {
|
||||
* if(dev->d_len > 0) {
|
||||
* ethernet_devicedriver_send();
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
#define uip_input() uip_interrupt(UIP_DATA)
|
||||
#define uip_input(dev) uip_interrupt(dev,UIP_DATA)
|
||||
|
||||
/* Periodic processing for a connection identified by its number.
|
||||
*
|
||||
@@ -134,8 +214,8 @@
|
||||
* connection, regardless of whether they are open of closed.
|
||||
*
|
||||
* When the function returns, it may have an outbound packet waiting
|
||||
* for service in the uIP packet buffer, and if so the uip_len
|
||||
* variable is set to a value larger than zero. The device driver
|
||||
* for service in the uIP packet buffer, and if so the d_len field
|
||||
* is set to a value larger than zero. The device driver
|
||||
* should be called to send out the packet.
|
||||
*
|
||||
* The ususal way of calling the function is through a for() loop like
|
||||
@@ -143,8 +223,8 @@
|
||||
*
|
||||
* for(i = 0; i < UIP_CONNS; ++i)
|
||||
* {
|
||||
* uip_tcppoll(i);
|
||||
* if (uip_len > 0)
|
||||
* uip_tcppoll(dev,i);
|
||||
* if (dev->d_len > 0)
|
||||
* {
|
||||
* devicedriver_send();
|
||||
* }
|
||||
@@ -157,8 +237,8 @@
|
||||
*
|
||||
* for(i = 0; i < UIP_CONNS; ++i)
|
||||
* {
|
||||
* uip_tcppoll(i);
|
||||
* if (uip_len > 0)
|
||||
* uip_tcppoll(dev,i);
|
||||
* if (dev->d_len > 0)
|
||||
* {
|
||||
* uip_arp_out();
|
||||
* ethernet_devicedriver_send();
|
||||
@@ -168,7 +248,7 @@
|
||||
* conn The number of the connection which is to be periodically polled.
|
||||
*/
|
||||
|
||||
extern void uip_tcppoll(unsigned int conn);
|
||||
extern void uip_tcppoll(struct uip_driver_s *dev, unsigned int conn);
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
/* Periodic processing for a UDP connection identified by its number.
|
||||
@@ -179,8 +259,8 @@ extern void uip_tcppoll(unsigned int conn);
|
||||
*
|
||||
* for(i = 0; i < UIP_UDP_CONNS; i++)
|
||||
* {
|
||||
* uip_udppoll(i);
|
||||
* if(uip_len > 0)
|
||||
* uip_udppoll(dev,i);
|
||||
* if(dev->d_len > 0)
|
||||
* {
|
||||
* devicedriver_send();
|
||||
* }
|
||||
@@ -191,8 +271,8 @@ extern void uip_tcppoll(unsigned int conn);
|
||||
*
|
||||
* for(i = 0; i < UIP_UDP_CONNS; i++)
|
||||
* {
|
||||
* uip_udppoll(i);
|
||||
* if(uip_len > 0)
|
||||
* uip_udppoll(dev,i);
|
||||
* if(dev->d_len > 0)
|
||||
* {
|
||||
* uip_arp_out();
|
||||
* ethernet_devicedriver_send();
|
||||
@@ -202,31 +282,17 @@ extern void uip_tcppoll(unsigned int conn);
|
||||
* conn The number of the UDP connection to be processed.
|
||||
*/
|
||||
|
||||
extern void uip_udppoll(unsigned int conn);
|
||||
extern void uip_udppoll(struct uip_driver_s *dev, unsigned int conn);
|
||||
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pulblic Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Architecure support
|
||||
*
|
||||
* uip_interrupt(flag):
|
||||
*
|
||||
* The actual uIP function which does all the work. Called from the
|
||||
* interrupt level by a device driver.
|
||||
*/
|
||||
|
||||
extern void uip_interrupt(uint8 flag);
|
||||
extern void uip_interrupt(struct uip_driver_s *dev, uint8 flag);
|
||||
|
||||
/* By defining UIP_ARCH_CHKSUM, the architecture can replace the following
|
||||
* functions with hardware assisted solutions.
|
||||
@@ -273,32 +339,32 @@ extern void uip_add32(uint8 *op32, uint16 op16);
|
||||
|
||||
extern uint16 uip_chksum(uint16 *buf, uint16 len);
|
||||
|
||||
/* Calculate the IP header checksum of the packet header in uip_buf.
|
||||
/* Calculate the IP header checksum of the packet header in d_buf.
|
||||
*
|
||||
* The IP header checksum is the Internet checksum of the 20 bytes of
|
||||
* the IP header.
|
||||
*
|
||||
* Return: The IP header checksum of the IP header in the uip_buf
|
||||
* Return: The IP header checksum of the IP header in the d_buf
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
extern uint16 uip_ipchksum(void);
|
||||
extern uint16 uip_ipchksum(struct uip_driver_s *dev);
|
||||
|
||||
/* Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
|
||||
/* Calculate the TCP checksum of the packet in d_buf and d_appdata.
|
||||
*
|
||||
* The TCP checksum is the Internet checksum of data contents of the
|
||||
* TCP segment, and a pseudo-header as defined in RFC793.
|
||||
*
|
||||
* Note: The uip_appdata pointer that points to the packet data may
|
||||
* Note: The d_appdata pointer that points to the packet data may
|
||||
* point anywhere in memory, so it is not possible to simply calculate
|
||||
* the Internet checksum of the contents of the uip_buf buffer.
|
||||
* the Internet checksum of the contents of the d_buf buffer.
|
||||
*
|
||||
* Return: The TCP checksum of the TCP segment in uip_buf and pointed
|
||||
* to by uip_appdata.
|
||||
* Return: The TCP checksum of the TCP segment in d_buf and pointed
|
||||
* to by d_appdata.
|
||||
*/
|
||||
|
||||
extern uint16 uip_tcpchksum(void);
|
||||
extern uint16 uip_tcpchksum(struct uip_driver_s *dev);
|
||||
|
||||
extern uint16 uip_udpchksum(void);
|
||||
extern uint16 uip_udpchksum(struct uip_driver_s *dev);
|
||||
|
||||
#endif /* __UIP_ARCH_H */
|
||||
|
||||
@@ -61,36 +61,35 @@ void uip_arp_init(void);
|
||||
/* The uip_arp_ipin() function should be called whenever an IP packet
|
||||
* arrives from the Ethernet. This function refreshes the ARP table or
|
||||
* inserts a new mapping if none exists. The function assumes that an
|
||||
* IP packet with an Ethernet header is present in the uip_buf buffer
|
||||
* and that the length of the packet is in the uip_len variable.
|
||||
* IP packet with an Ethernet header is present in the d_buf buffer
|
||||
* and that the length of the packet is in the d_len field.
|
||||
*/
|
||||
|
||||
/*void uip_arp_ipin(void);*/
|
||||
#define uip_arp_ipin()
|
||||
|
||||
/* The uip_arp_arpin() should be called when an ARP packet is received
|
||||
* by the Ethernet driver. This function also assumes that the
|
||||
* Ethernet frame is present in the uip_buf buffer. When the
|
||||
* uip_arp_arpin() function returns, the contents of the uip_buf
|
||||
* buffer should be sent out on the Ethernet if the uip_len variable
|
||||
* Ethernet frame is present in the d_buf buffer. When the
|
||||
* uip_arp_arpin() function returns, the contents of the d_buf
|
||||
* buffer should be sent out on the Ethernet if the d_len field
|
||||
* is > 0.
|
||||
*/
|
||||
|
||||
void uip_arp_arpin(void);
|
||||
void uip_arp_arpin(struct uip_driver_s *dev);
|
||||
|
||||
/* The uip_arp_out() function should be called when an IP packet
|
||||
* should be sent out on the Ethernet. This function creates an
|
||||
* Ethernet header before the IP header in the uip_buf buffer. The
|
||||
* Ethernet header before the IP header in the d_buf buffer. The
|
||||
* Ethernet header will have the correct Ethernet MAC destination
|
||||
* address filled in if an ARP table entry for the destination IP
|
||||
* address (or the IP address of the default router) is present. If no
|
||||
* such table entry is found, the IP packet is overwritten with an ARP
|
||||
* request and we rely on TCP to retransmit the packet that was
|
||||
* overwritten. In any case, the uip_len variable holds the length of
|
||||
* overwritten. In any case, the d_len field holds the length of
|
||||
* the Ethernet frame that should be transmitted.
|
||||
*/
|
||||
|
||||
void uip_arp_out(void);
|
||||
void uip_arp_out(struct uip_driver_s *dev);
|
||||
|
||||
/* The uip_arp_timer() function should be called every ten seconds. It
|
||||
* is responsible for flushing old entries in the ARP table.
|
||||
|
||||
+46
-78
@@ -84,6 +84,9 @@
|
||||
* successfully established. */
|
||||
#define UIP_TIMEDOUT (1 << 7) /* The connection has been aborted due to too many retransmissions. */
|
||||
|
||||
#define UIP_DATA_EVENTS (UIP_ACKDATA|UIP_NEWDATA|UIP_REXMIT|UIP_POLL)
|
||||
#define UIP_CONN_EVENTS (UIP_CLOSE|UIP_ABORT|UIP_CONNECTED|UIP_TIMEDOUT)
|
||||
|
||||
/* The TCP states used in the uip_conn->tcpstateflags. */
|
||||
|
||||
#define UIP_CLOSED 0 /* The connection is not in use and available */
|
||||
@@ -100,15 +103,15 @@
|
||||
#define UIP_TS_MASK 15
|
||||
#define UIP_STOPPED 16
|
||||
|
||||
/* The buffer size available for user data in the \ref uip_buf buffer.
|
||||
/* The buffer size available for user data in the d_buf buffer.
|
||||
*
|
||||
* This macro holds the available size for user data in the \ref
|
||||
* uip_buf buffer. The macro is intended to be used for checking
|
||||
* d_buf buffer. The macro is intended to be used for checking
|
||||
* bounds of available user data.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
|
||||
* snprintf(dev->d_appdata, UIP_APPDATA_SIZE, "%u\n", i);
|
||||
*/
|
||||
|
||||
#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
||||
@@ -156,6 +159,7 @@ typedef uip_ip4addr_t uip_ipaddr_t;
|
||||
* file pointers) for the connection.
|
||||
*/
|
||||
|
||||
struct uip_driver_s; /* Forward reference */
|
||||
struct uip_conn
|
||||
{
|
||||
dq_entry_t node; /* Implements a doubly linked list */
|
||||
@@ -186,8 +190,10 @@ struct uip_conn
|
||||
* in the following:
|
||||
*/
|
||||
|
||||
void *private;
|
||||
void (*callback)(void *private);
|
||||
void *data_private;
|
||||
void (*data_event)(struct uip_driver_s *dev, void *private);
|
||||
void *connection_private;
|
||||
void (*connection_event)(void *private);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
@@ -204,7 +210,7 @@ struct uip_udp_conn
|
||||
/* Defines the UDP callback */
|
||||
|
||||
void *private;
|
||||
void (*callback)(void *private);
|
||||
void (*event)(struct uip_driver_s *dev, void *private);
|
||||
};
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
@@ -232,6 +238,7 @@ struct uip_stats
|
||||
uip_stats_t protoerr; /* Number of packets dropped since they
|
||||
were neither ICMP, UDP nor TCP. */
|
||||
} ip; /* IP statistics. */
|
||||
|
||||
struct
|
||||
{
|
||||
uip_stats_t drop; /* Number of dropped ICMP packets. */
|
||||
@@ -239,7 +246,9 @@ struct uip_stats
|
||||
uip_stats_t sent; /* Number of sent ICMP packets. */
|
||||
uip_stats_t typeerr; /* Number of ICMP packets with a wrong type. */
|
||||
} icmp; /* ICMP statistics. */
|
||||
|
||||
struct
|
||||
|
||||
{
|
||||
uip_stats_t drop; /* Number of dropped TCP segments. */
|
||||
uip_stats_t recv; /* Number of recived TCP segments. */
|
||||
@@ -253,6 +262,7 @@ struct uip_stats
|
||||
uip_stats_t synrst; /* Number of SYNs for closed ports,
|
||||
triggering a RST. */
|
||||
} tcp; /* TCP statistics. */
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
struct
|
||||
{
|
||||
@@ -269,6 +279,7 @@ struct uip_stats
|
||||
struct uip_tcpip_hdr
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
|
||||
/* IPv6 header. */
|
||||
|
||||
uint8 vtc;
|
||||
@@ -279,6 +290,7 @@ struct uip_tcpip_hdr
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* IPv4 header. */
|
||||
|
||||
uint8 vhl;
|
||||
@@ -291,6 +303,7 @@ struct uip_tcpip_hdr
|
||||
uint16 ipchksum;
|
||||
uint16 srcipaddr[2];
|
||||
uint16 destipaddr[2];
|
||||
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* TCP header. */
|
||||
@@ -312,6 +325,7 @@ struct uip_tcpip_hdr
|
||||
struct uip_icmpip_hdr
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
|
||||
/* IPv6 header. */
|
||||
|
||||
uint8 vtc;
|
||||
@@ -324,6 +338,7 @@ struct uip_icmpip_hdr
|
||||
uip_ip6addr_t destipaddr;
|
||||
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* IPv4 header. */
|
||||
|
||||
uint8 vhl;
|
||||
@@ -336,17 +351,29 @@ struct uip_icmpip_hdr
|
||||
uint16 ipchksum;
|
||||
uint16 srcipaddr[2];
|
||||
uint16 destipaddr[2];
|
||||
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* ICMP (echo) header. */
|
||||
uint8 type, icode;
|
||||
|
||||
uint8 type;
|
||||
uint8 icode;
|
||||
uint16 icmpchksum;
|
||||
|
||||
#ifndef CONFIG_NET_IPv6
|
||||
uint16 id, seqno;
|
||||
|
||||
uint16 id;
|
||||
uint16 seqno;
|
||||
|
||||
#else /* !CONFIG_NET_IPv6 */
|
||||
uint8 flags, reserved1, reserved2, reserved3;
|
||||
|
||||
uint8 flags;
|
||||
uint8 reserved1;
|
||||
uint8 reserved2;
|
||||
uint8 reserved3;
|
||||
uint8 icmp6data[16];
|
||||
uint8 options[1];
|
||||
|
||||
#endif /* !CONFIG_NET_IPv6 */
|
||||
};
|
||||
|
||||
@@ -355,6 +382,7 @@ struct uip_icmpip_hdr
|
||||
struct uip_udpip_hdr
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
|
||||
/* IPv6 header. */
|
||||
|
||||
uint8 vtc;
|
||||
@@ -364,8 +392,10 @@ struct uip_udpip_hdr
|
||||
uint8 proto, ttl;
|
||||
uip_ip6addr_t srcipaddr;
|
||||
uip_ip6addr_t destipaddr;
|
||||
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
/* IP header. */
|
||||
|
||||
/* IPv4 header. */
|
||||
|
||||
uint8 vhl;
|
||||
uint8 tos;
|
||||
@@ -377,6 +407,7 @@ struct uip_udpip_hdr
|
||||
uint16 ipchksum;
|
||||
uint16 srcipaddr[2];
|
||||
uint16 destipaddr[2];
|
||||
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* UDP header. */
|
||||
@@ -398,42 +429,6 @@ struct uip_eth_addr
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The uIP packet buffer.
|
||||
*
|
||||
* The uip_buf array is used to hold incoming and outgoing
|
||||
* packets. The device driver should place incoming data into this
|
||||
* buffer. When sending data, the device driver should read the link
|
||||
* level headers and the TCP/IP headers from this buffer. The size of
|
||||
* the link level headers is configured by the UIP_LLH_LEN define.
|
||||
*
|
||||
* Note: The application data need not be placed in this buffer, so
|
||||
* the device driver must read it from the place pointed to by the
|
||||
* uip_appdata pointer as illustrated by the following example:
|
||||
*
|
||||
* void
|
||||
* devicedriver_send(void)
|
||||
* {
|
||||
* hwsend(&uip_buf[0], UIP_LLH_LEN);
|
||||
* if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
|
||||
* hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
|
||||
* } else {
|
||||
* hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
|
||||
* hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
extern uint8 uip_buf[UIP_BUFSIZE+2];
|
||||
|
||||
/* Pointer to the application data in the packet buffer.
|
||||
*
|
||||
* This pointer points to the application data when the application is
|
||||
* called. If the application wishes to send data, the application may
|
||||
* use this space to write the data into before calling uip_send().
|
||||
*/
|
||||
|
||||
extern void *uip_appdata;
|
||||
|
||||
#if UIP_URGDATA > 0
|
||||
/* uint8 *uip_urgdata:
|
||||
*
|
||||
@@ -448,24 +443,8 @@ extern void *uip_urgdata;
|
||||
*
|
||||
* uIP has a few global variables that are used in device drivers for
|
||||
* uIP.
|
||||
*
|
||||
* The length of the packet in the uip_buf buffer.
|
||||
*
|
||||
* The global variable uip_len holds the length of the packet in the
|
||||
* uip_buf buffer.
|
||||
*
|
||||
* When the network device driver calls the uIP input function,
|
||||
* uip_len should be set to the length of the packet in the uip_buf
|
||||
* buffer.
|
||||
*
|
||||
* When sending packets, the device driver should use the contents of
|
||||
* the uip_len variable to determine the length of the outgoing
|
||||
* packet.
|
||||
*
|
||||
*/
|
||||
|
||||
extern uint16 uip_len;
|
||||
|
||||
#if UIP_URGDATA > 0
|
||||
extern uint16 uip_urglen, uip_surglen;
|
||||
#endif /* UIP_URGDATA > 0 */
|
||||
@@ -703,16 +682,16 @@ void uip_unlisten(uint16 port);
|
||||
* len The maximum amount of data bytes to be sent.
|
||||
*/
|
||||
|
||||
void uip_send(const void *data, int len);
|
||||
void uip_send(struct uip_driver_s *dev, const void *buf, int len);
|
||||
|
||||
/* The length of any incoming data that is currently avaliable (if avaliable)
|
||||
* in the uip_appdata buffer.
|
||||
* in the d_appdata buffer.
|
||||
*
|
||||
* The test function uip_data() must first be used to check if there
|
||||
* is any data available at all.
|
||||
*/
|
||||
|
||||
#define uip_datalen() uip_len
|
||||
#define uip_datalen(dev) ((dev)->d_len)
|
||||
|
||||
/* The length of any out-of-band data (urgent data) that has arrived
|
||||
* on the connection.
|
||||
@@ -778,8 +757,8 @@ void uip_send(const void *data, int len);
|
||||
/* Is new incoming data available?
|
||||
*
|
||||
* Will reduce to non-zero if there is new data for the application
|
||||
* present at the uip_appdata pointer. The size of the data is
|
||||
* avaliable through the uip_len variable.
|
||||
* present at the d_appdata pointer. The size of the data is
|
||||
* avaliable through the d_len element.
|
||||
*/
|
||||
|
||||
#define uip_newdata() (uip_flags & UIP_NEWDATA)
|
||||
@@ -897,17 +876,6 @@ extern int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *a
|
||||
extern void uip_udpenable(struct uip_udp_conn *conn);
|
||||
extern void uip_udpdisable(struct uip_udp_conn *conn);
|
||||
|
||||
/* Send a UDP datagram of length len on the current connection.
|
||||
*
|
||||
* This function can only be called in response to a UDP event (poll
|
||||
* or newdata). The data must be present in the uip_buf buffer, at the
|
||||
* place pointed to by the uip_appdata pointer.
|
||||
*
|
||||
* len The length of the data in the uip_buf buffer.
|
||||
*/
|
||||
|
||||
#define uip_udp_send(len) uip_send((char *)uip_appdata, len)
|
||||
|
||||
/* uIP convenience and converting functions.
|
||||
*
|
||||
* These functions can be used for converting between different data
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
* uIP supports reassembly of fragmented IP packets. This features
|
||||
* requires an additonal amount of RAM to hold the reassembly buffer
|
||||
* and the reassembly code size is approximately 700 bytes. The
|
||||
* reassembly buffer is of the same size as the uip_buf buffer
|
||||
* reassembly buffer is of the same size as the d_buf buffer
|
||||
* (configured by UIP_BUFSIZE).
|
||||
*
|
||||
* Note: IP packet reassembly is not heavily tested.
|
||||
@@ -234,7 +234,7 @@
|
||||
|
||||
/* The size of the advertised receiver's window.
|
||||
*
|
||||
* Should be set low (i.e., to the size of the uip_buf buffer) is the
|
||||
* Should be set low (i.e., to the size of the d_buf buffer) is the
|
||||
* application is slow to process incoming data, or high (32768 bytes)
|
||||
* if the application processes data quickly.
|
||||
*/
|
||||
@@ -328,7 +328,7 @@
|
||||
|
||||
/* The link level header length.
|
||||
*
|
||||
* This is the offset into the uip_buf where the IP header can be
|
||||
* This is the offset into the d_buf where the IP header can be
|
||||
* found. For Ethernet, this should be set to 14. For SLIP, this
|
||||
* should be set to 0.
|
||||
*/
|
||||
|
||||
@@ -90,6 +90,7 @@ depend: .depend
|
||||
|
||||
clean:
|
||||
rm -f $(BIN) *.o *.rel *.asm *.lst *.sym *.adb *~
|
||||
rm -f uip/*~
|
||||
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
|
||||
|
||||
distclean: clean
|
||||
|
||||
+72
-12
@@ -47,7 +47,55 @@
|
||||
#include "net-internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
* Function: connection_event
|
||||
*
|
||||
* Description:
|
||||
* Some connection related event has occurred
|
||||
*
|
||||
* Parameters:
|
||||
* dev The sructure of the network driver that caused the interrupt
|
||||
* private An instance of struct recvfrom_s cast to void*
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void connection_event(void *private)
|
||||
{
|
||||
FAR struct socket *psock = (FAR struct socket *)private;
|
||||
if (psock)
|
||||
{
|
||||
/* UIP_CLOSE: The remote host has closed the connection
|
||||
* UIP_ABORT: The remote host has aborted the connection
|
||||
* UIP_TIMEDOUT: Connection aborted due to too many retransmissions.
|
||||
*/
|
||||
if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
/* Indicate that the socet is no longer connected */
|
||||
|
||||
psock->s_flags &= ~_SF_CONNECTED;
|
||||
}
|
||||
|
||||
/* UIP_CONNECTED: The socket is successfully connected */
|
||||
|
||||
else if ((uip_flags & UIP_CONNECTED) != 0)
|
||||
{
|
||||
/* Indicate that the socet is no longer connected */
|
||||
|
||||
psock->s_flags |= _SF_CONNECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
@@ -128,6 +176,7 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
|
||||
#endif
|
||||
int err;
|
||||
int ret;
|
||||
|
||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
||||
|
||||
@@ -155,7 +204,7 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
case SOCK_STREAM:
|
||||
{
|
||||
int ret;
|
||||
struct uip_conn *conn;
|
||||
|
||||
/* Verify that the socket is not already connected */
|
||||
|
||||
@@ -165,25 +214,36 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Perform the uIP connection operation */
|
||||
/* Get the connection reference from the socket */
|
||||
|
||||
ret = uip_tcpconnect(psock->s_conn, inaddr);
|
||||
if (ret < 0)
|
||||
conn = psock->s_conn;
|
||||
if (conn) /* Should alwasy be non-NULL */
|
||||
{
|
||||
err = -ret;
|
||||
goto errout;
|
||||
/* Perform the uIP connection operation */
|
||||
|
||||
ret = uip_tcpconnect(psock->s_conn, inaddr);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Mark the connection bound and connected */
|
||||
|
||||
psock->s_flags |= (_SF_BOUND|_SF_CONNECTED);
|
||||
|
||||
/* Set up to receive callbacks on connection-related events */
|
||||
|
||||
conn->connection_private = (void*)psock;
|
||||
conn->connection_event = connection_event;
|
||||
}
|
||||
|
||||
/* Mark the connection bound and connected */
|
||||
|
||||
psock->s_flags |= (_SF_BOUND|_SF_CONNECTED);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
case SOCK_DGRAM:
|
||||
{
|
||||
int ret = uip_udpconnect(psock->s_conn, inaddr);
|
||||
ret = uip_udpconnect(psock->s_conn, inaddr);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
|
||||
+77
-27
@@ -46,6 +46,7 @@
|
||||
#include <errno.h>
|
||||
#include <arch/irq.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
#include "net-internal.h"
|
||||
|
||||
@@ -78,7 +79,26 @@ struct recvfrom_s
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void recvfrom_interrupt(void *private)
|
||||
/****************************************************************************
|
||||
* Function: recvfrom_interrupt
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the interrupt level to perform the actual
|
||||
* receive operation via by the uIP layer.
|
||||
*
|
||||
* Parameters:
|
||||
* dev The sructure of the network driver that caused the interrupt
|
||||
* private An instance of struct recvfrom_s cast to void*
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
|
||||
{
|
||||
struct recvfrom_s *pstate = (struct recvfrom_s *)private;
|
||||
FAR struct socket *psock;
|
||||
@@ -97,18 +117,18 @@ static void recvfrom_interrupt(void *private)
|
||||
if (uip_newdata())
|
||||
{
|
||||
/* Get the length of the data to return */
|
||||
if (uip_len > pstate->rf_buflen)
|
||||
if (dev->d_len > pstate->rf_buflen)
|
||||
{
|
||||
recvlen = pstate->rf_buflen;
|
||||
}
|
||||
else
|
||||
{
|
||||
recvlen = uip_len;
|
||||
recvlen = dev->d_len;
|
||||
}
|
||||
|
||||
/* Copy the new appdata into the user buffer */
|
||||
|
||||
memcpy(pstate->rf_buffer, uip_appdata, recvlen);
|
||||
memcpy(pstate->rf_buffer, dev->d_appdata, recvlen);
|
||||
|
||||
/* Update the accumulated size of the data read */
|
||||
|
||||
@@ -127,9 +147,9 @@ static void recvfrom_interrupt(void *private)
|
||||
|
||||
/* Don't allow any further UDP call backs. */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->callback = NULL;
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
|
||||
/* Wake up the waiting thread, returning the number of bytes
|
||||
* actually read.
|
||||
@@ -149,9 +169,9 @@ static void recvfrom_interrupt(void *private)
|
||||
* Don't allow any further TCP call backs.
|
||||
*/
|
||||
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
|
||||
/* Wake up the waiting thread, returning the number of bytes
|
||||
* actually read.
|
||||
@@ -169,6 +189,36 @@ static void recvfrom_interrupt(void *private)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check for a loss of connection */
|
||||
|
||||
else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
/* Stop further callbacks */
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
if (psock->s_type == SOCK_DGRAM)
|
||||
{
|
||||
struct uip_udp_conn *udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
struct uip_conn *conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
}
|
||||
|
||||
/* Report not connected */
|
||||
|
||||
pstate->rf_result = -ENOTCONN;
|
||||
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
sem_post(&pstate->rf_sem);
|
||||
}
|
||||
|
||||
/* No data has been received -- this is some other event... probably a
|
||||
* poll -- check for a timeout.
|
||||
*/
|
||||
@@ -221,9 +271,9 @@ static void recvfrom_interrupt(void *private)
|
||||
|
||||
/* Stop further callbacks */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->callback = NULL;
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
|
||||
/* Report a timeout error */
|
||||
|
||||
@@ -234,9 +284,9 @@ static void recvfrom_interrupt(void *private)
|
||||
{
|
||||
struct uip_conn *conn;
|
||||
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
|
||||
/* Report an error only if no data has been received */
|
||||
|
||||
@@ -329,7 +379,7 @@ static ssize_t recvfrom_result(int result, struct recvfrom_s *pstate)
|
||||
|
||||
if (pstate->rf_result < 0)
|
||||
{
|
||||
/* Return EGAIN on a timeout */
|
||||
/* Return EGAIN on a timeout or ENOTCONN on loss of connection */
|
||||
|
||||
return pstate->rf_result;
|
||||
}
|
||||
@@ -401,9 +451,9 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
|
||||
/* Set up the callback in the connection */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->callback = recvfrom_interrupt;
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->event = recvfrom_interrupt;
|
||||
|
||||
/* Enable the UDP socket */
|
||||
|
||||
@@ -420,8 +470,8 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
uip_udpdisable(psock->s_conn);
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->callback = NULL;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
irqrestore(save);
|
||||
|
||||
#warning "Needs to return server address"
|
||||
@@ -482,9 +532,9 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
|
||||
/* Set up the callback in the connection */
|
||||
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->private = (void*)&state;
|
||||
conn->callback = recvfrom_interrupt;
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = (void*)&state;
|
||||
conn->data_event = recvfrom_interrupt;
|
||||
|
||||
/* Wait for either the receive to complete or for an error/timeout to occur.
|
||||
* NOTES: (1) sem_wait will also terminate if a signal is received, (2)
|
||||
@@ -496,8 +546,8 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
|
||||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
irqrestore(save);
|
||||
|
||||
#warning "Needs to return server address"
|
||||
|
||||
+30
-12
@@ -78,13 +78,14 @@ struct send_s
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: send_Interrupt
|
||||
* Function: send_interrupt
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the interrupt level to perform the actual
|
||||
* send operation when polled by the uIP layer.
|
||||
*
|
||||
* Parameters:
|
||||
* dev The sructure of the network driver that caused the interrupt
|
||||
* private An instance of struct send_s cast to void*
|
||||
*
|
||||
* Returned Value:
|
||||
@@ -95,7 +96,7 @@ struct send_s
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void send_interrupt(void *private)
|
||||
static void send_interrupt(struct uip_driver_s *dev, void *private)
|
||||
{
|
||||
struct send_s *pstate = (struct send_s *)private;
|
||||
struct uip_conn *conn;
|
||||
@@ -108,11 +109,11 @@ static void send_interrupt(void *private)
|
||||
{
|
||||
if (pstate->snd_buflen > uip_mss())
|
||||
{
|
||||
uip_send(pstate->snd_buffer, uip_mss());
|
||||
uip_send(dev, pstate->snd_buffer, uip_mss());
|
||||
}
|
||||
else
|
||||
{
|
||||
uip_send(pstate->snd_buffer, pstate->snd_buflen);
|
||||
uip_send(dev, pstate->snd_buffer, pstate->snd_buflen);
|
||||
}
|
||||
|
||||
pstate->snd_state = STATE_DATA_SENT;
|
||||
@@ -146,9 +147,9 @@ static void send_interrupt(void *private)
|
||||
|
||||
/* Don't allow any further call backs. */
|
||||
|
||||
conn = (struct uip_conn *)pstate->snd_sock->s_conn;
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn = (struct uip_conn *)pstate->snd_sock->s_conn;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
|
||||
/* Wake up the waiting thread, returning the number of bytes
|
||||
* actually sent.
|
||||
@@ -157,6 +158,23 @@ static void send_interrupt(void *private)
|
||||
sem_post(&pstate->snd_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for a loss of connection */
|
||||
|
||||
else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
/* Stop further callbacks */
|
||||
|
||||
uip_udp_conn->private = NULL;
|
||||
uip_udp_conn->event = NULL;
|
||||
|
||||
/* Report not connected */
|
||||
|
||||
pstate->snd_sent = -ENOTCONN;
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
sem_post(&pstate->snd_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -275,9 +293,9 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags)
|
||||
{
|
||||
/* Set up the callback in the connection */
|
||||
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->private = (void*)&state;
|
||||
conn->callback = send_interrupt;
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = (void*)&state;
|
||||
conn->data_event = send_interrupt;
|
||||
|
||||
/* Wait for the send to complete or an error to occur: NOTES: (1)
|
||||
* sem_wait will also terminate if a signal is received, (2) interrupts
|
||||
@@ -289,8 +307,8 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags)
|
||||
|
||||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
}
|
||||
|
||||
sem_destroy(&state. snd_sem);
|
||||
|
||||
+56
-12
@@ -45,6 +45,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arch/irq.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
#include "net-internal.h"
|
||||
|
||||
@@ -61,32 +62,64 @@ struct sendto_s
|
||||
sem_t st_sem; /* Semaphore signals sendto completion */
|
||||
uint16 st_buflen; /* Length of send buffer (error if <0) */
|
||||
const char *st_buffer; /* Pointer to send buffer */
|
||||
int st_sndlen; /* Result of the send (length sent or negated errno) */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
void sendto_interrupt(void *private)
|
||||
/****************************************************************************
|
||||
* Function: sendto_interrupt
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the interrupt level to perform the actual
|
||||
* send operation when polled by the uIP layer.
|
||||
*
|
||||
* Parameters:
|
||||
* dev The sructure of the network driver that caused the interrupt
|
||||
* private An instance of struct sendto_s cast to void*
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
void sendto_interrupt(struct uip_driver_s *dev, void *private)
|
||||
{
|
||||
struct sendto_s *pstate = (struct sendto_s *)private;
|
||||
if (private)
|
||||
{
|
||||
/* Copy the user data into appdata and send it */
|
||||
/* Check if the connectin was rejected */
|
||||
|
||||
memcpy(uip_appdata, pstate->st_buffer, pstate->st_buflen);
|
||||
uip_udp_send(pstate->st_buflen);
|
||||
if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
pstate->st_sndlen = -ENOTCONN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the user data into d_appdata and send it */
|
||||
|
||||
/* Don't allow any furhter call backs. */
|
||||
memcpy(dev->d_appdata, pstate->st_buffer, pstate->st_buflen);
|
||||
uip_send(dev, dev->d_appdata, pstate->st_buflen);
|
||||
pstate->st_sndlen = pstate->st_buflen;
|
||||
}
|
||||
|
||||
uip_conn->private = NULL;
|
||||
uip_conn->callback = NULL;
|
||||
/* Don't allow any further call backs. */
|
||||
|
||||
uip_udp_conn->private = NULL;
|
||||
uip_udp_conn->event = NULL;
|
||||
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
sem_post(&pstate->st_sem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
@@ -242,8 +275,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||
/* Set up the callback in the connection */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->callback = sendto_interrupt;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->event = sendto_interrupt;
|
||||
|
||||
/* Enable the UDP socket */
|
||||
|
||||
@@ -260,8 +293,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
uip_udpdisable(psock->s_conn);
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->callback = NULL;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
irqrestore(save);
|
||||
|
||||
sem_destroy(&state.st_sem);
|
||||
@@ -269,7 +302,18 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||
/* Set the socket state to idle */
|
||||
|
||||
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
|
||||
return len;
|
||||
|
||||
/* Check for errors */
|
||||
|
||||
if (state.st_sndlen < 0)
|
||||
{
|
||||
err = -state.st_sndlen;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Sucess */
|
||||
|
||||
return state.st_sndlen;
|
||||
#else
|
||||
err = ENOSYS;
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -34,6 +34,6 @@
|
||||
############################################################################
|
||||
|
||||
UIP_ASRCS =
|
||||
UIP_CSRCS = uip-arp.c uip.c uip-fw.c uip-neighbor.c uip-split.c \
|
||||
UIP_CSRCS = uip-arp.c uip.c uip-send.c uip-fw.c uip-neighbor.c uip-split.c \
|
||||
uip-tcpconn.c uip-udpconn.c
|
||||
|
||||
|
||||
+55
-75
@@ -41,6 +41,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
#include <net/uip/uip-arp.h>
|
||||
|
||||
struct arp_hdr
|
||||
@@ -94,36 +95,29 @@ static uint8 i, c;
|
||||
static uint8 arptime;
|
||||
static uint8 tmpage;
|
||||
|
||||
#define BUF ((struct arp_hdr *)&uip_buf[0])
|
||||
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initialize the ARP module.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_init(void)
|
||||
#define BUF ((struct arp_hdr *)&dev->d_buf[0])
|
||||
#define IPBUF ((struct ethip_hdr *)&dev->d_buf[0])
|
||||
|
||||
/* Initialize the ARP module. */
|
||||
|
||||
void uip_arp_init(void)
|
||||
{
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
memset(arp_table[i].ipaddr, 0, 4);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Periodic ARP processing function.
|
||||
|
||||
/* Periodic ARP processing function.
|
||||
*
|
||||
* This function performs periodic timer processing in the ARP module
|
||||
* and should be called at regular intervals. The recommended interval
|
||||
* is 10 seconds between the calls.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_timer(void)
|
||||
|
||||
void uip_arp_timer(void)
|
||||
{
|
||||
struct arp_entry *tabptr;
|
||||
|
||||
|
||||
++arptime;
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
@@ -135,9 +129,7 @@ uip_arp_timer(void)
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
||||
static void uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
||||
{
|
||||
register struct arp_entry *tabptr;
|
||||
/* Walk through the ARP mapping table and try to find an entry to
|
||||
@@ -154,7 +146,7 @@ uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
||||
the IP address in this ARP table entry. */
|
||||
if(pipaddr[0] == tabptr->ipaddr[0] &&
|
||||
pipaddr[1] == tabptr->ipaddr[1]) {
|
||||
|
||||
|
||||
/* An old entry found, update this and return. */
|
||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||
tabptr->time = arptime;
|
||||
@@ -198,9 +190,8 @@ uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||
tabptr->time = arptime;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* ARP processing for incoming IP packets
|
||||
|
||||
/* ARP processing for incoming IP packets
|
||||
*
|
||||
* This function should be called by the device driver when an IP
|
||||
* packet has been received. The function will check if the address is
|
||||
@@ -208,16 +199,15 @@ uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
||||
* refreshed. If no ARP cache entry was found, a new one is created.
|
||||
*
|
||||
* This function expects an IP packet with a prepended Ethernet header
|
||||
* in the uip_buf[] buffer, and the length of the packet in the global
|
||||
* variable uip_len.
|
||||
* in the d_buf[] buffer, and the length of the packet in the field
|
||||
* d_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
void
|
||||
uip_arp_ipin(void)
|
||||
void uip_arp_ipin(void)
|
||||
{
|
||||
uip_len -= sizeof(struct uip_eth_hdr);
|
||||
|
||||
dev->d_len -= sizeof(struct uip_eth_hdr);
|
||||
|
||||
/* Only insert/update an entry if the source IP address of the
|
||||
incoming IP packet comes from a host on the local network. */
|
||||
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
|
||||
@@ -229,13 +219,12 @@ uip_arp_ipin(void)
|
||||
return;
|
||||
}
|
||||
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* 0 */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* ARP processing for incoming ARP packets.
|
||||
|
||||
/* ARP processing for incoming ARP packets.
|
||||
*
|
||||
* This function should be called by the device driver when an ARP
|
||||
* packet has been received. The function will act differently
|
||||
@@ -243,29 +232,27 @@ uip_arp_ipin(void)
|
||||
* that we previously sent out, the ARP cache will be filled in with
|
||||
* the values from the ARP reply. If the incoming ARP packet is an ARP
|
||||
* request for our IP address, an ARP reply packet is created and put
|
||||
* into the uip_buf[] buffer.
|
||||
* into the d_buf[] buffer.
|
||||
*
|
||||
* When the function returns, the value of the global variable uip_len
|
||||
* When the function returns, the value of the field d_len
|
||||
* indicates whether the device driver should send out a packet or
|
||||
* not. If uip_len is zero, no packet should be sent. If uip_len is
|
||||
* not. If d_len is zero, no packet should be sent. If d_len is
|
||||
* non-zero, it contains the length of the outbound packet that is
|
||||
* present in the uip_buf[] buffer.
|
||||
* present in the d_buf[] buffer.
|
||||
*
|
||||
* This function expects an ARP packet with a prepended Ethernet
|
||||
* header in the uip_buf[] buffer, and the length of the packet in the
|
||||
* global variable uip_len.
|
||||
* header in the d_buf[] buffer, and the length of the packet in the
|
||||
* global variable d_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_arpin(void)
|
||||
|
||||
void uip_arp_arpin(struct uip_driver_s *dev)
|
||||
{
|
||||
|
||||
if(uip_len < sizeof(struct arp_hdr)) {
|
||||
uip_len = 0;
|
||||
if(dev->d_len < sizeof(struct arp_hdr)) {
|
||||
dev->d_len = 0;
|
||||
return;
|
||||
}
|
||||
uip_len = 0;
|
||||
|
||||
dev->d_len = 0;
|
||||
|
||||
switch(BUF->opcode) {
|
||||
case HTONS(ARP_REQUEST):
|
||||
/* ARP request. If it asked for our address, we send out a
|
||||
@@ -275,7 +262,7 @@ uip_arp_arpin(void)
|
||||
table, since it is likely that we will do more communication
|
||||
with this host in the future. */
|
||||
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
|
||||
|
||||
|
||||
/* The reply opcode is 2. */
|
||||
BUF->opcode = HTONS(2);
|
||||
|
||||
@@ -283,14 +270,14 @@ uip_arp_arpin(void)
|
||||
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
|
||||
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
|
||||
|
||||
|
||||
BUF->dipaddr[0] = BUF->sipaddr[0];
|
||||
BUF->dipaddr[1] = BUF->sipaddr[1];
|
||||
BUF->sipaddr[0] = uip_hostaddr[0];
|
||||
BUF->sipaddr[1] = uip_hostaddr[1];
|
||||
|
||||
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
|
||||
uip_len = sizeof(struct arp_hdr);
|
||||
dev->d_len = sizeof(struct arp_hdr);
|
||||
}
|
||||
break;
|
||||
case HTONS(ARP_REPLY):
|
||||
@@ -304,9 +291,8 @@ uip_arp_arpin(void)
|
||||
|
||||
return;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Prepend Ethernet header to an outbound IP packet and see if we need
|
||||
|
||||
/* Prepend Ethernet header to an outbound IP packet and see if we need
|
||||
* to send out an ARP request.
|
||||
*
|
||||
* This function should be called before sending out an IP packet. The
|
||||
@@ -319,7 +305,7 @@ uip_arp_arpin(void)
|
||||
* checks the ARP cache to see if an entry for the destination IP
|
||||
* address is found. If so, an Ethernet header is prepended and the
|
||||
* function returns. If no ARP cache entry is found for the
|
||||
* destination IP address, the packet in the uip_buf[] is replaced by
|
||||
* destination IP address, the packet in the d_buf[] is replaced by
|
||||
* an ARP request packet for the IP address. The IP packet is dropped
|
||||
* and it is assumed that they higher level protocols (e.g., TCP)
|
||||
* eventually will retransmit the dropped packet.
|
||||
@@ -327,16 +313,14 @@ uip_arp_arpin(void)
|
||||
* If the destination IP address is not on the local network, the IP
|
||||
* address of the default router is used instead.
|
||||
*
|
||||
* When the function returns, a packet is present in the uip_buf[]
|
||||
* buffer, and the length of the packet is in the global variable
|
||||
* uip_len.
|
||||
* When the function returns, a packet is present in the d_buf[]
|
||||
* buffer, and the length of the packet is in the field d_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_out(void)
|
||||
|
||||
void uip_arp_out(struct uip_driver_s *dev)
|
||||
{
|
||||
struct arp_entry *tabptr;
|
||||
|
||||
|
||||
/* Find the destination IP address in the ARP table and construct
|
||||
the Ethernet header. If the destination IP addres isn't on the
|
||||
local network, we use the default router's IP address instead.
|
||||
@@ -358,7 +342,7 @@ uip_arp_out(void)
|
||||
/* Else, we use the destination IP address. */
|
||||
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
|
||||
@@ -374,7 +358,7 @@ uip_arp_out(void)
|
||||
memset(BUF->dhwaddr.addr, 0x00, 6);
|
||||
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
|
||||
|
||||
|
||||
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
|
||||
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
|
||||
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
|
||||
@@ -384,9 +368,9 @@ uip_arp_out(void)
|
||||
BUF->protolen = 4;
|
||||
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
|
||||
|
||||
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
|
||||
|
||||
uip_len = sizeof(struct arp_hdr);
|
||||
dev->d_appdata = &dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
|
||||
|
||||
dev->d_len = sizeof(struct arp_hdr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -394,12 +378,8 @@ uip_arp_out(void)
|
||||
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
|
||||
}
|
||||
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||
|
||||
|
||||
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
|
||||
|
||||
uip_len += sizeof(struct uip_eth_hdr);
|
||||
dev->d_len += sizeof(struct uip_eth_hdr);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
+95
-137
@@ -33,6 +33,8 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <debug.h>
|
||||
#include <net/uip/uip.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
@@ -40,17 +42,16 @@
|
||||
|
||||
#include <string.h> /* for memcpy() */
|
||||
|
||||
/*
|
||||
* The list of registered network interfaces.
|
||||
*/
|
||||
/* The list of registered network interfaces. */
|
||||
|
||||
static struct uip_fw_netif *netifs = NULL;
|
||||
|
||||
/*
|
||||
* A pointer to the default network interface.
|
||||
*/
|
||||
/* A pointer to the default network interface. */
|
||||
|
||||
static struct uip_fw_netif *defaultnetif = NULL;
|
||||
|
||||
struct tcpip_hdr {
|
||||
struct tcpip_hdr
|
||||
{
|
||||
/* IP header. */
|
||||
uint8 vhl,
|
||||
tos;
|
||||
@@ -101,23 +102,19 @@ struct icmpip_hdr {
|
||||
/* ICMP TIME-EXCEEDED. */
|
||||
#define ICMP_TE 11
|
||||
|
||||
/*
|
||||
* Pointer to the TCP/IP headers of the packet in the uip_buf buffer.
|
||||
*/
|
||||
#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/* Pointer to the TCP/IP headers of the packet in the d_buf buffer. */
|
||||
#define BUF ((struct tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
|
||||
/*
|
||||
* Pointer to the ICMP/IP headers of the packet in the uip_buf buffer.
|
||||
*/
|
||||
#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/* Pointer to the ICMP/IP headers of the packet in the d_buf buffer. */
|
||||
#define ICMPBUF ((struct icmpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
|
||||
/*
|
||||
* Certain fields of an IP packet that are used for identifying
|
||||
/* Certain fields of an IP packet that are used for identifying
|
||||
* duplicate packets.
|
||||
*/
|
||||
struct fwcache_entry {
|
||||
uint16 timer;
|
||||
|
||||
struct fwcache_entry
|
||||
{
|
||||
uint16 timer;
|
||||
uint16 srcipaddr[2];
|
||||
uint16 destipaddr[2];
|
||||
uint16 ipid;
|
||||
@@ -133,35 +130,25 @@ struct fwcache_entry {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* The number of packets to remember when looking for duplicates.
|
||||
*/
|
||||
/* The number of packets to remember when looking for duplicates. */
|
||||
#ifdef CONFIG_NET_FWCACHE_SIZE
|
||||
# define FWCACHE_SIZE CONFIG_NET_FWCACHE_SIZE
|
||||
#else
|
||||
# define FWCACHE_SIZE 2
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* A cache of packet header fields which are used for
|
||||
/* A cache of packet header fields which are used for
|
||||
* identifying duplicate packets.
|
||||
*/
|
||||
|
||||
static struct fwcache_entry fwcache[FWCACHE_SIZE];
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* The time that a packet cache is active.
|
||||
*/
|
||||
/* The time that a packet cache is active. */
|
||||
#define FW_TIME 20
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initialize the uIP packet forwarding module.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_init(void)
|
||||
/* Initialize the uIP packet forwarding module. */
|
||||
|
||||
void uip_fw_init(void)
|
||||
{
|
||||
struct uip_fw_netif *t;
|
||||
defaultnetif = NULL;
|
||||
@@ -171,42 +158,36 @@ uip_fw_init(void)
|
||||
t->next = NULL;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Check if an IP address is within the network defined by an IP
|
||||
|
||||
/* Check if an IP address is within the network defined by an IP
|
||||
* address and a netmask.
|
||||
*
|
||||
* \param ipaddr The IP address to be checked.
|
||||
* \param netipaddr The IP address of the network.
|
||||
* \param netmask The netmask of the network.
|
||||
* ipaddr The IP address to be checked.
|
||||
* netipaddr The IP address of the network.
|
||||
* netmask The netmask of the network.
|
||||
*
|
||||
* \return Non-zero if IP address is in network, zero otherwise.
|
||||
* Return: Non-zero if IP address is in network, zero otherwise.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static unsigned char
|
||||
ipaddr_maskcmp(uint16 *ipaddr, uint16 *netipaddr, uint16 *netmask)
|
||||
|
||||
static unsigned char ipaddr_maskcmp(uint16 *ipaddr, uint16 *netipaddr, uint16 *netmask)
|
||||
{
|
||||
return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
|
||||
(ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Send out an ICMP TIME-EXCEEDED message.
|
||||
|
||||
/* Send out an ICMP TIME-EXCEEDED message.
|
||||
*
|
||||
* This function replaces the packet in the uip_buf buffer with the
|
||||
* This function replaces the packet in the d_buf buffer with the
|
||||
* ICMP packet.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static void
|
||||
time_exceeded(void)
|
||||
|
||||
static void time_exceeded(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 tmp16;
|
||||
|
||||
/* We don't send out ICMP errors for ICMP messages. */
|
||||
if(ICMPBUF->proto == UIP_PROTO_ICMP) {
|
||||
uip_len = 0;
|
||||
dev->d_len = 0;
|
||||
return;
|
||||
}
|
||||
/* Copy fields from packet header into payload of this ICMP packet. */
|
||||
@@ -235,9 +216,9 @@ time_exceeded(void)
|
||||
|
||||
/* The size of the ICMP time exceeded packet is 36 + the size of the
|
||||
IP header (20) = 56. */
|
||||
uip_len = 56;
|
||||
dev->d_len = 56;
|
||||
ICMPBUF->len[0] = 0;
|
||||
ICMPBUF->len[1] = uip_len;
|
||||
ICMPBUF->len[1] = dev->d_len;
|
||||
|
||||
/* Fill in the other fields in the IP header. */
|
||||
ICMPBUF->vhl = 0x45;
|
||||
@@ -245,29 +226,24 @@ time_exceeded(void)
|
||||
ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
|
||||
ICMPBUF->ttl = UIP_TTL;
|
||||
ICMPBUF->proto = UIP_PROTO_ICMP;
|
||||
|
||||
|
||||
/* Calculate IP checksum. */
|
||||
ICMPBUF->ipchksum = 0;
|
||||
ICMPBUF->ipchksum = ~(uip_ipchksum());
|
||||
|
||||
|
||||
ICMPBUF->ipchksum = ~(uip_ipchksum(dev));
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Register a packet in the forwarding cache so that it won't be
|
||||
|
||||
/* Register a packet in the forwarding cache so that it won't be
|
||||
* forwarded again.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static void
|
||||
fwcache_register(void)
|
||||
|
||||
static void fwcache_register(struct uip_driver_s *dev)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
int i, oldest;
|
||||
|
||||
oldest = FW_TIME;
|
||||
fw = NULL;
|
||||
|
||||
|
||||
/* Find the oldest entry in the cache. */
|
||||
for(i = 0; i < FWCACHE_SIZE; ++i) {
|
||||
if(fwcache[i].timer == 0) {
|
||||
@@ -295,17 +271,13 @@ fwcache_register(void)
|
||||
fw->offset = BUF->ipoffset;
|
||||
#endif
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Find a network interface for the IP packet in uip_buf.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static struct uip_fw_netif *
|
||||
find_netif(void)
|
||||
|
||||
/* Find a network interface for the IP packet in d_buf. */
|
||||
|
||||
static struct uip_fw_netif *find_netif(struct uip_driver_s *dev)
|
||||
{
|
||||
struct uip_fw_netif *netif;
|
||||
|
||||
|
||||
/* Walk through every network interface to check for a match. */
|
||||
for(netif = netifs; netif != NULL; netif = netif->next) {
|
||||
if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
|
||||
@@ -314,37 +286,35 @@ find_netif(void)
|
||||
return netif;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If no matching netif was found, we use default netif. */
|
||||
return defaultnetif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Output an IP packet on the correct network interface.
|
||||
|
||||
/* Output an IP packet on the correct network interface.
|
||||
*
|
||||
* The IP packet should be present in the uip_buf buffer and its
|
||||
* length in the global uip_len variable.
|
||||
* The IP packet should be present in the d_buf buffer and its
|
||||
* length in the d_len field.
|
||||
*
|
||||
* \retval UIP_FW_ZEROLEN Indicates that a zero-length packet
|
||||
* Return: UIP_FW_ZEROLEN Indicates that a zero-length packet
|
||||
* transmission was attempted and that no packet was sent.
|
||||
*
|
||||
* \retval UIP_FW_NOROUTE No suitable network interface could be found
|
||||
* Return: UIP_FW_NOROUTE No suitable network interface could be found
|
||||
* for the outbound packet, and the packet was not sent.
|
||||
*
|
||||
* \return The return value from the actual network interface output
|
||||
* Return: The return value from the actual network interface output
|
||||
* function is passed unmodified as a return value.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
uint8
|
||||
uip_fw_output(void)
|
||||
|
||||
uint8 uip_fw_output(struct uip_driver_s *dev)
|
||||
{
|
||||
struct uip_fw_netif *netif;
|
||||
|
||||
if(uip_len == 0) {
|
||||
if(dev->d_len == 0) {
|
||||
return UIP_FW_ZEROLEN;
|
||||
}
|
||||
|
||||
fwcache_register();
|
||||
fwcache_register(dev);
|
||||
|
||||
#if UIP_BROADCAST
|
||||
/* Link local broadcasts go out on all interfaces. */
|
||||
@@ -360,11 +330,9 @@ uip_fw_output(void)
|
||||
return UIP_FW_OK;
|
||||
}
|
||||
#endif /* UIP_BROADCAST */
|
||||
|
||||
netif = find_netif();
|
||||
/* printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
|
||||
netif->output,
|
||||
uip_len);*/
|
||||
|
||||
netif = find_netif(dev);
|
||||
dbg("uip_fw_output: netif %p ->output %p len %d\n", netif, netif->output, dev->d_len);
|
||||
|
||||
if(netif == NULL) {
|
||||
return UIP_FW_NOROUTE;
|
||||
@@ -373,18 +341,14 @@ uip_fw_output(void)
|
||||
output function to send out the packet. */
|
||||
return netif->output();
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Forward an IP packet in the uip_buf buffer.
|
||||
|
||||
/* Forward an IP packet in the d_buf buffer.
|
||||
*
|
||||
*
|
||||
*
|
||||
* \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
|
||||
* Return: UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
|
||||
* the packet should be processed locally.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
uint8
|
||||
uip_fw_forward(void)
|
||||
|
||||
uint8 uip_fw_forward(struct uip_driver_s *dev)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
|
||||
@@ -430,19 +394,21 @@ uip_fw_forward(void)
|
||||
}
|
||||
|
||||
/* If the TTL reaches zero we produce an ICMP time exceeded message
|
||||
in the uip_buf buffer and forward that packet back to the sender
|
||||
of the packet. */
|
||||
in the d_buf buffer and forward that packet back to the sender
|
||||
of the packet.
|
||||
*/
|
||||
|
||||
if(BUF->ttl <= 1) {
|
||||
/* No time exceeded for broadcasts and multicasts! */
|
||||
if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
|
||||
return UIP_FW_LOCAL;
|
||||
}
|
||||
time_exceeded();
|
||||
time_exceeded(dev);
|
||||
}
|
||||
|
||||
|
||||
/* Decrement the TTL (time-to-live) value in the IP header */
|
||||
BUF->ttl = BUF->ttl - 1;
|
||||
|
||||
|
||||
/* Update the IP checksum. */
|
||||
if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
|
||||
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
|
||||
@@ -450,9 +416,9 @@ uip_fw_forward(void)
|
||||
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
|
||||
}
|
||||
|
||||
if(uip_len > 0) {
|
||||
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
|
||||
uip_fw_output();
|
||||
if(dev->d_len > 0) {
|
||||
dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
|
||||
uip_fw_output(dev);
|
||||
}
|
||||
|
||||
#if UIP_BROADCAST
|
||||
@@ -465,43 +431,36 @@ uip_fw_forward(void)
|
||||
other processing should be made. */
|
||||
return UIP_FW_FORWARDED;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Register a network interface with the forwarding module.
|
||||
|
||||
/* Register a network interface with the forwarding module.
|
||||
*
|
||||
* \param netif A pointer to the network interface that is to be
|
||||
* netif A pointer to the network interface that is to be
|
||||
* registered.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_register(struct uip_fw_netif *netif)
|
||||
|
||||
void uip_fw_register(struct uip_fw_netif *netif)
|
||||
{
|
||||
netif->next = netifs;
|
||||
netifs = netif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Register a default network interface.
|
||||
|
||||
/* Register a default network interface.
|
||||
*
|
||||
* All packets that don't go out on any of the other interfaces will
|
||||
* be routed to the default interface.
|
||||
*
|
||||
* \param netif A pointer to the network interface that is to be
|
||||
* netif A pointer to the network interface that is to be
|
||||
* registered.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_default(struct uip_fw_netif *netif)
|
||||
|
||||
void uip_fw_default(struct uip_fw_netif *netif)
|
||||
{
|
||||
defaultnetif = netif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Perform periodic processing.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_periodic(void)
|
||||
|
||||
/* Perform periodic processing. */
|
||||
|
||||
void uip_fw_periodic(void)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
|
||||
@@ -510,4 +469,3 @@ uip_fw_periodic(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
+33
-57
@@ -60,116 +60,92 @@ struct uip_fw_netif
|
||||
sends a packet. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Intantiating macro for a uIP network interface.
|
||||
/* Intantiating macro for a uIP network interface.
|
||||
*
|
||||
* Example:
|
||||
\code
|
||||
struct uip_fw_netif slipnetif =
|
||||
{UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
|
||||
\endcode
|
||||
* \param ip1,ip2,ip3,ip4 The IP address of the network interface.
|
||||
*
|
||||
* \param nm1,nm2,nm3,nm4 The netmask of the network interface.
|
||||
* struct uip_fw_netif slipnetif =
|
||||
* {UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
|
||||
*
|
||||
* \param outputfunc A pointer to the output function of the network interface.
|
||||
* ip1,ip2,ip3,ip4 The IP address of the network interface.
|
||||
*
|
||||
* \hideinitializer
|
||||
* nm1,nm2,nm3,nm4 The netmask of the network interface.
|
||||
*
|
||||
* outputfunc A pointer to the output function of the network interface.
|
||||
*/
|
||||
|
||||
#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
|
||||
NULL, \
|
||||
{HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \
|
||||
{HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \
|
||||
outputfunc
|
||||
|
||||
/**
|
||||
* Set the IP address of a network interface.
|
||||
/* Set the IP address of a network interface.
|
||||
*
|
||||
* \param netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
* netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
*
|
||||
* \param addr A pointer to an IP address.
|
||||
*
|
||||
* \hideinitializer
|
||||
* addr A pointer to an IP address.
|
||||
*/
|
||||
|
||||
#define uip_fw_setipaddr(netif, addr) \
|
||||
do { (netif)->ipaddr[0] = ((uint16 *)(addr))[0]; \
|
||||
(netif)->ipaddr[1] = ((uint16 *)(addr))[1]; } while(0)
|
||||
/**
|
||||
* Set the netmask of a network interface.
|
||||
|
||||
/* Set the netmask of a network interface.
|
||||
*
|
||||
* \param netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
* netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
*
|
||||
* \param addr A pointer to an IP address representing the netmask.
|
||||
*
|
||||
* \hideinitializer
|
||||
* addr A pointer to an IP address representing the netmask.
|
||||
*/
|
||||
|
||||
#define uip_fw_setnetmask(netif, addr) \
|
||||
do { (netif)->netmask[0] = ((uint16 *)(addr))[0]; \
|
||||
(netif)->netmask[1] = ((uint16 *)(addr))[1]; } while(0)
|
||||
|
||||
void uip_fw_init(void);
|
||||
uint8 uip_fw_forward(void);
|
||||
uint8 uip_fw_output(void);
|
||||
uint8 uip_fw_forward(struct uip_driver_s *dev);
|
||||
uint8 uip_fw_output(struct uip_driver_s *dev);
|
||||
void uip_fw_register(struct uip_fw_netif *netif);
|
||||
void uip_fw_default(struct uip_fw_netif *netif);
|
||||
void uip_fw_periodic(void);
|
||||
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet should be
|
||||
/* A non-error message that indicates that a packet should be
|
||||
* processed locally.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_LOCAL 0
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that something went OK.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
/* A non-error message that indicates that something went OK. */
|
||||
|
||||
#define UIP_FW_OK 0
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet was forwarded.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
/* A non-error message that indicates that a packet was forwarded. */
|
||||
|
||||
#define UIP_FW_FORWARDED 1
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a zero-length packet
|
||||
/* A non-error message that indicates that a zero-length packet
|
||||
* transmission was attempted, and that no packet was sent.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_ZEROLEN 2
|
||||
|
||||
/**
|
||||
* An error message that indicates that a packet that was too large
|
||||
/* An error message that indicates that a packet that was too large
|
||||
* for the outbound network interface was detected.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_TOOLARGE 3
|
||||
|
||||
/**
|
||||
* An error message that indicates that no suitable interface could be
|
||||
/* An error message that indicates that no suitable interface could be
|
||||
* found for an outbound packet.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_NOROUTE 4
|
||||
|
||||
/**
|
||||
* An error message that indicates that a packet that should be
|
||||
/* An error message that indicates that a packet that should be
|
||||
* forwarded or output was dropped.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_DROPPED 5
|
||||
|
||||
|
||||
#endif /* __UIP_FW_H__ */
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
* uip-send.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Based in part on uIP which also has a BSD stylie license:
|
||||
*
|
||||
* Author: Adam Dunkels <adam@dunkels.com>
|
||||
* Copyright (c) 2001-2003, Adam Dunkels.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <net/uip/uip.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_send
|
||||
*
|
||||
* Description:
|
||||
* Called from socket logic in response to a xmit or poll request from the
|
||||
* the network interface driver.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from the interrupt level or, at a mimimum, with interrupts
|
||||
* disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void uip_send(struct uip_driver_s *dev, const void *buf, int len)
|
||||
{
|
||||
if (dev && len > 0 && len < UIP_BUFSIZE)
|
||||
{
|
||||
dev->d_sndlen = len;
|
||||
memcpy(dev->d_snddata, buf, len );
|
||||
}
|
||||
}
|
||||
+22
-26
@@ -38,19 +38,17 @@
|
||||
#include "uip-split.h"
|
||||
#include "uip-fw.h"
|
||||
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define BUF ((struct uip_tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_split_output(void)
|
||||
void uip_split_output(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 tcplen, len1, len2;
|
||||
|
||||
/* We only try to split maximum sized TCP segments. */
|
||||
if(BUF->proto == UIP_PROTO_TCP &&
|
||||
uip_len == UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
dev->d_len == UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
|
||||
tcplen = uip_len - UIP_TCPIP_HLEN;
|
||||
tcplen = dev->d_len - UIP_TCPIP_HLEN;
|
||||
/* Split the segment in two. If the original packet length was
|
||||
odd, we make the second packet one byte larger. */
|
||||
len1 = len2 = tcplen / 2;
|
||||
@@ -60,49 +58,49 @@ uip_split_output(void)
|
||||
|
||||
/* Create the first packet. This is done by altering the length
|
||||
field of the IP header and updating the checksums. */
|
||||
uip_len = len1 + UIP_TCPIP_HLEN;
|
||||
dev->d_len = len1 + UIP_TCPIP_HLEN;
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
BUF->len[0] = uip_len >> 8;
|
||||
BUF->len[1] = uip_len & 0xff;
|
||||
BUF->len[0] = dev->d_len >> 8;
|
||||
BUF->len[1] = dev->d_len & 0xff;
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* Recalculate the TCP checksum. */
|
||||
BUF->tcpchksum = 0;
|
||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
||||
BUF->tcpchksum = ~(uip_tcpchksum(dev));
|
||||
|
||||
#ifndef CONFIG_NET_IPv6
|
||||
/* Recalculate the IP checksum. */
|
||||
BUF->ipchksum = 0;
|
||||
BUF->ipchksum = ~(uip_ipchksum());
|
||||
BUF->ipchksum = ~(uip_ipchksum(dev));
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
|
||||
/* Transmit the first packet. */
|
||||
/* uip_fw_output();*/
|
||||
tcpip_output();
|
||||
|
||||
/* Now, create the second packet. To do this, it is not enough to
|
||||
just alter the length field, but we must also update the TCP
|
||||
sequence number and point the uip_appdata to a new place in
|
||||
sequence number and point the d_appdata to a new place in
|
||||
memory. This place is detemined by the length of the first
|
||||
packet (len1). */
|
||||
uip_len = len2 + UIP_TCPIP_HLEN;
|
||||
dev->d_len = len2 + UIP_TCPIP_HLEN;
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
BUF->len[0] = uip_len >> 8;
|
||||
BUF->len[1] = uip_len & 0xff;
|
||||
BUF->len[0] = dev->d_len >> 8;
|
||||
BUF->len[1] = dev->d_len & 0xff;
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* uip_appdata += len1;*/
|
||||
memcpy(uip_appdata, (uint8 *)uip_appdata + len1, len2);
|
||||
/* dev->d_appdata += len1;*/
|
||||
memcpy(dev->d_appdata, dev->d_appdata + len1, len2);
|
||||
|
||||
uip_add32(BUF->seqno, len1);
|
||||
BUF->seqno[0] = uip_acc32[0];
|
||||
@@ -112,12 +110,12 @@ uip_split_output(void)
|
||||
|
||||
/* Recalculate the TCP checksum. */
|
||||
BUF->tcpchksum = 0;
|
||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
||||
BUF->tcpchksum = ~(uip_tcpchksum(dev));
|
||||
|
||||
#ifndef CONFIG_NET_IPv6
|
||||
/* Recalculate the IP checksum. */
|
||||
BUF->ipchksum = 0;
|
||||
BUF->ipchksum = ~(uip_ipchksum());
|
||||
BUF->ipchksum = ~(uip_ipchksum(dev));
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* Transmit the second packet. */
|
||||
@@ -127,6 +125,4 @@ uip_split_output(void)
|
||||
/* uip_fw_output();*/
|
||||
tcpip_output();
|
||||
}
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
||||
+7
-8
@@ -66,23 +66,22 @@
|
||||
#ifndef __UIP_SPLIT_H__
|
||||
#define __UIP_SPLIT_H__
|
||||
|
||||
/**
|
||||
* Handle outgoing packets.
|
||||
/* Handle outgoing packets.
|
||||
*
|
||||
* This function inspects an outgoing packet in the uip_buf buffer and
|
||||
* This function inspects an outgoing packet in the d_buf buffer and
|
||||
* sends it out using the uip_fw_output() function. If the packet is a
|
||||
* full-sized TCP segment it will be split into two segments and
|
||||
* transmitted separately. This function should be called instead of
|
||||
* the actual device driver output function, or the uip_fw_output()
|
||||
* function.
|
||||
*
|
||||
* The headers of the outgoing packet is assumed to be in the uip_buf
|
||||
* buffer and the payload is assumed to be wherever uip_appdata
|
||||
* The headers of the outgoing packet is assumed to be in the d_buf
|
||||
* buffer and the payload is assumed to be wherever d_appdata
|
||||
* points. The length of the outgoing packet is assumed to be in the
|
||||
* uip_len variable.
|
||||
*
|
||||
* d_len field.
|
||||
*/
|
||||
void uip_split_output(void);
|
||||
|
||||
void uip_split_output(struct uip_driver_s *dev);
|
||||
|
||||
#endif /* __UIP_SPLIT_H__ */
|
||||
|
||||
|
||||
@@ -434,10 +434,10 @@ struct uip_conn *uip_tcplistener(struct uip_tcpip_hdr *buf)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void uip_tcppoll(unsigned int conn)
|
||||
void uip_tcppoll(struct uip_driver_s *dev, unsigned int conn)
|
||||
{
|
||||
uip_conn = &g_tcp_connections[conn];
|
||||
uip_interrupt(UIP_TIMER);
|
||||
uip_interrupt(dev, UIP_TIMER);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -282,10 +282,10 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void uip_udppoll(unsigned int conn)
|
||||
void uip_udppoll(struct uip_driver_s *dev, unsigned int conn)
|
||||
{
|
||||
uip_udp_conn = &g_udp_connections[conn];
|
||||
uip_interrupt(UIP_UDP_TIMER);
|
||||
uip_interrupt(dev, UIP_UDP_TIMER);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
+169
-174
File diff suppressed because it is too large
Load Diff
+222
-207
File diff suppressed because it is too large
Load Diff
@@ -57,6 +57,8 @@
|
||||
#include <net/uip/resolv.h>
|
||||
|
||||
#include "uiplib/uiplib.h"
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
#include "webclient.h"
|
||||
|
||||
#define WEBCLIENT_TIMEOUT 100
|
||||
@@ -178,14 +180,14 @@ static char *copy_string(char *dest, const char *src, int len)
|
||||
return dest + len;
|
||||
}
|
||||
|
||||
static void senddata(void)
|
||||
static void senddata(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 len;
|
||||
char *getrequest;
|
||||
char *cptr;
|
||||
|
||||
if (s.getrequestleft > 0) {
|
||||
cptr = getrequest = (char *)uip_appdata;
|
||||
cptr = getrequest = (char *)dev->d_appdata;
|
||||
|
||||
cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
|
||||
cptr = copy_string(cptr, s.file, strlen(s.file));
|
||||
@@ -204,7 +206,7 @@ static void senddata(void)
|
||||
len = s.getrequestleft > uip_mss()?
|
||||
uip_mss():
|
||||
s.getrequestleft;
|
||||
uip_send(&(getrequest[s.getrequestptr]), len);
|
||||
uip_send(dev, &(getrequest[s.getrequestptr]), len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,15 +223,15 @@ static void acked(void)
|
||||
}
|
||||
}
|
||||
|
||||
static uint16 parse_statusline(uint16 len)
|
||||
static uint16 parse_statusline(struct uip_driver_s *dev, uint16 len)
|
||||
{
|
||||
char *cptr;
|
||||
|
||||
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline))
|
||||
{
|
||||
char *pappdata = (char*)uip_appdata;
|
||||
char *pappdata = (char*)dev->d_appdata;
|
||||
s.httpheaderline[s.httpheaderlineptr] = *pappdata++;
|
||||
uip_appdata = (void*)pappdata;
|
||||
dev->d_appdata = (void*)pappdata;
|
||||
len--;
|
||||
|
||||
if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl)
|
||||
@@ -301,16 +303,16 @@ static char casecmp(char *str1, const char *str2, char len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16 parse_headers(uint16 len)
|
||||
static uint16 parse_headers(struct uip_driver_s *dev, uint16 len)
|
||||
{
|
||||
char *cptr;
|
||||
static unsigned char i;
|
||||
|
||||
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline))
|
||||
{
|
||||
char *pappdata = (char*)uip_appdata;
|
||||
char *pappdata = (char*)dev->d_appdata;
|
||||
s.httpheaderline[s.httpheaderlineptr] = *pappdata++;
|
||||
uip_appdata = (void*)pappdata;
|
||||
dev->d_appdata = (void*)pappdata;
|
||||
len--;
|
||||
|
||||
if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl)
|
||||
@@ -378,23 +380,23 @@ static uint16 parse_headers(uint16 len)
|
||||
return len;
|
||||
}
|
||||
|
||||
static void newdata(void)
|
||||
static void newdata(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 len;
|
||||
|
||||
len = uip_datalen();
|
||||
len = uip_datalen(dev);
|
||||
|
||||
if (s.state == WEBCLIENT_STATE_STATUSLINE) {
|
||||
len = parse_statusline(len);
|
||||
len = parse_statusline(dev, len);
|
||||
}
|
||||
|
||||
if (s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
|
||||
len = parse_headers(len);
|
||||
len = parse_headers(dev, len);
|
||||
}
|
||||
|
||||
if (len > 0 && s.state == WEBCLIENT_STATE_DATA &&
|
||||
s.httpflag != HTTPFLAG_MOVED) {
|
||||
webclient_datahandler((char *)uip_appdata, len);
|
||||
webclient_datahandler((char *)dev->d_appdata, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,14 +404,14 @@ static void newdata(void)
|
||||
* event of interest occurs.
|
||||
*/
|
||||
|
||||
void uip_interrupt_event(void)
|
||||
void uip_interrupt_event(struct uip_driver_s *dev)
|
||||
{
|
||||
#warning OBSOLETE -- needs to be redesigned
|
||||
if (uip_connected())
|
||||
{
|
||||
s.timer = 0;
|
||||
s.state = WEBCLIENT_STATE_STATUSLINE;
|
||||
senddata();
|
||||
senddata(dev);
|
||||
webclient_connected();
|
||||
return;
|
||||
}
|
||||
@@ -440,12 +442,12 @@ void uip_interrupt_event(void)
|
||||
if (uip_newdata())
|
||||
{
|
||||
s.timer = 0;
|
||||
newdata();
|
||||
newdata(dev);
|
||||
}
|
||||
|
||||
if (uip_rexmit() || uip_newdata() || uip_acked())
|
||||
{
|
||||
senddata();
|
||||
senddata(dev);
|
||||
}
|
||||
else if (uip_poll())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user