diff --git a/include/sigar_private.h b/include/sigar_private.h index f64baf2f..8e6728bf 100644 --- a/include/sigar_private.h +++ b/include/sigar_private.h @@ -66,6 +66,9 @@ /* cpu ticks to seconds */ #define SIGAR_TICK2SEC(s) ((s) / sigar->ticks) +#define IFTYPE_LO 2 +#define IFTYPE_ETH 3 + #define SIGAR_LAST_PROC_EXPIRE 2 #define SIGAR_FS_MAX 10 @@ -212,4 +215,8 @@ int sigar_group_name_get(sigar_t *sigar, int gid, char *buf, int buflen); fsusage->disk_read_bytes = fsusage->disk_write_bytes = \ fsusage->disk_queue = SIGAR_FIELD_NOTIMPL; +#if defined(WIN32) || defined(NETWARE) +int sigar_get_iftype(const char *name, int *type, int *inst); +#endif + #endif diff --git a/src/os/netware/Makefile b/src/os/netware/Makefile index 99261ffe..0609b30b 100644 --- a/src/os/netware/Makefile +++ b/src/os/netware/Makefile @@ -46,7 +46,8 @@ SIGAR_SRC = \ ..\..\sigar_cache.c \ ..\..\sigar_getline.c \ ..\..\sigar_fileinfo.c \ -..\..\sigar_util.c +..\..\sigar_util.c \ +..\..\sigar_win32ish.c \ JNI_SRC = $(JBINDINGS)\src\jni\javasigar.c diff --git a/src/os/netware/netware_sigar.c b/src/os/netware/netware_sigar.c index d8354612..5f0a2de1 100644 --- a/src/os/netware/netware_sigar.c +++ b/src/os/netware/netware_sigar.c @@ -292,19 +292,6 @@ int sigar_net_route_list_get(sigar_t *sigar, return SIGAR_ENOTIMPL; } -int sigar_net_interface_list_get(sigar_t *sigar, - sigar_net_interface_list_t *iflist) -{ - return SIGAR_ENOTIMPL; -} - -int sigar_net_interface_config_get(sigar_t *sigar, - const char *name, - sigar_net_interface_config_t *ifconfig) -{ - return SIGAR_ENOTIMPL; -} - int sigar_net_interface_stat_get(sigar_t *sigar, const char *name, sigar_net_interface_stat_t *ifstat) { diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index 1ab93ec8..10d041c5 100644 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -311,23 +311,6 @@ char *sigar_os_error_string(sigar_t *sigar, int err) return NULL; } -int sigar_wsa_init(sigar_t *sigar) -{ - if (sigar->ws_version == 0) { - WSADATA data; - - if (WSAStartup(MAKEWORD(2, 0), &data)) { - sigar->ws_error = WSAGetLastError(); - WSACleanup(); - return sigar->ws_error; - } - - sigar->ws_version = data.wVersion; - } - - return SIGAR_OK; -} - SIGAR_DECLARE(int) sigar_mem_get(sigar_t *sigar, sigar_mem_t *mem) { MEMORYSTATUS memstat; @@ -1741,31 +1724,6 @@ SIGAR_DECLARE(int) sigar_net_route_list_get(sigar_t *sigar, return SIGAR_OK; } -#define IFTYPE_LO 2 -#define IFTYPE_ETH 3 - -static int get_iftype(const char *name, int *type, int *inst) -{ - if (strnEQ(name, "eth", IFTYPE_ETH)) { - *type = IFTYPE_ETH; - } - else if (strnEQ(name, "lo", IFTYPE_LO)) { - *type = IFTYPE_LO; - } - else { - return EINVAL; - } - - if (isdigit(*(name + *type))) { - *inst = atoi(name + *type); - } - else { - return EINVAL; - } - - return SIGAR_OK; -} - SIGAR_DECLARE(int) sigar_net_interface_stat_get(sigar_t *sigar, const char *name, sigar_net_interface_stat_t *ifstat) @@ -1778,7 +1736,7 @@ sigar_net_interface_stat_get(sigar_t *sigar, const char *name, DWORD lo=0, eth=0; int status, type, inst; - if ((status = get_iftype(name, &type, &inst)) != SIGAR_OK) { + if ((status = sigar_get_iftype(name, &type, &inst)) != SIGAR_OK) { return status; } @@ -1848,220 +1806,6 @@ sigar_net_interface_stat_get(sigar_t *sigar, const char *name, return SIGAR_OK; } -static int get_iflist(sigar_t *sigar, char *buffer, DWORD buflen, DWORD *bytes) -{ - SOCKET sock = INVALID_SOCKET; - DWORD rc; - int status = sigar_wsa_init(sigar); - - if (status != SIGAR_OK) { - return status; - } - - sock = WSASocket(PF_INET, SOCK_RAW, AF_INET, 0, 0, 0); - if (sock == INVALID_SOCKET) { - return WSAGetLastError(); - } - - rc = WSAIoctl(sock, - SIO_GET_INTERFACE_LIST, - NULL, - 0, - (void *)buffer, - buflen, - bytes, - 0, - 0); - - status = rc ? WSAGetLastError() : SIGAR_OK; - - closesocket(sock); - - return status; -} - -#include - -static void hwaddr_lookup(sigar_net_interface_config_t *ifconfig, int num) -{ - NCB ncb; - UCHAR rc; - struct { - ADAPTER_STATUS status; - NAME_BUFFER name[30]; - } adapter; - - memset(&ncb, 0, sizeof(ncb)); - ncb.ncb_command = NCBRESET; - ncb.ncb_lana_num = num; - Netbios(&ncb); - - memset(&ncb, 0, sizeof(ncb)); - ncb.ncb_command = NCBASTAT; - ncb.ncb_lana_num = num; - - /* - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netbios/netbios_1l82.asp - * mdsn docs claim this needs to be padded with spaces and - * suggest the following silly code: - * strcpy(ncb.ncb_callname, "* "); - */ - ncb.ncb_callname[0] = '*'; - memset(&ncb.ncb_callname[1], ' ', - sizeof(ncb.ncb_callname)-1); - - ncb.ncb_callname[sizeof(ncb.ncb_callname)] = '\0'; - - ncb.ncb_buffer = (unsigned char *)&adapter; - ncb.ncb_length = sizeof(adapter); - if ((rc = Netbios(&ncb)) == 0) { - sigar_hwaddr_format(ifconfig->hwaddr, - adapter.status.adapter_address); - } - else { - sigar_hwaddr_set_null(ifconfig); - } -} - -SIGAR_DECLARE(int) -sigar_net_interface_config_get(sigar_t *sigar, - const char *name, - sigar_net_interface_config_t *ifconfig) -{ - char buffer[8192]; - DWORD i, num, bytes, inst; - DWORD lo=0, eth=0; - int status, type; - INTERFACE_INFO *if_info = NULL; - u_long flags; - - /* win32 lacks socket ioctls to query given interface. - * so we loop through the list to find our made up ifname. - */ - status = get_iflist(sigar, buffer, sizeof(buffer), &bytes); - if (status != SIGAR_OK) { - return status; - } - - num = bytes / sizeof(INTERFACE_INFO); - - if ((status = get_iftype(name, &type, &inst)) != SIGAR_OK) { - return status; - } - - for (i=0; iiiFlags & IFF_LOOPBACK) { - if ((type == IFTYPE_LO) && (inst == lo)) { - break; - } - ++lo; - } - else { - if ((type == IFTYPE_ETH) && (inst == eth)) { - break; - } - ++eth; - } - - if_info = NULL; - } - - if (!if_info) { - return ENOENT; - } - - SIGAR_ZERO(ifconfig); - - SIGAR_SSTRCPY(ifconfig->name, name); - -#define if_s_addr(a) \ - ((struct sockaddr_in *)&a)->sin_addr.s_addr - - ifconfig->address = if_s_addr(if_info->iiAddress); - ifconfig->broadcast = if_s_addr(if_info->iiBroadcastAddress); - ifconfig->netmask = if_s_addr(if_info->iiNetmask); - - flags = if_info->iiFlags; - - if (flags & IFF_UP) { - ifconfig->flags |= SIGAR_IFF_UP|SIGAR_IFF_RUNNING; - } - if (flags & IFF_BROADCAST) { - ifconfig->flags |= SIGAR_IFF_BROADCAST; - } - if (flags & IFF_LOOPBACK) { - ifconfig->flags |= SIGAR_IFF_LOOPBACK; - ifconfig->destination = ifconfig->address; - ifconfig->broadcast = 0; - sigar_hwaddr_set_null(ifconfig); - } - else { - hwaddr_lookup(ifconfig, i); - } - if (flags & IFF_POINTTOPOINT) { - ifconfig->flags |= SIGAR_IFF_POINTOPOINT; - } - if (flags & IFF_MULTICAST) { - ifconfig->flags |= SIGAR_IFF_MULTICAST; - } - - return SIGAR_OK; -} - -/* - * win32 interface list does not include a name. - * and the name from GetIfList() is the name of card - * including vendor name, etc. so we use 'eth' for ethernet - * interfaces and 'lo' for loopback. - */ - -#define ETH "eth" -#define LO "lo" - -SIGAR_DECLARE(int) -sigar_net_interface_list_get(sigar_t *sigar, - sigar_net_interface_list_t *iflist) -{ - char eth[56], lo[56]; - int ethcnt=0, locnt=0; - char buffer[8192]; - DWORD i, num, bytes; - int status; - - status = get_iflist(sigar, buffer, sizeof(buffer), &bytes); - if (status != SIGAR_OK) { - return status; - } - - num = bytes / sizeof(INTERFACE_INFO); - - iflist->number = 0; - iflist->size = num; - iflist->data = - malloc(sizeof(*(iflist->data)) * iflist->size); - - for (i=0; iiiFlags & IFF_LOOPBACK) { - sprintf(lo, LO "%d", locnt++); - name = strdup(lo); - } - else { - /* XXX: assuming ethernet here */ - sprintf(eth, ETH "%d", ethcnt++); - name = strdup(eth); - } - - iflist->data[iflist->number++] = name; - } - - return SIGAR_OK; -} - #define IS_TCP_SERVER(state, flags) \ ((flags & SIGAR_NETCONN_SERVER) && (state == MIB_TCP_STATE_LISTEN)) diff --git a/src/sigar_win32ish.c b/src/sigar_win32ish.c new file mode 100644 index 00000000..d24bfb92 --- /dev/null +++ b/src/sigar_win32ish.c @@ -0,0 +1,286 @@ +#if defined(WIN32) || defined(NETWARE) + +#define WIN32_LEAN_AND_MEAN + +#include "sigar.h" +#include "sigar_private.h" +#include "sigar_os.h" +#include "sigar_util.h" + +#include +#include +#ifdef NETWARE +#include +#include +#include +#endif + +int sigar_get_iftype(const char *name, int *type, int *inst) +{ + if (strnEQ(name, "eth", IFTYPE_ETH)) { + *type = IFTYPE_ETH; + } + else if (strnEQ(name, "lo", IFTYPE_LO)) { + *type = IFTYPE_LO; + } + else { + return EINVAL; + } + + if (isdigit(*(name + *type))) { + *inst = atoi(name + *type); + } + else { + return EINVAL; + } + + return SIGAR_OK; +} + +#ifdef WIN32 +int sigar_wsa_init(sigar_t *sigar) +{ + if (sigar->ws_version == 0) { + WSADATA data; + + if (WSAStartup(MAKEWORD(2, 0), &data)) { + sigar->ws_error = WSAGetLastError(); + WSACleanup(); + return sigar->ws_error; + } + + sigar->ws_version = data.wVersion; + } + + return SIGAR_OK; +} + +#include + +static void hwaddr_lookup(sigar_net_interface_config_t *ifconfig, int num) +{ + NCB ncb; + UCHAR rc; + struct { + ADAPTER_STATUS status; + NAME_BUFFER name[30]; + } adapter; + + memset(&ncb, 0, sizeof(ncb)); + ncb.ncb_command = NCBRESET; + ncb.ncb_lana_num = num; + Netbios(&ncb); + + memset(&ncb, 0, sizeof(ncb)); + ncb.ncb_command = NCBASTAT; + ncb.ncb_lana_num = num; + + /* + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netbios/netbios_1l82.asp + * mdsn docs claim this needs to be padded with spaces and + * suggest the following silly code: + * strcpy(ncb.ncb_callname, "* "); + */ + ncb.ncb_callname[0] = '*'; + memset(&ncb.ncb_callname[1], ' ', + sizeof(ncb.ncb_callname)-1); + + ncb.ncb_callname[sizeof(ncb.ncb_callname)] = '\0'; + + ncb.ncb_buffer = (unsigned char *)&adapter; + ncb.ncb_length = sizeof(adapter); + if ((rc = Netbios(&ncb)) == 0) { + sigar_hwaddr_format(ifconfig->hwaddr, + adapter.status.adapter_address); + } + else { + sigar_hwaddr_set_null(ifconfig); + } +} + +#else /* NETWARE */ + +static void hwaddr_lookup(sigar_net_interface_config_t *ifconfig, int num) +{ + sigar_hwaddr_set_null(ifconfig); +} + +#endif /* WIN32 */ + +static int get_iflist(sigar_t *sigar, char *buffer, DWORD buflen, DWORD *bytes) +{ + SOCKET sock = INVALID_SOCKET; + int status, rc; + +#ifdef WIN32 + status = sigar_wsa_init(sigar); + + if (status != SIGAR_OK) { + return status; + } + sock = WSASocket(PF_INET, SOCK_RAW, AF_INET, 0, 0, 0); +#else + sock = socket(AF_INET, SOCK_DGRAM, 0); +#endif + + if (sock == INVALID_SOCKET) { + return WSAGetLastError(); + } + + rc = WSAIoctl(sock, + SIO_GET_INTERFACE_LIST, + NULL, + 0, + (void *)buffer, + buflen, + (unsigned int*)bytes, + NULL, + NULL); + + status = rc ? WSAGetLastError() : SIGAR_OK; + + closesocket(sock); + + return status; +} + +SIGAR_DECLARE(int) +sigar_net_interface_config_get(sigar_t *sigar, + const char *name, + sigar_net_interface_config_t *ifconfig) +{ + char buffer[8192]; + DWORD i, num, bytes; + DWORD lo=0, eth=0; + int status, type, inst; + INTERFACE_INFO *if_info = NULL; + u_long flags; + + /* win32 lacks socket ioctls to query given interface. + * so we loop through the list to find our made up ifname. + */ + status = get_iflist(sigar, buffer, sizeof(buffer), &bytes); + if (status != SIGAR_OK) { + return status; + } + + num = bytes / sizeof(INTERFACE_INFO); + + if ((status = sigar_get_iftype(name, &type, &inst)) != SIGAR_OK) { + return status; + } + + for (i=0; iiiFlags & IFF_LOOPBACK) { + if ((type == IFTYPE_LO) && (inst == lo)) { + break; + } + ++lo; + } + else { + if ((type == IFTYPE_ETH) && (inst == eth)) { + break; + } + ++eth; + } + + if_info = NULL; + } + + if (!if_info) { + return ENOENT; + } + + SIGAR_ZERO(ifconfig); + + SIGAR_SSTRCPY(ifconfig->name, name); + +#define if_s_addr(a) \ + ((struct sockaddr_in *)&a)->sin_addr.s_addr + + ifconfig->address = if_s_addr(if_info->iiAddress); + ifconfig->broadcast = if_s_addr(if_info->iiBroadcastAddress); + ifconfig->netmask = if_s_addr(if_info->iiNetmask); + + flags = if_info->iiFlags; + + if (flags & IFF_UP) { + ifconfig->flags |= SIGAR_IFF_UP|SIGAR_IFF_RUNNING; + } + if (flags & IFF_BROADCAST) { + ifconfig->flags |= SIGAR_IFF_BROADCAST; + } + if (flags & IFF_LOOPBACK) { + ifconfig->flags |= SIGAR_IFF_LOOPBACK; + ifconfig->destination = ifconfig->address; + ifconfig->broadcast = 0; + sigar_hwaddr_set_null(ifconfig); + } + else { + hwaddr_lookup(ifconfig, i); + } + if (flags & IFF_POINTTOPOINT) { + ifconfig->flags |= SIGAR_IFF_POINTOPOINT; + } + if (flags & IFF_MULTICAST) { + ifconfig->flags |= SIGAR_IFF_MULTICAST; + } + + return SIGAR_OK; +} + +/* + * win32 interface list does not include a name. + * and the name from GetIfList() is the name of card + * including vendor name, etc. so we use 'eth' for ethernet + * interfaces and 'lo' for loopback. + */ + +#define ETH "eth" +#define LO "lo" + +SIGAR_DECLARE(int) +sigar_net_interface_list_get(sigar_t *sigar, + sigar_net_interface_list_t *iflist) +{ + char eth[56], lo[56]; + int ethcnt=0, locnt=0; + char buffer[8192]; + DWORD i, num, bytes; + int status; + + status = get_iflist(sigar, buffer, sizeof(buffer), &bytes); + if (status != SIGAR_OK) { + return status; + } + + num = bytes / sizeof(INTERFACE_INFO); + + iflist->number = 0; + iflist->size = num; + iflist->data = + malloc(sizeof(*(iflist->data)) * iflist->size); + + for (i=0; iiiFlags & IFF_LOOPBACK) { + sprintf(lo, LO "%d", locnt++); + name = strdup(lo); + } + else { + /* XXX: assuming ethernet here */ + sprintf(eth, ETH "%d", ethcnt++); + name = strdup(eth); + } + + iflist->data[iflist->number++] = name; + } + + return SIGAR_OK; +} + +#endif /* WIN32ISH */