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:
parent
d63a0352a5
commit
23dcda6743
30 changed files with 1172 additions and 962 deletions
|
@ -1391,9 +1391,6 @@ The system can be re-made subsequently by just typing <code>make</code>.
|
|||
<li>
|
||||
<code>CONFIG_NET_LLH_LEN</code>: The link level header length
|
||||
</li>
|
||||
<li>
|
||||
<code>CONFIG_NET_EXTERNAL_BUFFER</code>: Incoming packet buffer (uip_buf) is defined externally
|
||||
</li>
|
||||
<li>
|
||||
<code>CONFIG_NET_FWCACHE_SIZE</code>: number of packets to remember when looking for duplicates
|
||||
</li>
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
* Private Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define BUF ((struct uip_eth_hdr *)g_sim_dev.d_buf)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
|
@ -75,8 +75,9 @@ struct timer
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct timer periodic_timer;
|
||||
static struct timer arp_timer;
|
||||
static struct timer g_periodic_timer;
|
||||
static struct timer g_arp_timer;
|
||||
static struct uip_driver_s g_sim_dev;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -106,82 +107,82 @@ void uipdriver_loop(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
uip_len = tapdev_read((unsigned char*)uip_buf, UIP_BUFSIZE);
|
||||
if (uip_len > 0)
|
||||
g_sim_dev.d_len = tapdev_read((unsigned char*)g_sim_dev.d_buf, UIP_BUFSIZE);
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
if (BUF->type == htons(UIP_ETHTYPE_IP))
|
||||
{
|
||||
uip_arp_ipin();
|
||||
uip_input();
|
||||
uip_input(&g_sim_dev);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* uip_len is set to a value > 0.
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (uip_len > 0)
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
tapdev_send((char*)uip_buf, uip_len);
|
||||
uip_arp_out(&g_sim_dev);
|
||||
tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
|
||||
}
|
||||
}
|
||||
else if (BUF->type == htons(UIP_ETHTYPE_ARP))
|
||||
{
|
||||
uip_arp_arpin();
|
||||
uip_arp_arpin(&g_sim_dev);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* uip_len is set to a value > 0.
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (uip_len > 0)
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
tapdev_send((char*)uip_buf, uip_len);
|
||||
tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (timer_expired(&periodic_timer))
|
||||
else if (timer_expired(&g_periodic_timer))
|
||||
{
|
||||
timer_reset(&periodic_timer);
|
||||
timer_reset(&g_periodic_timer);
|
||||
for(i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
uip_tcppoll(i);
|
||||
uip_tcppoll(&g_sim_dev,i);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* uip_len is set to a value > 0.
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (uip_len > 0)
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
tapdev_send((char*)uip_buf, uip_len);
|
||||
uip_arp_out(&g_sim_dev);
|
||||
tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
for(i = 0; i < UIP_UDP_CONNS; i++)
|
||||
{
|
||||
uip_udppoll(i);
|
||||
uip_udppoll(&g_sim_dev,i);
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
* should be sent out on the network, the global variable
|
||||
* uip_len is set to a value > 0.
|
||||
* d_len is set to a value > 0.
|
||||
*/
|
||||
|
||||
if (uip_len > 0)
|
||||
if (g_sim_dev.d_len > 0)
|
||||
{
|
||||
uip_arp_out();
|
||||
tapdev_send((char*)uip_buf, uip_len);
|
||||
uip_arp_out(&g_sim_dev);
|
||||
tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
/* Call the ARP timer function every 10 seconds. */
|
||||
|
||||
if (timer_expired(&arp_timer))
|
||||
if (timer_expired(&g_arp_timer))
|
||||
{
|
||||
timer_reset(&arp_timer);
|
||||
timer_reset(&g_arp_timer);
|
||||
uip_arp_timer();
|
||||
}
|
||||
}
|
||||
|
@ -189,8 +190,8 @@ void uipdriver_loop(void)
|
|||
|
||||
int uipdriver_init(void)
|
||||
{
|
||||
timer_set(&periodic_timer, 500);
|
||||
timer_set(&arp_timer, 10000 );
|
||||
timer_set(&g_periodic_timer, 500);
|
||||
timer_set(&g_arp_timer, 10000 );
|
||||
|
||||
tapdev_init();
|
||||
uip_init();
|
||||
|
|
|
@ -229,8 +229,6 @@ defconfig -- This is a configuration file similar to the Linux
|
|||
CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
CONFIG_NET_BROADCAST - Broadcast support
|
||||
CONFIG_NET_LLH_LEN - The link level header length
|
||||
CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf)
|
||||
is defined externally
|
||||
CONFIG_NET_FWCACHE_SIZE - number of packets to remember when
|
||||
looking for duplicates
|
||||
|
||||
|
|
|
@ -268,7 +268,6 @@ CONFIG_PREALLOC_TIMERS=8
|
|||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
|
@ -287,7 +286,6 @@ CONFIG_NET_STATISTICS=y
|
|||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
|
|
@ -257,7 +257,6 @@ CONFIG_PREALLOC_TIMERS=8
|
|||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
|
@ -276,7 +275,6 @@ CONFIG_NET_STATISTICS=y
|
|||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
|
|
@ -281,7 +281,6 @@ CONFIG_PREALLOC_TIMERS=8
|
|||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
|
@ -300,7 +299,6 @@ CONFIG_NET_STATISTICS=y
|
|||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
|
|
@ -266,7 +266,6 @@ CONFIG_PREALLOC_TIMERS=8
|
|||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
|
@ -285,7 +284,6 @@ CONFIG_NET_STATISTICS=y
|
|||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
|
|
@ -254,7 +254,6 @@ CONFIG_PREALLOC_TIMERS=0
|
|||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
|
@ -273,7 +272,6 @@ CONFIG_NET_STATISTICS=y
|
|||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
|
|
@ -228,7 +228,6 @@ CONFIG_FS_FAT=y
|
|||
# CONFIG_NET_ARPTAB_SIZE - The size of the ARP table
|
||||
# CONFIG_NET_BROADCAST - Broadcast support
|
||||
# CONFIG_NET_LLH_LEN - The link level header length
|
||||
# CONFIG_NET_EXTERNAL_BUFFER - Incoming packet buffer (uip_buf) is defined externally
|
||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||
CONFIG_NET=n
|
||||
CONFIG_NET_IPv6=n
|
||||
|
@ -247,7 +246,6 @@ CONFIG_NET_STATISTICS=y
|
|||
#CONFIG_NET_ARPTAB_SIZE=8
|
||||
CONFIG_NET_BROADCAST=n
|
||||
#CONFIG_NET_LLH_LEN=14
|
||||
CONFIG_NET_EXTERNAL_BUFFER=n
|
||||
#CONFIG_NET_FWCACHE_SIZE=2
|
||||
|
||||
#
|
||||
|
|
|
@ -63,16 +63,96 @@
|
|||
* the macrose defined in this file.
|
||||
*/
|
||||
|
||||
#define UIP_DATA 1 /* Tells uIP that there is incoming data in the uip_buf buffer. The
|
||||
* length of the data is stored in the global variable uip_len. */
|
||||
#define UIP_DATA 1 /* Tells uIP that there is incoming data in the d_buf buffer. The
|
||||
* length of the data is stored in the field d_len. */
|
||||
#define UIP_TIMER 2 /* Tells uIP that the periodic timer has fired. */
|
||||
#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should be polled. */
|
||||
#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram should be constructed in the
|
||||
* uip_buf buffer. */
|
||||
#ifdef CONFIG_NET_UDP
|
||||
* d_buf buffer. */
|
||||
#ifdef CONFIG_NET_UDP
|
||||
# define UIP_UDP_TIMER 5
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure collects information that is specific to a specific network
|
||||
* interface driver. If the hardware platform supports only a single instance
|
||||
* of this structure.
|
||||
*/
|
||||
|
||||
struct uip_driver_s
|
||||
{
|
||||
/* The uIP packet buffer.
|
||||
*
|
||||
* The d_buf array is used to hold incoming and outgoing
|
||||
* packets. The device driver should place incoming data into this
|
||||
* buffer. When sending data, the device driver should read the link
|
||||
* level headers and the TCP/IP headers from this buffer. The size of
|
||||
* the link level headers is configured by the UIP_LLH_LEN define.
|
||||
*
|
||||
* Note: The application data need not be placed in this buffer, so
|
||||
* the device driver must read it from the place pointed to by the
|
||||
* d_appdata pointer as illustrated by the following example:
|
||||
*
|
||||
* void
|
||||
* devicedriver_send(void)
|
||||
* {
|
||||
* hwsend(&dev->d_buf[0], UIP_LLH_LEN);
|
||||
* if(dev->d_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
|
||||
* hwsend(&dev->d_buf[UIP_LLH_LEN], dev->d_len - UIP_LLH_LEN);
|
||||
* } else {
|
||||
* hwsend(&dev->d_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
|
||||
* hwsend(dev->d_appdata, dev->d_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
uint8 d_buf[UIP_BUFSIZE + 2];
|
||||
|
||||
/* d_appdata points to the location where application data can be read from
|
||||
* or written into a packet.
|
||||
*/
|
||||
|
||||
uint8 *d_appdata;
|
||||
|
||||
/* This is a pointer into d_buf where a user application may append
|
||||
* data to be sent.
|
||||
*/
|
||||
|
||||
uint8 *d_snddata;
|
||||
|
||||
/* The length of the packet in the d_buf buffer.
|
||||
*
|
||||
* Holds the length of the packet in the d_buf buffer.
|
||||
*
|
||||
* When the network device driver calls the uIP input function,
|
||||
* d_len should be set to the length of the packet in the d_buf
|
||||
* buffer.
|
||||
*
|
||||
* When sending packets, the device driver should use the contents of
|
||||
* the d_len variable to determine the length of the outgoing
|
||||
* packet.
|
||||
*/
|
||||
|
||||
uint16 d_len;
|
||||
|
||||
/* When d_buf contains outgoing xmit data, xmtlen is nonzero and represents
|
||||
* the amount of appllcation data after d_snddata
|
||||
*/
|
||||
|
||||
uint16 d_sndlen;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pulblic Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* uIP device driver functions
|
||||
*
|
||||
* These functions are used by a network device driver for interacting
|
||||
|
@ -82,21 +162,21 @@
|
|||
*
|
||||
* This function should be called when the device driver has received
|
||||
* a packet from the network. The packet from the device driver must
|
||||
* be present in the uip_buf buffer, and the length of the packet
|
||||
* should be placed in the uip_len variable.
|
||||
* be present in the d_buf buffer, and the length of the packet
|
||||
* should be placed in the d_len field.
|
||||
*
|
||||
* When the function returns, there may be an outbound packet placed
|
||||
* in the uip_buf packet buffer. If so, the uip_len variable is set to
|
||||
* in the d_buf packet buffer. If so, the d_len field is set to
|
||||
* the length of the packet. If no packet is to be sent out, the
|
||||
* uip_len variable is set to 0.
|
||||
* d_len field is set to 0.
|
||||
*
|
||||
* The usual way of calling the function is presented by the source
|
||||
* code below.
|
||||
*
|
||||
* uip_len = devicedriver_poll();
|
||||
* if(uip_len > 0) {
|
||||
* dev->d_len = devicedriver_poll();
|
||||
* if(dev->d_len > 0) {
|
||||
* uip_input();
|
||||
* if(uip_len > 0) {
|
||||
* if(dev->d_len > 0) {
|
||||
* devicedriver_send();
|
||||
* }
|
||||
* }
|
||||
|
@ -106,25 +186,25 @@
|
|||
* Ethernet, you will need to call the uIP ARP code before calling
|
||||
* this function:
|
||||
*
|
||||
* #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
* uip_len = ethernet_devicedrver_poll();
|
||||
* if(uip_len > 0) {
|
||||
* #define BUF ((struct uip_eth_hdr *)&dev->d_buf[0])
|
||||
* dev->d_len = ethernet_devicedrver_poll();
|
||||
* if(dev->d_len > 0) {
|
||||
* if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
|
||||
* uip_arp_ipin();
|
||||
* uip_input();
|
||||
* if(uip_len > 0) {
|
||||
* if(dev->d_len > 0) {
|
||||
* uip_arp_out();
|
||||
* ethernet_devicedriver_send();
|
||||
* }
|
||||
* } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
|
||||
* uip_arp_arpin();
|
||||
* if(uip_len > 0) {
|
||||
* if(dev->d_len > 0) {
|
||||
* ethernet_devicedriver_send();
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
#define uip_input() uip_interrupt(UIP_DATA)
|
||||
#define uip_input(dev) uip_interrupt(dev,UIP_DATA)
|
||||
|
||||
/* Periodic processing for a connection identified by its number.
|
||||
*
|
||||
|
@ -134,8 +214,8 @@
|
|||
* connection, regardless of whether they are open of closed.
|
||||
*
|
||||
* When the function returns, it may have an outbound packet waiting
|
||||
* for service in the uIP packet buffer, and if so the uip_len
|
||||
* variable is set to a value larger than zero. The device driver
|
||||
* for service in the uIP packet buffer, and if so the d_len field
|
||||
* is set to a value larger than zero. The device driver
|
||||
* should be called to send out the packet.
|
||||
*
|
||||
* The ususal way of calling the function is through a for() loop like
|
||||
|
@ -143,8 +223,8 @@
|
|||
*
|
||||
* for(i = 0; i < UIP_CONNS; ++i)
|
||||
* {
|
||||
* uip_tcppoll(i);
|
||||
* if (uip_len > 0)
|
||||
* uip_tcppoll(dev,i);
|
||||
* if (dev->d_len > 0)
|
||||
* {
|
||||
* devicedriver_send();
|
||||
* }
|
||||
|
@ -157,8 +237,8 @@
|
|||
*
|
||||
* for(i = 0; i < UIP_CONNS; ++i)
|
||||
* {
|
||||
* uip_tcppoll(i);
|
||||
* if (uip_len > 0)
|
||||
* uip_tcppoll(dev,i);
|
||||
* if (dev->d_len > 0)
|
||||
* {
|
||||
* uip_arp_out();
|
||||
* ethernet_devicedriver_send();
|
||||
|
@ -168,7 +248,7 @@
|
|||
* conn The number of the connection which is to be periodically polled.
|
||||
*/
|
||||
|
||||
extern void uip_tcppoll(unsigned int conn);
|
||||
extern void uip_tcppoll(struct uip_driver_s *dev, unsigned int conn);
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
/* Periodic processing for a UDP connection identified by its number.
|
||||
|
@ -179,8 +259,8 @@ extern void uip_tcppoll(unsigned int conn);
|
|||
*
|
||||
* for(i = 0; i < UIP_UDP_CONNS; i++)
|
||||
* {
|
||||
* uip_udppoll(i);
|
||||
* if(uip_len > 0)
|
||||
* uip_udppoll(dev,i);
|
||||
* if(dev->d_len > 0)
|
||||
* {
|
||||
* devicedriver_send();
|
||||
* }
|
||||
|
@ -191,8 +271,8 @@ extern void uip_tcppoll(unsigned int conn);
|
|||
*
|
||||
* for(i = 0; i < UIP_UDP_CONNS; i++)
|
||||
* {
|
||||
* uip_udppoll(i);
|
||||
* if(uip_len > 0)
|
||||
* uip_udppoll(dev,i);
|
||||
* if(dev->d_len > 0)
|
||||
* {
|
||||
* uip_arp_out();
|
||||
* ethernet_devicedriver_send();
|
||||
|
@ -202,31 +282,17 @@ extern void uip_tcppoll(unsigned int conn);
|
|||
* conn The number of the UDP connection to be processed.
|
||||
*/
|
||||
|
||||
extern void uip_udppoll(unsigned int conn);
|
||||
extern void uip_udppoll(struct uip_driver_s *dev, unsigned int conn);
|
||||
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pulblic Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Architecure support
|
||||
*
|
||||
* uip_interrupt(flag):
|
||||
*
|
||||
* The actual uIP function which does all the work. Called from the
|
||||
* interrupt level by a device driver.
|
||||
*/
|
||||
|
||||
extern void uip_interrupt(uint8 flag);
|
||||
extern void uip_interrupt(struct uip_driver_s *dev, uint8 flag);
|
||||
|
||||
/* By defining UIP_ARCH_CHKSUM, the architecture can replace the following
|
||||
* functions with hardware assisted solutions.
|
||||
|
@ -273,32 +339,32 @@ extern void uip_add32(uint8 *op32, uint16 op16);
|
|||
|
||||
extern uint16 uip_chksum(uint16 *buf, uint16 len);
|
||||
|
||||
/* Calculate the IP header checksum of the packet header in uip_buf.
|
||||
/* Calculate the IP header checksum of the packet header in d_buf.
|
||||
*
|
||||
* The IP header checksum is the Internet checksum of the 20 bytes of
|
||||
* the IP header.
|
||||
*
|
||||
* Return: The IP header checksum of the IP header in the uip_buf
|
||||
* Return: The IP header checksum of the IP header in the d_buf
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
extern uint16 uip_ipchksum(void);
|
||||
extern uint16 uip_ipchksum(struct uip_driver_s *dev);
|
||||
|
||||
/* Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
|
||||
/* Calculate the TCP checksum of the packet in d_buf and d_appdata.
|
||||
*
|
||||
* The TCP checksum is the Internet checksum of data contents of the
|
||||
* TCP segment, and a pseudo-header as defined in RFC793.
|
||||
*
|
||||
* Note: The uip_appdata pointer that points to the packet data may
|
||||
* Note: The d_appdata pointer that points to the packet data may
|
||||
* point anywhere in memory, so it is not possible to simply calculate
|
||||
* the Internet checksum of the contents of the uip_buf buffer.
|
||||
* the Internet checksum of the contents of the d_buf buffer.
|
||||
*
|
||||
* Return: The TCP checksum of the TCP segment in uip_buf and pointed
|
||||
* to by uip_appdata.
|
||||
* Return: The TCP checksum of the TCP segment in d_buf and pointed
|
||||
* to by d_appdata.
|
||||
*/
|
||||
|
||||
extern uint16 uip_tcpchksum(void);
|
||||
extern uint16 uip_tcpchksum(struct uip_driver_s *dev);
|
||||
|
||||
extern uint16 uip_udpchksum(void);
|
||||
extern uint16 uip_udpchksum(struct uip_driver_s *dev);
|
||||
|
||||
#endif /* __UIP_ARCH_H */
|
||||
|
|
|
@ -61,36 +61,35 @@ void uip_arp_init(void);
|
|||
/* The uip_arp_ipin() function should be called whenever an IP packet
|
||||
* arrives from the Ethernet. This function refreshes the ARP table or
|
||||
* inserts a new mapping if none exists. The function assumes that an
|
||||
* IP packet with an Ethernet header is present in the uip_buf buffer
|
||||
* and that the length of the packet is in the uip_len variable.
|
||||
* IP packet with an Ethernet header is present in the d_buf buffer
|
||||
* and that the length of the packet is in the d_len field.
|
||||
*/
|
||||
|
||||
/*void uip_arp_ipin(void);*/
|
||||
#define uip_arp_ipin()
|
||||
|
||||
/* The uip_arp_arpin() should be called when an ARP packet is received
|
||||
* by the Ethernet driver. This function also assumes that the
|
||||
* Ethernet frame is present in the uip_buf buffer. When the
|
||||
* uip_arp_arpin() function returns, the contents of the uip_buf
|
||||
* buffer should be sent out on the Ethernet if the uip_len variable
|
||||
* Ethernet frame is present in the d_buf buffer. When the
|
||||
* uip_arp_arpin() function returns, the contents of the d_buf
|
||||
* buffer should be sent out on the Ethernet if the d_len field
|
||||
* is > 0.
|
||||
*/
|
||||
|
||||
void uip_arp_arpin(void);
|
||||
void uip_arp_arpin(struct uip_driver_s *dev);
|
||||
|
||||
/* The uip_arp_out() function should be called when an IP packet
|
||||
* should be sent out on the Ethernet. This function creates an
|
||||
* Ethernet header before the IP header in the uip_buf buffer. The
|
||||
* Ethernet header before the IP header in the d_buf buffer. The
|
||||
* Ethernet header will have the correct Ethernet MAC destination
|
||||
* address filled in if an ARP table entry for the destination IP
|
||||
* address (or the IP address of the default router) is present. If no
|
||||
* such table entry is found, the IP packet is overwritten with an ARP
|
||||
* request and we rely on TCP to retransmit the packet that was
|
||||
* overwritten. In any case, the uip_len variable holds the length of
|
||||
* overwritten. In any case, the d_len field holds the length of
|
||||
* the Ethernet frame that should be transmitted.
|
||||
*/
|
||||
|
||||
void uip_arp_out(void);
|
||||
void uip_arp_out(struct uip_driver_s *dev);
|
||||
|
||||
/* The uip_arp_timer() function should be called every ten seconds. It
|
||||
* is responsible for flushing old entries in the ARP table.
|
||||
|
|
|
@ -84,6 +84,9 @@
|
|||
* successfully established. */
|
||||
#define UIP_TIMEDOUT (1 << 7) /* The connection has been aborted due to too many retransmissions. */
|
||||
|
||||
#define UIP_DATA_EVENTS (UIP_ACKDATA|UIP_NEWDATA|UIP_REXMIT|UIP_POLL)
|
||||
#define UIP_CONN_EVENTS (UIP_CLOSE|UIP_ABORT|UIP_CONNECTED|UIP_TIMEDOUT)
|
||||
|
||||
/* The TCP states used in the uip_conn->tcpstateflags. */
|
||||
|
||||
#define UIP_CLOSED 0 /* The connection is not in use and available */
|
||||
|
@ -100,15 +103,15 @@
|
|||
#define UIP_TS_MASK 15
|
||||
#define UIP_STOPPED 16
|
||||
|
||||
/* The buffer size available for user data in the \ref uip_buf buffer.
|
||||
/* The buffer size available for user data in the d_buf buffer.
|
||||
*
|
||||
* This macro holds the available size for user data in the \ref
|
||||
* uip_buf buffer. The macro is intended to be used for checking
|
||||
* d_buf buffer. The macro is intended to be used for checking
|
||||
* bounds of available user data.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
|
||||
* snprintf(dev->d_appdata, UIP_APPDATA_SIZE, "%u\n", i);
|
||||
*/
|
||||
|
||||
#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
||||
|
@ -156,6 +159,7 @@ typedef uip_ip4addr_t uip_ipaddr_t;
|
|||
* file pointers) for the connection.
|
||||
*/
|
||||
|
||||
struct uip_driver_s; /* Forward reference */
|
||||
struct uip_conn
|
||||
{
|
||||
dq_entry_t node; /* Implements a doubly linked list */
|
||||
|
@ -186,8 +190,10 @@ struct uip_conn
|
|||
* in the following:
|
||||
*/
|
||||
|
||||
void *private;
|
||||
void (*callback)(void *private);
|
||||
void *data_private;
|
||||
void (*data_event)(struct uip_driver_s *dev, void *private);
|
||||
void *connection_private;
|
||||
void (*connection_event)(void *private);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
|
@ -204,7 +210,7 @@ struct uip_udp_conn
|
|||
/* Defines the UDP callback */
|
||||
|
||||
void *private;
|
||||
void (*callback)(void *private);
|
||||
void (*event)(struct uip_driver_s *dev, void *private);
|
||||
};
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
|
@ -232,6 +238,7 @@ struct uip_stats
|
|||
uip_stats_t protoerr; /* Number of packets dropped since they
|
||||
were neither ICMP, UDP nor TCP. */
|
||||
} ip; /* IP statistics. */
|
||||
|
||||
struct
|
||||
{
|
||||
uip_stats_t drop; /* Number of dropped ICMP packets. */
|
||||
|
@ -239,7 +246,9 @@ struct uip_stats
|
|||
uip_stats_t sent; /* Number of sent ICMP packets. */
|
||||
uip_stats_t typeerr; /* Number of ICMP packets with a wrong type. */
|
||||
} icmp; /* ICMP statistics. */
|
||||
|
||||
struct
|
||||
|
||||
{
|
||||
uip_stats_t drop; /* Number of dropped TCP segments. */
|
||||
uip_stats_t recv; /* Number of recived TCP segments. */
|
||||
|
@ -253,6 +262,7 @@ struct uip_stats
|
|||
uip_stats_t synrst; /* Number of SYNs for closed ports,
|
||||
triggering a RST. */
|
||||
} tcp; /* TCP statistics. */
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
struct
|
||||
{
|
||||
|
@ -269,6 +279,7 @@ struct uip_stats
|
|||
struct uip_tcpip_hdr
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
|
||||
/* IPv6 header. */
|
||||
|
||||
uint8 vtc;
|
||||
|
@ -279,6 +290,7 @@ struct uip_tcpip_hdr
|
|||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* IPv4 header. */
|
||||
|
||||
uint8 vhl;
|
||||
|
@ -291,6 +303,7 @@ struct uip_tcpip_hdr
|
|||
uint16 ipchksum;
|
||||
uint16 srcipaddr[2];
|
||||
uint16 destipaddr[2];
|
||||
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* TCP header. */
|
||||
|
@ -312,6 +325,7 @@ struct uip_tcpip_hdr
|
|||
struct uip_icmpip_hdr
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
|
||||
/* IPv6 header. */
|
||||
|
||||
uint8 vtc;
|
||||
|
@ -324,6 +338,7 @@ struct uip_icmpip_hdr
|
|||
uip_ip6addr_t destipaddr;
|
||||
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* IPv4 header. */
|
||||
|
||||
uint8 vhl;
|
||||
|
@ -336,17 +351,29 @@ struct uip_icmpip_hdr
|
|||
uint16 ipchksum;
|
||||
uint16 srcipaddr[2];
|
||||
uint16 destipaddr[2];
|
||||
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* ICMP (echo) header. */
|
||||
uint8 type, icode;
|
||||
|
||||
uint8 type;
|
||||
uint8 icode;
|
||||
uint16 icmpchksum;
|
||||
|
||||
#ifndef CONFIG_NET_IPv6
|
||||
uint16 id, seqno;
|
||||
|
||||
uint16 id;
|
||||
uint16 seqno;
|
||||
|
||||
#else /* !CONFIG_NET_IPv6 */
|
||||
uint8 flags, reserved1, reserved2, reserved3;
|
||||
|
||||
uint8 flags;
|
||||
uint8 reserved1;
|
||||
uint8 reserved2;
|
||||
uint8 reserved3;
|
||||
uint8 icmp6data[16];
|
||||
uint8 options[1];
|
||||
|
||||
#endif /* !CONFIG_NET_IPv6 */
|
||||
};
|
||||
|
||||
|
@ -355,6 +382,7 @@ struct uip_icmpip_hdr
|
|||
struct uip_udpip_hdr
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
|
||||
/* IPv6 header. */
|
||||
|
||||
uint8 vtc;
|
||||
|
@ -364,8 +392,10 @@ struct uip_udpip_hdr
|
|||
uint8 proto, ttl;
|
||||
uip_ip6addr_t srcipaddr;
|
||||
uip_ip6addr_t destipaddr;
|
||||
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
/* IP header. */
|
||||
|
||||
/* IPv4 header. */
|
||||
|
||||
uint8 vhl;
|
||||
uint8 tos;
|
||||
|
@ -377,6 +407,7 @@ struct uip_udpip_hdr
|
|||
uint16 ipchksum;
|
||||
uint16 srcipaddr[2];
|
||||
uint16 destipaddr[2];
|
||||
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* UDP header. */
|
||||
|
@ -398,42 +429,6 @@ struct uip_eth_addr
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The uIP packet buffer.
|
||||
*
|
||||
* The uip_buf array is used to hold incoming and outgoing
|
||||
* packets. The device driver should place incoming data into this
|
||||
* buffer. When sending data, the device driver should read the link
|
||||
* level headers and the TCP/IP headers from this buffer. The size of
|
||||
* the link level headers is configured by the UIP_LLH_LEN define.
|
||||
*
|
||||
* Note: The application data need not be placed in this buffer, so
|
||||
* the device driver must read it from the place pointed to by the
|
||||
* uip_appdata pointer as illustrated by the following example:
|
||||
*
|
||||
* void
|
||||
* devicedriver_send(void)
|
||||
* {
|
||||
* hwsend(&uip_buf[0], UIP_LLH_LEN);
|
||||
* if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
|
||||
* hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
|
||||
* } else {
|
||||
* hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
|
||||
* hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
extern uint8 uip_buf[UIP_BUFSIZE+2];
|
||||
|
||||
/* Pointer to the application data in the packet buffer.
|
||||
*
|
||||
* This pointer points to the application data when the application is
|
||||
* called. If the application wishes to send data, the application may
|
||||
* use this space to write the data into before calling uip_send().
|
||||
*/
|
||||
|
||||
extern void *uip_appdata;
|
||||
|
||||
#if UIP_URGDATA > 0
|
||||
/* uint8 *uip_urgdata:
|
||||
*
|
||||
|
@ -448,24 +443,8 @@ extern void *uip_urgdata;
|
|||
*
|
||||
* uIP has a few global variables that are used in device drivers for
|
||||
* uIP.
|
||||
*
|
||||
* The length of the packet in the uip_buf buffer.
|
||||
*
|
||||
* The global variable uip_len holds the length of the packet in the
|
||||
* uip_buf buffer.
|
||||
*
|
||||
* When the network device driver calls the uIP input function,
|
||||
* uip_len should be set to the length of the packet in the uip_buf
|
||||
* buffer.
|
||||
*
|
||||
* When sending packets, the device driver should use the contents of
|
||||
* the uip_len variable to determine the length of the outgoing
|
||||
* packet.
|
||||
*
|
||||
*/
|
||||
|
||||
extern uint16 uip_len;
|
||||
|
||||
#if UIP_URGDATA > 0
|
||||
extern uint16 uip_urglen, uip_surglen;
|
||||
#endif /* UIP_URGDATA > 0 */
|
||||
|
@ -703,16 +682,16 @@ void uip_unlisten(uint16 port);
|
|||
* len The maximum amount of data bytes to be sent.
|
||||
*/
|
||||
|
||||
void uip_send(const void *data, int len);
|
||||
void uip_send(struct uip_driver_s *dev, const void *buf, int len);
|
||||
|
||||
/* The length of any incoming data that is currently avaliable (if avaliable)
|
||||
* in the uip_appdata buffer.
|
||||
* in the d_appdata buffer.
|
||||
*
|
||||
* The test function uip_data() must first be used to check if there
|
||||
* is any data available at all.
|
||||
*/
|
||||
|
||||
#define uip_datalen() uip_len
|
||||
#define uip_datalen(dev) ((dev)->d_len)
|
||||
|
||||
/* The length of any out-of-band data (urgent data) that has arrived
|
||||
* on the connection.
|
||||
|
@ -778,8 +757,8 @@ void uip_send(const void *data, int len);
|
|||
/* Is new incoming data available?
|
||||
*
|
||||
* Will reduce to non-zero if there is new data for the application
|
||||
* present at the uip_appdata pointer. The size of the data is
|
||||
* avaliable through the uip_len variable.
|
||||
* present at the d_appdata pointer. The size of the data is
|
||||
* avaliable through the d_len element.
|
||||
*/
|
||||
|
||||
#define uip_newdata() (uip_flags & UIP_NEWDATA)
|
||||
|
@ -897,17 +876,6 @@ extern int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *a
|
|||
extern void uip_udpenable(struct uip_udp_conn *conn);
|
||||
extern void uip_udpdisable(struct uip_udp_conn *conn);
|
||||
|
||||
/* Send a UDP datagram of length len on the current connection.
|
||||
*
|
||||
* This function can only be called in response to a UDP event (poll
|
||||
* or newdata). The data must be present in the uip_buf buffer, at the
|
||||
* place pointed to by the uip_appdata pointer.
|
||||
*
|
||||
* len The length of the data in the uip_buf buffer.
|
||||
*/
|
||||
|
||||
#define uip_udp_send(len) uip_send((char *)uip_appdata, len)
|
||||
|
||||
/* uIP convenience and converting functions.
|
||||
*
|
||||
* These functions can be used for converting between different data
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
* uIP supports reassembly of fragmented IP packets. This features
|
||||
* requires an additonal amount of RAM to hold the reassembly buffer
|
||||
* and the reassembly code size is approximately 700 bytes. The
|
||||
* reassembly buffer is of the same size as the uip_buf buffer
|
||||
* reassembly buffer is of the same size as the d_buf buffer
|
||||
* (configured by UIP_BUFSIZE).
|
||||
*
|
||||
* Note: IP packet reassembly is not heavily tested.
|
||||
|
@ -234,7 +234,7 @@
|
|||
|
||||
/* The size of the advertised receiver's window.
|
||||
*
|
||||
* Should be set low (i.e., to the size of the uip_buf buffer) is the
|
||||
* Should be set low (i.e., to the size of the d_buf buffer) is the
|
||||
* application is slow to process incoming data, or high (32768 bytes)
|
||||
* if the application processes data quickly.
|
||||
*/
|
||||
|
@ -328,7 +328,7 @@
|
|||
|
||||
/* The link level header length.
|
||||
*
|
||||
* This is the offset into the uip_buf where the IP header can be
|
||||
* This is the offset into the d_buf where the IP header can be
|
||||
* found. For Ethernet, this should be set to 14. For SLIP, this
|
||||
* should be set to 0.
|
||||
*/
|
||||
|
|
|
@ -90,6 +90,7 @@ depend: .depend
|
|||
|
||||
clean:
|
||||
rm -f $(BIN) *.o *.rel *.asm *.lst *.sym *.adb *~
|
||||
rm -f uip/*~
|
||||
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
|
||||
|
||||
distclean: clean
|
||||
|
|
|
@ -47,7 +47,55 @@
|
|||
#include "net-internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
* Function: connection_event
|
||||
*
|
||||
* Description:
|
||||
* Some connection related event has occurred
|
||||
*
|
||||
* Parameters:
|
||||
* dev The sructure of the network driver that caused the interrupt
|
||||
* private An instance of struct recvfrom_s cast to void*
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void connection_event(void *private)
|
||||
{
|
||||
FAR struct socket *psock = (FAR struct socket *)private;
|
||||
if (psock)
|
||||
{
|
||||
/* UIP_CLOSE: The remote host has closed the connection
|
||||
* UIP_ABORT: The remote host has aborted the connection
|
||||
* UIP_TIMEDOUT: Connection aborted due to too many retransmissions.
|
||||
*/
|
||||
if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
/* Indicate that the socet is no longer connected */
|
||||
|
||||
psock->s_flags &= ~_SF_CONNECTED;
|
||||
}
|
||||
|
||||
/* UIP_CONNECTED: The socket is successfully connected */
|
||||
|
||||
else if ((uip_flags & UIP_CONNECTED) != 0)
|
||||
{
|
||||
/* Indicate that the socet is no longer connected */
|
||||
|
||||
psock->s_flags |= _SF_CONNECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -128,6 +176,7 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
|||
FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
|
||||
#endif
|
||||
int err;
|
||||
int ret;
|
||||
|
||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
||||
|
||||
|
@ -155,7 +204,7 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
|||
{
|
||||
case SOCK_STREAM:
|
||||
{
|
||||
int ret;
|
||||
struct uip_conn *conn;
|
||||
|
||||
/* Verify that the socket is not already connected */
|
||||
|
||||
|
@ -165,25 +214,36 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
|||
goto errout;
|
||||
}
|
||||
|
||||
/* Perform the uIP connection operation */
|
||||
/* Get the connection reference from the socket */
|
||||
|
||||
ret = uip_tcpconnect(psock->s_conn, inaddr);
|
||||
if (ret < 0)
|
||||
conn = psock->s_conn;
|
||||
if (conn) /* Should alwasy be non-NULL */
|
||||
{
|
||||
err = -ret;
|
||||
goto errout;
|
||||
/* Perform the uIP connection operation */
|
||||
|
||||
ret = uip_tcpconnect(psock->s_conn, inaddr);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Mark the connection bound and connected */
|
||||
|
||||
psock->s_flags |= (_SF_BOUND|_SF_CONNECTED);
|
||||
|
||||
/* Set up to receive callbacks on connection-related events */
|
||||
|
||||
conn->connection_private = (void*)psock;
|
||||
conn->connection_event = connection_event;
|
||||
}
|
||||
|
||||
/* Mark the connection bound and connected */
|
||||
|
||||
psock->s_flags |= (_SF_BOUND|_SF_CONNECTED);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
case SOCK_DGRAM:
|
||||
{
|
||||
int ret = uip_udpconnect(psock->s_conn, inaddr);
|
||||
ret = uip_udpconnect(psock->s_conn, inaddr);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
|
|
104
net/recvfrom.c
104
net/recvfrom.c
|
@ -46,6 +46,7 @@
|
|||
#include <errno.h>
|
||||
#include <arch/irq.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
#include "net-internal.h"
|
||||
|
||||
|
@ -78,7 +79,26 @@ struct recvfrom_s
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void recvfrom_interrupt(void *private)
|
||||
/****************************************************************************
|
||||
* Function: recvfrom_interrupt
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the interrupt level to perform the actual
|
||||
* receive operation via by the uIP layer.
|
||||
*
|
||||
* Parameters:
|
||||
* dev The sructure of the network driver that caused the interrupt
|
||||
* private An instance of struct recvfrom_s cast to void*
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
|
||||
{
|
||||
struct recvfrom_s *pstate = (struct recvfrom_s *)private;
|
||||
FAR struct socket *psock;
|
||||
|
@ -97,18 +117,18 @@ static void recvfrom_interrupt(void *private)
|
|||
if (uip_newdata())
|
||||
{
|
||||
/* Get the length of the data to return */
|
||||
if (uip_len > pstate->rf_buflen)
|
||||
if (dev->d_len > pstate->rf_buflen)
|
||||
{
|
||||
recvlen = pstate->rf_buflen;
|
||||
}
|
||||
else
|
||||
{
|
||||
recvlen = uip_len;
|
||||
recvlen = dev->d_len;
|
||||
}
|
||||
|
||||
/* Copy the new appdata into the user buffer */
|
||||
|
||||
memcpy(pstate->rf_buffer, uip_appdata, recvlen);
|
||||
memcpy(pstate->rf_buffer, dev->d_appdata, recvlen);
|
||||
|
||||
/* Update the accumulated size of the data read */
|
||||
|
||||
|
@ -127,9 +147,9 @@ static void recvfrom_interrupt(void *private)
|
|||
|
||||
/* Don't allow any further UDP call backs. */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->callback = NULL;
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
|
||||
/* Wake up the waiting thread, returning the number of bytes
|
||||
* actually read.
|
||||
|
@ -149,9 +169,9 @@ static void recvfrom_interrupt(void *private)
|
|||
* Don't allow any further TCP call backs.
|
||||
*/
|
||||
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
|
||||
/* Wake up the waiting thread, returning the number of bytes
|
||||
* actually read.
|
||||
|
@ -169,6 +189,36 @@ static void recvfrom_interrupt(void *private)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Check for a loss of connection */
|
||||
|
||||
else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
/* Stop further callbacks */
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
if (psock->s_type == SOCK_DGRAM)
|
||||
{
|
||||
struct uip_udp_conn *udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
struct uip_conn *conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
}
|
||||
|
||||
/* Report not connected */
|
||||
|
||||
pstate->rf_result = -ENOTCONN;
|
||||
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
sem_post(&pstate->rf_sem);
|
||||
}
|
||||
|
||||
/* No data has been received -- this is some other event... probably a
|
||||
* poll -- check for a timeout.
|
||||
*/
|
||||
|
@ -221,9 +271,9 @@ static void recvfrom_interrupt(void *private)
|
|||
|
||||
/* Stop further callbacks */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->callback = NULL;
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
|
||||
/* Report a timeout error */
|
||||
|
||||
|
@ -234,9 +284,9 @@ static void recvfrom_interrupt(void *private)
|
|||
{
|
||||
struct uip_conn *conn;
|
||||
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
|
||||
/* Report an error only if no data has been received */
|
||||
|
||||
|
@ -329,7 +379,7 @@ static ssize_t recvfrom_result(int result, struct recvfrom_s *pstate)
|
|||
|
||||
if (pstate->rf_result < 0)
|
||||
{
|
||||
/* Return EGAIN on a timeout */
|
||||
/* Return EGAIN on a timeout or ENOTCONN on loss of connection */
|
||||
|
||||
return pstate->rf_result;
|
||||
}
|
||||
|
@ -401,9 +451,9 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||
|
||||
/* Set up the callback in the connection */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->callback = recvfrom_interrupt;
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->event = recvfrom_interrupt;
|
||||
|
||||
/* Enable the UDP socket */
|
||||
|
||||
|
@ -420,8 +470,8 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
uip_udpdisable(psock->s_conn);
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->callback = NULL;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
irqrestore(save);
|
||||
|
||||
#warning "Needs to return server address"
|
||||
|
@ -482,9 +532,9 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||
|
||||
/* Set up the callback in the connection */
|
||||
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->private = (void*)&state;
|
||||
conn->callback = recvfrom_interrupt;
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = (void*)&state;
|
||||
conn->data_event = recvfrom_interrupt;
|
||||
|
||||
/* Wait for either the receive to complete or for an error/timeout to occur.
|
||||
* NOTES: (1) sem_wait will also terminate if a signal is received, (2)
|
||||
|
@ -496,8 +546,8 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||
|
||||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
irqrestore(save);
|
||||
|
||||
#warning "Needs to return server address"
|
||||
|
|
42
net/send.c
42
net/send.c
|
@ -78,13 +78,14 @@ struct send_s
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: send_Interrupt
|
||||
* Function: send_interrupt
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the interrupt level to perform the actual
|
||||
* send operation when polled by the uIP layer.
|
||||
*
|
||||
* Parameters:
|
||||
* dev The sructure of the network driver that caused the interrupt
|
||||
* private An instance of struct send_s cast to void*
|
||||
*
|
||||
* Returned Value:
|
||||
|
@ -95,7 +96,7 @@ struct send_s
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void send_interrupt(void *private)
|
||||
static void send_interrupt(struct uip_driver_s *dev, void *private)
|
||||
{
|
||||
struct send_s *pstate = (struct send_s *)private;
|
||||
struct uip_conn *conn;
|
||||
|
@ -108,11 +109,11 @@ static void send_interrupt(void *private)
|
|||
{
|
||||
if (pstate->snd_buflen > uip_mss())
|
||||
{
|
||||
uip_send(pstate->snd_buffer, uip_mss());
|
||||
uip_send(dev, pstate->snd_buffer, uip_mss());
|
||||
}
|
||||
else
|
||||
{
|
||||
uip_send(pstate->snd_buffer, pstate->snd_buflen);
|
||||
uip_send(dev, pstate->snd_buffer, pstate->snd_buflen);
|
||||
}
|
||||
|
||||
pstate->snd_state = STATE_DATA_SENT;
|
||||
|
@ -146,9 +147,9 @@ static void send_interrupt(void *private)
|
|||
|
||||
/* Don't allow any further call backs. */
|
||||
|
||||
conn = (struct uip_conn *)pstate->snd_sock->s_conn;
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn = (struct uip_conn *)pstate->snd_sock->s_conn;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
|
||||
/* Wake up the waiting thread, returning the number of bytes
|
||||
* actually sent.
|
||||
|
@ -157,6 +158,23 @@ static void send_interrupt(void *private)
|
|||
sem_post(&pstate->snd_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for a loss of connection */
|
||||
|
||||
else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
/* Stop further callbacks */
|
||||
|
||||
uip_udp_conn->private = NULL;
|
||||
uip_udp_conn->event = NULL;
|
||||
|
||||
/* Report not connected */
|
||||
|
||||
pstate->snd_sent = -ENOTCONN;
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
sem_post(&pstate->snd_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -275,9 +293,9 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags)
|
|||
{
|
||||
/* Set up the callback in the connection */
|
||||
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->private = (void*)&state;
|
||||
conn->callback = send_interrupt;
|
||||
conn = (struct uip_conn *)psock->s_conn;
|
||||
conn->data_private = (void*)&state;
|
||||
conn->data_event = send_interrupt;
|
||||
|
||||
/* Wait for the send to complete or an error to occur: NOTES: (1)
|
||||
* sem_wait will also terminate if a signal is received, (2) interrupts
|
||||
|
@ -289,8 +307,8 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags)
|
|||
|
||||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
conn->private = NULL;
|
||||
conn->callback = NULL;
|
||||
conn->data_private = NULL;
|
||||
conn->data_event = NULL;
|
||||
}
|
||||
|
||||
sem_destroy(&state. snd_sem);
|
||||
|
|
68
net/sendto.c
68
net/sendto.c
|
@ -45,6 +45,7 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arch/irq.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
#include "net-internal.h"
|
||||
|
||||
|
@ -61,32 +62,64 @@ struct sendto_s
|
|||
sem_t st_sem; /* Semaphore signals sendto completion */
|
||||
uint16 st_buflen; /* Length of send buffer (error if <0) */
|
||||
const char *st_buffer; /* Pointer to send buffer */
|
||||
int st_sndlen; /* Result of the send (length sent or negated errno) */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
void sendto_interrupt(void *private)
|
||||
/****************************************************************************
|
||||
* Function: sendto_interrupt
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the interrupt level to perform the actual
|
||||
* send operation when polled by the uIP layer.
|
||||
*
|
||||
* Parameters:
|
||||
* dev The sructure of the network driver that caused the interrupt
|
||||
* private An instance of struct sendto_s cast to void*
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
void sendto_interrupt(struct uip_driver_s *dev, void *private)
|
||||
{
|
||||
struct sendto_s *pstate = (struct sendto_s *)private;
|
||||
if (private)
|
||||
{
|
||||
/* Copy the user data into appdata and send it */
|
||||
/* Check if the connectin was rejected */
|
||||
|
||||
memcpy(uip_appdata, pstate->st_buffer, pstate->st_buflen);
|
||||
uip_udp_send(pstate->st_buflen);
|
||||
if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
pstate->st_sndlen = -ENOTCONN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the user data into d_appdata and send it */
|
||||
|
||||
/* Don't allow any furhter call backs. */
|
||||
memcpy(dev->d_appdata, pstate->st_buffer, pstate->st_buflen);
|
||||
uip_send(dev, dev->d_appdata, pstate->st_buflen);
|
||||
pstate->st_sndlen = pstate->st_buflen;
|
||||
}
|
||||
|
||||
uip_conn->private = NULL;
|
||||
uip_conn->callback = NULL;
|
||||
/* Don't allow any further call backs. */
|
||||
|
||||
uip_udp_conn->private = NULL;
|
||||
uip_udp_conn->event = NULL;
|
||||
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
sem_post(&pstate->st_sem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
|
@ -242,8 +275,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
|||
/* Set up the callback in the connection */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->callback = sendto_interrupt;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->event = sendto_interrupt;
|
||||
|
||||
/* Enable the UDP socket */
|
||||
|
||||
|
@ -260,8 +293,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
|||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
uip_udpdisable(psock->s_conn);
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->callback = NULL;
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
irqrestore(save);
|
||||
|
||||
sem_destroy(&state.st_sem);
|
||||
|
@ -269,7 +302,18 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
|||
/* Set the socket state to idle */
|
||||
|
||||
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
|
||||
return len;
|
||||
|
||||
/* Check for errors */
|
||||
|
||||
if (state.st_sndlen < 0)
|
||||
{
|
||||
err = -state.st_sndlen;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Sucess */
|
||||
|
||||
return state.st_sndlen;
|
||||
#else
|
||||
err = ENOSYS;
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,6 @@
|
|||
############################################################################
|
||||
|
||||
UIP_ASRCS =
|
||||
UIP_CSRCS = uip-arp.c uip.c uip-fw.c uip-neighbor.c uip-split.c \
|
||||
UIP_CSRCS = uip-arp.c uip.c uip-send.c uip-fw.c uip-neighbor.c uip-split.c \
|
||||
uip-tcpconn.c uip-udpconn.c
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
#include <net/uip/uip-arp.h>
|
||||
|
||||
struct arp_hdr
|
||||
|
@ -94,36 +95,29 @@ static uint8 i, c;
|
|||
static uint8 arptime;
|
||||
static uint8 tmpage;
|
||||
|
||||
#define BUF ((struct arp_hdr *)&uip_buf[0])
|
||||
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initialize the ARP module.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_init(void)
|
||||
#define BUF ((struct arp_hdr *)&dev->d_buf[0])
|
||||
#define IPBUF ((struct ethip_hdr *)&dev->d_buf[0])
|
||||
|
||||
/* Initialize the ARP module. */
|
||||
|
||||
void uip_arp_init(void)
|
||||
{
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
memset(arp_table[i].ipaddr, 0, 4);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Periodic ARP processing function.
|
||||
|
||||
/* Periodic ARP processing function.
|
||||
*
|
||||
* This function performs periodic timer processing in the ARP module
|
||||
* and should be called at regular intervals. The recommended interval
|
||||
* is 10 seconds between the calls.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_timer(void)
|
||||
|
||||
void uip_arp_timer(void)
|
||||
{
|
||||
struct arp_entry *tabptr;
|
||||
|
||||
|
||||
++arptime;
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
|
@ -135,9 +129,7 @@ uip_arp_timer(void)
|
|||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
||||
static void uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
||||
{
|
||||
register struct arp_entry *tabptr;
|
||||
/* Walk through the ARP mapping table and try to find an entry to
|
||||
|
@ -154,7 +146,7 @@ uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
|||
the IP address in this ARP table entry. */
|
||||
if(pipaddr[0] == tabptr->ipaddr[0] &&
|
||||
pipaddr[1] == tabptr->ipaddr[1]) {
|
||||
|
||||
|
||||
/* An old entry found, update this and return. */
|
||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||
tabptr->time = arptime;
|
||||
|
@ -198,9 +190,8 @@ uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
|||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||
tabptr->time = arptime;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* ARP processing for incoming IP packets
|
||||
|
||||
/* ARP processing for incoming IP packets
|
||||
*
|
||||
* This function should be called by the device driver when an IP
|
||||
* packet has been received. The function will check if the address is
|
||||
|
@ -208,16 +199,15 @@ uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
|||
* refreshed. If no ARP cache entry was found, a new one is created.
|
||||
*
|
||||
* This function expects an IP packet with a prepended Ethernet header
|
||||
* in the uip_buf[] buffer, and the length of the packet in the global
|
||||
* variable uip_len.
|
||||
* in the d_buf[] buffer, and the length of the packet in the field
|
||||
* d_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
void
|
||||
uip_arp_ipin(void)
|
||||
void uip_arp_ipin(void)
|
||||
{
|
||||
uip_len -= sizeof(struct uip_eth_hdr);
|
||||
|
||||
dev->d_len -= sizeof(struct uip_eth_hdr);
|
||||
|
||||
/* Only insert/update an entry if the source IP address of the
|
||||
incoming IP packet comes from a host on the local network. */
|
||||
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
|
||||
|
@ -229,13 +219,12 @@ uip_arp_ipin(void)
|
|||
return;
|
||||
}
|
||||
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* 0 */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* ARP processing for incoming ARP packets.
|
||||
|
||||
/* ARP processing for incoming ARP packets.
|
||||
*
|
||||
* This function should be called by the device driver when an ARP
|
||||
* packet has been received. The function will act differently
|
||||
|
@ -243,29 +232,27 @@ uip_arp_ipin(void)
|
|||
* that we previously sent out, the ARP cache will be filled in with
|
||||
* the values from the ARP reply. If the incoming ARP packet is an ARP
|
||||
* request for our IP address, an ARP reply packet is created and put
|
||||
* into the uip_buf[] buffer.
|
||||
* into the d_buf[] buffer.
|
||||
*
|
||||
* When the function returns, the value of the global variable uip_len
|
||||
* When the function returns, the value of the field d_len
|
||||
* indicates whether the device driver should send out a packet or
|
||||
* not. If uip_len is zero, no packet should be sent. If uip_len is
|
||||
* not. If d_len is zero, no packet should be sent. If d_len is
|
||||
* non-zero, it contains the length of the outbound packet that is
|
||||
* present in the uip_buf[] buffer.
|
||||
* present in the d_buf[] buffer.
|
||||
*
|
||||
* This function expects an ARP packet with a prepended Ethernet
|
||||
* header in the uip_buf[] buffer, and the length of the packet in the
|
||||
* global variable uip_len.
|
||||
* header in the d_buf[] buffer, and the length of the packet in the
|
||||
* global variable d_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_arpin(void)
|
||||
|
||||
void uip_arp_arpin(struct uip_driver_s *dev)
|
||||
{
|
||||
|
||||
if(uip_len < sizeof(struct arp_hdr)) {
|
||||
uip_len = 0;
|
||||
if(dev->d_len < sizeof(struct arp_hdr)) {
|
||||
dev->d_len = 0;
|
||||
return;
|
||||
}
|
||||
uip_len = 0;
|
||||
|
||||
dev->d_len = 0;
|
||||
|
||||
switch(BUF->opcode) {
|
||||
case HTONS(ARP_REQUEST):
|
||||
/* ARP request. If it asked for our address, we send out a
|
||||
|
@ -275,7 +262,7 @@ uip_arp_arpin(void)
|
|||
table, since it is likely that we will do more communication
|
||||
with this host in the future. */
|
||||
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
|
||||
|
||||
|
||||
/* The reply opcode is 2. */
|
||||
BUF->opcode = HTONS(2);
|
||||
|
||||
|
@ -283,14 +270,14 @@ uip_arp_arpin(void)
|
|||
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
|
||||
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
|
||||
|
||||
|
||||
BUF->dipaddr[0] = BUF->sipaddr[0];
|
||||
BUF->dipaddr[1] = BUF->sipaddr[1];
|
||||
BUF->sipaddr[0] = uip_hostaddr[0];
|
||||
BUF->sipaddr[1] = uip_hostaddr[1];
|
||||
|
||||
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
|
||||
uip_len = sizeof(struct arp_hdr);
|
||||
dev->d_len = sizeof(struct arp_hdr);
|
||||
}
|
||||
break;
|
||||
case HTONS(ARP_REPLY):
|
||||
|
@ -304,9 +291,8 @@ uip_arp_arpin(void)
|
|||
|
||||
return;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Prepend Ethernet header to an outbound IP packet and see if we need
|
||||
|
||||
/* Prepend Ethernet header to an outbound IP packet and see if we need
|
||||
* to send out an ARP request.
|
||||
*
|
||||
* This function should be called before sending out an IP packet. The
|
||||
|
@ -319,7 +305,7 @@ uip_arp_arpin(void)
|
|||
* checks the ARP cache to see if an entry for the destination IP
|
||||
* address is found. If so, an Ethernet header is prepended and the
|
||||
* function returns. If no ARP cache entry is found for the
|
||||
* destination IP address, the packet in the uip_buf[] is replaced by
|
||||
* destination IP address, the packet in the d_buf[] is replaced by
|
||||
* an ARP request packet for the IP address. The IP packet is dropped
|
||||
* and it is assumed that they higher level protocols (e.g., TCP)
|
||||
* eventually will retransmit the dropped packet.
|
||||
|
@ -327,16 +313,14 @@ uip_arp_arpin(void)
|
|||
* If the destination IP address is not on the local network, the IP
|
||||
* address of the default router is used instead.
|
||||
*
|
||||
* When the function returns, a packet is present in the uip_buf[]
|
||||
* buffer, and the length of the packet is in the global variable
|
||||
* uip_len.
|
||||
* When the function returns, a packet is present in the d_buf[]
|
||||
* buffer, and the length of the packet is in the field d_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_out(void)
|
||||
|
||||
void uip_arp_out(struct uip_driver_s *dev)
|
||||
{
|
||||
struct arp_entry *tabptr;
|
||||
|
||||
|
||||
/* Find the destination IP address in the ARP table and construct
|
||||
the Ethernet header. If the destination IP addres isn't on the
|
||||
local network, we use the default router's IP address instead.
|
||||
|
@ -358,7 +342,7 @@ uip_arp_out(void)
|
|||
/* Else, we use the destination IP address. */
|
||||
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
|
||||
|
@ -374,7 +358,7 @@ uip_arp_out(void)
|
|||
memset(BUF->dhwaddr.addr, 0x00, 6);
|
||||
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
|
||||
|
||||
|
||||
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
|
||||
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
|
||||
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
|
||||
|
@ -384,9 +368,9 @@ uip_arp_out(void)
|
|||
BUF->protolen = 4;
|
||||
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
|
||||
|
||||
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
|
||||
|
||||
uip_len = sizeof(struct arp_hdr);
|
||||
dev->d_appdata = &dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
|
||||
|
||||
dev->d_len = sizeof(struct arp_hdr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -394,12 +378,8 @@ uip_arp_out(void)
|
|||
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
|
||||
}
|
||||
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||
|
||||
|
||||
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
|
||||
|
||||
uip_len += sizeof(struct uip_eth_hdr);
|
||||
dev->d_len += sizeof(struct uip_eth_hdr);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
232
net/uip/uip-fw.c
232
net/uip/uip-fw.c
|
@ -33,6 +33,8 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <debug.h>
|
||||
#include <net/uip/uip.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
|
@ -40,17 +42,16 @@
|
|||
|
||||
#include <string.h> /* for memcpy() */
|
||||
|
||||
/*
|
||||
* The list of registered network interfaces.
|
||||
*/
|
||||
/* The list of registered network interfaces. */
|
||||
|
||||
static struct uip_fw_netif *netifs = NULL;
|
||||
|
||||
/*
|
||||
* A pointer to the default network interface.
|
||||
*/
|
||||
/* A pointer to the default network interface. */
|
||||
|
||||
static struct uip_fw_netif *defaultnetif = NULL;
|
||||
|
||||
struct tcpip_hdr {
|
||||
struct tcpip_hdr
|
||||
{
|
||||
/* IP header. */
|
||||
uint8 vhl,
|
||||
tos;
|
||||
|
@ -101,23 +102,19 @@ struct icmpip_hdr {
|
|||
/* ICMP TIME-EXCEEDED. */
|
||||
#define ICMP_TE 11
|
||||
|
||||
/*
|
||||
* Pointer to the TCP/IP headers of the packet in the uip_buf buffer.
|
||||
*/
|
||||
#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/* Pointer to the TCP/IP headers of the packet in the d_buf buffer. */
|
||||
#define BUF ((struct tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
|
||||
/*
|
||||
* Pointer to the ICMP/IP headers of the packet in the uip_buf buffer.
|
||||
*/
|
||||
#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/* Pointer to the ICMP/IP headers of the packet in the d_buf buffer. */
|
||||
#define ICMPBUF ((struct icmpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
|
||||
/*
|
||||
* Certain fields of an IP packet that are used for identifying
|
||||
/* Certain fields of an IP packet that are used for identifying
|
||||
* duplicate packets.
|
||||
*/
|
||||
struct fwcache_entry {
|
||||
uint16 timer;
|
||||
|
||||
struct fwcache_entry
|
||||
{
|
||||
uint16 timer;
|
||||
uint16 srcipaddr[2];
|
||||
uint16 destipaddr[2];
|
||||
uint16 ipid;
|
||||
|
@ -133,35 +130,25 @@ struct fwcache_entry {
|
|||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* The number of packets to remember when looking for duplicates.
|
||||
*/
|
||||
/* The number of packets to remember when looking for duplicates. */
|
||||
#ifdef CONFIG_NET_FWCACHE_SIZE
|
||||
# define FWCACHE_SIZE CONFIG_NET_FWCACHE_SIZE
|
||||
#else
|
||||
# define FWCACHE_SIZE 2
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* A cache of packet header fields which are used for
|
||||
/* A cache of packet header fields which are used for
|
||||
* identifying duplicate packets.
|
||||
*/
|
||||
|
||||
static struct fwcache_entry fwcache[FWCACHE_SIZE];
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* The time that a packet cache is active.
|
||||
*/
|
||||
/* The time that a packet cache is active. */
|
||||
#define FW_TIME 20
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initialize the uIP packet forwarding module.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_init(void)
|
||||
/* Initialize the uIP packet forwarding module. */
|
||||
|
||||
void uip_fw_init(void)
|
||||
{
|
||||
struct uip_fw_netif *t;
|
||||
defaultnetif = NULL;
|
||||
|
@ -171,42 +158,36 @@ uip_fw_init(void)
|
|||
t->next = NULL;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Check if an IP address is within the network defined by an IP
|
||||
|
||||
/* Check if an IP address is within the network defined by an IP
|
||||
* address and a netmask.
|
||||
*
|
||||
* \param ipaddr The IP address to be checked.
|
||||
* \param netipaddr The IP address of the network.
|
||||
* \param netmask The netmask of the network.
|
||||
* ipaddr The IP address to be checked.
|
||||
* netipaddr The IP address of the network.
|
||||
* netmask The netmask of the network.
|
||||
*
|
||||
* \return Non-zero if IP address is in network, zero otherwise.
|
||||
* Return: Non-zero if IP address is in network, zero otherwise.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static unsigned char
|
||||
ipaddr_maskcmp(uint16 *ipaddr, uint16 *netipaddr, uint16 *netmask)
|
||||
|
||||
static unsigned char ipaddr_maskcmp(uint16 *ipaddr, uint16 *netipaddr, uint16 *netmask)
|
||||
{
|
||||
return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
|
||||
(ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Send out an ICMP TIME-EXCEEDED message.
|
||||
|
||||
/* Send out an ICMP TIME-EXCEEDED message.
|
||||
*
|
||||
* This function replaces the packet in the uip_buf buffer with the
|
||||
* This function replaces the packet in the d_buf buffer with the
|
||||
* ICMP packet.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static void
|
||||
time_exceeded(void)
|
||||
|
||||
static void time_exceeded(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 tmp16;
|
||||
|
||||
/* We don't send out ICMP errors for ICMP messages. */
|
||||
if(ICMPBUF->proto == UIP_PROTO_ICMP) {
|
||||
uip_len = 0;
|
||||
dev->d_len = 0;
|
||||
return;
|
||||
}
|
||||
/* Copy fields from packet header into payload of this ICMP packet. */
|
||||
|
@ -235,9 +216,9 @@ time_exceeded(void)
|
|||
|
||||
/* The size of the ICMP time exceeded packet is 36 + the size of the
|
||||
IP header (20) = 56. */
|
||||
uip_len = 56;
|
||||
dev->d_len = 56;
|
||||
ICMPBUF->len[0] = 0;
|
||||
ICMPBUF->len[1] = uip_len;
|
||||
ICMPBUF->len[1] = dev->d_len;
|
||||
|
||||
/* Fill in the other fields in the IP header. */
|
||||
ICMPBUF->vhl = 0x45;
|
||||
|
@ -245,29 +226,24 @@ time_exceeded(void)
|
|||
ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
|
||||
ICMPBUF->ttl = UIP_TTL;
|
||||
ICMPBUF->proto = UIP_PROTO_ICMP;
|
||||
|
||||
|
||||
/* Calculate IP checksum. */
|
||||
ICMPBUF->ipchksum = 0;
|
||||
ICMPBUF->ipchksum = ~(uip_ipchksum());
|
||||
|
||||
|
||||
ICMPBUF->ipchksum = ~(uip_ipchksum(dev));
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Register a packet in the forwarding cache so that it won't be
|
||||
|
||||
/* Register a packet in the forwarding cache so that it won't be
|
||||
* forwarded again.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static void
|
||||
fwcache_register(void)
|
||||
|
||||
static void fwcache_register(struct uip_driver_s *dev)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
int i, oldest;
|
||||
|
||||
oldest = FW_TIME;
|
||||
fw = NULL;
|
||||
|
||||
|
||||
/* Find the oldest entry in the cache. */
|
||||
for(i = 0; i < FWCACHE_SIZE; ++i) {
|
||||
if(fwcache[i].timer == 0) {
|
||||
|
@ -295,17 +271,13 @@ fwcache_register(void)
|
|||
fw->offset = BUF->ipoffset;
|
||||
#endif
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Find a network interface for the IP packet in uip_buf.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static struct uip_fw_netif *
|
||||
find_netif(void)
|
||||
|
||||
/* Find a network interface for the IP packet in d_buf. */
|
||||
|
||||
static struct uip_fw_netif *find_netif(struct uip_driver_s *dev)
|
||||
{
|
||||
struct uip_fw_netif *netif;
|
||||
|
||||
|
||||
/* Walk through every network interface to check for a match. */
|
||||
for(netif = netifs; netif != NULL; netif = netif->next) {
|
||||
if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
|
||||
|
@ -314,37 +286,35 @@ find_netif(void)
|
|||
return netif;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If no matching netif was found, we use default netif. */
|
||||
return defaultnetif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Output an IP packet on the correct network interface.
|
||||
|
||||
/* Output an IP packet on the correct network interface.
|
||||
*
|
||||
* The IP packet should be present in the uip_buf buffer and its
|
||||
* length in the global uip_len variable.
|
||||
* The IP packet should be present in the d_buf buffer and its
|
||||
* length in the d_len field.
|
||||
*
|
||||
* \retval UIP_FW_ZEROLEN Indicates that a zero-length packet
|
||||
* Return: UIP_FW_ZEROLEN Indicates that a zero-length packet
|
||||
* transmission was attempted and that no packet was sent.
|
||||
*
|
||||
* \retval UIP_FW_NOROUTE No suitable network interface could be found
|
||||
* Return: UIP_FW_NOROUTE No suitable network interface could be found
|
||||
* for the outbound packet, and the packet was not sent.
|
||||
*
|
||||
* \return The return value from the actual network interface output
|
||||
* Return: The return value from the actual network interface output
|
||||
* function is passed unmodified as a return value.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
uint8
|
||||
uip_fw_output(void)
|
||||
|
||||
uint8 uip_fw_output(struct uip_driver_s *dev)
|
||||
{
|
||||
struct uip_fw_netif *netif;
|
||||
|
||||
if(uip_len == 0) {
|
||||
if(dev->d_len == 0) {
|
||||
return UIP_FW_ZEROLEN;
|
||||
}
|
||||
|
||||
fwcache_register();
|
||||
fwcache_register(dev);
|
||||
|
||||
#if UIP_BROADCAST
|
||||
/* Link local broadcasts go out on all interfaces. */
|
||||
|
@ -360,11 +330,9 @@ uip_fw_output(void)
|
|||
return UIP_FW_OK;
|
||||
}
|
||||
#endif /* UIP_BROADCAST */
|
||||
|
||||
netif = find_netif();
|
||||
/* printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
|
||||
netif->output,
|
||||
uip_len);*/
|
||||
|
||||
netif = find_netif(dev);
|
||||
dbg("uip_fw_output: netif %p ->output %p len %d\n", netif, netif->output, dev->d_len);
|
||||
|
||||
if(netif == NULL) {
|
||||
return UIP_FW_NOROUTE;
|
||||
|
@ -373,18 +341,14 @@ uip_fw_output(void)
|
|||
output function to send out the packet. */
|
||||
return netif->output();
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Forward an IP packet in the uip_buf buffer.
|
||||
|
||||
/* Forward an IP packet in the d_buf buffer.
|
||||
*
|
||||
*
|
||||
*
|
||||
* \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
|
||||
* Return: UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
|
||||
* the packet should be processed locally.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
uint8
|
||||
uip_fw_forward(void)
|
||||
|
||||
uint8 uip_fw_forward(struct uip_driver_s *dev)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
|
||||
|
@ -430,19 +394,21 @@ uip_fw_forward(void)
|
|||
}
|
||||
|
||||
/* If the TTL reaches zero we produce an ICMP time exceeded message
|
||||
in the uip_buf buffer and forward that packet back to the sender
|
||||
of the packet. */
|
||||
in the d_buf buffer and forward that packet back to the sender
|
||||
of the packet.
|
||||
*/
|
||||
|
||||
if(BUF->ttl <= 1) {
|
||||
/* No time exceeded for broadcasts and multicasts! */
|
||||
if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
|
||||
return UIP_FW_LOCAL;
|
||||
}
|
||||
time_exceeded();
|
||||
time_exceeded(dev);
|
||||
}
|
||||
|
||||
|
||||
/* Decrement the TTL (time-to-live) value in the IP header */
|
||||
BUF->ttl = BUF->ttl - 1;
|
||||
|
||||
|
||||
/* Update the IP checksum. */
|
||||
if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
|
||||
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
|
||||
|
@ -450,9 +416,9 @@ uip_fw_forward(void)
|
|||
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
|
||||
}
|
||||
|
||||
if(uip_len > 0) {
|
||||
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
|
||||
uip_fw_output();
|
||||
if(dev->d_len > 0) {
|
||||
dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
|
||||
uip_fw_output(dev);
|
||||
}
|
||||
|
||||
#if UIP_BROADCAST
|
||||
|
@ -465,43 +431,36 @@ uip_fw_forward(void)
|
|||
other processing should be made. */
|
||||
return UIP_FW_FORWARDED;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Register a network interface with the forwarding module.
|
||||
|
||||
/* Register a network interface with the forwarding module.
|
||||
*
|
||||
* \param netif A pointer to the network interface that is to be
|
||||
* netif A pointer to the network interface that is to be
|
||||
* registered.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_register(struct uip_fw_netif *netif)
|
||||
|
||||
void uip_fw_register(struct uip_fw_netif *netif)
|
||||
{
|
||||
netif->next = netifs;
|
||||
netifs = netif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Register a default network interface.
|
||||
|
||||
/* Register a default network interface.
|
||||
*
|
||||
* All packets that don't go out on any of the other interfaces will
|
||||
* be routed to the default interface.
|
||||
*
|
||||
* \param netif A pointer to the network interface that is to be
|
||||
* netif A pointer to the network interface that is to be
|
||||
* registered.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_default(struct uip_fw_netif *netif)
|
||||
|
||||
void uip_fw_default(struct uip_fw_netif *netif)
|
||||
{
|
||||
defaultnetif = netif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Perform periodic processing.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_periodic(void)
|
||||
|
||||
/* Perform periodic processing. */
|
||||
|
||||
void uip_fw_periodic(void)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
|
||||
|
@ -510,4 +469,3 @@ uip_fw_periodic(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -60,116 +60,92 @@ struct uip_fw_netif
|
|||
sends a packet. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Intantiating macro for a uIP network interface.
|
||||
/* Intantiating macro for a uIP network interface.
|
||||
*
|
||||
* Example:
|
||||
\code
|
||||
struct uip_fw_netif slipnetif =
|
||||
{UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
|
||||
\endcode
|
||||
* \param ip1,ip2,ip3,ip4 The IP address of the network interface.
|
||||
*
|
||||
* \param nm1,nm2,nm3,nm4 The netmask of the network interface.
|
||||
* struct uip_fw_netif slipnetif =
|
||||
* {UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
|
||||
*
|
||||
* \param outputfunc A pointer to the output function of the network interface.
|
||||
* ip1,ip2,ip3,ip4 The IP address of the network interface.
|
||||
*
|
||||
* \hideinitializer
|
||||
* nm1,nm2,nm3,nm4 The netmask of the network interface.
|
||||
*
|
||||
* outputfunc A pointer to the output function of the network interface.
|
||||
*/
|
||||
|
||||
#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
|
||||
NULL, \
|
||||
{HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \
|
||||
{HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \
|
||||
outputfunc
|
||||
|
||||
/**
|
||||
* Set the IP address of a network interface.
|
||||
/* Set the IP address of a network interface.
|
||||
*
|
||||
* \param netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
* netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
*
|
||||
* \param addr A pointer to an IP address.
|
||||
*
|
||||
* \hideinitializer
|
||||
* addr A pointer to an IP address.
|
||||
*/
|
||||
|
||||
#define uip_fw_setipaddr(netif, addr) \
|
||||
do { (netif)->ipaddr[0] = ((uint16 *)(addr))[0]; \
|
||||
(netif)->ipaddr[1] = ((uint16 *)(addr))[1]; } while(0)
|
||||
/**
|
||||
* Set the netmask of a network interface.
|
||||
|
||||
/* Set the netmask of a network interface.
|
||||
*
|
||||
* \param netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
* netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
*
|
||||
* \param addr A pointer to an IP address representing the netmask.
|
||||
*
|
||||
* \hideinitializer
|
||||
* addr A pointer to an IP address representing the netmask.
|
||||
*/
|
||||
|
||||
#define uip_fw_setnetmask(netif, addr) \
|
||||
do { (netif)->netmask[0] = ((uint16 *)(addr))[0]; \
|
||||
(netif)->netmask[1] = ((uint16 *)(addr))[1]; } while(0)
|
||||
|
||||
void uip_fw_init(void);
|
||||
uint8 uip_fw_forward(void);
|
||||
uint8 uip_fw_output(void);
|
||||
uint8 uip_fw_forward(struct uip_driver_s *dev);
|
||||
uint8 uip_fw_output(struct uip_driver_s *dev);
|
||||
void uip_fw_register(struct uip_fw_netif *netif);
|
||||
void uip_fw_default(struct uip_fw_netif *netif);
|
||||
void uip_fw_periodic(void);
|
||||
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet should be
|
||||
/* A non-error message that indicates that a packet should be
|
||||
* processed locally.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_LOCAL 0
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that something went OK.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
/* A non-error message that indicates that something went OK. */
|
||||
|
||||
#define UIP_FW_OK 0
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet was forwarded.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
/* A non-error message that indicates that a packet was forwarded. */
|
||||
|
||||
#define UIP_FW_FORWARDED 1
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a zero-length packet
|
||||
/* A non-error message that indicates that a zero-length packet
|
||||
* transmission was attempted, and that no packet was sent.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_ZEROLEN 2
|
||||
|
||||
/**
|
||||
* An error message that indicates that a packet that was too large
|
||||
/* An error message that indicates that a packet that was too large
|
||||
* for the outbound network interface was detected.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_TOOLARGE 3
|
||||
|
||||
/**
|
||||
* An error message that indicates that no suitable interface could be
|
||||
/* An error message that indicates that no suitable interface could be
|
||||
* found for an outbound packet.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_NOROUTE 4
|
||||
|
||||
/**
|
||||
* An error message that indicates that a packet that should be
|
||||
/* An error message that indicates that a packet that should be
|
||||
* forwarded or output was dropped.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
#define UIP_FW_DROPPED 5
|
||||
|
||||
|
||||
#endif /* __UIP_FW_H__ */
|
||||
|
||||
/** @} */
|
||||
|
|
99
net/uip/uip-send.c
Normal file
99
net/uip/uip-send.c
Normal 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 );
|
||||
}
|
||||
}
|
|
@ -38,19 +38,17 @@
|
|||
#include "uip-split.h"
|
||||
#include "uip-fw.h"
|
||||
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define BUF ((struct uip_tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_split_output(void)
|
||||
void uip_split_output(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 tcplen, len1, len2;
|
||||
|
||||
/* We only try to split maximum sized TCP segments. */
|
||||
if(BUF->proto == UIP_PROTO_TCP &&
|
||||
uip_len == UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
dev->d_len == UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
|
||||
tcplen = uip_len - UIP_TCPIP_HLEN;
|
||||
tcplen = dev->d_len - UIP_TCPIP_HLEN;
|
||||
/* Split the segment in two. If the original packet length was
|
||||
odd, we make the second packet one byte larger. */
|
||||
len1 = len2 = tcplen / 2;
|
||||
|
@ -60,49 +58,49 @@ uip_split_output(void)
|
|||
|
||||
/* Create the first packet. This is done by altering the length
|
||||
field of the IP header and updating the checksums. */
|
||||
uip_len = len1 + UIP_TCPIP_HLEN;
|
||||
dev->d_len = len1 + UIP_TCPIP_HLEN;
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
BUF->len[0] = uip_len >> 8;
|
||||
BUF->len[1] = uip_len & 0xff;
|
||||
BUF->len[0] = dev->d_len >> 8;
|
||||
BUF->len[1] = dev->d_len & 0xff;
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* Recalculate the TCP checksum. */
|
||||
BUF->tcpchksum = 0;
|
||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
||||
BUF->tcpchksum = ~(uip_tcpchksum(dev));
|
||||
|
||||
#ifndef CONFIG_NET_IPv6
|
||||
/* Recalculate the IP checksum. */
|
||||
BUF->ipchksum = 0;
|
||||
BUF->ipchksum = ~(uip_ipchksum());
|
||||
BUF->ipchksum = ~(uip_ipchksum(dev));
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
|
||||
/* Transmit the first packet. */
|
||||
/* uip_fw_output();*/
|
||||
tcpip_output();
|
||||
|
||||
/* Now, create the second packet. To do this, it is not enough to
|
||||
just alter the length field, but we must also update the TCP
|
||||
sequence number and point the uip_appdata to a new place in
|
||||
sequence number and point the d_appdata to a new place in
|
||||
memory. This place is detemined by the length of the first
|
||||
packet (len1). */
|
||||
uip_len = len2 + UIP_TCPIP_HLEN;
|
||||
dev->d_len = len2 + UIP_TCPIP_HLEN;
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
BUF->len[0] = uip_len >> 8;
|
||||
BUF->len[1] = uip_len & 0xff;
|
||||
BUF->len[0] = dev->d_len >> 8;
|
||||
BUF->len[1] = dev->d_len & 0xff;
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* uip_appdata += len1;*/
|
||||
memcpy(uip_appdata, (uint8 *)uip_appdata + len1, len2);
|
||||
/* dev->d_appdata += len1;*/
|
||||
memcpy(dev->d_appdata, dev->d_appdata + len1, len2);
|
||||
|
||||
uip_add32(BUF->seqno, len1);
|
||||
BUF->seqno[0] = uip_acc32[0];
|
||||
|
@ -112,12 +110,12 @@ uip_split_output(void)
|
|||
|
||||
/* Recalculate the TCP checksum. */
|
||||
BUF->tcpchksum = 0;
|
||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
||||
BUF->tcpchksum = ~(uip_tcpchksum(dev));
|
||||
|
||||
#ifndef CONFIG_NET_IPv6
|
||||
/* Recalculate the IP checksum. */
|
||||
BUF->ipchksum = 0;
|
||||
BUF->ipchksum = ~(uip_ipchksum());
|
||||
BUF->ipchksum = ~(uip_ipchksum(dev));
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* Transmit the second packet. */
|
||||
|
@ -127,6 +125,4 @@ uip_split_output(void)
|
|||
/* uip_fw_output();*/
|
||||
tcpip_output();
|
||||
}
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -66,23 +66,22 @@
|
|||
#ifndef __UIP_SPLIT_H__
|
||||
#define __UIP_SPLIT_H__
|
||||
|
||||
/**
|
||||
* Handle outgoing packets.
|
||||
/* Handle outgoing packets.
|
||||
*
|
||||
* This function inspects an outgoing packet in the uip_buf buffer and
|
||||
* This function inspects an outgoing packet in the d_buf buffer and
|
||||
* sends it out using the uip_fw_output() function. If the packet is a
|
||||
* full-sized TCP segment it will be split into two segments and
|
||||
* transmitted separately. This function should be called instead of
|
||||
* the actual device driver output function, or the uip_fw_output()
|
||||
* function.
|
||||
*
|
||||
* The headers of the outgoing packet is assumed to be in the uip_buf
|
||||
* buffer and the payload is assumed to be wherever uip_appdata
|
||||
* The headers of the outgoing packet is assumed to be in the d_buf
|
||||
* buffer and the payload is assumed to be wherever d_appdata
|
||||
* points. The length of the outgoing packet is assumed to be in the
|
||||
* uip_len variable.
|
||||
*
|
||||
* d_len field.
|
||||
*/
|
||||
void uip_split_output(void);
|
||||
|
||||
void uip_split_output(struct uip_driver_s *dev);
|
||||
|
||||
#endif /* __UIP_SPLIT_H__ */
|
||||
|
||||
|
|
|
@ -434,10 +434,10 @@ struct uip_conn *uip_tcplistener(struct uip_tcpip_hdr *buf)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void uip_tcppoll(unsigned int conn)
|
||||
void uip_tcppoll(struct uip_driver_s *dev, unsigned int conn)
|
||||
{
|
||||
uip_conn = &g_tcp_connections[conn];
|
||||
uip_interrupt(UIP_TIMER);
|
||||
uip_interrupt(dev, UIP_TIMER);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -282,10 +282,10 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void uip_udppoll(unsigned int conn)
|
||||
void uip_udppoll(struct uip_driver_s *dev, unsigned int conn)
|
||||
{
|
||||
uip_udp_conn = &g_udp_connections[conn];
|
||||
uip_interrupt(UIP_UDP_TIMER);
|
||||
uip_interrupt(dev, UIP_UDP_TIMER);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
343
net/uip/uip.c
343
net/uip/uip.c
|
@ -51,17 +51,17 @@
|
|||
* size because of the overhead of parameter passing and the fact that
|
||||
* the optimier would not be as efficient.
|
||||
*
|
||||
* The principle is that we have a small buffer, called the uip_buf,
|
||||
* The principle is that we have a small buffer, called the d_buf,
|
||||
* in which the device driver puts an incoming packet. The TCP/IP
|
||||
* stack parses the headers in the packet, and calls the
|
||||
* application. If the remote host has sent data to the application,
|
||||
* this data is present in the uip_buf and the application read the
|
||||
* this data is present in the d_buf and the application read the
|
||||
* data from there. It is up to the application to put this data into
|
||||
* a byte stream if needed. The application will not be fed with data
|
||||
* that is out of sequence.
|
||||
*
|
||||
* If the application whishes to send data to the peer, it should put
|
||||
* its data into the uip_buf. The uip_appdata pointer points to the
|
||||
* its data into the d_buf. The d_appdata pointer points to the
|
||||
* first available byte. The TCP/IP stack will calculate the
|
||||
* checksums, and fill in the necessary header fields and finally send
|
||||
* the packet back to the peer.
|
||||
|
@ -129,10 +129,10 @@ extern void uip_log(char *msg);
|
|||
|
||||
/* Macros. */
|
||||
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define BUF ((struct uip_tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
|
||||
#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define ICMPBUF ((struct uip_icmpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
#define UDPBUF ((struct uip_udpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
|
@ -159,22 +159,13 @@ uip_ipaddr_t uip_draddr;
|
|||
uip_ipaddr_t uip_netmask;
|
||||
#endif /* UIP_FIXEDADDR */
|
||||
|
||||
#ifndef CONFIG_NET_EXTERNAL_BUFFER
|
||||
uint8 uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains incoming packets. */
|
||||
#endif /* CONFIG_NET_EXTERNAL_BUFFER */
|
||||
|
||||
void *uip_appdata; /* The uip_appdata pointer points to application data. */
|
||||
void *uip_sappdata; /* The uip_appdata pointer points to the application
|
||||
* data which is to be sent. */
|
||||
#if UIP_URGDATA > 0
|
||||
void *uip_urgdata; /* The uip_urgdata pointer points to urgent data
|
||||
* (out-of-band data), if present. */
|
||||
uint16 uip_urglen, uip_surglen;
|
||||
uint16 uip_urglen;
|
||||
uint16 uip_surglen;
|
||||
#endif /* UIP_URGDATA > 0 */
|
||||
|
||||
uint16 uip_len, uip_slen; /* The uip_len is either 8 or 16 bits, depending
|
||||
* on the maximum packet size. */
|
||||
|
||||
uint8 uip_flags; /* The uip_flags variable is used for communication
|
||||
* between the TCP/IP stack and the application
|
||||
* program. */
|
||||
|
@ -273,7 +264,7 @@ static uint16 chksum(uint16 sum, const uint8 *data, uint16 len)
|
|||
return sum;
|
||||
}
|
||||
|
||||
static uint16 upper_layer_chksum(uint8 proto)
|
||||
static uint16 upper_layer_chksum(struct uip_driver_s *dev, uint8 proto)
|
||||
{
|
||||
uint16 upper_layer_len;
|
||||
uint16 sum;
|
||||
|
@ -293,15 +284,15 @@ static uint16 upper_layer_chksum(uint8 proto)
|
|||
sum = chksum(sum, (uint8 *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
|
||||
|
||||
/* Sum TCP header and data. */
|
||||
sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_len);
|
||||
sum = chksum(sum, &dev->d_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_len);
|
||||
|
||||
return (sum == 0) ? 0xffff : htons(sum);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
static uint16 uip_icmp6chksum(void)
|
||||
static uint16 uip_icmp6chksum(struct uip_driver_s *dev)
|
||||
{
|
||||
return upper_layer_chksum(UIP_PROTO_ICMP6);
|
||||
return upper_layer_chksum(dev, UIP_PROTO_ICMP6);
|
||||
}
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
|
@ -358,32 +349,32 @@ uint16 uip_chksum(uint16 *data, uint16 len)
|
|||
return htons(chksum(0, (uint8 *)data, 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. */
|
||||
|
||||
#ifndef UIP_ARCH_IPCHKSUM
|
||||
uint16 uip_ipchksum(void)
|
||||
uint16 uip_ipchksum(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 sum;
|
||||
|
||||
sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
|
||||
sum = chksum(0, &dev->d_buf[UIP_LLH_LEN], UIP_IPH_LEN);
|
||||
dbg("uip_ipchksum: sum 0x%04x\n", sum);
|
||||
return (sum == 0) ? 0xffff : htons(sum);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
|
||||
uint16 uip_tcpchksum(void)
|
||||
uint16 uip_tcpchksum(struct uip_driver_s *dev)
|
||||
{
|
||||
return upper_layer_chksum(UIP_PROTO_TCP);
|
||||
return upper_layer_chksum(dev, UIP_PROTO_TCP);
|
||||
}
|
||||
|
||||
/* Calculate the UDP checksum of the packet in uip_buf and uip_appdata. */
|
||||
/* Calculate the UDP checksum of the packet in d_buf and d_appdata. */
|
||||
|
||||
#ifdef CONFIG_NET_UDP_CHECKSUMS
|
||||
uint16 uip_udpchksum(void)
|
||||
uint16 uip_udpchksum(struct uip_driver_s *dev)
|
||||
{
|
||||
return upper_layer_chksum(UIP_PROTO_UDP);
|
||||
return upper_layer_chksum(dev, UIP_PROTO_UDP);
|
||||
}
|
||||
#endif /* UIP_UDP_CHECKSUMS */
|
||||
#endif /* UIP_ARCH_CHKSUM */
|
||||
|
@ -573,7 +564,7 @@ static uint8 uip_reass(void)
|
|||
BUF->len[0] = uip_reasslen >> 8;
|
||||
BUF->len[1] = uip_reasslen & 0xff;
|
||||
BUF->ipchksum = 0;
|
||||
BUF->ipchksum = ~(uip_ipchksum());
|
||||
BUF->ipchksum = ~(uip_ipchksum(dev));
|
||||
|
||||
return uip_reasslen;
|
||||
}
|
||||
|
@ -593,31 +584,46 @@ static void uip_add_rcv_nxt(uint16 n)
|
|||
uip_conn->rcv_nxt[3] = uip_acc32[3];
|
||||
}
|
||||
|
||||
static void uip_udp_callback(void)
|
||||
static void uip_udp_callback(struct uip_driver_s *dev)
|
||||
{
|
||||
/* Some sanity checking */
|
||||
|
||||
if (uip_udp_conn && uip_udp_conn->callback)
|
||||
if (uip_udp_conn && uip_udp_conn->event)
|
||||
{
|
||||
/* Perform the callback */
|
||||
|
||||
uip_udp_conn->callback(uip_udp_conn->private);
|
||||
uip_udp_conn->event(dev, uip_udp_conn->private);
|
||||
}
|
||||
}
|
||||
|
||||
static void uip_tcp_callback(void)
|
||||
static void uip_tcp_callback(struct uip_driver_s *dev)
|
||||
{
|
||||
/* Some sanity checking */
|
||||
|
||||
if (uip_conn && uip_conn->callback)
|
||||
if (uip_conn)
|
||||
{
|
||||
/* Perform the callback */
|
||||
/* Check if there is a data callback */
|
||||
|
||||
uip_conn->callback(uip_conn->private);
|
||||
if (uip_conn->data_event)
|
||||
{
|
||||
/* Perform the callback */
|
||||
|
||||
uip_conn->data_event(dev, uip_conn->data_private);
|
||||
}
|
||||
|
||||
/* Check if there is a connection-related event and a connection
|
||||
* callback.
|
||||
*/
|
||||
if (((uip_flags & UIP_CONN_EVENTS) != 0) && uip_conn->connection_event)
|
||||
{
|
||||
/* Perform the callback */
|
||||
|
||||
uip_conn->connection_event(uip_conn->connection_private);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uip_interrupt(uint8 flag)
|
||||
void uip_interrupt(struct uip_driver_s *dev, uint8 flag)
|
||||
{
|
||||
register struct uip_conn *uip_connr = uip_conn;
|
||||
|
||||
|
@ -628,7 +634,7 @@ void uip_interrupt(uint8 flag)
|
|||
}
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
|
||||
dev->d_snddata = dev->d_appdata = &dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
|
||||
|
||||
/* Check if we were invoked because of a poll request for a
|
||||
* particular connection.
|
||||
|
@ -640,13 +646,13 @@ void uip_interrupt(uint8 flag)
|
|||
!uip_outstanding(uip_connr))
|
||||
{
|
||||
uip_flags = UIP_POLL;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
goto appsend;
|
||||
}
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Check if we were invoked because of the perodic timer fireing. */
|
||||
/* Check if we were invoked because of the perodic timer firing. */
|
||||
|
||||
else if (flag == UIP_TIMER)
|
||||
{
|
||||
|
@ -663,8 +669,8 @@ void uip_interrupt(uint8 flag)
|
|||
|
||||
/* Reset the length variables. */
|
||||
|
||||
uip_len = 0;
|
||||
uip_slen = 0;
|
||||
dev->d_len = 0;
|
||||
dev->d_sndlen = 0;
|
||||
|
||||
/* Check if the connection is in a state in which we simply wait
|
||||
* for the connection to time out. If so, we increase the
|
||||
|
@ -705,7 +711,7 @@ void uip_interrupt(uint8 flag)
|
|||
*/
|
||||
|
||||
uip_flags = UIP_TIMEDOUT;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
|
||||
/* We also send a reset packet to the remote host. */
|
||||
|
||||
|
@ -749,7 +755,7 @@ void uip_interrupt(uint8 flag)
|
|||
*/
|
||||
|
||||
uip_flags = UIP_REXMIT;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
goto apprexmit;
|
||||
|
||||
case UIP_FIN_WAIT_1:
|
||||
|
@ -768,7 +774,7 @@ void uip_interrupt(uint8 flag)
|
|||
*/
|
||||
|
||||
uip_flags = UIP_POLL;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
goto appsend;
|
||||
}
|
||||
}
|
||||
|
@ -781,10 +787,11 @@ void uip_interrupt(uint8 flag)
|
|||
if (uip_udp_conn->lport != 0)
|
||||
{
|
||||
uip_conn = NULL;
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
|
||||
uip_len = uip_slen = 0;
|
||||
dev->d_snddata = dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
|
||||
dev->d_len = 0;
|
||||
dev->d_sndlen = 0;
|
||||
uip_flags = UIP_POLL;
|
||||
uip_udp_callback();
|
||||
uip_udp_callback(dev);
|
||||
goto udp_send;
|
||||
}
|
||||
else
|
||||
|
@ -822,19 +829,19 @@ void uip_interrupt(uint8 flag)
|
|||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
/* Check the size of the packet. If the size reported to us in
|
||||
uip_len is smaller the size reported in the IP header, we assume
|
||||
d_len is smaller the size reported in the IP header, we assume
|
||||
that the packet has been corrupted in transit. If the size of
|
||||
uip_len is larger than the size reported in the IP packet header,
|
||||
the packet has been padded and we set uip_len to the correct
|
||||
d_len is larger than the size reported in the IP packet header,
|
||||
the packet has been padded and we set d_len to the correct
|
||||
value.. */
|
||||
|
||||
if ((BUF->len[0] << 8) + BUF->len[1] <= uip_len)
|
||||
if ((BUF->len[0] << 8) + BUF->len[1] <= dev->d_len)
|
||||
{
|
||||
uip_len = (BUF->len[0] << 8) + BUF->len[1];
|
||||
dev->d_len = (BUF->len[0] << 8) + BUF->len[1];
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
uip_len += 40; /* The length reported in the IPv6 header is the
|
||||
dev->d_len += 40; /* The length reported in the IPv6 header is the
|
||||
length of the payload that follows the
|
||||
header. However, uIP uses the uip_len variable
|
||||
header. However, uIP uses the d_len variable
|
||||
for holding the size of the entire packet,
|
||||
including the IP header. For IPv4 this is not a
|
||||
problem as the length field in the IPv4 header
|
||||
|
@ -856,8 +863,8 @@ void uip_interrupt(uint8 flag)
|
|||
BUF->ipoffset[1] != 0)
|
||||
{
|
||||
#if UIP_REASSEMBLY
|
||||
uip_len = uip_reass();
|
||||
if (uip_len == 0)
|
||||
dev->d_len = uip_reass();
|
||||
if (dev->d_len == 0)
|
||||
{
|
||||
goto drop;
|
||||
}
|
||||
|
@ -894,10 +901,10 @@ void uip_interrupt(uint8 flag)
|
|||
/* If IP broadcast support is configured, we check for a broadcast
|
||||
UDP packet, which may be destined to us. */
|
||||
#if UIP_BROADCAST
|
||||
dbg("UDP IP checksum 0x%04x\n", uip_ipchksum());
|
||||
dbg("UDP IP checksum 0x%04x\n", uip_ipchksum(dev));
|
||||
if (BUF->proto == UIP_PROTO_UDP &&
|
||||
uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
|
||||
/*&& uip_ipchksum() == 0xffff*/)
|
||||
/*&& uip_ipchksum(dev) == 0xffff*/)
|
||||
{
|
||||
goto udp_input;
|
||||
}
|
||||
|
@ -926,7 +933,7 @@ void uip_interrupt(uint8 flag)
|
|||
}
|
||||
|
||||
#ifndef CONFIG_NET_IPv6
|
||||
if (uip_ipchksum() != 0xffff)
|
||||
if (uip_ipchksum(dev) != 0xffff)
|
||||
{
|
||||
/* Compute and check the IP header checksum. */
|
||||
|
||||
|
@ -1013,7 +1020,7 @@ void uip_interrupt(uint8 flag)
|
|||
#else /* !CONFIG_NET_IPv6 */
|
||||
|
||||
/* This is IPv6 ICMPv6 processing code. */
|
||||
dbg("icmp6_input: length %d\n", uip_len);
|
||||
dbg("icmp6_input: length %d\n", dev->d_len);
|
||||
|
||||
if (BUF->proto != UIP_PROTO_ICMP6)
|
||||
{
|
||||
|
@ -1052,7 +1059,7 @@ void uip_interrupt(uint8 flag)
|
|||
ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
|
||||
memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
|
||||
ICMPBUF->icmpchksum = 0;
|
||||
ICMPBUF->icmpchksum = ~uip_icmp6chksum();
|
||||
ICMPBUF->icmpchksum = ~uip_icmp6chksum(dev);
|
||||
goto send;
|
||||
}
|
||||
goto drop;
|
||||
|
@ -1068,7 +1075,7 @@ void uip_interrupt(uint8 flag)
|
|||
uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
|
||||
uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
|
||||
ICMPBUF->icmpchksum = 0;
|
||||
ICMPBUF->icmpchksum = ~uip_icmp6chksum();
|
||||
ICMPBUF->icmpchksum = ~uip_icmp6chksum(dev);
|
||||
|
||||
UIP_STAT(++uip_stat.icmp.sent);
|
||||
goto send;
|
||||
|
@ -1091,12 +1098,12 @@ void uip_interrupt(uint8 flag)
|
|||
udp_input:
|
||||
/* UDP processing is really just a hack. We don't do anything to the
|
||||
UDP/IP headers, but let the UDP application do all the hard
|
||||
work. If the application sets uip_slen, it has a packet to
|
||||
work. If the application sets d_sndlen, it has a packet to
|
||||
send. */
|
||||
#ifdef CONFIG_NET_UDP_CHECKSUMS
|
||||
uip_len = uip_len - UIP_IPUDPH_LEN;
|
||||
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
|
||||
if (UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff)
|
||||
dev->d_len -= UIP_IPUDPH_LEN;
|
||||
dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
|
||||
if (UDPBUF->udpchksum != 0 && uip_udpchksum(dev) != 0xffff)
|
||||
{
|
||||
UIP_STAT(++uip_stat.udp.drop);
|
||||
UIP_STAT(++uip_stat.udp.chkerr);
|
||||
|
@ -1104,7 +1111,7 @@ void uip_interrupt(uint8 flag)
|
|||
goto drop;
|
||||
}
|
||||
#else /* UIP_UDP_CHECKSUMS */
|
||||
uip_len = uip_len - UIP_IPUDPH_LEN;
|
||||
dev->d_len -= UIP_IPUDPH_LEN;
|
||||
#endif /* UIP_UDP_CHECKSUMS */
|
||||
|
||||
/* Demultiplex this UDP packet between the UDP "connections". */
|
||||
|
@ -1121,31 +1128,31 @@ void uip_interrupt(uint8 flag)
|
|||
udp_found:
|
||||
uip_conn = NULL;
|
||||
uip_flags = UIP_NEWDATA;
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
|
||||
uip_slen = 0;
|
||||
uip_udp_callback();
|
||||
dev->d_snddata = dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
|
||||
dev->d_sndlen = 0;
|
||||
uip_udp_callback(dev);
|
||||
|
||||
udp_send:
|
||||
if (uip_slen == 0)
|
||||
if (dev->d_sndlen == 0)
|
||||
{
|
||||
goto drop;
|
||||
}
|
||||
uip_len = uip_slen + UIP_IPUDPH_LEN;
|
||||
dev->d_len = dev->d_sndlen + UIP_IPUDPH_LEN;
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
BUF->len[0] = (uip_len >> 8);
|
||||
BUF->len[1] = (uip_len & 0xff);
|
||||
BUF->len[0] = (dev->d_len >> 8);
|
||||
BUF->len[1] = (dev->d_len & 0xff);
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
BUF->ttl = uip_udp_conn->ttl;
|
||||
BUF->proto = UIP_PROTO_UDP;
|
||||
|
||||
UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
|
||||
UDPBUF->udplen = HTONS(dev->d_sndlen + UIP_UDPH_LEN);
|
||||
UDPBUF->udpchksum = 0;
|
||||
|
||||
BUF->srcport = uip_udp_conn->lport;
|
||||
|
@ -1154,11 +1161,11 @@ void uip_interrupt(uint8 flag)
|
|||
uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
|
||||
uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
|
||||
|
||||
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
|
||||
dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
|
||||
|
||||
#ifdef CONFIG_NET_UDP_CHECKSUMS
|
||||
/* Calculate UDP checksum. */
|
||||
UDPBUF->udpchksum = ~(uip_udpchksum());
|
||||
UDPBUF->udpchksum = ~(uip_udpchksum(dev));
|
||||
if (UDPBUF->udpchksum == 0)
|
||||
{
|
||||
UDPBUF->udpchksum = 0xffff;
|
||||
|
@ -1174,7 +1181,7 @@ void uip_interrupt(uint8 flag)
|
|||
|
||||
/* Start of TCP input header processing code. */
|
||||
|
||||
if (uip_tcpchksum() != 0xffff)
|
||||
if (uip_tcpchksum(dev) != 0xffff)
|
||||
{
|
||||
/* Compute and check the TCP checksum. */
|
||||
|
||||
|
@ -1225,7 +1232,7 @@ void uip_interrupt(uint8 flag)
|
|||
UIP_STAT(++uip_stat.tcp.rst);
|
||||
|
||||
BUF->flags = TCP_RST | TCP_ACK;
|
||||
uip_len = UIP_IPTCPH_LEN;
|
||||
dev->d_len = UIP_IPTCPH_LEN;
|
||||
BUF->tcpoffset = 5 << 4;
|
||||
|
||||
/* Flip the seqno and ackno fields in the TCP header. */
|
||||
|
@ -1302,7 +1309,7 @@ found_listen:
|
|||
{
|
||||
for (c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;)
|
||||
{
|
||||
opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
|
||||
opt = dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
|
||||
if (opt == TCP_OPT_END)
|
||||
{
|
||||
/* End of options. */
|
||||
|
@ -1314,11 +1321,11 @@ found_listen:
|
|||
/* NOP option. */
|
||||
}
|
||||
else if (opt == TCP_OPT_MSS &&
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN)
|
||||
dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN)
|
||||
{
|
||||
/* An MSS option with the right option length. */
|
||||
tmp16 = ((uint16)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
(uint16)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
|
||||
tmp16 = ((uint16)dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
(uint16)dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
|
||||
uip_connr->initialmss = uip_connr->mss =
|
||||
tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
|
||||
|
||||
|
@ -1329,13 +1336,13 @@ found_listen:
|
|||
{
|
||||
/* All other options have a length field, so that we easily
|
||||
can skip past them. */
|
||||
if (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0)
|
||||
if (dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0)
|
||||
{
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
break;
|
||||
}
|
||||
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
c += dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1353,7 +1360,7 @@ tcp_send_synack:
|
|||
BUF->optdata[1] = TCP_OPT_MSS_LEN;
|
||||
BUF->optdata[2] = (UIP_TCP_MSS) / 256;
|
||||
BUF->optdata[3] = (UIP_TCP_MSS) & 255;
|
||||
uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
|
||||
dev->d_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
|
||||
BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
|
||||
goto tcp_send;
|
||||
|
||||
|
@ -1373,7 +1380,7 @@ tcp_send_synack:
|
|||
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||
UIP_LOG("tcp: got reset, aborting connection.");
|
||||
uip_flags = UIP_ABORT;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
|
@ -1383,12 +1390,12 @@ tcp_send_synack:
|
|||
|
||||
c = (BUF->tcpoffset >> 4) << 2;
|
||||
|
||||
/* uip_len will contain the length of the actual TCP data. This is
|
||||
/* d_len will contain the length of the actual TCP data. This is
|
||||
* calculated by subtracing the length of the TCP header (in
|
||||
* c) and the length of the IP header (20 bytes).
|
||||
*/
|
||||
|
||||
uip_len = uip_len - c - UIP_IPH_LEN;
|
||||
dev->d_len -= (c + UIP_IPH_LEN);
|
||||
|
||||
/* First, check if the sequence number of the incoming packet is
|
||||
* what we're expecting next. If not, we send out an ACK with the
|
||||
|
@ -1398,7 +1405,7 @@ tcp_send_synack:
|
|||
if (!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
|
||||
((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))))
|
||||
{
|
||||
if ((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
|
||||
if ((dev->d_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
|
||||
(BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
|
||||
BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
|
||||
BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
|
||||
|
@ -1476,14 +1483,14 @@ tcp_send_synack:
|
|||
uip_flags = UIP_CONNECTED;
|
||||
uip_connr->len = 0;
|
||||
|
||||
if (uip_len > 0)
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
uip_flags |= UIP_NEWDATA;
|
||||
uip_add_rcv_nxt(uip_len);
|
||||
uip_add_rcv_nxt(dev->d_len);
|
||||
}
|
||||
|
||||
uip_slen = 0;
|
||||
uip_tcp_callback();
|
||||
dev->d_sndlen = 0;
|
||||
uip_tcp_callback(dev);
|
||||
goto appsend;
|
||||
}
|
||||
goto drop;
|
||||
|
@ -1501,7 +1508,7 @@ tcp_send_synack:
|
|||
{
|
||||
for (c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;)
|
||||
{
|
||||
opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
|
||||
opt = dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
|
||||
if (opt == TCP_OPT_END)
|
||||
{
|
||||
/* End of options. */
|
||||
|
@ -1513,11 +1520,11 @@ tcp_send_synack:
|
|||
/* NOP option. */
|
||||
}
|
||||
else if (opt == TCP_OPT_MSS &&
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN)
|
||||
dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN)
|
||||
{
|
||||
/* An MSS option with the right option length. */
|
||||
tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
|
||||
tmp16 = (dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
|
||||
uip_connr->initialmss =
|
||||
uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
|
||||
|
||||
|
@ -1528,13 +1535,13 @@ tcp_send_synack:
|
|||
{
|
||||
/* All other options have a length field, so that we easily
|
||||
can skip past them. */
|
||||
if (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0)
|
||||
if (dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0)
|
||||
{
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
break;
|
||||
}
|
||||
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
c += dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1547,15 +1554,15 @@ tcp_send_synack:
|
|||
uip_add_rcv_nxt(1);
|
||||
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
|
||||
uip_connr->len = 0;
|
||||
uip_len = 0;
|
||||
uip_slen = 0;
|
||||
uip_tcp_callback();
|
||||
dev->d_len = 0;
|
||||
dev->d_sndlen = 0;
|
||||
uip_tcp_callback(dev);
|
||||
goto appsend;
|
||||
}
|
||||
|
||||
/* Inform the application that the connection failed */
|
||||
uip_flags = UIP_ABORT;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
|
||||
/* The connection is closed after we send the RST */
|
||||
uip_conn->tcpstateflags = UIP_CLOSED;
|
||||
|
@ -1563,7 +1570,7 @@ tcp_send_synack:
|
|||
|
||||
case UIP_ESTABLISHED:
|
||||
/* In the ESTABLISHED state, we call upon the application to feed
|
||||
data into the uip_buf. If the UIP_ACKDATA flag is set, the
|
||||
data into the d_buf. If the UIP_ACKDATA flag is set, the
|
||||
application should put new data into the buffer, otherwise we are
|
||||
retransmitting an old segment, and the application should put that
|
||||
data into the buffer.
|
||||
|
@ -1580,15 +1587,15 @@ tcp_send_synack:
|
|||
goto drop;
|
||||
}
|
||||
|
||||
uip_add_rcv_nxt(1 + uip_len);
|
||||
uip_add_rcv_nxt(dev->d_len + 1);
|
||||
uip_flags |= UIP_CLOSE;
|
||||
|
||||
if (uip_len > 0)
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
uip_flags |= UIP_NEWDATA;
|
||||
}
|
||||
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
uip_connr->len = 1;
|
||||
uip_connr->tcpstateflags = UIP_LAST_ACK;
|
||||
uip_connr->nrtx = 0;
|
||||
|
@ -1604,34 +1611,34 @@ tcp_send_synack:
|
|||
{
|
||||
#if UIP_URGDATA > 0
|
||||
uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
|
||||
if (uip_urglen > uip_len)
|
||||
if (uip_urglen > dev->d_len)
|
||||
{
|
||||
/* There is more urgent data in the next segment to come. */
|
||||
uip_urglen = uip_len;
|
||||
uip_urglen = dev->d_len;
|
||||
}
|
||||
uip_add_rcv_nxt(uip_urglen);
|
||||
uip_len -= uip_urglen;
|
||||
uip_urgdata = uip_appdata;
|
||||
uip_appdata += uip_urglen;
|
||||
dev->d_len -= uip_urglen;
|
||||
uip_urgdata = dev->d_appdata;
|
||||
dev->d_appdata += uip_urglen;
|
||||
}
|
||||
else
|
||||
{
|
||||
uip_urglen = 0;
|
||||
#else /* UIP_URGDATA > 0 */
|
||||
uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
|
||||
uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
|
||||
dev->d_appdata = ((char *)dev->d_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
|
||||
dev->d_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
|
||||
#endif /* UIP_URGDATA > 0 */
|
||||
}
|
||||
|
||||
/* If uip_len > 0 we have TCP data in the packet, and we flag this
|
||||
/* If d_len > 0 we have TCP data in the packet, and we flag this
|
||||
by setting the UIP_NEWDATA flag and update the sequence number
|
||||
we acknowledge. If the application has stopped the dataflow
|
||||
using uip_stop(), we must not accept any data packets from the
|
||||
remote host. */
|
||||
if (uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED))
|
||||
if (dev->d_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED))
|
||||
{
|
||||
uip_flags |= UIP_NEWDATA;
|
||||
uip_add_rcv_nxt(uip_len);
|
||||
uip_add_rcv_nxt(dev->d_len);
|
||||
}
|
||||
|
||||
/* Check if the available buffer space advertised by the other end
|
||||
|
@ -1659,25 +1666,25 @@ tcp_send_synack:
|
|||
from the peer (as flagged by the UIP_NEWDATA flag), the
|
||||
application must also be notified.
|
||||
|
||||
When the application is called, the global variable uip_len
|
||||
When the application is called, the d_len field
|
||||
contains the length of the incoming data. The application can
|
||||
access the incoming data through the global pointer
|
||||
uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
|
||||
bytes into the uip_buf array.
|
||||
d_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
|
||||
bytes into the d_buf array.
|
||||
|
||||
If the application wishes to send any data, this data should be
|
||||
put into the uip_appdata and the length of the data should be
|
||||
put into uip_len. If the application don't have any data to
|
||||
send, uip_len must be set to 0. */
|
||||
put into the d_appdata and the length of the data should be
|
||||
put into d_len. If the application don't have any data to
|
||||
send, d_len must be set to 0. */
|
||||
if (uip_flags & (UIP_NEWDATA | UIP_ACKDATA))
|
||||
{
|
||||
uip_slen = 0;
|
||||
uip_tcp_callback();
|
||||
dev->d_sndlen = 0;
|
||||
uip_tcp_callback(dev);
|
||||
|
||||
appsend:
|
||||
if (uip_flags & UIP_ABORT)
|
||||
{
|
||||
uip_slen = 0;
|
||||
dev->d_sndlen = 0;
|
||||
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||
BUF->flags = TCP_RST | TCP_ACK;
|
||||
goto tcp_send_nodata;
|
||||
|
@ -1685,7 +1692,7 @@ tcp_send_synack:
|
|||
|
||||
if (uip_flags & UIP_CLOSE)
|
||||
{
|
||||
uip_slen = 0;
|
||||
dev->d_sndlen = 0;
|
||||
uip_connr->len = 1;
|
||||
uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
|
||||
uip_connr->nrtx = 0;
|
||||
|
@ -1693,8 +1700,8 @@ tcp_send_synack:
|
|||
goto tcp_send_nodata;
|
||||
}
|
||||
|
||||
/* If uip_slen > 0, the application has data to be sent. */
|
||||
if (uip_slen > 0)
|
||||
/* If d_sndlen > 0, the application has data to be sent. */
|
||||
if (dev->d_sndlen > 0)
|
||||
{
|
||||
/* If the connection has acknowledged data, the contents of
|
||||
the ->len variable should be discarded. */
|
||||
|
@ -1711,33 +1718,33 @@ tcp_send_synack:
|
|||
/* The application cannot send more than what is allowed by
|
||||
the mss (the minumum of the MSS and the available
|
||||
window). */
|
||||
if (uip_slen > uip_connr->mss)
|
||||
if (dev->d_sndlen > uip_connr->mss)
|
||||
{
|
||||
uip_slen = uip_connr->mss;
|
||||
dev->d_sndlen = uip_connr->mss;
|
||||
}
|
||||
|
||||
/* Remember how much data we send out now so that we know
|
||||
when everything has been acknowledged. */
|
||||
uip_connr->len = uip_slen;
|
||||
uip_connr->len = dev->d_sndlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the application already had unacknowledged data, we
|
||||
make sure that the application does not send (i.e.,
|
||||
retransmit) out more than it previously sent out. */
|
||||
uip_slen = uip_connr->len;
|
||||
dev->d_sndlen = uip_connr->len;
|
||||
}
|
||||
}
|
||||
uip_connr->nrtx = 0;
|
||||
apprexmit:
|
||||
uip_appdata = uip_sappdata;
|
||||
dev->d_appdata = dev->d_snddata;
|
||||
|
||||
/* If the application has data to be sent, or if the incoming
|
||||
packet had new data in it, we must send out a packet. */
|
||||
if (uip_slen > 0 && uip_connr->len > 0)
|
||||
if (dev->d_sndlen > 0 && uip_connr->len > 0)
|
||||
{
|
||||
/* Add the length of the IP and TCP headers. */
|
||||
uip_len = uip_connr->len + UIP_TCPIP_HLEN;
|
||||
dev->d_len = uip_connr->len + UIP_TCPIP_HLEN;
|
||||
|
||||
/* We always set the ACK flag in response packets. */
|
||||
BUF->flags = TCP_ACK | TCP_PSH;
|
||||
|
@ -1750,7 +1757,7 @@ tcp_send_synack:
|
|||
there is newdata. */
|
||||
if (uip_flags & UIP_NEWDATA)
|
||||
{
|
||||
uip_len = UIP_TCPIP_HLEN;
|
||||
dev->d_len = UIP_TCPIP_HLEN;
|
||||
BUF->flags = TCP_ACK;
|
||||
goto tcp_send_noopts;
|
||||
}
|
||||
|
@ -1764,7 +1771,7 @@ tcp_send_synack:
|
|||
{
|
||||
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||
uip_flags = UIP_CLOSE;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1772,9 +1779,9 @@ tcp_send_synack:
|
|||
/* The application has closed the connection, but the remote host
|
||||
hasn't closed its end yet. Thus we do nothing but wait for a
|
||||
FIN from the other side. */
|
||||
if (uip_len > 0)
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
uip_add_rcv_nxt(uip_len);
|
||||
uip_add_rcv_nxt(dev->d_len);
|
||||
}
|
||||
if (BUF->flags & TCP_FIN)
|
||||
{
|
||||
|
@ -1791,7 +1798,7 @@ tcp_send_synack:
|
|||
|
||||
uip_add_rcv_nxt(1);
|
||||
uip_flags = UIP_CLOSE;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
goto tcp_send_ack;
|
||||
}
|
||||
else if (uip_flags & UIP_ACKDATA)
|
||||
|
@ -1800,16 +1807,16 @@ tcp_send_synack:
|
|||
uip_connr->len = 0;
|
||||
goto drop;
|
||||
}
|
||||
if (uip_len > 0)
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
goto tcp_send_ack;
|
||||
}
|
||||
goto drop;
|
||||
|
||||
case UIP_FIN_WAIT_2:
|
||||
if (uip_len > 0)
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
uip_add_rcv_nxt(uip_len);
|
||||
uip_add_rcv_nxt(dev->d_len);
|
||||
}
|
||||
if (BUF->flags & TCP_FIN)
|
||||
{
|
||||
|
@ -1817,10 +1824,10 @@ tcp_send_synack:
|
|||
uip_connr->timer = 0;
|
||||
uip_add_rcv_nxt(1);
|
||||
uip_flags = UIP_CLOSE;
|
||||
uip_tcp_callback();
|
||||
uip_tcp_callback(dev);
|
||||
goto tcp_send_ack;
|
||||
}
|
||||
if (uip_len > 0)
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
goto tcp_send_ack;
|
||||
}
|
||||
|
@ -1843,7 +1850,7 @@ tcp_send_synack:
|
|||
tcp_send_ack:
|
||||
BUF->flags = TCP_ACK;
|
||||
tcp_send_nodata:
|
||||
uip_len = UIP_IPTCPH_LEN;
|
||||
dev->d_len = UIP_IPTCPH_LEN;
|
||||
tcp_send_noopts:
|
||||
BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
|
||||
tcp_send:
|
||||
|
@ -1886,18 +1893,18 @@ tcp_send_synack:
|
|||
#ifdef CONFIG_NET_IPv6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
BUF->len[0] = (uip_len >> 8);
|
||||
BUF->len[1] = (uip_len & 0xff);
|
||||
BUF->len[0] = (dev->d_len >> 8);
|
||||
BUF->len[1] = (dev->d_len & 0xff);
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
BUF->urgp[0] = BUF->urgp[1] = 0;
|
||||
|
||||
/* Calculate TCP checksum. */
|
||||
BUF->tcpchksum = 0;
|
||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
||||
BUF->tcpchksum = ~(uip_tcpchksum(dev));
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
ip_send_nolen:
|
||||
|
@ -1917,13 +1924,13 @@ tcp_send_synack:
|
|||
|
||||
/* Calculate IP checksum. */
|
||||
BUF->ipchksum = 0;
|
||||
BUF->ipchksum = ~(uip_ipchksum());
|
||||
dbg("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
|
||||
BUF->ipchksum = ~(uip_ipchksum(dev));
|
||||
dbg("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum(dev));
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
UIP_STAT(++uip_stat.tcp.sent);
|
||||
send:
|
||||
dbg("Sending packet with length %d (%d)\n", uip_len,
|
||||
dbg("Sending packet with length %d (%d)\n", dev->d_len,
|
||||
(BUF->len[0] << 8) | BUF->len[1]);
|
||||
|
||||
UIP_STAT(++uip_stat.ip.sent);
|
||||
|
@ -1932,19 +1939,7 @@ tcp_send_synack:
|
|||
uip_flags = 0;
|
||||
return;
|
||||
drop:
|
||||
uip_len = 0;
|
||||
dev->d_len = 0;
|
||||
uip_flags = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void uip_send(const void *data, int len)
|
||||
{
|
||||
if (len > 0)
|
||||
{
|
||||
uip_slen = len;
|
||||
if (data != uip_sappdata)
|
||||
{
|
||||
memcpy(uip_sappdata, (data), uip_slen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/* netutils/telnetd/telnetd.c
|
||||
*
|
||||
* Copyright (c) 2003, Adam Dunkels.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -32,6 +33,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <net/uip/uip.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
#include "telnetd.h"
|
||||
#include "shell.h"
|
||||
|
@ -55,278 +57,291 @@ static struct telnetd_state s;
|
|||
#define TELNET_DO 253
|
||||
#define TELNET_DONT 254
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
shell_quit(char *str)
|
||||
void shell_quit(char *str)
|
||||
{
|
||||
s.state = STATE_CLOSE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
sendline(char *line)
|
||||
static void sendline(char *line)
|
||||
{
|
||||
static unsigned int i;
|
||||
unsigned int i;
|
||||
|
||||
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
|
||||
if(s.lines[i] == NULL) {
|
||||
s.lines[i] = line;
|
||||
break;
|
||||
for (i = 0; i < TELNETD_CONF_NUMLINES; ++i)
|
||||
{
|
||||
if (s.lines[i] == NULL)
|
||||
{
|
||||
s.lines[i] = line;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == TELNETD_CONF_NUMLINES)
|
||||
{
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
if(i == TELNETD_CONF_NUMLINES) {
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
shell_prompt(char *str)
|
||||
|
||||
void shell_prompt(char *str)
|
||||
{
|
||||
char *line;
|
||||
line = (char*)malloc(TELNETD_CONF_LINELEN);
|
||||
if(line != NULL) {
|
||||
strncpy(line, str, TELNETD_CONF_LINELEN);
|
||||
/* petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
|
||||
sendline(line);
|
||||
}
|
||||
if (line != NULL)
|
||||
{
|
||||
strncpy(line, str, TELNETD_CONF_LINELEN);
|
||||
sendline(line);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
shell_output(char *str1, char *str2)
|
||||
|
||||
void shell_output(char *str1, char *str2)
|
||||
{
|
||||
static unsigned len;
|
||||
unsigned len;
|
||||
char *line;
|
||||
|
||||
line = (char*)malloc(TELNETD_CONF_LINELEN);
|
||||
if(line != NULL) {
|
||||
len = strlen(str1);
|
||||
strncpy(line, str1, TELNETD_CONF_LINELEN);
|
||||
if(len < TELNETD_CONF_LINELEN) {
|
||||
strncpy(line + len, str2, TELNETD_CONF_LINELEN - len);
|
||||
if (line != NULL)
|
||||
{
|
||||
len = strlen(str1);
|
||||
strncpy(line, str1, TELNETD_CONF_LINELEN);
|
||||
if (len < TELNETD_CONF_LINELEN)
|
||||
{
|
||||
strncpy(line + len, str2, TELNETD_CONF_LINELEN - len);
|
||||
}
|
||||
len = strlen(line);
|
||||
if (len < TELNETD_CONF_LINELEN - 2)
|
||||
{
|
||||
line[len] = ISO_cr;
|
||||
line[len+1] = ISO_nl;
|
||||
line[len+2] = 0;
|
||||
}
|
||||
sendline(line);
|
||||
}
|
||||
len = strlen(line);
|
||||
if(len < TELNETD_CONF_LINELEN - 2) {
|
||||
line[len] = ISO_cr;
|
||||
line[len+1] = ISO_nl;
|
||||
line[len+2] = 0;
|
||||
}
|
||||
/* petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/
|
||||
sendline(line);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
telnetd_init(void)
|
||||
|
||||
void telnetd_init(void)
|
||||
{
|
||||
uip_listen(HTONS(23));
|
||||
shell_init();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
acked(void)
|
||||
|
||||
static void acked(void)
|
||||
{
|
||||
static unsigned int i;
|
||||
|
||||
while(s.numsent > 0) {
|
||||
free(s.lines[0]);
|
||||
for(i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
|
||||
s.lines[i - 1] = s.lines[i];
|
||||
unsigned int i;
|
||||
|
||||
while(s.numsent > 0)
|
||||
{
|
||||
free(s.lines[0]);
|
||||
for (i = 1; i < TELNETD_CONF_NUMLINES; ++i)
|
||||
{
|
||||
s.lines[i - 1] = s.lines[i];
|
||||
}
|
||||
s.lines[TELNETD_CONF_NUMLINES - 1] = NULL;
|
||||
--s.numsent;
|
||||
}
|
||||
s.lines[TELNETD_CONF_NUMLINES - 1] = NULL;
|
||||
--s.numsent;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
senddata(void)
|
||||
|
||||
static void senddata(struct uip_driver_s *dev)
|
||||
{
|
||||
static char *bufptr, *lineptr;
|
||||
static int buflen, linelen;
|
||||
|
||||
bufptr = uip_appdata;
|
||||
char *bufptr, *lineptr;
|
||||
int buflen, linelen;
|
||||
|
||||
bufptr = (char*)dev->d_appdata;
|
||||
buflen = 0;
|
||||
for(s.numsent = 0; s.numsent < TELNETD_CONF_NUMLINES &&
|
||||
s.lines[s.numsent] != NULL ; ++s.numsent) {
|
||||
lineptr = s.lines[s.numsent];
|
||||
linelen = strlen(lineptr);
|
||||
if(linelen > TELNETD_CONF_LINELEN) {
|
||||
linelen = TELNETD_CONF_LINELEN;
|
||||
for (s.numsent = 0;
|
||||
s.numsent < TELNETD_CONF_NUMLINES && s.lines[s.numsent] != NULL;
|
||||
++s.numsent)
|
||||
{
|
||||
lineptr = s.lines[s.numsent];
|
||||
linelen = strlen(lineptr);
|
||||
if (linelen > TELNETD_CONF_LINELEN)
|
||||
{
|
||||
linelen = TELNETD_CONF_LINELEN;
|
||||
}
|
||||
if (buflen + linelen < uip_mss())
|
||||
{
|
||||
memcpy(bufptr, lineptr, linelen);
|
||||
bufptr += linelen;
|
||||
buflen += linelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(buflen + linelen < uip_mss()) {
|
||||
memcpy(bufptr, lineptr, linelen);
|
||||
bufptr += linelen;
|
||||
buflen += linelen;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
uip_send(uip_appdata, buflen);
|
||||
uip_send(dev, dev->d_appdata, buflen);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
closed(void)
|
||||
|
||||
static void closed(void)
|
||||
{
|
||||
static unsigned int i;
|
||||
|
||||
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
|
||||
if(s.lines[i] != NULL) {
|
||||
free(s.lines[i]);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < TELNETD_CONF_NUMLINES; ++i)
|
||||
{
|
||||
if (s.lines[i] != NULL)
|
||||
{
|
||||
free(s.lines[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
get_char(uint8 c)
|
||||
|
||||
static void get_char(uint8 c)
|
||||
{
|
||||
if(c == ISO_cr) {
|
||||
if (c == ISO_cr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
s.buf[(int)s.bufptr] = c;
|
||||
if(s.buf[(int)s.bufptr] == ISO_nl ||
|
||||
s.bufptr == sizeof(s.buf) - 1) {
|
||||
if(s.bufptr > 0) {
|
||||
s.buf[(int)s.bufptr] = 0;
|
||||
/* petsciiconv_topetscii(s.buf, TELNETD_CONF_LINELEN);*/
|
||||
if (s.buf[(int)s.bufptr] == ISO_nl || s.bufptr == sizeof(s.buf) - 1)
|
||||
{
|
||||
if (s.bufptr > 0)
|
||||
{
|
||||
s.buf[(int)s.bufptr] = 0;
|
||||
}
|
||||
shell_input(s.buf);
|
||||
s.bufptr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++s.bufptr;
|
||||
}
|
||||
shell_input(s.buf);
|
||||
s.bufptr = 0;
|
||||
} else {
|
||||
++s.bufptr;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
sendopt(uint8 option, uint8 value)
|
||||
|
||||
static void sendopt(uint8 option, uint8 value)
|
||||
{
|
||||
char *line;
|
||||
line = (char*)malloc(TELNETD_CONF_LINELEN);
|
||||
if(line != NULL) {
|
||||
line[0] = TELNET_IAC;
|
||||
line[1] = option;
|
||||
line[2] = value;
|
||||
line[3] = 0;
|
||||
sendline(line);
|
||||
}
|
||||
if (line != NULL)
|
||||
{
|
||||
line[0] = TELNET_IAC;
|
||||
line[1] = option;
|
||||
line[2] = value;
|
||||
line[3] = 0;
|
||||
sendline(line);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
newdata(void)
|
||||
|
||||
static void newdata(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 len;
|
||||
uint8 c;
|
||||
char *dataptr;
|
||||
|
||||
|
||||
len = uip_datalen();
|
||||
dataptr = (char *)uip_appdata;
|
||||
|
||||
while(len > 0 && s.bufptr < sizeof(s.buf)) {
|
||||
c = *dataptr;
|
||||
++dataptr;
|
||||
--len;
|
||||
switch(s.state) {
|
||||
case STATE_IAC:
|
||||
if(c == TELNET_IAC) {
|
||||
get_char(c);
|
||||
s.state = STATE_NORMAL;
|
||||
} else {
|
||||
switch(c) {
|
||||
case TELNET_WILL:
|
||||
s.state = STATE_WILL;
|
||||
break;
|
||||
case TELNET_WONT:
|
||||
s.state = STATE_WONT;
|
||||
break;
|
||||
case TELNET_DO:
|
||||
s.state = STATE_DO;
|
||||
break;
|
||||
case TELNET_DONT:
|
||||
s.state = STATE_DONT;
|
||||
break;
|
||||
default:
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_WILL:
|
||||
/* Reply with a DONT */
|
||||
sendopt(TELNET_DONT, c);
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
|
||||
case STATE_WONT:
|
||||
/* Reply with a DONT */
|
||||
sendopt(TELNET_DONT, c);
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
case STATE_DO:
|
||||
/* Reply with a WONT */
|
||||
sendopt(TELNET_WONT, c);
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
case STATE_DONT:
|
||||
/* Reply with a WONT */
|
||||
sendopt(TELNET_WONT, c);
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
case STATE_NORMAL:
|
||||
if(c == TELNET_IAC) {
|
||||
s.state = STATE_IAC;
|
||||
} else {
|
||||
get_char(c);
|
||||
}
|
||||
break;
|
||||
|
||||
len = uip_datalen(dev);
|
||||
dataptr = (char *)dev->d_appdata;
|
||||
|
||||
while(len > 0 && s.bufptr < sizeof(s.buf))\
|
||||
{
|
||||
c = *dataptr;
|
||||
++dataptr;
|
||||
--len;
|
||||
switch(s.state)
|
||||
{
|
||||
case STATE_IAC:
|
||||
if (c == TELNET_IAC)
|
||||
{
|
||||
get_char(c);
|
||||
s.state = STATE_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case TELNET_WILL:
|
||||
s.state = STATE_WILL;
|
||||
break;
|
||||
case TELNET_WONT:
|
||||
s.state = STATE_WONT;
|
||||
break;
|
||||
case TELNET_DO:
|
||||
s.state = STATE_DO;
|
||||
break;
|
||||
case TELNET_DONT:
|
||||
s.state = STATE_DONT;
|
||||
break;
|
||||
default:
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_WILL:
|
||||
/* Reply with a DONT */
|
||||
sendopt(TELNET_DONT, c);
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
|
||||
case STATE_WONT:
|
||||
/* Reply with a DONT */
|
||||
sendopt(TELNET_DONT, c);
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
case STATE_DO:
|
||||
/* Reply with a WONT */
|
||||
sendopt(TELNET_WONT, c);
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
case STATE_DONT:
|
||||
/* Reply with a WONT */
|
||||
sendopt(TELNET_WONT, c);
|
||||
s.state = STATE_NORMAL;
|
||||
break;
|
||||
case STATE_NORMAL:
|
||||
if (c == TELNET_IAC)
|
||||
{
|
||||
s.state = STATE_IAC;
|
||||
}
|
||||
else
|
||||
{
|
||||
get_char(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called by the UIP interrupt handling logic whenevent an
|
||||
* event of interest occurs.
|
||||
*/
|
||||
|
||||
void uip_interrupt_event(void)
|
||||
void uip_interrupt_event(struct uip_driver_s *dev, void *private)
|
||||
{
|
||||
#warning OBSOLETE -- needs to be redesigned
|
||||
static unsigned int i;
|
||||
if(uip_connected()) {
|
||||
/* tcp_markconn(uip_conn, &s);*/
|
||||
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
|
||||
s.lines[i] = NULL;
|
||||
}
|
||||
s.bufptr = 0;
|
||||
s.state = STATE_NORMAL;
|
||||
unsigned int i;
|
||||
if (uip_connected())
|
||||
{
|
||||
for (i = 0; i < TELNETD_CONF_NUMLINES; ++i)
|
||||
{
|
||||
s.lines[i] = NULL;
|
||||
}
|
||||
s.bufptr = 0;
|
||||
s.state = STATE_NORMAL;
|
||||
|
||||
shell_start();
|
||||
shell_start();
|
||||
}
|
||||
|
||||
if(s.state == STATE_CLOSE) {
|
||||
if (s.state == STATE_CLOSE)
|
||||
{
|
||||
s.state = STATE_NORMAL;
|
||||
uip_close();
|
||||
return;
|
||||
}
|
||||
|
||||
if(uip_closed() ||
|
||||
uip_aborted() ||
|
||||
uip_timedout()) {
|
||||
|
||||
if (uip_closed() || uip_aborted() || uip_timedout())
|
||||
{
|
||||
closed();
|
||||
}
|
||||
|
||||
if(uip_acked()) {
|
||||
|
||||
if (uip_acked())
|
||||
{
|
||||
acked();
|
||||
}
|
||||
|
||||
if(uip_newdata()) {
|
||||
newdata();
|
||||
|
||||
if (uip_newdata())
|
||||
{
|
||||
newdata(dev);
|
||||
}
|
||||
|
||||
if(uip_rexmit() ||
|
||||
uip_newdata() ||
|
||||
uip_acked() ||
|
||||
uip_connected() ||
|
||||
uip_poll()) {
|
||||
senddata();
|
||||
|
||||
if (uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll())
|
||||
{
|
||||
senddata(dev);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
#include <net/uip/resolv.h>
|
||||
|
||||
#include "uiplib/uiplib.h"
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
#include "webclient.h"
|
||||
|
||||
#define WEBCLIENT_TIMEOUT 100
|
||||
|
@ -178,14 +180,14 @@ static char *copy_string(char *dest, const char *src, int len)
|
|||
return dest + len;
|
||||
}
|
||||
|
||||
static void senddata(void)
|
||||
static void senddata(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 len;
|
||||
char *getrequest;
|
||||
char *cptr;
|
||||
|
||||
if (s.getrequestleft > 0) {
|
||||
cptr = getrequest = (char *)uip_appdata;
|
||||
cptr = getrequest = (char *)dev->d_appdata;
|
||||
|
||||
cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
|
||||
cptr = copy_string(cptr, s.file, strlen(s.file));
|
||||
|
@ -204,7 +206,7 @@ static void senddata(void)
|
|||
len = s.getrequestleft > uip_mss()?
|
||||
uip_mss():
|
||||
s.getrequestleft;
|
||||
uip_send(&(getrequest[s.getrequestptr]), len);
|
||||
uip_send(dev, &(getrequest[s.getrequestptr]), len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,15 +223,15 @@ static void acked(void)
|
|||
}
|
||||
}
|
||||
|
||||
static uint16 parse_statusline(uint16 len)
|
||||
static uint16 parse_statusline(struct uip_driver_s *dev, uint16 len)
|
||||
{
|
||||
char *cptr;
|
||||
|
||||
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline))
|
||||
{
|
||||
char *pappdata = (char*)uip_appdata;
|
||||
char *pappdata = (char*)dev->d_appdata;
|
||||
s.httpheaderline[s.httpheaderlineptr] = *pappdata++;
|
||||
uip_appdata = (void*)pappdata;
|
||||
dev->d_appdata = (void*)pappdata;
|
||||
len--;
|
||||
|
||||
if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl)
|
||||
|
@ -301,16 +303,16 @@ static char casecmp(char *str1, const char *str2, char len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint16 parse_headers(uint16 len)
|
||||
static uint16 parse_headers(struct uip_driver_s *dev, uint16 len)
|
||||
{
|
||||
char *cptr;
|
||||
static unsigned char i;
|
||||
|
||||
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline))
|
||||
{
|
||||
char *pappdata = (char*)uip_appdata;
|
||||
char *pappdata = (char*)dev->d_appdata;
|
||||
s.httpheaderline[s.httpheaderlineptr] = *pappdata++;
|
||||
uip_appdata = (void*)pappdata;
|
||||
dev->d_appdata = (void*)pappdata;
|
||||
len--;
|
||||
|
||||
if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl)
|
||||
|
@ -378,23 +380,23 @@ static uint16 parse_headers(uint16 len)
|
|||
return len;
|
||||
}
|
||||
|
||||
static void newdata(void)
|
||||
static void newdata(struct uip_driver_s *dev)
|
||||
{
|
||||
uint16 len;
|
||||
|
||||
len = uip_datalen();
|
||||
len = uip_datalen(dev);
|
||||
|
||||
if (s.state == WEBCLIENT_STATE_STATUSLINE) {
|
||||
len = parse_statusline(len);
|
||||
len = parse_statusline(dev, len);
|
||||
}
|
||||
|
||||
if (s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
|
||||
len = parse_headers(len);
|
||||
len = parse_headers(dev, len);
|
||||
}
|
||||
|
||||
if (len > 0 && s.state == WEBCLIENT_STATE_DATA &&
|
||||
s.httpflag != HTTPFLAG_MOVED) {
|
||||
webclient_datahandler((char *)uip_appdata, len);
|
||||
webclient_datahandler((char *)dev->d_appdata, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,14 +404,14 @@ static void newdata(void)
|
|||
* event of interest occurs.
|
||||
*/
|
||||
|
||||
void uip_interrupt_event(void)
|
||||
void uip_interrupt_event(struct uip_driver_s *dev)
|
||||
{
|
||||
#warning OBSOLETE -- needs to be redesigned
|
||||
if (uip_connected())
|
||||
{
|
||||
s.timer = 0;
|
||||
s.state = WEBCLIENT_STATE_STATUSLINE;
|
||||
senddata();
|
||||
senddata(dev);
|
||||
webclient_connected();
|
||||
return;
|
||||
}
|
||||
|
@ -440,12 +442,12 @@ void uip_interrupt_event(void)
|
|||
if (uip_newdata())
|
||||
{
|
||||
s.timer = 0;
|
||||
newdata();
|
||||
newdata(dev);
|
||||
}
|
||||
|
||||
if (uip_rexmit() || uip_newdata() || uip_acked())
|
||||
{
|
||||
senddata();
|
||||
senddata(dev);
|
||||
}
|
||||
else if (uip_poll())
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue