delphi networking snmp indy

Delphi: Obtenga MAC de enrutador



networking snmp (2)

Estoy usando Delphi y quiero determinar la dirección MAC física de un dispositivo de red en mi red, en este caso, el enrutador.

Mi código:

var idsnmp: tidsnmp; val:string; begin idsnmp := tidsnmp.create; try idsnmp.QuickSend(''.1.3.6.1.2.1.4.22.1.2'', ''public'', ''10.0.0.1'', val); showmessage(val); finally idsnmp.free; end; end;

donde 10.0.0.1 es mi enrutador

Por desgracia, QuickSend siempre envía "Restablecimiento de la conexión por el compañero # 10054". Traté de modificar el MIB-OID y también probé el IP 127.0.0.1 cuya conexión nunca debería fallar. No encontré Tutoriales utilizables sobre TIdSNMP en Google. :-(

Saludos Daniel Marschall


No queriendo robar el trueno de RRUZ, ofrezco la siguiente variante, tomada de mi base de código, con algunas observaciones. He hecho esto como una respuesta en lugar de un comentario para incluir el código.

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;

Hay un par de puntos para hacer.

No es necesario llamar a WSAStartup / WSACleanup.

EDITAR Como señala RRUZ en un comentario, la documentación winsock no exime explícitamente a inet_addr de WSAStartup / WSACleanup, así que me retracto de este punto. En Vista, es más simple simplemente llamar a RtlIpv4StringToAddress. Habiendo dicho todo eso, inet_addr es tan fácil de implementar que puede ser más fácil hacer el suyo.

En segundo lugar, la declaración de inet_addr en WinSock.pas es incorrecta. Declara que el valor de retorno es de un tipo u_long que se define en WinSock.pas como Entero largo. Este es un entero de 4 bytes con signo, pero debe ser un entero de 4 bytes sin signo, ULONG. Sin el reparto explícito, puedes obtener errores de rango.


Puede usar la función SendARP para obtener la dirección Mac.

verifica esta muestra

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;