取MAC地址

本文介绍两种获取计算机MAC地址的方法:一种是通过IP地址使用SendARP函数查找,另一种是利用NetBIOS API函数获取多网卡的MAC地址详情。

取MAC地址

 

1、通过IP取MAC地址

uses
WinSock;

Function sendarp(ipaddr:ulong;
temp:dword;
ulmacaddr:pointer;
ulmacaddrleng:pointer) : DWord; StdCall; External 'Iphlpapi.dll' Name 'SendARP';

procedure TForm1.Button1Click(Sender: TObject);
var
myip:ulong;
mymac:array[0..5] of byte;
mymaclength:ulong;
r:integer;
begin
myip:=inet_addr(PChar('192.168.6.180'));
mymaclength:=length(mymac);
r:=sendarp(myip,0,@mymac,@mymaclength);
label1.caption:='errorcode:'+inttostr(r);
label2.caption:=format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',[mymac[0],mymac[1],mymac[2],mymac[3],mymac[4],mymac[5]]);
end;


2、取MAC地址 (含多网卡)

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
WinSock, StdCtrls;

Const
MAX_HOSTNAME_LEN = 128; { from IPTYPES.H }
MAX_DOMAIN_NAME_LEN = 128;
MAX_SCOPE_ID_LEN = 256;
MAX_ADAPTER_NAME_LENGTH = 256;
MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
MAX_ADAPTER_ADDRESS_LENGTH = 8;

Type
TIPAddressString = Array[0..4*4-1] of Char;

PIPAddrString = ^TIPAddrString;
TIPAddrString = Record
Next : PIPAddrString;
IPAddress : TIPAddressString;
IPMask : TIPAddressString;
Context : Integer;
End;

PFixedInfo = ^TFixedInfo;
TFixedInfo = Record { FIXED_INFO }
HostName : Array[0..MAX_HOSTNAME_LEN+3] of Char;
DomainName : Array[0..MAX_DOMAIN_NAME_LEN+3] of Char;
CurrentDNSServer : PIPAddrString;
DNSServerList : TIPAddrString;
NodeType : Integer;
ScopeId : Array[0..MAX_SCOPE_ID_LEN+3] of Char;
EnableRouting : Integer;
EnableProxy : Integer;
EnableDNS : Integer;
End;

