⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethsock.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 4 页
字号:
/*
 * ethsock.cxx
 *
 * Direct Ethernet socket implementation.
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: ethsock.cxx,v $
 * Revision 1.1  2006/06/29 04:18:40  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.48  2006/04/09 11:03:59  csoutheren
 * Remove warnings on VS.net 2005
 *
 * Revision 1.47  2005/11/30 12:47:42  csoutheren
 * Removed tabs, reformatted some code, and changed tags for Doxygen
 *
 * Revision 1.46  2005/09/18 13:01:43  dominance
 * fixed pragma warnings when building with gcc.
 *
 * Revision 1.45  2005/07/13 11:48:54  csoutheren
 * Backported QOS changes from isvo branch
 *
 * Revision 1.44.4.1  2005/04/25 13:33:56  shorne
 * Extra support for DHCP Environment (Win32)
 *
 * Revision 1.44  2004/10/23 10:52:59  ykiryanov
 * Added ifdef _WIN32_WCE for PocketPC 2003 SDK port
 *
 * Revision 1.43  2004/06/30 12:17:06  rjongbloed
 * Rewrite of plug in system to use single global variable for all factories to avoid all sorts
 *   of issues with startup orders and Windows DLL multiple instances.
 *
 * Revision 1.42  2004/06/08 01:19:22  csoutheren
 * Fixed problem with SNMP library not loading under Windows in some cases
 *
 * Revision 1.41  2004/06/01 05:24:12  csoutheren
 * Changed loading of inetmib1.dll to use PProcessStartup to avoid crashes when it is unloaded before ~H323Endpoint is called
 *
 * Revision 1.40  2004/01/30 02:06:06  csoutheren
 * Added mutex to avoid threading problems on Windows
 * Thanks to Hans Verbeek
 *
 * Revision 1.39  2003/11/05 22:51:22  csoutheren
 * Added pragma to automatically included required libs
 *
 * Revision 1.38  2003/09/17 05:45:10  csoutheren
 * Removed recursive includes
 *
 * Revision 1.37  2003/04/01 06:01:48  robertj
 * Fixed problem with returning correct route table device name if have
 *   2 NIC's under Windows 2000, thanks faa06@tid.es
 *
 * Revision 1.36  2003/01/11 05:10:51  robertj
 * Fixed Win CE compatibility issues, thanks Joerg Schoemer
 *
 * Revision 1.35  2002/11/12 02:22:16  robertj
 * Fixed problem where if SNMP not correctly installed on some flavours of
 *   windows (eg ME) the system cannot find any interfaces. Added fail safe
 *   that if could not determine one, it uses the ip address of gethostname()
 *   which should be one of the interfaces on the system.
 *
 * Revision 1.34  2002/11/08 06:45:23  robertj
 * Fixed problem with very long interface names, pointed out by Kees Klop.
 *
 * Revision 1.33  2002/10/08 12:41:52  robertj
 * Changed for IPv6 support, thanks S閎astien Josset.
 *
 * Revision 1.32  2002/02/25 09:57:29  robertj
 * Fixed possible NULL pointer use and  memory leak, thanks Klaus K鰊ig
 *
 * Revision 1.31  2002/02/15 03:56:46  yurik
 * Warnings removed during compilation, patch courtesy of Jehan Bing, jehan@bravobrava.com
 *
 * Revision 1.30  2001/10/12 19:04:24  yurik
 * New more robust ip collection routine
 *
 * Revision 1.29  2001/10/04 05:59:41  robertj
 * Plugged numerous memory leaks.
 *
 * Revision 1.28  2001/10/03 03:12:21  robertj
 * Changed to use only a single instance of SNMP library to avoid memory leak.
 *
 * Revision 1.27  2001/09/10 02:51:23  robertj
 * Major change to fix problem with error codes being corrupted in a
 *   PChannel when have simultaneous reads and writes in threads.
 *
 * Revision 1.26  2001/09/09 02:03:49  yurik
 * no message
 *
 * Revision 1.25  2001/08/28 03:22:01  yurik
 * Fixed crash on snmp init bug
 *
 * Revision 1.24  2001/08/16 20:12:25  yurik
 * Fixed duplicate ordinal - ifdef'd ce code
 *
 * Revision 1.23  2001/08/15 22:15:27  yurik
 * First cut of Windows CE port  to support gatekeeper
 *
 * Revision 1.22  2001/03/05 04:18:27  robertj
 * Added net mask to interface info returned by GetInterfaceTable()
 *
 * Revision 1.21  2000/03/06 03:59:22  robertj
 * Fixed warning about handle types, thanks Steve Bennett
 *
 * Revision 1.20  1999/10/29 03:34:19  robertj
 * Fixed possible crash accessing IP addresses from SNMP tables.
 *
 * Revision 1.19  1999/10/14 01:34:55  robertj
 * Fixed backward compatibility problem with old SNMP header file.
 *
 * Revision 1.18  1999/09/10 04:35:42  robertj
 * Added Windows version of PIPSocket::GetInterfaceTable() function.
 *
 * Revision 1.17  1999/04/18 12:58:39  robertj
 * MSVC 5 backward compatibility
 *
 * Revision 1.16  1999/02/16 08:08:06  robertj
 * MSVC 6.0 compatibility changes.
 *
 * Revision 1.15  1998/11/30 04:48:38  robertj
 * New directory structure
 *
 * Revision 1.14  1998/11/22 11:30:10  robertj
 * Check route table function to get a list
 *
 * Revision 1.13  1998/11/20 03:17:43  robertj
 * Split rad and write buffers to separate pools.
 *
 * Revision 1.12  1998/11/19 05:18:48  robertj
 * Added route table manipulation functions to PIPSocket class.
 *
 * Revision 1.11  1998/11/14 06:31:41  robertj
 * Changed semantics of os_sendto to return TRUE if ANY bytes are sent.
 * Added support for MSDUN1.3 DHCP registry entries.
 *
 * Revision 1.10  1998/10/23 04:09:08  robertj
 * Fixes for NT support.
 * Allowed both old and new driver by compilation option.
 *
 * Revision 1.9  1998/10/15 05:41:48  robertj
 * New memory leak check code.
 *
 * Revision 1.8  1998/10/12 09:34:42  robertj
 * New method for getting IP addresses of interfaces.
 *
 * Revision 1.7  1998/10/06 10:24:41  robertj
 * Fixed hang when using reset command, removed the command!
 *
 * Revision 1.6  1998/09/24 03:30:45  robertj
 * Added open software license.
 *
 * Revision 1.5  1998/09/15 08:25:36  robertj
 * Fixed a number of warnings at maximum optimisation.
 *
 * Revision 1.4  1998/09/08 15:14:36  robertj
 * Fixed packet type based filtering in Read() function.
 *
 * Revision 1.3  1998/08/25 11:03:15  robertj
 * Fixed proble with NT get of OID.
 * Fixed bug with not setting channel name when interface opened.
 *
 * Revision 1.2  1998/08/21 05:27:13  robertj
 * Fine tuning of interface.
 *
 * Revision 1.1  1998/08/20 06:04:52  robertj
 * Initial revision
 *
 */

