This source file includes following definitions.
- proc_lookupnet
- proc_readnetdir
- proc_readnet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <linux/autoconf.h>
24
25 #include <asm/segment.h>
26
27 #include <linux/errno.h>
28 #include <linux/sched.h>
29 #include <linux/proc_fs.h>
30 #include <linux/stat.h>
31
32
33 static int proc_readnet(struct inode * inode, struct file * file,
34 char * buf, int count);
35 static int proc_readnetdir(struct inode *, struct file *,
36 struct dirent *, int);
37 static int proc_lookupnet(struct inode *,const char *,int,struct inode **);
38
39
40
41 extern int unix_get_info(char *, char **, off_t, int);
42 #ifdef CONFIG_INET
43 extern int tcp_get_info(char *, char **, off_t, int);
44 extern int udp_get_info(char *, char **, off_t, int);
45 extern int raw_get_info(char *, char **, off_t, int);
46 extern int arp_get_info(char *, char **, off_t, int);
47 extern int rarp_get_info(char *, char **, off_t, int);
48 extern int dev_get_info(char *, char **, off_t, int);
49 extern int rt_get_info(char *, char **, off_t, int);
50 #endif
51 #ifdef CONFIG_IPX
52 extern int ipx_get_info(char *, char **, off_t, int);
53 extern int ipx_rt_get_info(char *, char **, off_t, int);
54 #endif
55 #ifdef CONFIG_AX25
56 extern int ax25_get_info(char *, char **, off_t, int);
57 extern int ax25_rt_get_info(char *, char **, off_t, int);
58 #ifdef CONFIG_NETROM
59 extern int nr_get_info(char *, char **, off_t, int);
60 extern int nr_nodes_get_info(char *, char **, off_t, int);
61 extern int nr_neigh_get_info(char *, char **, off_t, int);
62 #endif
63 #endif
64
65
66 static struct file_operations proc_net_operations = {
67 NULL,
68 proc_readnet,
69 NULL,
70 proc_readnetdir,
71 NULL,
72 NULL,
73 NULL,
74 NULL,
75 NULL,
76 NULL
77 };
78
79
80
81
82 struct inode_operations proc_net_inode_operations = {
83 &proc_net_operations,
84 NULL,
85 proc_lookupnet,
86 NULL,
87 NULL,
88 NULL,
89 NULL,
90 NULL,
91 NULL,
92 NULL,
93 NULL,
94 NULL,
95 NULL,
96 NULL,
97 NULL
98 };
99
100 static struct proc_dir_entry net_dir[] = {
101 { 1,2,".." },
102 { 8,1,"." },
103 { 128,4,"unix" }
104 #ifdef CONFIG_INET
105 ,{ 129,3,"arp" },
106 { 130,5,"route" },
107 { 131,3,"dev" },
108 { 132,3,"raw" },
109 { 133,3,"tcp" },
110 { 134,3,"udp" }
111 #ifdef CONFIG_INET_RARP
112 ,{ 135,4,"rarp"}
113 #endif
114 #endif
115 #ifdef CONFIG_IPX
116 ,{ 136,9,"ipx_route" },
117 { 137,3,"ipx" }
118 #endif
119 #ifdef CONFIG_AX25
120 ,{ 138,10,"ax25_route" },
121 { 139,4,"ax25" }
122 #ifdef CONFIG_NETROM
123 ,{ 140,8,"nr_nodes" },
124 { 141,8,"nr_neigh" },
125 { 142,2,"nr" }
126 #endif
127 #endif
128 };
129
130 #define NR_NET_DIRENTRY ((sizeof (net_dir))/(sizeof (net_dir[0])))
131
132
133 static int proc_lookupnet(struct inode * dir,const char * name, int len,
134 struct inode ** result)
135 {
136 unsigned int ino;
137 int i;
138
139 *result = NULL;
140 if (!dir)
141 return -ENOENT;
142 if (!S_ISDIR(dir->i_mode)) {
143 iput(dir);
144 return -ENOENT;
145 }
146 i = NR_NET_DIRENTRY;
147 while (i-- > 0 && !proc_match(len,name,net_dir+i))
148 ;
149 if (i < 0) {
150 iput(dir);
151 return -ENOENT;
152 }
153 ino = net_dir[i].low_ino;
154 if (!(*result = iget(dir->i_sb,ino))) {
155 iput(dir);
156 return -ENOENT;
157 }
158 iput(dir);
159 return 0;
160 }
161
162 static int proc_readnetdir(struct inode * inode, struct file * filp,
163 struct dirent * dirent, int count)
164 {
165 struct proc_dir_entry * de;
166 unsigned int ino;
167 int i,j;
168
169 if (!inode || !S_ISDIR(inode->i_mode))
170 return -EBADF;
171 ino = inode->i_ino;
172 if (((unsigned) filp->f_pos) < NR_NET_DIRENTRY) {
173 de = net_dir + filp->f_pos;
174 filp->f_pos++;
175 i = de->namelen;
176 ino = de->low_ino;
177 put_fs_long(ino, &dirent->d_ino);
178 put_fs_word(i,&dirent->d_reclen);
179 put_fs_byte(0,i+dirent->d_name);
180 j = i;
181 while (i--)
182 put_fs_byte(de->name[i], i+dirent->d_name);
183 return j;
184 }
185 return 0;
186 }
187
188
189 #define PROC_BLOCK_SIZE (3*1024)
190
191 static int proc_readnet(struct inode * inode, struct file * file,
192 char * buf, int count)
193 {
194 char * page;
195 int length;
196 unsigned int ino;
197 int bytes=count;
198 int thistime;
199 int copied=0;
200 char *start;
201
202 if (count < 0)
203 return -EINVAL;
204 if (!(page = (char*) __get_free_page(GFP_KERNEL)))
205 return -ENOMEM;
206 ino = inode->i_ino;
207
208 while(bytes>0)
209 {
210 thistime=bytes;
211 if(bytes>PROC_BLOCK_SIZE)
212 thistime=PROC_BLOCK_SIZE;
213
214 switch (ino)
215 {
216 case 128:
217 length = unix_get_info(page,&start,file->f_pos,thistime);
218 break;
219 #ifdef CONFIG_INET
220 case 129:
221 length = arp_get_info(page,&start,file->f_pos,thistime);
222 break;
223 case 130:
224 length = rt_get_info(page,&start,file->f_pos,thistime);
225 break;
226 case 131:
227 length = dev_get_info(page,&start,file->f_pos,thistime);
228 break;
229 case 132:
230 length = raw_get_info(page,&start,file->f_pos,thistime);
231 break;
232 case 133:
233 length = tcp_get_info(page,&start,file->f_pos,thistime);
234 break;
235 case 134:
236 length = udp_get_info(page,&start,file->f_pos,thistime);
237 break;
238 #ifdef CONFIG_INET_RARP
239 case 135:
240 length = rarp_get_info(page,&start,file->f_pos,thistime);
241 break;
242 #endif
243 #endif
244 #ifdef CONFIG_IPX
245 case 136:
246 length = ipx_rt_get_info(page,&start,file->f_pos,thistime);
247 break;
248 case 137:
249 length = ipx_get_info(page,&start,file->f_pos,thistime);
250 break;
251 #endif
252 #ifdef CONFIG_AX25
253 case 138:
254 length = ax25_rt_get_info(page,&start,file->f_pos,thistime);
255 break;
256 case 139:
257 length = ax25_get_info(page,&start,file->f_pos,thistime);
258 break;
259 #ifdef CONFIG_NETROM
260 case 140:
261 length = nr_nodes_get_info(page,&start,file->f_pos,thistime);
262 break;
263 case 141:
264 length = nr_neigh_get_info(page,&start,file->f_pos,thistime);
265 break;
266 case 142:
267 length = nr_get_info(page,&start,file->f_pos,thistime);
268 break;
269 #endif
270 #endif
271
272 default:
273 free_page((unsigned long) page);
274 return -EBADF;
275 }
276
277
278
279
280
281
282
283 if (length <= 0)
284 break;
285
286
287
288 memcpy_tofs(buf+copied, start, length);
289 file->f_pos+=length;
290 bytes-=length;
291 copied+=length;
292 if(length<thistime)
293 break;
294 }
295 free_page((unsigned long) page);
296 return copied;
297
298 }