From e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:34:10 +0200 Subject: Adding upstream version 4.2.2. Signed-off-by: Daniel Baumann --- capture/capture_win_ifnames.c | 269 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 capture/capture_win_ifnames.c (limited to 'capture/capture_win_ifnames.c') diff --git a/capture/capture_win_ifnames.c b/capture/capture_win_ifnames.c new file mode 100644 index 0000000..25de291 --- /dev/null +++ b/capture/capture_win_ifnames.c @@ -0,0 +1,269 @@ +/* capture_win_ifnames.c + * Routines supporting the use of Windows friendly interface names within Wireshark + * Copyright 2011-2012, Mike Garratt + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#ifdef _WIN32 + +#include + +#include +#include +#include +#include +#include + +#include + +#ifndef NDIS_IF_MAX_STRING_SIZE +#define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE /* =256 in */ +#endif + +#ifndef NETIO_STATUS +#define NETIO_STATUS DWORD +#endif + +#include "capture/capture_ifinfo.h" +#include "capture/capture_win_ifnames.h" + +#include + +static int gethexdigit(const char *p) +{ + if(*p >= '0' && *p <= '9'){ + return *p - '0'; + }else if(*p >= 'A' && *p <= 'F'){ + return *p - 'A' + 0xA; + }else if(*p >= 'a' && *p <= 'f'){ + return *p - 'a' + 0xa; + }else{ + return -1; /* Not a hex digit */ + } +} + +static bool get8hexdigits(const char *p, DWORD *d) +{ + int digit; + DWORD val; + int i; + + val = 0; + for(i = 0; i < 8; i++){ + digit = gethexdigit(p++); + if(digit == -1){ + return false; /* Not a hex digit */ + } + val = (val << 4) | digit; + } + *d = val; + return true; +} + +static bool get4hexdigits(const char *p, WORD *w) +{ + int digit; + WORD val; + int i; + + val = 0; + for(i = 0; i < 4; i++){ + digit = gethexdigit(p++); + if(digit == -1){ + return false; /* Not a hex digit */ + } + val = (val << 4) | digit; + } + *w = val; + return true; +} + +/* + * If a string is a GUID in {}, fill in a GUID structure with the GUID + * value and return true; otherwise, if the string is not a valid GUID + * in {}, return false. + */ +bool +parse_as_guid(const char *guid_text, GUID *guid) +{ + int i; + int digit1, digit2; + + if(*guid_text != '{'){ + return false; /* Nope, not enclosed in {} */ + } + guid_text++; + /* There must be 8 hex digits; if so, they go into guid->Data1 */ + if(!get8hexdigits(guid_text, &guid->Data1)){ + return false; /* nope, not 8 hex digits */ + } + guid_text += 8; + /* Now there must be a hyphen */ + if(*guid_text != '-'){ + return false; /* Nope */ + } + guid_text++; + /* There must be 4 hex digits; if so, they go into guid->Data2 */ + if(!get4hexdigits(guid_text, &guid->Data2)){ + return false; /* nope, not 4 hex digits */ + } + guid_text += 4; + /* Now there must be a hyphen */ + if(*guid_text != '-'){ + return false; /* Nope */ + } + guid_text++; + /* There must be 4 hex digits; if so, they go into guid->Data3 */ + if(!get4hexdigits(guid_text, &guid->Data3)){ + return false; /* nope, not 4 hex digits */ + } + guid_text += 4; + /* Now there must be a hyphen */ + if(*guid_text != '-'){ + return false; /* Nope */ + } + guid_text++; + /* + * There must be 4 hex digits; if so, they go into the first 2 bytes + * of guid->Data4. + */ + for(i = 0; i < 2; i++){ + digit1 = gethexdigit(guid_text); + if(digit1 == -1){ + return false; /* Not a hex digit */ + } + guid_text++; + digit2 = gethexdigit(guid_text); + if(digit2 == -1){ + return false; /* Not a hex digit */ + } + guid_text++; + guid->Data4[i] = (digit1 << 4)|(digit2); + } + /* Now there must be a hyphen */ + if(*guid_text != '-'){ + return false; /* Nope */ + } + guid_text++; + /* + * There must be 12 hex digits; if so,t hey go into the next 6 bytes + * of guid->Data4. + */ + for(i = 0; i < 6; i++){ + digit1 = gethexdigit(guid_text); + if(digit1 == -1){ + return false; /* Not a hex digit */ + } + guid_text++; + digit2 = gethexdigit(guid_text); + if(digit2 == -1){ + return false; /* Not a hex digit */ + } + guid_text++; + guid->Data4[i+2] = (digit1 << 4)|(digit2); + } + /* Now there must be a closing } */ + if(*guid_text != '}'){ + return false; /* Nope */ + } + guid_text++; + /* And that must be the end of the string */ + if(*guid_text != '\0'){ + return false; /* Nope */ + } + return true; +} + +/**********************************************************************************/ +/* Get the friendly name for the given GUID */ +char * +get_interface_friendly_name_from_device_guid(__in GUID *guid) +{ + HRESULT hr; + + /* Need to convert an Interface GUID to the interface friendly name (e.g. "Local Area Connection") + * The functions required to do this all reside within iphlpapi.dll + */ + + NET_LUID InterfaceLuid; + hr = ConvertInterfaceGuidToLuid(guid, &InterfaceLuid); + if(hr == NO_ERROR) { + /* guid->luid success */ + WCHAR wName[NDIS_IF_MAX_STRING_SIZE + 1]; + hr = ConvertInterfaceLuidToAlias(&InterfaceLuid, wName, NDIS_IF_MAX_STRING_SIZE+1); + if(hr == NO_ERROR) { + /* luid->friendly name success */ + + /* Get the required buffer size, and then convert the string + * from UTF-16 to UTF-8. */ + int size; + char *name; + size = WideCharToMultiByte(CP_UTF8, 0, wName, -1, NULL, 0, NULL, NULL); + if(size != 0) { + name = (char *) g_malloc(size); + if (name != NULL) { + size = WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, size, NULL, NULL); + if(size != 0) { + return name; + } + /* Failed, clean up the allocation */ + g_free(name); + } + } + } + } + + /* Failed to get a name */ + return NULL; +} + +/* + * Given an interface name, try to extract the GUID from it and parse it. + * If that fails, return NULL; if that succeeds, attempt to get the + * friendly name for the interface in question. If that fails, return + * NULL, otherwise return the friendly name, allocated with g_malloc() + * (so that it must be freed with g_free()). + */ +char * +get_windows_interface_friendly_name(const char *interface_devicename) +{ + const char* guid_text; + GUID guid; + + /* Extract the guid text from the interface device name */ + if(strncmp("\\Device\\NPF_", interface_devicename, 12)==0){ + guid_text=interface_devicename+12; /* skip over the '\Device\NPF_' prefix, assume the rest is the guid text */ + }else{ + guid_text=interface_devicename; + } + + if (!parse_as_guid(guid_text, &guid)){ + return NULL; /* not a GUID, so no friendly name */ + } + + /* guid okay, get the interface friendly name associated with the guid */ + return get_interface_friendly_name_from_device_guid(&guid); +} + +/**************************************************************************************/ +#endif + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ -- cgit v1.2.3