[2/3] netstat: Parse command line arguments
André Hentschel
nerv at dawncrow.de
Wed Jan 2 10:13:56 CST 2013
---
programs/netstat/netstat.c | 60 ++++++++++++++++++++++++++++++++++++++--------
programs/netstat/netstat.h | 12 ++++++++++
2 files changed, 62 insertions(+), 10 deletions(-)
diff --git a/programs/netstat/netstat.c b/programs/netstat/netstat.c
index 999e409..dede96d 100644
--- a/programs/netstat/netstat.c
+++ b/programs/netstat/netstat.c
@@ -24,7 +24,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(netstat);
+static const WCHAR ipW[] = {'I', 'P', 0};
+static const WCHAR ipv6W[] = {'I', 'P', 'v', '6', 0};
+static const WCHAR icmpW[] = {'I', 'C', 'M', 'P', 0};
+static const WCHAR icmpv6W[] = {'I', 'C', 'M', 'P', 'v', '6', 0};
static const WCHAR tcpW[] = {'T', 'C', 'P', 0};
+static const WCHAR tcpv6W[] = {'T', 'C', 'P', 'v', '6', 0};
+static const WCHAR udpW[] = {'U', 'D', 'P', 0};
+static const WCHAR udpv6W[] = {'U', 'D', 'P', 'v', '6', 0};
+
static const WCHAR fmtport[] = {'%', 'd', 0};
static const WCHAR fmtip[] = {'%', 'd', '.', '%', 'd', '.', '%', 'd', '.', '%', 'd', 0};
static const WCHAR fmtn[] = {'\n', 0};
@@ -181,26 +189,58 @@ static void NETSTAT_tcp_table(void)
HeapFree(GetProcessHeap(), 0, table);
}
+static NETSTATPROTOCOLS NETSTAT_get_protocol(WCHAR name[])
+{
+ if (!strcmpiW(name, ipW)) return PROT_IP;
+ if (!strcmpiW(name, ipv6W)) return PROT_IPV6;
+ if (!strcmpiW(name, icmpW)) return PROT_ICMP;
+ if (!strcmpiW(name, icmpv6W)) return PROT_ICMPV6;
+ if (!strcmpiW(name, tcpW)) return PROT_TCP;
+ if (!strcmpiW(name, tcpv6W)) return PROT_TCPV6;
+ if (!strcmpiW(name, udpW)) return PROT_UDP;
+ if (!strcmpiW(name, udpv6W)) return PROT_UDPV6;
+ return PROT_UNKNOWN;
+}
+
int wmain(int argc, WCHAR *argv[])
{
WSADATA wsa_data;
- if (argc > 1)
- {
- int i;
- WINE_FIXME("stub:");
- for (i = 0; i < argc; i++)
- WINE_FIXME(" %s", wine_dbgstr_w(argv[i]));
- WINE_FIXME("\n");
- }
-
if (WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
WINE_ERR("WSAStartup failed: %d\n", WSAGetLastError());
return 1;
}
- NETSTAT_tcp_table();
+ if (argc == 1)
+ {
+ /* No options */
+ NETSTAT_tcp_table();
+ return 0;
+ }
+
+ while (argv[1] && argv[1][0] == '-')
+ {
+ switch (argv[1][1])
+ {
+ case 'p':
+ argv++; argc--;
+ if (argc == 1) return 1;
+ switch (NETSTAT_get_protocol(argv[1]))
+ {
+ case PROT_TCP:
+ NETSTAT_tcp_table();
+ break;
+ default:
+ WINE_FIXME("Protocol not yet implemented: %s\n", debugstr_w(argv[1]));
+ }
+ break;
+ default:
+ WINE_FIXME("Unknown option: %s\n", debugstr_w(argv[1]));
+ return 1;
+ }
+ argv++; argc--;
+ }
return 0;
}
diff --git a/programs/netstat/netstat.h b/programs/netstat/netstat.h
index b51a81f..dc4fb1e 100644
--- a/programs/netstat/netstat.h
+++ b/programs/netstat/netstat.h
@@ -18,6 +18,18 @@
#include <windows.h>
+typedef enum _NETSTATPROTOCOLS {
+ PROT_UNKNOWN,
+ PROT_IP,
+ PROT_IPV6,
+ PROT_ICMP,
+ PROT_ICMPV6,
+ PROT_TCP,
+ PROT_TCPV6,
+ PROT_UDP,
+ PROT_UDPV6,
+} NETSTATPROTOCOLS;
+
#define IDS_TCP_CLOSED 1
#define IDS_TCP_LISTENING 2
#define IDS_TCP_SYN_SENT 3
--
1.8.0
--
Best Regards, André Hentschel
-------------- next part --------------
diff --git a/programs/netstat/netstat.c b/programs/netstat/netstat.c
index dede96d..a3f584c 100644
--- a/programs/netstat/netstat.c
+++ b/programs/netstat/netstat.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2012 André Hentschel
+ * Copyright 2011-2013 André Hentschel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -39,6 +39,7 @@ static const WCHAR fmtn[] = {'\n', 0};
static const WCHAR fmtnn[] = {'\n', '%', 's', '\n', 0};
static const WCHAR fmtcolon[] = {'%', 's', ':', '%', 's', 0};
static const WCHAR fmttcpout[] = {' ', ' ', '%', '-', '6', 's', ' ', '%', '-', '2', '2', 's', ' ', '%', '-', '2', '2', 's', ' ', '%', 's', '\n', 0};
+static const WCHAR fmtudpout[] = {' ', ' ', '%', '-', '6', 's', ' ', '%', '-', '2', '2', 's', ' ', '*', ':', '*', '\n', 0};
/* =========================================================================
* Output a unicode string. Ideally this will go to the console
@@ -143,11 +144,21 @@ static WCHAR *NETSTAT_host_name(UINT ip, WCHAR name[])
return name;
}
+static void NETSTAT_tcp_header(void)
+{
+ WCHAR local[22], remote[22], state[22];
+ NETSTAT_wprintf(fmtnn, NETSTAT_load_message(IDS_TCP_ACTIVE_CONN));
+ NETSTAT_wprintf(fmtn);
+ strcpyW(local, NETSTAT_load_message(IDS_TCP_LOCAL_ADDR));
+ strcpyW(remote, NETSTAT_load_message(IDS_TCP_REMOTE_ADDR));
+ strcpyW(state, NETSTAT_load_message(IDS_TCP_STATE));
+ NETSTAT_wprintf(fmttcpout, NETSTAT_load_message(IDS_TCP_PROTO), local, remote, state);
+}
+
static void NETSTAT_tcp_table(void)
{
PMIB_TCPTABLE table;
DWORD err, size, i;
- WCHAR local[22], remote[22], state[22];
WCHAR HostIp[MAX_HOSTNAME_LEN], HostPort[32];
WCHAR RemoteIp[MAX_HOSTNAME_LEN], RemotePort[32];
WCHAR Host[MAX_HOSTNAME_LEN + 32];
@@ -163,12 +174,7 @@ static void NETSTAT_tcp_table(void)
if (err) return;
- NETSTAT_wprintf(fmtnn, NETSTAT_load_message(IDS_TCP_ACTIVE_CONN));
- NETSTAT_wprintf(fmtn);
- strcpyW(local, NETSTAT_load_message(IDS_TCP_LOCAL_ADDR));
- strcpyW(remote, NETSTAT_load_message(IDS_TCP_REMOTE_ADDR));
- strcpyW(state, NETSTAT_load_message(IDS_TCP_STATE));
- NETSTAT_wprintf(fmttcpout, NETSTAT_load_message(IDS_TCP_PROTO), local, remote, state);
+ NETSTAT_tcp_header();
for (i = 0; i < table->dwNumEntries; i++)
{
@@ -189,6 +195,36 @@ static void NETSTAT_tcp_table(void)
HeapFree(GetProcessHeap(), 0, table);
}
+static void NETSTAT_udp_table(void)
+{
+ PMIB_UDPTABLE table;
+ DWORD err, size, i;
+ WCHAR HostIp[MAX_HOSTNAME_LEN], HostPort[32];
+ WCHAR Host[MAX_HOSTNAME_LEN + 32];
+
+ size = sizeof(MIB_UDPTABLE);
+ do
+ {
+ table = (PMIB_UDPTABLE)HeapAlloc(GetProcessHeap(), 0, size);
+ err = GetUdpTable(table, &size, TRUE);
+ if (err != NO_ERROR) HeapFree(GetProcessHeap(), 0, table);
+ } while (err == ERROR_INSUFFICIENT_BUFFER);
+
+ if (err) return;
+
+ NETSTAT_tcp_header();
+
+ for (i = 0; i < table->dwNumEntries; i++)
+ {
+ NETSTAT_host_name(table->table[i].dwLocalAddr, HostIp);
+ NETSTAT_port_name(table->table[i].dwLocalPort, HostPort);
+
+ sprintfW(Host, fmtcolon, HostIp, HostPort);
+ NETSTAT_wprintf(fmtudpout, udpW, Host);
+ }
+ HeapFree(GetProcessHeap(), 0, table);
+}
+
static NETSTATPROTOCOLS NETSTAT_get_protocol(WCHAR name[])
{
if (!strcmpiW(name, ipW)) return PROT_IP;
@@ -231,6 +267,9 @@ int wmain(int argc, WCHAR *argv[])
case PROT_TCP:
NETSTAT_tcp_table();
break;
+ case PROT_UDP:
+ NETSTAT_udp_table();
+ break;
default:
WINE_FIXME("Protocol not yet implemented: %s\n", debugstr_w(argv[1]));
}
More information about the wine-patches
mailing list