]> 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 -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, r->idiag_family == AF_INET ? "tcp" : "tcp6");
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, "tcp", "tcp6");
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, "tcp", "tcp6");   
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,const char *prot)
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 'Build iptunnel and ipmaddr' HAVE_IP_TOOLS n
225  bool 'Build mii-tool' HAVE_MII n
226  bool 'SELinux support' HAVE_SELINUX 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_IP_TOOLS 0
232  #define HAVE_MII 1
233  #define HAVE_SELINUX 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_IP_TOOLS=0
239  HAVE_MII=1
240  HAVE_SELINUX=1
241 +HAVE_NETLINK=1
This page took 0.145082 seconds and 3 git commands to generate.