idiag.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * lib/idiag/idiag.c Inet Diag Netlink
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation version 2.1
  7. * of the License.
  8. *
  9. * Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
  10. */
  11. /**
  12. * @defgroup idiag Inet Diag library (libnl-idiag)
  13. * @brief
  14. * @{
  15. */
  16. #include <netlink-private/netlink.h>
  17. #include <netlink/netlink.h>
  18. #include <netlink/cache.h>
  19. #include <netlink/idiag/idiagnl.h>
  20. #include <linux/inet_diag.h>
  21. /**
  22. * @name Socket Creation
  23. * @{
  24. */
  25. /**
  26. * Create and connect idiag netlink socket.
  27. * @arg sk Netlink socket.
  28. *
  29. * Creates a NETLINK_INET_DIAG socket, binds the socket, and issues a connection
  30. * attemp.
  31. *
  32. * @see nl_connect()
  33. *
  34. * @return 0 on success or a negative error code.
  35. */
  36. int idiagnl_connect(struct nl_sock *sk)
  37. {
  38. return nl_connect(sk, NETLINK_INET_DIAG);
  39. }
  40. /** @} */
  41. /**
  42. * @name Sending
  43. * @{
  44. */
  45. /**
  46. * Send trivial idiag netlink message
  47. * @arg sk Netlink socket.
  48. * @arg flags Message flags
  49. * @arg family Address family
  50. * @arg states Socket states to query
  51. * @arg ext Inet Diag attribute extensions to query
  52. *
  53. * @return Newly allocated netlink message or NULL.
  54. */
  55. int idiagnl_send_simple(struct nl_sock *sk, int flags, uint8_t family,
  56. uint16_t states, uint16_t ext)
  57. {
  58. struct inet_diag_req req;
  59. memset(&req, 0, sizeof(req));
  60. flags |= NLM_F_ROOT;
  61. req.idiag_family = family;
  62. req.idiag_states = states;
  63. req.idiag_ext = ext;
  64. return nl_send_simple(sk, TCPDIAG_GETSOCK, flags, &req, sizeof(req));
  65. }
  66. /** @} */
  67. /**
  68. * @name Inet Diag flag and attribute conversions
  69. * @{
  70. */
  71. static const struct trans_tbl idiag_states[] = {
  72. __ADD(IDIAG_SS_UNKNOWN, unknown)
  73. __ADD(IDIAG_SS_ESTABLISHED, established)
  74. __ADD(IDIAG_SS_SYN_SENT, syn_sent)
  75. __ADD(IDIAG_SS_SYN_RECV, syn_recv)
  76. __ADD(IDIAG_SS_FIN_WAIT1, fin_wait)
  77. __ADD(IDIAG_SS_FIN_WAIT2, fin_wait2)
  78. __ADD(IDIAG_SS_TIME_WAIT, time_wait)
  79. __ADD(IDIAG_SS_CLOSE, close)
  80. __ADD(IDIAG_SS_CLOSE_WAIT, close_wait)
  81. __ADD(IDIAG_SS_LAST_ACK, last_ack)
  82. __ADD(IDIAG_SS_LISTEN, listen)
  83. __ADD(IDIAG_SS_CLOSING, closing)
  84. __ADD(IDIAG_SS_MAX, max)
  85. { ((1<<IDIAG_SS_MAX)-1), "all" }
  86. };
  87. /**
  88. * Convert inet diag socket states to strings.
  89. * @arg state inetdiag socket state (e.g., IDIAG_SS_ESTABLISHED)
  90. * @arg buf output buffer which will hold string result
  91. * @arg len length in bytes of the output buffer
  92. *
  93. * @return string representation of the inetdiag socket state or an empty
  94. * string.
  95. */
  96. char * idiagnl_state2str(int state, char *buf, size_t len)
  97. {
  98. return __type2str(state, buf, len, idiag_states,
  99. ARRAY_SIZE(idiag_states));
  100. }
  101. /**
  102. * Convert inet diag socket state string to int.
  103. * @arg name inetdiag socket state string
  104. *
  105. * @return the int representation of the socket state strign or a negative error
  106. * code.
  107. */
  108. int idiagnl_str2state(const char *name)
  109. {
  110. return __str2type(name, idiag_states, ARRAY_SIZE(idiag_states));
  111. }
  112. static const struct trans_tbl idiag_timers[] = {
  113. __ADD(IDIAG_TIMER_OFF, off)
  114. __ADD(IDIAG_TIMER_ON, on)
  115. __ADD(IDIAG_TIMER_KEEPALIVE, keepalive)
  116. __ADD(IDIAG_TIMER_TIMEWAIT, timewait)
  117. __ADD(IDIAG_TIMER_PERSIST, persist)
  118. __ADD(IDIAG_TIMER_UNKNOWN, unknown)
  119. };
  120. /**
  121. * Convert inet diag timer types to strings.
  122. * @arg timer inetdiag timer (e.g., IDIAG_TIMER_ON)
  123. * @arg buf output buffer which will hold string result
  124. * @arg len length in bytes of the output buffer
  125. *
  126. * @return string representation of the inetdiag timer type or an empty string.
  127. */
  128. char * idiagnl_timer2str(int timer, char *buf, size_t len)
  129. {
  130. return __type2str(timer, buf, len, idiag_timers,
  131. ARRAY_SIZE(idiag_timers));
  132. }
  133. /**
  134. * Convert inet diag timer string to int.
  135. * @arg name inetdiag timer string
  136. *
  137. * @return the int representation of the timer string or a negative error code.
  138. */
  139. int idiagnl_str2timer(const char *name)
  140. {
  141. return __str2type(name, idiag_timers, ARRAY_SIZE(idiag_timers));
  142. }
  143. static const struct trans_tbl idiag_attrs[] = {
  144. __ADD(IDIAG_ATTR_NONE, none)
  145. __ADD(IDIAG_ATTR_MEMINFO, meminfo)
  146. __ADD(IDIAG_ATTR_INFO, info)
  147. __ADD(IDIAG_ATTR_VEGASINFO, vegasinfo)
  148. __ADD(IDIAG_ATTR_CONG, congestion)
  149. __ADD(IDIAG_ATTR_TOS, tos)
  150. __ADD(IDIAG_ATTR_TCLASS, tclass)
  151. };
  152. /**
  153. * Convert inetdiag extended attributes to strings.
  154. * @arg attrs inetdiag attribute (e.g., IDIAG_ATTR_MEMINFO)
  155. * @arg buf output buffer which will hold string result
  156. * @arg len length in bytes of the output buffer
  157. *
  158. * @return string representation of attrs or an empty string.
  159. */
  160. char *idiagnl_attrs2str(int attrs, char *buf, size_t len)
  161. {
  162. return __type2str(attrs, buf, len, idiag_attrs, ARRAY_SIZE(idiag_attrs));
  163. }
  164. static const struct trans_tbl idiagnl_tcpstates[] = {
  165. __ADD(TCP_CA_Open, open)
  166. __ADD(TCP_CA_Disorder, disorder)
  167. __ADD(TCP_CA_CWR, cwr)
  168. __ADD(TCP_CA_Recovery, recovery)
  169. __ADD(TCP_CA_Loss, loss)
  170. };
  171. /**
  172. * Convert inetdiag tcp states to strings.
  173. * @arg state TCP state (e.g., TCP_CA_Open)
  174. * @arg buf output buffer which will hold string result
  175. * @arg len length in bytes of the output buffer
  176. */
  177. char *idiagnl_tcpstate2str(uint8_t state, char *buf, size_t len)
  178. {
  179. return __type2str(state, buf, len, idiagnl_tcpstates,
  180. ARRAY_SIZE(idiagnl_tcpstates));
  181. }
  182. static const struct trans_tbl idiagnl_tcpopt_attrs[] = {
  183. __ADD(TCPI_OPT_TIMESTAMPS, timestamps)
  184. __ADD(TCPI_OPT_SACK, sACK)
  185. __ADD(TCPI_OPT_WSCALE, wscale)
  186. __ADD(TCPI_OPT_ECN, ecn)
  187. };
  188. /**
  189. * Convert TCP option attributes to string
  190. * @arg attrs TCP option attributes to convert (e.g., TCPI_OPT_SACK |
  191. * TCPI_OPT_WSCALE)
  192. * @arg buf Output buffer for string
  193. * @arg len Length in bytes of output buffer
  194. *
  195. * @return buffer with string representation or empty string
  196. */
  197. char *idiagnl_tcpopts2str(uint8_t attrs, char *buf, size_t len)
  198. {
  199. return __flags2str(attrs, buf, len, idiagnl_tcpopt_attrs,
  200. ARRAY_SIZE(idiagnl_tcpopt_attrs));
  201. }
  202. /**
  203. * Convert shutdown state to string.
  204. * @arg shutdown Shutdown state (e.g., idiag_msg->shutdown)
  205. * @arg buf Ouput buffer to hold string representation
  206. * @arg len Length in bytes of output buffer
  207. *
  208. * @return string representation of shutdown state or NULL
  209. */
  210. char * idiagnl_shutdown2str(uint8_t shutdown, char *buf, size_t len)
  211. {
  212. if (shutdown == 0) {
  213. snprintf(buf, len, " ");
  214. return buf;
  215. } else if (shutdown == 1) {
  216. snprintf(buf, len, "receive shutdown");
  217. return buf;
  218. } else if (shutdown == 2) {
  219. snprintf(buf, len, "send shutdown");
  220. return buf;
  221. }
  222. return NULL;
  223. }
  224. static const struct trans_tbl idiag_exts[] = {
  225. __ADD(IDIAG_ATTR_NONE, none)
  226. __ADD(IDIAG_ATTR_MEMINFO, meminfo)
  227. __ADD(IDIAG_ATTR_INFO, info)
  228. __ADD(IDIAG_ATTR_VEGASINFO, vegasinfo)
  229. __ADD(IDIAG_ATTR_CONG, congestion)
  230. __ADD(IDIAG_ATTR_TOS, tos)
  231. __ADD(IDIAG_ATTR_TCLASS, tclass)
  232. };
  233. /**
  234. * Convert inet diag extension flags to a string.
  235. * @arg attrs inet diag extension flags (e.g., (IDIAG_ATTR_MEMINFO |
  236. * IDIAG_ATTR_CONG | IDIAG_ATTR_TOS))
  237. * @arg buf Output buffer to hold string representation
  238. * @arg len length in bytes of the output buffer
  239. */
  240. char *idiagnl_exts2str(uint8_t attrs, char *buf, size_t len)
  241. {
  242. return __flags2str(attrs, buf, len, idiag_exts, ARRAY_SIZE(idiag_exts));
  243. }
  244. /** @} */
  245. /** @} */