summaryrefslogtreecommitdiffstats
path: root/capture/capture_win_ifnames.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /capture/capture_win_ifnames.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'capture/capture_win_ifnames.c')
-rw-r--r--capture/capture_win_ifnames.c269
1 files changed, 269 insertions, 0 deletions
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@evn.co.nz>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#ifdef _WIN32
+
+#include <wireshark.h>
+
+#include <winsock2.h>
+#include <windows.h>
+#include <iphlpapi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <ntddndis.h>
+
+#ifndef NDIS_IF_MAX_STRING_SIZE
+#define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE /* =256 in <ifdef.h> */
+#endif
+
+#ifndef NETIO_STATUS
+#define NETIO_STATUS DWORD
+#endif
+
+#include "capture/capture_ifinfo.h"
+#include "capture/capture_win_ifnames.h"
+
+#include <wsutil/file_util.h>
+
+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:
+ */