netdev.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-03-18 ChenYong First version
  9. * 2025-01-04 Evlers add statistics and more inupt parameters to ping command
  10. */
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <rtthread.h>
  15. #include <rthw.h>
  16. #include <netdev_ipaddr.h>
  17. #include <netdev.h>
  18. #ifdef RT_USING_SAL
  19. #include <sal_netdb.h>
  20. #include <sal_low_lvl.h>
  21. #endif /* RT_USING_SAL */
  22. #define DBG_TAG "netdev"
  23. #define DBG_LVL DBG_INFO
  24. #include <rtdbg.h>
  25. #if defined(SAL_USING_AF_NETLINK)
  26. #include <route_netlink.h>
  27. #endif
  28. /* The list of network interface device */
  29. struct netdev *netdev_list = RT_NULL;
  30. /* The default network interface device */
  31. struct netdev *netdev_default = RT_NULL;
  32. /* The global network register callback */
  33. static netdev_callback_fn g_netdev_register_callback = RT_NULL;
  34. static netdev_callback_fn g_netdev_default_change_callback = RT_NULL;
  35. static RT_DEFINE_SPINLOCK(_spinlock);
  36. static int netdev_num;
  37. /**
  38. * This function will register network interface device and
  39. * add it to network interface device list.
  40. *
  41. * @param netdev the network interface device object
  42. * @param name the network interface device name
  43. * @param user_data user-specific data
  44. *
  45. * @return 0: registered successfully
  46. * -1: registered failed
  47. */
  48. int netdev_register(struct netdev *netdev, const char *name, void *user_data)
  49. {
  50. rt_uint16_t flags_mask;
  51. rt_uint16_t index;
  52. RT_ASSERT(netdev);
  53. RT_ASSERT(name);
  54. /* clean network interface device */
  55. flags_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP | NETDEV_FLAG_DHCP;
  56. netdev->flags &= ~flags_mask;
  57. ip_addr_set_zero(&(netdev->ip_addr));
  58. ip_addr_set_zero(&(netdev->netmask));
  59. ip_addr_set_zero(&(netdev->gw));
  60. IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
  61. IP_SET_TYPE_VAL(netdev->netmask, IPADDR_TYPE_V4);
  62. IP_SET_TYPE_VAL(netdev->gw, IPADDR_TYPE_V4);
  63. #if NETDEV_IPV6
  64. for (index = 0; index < NETDEV_IPV6_NUM_ADDRESSES; index++)
  65. {
  66. ip_addr_set_zero(&(netdev->ip6_addr[index]));
  67. IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V6);
  68. }
  69. #endif /* NETDEV_IPV6 */
  70. for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
  71. {
  72. ip_addr_set_zero(&(netdev->dns_servers[index]));
  73. IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
  74. }
  75. netdev->status_callback = RT_NULL;
  76. netdev->addr_callback = RT_NULL;
  77. if(rt_strlen(name) > RT_NAME_MAX)
  78. {
  79. char netdev_name[RT_NAME_MAX + 1] = {0};
  80. rt_strncpy(netdev_name, name, RT_NAME_MAX);
  81. LOG_E("netdev name[%s] length is so long that have been cut into [%s].", name, netdev_name);
  82. }
  83. /* fill network interface device */
  84. rt_strncpy(netdev->name, name, RT_NAME_MAX);
  85. netdev->user_data = user_data;
  86. /* initialize current network interface device single list */
  87. rt_slist_init(&(netdev->list));
  88. rt_spin_lock(&_spinlock);
  89. if (netdev_list == RT_NULL)
  90. {
  91. netdev_list = netdev;
  92. }
  93. else
  94. {
  95. /* tail insertion */
  96. rt_slist_append(&(netdev_list->list), &(netdev->list));
  97. }
  98. netdev_num++;
  99. netdev->ifindex = netdev_num;
  100. rt_spin_unlock(&_spinlock);
  101. if (netdev_default == RT_NULL)
  102. {
  103. netdev_set_default(netdev_list);
  104. }
  105. /* execute netdev register callback */
  106. if (g_netdev_register_callback)
  107. {
  108. g_netdev_register_callback(netdev, NETDEV_CB_REGISTER);
  109. }
  110. #if defined(SAL_USING_AF_NETLINK)
  111. rtnl_ip_notify(netdev, RTM_NEWLINK);
  112. #endif
  113. return RT_EOK;
  114. }
  115. /**
  116. * This function will unregister network interface device and
  117. * delete it from network interface device list.
  118. *
  119. * @param netdev the network interface device object
  120. *
  121. * @return 0: unregistered successfully
  122. * -1: unregistered failed
  123. */
  124. int netdev_unregister(struct netdev *netdev)
  125. {
  126. rt_slist_t *node = RT_NULL;
  127. struct netdev *cur_netdev = RT_NULL;
  128. RT_ASSERT(netdev);
  129. if (netdev_list == RT_NULL)
  130. {
  131. return -RT_ERROR;
  132. }
  133. rt_spin_lock(&_spinlock);
  134. for (node = &(netdev_list->list); node; node = rt_slist_next(node))
  135. {
  136. cur_netdev = rt_slist_entry(node, struct netdev, list);
  137. if (cur_netdev == netdev)
  138. {
  139. /* find this network interface device in network interface device list */
  140. if (netdev_list == netdev)
  141. {
  142. rt_slist_t *next = rt_slist_next(node);
  143. if (next)
  144. {
  145. netdev_list = rt_slist_entry(next, struct netdev, list);
  146. }
  147. else
  148. {
  149. netdev_list = RT_NULL;
  150. }
  151. }
  152. else
  153. {
  154. rt_slist_remove(&(netdev_list->list), &(cur_netdev->list));
  155. }
  156. if (netdev_default == netdev)
  157. {
  158. netdev_default = RT_NULL;
  159. }
  160. break;
  161. }
  162. }
  163. rt_spin_unlock(&_spinlock);
  164. #if defined(SAL_USING_AF_NETLINK)
  165. rtnl_ip_notify(netdev, RTM_DELLINK);
  166. #endif
  167. if (netdev_default == RT_NULL)
  168. {
  169. netdev_set_default(netdev_list);
  170. }
  171. if (cur_netdev == netdev)
  172. {
  173. #ifdef RT_USING_SAL
  174. extern int sal_netdev_cleanup(struct netdev *netdev);
  175. sal_netdev_cleanup(netdev);
  176. #endif
  177. rt_memset(netdev, 0, sizeof(*netdev));
  178. }
  179. return -RT_ERROR;
  180. }
  181. /**
  182. * This function will set register callback
  183. *
  184. * @param register_callback the network register callback
  185. *
  186. */
  187. void netdev_set_register_callback(netdev_callback_fn register_callback)
  188. {
  189. g_netdev_register_callback = register_callback;
  190. }
  191. /**
  192. * This function will get the first network interface device
  193. * with the flags in network interface device list.
  194. *
  195. * @param flags the network interface device flags
  196. *
  197. * @return != NULL: network interface device object
  198. * NULL: get failed
  199. */
  200. struct netdev *netdev_get_first_by_flags(uint16_t flags)
  201. {
  202. rt_slist_t *node = RT_NULL;
  203. struct netdev *netdev = RT_NULL;
  204. if (netdev_list == RT_NULL)
  205. {
  206. return RT_NULL;
  207. }
  208. rt_spin_lock(&_spinlock);
  209. for (node = &(netdev_list->list); node; node = rt_slist_next(node))
  210. {
  211. netdev = rt_slist_entry(node, struct netdev, list);
  212. if (netdev && (netdev->flags & flags) != 0)
  213. {
  214. rt_spin_unlock(&_spinlock);
  215. return netdev;
  216. }
  217. }
  218. rt_spin_unlock(&_spinlock);
  219. return RT_NULL;
  220. }
  221. /**
  222. * This function will get the first network interface device
  223. * in network interface device list by IP address.
  224. *
  225. * @param ip_addr the network interface device IP address
  226. *
  227. * @return != NULL: network interface device object
  228. * NULL: get failed
  229. */
  230. struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
  231. {
  232. rt_slist_t *node = RT_NULL;
  233. struct netdev *netdev = RT_NULL;
  234. if (netdev_list == RT_NULL)
  235. {
  236. return RT_NULL;
  237. }
  238. rt_spin_lock(&_spinlock);
  239. for (node = &(netdev_list->list); node; node = rt_slist_next(node))
  240. {
  241. netdev = rt_slist_entry(node, struct netdev, list);
  242. if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr))
  243. {
  244. rt_spin_unlock(&_spinlock);
  245. return netdev;
  246. }
  247. }
  248. rt_spin_unlock(&_spinlock);
  249. return RT_NULL;
  250. }
  251. /**
  252. * This function will get network interface device
  253. * in network interface device list by netdev name.
  254. *
  255. * @param name the network interface device name
  256. *
  257. * @return != NULL: network interface device object
  258. * NULL: get failed
  259. */
  260. struct netdev *netdev_get_by_name(const char *name)
  261. {
  262. rt_slist_t *node = RT_NULL;
  263. struct netdev *netdev = RT_NULL;
  264. if (netdev_list == RT_NULL)
  265. {
  266. return RT_NULL;
  267. }
  268. rt_spin_lock(&_spinlock);
  269. for (node = &(netdev_list->list); node; node = rt_slist_next(node))
  270. {
  271. netdev = rt_slist_entry(node, struct netdev, list);
  272. if (netdev && (rt_strncmp(netdev->name, name, rt_strlen(name) < RT_NAME_MAX ? rt_strlen(name) : RT_NAME_MAX) == 0))
  273. {
  274. rt_spin_unlock(&_spinlock);
  275. return netdev;
  276. }
  277. }
  278. rt_spin_unlock(&_spinlock);
  279. return RT_NULL;
  280. }
  281. /**
  282. * This function will get network interface device
  283. * in network interface device list by netdev ifindex.
  284. *
  285. * @param ifindex the ifindex of network interface device
  286. *
  287. * @return != NULL: network interface device object
  288. * NULL: get failed
  289. */
  290. struct netdev *netdev_get_by_ifindex(int ifindex)
  291. {
  292. rt_slist_t *node = RT_NULL;
  293. struct netdev *netdev = RT_NULL;
  294. if (netdev_list == RT_NULL)
  295. {
  296. return RT_NULL;
  297. }
  298. rt_spin_lock(&_spinlock);
  299. for (node = &(netdev_list->list); node; node = rt_slist_next(node))
  300. {
  301. netdev = rt_slist_entry(node, struct netdev, list);
  302. if (netdev && (netdev->ifindex == ifindex))
  303. {
  304. rt_spin_unlock(&_spinlock);
  305. return netdev;
  306. }
  307. }
  308. rt_spin_unlock(&_spinlock);
  309. return RT_NULL;
  310. }
  311. #ifdef RT_USING_SAL
  312. /**
  313. * This function will get the first network interface device
  314. * in network interface device list by protocol family type.
  315. *
  316. * @param family the network interface device protocol family type
  317. *
  318. * @return != NULL: network interface device object
  319. * NULL: get failed
  320. */
  321. struct netdev *netdev_get_by_family(int family)
  322. {
  323. rt_slist_t *node = RT_NULL;
  324. struct netdev *netdev = RT_NULL;
  325. struct sal_proto_family *pf = RT_NULL;
  326. if (netdev_list == RT_NULL)
  327. {
  328. return RT_NULL;
  329. }
  330. rt_spin_lock(&_spinlock);
  331. for (node = &(netdev_list->list); node; node = rt_slist_next(node))
  332. {
  333. netdev = rt_slist_entry(node, struct netdev, list);
  334. pf = (struct sal_proto_family *) netdev->sal_user_data;
  335. if (pf && pf->skt_ops && pf->family == family && netdev_is_up(netdev))
  336. {
  337. rt_spin_unlock(&_spinlock);
  338. return netdev;
  339. }
  340. }
  341. for (node = &(netdev_list->list); node; node = rt_slist_next(node))
  342. {
  343. netdev = rt_slist_entry(node, struct netdev, list);
  344. pf = (struct sal_proto_family *) netdev->sal_user_data;
  345. if (pf && pf->skt_ops && pf->sec_family == family && netdev_is_up(netdev))
  346. {
  347. rt_spin_unlock(&_spinlock);
  348. return netdev;
  349. }
  350. }
  351. rt_spin_unlock(&_spinlock);
  352. return RT_NULL;
  353. }
  354. /**
  355. * This function will get the family type from network interface device
  356. *
  357. * @param netdev network interface device object
  358. *
  359. * @return the network interface device family type
  360. */
  361. int netdev_family_get(struct netdev *netdev)
  362. {
  363. RT_ASSERT(netdev);
  364. return ((struct sal_proto_family *)netdev->sal_user_data)->family;
  365. }
  366. #endif /* RT_USING_SAL */
  367. #if defined(SAL_USING_AF_NETLINK)
  368. int netdev_getnetdev(struct msg_buf *msg, int (*cb)(struct msg_buf *m_buf, struct netdev *nd, int nd_num, int index, int ipvx))
  369. {
  370. struct netdev *cur_nd_list = netdev_list;
  371. struct netdev *nd_node;
  372. int nd_num = 0;
  373. int err = 0;
  374. if (cur_nd_list == RT_NULL)
  375. return 0;
  376. rt_spin_lock(&_spinlock);
  377. nd_num = rt_slist_len(&cur_nd_list->list) + 1;
  378. rt_spin_unlock(&_spinlock);
  379. err = cb(msg, cur_nd_list, nd_num, nd.ifindex, ROUTE_IPV4_TRUE);
  380. if (err < 0)
  381. return err;
  382. rt_spin_lock(&_spinlock);
  383. rt_slist_for_each_entry(nd_node, &(cur_nd_list->list), list)
  384. {
  385. rt_spin_unlock(&_spinlock);
  386. err = cb(msg, nd_node, nd_num, nd.ifindex, ROUTE_IPV4_TRUE);
  387. if (err < 0)
  388. {
  389. return err;
  390. }
  391. rt_spin_lock(&_spinlock);
  392. }
  393. rt_spin_unlock(&_spinlock);
  394. return 0;
  395. }
  396. #endif
  397. /**
  398. * This function will set default network interface device.
  399. *
  400. * @param netdev the network interface device to change
  401. */
  402. void netdev_set_default(struct netdev *netdev)
  403. {
  404. if (netdev && (netdev != netdev_default))
  405. {
  406. netdev_default = netdev;
  407. /* execture the default network interface device in the current network stack */
  408. if (netdev->ops && netdev->ops->set_default)
  409. {
  410. netdev->ops->set_default(netdev);
  411. }
  412. /* execture application netdev default change callback */
  413. if (g_netdev_default_change_callback)
  414. {
  415. g_netdev_default_change_callback(netdev, NETDEV_CB_DEFAULT_CHANGE);
  416. }
  417. LOG_D("Setting default network interface device name(%s) successfully.", netdev->name);
  418. }
  419. }
  420. /**
  421. * This function will set defalut netdev change callback
  422. *
  423. * @param register_callback the network default change callback
  424. *
  425. */
  426. void netdev_set_default_change_callback(netdev_callback_fn register_callback)
  427. {
  428. g_netdev_default_change_callback = register_callback;
  429. }
  430. /**
  431. * This function will enable network interface device .
  432. *
  433. * @param netdev the network interface device to change
  434. *
  435. * @return 0: set status successfully
  436. * -1: set status failed
  437. */
  438. int netdev_set_up(struct netdev *netdev)
  439. {
  440. int err = 0;
  441. RT_ASSERT(netdev);
  442. if (!netdev->ops || !netdev->ops->set_up)
  443. {
  444. LOG_E("The network interface device(%s) not support to set status.", netdev->name);
  445. return -RT_ERROR;
  446. }
  447. /* network interface device status flags check */
  448. if (netdev_is_up(netdev))
  449. {
  450. return RT_EOK;
  451. }
  452. /* execute enable network interface device operations by network interface device driver */
  453. err = netdev->ops->set_up(netdev);
  454. #if defined(SAL_USING_AF_NETLINK)
  455. if (err)
  456. rtnl_ip_notify(netdev, RTM_NEWLINK);
  457. #endif
  458. return err;
  459. }
  460. /**
  461. * This function will disable network interface device.
  462. *
  463. * @param netdev the network interface device to change
  464. *
  465. * @return 0: set status successfully
  466. * -1: set sttaus failed
  467. */
  468. int netdev_set_down(struct netdev *netdev)
  469. {
  470. int err;
  471. RT_ASSERT(netdev);
  472. if (!netdev->ops || !netdev->ops->set_down)
  473. {
  474. LOG_E("The network interface device(%s) not support to set status.", netdev->name);
  475. return -RT_ERROR;
  476. }
  477. /* network interface device status flags check */
  478. if (!netdev_is_up(netdev))
  479. {
  480. return RT_EOK;
  481. }
  482. /* execute disable network interface device operations by network interface driver */
  483. err = netdev->ops->set_down(netdev);
  484. #if defined(SAL_USING_AF_NETLINK)
  485. if (err)
  486. rtnl_ip_notify(netdev, RTM_NEWLINK);
  487. #endif
  488. return err;
  489. }
  490. /**
  491. * This function will control network interface device DHCP capability enable or disable.
  492. *
  493. * @param netdev the network interface device device to change
  494. * @param is_enable the new DHCP status
  495. *
  496. * @return 0: set DHCP status successfully
  497. * -1: set DHCP status failed
  498. */
  499. int netdev_dhcp_enabled(struct netdev *netdev, rt_bool_t is_enabled)
  500. {
  501. RT_ASSERT(netdev);
  502. if (!netdev->ops || !netdev->ops->set_dhcp)
  503. {
  504. LOG_E("The network interface device(%s) not support to set DHCP status.", netdev->name);
  505. return -RT_ERROR;
  506. }
  507. /* network interface device DHCP flags check */
  508. if (netdev_is_dhcp_enabled(netdev) == is_enabled)
  509. {
  510. return RT_EOK;
  511. }
  512. /* execute network interface device DHCP capability control operations */
  513. return netdev->ops->set_dhcp(netdev, is_enabled);
  514. }
  515. /**
  516. * This function will set network interface device IP address.
  517. *
  518. * @param netdev the network interface device to change
  519. * @param ip_addr the new IP address
  520. *
  521. * @return 0: set IP address successfully
  522. * -1: set IP address failed
  523. */
  524. int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
  525. {
  526. int err;
  527. RT_ASSERT(netdev);
  528. RT_ASSERT(ip_addr);
  529. if (!netdev->ops || !netdev->ops->set_addr_info)
  530. {
  531. LOG_E("The network interface device(%s) not support to set IP address.", netdev->name);
  532. return -RT_ERROR;
  533. }
  534. if (netdev_is_dhcp_enabled(netdev))
  535. {
  536. LOG_E("The network interface device(%s) DHCP capability is enable, not support set IP address.", netdev->name);
  537. return -RT_ERROR;
  538. }
  539. /* execute network interface device set IP address operations */
  540. err = netdev->ops->set_addr_info(netdev, (ip_addr_t *)ip_addr, RT_NULL, RT_NULL);
  541. #if defined(SAL_USING_AF_NETLINK)
  542. if (err == 0)
  543. rtnl_ip_notify(netdev, RTM_SETLINK);
  544. #endif
  545. return err;
  546. }
  547. /**
  548. * This function will set network interface device netmask address.
  549. *
  550. * @param netdev the network interface device to change
  551. * @param netmask the new netmask address
  552. *
  553. * @return 0: set netmask address successfully
  554. * -1: set netmask address failed
  555. */
  556. int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
  557. {
  558. RT_ASSERT(netdev);
  559. RT_ASSERT(netmask);
  560. if (!netdev->ops || !netdev->ops->set_addr_info)
  561. {
  562. LOG_E("The network interface device(%s) not support to set netmask address.", netdev->name);
  563. return -RT_ERROR;
  564. }
  565. if (netdev_is_dhcp_enabled(netdev))
  566. {
  567. LOG_E("The network interface device(%s) DHCP capability is enable, not support set netmask address.", netdev->name);
  568. return -RT_ERROR;
  569. }
  570. /* execute network interface device set netmask address operations */
  571. return netdev->ops->set_addr_info(netdev, RT_NULL, (ip_addr_t *)netmask, RT_NULL);
  572. }
  573. /**
  574. * This function will set network interface device gateway address.
  575. *
  576. * @param netdev the network interface device to change
  577. * @param gw the new gateway address
  578. *
  579. * @return 0: set gateway address successfully
  580. * -1: set gateway address failed
  581. */
  582. int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw)
  583. {
  584. RT_ASSERT(netdev);
  585. RT_ASSERT(gw);
  586. if (!netdev->ops || !netdev->ops->set_addr_info)
  587. {
  588. LOG_E("The network interface device(%s) not support to set gateway address.", netdev->name);
  589. return -RT_ERROR;
  590. }
  591. if (netdev_is_dhcp_enabled(netdev))
  592. {
  593. LOG_E("The network interface device(%s) DHCP capability is enable, not support set gateway address.", netdev->name);
  594. return -RT_ERROR;
  595. }
  596. /* execute network interface device set gateway address operations */
  597. return netdev->ops->set_addr_info(netdev, RT_NULL, RT_NULL, (ip_addr_t *)gw);
  598. }
  599. /**
  600. * This function will set network interface device DNS server address.
  601. *
  602. * @param netdev the network interface device to change
  603. * @param dns_num the number of the DNS server
  604. * @param dns_server the new DNS server address
  605. *
  606. * @return 0: set netmask address successfully
  607. * -1: set netmask address failed
  608. */
  609. int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
  610. {
  611. RT_ASSERT(netdev);
  612. RT_ASSERT(dns_server);
  613. if (dns_num >= NETDEV_DNS_SERVERS_NUM)
  614. {
  615. LOG_E("The number of DNS servers(%d) set exceeds the maximum number(%d).", dns_num + 1, NETDEV_DNS_SERVERS_NUM);
  616. return -RT_ERROR;
  617. }
  618. if (!netdev->ops || !netdev->ops->set_dns_server)
  619. {
  620. LOG_E("The network interface device(%s) not support to set DNS server address.", netdev->name);
  621. return -RT_ERROR;
  622. }
  623. /* execute network interface device set DNS server address operations */
  624. return netdev->ops->set_dns_server(netdev, dns_num, (ip_addr_t *)dns_server);
  625. }
  626. /**
  627. * This function will set callback to be called when the network interface device status has been changed.
  628. *
  629. * @param netdev the network interface device to change
  630. * @param status_callback the callback be called when the status has been changed.
  631. */
  632. void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback)
  633. {
  634. RT_ASSERT(netdev);
  635. RT_ASSERT(status_callback);
  636. netdev->status_callback = status_callback;
  637. }
  638. /**
  639. * This function will set callback to be called when the network interface device address has been changed.
  640. *
  641. * @param netdev the network interface device to change
  642. * @param addr_callback the callback be called when the address has been changed.
  643. */
  644. void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback)
  645. {
  646. RT_ASSERT(netdev);
  647. RT_ASSERT(addr_callback);
  648. netdev->addr_callback = addr_callback;
  649. }
  650. /**
  651. * This function will set network interface device IP address.
  652. * @NOTE it can only be called in the network interface device driver.
  653. *
  654. * @param netdev the network interface device to change
  655. * @param ip_addr the new IP address
  656. */
  657. void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
  658. {
  659. RT_ASSERT(ip_addr);
  660. if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr) == 0)
  661. {
  662. ip_addr_copy(netdev->ip_addr, *ip_addr);
  663. #ifdef RT_USING_SAL
  664. /* set network interface device flags to internet up */
  665. if (netdev_is_up(netdev) && netdev_is_link_up(netdev))
  666. {
  667. sal_check_netdev_internet_up(netdev);
  668. }
  669. #endif /* RT_USING_SAL */
  670. /* execute IP address change callback function */
  671. if (netdev->addr_callback)
  672. {
  673. netdev->addr_callback(netdev, NETDEV_CB_ADDR_IP);
  674. }
  675. }
  676. }
  677. /**
  678. * This function will set network interface device netmask address.
  679. * @NOTE it can only be called in the network interface device driver.
  680. *
  681. * @param netdev the network interface device to change
  682. * @param netmask the new netmask address
  683. */
  684. void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
  685. {
  686. RT_ASSERT(netmask);
  687. if (netdev && ip_addr_cmp(&(netdev->netmask), netmask) == 0)
  688. {
  689. ip_addr_copy(netdev->netmask, *netmask);
  690. #ifdef RT_USING_SAL
  691. /* set network interface device flags to internet up */
  692. if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
  693. !ip_addr_isany(&(netdev->ip_addr)))
  694. {
  695. sal_check_netdev_internet_up(netdev);
  696. }
  697. #endif /* RT_USING_SAL */
  698. /* execute netmask address change callback function */
  699. if (netdev->addr_callback)
  700. {
  701. netdev->addr_callback(netdev, NETDEV_CB_ADDR_NETMASK);
  702. }
  703. }
  704. }
  705. /**
  706. * This function will set network interface device gateway address.
  707. * @NOTE it can only be called in the network interface device driver.
  708. *
  709. * @param netdev the network interface device to change
  710. * @param gw the new gateway address
  711. */
  712. void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw)
  713. {
  714. RT_ASSERT(gw);
  715. if (netdev && ip_addr_cmp(&(netdev->gw), gw) == 0)
  716. {
  717. ip_addr_copy(netdev->gw, *gw);
  718. #ifdef RT_USING_SAL
  719. /* set network interface device flags to internet up */
  720. if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
  721. !ip_addr_isany(&(netdev->ip_addr)))
  722. {
  723. sal_check_netdev_internet_up(netdev);
  724. }
  725. #endif /* RT_USING_SAL */
  726. /* execute gateway address change callback function */
  727. if (netdev->addr_callback)
  728. {
  729. netdev->addr_callback(netdev, NETDEV_CB_ADDR_GATEWAY);
  730. }
  731. }
  732. }
  733. /**
  734. * This function will set network interface device DNS server address.
  735. * @NOTE it can only be called in the network interface device driver.
  736. *
  737. * @param netdev the network interface device to change
  738. * @param dns_num the number of the DNS server
  739. * @param dns_server the new DNS server address
  740. *
  741. */
  742. void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
  743. {
  744. unsigned int index;
  745. RT_ASSERT(dns_server);
  746. if (netdev == RT_NULL)
  747. {
  748. return;
  749. }
  750. /* check DNS servers is exist */
  751. for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
  752. {
  753. if (ip_addr_cmp(&(netdev->dns_servers[index]), dns_server))
  754. {
  755. return;
  756. }
  757. }
  758. if (dns_num < NETDEV_DNS_SERVERS_NUM)
  759. {
  760. ip_addr_copy(netdev->dns_servers[dns_num], *dns_server);
  761. /* execute DNS servers address change callback function */
  762. if (netdev->addr_callback)
  763. {
  764. netdev->addr_callback(netdev, NETDEV_CB_ADDR_DNS_SERVER);
  765. }
  766. }
  767. }
  768. #ifdef NETDEV_USING_AUTO_DEFAULT
  769. /* Change to the first link_up network interface device automatically */
  770. static void netdev_auto_change_default(struct netdev *netdev)
  771. {
  772. struct netdev *new_netdev = RT_NULL;
  773. if (netdev->flags & NETDEV_FLAG_LINK_UP)
  774. {
  775. if (!(netdev_default->flags & NETDEV_FLAG_LINK_UP))
  776. {
  777. netdev_set_default(netdev);
  778. }
  779. return;
  780. }
  781. if (rt_memcmp(netdev, netdev_default, sizeof(struct netdev)) == 0)
  782. {
  783. new_netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP);
  784. if (new_netdev)
  785. {
  786. netdev_set_default(new_netdev);
  787. }
  788. }
  789. }
  790. #endif /* NETDEV_USING_AUTO_DEFAULT */
  791. /**
  792. * This function will set network interface device status.
  793. * @NOTE it can only be called in the network interface device driver.
  794. *
  795. * @param netdev the network interface device to change
  796. * @param is_up the new status
  797. */
  798. void netdev_low_level_set_status(struct netdev *netdev, rt_bool_t is_up)
  799. {
  800. if (netdev && netdev_is_up(netdev) != is_up)
  801. {
  802. if (is_up)
  803. {
  804. netdev->flags |= NETDEV_FLAG_UP;
  805. }
  806. else
  807. {
  808. netdev->flags &= ~NETDEV_FLAG_UP;
  809. #ifdef NETDEV_USING_AUTO_DEFAULT
  810. /* change to the first link_up network interface device automatically */
  811. netdev_auto_change_default(netdev);
  812. #endif /* NETDEV_USING_AUTO_DEFAULT */
  813. }
  814. /* execute network interface device status change callback function */
  815. if (netdev->status_callback)
  816. {
  817. netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_UP : NETDEV_CB_STATUS_DOWN);
  818. }
  819. }
  820. }
  821. /**
  822. * This function will set network interface device active link status.
  823. * @NOTE it can only be called in the network interface device driver.
  824. *
  825. * @param netdev the network interface device to change
  826. * @param is_up the new link status
  827. */
  828. void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up)
  829. {
  830. if (netdev && netdev_is_link_up(netdev) != is_up)
  831. {
  832. if (is_up)
  833. {
  834. netdev->flags |= NETDEV_FLAG_LINK_UP;
  835. #ifdef RT_USING_SAL
  836. /* set network interface device flags to internet up */
  837. if (netdev_is_up(netdev) && !ip_addr_isany(&(netdev->ip_addr)))
  838. {
  839. sal_check_netdev_internet_up(netdev);
  840. }
  841. #endif /* RT_USING_SAL */
  842. }
  843. else
  844. {
  845. netdev->flags &= ~NETDEV_FLAG_LINK_UP;
  846. /* set network interface device flags to internet down */
  847. netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
  848. #ifdef NETDEV_USING_AUTO_DEFAULT
  849. /* change to the first link_up network interface device automatically */
  850. netdev_auto_change_default(netdev);
  851. #endif /* NETDEV_USING_AUTO_DEFAULT */
  852. }
  853. /* execute link status change callback function */
  854. if (netdev->status_callback)
  855. {
  856. netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_LINK_UP : NETDEV_CB_STATUS_LINK_DOWN);
  857. }
  858. }
  859. }
  860. /**
  861. * This function will set network interface device active internet status.
  862. * @NOTE it can only be called in the network interface device driver.
  863. *
  864. * @param netdev the network interface device to change
  865. * @param is_up the new internet status
  866. */
  867. void netdev_low_level_set_internet_status(struct netdev *netdev, rt_bool_t is_up)
  868. {
  869. if (netdev && netdev_is_internet_up(netdev) != is_up)
  870. {
  871. if (is_up)
  872. {
  873. netdev->flags |= NETDEV_FLAG_INTERNET_UP;
  874. }
  875. else
  876. {
  877. netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
  878. }
  879. /* execute network interface device status change callback function */
  880. if (netdev->status_callback)
  881. {
  882. netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_INTERNET_UP : NETDEV_CB_STATUS_INTERNET_DOWN);
  883. }
  884. }
  885. }
  886. /**
  887. * This function will set network interface device DHCP status.
  888. * @NOTE it can only be called in the network interface device driver.
  889. *
  890. * @param netdev the network interface device to change
  891. * @param is_up the new DHCP status
  892. */
  893. void netdev_low_level_set_dhcp_status(struct netdev *netdev, rt_bool_t is_enable)
  894. {
  895. if (netdev && netdev_is_dhcp_enabled(netdev) != is_enable)
  896. {
  897. if (is_enable)
  898. {
  899. netdev->flags |= NETDEV_FLAG_DHCP;
  900. }
  901. else
  902. {
  903. netdev->flags &= ~NETDEV_FLAG_DHCP;
  904. }
  905. /* execute DHCP status change callback function */
  906. if (netdev->status_callback)
  907. {
  908. netdev->status_callback(netdev, is_enable ? NETDEV_CB_STATUS_DHCP_ENABLE : NETDEV_CB_STATUS_DHCP_DISABLE);
  909. }
  910. }
  911. }
  912. #ifdef RT_USING_FINSH
  913. #include <finsh.h>
  914. #ifdef NETDEV_USING_IFCONFIG
  915. static void netdev_list_if(void)
  916. {
  917. #define NETDEV_IFCONFIG_MAC_MAX_LEN 6
  918. #define NETDEV_IFCONFIG_IMEI_MAX_LEN 8
  919. rt_ubase_t index;
  920. rt_slist_t *node = RT_NULL;
  921. struct netdev *netdev = RT_NULL;
  922. struct netdev *cur_netdev_list = netdev_list;
  923. if (cur_netdev_list == RT_NULL)
  924. {
  925. rt_kprintf("ifconfig: network interface device list error.\n");
  926. return;
  927. }
  928. for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
  929. {
  930. netdev = rt_list_entry(node, struct netdev, list);
  931. rt_kprintf("network interface device: %.*s%s\n",
  932. RT_NAME_MAX, netdev->name,
  933. (netdev == netdev_default) ? " (Default)" : "");
  934. rt_kprintf("MTU: %d\n", netdev->mtu);
  935. /* 6 - MAC address, 8 - IEMI */
  936. if (netdev->hwaddr_len == NETDEV_IFCONFIG_MAC_MAX_LEN)
  937. {
  938. rt_kprintf("MAC: ");
  939. for (index = 0; index < netdev->hwaddr_len; index++)
  940. {
  941. rt_kprintf("%02x ", netdev->hwaddr[index]);
  942. }
  943. }
  944. else if (netdev->hwaddr_len == NETDEV_IFCONFIG_IMEI_MAX_LEN)
  945. {
  946. rt_kprintf("IMEI: ");
  947. for (index = 0; index < netdev->hwaddr_len; index++)
  948. {
  949. /* two numbers are displayed at one time*/
  950. if (netdev->hwaddr[index] < 10 && index != netdev->hwaddr_len - 1)
  951. {
  952. rt_kprintf("%02d", netdev->hwaddr[index]);
  953. }
  954. else
  955. {
  956. rt_kprintf("%d", netdev->hwaddr[index]);
  957. }
  958. }
  959. }
  960. rt_kprintf("\nFLAGS:");
  961. if (netdev->flags & NETDEV_FLAG_UP) rt_kprintf(" UP");
  962. else rt_kprintf(" DOWN");
  963. if (netdev->flags & NETDEV_FLAG_LINK_UP) rt_kprintf(" LINK_UP");
  964. else rt_kprintf(" LINK_DOWN");
  965. #ifdef SAL_INTERNET_CHECK
  966. if (netdev->flags & NETDEV_FLAG_INTERNET_UP) rt_kprintf(" INTERNET_UP");
  967. else rt_kprintf(" INTERNET_DOWN");
  968. #endif
  969. if (netdev->flags & NETDEV_FLAG_DHCP) rt_kprintf(" DHCP_ENABLE");
  970. else rt_kprintf(" DHCP_DISABLE");
  971. if (netdev->flags & NETDEV_FLAG_ETHARP) rt_kprintf(" ETHARP");
  972. if (netdev->flags & NETDEV_FLAG_BROADCAST) rt_kprintf(" BROADCAST");
  973. if (netdev->flags & NETDEV_FLAG_IGMP) rt_kprintf(" IGMP");
  974. rt_kprintf("\n");
  975. rt_kprintf("ip address: %s\n", inet_ntoa(netdev->ip_addr));
  976. rt_kprintf("gw address: %s\n", inet_ntoa(netdev->gw));
  977. rt_kprintf("net mask : %s\n", inet_ntoa(netdev->netmask));
  978. #if NETDEV_IPV6
  979. {
  980. ip_addr_t *addr;
  981. int i;
  982. addr = &netdev->ip6_addr[0];
  983. if (!ip_addr_isany(addr))
  984. {
  985. rt_kprintf("ipv6 link-local: %s %s\n", inet_ntoa(*addr),
  986. !ip_addr_isany(addr) ? "VALID" : "INVALID");
  987. for (i = 1; i < NETDEV_IPV6_NUM_ADDRESSES; i++)
  988. {
  989. addr = &netdev->ip6_addr[i];
  990. rt_kprintf("ipv6[%d] address: %s %s\n", i, inet_ntoa(*addr),
  991. !ip_addr_isany(addr) ? "VALID" : "INVALID");
  992. }
  993. }
  994. }
  995. #endif /* NETDEV_IPV6 */
  996. for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
  997. {
  998. rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index]));
  999. }
  1000. if (rt_slist_next(node))
  1001. {
  1002. rt_kprintf("\n");
  1003. }
  1004. }
  1005. }
  1006. #ifdef RT_LWIP_DHCP
  1007. int netdev_dhcp_open(char* netdev_name)
  1008. {
  1009. struct netdev *netdev = RT_NULL;
  1010. netdev = netdev_get_by_name(netdev_name);
  1011. if (netdev == RT_NULL)
  1012. {
  1013. rt_kprintf("bad network interface device name(%s).\n", netdev_name);
  1014. return -1;
  1015. }
  1016. netdev_dhcp_enabled(netdev,RT_TRUE);
  1017. return 0;
  1018. }
  1019. int netdev_dhcp_close(char* netdev_name)
  1020. {
  1021. struct netdev *netdev = RT_NULL;
  1022. netdev = netdev_get_by_name(netdev_name);
  1023. if (netdev == RT_NULL)
  1024. {
  1025. rt_kprintf("bad network interface device name(%s).\n", netdev_name);
  1026. return -1;
  1027. }
  1028. netdev_dhcp_enabled(netdev,RT_FALSE);
  1029. return 0;
  1030. }
  1031. #endif
  1032. static void netdev_set_if(char* netdev_name, char* ip_addr, char* gw_addr, char* nm_addr)
  1033. {
  1034. struct netdev *netdev = RT_NULL;
  1035. ip_addr_t addr;
  1036. netdev = netdev_get_by_name(netdev_name);
  1037. if (netdev == RT_NULL)
  1038. {
  1039. rt_kprintf("bad network interface device name(%s).\n", netdev_name);
  1040. return;
  1041. }
  1042. #ifdef RT_LWIP_DHCP
  1043. netdev_dhcp_close(netdev_name);
  1044. #endif
  1045. /* set IP address */
  1046. if ((ip_addr != RT_NULL) && inet_aton(ip_addr, &addr))
  1047. {
  1048. netdev_set_ipaddr(netdev, &addr);
  1049. }
  1050. /* set gateway address */
  1051. if ((gw_addr != RT_NULL) && inet_aton(gw_addr, &addr))
  1052. {
  1053. netdev_set_gw(netdev, &addr);
  1054. }
  1055. /* set netmask address */
  1056. if ((nm_addr != RT_NULL) && inet_aton(nm_addr, &addr))
  1057. {
  1058. netdev_set_netmask(netdev, &addr);
  1059. }
  1060. }
  1061. int netdev_ifconfig(int argc, char **argv)
  1062. {
  1063. if (argc == 1)
  1064. {
  1065. netdev_list_if();
  1066. }
  1067. #ifdef RT_LWIP_DHCP
  1068. else if(argc == 3)
  1069. {
  1070. if (!strcmp(argv[2], "dhcp"))
  1071. {
  1072. netdev_dhcp_open(argv[1]);
  1073. }
  1074. }
  1075. #endif
  1076. else if (argc == 5)
  1077. {
  1078. rt_kprintf("config : %s\n", argv[1]);
  1079. rt_kprintf("IP addr: %s\n", argv[2]);
  1080. rt_kprintf("Gateway: %s\n", argv[3]);
  1081. rt_kprintf("netmask: %s\n", argv[4]);
  1082. netdev_set_if(argv[1], argv[2], argv[3], argv[4]);
  1083. }
  1084. else
  1085. {
  1086. rt_kprintf("bad parameter! e.g: ifconfig e0 192.168.1.30 192.168.1.1 255.255.255.0\n");
  1087. #ifdef RT_LWIP_DHCP
  1088. rt_kprintf("bad parameter! e.g: ifconfig e0 dhcp\n");
  1089. #endif
  1090. }
  1091. return 0;
  1092. }
  1093. MSH_CMD_EXPORT_ALIAS(netdev_ifconfig, ifconfig, list the information of all network interfaces);
  1094. #endif /* NETDEV_USING_IFCONFIG */
  1095. #ifdef NETDEV_USING_PING
  1096. int netdev_cmd_ping(char* target_name, char *netdev_name, rt_uint32_t times, rt_size_t size)
  1097. {
  1098. #define NETDEV_PING_DATA_SIZE 32
  1099. /** ping receive timeout - in milliseconds */
  1100. #define NETDEV_PING_RECV_TIMEO (2 * RT_TICK_PER_SECOND)
  1101. /** ping delay - in milliseconds */
  1102. #define NETDEV_PING_DELAY (1 * RT_TICK_PER_SECOND)
  1103. /* check netdev ping options */
  1104. #define NETDEV_PING_IS_COMMONICABLE(netdev) \
  1105. ((netdev) && (netdev)->ops && (netdev)->ops->ping && \
  1106. netdev_is_up(netdev) && netdev_is_link_up(netdev)) \
  1107. struct netdev *netdev = RT_NULL;
  1108. struct netdev_ping_resp ping_resp;
  1109. rt_uint32_t index, received, loss, max_time, min_time, avg_time;
  1110. int ret = 0;
  1111. rt_bool_t isbind = RT_FALSE;
  1112. if (size == 0)
  1113. {
  1114. size = NETDEV_PING_DATA_SIZE;
  1115. }
  1116. if (netdev_name != RT_NULL)
  1117. {
  1118. netdev = netdev_get_by_name(netdev_name);
  1119. isbind = RT_TRUE;
  1120. }
  1121. if (netdev == RT_NULL)
  1122. {
  1123. netdev = netdev_default;
  1124. rt_kprintf("ping: not found specified netif, using default netdev %s.\n", netdev->name);
  1125. }
  1126. if (!NETDEV_PING_IS_COMMONICABLE(netdev))
  1127. {
  1128. if (netdev == RT_NULL)
  1129. {
  1130. rt_kprintf("ping: not found available network interface device.\n");
  1131. return -RT_ERROR;
  1132. }
  1133. else if (netdev->ops == RT_NULL || netdev->ops->ping == RT_NULL)
  1134. {
  1135. rt_kprintf("ping: network interface device(%s) not support ping feature.\n", netdev->name);
  1136. return -RT_ERROR;
  1137. }
  1138. else if (!netdev_is_up(netdev) || !netdev_is_link_up(netdev))
  1139. {
  1140. rt_kprintf("ping: network interface device(%s) status error.\n", netdev->name);
  1141. return -RT_ERROR;
  1142. }
  1143. }
  1144. max_time = avg_time = received = 0;
  1145. min_time = 0xFFFFFFFF;
  1146. for (index = 0; index < times; index++)
  1147. {
  1148. int delay_tick = 0;
  1149. rt_tick_t start_tick = 0;
  1150. rt_memset(&ping_resp, 0x00, sizeof(struct netdev_ping_resp));
  1151. start_tick = rt_tick_get();
  1152. ret = netdev->ops->ping(netdev, (const char *)target_name, size, NETDEV_PING_RECV_TIMEO, &ping_resp, isbind);
  1153. if (ret == -RT_ETIMEOUT)
  1154. {
  1155. rt_kprintf("ping: from %s icmp_seq=%d timeout\n",
  1156. (ip_addr_isany(&(ping_resp.ip_addr))) ? target_name : inet_ntoa(ping_resp.ip_addr), index + 1);
  1157. }
  1158. else if (ret == -RT_ERROR)
  1159. {
  1160. rt_kprintf("ping: unknown %s %s\n",
  1161. (ip_addr_isany(&(ping_resp.ip_addr))) ? "host" : "address",
  1162. (ip_addr_isany(&(ping_resp.ip_addr))) ? target_name : inet_ntoa(ping_resp.ip_addr));
  1163. }
  1164. else
  1165. {
  1166. if (ping_resp.ttl == 0)
  1167. {
  1168. rt_kprintf("%d bytes from %s icmp_seq=%d time=%d ms\n",
  1169. ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index + 1, ping_resp.ticks);
  1170. }
  1171. else
  1172. {
  1173. rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n",
  1174. ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index + 1, ping_resp.ttl, ping_resp.ticks);
  1175. }
  1176. received += 1;
  1177. if (ping_resp.ticks > max_time)
  1178. {
  1179. max_time = ping_resp.ticks;
  1180. }
  1181. else if (ping_resp.ticks < min_time)
  1182. {
  1183. min_time = ping_resp.ticks;
  1184. }
  1185. avg_time += ping_resp.ticks;
  1186. }
  1187. /* if the response time is more than NETDEV_PING_DELAY, no need to delay */
  1188. delay_tick = ((rt_tick_get() - start_tick) > NETDEV_PING_DELAY) || (index == times) ? 0 : NETDEV_PING_DELAY;
  1189. rt_thread_delay(delay_tick);
  1190. }
  1191. /* print ping statistics */
  1192. loss = (uint32_t)((1 - ((float)received) / index) * 100);
  1193. avg_time = (uint32_t)(avg_time / received);
  1194. #if NETDEV_IPV4 && NETDEV_IPV6
  1195. if (IP_IS_V4_VAL(&ping_resp.ip_addr))
  1196. {
  1197. rt_kprintf("\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&ping_resp.ip_addr)));
  1198. }
  1199. else
  1200. {
  1201. rt_kprintf("\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&ping_resp.ip_addr)));
  1202. }
  1203. #elif NETDEV_IPV4
  1204. rt_kprintf("\n--- %s ping statistics ---\n", inet_ntoa(ping_resp.ip_addr));
  1205. #elif NETDEV_IPV6
  1206. rt_kprintf("\n--- %s ping statistics ---\n", inet6_ntoa(ping_resp.ip_addr));
  1207. #endif
  1208. rt_kprintf("%d packets transmitted, %d received, %d%% packet loss\n", index, received, loss);
  1209. if (received > 0)
  1210. {
  1211. rt_kprintf("minimum = %dms, maximum = %dms, average = %dms\n", min_time, max_time, avg_time);
  1212. }
  1213. return RT_EOK;
  1214. }
  1215. int netdev_ping(int argc, char **argv)
  1216. {
  1217. if (argc == 1)
  1218. {
  1219. rt_kprintf("Please input: ping <host address> [netdev name] [times] [data size]\n");
  1220. }
  1221. else if (argc == 2)
  1222. {
  1223. netdev_cmd_ping(argv[1], RT_NULL, 4, 0);
  1224. }
  1225. else if (argc == 3)
  1226. {
  1227. netdev_cmd_ping(argv[1], argv[2], 4, 0);
  1228. }
  1229. else if (argc == 4)
  1230. {
  1231. netdev_cmd_ping(argv[1], argv[2], atoi(argv[3]), 0);
  1232. }
  1233. else if (argc == 5)
  1234. {
  1235. netdev_cmd_ping(argv[1], argv[2], atoi(argv[3]), atoi(argv[4]));
  1236. }
  1237. return 0;
  1238. }
  1239. MSH_CMD_EXPORT_ALIAS(netdev_ping, ping, ping network host);
  1240. #endif /* NETDEV_USING_IFCONFIG */
  1241. static void netdev_list_dns(void)
  1242. {
  1243. unsigned int index = 0;
  1244. struct netdev *netdev = RT_NULL;
  1245. rt_slist_t *node = RT_NULL;
  1246. for (node = &(netdev_list->list); node; node = rt_slist_next(node))
  1247. {
  1248. netdev = rt_list_entry(node, struct netdev, list);
  1249. rt_kprintf("network interface device: %.*s%s\n",
  1250. RT_NAME_MAX, netdev->name,
  1251. (netdev == netdev_default)?" (Default)":"");
  1252. for(index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
  1253. {
  1254. rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index]));
  1255. }
  1256. if (rt_slist_next(node))
  1257. {
  1258. rt_kprintf("\n");
  1259. }
  1260. }
  1261. }
  1262. static void netdev_set_dns(char *netdev_name, uint8_t dns_num, char *dns_server)
  1263. {
  1264. struct netdev *netdev = RT_NULL;
  1265. ip_addr_t dns_addr;
  1266. netdev = netdev_get_by_name(netdev_name);
  1267. if (netdev == RT_NULL)
  1268. {
  1269. rt_kprintf("bad network interface device name(%s).\n", netdev_name);
  1270. return;
  1271. }
  1272. inet_aton(dns_server, &dns_addr);
  1273. if (netdev_set_dns_server(netdev, dns_num, &dns_addr) == RT_EOK)
  1274. {
  1275. rt_kprintf("set network interface device(%s) dns server #%d: %s\n", netdev_name, dns_num, dns_server);
  1276. }
  1277. }
  1278. int netdev_dns(int argc, char **argv)
  1279. {
  1280. if (argc == 1)
  1281. {
  1282. netdev_list_dns();
  1283. }
  1284. else if (argc == 3)
  1285. {
  1286. netdev_set_dns(argv[1], 0, argv[2]);
  1287. }
  1288. else if (argc == 4)
  1289. {
  1290. netdev_set_dns(argv[1], atoi(argv[2]), argv[3]);
  1291. }
  1292. else
  1293. {
  1294. rt_kprintf("bad parameter! input: dns <netdev_name> [dns_num] <dns_server>\n");
  1295. return -1;
  1296. }
  1297. return 0;
  1298. }
  1299. MSH_CMD_EXPORT_ALIAS(netdev_dns, dns, list and set the information of dns);
  1300. #ifdef NETDEV_USING_NETSTAT
  1301. static void netdev_cmd_netstat(void)
  1302. {
  1303. rt_slist_t *node = RT_NULL;
  1304. struct netdev *netdev = RT_NULL;
  1305. struct netdev *cur_netdev_list = netdev_list;
  1306. if (cur_netdev_list == RT_NULL)
  1307. {
  1308. rt_kprintf("netstat: network interface device list error.\n");
  1309. return;
  1310. }
  1311. for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
  1312. {
  1313. netdev = rt_list_entry(node, struct netdev, list);
  1314. if (netdev && netdev->ops && netdev->ops->netstat)
  1315. {
  1316. break;
  1317. }
  1318. }
  1319. if (netdev->ops->netstat != RT_NULL)
  1320. {
  1321. netdev->ops->netstat(netdev);
  1322. }
  1323. else
  1324. {
  1325. rt_kprintf("netstat: this command is not supported!\n");
  1326. }
  1327. }
  1328. int netdev_netstat(int argc, char **argv)
  1329. {
  1330. if (argc != 1)
  1331. {
  1332. rt_kprintf("Please input: netstat \n");
  1333. }
  1334. else
  1335. {
  1336. netdev_cmd_netstat();
  1337. }
  1338. return 0;
  1339. }
  1340. MSH_CMD_EXPORT_ALIAS(netdev_netstat, netstat, list the information of TCP / IP);
  1341. #endif /* NETDEV_USING_NETSTAT */
  1342. #endif /* RT_USING_FINSH */