PIPAdapterInfo = ^TIPAdapterInfo;
TIPAdapterInfo = Record { IP_ADAPTER_INFO }
Next : PIPAdapterInfo;
ComboIndex : Integer;
AdapterName : Array[0..MAX_ADAPTER_NAME_LENGTH+3] of Char;
Description : Array[0..MAX_ADAPTER_DESCRIPTION_LENGTH+3] of Char;
AddressLength : Integer;
Address : Array[1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
Index : Integer;
_Type : Integer;
DHCPEnabled : Integer;
CurrentIPAddress : PIPAddrString;
IPAddressList : TIPAddrString;
GatewayList : TIPAddrString;
DHCPServer : TIPAddrString;
HaveWINS : Bool;
PrimaryWINSServer : TIPAddrString;
SecondaryWINSServer : TIPAddrString;
LeaseObtained : Integer;
LeaseExpires : Integer;
End;

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

var
Form1: TForm1;

Function sendarp(ipaddr:ulong;
temp:dword;
ulmacaddr:pointer;
ulmacaddrleng:pointer) : DWord; StdCall;

implementation

{$R *.dfm}

Function sendarp; External 'Iphlpapi.dll' Name 'SendARP';
Function GetAdaptersInfo(AI : PIPAdapterInfo; Var BufLen : Integer) : Integer;
StdCall; External 'iphlpapi.dll' Name 'GetAdaptersInfo';

procedure TForm1.GetAdapterInformation;
Var
AI,Work : PIPAdapterInfo;
Size : Integer;
Res : Integer;
I : Integer;

Function MACToStr(ByteArr : PByte; Len : Integer) : String;
Begin
Result := '';
While (Len > 0) do Begin
Result := Result+IntToHex(ByteArr^,2)+'-';
ByteArr := Pointer(Integer(ByteArr)+SizeOf(Byte));
Dec(Len);
End;
SetLength(Result,Length(Result)-1); { remove last dash }
End;

Function GetAddrString(Addr : PIPAddrString) : String;
Begin
Result := '';
While (Addr <> nil) do Begin
Result := Result+'A: '+Addr^.IPAddress+' M: '+Addr^.IPMask+#13;
Addr := Addr^.Next;
End;
End;

Function TimeTToDateTimeStr(TimeT : Integer) : String;
Const UnixDateDelta = 25569; { days between 12/31/1899 and 1/1/1970 }
Var
DT : TDateTime;
TZ : TTimeZoneInformation;
Res : DWord;

Begin
If (TimeT = 0) Then Result := ''
Else Begin
{ Unix TIME_T is secs since 1/1/1970 }
DT := UnixDateDelta+(TimeT / (24*60*60)); { in UTC }
{ calculate bias }
Res := GetTimeZoneInformation(TZ);
If (Res = TIME_ZONE_ID_INVALID) Then RaiseLastWin32Error;
If (Res = TIME_ZONE_ID_STANDARD) Then Begin
DT := DT-((TZ.Bias+TZ.StandardBias) / (24*60));
Result := DateTimeToStr(DT)+' '+WideCharToString(TZ.StandardName);
End
Else Begin { daylight saving time }
DT := DT-((TZ.Bias+TZ.DaylightBias) / (24*60));
Result := DateTimeToStr(DT)+' '+WideCharToString(TZ.DaylightName);
End;
End;
End;

begin
Memo1.Lines.Clear;
Size := 5120;
GetMem(AI,Size);
Res := GetAdaptersInfo(AI,Size);
If (Res <> ERROR_SUCCESS) Then Begin
SetLastError(Res);
RaiseLastWin32Error;
End;
With Memo1,Lines do Begin
Work := AI;
I := 1;
Repeat
Add('');
Add('Adapter ' + IntToStr(I));
Add(' ComboIndex: '+IntToStr(Work^.ComboIndex));
Add(' Adapter name: '+Work^.AdapterName);
Add(' Description: '+Work^.Description);
Add(' Adapter address: '+MACToStr(@Work^.Address,Work^.AddressLength));
Add(' Index: '+IntToStr(Work^.Index));
Add(' Type: '+IntToStr(Work^._Type));
Add(' DHCP: '+IntToStr(Work^.DHCPEnabled));
Add(' Current IP: '+GetAddrString(Work^.CurrentIPAddress));
Add(' IP addresses: '+GetAddrString(@Work^.IPAddressList));
Add(' Gateways: '+GetAddrString(@Work^.GatewayList));
Add(' DHCP servers: '+GetAddrString(@Work^.DHCPServer));
Add(' Has WINS: '+IntToStr(Integer(Work^.HaveWINS)));
Add(' Primary WINS: '+GetAddrString(@Work^.PrimaryWINSServer));
Add(' Secondary WINS: '+GetAddrString(@Work^.SecondaryWINSServer));
Add(' Lease obtained: '+TimeTToDateTimeStr(Work^.LeaseObtained));
Add(' Lease expires: '+TimeTToDateTimeStr(Work^.LeaseExpires));
Inc(I);
Work := Work^.Next;
Until (Work = nil);
End;
FreeMem(AI);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
GetAdapterInformation;
end;

end.

方法2

uses nb30;

function NBGetAdapterAddress(a: Integer): string;
var
NCB: TNCB; // Netbios control block //NetBios控制块
ADAPTER: TADAPTERSTATUS; // Netbios adapter status//取网卡状态
LANAENUM: TLANAENUM; // Netbios lana
intIdx: Integer; // Temporary work value//临时变量
cRC: Char; // Netbios return code//NetBios返回值
strTemp: string; // Temporary string//临时变量
begin
Result := '';

try
ZeroMemory(@NCB, SizeOf(NCB)); // Zero control blocl

NCB.ncb_command := Chr(NCBENUM); // Issue enum command
cRC := NetBios(@NCB);

NCB.ncb_buffer := @LANAENUM; // Reissue enum command
NCB.ncb_length := SizeOf(LANAENUM);
cRC := NetBios(@NCB);
if Ord(cRC) <> 0 then
exit;

ZeroMemory(@NCB, SizeOf(NCB)); // Reset adapter
NCB.ncb_command := Chr(NCBRESET);
NCB.ncb_lana_num := LANAENUM.lana[a];
cRC := NetBios(@NCB);
if Ord(cRC) <> 0 then
exit;


ZeroMemory(@NCB, SizeOf(NCB)); // Get adapter address
NCB.ncb_command := Chr(NCBASTAT);
NCB.ncb_lana_num := LANAENUM.lana[a];
StrPCopy(NCB.ncb_callname, '*');
NCB.ncb_buffer := @ADAPTER;
NCB.ncb_length := SizeOf(ADAPTER);
cRC := NetBios(@NCB);

strTemp := ''; // Convert it to string
for intIdx := 0 to 5 do
strTemp := strTemp + InttoHex(Integer(ADAPTER.adapter_address[intIdx]), 2);
Result := strTemp;
finally
end;
end;  

在Linux系统的ARM架构设备上获MAC地址,可以通过以下几种方法实现: 1. **通过`/sys/class/net/`目录获MAC地址** Linux系统会在`/sys/class/net/`目录下为每个网络接口创建一个子目录,例如`eth0`、`wlan0`等。每个子目录中包含一个名为`address`的文件,其中存储了该接口的MAC地址。可以使用`cat`命令查看该文件的内容,例如: ```bash cat /sys/class/net/eth0/address ``` 这将输出类似`00:1a:2b:3c:4d:5e`的MAC地址。 2. **使用`ip`命令获MAC地址** `ip`命令是Linux中用于管理网络接口的工具之一,可以通过以下命令获指定网络接口的MAC地址: ```bash ip link show eth0 ``` 在输出的信息中,`link/ether`后面的部分即为MAC地址,例如: ``` 2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:1a:2b:3c:4d:5e brd ff:ff:ff:ff:ff:ff ``` 3. **使用`ifconfig`命令获MAC地址** 尽管`ifconfig`命令在某些Linux发行版中已被`ip`命令代,但它仍然广泛可用。可以通过以下命令获MAC地址: ```bash ifconfig eth0 ``` 在输出的信息中,`HWaddr`后面的部分即为MAC地址,例如: ``` eth0 Link encap:Ethernet HWaddr 00:1a:2b:3c:4d:5e inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:123456 errors:0 dropped:0 overruns:0 frame:0 TX packets:123456 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:123456789 (117.7 MiB) TX bytes:123456789 (117.7 MiB) ``` 4. **通过编程方式获MAC地址** 如果需要在程序中获MAC地址,可以使用C语言调用`ioctl`函数来实现。以下是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <net/if.h> #include <unistd.h> #include <linux/sockios.h> int main() { struct ifreq ifr; int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket"); exit(EXIT_FAILURE); } strcpy(ifr.ifr_name, "eth0"); if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl"); close(sockfd); exit(EXIT_FAILURE); } unsigned char *mac = (unsigned char *)ifr.ifr_hwaddr.sa_data; printf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); close(sockfd); return 0; } ``` 编译并运行该程序后,将输出指定网络接口的MAC地址。 5. **通过`dmesg`日志获MAC地址** 在系统启动过程中,内核会记录网络接口的初始化信息,其中包括MAC地址。可以通过以下命令查看相关日志: ```bash dmesg | grep eth0 ``` 在输出的信息中,可能会包含类似`eth0: MAC: 00:1a:2b:3c:4d:5e`的内容。 以上方法均适用于ARM架构的Linux设备,可以根据具体需求选择合适的方式获MAC地址
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值