#include <ptlib.h>
#include <ptlib/sockets.h>
#include <snmp.h>

#ifndef _WIN32_WCE
#ifdef _MSC_VER
#pragma comment(lib, "snmpapi.lib")
#endif
#endif

///////////////////////////////////////////////////////////////////////////////
// Stuff from snmp.h

#ifndef RFC1157VarBindList
typedef RFC1157VarBind SnmpVarBind;
typedef RFC1157VarBindList SnmpVarBindList;
typedef LONG AsnInteger32;
#define SNMP_PDU_GET ASN_RFC1157_GETREQUEST
#define SNMP_PDU_GETNEXT ASN_RFC1157_GETNEXTREQUEST
#define ASN_IPADDRESS    ASN_RFC1155_IPADDRESS // Prevents GetInterfaceTable failure
#pragma message("Later version of snmp.h required!")
#endif

///////////////////////////////////////////////////////////////////////////////
// Stuff from ndis.h

#define OID_802_3_PERMANENT_ADDRESS         0x01010101
#define OID_802_3_CURRENT_ADDRESS           0x01010102

#define OID_GEN_DRIVER_VERSION              0x00010110
#define OID_GEN_CURRENT_PACKET_FILTER       0x0001010E
#define OID_GEN_MEDIA_SUPPORTED             0x00010103

