ASP获取远程MAC地址

ASP获取远程MAC地址

http://blog.csdn.net/apoet/archive/2008/05/02/2360360.aspx

 

Today is Mon.
这周的任务是教会公司的老领导们使用内部论坛
为了免去很多无谓的麻烦我决定以MAC地址自动登陆的方式进行身份验证
关键问题出来了:如何获取浏览者的MAC地址?
以服务器现有的组件来看根本无法完成整个任务,还好MS提供了一套扩展ASP组件功能的接口:ActiveX DLL。
以前做过这方面的尝试所以头脑中还有些映像主要是合成和改善了网上的两篇文章
1、将ASP变成ActiveX DLL
引用地址:http://www.cnblogs.com/cnliou/articles/201059.html
介绍了AxtiveX DLL的编程和使用
其中有个小错误
在组件的创建动作中:
Public Sub OnStartPage(mysc as scriptingContent)
参数mysc的数据类型应该是scriptingContext二并非scriptingContent

2、vb获得本地和远程的MAC地址 (网卡地址)
引用地址:http://blog.csdn.net/hot1kang1/archive/2006/03/27/639713.aspx
他所提供的方法是在VB的exe应用程序里实现的
应用到ActiveX DLL里的话还要作一些小的变动
将这篇文章中的代码作为模块、将上篇文章里所使用的cls作为类
这样就出现了一个新问题:在类中无法访问GetRemoteMACAddress函数。
这是因为在模块中GetRemoteMACAddress函数被定义为Private,修改成Public
这样还不够因为地址中的某段如果长度为一的话那就不会自动补零
我们需要这样一段代码:If Len(CStr(bpMacAddr(cnt))) = 1 Then tmp = tmp & "0"


我修改后的代码如下:
模块文件
Module1.bas
------------------------------------------------------------------------
Option Explicit

Private Declare Function gethostname _
               Lib "wsock32.dll" (ByVal szHost As String, _
                                  ByVal dwHostLen As Long) As Long
Private Declare Function gethostbyname _
               Lib "wsock32.dll" (ByVal szHost As String) As Long
Private Declare Function WSAStartup _
               Lib "wsock32.dll" (ByVal wVersionRequired As Long, _
                                  lpWSADATA As WSADATA) As Long
Private Declare Function WSAGetLastError _
               Lib "wsock32.dll" () As Long
Private Declare Function WSACleanup _
               Lib "wsock32.dll" () As Long
              
Private Declare Sub CopyMemory _
               Lib "kernel32" _
               Alias "RtlMoveMemory" (hpvDest As Any, _
                                      ByVal hpvSource As Long, _
                                      ByVal cbCopy As Long)

'  Socket错误常数和版本常数
Private Const SOCKET_ERROR As Long = -1
Private Const MAX_WSADescription = 256
Private Const MAX_WSASYSStatus = 128
Private Const ERROR_SUCCESS As Long = 0
Private Const WS_VERSION_REQD As Long = &H101
Private Const MIN_SOCKETS_REQD As Long = 1
Private Const WS_VERSION_MAJOR As Long = WS_VERSION_REQD / &H100 And &HFF&
Private Const WS_VERSION_MINOR As Long = WS_VERSION_REQD And &HFF&
'  存放主机信息的结构
Private Type HOSTENT
    hName As Long    '  主机的正式名称
    hAliases As Long  '  主机别名列表
    hAddrType As Integer    '  主机地址类型
    hLen As Integer    '  主机地址长度
    hAddrList As Long   '  主机IP地址列表
End Type
'  存放Winsock版本等信息的结构
Private Type WSADATA
    wVersion As Integer
    wHighVersion As Integer
    szDescription(0 To MAX_WSADescription) As Byte
    szSystemStatus(0 To MAX_WSASYSStatus) As Byte
    wMaxSockets As Integer
    wMaxUDPDG As Integer
    dwVendorInfo As Long
End Type
'---------------------------------
'MAC使用的API
Private Const NO_ERROR = 0
Private Declare Function inet_addr _
                Lib "wsock32.dll" (ByVal s As String) As Long
Private Declare Function SendARP _
                Lib "iphlpapi.dll" (ByVal DestIP As Long, _
                                    ByVal SrcIP As Long, _
                                    pMacAddr As Long, _
                                    PhyAddrLen As Long) As Long
Private Declare Sub CopyMemory1 _
                Lib "kernel32" _
                Alias "RtlMoveMemory" (dst As Any, _
                                       src As Any, _
                                       ByVal bcount As Long)
'---------------------------------
Public Function GetMyMAC() As String
    Dim sMyIP$, sMyMAC$
    sMyIP$ = GetIPAddress
    If sMyIP = "" Then Exit Function
    GetRemoteMACAddress sMyIP$, sMyMAC$
    GetMyMAC = sMyMAC$
End Function
Public Function GetRemoteMACAddress(ByVal sRemoteIP As String, _
                                     sRemoteMacAddress As String) As Boolean
    Dim dwRemoteIP   As Long
    Dim pMacAddr   As Long
    Dim bpMacAddr()   As Byte
    Dim PhyAddrLen   As Long
    Dim cnt   As Long
    Dim tmp   As String
    'convert  the  string  IP  into
    'an  unsigned  long  value  containing
    'a  suitable  binary  representation
    'of  the  Internet  address  given
    dwRemoteIP = inet_addr(sRemoteIP)
    If dwRemoteIP <> 0 Then
        'set  PhyAddrLen  to  6
        PhyAddrLen = 6
        'retrieve  the  remote  MAC  address
        If SendARP(dwRemoteIP, 0&, pMacAddr, PhyAddrLen) = NO_ERROR Then
            If pMacAddr <> 0 And PhyAddrLen <> 0 Then
                'returned  value  is  a  long  pointer
                'to  the  mac  address,  so  copy  data
                'to  a  byte  array
                ReDim bpMacAddr(0 To PhyAddrLen - 1)
                CopyMemory1 bpMacAddr(0), pMacAddr, ByVal PhyAddrLen
                'loop  through  array  to  build  string
                For cnt = 0 To PhyAddrLen - 1
                    If bpMacAddr(cnt) = 0 Then
                        tmp = tmp & "00-"
                    Else
            If Len(CStr(bpMacAddr(cnt))) = 1 Then tmp = tmp & "0"
                        tmp = tmp & Hex$(bpMacAddr(cnt)) & "-"
                    End If
                Next
                'remove  the  trailing  dash
                'added  above  and  return  True
                If Len(tmp) > 0 Then
                    sRemoteMacAddress = Left$(tmp, Len(tmp) - 1)
                    GetRemoteMACAddress = True
                End If
                Exit Function
            Else
                GetRemoteMACAddress = False
            End If
        Else
            GetRemoteMACAddress = False
        End If     'SendARP
    Else
        GetRemoteMACAddress = False
    End If     'dwRemoteIP
End Function
'------------------------------
'  返回给定机器名的Ip地址,机器名为空时返回本机Ip地址
Public Function GetIPAddress(Optional sHost As String) As String
    Dim sHostName As String * 256
    Dim lpHost As Long
    Dim HOST As HOSTENT
    Dim dwIPAddr As Long
    Dim tmpIPAddr() As Byte
    Dim i As Integer
    Dim sIPAddr As String
    Dim werr As Long
    '  如果无法初始化Socket则退出函数
    If Not SocketsInitialize() Then
        GetIPAddress = ""
        Exit Function
    End If
    '  如果未指定主机名称,则取得本地主机名称并获取其IP
    If sHost = "" Then
        If gethostname(sHostName, 256) = SOCKET_ERROR Then
            werr = WSAGetLastError()
            GetIPAddress = ""
            SocketsCleanup
            Exit Function
        End If
        sHostName = Trim$(sHostName)
    Else
        sHostName = Trim$(sHost) & Chr$(0)
    End If
    '  获得指向主机信息结构的指针
    lpHost = gethostbyname(sHostName)
    '  如果指针为零,则错误退出
    If lpHost = 0 Then
        werr = WSAGetLastError()
        GetIPAddress = ""
        SocketsCleanup
        Exit Function
    End If
    '  从指定内存取得数据
    CopyMemory HOST, lpHost, Len(HOST)
    CopyMemory dwIPAddr, HOST.hAddrList, 4
    '  重新动态分配变量内存
    ReDim tmpIPAddr(1 To HOST.hLen)
    '  将主机地址存储到tmpIPAddr中
    CopyMemory tmpIPAddr(1), dwIPAddr, HOST.hLen
    '  获得最终的主机IP地址字符串
    For i = 1 To HOST.hLen
        sIPAddr = sIPAddr & tmpIPAddr(i) & "."
    Next
    '  返回
    GetIPAddress = Mid$(sIPAddr, 1, Len(sIPAddr) - 1)
    ' 释放Socket库所占用的系统资源
    SocketsCleanup
