decryption works, but addid doesn't because of unique pointer layers
[wireshark-sm.git] / capture / capture_win_ifnames.c
blob25de291b7cff91db52b6ebf79d7b89dd229bacd4
1 /* capture_win_ifnames.c
2 * Routines supporting the use of Windows friendly interface names within Wireshark
3 * Copyright 2011-2012, Mike Garratt <wireshark@evn.co.nz>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #ifdef _WIN32
16 #include <wireshark.h>
18 #include <winsock2.h>
19 #include <windows.h>
20 #include <iphlpapi.h>
21 #include <stdio.h>
22 #include <stdlib.h>
24 #include <ntddndis.h>
26 #ifndef NDIS_IF_MAX_STRING_SIZE
27 #define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE /* =256 in <ifdef.h> */
28 #endif
30 #ifndef NETIO_STATUS
31 #define NETIO_STATUS DWORD
32 #endif
34 #include "capture/capture_ifinfo.h"
35 #include "capture/capture_win_ifnames.h"
37 #include <wsutil/file_util.h>
39 static int gethexdigit(const char *p)
41 if(*p >= '0' && *p <= '9'){
42 return *p - '0';
43 }else if(*p >= 'A' && *p <= 'F'){
44 return *p - 'A' + 0xA;
45 }else if(*p >= 'a' && *p <= 'f'){
46 return *p - 'a' + 0xa;
47 }else{
48 return -1; /* Not a hex digit */
52 static bool get8hexdigits(const char *p, DWORD *d)
54 int digit;
55 DWORD val;
56 int i;
58 val = 0;
59 for(i = 0; i < 8; i++){
60 digit = gethexdigit(p++);
61 if(digit == -1){
62 return false; /* Not a hex digit */
64 val = (val << 4) | digit;
66 *d = val;
67 return true;
70 static bool get4hexdigits(const char *p, WORD *w)
72 int digit;
73 WORD val;
74 int i;
76 val = 0;
77 for(i = 0; i < 4; i++){
78 digit = gethexdigit(p++);
79 if(digit == -1){
80 return false; /* Not a hex digit */
82 val = (val << 4) | digit;
84 *w = val;
85 return true;
89 * If a string is a GUID in {}, fill in a GUID structure with the GUID
90 * value and return true; otherwise, if the string is not a valid GUID
91 * in {}, return false.
93 bool
94 parse_as_guid(const char *guid_text, GUID *guid)
96 int i;
97 int digit1, digit2;
99 if(*guid_text != '{'){
100 return false; /* Nope, not enclosed in {} */
102 guid_text++;
103 /* There must be 8 hex digits; if so, they go into guid->Data1 */
104 if(!get8hexdigits(guid_text, &guid->Data1)){
105 return false; /* nope, not 8 hex digits */
107 guid_text += 8;
108 /* Now there must be a hyphen */
109 if(*guid_text != '-'){
110 return false; /* Nope */
112 guid_text++;
113 /* There must be 4 hex digits; if so, they go into guid->Data2 */
114 if(!get4hexdigits(guid_text, &guid->Data2)){
115 return false; /* nope, not 4 hex digits */
117 guid_text += 4;
118 /* Now there must be a hyphen */
119 if(*guid_text != '-'){
120 return false; /* Nope */
122 guid_text++;
123 /* There must be 4 hex digits; if so, they go into guid->Data3 */
124 if(!get4hexdigits(guid_text, &guid->Data3)){
125 return false; /* nope, not 4 hex digits */
127 guid_text += 4;
128 /* Now there must be a hyphen */
129 if(*guid_text != '-'){
130 return false; /* Nope */
132 guid_text++;
134 * There must be 4 hex digits; if so, they go into the first 2 bytes
135 * of guid->Data4.
137 for(i = 0; i < 2; i++){
138 digit1 = gethexdigit(guid_text);
139 if(digit1 == -1){
140 return false; /* Not a hex digit */
142 guid_text++;
143 digit2 = gethexdigit(guid_text);
144 if(digit2 == -1){
145 return false; /* Not a hex digit */
147 guid_text++;
148 guid->Data4[i] = (digit1 << 4)|(digit2);
150 /* Now there must be a hyphen */
151 if(*guid_text != '-'){
152 return false; /* Nope */
154 guid_text++;
156 * There must be 12 hex digits; if so,t hey go into the next 6 bytes
157 * of guid->Data4.
159 for(i = 0; i < 6; i++){
160 digit1 = gethexdigit(guid_text);
161 if(digit1 == -1){
162 return false; /* Not a hex digit */
164 guid_text++;
165 digit2 = gethexdigit(guid_text);
166 if(digit2 == -1){
167 return false; /* Not a hex digit */
169 guid_text++;
170 guid->Data4[i+2] = (digit1 << 4)|(digit2);
172 /* Now there must be a closing } */
173 if(*guid_text != '}'){
174 return false; /* Nope */
176 guid_text++;
177 /* And that must be the end of the string */
178 if(*guid_text != '\0'){
179 return false; /* Nope */
181 return true;
184 /**********************************************************************************/
185 /* Get the friendly name for the given GUID */
186 char *
187 get_interface_friendly_name_from_device_guid(__in GUID *guid)
189 HRESULT hr;
191 /* Need to convert an Interface GUID to the interface friendly name (e.g. "Local Area Connection")
192 * The functions required to do this all reside within iphlpapi.dll
195 NET_LUID InterfaceLuid;
196 hr = ConvertInterfaceGuidToLuid(guid, &InterfaceLuid);
197 if(hr == NO_ERROR) {
198 /* guid->luid success */
199 WCHAR wName[NDIS_IF_MAX_STRING_SIZE + 1];
200 hr = ConvertInterfaceLuidToAlias(&InterfaceLuid, wName, NDIS_IF_MAX_STRING_SIZE+1);
201 if(hr == NO_ERROR) {
202 /* luid->friendly name success */
204 /* Get the required buffer size, and then convert the string
205 * from UTF-16 to UTF-8. */
206 int size;
207 char *name;
208 size = WideCharToMultiByte(CP_UTF8, 0, wName, -1, NULL, 0, NULL, NULL);
209 if(size != 0) {
210 name = (char *) g_malloc(size);
211 if (name != NULL) {
212 size = WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, size, NULL, NULL);
213 if(size != 0) {
214 return name;
216 /* Failed, clean up the allocation */
217 g_free(name);
223 /* Failed to get a name */
224 return NULL;
228 * Given an interface name, try to extract the GUID from it and parse it.
229 * If that fails, return NULL; if that succeeds, attempt to get the
230 * friendly name for the interface in question. If that fails, return
231 * NULL, otherwise return the friendly name, allocated with g_malloc()
232 * (so that it must be freed with g_free()).
234 char *
235 get_windows_interface_friendly_name(const char *interface_devicename)
237 const char* guid_text;
238 GUID guid;
240 /* Extract the guid text from the interface device name */
241 if(strncmp("\\Device\\NPF_", interface_devicename, 12)==0){
242 guid_text=interface_devicename+12; /* skip over the '\Device\NPF_' prefix, assume the rest is the guid text */
243 }else{
244 guid_text=interface_devicename;
247 if (!parse_as_guid(guid_text, &guid)){
248 return NULL; /* not a GUID, so no friendly name */
251 /* guid okay, get the interface friendly name associated with the guid */
252 return get_interface_friendly_name_from_device_guid(&guid);
255 /**************************************************************************************/
256 #endif
259 * Editor modelines - https://www.wireshark.org/tools/modelines.html
261 * Local variables:
262 * c-basic-offset: 4
263 * tab-width: 8
264 * indent-tabs-mode: nil
265 * End:
267 * vi: set shiftwidth=4 tabstop=8 expandtab:
268 * :indentSize=4:tabSize=8:noTabs=true: