怎样获得局域网内数据库服务器网卡的MAC地址。

解决方案 »

  1.   

    用编程的方法还是不用编程的方法。
    先告诉你不用编程的方法吧
    1,把自己的IP设置和服务器一样,重起等机器报错,错误里面包含对方的MAC
    2,去哪个机器看看。
    用编程的方法可以向对方发送一个ICMP或随便什么包只要它能回来的就可以。
    然后你只要接受哪个数据包分析包头就可以了,不过这个只能在LINUX下面用,如果非要在WINDOWS下面用你就需要一个NDIS的驱动。
      

  2.   

    http://www.st0754.net/dispprogram.asp?ID=299
      

  3.   

    上面那个地址是程序示例,不过是VC++的,没问题吧?不用编程的方法也没那么复杂,直接在命令提示符(或DOS窗口)下输入下面的命令就看到了:ipconfig /all
      

  4.   

    直接从硬件地址取MAC地址:
    function GetMACAddress(LanaNum: Byte; MACAddress: PMACAddress): Byte;
    var
      AdapterStatus: PAdapterStatus;
      StatNCB: PNCB;
    begin
      New(StatNCB);
      ZeroMemory(StatNCB, SizeOf(TNCB));
      StatNCB.ncb_length := SizeOf(TAdapterStatus) +  255 * SizeOf(TNameBuffer);
      GetMem(AdapterStatus, StatNCB.ncb_length);
      try
        with StatNCB^ do
        begin
          ZeroMemory(MACAddress, SizeOf(TMACAddress));
          ncb_buffer := PChar(AdapterStatus);
          ncb_callname := '*              ' + #0;
          ncb_lana_num := Char(LanaNum);
          ncb_command  := Char(NCBASTAT);
          NetBios(StatNCB);
          Result := Byte(ncb_cmd_cplt);
          if Result = NRC_GOODRET then
            MoveMemory(MACAddress, AdapterStatus, SizeOf(TMACAddress));
        end;
      finally
        FreeMem(AdapterStatus);
        Dispose(StatNCB);
      end;
    end;
    用法procedure TForm1.MacAddrClick(Sender: TObject);
    var
      LanaNum: Byte;
      MACAddress: PMACAddress;
      RetCode: Byte;
    begin
      LanaNum := StrToInt(ComboBox1.Text);
      New(MACAddress);
      try
        RetCode := GetMACAddress(LanaNum, MACAddress);
        if RetCode = NRC_GOODRET then
        begin
          Edit1.Text := Format('%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x',
            [MACAddress[0], MACAddress[1], MACAddress[2],
             MACAddress[3], MACAddress[4], MACAddress[5]]);
        end else
        begin
          Beep;
          Edit1.Text := 'Error';
          ShowMessage('GetMACAddress Error! RetCode = $' + IntToHex(RetCode, 2));
        end;
      finally
        Dispose(MACAddress);
      end;
    end;
      

  5.   

    怎样获得局域网内数据库服务器网卡的MAC地址。
    楼上的都只能取得本机的MAC
      

  6.   

    哦,呵呵,不好意思,看错题了:P如果要取其它机器的MAC地址,用大头的方法,也就是向它发一个ICMP包,然后收下它的返回信息,在其中就有它的MAC地址的。大头不错哦:)
      

  7.   

    各位不好意思,我没有清楚。
    取本地的我写好了,我只是想要如何用DELPHI编程来实现获取网络上数据库服务起的MAC地址。
      

  8.   

    nbtstat -A <数据库服务器IP>
      

  9.   

    本人摘自 kingron Dephi_tips(my_base)
    请问:如何实现网卡的物理地址和IP地址的相互查询 (即在局域网内,知道IP查MAC地址,知道MAC地址查IP)
    你可以使用arp程序(WINDOWS自带)
    eg: arp -a 192.168.0.1如果使用程序查的话,你需要去实现一个ARP、RARP协议的软件
    如果只是查看一下对应关系,可以登陆到以太网交换机上查看IP和MAC之间的对应
    在Windows9x中,可按如下思路进行:
    1、建立局域网内IP地址--MAC地址对照表:
      调用icmp.dll中的IcmpSendEcho函数对一个地址发一个ping操作。
      成功后马上调用Iphlpapi.dll中的GetIpNetTable函数来取所有的ARP表,从中找出
    所关心的MAC地址。
      保存IP地址和MAC地址。
      依此类推,取得局域网内所有IP地址和MAC地址的对照表。
      (可取范围为IPADDR and SUBMASK 子网范围内的对照表)
    2、做一个查询界面。Windows2000中,应该可以更简单一些。因为它支持更多的函数如SendARP。
    IP to MAC 较容易:
    方法1. DOS命令: nbtstat -a IP
    方法2. DOS命令: ping IP 然后 arp -a
    方法3. 仿照nbtstat,向对方的137端口发数据包,包的内容如下(C代码)
     BYTE b[50]={0x0,0x00,0x0,0x10,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,
                 0x20,0x43,0x4b,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x0,0x0,0x21,0x0,0x1};
     (这是发nbtstat命令后用IPMan截获的),对方会向你返回一个数据包,
     其中有对方的工作组,主机名,用户名,MAC地址。当然,返回包的格式要
     自己分析,也可以查RFC文档。你自己的端口可以随便取一个值。
    方法4.在win9x下可用IPMan直接发ARP。
    方法5.在win2000下可用SendArp()直接发ARP。
    ----------------------------------------------------------------
    MAC to IP似乎较困难。
    Win9x下IPMan有此项功能,但我试了一下似乎不行。
    来自:zw84611, 时间:2001-10-7 19:37:00, ID:659172 
    发出去了,是用VC写的。因为我不喜欢Delphi5 的udp控件。其实用delphi也一样。很
    简单的,就是向对方137端口发内容为
    BYTE b[50]={0x0,0x00,0x0,0x10,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,
                 0x20,0x43,0x4b,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
                 0x41,0x41,0x41,0x0,0x0,0x21,0x0,0x1};
    的UDP包(Delphi中用$代替0x),对方就会给你应答,你接收就是了。
     
    Delphi源码如下,其中UDP用Socket API实现。
    -------------------------------------------------------unit udp;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, winsock,
      StdCtrls;const
      WM_SOCK = WM_USER + 1;     //自定义windows消息
      UDPPORT = 6767;            //设定UDP端口号
      NBTPORT = 137;type
      Tfrmmain = class(TForm)
        Button1: TButton;
        ListBox1: TListBox;
        Edit1: TEdit;
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
        s: TSocket;
        addr: TSockAddr;
        FSockAddrIn : TSockAddrIn; //利用消息实时获知UDP消息
        procedure ReadData(var Message: TMessage); message WM_SOCK;
      public
        { Public declarations }
        procedure SendData(b:array of byte);
      end;var
      frmmain: Tfrmmain;implementation{$R *.DFM}procedure Tfrmmain.FormCreate(Sender: TObject);
    var
       TempWSAData: TWSAData;
       //optval: integer;
    begin
         // 初始化SOCKET
         if WSAStartup($101, TempWSAData)=1 then
            showmessage('StartUp Error!');     s := Socket(AF_INET, SOCK_DGRAM, 0);
         if (s = INVALID_SOCKET) then   //Socket创建失败
         begin
              showmessage(inttostr(WSAGetLastError())+'  Socket创建失败');
              CloseSocket(s);
         end;
         //本机SockAddr绑定
         addr.sin_family := AF_INET;
         addr.sin_addr.S_addr := INADDR_ANY;
         addr.sin_port := htons(UDPPORT);
         if Bind(s, addr, sizeof(addr)) <> 0  then
           begin
             showmessage('bind fail');
           end;
         WSAAsyncSelect(s, frmmain.Handle , WM_SOCK, FD_READ);
         //对方SockAddrIn设定
         FSockAddrIn.SIn_Family := AF_INET;
         FSockAddrIn.SIn_Port := htons(NBTPORT);
    end;procedure Tfrmmain.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
        CloseSocket(s);
    end;procedure GetInfo(buf: Array of byte);
    {这个过程是根据返回报文的内容凑出来的,偶尔会出错。如果能根据
    报文格式的定义来做(可查阅相关RFC文档,可惜我没时间,以后做吧),就更好了。
    如果你作出来了,不妨寄给我一个哟。e-mail:[email protected]}
    var bAdd,bMac:boolean;
        str,strHost,strHex,strMac:string;
        tem,i,j:integer;
    begin  bAdd:=true;
      strHost:='';
      strHex:='';
      tem:=0;
      for i:=57 to 500 do //57-72
      begin
        if(Buf[i]=$cc)then break;
        if(Buf[i]=$20)then bAdd:=false;
        if(bAdd)then
        begin
          str:=char(Buf[i]);
          strHost:=strHost+str;      str:=Format('%x.',[Buf[i]]);
          strHex:=strHex+str;
        end;    inc(tem);
        if(tem mod 18=0)then
        begin
          bAdd:=true;
          Trim(strHex);
          bMac:=true;
          for j:=1 to length(strHex) do if strHex[j]>'0' then bMac:=false;
          //showmessage(strHex);
          if(bMac)then
          with frmmain.ListBox1 do
          begin
            Items.Delete(items.count-1);
            Items.add('mac address:');
            Delete(strMac,17,length(strMac)-17);
            Items.Add(strMac);
            break;
          end;
          frmmain.ListBox1.items.Add(strHost);
          strMac:=strHex;
          strHost:='';
          strHex:='';
        end;
      end;end;procedure Tfrmmain.ReadData(var Message: TMessage);
    var
       buffer: Array [1..500] of byte;
       len{,i}: integer;
       flen: integer;
       Event: word;
       value: string;begin
         value:='';
         Event := WSAGetSelectEvent(Message.LParam);
         if Event = FD_READ then
         begin
              len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
              {for i:=1 to len do value:=value+format('%x',[buffer[i]]);
              ListBox1.items.add(value);
              value:='';
              for i:=1 to len do if char(buffer[i])<>#0 then value:=value+char(buffer[i]);
              ListBox1.items.add(value);}
              if len<> 0 then GetInfo(buffer);
         end;
    end;procedure Tfrmmain.SendData(b:array of byte);
    var
       len: integer;
    begin     FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(edit1.text));
         len := sendto(s, b[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn));
         //if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then showmessage(inttostr(WSAGetLastError()));
         if len = SOCKET_ERROR then
            showmessage('send fail');
         if len <> 50 then
            showmessage('Not Send all');
    end;procedure Tfrmmain.Button1Click(Sender: TObject);
    const NbtstatPacket:array[0..49]of byte
          =($0,$0,$0,$10,$0,$1,
          $0,$0,$0,$0,$0,$0,$20,$43,$4b,
          $41,$41,$41,$41,$41,$41,$41,$41,
          $41,$41,$41,$41,$41,$41,$41,$41,
          $41,$41,$41,$41,$41,$41,$41,$41,
          $41,$41,$41,$41,$41,$41,$0,$0,$21,$0,$1);
    begin  senddata(NbtstatPacket);
      
    end;end.