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