1 /* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * This file implements the various access functions for the 7 * PROC file system. It is mainly used for debugging and 8 * statistics. 9 * 10 * Version: @(#)proc.c 1.0.5 05/27/93 11 * 12 * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 13 * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de> 14 * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de> 15 * 16 * This program is free software; you can redistribute it and/or 17 * modify it under the terms of the GNU General Public License 18 * as published by the Free Software Foundation; either version 19 * 2 of the License, or (at your option) any later version. 20 */ 21 #include <asm/system.h>
22 #include <linux/autoconf.h>
23 #include <linux/sched.h>
24 #include <linux/socket.h>
25 #include <linux/net.h>
26 #include <linux/un.h>
27 #include <linux/in.h>
28 #include <sys/param.h>
29 #include "inet.h"
30 #include "timer.h"
31 #include "dev.h"
32 #include "ip.h"
33 #include "protocol.h"
34 #include "tcp.h"
35 #include "udp.h"
36 #include "skbuff.h"
37 #include "sock.h"
38 #include "raw.h"
39
40 externstructtimer *timer_base;
41
42 /* 43 * Get__netinfo returns the length of that string. 44 * 45 * KNOWN BUGS 46 * As in get_unix_netinfo, the buffer might be too small. If this 47 * happens, get__netinfo returns only part of the available infos. 48 */ 49 staticint 50 get__netinfo(structproto *pro, char *buffer)
/* */ 51 { 52 structsock **s_array;
53 structsock *sp;
54 char *pos=buffer;
55 inti;
56 unsignedlongdest, src;
57 unsignedshortdestp, srcp;
58 structtimer *tp;
59
60 s_array = pro->sock_array;
61 pos+=sprintf(pos, "sl local_address rem_address st tx_queue rx_queue tr tm->when\n");
62 for(i = 0; i < SOCK_ARRAY_SIZE; i++) { 63 sp = s_array[i];
64 while(sp != NULL) { 65 dest = sp->daddr;
66 src = sp->saddr;
67 destp = sp->dummy_th.dest;
68 srcp = sp->dummy_th.source;
69
70 /* Since we are Little Endian we need to swap the bytes :-( */ 71 destp = ntohs(destp);
72 srcp = ntohs(srcp);
73
74 pos+=sprintf(pos, "%2d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08X %02X",
75 i, src, srcp, dest, destp, sp->state,
76 sp->send_seq-sp->rcv_ack_seq, sp->acked_seq-sp->copied_seq,
77 sp->time_wait.running, sp->time_wait.when-jiffies, sp->retransmits);
78
79 cli();
80 tp = timer_base;
81 while (tp) { 82 if (tp == &(sp->time_wait)) { 83 pos+=sprintf(pos, " *");
84 } 85 tp = tp->next;
86 } 87 sti();
88 pos+=sprintf(pos, "\n");
89
90 /* Is place in buffer too rare? then abort. */ 91 if (pos > buffer+PAGE_SIZE-80) { 92 printk("oops, too many %s sockets for netinfo.\n",
93 pro->name);
94 return(strlen(buffer));
95 } 96
97 /* 98 * All sockets with (port mod SOCK_ARRAY_SIZE) = i 99 * are kept in sock_array[i], so we must follow the 100 * 'next' link to get them all. 101 */ 102 sp = sp->next;
103 } 104 } 105 return(strlen(buffer));
106 } 107
108
109 inttcp_get_info(char *buffer)
/* */ 110 { 111 returnget__netinfo(&tcp_prot, buffer);
112 } 113
114
115 intudp_get_info(char *buffer)
/* */ 116 { 117 returnget__netinfo(&udp_prot, buffer);
118 } 119
120
121 intraw_get_info(char *buffer)
/* */ 122 { 123 returnget__netinfo(&raw_prot, buffer);
124 }