#define NDIS_PACKET_TYPE_DIRECTED           0x0001
#define NDIS_PACKET_TYPE_MULTICAST          0x0002
#define NDIS_PACKET_TYPE_ALL_MULTICAST      0x0004
#define NDIS_PACKET_TYPE_BROADCAST          0x0008
#define NDIS_PACKET_TYPE_PROMISCUOUS        0x0020

typedef enum _NDIS_MEDIUM {
    NdisMedium802_3,
    NdisMedium802_5,
    NdisMediumFddi,
    NdisMediumWan,
    NdisMediumLocalTalk,
    NdisMediumDix,              // defined for convenience, not a real medium
    NdisMediumArcnetRaw,
    NdisMediumArcnet878_2
} NDIS_MEDIUM, *PNDIS_MEDIUM;                    

///////////////////////////////////////////////////////////////////////////////


#define USE_VPACKET
#include <ptlib/msos/ptlib/epacket.h>

#ifdef USE_VPACKET
#define PACKET_SERVICE_NAME "Packet"
#define PACKET_VXD_NAME     "VPacket"
#else
#define PACKET_SERVICE_NAME "EPacket"
#define PACKET_VXD_NAME     "EPacket"
#define GetQueryOidCommand(oid) IOCTL_EPACKET_QUERY_OID
#endif

#define SERVICES_REGISTRY_KEY "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\"


///////////////////////////////////////////////////////////////////////////////

class PWin32AsnAny : public AsnAny
{
  public:
    PWin32AsnAny();
    ~PWin32AsnAny() { MemFree(); }
    BOOL GetInteger(AsnInteger & i);
    BOOL GetIpAddress(PIPSocket::Address & addr);
    void MemFree();
  private:
    PWin32AsnAny(const PWin32AsnAny &) { }
    PWin32AsnAny & operator=(const PWin32AsnAny &) { return *this; }
};


///////////////////////////////////////////////////////////////////////////////

class PWin32AsnOid : public AsnObjectIdentifier
{
  public:
    PWin32AsnOid();
    PWin32AsnOid(const char * str);
    PWin32AsnOid(const PWin32AsnOid & oid)              { SnmpUtilOidCpy(this, (AsnObjectIdentifier *)&oid); }
    ~PWin32AsnOid()                                     { SnmpUtilOidFree(this); }
    PWin32AsnOid & operator=(const AsnObjectIdentifier&);
    PWin32AsnOid & operator=(const PWin32AsnOid & oid)  { SnmpUtilOidFree(this); SnmpUtilOidCpy(this, (AsnObjectIdentifier *)&oid); return *this; }
    PWin32AsnOid & operator+=(const PWin32AsnOid & oid) { SnmpUtilOidAppend(this, (AsnObjectIdentifier *)&oid); return *this; }
    UINT & operator[](int idx)                          { return ids[idx]; }
    UINT   operator[](int idx) const                    { return ids[idx]; }
    bool operator==(const PWin32AsnOid & oid)           { return SnmpUtilOidCmp(this, (AsnObjectIdentifier *)&oid) == 0; }
    bool operator!=(const PWin32AsnOid & oid)           { return SnmpUtilOidCmp(this, (AsnObjectIdentifier *)&oid) != 0; }
    bool operator< (const PWin32AsnOid & oid)           { return SnmpUtilOidCmp(this, (AsnObjectIdentifier *)&oid) <  0; }
    bool operator<=(const PWin32AsnOid & oid)           { return SnmpUtilOidCmp(this, (AsnObjectIdentifier *)&oid) <= 0; }
    bool operator> (const PWin32AsnOid & oid)           { return SnmpUtilOidCmp(this, (AsnObjectIdentifier *)&oid) >  0; }
    bool operator>=(const PWin32AsnOid & oid)           { return SnmpUtilOidCmp(this, (AsnObjectIdentifier *)&oid) >= 0; }
    bool operator*=(const PWin32AsnOid & oid)           { return SnmpUtilOidNCmp(this, (AsnObjectIdentifier *)&oid, idLength) == 0; }
};


/////////////////////////////////////////////////////////////////////////////

class PWin32SnmpLibrary
#ifndef _WIN32_WCE
                        : public PDynaLink
{
    PCLASSINFO(PWin32SnmpLibrary, PDynaLink)
  public:
#else
{
  public:
    void Close();
    BOOL IsLoaded() { return TRUE; }
#endif
public:
    PWin32SnmpLibrary();

    BOOL GetOid(AsnObjectIdentifier & oid, AsnInteger & value);
    BOOL GetOid(AsnObjectIdentifier & oid, PIPSocket::Address & ip_address);
    BOOL GetOid(AsnObjectIdentifier & oid, PString & str);
    BOOL GetOid(AsnObjectIdentifier & oid, void * value, UINT valSize, UINT * len = NULL);
    BOOL GetOid(AsnObjectIdentifier & oid, PWin32AsnAny & value)     { return QueryOid(SNMP_PDU_GET, oid, value); }

    BOOL GetNextOid(AsnObjectIdentifier & oid, PWin32AsnAny & value) { return QueryOid(SNMP_PDU_GETNEXT, oid, value); }

    PString GetInterfaceName(int ifNum);
    PString GetInterfaceName(PIPSocket::Address ipAddr);
    PIPSocket::Address GetInterfaceAddress(int ifNum);

    static PWin32SnmpLibrary & Current();
    static PMutex & GetMutex();

  private:
    PMutex mutex;

    BOOL (WINAPI *_Init)(DWORD,HANDLE*,AsnObjectIdentifier*);
    BOOL (WINAPI *_Query)(BYTE,SnmpVarBindList*,AsnInteger32*,AsnInteger32*);

    BOOL Init(DWORD upTime, HANDLE * trapEvent, AsnObjectIdentifier * firstSupportedRegion)
    { return (*_Init)(upTime, trapEvent, firstSupportedRegion); }

    BOOL Query(BYTE pduType, SnmpVarBindList * pVarBindList, AsnInteger32 * pErrorStatus, AsnInteger32 * pErrorIndex)
    { return _Query(pduType, pVarBindList, pErrorStatus, pErrorIndex); }

    BOOL QueryOid(BYTE cmd, AsnObjectIdentifier & oid, PWin32AsnAny & value);
};

class WinSNMPLoader : public PProcessStartup
{
  PCLASSINFO(WinSNMPLoader, PProcessStartup);
  public:
    void OnStartup()
    { }

    PWin32SnmpLibrary & Current()
    {
      PWaitAndSignal m(mutex);
      if (snmpLibrary == NULL) {
        snmpLibrary = new PWin32SnmpLibrary;
      }
      return *snmpLibrary;
    }

    void OnShutdown()
    { 
      PWaitAndSignal m(mutex); 
      delete snmpLibrary; 
      snmpLibrary = NULL;
    }

  protected:
    PMutex mutex;
    static PWin32SnmpLibrary * snmpLibrary;
};

PWin32SnmpLibrary * WinSNMPLoader::snmpLibrary = NULL;

static PFactory<PProcessStartup>::Worker<WinSNMPLoader> winSNMPLoadedStartupFactory("WinSNMPLoader", true);

PWin32SnmpLibrary & PWin32SnmpLibrary::Current()
{ 
  return ((WinSNMPLoader *)PFactory<PProcessStartup>::CreateInstance("WinSNMPLoader"))->Current();
}

PMutex & PWin32SnmpLibrary::GetMutex()
{
  return Current().mutex;
}

#define GetSNMPMutex    PWin32SnmpLibrary::GetMutex

///////////////////////////////////////////////////////////////////////////////

class PWin32OidBuffer
{
  public:
    PWin32OidBuffer(UINT oid, UINT len, const BYTE * data = NULL);
    ~PWin32OidBuffer() { delete buffer; }

    operator void *()         { return buffer; }
    operator DWORD ()         { return size; }
    DWORD operator [](int i)  { return buffer[i]; }

    void Move(BYTE * data, DWORD received);

  private:
    DWORD * buffer;
    UINT size;
};


///////////////////////////////////////////////////////////////////////////////

class PWin32PacketDriver
{
  public:
    static PWin32PacketDriver * Create();

    virtual ~PWin32PacketDriver();

    BOOL IsOpen() const;
    void Close();
    DWORD GetLastError() const;

    virtual BOOL EnumInterfaces(PINDEX idx, PString & name) = 0;
    virtual BOOL BindInterface(const PString & interfaceName) = 0;

    virtual BOOL EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask) = 0;

    virtual BOOL BeginRead(void * buf, DWORD size, DWORD & received, PWin32Overlapped & overlap) = 0;
    virtual BOOL BeginWrite(const void * buf, DWORD len, PWin32Overlapped & overlap) = 0;
    BOOL CompleteIO(DWORD & received, PWin32Overlapped & overlap);

    BOOL IoControl(UINT func,
                   const void * input, DWORD inSize,
                   void * output, DWORD outSize,
                   DWORD & received);

    BOOL QueryOid(UINT oid, DWORD & data);
    BOOL QueryOid(UINT oid, UINT len, BYTE * data);
    BOOL SetOid(UINT oid, DWORD data);
    BOOL SetOid(UINT oid, UINT len, const BYTE * data);
#ifdef USE_VPACKET
    virtual UINT GetQueryOidCommand(DWORD oid) const = 0;
#endif

  protected:
    PWin32PacketDriver();

    DWORD dwError;
    HANDLE hDriver;
};

