Entwickler-Ecke

Internet / Netzwerk - MAC Addresse nur von LAN-Karte (nicht WLAN-Karte) ermitteln


starsurfer - Mi 25.10.06 17:44
Titel: MAC Addresse nur von LAN-Karte (nicht WLAN-Karte) ermitteln
Hallo DF´ler,

es gibt ja genug Ansätze die MAC Addresse raus zu finden.

Allerdings finden machen nur die erste oder manche alle MAC Adressen herraus.

Was mir recht wenig nützt.

Gibt es eine Möglichkeit nur die MAC Adressen der LAN-Karten(nur die MIT Kabel, WLAN nicht!) herraus zu finden?
bzw
Zwischen WLAN und LAN unterscheiden zu können?

Beispiel:
Notebook mit LAN und WLAN.
Jetzt weis man ja nicht ob LAN oder WLAN die "erste" Karte ist(oder doch?).
Und ich brauch jetzt von den 2 MAC Adressen nur die von der LAN Karte.

mfg Star


mkinzler - Mi 25.10.06 18:11

IMHO nur über die Beschreibung


starsurfer - Mi 25.10.06 18:18

und wo bekomm ich die Beschreibung her?

Oder wie meinst du das jetzt?!

Windows "weis" ja quasi ob es sich um ne LAN oder WLAN Karte handelt....kann ich das irgendwie anzapfen ?


mkinzler - Mi 25.10.06 18:26

Wie liest du das den aus?


starsurfer - Mi 25.10.06 18:33

Zur Zeit würde ich das so machen:

->cmd->ipconfig/all-> in ne .txt speichern und dann nach ethernetadapter suchen und raus filtern was ich brauch....

was natürlich nicht alzu elegant is(und wahrscheinlich recht fehleranfällig)...
aber da steht was für eine Art eine Verbindung ist (ethernetadapter/Drahtlose Verbindung....) also muss es ja irgendwo im system stehen... (registry?)


mkinzler - Mi 25.10.06 18:39

das bekommst du auch über die winapi raus oder verwendest vorgefertigte Funktionen (Z.B. jclsysinfo)


starsurfer - Mi 25.10.06 19:32

JEDI Code Library (JCL) lässt sich nich installieren weil die ganzen Dateien kaputt sind -_-

irgendwie werden alle Zeilenumbrüche nicht erkannt und da is dann nur son Viereck, und er meckert dann das die Zeilen zu lang sind -_-

in den Dateien steht irgendwie nur #13 als zeilumbruch und er will aber nur #13#10 erkennen...*hmpf*

bekomm ich rigendwo "ganze" Dateien her?
(habs von der offizielen Jedi WebSite)


mkinzler - Mi 25.10.06 19:39

http://jvcl.sourceforge.net/daily/
http://jcl.sf.net/daily/


Narses - Mi 25.10.06 22:39

Moin!

user profile iconstarsurfer hat folgendes geschrieben:
Windows "weis" ja quasi ob es sich um ne LAN oder WLAN Karte handelt....kann ich das irgendwie anzapfen ?

Nein, Windows "weiß" das leider nicht (erst Vista wird das können), LAN und WLAN wird im IP-Stack nicht unterschieden. Der Kartentreiber liefert zwar eine Beschreibung ab, aber das kann halt "beliebiger" Text sein, daraus kannst du nicht wirklich sauber ableiten, um was für einen Hardwaretyp es sich bei der Schicht-1-Anbindung handelt. :|

Fazit: AFAIK gibt es keine Möglichkeit, zweifelsfrei zu bestimmen, ob es sich bei dem Netzwerkadapter um eine LAN oder WLAN-Anbindung handelt.

cu
Narses


starsurfer - Mi 25.10.06 23:26

*hmpf* So ein Mist.

Das ist ja so ärgerlich...

Naja kann man nix machen,

Danke an alle.

mfg Star

ps.: mkinzler, auch die Files von deinem Link lassen sich nicht installieren:
"JcLSysUtils.pas(409) Fehler: undefinierter Bezeichner PBoolean"


