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 #include <linux/autoconf.h>
22
23 #include <asm/segment.h>
24
25 #include <linux/errno.h>
26 #include <linux/sched.h>
27 #include <linux/proc_fs.h>
28 #include <linux/stat.h>
29
30
31 static int proc_readnet(struct inode * inode, struct file * file,
32 char * buf, int count);
33 static int proc_readnetdir(struct inode *, struct file *,
34 struct dirent *, int);
35 static int proc_lookupnet(struct inode *,const char *,int,struct inode **);
36
37
38
39 #ifdef CONFIG_INET
40 extern int unix_get_info(char *);
41 extern int tcp_get_info(char *);
42 extern int udp_get_info(char *);
43 extern int raw_get_info(char *);
44 extern int arp_get_info(char *);
45 extern int dev_get_info(char *);
46 extern int rt_get_info(char *);
47 #endif
48
49
50 static struct file_operations proc_net_operations = {
51 NULL,
52 proc_readnet,
53 NULL,
54 proc_readnetdir,
55 NULL,
56 NULL,
57 NULL,
58 NULL,
59 NULL,
60 NULL
61 };
62
63
64
65
66 struct inode_operations proc_net_inode_operations = {
67 &proc_net_operations,
68 NULL,
69 proc_lookupnet,
70 NULL,
71 NULL,
72 NULL,
73 NULL,
74 NULL,
75 NULL,
76 NULL,
77 NULL,
78 NULL,
79 NULL,
80 NULL,
81 NULL
82 };
83
84 static struct proc_dir_entry net_dir[] = {
85 { 1,2,".." },
86 { 8,1,"." }
87 #ifdef CONFIG_INET
88 ,{ 128,4,"unix" },
89 { 129,3,"arp" },
90 { 130,5,"route" },
91 { 131,3,"dev" },
92 { 132,3,"raw" },
93 { 133,3,"tcp" },
94 { 134,3,"udp" }
95 #endif
96 };
97
98 #define NR_NET_DIRENTRY ((sizeof (net_dir))/(sizeof (net_dir[0])))
99
100
101 static int proc_lookupnet(struct inode * dir,const char * name, int len,
102 struct inode ** result)
103 {
104 unsigned int ino;
105 int i;
106
107 *result = NULL;
108 if (!dir)
109 return -ENOENT;
110 if (!S_ISDIR(dir->i_mode)) {
111 iput(dir);
112 return -ENOENT;
113 }
114 i = NR_NET_DIRENTRY;
115 while (i-- > 0 && !proc_match(len,name,net_dir+i))
116 ;
117 if (i < 0) {
118 iput(dir);
119 return -ENOENT;
120 }
121 ino = net_dir[i].low_ino;
122 if (!(*result = iget(dir->i_sb,ino))) {
123 iput(dir);
124 return -ENOENT;
125 }
126 iput(dir);
127 return 0;
128 }
129
130 static int proc_readnetdir(struct inode * inode, struct file * filp,
131 struct dirent * dirent, int count)
132 {
133 struct proc_dir_entry * de;
134 unsigned int ino;
135 int i,j;
136
137 if (!inode || !S_ISDIR(inode->i_mode))
138 return -EBADF;
139 ino = inode->i_ino;
140 if (((unsigned) filp->f_pos) < NR_NET_DIRENTRY) {
141 de = net_dir + filp->f_pos;
142 filp->f_pos++;
143 i = de->namelen;
144 ino = de->low_ino;
145 put_fs_long(ino, &dirent->d_ino);
146 put_fs_word(i,&dirent->d_reclen);
147 put_fs_byte(0,i+dirent->d_name);
148 j = i;
149 while (i--)
150 put_fs_byte(de->name[i], i+dirent->d_name);
151 return j;
152 }
153 return 0;
154 }
155
156
157 static int proc_readnet(struct inode * inode, struct file * file,
158 char * buf, int count)
159 {
160 char * page;
161 int length;
162 int end;
163 unsigned int ino;
164
165 if (count < 0)
166 return -EINVAL;
167 if (!(page = (char*) __get_free_page(GFP_KERNEL)))
168 return -ENOMEM;
169 ino = inode->i_ino;
170 switch (ino) {
171 #ifdef CONFIG_INET
172 case 128:
173 length = unix_get_info(page);
174 break;
175 case 129:
176 length = arp_get_info(page);
177 break;
178 case 130:
179 length = rt_get_info(page);
180 break;
181 case 131:
182 length = dev_get_info(page);
183 break;
184 case 132:
185 length = raw_get_info(page);
186 break;
187 case 133:
188 length = tcp_get_info(page);
189 break;
190 case 134:
191 length = udp_get_info(page);
192 break;
193 #endif
194 default:
195 free_page((unsigned long) page);
196 return -EBADF;
197 }
198 if (file->f_pos >= length) {
199 free_page((unsigned long) page);
200 return 0;
201 }
202 if (count + file->f_pos > length)
203 count = length - file->f_pos;
204 end = count + file->f_pos;
205 memcpy_tofs(buf, page + file->f_pos, count);
206 free_page((unsigned long) page);
207 file->f_pos = end;
208 return count;
209
210 }