]> git.pld-linux.org Git - packages/net-tools.git/blame - net-tools-netstat-netlink-diag.patch
- netlink to netstat patch. based on http://www.ducksong.com/misc/netstat-netlink...
[packages/net-tools.git] / net-tools-netstat-netlink-diag.patch
CommitLineData
3ada5ed8
ER
1- from http://www.ducksong.com/misc/netstat-netlink-diag-patch.txt
2
3Index: netstat.c
4===================================================================
5RCS file: /cvsroot/net-tools/net-tools/netstat.c,v
6retrieving revision 1.55
7diff -c -d -u -r1.55 netstat.c
8--- netstat.c 1 Dec 2007 19:00:40 -0000 1.55
9+++ netstat.c 20 Feb 2008 23:04:29 -0000
10@@ -96,6 +96,13 @@
11 #include "util.h"
12 #include "proc.h"
13
14+#ifdef HAVE_NETLINK
15+#include <asm/types.h>
16+#include <linux/netlink.h>
17+#include <linux/inet_diag.h>
18+#endif
19+
20+
21 #define PROGNAME_WIDTH 20
22
23 #if !defined(s6_addr32) && defined(in6a_words)
24@@ -828,11 +835,194 @@
25 }
26 }
27
28+
29+
30+#ifdef HAVE_NETLINK
31+int tcp_netlink()
32+{
33+ /* a newer alternative to /proc/net/tcp[6] - using NETLINK DIAG
34+ runs much faster with large number of entries
35+ essentially just a bridge - converts from DIAG to /proc/net/tcp format
36+ largely taken directly from ss of iproute package
37+
38+ returns -1 if NETLINK isn't available, in which case the old /proc/net/tcp code is run
39+ */
40+
41+ int fd;
42+ struct sockaddr_nl nladdr;
43+ struct {
44+ struct nlmsghdr nlh;
45+ struct inet_diag_req r;
46+ } req;
47+ struct msghdr msg;
48+ char buf[8192];
49+ char linebuf[8192];
50+ struct iovec iov;
51+ int lnr = 0;
52+ struct inet_diag_msg *r;
53+ int rv = 0;
54+
55+ if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG)) < 0)
56+ return -1;
57+
58+ memset(&nladdr, 0, sizeof(nladdr));
59+ nladdr.nl_family = AF_NETLINK;
60+
61+ req.nlh.nlmsg_len = sizeof(req);
62+ req.nlh.nlmsg_type = TCPDIAG_GETSOCK;
63+ req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
64+ req.nlh.nlmsg_pid = 0;
65+ req.nlh.nlmsg_seq = 123456;
66+ memset(&req.r, 0, sizeof(req.r));
67+ req.r.idiag_family = AF_INET;
68+ req.r.idiag_states = 0xfff;
69+ req.r.idiag_ext = 0;
70+
71+ iov.iov_base = &req;
72+ iov.iov_len = sizeof(req);
73+
74+ msg = (struct msghdr) {
75+ .msg_name = (void*)&nladdr,
76+ .msg_namelen = sizeof(nladdr),
77+ .msg_iov = &iov,
78+ .msg_iovlen = 1,
79+ };
80+
81+ if (sendmsg(fd, &msg, 0) < 0)
82+ {
83+ rv = -1;
84+ goto netlink_done;
85+ }
86+
87+ iov.iov_base = buf;
88+ iov.iov_len = sizeof(buf);
89+
90+ while (1)
91+ {
92+ int status;
93+ struct nlmsghdr *h;
94+
95+ msg = (struct msghdr) {
96+ (void*)&nladdr, sizeof(nladdr),
97+ &iov, 1,
98+ NULL, 0,
99+ 0
100+ };
101+
102+ status = recvmsg(fd, &msg, 0);
103+
104+ if (status < 0)
105+ {
106+ if (errno == EINTR)
107+ continue;
108+ rv = -2;
109+ goto netlink_done;
110+ }
111+
112+ if (status == 0)
113+ {
114+ rv = 0;
115+ goto netlink_done;
116+ }
117+
118+
119+ h = (struct nlmsghdr*)buf;
120+ while (NLMSG_OK(h, status))
121+ {
122+ if (h->nlmsg_seq == 123456)
123+ {
124+ if (h->nlmsg_type == NLMSG_DONE)
125+ {
126+ rv = 0;
127+ goto netlink_done;
128+ }
129+
130+ if (h->nlmsg_type == NLMSG_ERROR)
131+ {
132+ rv = -2;
133+ goto netlink_done;
134+ }
135+
136+ r = NLMSG_DATA(h);
137+
138+ if (r->idiag_family == AF_INET)
139+ {
140+ snprintf (linebuf,8192,
141+ "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08X %08X %5d %8d %d",
142+ lnr,
143+ r->id.idiag_src[0],
144+ ntohs(r->id.idiag_sport),
145+ r->id.idiag_dst[0],
146+ ntohs(r->id.idiag_dport),
147+ r->idiag_state,
148+ r->idiag_wqueue, r->idiag_rqueue,
149+ r->idiag_timer,
150+ r->idiag_expires/10, // (diag reports as miliseconds, /proc interface stuck at centiseconds)
151+ r->idiag_retrans,
152+ r->idiag_uid,
153+ r->idiag_retrans,
154+ r->idiag_inode);
155+ }
156+ else
157+ { /* ipv6 */
158+ snprintf (linebuf,8192,
159+ "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X %02X %08X:%08X %02X:%08X %08X %5d %8d %d",
160+ lnr,
161+ r->id.idiag_src[0],
162+ r->id.idiag_src[1],
163+ r->id.idiag_src[2],
164+ r->id.idiag_src[3],
165+ ntohs(r->id.idiag_sport),
166+ r->id.idiag_dst[0],
167+ r->id.idiag_dst[1],
168+ r->id.idiag_dst[2],
169+ r->id.idiag_dst[3],
170+ ntohs(r->id.idiag_dport),
171+ r->idiag_state,
172+ r->idiag_wqueue, r->idiag_rqueue,
173+ r->idiag_timer,
174+ r->idiag_expires/10, // (diag reports as miliseconds, /proc interface stuck at centiseconds)
175+ r->idiag_retrans,
176+ r->idiag_uid,
177+ r->idiag_retrans,
178+ r->idiag_inode);
179+ }
180+
181+ tcp_do_one (++lnr, linebuf);
182+ }
183+ h = NLMSG_NEXT(h, status);
184+ }
185+ }
186+
187+
188+ netlink_done:
189+ if (fd >= 0)
190+ close (fd);
191+ return rv;
192+}
193+#endif
194+
195+
196 static int tcp_info(void)
197 {
198- INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
199- tcp_do_one);
200+ int rv = -1;
201+
202+#ifdef HAVE_NETLINK
203+ rv = tcp_netlink();
204+#endif
205+
206+ if (rv == -1)
207+ {
208+ // netlink is not available - so parse /proc/net/tcp
209+ INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
210+ tcp_do_one);
211+ }
212+ else if (rv == 0)
213+ return 0;
214+
215+ return -1;
216 }
217+
218
219 static void udp_do_one(int lnr, const char *line)
220 {
221--- config.in~ 2009-03-10 04:37:40.000000000 +0200
222+++ config.in 2009-03-10 04:38:14.092903210 +0200
223@@ -89,3 +89,4 @@
224 bool 'IP Masquerading support' HAVE_FW_MASQUERADE n
225 bool 'Build iptunnel and ipmaddr' HAVE_IP_TOOLS n
226 bool 'Build mii-tool' HAVE_MII n
227+bool 'Use Netlink Diag' HAVE_NETLINK y
228--- config.h~ 2009-03-10 04:49:18.000000000 +0200
229+++ config.h 2009-03-10 04:49:55.762832175 +0200
230@@ -72,3 +72,4 @@
231 #define HAVE_FW_MASQUERADE 1
232 #define HAVE_IP_TOOLS 0
233 #define HAVE_MII 1
234+#define HAVE_NETLINK 1
235--- config.make~ 2009-03-10 04:49:18.000000000 +0200
236+++ config.make 2009-03-10 04:50:19.880072014 +0200
237@@ -33,3 +33,4 @@
238 # HAVE_FW_MASQUERADE=1
239 # HAVE_IP_TOOLS=0
240 HAVE_MII=1
241+HAVE_NETLINK=1
This page took 0.474587 seconds and 4 git commands to generate.