diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/x25/x25_proc.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'net/x25/x25_proc.c')
-rw-r--r-- | net/x25/x25_proc.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c new file mode 100644 index 000000000000..dfb80116c59f --- /dev/null +++ b/net/x25/x25_proc.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /* | ||
2 | * X.25 Packet Layer release 002 | ||
3 | * | ||
4 | * This is ALPHA test software. This code may break your machine, | ||
5 | * randomly fail to work with new releases, misbehave and/or generally | ||
6 | * screw up. It might even work. | ||
7 | * | ||
8 | * This code REQUIRES 2.4 with seq_file support | ||
9 | * | ||
10 | * This module: | ||
11 | * This module is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * History | ||
17 | * 2002/10/06 Arnaldo Carvalho de Melo seq_file support | ||
18 | */ | ||
19 | |||
20 | #include <linux/config.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/proc_fs.h> | ||
23 | #include <linux/seq_file.h> | ||
24 | #include <net/sock.h> | ||
25 | #include <net/x25.h> | ||
26 | |||
27 | #ifdef CONFIG_PROC_FS | ||
28 | static __inline__ struct x25_route *x25_get_route_idx(loff_t pos) | ||
29 | { | ||
30 | struct list_head *route_entry; | ||
31 | struct x25_route *rt = NULL; | ||
32 | |||
33 | list_for_each(route_entry, &x25_route_list) { | ||
34 | rt = list_entry(route_entry, struct x25_route, node); | ||
35 | if (!pos--) | ||
36 | goto found; | ||
37 | } | ||
38 | rt = NULL; | ||
39 | found: | ||
40 | return rt; | ||
41 | } | ||
42 | |||
43 | static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos) | ||
44 | { | ||
45 | loff_t l = *pos; | ||
46 | |||
47 | read_lock_bh(&x25_route_list_lock); | ||
48 | return l ? x25_get_route_idx(--l) : SEQ_START_TOKEN; | ||
49 | } | ||
50 | |||
51 | static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos) | ||
52 | { | ||
53 | struct x25_route *rt; | ||
54 | |||
55 | ++*pos; | ||
56 | if (v == SEQ_START_TOKEN) { | ||
57 | rt = NULL; | ||
58 | if (!list_empty(&x25_route_list)) | ||
59 | rt = list_entry(x25_route_list.next, | ||
60 | struct x25_route, node); | ||
61 | goto out; | ||
62 | } | ||
63 | rt = v; | ||
64 | if (rt->node.next != &x25_route_list) | ||
65 | rt = list_entry(rt->node.next, struct x25_route, node); | ||
66 | else | ||
67 | rt = NULL; | ||
68 | out: | ||
69 | return rt; | ||
70 | } | ||
71 | |||
72 | static void x25_seq_route_stop(struct seq_file *seq, void *v) | ||
73 | { | ||
74 | read_unlock_bh(&x25_route_list_lock); | ||
75 | } | ||
76 | |||
77 | static int x25_seq_route_show(struct seq_file *seq, void *v) | ||
78 | { | ||
79 | struct x25_route *rt; | ||
80 | |||
81 | if (v == SEQ_START_TOKEN) { | ||
82 | seq_puts(seq, "Address Digits Device\n"); | ||
83 | goto out; | ||
84 | } | ||
85 | |||
86 | rt = v; | ||
87 | seq_printf(seq, "%-15s %-6d %-5s\n", | ||
88 | rt->address.x25_addr, rt->sigdigits, | ||
89 | rt->dev ? rt->dev->name : "???"); | ||
90 | out: | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static __inline__ struct sock *x25_get_socket_idx(loff_t pos) | ||
95 | { | ||
96 | struct sock *s; | ||
97 | struct hlist_node *node; | ||
98 | |||
99 | sk_for_each(s, node, &x25_list) | ||
100 | if (!pos--) | ||
101 | goto found; | ||
102 | s = NULL; | ||
103 | found: | ||
104 | return s; | ||
105 | } | ||
106 | |||
107 | static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos) | ||
108 | { | ||
109 | loff_t l = *pos; | ||
110 | |||
111 | read_lock_bh(&x25_list_lock); | ||
112 | return l ? x25_get_socket_idx(--l) : SEQ_START_TOKEN; | ||
113 | } | ||
114 | |||
115 | static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos) | ||
116 | { | ||
117 | struct sock *s; | ||
118 | |||
119 | ++*pos; | ||
120 | if (v == SEQ_START_TOKEN) { | ||
121 | s = sk_head(&x25_list); | ||
122 | goto out; | ||
123 | } | ||
124 | s = sk_next(v); | ||
125 | out: | ||
126 | return s; | ||
127 | } | ||
128 | |||
129 | static void x25_seq_socket_stop(struct seq_file *seq, void *v) | ||
130 | { | ||
131 | read_unlock_bh(&x25_list_lock); | ||
132 | } | ||
133 | |||
134 | static int x25_seq_socket_show(struct seq_file *seq, void *v) | ||
135 | { | ||
136 | struct sock *s; | ||
137 | struct x25_sock *x25; | ||
138 | struct net_device *dev; | ||
139 | const char *devname; | ||
140 | |||
141 | if (v == SEQ_START_TOKEN) { | ||
142 | seq_printf(seq, "dest_addr src_addr dev lci st vs vr " | ||
143 | "va t t2 t21 t22 t23 Snd-Q Rcv-Q inode\n"); | ||
144 | goto out; | ||
145 | } | ||
146 | |||
147 | s = v; | ||
148 | x25 = x25_sk(s); | ||
149 | |||
150 | if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL) | ||
151 | devname = "???"; | ||
152 | else | ||
153 | devname = x25->neighbour->dev->name; | ||
154 | |||
155 | seq_printf(seq, "%-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu " | ||
156 | "%3lu %3lu %3lu %5d %5d %ld\n", | ||
157 | !x25->dest_addr.x25_addr[0] ? "*" : x25->dest_addr.x25_addr, | ||
158 | !x25->source_addr.x25_addr[0] ? "*" : x25->source_addr.x25_addr, | ||
159 | devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr, | ||
160 | x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ, | ||
161 | x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ, | ||
162 | atomic_read(&s->sk_wmem_alloc), | ||
163 | atomic_read(&s->sk_rmem_alloc), | ||
164 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); | ||
165 | out: | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static struct seq_operations x25_seq_route_ops = { | ||
170 | .start = x25_seq_route_start, | ||
171 | .next = x25_seq_route_next, | ||
172 | .stop = x25_seq_route_stop, | ||
173 | .show = x25_seq_route_show, | ||
174 | }; | ||
175 | |||
176 | static struct seq_operations x25_seq_socket_ops = { | ||
177 | .start = x25_seq_socket_start, | ||
178 | .next = x25_seq_socket_next, | ||
179 | .stop = x25_seq_socket_stop, | ||
180 | .show = x25_seq_socket_show, | ||
181 | }; | ||
182 | |||
183 | static int x25_seq_socket_open(struct inode *inode, struct file *file) | ||
184 | { | ||
185 | return seq_open(file, &x25_seq_socket_ops); | ||
186 | } | ||
187 | |||
188 | static int x25_seq_route_open(struct inode *inode, struct file *file) | ||
189 | { | ||
190 | return seq_open(file, &x25_seq_route_ops); | ||
191 | } | ||
192 | |||
193 | static struct file_operations x25_seq_socket_fops = { | ||
194 | .owner = THIS_MODULE, | ||
195 | .open = x25_seq_socket_open, | ||
196 | .read = seq_read, | ||
197 | .llseek = seq_lseek, | ||
198 | .release = seq_release, | ||
199 | }; | ||
200 | |||
201 | static struct file_operations x25_seq_route_fops = { | ||
202 | .owner = THIS_MODULE, | ||
203 | .open = x25_seq_route_open, | ||
204 | .read = seq_read, | ||
205 | .llseek = seq_lseek, | ||
206 | .release = seq_release, | ||
207 | }; | ||
208 | |||
209 | static struct proc_dir_entry *x25_proc_dir; | ||
210 | |||
211 | int __init x25_proc_init(void) | ||
212 | { | ||
213 | struct proc_dir_entry *p; | ||
214 | int rc = -ENOMEM; | ||
215 | |||
216 | x25_proc_dir = proc_mkdir("x25", proc_net); | ||
217 | if (!x25_proc_dir) | ||
218 | goto out; | ||
219 | |||
220 | p = create_proc_entry("route", S_IRUGO, x25_proc_dir); | ||
221 | if (!p) | ||
222 | goto out_route; | ||
223 | p->proc_fops = &x25_seq_route_fops; | ||
224 | |||
225 | p = create_proc_entry("socket", S_IRUGO, x25_proc_dir); | ||
226 | if (!p) | ||
227 | goto out_socket; | ||
228 | p->proc_fops = &x25_seq_socket_fops; | ||
229 | rc = 0; | ||
230 | out: | ||
231 | return rc; | ||
232 | out_socket: | ||
233 | remove_proc_entry("route", x25_proc_dir); | ||
234 | out_route: | ||
235 | remove_proc_entry("x25", proc_net); | ||
236 | goto out; | ||
237 | } | ||
238 | |||
239 | void __exit x25_proc_exit(void) | ||
240 | { | ||
241 | remove_proc_entry("route", x25_proc_dir); | ||
242 | remove_proc_entry("socket", x25_proc_dir); | ||
243 | remove_proc_entry("x25", proc_net); | ||
244 | } | ||
245 | |||
246 | #else /* CONFIG_PROC_FS */ | ||
247 | |||
248 | int __init x25_proc_init(void) | ||
249 | { | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | void __exit x25_proc_exit(void) | ||
254 | { | ||
255 | } | ||
256 | #endif /* CONFIG_PROC_FS */ | ||