UDPlite Support for net-stat by Brian Micek <bmicek@gmail.com>
authorBernd Eckenfels <net-tools@lina.inka.de>
Mon, 1 Dec 2008 23:15:35 +0000 (23:15 +0000)
committerBernd Eckenfels <net-tools@lina.inka.de>
Mon, 1 Dec 2008 23:15:35 +0000 (23:15 +0000)
lib/pathnames.h
man/en_US/netstat.8
netstat.c

index 0764ce9..dd487f7 100644 (file)
@@ -16,6 +16,8 @@
 #define _PATH_PROCNET_TCP6             "/proc/net/tcp6"
 #define _PATH_PROCNET_UDP              "/proc/net/udp"
 #define _PATH_PROCNET_UDP6             "/proc/net/udp6"
+#define _PATH_PROCNET_UDPLITE           "/proc/net/udplite"
+#define _PATH_PROCNET_UDPLITE6          "/proc/net/udplite6"
 #define _PATH_PROCNET_RAW              "/proc/net/raw"
 #define _PATH_PROCNET_RAW6             "/proc/net/raw6"
 #define _PATH_PROCNET_UNIX             "/proc/net/unix"
index f93996b..6c75c78 100644 (file)
@@ -19,6 +19,7 @@ netstat \- Print network connections, routing tables, interface statistics, masq
 .RI [ address_family_options ]
 .RB [ \-\-tcp | \-t ]
 .RB [ \-\-udp | \-u ]
+.RB [ \-\-udplite | \-U ]
 .RB [ \-\-raw | \-w ]
 .RB [ \-\-listening | \-l ]
 .RB [ \-\-all | \-a ]
@@ -67,6 +68,7 @@ netstat \- Print network connections, routing tables, interface statistics, masq
 .RB { \-\-statistics | -s }
 .RB [ \-\-tcp | \-t ]
 .RB [ \-\-udp | \-u ]
+.RB [ \-\-udplite | \-U ]
 .RB [ \-\-raw | \-w ]
 .P
 .B netstat 
@@ -158,7 +160,7 @@ options.
 .P
 The address family
 .B inet
-includes raw, udp and tcp protocol sockets.
+includes raw, udp, udplite and tcp protocol sockets.
 .SS "\-c, \-\-continuous"
 This will cause
 .B netstat
@@ -182,9 +184,9 @@ Print routing information from the route cache.
 .P
 .SH OUTPUT
 .P
-.SS Active Internet connections \fR(TCP, UDP, raw)\fR
+.SS Active Internet connections \fR(TCP, UDP, UDPLite, raw)\fR
 .SS "Proto" 
-The protocol (tcp, udp, raw) used by the socket. 
+The protocol (tcp, udp, udpl, raw) used by the socket. 
 .SS "Recv\-Q"
 Established: The count of bytes not copied by the user program connected to this socket.
 Listening: Since Kernel 2.6.18 this column contains the current syn backlog.
@@ -202,7 +204,7 @@ Address and port number of the remote end of the socket.
 Analogous to "Local Address."
 .SS "State"
 The state of the socket. Since there are no states in raw mode and usually no
-states used in UDP, this column may be left blank. Normally this can be one
+states used in UDP and UDPLite, this column may be left blank. Normally this can be one
 of several values:
 .TP
 .I
@@ -395,6 +397,9 @@ status information via the following files.
 .I /proc/net/udp
 -- UDP socket information
 
+.I /proc/net/udplite
+-- UDPLite socket information
+
 .I /proc/net/igmp
 -- IGMP multicast information
 
@@ -456,4 +461,5 @@ work.  It was updated again by Tuan Hoang
 .br
 The man page and the command included in the net\-tools
 package is totally rewritten by Bernd Eckenfels 
-<ecki@linux.de>.
+<ecki@linux.de>.  UDPLite options were added by Brian Micek
+<bmicek@gmail.com>
index c8460bf..8de43b9 100644 (file)
--- a/netstat.c
+++ b/netstat.c
@@ -6,7 +6,7 @@
  *              NET-3 Networking Distribution for the LINUX operating
  *              system.
  *
