]> git.pld-linux.org Git - packages/net-tools.git/blob - net-tools-netstat-netlink-diag.patch
- rediffed
[packages/net-tools.git] / net-tools-netstat-netlink-diag.patch
1 - from http://www.ducksong.com/misc/netstat-netlink-diag-patch.txt
2
3 Index: netstat.c
4 ===================================================================
5 RCS file: /cvsroot/net-tools/net-tools/netstat.c,v
6 retrieving revision 1.55
7 diff -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
15 diff -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
23 diff -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
31 diff -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
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
46  #define SELINUX_WIDTH 50
47  
48 @@ -1216,11 +1223,194 @@ static void tcp_do_one(int lnr, const ch
49         finish_this_one(uid,inode,timers);
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 +             
205 +             tcp_do_one (++lnr, linebuf, r->idiag_family == AF_INET ? "tcp" : "tcp6");
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)",
223 -              tcp_do_one, "tcp", "tcp6");
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)",
234 +                tcp_do_one, "tcp", "tcp6");   
235 +    }
236 +  else if (rv == 0) 
237 +    return 0;
238 +  
239 +  return -1;
240  }
241
242  
243  static int notnull(const struct sockaddr_storage *sas)
244  {
This page took 0.754278 seconds and 4 git commands to generate.