[haiku-commits] haiku: hrev53366 - src/bin/network/netstat

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 12 Aug 2019 18:09:37 -0400 (EDT)

hrev53366 adds 1 changeset to branch 'master'
old head: 96e64e6e146a9f9e2b0b1a45116721c9109bbe06
new head: 20a31c45b96784d1080bb8e1a66eedbff49e227c
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=20a31c45b967+%5E96e64e6e146a

----------------------------------------------------------------------------

20a31c45b967: netstat: Added family, protocol, and state filter options
  
  * Uses the same option names as net-tools's netstat.
  
  Change-Id: I3363a091dfa1bcf09065f77d3fdc9c9bf27cbcaf
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/1701
  Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>

                                   [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev53366
Commit:      20a31c45b96784d1080bb8e1a66eedbff49e227c
URL:         https://git.haiku-os.org/haiku/commit/?id=20a31c45b967
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Sun Aug 11 10:19:02 2019 UTC
Committer:   waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Mon Aug 12 22:09:34 2019 UTC

----------------------------------------------------------------------------

1 file changed, 87 insertions(+), 5 deletions(-)
src/bin/network/netstat/netstat.cpp | 92 +++++++++++++++++++++++++++++++--

----------------------------------------------------------------------------

diff --git a/src/bin/network/netstat/netstat.cpp 
b/src/bin/network/netstat/netstat.cpp
index 85fde801ef..039e7af27a 100644
--- a/src/bin/network/netstat/netstat.cpp
+++ b/src/bin/network/netstat/netstat.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2019, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -7,6 +7,7 @@
  *             James Woodcock
  */
 
+
 #include <arpa/inet.h>
 #include <errno.h>
 #include <getopt.h>
@@ -36,6 +37,24 @@ struct address_family {
        void            (*print_address)(sockaddr* address);
 };
 
+enum filter_flags {
+       FILTER_FAMILY_MASK              = 0x0000ff,
+       FILTER_PROTOCOL_MASK    = 0x00ff00,
+       FILTER_STATE_MASK               = 0xff0000,
+
+       // Families
+       FILTER_AF_INET                  = 0x000001,
+       FILTER_AF_INET6                 = 0x000002,
+       FILTER_AF_UNIX                  = 0x000004,
+
+       // Protocols
+       FILTER_IPPROTO_TCP              = 0x000100,
+       FILTER_IPPROTO_UDP              = 0x000200,
+
+       // States
+       FILTER_STATE_LISTEN             = 0x010000,
+};
+
 // AF_INET family
 static void inet_print_address(sockaddr* address);
 
@@ -99,10 +118,17 @@ inet_print_address(sockaddr* _address)
 void
 usage(int status)
 {
-       printf("usage: %s [-nh]\n", kProgramName);
-       printf("options:\n");
+       printf("Usage: %s [-nh]\n", kProgramName);
+       printf("Options:\n");
        printf("        -n      don't resolve names\n");
        printf("        -h      this help\n");
+       printf("Filter options:\n");
+       printf("        -4      IPv4\n");
+       printf("        -6      IPv6\n");
+       printf("        -x      Unix\n");
+       printf("        -t      TCP\n");
+       printf("        -u      UDP\n");
+       printf("        -l      listen state\n");
 
        exit(status);
 }
@@ -135,14 +161,27 @@ main(int argc, char** argv)
 {
        int optionIndex = 0;
        int opt;
-       static struct option longOptions[] = {
+       int filter = 0;
+
+       const static struct option kLongOptions[] = {
                {"help", no_argument, 0, 'h'},
                {"numeric", no_argument, 0, 'n'},
+
+               {"inet", no_argument, 0, '4'},
+               {"inet6", no_argument, 0, '6'},
+               {"unix", no_argument, 0, 'x'},
+
+               {"tcp", no_argument, 0, 't'},
+               {"udp", no_argument, 0, 'u'},
+
+               {"listen", no_argument, 0, 'l'},
+
                {0, 0, 0, 0}
        };
 
        do {
-               opt = getopt_long(argc, argv, "hn", longOptions, &optionIndex);
+               opt = getopt_long(argc, argv, "hn46xtul", kLongOptions,
+                       &optionIndex);
                switch (opt) {
                        case -1:
                                // end of arguments, do nothing
@@ -152,6 +191,28 @@ main(int argc, char** argv)
                                sResolveNames = 0;
                                break;
 
+                       // Family filter
+                       case '4':
+                               filter |= FILTER_AF_INET;
+                               break;
+                       case '6':
+                               filter |= FILTER_AF_INET6;
+                               break;
+                       case 'x':
+                               filter |= FILTER_AF_UNIX;
+                               break;
+                       // Protocol filter
+                       case 't':
+                               filter |= FILTER_IPPROTO_TCP;
+                               break;
+                       case 'u':
+                               filter |= FILTER_IPPROTO_UDP;
+                               break;
+                       // State filter
+                       case 'l':
+                               filter |= FILTER_STATE_LISTEN;
+                               break;
+
                        case 'h':
                        default:
                                usage(0);
@@ -169,6 +230,27 @@ main(int argc, char** argv)
        int family = -1;
        net_stat stat;
        while (_kern_get_next_socket_stat(family, &cookie, &stat) == B_OK) {
+               // Filter families
+               if ((filter & FILTER_FAMILY_MASK) != 0) {
+                       if (((filter & FILTER_AF_INET) == 0 || family != 
AF_INET)
+                               && ((filter & FILTER_AF_INET6) == 0 || family 
!= AF_INET6)
+                               && ((filter & FILTER_AF_UNIX) == 0 || family != 
AF_UNIX))
+                               continue;
+               }
+               // Filter protocols
+               if ((filter & FILTER_PROTOCOL_MASK) != 0) {
+                       if (((filter & FILTER_IPPROTO_TCP) == 0
+                                       || stat.protocol != IPPROTO_TCP)
+                               && ((filter & FILTER_IPPROTO_UDP) == 0
+                                       || stat.protocol != IPPROTO_UDP))
+                               continue;
+               }
+               if ((filter & FILTER_STATE_MASK) != 0) {
+                       if ((filter & FILTER_STATE_LISTEN) == 0
+                               || strcmp(stat.state, "listen") != 0)
+                               continue;
+               }
+
                protoent* proto = getprotobynumber(stat.protocol);
                if (proto != NULL)
                        printf("%-6s ", proto->p_name);


Other related posts:

  • » [haiku-commits] haiku: hrev53366 - src/bin/network/netstat - waddlesplash