diff --git a/components/net/lwip/src/netif/ethernetif.c b/components/net/lwip/src/netif/ethernetif.c index 42e6ac39f40df90b8e2e3b5f75d06c23a9ff3247..3f0fd21e594bc24a88b51a6f78d957e3dc26eab1 100644 --- a/components/net/lwip/src/netif/ethernetif.c +++ b/components/net/lwip/src/netif/ethernetif.c @@ -12,15 +12,16 @@ * 2010-07-07 Bernard fix send mail to mailbox issue. * 2011-07-30 mbbill port lwIP 1.4.0 to RT-Thread * 2012-04-10 Bernard add more compatible with RT-Thread. - * 2012-11-12 Bernard The network interface can be initialized + * 2012-11-12 Bernard The network interface can be initialized * after lwIP initialization. + * 2013-02-28 aozima fixed list_tcps bug: ipaddr_ntoa isn't reentrant. */ /* * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, + * 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, @@ -29,21 +30,21 @@ * 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. + * 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 + * 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. * * This file is part of the lwIP TCP/IP stack. - * + * * Author: Adam Dunkels * */ @@ -71,8 +72,8 @@ */ struct eth_tx_msg { - struct netif *netif; - struct pbuf *buf; + struct netif *netif; + struct pbuf *buf; }; static struct rt_mailbox eth_tx_thread_mb; @@ -99,288 +100,288 @@ static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE]; static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p) { - struct eth_tx_msg msg; - struct eth_device* enetif; + struct eth_tx_msg msg; + struct eth_device* enetif; - enetif = (struct eth_device*)netif->state; + enetif = (struct eth_device*)netif->state; - /* send a message to eth tx thread */ - msg.netif = netif; - msg.buf = p; - if (rt_mb_send(ð_tx_thread_mb, (rt_uint32_t) &msg) == RT_EOK) - { - /* waiting for ack */ - rt_sem_take(&(enetif->tx_ack), RT_WAITING_FOREVER); - } + /* send a message to eth tx thread */ + msg.netif = netif; + msg.buf = p; + if (rt_mb_send(ð_tx_thread_mb, (rt_uint32_t) &msg) == RT_EOK) + { + /* waiting for ack */ + rt_sem_take(&(enetif->tx_ack), RT_WAITING_FOREVER); + } - return ERR_OK; + return ERR_OK; } static err_t eth_netif_device_init(struct netif *netif) { - struct eth_device *ethif; + struct eth_device *ethif; - ethif = (struct eth_device*)netif->state; - if (ethif != RT_NULL) - { - rt_device_t device; + ethif = (struct eth_device*)netif->state; + if (ethif != RT_NULL) + { + rt_device_t device; - /* get device object */ - device = (rt_device_t) ethif; - if (rt_device_init(device) != RT_EOK) - { - return ERR_IF; - } + /* get device object */ + device = (rt_device_t) ethif; + if (rt_device_init(device) != RT_EOK) + { + return ERR_IF; + } - /* copy device flags to netif flags */ - netif->flags = ethif->flags; + /* copy device flags to netif flags */ + netif->flags = ethif->flags; - /* set default netif */ - if (netif_default == RT_NULL) - netif_set_default(ethif->netif); + /* set default netif */ + if (netif_default == RT_NULL) + netif_set_default(ethif->netif); #if LWIP_DHCP - if (ethif->flags & NETIF_FLAG_DHCP) - { - /* if this interface uses DHCP, start the DHCP client */ - dhcp_start(ethif->netif); - } - else + if (ethif->flags & NETIF_FLAG_DHCP) + { + /* if this interface uses DHCP, start the DHCP client */ + dhcp_start(ethif->netif); + } + else #endif - { - /* set interface up */ - netif_set_up(ethif->netif); - } + { + /* set interface up */ + netif_set_up(ethif->netif); + } #ifdef LWIP_NETIF_LINK_CALLBACK - netif_set_link_up(ethif->netif); + netif_set_link_up(ethif->netif); #endif - return ERR_OK; - } + return ERR_OK; + } - return ERR_IF; + return ERR_IF; } /* Keep old drivers compatible in RT-Thread */ rt_err_t eth_device_init_with_flag(struct eth_device *dev, char *name, rt_uint8_t flags) { - struct netif* netif; - - netif = (struct netif*) rt_malloc (sizeof(struct netif)); - if (netif == RT_NULL) - { - rt_kprintf("malloc netif failed\n"); - return -RT_ERROR; - } - rt_memset(netif, 0, sizeof(struct netif)); - - /* set netif */ - dev->netif = netif; - /* device flags, which will be set to netif flags when initializing */ - dev->flags = flags; - /* link changed status of device */ - dev->link_changed = 0x00; - dev->parent.type = RT_Device_Class_NetIf; - /* register to RT-Thread device manager */ - rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR); - rt_sem_init(&(dev->tx_ack), name, 0, RT_IPC_FLAG_FIFO); - - /* set name */ - netif->name[0] = name[0]; - netif->name[1] = name[1]; - - /* set hw address to 6 */ - netif->hwaddr_len = 6; - /* maximum transfer unit */ - netif->mtu = ETHERNET_MTU; - - /* get hardware MAC address */ - rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr); - - /* set output */ - netif->output = etharp_output; - netif->linkoutput = ethernetif_linkoutput; - - /* if tcp thread has been started up, we add this netif to the system */ - if (rt_thread_find("tcpip") != RT_NULL) - { - struct ip_addr ipaddr, netmask, gw; + struct netif* netif; + + netif = (struct netif*) rt_malloc (sizeof(struct netif)); + if (netif == RT_NULL) + { + rt_kprintf("malloc netif failed\n"); + return -RT_ERROR; + } + rt_memset(netif, 0, sizeof(struct netif)); + + /* set netif */ + dev->netif = netif; + /* device flags, which will be set to netif flags when initializing */ + dev->flags = flags; + /* link changed status of device */ + dev->link_changed = 0x00; + dev->parent.type = RT_Device_Class_NetIf; + /* register to RT-Thread device manager */ + rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR); + rt_sem_init(&(dev->tx_ack), name, 0, RT_IPC_FLAG_FIFO); + + /* set name */ + netif->name[0] = name[0]; + netif->name[1] = name[1]; + + /* set hw address to 6 */ + netif->hwaddr_len = 6; + /* maximum transfer unit */ + netif->mtu = ETHERNET_MTU; + + /* get hardware MAC address */ + rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr); + + /* set output */ + netif->output = etharp_output; + netif->linkoutput = ethernetif_linkoutput; + + /* if tcp thread has been started up, we add this netif to the system */ + if (rt_thread_find("tcpip") != RT_NULL) + { + struct ip_addr ipaddr, netmask, gw; #if !LWIP_DHCP - IP4_ADDR(&ipaddr, RT_LWIP_IPADDR0, RT_LWIP_IPADDR1, RT_LWIP_IPADDR2, RT_LWIP_IPADDR3); - IP4_ADDR(&gw, RT_LWIP_GWADDR0, RT_LWIP_GWADDR1, RT_LWIP_GWADDR2, RT_LWIP_GWADDR3); - IP4_ADDR(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3); + IP4_ADDR(&ipaddr, RT_LWIP_IPADDR0, RT_LWIP_IPADDR1, RT_LWIP_IPADDR2, RT_LWIP_IPADDR3); + IP4_ADDR(&gw, RT_LWIP_GWADDR0, RT_LWIP_GWADDR1, RT_LWIP_GWADDR2, RT_LWIP_GWADDR3); + IP4_ADDR(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3); #else - IP4_ADDR(&ipaddr, 0, 0, 0, 0); - IP4_ADDR(&gw, 0, 0, 0, 0); - IP4_ADDR(&netmask, 0, 0, 0, 0); + IP4_ADDR(&ipaddr, 0, 0, 0, 0); + IP4_ADDR(&gw, 0, 0, 0, 0); + IP4_ADDR(&netmask, 0, 0, 0, 0); #endif - - netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, eth_netif_device_init, tcpip_input); - } - return RT_EOK; + netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, eth_netif_device_init, tcpip_input); + } + + return RT_EOK; } rt_err_t eth_device_init(struct eth_device * dev, char *name) { - rt_uint8_t flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + rt_uint8_t flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; #if LWIP_DHCP - /* DHCP support */ - flags |= NETIF_FLAG_DHCP; + /* DHCP support */ + flags |= NETIF_FLAG_DHCP; #endif #if LWIP_IGMP - /* IGMP support */ - flags |= NETIF_FLAG_IGMP; + /* IGMP support */ + flags |= NETIF_FLAG_IGMP; #endif - return eth_device_init_with_flag(dev, name, flags); + return eth_device_init_with_flag(dev, name, flags); } rt_err_t eth_device_ready(struct eth_device* dev) { - if (dev->netif) - /* post message to Ethernet thread */ - return rt_mb_send(ð_rx_thread_mb, (rt_uint32_t)dev); - else - return ERR_OK; /* netif is not initialized yet, just return. */ + if (dev->netif) + /* post message to Ethernet thread */ + return rt_mb_send(ð_rx_thread_mb, (rt_uint32_t)dev); + else + return ERR_OK; /* netif is not initialized yet, just return. */ } rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up) { - rt_uint32_t level; + rt_uint32_t level; - RT_ASSERT(dev != RT_NULL); + RT_ASSERT(dev != RT_NULL); - level = rt_hw_interrupt_disable(); - dev->link_changed = 0x01; - if (up == RT_TRUE) - dev->link_status = 0x01; - else - dev->link_status = 0x00; - rt_hw_interrupt_enable(level); + level = rt_hw_interrupt_disable(); + dev->link_changed = 0x01; + if (up == RT_TRUE) + dev->link_status = 0x01; + else + dev->link_status = 0x00; + rt_hw_interrupt_enable(level); - /* post message to ethernet thread */ - return rt_mb_send(ð_rx_thread_mb, (rt_uint32_t)dev); + /* post message to ethernet thread */ + return rt_mb_send(ð_rx_thread_mb, (rt_uint32_t)dev); } /* Ethernet Tx Thread */ static void eth_tx_thread_entry(void* parameter) { - struct eth_tx_msg* msg; - - while (1) - { - if (rt_mb_recv(ð_tx_thread_mb, (rt_uint32_t*)&msg, RT_WAITING_FOREVER) == RT_EOK) - { - struct eth_device* enetif; - - RT_ASSERT(msg->netif != RT_NULL); - RT_ASSERT(msg->buf != RT_NULL); - - enetif = (struct eth_device*)msg->netif->state; - if (enetif != RT_NULL) - { - /* call driver's interface */ - if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK) - { - rt_kprintf("transmit eth packet failed\n"); - } - } - - /* send ACK */ - rt_sem_release(&(enetif->tx_ack)); - } - } + struct eth_tx_msg* msg; + + while (1) + { + if (rt_mb_recv(ð_tx_thread_mb, (rt_uint32_t*)&msg, RT_WAITING_FOREVER) == RT_EOK) + { + struct eth_device* enetif; + + RT_ASSERT(msg->netif != RT_NULL); + RT_ASSERT(msg->buf != RT_NULL); + + enetif = (struct eth_device*)msg->netif->state; + if (enetif != RT_NULL) + { + /* call driver's interface */ + if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK) + { + rt_kprintf("transmit eth packet failed\n"); + } + } + + /* send ACK */ + rt_sem_release(&(enetif->tx_ack)); + } + } } /* Ethernet Rx Thread */ static void eth_rx_thread_entry(void* parameter) { - struct eth_device* device; - - while (1) - { - if (rt_mb_recv(ð_rx_thread_mb, (rt_uint32_t*)&device, RT_WAITING_FOREVER) == RT_EOK) - { - struct pbuf *p; - - /* check link status */ - if (device->link_changed) - { - int status; - rt_uint32_t level; - - level = rt_hw_interrupt_disable(); - status = device->link_status; - device->link_changed = 0x00; - rt_hw_interrupt_enable(level); - - if (status) - netifapi_netif_set_link_up(device->netif); - else - netifapi_netif_set_link_down(device->netif); - } - - /* receive all of buffer */ - while (1) - { - p = device->eth_rx(&(device->parent)); - if (p != RT_NULL) - { - /* notify to upper layer */ - if( device->netif->input(p, device->netif) != ERR_OK ) - { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Input error\n")); - pbuf_free(p); - p = NULL; - } - } - else break; - } - } - else - { - LWIP_ASSERT("Should not happen!\n",0); - } - } + struct eth_device* device; + + while (1) + { + if (rt_mb_recv(ð_rx_thread_mb, (rt_uint32_t*)&device, RT_WAITING_FOREVER) == RT_EOK) + { + struct pbuf *p; + + /* check link status */ + if (device->link_changed) + { + int status; + rt_uint32_t level; + + level = rt_hw_interrupt_disable(); + status = device->link_status; + device->link_changed = 0x00; + rt_hw_interrupt_enable(level); + + if (status) + netifapi_netif_set_link_up(device->netif); + else + netifapi_netif_set_link_down(device->netif); + } + + /* receive all of buffer */ + while (1) + { + p = device->eth_rx(&(device->parent)); + if (p != RT_NULL) + { + /* notify to upper layer */ + if( device->netif->input(p, device->netif) != ERR_OK ) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Input error\n")); + pbuf_free(p); + p = NULL; + } + } + else break; + } + } + else + { + LWIP_ASSERT("Should not happen!\n",0); + } + } } void eth_system_device_init() { - rt_err_t result = RT_EOK; - - /* initialize Rx thread. - * initialize mailbox and create Ethernet Rx thread */ - result = rt_mb_init(ð_rx_thread_mb, "erxmb", - ð_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/4, - RT_IPC_FLAG_FIFO); - RT_ASSERT(result == RT_EOK); - - result = rt_thread_init(ð_rx_thread, "erx", eth_rx_thread_entry, RT_NULL, - ð_rx_thread_stack[0], sizeof(eth_rx_thread_stack), - RT_LWIP_ETHTHREAD_PRIORITY, 16); - RT_ASSERT(result == RT_EOK); - result = rt_thread_startup(ð_rx_thread); - RT_ASSERT(result == RT_EOK); - - /* initialize Tx thread */ - /* initialize mailbox and create Ethernet Tx thread */ - result = rt_mb_init(ð_tx_thread_mb, "etxmb", - ð_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/4, - RT_IPC_FLAG_FIFO); - RT_ASSERT(result == RT_EOK); - - result = rt_thread_init(ð_tx_thread, "etx", eth_tx_thread_entry, RT_NULL, - ð_tx_thread_stack[0], sizeof(eth_tx_thread_stack), - RT_ETHERNETIF_THREAD_PREORITY, 16); - RT_ASSERT(result == RT_EOK); - - result = rt_thread_startup(ð_tx_thread); - RT_ASSERT(result == RT_EOK); + rt_err_t result = RT_EOK; + + /* initialize Rx thread. + * initialize mailbox and create Ethernet Rx thread */ + result = rt_mb_init(ð_rx_thread_mb, "erxmb", + ð_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/4, + RT_IPC_FLAG_FIFO); + RT_ASSERT(result == RT_EOK); + + result = rt_thread_init(ð_rx_thread, "erx", eth_rx_thread_entry, RT_NULL, + ð_rx_thread_stack[0], sizeof(eth_rx_thread_stack), + RT_LWIP_ETHTHREAD_PRIORITY, 16); + RT_ASSERT(result == RT_EOK); + result = rt_thread_startup(ð_rx_thread); + RT_ASSERT(result == RT_EOK); + + /* initialize Tx thread */ + /* initialize mailbox and create Ethernet Tx thread */ + result = rt_mb_init(ð_tx_thread_mb, "etxmb", + ð_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/4, + RT_IPC_FLAG_FIFO); + RT_ASSERT(result == RT_EOK); + + result = rt_thread_init(ð_tx_thread, "etx", eth_tx_thread_entry, RT_NULL, + ð_tx_thread_stack[0], sizeof(eth_tx_thread_stack), + RT_ETHERNETIF_THREAD_PREORITY, 16); + RT_ASSERT(result == RT_EOK); + + result = rt_thread_startup(ð_tx_thread); + RT_ASSERT(result == RT_EOK); } #ifdef RT_USING_FINSH @@ -436,12 +437,12 @@ FINSH_FUNCTION_EXPORT(set_if, set network interface address); #include void set_dns(char* dns_server) { - struct ip_addr addr; - - if ((dns_server != RT_NULL) && ipaddr_aton(dns_server, &addr)) - { - dns_setserver(0, &addr); - } + struct ip_addr addr; + + if ((dns_server != RT_NULL) && ipaddr_aton(dns_server, &addr)) + { + dns_setserver(0, &addr); + } } FINSH_FUNCTION_EXPORT(set_dns, set DNS server address); #endif @@ -451,11 +452,16 @@ void list_if(void) rt_ubase_t index; struct netif * netif; + rt_enter_critical(); + netif = netif_list; while( netif != RT_NULL ) { - rt_kprintf("network interface: %c%c%s\n", netif->name[0], netif->name[1], (netif == netif_default)?" (Default)":""); + rt_kprintf("network interface: %c%c%s\n", + netif->name[0], + netif->name[1], + (netif == netif_default)?" (Default)":""); rt_kprintf("MTU: %d\n", netif->mtu); rt_kprintf("MAC: "); for (index = 0; index < netif->hwaddr_len; index ++) @@ -489,6 +495,8 @@ void list_if(void) } } #endif /**< #if LWIP_DNS */ + + rt_exit_critical(); } FINSH_FUNCTION_EXPORT(list_if, list network interface information); @@ -496,42 +504,62 @@ FINSH_FUNCTION_EXPORT(list_if, list network interface information); #include #include -void list_tcps() +void list_tcps(void) { - struct tcp_pcb *pcb; - extern struct tcp_pcb *tcp_active_pcbs; - extern union tcp_listen_pcbs_t tcp_listen_pcbs; - extern struct tcp_pcb *tcp_tw_pcbs; - extern const char *tcp_state_str[]; - - rt_enter_critical(); - rt_kprintf("Active PCB states:\n"); - for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) - { - rt_kprintf("%s:%d <==> %s:%d snd_nxt %d rcv_nxt %d ", - ipaddr_ntoa(&(pcb->local_ip)), pcb->local_port, - ipaddr_ntoa(&(pcb->remote_ip)), pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt); - rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); - } - - rt_kprintf("Listen PCB states:\n"); - for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) - { - rt_kprintf("local port %d ", pcb->local_port); - rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); - } - - rt_kprintf("TIME-WAIT PCB states:\n"); - for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) - { - rt_kprintf("%s:%d <==> %s:%d snd_nxt %d rcv_nxt %d ", - ipaddr_ntoa(&(pcb->local_ip)), pcb->local_port, - ipaddr_ntoa(&(pcb->remote_ip)), pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt); - rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); - } - rt_exit_critical(); + rt_uint32_t num = 0; + struct tcp_pcb *pcb; + char local_ip_str[16]; + char remote_ip_str[16]; + + extern struct tcp_pcb *tcp_active_pcbs; + extern union tcp_listen_pcbs_t tcp_listen_pcbs; + extern struct tcp_pcb *tcp_tw_pcbs; + extern const char *tcp_state_str[]; + + rt_enter_critical(); + rt_kprintf("Active PCB states:\n"); + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) + { + strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip))); + strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip))); + + rt_kprintf("#%d %s:%d <==> %s:%d snd_nxt 0x%08X rcv_nxt 0x%08X ", + num++, + local_ip_str, + pcb->local_port, + remote_ip_str, + pcb->remote_port, + pcb->snd_nxt, + pcb->rcv_nxt); + rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); + } + + rt_kprintf("Listen PCB states:\n"); + num = 0; + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) + { + rt_kprintf("#%d local port %d ", num++, pcb->local_port); + rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); + } + + rt_kprintf("TIME-WAIT PCB states:\n"); + num = 0; + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) + { + strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip))); + strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip))); + + rt_kprintf("#%d %s:%d <==> %s:%d snd_nxt 0x%08X rcv_nxt 0x%08X ", + num++, + local_ip_str, + pcb->local_port, + remote_ip_str, + pcb->remote_port, + pcb->snd_nxt, + pcb->rcv_nxt); + rt_kprintf("state: %s\n", tcp_state_str[pcb->state]); + } + rt_exit_critical(); } FINSH_FUNCTION_EXPORT(list_tcps, list all of tcp connections); #endif