Just something I was playing around with today that I thought I might share.
I was curious about how to get network statistics in windows so I've been reading MSDN all day trying to work it out. I've written a little bit of python using the ctypes
module to access the API on network statistics. All I can say is that doing these things on Linux is so much easier as you can just access the /proc
directory and parse the system files there that contain such information.
Here's the snippet, please read the comment header as there is some funky behaviour I haven't quite understood yet.
# ------------------------------------------------- # Description: Prints out a nice report of protocol # statistics # # Author: doug@neverfear.org # Platform: Windows XP/Vista # # Notes: # This code snippet demonstrates how to access the # GetTcpStatisticsEx WINAPI routines located in # iphlpapi.dll using the ctypes python module. # # There is odd behaviour that I haven't quite # figured out. The script is safe but for some # unexplained reason on occasion this script hangs # after completing it's task successfully or the # python executable crashes. I have a gut feeling # it's something to do with the C-style workings of # the ctypes library and pythons garbage collection # tripping up over one another. I've yet to locate # the issue with sufficient certainty to say. # # If anybody knows why, mail me: doug@neverfear.org # ------------------------------------------------- from ctypes import * from ctypes.wintypes import DWORD import socket, sys Iphlpapi = windll.Iphlpapi class PrintableStruct(Structure): def __dict__(self): l = {} for field, type in self._fields_: l[field] = repr(self.__getattribute__(field)) return l def __str__(self): return str(self.__dict__()) def __repr__(self): return repr(self.__dict__()) def formatted_string(self): for field, type in self._fields_: value = self.__getattribute__(field) print "% 20s = %s" % (field, repr(value)) class TCPSTATS(PrintableStruct): """ Modelled after the MIB_TCPSTATS structure. For more information: http://msdn.microsoft.com/en-us/library/aa366915(VS.85).aspx (Visited 2009-07-23) """ _fields_ = [ ("dwRtoAlgorithm", DWORD), ("dwRtoMin", DWORD), ("dwRtoMax", DWORD), ("dwMaxConn", DWORD), ("dwActiveOpens", DWORD), ("dwPassiveOpens", DWORD), ("dwAttemptFails", DWORD), ("dwEstabResets", DWORD), ("dwCurrEstab", DWORD), ("dwInSegs", DWORD), ("dwOutSegs", DWORD), ("dwRetransSegs", DWORD), ("dwInErrs", DWORD), ("dwOutRsts", DWORD), ("dwNumConns", DWORD) ] class ICMPSTATS_EX(PrintableStruct): """ Modelled after the MIBICMPSTATS_EX structure. For more information: http://msdn.microsoft.com/en-us/library/aa366819(VS.85).aspx (Visited 2009-07-23) """ _fields_ = [ ("dwMsgs", DWORD), ("dwErrors", DWORD), ("rgdwTypeCount", DWORD) ] class ICMP_EX(PrintableStruct): """ Modelled after the MIB_ICMP_EX structure. For more information: http://msdn.microsoft.com/en-us/library/aa366832(VS.85).aspx (Visited 2009-07-23) """ _fields_ = [ ("icmpInStats", ICMPSTATS_EX), ("icmpOutStats", ICMPSTATS_EX) ] class IPSTATS(PrintableStruct): """ Modelled after the MIB_IPSTATS structure. For more information: http://msdn.microsoft.com/en-us/library/aa366871(VS.85).aspx (Visited 2009-07-23) """ _fields_ = [ ("dwForwarding", DWORD), ("dwDefaultTTL", DWORD), ("dwInReceives", DWORD), ("dwInHdrErrors", DWORD), ("dwInAddrErrors", DWORD), ("dwForwDatagrams", DWORD), ("dwInUnknownProtos", DWORD), ("dwInDiscards", DWORD), ("dwInDelivers", DWORD), ("dwOutRequests", DWORD), ("dwRoutingDiscards", DWORD), ("dwOutDiscards", DWORD), ("dwOutNoRoutes", DWORD), ("dwReasmTimeout", DWORD), ("dwReasmReqds", DWORD), ("dwReasmOks", DWORD), ("dwReasmFails", DWORD), ("dwFragOks", DWORD), ("dwFragFails", DWORD), ("dwFragCreates", DWORD), ("dwNumIf", DWORD), ("dwNumAddr", DWORD), ("dwNumRoutes", DWORD) ] class UDPSTATS(PrintableStruct): """ Modelled after the MIB_UDPSTATS structure. For more information: http://msdn.microsoft.com/en-us/library/aa366929(VS.85).aspx (Visited 2009-07-23) """ _fields_ = [ ("dwInDatagrams", DWORD), ("dwNoPorts", DWORD), ("dwInErrors", DWORD), ("dwOutDatagrams", DWORD), ("dwNumAddrs", DWORD) ] StatsFuncs = [ # Protocol: (Statistics function pointer, statistics structure class) ("ICMP", Iphlpapi.GetIcmpStatisticsEx, ICMP_EX), ("TCP", Iphlpapi.GetTcpStatisticsEx, TCPSTATS), ("IP", Iphlpapi.GetIpStatisticsEx, IPSTATS), ("UDP", Iphlpapi.GetUdpStatisticsEx, UDPSTATS) ] # Basic usage for IPv4 and IPv6 protocols (for reference): # # stats = TCPSTATS() # print "IPv4 statistics:", # if Iphlpapi.GetTcpStatisticsEx(byref(stats), socket.AF_INET) == 0: # print str(stats) # else: # print "Error getting statistics for IPv4" # print # stats = TCPSTATS() # print "IPv6 statistics:", # if Iphlpapi.GetTcpStatisticsEx(byref(stats), socket.AF_INET6) == 0: # print str(stats) # else: # print "Error getting statistics for IPv6" for (Protocol, GetProtocolStats, StructType) in StatsFuncs: print "-" * 30 print Protocol, "statistics" print "-" * 30 print stats = StructType() if GetProtocolStats(byref(stats), socket.AF_INET): print "Error getting", Protocol, "v4 statistics" else: print Protocol, "v4 statistics" print "-" * 20 stats.formatted_string() print if GetProtocolStats(byref(stats), socket.AF_INET6): print "Error getting", Protocol, "v6 statistics" else: print Protocol, "v6 statistics:" print "-" * 20 stats.formatted_string() print sys.exit(0)