📄 ifnet.c
字号:
/* * The olsr.org Optimized Link-State Routing daemon (olsrd) * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of olsr.org, olsrd nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: ifnet.c,v 1.38 2007/05/13 22:23:55 bernd67 Exp $ */#include "interfaces.h"#include "olsr.h"#include "parser.h"#include "socket_parser.h"#include "defs.h"#include "net_os.h"#include "ifnet.h"#include "generate_msg.h"#include "scheduler.h"#include "mantissa.h"#include "lq_packet.h"#include <iphlpapi.h>#include <iprtrmib.h>struct MibIpInterfaceRow{ USHORT Family; ULONG64 InterfaceLuid; ULONG InterfaceIndex; ULONG MaxReassemblySize; ULONG64 InterfaceIdentifier; ULONG MinRouterAdvertisementInterval; ULONG MaxRouterAdvertisementInterval; BOOLEAN AdvertisingEnabled; BOOLEAN ForwardingEnabled; BOOLEAN WeakHostSend; BOOLEAN WeakHostReceive; BOOLEAN UseAutomaticMetric; BOOLEAN UseNeighborUnreachabilityDetection; BOOLEAN ManagedAddressConfigurationSupported; BOOLEAN OtherStatefulConfigurationSupported; BOOLEAN AdvertiseDefaultRoute; INT RouterDiscoveryBehavior; ULONG DadTransmits; ULONG BaseReachableTime; ULONG RetransmitTime; ULONG PathMtuDiscoveryTimeout; INT LinkLocalAddressBehavior; ULONG LinkLocalAddressTimeout; ULONG ZoneIndices[16]; ULONG SitePrefixLength; ULONG Metric; ULONG NlMtu; BOOLEAN Connected; BOOLEAN SupportsWakeUpPatterns; BOOLEAN SupportsNeighborDiscovery; BOOLEAN SupportsRouterDiscovery; ULONG ReachableTime; BYTE TransmitOffload; BYTE ReceiveOffload; BOOLEAN DisableDefaultRoutes;};typedef DWORD (__stdcall *GETIPINTERFACEENTRY) (struct MibIpInterfaceRow *Row);typedef DWORD (__stdcall *GETADAPTERSADDRESSES) (ULONG Family, DWORD Flags, PVOID Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen);struct InterfaceInfo{ unsigned int Index; int Mtu; int Metric; unsigned int Addr; unsigned int Mask; unsigned int Broad; char Guid[39];};void WinSockPError(char *);char *StrError(unsigned int ErrNo);void ListInterfaces(void);int GetIntInfo(struct InterfaceInfo *Info, char *Name);void RemoveInterface(struct olsr_if *IntConf);#define MAX_INTERFACES 100int __stdcall SignalHandler(unsigned long Signal);static unsigned long __stdcall SignalHandlerWrapper(void *Dummy __attribute__((unused))){ SignalHandler(0); return 0;}static void CallSignalHandler(void){ unsigned long ThreadId; CreateThread(NULL, 0, SignalHandlerWrapper, NULL, 0, &ThreadId);}static void MiniIndexToIntName(char *String, int MiniIndex){ char *HexDigits = "0123456789abcdef"; String[0] = 'i'; String[1] = 'f'; String[2] = HexDigits[(MiniIndex >> 4) & 15]; String[3] = HexDigits[MiniIndex & 15]; String[4] = 0;}static int IntNameToMiniIndex(int *MiniIndex, char *String){ char *HexDigits = "0123456789abcdef"; int i, k; char ch; if ((String[0] != 'i' && String[0] != 'I') || (String[1] != 'f' && String[1] != 'F')) return -1; *MiniIndex = 0; for (i = 2; i < 4; i++) { ch = String[i]; if (ch >= 'A' && ch <= 'F') ch += 32; for (k = 0; k < 16 && ch != HexDigits[k]; k++); if (k == 16) return -1; *MiniIndex = (*MiniIndex << 4) | k; } return 0;}static int FriendlyNameToMiniIndex(int *MiniIndex, char *String){ unsigned long BuffLen; unsigned long Res; IP_ADAPTER_ADDRESSES AdAddr[MAX_INTERFACES], *WalkerAddr; char FriendlyName[MAX_INTERFACE_NAME_LEN]; HMODULE h; GETADAPTERSADDRESSES pfGetAdaptersAddresses; h = LoadLibrary("iphlpapi.dll"); if (h == NULL) { fprintf(stderr, "LoadLibrary() = %08lx", GetLastError()); return -1; } pfGetAdaptersAddresses = (GETADAPTERSADDRESSES) GetProcAddress(h, "GetAdaptersAddresses"); if (pfGetAdaptersAddresses == NULL) { fprintf(stderr, "Unable to use adapter friendly name (GetProcAddress() = %08lx)\n", GetLastError()); return -1; } BuffLen = sizeof (AdAddr); Res = pfGetAdaptersAddresses(AF_INET, 0, NULL, AdAddr, &BuffLen); if (Res != NO_ERROR) { fprintf(stderr, "GetAdaptersAddresses() = %08lx", GetLastError()); return -1; } for (WalkerAddr = AdAddr; WalkerAddr != NULL; WalkerAddr = WalkerAddr->Next) { OLSR_PRINTF(5, "Index = %08x - ", (int)WalkerAddr->IfIndex); wcstombs(FriendlyName, WalkerAddr->FriendlyName, MAX_INTERFACE_NAME_LEN); OLSR_PRINTF(5, "Friendly name = %s\n", FriendlyName); if (strncmp(FriendlyName, String, MAX_INTERFACE_NAME_LEN) == 0) break; } if (WalkerAddr == NULL) { fprintf(stderr, "No such interface: %s!\n", String); return -1; } *MiniIndex = WalkerAddr->IfIndex & 255;}int GetIntInfo(struct InterfaceInfo *Info, char *Name){ int MiniIndex; unsigned char Buff[MAX_INTERFACES * sizeof (MIB_IFROW) + 4]; MIB_IFTABLE *IfTable; unsigned long BuffLen; unsigned long Res; int TabIdx; IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker; HMODULE Lib; struct MibIpInterfaceRow Row; GETIPINTERFACEENTRY InterfaceEntry; if (olsr_cnf->ip_version == AF_INET6) { fprintf(stderr, "IPv6 not supported by GetIntInfo()!\n"); return -1; } if ((Name[0] != 'i' && Name[0] != 'I') || (Name[1] != 'f' && Name[1] != 'F')) { if (FriendlyNameToMiniIndex(&MiniIndex, Name) < 0) { fprintf(stderr, "No such interface: %s!\n", Name); return -1; } } else { if (IntNameToMiniIndex(&MiniIndex, Name) < 0) { fprintf(stderr, "No such interface: %s!\n", Name); return -1; } } IfTable = (MIB_IFTABLE *)Buff; BuffLen = sizeof (Buff); Res = GetIfTable(IfTable, &BuffLen, FALSE); if (Res != NO_ERROR) { fprintf(stderr, "GetIfTable() = %08lx, %s", Res, StrError(Res)); return -1; } for (TabIdx = 0; TabIdx < (int)IfTable->dwNumEntries; TabIdx++) { OLSR_PRINTF(5, "Index = %08x\n", (int)IfTable->table[TabIdx].dwIndex); if ((int)(IfTable->table[TabIdx].dwIndex & 255) == MiniIndex) break; } if (TabIdx == (int)IfTable->dwNumEntries) { fprintf(stderr, "No such interface: %s!\n", Name); return -1; } Info->Index = IfTable->table[TabIdx].dwIndex; Info->Mtu = (int)IfTable->table[TabIdx].dwMtu; Info->Mtu -= (olsr_cnf->ip_version == AF_INET6) ? UDP_IPV6_HDRSIZE : UDP_IPV4_HDRSIZE; Lib = LoadLibrary("iphlpapi.dll"); if (Lib == NULL) { fprintf(stderr, "Cannot load iphlpapi.dll: %08lx\n", GetLastError()); return -1; } InterfaceEntry = (GETIPINTERFACEENTRY)GetProcAddress(Lib, "GetIpInterfaceEntry"); if (InterfaceEntry == NULL) { OLSR_PRINTF(5, "Not running on Vista - setting interface metric to 0.\n"); Info->Metric = 0; } else { memset(&Row, 0, sizeof (struct MibIpInterfaceRow)); Row.Family = AF_INET; Row.InterfaceIndex = Info->Index; Res = InterfaceEntry(&Row); if (Res != NO_ERROR) { fprintf(stderr, "GetIpInterfaceEntry() = %08lx", Res); FreeLibrary(Lib); return -1; } Info->Metric = Row.Metric; OLSR_PRINTF(5, "Running on Vista - interface metric is %d.\n", Info->Metric); } FreeLibrary(Lib); BuffLen = sizeof (AdInfo); Res = GetAdaptersInfo(AdInfo, &BuffLen); if (Res != NO_ERROR) { fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", GetLastError(), StrError(Res)); return -1; } for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next) { OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index); if ((int)(Walker->Index & 255) == MiniIndex) break; } if (Walker == NULL) { fprintf(stderr, "No such interface: %s!\n", Name); return -1; } inet_pton(AF_INET, Walker->IpAddressList.IpAddress.String, &Info->Addr); inet_pton(AF_INET, Walker->IpAddressList.IpMask.String, &Info->Mask); Info->Broad = Info->Addr | ~Info->Mask; strcpy(Info->Guid, Walker->AdapterName); if ((IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_CONNECTED && IfTable->table[TabIdx].dwOperStatus != MIB_IF_OPER_STATUS_OPERATIONAL) || Info->Addr == 0) { OLSR_PRINTF(3, "Interface %s not up!\n", Name); return -1; } return 0;}#if !defined OID_802_11_CONFIGURATION#define OID_802_11_CONFIGURATION 0x0d010211#endif#if !defined IOCTL_NDIS_QUERY_GLOBAL_STATS#define IOCTL_NDIS_QUERY_GLOBAL_STATS 0x00170002#endifstatic int IsWireless(char *IntName){#if !defined WINCE struct InterfaceInfo Info; char DevName[43]; HANDLE DevHand; unsigned int ErrNo; unsigned int Oid; unsigned char OutBuff[100]; unsigned long OutBytes; if (GetIntInfo(&Info, IntName) < 0) return -1; DevName[0] = '\\'; DevName[1] = '\\'; DevName[2] = '.'; DevName[3] = '\\'; strcpy(DevName + 4, Info.Guid); OLSR_PRINTF(5, "Checking whether interface %s is wireless.\n", DevName); DevHand = CreateFile(DevName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (DevHand == INVALID_HANDLE_VALUE) { ErrNo = GetLastError(); OLSR_PRINTF(5, "CreateFile() = %08x, %s\n", ErrNo, StrError(ErrNo)); return -1; } Oid = OID_802_11_CONFIGURATION; if (!DeviceIoControl(DevHand, IOCTL_NDIS_QUERY_GLOBAL_STATS, &Oid, sizeof (Oid), OutBuff, sizeof (OutBuff), &OutBytes, NULL)) { ErrNo = GetLastError(); CloseHandle(DevHand); if (ErrNo == ERROR_GEN_FAILURE || ErrNo == ERROR_INVALID_PARAMETER) { OLSR_PRINTF(5, "OID not supported. Device probably not wireless.\n"); return 0; } OLSR_PRINTF(5, "DeviceIoControl() = %08x, %s\n", ErrNo, StrError(ErrNo)); return -1; } CloseHandle(DevHand);#endif return 1;}void ListInterfaces(void){ IP_ADAPTER_INFO AdInfo[MAX_INTERFACES], *Walker; unsigned long AdInfoLen; char IntName[5]; IP_ADDR_STRING *Walker2; unsigned long Res; int IsWlan; if (olsr_cnf->ip_version == AF_INET6) { fprintf(stderr, "IPv6 not supported by ListInterfaces()!\n"); return; } AdInfoLen = sizeof (AdInfo); Res = GetAdaptersInfo(AdInfo, &AdInfoLen); if (Res == ERROR_NO_DATA) { printf("No interfaces detected.\n"); return; } if (Res != NO_ERROR) { fprintf(stderr, "GetAdaptersInfo() = %08lx, %s", Res, StrError(Res)); return; } for (Walker = AdInfo; Walker != NULL; Walker = Walker->Next) { OLSR_PRINTF(5, "Index = %08x\n", (int)Walker->Index); MiniIndexToIntName(IntName, Walker->Index); printf("%s: ", IntName); IsWlan = IsWireless(IntName); if (IsWlan < 0) printf("?"); else if (IsWlan == 0) printf("-"); else printf("+"); for (Walker2 = &Walker->IpAddressList; Walker2 != NULL; Walker2 = Walker2->Next) printf(" %s", Walker2->IpAddress.String); printf("\n"); }}void RemoveInterface(struct olsr_if *IntConf){ struct interface *Int, *Prev; OLSR_PRINTF(1, "Removing interface %s.\n", IntConf->name); Int = IntConf->interf; run_ifchg_cbs(Int, IFCHG_IF_ADD); if (Int == ifnet) ifnet = Int->int_next; else { for (Prev = ifnet; Prev->int_next != Int; Prev = Prev->int_next); Prev->int_next = Int->int_next; } if(COMP_IP(&olsr_cnf->main_addr, &Int->ip_addr)) { if(ifnet == NULL) { memset(&olsr_cnf->main_addr, 0, olsr_cnf->ipsize); OLSR_PRINTF(1, "Removed last interface. Cleared main address.\n"); } else { COPY_IP(&olsr_cnf->main_addr, &ifnet->ip_addr); OLSR_PRINTF(1, "New main address: %s.\n", olsr_ip_to_string(&olsr_cnf->main_addr)); } } if (olsr_cnf->lq_level == 0) { olsr_remove_scheduler_event(&generate_hello, Int, IntConf->cnf->hello_params.emission_interval, 0, NULL); olsr_remove_scheduler_event(&generate_tc, Int, IntConf->cnf->tc_params.emission_interval,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -