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:
patacongo
2007-09-15 22:45:45 +00:00
parent d63a0352a5
commit 23dcda6743
30 changed files with 1172 additions and 962 deletions
-3
View File
@@ -1391,9 +1391,6 @@ The system can be re-made subsequently by just typing <code>make</code>.
<li> <li>
<code>CONFIG_NET_LLH_LEN</code>: The link level header length <code>CONFIG_NET_LLH_LEN</code>: The link level header length
</li> </li>
<li>
<code>CONFIG_NET_EXTERNAL_BUFFER</code>: Incoming packet buffer (uip_buf) is defined externally
</li>
<li> <li>
<code>CONFIG_NET_FWCACHE_SIZE</code>: number of packets to remember when looking for duplicates <code>CONFIG_NET_FWCACHE_SIZE</code>: number of packets to remember when looking for duplicates
</li> </li>
+31 -30
View File
@@ -55,7 +55,7 @@
* Private Definitions * Private Definitions
****************************************************************************/ ****************************************************************************/
#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) #define BUF ((struct uip_eth_hdr *)g_sim_dev.d_buf)
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
@@ -75,8 +75,9 @@ struct timer
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
static struct timer periodic_timer; static struct timer g_periodic_timer;
static struct timer arp_timer; static struct timer g_arp_timer;
static struct uip_driver_s g_sim_dev;
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@@ -106,82 +107,82 @@ void uipdriver_loop(void)
{ {
int i; int i;
uip_len = tapdev_read((unsigned char*)uip_buf, UIP_BUFSIZE); g_sim_dev.d_len = tapdev_read((unsigned char*)g_sim_dev.d_buf, UIP_BUFSIZE);
if (uip_len > 0) if (g_sim_dev.d_len > 0)
{ {
if (BUF->type == htons(UIP_ETHTYPE_IP)) if (BUF->type == htons(UIP_ETHTYPE_IP))
{ {
uip_arp_ipin(); uip_arp_ipin();
uip_input(); uip_input(&g_sim_dev);
/* If the above function invocation resulted in data that /* If the above function invocation resulted in data that
* should be sent out on the network, the global variable * 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(); uip_arp_out(&g_sim_dev);
tapdev_send((char*)uip_buf, uip_len); tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
} }
} }
else if (BUF->type == htons(UIP_ETHTYPE_ARP)) 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 /* If the above function invocation resulted in data that
* should be sent out on the network, the global variable * 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++) 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 /* If the above function invocation resulted in data that
* should be sent out on the network, the global variable * 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(); uip_arp_out(&g_sim_dev);
tapdev_send((char*)uip_buf, uip_len); tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
} }
} }
#ifdef CONFIG_NET_UDP #ifdef CONFIG_NET_UDP
for(i = 0; i < UIP_UDP_CONNS; i++) 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 /* If the above function invocation resulted in data that
* should be sent out on the network, the global variable * 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(); uip_arp_out(&g_sim_dev);
tapdev_send((char*)uip_buf, uip_len); tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
} }
} }
#endif /* CONFIG_NET_UDP */ #endif /* CONFIG_NET_UDP */
/* Call the ARP timer function every 10 seconds. */ /* 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(); uip_arp_timer();
} }
} }
@@ -189,8 +190,8 @@ void uipdriver_loop(void)
int uipdriver_init(void) int uipdriver_init(void)
{ {
timer_set(&periodic_timer, 500); timer_set(&g_periodic_timer, 500);
timer_set(&arp_timer, 10000 ); timer_set(&g_arp_timer, 10000 );
tapdev_init(); tapdev_init();
uip_init(); uip_init();
-2
View File
@@ -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_ARPTAB_SIZE - The size of the ARP table
CONFIG_NET_BROADCAST - Broadcast support CONFIG_NET_BROADCAST - Broadcast support
CONFIG_NET_LLH_LEN - The link level header length 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 CONFIG_NET_FWCACHE_SIZE - number of packets to remember when
looking for duplicates looking for duplicates
-2
View File
@@ -268,7 +268,6 @@ CONFIG_PREALLOC_TIMERS=8
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table # CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
# CONFIG_NET_BROADCAST - Broadcast support # CONFIG_NET_BROADCAST - Broadcast support
# CONFIG_NET_LLH_LEN - The link level header length # 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_FWCACHE_SIZE - number of packets to remember when looking for duplicates
CONFIG_NET=n CONFIG_NET=n
CONFIG_NET_IPv6=n CONFIG_NET_IPv6=n
@@ -287,7 +286,6 @@ CONFIG_NET_STATISTICS=y
#CONFIG_NET_ARPTAB_SIZE=8 #CONFIG_NET_ARPTAB_SIZE=8
CONFIG_NET_BROADCAST=n CONFIG_NET_BROADCAST=n
#CONFIG_NET_LLH_LEN=14 #CONFIG_NET_LLH_LEN=14
CONFIG_NET_EXTERNAL_BUFFER=n
#CONFIG_NET_FWCACHE_SIZE=2 #CONFIG_NET_FWCACHE_SIZE=2
# #
-2
View File
@@ -257,7 +257,6 @@ CONFIG_PREALLOC_TIMERS=8
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table # CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
# CONFIG_NET_BROADCAST - Broadcast support # CONFIG_NET_BROADCAST - Broadcast support
# CONFIG_NET_LLH_LEN - The link level header length # 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_FWCACHE_SIZE - number of packets to remember when looking for duplicates
CONFIG_NET=n CONFIG_NET=n
CONFIG_NET_IPv6=n CONFIG_NET_IPv6=n
@@ -276,7 +275,6 @@ CONFIG_NET_STATISTICS=y
#CONFIG_NET_ARPTAB_SIZE=8 #CONFIG_NET_ARPTAB_SIZE=8
CONFIG_NET_BROADCAST=n CONFIG_NET_BROADCAST=n
#CONFIG_NET_LLH_LEN=14 #CONFIG_NET_LLH_LEN=14
CONFIG_NET_EXTERNAL_BUFFER=n
#CONFIG_NET_FWCACHE_SIZE=2 #CONFIG_NET_FWCACHE_SIZE=2
# #
-2
View File
@@ -281,7 +281,6 @@ CONFIG_PREALLOC_TIMERS=8
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table # CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
# CONFIG_NET_BROADCAST - Broadcast support # CONFIG_NET_BROADCAST - Broadcast support
# CONFIG_NET_LLH_LEN - The link level header length # 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_FWCACHE_SIZE - number of packets to remember when looking for duplicates
CONFIG_NET=n CONFIG_NET=n
CONFIG_NET_IPv6=n CONFIG_NET_IPv6=n
@@ -300,7 +299,6 @@ CONFIG_NET_STATISTICS=y
#CONFIG_NET_ARPTAB_SIZE=8 #CONFIG_NET_ARPTAB_SIZE=8
CONFIG_NET_BROADCAST=n CONFIG_NET_BROADCAST=n
#CONFIG_NET_LLH_LEN=14 #CONFIG_NET_LLH_LEN=14
CONFIG_NET_EXTERNAL_BUFFER=n
#CONFIG_NET_FWCACHE_SIZE=2 #CONFIG_NET_FWCACHE_SIZE=2
# #
-2
View File
@@ -266,7 +266,6 @@ CONFIG_PREALLOC_TIMERS=8
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table # CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
# CONFIG_NET_BROADCAST - Broadcast support # CONFIG_NET_BROADCAST - Broadcast support
# CONFIG_NET_LLH_LEN - The link level header length # 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_FWCACHE_SIZE - number of packets to remember when looking for duplicates
CONFIG_NET=n CONFIG_NET=n
CONFIG_NET_IPv6=n CONFIG_NET_IPv6=n
@@ -285,7 +284,6 @@ CONFIG_NET_STATISTICS=y
#CONFIG_NET_ARPTAB_SIZE=8 #CONFIG_NET_ARPTAB_SIZE=8
CONFIG_NET_BROADCAST=n CONFIG_NET_BROADCAST=n
#CONFIG_NET_LLH_LEN=14 #CONFIG_NET_LLH_LEN=14
CONFIG_NET_EXTERNAL_BUFFER=n
#CONFIG_NET_FWCACHE_SIZE=2 #CONFIG_NET_FWCACHE_SIZE=2
# #
-2
View File
@@ -254,7 +254,6 @@ CONFIG_PREALLOC_TIMERS=0
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table # CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
# CONFIG_NET_BROADCAST - Broadcast support # CONFIG_NET_BROADCAST - Broadcast support
# CONFIG_NET_LLH_LEN - The link level header length # 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_FWCACHE_SIZE - number of packets to remember when looking for duplicates
CONFIG_NET=n CONFIG_NET=n
CONFIG_NET_IPv6=n CONFIG_NET_IPv6=n
@@ -273,7 +272,6 @@ CONFIG_NET_STATISTICS=y
#CONFIG_NET_ARPTAB_SIZE=8 #CONFIG_NET_ARPTAB_SIZE=8
CONFIG_NET_BROADCAST=n CONFIG_NET_BROADCAST=n
#CONFIG_NET_LLH_LEN=14 #CONFIG_NET_LLH_LEN=14
CONFIG_NET_EXTERNAL_BUFFER=n
#CONFIG_NET_FWCACHE_SIZE=2 #CONFIG_NET_FWCACHE_SIZE=2
# #
-2
View File
@@ -228,7 +228,6 @@ CONFIG_FS_FAT=y
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table # CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
# CONFIG_NET_BROADCAST - Broadcast support # CONFIG_NET_BROADCAST - Broadcast support
# CONFIG_NET_LLH_LEN - The link level header length # 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_FWCACHE_SIZE - number of packets to remember when looking for duplicates
CONFIG_NET=n CONFIG_NET=n
CONFIG_NET_IPv6=n CONFIG_NET_IPv6=n
@@ -247,7 +246,6 @@ CONFIG_NET_STATISTICS=y
#CONFIG_NET_ARPTAB_SIZE=8 #CONFIG_NET_ARPTAB_SIZE=8
CONFIG_NET_BROADCAST=n CONFIG_NET_BROADCAST=n
#CONFIG_NET_LLH_LEN=14 #CONFIG_NET_LLH_LEN=14
CONFIG_NET_EXTERNAL_BUFFER=n
#CONFIG_NET_FWCACHE_SIZE=2 #CONFIG_NET_FWCACHE_SIZE=2
# #
+120 -54
View File
@@ -63,16 +63,96 @@
* the macrose defined in this file. * the macrose defined in this file.
*/ */
#define UIP_DATA 1 /* Tells uIP that there is incoming data in the uip_buf buffer. The #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 global variable uip_len. */ * 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_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_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 #define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram should be constructed in the
* uip_buf buffer. */ * d_buf buffer. */
#ifdef CONFIG_NET_UDP #ifdef CONFIG_NET_UDP
# define UIP_UDP_TIMER 5 # define UIP_UDP_TIMER 5
#endif /* CONFIG_NET_UDP */ #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 /* uIP device driver functions
* *
* These functions are used by a network device driver for interacting * 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 * This function should be called when the device driver has received
* a packet from the network. The packet from the device driver must * 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 * be present in the d_buf buffer, and the length of the packet
* should be placed in the uip_len variable. * should be placed in the d_len field.
* *
* When the function returns, there may be an outbound packet placed * 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 * 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 * The usual way of calling the function is presented by the source
* code below. * code below.
* *
* uip_len = devicedriver_poll(); * dev->d_len = devicedriver_poll();
* if(uip_len > 0) { * if(dev->d_len > 0) {
* uip_input(); * uip_input();
* if(uip_len > 0) { * if(dev->d_len > 0) {
* devicedriver_send(); * devicedriver_send();
* } * }
* } * }
@@ -106,25 +186,25 @@
* Ethernet, you will need to call the uIP ARP code before calling * Ethernet, you will need to call the uIP ARP code before calling
* this function: * this function:
* *
* #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) * #define BUF ((struct uip_eth_hdr *)&dev->d_buf[0])
* uip_len = ethernet_devicedrver_poll(); * dev->d_len = ethernet_devicedrver_poll();
* if(uip_len > 0) { * if(dev->d_len > 0) {
* if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { * if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
* uip_arp_ipin(); * uip_arp_ipin();
* uip_input(); * uip_input();
* if(uip_len > 0) { * if(dev->d_len > 0) {
* uip_arp_out(); * uip_arp_out();
* ethernet_devicedriver_send(); * ethernet_devicedriver_send();
* } * }
* } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { * } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
* uip_arp_arpin(); * uip_arp_arpin();
* if(uip_len > 0) { * if(dev->d_len > 0) {
* ethernet_devicedriver_send(); * 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. /* Periodic processing for a connection identified by its number.
* *
@@ -134,8 +214,8 @@
* connection, regardless of whether they are open of closed. * connection, regardless of whether they are open of closed.
* *
* When the function returns, it may have an outbound packet waiting * When the function returns, it may have an outbound packet waiting
* for service in the uIP packet buffer, and if so the uip_len * for service in the uIP packet buffer, and if so the d_len field
* variable is set to a value larger than zero. The device driver * is set to a value larger than zero. The device driver
* should be called to send out the packet. * should be called to send out the packet.
* *
* The ususal way of calling the function is through a for() loop like * The ususal way of calling the function is through a for() loop like
@@ -143,8 +223,8 @@
* *
* for(i = 0; i < UIP_CONNS; ++i) * for(i = 0; i < UIP_CONNS; ++i)
* { * {
* uip_tcppoll(i); * uip_tcppoll(dev,i);
* if (uip_len > 0) * if (dev->d_len > 0)
* { * {
* devicedriver_send(); * devicedriver_send();
* } * }
@@ -157,8 +237,8 @@
* *
* for(i = 0; i < UIP_CONNS; ++i) * for(i = 0; i < UIP_CONNS; ++i)
* { * {
* uip_tcppoll(i); * uip_tcppoll(dev,i);
* if (uip_len > 0) * if (dev->d_len > 0)
* { * {
* uip_arp_out(); * uip_arp_out();
* ethernet_devicedriver_send(); * ethernet_devicedriver_send();
@@ -168,7 +248,7 @@
* conn The number of the connection which is to be periodically polled. * 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 #ifdef CONFIG_NET_UDP
/* Periodic processing for a UDP connection identified by its number. /* 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++) * for(i = 0; i < UIP_UDP_CONNS; i++)
* { * {
* uip_udppoll(i); * uip_udppoll(dev,i);
* if(uip_len > 0) * if(dev->d_len > 0)
* { * {
* devicedriver_send(); * devicedriver_send();
* } * }
@@ -191,8 +271,8 @@ extern void uip_tcppoll(unsigned int conn);
* *
* for(i = 0; i < UIP_UDP_CONNS; i++) * for(i = 0; i < UIP_UDP_CONNS; i++)
* { * {
* uip_udppoll(i); * uip_udppoll(dev,i);
* if(uip_len > 0) * if(dev->d_len > 0)
* { * {
* uip_arp_out(); * uip_arp_out();
* ethernet_devicedriver_send(); * ethernet_devicedriver_send();
@@ -202,31 +282,17 @@ extern void uip_tcppoll(unsigned int conn);
* conn The number of the UDP connection to be processed. * 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 */ #endif /* CONFIG_NET_UDP */
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Variables
****************************************************************************/
/****************************************************************************
* Pulblic Function Prototypes
****************************************************************************/
/* Architecure support /* Architecure support
*
* uip_interrupt(flag):
* *
* The actual uIP function which does all the work. Called from the * The actual uIP function which does all the work. Called from the
* interrupt level by a device driver. * 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 /* By defining UIP_ARCH_CHKSUM, the architecture can replace the following
* functions with hardware assisted solutions. * 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); 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 checksum is the Internet checksum of the 20 bytes of
* the IP header. * 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. * 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 * The TCP checksum is the Internet checksum of data contents of the
* TCP segment, and a pseudo-header as defined in RFC793. * 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 * 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 * Return: The TCP checksum of the TCP segment in d_buf and pointed
* to by uip_appdata. * 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 */ #endif /* __UIP_ARCH_H */
+9 -10
View File
@@ -61,36 +61,35 @@ void uip_arp_init(void);
/* The uip_arp_ipin() function should be called whenever an IP packet /* The uip_arp_ipin() function should be called whenever an IP packet
* arrives from the Ethernet. This function refreshes the ARP table or * arrives from the Ethernet. This function refreshes the ARP table or
* inserts a new mapping if none exists. The function assumes that an * 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 * IP packet with an Ethernet header is present in the d_buf buffer
* and that the length of the packet is in the uip_len variable. * and that the length of the packet is in the d_len field.
*/ */
/*void uip_arp_ipin(void);*/
#define uip_arp_ipin() #define uip_arp_ipin()
/* The uip_arp_arpin() should be called when an ARP packet is received /* The uip_arp_arpin() should be called when an ARP packet is received
* by the Ethernet driver. This function also assumes that the * by the Ethernet driver. This function also assumes that the
* Ethernet frame is present in the uip_buf buffer. When the * Ethernet frame is present in the d_buf buffer. When the
* uip_arp_arpin() function returns, the contents of the uip_buf * uip_arp_arpin() function returns, the contents of the d_buf
* buffer should be sent out on the Ethernet if the uip_len variable * buffer should be sent out on the Ethernet if the d_len field
* is > 0. * 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 /* The uip_arp_out() function should be called when an IP packet
* should be sent out on the Ethernet. This function creates an * 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 * Ethernet header will have the correct Ethernet MAC destination
* address filled in if an ARP table entry for the destination IP * 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 * 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 * 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 * 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. * 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 /* The uip_arp_timer() function should be called every ten seconds. It
* is responsible for flushing old entries in the ARP table. * is responsible for flushing old entries in the ARP table.
+46 -78
View File
@@ -84,6 +84,9 @@
* successfully established. */ * successfully established. */
#define UIP_TIMEDOUT (1 << 7) /* The connection has been aborted due to too many retransmissions. */ #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. */ /* The TCP states used in the uip_conn->tcpstateflags. */
#define UIP_CLOSED 0 /* The connection is not in use and available */ #define UIP_CLOSED 0 /* The connection is not in use and available */
@@ -100,15 +103,15 @@
#define UIP_TS_MASK 15 #define UIP_TS_MASK 15
#define UIP_STOPPED 16 #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 * 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. * bounds of available user data.
* *
* Example: * 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) #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. * file pointers) for the connection.
*/ */
struct uip_driver_s; /* Forward reference */
struct uip_conn struct uip_conn
{ {
dq_entry_t node; /* Implements a doubly linked list */ dq_entry_t node; /* Implements a doubly linked list */
@@ -186,8 +190,10 @@ struct uip_conn
* in the following: * in the following:
*/ */
void *private; void *data_private;
void (*callback)(void *private); void (*data_event)(struct uip_driver_s *dev, void *private);
void *connection_private;
void (*connection_event)(void *private);
}; };
#ifdef CONFIG_NET_UDP #ifdef CONFIG_NET_UDP
@@ -204,7 +210,7 @@ struct uip_udp_conn
/* Defines the UDP callback */ /* Defines the UDP callback */
void *private; void *private;
void (*callback)(void *private); void (*event)(struct uip_driver_s *dev, void *private);
}; };
#endif /* CONFIG_NET_UDP */ #endif /* CONFIG_NET_UDP */
@@ -232,6 +238,7 @@ struct uip_stats
uip_stats_t protoerr; /* Number of packets dropped since they uip_stats_t protoerr; /* Number of packets dropped since they
were neither ICMP, UDP nor TCP. */ were neither ICMP, UDP nor TCP. */
} ip; /* IP statistics. */ } ip; /* IP statistics. */
struct struct
{ {
uip_stats_t drop; /* Number of dropped ICMP packets. */ 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 sent; /* Number of sent ICMP packets. */
uip_stats_t typeerr; /* Number of ICMP packets with a wrong type. */ uip_stats_t typeerr; /* Number of ICMP packets with a wrong type. */
} icmp; /* ICMP statistics. */ } icmp; /* ICMP statistics. */
struct struct
{ {
uip_stats_t drop; /* Number of dropped TCP segments. */ uip_stats_t drop; /* Number of dropped TCP segments. */
uip_stats_t recv; /* Number of recived 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, uip_stats_t synrst; /* Number of SYNs for closed ports,
triggering a RST. */ triggering a RST. */
} tcp; /* TCP statistics. */ } tcp; /* TCP statistics. */
#ifdef CONFIG_NET_UDP #ifdef CONFIG_NET_UDP
struct struct
{ {
@@ -269,6 +279,7 @@ struct uip_stats
struct uip_tcpip_hdr struct uip_tcpip_hdr
{ {
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
/* IPv6 header. */ /* IPv6 header. */
uint8 vtc; uint8 vtc;
@@ -279,6 +290,7 @@ struct uip_tcpip_hdr
uip_ip6addr_t srcipaddr, destipaddr; uip_ip6addr_t srcipaddr, destipaddr;
#else /* CONFIG_NET_IPv6 */ #else /* CONFIG_NET_IPv6 */
/* IPv4 header. */ /* IPv4 header. */
uint8 vhl; uint8 vhl;
@@ -291,6 +303,7 @@ struct uip_tcpip_hdr
uint16 ipchksum; uint16 ipchksum;
uint16 srcipaddr[2]; uint16 srcipaddr[2];
uint16 destipaddr[2]; uint16 destipaddr[2];
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
/* TCP header. */ /* TCP header. */
@@ -312,6 +325,7 @@ struct uip_tcpip_hdr
struct uip_icmpip_hdr struct uip_icmpip_hdr
{ {
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
/* IPv6 header. */ /* IPv6 header. */
uint8 vtc; uint8 vtc;
@@ -324,6 +338,7 @@ struct uip_icmpip_hdr
uip_ip6addr_t destipaddr; uip_ip6addr_t destipaddr;
#else /* CONFIG_NET_IPv6 */ #else /* CONFIG_NET_IPv6 */
/* IPv4 header. */ /* IPv4 header. */
uint8 vhl; uint8 vhl;
@@ -336,17 +351,29 @@ struct uip_icmpip_hdr
uint16 ipchksum; uint16 ipchksum;
uint16 srcipaddr[2]; uint16 srcipaddr[2];
uint16 destipaddr[2]; uint16 destipaddr[2];
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
/* ICMP (echo) header. */ /* ICMP (echo) header. */
uint8 type, icode;
uint8 type;
uint8 icode;
uint16 icmpchksum; uint16 icmpchksum;
#ifndef CONFIG_NET_IPv6 #ifndef CONFIG_NET_IPv6
uint16 id, seqno;
uint16 id;
uint16 seqno;
#else /* !CONFIG_NET_IPv6 */ #else /* !CONFIG_NET_IPv6 */
uint8 flags, reserved1, reserved2, reserved3;
uint8 flags;
uint8 reserved1;
uint8 reserved2;
uint8 reserved3;
uint8 icmp6data[16]; uint8 icmp6data[16];
uint8 options[1]; uint8 options[1];
#endif /* !CONFIG_NET_IPv6 */ #endif /* !CONFIG_NET_IPv6 */
}; };
@@ -355,6 +382,7 @@ struct uip_icmpip_hdr
struct uip_udpip_hdr struct uip_udpip_hdr
{ {
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
/* IPv6 header. */ /* IPv6 header. */
uint8 vtc; uint8 vtc;
@@ -364,8 +392,10 @@ struct uip_udpip_hdr
uint8 proto, ttl; uint8 proto, ttl;
uip_ip6addr_t srcipaddr; uip_ip6addr_t srcipaddr;
uip_ip6addr_t destipaddr; uip_ip6addr_t destipaddr;
#else /* CONFIG_NET_IPv6 */ #else /* CONFIG_NET_IPv6 */
/* IP header. */
/* IPv4 header. */
uint8 vhl; uint8 vhl;
uint8 tos; uint8 tos;
@@ -377,6 +407,7 @@ struct uip_udpip_hdr
uint16 ipchksum; uint16 ipchksum;
uint16 srcipaddr[2]; uint16 srcipaddr[2];
uint16 destipaddr[2]; uint16 destipaddr[2];
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
/* UDP header. */ /* UDP header. */
@@ -398,42 +429,6 @@ struct uip_eth_addr
* Public Data * 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 #if UIP_URGDATA > 0
/* uint8 *uip_urgdata: /* 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 has a few global variables that are used in device drivers for
* uIP. * 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 #if UIP_URGDATA > 0
extern uint16 uip_urglen, uip_surglen; extern uint16 uip_urglen, uip_surglen;
#endif /* UIP_URGDATA > 0 */ #endif /* UIP_URGDATA > 0 */
@@ -703,16 +682,16 @@ void uip_unlisten(uint16 port);
* len The maximum amount of data bytes to be sent. * 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) /* 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 * The test function uip_data() must first be used to check if there
* is any data available at all. * 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 /* The length of any out-of-band data (urgent data) that has arrived
* on the connection. * on the connection.
@@ -778,8 +757,8 @@ void uip_send(const void *data, int len);
/* Is new incoming data available? /* Is new incoming data available?
* *
* Will reduce to non-zero if there is new data for the application * 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 * present at the d_appdata pointer. The size of the data is
* avaliable through the uip_len variable. * avaliable through the d_len element.
*/ */
#define uip_newdata() (uip_flags & UIP_NEWDATA) #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_udpenable(struct uip_udp_conn *conn);
extern void uip_udpdisable(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. /* uIP convenience and converting functions.
* *
* These functions can be used for converting between different data * These functions can be used for converting between different data
+3 -3
View File
@@ -129,7 +129,7 @@
* uIP supports reassembly of fragmented IP packets. This features * uIP supports reassembly of fragmented IP packets. This features
* requires an additonal amount of RAM to hold the reassembly buffer * requires an additonal amount of RAM to hold the reassembly buffer
* and the reassembly code size is approximately 700 bytes. The * 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). * (configured by UIP_BUFSIZE).
* *
* Note: IP packet reassembly is not heavily tested. * Note: IP packet reassembly is not heavily tested.
@@ -234,7 +234,7 @@
/* The size of the advertised receiver's window. /* 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) * application is slow to process incoming data, or high (32768 bytes)
* if the application processes data quickly. * if the application processes data quickly.
*/ */
@@ -328,7 +328,7 @@
/* The link level header length. /* 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 * found. For Ethernet, this should be set to 14. For SLIP, this
* should be set to 0. * should be set to 0.
*/ */
+1
View File
@@ -90,6 +90,7 @@ depend: .depend
clean: clean:
rm -f $(BIN) *.o *.rel *.asm *.lst *.sym *.adb *~ rm -f $(BIN) *.o *.rel *.asm *.lst *.sym *.adb *~
rm -f uip/*~
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
distclean: clean distclean: clean
+72 -12
View File
@@ -47,7 +47,55 @@
#include "net-internal.h" #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; FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
#endif #endif
int err; int err;
int ret;
/* Verify that the sockfd corresponds to valid, allocated socket */ /* 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: case SOCK_STREAM:
{ {
int ret; struct uip_conn *conn;
/* Verify that the socket is not already connected */ /* 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; goto errout;
} }
/* Perform the uIP connection operation */ /* Get the connection reference from the socket */
ret = uip_tcpconnect(psock->s_conn, inaddr); conn = psock->s_conn;
if (ret < 0) if (conn) /* Should alwasy be non-NULL */
{ {
err = -ret; /* Perform the uIP connection operation */
goto errout;
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; break;
#ifdef CONFIG_NET_UDP #ifdef CONFIG_NET_UDP
case SOCK_DGRAM: case SOCK_DGRAM:
{ {
int ret = uip_udpconnect(psock->s_conn, inaddr); ret = uip_udpconnect(psock->s_conn, inaddr);
if (ret < 0) if (ret < 0)
{ {
err = -ret; err = -ret;
+77 -27
View File
@@ -46,6 +46,7 @@
#include <errno.h> #include <errno.h>
#include <arch/irq.h> #include <arch/irq.h>
#include <nuttx/clock.h> #include <nuttx/clock.h>
#include <net/uip/uip-arch.h>
#include "net-internal.h" #include "net-internal.h"
@@ -78,7 +79,26 @@ struct recvfrom_s
* Private Functions * 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; struct recvfrom_s *pstate = (struct recvfrom_s *)private;
FAR struct socket *psock; FAR struct socket *psock;
@@ -97,18 +117,18 @@ static void recvfrom_interrupt(void *private)
if (uip_newdata()) if (uip_newdata())
{ {
/* Get the length of the data to return */ /* 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; recvlen = pstate->rf_buflen;
} }
else else
{ {
recvlen = uip_len; recvlen = dev->d_len;
} }
/* Copy the new appdata into the user buffer */ /* 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 */ /* 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. */ /* Don't allow any further UDP call backs. */
udp_conn = (struct uip_udp_conn *)psock->s_conn; udp_conn = (struct uip_udp_conn *)psock->s_conn;
udp_conn->private = NULL; udp_conn->private = NULL;
udp_conn->callback = NULL; udp_conn->event = NULL;
/* Wake up the waiting thread, returning the number of bytes /* Wake up the waiting thread, returning the number of bytes
* actually read. * actually read.
@@ -149,9 +169,9 @@ static void recvfrom_interrupt(void *private)
* Don't allow any further TCP call backs. * Don't allow any further TCP call backs.
*/ */
conn = (struct uip_conn *)psock->s_conn; conn = (struct uip_conn *)psock->s_conn;
conn->private = NULL; conn->data_private = NULL;
conn->callback = NULL; conn->data_event = NULL;
/* Wake up the waiting thread, returning the number of bytes /* Wake up the waiting thread, returning the number of bytes
* actually read. * actually read.
@@ -169,6 +189,36 @@ static void recvfrom_interrupt(void *private)
#endif #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 /* No data has been received -- this is some other event... probably a
* poll -- check for a timeout. * poll -- check for a timeout.
*/ */
@@ -221,9 +271,9 @@ static void recvfrom_interrupt(void *private)
/* Stop further callbacks */ /* Stop further callbacks */
udp_conn = (struct uip_udp_conn *)psock->s_conn; udp_conn = (struct uip_udp_conn *)psock->s_conn;
udp_conn->private = NULL; udp_conn->private = NULL;
udp_conn->callback = NULL; udp_conn->event = NULL;
/* Report a timeout error */ /* Report a timeout error */
@@ -234,9 +284,9 @@ static void recvfrom_interrupt(void *private)
{ {
struct uip_conn *conn; struct uip_conn *conn;
conn = (struct uip_conn *)psock->s_conn; conn = (struct uip_conn *)psock->s_conn;
conn->private = NULL; conn->data_private = NULL;
conn->callback = NULL; conn->data_event = NULL;
/* Report an error only if no data has been received */ /* 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) 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; 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 */ /* Set up the callback in the connection */
udp_conn = (struct uip_udp_conn *)psock->s_conn; udp_conn = (struct uip_udp_conn *)psock->s_conn;
udp_conn->private = (void*)&state; udp_conn->private = (void*)&state;
udp_conn->callback = recvfrom_interrupt; udp_conn->event = recvfrom_interrupt;
/* Enable the UDP socket */ /* 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 */ /* Make sure that no further interrupts are processed */
uip_udpdisable(psock->s_conn); uip_udpdisable(psock->s_conn);
udp_conn->private = NULL; udp_conn->private = NULL;
udp_conn->callback = NULL; udp_conn->event = NULL;
irqrestore(save); irqrestore(save);
#warning "Needs to return server address" #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 */ /* Set up the callback in the connection */
conn = (struct uip_conn *)psock->s_conn; conn = (struct uip_conn *)psock->s_conn;
conn->private = (void*)&state; conn->data_private = (void*)&state;
conn->callback = recvfrom_interrupt; conn->data_event = recvfrom_interrupt;
/* Wait for either the receive to complete or for an error/timeout to occur. /* 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) * 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 */ /* Make sure that no further interrupts are processed */
conn->private = NULL; conn->data_private = NULL;
conn->callback = NULL; conn->data_event = NULL;
irqrestore(save); irqrestore(save);
#warning "Needs to return server address" #warning "Needs to return server address"
+30 -12
View File
@@ -78,13 +78,14 @@ struct send_s
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: send_Interrupt * Function: send_interrupt
* *
* Description: * Description:
* This function is called from the interrupt level to perform the actual * This function is called from the interrupt level to perform the actual
* send operation when polled by the uIP layer. * send operation when polled by the uIP layer.
* *
* Parameters: * Parameters:
* dev The sructure of the network driver that caused the interrupt
* private An instance of struct send_s cast to void* * private An instance of struct send_s cast to void*
* *
* Returned Value: * 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 send_s *pstate = (struct send_s *)private;
struct uip_conn *conn; struct uip_conn *conn;
@@ -108,11 +109,11 @@ static void send_interrupt(void *private)
{ {
if (pstate->snd_buflen > uip_mss()) if (pstate->snd_buflen > uip_mss())
{ {
uip_send(pstate->snd_buffer, uip_mss()); uip_send(dev, pstate->snd_buffer, uip_mss());
} }
else else
{ {
uip_send(pstate->snd_buffer, pstate->snd_buflen); uip_send(dev, pstate->snd_buffer, pstate->snd_buflen);
} }
pstate->snd_state = STATE_DATA_SENT; pstate->snd_state = STATE_DATA_SENT;
@@ -146,9 +147,9 @@ static void send_interrupt(void *private)
/* Don't allow any further call backs. */ /* Don't allow any further call backs. */
conn = (struct uip_conn *)pstate->snd_sock->s_conn; conn = (struct uip_conn *)pstate->snd_sock->s_conn;
conn->private = NULL; conn->data_private = NULL;
conn->callback = NULL; conn->data_event = NULL;
/* Wake up the waiting thread, returning the number of bytes /* Wake up the waiting thread, returning the number of bytes
* actually sent. * actually sent.
@@ -157,6 +158,23 @@ static void send_interrupt(void *private)
sem_post(&pstate->snd_sem); 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 */ /* Set up the callback in the connection */
conn = (struct uip_conn *)psock->s_conn; conn = (struct uip_conn *)psock->s_conn;
conn->private = (void*)&state; conn->data_private = (void*)&state;
conn->callback = send_interrupt; conn->data_event = send_interrupt;
/* Wait for the send to complete or an error to occur: NOTES: (1) /* 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 * 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 */ /* Make sure that no further interrupts are processed */
conn->private = NULL; conn->data_private = NULL;
conn->callback = NULL; conn->data_event = NULL;
} }
sem_destroy(&state. snd_sem); sem_destroy(&state. snd_sem);
+56 -12
View File
@@ -45,6 +45,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <arch/irq.h> #include <arch/irq.h>
#include <net/uip/uip-arch.h>
#include "net-internal.h" #include "net-internal.h"
@@ -61,32 +62,64 @@ struct sendto_s
sem_t st_sem; /* Semaphore signals sendto completion */ sem_t st_sem; /* Semaphore signals sendto completion */
uint16 st_buflen; /* Length of send buffer (error if <0) */ uint16 st_buflen; /* Length of send buffer (error if <0) */
const char *st_buffer; /* Pointer to send buffer */ const char *st_buffer; /* Pointer to send buffer */
int st_sndlen; /* Result of the send (length sent or negated errno) */
}; };
/**************************************************************************** /****************************************************************************
* Private Functions * 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; struct sendto_s *pstate = (struct sendto_s *)private;
if (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); if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
uip_udp_send(pstate->st_buflen); {
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; /* Don't allow any further call backs. */
uip_conn->callback = NULL;
uip_udp_conn->private = NULL;
uip_udp_conn->event = NULL;
/* Wake up the waiting thread */ /* Wake up the waiting thread */
sem_post(&pstate->st_sem); sem_post(&pstate->st_sem);
} }
} }
#endif
/**************************************************************************** /****************************************************************************
* Global Functions * 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 */ /* Set up the callback in the connection */
udp_conn = (struct uip_udp_conn *)psock->s_conn; udp_conn = (struct uip_udp_conn *)psock->s_conn;
udp_conn->private = (void*)&state; udp_conn->private = (void*)&state;
udp_conn->callback = sendto_interrupt; udp_conn->event = sendto_interrupt;
/* Enable the UDP socket */ /* 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 */ /* Make sure that no further interrupts are processed */
uip_udpdisable(psock->s_conn); uip_udpdisable(psock->s_conn);
udp_conn->private = NULL; udp_conn->private = NULL;
udp_conn->callback = NULL; udp_conn->event = NULL;
irqrestore(save); irqrestore(save);
sem_destroy(&state.st_sem); 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 */ /* Set the socket state to idle */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_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 #else
err = ENOSYS; err = ENOSYS;
#endif #endif
+1 -1
View File
@@ -34,6 +34,6 @@
############################################################################ ############################################################################
UIP_ASRCS = 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 uip-tcpconn.c uip-udpconn.c
+55 -75
View File
@@ -41,6 +41,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include <net/uip/uip-arch.h>
#include <net/uip/uip-arp.h> #include <net/uip/uip-arp.h>
struct arp_hdr struct arp_hdr
@@ -94,36 +95,29 @@ static uint8 i, c;
static uint8 arptime; static uint8 arptime;
static uint8 tmpage; static uint8 tmpage;
#define BUF ((struct arp_hdr *)&uip_buf[0]) #define BUF ((struct arp_hdr *)&dev->d_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0]) #define IPBUF ((struct ethip_hdr *)&dev->d_buf[0])
/*-----------------------------------------------------------------------------------*/
/** /* Initialize the ARP module. */
* Initialize the ARP module.
* void uip_arp_init(void)
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_init(void)
{ {
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
memset(arp_table[i].ipaddr, 0, 4); 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 * This function performs periodic timer processing in the ARP module
* and should be called at regular intervals. The recommended interval * and should be called at regular intervals. The recommended interval
* is 10 seconds between the calls. * is 10 seconds between the calls.
*
*/ */
/*-----------------------------------------------------------------------------------*/
void void uip_arp_timer(void)
uip_arp_timer(void)
{ {
struct arp_entry *tabptr; struct arp_entry *tabptr;
++arptime; ++arptime;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[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; register struct arp_entry *tabptr;
/* Walk through the ARP mapping table and try to find an entry to /* 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. */ the IP address in this ARP table entry. */
if(pipaddr[0] == tabptr->ipaddr[0] && if(pipaddr[0] == tabptr->ipaddr[0] &&
pipaddr[1] == tabptr->ipaddr[1]) { pipaddr[1] == tabptr->ipaddr[1]) {
/* An old entry found, update this and return. */ /* An old entry found, update this and return. */
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime; tabptr->time = arptime;
@@ -198,9 +190,8 @@ uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime; 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 * This function should be called by the device driver when an IP
* packet has been received. The function will check if the address is * 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. * refreshed. If no ARP cache entry was found, a new one is created.
* *
* This function expects an IP packet with a prepended Ethernet header * 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 * in the d_buf[] buffer, and the length of the packet in the field
* variable uip_len. * d_len.
*/ */
/*-----------------------------------------------------------------------------------*/
#if 0 #if 0
void void uip_arp_ipin(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 /* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */ incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & uip_netmask[0]) != if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
@@ -229,13 +219,12 @@ uip_arp_ipin(void)
return; return;
} }
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src)); uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return; return;
} }
#endif /* 0 */ #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 * This function should be called by the device driver when an ARP
* packet has been received. The function will act differently * 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 * 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 * 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 * 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 * 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 * 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 * This function expects an ARP packet with a prepended Ethernet
* header in the uip_buf[] buffer, and the length of the packet in the * header in the d_buf[] buffer, and the length of the packet in the
* global variable uip_len. * global variable d_len.
*/ */
/*-----------------------------------------------------------------------------------*/
void void uip_arp_arpin(struct uip_driver_s *dev)
uip_arp_arpin(void)
{ {
if(dev->d_len < sizeof(struct arp_hdr)) {
if(uip_len < sizeof(struct arp_hdr)) { dev->d_len = 0;
uip_len = 0;
return; return;
} }
uip_len = 0; dev->d_len = 0;
switch(BUF->opcode) { switch(BUF->opcode) {
case HTONS(ARP_REQUEST): case HTONS(ARP_REQUEST):
/* ARP request. If it asked for our address, we send out a /* 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 table, since it is likely that we will do more communication
with this host in the future. */ with this host in the future. */
uip_arp_update(BUF->sipaddr, &BUF->shwaddr); uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
/* The reply opcode is 2. */ /* The reply opcode is 2. */
BUF->opcode = HTONS(2); BUF->opcode = HTONS(2);
@@ -283,14 +270,14 @@ uip_arp_arpin(void)
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6); memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
BUF->dipaddr[0] = BUF->sipaddr[0]; BUF->dipaddr[0] = BUF->sipaddr[0];
BUF->dipaddr[1] = BUF->sipaddr[1]; BUF->dipaddr[1] = BUF->sipaddr[1];
BUF->sipaddr[0] = uip_hostaddr[0]; BUF->sipaddr[0] = uip_hostaddr[0];
BUF->sipaddr[1] = uip_hostaddr[1]; BUF->sipaddr[1] = uip_hostaddr[1];
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_len = sizeof(struct arp_hdr); dev->d_len = sizeof(struct arp_hdr);
} }
break; break;
case HTONS(ARP_REPLY): case HTONS(ARP_REPLY):
@@ -304,9 +291,8 @@ uip_arp_arpin(void)
return; 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. * to send out an ARP request.
* *
* This function should be called before sending out an IP packet. The * 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 * 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 * address is found. If so, an Ethernet header is prepended and the
* function returns. If no ARP cache entry is found for 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 * 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) * and it is assumed that they higher level protocols (e.g., TCP)
* eventually will retransmit the dropped packet. * 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 * If the destination IP address is not on the local network, the IP
* address of the default router is used instead. * address of the default router is used instead.
* *
* When the function returns, a packet is present in the uip_buf[] * When the function returns, a packet is present in the d_buf[]
* buffer, and the length of the packet is in the global variable * buffer, and the length of the packet is in the field d_len.
* uip_len.
*/ */
/*-----------------------------------------------------------------------------------*/
void void uip_arp_out(struct uip_driver_s *dev)
uip_arp_out(void)
{ {
struct arp_entry *tabptr; struct arp_entry *tabptr;
/* Find the destination IP address in the ARP table and construct /* Find the destination IP address in the ARP table and construct
the Ethernet header. If the destination IP addres isn't on the the Ethernet header. If the destination IP addres isn't on the
local network, we use the default router's IP address instead. 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. */ /* Else, we use the destination IP address. */
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr); uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
} }
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i]; tabptr = &arp_table[i];
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) { if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
@@ -374,7 +358,7 @@ uip_arp_out(void)
memset(BUF->dhwaddr.addr, 0x00, 6); memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
uip_ipaddr_copy(BUF->dipaddr, ipaddr); uip_ipaddr_copy(BUF->dipaddr, ipaddr);
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr); uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */ BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
@@ -384,9 +368,9 @@ uip_arp_out(void)
BUF->protolen = 4; BUF->protolen = 4;
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN]; dev->d_appdata = &dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
uip_len = sizeof(struct arp_hdr); dev->d_len = sizeof(struct arp_hdr);
return; return;
} }
@@ -394,12 +378,8 @@ uip_arp_out(void)
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
} }
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6); memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP); IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr); dev->d_len += sizeof(struct uip_eth_hdr);
} }
/*-----------------------------------------------------------------------------------*/
/** @} */
/** @} */
+95 -137
View File
@@ -33,6 +33,8 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <nuttx/config.h>
#include <debug.h>
#include <net/uip/uip.h> #include <net/uip/uip.h>
#include <net/uip/uip-arch.h> #include <net/uip/uip-arch.h>
@@ -40,17 +42,16 @@
#include <string.h> /* for memcpy() */ #include <string.h> /* for memcpy() */
/* /* The list of registered network interfaces. */
* The list of registered network interfaces.
*/
static struct uip_fw_netif *netifs = NULL; 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; static struct uip_fw_netif *defaultnetif = NULL;
struct tcpip_hdr { struct tcpip_hdr
{
/* IP header. */ /* IP header. */
uint8 vhl, uint8 vhl,
tos; tos;
@@ -101,23 +102,19 @@ struct icmpip_hdr {
/* ICMP TIME-EXCEEDED. */ /* ICMP TIME-EXCEEDED. */
#define ICMP_TE 11 #define ICMP_TE 11
/* /* Pointer to the TCP/IP headers of the packet in the d_buf buffer. */
* Pointer to the TCP/IP headers of the packet in the uip_buf buffer. #define BUF ((struct tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
*/
#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
/* /* Pointer to the ICMP/IP headers of the packet in the d_buf buffer. */
* Pointer to the ICMP/IP headers of the packet in the uip_buf buffer. #define ICMPBUF ((struct icmpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
*/
#define ICMPBUF ((struct icmpip_hdr *)&uip_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. * duplicate packets.
*/ */
struct fwcache_entry {
uint16 timer;
struct fwcache_entry
{
uint16 timer;
uint16 srcipaddr[2]; uint16 srcipaddr[2];
uint16 destipaddr[2]; uint16 destipaddr[2];
uint16 ipid; uint16 ipid;
@@ -133,35 +130,25 @@ struct fwcache_entry {
#endif #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 #ifdef CONFIG_NET_FWCACHE_SIZE
# define FWCACHE_SIZE CONFIG_NET_FWCACHE_SIZE # define FWCACHE_SIZE CONFIG_NET_FWCACHE_SIZE
#else #else
# define FWCACHE_SIZE 2 # define FWCACHE_SIZE 2
#endif #endif
/* A cache of packet header fields which are used for
/*
* A cache of packet header fields which are used for
* identifying duplicate packets. * identifying duplicate packets.
*/ */
static struct fwcache_entry fwcache[FWCACHE_SIZE]; static struct fwcache_entry fwcache[FWCACHE_SIZE];
/** /* The time that a packet cache is active. */
* \internal
* The time that a packet cache is active.
*/
#define FW_TIME 20 #define FW_TIME 20
/*------------------------------------------------------------------------------*/ /* Initialize the uIP packet forwarding module. */
/**
* Initialize the uIP packet forwarding module. void uip_fw_init(void)
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_init(void)
{ {
struct uip_fw_netif *t; struct uip_fw_netif *t;
defaultnetif = NULL; defaultnetif = NULL;
@@ -171,42 +158,36 @@ uip_fw_init(void)
t->next = NULL; t->next = NULL;
} }
} }
/*------------------------------------------------------------------------------*/
/** /* Check if an IP address is within the network defined by an IP
* \internal
* Check if an IP address is within the network defined by an IP
* address and a netmask. * address and a netmask.
* *
* \param ipaddr The IP address to be checked. * ipaddr The IP address to be checked.
* \param netipaddr The IP address of the network. * netipaddr The IP address of the network.
* \param netmask The netmask 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 static unsigned char ipaddr_maskcmp(uint16 *ipaddr, uint16 *netipaddr, uint16 *netmask)
ipaddr_maskcmp(uint16 *ipaddr, uint16 *netipaddr, uint16 *netmask)
{ {
return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) && return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
(ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]); (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
} }
/*------------------------------------------------------------------------------*/
/** /* Send out an ICMP TIME-EXCEEDED message.
* \internal
* 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. * ICMP packet.
*/ */
/*------------------------------------------------------------------------------*/
static void static void time_exceeded(struct uip_driver_s *dev)
time_exceeded(void)
{ {
uint16 tmp16; uint16 tmp16;
/* We don't send out ICMP errors for ICMP messages. */ /* We don't send out ICMP errors for ICMP messages. */
if(ICMPBUF->proto == UIP_PROTO_ICMP) { if(ICMPBUF->proto == UIP_PROTO_ICMP) {
uip_len = 0; dev->d_len = 0;
return; return;
} }
/* Copy fields from packet header into payload of this ICMP packet. */ /* 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 /* The size of the ICMP time exceeded packet is 36 + the size of the
IP header (20) = 56. */ IP header (20) = 56. */
uip_len = 56; dev->d_len = 56;
ICMPBUF->len[0] = 0; ICMPBUF->len[0] = 0;
ICMPBUF->len[1] = uip_len; ICMPBUF->len[1] = dev->d_len;
/* Fill in the other fields in the IP header. */ /* Fill in the other fields in the IP header. */
ICMPBUF->vhl = 0x45; ICMPBUF->vhl = 0x45;
@@ -245,29 +226,24 @@ time_exceeded(void)
ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0; ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
ICMPBUF->ttl = UIP_TTL; ICMPBUF->ttl = UIP_TTL;
ICMPBUF->proto = UIP_PROTO_ICMP; ICMPBUF->proto = UIP_PROTO_ICMP;
/* Calculate IP checksum. */ /* Calculate IP checksum. */
ICMPBUF->ipchksum = 0; ICMPBUF->ipchksum = 0;
ICMPBUF->ipchksum = ~(uip_ipchksum()); ICMPBUF->ipchksum = ~(uip_ipchksum(dev));
} }
/*------------------------------------------------------------------------------*/
/** /* Register a packet in the forwarding cache so that it won't be
* \internal
* Register a packet in the forwarding cache so that it won't be
* forwarded again. * forwarded again.
*/ */
/*------------------------------------------------------------------------------*/
static void static void fwcache_register(struct uip_driver_s *dev)
fwcache_register(void)
{ {
struct fwcache_entry *fw; struct fwcache_entry *fw;
int i, oldest; int i, oldest;
oldest = FW_TIME; oldest = FW_TIME;
fw = NULL; fw = NULL;
/* Find the oldest entry in the cache. */ /* Find the oldest entry in the cache. */
for(i = 0; i < FWCACHE_SIZE; ++i) { for(i = 0; i < FWCACHE_SIZE; ++i) {
if(fwcache[i].timer == 0) { if(fwcache[i].timer == 0) {
@@ -295,17 +271,13 @@ fwcache_register(void)
fw->offset = BUF->ipoffset; fw->offset = BUF->ipoffset;
#endif #endif
} }
/*------------------------------------------------------------------------------*/
/** /* Find a network interface for the IP packet in d_buf. */
* \internal
* Find a network interface for the IP packet in uip_buf. static struct uip_fw_netif *find_netif(struct uip_driver_s *dev)
*/
/*------------------------------------------------------------------------------*/
static struct uip_fw_netif *
find_netif(void)
{ {
struct uip_fw_netif *netif; struct uip_fw_netif *netif;
/* Walk through every network interface to check for a match. */ /* Walk through every network interface to check for a match. */
for(netif = netifs; netif != NULL; netif = netif->next) { for(netif = netifs; netif != NULL; netif = netif->next) {
if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr, if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
@@ -314,37 +286,35 @@ find_netif(void)
return netif; return netif;
} }
} }
/* If no matching netif was found, we use default netif. */ /* If no matching netif was found, we use default netif. */
return defaultnetif; 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 * The IP packet should be present in the d_buf buffer and its
* length in the global uip_len variable. * 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. * 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. * 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. * function is passed unmodified as a return value.
*/ */
/*------------------------------------------------------------------------------*/
uint8 uint8 uip_fw_output(struct uip_driver_s *dev)
uip_fw_output(void)
{ {
struct uip_fw_netif *netif; struct uip_fw_netif *netif;
if(uip_len == 0) { if(dev->d_len == 0) {
return UIP_FW_ZEROLEN; return UIP_FW_ZEROLEN;
} }
fwcache_register(); fwcache_register(dev);
#if UIP_BROADCAST #if UIP_BROADCAST
/* Link local broadcasts go out on all interfaces. */ /* Link local broadcasts go out on all interfaces. */
@@ -360,11 +330,9 @@ uip_fw_output(void)
return UIP_FW_OK; return UIP_FW_OK;
} }
#endif /* UIP_BROADCAST */ #endif /* UIP_BROADCAST */
netif = find_netif(); netif = find_netif(dev);
/* printf("uip_fw_output: netif %p ->output %p len %d\n", netif, dbg("uip_fw_output: netif %p ->output %p len %d\n", netif, netif->output, dev->d_len);
netif->output,
uip_len);*/
if(netif == NULL) { if(netif == NULL) {
return UIP_FW_NOROUTE; return UIP_FW_NOROUTE;
@@ -373,18 +341,14 @@ uip_fw_output(void)
output function to send out the packet. */ output function to send out the packet. */
return netif->output(); return netif->output();
} }
/*------------------------------------------------------------------------------*/
/** /* Forward an IP packet in the d_buf buffer.
* Forward an IP packet in the uip_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. * the packet should be processed locally.
*/ */
/*------------------------------------------------------------------------------*/
uint8 uint8 uip_fw_forward(struct uip_driver_s *dev)
uip_fw_forward(void)
{ {
struct fwcache_entry *fw; struct fwcache_entry *fw;
@@ -430,19 +394,21 @@ uip_fw_forward(void)
} }
/* If the TTL reaches zero we produce an ICMP time exceeded message /* 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 in the d_buf buffer and forward that packet back to the sender
of the packet. */ of the packet.
*/
if(BUF->ttl <= 1) { if(BUF->ttl <= 1) {
/* No time exceeded for broadcasts and multicasts! */ /* No time exceeded for broadcasts and multicasts! */
if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
return UIP_FW_LOCAL; return UIP_FW_LOCAL;
} }
time_exceeded(); time_exceeded(dev);
} }
/* Decrement the TTL (time-to-live) value in the IP header */ /* Decrement the TTL (time-to-live) value in the IP header */
BUF->ttl = BUF->ttl - 1; BUF->ttl = BUF->ttl - 1;
/* Update the IP checksum. */ /* Update the IP checksum. */
if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) { if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1; BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
@@ -450,9 +416,9 @@ uip_fw_forward(void)
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100); BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
} }
if(uip_len > 0) { if(dev->d_len > 0) {
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]; dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
uip_fw_output(); uip_fw_output(dev);
} }
#if UIP_BROADCAST #if UIP_BROADCAST
@@ -465,43 +431,36 @@ uip_fw_forward(void)
other processing should be made. */ other processing should be made. */
return UIP_FW_FORWARDED; 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. * registered.
*/ */
/*------------------------------------------------------------------------------*/
void void uip_fw_register(struct uip_fw_netif *netif)
uip_fw_register(struct uip_fw_netif *netif)
{ {
netif->next = netifs; netif->next = netifs;
netifs = netif; 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 * All packets that don't go out on any of the other interfaces will
* be routed to the default interface. * 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. * registered.
*/ */
/*------------------------------------------------------------------------------*/
void void uip_fw_default(struct uip_fw_netif *netif)
uip_fw_default(struct uip_fw_netif *netif)
{ {
defaultnetif = netif; defaultnetif = netif;
} }
/*------------------------------------------------------------------------------*/
/** /* Perform periodic processing. */
* Perform periodic processing.
*/ void uip_fw_periodic(void)
/*------------------------------------------------------------------------------*/
void
uip_fw_periodic(void)
{ {
struct fwcache_entry *fw; struct fwcache_entry *fw;
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
@@ -510,4 +469,3 @@ uip_fw_periodic(void)
} }
} }
} }
/*------------------------------------------------------------------------------*/
+33 -57
View File
@@ -60,116 +60,92 @@ struct uip_fw_netif
sends a packet. */ sends a packet. */
}; };
/** /* Intantiating macro for a uIP network interface.
* Intantiating macro for a uIP network interface.
* *
* Example: * 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) \ #define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
NULL, \ NULL, \
{HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \ {HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \
{HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \ {HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \
outputfunc 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. * addr A pointer to an IP address.
*
* \hideinitializer
*/ */
#define uip_fw_setipaddr(netif, addr) \ #define uip_fw_setipaddr(netif, addr) \
do { (netif)->ipaddr[0] = ((uint16 *)(addr))[0]; \ do { (netif)->ipaddr[0] = ((uint16 *)(addr))[0]; \
(netif)->ipaddr[1] = ((uint16 *)(addr))[1]; } while(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. * addr A pointer to an IP address representing the netmask.
*
* \hideinitializer
*/ */
#define uip_fw_setnetmask(netif, addr) \ #define uip_fw_setnetmask(netif, addr) \
do { (netif)->netmask[0] = ((uint16 *)(addr))[0]; \ do { (netif)->netmask[0] = ((uint16 *)(addr))[0]; \
(netif)->netmask[1] = ((uint16 *)(addr))[1]; } while(0) (netif)->netmask[1] = ((uint16 *)(addr))[1]; } while(0)
void uip_fw_init(void); void uip_fw_init(void);
uint8 uip_fw_forward(void); uint8 uip_fw_forward(struct uip_driver_s *dev);
uint8 uip_fw_output(void); uint8 uip_fw_output(struct uip_driver_s *dev);
void uip_fw_register(struct uip_fw_netif *netif); void uip_fw_register(struct uip_fw_netif *netif);
void uip_fw_default(struct uip_fw_netif *netif); void uip_fw_default(struct uip_fw_netif *netif);
void uip_fw_periodic(void); 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. * processed locally.
*
* \hideinitializer
*/ */
#define UIP_FW_LOCAL 0 #define UIP_FW_LOCAL 0
/** /* A non-error message that indicates that something went OK. */
* A non-error message that indicates that something went OK.
*
* \hideinitializer
*/
#define UIP_FW_OK 0 #define UIP_FW_OK 0
/** /* A non-error message that indicates that a packet was forwarded. */
* A non-error message that indicates that a packet was forwarded.
*
* \hideinitializer
*/
#define UIP_FW_FORWARDED 1 #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. * transmission was attempted, and that no packet was sent.
*
* \hideinitializer
*/ */
#define UIP_FW_ZEROLEN 2 #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. * for the outbound network interface was detected.
*
* \hideinitializer
*/ */
#define UIP_FW_TOOLARGE 3 #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. * found for an outbound packet.
*
* \hideinitializer
*/ */
#define UIP_FW_NOROUTE 4 #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. * forwarded or output was dropped.
*
* \hideinitializer
*/ */
#define UIP_FW_DROPPED 5 #define UIP_FW_DROPPED 5
#endif /* __UIP_FW_H__ */ #endif /* __UIP_FW_H__ */
/** @} */
+99
View File
@@ -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
View File
@@ -38,19 +38,17 @@
#include "uip-split.h" #include "uip-split.h"
#include "uip-fw.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(struct uip_driver_s *dev)
void
uip_split_output(void)
{ {
uint16 tcplen, len1, len2; uint16 tcplen, len1, len2;
/* We only try to split maximum sized TCP segments. */ /* We only try to split maximum sized TCP segments. */
if(BUF->proto == UIP_PROTO_TCP && 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 /* Split the segment in two. If the original packet length was
odd, we make the second packet one byte larger. */ odd, we make the second packet one byte larger. */
len1 = len2 = tcplen / 2; len1 = len2 = tcplen / 2;
@@ -60,49 +58,49 @@ uip_split_output(void)
/* Create the first packet. This is done by altering the length /* Create the first packet. This is done by altering the length
field of the IP header and updating the checksums. */ 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 #ifdef CONFIG_NET_IPv6
/* For IPv6, the IP length field does not include the IPv6 IP header /* For IPv6, the IP length field does not include the IPv6 IP header
length. */ length. */
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
#else /* CONFIG_NET_IPv6 */ #else /* CONFIG_NET_IPv6 */
BUF->len[0] = uip_len >> 8; BUF->len[0] = dev->d_len >> 8;
BUF->len[1] = uip_len & 0xff; BUF->len[1] = dev->d_len & 0xff;
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
/* Recalculate the TCP checksum. */ /* Recalculate the TCP checksum. */
BUF->tcpchksum = 0; BUF->tcpchksum = 0;
BUF->tcpchksum = ~(uip_tcpchksum()); BUF->tcpchksum = ~(uip_tcpchksum(dev));
#ifndef CONFIG_NET_IPv6 #ifndef CONFIG_NET_IPv6
/* Recalculate the IP checksum. */ /* Recalculate the IP checksum. */
BUF->ipchksum = 0; BUF->ipchksum = 0;
BUF->ipchksum = ~(uip_ipchksum()); BUF->ipchksum = ~(uip_ipchksum(dev));
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
/* Transmit the first packet. */ /* Transmit the first packet. */
/* uip_fw_output();*/ /* uip_fw_output();*/
tcpip_output(); tcpip_output();
/* Now, create the second packet. To do this, it is not enough to /* 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 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 memory. This place is detemined by the length of the first
packet (len1). */ packet (len1). */
uip_len = len2 + UIP_TCPIP_HLEN; dev->d_len = len2 + UIP_TCPIP_HLEN;
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
/* For IPv6, the IP length field does not include the IPv6 IP header /* For IPv6, the IP length field does not include the IPv6 IP header
length. */ length. */
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
#else /* CONFIG_NET_IPv6 */ #else /* CONFIG_NET_IPv6 */
BUF->len[0] = uip_len >> 8; BUF->len[0] = dev->d_len >> 8;
BUF->len[1] = uip_len & 0xff; BUF->len[1] = dev->d_len & 0xff;
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
/* uip_appdata += len1;*/ /* dev->d_appdata += len1;*/
memcpy(uip_appdata, (uint8 *)uip_appdata + len1, len2); memcpy(dev->d_appdata, dev->d_appdata + len1, len2);
uip_add32(BUF->seqno, len1); uip_add32(BUF->seqno, len1);
BUF->seqno[0] = uip_acc32[0]; BUF->seqno[0] = uip_acc32[0];
@@ -112,12 +110,12 @@ uip_split_output(void)
/* Recalculate the TCP checksum. */ /* Recalculate the TCP checksum. */
BUF->tcpchksum = 0; BUF->tcpchksum = 0;
BUF->tcpchksum = ~(uip_tcpchksum()); BUF->tcpchksum = ~(uip_tcpchksum(dev));
#ifndef CONFIG_NET_IPv6 #ifndef CONFIG_NET_IPv6
/* Recalculate the IP checksum. */ /* Recalculate the IP checksum. */
BUF->ipchksum = 0; BUF->ipchksum = 0;
BUF->ipchksum = ~(uip_ipchksum()); BUF->ipchksum = ~(uip_ipchksum(dev));
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
/* Transmit the second packet. */ /* Transmit the second packet. */
@@ -127,6 +125,4 @@ uip_split_output(void)
/* uip_fw_output();*/ /* uip_fw_output();*/
tcpip_output(); tcpip_output();
} }
} }
/*-----------------------------------------------------------------------------*/
+7 -8
View File
@@ -66,23 +66,22 @@
#ifndef __UIP_SPLIT_H__ #ifndef __UIP_SPLIT_H__
#define __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 * 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 * full-sized TCP segment it will be split into two segments and
* transmitted separately. This function should be called instead of * transmitted separately. This function should be called instead of
* the actual device driver output function, or the uip_fw_output() * the actual device driver output function, or the uip_fw_output()
* function. * function.
* *
* The headers of the outgoing packet is assumed to be in the uip_buf * The headers of the outgoing packet is assumed to be in the d_buf
* buffer and the payload is assumed to be wherever uip_appdata * buffer and the payload is assumed to be wherever d_appdata
* points. The length of the outgoing packet is assumed to be in the * 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__ */ #endif /* __UIP_SPLIT_H__ */
+2 -2
View File
@@ -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_conn = &g_tcp_connections[conn];
uip_interrupt(UIP_TIMER); uip_interrupt(dev, UIP_TIMER);
} }
/**************************************************************************** /****************************************************************************
+2 -2
View File
@@ -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_udp_conn = &g_udp_connections[conn];
uip_interrupt(UIP_UDP_TIMER); uip_interrupt(dev, UIP_UDP_TIMER);
} }
/**************************************************************************** /****************************************************************************
+169 -174
View File
File diff suppressed because it is too large Load Diff
+222 -207
View File
File diff suppressed because it is too large Load Diff
+20 -18
View File
@@ -57,6 +57,8 @@
#include <net/uip/resolv.h> #include <net/uip/resolv.h>
#include "uiplib/uiplib.h" #include "uiplib/uiplib.h"
#include <net/uip/uip-arch.h>
#include "webclient.h" #include "webclient.h"
#define WEBCLIENT_TIMEOUT 100 #define WEBCLIENT_TIMEOUT 100
@@ -178,14 +180,14 @@ static char *copy_string(char *dest, const char *src, int len)
return dest + len; return dest + len;
} }
static void senddata(void) static void senddata(struct uip_driver_s *dev)
{ {
uint16 len; uint16 len;
char *getrequest; char *getrequest;
char *cptr; char *cptr;
if (s.getrequestleft > 0) { 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, http_get, sizeof(http_get) - 1);
cptr = copy_string(cptr, s.file, strlen(s.file)); cptr = copy_string(cptr, s.file, strlen(s.file));
@@ -204,7 +206,7 @@ static void senddata(void)
len = s.getrequestleft > uip_mss()? len = s.getrequestleft > uip_mss()?
uip_mss(): uip_mss():
s.getrequestleft; 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; char *cptr;
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline))
{ {
char *pappdata = (char*)uip_appdata; char *pappdata = (char*)dev->d_appdata;
s.httpheaderline[s.httpheaderlineptr] = *pappdata++; s.httpheaderline[s.httpheaderlineptr] = *pappdata++;
uip_appdata = (void*)pappdata; dev->d_appdata = (void*)pappdata;
len--; len--;
if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl) if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl)
@@ -301,16 +303,16 @@ static char casecmp(char *str1, const char *str2, char len)
return 0; return 0;
} }
static uint16 parse_headers(uint16 len) static uint16 parse_headers(struct uip_driver_s *dev, uint16 len)
{ {
char *cptr; char *cptr;
static unsigned char i; static unsigned char i;
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline))
{ {
char *pappdata = (char*)uip_appdata; char *pappdata = (char*)dev->d_appdata;
s.httpheaderline[s.httpheaderlineptr] = *pappdata++; s.httpheaderline[s.httpheaderlineptr] = *pappdata++;
uip_appdata = (void*)pappdata; dev->d_appdata = (void*)pappdata;
len--; len--;
if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl) if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl)
@@ -378,23 +380,23 @@ static uint16 parse_headers(uint16 len)
return len; return len;
} }
static void newdata(void) static void newdata(struct uip_driver_s *dev)
{ {
uint16 len; uint16 len;
len = uip_datalen(); len = uip_datalen(dev);
if (s.state == WEBCLIENT_STATE_STATUSLINE) { if (s.state == WEBCLIENT_STATE_STATUSLINE) {
len = parse_statusline(len); len = parse_statusline(dev, len);
} }
if (s.state == WEBCLIENT_STATE_HEADERS && len > 0) { 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 && if (len > 0 && s.state == WEBCLIENT_STATE_DATA &&
s.httpflag != HTTPFLAG_MOVED) { 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. * event of interest occurs.
*/ */
void uip_interrupt_event(void) void uip_interrupt_event(struct uip_driver_s *dev)
{ {
#warning OBSOLETE -- needs to be redesigned #warning OBSOLETE -- needs to be redesigned
if (uip_connected()) if (uip_connected())
{ {
s.timer = 0; s.timer = 0;
s.state = WEBCLIENT_STATE_STATUSLINE; s.state = WEBCLIENT_STATE_STATUSLINE;
senddata(); senddata(dev);
webclient_connected(); webclient_connected();
return; return;
} }
@@ -440,12 +442,12 @@ void uip_interrupt_event(void)
if (uip_newdata()) if (uip_newdata())
{ {
s.timer = 0; s.timer = 0;
newdata(); newdata(dev);
} }
if (uip_rexmit() || uip_newdata() || uip_acked()) if (uip_rexmit() || uip_newdata() || uip_acked())
{ {
senddata(); senddata(dev);
} }
else if (uip_poll()) else if (uip_poll())
{ {