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);