Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

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