summaryrefslogtreecommitdiffstats
path: root/net/ipv4/proc.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
commit545f435ebcfd94a1e7c20b46efe81b4d6ac4e698 (patch)
treee9ce4bc598d06374bda906f18365984bf22a526a /net/ipv4/proc.c
parent4291a610eef89d0d5c69d9a10ee6560e1aa36c74 (diff)
Merge with Linux 2.1.55. More bugfixes and goodies from my private
CVS archive.
Diffstat (limited to 'net/ipv4/proc.c')
-rw-r--r--net/ipv4/proc.c161
1 files changed, 106 insertions, 55 deletions
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 1184c9f41..0ce80fec4 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -23,6 +23,8 @@
* Alan Cox : Handle dead sockets properly.
* Gerhard Koerting : Show both timers
* Alan Cox : Allow inode to be NULL (kernel socket)
+ * Andi Kleen : Add support for open_requests and
+ * split functions for more readibility.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -47,6 +49,82 @@
#include <net/sock.h>
#include <net/raw.h>
+/* Format a single open_request into tmpbuf. */
+static inline void get__openreq(struct sock *sk, struct open_request *req,
+ char *tmpbuf,
+ int i)
+{
+ /* FIXME: I'm not sure if the timer fields are correct. */
+ sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu",
+ i,
+ (long unsigned int)req->af.v4_req.loc_addr,
+ ntohs(sk->dummy_th.source),
+ (long unsigned int)req->af.v4_req.rmt_addr,
+ req->rmt_port,
+ TCP_SYN_RECV,
+ 0,0, /* use sizeof(struct open_request) here? */
+ 0, (unsigned long)(req->expires - jiffies), /* ??? */
+ req->retrans,
+ sk->socket ? sk->socket->inode->i_uid : 0,
+ 0, /* ??? */
+ sk->socket ? sk->socket->inode->i_ino:0);
+}
+
+/* Format a single socket into tmpbuf. */
+static inline void get__sock(struct sock *sp, char *tmpbuf, int i, int format)
+{
+ unsigned long dest, src;
+ unsigned short destp, srcp;
+ int timer_active, timer_active1, timer_active2;
+ unsigned long timer_expires;
+ struct tcp_opt *tp = &sp->tp_pinfo.af_tcp;
+
+ dest = sp->daddr;
+ src = sp->saddr;
+ destp = sp->dummy_th.dest;
+ srcp = sp->dummy_th.source;
+
+ /* FIXME: The fact that retransmit_timer occurs as a field
+ * in two different parts of the socket structure is,
+ * to say the least, confusing. This code now uses the
+ * right retransmit_timer variable, but I'm not sure
+ * the rest of the timer stuff is still correct.
+ * In particular I'm not sure what the timeout value
+ * is suppose to reflect (as opposed to tm->when). -- erics
+ */
+
+ destp = ntohs(destp);
+ srcp = ntohs(srcp);
+ timer_active1 = del_timer(&tp->retransmit_timer);
+ timer_active2 = del_timer(&sp->timer);
+ if (!timer_active1) tp->retransmit_timer.expires=0;
+ if (!timer_active2) sp->timer.expires=0;
+ timer_active=0;
+ timer_expires=(unsigned)-1;
+ if (timer_active1 && tp->retransmit_timer.expires < timer_expires) {
+ timer_active=timer_active1;
+ timer_expires=tp->retransmit_timer.expires;
+ }
+ if (timer_active2 && sp->timer.expires < timer_expires) {
+ timer_active=timer_active2;
+ timer_expires=sp->timer.expires;
+ }
+ sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld",
+ i, src, srcp, dest, destp, sp->state,
+ format==0?sp->write_seq-tp->snd_una:atomic_read(&sp->wmem_alloc),
+ format==0?tp->rcv_nxt-sp->copied_seq:atomic_read(&sp->rmem_alloc),
+ timer_active, timer_expires-jiffies,
+ tp->retransmits,
+ sp->socket ? sp->socket->inode->i_uid:0,
+ timer_active?sp->timeout:0,
+ sp->socket ? sp->socket->inode->i_ino:0);
+
+ if (timer_active1) add_timer(&tp->retransmit_timer);
+ if (timer_active2) add_timer(&sp->timer);
+}
+
/*
* Get__netinfo returns the length of that string.
*
@@ -57,12 +135,7 @@
static int
get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t offset, int length)
{
- struct sock *sp;
- struct tcp_opt *tp;
- int timer_active, timer_active1, timer_active2;
- unsigned long timer_expires;
- unsigned long dest, src;
- unsigned short destp, srcp;
+ struct sock *sp, *next;
int len=0, i = 0;
off_t pos=0;
off_t begin;
@@ -78,68 +151,46 @@ get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t of
* at the wrong moment (eg a syn recv socket getting a reset), or
* a memory timer destroy. Instead of playing with timers we just
* concede defeat and do a start_bh_atomic().
+ * Why not just use lock_sock()? As far as I can see all timer routines
+ * check for sock_readers before doing anything. -AK
+ * [Disabled for now again, because it hard-locked my machine, and there
+ * is an theoretical situation then, where an user could prevent
+ * sockets from being destroyed by constantly reading /proc/net/tcp.]
*/
- SOCKHASH_LOCK();
+ SOCKHASH_LOCK();
sp = pro->sklist_next;
while(sp != (struct sock *)pro) {
+ if (format == 0 && sp->state == TCP_LISTEN) {
+ struct open_request *req;
+
+ for (req = sp->tp_pinfo.af_tcp.syn_wait_queue; req;
+ i++, req = req->dl_next) {
+ pos += 128;
+ if (pos < offset)
+ continue;
+ get__openreq(sp, req, tmpbuf, i);
+ len += sprintf(buffer+len, "%-127s\n", tmpbuf);
+ if(len >= length)
+ break;
+ }
+ }
+
pos += 128;
if (pos < offset)
goto next;
-
- tp = &(sp->tp_pinfo.af_tcp);
- dest = sp->daddr;
- src = sp->saddr;
- destp = sp->dummy_th.dest;
- srcp = sp->dummy_th.source;
-
- /* FIXME: The fact that retransmit_timer occurs as a field
- * in two different parts of the socket structure is,
- * to say the least, confusing. This code now uses the
- * right retransmit_timer variable, but I'm not sure
- * the rest of the timer stuff is still correct.
- * In particular I'm not sure what the timeout value
- * is suppose to reflect (as opposed to tm->when). -- erics
- */
-
- /* Since we are Little Endian we need to swap the bytes :-( */
- destp = ntohs(destp);
- srcp = ntohs(srcp);
- timer_active1 = del_timer(&tp->retransmit_timer);
- timer_active2 = del_timer(&sp->timer);
- if (!timer_active1) tp->retransmit_timer.expires=0;
- if (!timer_active2) sp->timer.expires=0;
- timer_active=0;
- timer_expires=(unsigned)-1;
- if (timer_active1 && tp->retransmit_timer.expires < timer_expires) {
- timer_active=timer_active1;
- timer_expires=tp->retransmit_timer.expires;
- }
- if (timer_active2 && sp->timer.expires < timer_expires) {
- timer_active=timer_active2;
- timer_expires=sp->timer.expires;
- }
- sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld",
- i, src, srcp, dest, destp, sp->state,
- format==0?sp->write_seq-tp->snd_una:atomic_read(&sp->wmem_alloc),
- format==0?tp->rcv_nxt-sp->copied_seq:atomic_read(&sp->rmem_alloc),
- timer_active, timer_expires-jiffies,
- tp->retransmits,
- sp->socket ? sp->socket->inode->i_uid:0,
- timer_active?sp->timeout:0,
- sp->socket ? sp->socket->inode->i_ino:0);
-
- if (timer_active1) add_timer(&tp->retransmit_timer);
- if (timer_active2) add_timer(&sp->timer);
+
+ get__sock(sp, tmpbuf, i, format);
+
len += sprintf(buffer+len, "%-127s\n", tmpbuf);
if(len >= length)
break;
next:
- sp = sp->sklist_next;
+ next = sp->sklist_next;
+ sp = next;
i++;
}
SOCKHASH_UNLOCK();
-
+
begin = len - (pos - offset);
*start = buffer + begin;
len -= begin;