///////////////////////////////////////////////////////////////////////////////

class PWin32PacketVxD : public PWin32PacketDriver
{
  public:
    virtual BOOL EnumInterfaces(PINDEX idx, PString & name);
    virtual BOOL BindInterface(const PString & interfaceName);

    virtual BOOL EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask);

    virtual BOOL BeginRead(void * buf, DWORD size, DWORD & received, PWin32Overlapped & overlap);
    virtual BOOL BeginWrite(const void * buf, DWORD len, PWin32Overlapped & overlap);

#ifdef USE_VPACKET
    virtual UINT GetQueryOidCommand(DWORD oid) const
      { return oid >= OID_802_3_PERMANENT_ADDRESS ? IOCTL_EPACKET_QUERY_OID : IOCTL_EPACKET_STATISTICS; }
#endif

  protected:
    PStringList transportBinding;
};


///////////////////////////////////////////////////////////////////////////////

class PWin32PacketSYS : public PWin32PacketDriver
{
  public:
    PWin32PacketSYS();

    virtual BOOL EnumInterfaces(PINDEX idx, PString & name);
    virtual BOOL BindInterface(const PString & interfaceName);

    virtual BOOL EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask);

    virtual BOOL BeginRead(void * buf, DWORD size, DWORD & received, PWin32Overlapped & overlap);
    virtual BOOL BeginWrite(const void * buf, DWORD len, PWin32Overlapped & overlap);

#ifdef USE_VPACKET
    virtual UINT GetQueryOidCommand(DWORD) const
      { return IOCTL_EPACKET_QUERY_OID; }
#endif

  protected:
    PString registryKey;
};

///////////////////////////////////////////////////////////////////////////////

#ifdef _WIN32_WCE

class PWin32PacketCe : public PWin32PacketDriver
{
  public:
    PWin32PacketCe();

    virtual BOOL EnumInterfaces(PINDEX idx, PString & name);
    virtual BOOL BindInterface(const PString & interfaceName);

    virtual BOOL EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask);

    virtual BOOL BeginRead(void * buf, DWORD size, DWORD & received, PWin32Overlapped & overlap);
    virtual BOOL BeginWrite(const void * buf, DWORD len, PWin32Overlapped & overlap);

#ifdef USE_VPACKET
    virtual UINT GetQueryOidCommand(DWORD) const
      { return IOCTL_EPACKET_QUERY_OID; }
#endif
  protected:
    PStringArray ipAddresses;
    PStringArray netMasks;
    PStringArray interfaces;
};

#endif // _WIN32_WCE

/////////////////////////////////////////////////////////////////////////////

class PWin32PacketBuffer : public PBYTEArray
{
  PCLASSINFO(PWin32PacketBuffer, PBYTEArray)
  public:
    enum Statuses {
      Uninitialised,
      Progressing,
      Completed
    };

    PWin32PacketBuffer(PINDEX sz);

    PINDEX GetData(void * buf, PINDEX size);
    PINDEX PutData(const void * buf, PINDEX length);
    HANDLE GetEvent() const { return overlap.hEvent; }

    BOOL ReadAsync(PWin32PacketDriver & pkt);
    BOOL ReadComplete(PWin32PacketDriver & pkt);
    BOOL WriteAsync(PWin32PacketDriver & pkt);
    BOOL WriteComplete(PWin32PacketDriver & pkt);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -