From ad48e6fb1f8749a059696612ad503aea28c4707d Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Fri, 15 Jan 2010 15:39:12 -0500 Subject: [PATCH] Windows: Query the MTU value from the registry The syscfg_GetIFInfo() call uses the interface info returned by GetAdaptersAddresses(). Also manually query the MTU value in the registry for any interfaces bound to the same adapter and use the smallest such MTU as the value returned by syscfg_GetIFInfo(). Change-Id: I8a1d487b51f6674ff6ebbf6b1f20d37b1e278279 Reviewed-on: http://gerrit.openafs.org/1105 Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman --- src/WINNT/afsreg/syscfg.c | 113 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 6 deletions(-) diff --git a/src/WINNT/afsreg/syscfg.c b/src/WINNT/afsreg/syscfg.c index a980ca8..820e2f4 100644 --- a/src/WINNT/afsreg/syscfg.c +++ b/src/WINNT/afsreg/syscfg.c @@ -20,9 +20,99 @@ #include "afsreg.h" #include "syscfg.h" +#ifdef DEBUG +#include +#endif + static int IsLoopback(char * guid); int syscfg_GetIFInfo_2000(int *count, int *addrs, int *masks, int *mtus, int *flags); +DWORD GetMTUForAddress(PIP_ADAPTER_ADDRESSES cAddress) +{ + DWORD min_mtu = 0xFFFFFFFF; /* Default */ + + HKEY hk_services = NULL; + + HKEY hk_adapters = NULL; + + HKEY hk_adapter = NULL; + + char * ipconfig = NULL; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services", 0, + KEY_READ, &hk_services) != ERROR_SUCCESS) + goto done; + + if (RegOpenKeyEx(hk_services, "Tcpip\\Parameters\\Adapters", 0, KEY_READ, + &hk_adapters) + != ERROR_SUCCESS) + goto done; + + if (RegOpenKeyEx(hk_adapters, cAddress->AdapterName, 0, KEY_READ, &hk_adapter) + != ERROR_SUCCESS) + goto done; + + { + DWORD cb_alloc = 0; + DWORD cb_ipc = 0; + DWORD type = 0; + char * this_ipc; + + if (RegQueryValueEx(hk_adapter, "IpConfig", 0, NULL, NULL, &cb_ipc) + != ERROR_SUCCESS) + goto done; + + cb_alloc = cb_ipc + sizeof(char) * 2; + ipconfig = malloc(cb_alloc); + if (ipconfig == NULL) + goto done; + + if (RegQueryValueEx(hk_adapter, "IpConfig", 0, &type, ipconfig, + &cb_ipc) != ERROR_SUCCESS) { + goto done; + } + + if (cb_ipc < cb_alloc) + memset(ipconfig + cb_ipc / sizeof(char), 0, + (cb_alloc - cb_ipc) / sizeof(char)); + + for (this_ipc = ipconfig; (this_ipc - ipconfig) < cb_alloc / sizeof(char) && + *this_ipc; this_ipc = this_ipc + (strlen(this_ipc) + 1)) { + + HKEY hk_interface = NULL; + DWORD mtu = 0; + DWORD cb_mtu; + + if (RegOpenKeyEx(hk_services, this_ipc, 0, KEY_READ, + &hk_interface) != ERROR_SUCCESS) + continue; + + cb_mtu = sizeof(mtu); + if (RegQueryValueEx(hk_interface, "MTU", NULL, NULL, &mtu, + &cb_mtu) == ERROR_SUCCESS) { + min_mtu = min(min_mtu, mtu); + } + + RegCloseKey(hk_interface); + } + } + + done: + if (ipconfig) + free(ipconfig); + + if (hk_services != NULL) + RegCloseKey(hk_services); + + if (hk_adapters != NULL) + RegCloseKey(hk_adapters); + + if (hk_adapter != NULL) + RegCloseKey(hk_adapter); + + return min_mtu; +} + /* syscfg_GetIFInfo * * Retrieve IP addresses, subnet masks, MTU sizes, and flags for all @@ -83,11 +173,11 @@ int syscfg_GetIFInfo(int *count, int *addrs, int *masks, int *mtus, int *flags) nConfig = -1; goto done; } - + /* second pass to get the actual data */ free(pIpTbl); pIpTbl = (PMIB_IPADDRTABLE) malloc(outBufLen); - + dwRetVal = GetIpAddrTable(pIpTbl, &outBufLen, FALSE); if (dwRetVal != NO_ERROR) { free(pIpTbl); @@ -95,9 +185,9 @@ int syscfg_GetIFInfo(int *count, int *addrs, int *masks, int *mtus, int *flags) nConfig = -1; goto done; } - + pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(sizeof(IP_ADAPTER_ADDRESSES)); - + /* first call gets required buffer size */ if (pGetAdaptersAddresses(AF_INET, 0, @@ -137,17 +227,28 @@ int syscfg_GetIFInfo(int *count, int *addrs, int *masks, int *mtus, int *flags) instance GUID, check if this is a MS loopback device */ if (IsLoopback(cAddress->AdapterName)) continue; - + /* ok. looks good. Now fish out all the addresses from the address table corresponding to the interface, and add them to the list */ for (i=0;idwNumEntries;i++) { if (pIpTbl->table[i].dwIndex == cAddress->IfIndex) { + DWORD if_mtu; + + if_mtu = GetMTUForAddress(cAddress); +#ifdef DEBUG + if (if_mtu < cAddress->Mtu) { + char s[1024]; + StringCbPrintf(s, sizeof(s), "MTU from registry is less than MTU from adapter address (%d vs %d)\n", if_mtu, cAddress->Mtu); + OutputDebugString(s); + } +#endif + if (n < maxCount) { addrs[n] = ntohl(pIpTbl->table[i].dwAddr); masks[n] = ntohl(pIpTbl->table[i].dwMask); - mtus[n] = cAddress->Mtu; + mtus[n] = min(cAddress->Mtu, if_mtu); flags[n] = 0; n++; } -- 1.9.4