- * Version:     $Id: netstat.c,v 1.60 2008/11/16 16:45:08 luk Exp $
+ * Version:     $Id: netstat.c,v 1.61 2008/12/01 23:15:35 ecki Exp $
  *
  * Authors:     Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
  *              Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
@@ -58,6 +58,7 @@
  *
  *990420 {1.38} Tuan Hoang              removed a useless assignment from igmp_do_one()
  *20010404 {1.39} Arnaldo Carvalho de Melo - use setlocale
+ *20081201 {1.42} Brian Micek           added -L|--udplite options for RFC 3828 
  *
  *              This program is free software; you can redistribute it
  *              and/or  modify it under  the terms of  the GNU General
@@ -125,7 +126,7 @@ typedef enum {
 #define FEATURE_NETSTAT
 #include "lib/net-features.h"
 
-char *Release = RELEASE, *Version = "netstat 1.42 (2001-04-15)", *Signature = "Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang and others";
+char *Release = RELEASE, *Version = "netstat 1.42 (2001-04-15)", *Signature = "Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang, Brian Micek and others";
 
 
 #define E_READ  -1
@@ -146,6 +147,7 @@ int flag_opt = 0;
 int flag_raw = 0;
 int flag_tcp = 0;
 int flag_udp = 0;
+int flag_udplite = 0;
 int flag_igmp= 0;
 int flag_rom = 0;
 int flag_exp = 1;
@@ -156,7 +158,7 @@ int flag_ver = 0;
 
 FILE *procinfo;
 
-#define INFO_GUTS1(file,name,proc)                     \
+#define INFO_GUTS1(file,name,proc,prot)                        \
   procinfo = proc_fopen((file));                       \
   if (procinfo == NULL) {                              \
     if (errno != ENOENT) {                             \
@@ -170,46 +172,46 @@ FILE *procinfo;
   } else {                                             \
     do {                                               \
       if (fgets(buffer, sizeof(buffer), procinfo))     \
-        (proc)(lnr++, buffer);                         \
+        (proc)(lnr++, buffer,prot);                    \
     } while (!feof(procinfo));                         \
     fclose(procinfo);                                  \
   }
 
 #if HAVE_AFINET6
-#define INFO_GUTS2(file,proc)                          \
+#define INFO_GUTS2(file,proc,prot)                     \
   lnr = 0;                                             \
   procinfo = proc_fopen((file));                       \
   if (procinfo != NULL) {                              \
     do {                                               \
       if (fgets(buffer, sizeof(buffer), procinfo))     \
-       (proc)(lnr++, buffer);                          \
+       (proc)(lnr++, buffer,prot);                     \
     } while (!feof(procinfo));                         \
     fclose(procinfo);                                  \
   }
 #else
-#define INFO_GUTS2(file,proc)
+#define INFO_GUTS2(file,proc,prot)
 #endif
 
 #define INFO_GUTS3                                     \
  return rc;
 
-#define INFO_GUTS6(file,file6,name,proc)               \
+#define INFO_GUTS6(file,file6,name,proc,prot4,prot6)   \
  char buffer[8192];                                    \
  int rc = 0;                                           \
  int lnr = 0;                                          \
  if (!flag_arg || flag_inet) {                         \
-    INFO_GUTS1(file,name,proc)                         \
+    INFO_GUTS1(file,name,proc,prot4)                   \
  }                                                     \
  if (!flag_arg || flag_inet6) {                                \
-    INFO_GUTS2(file6,proc)                             \
+    INFO_GUTS2(file6,proc,prot6)                       \
  }                                                     \
  INFO_GUTS3
 
-#define INFO_GUTS(file,name,proc)                      \
+#define INFO_GUTS(file,name,proc,prot)                 \
  char buffer[8192];                                    \
  int rc = 0;                                           \
  int lnr = 0;                                          \
- INFO_GUTS1(file,name,proc)                            \
+ INFO_GUTS1(file,name,proc,prot)                       \
  INFO_GUTS3
 
 #define PROGNAME_WIDTHs PROGNAME_WIDTH1(PROGNAME_WIDTH)
@@ -541,7 +543,7 @@ static void finish_this_one(int uid, unsigned long inode, const char *timers)
     putchar('\n');
 }
 
-static void igmp_do_one(int lnr, const char *line)
+static void igmp_do_one(int lnr, const char *line,const char *prot)
 {
     char mcast_addr[128];
 #if HAVE_AFINET6
@@ -699,15 +701,14 @@ static int x25_info(void)
 static int igmp_info(void)
 {
     INFO_GUTS6(_PATH_PROCNET_IGMP, _PATH_PROCNET_IGMP6, "AF INET (igmp)",
-              igmp_do_one);
+              igmp_do_one, "igmp", "igmp6");
 }
 
-static void tcp_do_one(int lnr, const char *line)
+static void tcp_do_one(int lnr, const char *line, const char *prot)
 {
     unsigned long rxq, txq, time_len, retr, inode;
     int num, local_port, rem_port, d, state, uid, timer_run, timeout;
     char rem_addr[128], local_addr[128], timers[64], buffer[1024], more[512];
-    char *protname;
     struct aftype *ap;
 #if HAVE_AFINET6
     struct sockaddr_in6 localaddr, remaddr;
@@ -728,7 +729,6 @@ static void tcp_do_one(int lnr, const char *line)
 
     if (strlen(local_addr) > 8) {
 #if HAVE_AFINET6
-       protname = "tcp6";
        /* Demangle what the kernel gives us */
        sscanf(local_addr, "%08X%08X%08X%08X",
               &in6.s6_addr32[0], &in6.s6_addr32[1],
@@ -744,7 +744,6 @@ static void tcp_do_one(int lnr, const char *line)
        remaddr.sin6_family = AF_INET6;
 #endif
     } else {
-       protname = "tcp";
        sscanf(local_addr, "%X",
               &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
        sscanf(rem_addr, "%X",
@@ -817,7 +816,7 @@ static void tcp_do_one(int lnr, const char *line)
                break;
            }
        printf("%-4s  %6ld %6ld %-*s %-*s %-11s",
-              protname, rxq, txq, netmax(23,strlen(local_addr)), local_addr, netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
+              prot, rxq, txq, netmax(23,strlen(local_addr)), local_addr, netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state]));
 
        finish_this_one(uid,inode,timers);
     }
@@ -826,15 +825,14 @@ static void tcp_do_one(int lnr, const char *line)
 static int tcp_info(void)
 {
     INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)",
-              tcp_do_one);
+              tcp_do_one, "tcp", "tcp6");
 }
 
-static void udp_do_one(int lnr, const char *line)
+static void udp_do_one(int lnr, const char *line,const char *prot)
 {
     char buffer[8192], local_addr[64], rem_addr[64];
     char *udp_state, timers[64], more[512];
     int num, local_port, rem_port, d, state, timer_run, uid, timeout;
-    char *protname;
 #if HAVE_AFINET6
     struct sockaddr_in6 localaddr, remaddr;
     char addr6[INET6_ADDRSTRLEN];
@@ -858,7 +856,6 @@ static void udp_do_one(int lnr, const char *line)
 
     if (strlen(local_addr) > 8) {
 #if HAVE_AFINET6
-       protname="udp6";
        sscanf(local_addr, "%08X%08X%08X%08X",
               &in6.s6_addr32[0], &in6.s6_addr32[1],
               &in6.s6_addr32[2], &in6.s6_addr32[3]);
@@ -873,7 +870,6 @@ static void udp_do_one(int lnr, const char *line)
        remaddr.sin6_family = AF_INET6;
 #endif
     } else {
-        protname="udp";
        sscanf(local_addr, "%X",
               &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
        sscanf(rem_addr, "%X",
@@ -959,8 +955,8 @@ static void udp_do_one(int lnr, const char *line)
                         retr, timeout);
                break;
            }
-       printf("%-4s  %6ld %6ld %-23s %-23s %-11s",
-              protname, rxq, txq, local_addr, rem_addr, udp_state);
+       printf("%-5s %6ld %6ld %-23s %-23s %-11s",
+              prot, rxq, txq, local_addr, rem_addr, udp_state);
 
        finish_this_one(uid,inode,timers);
     }
@@ -969,15 +965,20 @@ static void udp_do_one(int lnr, const char *line)
 static int udp_info(void)
 {
     INFO_GUTS6(_PATH_PROCNET_UDP, _PATH_PROCNET_UDP6, "AF INET (udp)",
-              udp_do_one);
+              udp_do_one, "upd", "udp6");
 }
 
-static void raw_do_one(int lnr, const char *line)
+static int udplite_info(void)
+{
+    INFO_GUTS6(_PATH_PROCNET_UDPLITE, _PATH_PROCNET_UDPLITE6, 
+               "AF INET (udplite)", udp_do_one, "udpl", "udpl6" );
+}
+
+static void raw_do_one(int lnr, const char *line,const char *prot)
 {
     char buffer[8192], local_addr[64], rem_addr[64];
     char timers[64], more[512];
     int num, local_port, rem_port, d, state, timer_run, uid, timeout;
-    char *protname;
 #if HAVE_AFINET6
     struct sockaddr_in6 localaddr, remaddr;
     char addr6[INET6_ADDRSTRLEN];
@@ -1000,7 +1001,6 @@ static void raw_do_one(int lnr, const char *line)
 
     if (strlen(local_addr) > 8) {
 #if HAVE_AFINET6
-       protname = "raw6";
        sscanf(local_addr, "%08X%08X%08X%08X",
               &in6.s6_addr32[0], &in6.s6_addr32[1],
            &in6.s6_addr32[2], &in6.s6_addr32[3]);
@@ -1015,7 +1015,6 @@ static void raw_do_one(int lnr, const char *line)
        remaddr.sin6_family = AF_INET6;
 #endif
     } else {
-        protname = "raw";
        sscanf(local_addr, "%X",
               &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);
        sscanf(rem_addr, "%X",
@@ -1084,7 +1083,7 @@ static void raw_do_one(int lnr, const char *line)
                break;
            }
        printf("%-4s  %6ld %6ld %-23s %-23s %-11d",
-              protname, rxq, txq, local_addr, rem_addr, state);
+              prot, rxq, txq, local_addr, rem_addr, state);
 
        finish_this_one(uid,inode,timers);
     }
@@ -1093,7 +1092,7 @@ static void raw_do_one(int lnr, const char *line)
 static int raw_info(void)
 {
     INFO_GUTS6(_PATH_PROCNET_RAW, _PATH_PROCNET_RAW6, "AF INET (raw)",
-              raw_do_one);
+              raw_do_one, "raw", "raw6");
 }
 
 #endif
@@ -1103,7 +1102,7 @@ static int raw_info(void)
 
 #define HAS_INODE 1
 
-static void unix_do_one(int nr, const char *line)
+static void unix_do_one(int nr, const char *line, const char *prot)
 {
     static int has = 0;
     char path[MAXPATHLEN], ss_flags[32];
@@ -1244,7 +1243,7 @@ static int unix_info(void)
     printf(_(" Path\n"));      /* xxx */
 
     {
-       INFO_GUTS(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one);
+       INFO_GUTS(_PATH_PROCNET_UNIX, "AF UNIX", unix_do_one, "unix");
     }
 }
 #endif
@@ -1532,7 +1531,7 @@ static void usage(void)
     fprintf(stderr, _("        -F, --fib                display Forwarding Information Base (default)\n"));
     fprintf(stderr, _("        -C, --cache              display routing cache instead of FIB\n\n"));
 
