[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