End Function
'  初始化Socket
Public Function SocketsInitialize(Optional sErr As String) As Boolean
    Dim WSAD As WSADATA
    Dim sLoByte As String
    Dim sHiByte As String
    '  初始化Winsock DLL,并判断版本是否满足要求
    If WSAStartup(WS_VERSION_REQD, WSAD) <> ERROR_SUCCESS Then
        sErr = "The 32-bit Windows Socket is not responding."
        SocketsInitialize = False
        Exit Function
    End If
    '  判断是否有支持足够的Socket
    If WSAD.wMaxSockets < MIN_SOCKETS_REQD Then
        sErr = "This application requires a minimum of " & CStr(MIN_SOCKETS_REQD) & " supported sockets."
        SocketsInitialize = False
        Exit Function
    End If
    '  判断Winsock的版本是否被32为Winsock支持
    If LoByte(WSAD.wVersion) < WS_VERSION_MAJOR Or (LoByte(WSAD.wVersion) = WS_VERSION_MAJOR And HiByte(WSAD.wVersion) < WS_VERSION_MINOR) Then
        sHiByte = CStr(HiByte(WSAD.wVersion))
        sLoByte = CStr(LoByte(WSAD.wVersion))
        sErr = "Sockets version " & sLoByte & "." & sHiByte & " is not supported by 32-bit Windows Sockets."
        SocketsInitialize = False
        Exit Function
    End If
    SocketsInitialize = True
End Function
' 释放Socket库所占用的系统资源
Public Sub SocketsCleanup()
    If WSACleanup() <> ERROR_SUCCESS Then
    End If
End Sub
'  获得一个整数的高字节位
Public Function HiByte(ByVal wParam As Integer)
    HiByte = wParam / &H1 And &HFF&
End Function
'  获得一个整数的低字节位
Public Function LoByte(ByVal wParam As Integer)
    LoByte = wParam And &HFF&
End Function
类文件
my.cls
------------------------------------------------------------------------
Dim rp As Response
    Dim rq As Request
    Dim ap As Application
    Dim sr As Server
    Dim sn As Session
    ''当组件被创建的时候会触发这个事件
    Public Sub OnStartPage(mysc As scriptingContext)
     ''进行对象的实例化
     Set rp = mysc.Response
     Set rq = mysc.Request
     Set sr = mysc.Server
     Set ap = mysc.Application
     Set sn = mysc.Session
    End Sub
    ''当组件被销毁的时候触发这个事件
    Public Sub OnEndPage()
   
     Set rp = Nothing
     Set rq = Nothing
     Set sr = Nothing
     Set ap = Nothing
     Set sn = Nothing
    End Sub
    ''定义我们自己的一个组件方法
    Public Sub Local_MAC()
     rp.Write GetMyMAC
    End Sub
   
    Public Sub Remote_MAC(ip As String)
    If ip = "" Then
   
    rp.Write "无法获取IP地址"
   
    Else
   
    Dim r_mac As String
    GetRemoteMACAddress ip, r_mac
    rp.Write r_mac
   
    End If
    End Sub
调用文件
mac.asp
------------------------------------------------------------------------
<%
Dim try_mac
set try_mac = server.createobject("mac.my")
response.write "本机MAC地址:"
try_mac .Local_MAC
response.write "<br>'192.168.1.1'的MAC地址:"
try_mac .Remote_MAC("192.168.1.1")
set try_mac = nothing
%>

因为调用了系统API 所以IIS需要系统权限才能运行此DLL

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/apoet/archive/2008/05/02/2360360.aspx

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值