starsurfer - Do 26.10.06 22:54

Kann mir einer zeigen wie ich die Bezeichnung der Netzwerkkarte raus bekomme?
(JCL Code Libary funktioniert ja leider nicht)


Narses - Do 26.10.06 22:59

Moin!

Suche im MSDN IPHLPAPI.DLL ;)

cu
Narses


jaenicke - Do 26.10.06 23:26

Aber wenn Windows nicht wüsste, dass es eine WLAN-Karte ist, wüsste Windows doch auch nicht, wann es den Befehl "Verfügbare drahtlose Netzwerke anzeigen" anzeigen muss. Und das Symbol ist ja auch entsprechend.

Deshalb: Irgendwoher muss Windows das wissen. Die Frage ist nur: Wie liest man das aus...


Narses - Do 26.10.06 23:35

Moin!

Das kommt über den Kartentreiber, aber "hängt" nicht an der Karte. :| Wenn also diese Option verfügbar ist, dann weißt du nur, dass ein Kartentreiber für WLAN geladen ist, aber nicht, an welchem Interface als Schicht-1-Hardware eine Funke hängt... :(

cu
Narses


starsurfer - So 29.10.06 14:01

Moin,

ich hab jetzt JCL zu laufen gebracht, die nützen mir aber nicht viel weil die mir nur de MAC Adressen liefern...

der vorschlag von Nares sieht gut aus.

Ich hab mir also die DLL besorgt und die benötigte Funktion raus gesucht:

-GetAdaptersAddresses-


Quelltext
1:
2:
3:
4:
5:
6:
7:
ULONG WINAPI GetAdaptersAddresses(
  ULONG Family,
  ULONG Flags,
  PVOID Reserved,
  PIP_ADAPTER_ADDRESSES AdapterAddresses,
  PULONG SizePointer
);


nur hab ich keine Erfahrung mit c/c++ also hab ich keine Ahnung wie ich die Funktion nutzen soll....

mein Ansatz:

Delphi-Quelltext
1:
2:
function GetAdaptersaddresses(?):?; stdcall;
external 'IPHLPAPI.DLL';


was natürlich nich allzu viel ist :)

wie bekomm ich die Funktion zum laufen ?


jaenicke - So 29.10.06 14:17

Wie wärs, wenn du die vorliegenden Übersetzungen der IP Helper API nutzt... :lol:
http://www.delphi-jedi.org/APILIBRARY:947996
Die Funkton wird da ziemlich sicher auch dabei sein.


starsurfer - So 29.10.06 14:23

nein,

-GetAdaptersAddresses- ist nicht in der "Übersetzung" enthalten,

nur GetAdaptersInfo ist enthalten...
na mal guggn ob ich damit das bekomme was ich brauch...

thx für den Tipp

//EDIT: wenn ich mit den TYP PIP_ADAPTER_INFO so angugg wird das was, jetzt muss ichs nur noch hin bekommen ^^


jaenicke - So 29.10.06 14:32

Nun, ich habe mal in die JwaIpHlpApi.pas aus der Win32 API gekuckt, da ist de Funktion drin. Hmm, vielleicht nicht in der extra IP Helper API Übersetzung...

Delphi-Quelltext
1:
2:
function GetAdaptersAddresses(Family: ULONG; Flags: DWORD; Reserved: PVOID;
  pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen: PULONG): DWORD; stdcall;


starsurfer - So 29.10.06 14:45

naja ich hatte nur die IpHlpApi.zip gesehen und die angeguggt...

gleich mal schauen :)


starsurfer - So 29.10.06 19:37

ok habs jetzt mit der Unit versucht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, jwaiphlpapi,jwaiptypes,jwawinsock2,Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var adapter:IP_ADAPTER_ADDRESSES;
    i:integer;
    adresse:string;
    a:pointer;
begin
GetAdaptersAddresses(AF_UNSPEC,GAA_FLAG_INCLUDE_PREFIX,Nil,@adapter,@a);
for i:=0 to 7 do
adresse:=adresse+'-'+inttohex(ord(adapter.PhysicalAddress[i]),2);
memo1.lines.add(adresse);
end;

