C : List all network devices with their properties / attributes like GUID, adapter name, MAC address, Description

Problem

In some cases mighty libs like NPCap or WinPCap are used to get a list of all network devices with common properties like GUID and so on.

Approach

#pragma comment(lib, "iphlpapi.lib")
This links the IP Helper API library, which provides functions for retrieving network configuration and statistics, such as:

  • Network adapter information
  • IP address tables
  • Routing tables

#pragma comment(lib, "ws2_32.lib")
This links the Winsock 2 library, which is essential for network programming on Windows. It provides:

  • Socket APIs for TCP/UDP communication
  • DNS resolution
  • Network initialization and cleanup functions

Solution

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

int main() {
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    IP_ADAPTER_ADDRESSES *pAddresses = NULL;
    IP_ADAPTER_ADDRESSES *pCurrAddresses = NULL;

    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
    ULONG family = AF_UNSPEC;

    // Erste Abfrage zur Bestimmung der Puffergröße
    dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &dwSize);
    if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
        pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(dwSize);
        if (pAddresses == NULL) {
            printf("Speicher konnte nicht reserviert werden.\n");
            return 1;
        }
    }

    // Zweiter Aufruf mit gültigem Puffer
    dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &dwSize);
    if (dwRetVal == NO_ERROR) {
        pCurrAddresses = pAddresses;
        while (pCurrAddresses) {
            printf("Adapter GUID: %s\n", pCurrAddresses->AdapterName);
            printf("Adaptername: %ws\n", pCurrAddresses->FriendlyName);
            printf("Beschreibung: %ws\n", pCurrAddresses->Description);
            if (pCurrAddresses->PhysicalAddressLength != 0) {
                printf("MAC-Adresse: ");
                for (DWORD i = 0; i < pCurrAddresses->PhysicalAddressLength; i++) {
                    printf("%02X", pCurrAddresses->PhysicalAddress[i]);
                    if (i < pCurrAddresses->PhysicalAddressLength - 1)
                        printf(":");
                }
                printf("\n");
            }
            
            printf("--------------------------------------------------\n");
            pCurrAddresses = pCurrAddresses->Next;
        }       
    } else {
        printf("GetAdaptersAddresses fehlgeschlagen mit Fehler: %lu\n", dwRetVal);
    }

    if (pAddresses) {
        free(pAddresses);
    }

    return 0;
}

Output

PS C:\Betriebssysteme\Übung 6> .\ListNetworkDevices  
Adapter GUID: {E01CE7A3-099B-4184-8C16-1F5054A8317F}
Adaptername: Ethernet
Beschreibung: Intel(R) Ethernet Connection (7) I219-LM
MAC-Adresse: 34:48:ED:61:86:BA
--------------------------------------------------
Adapter GUID: {4012AE18-3341-4541-892C-BC0286FA6504}
Adaptername: Ethernet 2
Beschreibung: Check Point Virtual Network Adapter For Endpoint VPN Client
MAC-Adresse: 54:DF:6F:F5:98:06
--------------------------------------------------
Adapter GUID: {6EFE57EA-027E-45AA-9BFD-8071CE36C5FD}
Adaptername: Ethernet 7
Beschreibung: VirtualBox Host-Only Ethernet Adapter
MAC-Adresse: 0A:00:27:00:00:0F
--------------------------------------------------
Adapter GUID: {1A8FA3D8-A753-4453-8362-78FA3A6B314C}
Adaptername: Local Area Connection* 1
Beschreibung: Microsoft Wi-Fi Direct Virtual Adapter
MAC-Adresse: B8:9A:2A:2F:51:8F
--------------------------------------------------
Adapter GUID: {4BE430BD-CB19-4CBB-BA70-0D4EE0F6AECE}
Adaptername: Local Area Connection* 2
Beschreibung: Microsoft Wi-Fi Direct Virtual Adapter #2
MAC-Adresse: BA:9A:2A:2F:51:8E
--------------------------------------------------
Adapter GUID: {DFDC464C-3487-4D61-B1AE-28733CA18E2E}
Adaptername: Wi-Fi
Beschreibung: Intel(R) Wi-Fi 6 AX200 160MHz
MAC-Adresse: B8:9A:2A:2F:51:8E
--------------------------------------------------
Adapter GUID: {BAA489E2-AF2D-4A75-A99C-2E4C19B04F44}
Adaptername: Bluetooth Network Connection
Beschreibung: Bluetooth Device (Personal Area Network)
MAC-Adresse: B8:9A:2A:2F:51:92
--------------------------------------------------
Adapter GUID: {88CB09EB-7A9D-11EF-986B-806E6F6E6963}
Adaptername: Loopback Pseudo-Interface 1
Beschreibung: Software Loopback Interface 1
--------------------------------------------------
PS C:\Betriebssysteme\Übung 6>

