📄 interface.c
字号:
/* * interfaces.c - network interface function implementation * * Copyright (C) 2000, 2001 Stefan Jahn <stefan@lkcc.org> * Copyright (C) 2000 Raimund Jacob <raimi@lkcc.org> * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * $Id: interface.c,v 1.10 2001/09/27 15:47:36 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#if ENABLE_IFLIST#ifndef __MINGW32__# include <sys/types.h># include <sys/socket.h># include <sys/ioctl.h># include <net/if.h># include <netinet/in.h># include <arpa/inet.h>#endif#if HAVE_UNISTD_H# include <unistd.h>#endif/* Solaris, IRIX */#if HAVE_SYS_SOCKIO_H# include <sys/sockio.h>#endif#ifdef __MINGW32__# include <winsock2.h># include "libserveez/ipdata.h" # include "libserveez/iphlpapi.h"#endif#endif /* ENABLE_IFLIST */#include "libserveez/alloc.h"#include "libserveez/util.h"#include "libserveez/core.h"#include "libserveez/vector.h"#include "libserveez/interface.h"/* * The available interface list. */svz_vector_t *svz_interfaces = NULL;#if ENABLE_IFLIST#ifdef __MINGW32__/* Function pointer definition for use with GetProcAddress. */typedef int (__stdcall *WsControlProc) (DWORD, DWORD, LPVOID, LPDWORD, LPVOID, LPDWORD);#define WSCTL_TCP_QUERY_INFORMATION 0#define WSCTL_TCP_SET_INFORMATION 1 /* * The local interface list is requested by some "unrevealed" Winsock API * routine called "WsControl". Works with Win95 and Win98. * Otherwise try using the IP Helper API which works with WinNT4x and Win2k. */static WsControlProc WsControl = NULL;static GetIfTableProc GetIfTable = NULL;static GetIpAddrTableProc GetIpAddrTable = NULL;#define NO_METHOD 0#define WSCTL_METHOD 1#define IPAPI_METHOD 2voidsvz_interface_collect (void){ int result = 0; HMODULE WSockHandle; WSADATA WSAData; TCP_REQUEST_QUERY_INFORMATION_EX tcpRequestQueryInfoEx; DWORD tcpRequestBufSize; DWORD entityIdsBufSize; TDIEntityID *entityIds; DWORD entityCount; DWORD i, n, k; DWORD ifCount; ULONG entityType; DWORD entityTypeSize; DWORD ifEntrySize; IFEntry *ifEntry; DWORD ipAddrEntryBufSize; IPAddrEntry *ipAddrEntry; ULONG ifTableSize, ipTableSize; PMIB_IFTABLE ifTable; PMIB_IPADDRTABLE ipTable; unsigned long addr; svz_interface_t *ifc; DWORD Method = NO_METHOD; /* * Try getting WsControl () from "wsock32.dll" via LoadLibrary * and GetProcAddress. Or try the IP Helper API. */ if ((WSockHandle = LoadLibrary ("iphlpapi.dll")) != NULL) { Method = IPAPI_METHOD; } else { if ((WSockHandle = LoadLibrary ("wsock32.dll")) != NULL) { WsControl = (WsControlProc) GetProcAddress (WSockHandle, "WsControl"); if (!WsControl) { printf ("GetProcAddress (WsControl): %s\n", SYS_ERROR); FreeLibrary (WSockHandle); return; } Method = WSCTL_METHOD; } else { printf ("LoadLibrary (WSock32.dll): %s\n", SYS_ERROR); return; } } if (Method == WSCTL_METHOD) { result = WSAStartup (MAKEWORD (1, 1), &WSAData); if (result) { printf ("WSAStartup: %s\n", NET_ERROR); FreeLibrary (WSockHandle); return; } memset (&tcpRequestQueryInfoEx, 0, sizeof (tcpRequestQueryInfoEx)); tcpRequestQueryInfoEx.ID.toi_entity.tei_entity = GENERIC_ENTITY; tcpRequestQueryInfoEx.ID.toi_entity.tei_instance = 0; tcpRequestQueryInfoEx.ID.toi_class = INFO_CLASS_GENERIC; tcpRequestQueryInfoEx.ID.toi_type = INFO_TYPE_PROVIDER; tcpRequestQueryInfoEx.ID.toi_id = ENTITY_LIST_ID; tcpRequestBufSize = sizeof (tcpRequestQueryInfoEx); /* * this probably allocates too much space; not sure if MAX_TDI_ENTITIES * represents the max number of entities that can be returned or, if it * is the highest entity value that can be defined. */ entityIdsBufSize = MAX_TDI_ENTITIES * sizeof (TDIEntityID); entityIds = (TDIEntityID *) calloc (1, entityIdsBufSize); result = WsControl (IPPROTO_TCP, WSCTL_TCP_QUERY_INFORMATION, &tcpRequestQueryInfoEx, &tcpRequestBufSize, entityIds, &entityIdsBufSize); if (result) { printf ("WsControl: %s\n", NET_ERROR); WSACleanup (); FreeLibrary (WSockHandle); free (entityIds); return; } /* ... after the call we compute */ entityCount = entityIdsBufSize / sizeof (TDIEntityID); ifCount = 0; /* find out the interface info for the generic interfaces */ for (i = 0; i < entityCount; i++) { if (entityIds[i].tei_entity == IF_ENTITY) { ++ifCount; /* see if the interface supports snmp mib-2 info */ memset (&tcpRequestQueryInfoEx, 0, sizeof (tcpRequestQueryInfoEx)); tcpRequestQueryInfoEx.ID.toi_entity = entityIds[i]; tcpRequestQueryInfoEx.ID.toi_class = INFO_CLASS_GENERIC; tcpRequestQueryInfoEx.ID.toi_type = INFO_TYPE_PROVIDER; tcpRequestQueryInfoEx.ID.toi_id = ENTITY_TYPE_ID; entityTypeSize = sizeof (entityType); result = WsControl (IPPROTO_TCP, WSCTL_TCP_QUERY_INFORMATION, &tcpRequestQueryInfoEx, &tcpRequestBufSize, &entityType, &entityTypeSize); if (result) { printf ("WsControl: %s\n", NET_ERROR); WSACleanup (); FreeLibrary (WSockHandle); free (entityIds); return; } if (entityType == IF_MIB) { /* Supports MIB-2 interface. Get snmp mib-2 info. */ tcpRequestQueryInfoEx.ID.toi_class = INFO_CLASS_PROTOCOL; tcpRequestQueryInfoEx.ID.toi_id = IF_MIB_STATS_ID; /* * note: win95 winipcfg use 130 for MAX_IFDESCR_LEN while * ddk\src\network\wshsmple\SMPLETCP.H defines it as 256 * we are trying to dup the winipcfg parameters for now */ ifEntrySize = sizeof (IFEntry) + 128 + 1; ifEntry = (IFEntry *) calloc (ifEntrySize, 1); result = WsControl (IPPROTO_TCP, WSCTL_TCP_QUERY_INFORMATION, &tcpRequestQueryInfoEx, &tcpRequestBufSize, ifEntry, &ifEntrySize); if (result) { printf ("WsControl: %s\n", NET_ERROR); WSACleanup (); FreeLibrary (WSockHandle); return; } /* store interface index and description */ *(ifEntry->if_descr + ifEntry->if_descrlen) = '\0'; svz_interface_add (ifEntry->if_index, (char *) ifEntry->if_descr, ifEntry->if_index); } } } /* find the ip interfaces */ for (i = 0; i < entityCount; i++) { if (entityIds[i].tei_entity == CL_NL_ENTITY) { /* get ip interface info */ memset (&tcpRequestQueryInfoEx, 0, sizeof (tcpRequestQueryInfoEx)); tcpRequestQueryInfoEx.ID.toi_entity = entityIds[i]; tcpRequestQueryInfoEx.ID.toi_class = INFO_CLASS_GENERIC; tcpRequestQueryInfoEx.ID.toi_type = INFO_TYPE_PROVIDER; tcpRequestQueryInfoEx.ID.toi_id = ENTITY_TYPE_ID; entityTypeSize = sizeof (entityType); result = WsControl (IPPROTO_TCP, WSCTL_TCP_QUERY_INFORMATION, &tcpRequestQueryInfoEx, &tcpRequestBufSize, &entityType, &entityTypeSize); if (result) { printf ("WsControl: %s\n", NET_ERROR); WSACleanup (); FreeLibrary (WSockHandle); return; } if (entityType == CL_NL_IP) { /* Entity implements IP. Get ip address list. */ tcpRequestQueryInfoEx.ID.toi_class = INFO_CLASS_PROTOCOL; tcpRequestQueryInfoEx.ID.toi_id = IP_MIB_ADDRTABLE_ENTRY_ID; ipAddrEntryBufSize = sizeof (IPAddrEntry) * ifCount; ipAddrEntry = (IPAddrEntry *) calloc (ipAddrEntryBufSize, 1); result = WsControl (IPPROTO_TCP, WSCTL_TCP_QUERY_INFORMATION, &tcpRequestQueryInfoEx, &tcpRequestBufSize, ipAddrEntry, &ipAddrEntryBufSize); if (result) { printf ("WsControl: %s\n", NET_ERROR); WSACleanup (); FreeLibrary (WSockHandle); return; } /* find ip address list and interface description */ for (n = 0; n < ifCount; n++) { memcpy (&addr, &ipAddrEntry[n].iae_addr, sizeof (addr)); for (k = 0; k < svz_vector_length (svz_interfaces); k++) { ifc = svz_vector_get (svz_interfaces, k); if (ifc->index == ipAddrEntry[n].iae_index) ifc->ipaddr = addr; } } } } } WSACleanup (); FreeLibrary (WSockHandle); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -