Einzelnen Beitrag anzeigen

quendolineDD

Registriert seit: 19. Apr 2007
Ort: Dresden
781 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: IP-ADAPTER_ADDRESS Structure

  Alt 7. Dez 2008, 20:19
Hab das ganze mal noch um eine Klasse erweitert, die das Interface beinhaltet um es besser zu verwenden.
Aber da ist mir bei der Anwendung was aufgefallen:
Zitat:
TransmitLinkSpeed

The current speed in bits per second of the transmit link for the adapter.

Note This structure member is only available on Windows Vista and later.
ReceiveLinkSpeed

The current speed in bits per second of the receive link for the adapter.

Note This structure member is only available on Windows Vista and later.
Aber wenn ich nun die Werte, welche ich bei mir als Extended speichere benutzte, sind sie um ein 10-tausendfaches mal größer als sie sollten. Sicher kann ich die Werte einfach als ein 10-tausendstel interpretieren, jedoch würde ich gerne die Ursache des so überhöhten Wertes wissen.
Beispiel:
  FTransmitLinkspeed := aAdapter.TransmitLinkspeed / (8*1024*1024*1024); // MByte/s D.h. Müsste da nun eigentlich ~33 MB/s dastehen. Was steht wirklich da? 3276860.
Kann doch nicht sein, oder hab ich mal wieder einen Blackout?

Achja. Ich poste hier mal nun die wiederum erweitere Version der Unit, ist jedoch immer noch im Aufbau

Delphi-Quellcode:
unit uWinGetAdaptersAddresses;

interface

uses Windows, SysUtils;

const
  MAX_ADAPTER_ADDRESS_LENGTH = 8;
  MAX_DHCPV6_DUID_LENGTH = 130;

  { Which values?
//Family
  AF_INET                        = ;
  AF_INET6                        = ;
  AF_UNSPEC                      = ;
}

//ifType Const
  IF_TYPE_OTHER = 1;
  IF_TYPE_ETHERNET_CSMACD = 6;
  IF_TYPE_ISO88025_TOKENRING = 9;
  IF_TYPE_PPP = 23;
  IF_TYPE_SOFTWARE_LOOPBACK = 24;
  IF_TYPE_ATM = 37;
  IF_TYPE_IEEE80211 = 71;
  IF_TYPE_TUNNEL = 131;
  IF_TYPE_IEEE1394 = 144;

//OperStatus Const
  IfOperStatusUp = 1;
  IfOperStatusDown = 2;
  IfOperStatusTesting = 3;
  IfOperStatusUnknown = 4;
  IfOperStatusDormant = 5;
  IfOperStatusNotPresent = 6;
  IfOperStatusLowerLayerDown = 7;

type
PhysAddrArray = array[0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;

//http://msdn.microsoft.com/en-us/library/ms740496(VS.85).aspx

PSOCKADDR = ^SOCKADDR;
SOCKADDR = record
  sa_family : ShortInt;
  sa_data : array[0..13] of Char;
end;


//http://msdn.microsoft.com/en-us/library/ms740507(VS.85).aspx

PSOCKET_ADDRESS = ^SOCKET_ADDRESS;
SOCKET_ADDRESS = record
  lpSocketaddr : PSOCKADDR;
  iSockaddrLength : Integer;
end;

//NET_IF_CONNECTION_TYPE Const
NET_IF_CONNECTION_TYPE = (
  NET_IF_CONNECTION_DEDICATED = 1,
  NET_IF_CONNECTION_PASSIVE = 2,
  NET_IF_CONNECTION_DEMAND = 3,
  NET_IF_CONNECTION_MAXIMUM = 4
);

//http://msdn.microsoft.com/en-us/library/aa366281(VS.85).aspx

IP_PREFIX_ORIGIN = (
  IpPrefixOriginOther = 0,
  IpPrefixOriginManual,
  IpPrefixOriginWellKnown,
  IpPrefixOriginDhcp,
  IpPrefixOriginRouterAdvertisement,
  IpPrefixOriginUnchanged = 16
);


//http://msdn.microsoft.com/en-us/library/aa366283(VS.85).aspx

IP_SUFFIX_ORIGIN = (
  IpSuffixOriginOther = 0,
  IpSuffixOriginManual,
  IpSuffixOriginWellKnown,
  IpSuffixOriginDhcp,
  IpSuffixOriginLinkLayerAddress,
  IpSuffixOriginRandom,
  IpSuffixOriginUnchanged = 16
);


//http://msdn.microsoft.com/en-us/library/aa366069(VS.85).aspx

IP_DAD_STATE = (
  IpDadStateInvalid = 0,
  IpDadStateTentative,
  IpDadStateDuplicate,
  IpDadStateDeprecated,
  IpDadStatePreferred
);

//http://msdn.microsoft.com/en-us/library/aa366066(VS.85).aspx

PIP_ADAPTER_UNICAST_ADDRESS = ^IP_ADAPTER_UNICAST_ADDRESS;
IP_ADAPTER_UNICAST_ADDRESS = record
  union: record
    case Integer of
    0: (Length: LongInt; Flags: DWORD);
    end;
  Next : PIP_ADAPTER_UNICAST_ADDRESS;
  Address : SOCKET_ADDRESS;
  PrefixOrigin : IP_PREFIX_ORIGIN;
  SuffixOrigin : IP_SUFFIX_ORIGIN;
  DadState : IP_DAD_STATE;
  ValidLifeTime : LongInt;
  PreferredLifeTime : LongInt;
  LeaseLifeTime : LongInt;
  OnLinkPrefixLength : array[0..7] of Integer;
end;


//http://msdn.microsoft.com/en-us/library/aa366059(VS.85).aspx

PIP_ADAPTER_ANYCAST_ADDRESS = ^IP_ADAPTER_ANYCAST_ADDRESS;
IP_ADAPTER_ANYCAST_ADDRESS = record
  union: record
    case Integer of
      0: (Alignment: LongInt);
      1: (Length: LongInt; Flags: DWORD);
    end;
  Next : PIP_ADAPTER_ANYCAST_ADDRESS;
  Address : SOCKET_ADDRESS;
end;


//http://msdn.microsoft.com/en-us/library/aa366063(VS.85).aspx

PIP_ADAPTER_MULTICAST_ADDRESS = ^IP_ADAPTER_MULTICAST_ADDRESS;
IP_ADAPTER_MULTICAST_ADDRESS = record
  union: record
    case Integer of
      0: (Alignment: LongInt);
      1: (Length: LongInt; Flags: DWORD);
    end;
  Next : PIP_ADAPTER_MULTICAST_ADDRESS;
  Address : SOCKET_ADDRESS;
end;


//http://msdn.microsoft.com/en-us/library/aa366060(VS.85).aspx

PIP_ADAPTER_DNS_SERVER_ADDRESS = ^IP_ADAPTER_DNS_SERVER_ADDRESS;
IP_ADAPTER_DNS_SERVER_ADDRESS = record
  union: record
    case Integer of
      0: (Alignment: LongInt);
      1: (Length: LongInt; Reserved: DWORD);
    end;
    Next : PIP_ADAPTER_DNS_SERVER_ADDRESS;
    Address : SOCKET_ADDRESS;
end;


//http://msdn.microsoft.com/en-us/library/aa366065(VS.85).aspx

PIP_ADAPTER_PREFIX = ^IP_ADAPTER_PREFIX;
IP_ADAPTER_PREFIX = record
  union: record
    case Integer of
      0: (Alignment: LongInt);
      1: (Length: LongInt; Flags: DWORD);
    end;
  Next : PIP_ADAPTER_PREFIX;
  Address : SOCKET_ADDRESS;
  PrefixLength : LongInt;
end;


//http://msdn.microsoft.com/en-us/library/aa366058(VS.85).aspx

PIP_ADAPTER_ADDRESSES = ^IP_ADAPTER_ADDRESSES;
IP_ADAPTER_ADDRESSES = record
  union: record
    case Integer of
      0: (Alignment: LongInt);
      1: (Length: LongInt; IfIndex: DWORD);
    end;
  Next : PIP_ADAPTER_ADDRESSES;
  AdapterName : PCHAR;
  FirstUnicastAddress : PIP_ADAPTER_UNICAST_ADDRESS;
  FirstAnycastAddress : PIP_ADAPTER_ANYCAST_ADDRESS;
  FirstMulticastAddress : PIP_ADAPTER_MULTICAST_ADDRESS;
  FirstDnsServerAddress : PIP_ADAPTER_DNS_SERVER_ADDRESS;
  DnsSuffix : PWCHAR;
  Description : PWCHAR;
  FriendlyName : PWCHAR;
  PhysicalAdress : PhysAddrArray;
  PhysicalAdressLength : DWORD;
  Flags : DWORD;
  Mtu : DWORD;
  IfType : DWORD;
// OperStatus : IF_OPER_STATUS;
  Ipv6IfIndex : DWORD;
  ZoneIndices : array[0..15] of DWORD;
  FirstPrefix : PIP_ADAPTER_PREFIX;
  TransmitLinkSpeed : Int64;
  ReceiveLinkSpeed : Int64;
// FirstWinsServerAddress: PIP_ADAPTER_WINS_SERVER_ADDRESS_LH;
// FirstGatewayAddress : PIP_ADAPTER_GATEWAY_ADDRESS_LH;
  Ipv4Metric : LongInt;
  Ipv6Metric : LongInt;
// Luid : IF_LUID;
  Dhcpv4Server : SOCKET_ADDRESS;
// CompartmentId : NET_IF_COMPARTMENT_ID; [This member is not currently supported and is reserved for future use]
// NetworkGuid : NET_IF_NETWORK_GUID;
  ConnectionType : NET_IF_CONNECTION_TYPE;
// TunnelType : TUNNEL_TYPE;
  Dhcpv6Server : SOCKET_ADDRESS;
  Dhcpv6ClientDuid : array[0..MAX_DHCPV6_DUID_LENGTH - 1] of BYTE;
  Dhcpv6ClientDuidLength: LongInt;
  Dhcpv6Iaid : LongInt;
// FirstDnsSuffix : PIP_ADAPTER_DNS_SUFFIX;
end;

TAdapter = Class(TObject)
private
  FAdapterName : PChar;
  FFriendlyName : PWChar;
  FDnsSuffix : PWChar;
  FSockAddr : PChar;
  FIpv4Metric : LongInt;
  FTransmitLinkspeed : Extended;
  FReceiveLinkSpeed : Extended;
  FIfType : DWORD;
  FPhysicalAddress : String;

  function GetIfType : string;
  function GetPhysicalAddress : string;
  procedure SetPhysicalAddress(const aPhysAddr : PhysAddrArray; const Len : DWORD);
public
  constructor Create(aAdapter : IP_ADAPTER_ADDRESSES);
  destructor Destroy; override;

  property FriendlyName : PWChar read FFriendlyName;
  property AdapterName : PChar read FAdapterName;
  property DnsSuffix : PWChar read FDnsSuffix;
  property SockAddr : PChar read FSockAddr;
  property Ipv4Metric : LongInt read FIpv4Metric;
  property TransmitLinkspeed : Extended read FTransmitLinkspeed;
  property ReceiveLinkSpeed : Extended read FReceiveLinkSpeed;
  property IfType : String read GetIfType;
  property PhysicalAddress : String read GetPhysicalAddress;
end;


PVOID = Pointer;

//http://msdn.microsoft.com/en-us/library/aa365915(VS.85).aspx

function GetAdaptersAddresses(Family: ULONG; Flags: DWORD; Reserved: PVOID;
                             pAdapterAddresses: PIP_ADAPTER_ADDRESSES;
                             pOutBufLen: PULONG): DWORD; stdcall;
                             external 'IPHLPAPI.DLLname 'GetAdaptersAddresses';

function DecToHex(dec : integer) : String;
implementation

{ TAdaper }

constructor TAdapter.Create(aAdapter: IP_ADAPTER_ADDRESSES);
begin
  inherited Create;
  FAdapterName := aAdapter.AdapterName;
  FFriendlyName := aAdapter.FriendlyName;
  FDnsSuffix := aAdapter.DnsSuffix;
  FSockAddr := aAdapter.Dhcpv4Server.lpSocketaddr^.sa_data;
  FIpv4Metric := aAdapter.Ipv4Metric;
  FTransmitLinkspeed := aAdapter.TransmitLinkspeed / 8589934592; // MByte/s
  FReceiveLinkspeed := aAdapter.ReceiveLinkSpeed / 8589934592;
  FIfType := aAdapter.IfType;
  SetPhysicalAddress(aAdapter.PhysicalAdress, aAdapter.PhysicalAdressLength);
end;

destructor TAdapter.Destroy;
begin
//
  inherited;
end;

function TAdapter.GetIfType: string;
begin
  case FIfType of
    1: result := 'IF_TYPE_OTHER';
    6: result := 'IF_TYPE_ETHERNET_CSMACD';
    9: result := 'IF_TYPE_ISO88025_TOKENRING';
    23: result := 'IF_TYPE_PPP';
    24: result := 'IF_TYPE_SOFTWARE_LOOPBACK';
    37: result := 'IF_TYPE_ATM';
    71: result := 'IF_TYPE_IEEE80211';
    131: result := 'IF_TYPE_TUNNEL';
    144: result := 'IF_TYPE_IEEE1394';
  else result := 'Not set yet';
  end;
end;

function TAdapter.GetPhysicalAddress: string;
begin
  result := FPhysicalAddress;
end;

procedure TAdapter.SetPhysicalAddress(const aPhysAddr: PhysAddrArray;
  const Len: DWORD);
var
  i : integer;
begin
FPhysicalAddress := DecToHex(aPhysAddr[0]);
if len = 0 then exit;
  for i := 1 to len-1 do begin
    FPhysicalAddress := FPhysicalAddress + '-' + DecToHex(aPhysAddr[i]);
  end;
end;

function DecToHex(dec : Integer) : String;
const
  HexArr : array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
var
  tmp : Integer;
begin
result := '';
tmp := 0;
{
HEX |0|1|2|3|4|5|6|7|8|9|A |B |C |D |E |F  represent Array[tmp]
------------------------------------------
DEC |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15 represent tmp
}


  repeat
    tmp := dec mod 16;
    dec := dec div 16;
    result := HexArr[tmp] + result;
  until (tmp = 0) or (length(result) = 2);
  if result = '0then result := '00';
end;

end.
Wenn es im Quelltext irgendwelche Beanstandungen gibt, einfach hier oder per PN melden

Dann noch eine weitere Frage:
Ich scheine die IPs falsch zu interpretieren:
zB der broadcast
Delphi-Quellcode:
IP_ADAPTER_UNICAST_ADDRESS = record
  union: record
    case Integer of
    0: (Length: LongInt; Flags: DWORD);
    end;
  Next : PIP_ADAPTER_UNICAST_ADDRESS;
  Address : SOCKET_ADDRESS;
  PrefixOrigin : IP_PREFIX_ORIGIN;
  SuffixOrigin : IP_SUFFIX_ORIGIN;
  DadState : IP_DAD_STATE;
  ValidLifeTime : LongInt;
  PreferredLifeTime : LongInt;
  LeaseLifeTime : LongInt;
  OnLinkPrefixLength : array[0..7] of Integer;
end;
drüfte die IP doch in Address.lpSocketaddr^.sa_data zu finden sein!? Wenn ich das auslese, bekomme ich nur wirre Datenmengen -.-"
Wo stehen denn die IPs in dieser komplexen Structure?

Und welche Werte haben AF_INET, AF_INET6 und AF_UNSPEC?

Dangöö
Angehängte Dateien
Dateityp: pas uwingetadaptersaddresses_111.pas (9,9 KB, 56x aufgerufen)
Lars S.
Wer nicht mit der Zeit geht, geht mit der Zeit.
  Mit Zitat antworten Zitat