end.


aber das liefert mir nur Mist!
Die Adresse die ich zurückgeliefert bekomme ist erstens falsch und zweitens ändert die sich immer mal.

was mach ich falsch ?

//EDIT:

Info zur Funktion GetAdaotersAddresses
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iphlp/iphlp/getadaptersaddresses.asp

und der Typ IP_ADAPTER_ADDRESSES sieht so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
PIP_ADAPTER_ADDRESSES = ^_IP_ADAPTER_ADDRESSES;
  {$EXTERNALSYM PIP_ADAPTER_ADDRESSES}
  _IP_ADAPTER_ADDRESSES = record
    Union: record
      case Integer of
        0: (
          Alignment: ULONGLONG);
        1: (
          Length: ULONG;
          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;
    PhysicalAddress: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1of BYTE;
    PhysicalAddressLength: DWORD;
    Flags: DWORD;
    Mtu: DWORD;
    IfType: DWORD;
    OperStatus: IF_OPER_STATUS;
    Ipv6IfIndex: DWORD;
    ZoneIndices: array [0..15of DWORD;
    FirstPrefix: PIP_ADAPTER_PREFIX;
  end;
  {$EXTERNALSYM _IP_ADAPTER_ADDRESSES}
  IP_ADAPTER_ADDRESSES = _IP_ADAPTER_ADDRESSES;
  {$EXTERNALSYM IP_ADAPTER_ADDRESSES}
  TIpAdapterAddresses = IP_ADAPTER_ADDRESSES;
  PIpAdapterAddresses = PIP_ADAPTER_ADDRESSES;


starsurfer - Mo 30.10.06 12:00

ok, ich habs jetzt selber zum laufen gebracht, und natürlich hat sich ein neues Problem ergeben :bawling:

Es liest die Informationen über die Netzwerkadapter richtig aus, aber so bald ich 3 aktiviert habe (LAN,WLAN,DSL ADAPTER) und das Programm suchen lasse sagt er mir "Dateiname zu lang" obwohl ich rein gar nix mit Dateien mach....

sind nur 2 Adapter aktiviert funktionierts ohne Probleme, könnt ihr das bei euch bitte testen ?

Exe ist im Anhang.

Danke star

//EDIT: EXE und Source angehängt + IpHlpAPI.pas


espen - Mo 30.10.06 12:32

Hi,

eine Möglichkeit wäre noch über WMI:
http://www.delphipraxis.net/topic24332_mac+adressen+des+rechners+via+wmi+ermitteln.html

oder über die shell:

Quelltext
1:
GetMac /V > mac.txt                    

und die mac.txt parsen.


jaenicke - Mo 30.10.06 15:13

Also, ich bin jetzt leider nicht zu Hause, deshalb geht es jetzt nicht, aber ich werd mir das Programm mal nachher ansehen.

Und klar, WMI ist auch eine sehr gute Moeglichkeit.


starsurfer - Mo 30.10.06 19:30

Mmmhhh...

Die Uses für wmi hab ich nicht. Ich hab nach denen gesucht aber nix gefunden...

Das Beispiel was du mir gegeben hast liefert mir das nur die MAC Adressen oder auch die Bezeichnungen dazu?
So wie ich das versteh bekomm ich nur de MAC geliefert.

Nur ne MAC nützt mir aber recht wenig, ich brauch min de Bezeichnung und den Name des Adapters.

--------------------------------------
Hab noch was anderes probiert:

im Programm (siehe oben) hab ich getadaptersinfo() genutzt,
jetzt hab ichs mal mit getadaptersaddresses() versucht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
uses  ..., jwaiphlpapi,jwaiptypes,jwawinsock2,...

.
.
.

procedure TForm1.Button1Click(Sender: TObject);
var adapter:pip_adapter_addresses;
    buffer:dword;
    Error:dword;
    P:pointer;
begin
buffer:=sizeof(adapter^);
new(adapter);
error:=GetAdaptersAddresses(0,0,nil,adapter,@buffer);
p:= adapter;
if error = no_error then
   begin

   end
    else
   begin
   memo1.Clear;
   memo1.lines.add(SysErrorMessage( Error ));
   end;
end;


jetzt liefert er mir immer den Error 111 (Dateiname zu lang) egal welcher Adapter an oder aus ist... :?


Roy - Mo 19.05.08 20:28

Hallo Starsurver,
bei deinem Angehängten Dateien ermittelt er mir nichts. Es kommt nur die Meldung "Der Dateiname ist zu lang".

Gruß Roy


Narses - Mo 19.05.08 23:03

Moin!

Auch wenn der Thread schon etwas angestaubt ist, kann ja nicht schaden, nochmal eine Lösung nachzuliefern! ;)

user profile iconstarsurfer hat folgendes geschrieben:
jetzt hab ichs mal mit getadaptersaddresses() versucht:
Wie auch immer du auf diesen Code gekommen bist :shock:, hier ist ein Port des Quelltextes von der MSDN-Seite [http://msdn.microsoft.com/en-us/library/aa365915(VS.85).aspx] (läuft aber erst ab WinXP!): :idea:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
type
  TfrmMain = class(TForm)
    meLog: TMemo;
    BtnStart: TButton;
    procedure BtnStartClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
//...
uses
  jwaiphlpapi, jwaiptypes, jwawinsock2;

function CheckWinXP: Boolean;
begin
  Result := (Win32Platform = 2and
            (Win32MajorVersion = 5and
            (Win32MinorVersion >= 1);
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  // naja, das Ding bricht sowieso schon vorher ins Essen,
  // weil die statische Bindung der DLL nicht klappen wird...
  if NOT CheckWinXP then begin
    MessageDlg('Required OS: >= WinXP!',mtInformation,[mbCancel],0);
    Application.Terminate;
  end;
end;

procedure TfrmMain.BtnStartClick(Sender: TObject);
  var
    dwFamily,
    dwFlags,
    dwBufLen,
    dwRetVal: DWORD;
    pAddresses,
    pCurrAddresses: PIP_ADAPTER_ADDRESSES;

    pUnicast: PIP_ADAPTER_UNICAST_ADDRESS;
    pAnycast: PIP_ADAPTER_ANYCAST_ADDRESS;
    pMulticast: PIP_ADAPTER_MULTICAST_ADDRESS;
    pDnServer: PIP_ADAPTER_DNS_SERVER_ADDRESS;
    pPrefix: PIP_ADAPTER_PREFIX;

    i: Integer;
    tmp: String;

  procedure Logout(const S: String);
  begin
    meLog.Lines.Add(S);
  end;

begin
  meLog.Clear;
  dwFamily := AF_UNSPEC;
  dwFlags := GAA_FLAG_INCLUDE_PREFIX;
  dwBufLen := SizeOf(IP_ADAPTER_ADDRESSES);
  GetMem(pAddresses,dwBufLen);
  if Assigned(pAddresses) then
    try
      if (GetAdaptersAddresses(dwFamily, dwFlags, NIL, pAddresses, @dwBufLen) = ERROR_BUFFER_OVERFLOW) then begin
        FreeMem(pAddresses);
        GetMem(pAddresses,dwBufLen);
        if Assigned(pAddresses) then begin
          dwRetVal := GetAdaptersAddresses(dwFamily, dwFlags, NIL, pAddresses, @dwBufLen);
          if (dwRetVal = NO_ERROR) then begin
// -----------------------------------------------------------------------------
            pCurrAddresses := pAddresses;
            while Assigned(pCurrAddresses) do begin
              Logout('Length of the IP_ADAPTER_ADDRESS struct: '+IntToStr(pCurrAddresses^.Union.Length));
              Logout('IfIndex (IPv4 interface): '+IntToStr(pCurrAddresses^.Union.IfIndex));
              Logout('Adapter name: '+pCurrAddresses^.AdapterName);

              pUnicast := pCurrAddresses^.FirstUnicastAddress;
              if Assigned(pUnicast) then begin
                i := 0;
                while Assigned(pUnicast) do begin
                  pUnicast := pUnicast^.Next;
                  Inc(i);
                end;
                Logout('Number of Unicast Addresses: '+IntToStr(i));
              end
              else
                Logout('No Unicast Addresses');

              pAnycast := pCurrAddresses^.FirstAnycastAddress;
              if Assigned(pAnycast) then begin
                i := 0;
                while Assigned(pAnycast) do begin
                  pAnycast := pAnycast^.Next;
                  Inc(i);
                end;
                Logout('Number of Anycast Addresses: '+IntToStr(i));
              end
              else
                Logout('No Anycast Addresses');

              pMulticast := pCurrAddresses^.FirstMulticastAddress;
              if Assigned(pMulticast) then begin
                i := 0;
                while Assigned(pMulticast) do begin
                  pMulticast := pMulticast^.Next;
                  Inc(i);
                end;
                Logout('Number of Multicast Addresses: '+IntToStr(i));
              end
              else
                Logout('No Multicast Addresses');

              pDnServer := pCurrAddresses^.FirstDnsServerAddress;
              if Assigned(pDnServer) then begin
                i := 0;
                while Assigned(pDnServer) do begin
                  pDnServer := pDnServer^.Next;
                  Inc(i);
                end;
                Logout('Number of DNS Server Addresses: '+IntToStr(i));
              end
              else
                Logout('No DNS Server Addresses');

              Logout('DNS Suffix: '+pCurrAddresses^.DnsSuffix);
              Logout('Description: '+pCurrAddresses^.Description);
              Logout('Friendly name: '+pCurrAddresses^.FriendlyName);

              if (pCurrAddresses^.PhysicalAddressLength <> 0then begin
                tmp := '';
                for i := 0 to pCurrAddresses^.PhysicalAddressLength -1 do begin
                  tmp := tmp +IntToHex(pCurrAddresses^.PhysicalAddress[i],2);
                  if (i < Integer(pCurrAddresses^.PhysicalAddressLength -1)) then
                    tmp := tmp +'-';
                end;
                Logout('Physical address: '+tmp);
              end;
              Logout('Flags: '+IntToStr(pCurrAddresses^.Flags));
              Logout('MTU: '+IntToStr(pCurrAddresses^.Mtu));
              Logout('IfType: '+IntToStr(pCurrAddresses^.IfType));
              Logout('OperStatus: '+IntToStr(Integer(pCurrAddresses^.OperStatus)));
              Logout('Ipv6IfIndex (IPv6 interface): '+IntToStr(pCurrAddresses^.Ipv6IfIndex));
              tmp := '';
              for i := 0 to 15 do
                  tmp := tmp +IntToHex(pCurrAddresses^.ZoneIndices[i],8);
              Logout('ZoneIndices (hex): '+tmp);

              pPrefix := pCurrAddresses^.FirstPrefix;
              if Assigned(pPrefix) then begin
                i := 0;
                while Assigned(pPrefix) do begin
                  pPrefix := pPrefix^.Next;
                  Inc(i);
                end;
                Logout('Number of IP Adapter Prefix entries: '+IntToStr(i));
              end
              else
                Logout('Number of IP Adapter Prefix entries: 0');
              Logout('');
              pCurrAddresses := pCurrAddresses^.Next;
            end// while
// -----------------------------------------------------------------------------
          end
          else begin
            if (dwRetVal = ERROR_NO_DATA) then
              MessageDlg('No adapter information available!',mtInformation,[mbOK],0)
            else
              SysErrorMessage(dwRetVal);
          end;
        end
        else
          MessageDlg('Out of memory! (2)',mtError,[mbCancel],0);
      end;
    finally
      FreeMem(pAddresses);
    end
  else
    MessageDlg('Out of memory! (1)',mtError,[mbCancel],0);
end;



user profile iconRoy hat folgendes geschrieben:
bei deinem Angehängten Dateien ermittelt er mir nichts. Es kommt nur die Meldung "Der Dateiname ist zu lang".
Ähm... 8) das sagt er doch selbst schon die ganze Zeit... :lol:

cu
Narses