PageRenderTime 26ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/release/src-rt/linux/linux-2.6/net/ipx/ipx_proc.c

https://gitlab.com/envieidoc/advancedtomato2
C | 407 lines | 345 code | 57 blank | 5 comment | 37 complexity | 6921bf6c66b73e714b41f28bfcf48835 MD5 | raw file
  1. /*
  2. * IPX proc routines
  3. *
  4. * Copyright(C) Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2002
  5. */
  6. #include <linux/init.h>
  7. #ifdef CONFIG_PROC_FS
  8. #include <linux/proc_fs.h>
  9. #include <linux/spinlock.h>
  10. #include <linux/seq_file.h>
  11. #include <net/tcp_states.h>
  12. #include <net/ipx.h>
  13. static __inline__ struct ipx_interface *ipx_get_interface_idx(loff_t pos)
  14. {
  15. struct ipx_interface *i;
  16. list_for_each_entry(i, &ipx_interfaces, node)
  17. if (!pos--)
  18. goto out;
  19. i = NULL;
  20. out:
  21. return i;
  22. }
  23. static struct ipx_interface *ipx_interfaces_next(struct ipx_interface *i)
  24. {
  25. struct ipx_interface *rc = NULL;
  26. if (i->node.next != &ipx_interfaces)
  27. rc = list_entry(i->node.next, struct ipx_interface, node);
  28. return rc;
  29. }
  30. static void *ipx_seq_interface_start(struct seq_file *seq, loff_t *pos)
  31. {
  32. loff_t l = *pos;
  33. spin_lock_bh(&ipx_interfaces_lock);
  34. return l ? ipx_get_interface_idx(--l) : SEQ_START_TOKEN;
  35. }
  36. static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
  37. {
  38. struct ipx_interface *i;
  39. ++*pos;
  40. if (v == SEQ_START_TOKEN)
  41. i = ipx_interfaces_head();
  42. else
  43. i = ipx_interfaces_next(v);
  44. return i;
  45. }
  46. static void ipx_seq_interface_stop(struct seq_file *seq, void *v)
  47. {
  48. spin_unlock_bh(&ipx_interfaces_lock);
  49. }
  50. static int ipx_seq_interface_show(struct seq_file *seq, void *v)
  51. {
  52. struct ipx_interface *i;
  53. if (v == SEQ_START_TOKEN) {
  54. seq_puts(seq, "Network Node_Address Primary Device "
  55. "Frame_Type");
  56. #ifdef IPX_REFCNT_DEBUG
  57. seq_puts(seq, " refcnt");
  58. #endif
  59. seq_puts(seq, "\n");
  60. goto out;
  61. }
  62. i = v;
  63. seq_printf(seq, "%08lX ", (unsigned long int)ntohl(i->if_netnum));
  64. seq_printf(seq, "%02X%02X%02X%02X%02X%02X ",
  65. i->if_node[0], i->if_node[1], i->if_node[2],
  66. i->if_node[3], i->if_node[4], i->if_node[5]);
  67. seq_printf(seq, "%-9s", i == ipx_primary_net ? "Yes" : "No");
  68. seq_printf(seq, "%-11s", ipx_device_name(i));
  69. seq_printf(seq, "%-9s", ipx_frame_name(i->if_dlink_type));
  70. #ifdef IPX_REFCNT_DEBUG
  71. seq_printf(seq, "%6d", atomic_read(&i->refcnt));
  72. #endif
  73. seq_puts(seq, "\n");
  74. out:
  75. return 0;
  76. }
  77. static struct ipx_route *ipx_routes_head(void)
  78. {
  79. struct ipx_route *rc = NULL;
  80. if (!list_empty(&ipx_routes))
  81. rc = list_entry(ipx_routes.next, struct ipx_route, node);
  82. return rc;
  83. }
  84. static struct ipx_route *ipx_routes_next(struct ipx_route *r)
  85. {
  86. struct ipx_route *rc = NULL;
  87. if (r->node.next != &ipx_routes)
  88. rc = list_entry(r->node.next, struct ipx_route, node);
  89. return rc;
  90. }
  91. static __inline__ struct ipx_route *ipx_get_route_idx(loff_t pos)
  92. {
  93. struct ipx_route *r;
  94. list_for_each_entry(r, &ipx_routes, node)
  95. if (!pos--)
  96. goto out;
  97. r = NULL;
  98. out:
  99. return r;
  100. }
  101. static void *ipx_seq_route_start(struct seq_file *seq, loff_t *pos)
  102. {
  103. loff_t l = *pos;
  104. read_lock_bh(&ipx_routes_lock);
  105. return l ? ipx_get_route_idx(--l) : SEQ_START_TOKEN;
  106. }
  107. static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
  108. {
  109. struct ipx_route *r;
  110. ++*pos;
  111. if (v == SEQ_START_TOKEN)
  112. r = ipx_routes_head();
  113. else
  114. r = ipx_routes_next(v);
  115. return r;
  116. }
  117. static void ipx_seq_route_stop(struct seq_file *seq, void *v)
  118. {
  119. read_unlock_bh(&ipx_routes_lock);
  120. }
  121. static int ipx_seq_route_show(struct seq_file *seq, void *v)
  122. {
  123. struct ipx_route *rt;
  124. if (v == SEQ_START_TOKEN) {
  125. seq_puts(seq, "Network Router_Net Router_Node\n");
  126. goto out;
  127. }
  128. rt = v;
  129. seq_printf(seq, "%08lX ", (unsigned long int)ntohl(rt->ir_net));
  130. if (rt->ir_routed)
  131. seq_printf(seq, "%08lX %02X%02X%02X%02X%02X%02X\n",
  132. (long unsigned int)ntohl(rt->ir_intrfc->if_netnum),
  133. rt->ir_router_node[0], rt->ir_router_node[1],
  134. rt->ir_router_node[2], rt->ir_router_node[3],
  135. rt->ir_router_node[4], rt->ir_router_node[5]);
  136. else
  137. seq_puts(seq, "Directly Connected\n");
  138. out:
  139. return 0;
  140. }
  141. static __inline__ struct sock *ipx_get_socket_idx(loff_t pos)
  142. {
  143. struct sock *s = NULL;
  144. struct hlist_node *node;
  145. struct ipx_interface *i;
  146. list_for_each_entry(i, &ipx_interfaces, node) {
  147. spin_lock_bh(&i->if_sklist_lock);
  148. sk_for_each(s, node, &i->if_sklist) {
  149. if (!pos)
  150. break;
  151. --pos;
  152. }
  153. spin_unlock_bh(&i->if_sklist_lock);
  154. if (!pos) {
  155. if (node)
  156. goto found;
  157. break;
  158. }
  159. }
  160. s = NULL;
  161. found:
  162. return s;
  163. }
  164. static void *ipx_seq_socket_start(struct seq_file *seq, loff_t *pos)
  165. {
  166. loff_t l = *pos;
  167. spin_lock_bh(&ipx_interfaces_lock);
  168. return l ? ipx_get_socket_idx(--l) : SEQ_START_TOKEN;
  169. }
  170. static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
  171. {
  172. struct sock* sk, *next;
  173. struct ipx_interface *i;
  174. struct ipx_sock *ipxs;
  175. ++*pos;
  176. if (v == SEQ_START_TOKEN) {
  177. sk = NULL;
  178. i = ipx_interfaces_head();
  179. if (!i)
  180. goto out;
  181. sk = sk_head(&i->if_sklist);
  182. if (sk)
  183. spin_lock_bh(&i->if_sklist_lock);
  184. goto out;
  185. }
  186. sk = v;
  187. next = sk_next(sk);
  188. if (next) {
  189. sk = next;
  190. goto out;
  191. }
  192. ipxs = ipx_sk(sk);
  193. i = ipxs->intrfc;
  194. spin_unlock_bh(&i->if_sklist_lock);
  195. sk = NULL;
  196. for (;;) {
  197. i = ipx_interfaces_next(i);
  198. if (!i)
  199. break;
  200. spin_lock_bh(&i->if_sklist_lock);
  201. if (!hlist_empty(&i->if_sklist)) {
  202. sk = sk_head(&i->if_sklist);
  203. break;
  204. }
  205. spin_unlock_bh(&i->if_sklist_lock);
  206. }
  207. out:
  208. return sk;
  209. }
  210. static int ipx_seq_socket_show(struct seq_file *seq, void *v)
  211. {
  212. struct sock *s;
  213. struct ipx_sock *ipxs;
  214. if (v == SEQ_START_TOKEN) {
  215. #ifdef CONFIG_IPX_INTERN
  216. seq_puts(seq, "Local_Address "
  217. "Remote_Address Tx_Queue "
  218. "Rx_Queue State Uid\n");
  219. #else
  220. seq_puts(seq, "Local_Address Remote_Address "
  221. "Tx_Queue Rx_Queue State Uid\n");
  222. #endif
  223. goto out;
  224. }
  225. s = v;
  226. ipxs = ipx_sk(s);
  227. #ifdef CONFIG_IPX_INTERN
  228. seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
  229. (unsigned long)ntohl(ipxs->intrfc->if_netnum),
  230. ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3],
  231. ipxs->node[4], ipxs->node[5], ntohs(ipxs->port));
  232. #else
  233. seq_printf(seq, "%08lX:%04X ", (unsigned long) ntohl(ipxs->intrfc->if_netnum),
  234. ntohs(ipxs->port));
  235. #endif /* CONFIG_IPX_INTERN */
  236. if (s->sk_state != TCP_ESTABLISHED)
  237. seq_printf(seq, "%-28s", "Not_Connected");
  238. else {
  239. seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
  240. (unsigned long)ntohl(ipxs->dest_addr.net),
  241. ipxs->dest_addr.node[0], ipxs->dest_addr.node[1],
  242. ipxs->dest_addr.node[2], ipxs->dest_addr.node[3],
  243. ipxs->dest_addr.node[4], ipxs->dest_addr.node[5],
  244. ntohs(ipxs->dest_addr.sock));
  245. }
  246. seq_printf(seq, "%08X %08X %02X %03d\n",
  247. sk_wmem_alloc_get(s),
  248. sk_rmem_alloc_get(s),
  249. s->sk_state, SOCK_INODE(s->sk_socket)->i_uid);
  250. out:
  251. return 0;
  252. }
  253. static struct seq_operations ipx_seq_interface_ops = {
  254. .start = ipx_seq_interface_start,
  255. .next = ipx_seq_interface_next,
  256. .stop = ipx_seq_interface_stop,
  257. .show = ipx_seq_interface_show,
  258. };
  259. static struct seq_operations ipx_seq_route_ops = {
  260. .start = ipx_seq_route_start,
  261. .next = ipx_seq_route_next,
  262. .stop = ipx_seq_route_stop,
  263. .show = ipx_seq_route_show,
  264. };
  265. static struct seq_operations ipx_seq_socket_ops = {
  266. .start = ipx_seq_socket_start,
  267. .next = ipx_seq_socket_next,
  268. .stop = ipx_seq_interface_stop,
  269. .show = ipx_seq_socket_show,
  270. };
  271. static int ipx_seq_route_open(struct inode *inode, struct file *file)
  272. {
  273. return seq_open(file, &ipx_seq_route_ops);
  274. }
  275. static int ipx_seq_interface_open(struct inode *inode, struct file *file)
  276. {
  277. return seq_open(file, &ipx_seq_interface_ops);
  278. }
  279. static int ipx_seq_socket_open(struct inode *inode, struct file *file)
  280. {
  281. return seq_open(file, &ipx_seq_socket_ops);
  282. }
  283. static const struct file_operations ipx_seq_interface_fops = {
  284. .owner = THIS_MODULE,
  285. .open = ipx_seq_interface_open,
  286. .read = seq_read,
  287. .llseek = seq_lseek,
  288. .release = seq_release,
  289. };
  290. static const struct file_operations ipx_seq_route_fops = {
  291. .owner = THIS_MODULE,
  292. .open = ipx_seq_route_open,
  293. .read = seq_read,
  294. .llseek = seq_lseek,
  295. .release = seq_release,
  296. };
  297. static const struct file_operations ipx_seq_socket_fops = {
  298. .owner = THIS_MODULE,
  299. .open = ipx_seq_socket_open,
  300. .read = seq_read,
  301. .llseek = seq_lseek,
  302. .release = seq_release,
  303. };
  304. static struct proc_dir_entry *ipx_proc_dir;
  305. int __init ipx_proc_init(void)
  306. {
  307. struct proc_dir_entry *p;
  308. int rc = -ENOMEM;
  309. ipx_proc_dir = proc_mkdir("ipx", proc_net);
  310. if (!ipx_proc_dir)
  311. goto out;
  312. p = create_proc_entry("interface", S_IRUGO, ipx_proc_dir);
  313. if (!p)
  314. goto out_interface;
  315. p->proc_fops = &ipx_seq_interface_fops;
  316. p = create_proc_entry("route", S_IRUGO, ipx_proc_dir);
  317. if (!p)
  318. goto out_route;
  319. p->proc_fops = &ipx_seq_route_fops;
  320. p = create_proc_entry("socket", S_IRUGO, ipx_proc_dir);
  321. if (!p)
  322. goto out_socket;
  323. p->proc_fops = &ipx_seq_socket_fops;
  324. rc = 0;
  325. out:
  326. return rc;
  327. out_socket:
  328. remove_proc_entry("route", ipx_proc_dir);
  329. out_route:
  330. remove_proc_entry("interface", ipx_proc_dir);
  331. out_interface:
  332. remove_proc_entry("ipx", proc_net);
  333. goto out;
  334. }
  335. void __exit ipx_proc_exit(void)
  336. {
  337. remove_proc_entry("interface", ipx_proc_dir);
  338. remove_proc_entry("route", ipx_proc_dir);
  339. remove_proc_entry("socket", ipx_proc_dir);
  340. remove_proc_entry("ipx", proc_net);
  341. }
  342. #else /* CONFIG_PROC_FS */
  343. int __init ipx_proc_init(void)
  344. {
  345. return 0;
  346. }
  347. void __exit ipx_proc_exit(void)
  348. {
  349. }
  350. #endif /* CONFIG_PROC_FS */