REST-Client für Visual Studio Code (Extension: „REST Client“)

Intention

Zum Testen / Aufrufen von REST-API’s benötigt man am Besten einen Client, der nicht unbedingt im Webspace der selben Domain gehostet ist, da man Testen möchte ob die Cross-Origin Resource Policy (CORP) / Cross Site Policy korrekt konfiguriert ist.

Problem

Würde man einen Javascript-REST-Client im Web-Root / wwwroot / inetpub der selben Domain hosten, könnte dieser ohne Verletzung der Policy auf die REST-Services der selben Domain zugreifen. Würde man die Endpoints / Endpunkte an einen Konsumenten weitergeben, könnte dieser bei einer Fehlkonfiguration diese trotzdem nicht aufrufen.

Beispiel für einen Javascript-REST-Client, der durch den Response-Body ein JSON-Array iteriert (für Tests nicht empfohlen):

<button id="loadData">Get Rides</button>
<div id="rideData"></div>

<script>
    async function fetchRideData() {
        const response = await fetch("/Ride");
        if (!response.ok) {
            document.getElementById("rideData").innerText = "Fehler beim Laden der Daten.";
            return;
        }
        const data = await response.json();
        let html = "<ul>";
        data.forEach(item => {
            html += `<li>ID: ${item.id}, Datum: ${item.timestamp}, GPS Position: ${item.gpS_Position}, Kennzeichen: ${item.kennzeichen}</li>`;
        });
        html += "</ul>";
        document.getElementById("rideData").innerHTML = html;
    }

    document.getElementById("loadData").addEventListener("click", fetchRideData);
</script>

Lösung

Die Extension „REST Client“ kann als autarker REST-Client, der nicht in der Domäne des Webspaces läuft, sondern lokal vom Rechner aus den Aufruf tätigt, genutzt werden:

Im Screenshot oben wurde die Extension „REST Client“ installiert und eine neue Datei mit dem Namen „restapi.http“ angelegt.

Die Datei hat den folgenden Inhalt (im Body wird ein JSON-Array übermittelt, dieses müsste dem Service entsprechend ersetzt werden):

POST https://www.domain.info/GenericRequest
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-WS-RateLimit-Limit: 1000
X-WS-RateLimit-Remaining: 999
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Wed, 07 May 2025 10:27:38 GMT

[ {
"ts": 1530536430,
"lat":-34.1868759,
"lng":-56.9065776,
"head": 30,
"speed": 50,
"id": "SBV3399",
"temp": "20",
"motor":"on"

},
{
"ts": 1530536430,
"lat":-34.1868759,
"lng":-56.9065776,
"head": 0,
"speed": 50,
"id": "MAV4099",
"temp": "8",
"motor":"off"
}]

Fazit

REST API’s lassen sich am Besten mit einem REST-Client testen / aufrufen, der nicht auf dem Domain-Space läuft, auf dem die Endpunkte gehostet sind um CORP zu testen. Dies verhindert unangenehme Überraschungen zwischen der aufrufenden und aufzurufenden Seite.