1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include <asm/system.h>
36#include <linux/sched.h>
37#include <linux/socket.h>
38#include <linux/net.h>
39#include <linux/un.h>
40#include <linux/in.h>
41#include <linux/param.h>
42#include <linux/inet.h>
43#include <linux/netdevice.h>
44#include <net/ip.h>
45#include <net/icmp.h>
46#include <net/protocol.h>
47#include <net/tcp.h>
48#include <net/udp.h>
49#include <linux/skbuff.h>
50#include <net/sock.h>
51#include <net/raw.h>
52
53
54static inline void get__openreq(struct sock *sk, struct open_request *req,
55 char *tmpbuf,
56 int i)
57{
58 sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
59 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u",
60 i,
61 (long unsigned int)req->af.v4_req.loc_addr,
62 ntohs(sk->sport),
63 (long unsigned int)req->af.v4_req.rmt_addr,
64 ntohs(req->rmt_port),
65 TCP_SYN_RECV,
66 0,0,
67 1,
68 (unsigned long)(req->expires - jiffies),
69 req->retrans,
70 sk->socket ? sk->socket->inode->i_uid : 0,
71 0,
72 0
73 );
74}
75
76
77static inline void get__sock(struct sock *sp, char *tmpbuf, int i, int format)
78{
79 unsigned long dest, src;
80 unsigned short destp, srcp;
81 int timer_active, timer_active1, timer_active2;
82 int tw_bucket = 0;
83 unsigned long timer_expires;
84 struct tcp_opt *tp = &sp->tp_pinfo.af_tcp;
85
86 dest = sp->daddr;
87 src = sp->rcv_saddr;
88 destp = sp->dport;
89 srcp = sp->sport;
90
91
92
93
94
95
96
97
98
99
100 destp = ntohs(destp);
101 srcp = ntohs(srcp);
102 if((format == 0) && (sp->state == TCP_TIME_WAIT)) {
103 extern int tcp_tw_death_row_slot;
104 struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sp;
105 int slot_dist;
106
107 tw_bucket = 1;
108 timer_active1 = timer_active2 = 0;
109 timer_active = 3;
110 slot_dist = tw->death_slot;
111 if(slot_dist > tcp_tw_death_row_slot)
112 slot_dist = (TCP_TWKILL_SLOTS - slot_dist) + tcp_tw_death_row_slot;
113 else
114 slot_dist = tcp_tw_death_row_slot - slot_dist;
115 timer_expires = jiffies + (slot_dist * TCP_TWKILL_PERIOD);
116 } else {
117 timer_active1 = del_timer(&tp->retransmit_timer);
118 timer_active2 = del_timer(&sp->timer);
119 if (!timer_active1) tp->retransmit_timer.expires=0;
120 if (!timer_active2) sp->timer.expires=0;
121 timer_active = 0;
122 timer_expires = (unsigned) -1;
123 }
124 if (timer_active1 && tp->retransmit_timer.expires < timer_expires) {
125 timer_active = 1;
126 timer_expires = tp->retransmit_timer.expires;
127 }
128 if (timer_active2 && sp->timer.expires < timer_expires) {
129 timer_active = 2;
130 timer_expires = sp->timer.expires;
131 }
132 if(timer_active == 0)
133 timer_expires = jiffies;
134 sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
135 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld",
136 i, src, srcp, dest, destp, sp->state,
137 (tw_bucket ?
138 0 :
139 (format == 0) ?
140 tp->write_seq-tp->snd_una : atomic_read(&sp->wmem_alloc)),
141 (tw_bucket ?
142 0 :
143 (format == 0) ?
144 tp->rcv_nxt-tp->copied_seq: atomic_read(&sp->rmem_alloc)),
145 timer_active, timer_expires-jiffies,
146 (tw_bucket ? 0 : tp->retransmits),
147 (!tw_bucket && sp->socket) ? sp->socket->inode->i_uid : 0,
148 (!tw_bucket && timer_active) ? sp->timeout : 0,
149 (!tw_bucket && sp->socket) ? sp->socket->inode->i_ino : 0);
150
151 if (timer_active1) add_timer(&tp->retransmit_timer);
152 if (timer_active2) add_timer(&sp->timer);
153}
154
155
156
157
158
159
160
161
162
163
164
165static int
166get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t offset, int length)
167{
168 struct sock *sp, *next;
169 int len=0, i = 0;
170 off_t pos=0;
171 off_t begin;
172 char tmpbuf[129];
173
174 if (offset < 128)
175 len += sprintf(buffer, "%-127s\n",
176 " sl local_address rem_address st tx_queue "
177 "rx_queue tr tm->when retrnsmt uid timeout inode");
178 pos = 128;
179 SOCKHASH_LOCK();
180 sp = pro->sklist_next;
181 while(sp != (struct sock *)pro) {
182 if (format == 0 && sp->state == TCP_LISTEN) {
183 struct open_request *req;
184
185 for (req = sp->tp_pinfo.af_tcp.syn_wait_queue; req;
186 i++, req = req->dl_next) {
187 if (req->sk)
188 continue;
189 pos += 128;
190 if (pos < offset)
191 continue;
192 get__openreq(sp, req, tmpbuf, i);
193 len += sprintf(buffer+len, "%-127s\n", tmpbuf);
194 if(len >= length)
195 goto out;
196 }
197 }
198
199 pos += 128;
200 if (pos < offset)
201 goto next;
202
203 get__sock(sp, tmpbuf, i, format);
204
205 len += sprintf(buffer+len, "%-127s\n", tmpbuf);
206 if(len >= length)
207 break;
208 next:
209 next = sp->sklist_next;
210 sp = next;
211 i++;
212 }
213out:
214 SOCKHASH_UNLOCK();
215
216 begin = len - (pos - offset);
217 *start = buffer + begin;
218 len -= begin;
219 if(len>length)
220 len = length;
221 if (len<0)
222 len = 0;
223 return len;
224}
225
226int tcp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
227{
228 return get__netinfo(&tcp_prot, buffer,0, start, offset, length);
229}
230
231int udp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
232{
233 return get__netinfo(&udp_prot, buffer,1, start, offset, length);
234}
235
236int raw_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
237{
238 return get__netinfo(&raw_prot, buffer,1, start, offset, length);
239}
240
241
242
243
244int afinet_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
245{
246
247 extern int socket_get_info(char *, char **, off_t, int);
248
249 int len = socket_get_info(buffer,start,offset,length);
250
251 len += sprintf(buffer+len,"TCP: inuse %d highest %d\n",
252 tcp_prot.inuse, tcp_prot.highestinuse);
253 len += sprintf(buffer+len,"UDP: inuse %d highest %d\n",
254 udp_prot.inuse, udp_prot.highestinuse);
255 len += sprintf(buffer+len,"RAW: inuse %d highest %d\n",
256 raw_prot.inuse, raw_prot.highestinuse);
257 if (offset >= len)
258 {
259 *start = buffer;
260 return 0;
261 }
262 *start = buffer + offset;
263 len -= offset;
264 if (len > length)
265 len = length;
266 if (len < 0)
267 len = 0;
268 return len;
269}
270
271
272
273
274
275
276int snmp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
277{
278 extern struct tcp_mib tcp_statistics;
279 extern struct udp_mib udp_statistics;
280 int len;
281
282
283
284
285 len = sprintf (buffer,
286 "Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates\n"
287 "Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
288 ip_statistics.IpForwarding, ip_statistics.IpDefaultTTL,
289 ip_statistics.IpInReceives, ip_statistics.IpInHdrErrors,
290 ip_statistics.IpInAddrErrors, ip_statistics.IpForwDatagrams,
291 ip_statistics.IpInUnknownProtos, ip_statistics.IpInDiscards,
292 ip_statistics.IpInDelivers, ip_statistics.IpOutRequests,
293 ip_statistics.IpOutDiscards, ip_statistics.IpOutNoRoutes,
294 ip_statistics.IpReasmTimeout, ip_statistics.IpReasmReqds,
295 ip_statistics.IpReasmOKs, ip_statistics.IpReasmFails,
296 ip_statistics.IpFragOKs, ip_statistics.IpFragFails,
297 ip_statistics.IpFragCreates);
298
299 len += sprintf (buffer + len,
300 "Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps\n"
301 "Icmp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
302 icmp_statistics.IcmpInMsgs, icmp_statistics.IcmpInErrors,
303 icmp_statistics.IcmpInDestUnreachs, icmp_statistics.IcmpInTimeExcds,
304 icmp_statistics.IcmpInParmProbs, icmp_statistics.IcmpInSrcQuenchs,
305 icmp_statistics.IcmpInRedirects, icmp_statistics.IcmpInEchos,
306 icmp_statistics.IcmpInEchoReps, icmp_statistics.IcmpInTimestamps,
307 icmp_statistics.IcmpInTimestampReps, icmp_statistics.IcmpInAddrMasks,
308 icmp_statistics.IcmpInAddrMaskReps, icmp_statistics.IcmpOutMsgs,
309 icmp_statistics.IcmpOutErrors, icmp_statistics.IcmpOutDestUnreachs,
310 icmp_statistics.IcmpOutTimeExcds, icmp_statistics.IcmpOutParmProbs,
311 icmp_statistics.IcmpOutSrcQuenchs, icmp_statistics.IcmpOutRedirects,
312 icmp_statistics.IcmpOutEchos, icmp_statistics.IcmpOutEchoReps,
313 icmp_statistics.IcmpOutTimestamps, icmp_statistics.IcmpOutTimestampReps,
314 icmp_statistics.IcmpOutAddrMasks, icmp_statistics.IcmpOutAddrMaskReps);
315
316 len += sprintf (buffer + len,
317 "Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts\n"
318 "Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
319 tcp_statistics.TcpRtoAlgorithm, tcp_statistics.TcpRtoMin,
320 tcp_statistics.TcpRtoMax, tcp_statistics.TcpMaxConn,
321 tcp_statistics.TcpActiveOpens, tcp_statistics.TcpPassiveOpens,
322 tcp_statistics.TcpAttemptFails, tcp_statistics.TcpEstabResets,
323 tcp_statistics.TcpCurrEstab, tcp_statistics.TcpInSegs,
324 tcp_statistics.TcpOutSegs, tcp_statistics.TcpRetransSegs,
325 tcp_statistics.TcpInErrs, tcp_statistics.TcpOutRsts);
326
327 len += sprintf (buffer + len,
328 "Udp: InDatagrams NoPorts InErrors OutDatagrams\nUdp: %lu %lu %lu %lu\n",
329 udp_statistics.UdpInDatagrams, udp_statistics.UdpNoPorts,
330 udp_statistics.UdpInErrors, udp_statistics.UdpOutDatagrams);
331
332
333
334
335
336
337 if (offset >= len)
338 {
339 *start = buffer;
340 return 0;
341 }
342 *start = buffer + offset;
343 len -= offset;
344 if (len > length)
345 len = length;
346 if (len < 0)
347 len = 0;
348 return len;
349}
350
351
352
353
354
355int netstat_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
356{
357 extern struct linux_mib net_statistics;
358 int len;
359
360 len = sprintf(buffer,
361 "TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed"
362 " EmbryonicRsts PruneCalled RcvPruned OfoPruned"
363 " OutOfWindowIcmps LockDroppedIcmps\n"
364 "TcpExt: %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
365 net_statistics.SyncookiesSent,
366 net_statistics.SyncookiesRecv,
367 net_statistics.SyncookiesFailed,
368 net_statistics.EmbryonicRsts,
369 net_statistics.PruneCalled,
370 net_statistics.RcvPruned,
371 net_statistics.OfoPruned,
372 net_statistics.OutOfWindowIcmps,
373 net_statistics.LockDroppedIcmps);
374
375 if (offset >= len)
376 {
377 *start = buffer;
378 return 0;
379 }
380 *start = buffer + offset;
381 len -= offset;
382 if (len > length)
383 len = length;
384 if (len < 0)
385 len = 0;
386 return len;
387}
388