net_statistics.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. /****************************************************************************
  2. * net/procfs/net_statistics.c
  3. *
  4. * Copyright (C) 2015 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <sys/types.h>
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <debug.h>
  43. #include <nuttx/net/netstats.h>
  44. #include "procfs/procfs.h"
  45. #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \
  46. !defined(CONFIG_FS_PROCFS_EXCLUDE_NET) && defined(CONFIG_NET_STATISTICS)
  47. #if defined(CONFIG_NET_IPv4) || defined(CONFIG_NET_IPv6) || \
  48. defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP) || \
  49. defined(CONFIG_NET_ICMP) || defined(CONFIG_NET_ICMPv6)
  50. /****************************************************************************
  51. * Private Function Prototypes
  52. ****************************************************************************/
  53. /* Line generating functions */
  54. static int netprocfs_header(FAR struct netprocfs_file_s *netfile);
  55. static int netprocfs_received(FAR struct netprocfs_file_s *netfile);
  56. static int netprocfs_dropped(FAR struct netprocfs_file_s *netfile);
  57. #ifdef CONFIG_NET_IPv4
  58. static int netprocfs_ipv4_dropped(FAR struct netprocfs_file_s *netfile);
  59. #endif /* CONFIG_NET_IPv4 */
  60. #ifdef CONFIG_NET_IPv6
  61. static int netprocfs_ipv6_dropped(FAR struct netprocfs_file_s *netfile);
  62. #endif /* CONFIG_NET_IPv4 */
  63. static int netprocfs_checksum(FAR struct netprocfs_file_s *netfile);
  64. #ifdef CONFIG_NET_TCP
  65. static int netprocfs_tcp_dropped_1(FAR struct netprocfs_file_s *netfile);
  66. static int netprocfs_tcp_dropped_2(FAR struct netprocfs_file_s *netfile);
  67. #endif /* CONFIG_NET_TCP */
  68. static int netprocfs_prototype(FAR struct netprocfs_file_s *netfile);
  69. static int netprocfs_sent(FAR struct netprocfs_file_s *netfile);
  70. #ifdef CONFIG_NET_TCP
  71. static int netprocfs_retransmissions(FAR struct netprocfs_file_s *netfile);
  72. #endif /* CONFIG_NET_TCP */
  73. /****************************************************************************
  74. * Private Data
  75. ****************************************************************************/
  76. /* Line generating functions */
  77. static const linegen_t g_stat_linegen[] =
  78. {
  79. netprocfs_header,
  80. netprocfs_received,
  81. netprocfs_dropped,
  82. #ifdef CONFIG_NET_IPv4
  83. netprocfs_ipv4_dropped,
  84. #endif /* CONFIG_NET_IPv4 */
  85. #ifdef CONFIG_NET_IPv6
  86. netprocfs_ipv6_dropped,
  87. #endif /* CONFIG_NET_IPv4 */
  88. netprocfs_checksum,
  89. #ifdef CONFIG_NET_TCP
  90. netprocfs_tcp_dropped_1,
  91. netprocfs_tcp_dropped_2,
  92. #endif /* CONFIG_NET_TCP */
  93. netprocfs_prototype,
  94. netprocfs_sent
  95. #ifdef CONFIG_NET_TCP
  96. , netprocfs_retransmissions
  97. #endif /* CONFIG_NET_TCP */
  98. };
  99. #define NSTAT_LINES (sizeof(g_stat_linegen) / sizeof(linegen_t))
  100. /****************************************************************************
  101. * Private Functions
  102. ****************************************************************************/
  103. /****************************************************************************
  104. * Name: netprocfs_header
  105. ****************************************************************************/
  106. #ifdef CONFIG_NET_STATISTICS
  107. static int netprocfs_header(FAR struct netprocfs_file_s *netfile)
  108. {
  109. int len = 0;
  110. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ");
  111. #ifdef CONFIG_NET_IPv4
  112. len += snprintf(&netfile->line[len], NET_LINELEN - len, " IPv4");
  113. #endif
  114. #ifdef CONFIG_NET_IPv6
  115. len += snprintf(&netfile->line[len], NET_LINELEN - len, " IPv6");
  116. #endif
  117. #ifdef CONFIG_NET_TCP
  118. len += snprintf(&netfile->line[len], NET_LINELEN - len, " TCP");
  119. #endif
  120. #ifdef CONFIG_NET_UDP
  121. len += snprintf(&netfile->line[len], NET_LINELEN - len, " UDP");
  122. #endif
  123. #ifdef CONFIG_NET_ICMP
  124. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ICMP");
  125. #endif
  126. #ifdef CONFIG_NET_ICMPv6
  127. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ICMPv6");
  128. #endif
  129. len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n");
  130. return len;
  131. }
  132. #endif /* CONFIG_NET_STATISTICS */
  133. /****************************************************************************
  134. * Name: netprocfs_received
  135. ****************************************************************************/
  136. #ifdef CONFIG_NET_STATISTICS
  137. static int netprocfs_received(FAR struct netprocfs_file_s *netfile)
  138. {
  139. int len = 0;
  140. len += snprintf(&netfile->line[len], NET_LINELEN - len, "Received ");
  141. #ifdef CONFIG_NET_IPv4
  142. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  143. g_netstats.ipv4.recv);
  144. #endif
  145. #ifdef CONFIG_NET_IPv6
  146. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  147. g_netstats.ipv6.recv);
  148. #endif
  149. #ifdef CONFIG_NET_TCP
  150. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  151. g_netstats.tcp.recv);
  152. #endif
  153. #ifdef CONFIG_NET_UDP
  154. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  155. g_netstats.udp.recv);
  156. #endif
  157. #ifdef CONFIG_NET_ICMP
  158. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  159. g_netstats.icmp.recv);
  160. #endif
  161. #ifdef CONFIG_NET_ICMPv6
  162. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  163. g_netstats.icmpv6.recv);
  164. #endif
  165. len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n");
  166. return len;
  167. }
  168. #endif /* CONFIG_NET_STATISTICS */
  169. /****************************************************************************
  170. * Name: netprocfs_dropped
  171. ****************************************************************************/
  172. #ifdef CONFIG_NET_STATISTICS
  173. static int netprocfs_dropped(FAR struct netprocfs_file_s *netfile)
  174. {
  175. int len = 0;
  176. len += snprintf(&netfile->line[len], NET_LINELEN - len, "Dropped ");
  177. #ifdef CONFIG_NET_IPv4
  178. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  179. g_netstats.ipv4.drop);
  180. #endif
  181. #ifdef CONFIG_NET_IPv6
  182. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  183. g_netstats.ipv6.drop);
  184. #endif
  185. #ifdef CONFIG_NET_TCP
  186. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  187. g_netstats.tcp.drop);
  188. #endif
  189. #ifdef CONFIG_NET_UDP
  190. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  191. g_netstats.udp.drop);
  192. #endif
  193. #ifdef CONFIG_NET_ICMP
  194. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  195. g_netstats.icmp.drop);
  196. #endif
  197. #ifdef CONFIG_NET_ICMPv6
  198. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  199. g_netstats.icmpv6.drop);
  200. #endif
  201. len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n");
  202. return len;
  203. }
  204. #endif /* CONFIG_NET_STATISTICS */
  205. /****************************************************************************
  206. * Name: netprocfs_ipv4_dropped
  207. ****************************************************************************/
  208. #if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_IPv4)
  209. static int netprocfs_ipv4_dropped(FAR struct netprocfs_file_s *netfile)
  210. {
  211. return snprintf(netfile->line, NET_LINELEN,
  212. " IPv4 VHL: %04x Frg: %04x\n",
  213. g_netstats.ipv4.vhlerr, g_netstats.ipv4.fragerr);
  214. }
  215. #endif /* CONFIG_NET_STATISTICS && CONFIG_NET_IPv4 */
  216. /****************************************************************************
  217. * Name: netprocfs_ipv6_dropped
  218. ****************************************************************************/
  219. #if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_IPv6)
  220. static int netprocfs_ipv6_dropped(FAR struct netprocfs_file_s *netfile)
  221. {
  222. return snprintf(netfile->line, NET_LINELEN,
  223. " IPv6 VHL: %04x\n",
  224. g_netstats.ipv6.vhlerr);
  225. }
  226. #endif /* CONFIG_NET_STATISTICS && CONFIG_NET_IPv6 */
  227. /****************************************************************************
  228. * Name: netprocfs_checksum
  229. ****************************************************************************/
  230. #ifdef CONFIG_NET_STATISTICS
  231. static int netprocfs_checksum(FAR struct netprocfs_file_s *netfile)
  232. {
  233. int len = 0;
  234. len += snprintf(&netfile->line[len], NET_LINELEN - len, " Checksum ");
  235. #ifdef CONFIG_NET_IPv4
  236. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  237. g_netstats.ipv4.chkerr);
  238. #endif
  239. #ifdef CONFIG_NET_IPv6
  240. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  241. #endif
  242. #ifdef CONFIG_NET_TCP
  243. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  244. g_netstats.tcp.chkerr);
  245. #endif
  246. #ifdef CONFIG_NET_UDP
  247. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  248. g_netstats.udp.chkerr);
  249. #endif
  250. #ifdef CONFIG_NET_ICMP
  251. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  252. #endif
  253. #ifdef CONFIG_NET_ICMPv6
  254. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  255. #endif
  256. len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n");
  257. return len;
  258. }
  259. #endif /* CONFIG_NET_STATISTICS */
  260. /****************************************************************************
  261. * Name: netprocfs_tcp_dropped_1
  262. ****************************************************************************/
  263. #if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_TCP)
  264. static int netprocfs_tcp_dropped_1(FAR struct netprocfs_file_s *netfile)
  265. {
  266. return snprintf(netfile->line, NET_LINELEN,
  267. " TCP ACK: %04x SYN: %04x\n",
  268. g_netstats.tcp.ackerr, g_netstats.tcp.syndrop);
  269. }
  270. #endif /* CONFIG_NET_STATISTICS && CONFIG_NET_TCP */
  271. /****************************************************************************
  272. * Name: netprocfs_tcp_dropped_2
  273. ****************************************************************************/
  274. #if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_TCP)
  275. static int netprocfs_tcp_dropped_2(FAR struct netprocfs_file_s *netfile)
  276. {
  277. return snprintf(netfile->line, NET_LINELEN,
  278. " RST: %04x %04x\n",
  279. g_netstats.tcp.rst, g_netstats.tcp.synrst);
  280. }
  281. #endif /* CONFIG_NET_STATISTICS && CONFIG_NET_TCP */
  282. /****************************************************************************
  283. * Name: netprocfs_prototype
  284. ****************************************************************************/
  285. #ifdef CONFIG_NET_STATISTICS
  286. static int netprocfs_prototype(FAR struct netprocfs_file_s *netfile)
  287. {
  288. int len = 0;
  289. len += snprintf(&netfile->line[len], NET_LINELEN - len, " Type ");
  290. #ifdef CONFIG_NET_IPv4
  291. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  292. g_netstats.ipv4.protoerr);
  293. #endif
  294. #ifdef CONFIG_NET_IPv6
  295. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  296. g_netstats.ipv6.protoerr);
  297. #endif
  298. #ifdef CONFIG_NET_TCP
  299. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  300. #endif
  301. #ifdef CONFIG_NET_UDP
  302. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  303. #endif
  304. #ifdef CONFIG_NET_ICMP
  305. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  306. g_netstats.icmp.typeerr);
  307. #endif
  308. #ifdef CONFIG_NET_ICMPv6
  309. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  310. g_netstats.icmpv6.typeerr);
  311. #endif
  312. len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n");
  313. return len;
  314. }
  315. #endif /* CONFIG_NET_STATISTICS */
  316. /****************************************************************************
  317. * Name: netprocfs_sent
  318. ****************************************************************************/
  319. #ifdef CONFIG_NET_STATISTICS
  320. static int netprocfs_sent(FAR struct netprocfs_file_s *netfile)
  321. {
  322. int len = 0;
  323. len += snprintf(&netfile->line[len], NET_LINELEN - len, "Sent ");
  324. #ifdef CONFIG_NET_IPv4
  325. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  326. g_netstats.ipv4.sent);
  327. #endif
  328. #ifdef CONFIG_NET_IPv6
  329. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  330. g_netstats.ipv6.sent);
  331. #endif
  332. #ifdef CONFIG_NET_TCP
  333. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  334. g_netstats.tcp.sent);
  335. #endif
  336. #ifdef CONFIG_NET_UDP
  337. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  338. g_netstats.udp.sent);
  339. #endif
  340. #ifdef CONFIG_NET_ICMP
  341. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  342. g_netstats.icmp.sent);
  343. #endif
  344. #ifdef CONFIG_NET_ICMPv6
  345. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  346. g_netstats.icmpv6.sent);
  347. #endif
  348. len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n");
  349. return len;
  350. }
  351. #endif /* CONFIG_NET_STATISTICS */
  352. /****************************************************************************
  353. * Name: netprocfs_retransmissions
  354. ****************************************************************************/
  355. #if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_TCP)
  356. static int netprocfs_retransmissions(FAR struct netprocfs_file_s *netfile)
  357. {
  358. int len = 0;
  359. len += snprintf(&netfile->line[len], NET_LINELEN - len, " Rexmit ");
  360. #ifdef CONFIG_NET_IPv4
  361. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  362. #endif
  363. #ifdef CONFIG_NET_IPv6
  364. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  365. #endif
  366. len += snprintf(&netfile->line[len], NET_LINELEN - len, " %04x",
  367. g_netstats.tcp.rexmit);
  368. #ifdef CONFIG_NET_UDP
  369. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  370. #endif
  371. #ifdef CONFIG_NET_ICMP
  372. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  373. #endif
  374. #ifdef CONFIG_NET_ICMPv6
  375. len += snprintf(&netfile->line[len], NET_LINELEN - len, " ----");
  376. #endif
  377. len += snprintf(&netfile->line[len], NET_LINELEN - len, "\n");
  378. return len;
  379. }
  380. #endif /* CONFIG_NET_STATISTICS && CONFIG_NET_TCP */
  381. /****************************************************************************
  382. * Public Functions
  383. ****************************************************************************/
  384. /****************************************************************************
  385. * Name: netprocfs_read_netstats
  386. *
  387. * Description:
  388. * Read and format network layer statistics.
  389. *
  390. * Input Parameters:
  391. * priv - A reference to the network procfs file structure
  392. * buffer - The user-provided buffer into which network status will be
  393. * returned.
  394. * bulen - The size in bytes of the user provided buffer.
  395. *
  396. * Returned Value:
  397. * Zero (OK) is returned on success; a negated errno value is returned
  398. * on failure.
  399. *
  400. ****************************************************************************/
  401. ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv,
  402. FAR char *buffer, size_t buflen)
  403. {
  404. return netprocfs_read_linegen(priv, buffer, buflen, g_stat_linegen, NSTAT_LINES);
  405. }
  406. #else
  407. ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv,
  408. FAR char *buffer, size_t buflen)
  409. {
  410. return OK;
  411. }
  412. #endif /* CONFIG_NET_IPv4 || CONFIG_NET_IPv6 || CONFIG_NET_TCP || \
  413. * CONFIG_NET_UDP || CONFIG_NET_ICMP || CONFIG_NET_ICMPv6 */
  414. #endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS &&
  415. * !CONFIG_FS_PROCFS_EXCLUDE_NET */