ethernetif.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2010-07-07 Bernard fix send mail to mailbox issue.
  9. * 2011-07-30 mbbill port lwIP 1.4.0 to RT-Thread
  10. * 2012-04-10 Bernard add more compatible with RT-Thread.
  11. * 2012-11-12 Bernard The network interface can be initialized
  12. * after lwIP initialization.
  13. * 2013-02-28 aozima fixed list_tcps bug: ipaddr_ntoa isn't reentrant.
  14. * 2016-08-18 Bernard port to lwIP 2.0.0
  15. * 2018-11-02 MurphyZhao port to lwIP 2.1.0
  16. * 2021-09-07 Grissiom fix eth_tx_msg ack bug
  17. * 2022-02-22 xiangxistu integrate v1.4.1 v2.0.3 and v2.1.2 porting layer
  18. */
  19. /*
  20. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  21. * All rights reserved.
  22. *
  23. * Redistribution and use in source and binary forms, with or without modification,
  24. * are permitted provided that the following conditions are met:
  25. *
  26. * 1. Redistributions of source code must retain the above copyright notice,
  27. * this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright notice,
  29. * this list of conditions and the following disclaimer in the documentation
  30. * and/or other materials provided with the distribution.
  31. * 3. The name of the author may not be used to endorse or promote products
  32. * derived from this software without specific prior written permission.
  33. *
  34. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  35. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  36. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  37. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  38. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  39. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  40. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  41. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  42. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  43. * OF SUCH DAMAGE.
  44. *
  45. * This file is part of the lwIP TCP/IP stack.
  46. *
  47. * Author: Adam Dunkels <adam@sics.se>
  48. */
  49. #include <string.h>
  50. #include <lwip/init.h>
  51. #include <lwip/opt.h>
  52. #include <lwip/debug.h>
  53. #include <lwip/def.h>
  54. #include <lwip/mem.h>
  55. #include <lwip/pbuf.h>
  56. #include <lwip/sys.h>
  57. #include <lwip/netif.h>
  58. #include <lwip/stats.h>
  59. #include <lwip/tcpip.h>
  60. #include <lwip/dhcp.h>
  61. #include <lwip/netifapi.h>
  62. #include <lwip/inet.h>
  63. #include <netif/etharp.h>
  64. #include <netif/ethernetif.h>
  65. #include <ipc/completion.h>
  66. #if LWIP_IPV6
  67. #include "lwip/ethip6.h"
  68. #endif /* LWIP_IPV6 */
  69. #if LWIP_NETIF_HOSTNAME
  70. #define LWIP_HOSTNAME_LEN 16
  71. #endif
  72. #define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL)
  73. #define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL)
  74. #ifndef RT_LWIP_ETHTHREAD_PRIORITY
  75. #define RT_ETHERNETIF_THREAD_PREORITY 0x90
  76. #else
  77. #define RT_ETHERNETIF_THREAD_PREORITY RT_LWIP_ETHTHREAD_PRIORITY
  78. #endif
  79. #ifndef LWIP_NO_TX_THREAD
  80. /**
  81. * Tx message structure for Ethernet interface
  82. */
  83. struct eth_tx_msg
  84. {
  85. struct netif *netif;
  86. struct pbuf *buf;
  87. struct rt_completion ack;
  88. };
  89. static struct rt_mailbox eth_tx_thread_mb;
  90. static struct rt_thread eth_tx_thread;
  91. #ifndef RT_LWIP_ETHTHREAD_MBOX_SIZE
  92. static char eth_tx_thread_mb_pool[32 * sizeof(rt_ubase_t)];
  93. static char eth_tx_thread_stack[512];
  94. #else
  95. static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * sizeof(rt_ubase_t)];
  96. static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
  97. #endif
  98. #endif
  99. #ifndef LWIP_NO_RX_THREAD
  100. static struct rt_mailbox eth_rx_thread_mb;
  101. static struct rt_thread eth_rx_thread;
  102. #ifndef RT_LWIP_ETHTHREAD_MBOX_SIZE
  103. static char eth_rx_thread_mb_pool[48 * sizeof(rt_ubase_t)];
  104. static char eth_rx_thread_stack[1024];
  105. #else
  106. static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * sizeof(rt_ubase_t)];
  107. static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
  108. #endif
  109. #endif
  110. #ifdef RT_USING_NETDEV
  111. #include "lwip/ip.h"
  112. #include "lwip/init.h"
  113. #include "lwip/netdb.h"
  114. #include <netdev.h>
  115. static int lwip_netdev_set_up(struct netdev *netif)
  116. {
  117. netif_set_up((struct netif *)netif->user_data);
  118. return ERR_OK;
  119. }
  120. static int lwip_netdev_set_down(struct netdev *netif)
  121. {
  122. netif_set_down((struct netif *)netif->user_data);
  123. return ERR_OK;
  124. }
  125. #ifndef ip_2_ip4
  126. #define ip_2_ip4(ipaddr) (ipaddr)
  127. #endif
  128. static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw)
  129. {
  130. if (ip_addr && netmask && gw)
  131. {
  132. netif_set_addr((struct netif *)netif->user_data, ip_2_ip4(ip_addr), ip_2_ip4(netmask), ip_2_ip4(gw));
  133. }
  134. else
  135. {
  136. if (ip_addr)
  137. {
  138. netif_set_ipaddr((struct netif *)netif->user_data, ip_2_ip4(ip_addr));
  139. }
  140. if (netmask)
  141. {
  142. netif_set_netmask((struct netif *)netif->user_data, ip_2_ip4(netmask));
  143. }
  144. if (gw)
  145. {
  146. netif_set_gw((struct netif *)netif->user_data, ip_2_ip4(gw));
  147. }
  148. }
  149. return ERR_OK;
  150. }
  151. #ifdef RT_LWIP_DNS
  152. static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_addr_t *dns_server)
  153. {
  154. #if LWIP_VERSION_MAJOR == 1U /* v1.x */
  155. extern void dns_setserver(u8_t numdns, ip_addr_t *dnsserver);
  156. #else /* >=2.x */
  157. extern void dns_setserver(uint8_t dns_num, const ip_addr_t *dns_server);
  158. #endif /* LWIP_VERSION_MAJOR == 1U */
  159. dns_setserver(dns_num, dns_server);
  160. return ERR_OK;
  161. }
  162. #endif /* RT_LWIP_DNS */
  163. #ifdef RT_LWIP_DHCP
  164. static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
  165. {
  166. netdev_low_level_set_dhcp_status(netif, is_enabled);
  167. if(RT_TRUE == is_enabled)
  168. {
  169. dhcp_start((struct netif *)netif->user_data);
  170. }
  171. else
  172. {
  173. dhcp_stop((struct netif *)netif->user_data);
  174. }
  175. return ERR_OK;
  176. }
  177. #endif /* RT_LWIP_DHCP */
  178. #ifdef RT_USING_FINSH
  179. #ifdef RT_LWIP_USING_PING
  180. extern int lwip_ping_recv(int s, int *ttl);
  181. extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size);
  182. int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len,
  183. uint32_t timeout, struct netdev_ping_resp *ping_resp, rt_bool_t isbind)
  184. {
  185. int s, ttl, recv_len, result = 0;
  186. int elapsed_time;
  187. rt_tick_t recv_start_tick;
  188. #if LWIP_VERSION_MAJOR == 1U /* v1.x */
  189. int recv_timeout = timeout;
  190. #else /* >= v2.x */
  191. struct timeval recv_timeout = { timeout / 1000UL, timeout % 1000UL * 1000 };
  192. #endif
  193. ip_addr_t target_addr;
  194. struct addrinfo hint, *res = RT_NULL;
  195. struct sockaddr_in *h = RT_NULL;
  196. struct in_addr ina;
  197. struct sockaddr_in local;
  198. RT_ASSERT(netif);
  199. RT_ASSERT(host);
  200. RT_ASSERT(ping_resp);
  201. rt_memset(&hint, 0x00, sizeof(hint));
  202. /* convert URL to IP */
  203. if (lwip_getaddrinfo(host, RT_NULL, &hint, &res) != 0)
  204. {
  205. return -RT_ERROR;
  206. }
  207. SMEMCPY(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
  208. SMEMCPY(&ina, &h->sin_addr, sizeof(ina));
  209. lwip_freeaddrinfo(res);
  210. if (inet_aton(inet_ntoa(ina), &target_addr) == 0)
  211. {
  212. return -RT_ERROR;
  213. }
  214. SMEMCPY(&(ping_resp->ip_addr), &target_addr, sizeof(ip_addr_t));
  215. /* new a socket */
  216. if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
  217. {
  218. return -RT_ERROR;
  219. }
  220. local.sin_len = sizeof(local);
  221. local.sin_family = AF_INET;
  222. local.sin_port = 0;
  223. #ifndef NETDEV_USING_IPV6
  224. local.sin_addr.s_addr = (netif->ip_addr.addr);
  225. #else
  226. local.sin_addr.s_addr = (netif->ip_addr.u_addr.ip4.addr);
  227. #endif
  228. if (isbind) {
  229. lwip_bind(s, (struct sockaddr *)&local, sizeof(struct sockaddr_in));
  230. }
  231. lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout));
  232. if (lwip_ping_send(s, &target_addr, data_len) == ERR_OK)
  233. {
  234. recv_start_tick = rt_tick_get();
  235. if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0)
  236. {
  237. elapsed_time = (rt_tick_get() - recv_start_tick) * 1000UL / RT_TICK_PER_SECOND;
  238. ping_resp->data_len = recv_len;
  239. ping_resp->ttl = ttl;
  240. ping_resp->ticks = elapsed_time;
  241. }
  242. else
  243. {
  244. result = -RT_ETIMEOUT;
  245. goto __exit;
  246. }
  247. }
  248. else
  249. {
  250. result = -RT_ETIMEOUT;
  251. goto __exit;
  252. }
  253. __exit:
  254. lwip_close(s);
  255. return result;
  256. }
  257. #endif /* RT_LWIP_USING_PING */
  258. #if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
  259. void lwip_netdev_netstat(struct netdev *netif)
  260. {
  261. extern void list_tcps(void);
  262. extern void list_udps(void);
  263. #ifdef RT_LWIP_TCP
  264. list_tcps();
  265. #endif
  266. #ifdef RT_LWIP_UDP
  267. list_udps();
  268. #endif
  269. }
  270. #endif /* RT_LWIP_TCP || RT_LWIP_UDP */
  271. #endif /* RT_USING_FINSH */
  272. static int lwip_netdev_set_default(struct netdev *netif)
  273. {
  274. netif_set_default((struct netif *)netif->user_data);
  275. return ERR_OK;
  276. }
  277. const struct netdev_ops lwip_netdev_ops =
  278. {
  279. lwip_netdev_set_up,
  280. lwip_netdev_set_down,
  281. lwip_netdev_set_addr_info,
  282. #ifdef RT_LWIP_DNS
  283. lwip_netdev_set_dns_server,
  284. #else
  285. NULL,
  286. #endif /* RT_LWIP_DNS */
  287. #ifdef RT_LWIP_DHCP
  288. lwip_netdev_set_dhcp,
  289. #else
  290. NULL,
  291. #endif /* RT_LWIP_DHCP */
  292. #ifdef RT_USING_FINSH
  293. #ifdef RT_LWIP_USING_PING
  294. lwip_netdev_ping,
  295. #else
  296. NULL,
  297. #endif /* RT_LWIP_USING_PING */
  298. #if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
  299. lwip_netdev_netstat,
  300. #endif /* RT_LWIP_TCP || RT_LWIP_UDP */
  301. #endif /* RT_USING_FINSH */
  302. lwip_netdev_set_default,
  303. };
  304. /* synchronize lwIP network interface device and network interface device flags */
  305. static int netdev_flags_sync(struct netif *lwip_netif)
  306. {
  307. struct netdev *netdev = NULL;
  308. RT_ASSERT(lwip_netif);
  309. netdev = netdev_get_by_name(lwip_netif->name);
  310. if (netdev == RT_NULL)
  311. {
  312. return -ERR_IF;
  313. }
  314. netdev->mtu = lwip_netif->mtu;
  315. /* the macro definition is different from lwip-1.4.1 and lwip-2.x.x about 'flags'. */
  316. if(lwip_netif->flags & NETIF_FLAG_BROADCAST)
  317. {
  318. netdev->flags |= NETDEV_FLAG_BROADCAST;
  319. }
  320. if(lwip_netif->flags & NETIF_FLAG_ETHARP)
  321. {
  322. netdev->flags |= NETDEV_FLAG_ETHARP;
  323. }
  324. if(lwip_netif->flags & NETIF_FLAG_IGMP)
  325. {
  326. netdev->flags |= NETDEV_FLAG_IGMP;
  327. }
  328. #if LWIP_VERSION_MAJOR >= 2U /* >= v2.x */
  329. if(lwip_netif->flags & NETIF_FLAG_MLD6)
  330. {
  331. netdev->flags |= NETDEV_FLAG_MLD6;
  332. }
  333. #endif /* LWIP_VERSION_MAJOR >= 2U */
  334. #if LWIP_DHCP
  335. netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
  336. #else
  337. netdev_low_level_set_dhcp_status(netdev, RT_FALSE);
  338. #endif
  339. return ERR_OK;
  340. }
  341. static int netdev_add(struct netif *lwip_netif)
  342. {
  343. int result = 0;
  344. struct netdev *netdev = RT_NULL;
  345. char name[NETIF_NAMESIZE] = {0};
  346. RT_ASSERT(lwip_netif);
  347. netdev = (struct netdev *)rt_calloc(1, sizeof(struct netdev));
  348. if (netdev == RT_NULL)
  349. {
  350. return -ERR_IF;
  351. }
  352. #ifdef SAL_USING_LWIP
  353. extern int sal_lwip_netdev_set_pf_info(struct netdev *netdev);
  354. /* set the lwIP network interface device protocol family information */
  355. sal_lwip_netdev_set_pf_info(netdev);
  356. #endif /* SAL_USING_LWIP */
  357. rt_strncpy(name, lwip_netif->name, NETIF_NAMESIZE);
  358. result = netdev_register(netdev, name, (void *)lwip_netif);
  359. /* Update netdev info after registered */
  360. netdev_flags_sync(lwip_netif);
  361. netdev->ops = &lwip_netdev_ops;
  362. netdev->hwaddr_len = lwip_netif->hwaddr_len;
  363. SMEMCPY(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
  364. netdev->ip_addr = lwip_netif->ip_addr;
  365. netdev->gw = lwip_netif->gw;
  366. netdev->netmask = lwip_netif->netmask;
  367. return result;
  368. }
  369. static void netdev_del(struct netif *lwip_netif)
  370. {
  371. char name[NETIF_NAMESIZE];
  372. struct netdev *netdev;
  373. RT_ASSERT(lwip_netif);
  374. rt_strncpy(name, lwip_netif->name, NETIF_NAMESIZE);
  375. netdev = netdev_get_by_name(name);
  376. netdev_unregister(netdev);
  377. rt_free(netdev);
  378. }
  379. #endif /* RT_USING_NETDEV */
  380. static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
  381. {
  382. #ifndef LWIP_NO_TX_THREAD
  383. struct eth_tx_msg msg;
  384. RT_ASSERT(netif != RT_NULL);
  385. /* send a message to eth tx thread */
  386. msg.netif = netif;
  387. msg.buf = p;
  388. rt_completion_init(&msg.ack);
  389. if (rt_mb_send(&eth_tx_thread_mb, (rt_ubase_t) &msg) == RT_EOK)
  390. {
  391. /* waiting for ack */
  392. rt_completion_wait(&msg.ack, RT_WAITING_FOREVER);
  393. }
  394. #else
  395. struct eth_device* enetif;
  396. RT_ASSERT(netif != RT_NULL);
  397. enetif = (struct eth_device*)netif->state;
  398. if (enetif->eth_tx(&(enetif->parent), p) != RT_EOK)
  399. {
  400. return ERR_IF;
  401. }
  402. #endif
  403. return ERR_OK;
  404. }
  405. static err_t eth_netif_device_init(struct netif *netif)
  406. {
  407. struct eth_device *ethif;
  408. ethif = (struct eth_device*)netif->state;
  409. if (ethif != RT_NULL)
  410. {
  411. rt_device_t device;
  412. #ifdef RT_USING_NETDEV
  413. /* network interface device register */
  414. netdev_add(netif);
  415. #endif /* RT_USING_NETDEV */
  416. /* get device object */
  417. device = (rt_device_t) ethif;
  418. if (rt_device_init(device) != RT_EOK)
  419. {
  420. return ERR_IF;
  421. }
  422. if (rt_device_open(device, RT_DEVICE_FLAG_RDWR) != RT_EOK)
  423. {
  424. return ERR_IF;
  425. }
  426. /* copy device flags to netif flags */
  427. netif->flags = (ethif->flags & 0xff);
  428. netif->mtu = ETHERNET_MTU;
  429. /* set output */
  430. netif->output = etharp_output;
  431. #if LWIP_IPV6
  432. netif->output_ip6 = ethip6_output;
  433. netif->ip6_autoconfig_enabled = 1;
  434. netif_create_ip6_linklocal_address(netif, 1);
  435. #if LWIP_IPV6_MLD
  436. netif->flags |= NETIF_FLAG_MLD6;
  437. /*
  438. * For hardware/netifs that implement MAC filtering.
  439. * All-nodes link-local is handled by default, so we must let the hardware know
  440. * to allow multicast packets in.
  441. * Should set mld_mac_filter previously. */
  442. if (netif->mld_mac_filter != NULL)
  443. {
  444. ip6_addr_t ip6_allnodes_ll;
  445. ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
  446. netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
  447. }
  448. #endif /* LWIP_IPV6_MLD */
  449. #endif /* LWIP_IPV6 */
  450. /* set default netif */
  451. if (netif_default == RT_NULL)
  452. netif_set_default(netif);
  453. /* set interface up */
  454. netif_set_up(netif);
  455. #if LWIP_DHCP
  456. /* if this interface uses DHCP, start the DHCP client */
  457. dhcp_start(netif);
  458. #endif
  459. if (ethif->flags & ETHIF_LINK_PHYUP)
  460. {
  461. /* set link_up for this netif */
  462. netif_set_link_up(netif);
  463. }
  464. #ifdef RT_USING_NETDEV
  465. /* network interface device flags synchronize */
  466. netdev_flags_sync(netif);
  467. #endif /* RT_USING_NETDEV */
  468. return ERR_OK;
  469. }
  470. return ERR_IF;
  471. }
  472. /* Keep old drivers compatible in RT-Thread */
  473. rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flags)
  474. {
  475. struct netif* netif;
  476. #if LWIP_NETIF_HOSTNAME
  477. char *hostname = RT_NULL;
  478. netif = (struct netif*) rt_calloc (1, sizeof(struct netif) + LWIP_HOSTNAME_LEN);
  479. #else
  480. netif = (struct netif*) rt_calloc (1, sizeof(struct netif));
  481. #endif
  482. if (netif == RT_NULL)
  483. {
  484. rt_kprintf("malloc netif failed\n");
  485. return -RT_ERROR;
  486. }
  487. rt_spin_lock_init(&(dev->spinlock));
  488. /* set netif */
  489. dev->netif = netif;
  490. dev->flags = flags;
  491. /* link changed status of device */
  492. dev->link_changed = 0x00;
  493. /* avoid send the same mail to mailbox */
  494. dev->rx_notice = 0x00;
  495. dev->parent.type = RT_Device_Class_NetIf;
  496. /* register to RT-Thread device manager */
  497. rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
  498. /* set name */
  499. rt_strncpy(netif->name, name, NETIF_NAMESIZE);
  500. /* set hw address to 6 */
  501. netif->hwaddr_len = 6;
  502. /* maximum transfer unit */
  503. netif->mtu = ETHERNET_MTU;
  504. /* set linkoutput */
  505. netif->linkoutput = ethernetif_linkoutput;
  506. /* get hardware MAC address */
  507. rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
  508. #if LWIP_NETIF_HOSTNAME
  509. /* Initialize interface hostname */
  510. hostname = (char *)netif + sizeof(struct netif);
  511. rt_sprintf(hostname, "rtthread_%02x%02x", name[0], name[1]);
  512. netif->hostname = hostname;
  513. #endif /* LWIP_NETIF_HOSTNAME */
  514. /* if tcp thread has been started up, we add this netif to the system */
  515. if (rt_thread_find("tcpip") != RT_NULL)
  516. {
  517. #if LWIP_VERSION_MAJOR == 1U /* v1.x */
  518. struct ip_addr ipaddr, netmask, gw;
  519. #else /* >= v2.x */
  520. ip4_addr_t ipaddr, netmask, gw;
  521. #endif /* LWIP_VERSION_MAJOR == 1U */
  522. #if !LWIP_DHCP
  523. ipaddr.addr = inet_addr(RT_LWIP_IPADDR);
  524. gw.addr = inet_addr(RT_LWIP_GWADDR);
  525. netmask.addr = inet_addr(RT_LWIP_MSKADDR);
  526. #else
  527. IP4_ADDR(&ipaddr, 0, 0, 0, 0);
  528. IP4_ADDR(&gw, 0, 0, 0, 0);
  529. IP4_ADDR(&netmask, 0, 0, 0, 0);
  530. #endif
  531. netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, eth_netif_device_init, tcpip_input);
  532. }
  533. return RT_EOK;
  534. }
  535. rt_err_t eth_device_init(struct eth_device * dev, const char *name)
  536. {
  537. rt_uint16_t flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
  538. #if LWIP_IGMP
  539. /* IGMP support */
  540. flags |= NETIF_FLAG_IGMP;
  541. #endif
  542. return eth_device_init_with_flag(dev, name, flags);
  543. }
  544. void eth_device_deinit(struct eth_device *dev)
  545. {
  546. struct netif* netif = dev->netif;
  547. #if LWIP_DHCP
  548. dhcp_stop(netif);
  549. dhcp_cleanup(netif);
  550. #endif
  551. netif_set_down(netif);
  552. netif_remove(netif);
  553. #ifdef RT_USING_NETDEV
  554. netdev_del(netif);
  555. #endif
  556. rt_device_close(&(dev->parent));
  557. rt_device_unregister(&(dev->parent));
  558. rt_free(netif);
  559. }
  560. #ifdef SAL_USING_AF_UNIX /* create loopback netdev */
  561. static err_t af_unix_eth_netif_device_init(struct netif *netif)
  562. {
  563. struct eth_device *ethif;
  564. ethif = (struct eth_device*)netif->state;
  565. if (ethif != RT_NULL)
  566. {
  567. rt_device_t device;
  568. #ifdef RT_USING_NETDEV
  569. /* network interface device register */
  570. netdev_add(netif);
  571. #endif /* RT_USING_NETDEV */
  572. /* get device object */
  573. device = (rt_device_t) ethif;
  574. if (rt_device_init(device) != RT_EOK)
  575. {
  576. return ERR_IF;
  577. }
  578. if (rt_device_open(device, RT_DEVICE_FLAG_RDWR) != RT_EOK)
  579. {
  580. return ERR_IF;
  581. }
  582. /* copy device flags to netif flags */
  583. netif->flags = (ethif->flags & 0xff);
  584. netif->mtu = ETHERNET_MTU;
  585. /* set output */
  586. netif->output = etharp_output;
  587. #if LWIP_IPV6
  588. netif->output_ip6 = ethip6_output;
  589. netif->ip6_autoconfig_enabled = 1;
  590. netif_create_ip6_linklocal_address(netif, 1);
  591. #if LWIP_IPV6_MLD
  592. netif->flags |= NETIF_FLAG_MLD6;
  593. /*
  594. * For hardware/netifs that implement MAC filtering.
  595. * All-nodes link-local is handled by default, so we must let the hardware know
  596. * to allow multicast packets in.
  597. * Should set mld_mac_filter previously. */
  598. if (netif->mld_mac_filter != NULL)
  599. {
  600. ip6_addr_t ip6_allnodes_ll;
  601. ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
  602. netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
  603. }
  604. #endif /* LWIP_IPV6_MLD */
  605. #endif /* LWIP_IPV6 */
  606. /* set default netif */
  607. if (netif_default == RT_NULL)
  608. netif_set_default(netif);
  609. /* set interface up */
  610. netif_set_up(netif);
  611. if (ethif->flags & ETHIF_LINK_PHYUP)
  612. {
  613. /* set link_up for this netif */
  614. netif_set_link_up(netif);
  615. }
  616. #ifdef RT_USING_NETDEV
  617. /* network interface device flags synchronize */
  618. netdev_flags_sync(netif);
  619. #endif /* RT_USING_NETDEV */
  620. return ERR_OK;
  621. }
  622. return ERR_IF;
  623. }
  624. /* Keep old drivers compatible in RT-Thread */
  625. rt_err_t af_unix_eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flags)
  626. {
  627. struct netif* netif;
  628. #if LWIP_NETIF_HOSTNAME
  629. char *hostname = RT_NULL;
  630. netif = (struct netif*) rt_calloc (1, sizeof(struct netif) + LWIP_HOSTNAME_LEN);
  631. #else
  632. netif = (struct netif*) rt_calloc (1, sizeof(struct netif));
  633. #endif
  634. if (netif == RT_NULL)
  635. {
  636. rt_kprintf("malloc netif failed\n");
  637. return -RT_ERROR;
  638. }
  639. /* set netif */
  640. dev->netif = netif;
  641. dev->flags = flags;
  642. /* link changed status of device */
  643. dev->link_changed = 0x00;
  644. /* avoid send the same mail to mailbox */
  645. dev->rx_notice = 0x00;
  646. dev->parent.type = RT_Device_Class_NetIf;
  647. /* register to RT-Thread device manager */
  648. rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
  649. /* set name */
  650. netif->name[0] = name[0];
  651. netif->name[1] = name[1];
  652. /* set hw address to 6 */
  653. netif->hwaddr_len = 6;
  654. /* maximum transfer unit */
  655. netif->mtu = ETHERNET_MTU;
  656. /* set linkoutput */
  657. netif->linkoutput = ethernetif_linkoutput;
  658. /* get hardware MAC address */
  659. rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
  660. #if LWIP_NETIF_HOSTNAME
  661. /* Initialize interface hostname */
  662. hostname = (char *)netif + sizeof(struct netif);
  663. rt_sprintf(hostname, "rtthread_%02x%02x", name[0], name[1]);
  664. netif->hostname = hostname;
  665. #endif /* LWIP_NETIF_HOSTNAME */
  666. /* if tcp thread has been started up, we add this netif to the system */
  667. if (rt_thread_find("tcpip") != RT_NULL)
  668. {
  669. #if LWIP_VERSION_MAJOR == 1U /* v1.x */
  670. struct ip_addr ipaddr, netmask, gw;
  671. #else /* >= v2.x */
  672. ip4_addr_t ipaddr, netmask, gw;
  673. #endif /* LWIP_VERSION_MAJOR == 1U */
  674. ipaddr.addr = inet_addr("127.0.0.1");
  675. gw.addr = inet_addr("255.0.0.0");
  676. netmask.addr = inet_addr("127.0.0.1");
  677. netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, af_unix_eth_netif_device_init, tcpip_input);
  678. }
  679. return RT_EOK;
  680. }
  681. rt_err_t af_unix_eth_device_init(struct eth_device * dev, const char *name)
  682. {
  683. rt_uint16_t flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
  684. #if LWIP_IGMP
  685. /* IGMP support */
  686. flags |= NETIF_FLAG_IGMP;
  687. #endif
  688. return af_unix_eth_device_init_with_flag(dev, name, flags);
  689. }
  690. #endif /* SAL_USING_AF_UNIX */
  691. #ifndef LWIP_NO_RX_THREAD
  692. rt_err_t eth_device_ready(struct eth_device* dev)
  693. {
  694. if (dev->netif)
  695. {
  696. if(dev->rx_notice == RT_FALSE)
  697. {
  698. dev->rx_notice = RT_TRUE;
  699. return rt_mb_send(&eth_rx_thread_mb, (rt_ubase_t)dev);
  700. }
  701. else
  702. return RT_EOK;
  703. /* post message to Ethernet thread */
  704. }
  705. else
  706. return -RT_ERROR; /* netif is not initialized yet, just return. */
  707. }
  708. rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up)
  709. {
  710. rt_base_t level;
  711. RT_ASSERT(dev != RT_NULL);
  712. level = rt_spin_lock_irqsave(&(dev->spinlock));
  713. dev->link_changed = 0x01;
  714. if (up == RT_TRUE)
  715. dev->link_status = 0x01;
  716. else
  717. dev->link_status = 0x00;
  718. rt_spin_unlock_irqrestore(&(dev->spinlock), level);
  719. /* post message to ethernet thread */
  720. return rt_mb_send(&eth_rx_thread_mb, (rt_ubase_t)dev);
  721. }
  722. #else
  723. /* NOTE: please not use it in interrupt when no RxThread exist */
  724. rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up)
  725. {
  726. if (up == RT_TRUE)
  727. netifapi_netif_set_link_up(dev->netif);
  728. else
  729. netifapi_netif_set_link_down(dev->netif);
  730. return RT_EOK;
  731. }
  732. #endif
  733. #ifndef LWIP_NO_TX_THREAD
  734. /* Ethernet Tx Thread */
  735. static void eth_tx_thread_entry(void* parameter)
  736. {
  737. struct eth_tx_msg* msg;
  738. while (1)
  739. {
  740. if (rt_mb_recv(&eth_tx_thread_mb, (rt_ubase_t *)&msg, RT_WAITING_FOREVER) == RT_EOK)
  741. {
  742. struct eth_device* enetif;
  743. RT_ASSERT(msg->netif != RT_NULL);
  744. RT_ASSERT(msg->buf != RT_NULL);
  745. enetif = (struct eth_device*)msg->netif->state;
  746. if (enetif != RT_NULL)
  747. {
  748. /* call driver's interface */
  749. if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK)
  750. {
  751. /* transmit eth packet failed */
  752. }
  753. }
  754. /* send ACK */
  755. rt_completion_done(&msg->ack);
  756. }
  757. }
  758. }
  759. #endif
  760. #ifndef LWIP_NO_RX_THREAD
  761. /* Ethernet Rx Thread */
  762. static void eth_rx_thread_entry(void* parameter)
  763. {
  764. struct eth_device* device;
  765. while (1)
  766. {
  767. if (rt_mb_recv(&eth_rx_thread_mb, (rt_ubase_t *)&device, RT_WAITING_FOREVER) == RT_EOK)
  768. {
  769. rt_base_t level;
  770. struct pbuf *p;
  771. /* check link status */
  772. if (device->link_changed)
  773. {
  774. int status;
  775. level = rt_spin_lock_irqsave(&(device->spinlock));
  776. status = device->link_status;
  777. device->link_changed = 0x00;
  778. rt_spin_unlock_irqrestore(&(device->spinlock), level);
  779. if (status)
  780. netifapi_netif_set_link_up(device->netif);
  781. else
  782. netifapi_netif_set_link_down(device->netif);
  783. }
  784. level = rt_spin_lock_irqsave(&(device->spinlock));
  785. /* 'rx_notice' will be modify in the interrupt or here */
  786. device->rx_notice = RT_FALSE;
  787. rt_spin_unlock_irqrestore(&(device->spinlock), level);
  788. /* receive all of buffer */
  789. while (1)
  790. {
  791. if(device->eth_rx == RT_NULL) break;
  792. p = device->eth_rx(&(device->parent));
  793. if (p != RT_NULL)
  794. {
  795. /* notify to upper layer */
  796. if( device->netif->input(p, device->netif) != ERR_OK )
  797. {
  798. LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Input error\n"));
  799. pbuf_free(p);
  800. p = NULL;
  801. }
  802. }
  803. else break;
  804. }
  805. }
  806. else
  807. {
  808. LWIP_ASSERT("Should not happen!\n",0);
  809. }
  810. }
  811. }
  812. #endif
  813. /* this function does not need,
  814. * use eth_system_device_init_private()
  815. * call by lwip_system_init().
  816. */
  817. int eth_system_device_init(void)
  818. {
  819. return 0;
  820. }
  821. int eth_system_device_init_private(void)
  822. {
  823. rt_err_t result = RT_EOK;
  824. /* initialize Rx thread. */
  825. #ifndef LWIP_NO_RX_THREAD
  826. /* initialize mailbox and create Ethernet Rx thread */
  827. result = rt_mb_init(&eth_rx_thread_mb, "erxmb",
  828. &eth_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/sizeof(rt_ubase_t),
  829. RT_IPC_FLAG_FIFO);
  830. RT_ASSERT(result == RT_EOK);
  831. result = rt_thread_init(&eth_rx_thread, "erx", eth_rx_thread_entry, RT_NULL,
  832. &eth_rx_thread_stack[0], sizeof(eth_rx_thread_stack),
  833. RT_ETHERNETIF_THREAD_PREORITY, 16);
  834. RT_ASSERT(result == RT_EOK);
  835. result = rt_thread_startup(&eth_rx_thread);
  836. RT_ASSERT(result == RT_EOK);
  837. #endif
  838. /* initialize Tx thread */
  839. #ifndef LWIP_NO_TX_THREAD
  840. /* initialize mailbox and create Ethernet Tx thread */
  841. result = rt_mb_init(&eth_tx_thread_mb, "etxmb",
  842. &eth_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/sizeof(rt_ubase_t),
  843. RT_IPC_FLAG_FIFO);
  844. RT_ASSERT(result == RT_EOK);
  845. result = rt_thread_init(&eth_tx_thread, "etx", eth_tx_thread_entry, RT_NULL,
  846. &eth_tx_thread_stack[0], sizeof(eth_tx_thread_stack),
  847. RT_ETHERNETIF_THREAD_PREORITY, 16);
  848. RT_ASSERT(result == RT_EOK);
  849. result = rt_thread_startup(&eth_tx_thread);
  850. RT_ASSERT(result == RT_EOK);
  851. #endif
  852. return (int)result;
  853. }
  854. void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr)
  855. {
  856. #if LWIP_VERSION_MAJOR == 1U /* v1.x */
  857. struct ip_addr *ip;
  858. struct ip_addr addr;
  859. #else /* >= v2.x */
  860. ip4_addr_t *ip;
  861. ip4_addr_t addr;
  862. #endif /* LWIP_VERSION_MAJOR == 1U */
  863. struct netif * netif = netif_list;
  864. if(strlen(netif_name) > sizeof(netif->name))
  865. {
  866. rt_kprintf("network interface name too long!\r\n");
  867. return;
  868. }
  869. while(netif != RT_NULL)
  870. {
  871. if(strncmp(netif_name, netif->name, sizeof(netif->name)) == 0)
  872. break;
  873. netif = netif->next;
  874. if( netif == RT_NULL )
  875. {
  876. rt_kprintf("network interface: %s not found!\r\n", netif_name);
  877. return;
  878. }
  879. }
  880. #if LWIP_VERSION_MAJOR == 1U /* v1.x */
  881. ip = (struct ip_addr *)&addr;
  882. #else /* >= v2.x */
  883. ip = (ip4_addr_t *)&addr;
  884. #endif /* LWIP_VERSION_MAJOR == 1U */
  885. /* set ip address */
  886. if ((ip_addr != RT_NULL) && inet_aton(ip_addr, &addr))
  887. {
  888. netif_set_ipaddr(netif, ip);
  889. }
  890. /* set gateway address */
  891. if ((gw_addr != RT_NULL) && inet_aton(gw_addr, &addr))
  892. {
  893. netif_set_gw(netif, ip);
  894. }
  895. /* set netmask address */
  896. if ((nm_addr != RT_NULL) && inet_aton(nm_addr, &addr))
  897. {
  898. netif_set_netmask(netif, ip);
  899. }
  900. }
  901. #ifdef RT_USING_FINSH
  902. #include <finsh.h>
  903. FINSH_FUNCTION_EXPORT(set_if, set network interface address);
  904. #if LWIP_DNS
  905. #include <lwip/dns.h>
  906. void set_dns(uint8_t dns_num, char* dns_server)
  907. {
  908. ip_addr_t addr;
  909. if ((dns_server != RT_NULL) && ipaddr_aton(dns_server, &addr))
  910. {
  911. dns_setserver(dns_num, &addr);
  912. }
  913. }
  914. FINSH_FUNCTION_EXPORT(set_dns, set DNS server address);
  915. #endif
  916. void list_if(void)
  917. {
  918. rt_uint8_t index;
  919. struct netif * netif;
  920. rt_enter_critical();
  921. netif = netif_list;
  922. while( netif != RT_NULL )
  923. {
  924. rt_kprintf("network interface: %c%c%s\n",
  925. netif->name[0],
  926. netif->name[1],
  927. (netif == netif_default)?" (Default)":"");
  928. rt_kprintf("MTU: %d\n", netif->mtu);
  929. rt_kprintf("MAC: ");
  930. for (index = 0; index < netif->hwaddr_len; index ++)
  931. rt_kprintf("%02x ", netif->hwaddr[index]);
  932. rt_kprintf("\nFLAGS:");
  933. if (netif->flags & NETIF_FLAG_UP) rt_kprintf(" UP");
  934. else rt_kprintf(" DOWN");
  935. if (netif->flags & NETIF_FLAG_LINK_UP) rt_kprintf(" LINK_UP");
  936. else rt_kprintf(" LINK_DOWN");
  937. if (netif->flags & NETIF_FLAG_ETHARP) rt_kprintf(" ETHARP");
  938. if (netif->flags & NETIF_FLAG_BROADCAST) rt_kprintf(" BROADCAST");
  939. if (netif->flags & NETIF_FLAG_IGMP) rt_kprintf(" IGMP");
  940. rt_kprintf("\n");
  941. rt_kprintf("ip address: %s\n", ipaddr_ntoa(&(netif->ip_addr)));
  942. rt_kprintf("gw address: %s\n", ipaddr_ntoa(&(netif->gw)));
  943. rt_kprintf("net mask : %s\n", ipaddr_ntoa(&(netif->netmask)));
  944. #if LWIP_IPV6
  945. {
  946. ip6_addr_t *addr;
  947. int addr_state;
  948. int i;
  949. addr = (ip6_addr_t *)&netif->ip6_addr[0];
  950. addr_state = netif->ip6_addr_state[0];
  951. rt_kprintf("\nipv6 link-local: %s state:%02X %s\n", ip6addr_ntoa(addr),
  952. addr_state, ip6_addr_isvalid(addr_state)?"VALID":"INVALID");
  953. for(i=1; i<LWIP_IPV6_NUM_ADDRESSES; i++)
  954. {
  955. addr = (ip6_addr_t *)&netif->ip6_addr[i];
  956. addr_state = netif->ip6_addr_state[i];
  957. rt_kprintf("ipv6[%d] address: %s state:%02X %s\n", i, ip6addr_ntoa(addr),
  958. addr_state, ip6_addr_isvalid(addr_state)?"VALID":"INVALID");
  959. }
  960. }
  961. rt_kprintf("\r\n");
  962. #endif /* LWIP_IPV6 */
  963. netif = netif->next;
  964. }
  965. #if LWIP_DNS
  966. {
  967. #if LWIP_VERSION_MAJOR == 1U /* v1.x */
  968. struct ip_addr ip_addr;
  969. for(index=0; index<DNS_MAX_SERVERS; index++)
  970. {
  971. ip_addr = dns_getserver(index);
  972. rt_kprintf("dns server #%d: %s\n", index, ipaddr_ntoa(&(ip_addr)));
  973. }
  974. #else /* >= v2.x */
  975. const ip_addr_t *ip_addr;
  976. for(index=0; index<DNS_MAX_SERVERS; index++)
  977. {
  978. ip_addr = dns_getserver(index);
  979. rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(ip_addr));
  980. }
  981. #endif /* LWIP_VERSION_MAJOR == 1U */
  982. }
  983. #endif /**< #if LWIP_DNS */
  984. rt_exit_critical();
  985. }
  986. FINSH_FUNCTION_EXPORT(list_if, list network interface information);
  987. #if LWIP_TCP
  988. #include <lwip/tcp.h>
  989. #if LWIP_VERSION_MAJOR == 1U /* v1.x */
  990. #include <lwip/tcp_impl.h>
  991. #else /* >= v2.x */
  992. #include <lwip/priv/tcp_priv.h>
  993. #endif /* LWIP_VERSION_MAJOR == 1U */
  994. void list_tcps(void)
  995. {
  996. rt_uint32_t num = 0;
  997. struct tcp_pcb *pcb;
  998. char local_ip_str[16];
  999. char remote_ip_str[16];
  1000. extern struct tcp_pcb *tcp_active_pcbs;
  1001. extern union tcp_listen_pcbs_t tcp_listen_pcbs;
  1002. extern struct tcp_pcb *tcp_tw_pcbs;
  1003. rt_enter_critical();
  1004. rt_kprintf("Active PCB states:\n");
  1005. for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
  1006. {
  1007. strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip)));
  1008. strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip)));
  1009. rt_kprintf("#%d %s:%d <==> %s:%d snd_nxt 0x%08X rcv_nxt 0x%08X ",
  1010. num++,
  1011. local_ip_str,
  1012. pcb->local_port,
  1013. remote_ip_str,
  1014. pcb->remote_port,
  1015. pcb->snd_nxt,
  1016. pcb->rcv_nxt);
  1017. rt_kprintf("state: %s\n", tcp_debug_state_str(pcb->state));
  1018. }
  1019. rt_kprintf("Listen PCB states:\n");
  1020. num = 0;
  1021. for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next)
  1022. {
  1023. rt_kprintf("#%d local port %d ", num++, pcb->local_port);
  1024. rt_kprintf("state: %s\n", tcp_debug_state_str(pcb->state));
  1025. }
  1026. rt_kprintf("TIME-WAIT PCB states:\n");
  1027. num = 0;
  1028. for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next)
  1029. {
  1030. strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip)));
  1031. strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip)));
  1032. rt_kprintf("#%d %s:%d <==> %s:%d snd_nxt 0x%08X rcv_nxt 0x%08X ",
  1033. num++,
  1034. local_ip_str,
  1035. pcb->local_port,
  1036. remote_ip_str,
  1037. pcb->remote_port,
  1038. pcb->snd_nxt,
  1039. pcb->rcv_nxt);
  1040. rt_kprintf("state: %s\n", tcp_debug_state_str(pcb->state));
  1041. }
  1042. rt_exit_critical();
  1043. }
  1044. FINSH_FUNCTION_EXPORT(list_tcps, list all of tcp connections);
  1045. #endif /* LWIP_TCP */
  1046. #if LWIP_UDP
  1047. #include "lwip/udp.h"
  1048. void list_udps(void)
  1049. {
  1050. struct udp_pcb *pcb;
  1051. rt_uint32_t num = 0;
  1052. char local_ip_str[16];
  1053. char remote_ip_str[16];
  1054. rt_enter_critical();
  1055. rt_kprintf("Active UDP PCB states:\n");
  1056. for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next)
  1057. {
  1058. strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip)));
  1059. strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip)));
  1060. rt_kprintf("#%d %d %s:%d <==> %s:%d \n",
  1061. num, (int)pcb->flags,
  1062. local_ip_str,
  1063. pcb->local_port,
  1064. remote_ip_str,
  1065. pcb->remote_port);
  1066. num++;
  1067. }
  1068. rt_exit_critical();
  1069. }
  1070. FINSH_FUNCTION_EXPORT(list_udps, list all of udp connections);
  1071. #endif /* LWIP_UDP */
  1072. #endif