線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4471
推到 Plurk!
推到 Facebook!

取得系統中網卡MAC位址的三種方法

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-07-25 12:29:08 IP:61.64.xxx.xxx 未訂閱
取得系統中網卡MAC位址的三種方法 http://www.legalsoft.com.cn/Articles/ArticleBrowse.asp?idArticle=357 做好的程式師一如做人。多看多想或許他山之石可以攻玉,但永遠不要成為代碼的奴隸。 CKER  原著:Borland  Translated by CKER     第一種方法使用Microsoft的Netbios API。 這是一套通過Winsock提供底層網路支援的命令。使用Netbios的最大缺點是您必須在系統中安裝了Netbios服務(如果您在windows網路中啟用了檔共用的話,這就不是問題了)。除此此外,這種方法又快又準確。     Netbios API只包括了一個函數,就叫做Netbios。這個函數使用網路控制塊(network control block)結構作為參數,這個結構告訴函數要做什麼。結構的定義如下:  typedef struct _NCB {  UCHAR ncb_command;  UCHAR ncb_retcode;  UCHAR ncb_lsn;  UCHAR ncb_num;  PUCHAR ncb_buffer;  WORD ncb_length;  UCHAR ncb_callname[NCBNAMSZ];  UCHAR ncb_name[NCBNAMSZ];  UCHAR ncb_rto;  UCHAR ncb_sto;  void (CALLBACK *ncb_post) (struct _NCB *);  UCHAR ncb_lana_num;  UCHAR ncb_cmd_cplt;  #ifdef _WIN64  UCHAR ncb_reserve[18];  #else  UCHAR ncb_reserve[10];  #endif  HANDLE ncb_event;  } NCB, *PNCB;         重點在於ncb_command 成員。這個成員告訴Netbios該作什麼。我們使用三個命令來探測MAC位址。他們在MSDN的定義如下:  命令描述:  NCBENUM Windows NT/2000: 列舉系統中網卡的數量。使用此命令後,ncb_buffer成員指向由LANA_ENUM結構填充的緩衝區。  NCBENUM 不是標準的 NetBIOS 3.0 命令。     NCBRESET 重置網卡。網卡在接受新的NCB命令之前必須重置。  NCBASTAT 接受本地或遠端介面卡的狀態。使用此命令後,ncb_buffer成員指向由ADAPTER_STATUS結構填充的緩衝區,隨後是NAME_BUFFER結構的陣列。     下面就是取得您系統MAC位址的步驟:  1》列舉所有的介面卡。  2》重置每塊卡以取得它的正確資訊。  3》查詢介面卡,取得MAC位址並生成標準的冒號分隔格式。     下面就是實例根源程式。  netbios.cpp     #include  #include #include #include #include using namespace std; #define bzero(thing,sz) memset(thing,0,sz) bool GetAdapterInfo(int adapter_num, string &mac_addr) { // 重置網卡,以便我們可以查詢 NCB Ncb; memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBRESET; Ncb.ncb_lana_num = adapter_num; if (Netbios(&Ncb) != NRC_GOODRET) { mac_addr = "bad (NCBRESET): "; mac_addr = string(Ncb.ncb_retcode); return false; } // 準備取得介面卡的狀態塊 bzero(&Ncb,sizeof(Ncb); Ncb.ncb_command = NCBASTAT; Ncb.ncb_lana_num = adapter_num; strcpy((char *) Ncb.ncb_callname, "*"); struct ASTAT { ADAPTER_STATUS adapt; NAME_BUFFER NameBuff[30]; } Adapter; bzero(&Adapter,sizeof(Adapter)); Ncb.ncb_buffer = (unsigned char *)&Adapter; Ncb.ncb_length = sizeof(Adapter); // 取得網卡的資訊,並且如果網卡正常工作的話,返回標準的冒號分隔格式。 if (Netbios(&Ncb) == 0) { char acMAC[18]; sprintf(acMAC, "X:X:X:X:X:X", int (Adapter.adapt.adapter_address[0]), int (Adapter.adapt.adapter_address[1]), int (Adapter.adapt.adapter_address[2]), int (Adapter.adapt.adapter_address[3]), int (Adapter.adapt.adapter_address[4]), int (Adapter.adapt.adapter_address[5])); mac_addr = acMAC; return true; } else { mac_addr = "bad (NCBASTAT): "; mac_addr = string(Ncb.ncb_retcode); return false; } } int main() { // 取得網卡列表 LANA_ENUM AdapterList; NCB Ncb; memset(&Ncb, 0, sizeof(NCB)); Ncb.ncb_command = NCBENUM; Ncb.ncb_buffer = (unsigned char *)&AdapterList; Ncb.ncb_length = sizeof(AdapterList); Netbios(&Ncb); // 取得本地乙太網卡的位址 string mac_addr; for (int i = 0; i < AdapterList.length - 1; i) { if (GetAdapterInfo(AdapterList.lana[i], mac_addr)) { cout << "Adapter " << int (AdapterList.lana[i]) << "“s MAC is " << mac_addr << endl; } else { cerr << "Failed to get MAC address! Do you" << endl; cerr << "have the NetBIOS protocol installed?" << endl; break; } } return 0; } file://--------------------------------------------------------------------------- 第二種方法-使用COM GUID API 這種方法使用COM API創建一個GUID(全局唯一識別字)並從那裏繼承MAC地址。GUID通常用來標識COM元件以及系統中的其他物件。它們是由MAC位址(結合其他東西)計算得來的,表面上MAC位址就包含在其中。我說表面上是因為事實上並沒有包含。 我提供這種方法更多的是為了作為反面教材。您也許用這種方法能夠得到MAC位址,但有時候您只會得到隨機的十六進位數值。 下面的例子十分簡單,無需多講。我們使用CoCreateGuid創建GUID,並將最後六個位元組放入字串中。它們可能是MAC地址,但並不是必然的。 uuid.cpp #include #include #include using namespace std; int main() { cout << "MAC address is: "; // 向COM要求一個UUID。如果機器中有乙太網卡, // UUID最後的六個位元組(Data4的2-7位元組)應該是本地乙太網卡的MAC位址。 GUID uuid; CoCreateGuid(&uuid); // Spit the address out char mac_addr[18]; sprintf(mac_addr,"X:X:X:X:X:X", uuid.Data4[2],uuid.Data4[3],uuid.Data4[4], uuid.Data4[5],uuid.Data4[6],uuid.Data4[7]); cout << mac_addr << endl; getch(); return 0; } 第三種方法- 使用SNMP擴展API 我要討論的第三種方法是使用Windows的SNMP(簡單網路管理協定)擴展來取得MAC位址。在我的經驗裏,這個協議很簡單。代碼也是直勾勾的向前的。基本步驟和Netbios相同: 1》取得網卡列表 2》查詢每塊卡的類型和MAC地址 3》保存當前網卡 我個人對SNMP瞭解不多,但如我剛剛所言,代碼十分清楚。 snmp.cpp #include #include #include typedef bool(WINAPI * pSnmpExtensionInit) ( IN DWORD dwTimeZeroReference, OUT HANDLE * hPollForTrapEvent, OUT AsnObjectIdentifier * supportedView); typedef bool(WINAPI * pSnmpExtensionTrap) ( OUT AsnObjectIdentifier * enterprise, OUT AsnInteger * genericTrap, OUT AsnInteger * specificTrap, OUT AsnTimeticks * timeStamp, OUT RFC1157VarBindList * variableBindings); typedef bool(WINAPI * pSnmpExtensionQuery) ( IN BYTE requestType, IN OUT RFC1157VarBindList * variableBindings, OUT AsnInteger * errorStatus, OUT AsnInteger * errorIndex); typedef bool(WINAPI * pSnmpExtensionInitEx) ( OUT AsnObjectIdentifier * supportedView); void main() { HINSTANCE m_hInst; pSnmpExtensionInit m_Init; pSnmpExtensionInitEx m_InitEx; pSnmpExtensionQuery m_Query; pSnmpExtensionTrap m_Trap; HANDLE PollForTrapEvent; AsnObjectIdentifier SupportedView; UINT OID_ifEntryType[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 3}; UINT OID_ifEntryNum[] = {1, 3, 6, 1, 2, 1, 2, 1}; UINT OID_ipMACEntAddr[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 6}; AsnObjectIdentifier MIB_ifMACEntAddr = { sizeof(OID_ipMACEntAddr) sizeof(UINT), OID_ipMACEntAddr }; AsnObjectIdentifier MIB_ifEntryType = {sizeof(OID_ifEntryType) sizeof(UINT), OID_ifEntryType}; AsnObjectIdentifier MIB_ifEntryNum = {sizeof(OID_ifEntryNum) sizeof(UINT), OID_ifEntryNum}; RFC1157VarBindList varBindList; RFC1157VarBind varBind[2]; AsnInteger errorStatus; AsnInteger errorIndex; AsnObjectIdentifier MIB_NULL = {0, 0}; int ret; int dtmp; int i = 0, j = 0; bool found = false; char TempEthernet[13]; m_Init = NULL; m_InitEx = NULL; m_Query = NULL; m_Trap = NULL; /* 載入SNMP DLL並取得實例控制碼 */ m_hInst = LoadLibrary("inetmib1.dll"); if (m_hInst < (HINSTANCE) HINSTANCE_ERROR) { m_hInst = NULL; return; } m_Init = (pSnmpExtensionInit) GetProcAddress(m_hInst, "SnmpExtensionInit"); m_InitEx = (pSnmpExtensionInitEx) GetProcAddress(m_hInst, "SnmpExtensionInitEx"); m_Query = (pSnmpExtensionQuery) GetProcAddress(m_hInst, "SnmpExtensionQuery"); m_Trap = (pSnmpExtensionTrap) GetProcAddress(m_hInst, "SnmpExtensionTrap"); m_Init(GetTickCount(), &PollForTrapEvent, &SupportedView); /* 初始化用來接收m_Query查詢結果的變數列表 */ varBindList.list = varBind; varBind[0].name = MIB_NULL; varBind[1].name = MIB_NULL; /* 在OID中拷貝並查找介面表中的入口數量 */ varBindList.len = 1; /* Only retrieving one item */ SNMP_oidcpy(&varBind[0].name, &MIB_ifEntryNum); ret = m_Query(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &errorStatus, &errorIndex); printf("# of adapters in this system : %in", varBind[0].value.asnValue.number); varBindList.len = 2; /* 拷貝OID的ifType-介面類型 */ SNMP_oidcpy(&varBind[0].name, &MIB_ifEntryType); /* 拷貝OID的ifPhysAddress-物理位元址 */ SNMP_oidcpy(&varBind[1].name, &MIB_ifMACEntAddr); do { /* 提交查詢,結果將載入 varBindList。 可以預料這個迴圈調用的次數和系統中的介面卡數量相等 */ ret = m_Query(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &errorStatus, &errorIndex); if (!ret) ret = 1; else /* 確認正確的返回類型 */ ret = SNMP_oidncmp(&varBind[0].name, &MIB_ifEntryType, MIB_ifEntryType.idLength); if (!ret) { j ; dtmp = varBind[0].value.asnValue.number; printf("Interface #%i type : %in", j, dtmp); /* Type 6 describes ethernet interfaces */ if (dtmp == 6) { /* 確認我們已經在此取得地址 */ ret = SNMP_oidncmp(&varBind[1].name, &MIB_ifMACEntAddr, MIB_ifMACEntAddr.idLength); if ((!ret) && (varBind[1].value.asnValue.address.stream != NULL)) { if((varBind[1].value.asnValue.address.stream[0] == 0x44) && (varBind[1].value.asnValue.address.stream[1] == 0x45) && (varBind[1].value.asnValue.address.stream[2] == 0x53) && (varBind[1].value.asnValue.address.stream[3] == 0x54) && (varBind[1].value.asnValue.address.stream[4] == 0x00)) { /* 忽略所有的撥號網路介面卡 */ printf("Interface #%i is a DUN adaptern", j); continue; } if ((varBind[1].value.asnValue.address.stream[0] == 0x00) && (varBind[1].value.asnValue.address.stream[1] == 0x00) && (varBind[1].value.asnValue.address.stream[2] == 0x00) && (varBind[1].value.asnValue.address.stream[3] == 0x00) && (varBind[1].value.asnValue.address.stream[4] == 0x00) && (varBind[1].value.asnValue.address.stream[5] == 0x00)) { /* 忽略由其他的網路介面卡返回的NULL位址 */ printf("Interface #%i is a NULL addressn", j); continue; } sprintf(TempEthernet, "xxxxxx", varBind[1].value.asnValue.address.stream[0], varBind[1].value.asnValue.address.stream[1], varBind[1].value.asnValue.address.stream[2], varBind[1].value.asnValue.address.stream[3], varBind[1].value.asnValue.address.stream[4], varBind[1].value.asnValue.address.stream[5]); printf("MAC Address of interface #%i: %sn", j, TempEthernet);} } } } while (!ret); /* 發生錯誤終止。 */ getch(); FreeLibrary(m_hInst); /* 解除綁定 */ SNMP_FreeVarBind(&varBind[0]); SNMP_FreeVarBind(&varBind[1]); } 發表人 - conundrum 於 2004/07/25 12:44:14
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-07-27 13:23:13 IP:220.139.xxx.xxx 未訂閱
請 conundrum 大大在貼 BCB 原始碼時,記得使用    [ code ]  原始碼 [ /code ]    的方式來貼,否則 include 的東西都不見了...    謝謝您轉貼的資料  < href="http://www.ViewMove.com" target="blank">視動科技 VMASK - ViewMove Automation Software Kernel 發表人 - dllee 於 2004/07/27 13:24:17
------
http://www.ViewMove.com
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-07-27 14:36:03 IP:61.221.xxx.xxx 未訂閱
報告d sir不是我不用 是原來源即無縮排阿 (哈哈 > 我又是很懶的人 所以只有期待 更熱心人士 接棒 哈哈 否則
lovejingtao
一般會員


發表:10
回覆:33
積分:13
註冊:2003-04-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-07-29 01:15:19 IP:220.173.xxx.xxx 未訂閱
嗯.我补上一个方法,是利用ARP数据包. ===================================================================== unit Unit_GetMacByIp; interface uses Windows, SysUtils,winsock; function My_GetMacByIp(const ipaddress: WideString):String; implementation type ipaddr = longint; pulong = ^u_long; function SendARP(DestIP: ipaddr; SrcIP: ipaddr; pMacAddr: pulong; PhyAddrLen:pulong): DWORD; stdcall; external 'IPHLPAPI.DLL'; procedure GetMacByIp(const ipaddress: WideString; var macaddress: OleVariant); var destip: integer; pmacaddr: pulong; addrlen: u_long; macaddr: array[1..6] of byte; p: pbyte; s: string; i: integer; ipstr: string; begin IPstr := IPaddress; DestIP := inet_addr(pchar(IPstr)); //目标机器的IP地址 pMacAddr := pulong(@MacAddr); AddrLen := sizeof(MacAddr); if SendARP(DestIP, 0, pMacAddr, @AddrLen) = 0 then begin s := ''; p := pbyte(pMacAddr); if ((p <> nil) and (AddrLen > 0)) then begin for i := 1 to AddrLen do begin s := s IntToHex(p^, 2) '.'; p := Pointer(Integer(p) SizeOf(Byte)); end; SetLength(s, Length(s) - 1); end; end; macaddress := s; end; function My_GetMacByIp(const ipaddress: WideString):String; var S:OleVariant; begin GetMacByIp(ipaddress,s); Result:=s; end; end. ===================================================================== 不过ARP方式好像无法垮网段.所以,还可以利用UDP发送数据包.一些扫描网络MAC地址的软件就是用UDP协议的.下面这个忘记谁写的了. { 设置IP后调用GetMac方法,取结果代码放在OnReceive事件里。 } unit GetMac; interface uses Windows, Messages, SysUtils,Forms, Classes, WinSock, Dialogs; const WM_SOCK = WM_USER $0001; //自定义windows消息 UDPPort = 6767; //设定本端UDP端口号 NBTPort = 137; //设定对端UDP端口号 var MyByte: array [0..3]of byte; WAIT_ACK_EVENT: Thandle; MySock: TSocket; MyAddr: TSockAddr; FSockAddrIn : TSockAddrIn; type TGetMac = class(TComponent) private { Private declarations } FIP:string; //输入的欲取得MAC地址的机子的IP地址 FWorkGroup:string; //返回的工作组名称 FHostName:string; //返回的主机名 FUserName:string; //返回的用户名 FMacAddress:string; //返回的网卡Mac地址 FHandle: HWnd; //非可视构件消息处理使用 FOnReceive: TNotifyEvent;//接收到返回结果触发的事件 Binded: Boolean; //对输入的IP地址进行合法性检查并赋给FIP变量 procedure SetFIP(Value: string); //判断IP地址是否合法 Function IsLegalIP(IP:string):Boolean; //将IP地址分成四部份 procedure GetAddrByte(IP:string;var B:array of byte); protected { Protected declarations } procedure ReceiveReturn; dynamic; //利用消息实时获知UDP消息 procedure ReadData(var Msg: TMessage);//message WM_SOCK; //分析返回的消息内容 procedure RecvNbMsg(buffer: Array of byte;len:integer;IP:string); public { Public declarations } procedure GetMac; //先对IP属性赋值后调用此方法取得相关资料 constructor Create(AOwner: TComponent); override; destructor Destroy; override; published { Published declarations } property IP: string read FIP write SetFIP; property WorkGroup: string read FWorkGroup;// write FWorkGroup; property UserName: string read FUserName;// write FUserName; property HostName: string read FHostName;// write FHostName; property MacAddress: string read FMacAddress;// write FMacAddress; property OnReceive: TNotifyEvent read FOnReceive write FOnReceive; end; procedure Register; implementation //接收到返回的数据后内部处理完毕执行用户定义的代码 procedure TGetMac.ReceiveReturn; begin if Assigned(FOnReceive) then FOnReceive(Self); end; //检测输入的IP地址是否合法并赋值给FIP变量 procedure TGetMac.SetFIP(Value: string); begin if (not IsLegalIP(Value)) then begin ShowMessage('非法IP地址!'); FIP:='127.0.0.1'; exit; end else begin GetAddrByte(Value,MyByte); FIP:=format('%d.%d.%d.%d',[MyByte[0],MyByte[1],MyByte[2],MyByte[3]]); end; end; //判断IP地址是否合法 Function TGetMac.IsLegalIP(IP:string):Boolean; begin if inet_addr(pchar(IP))=INADDR_NONE then begin Result:=False; exit; end else result:=true; end; //将IP地址分成四部份 procedure TGetMac.GetAddrByte(IP:string;var B:array of byte); var i,j:integer; sTemp:string; begin sTemp:=''; j:=0; IP:=IP '.'; for i:=1 to length(IP)do begin if IP[i]<>'.' then sTemp:=sTemp IP[i] else begin B[j]:=byte(strtoint(sTemp)); inc(j); sTemp:=''; end; end; end; //开始取网卡地址 procedure TGetMac.GetMac; //欲发送的数据包内容 const NbtstatPacket:array[0..49]of byte =($0,$0,$0,$0,$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); var len: integer; TempWSAData: TWSAData; begin if not Binded then begin // 初始化SOCKET,0成功,使用WinSock1.1版本$0001是1.0版本$0002是2.0版本 if WSAStartup($0101, TempWSAData)<>ERROR_SUCCESS then ShowMessage('启动错误'); MySock := Socket(AF_INET, SOCK_DGRAM, 0); if (MySock = INVALID_SOCKET) then //Socket创建失败 begin ShowMessage(inttostr(WSAGetLastError()) ' Socket创建失败!'); CloseSocket(MySock); end; //本机SockAddr绑定 MyAddr.sin_family := AF_INET; MyAddr.sin_addr.S_addr := INADDR_ANY; MyAddr.sin_port := htons(UDPPORT); if Bind(MySock, MyAddr, sizeof(MyAddr)) <> 0 then begin ShowMessage('绑定错误!'); Binded:=False; end else Binded:=True; WSAAsyncSelect(MySock, FHandle, WM_SOCK, FD_READ); WAIT_ACK_EVENT:=CreateEvent(nil,true,false,pchar('WAIT_ACK')); //ResetEvent(WAIT_ACK_EVENT);} end; //向对方主机UDP指定的端口发送数据包 FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(FIP)); FSockAddrIn.SIn_Family := AF_INET; FSockAddrIn.SIn_Port := htons(NBTPORT); len := SendTo(MySock, NbtstatPacket[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn)); //if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then showmessage(inttostr(WSAGetLastError())); if len = SOCKET_ERROR then ShowMessage('SOCKET_ERROR,发送失败!'); if len <> 50 then ShowMessage('数据没有全部发送!'); // WaitForSingleObject(WAIT_ACK_EVENT,WaitTime); ResetEvent(WAIT_ACK_EVENT); end; //接收返回的消息数据 procedure TGetMac.ReadData(var Msg:TMessage); var buffer: Array [1..500] of byte; flen,len: integer; Event: word; IP:string; begin if Msg.msg<>WM_SOCK then exit; flen:=sizeof(FSockAddrIn); FSockAddrIn.SIn_Family := AF_INET; FSockAddrIn.SIn_Port := htons(NBTPORT); Event := WSAGetSelectEvent(Msg.LParam); if Event = FD_READ then begin len := recvfrom(MySock, buffer, sizeof(buffer), 0, FSockAddrIn, flen); if len> 0 then begin //FSockAddrIn.sin_addr.S_un_b.s_b1 with FSockAddrIn.sin_addr.S_un_b do IP:=format('%d.%d.%d.%d',[ord(s_b1),ord(s_b2),ord(s_b3),ord(s_b4)]); RecvNbMsg(buffer,len,IP); end; SetEvent(WAIT_ACK_EVENT); end; //触发事件,执行用户指定的代码 ReceiveReturn; end; //分析返回的消息 procedure TGetMac.RecvNbMsg(buffer: Array of byte;len:integer;IP:string); var TempStr:string; i,j,pos,name_num: integer; begin name_num:=0; for i:=1 to len do begin if((buffer[i]=$21)and(buffer[i 1]=$00)and(buffer[i 2]=$01)) then begin name_num:=buffer[i 9]; break; end; end; if name_num=0 then exit; pos:=i 10; TempStr:=''; for i:=pos to (pos 18*name_num-1) do begin if (((i-pos)mod 18) =0) then begin for j:=0 to 14 do begin if trim(char(buffer[i j]))='' then buffer[i j]:=ord(' '); TempStr:=TempStr char(buffer[i j]); end; if (buffer[i 16] and $80)=$80 then begin if buffer[i 15]=$0 then FWorkGroup:=TempStr; end else begin if buffer[i 15]=$20 then FHostName:=TempStr else if buffer[i 15]=$3 then FUserName:=TempStr; end; TempStr:=''; end; end; //取得网卡地址 for i:=0 to 5 do begin TempStr:=TempStr format('%.2x.',[buffer[i pos 18*name_num]]); end; delete(TempStr,length(TempStr),1); FMacAddress:=TempStr; end; //构件创建 constructor TGetMac.Create; begin inherited Create(AOwner); FHandle := AllocateHWnd(ReadData); //初始化属性值 FIP:='127.0.0.1'; FUserName:=''; FHostName:=''; FWorkGroup:=''; FMacAddress:=''; Binded:=False; end; //构件消毁 destructor TGetMac.Destroy; begin CloseSocket(MySock); WSACleanup(); DeallocateHWnd(FHandle); inherited Destroy; end; //登记控件 procedure Register; begin RegisterComponents('FastNet', [TGetMac]); end; end. ===================================================================== 当然,ARP数据包用处也是很大的.例如,在局部网内,你可以利用ARP包欺骗其它电脑,让它无法上网.或者SNIFF----------对于交换机来说,传统的SNIFF已经不起作用了,而利用ARP欺骗达到SNIFF的目的是比较高效的.当然前提是你绑定的BUF要正确. 冷静的思考问题 充满激情的工作
tokezmax
一般會員


發表:1
回覆:2
積分:0
註冊:2004-09-22

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-10-20 15:03:26 IP:203.67.xxx.xxx 未訂閱
小弟試了很久,只有第二隻程式沒問題。 我去過原本的網站看一下。code 都沒改過,只有註解有改。 不知道各位大大都成功的把這1、3程式RUN起來了嗎?    第1隻程式, 是不是少 include 一些檔案?例如:nb30.h 然後在下列程式碼有誤:     // 準備取得介面卡的狀態塊      bzero(&Ncb,sizeof(Ncb);    //←少了一個括號 東改改西改改,改到最後還是過不了。    第2隻程式 就如他所序敘的,得到的mac 不盡然是正確的    第3隻程式 一執行就出現error
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-10-26 12:06:18 IP:203.69.xxx.xxx 未訂閱
哈。當初要找到MAC時。花了很多時間。 這一篇我也看過。也做過。有些根本不能用。(在WINXP/2000) 還有一個問題是。這三個方法,在當時,我測試時。好像只有在”已連線”時才能取得。 如果未連線時就無法取得MAC。 ^_^
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-10-27 00:08:45 IP:220.143.xxx.xxx 未訂閱
ipconfig /all >c:\123.txt
系統時間:2024-05-19 4:29:58
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!