Delphi: Get MAC of Router

前端 未结 2 1079
借酒劲吻你
借酒劲吻你 2020-12-30 11:36

I am using Delphi and I want to determinate the physical MAC address of a network device in my network, in this case the Router itself.

My code:

var
         


        
相关标签:
2条回答
  • 2020-12-30 11:54

    Not wishing to steal the thunder of RRUZ, I offer the following variant, taken from my codebase, with some observations. I've done this as an answer rather than a comment in order to include code.

    type
      TMacAddress = array [0..5] of Byte;
    
    function inet_addr(const IPAddress: string): ULONG;
    begin
      Result := ULONG(WinSock.inet_addr(PAnsiChar(AnsiString(IPAddress))));
    end;
    
    function SendARP(DestIP, SrcIP: ULONG; pMacAddr: Pointer; var PhyAddrLen: ULONG): DWORD; stdcall; external 'Iphlpapi.dll';
    
    function GetMacAddress(const IPAddress: string): TMacAddress;
    var
      MaxMacAddrLen: ULONG;
    begin
      MaxMacAddrLen := SizeOf(Result);
      if SendARP(inet_addr(IPAddress), 0, @Result, MaxMacAddrLen)<>NO_ERROR then begin
        raise EMacAddressError.CreateFmt('Unable to do SendARP on address: ''%s''', [IPAddress]);
      end;
    end;
    

    There are a couple of points to make.

    There is no need to call WSAStartup/WSACleanup.

    EDIT As RRUZ points out in a comment, the winsock documentation does not explictly exempt inet_addr from WSAStartup/WSACleanup so I retract this point. On Vista it is simpler just to call RtlIpv4StringToAddress. Having said all that, inet_addr is so easy to implement it may just be easier to roll your own.

    Secondly the declaration of inet_addr in WinSock.pas is incorrect. It declares the return value to be of a type u_long which is defined in WinSock.pas as Longint. This is a signed 4 byte integer but it should be an unsigned 4 byte integer, ULONG. Without the explicit cast you can get range errors.

    0 讨论(0)
  • 2020-12-30 12:17

    You can use the SendARP function to get the Mac Address.

    check this sample

    uses
     Windows,
     WinSock,
     SysUtils;
    
    
    function SendArp(DestIP,SrcIP:ULONG;pMacAddr:pointer;PhyAddrLen:pointer) : DWord; StdCall; external 'iphlpapi.dll' name 'SendARP';
    
    
    function GetMacAddr(const IPAddress: string; var ErrCode : DWORD): string;
    var
    MacAddr    : Array[0..5] of Byte;
    DestIP     : ULONG;
    PhyAddrLen : ULONG;
    WSAData    : TWSAData;
    begin
      Result    :='';
      WSAStartup($0101, WSAData);
      try
        ZeroMemory(@MacAddr,SizeOf(MacAddr));
        DestIP    :=inet_addr(PAnsiChar(IPAddress));
        PhyAddrLen:=SizeOf(MacAddr);
        ErrCode   :=SendArp(DestIP,0,@MacAddr,@PhyAddrLen);
        if ErrCode = S_OK then
         Result:=Format('%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x',[MacAddr[0], MacAddr[1],MacAddr[2], MacAddr[3], MacAddr[4], MacAddr[5]])
      finally
        WSACleanup;
      end;
    end;
    
    0 讨论(0)
提交回复
热议问题