hxnetif.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:11k
源码类别:

Symbian

开发平台:

Visual C++

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