-    fprintf(stderr, _("  <Socket>={-t|--tcp} {-u|--udp} {-w|--raw} {-x|--unix} --ax25 --ipx --netrom\n"));
+    fprintf(stderr, _("  <Socket>={-t|--tcp} {-u|--udp} {-U|--udplite} {-w|--raw} {-x|--unix} --ax25 --ipx --netrom\n"));
     fprintf(stderr, _("  <AF>=Use '-6|-4' or '-A <af>' or '--<af>'; default: %s\n"), DFLT_AF);
     fprintf(stderr, _("  List of possible address families (which support routing):\n"));
     print_aflist(1); /* 1 = routeable */
@@ -1557,6 +1556,7 @@ int main
        {"protocol", 1, 0, 'A'},
        {"tcp", 0, 0, 't'},
        {"udp", 0, 0, 'u'},
+        {"udplite", 0, 0, 'U'},
        {"raw", 0, 0, 'w'},
        {"unix", 0, 0, 'x'},
        {"listening", 0, 0, 'l'},
@@ -1587,7 +1587,7 @@ int main
     getroute_init();           /* Set up AF routing support */
 
     afname[0] = '\0';
-    while ((i = getopt_long(argc, argv, "MCFA:acdegphinNorstuWVv?wxl64", longopts, &lop)) != EOF)
+    while ((i = getopt_long(argc, argv, "MCFA:acdegphinNorstuWVv?wxl64U", longopts, &lop)) != EOF)
        switch (i) {
        case -1:
            break;
@@ -1683,6 +1683,9 @@ int main
        case 'u':
            flag_udp++;
            break;
+        case 'U':
+           flag_udplite++;
+           break;
        case 'w':
            flag_raw++;
            break;
@@ -1700,14 +1703,16 @@ int main
     if (flag_int + flag_rou + flag_mas + flag_sta > 1)
        usage();
 
-    if ((flag_inet || flag_inet6 || flag_sta) && !(flag_tcp || flag_udp || flag_raw))
-       flag_tcp = flag_udp = flag_raw = 1;
+    if ((flag_inet || flag_inet6 || flag_sta) && 
+        !(flag_tcp || flag_udp || flag_udplite || flag_raw))
+          flag_tcp = flag_udp = flag_udplite = flag_raw = 1;
 
-    if ((flag_tcp || flag_udp || flag_raw || flag_igmp) && !(flag_inet || flag_inet6))
+    if ((flag_tcp || flag_udp || flag_udplite || flag_raw || flag_igmp) && 
+        !(flag_inet || flag_inet6))
         flag_inet = flag_inet6 = 1;
 
-    flag_arg = flag_tcp + flag_udp + flag_raw + flag_unx + flag_ipx
-       + flag_ax25 + flag_netrom + flag_igmp + flag_x25 + flag_rose;
+    flag_arg = flag_tcp + flag_udplite + flag_udp + flag_raw + flag_unx 
+        + flag_ipx + flag_ax25 + flag_netrom + flag_igmp + flag_x25 + flag_rose;
 
     if (flag_mas) {
 #if HAVE_FW_MASQUERADE && HAVE_AFINET
@@ -1787,7 +1792,7 @@ int main
        return (i);
     }
     for (;;) {
-       if (!flag_arg || flag_tcp || flag_udp || flag_raw) {
+       if (!flag_arg || flag_tcp || flag_udp || flag_udplite || flag_raw) {
 #if HAVE_AFINET
            prg_cache_load();
            printf(_("Active Internet connections "));  /* xxx */
@@ -1820,11 +1825,19 @@ int main
            if (i)
                return (i);
        }
+
        if (!flag_arg || flag_udp) {
            i = udp_info();
            if (i)
                return (i);
        }
+
+       if (!flag_arg || flag_udplite) {
+           i = udplite_info();
+           if (i)
+               return (i);
+       }
+
        if (!flag_arg || flag_raw) {
            i = raw_info();
            if (i)