int NetworkMuninNodePlugin::GetValues(char *buffer, int len) { int ret = 0; MIB_TCPSTATS tcpStats; MIB_UDPSTATS udpStats; ret = GetTcpStatistics(&tcpStats); ret = GetUdpStatistics(&udpStats); _snprintf(buffer, len, "down.value %u\nup.value %u\n.\n", tcpStats.dwInSegs + udpStats.dwInDatagrams, tcpStats.dwOutSegs + udpStats.dwOutDatagrams); return 0; };
int udp_load(netsnmp_cache *cache, void *vmagic) { long ret_value = -1; ret_value = GetUdpStatistics(&udpstat); if ( ret_value < 0 ) { DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (win32)\n")); } else { DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (win32)\n")); } return ret_value; }
static void NETSTAT_udp_stats(void) { PMIB_UDPSTATS stats; stats = (PMIB_UDPSTATS)HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_UDPSTATS)); if (GetUdpStatistics(stats) == NO_ERROR) { NETSTAT_wprintf(fmtnn, NETSTAT_load_message(IDS_UDP_STAT)); NETSTAT_wprintf(fmtn); NETSTAT_wprintf(fmtudpstat, NETSTAT_load_message(IDS_UDP_DGRAMS_RECV), stats->dwInDatagrams); NETSTAT_wprintf(fmtudpstat, NETSTAT_load_message(IDS_UDP_NO_PORTS), stats->dwNoPorts); NETSTAT_wprintf(fmtudpstat, NETSTAT_load_message(IDS_UDP_RECV_ERRORS), stats->dwInErrors); NETSTAT_wprintf(fmtudpstat, NETSTAT_load_message(IDS_UDP_DGRAMS_SENT), stats->dwOutDatagrams); } HeapFree(GetProcessHeap(), 0, stats); }
VOID ShowUdpStatistics() { PMIB_UDPSTATS pUdpStats; DWORD dwRetVal; pUdpStats = (MIB_UDPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_UDPSTATS)); if ((dwRetVal = GetUdpStatistics(pUdpStats)) == NO_ERROR) { _tprintf(_T("\nUDP Statistics for IPv4\n\n")); _tprintf(_T(" %-21s = %lu\n"), _T("Datagrams Received"), pUdpStats->dwInDatagrams); _tprintf(_T(" %-21s = %lu\n"), _T("No Ports"), pUdpStats->dwNoPorts); _tprintf(_T(" %-21s = %lu\n"), _T("Receive Errors"), pUdpStats->dwInErrors); _tprintf(_T(" %-21s = %lu\n"), _T("Datagrams Sent"), pUdpStats->dwOutDatagrams); } else DoFormatMessage(dwRetVal); HeapFree(GetProcessHeap(), 0, pUdpStats); }
long read_udp_stat(UDP_STAT_STRUCTURE * udpstat, int magic) { long ret_value = -1; #if (defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS)) static int sname[4] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS }; size_t len = sizeof(*udpstat); #endif #ifdef solaris2 static mib2_ip_t ipstat; #endif #ifdef hpux11 int fd; struct nmparms p; unsigned int ulen; if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) return (-1); /* error */ switch (magic) { case UDPINDATAGRAMS: p.objid = ID_udpInDatagrams; break; case UDPNOPORTS: p.objid = ID_udpNoPorts; break; case UDPOUTDATAGRAMS: p.objid = ID_udpOutDatagrams; break; case UDPINERRORS: p.objid = ID_udpInErrors; break; default: *udpstat = 0; close_mib(fd); return (0); } p.buffer = (void *) udpstat; ulen = sizeof(UDP_STAT_STRUCTURE); p.len = &ulen; ret_value = get_mib_info(fd, &p); close_mib(fd); return (ret_value); /* 0: ok, < 0: error */ #else /* hpux11 */ if (udp_stats_cache_marker && (!atime_ready (udp_stats_cache_marker, UDP_STATS_CACHE_TIMEOUT * 1000))) #ifdef solaris2 return (magic == UDPNOPORTS ? ipstat.udpNoPorts : 0); #else return 0; #endif if (udp_stats_cache_marker) atime_setMarker(udp_stats_cache_marker); else udp_stats_cache_marker = atime_newMarker(); #ifdef linux ret_value = linux_read_udp_stat(udpstat); #endif #ifdef WIN32 ret_value = GetUdpStatistics(udpstat); #endif #ifdef solaris2 if (magic == UDPNOPORTS) { if (getMibstat (MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST, &Get_everything, NULL) < 0) ret_value = -1; else ret_value = ipstat.udpNoPorts; } else ret_value = getMibstat(MIB_UDP, udpstat, sizeof(mib2_udp_t), GET_FIRST, &Get_everything, NULL); #endif #ifdef HAVE_SYS_TCPIPSTATS_H ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, udpstat, sizeof *udpstat); #endif #if defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS) ret_value = sysctl(sname, 4, udpstat, &len, 0, 0); #endif #ifdef UDPSTAT_SYMBOL if (auto_nlist(UDPSTAT_SYMBOL, (char *) udpstat, sizeof(*udpstat))) ret_value = 0; #endif if (ret_value == -1) { free(udp_stats_cache_marker); udp_stats_cache_marker = NULL; } return ret_value; #endif /* hpux11 */ }
DWORD WINAPI WsControl(DWORD protocol, DWORD action, LPVOID pRequestInfo, LPDWORD pcbRequestInfoLen, LPVOID pResponseInfo, LPDWORD pcbResponseInfoLen) { /* Get the command structure into a pointer we can use, rather than void */ TDIObjectID *pcommand = pRequestInfo; /* validate input parameters. Error codes are from winerror.h, not from * winsock.h. pcbResponseInfoLen is apparently allowed to be NULL for some * commands, since winipcfg.exe fails if we ensure it's non-NULL in every * case. */ if (protocol != IPPROTO_TCP) return ERROR_INVALID_PARAMETER; if (!pcommand) return ERROR_INVALID_PARAMETER; if (!pcbRequestInfoLen) return ERROR_INVALID_ACCESS; if (*pcbRequestInfoLen < sizeof(TDIObjectID)) return ERROR_INVALID_ACCESS; if (!pResponseInfo) return ERROR_INVALID_PARAMETER; if (pcommand->toi_type != INFO_TYPE_PROVIDER) return ERROR_INVALID_PARAMETER; TRACE (" WsControl TOI_ID=>0x%lx<, {TEI_ENTITY=0x%lx, TEI_INSTANCE=0x%lx}, TOI_CLASS=0x%lx, TOI_TYPE=0x%lx\n", pcommand->toi_id, pcommand->toi_entity.tei_entity, pcommand->toi_entity.tei_instance, pcommand->toi_class, pcommand->toi_type ); switch (action) { case WSCNTL_TCPIP_QUERY_INFO: { if (pcommand->toi_class != INFO_CLASS_GENERIC && pcommand->toi_class != INFO_CLASS_PROTOCOL) { ERR("Unexpected class %ld for WSCNTL_TCPIP_QUERY_INFO\n", pcommand->toi_class); return ERROR_BAD_ENVIRONMENT; } switch (pcommand->toi_id) { /* ENTITY_LIST_ID gets the list of "entity IDs", where an entity may represent an interface, or a datagram service, or address translation, or other fun things. Typically an entity ID represents a class of service, which is further queried for what type it is. Different types will then have more specific queries defined. */ case ENTITY_LIST_ID: { TDIEntityID *baseptr = pResponseInfo; DWORD numInt, i, ifTable, spaceNeeded; PMIB_IFTABLE table; if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; if (pcommand->toi_class != INFO_CLASS_GENERIC) { FIXME ("Unexpected Option for ENTITY_LIST_ID request -> toi_class=0x%lx\n", pcommand->toi_class); return (ERROR_BAD_ENVIRONMENT); } GetNumberOfInterfaces(&numInt); spaceNeeded = sizeof(TDIEntityID) * (numInt * 2 + 3); if (*pcbResponseInfoLen < spaceNeeded) return (ERROR_LOCK_VIOLATION); ifTable = 0; GetIfTable(NULL, &ifTable, FALSE); table = HeapAlloc( GetProcessHeap(), 0, ifTable ); if (!table) return ERROR_NOT_ENOUGH_MEMORY; GetIfTable(table, &ifTable, FALSE); spaceNeeded = sizeof(TDIEntityID) * (table->dwNumEntries + 4); if (*pcbResponseInfoLen < spaceNeeded) { HeapFree( GetProcessHeap(), 0, table ); return ERROR_LOCK_VIOLATION; } memset(baseptr, 0, spaceNeeded); for (i = 0; i < table->dwNumEntries; i++) { /* Return IF_GENERIC and CL_NL_ENTITY on every interface, and * AT_ENTITY, CL_TL_ENTITY, and CO_TL_ENTITY on the first * interface. MS returns them only on the loopback interface, * but it doesn't seem to matter. */ if (i == 0) { baseptr->tei_entity = CO_TL_ENTITY; baseptr->tei_instance = table->table[i].dwIndex; baseptr++; baseptr->tei_entity = CL_TL_ENTITY; baseptr->tei_instance = table->table[i].dwIndex; baseptr++; baseptr->tei_entity = AT_ENTITY; baseptr->tei_instance = table->table[i].dwIndex; baseptr++; } baseptr->tei_entity = CL_NL_ENTITY; baseptr->tei_instance = table->table[i].dwIndex; baseptr++; baseptr->tei_entity = IF_GENERIC; baseptr->tei_instance = table->table[i].dwIndex; baseptr++; } *pcbResponseInfoLen = spaceNeeded; HeapFree( GetProcessHeap(), 0, table ); break; } /* Returns MIB-II statistics for an interface */ case ENTITY_TYPE_ID: switch (pcommand->toi_entity.tei_entity) { case IF_GENERIC: if (pcommand->toi_class == INFO_CLASS_GENERIC) { if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; *((ULONG *)pResponseInfo) = IF_MIB; *pcbResponseInfoLen = sizeof(ULONG); } else if (pcommand->toi_class == INFO_CLASS_PROTOCOL) { MIB_IFROW row; DWORD index = pcommand->toi_entity.tei_instance, ret; DWORD size = sizeof(row) - sizeof(row.wszName) - sizeof(row.bDescr); if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; if (*pcbResponseInfoLen < size) return (ERROR_LOCK_VIOLATION); row.dwIndex = index; ret = GetIfEntry(&row); if (ret != NO_ERROR) { /* FIXME: Win98's arp.exe insists on querying index 1 for * its MIB-II stats, regardless of the tei_instances * returned in the ENTITY_LIST query above. If the query * fails, arp.exe fails. So, I do this hack return value * if index is 1 and the query failed just to get arp.exe * to continue. */ if (index == 1) return NO_ERROR; ERR ("Error retrieving data for interface index %u\n", index); return ret; } size = sizeof(row) - sizeof(row.wszName) - sizeof(row.bDescr) + row.dwDescrLen; if (*pcbResponseInfoLen < size) return (ERROR_LOCK_VIOLATION); memcpy(pResponseInfo, &row.dwIndex, size); *pcbResponseInfoLen = size; } break; /* Returns address-translation related data. In our case, this is * ARP. */ case AT_ENTITY: if (pcommand->toi_class == INFO_CLASS_GENERIC) { if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; *((ULONG *)pResponseInfo) = AT_ARP; *pcbResponseInfoLen = sizeof(ULONG); } else if (pcommand->toi_class == INFO_CLASS_PROTOCOL) { PMIB_IPNETTABLE table; DWORD size; PULONG output = pResponseInfo; if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; if (*pcbResponseInfoLen < sizeof(ULONG) * 2) return (ERROR_LOCK_VIOLATION); GetIpNetTable(NULL, &size, FALSE); table = HeapAlloc( GetProcessHeap(), 0, size ); if (!table) return ERROR_NOT_ENOUGH_MEMORY; GetIpNetTable(table, &size, FALSE); /* FIXME: I don't understand the meaning of the ARP output * very well, but it seems to indicate how many ARP entries * exist. I don't know whether this should reflect the * number per interface, as I'm only testing with a single * interface. So, I lie and say all ARP entries exist on * a single interface--the first one that appears in the * ARP table. */ *(output++) = table->dwNumEntries; *output = table->table[0].dwIndex; HeapFree( GetProcessHeap(), 0, table ); *pcbResponseInfoLen = sizeof(ULONG) * 2; } break; /* Returns connectionless network layer statistics--in our case, * this is IP. */ case CL_NL_ENTITY: if (pcommand->toi_class == INFO_CLASS_GENERIC) { if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; *((ULONG *)pResponseInfo) = CL_NL_IP; *pcbResponseInfoLen = sizeof(ULONG); } else if (pcommand->toi_class == INFO_CLASS_PROTOCOL) { if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; if (*pcbResponseInfoLen < sizeof(MIB_IPSTATS)) return ERROR_LOCK_VIOLATION; GetIpStatistics(pResponseInfo); *pcbResponseInfoLen = sizeof(MIB_IPSTATS); } break; /* Returns connectionless transport layer statistics--in our case, * this is UDP. */ case CL_TL_ENTITY: if (pcommand->toi_class == INFO_CLASS_GENERIC) { if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; *((ULONG *)pResponseInfo) = CL_TL_UDP; *pcbResponseInfoLen = sizeof(ULONG); } else if (pcommand->toi_class == INFO_CLASS_PROTOCOL) { if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; if (*pcbResponseInfoLen < sizeof(MIB_UDPSTATS)) return ERROR_LOCK_VIOLATION; GetUdpStatistics(pResponseInfo); *pcbResponseInfoLen = sizeof(MIB_UDPSTATS); } break; /* Returns connection-oriented transport layer statistics--in our * case, this is TCP. */ case CO_TL_ENTITY: if (pcommand->toi_class == INFO_CLASS_GENERIC) { if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; *((ULONG *)pResponseInfo) = CO_TL_TCP; *pcbResponseInfoLen = sizeof(ULONG); } else if (pcommand->toi_class == INFO_CLASS_PROTOCOL) { if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; if (*pcbResponseInfoLen < sizeof(MIB_TCPSTATS)) return ERROR_LOCK_VIOLATION; GetTcpStatistics(pResponseInfo); *pcbResponseInfoLen = sizeof(MIB_TCPSTATS); } break; default: ERR("Unknown entity %ld for ENTITY_TYPE_ID query\n", pcommand->toi_entity.tei_entity); } break; /* This call returns the IP address, subnet mask, and broadcast * address for an interface. If there are multiple IP addresses for * the interface with the given index, returns the "first" one. */ case IP_MIB_ADDRTABLE_ENTRY_ID: { DWORD index = pcommand->toi_entity.tei_instance; PMIB_IPADDRROW baseIPInfo = pResponseInfo; PMIB_IPADDRTABLE table; DWORD tableSize, i; if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; if (*pcbResponseInfoLen < sizeof(MIB_IPADDRROW)) return (ERROR_LOCK_VIOLATION); /* get entire table, because there isn't an exported function that gets just one entry. */ tableSize = 0; GetIpAddrTable(NULL, &tableSize, FALSE); table = HeapAlloc( GetProcessHeap(), 0, tableSize ); if (!table) return ERROR_NOT_ENOUGH_MEMORY; GetIpAddrTable(table, &tableSize, FALSE); for (i = 0; i < table->dwNumEntries; i++) { if (table->table[i].dwIndex == index) { TRACE("Found IP info for tei_instance 0x%x:\n", index); TRACE("IP 0x%08x, mask 0x%08x\n", table->table[i].dwAddr, table->table[i].dwMask); *baseIPInfo = table->table[i]; break; } } HeapFree( GetProcessHeap(), 0, table ); *pcbResponseInfoLen = sizeof(MIB_IPADDRROW); break; } case IP_MIB_TABLE_ENTRY_ID: { switch (pcommand->toi_entity.tei_entity) { /* This call returns the routing table. * No official documentation found, even the name of the command is unknown. * Work is based on * http://www.cyberport.com/~tangent/programming/winsock/articles/wscontrol.html * and testings done with winipcfg.exe, route.exe and ipconfig.exe. * pcommand->toi_entity.tei_instance seems to be the interface number * but route.exe outputs only the information for the last interface * if only the routes for the pcommand->toi_entity.tei_instance * interface are returned. */ case CL_NL_ENTITY: { DWORD routeTableSize, numRoutes, ndx, ret; PMIB_IPFORWARDTABLE table; IPRouteEntry *winRouteTable = pResponseInfo; if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; ret = GetIpForwardTable(NULL, &routeTableSize, FALSE); if (ret != ERROR_INSUFFICIENT_BUFFER) return ret; numRoutes = (routeTableSize - sizeof(MIB_IPFORWARDTABLE)) / sizeof(MIB_IPFORWARDROW) + 1; if (*pcbResponseInfoLen < sizeof(IPRouteEntry) * numRoutes) return (ERROR_LOCK_VIOLATION); table = HeapAlloc( GetProcessHeap(), 0, routeTableSize ); if (!table) return ERROR_NOT_ENOUGH_MEMORY; ret = GetIpForwardTable(table, &routeTableSize, FALSE); if (ret != NO_ERROR) { HeapFree( GetProcessHeap(), 0, table ); return ret; } memset(pResponseInfo, 0, sizeof(IPRouteEntry) * numRoutes); for (ndx = 0; ndx < table->dwNumEntries; ndx++) { winRouteTable->ire_addr = table->table[ndx].dwForwardDest; winRouteTable->ire_index = table->table[ndx].dwForwardIfIndex; winRouteTable->ire_metric = table->table[ndx].dwForwardMetric1; /* winRouteTable->ire_option4 = winRouteTable->ire_option5 = winRouteTable->ire_option6 = */ winRouteTable->ire_gw = table->table[ndx].dwForwardNextHop; /* winRouteTable->ire_option8 = winRouteTable->ire_option9 = winRouteTable->ire_option10 = */ winRouteTable->ire_mask = table->table[ndx].dwForwardMask; /* winRouteTable->ire_option12 = */ winRouteTable++; } /* calculate the length of the data in the output buffer */ *pcbResponseInfoLen = sizeof(IPRouteEntry) * table->dwNumEntries; HeapFree( GetProcessHeap(), 0, table ); } break; case AT_ARP: { DWORD arpTableSize, numEntries, ret; PMIB_IPNETTABLE table; if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; ret = GetIpNetTable(NULL, &arpTableSize, FALSE); if (ret != ERROR_INSUFFICIENT_BUFFER) return ret; numEntries = (arpTableSize - sizeof(MIB_IPNETTABLE)) / sizeof(MIB_IPNETROW) + 1; if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) * numEntries) return (ERROR_LOCK_VIOLATION); table = HeapAlloc( GetProcessHeap(), 0, arpTableSize ); if (!table) return ERROR_NOT_ENOUGH_MEMORY; ret = GetIpNetTable(table, &arpTableSize, FALSE); if (ret != NO_ERROR) { HeapFree( GetProcessHeap(), 0, table ); return ret; } if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) * table->dwNumEntries) { HeapFree( GetProcessHeap(), 0, table ); return ERROR_LOCK_VIOLATION; } memcpy(pResponseInfo, table->table, sizeof(MIB_IPNETROW) * table->dwNumEntries); /* calculate the length of the data in the output buffer */ *pcbResponseInfoLen = sizeof(MIB_IPNETROW) * table->dwNumEntries; HeapFree( GetProcessHeap(), 0, table ); } break; case CO_TL_ENTITY: { DWORD tcpTableSize, numEntries, ret; PMIB_TCPTABLE table; DWORD i; if (!pcbResponseInfoLen) return ERROR_BAD_ENVIRONMENT; ret = GetTcpTable(NULL, &tcpTableSize, FALSE); if (ret != ERROR_INSUFFICIENT_BUFFER) return ret; numEntries = (tcpTableSize - sizeof(MIB_TCPTABLE)) / sizeof(MIB_TCPROW) + 1; if (*pcbResponseInfoLen < sizeof(MIB_TCPROW) * numEntries) return (ERROR_LOCK_VIOLATION); table = HeapAlloc( GetProcessHeap(), 0, tcpTableSize ); if (!table) return ERROR_NOT_ENOUGH_MEMORY; ret = GetTcpTable(table, &tcpTableSize, FALSE); if (ret != NO_ERROR) { HeapFree( GetProcessHeap(), 0, table ); return ret; } if (*pcbResponseInfoLen < sizeof(MIB_TCPROW) * table->dwNumEntries) { HeapFree( GetProcessHeap(), 0, table ); return ERROR_LOCK_VIOLATION; } for (i = 0; i < table->dwNumEntries; i++) { USHORT sPort; sPort = ntohs((USHORT)table->table[i].dwLocalPort); table->table[i].dwLocalPort = (DWORD)sPort; sPort = ntohs((USHORT)table->table[i].dwRemotePort); table->table[i].dwRemotePort = (DWORD)sPort; } memcpy(pResponseInfo, table->table, sizeof(MIB_TCPROW) * table->dwNumEntries); /* calculate the length of the data in the output buffer */ *pcbResponseInfoLen = sizeof(MIB_TCPROW) * table->dwNumEntries; HeapFree( GetProcessHeap(), 0, table ); } break; default: { FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n", pcommand->toi_id, pcommand->toi_entity.tei_entity, pcommand->toi_entity.tei_instance, pcommand->toi_class); return (ERROR_BAD_ENVIRONMENT); } } } break; default: { FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n", pcommand->toi_id, pcommand->toi_entity.tei_entity, pcommand->toi_entity.tei_instance, pcommand->toi_class); return (ERROR_BAD_ENVIRONMENT); } } break; } case WSCNTL_TCPIP_ICMP_ECHO: { unsigned int addr = *(unsigned int*)pRequestInfo; #if 0 int timeout= *(unsigned int*)(inbuf+4); short x1 = *(unsigned short*)(inbuf+8); short sendbufsize = *(unsigned short*)(inbuf+10); char x2 = *(unsigned char*)(inbuf+12); char ttl = *(unsigned char*)(inbuf+13); char service = *(unsigned char*)(inbuf+14); char type= *(unsigned char*)(inbuf+15); /* 0x2: don't fragment*/ #endif FIXME("(ICMP_ECHO) to 0x%08x stub\n", addr); break; } default: FIXME("Protocol Not Supported -> protocol=0x%x, action=0x%x, Request=%p, RequestLen=%p, Response=%p, ResponseLen=%p\n", protocol, action, pRequestInfo, pcbRequestInfoLen, pResponseInfo, pcbResponseInfoLen); return (WSAEOPNOTSUPP); } return (WSCTL_SUCCESS); }
static void mib2UdpInit(void) { GetUdpStatistics(&udpStats); }
DWORD MyGetUdpStatistics(PMIB_UDPSTATS& pUdpStats) { pUdpStats = (PMIB_UDPSTATS)malloc(sizeof(MIB_UDPSTATS)); assert(pUdpStats != NULL); return GetUdpStatistics(pUdpStats); }