Delphi, WinAPI, WMI – wykrywanie dynamicznego lub statycznego IP, flaga DHCPEnabled

Pytanie

delphi programowanie, jak wykryć czy IP jest dynamiczne czy statyczne

Odpowiedź Sztucznej Inteligencji


Bezpośrednia odpowiedź na pytanie

  • Sam numer IP nie niesie informacji, czy został nadany ręcznie, czy przez serwer DHCP.
  • W Delphi należy odpytać system operacyjny o ustawienie interfejsu sieciowego:
    DHCPEnabled = True → adres dynamiczny (DHCP)
    DHCPEnabled = False → adres statyczny (manualny)
  • Najpewniej zrobisz to:
    1. przez WinAPI (IP Helper – GetAdaptersInfo / GetAdaptersAddresses), lub
    2. przez WMI (Win32_NetworkAdapterConfiguration.DHCPEnabled).

Szczegółowa analiza problemu

1. WinAPI – IP Helper (rekomendowane)

Najmniejszy narzut, brak zależności od usług systemowych.

uses
  Windows, SysUtils, IpHlpApi;
function IsAdapterDhcpEnabled(const AdapterDescMask: string = ''): Boolean;
var
  BufLen: ULONG;
  PInfo, PIt: PIP_ADAPTER_INFO;
begin
  Result := False;
  BufLen := 0;
  // Najpierw pobieramy wymagany rozmiar bufora
  if GetAdaptersInfo(nil, BufLen) <> ERROR_BUFFER_OVERFLOW then Exit;
  GetMem(PInfo, BufLen);
  try
    if GetAdaptersInfo(PInfo, BufLen) = NO_ERROR then
    begin
      PIt := PInfo;
      while PIt <> nil do
      begin
        // opcjonalnie filtrujemy po opisie karty
        if (AdapterDescMask = '') or
           (Pos(LowerCase(AdapterDescMask), LowerCase(AnsiString(PIt^.Description))) > 0) then
        begin
          Result := PIt^.DhcpEnabled <> 0;  // True → dynamiczny
          Exit;
        end;
        PIt := PIt^.Next;
      end;
    end;
  finally
    FreeMem(PInfo);
  end;
end;

‐ Zmienna DhcpEnabled jest wspólna dla wszystkich adresów przypisanych do danego interfejsu (IPv4).
‐ Dla Windows Vista+ można użyć nowszego GetAdaptersAddresses, które obsługuje też IPv6.

2. WMI – szybkie i elastyczne (COM)

uses
  ActiveX, ComObj, Variants;
function IsAnyDhcpEnabledViaWmi: Boolean;
var
  Locator, Services, ObjSet, Item: OleVariant;
  Enum: IEnumVariant; Fetched: Cardinal;
begin
  Result := False;
  CoInitialize(nil);
  try
    Locator  := CreateOleObject('WbemScripting.SWbemLocator');
    Services := Locator.ConnectServer('.', 'root\CIMV2');
    ObjSet   := Services.ExecQuery(
      'SELECT DHCPEnabled FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE');
    Enum := IUnknown(ObjSet._NewEnum) as IEnumVariant;
    while Enum.Next(1, Item, Fetched) = S_OK do
    begin
      if Item.DHCPEnabled then
        Exit(True);  // znaleziono interfejs z DHCP
    end;
  finally
    CoUninitialize;
  end;
end;

‐ Zwraca wynik również dla IPv6 (właściwość DHCPv6Enabled).
‐ WMI bywa wyłączone na systemach „odchudzonych”, a zapytania są wolniejsze niż IP Helper.

3. Rejestr lub ipconfig /all

Dostęp awaryjny, ale wymaga parsowania tekstu lub struktury kluczy:

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<GUID>\EnableDHCP

Aktualne informacje i trendy

  • Windows 10/11 i Windows Server 2022 zalecają nowy ConvertInterfaceLuidToAlias + GetAdapterAddresses (obsługa IPv6, mobilne interfejsy, tunelowanie).
  • W środowiskach kontenerowych (WSL, Docker Desktop) interfejsy wirtualne również raportują DHCPEnabled, ale adresy mogą być stale przekazywane z hosta — warto filtrować po typie NIC.
  • Coraz częściej stosuje się DHCPv6 lub SLAAC; odpowiednie pola w strukturach WinAPI mają nazwy Ipv6EnableDhcp albo DHCPv6Enabled.

Wspierające wyjaśnienia i detale

  • Adresy z puli 169.254.x.x (APIPA) pojawią się w przypadku nieosiągalnego serwera DHCP; nadal oznacza to, że interfejs pracuje w trybie DHCP.
  • „Statyczny” adres może w praktyce pochodzić z DHCP, jeśli administrator ustawi rezerwację na serwerze – program nadal zobaczy DHCPEnabled = True.
  • IP Helper zwraca dodatkowo czasy dzierżawy (LeaseObtained, LeaseExpires) – przydatne do diagnostyki.

Aspekty etyczne i prawne

  • Odczyt konfiguracji lokalnych interfejsów nie narusza prywatności, ale zmiana ustawień IP (np. przez netsh interface ip set) wymaga uprawnień administratora.
  • Zdalne ustalanie rodzaju IP innego hosta nie jest możliwe; wszelkie próby zgadywania (np. po RDNS) mogą być mylące.

Praktyczne wskazówki

  1. Inicjalizuj/zwalniaj COM (CoInitialize, CoUninitialize) przy kodzie WMI.
  2. W wersjach 64-bit dodaj dyrektywy kompilatora i linkuj "iphlpapi.lib" lub użyj delayload dla iphlpapi.dll.
  3. Obsłuż wiele kart: filtruj po polu Type (Ethernet = 6, Wi-Fi = 71) lub po nazwie/ GUID.
  4. Przy testach automatycznych zmieniaj dzierżawę poleceniem ipconfig /renew lub wyłącz/ włącz adapter poprzez netsh.

Ewentualne zastrzeżenia lub uwagi dodatkowe

  • W starszych Windows XP funkcja GetAdaptersInfo nie pokazuje IPv6.
  • WMI może być zablokowane w politykach GPO; wtedy należy przejść na IP Helper.
  • Na Linux/ macOS potrzebne są inne techniki (parsowanie ip addr, systemd-networkd, pliki /etc/netplan itp.).

Sugestie dalszych badań

  • Implementacja cross-platform z użyciem biblioteki libuv lub QtNetwork.
  • Wykorzystanie PowerShell Core (cmdlet Get-NetIPConfiguration) wywoływanego z Delphi.
  • Analiza parametrów dzierżawy DHCP (opcja 51 – Lease Time) w aplikacjach monitorujących sieć.

Krótkie podsumowanie

Sprawdzenie, czy IP jest „dynamiczne”, sprowadza się do odczytu flagi DHCP na interfejsie.
W Delphi najpewniej zrobisz to wywołując GetAdaptersInfo / GetAdaptersAddresses (WinAPI) lub zapytaniem WMI. Wynik DHCPEnabled = True oznacza adres przydzielony dynamicznie, False – statycznie. Nie istnieje metoda umożliwiająca rozpoznanie tego faktu wyłącznie po samym numerze IP.

Oceń odpowiedź:

Zadaj dodatkowe pytanie Sztucznej Inteligencji

Czekaj (1min)...
Zastrzeżenie: Odpowiedzi udzielone przez sztuczną inteligencję (model językowy) mogą być niedokładne i wprowadzające w błąd. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi powinny być zweryfikowane przez użytkownika.