hxnetif.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxcom.h"
  36. #include <string.h>
  37. #include <stdio.h>
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40. #include <time.h>
  41. #include "hxresult.h"
  42. #include "hxslist.h"
  43. #include "netbyte.h"
  44. #include "hxengin.h"
  45. #include "hxnetif.h"
  46. #ifdef _UNIX
  47. #include <sys/types.h>
  48. #include <sys/stat.h>
  49. #include <netinet/in.h>
  50. #include <sys/socket.h>
  51. #if defined _SOLARIS || defined _FREEBSD || defined _OPENBSD || defined _NETBSD
  52. #include <sys/sockio.h>
  53. #endif
  54. #include <net/if.h>
  55. #include <sys/ioctl.h>
  56. #endif
  57. #if defined (_UNIX) && !defined(_SUN) && !defined(_SCO_UW) && !defined(_HPUX) && !defined(_IRIX) && !defined(_OSF1)
  58. #include <sys/file.h>
  59. #endif /* UNIX */
  60. HXNetInterface::HXNetInterface(IUnknown* pContext)
  61.     : m_lRefCount(0)
  62.     , m_bInitialized(FALSE)
  63.     , m_pNetInterfaceList(NULL)
  64.     , m_pSinkList(NULL)
  65. {
  66. }
  67. HXNetInterface::~HXNetInterface()
  68. {
  69.     Close();
  70. }
  71. STDMETHODIMP
  72. HXNetInterface::QueryInterface(REFIID riid, void**ppvObj)
  73. {
  74.     if (IsEqualIID(riid, IID_IUnknown))
  75.     {
  76.         AddRef();
  77.         *ppvObj = this;
  78.         return HXR_OK;
  79.     }
  80.     else if (IsEqualIID(riid, IID_IHXNetInterfaces))
  81.     {
  82.         AddRef();
  83.         *ppvObj = (IHXNetInterfaces*)this;
  84.         return HXR_OK;
  85.     }
  86.     *ppvObj = NULL;
  87.     return HXR_NOINTERFACE;
  88. }
  89. /////////////////////////////////////////////////////////////////////////
  90. //  Method:
  91. //  IUnknown::AddRef
  92. //  Purpose:
  93. //  Everyone usually implements this the same... feel free to use
  94. //  this implementation.
  95. //
  96. STDMETHODIMP_(ULONG32) 
  97.     HXNetInterface::AddRef()
  98. {
  99.     return InterlockedIncrement(&m_lRefCount);
  100. }
  101. /////////////////////////////////////////////////////////////////////////
  102. //  Method:
  103. //  IUnknown::Release
  104. //  Purpose:
  105. //  Everyone usually implements this the same... feel free to use
  106. //  this implementation.
  107. //
  108. STDMETHODIMP_(ULONG32) 
  109.     HXNetInterface::Release()
  110. {
  111.     if (InterlockedDecrement(&m_lRefCount) > 0)
  112.     {
  113.         return m_lRefCount;
  114.     }
  115.     delete this;
  116.     return 0;
  117. }
  118. STDMETHODIMP
  119. HXNetInterface::UpdateNetInterfaces(void)
  120. {
  121.     HX_RESULT rc = HXR_OK;    
  122.     BOOL bChanged = FALSE;
  123.     bChanged = IsNetInterfaceChanged();
  124.     if (!m_bInitialized)
  125.     {
  126. m_bInitialized = TRUE;
  127.     }
  128.     else if (bChanged && m_pSinkList)
  129.     {
  130.         CHXSimpleList::Iterator ndx = m_pSinkList->Begin();
  131.         for (; ndx != m_pSinkList->End(); ++ndx)
  132.         {
  133.             IHXNetInterfacesAdviseSink* pSink = (IHXNetInterfacesAdviseSink*) (*ndx);
  134.             pSink->NetInterfacesUpdated();
  135.         }
  136.     }
  137.     
  138.     return rc;
  139. }
  140. HX_RESULT
  141. HXNetInterface::RetrieveNetInterface(CHXSimpleList*& pNetInterfaceList)
  142. {
  143.     HX_RESULT     rc = HXR_OK;    
  144.     int           i, fd, num;
  145.     char          buf[BUFSIZ]; /* Flawfinder: ignore */
  146.     long          lFlags = 0;
  147.     NIInfo*       pNIInfo = NULL; 
  148.     struct ifconf ifc;
  149.     struct ifreq* ifr;
  150.     fd = socket(AF_INET, SOCK_DGRAM, 0);
  151.     if (-1 == fd)
  152.     {
  153.         rc = HXR_FAILED;
  154.         goto cleanup;
  155.     }
  156.     ifc.ifc_len = BUFSIZ;
  157.     ifc.ifc_buf = buf;
  158.     // get network interface configuration
  159.     if (-1 == ioctl(fd, SIOCGIFCONF, &ifc))
  160.     {
  161.         rc = HXR_FAILED;
  162.         goto cleanup;
  163.     }
  164.     num = ifc.ifc_len / sizeof(struct ifreq);
  165.     // iterate through the network interface
  166.     for (i = 0, ifr = ifc.ifc_req; i < num; i++, ifr += 1) 
  167.     {
  168.         if (-1 != ioctl(fd, SIOCGIFFLAGS, ifr)) 
  169.         {
  170.             pNIInfo = new NIInfo;
  171.         
  172.             lFlags = ifr->ifr_flags;
  173.             if (lFlags & IFF_LOOPBACK)
  174.             {
  175.                 pNIInfo->type = LOOPBACK;
  176.             }
  177.             else if (lFlags & IFF_POINTOPOINT)
  178.             {
  179.                 pNIInfo->type = POINTTOPOINT;
  180.             }
  181.             else if (lFlags & IFF_BROADCAST)
  182.             {
  183.                 pNIInfo->type = BROADCAST;
  184.             }
  185.             if (lFlags & IFF_UP)
  186.             {
  187.                 pNIInfo->bActive = TRUE;
  188.             }
  189.             if (-1 != ioctl(fd, SIOCGIFADDR, ifr))
  190.             {
  191.                 pNIInfo->ulNetAddress =
  192.                     ((struct sockaddr_in *)&ifr->ifr_broadaddr)->sin_addr.s_addr;   
  193.             }
  194.             
  195.             if (-1 != ioctl(fd, SIOCGIFNETMASK, ifr))
  196.             {
  197.                 pNIInfo->ulNetMask =
  198.                     ((struct sockaddr_in *)&ifr->ifr_broadaddr)->sin_addr.s_addr;
  199.             }
  200.             if (!pNetInterfaceList)
  201.             {
  202.                 pNetInterfaceList = new CHXSimpleList;
  203.             }
  204.             pNetInterfaceList->AddTail(pNIInfo);
  205.         }
  206.     }
  207. cleanup:
  208.     close(fd);
  209.     
  210.     return rc;
  211. }
  212. STDMETHODIMP_(UINT32)
  213.     HXNetInterface::GetNumOfNetInterfaces()
  214. {
  215.     if (!m_bInitialized)
  216.     {
  217. UpdateNetInterfaces();
  218.     }
  219.     return m_pNetInterfaceList ? m_pNetInterfaceList->GetCount() : 0;
  220. }
  221. STDMETHODIMP HXNetInterface::GetNetInterfaces(UINT16   lIndex,
  222.                                                REF(NIInfo*) pNIInfo)
  223. {
  224.     HX_RESULT  rc = HXR_OK;
  225.     int        i = 0;
  226.     CHXSimpleList::Iterator iter;
  227.     
  228.     pNIInfo = NULL;
  229.     
  230.     if (!m_bInitialized)
  231.     {
  232. UpdateNetInterfaces();
  233.     }
  234.     
  235.     if (m_pNetInterfaceList)
  236.     {
  237.         iter = m_pNetInterfaceList->Begin();
  238.         for (; iter != m_pNetInterfaceList->End(); ++iter, ++i)
  239.         {
  240.             NIInfo* pInfo = (NIInfo*)(*iter);
  241.             if (i == lIndex)
  242.             {
  243.                 pNIInfo = pInfo;
  244.                 break;
  245.             }
  246.         }
  247.     }
  248.     
  249.     if (!pNIInfo)
  250.     {
  251.         rc = HXR_FAILED;
  252.     }
  253.     
  254.   cleanup:
  255.     
  256.     return rc;
  257. }
  258. STDMETHODIMP
  259. HXNetInterface::AddAdviseSink(IHXNetInterfacesAdviseSink* pSink)
  260. {
  261.     HX_RESULT   rc = HXR_OK;
  262.     if (!m_pSinkList)
  263.     {
  264.         m_pSinkList = new CHXSimpleList();
  265.     }
  266.     pSink->AddRef();
  267.     m_pSinkList->AddTail(pSink);
  268.     return rc;
  269. }
  270. STDMETHODIMP
  271. HXNetInterface::RemoveAdviseSink(IHXNetInterfacesAdviseSink* pSink)
  272. {
  273.     HX_RESULT   rc = HXR_OK;
  274.     LISTPOSITION lPosition = m_pSinkList->Find(pSink);
  275.     if (!lPosition)
  276.     {
  277.         rc = HXR_UNEXPECTED;
  278.         goto cleanup;
  279.     }
  280.     m_pSinkList->RemoveAt(lPosition);
  281.     pSink->Release();
  282.   cleanup:
  283.     return rc;
  284. }
  285. BOOL HXNetInterface::IsNetInterfaceChanged(void)
  286. {
  287.     BOOL            bResult = FALSE;
  288.     CHXSimpleList*  pTempNetInterfaceList = new CHXSimpleList();
  289.     RetrieveNetInterface(pTempNetInterfaceList);
  290.     
  291.     if (pTempNetInterfaceList && m_pNetInterfaceList)
  292.     {
  293.         if (pTempNetInterfaceList->GetCount() != m_pNetInterfaceList->GetCount())
  294.         {
  295.             bResult = TRUE;
  296.         }
  297.         else
  298.         {
  299.             CHXSimpleList::Iterator ndx0 = pTempNetInterfaceList->Begin();
  300.             CHXSimpleList::Iterator ndx1 = m_pNetInterfaceList->Begin();
  301.             for (; ndx0 != pTempNetInterfaceList->End() && ndx1 != m_pNetInterfaceList->End(); ++ndx0, ++ndx1)
  302.             {
  303.                 NIInfo* pInfo0 = (NIInfo*)(*ndx0);
  304.                 NIInfo* pInfo1 = (NIInfo*)(*ndx1);
  305.                 
  306.                 if (pInfo0->ulNetAddress != pInfo1->ulNetAddress ||
  307.                     pInfo0->ulNetMask != pInfo1->ulNetMask)
  308.                 {
  309.                     bResult = TRUE;
  310.                 }
  311.             }
  312.         }
  313.     }
  314.     else if (pTempNetInterfaceList != m_pNetInterfaceList)
  315.     {
  316.         bResult = TRUE;
  317.     }
  318.     
  319.     if (bResult)
  320.     {
  321.         Reset(m_pNetInterfaceList); 
  322.         HX_DELETE(m_pNetInterfaceList);
  323.         
  324.         m_pNetInterfaceList = pTempNetInterfaceList;
  325.     }
  326.     else
  327.     {
  328.         Reset(pTempNetInterfaceList);
  329.         HX_DELETE(pTempNetInterfaceList);
  330.     }
  331.     
  332.     return bResult;
  333. }
  334. void
  335. HXNetInterface::Reset(CHXSimpleList* pNetInterfaceList)
  336. {
  337.     if (pNetInterfaceList)
  338.     {
  339.         while (pNetInterfaceList->GetCount())
  340.         {
  341.             NIInfo* pNIInfo = (NIInfo*)pNetInterfaceList->RemoveHead();
  342.             HX_DELETE(pNIInfo);
  343.         }
  344.     }
  345. }
  346. void
  347. HXNetInterface::Close(void)
  348. {
  349.     Reset(m_pNetInterfaceList);
  350.     HX_DELETE(m_pNetInterfaceList);
  351.     if (m_pSinkList)
  352.     {
  353.         HX_ASSERT(m_pSinkList->GetCount() == 0);
  354.         CHXSimpleList::Iterator ndx = m_pSinkList->Begin();
  355.         for (; ndx != m_pSinkList->End(); ++ndx)
  356.         {
  357.             IHXNetInterfacesAdviseSink* pSink = (IHXNetInterfacesAdviseSink*) (*ndx);
  358.             HX_RELEASE(pSink);
  359.         }
  360.         HX_DELETE(m_pSinkList);
  361.     }
  362. }