internal static FixedInfo GetFixedInfo()
        {
            uint          size      = 0;
            SafeLocalFree buffer    = null;
            FixedInfo     fixedInfo = new FixedInfo();

            //first we need to get the size of the buffer
            uint result = UnsafeNetInfoNativeMethods.GetNetworkParams(SafeLocalFree.Zero, ref size);

            while (result == IpHelperErrors.ErrorBufferOverflow)
            {
                try {
                    //now we allocate the buffer and read the network parameters.
                    buffer = SafeLocalFree.LocalAlloc((int)size);
                    result = UnsafeNetInfoNativeMethods.GetNetworkParams(buffer, ref size);
                    if (result == IpHelperErrors.Success)
                    {
                        fixedInfo = new FixedInfo((FIXED_INFO)Marshal.PtrToStructure(buffer.DangerousGetHandle(), typeof(FIXED_INFO)));
                    }
                }
                finally {
                    if (buffer != null)
                    {
                        buffer.Close();
                    }
                }
            }

            //if the result include there being no information, we'll still throw
            if (result != IpHelperErrors.Success)
            {
                throw new NetworkInformationException((int)result);
            }
            return(fixedInfo);
        }
        protected override bool ReleaseHandle()
        {
            uint err = UnsafeNetInfoNativeMethods.CancelMibChangeNotify2(base.handle);

            base.handle = IntPtr.Zero;
            return(err == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS);
        }
        internal static System.Net.NetworkInformation.FixedInfo GetFixedInfo()
        {
            uint          pOutBufLen = 0;
            SafeLocalFree pFixedInfo = null;

            System.Net.NetworkInformation.FixedInfo info = new System.Net.NetworkInformation.FixedInfo();
            uint networkParams = UnsafeNetInfoNativeMethods.GetNetworkParams(SafeLocalFree.Zero, ref pOutBufLen);

            while (networkParams == 0x6f)
            {
                try
                {
                    pFixedInfo    = SafeLocalFree.LocalAlloc((int)pOutBufLen);
                    networkParams = UnsafeNetInfoNativeMethods.GetNetworkParams(pFixedInfo, ref pOutBufLen);
                    if (networkParams == 0)
                    {
                        info = new System.Net.NetworkInformation.FixedInfo((FIXED_INFO)Marshal.PtrToStructure(pFixedInfo.DangerousGetHandle(), typeof(FIXED_INFO)));
                    }
                    continue;
                }
                finally
                {
                    if (pFixedInfo != null)
                    {
                        pFixedInfo.Close();
                    }
                }
            }
            if (networkParams != 0)
            {
                throw new NetworkInformationException((int)networkParams);
            }
            return(info);
        }
Пример #4
0
        public static bool UnsafeNotifyStableUnicastIpAddressTable(Action <object> callback, object state)
        {
            TeredoHelper     item  = new TeredoHelper(callback, state);
            uint             num   = 0;
            SafeFreeMibTable table = null;

            lock (pendingNotifications)
            {
                if (impendingAppDomainUnload)
                {
                    return(false);
                }
                num = UnsafeNetInfoNativeMethods.NotifyStableUnicastIpAddressTable(AddressFamily.Unspecified, out table, item.onStabilizedDelegate, IntPtr.Zero, out item.cancelHandle);
                if (table != null)
                {
                    table.Dispose();
                }
                if (num == 0x3e5)
                {
                    pendingNotifications.Add(item);
                    return(false);
                }
            }
            if (num != 0)
            {
                throw new Win32Exception((int)num);
            }
            return(true);
        }
        protected override bool ReleaseHandle()
        {
            uint num = UnsafeNetInfoNativeMethods.CancelMibChangeNotify2(base.handle);

            base.handle = IntPtr.Zero;
            return(num == 0);
        }
        private static NetworkInterface[] GetNetworkInterfaces(AddressFamily family)
        {
            IpHelperErrors.CheckFamilyUnspecified(family);
            if (ComNetOS.IsPostWin2K)
            {
                return(PostWin2KGetNetworkInterfaces(family));
            }
            FixedInfo fixedInfo = SystemIPGlobalProperties.GetFixedInfo();

            if ((family != AddressFamily.Unspecified) && (family != AddressFamily.InterNetwork))
            {
                throw new PlatformNotSupportedException(SR.GetString("WinXPRequired"));
            }
            SafeLocalFree pAdapterInfo = null;
            uint          pOutBufLen   = 0;
            ArrayList     list         = new ArrayList();
            uint          adaptersInfo = UnsafeNetInfoNativeMethods.GetAdaptersInfo(SafeLocalFree.Zero, ref pOutBufLen);

            while (adaptersInfo == 0x6f)
            {
                try
                {
                    pAdapterInfo = SafeLocalFree.LocalAlloc((int)pOutBufLen);
                    adaptersInfo = UnsafeNetInfoNativeMethods.GetAdaptersInfo(pAdapterInfo, ref pOutBufLen);
                    if (adaptersInfo == 0)
                    {
                        IpAdapterInfo ipAdapterInfo = (IpAdapterInfo)Marshal.PtrToStructure(pAdapterInfo.DangerousGetHandle(), typeof(IpAdapterInfo));
                        list.Add(new SystemNetworkInterface(fixedInfo, ipAdapterInfo));
                        while (ipAdapterInfo.Next != IntPtr.Zero)
                        {
                            ipAdapterInfo = (IpAdapterInfo)Marshal.PtrToStructure(ipAdapterInfo.Next, typeof(IpAdapterInfo));
                            list.Add(new SystemNetworkInterface(fixedInfo, ipAdapterInfo));
                        }
                    }
                    continue;
                }
                finally
                {
                    if (pAdapterInfo != null)
                    {
                        pAdapterInfo.Close();
                    }
                }
            }
            if (adaptersInfo == 0xe8)
            {
                return(new SystemNetworkInterface[0]);
            }
            if (adaptersInfo != 0)
            {
                throw new NetworkInformationException((int)adaptersInfo);
            }
            SystemNetworkInterface[] interfaceArray = new SystemNetworkInterface[list.Count];
            for (int i = 0; i < list.Count; i++)
            {
                interfaceArray[i] = (SystemNetworkInterface)list[i];
            }
            return(interfaceArray);
        }
Пример #7
0
        internal SystemIcmpV6Statistics()
        {
            uint result = UnsafeNetInfoNativeMethods.GetIcmpStatisticsEx(out stats, AddressFamily.InterNetworkV6);

            if (result != IpHelperErrors.Success)
            {
                throw new NetworkInformationException((int)result);
            }
        }
        internal SystemUdpStatistics(AddressFamily family)
        {
            uint result = UnsafeNetInfoNativeMethods.GetUdpStatisticsEx(out stats, family);

            if (result != IpHelperErrors.Success)
            {
                throw new NetworkInformationException((int)result);
            }
        }
Пример #9
0
        internal SystemIcmpV4Statistics()
        {
            uint icmpStatistics = UnsafeNetInfoNativeMethods.GetIcmpStatistics(out this.stats);

            if (icmpStatistics != 0)
            {
                throw new NetworkInformationException((int)icmpStatistics);
            }
        }
Пример #10
0
        private static void PingCallback(object state, bool signaled)
        {
            Ping ping = (Ping)state;
            PingCompletedEventArgs arg   = null;
            bool               cancelled = false;
            AsyncOperation     asyncOp   = null;
            SendOrPostCallback d         = null;

            try
            {
                lock (ping.lockObject)
                {
                    cancelled = ping.cancelled;
                    asyncOp   = ping.asyncOp;
                    d         = ping.onPingCompletedDelegate;
                    if (!cancelled)
                    {
                        PingReply     reply;
                        SafeLocalFree replyBuffer = ping.replyBuffer;
                        if (!ping.ipv6 && !ComNetOS.IsVista)
                        {
                            UnsafeNetInfoNativeMethods.IcmpParseReplies(replyBuffer.DangerousGetHandle(), 0x100ff);
                        }
                        if (ping.ipv6)
                        {
                            Icmp6EchoReply reply2 = (Icmp6EchoReply)Marshal.PtrToStructure(replyBuffer.DangerousGetHandle(), typeof(Icmp6EchoReply));
                            reply = new PingReply(reply2, replyBuffer.DangerousGetHandle(), ping.sendSize);
                        }
                        else
                        {
                            IcmpEchoReply reply3 = (IcmpEchoReply)Marshal.PtrToStructure(replyBuffer.DangerousGetHandle(), typeof(IcmpEchoReply));
                            reply = new PingReply(reply3);
                        }
                        arg = new PingCompletedEventArgs(reply, null, false, asyncOp.UserSuppliedState);
                    }
                    else
                    {
                        arg = new PingCompletedEventArgs(null, null, true, asyncOp.UserSuppliedState);
                    }
                }
            }
            catch (Exception exception)
            {
                PingException error = new PingException(SR.GetString("net_ping"), exception);
                arg = new PingCompletedEventArgs(null, error, false, asyncOp.UserSuppliedState);
            }
            finally
            {
                ping.FreeUnmanagedStructures();
                ping.UnregisterWaitHandle();
                ping.Finish(true);
            }
            asyncOp.PostOperationCompleted(d, arg);
        }
        private static SystemNetworkInterface[] GetAdaptersAddresses(AddressFamily family, FixedInfo fixedInfo)
        {
            uint          outBufLen        = 0;
            SafeLocalFree adapterAddresses = null;
            ArrayList     list             = new ArrayList();

            SystemNetworkInterface[] interfaceArray = null;
            uint num2 = UnsafeNetInfoNativeMethods.GetAdaptersAddresses(family, 0, IntPtr.Zero, SafeLocalFree.Zero, ref outBufLen);

            while (num2 == 0x6f)
            {
                try
                {
                    adapterAddresses = SafeLocalFree.LocalAlloc((int)outBufLen);
                    num2             = UnsafeNetInfoNativeMethods.GetAdaptersAddresses(family, 0, IntPtr.Zero, adapterAddresses, ref outBufLen);
                    if (num2 == 0)
                    {
                        IpAdapterAddresses ipAdapterAddresses = (IpAdapterAddresses)Marshal.PtrToStructure(adapterAddresses.DangerousGetHandle(), typeof(IpAdapterAddresses));
                        list.Add(new SystemNetworkInterface(fixedInfo, ipAdapterAddresses));
                        while (ipAdapterAddresses.next != IntPtr.Zero)
                        {
                            ipAdapterAddresses = (IpAdapterAddresses)Marshal.PtrToStructure(ipAdapterAddresses.next, typeof(IpAdapterAddresses));
                            list.Add(new SystemNetworkInterface(fixedInfo, ipAdapterAddresses));
                        }
                    }
                    continue;
                }
                finally
                {
                    if (adapterAddresses != null)
                    {
                        adapterAddresses.Close();
                    }
                    adapterAddresses = null;
                }
            }
            switch (num2)
            {
            case 0xe8:
            case 0x57:
                return(new SystemNetworkInterface[0]);
            }
            if (num2 != 0)
            {
                throw new NetworkInformationException((int)num2);
            }
            interfaceArray = new SystemNetworkInterface[list.Count];
            for (int i = 0; i < list.Count; i++)
            {
                interfaceArray[i] = (SystemNetworkInterface)list[i];
            }
            return(interfaceArray);
        }
Пример #12
0
 private void GetIfEntry(long index)
 {
     if (index != 0L)
     {
         this.ifRow.dwIndex = (uint)index;
         uint ifEntry = UnsafeNetInfoNativeMethods.GetIfEntry(ref this.ifRow);
         if (ifEntry != 0)
         {
             throw new NetworkInformationException((int)ifEntry);
         }
     }
 }
        private static int GetBestInterfaceForAddress(IPAddress addr)
        {
            int           index;
            SocketAddress address = new SocketAddress(addr);
            int           error   = (int)UnsafeNetInfoNativeMethods.GetBestInterfaceEx(address.m_Buffer, out index);

            if (error != 0)
            {
                throw new NetworkInformationException(error);
            }

            return(index);
        }
        internal SystemIcmpV6Statistics()
        {
            if (!ComNetOS.IsPostWin2K)
            {
                throw new PlatformNotSupportedException(SR.GetString("WinXPRequired"));
            }
            uint icmpStatisticsEx = UnsafeNetInfoNativeMethods.GetIcmpStatisticsEx(out this.stats, AddressFamily.InterNetworkV6);

            if (icmpStatisticsEx != 0)
            {
                throw new NetworkInformationException((int)icmpStatisticsEx);
            }
        }
Пример #15
0
 private void OnStabilized(IntPtr context, IntPtr table)
 {
     UnsafeNetInfoNativeMethods.FreeMibTable(table);
     if (!this.runCallbackCalled)
     {
         lock (this)
         {
             if (!this.runCallbackCalled)
             {
                 this.runCallbackCalled = true;
                 ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(this.RunCallback), null);
             }
         }
     }
 }
        // Returns true if the address table is already stable.  Otherwise, calls callback when it becomes stable.
        // 'Unsafe' because it does not flow ExecutionContext to the callback.
        public static bool UnsafeNotifyStableUnicastIpAddressTable(Action <object> callback, object state)
        {
            GlobalLog.Assert(callback != null,
                             "UnsafeNotifyStableUnicastIpAddressTable called without specifying callback!");

            TeredoHelper helper = new TeredoHelper(callback, state);

            uint             err   = UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS;
            SafeFreeMibTable table = null;

            lock (pendingNotifications)
            {
                // If OnAppDomainUnload gets the lock first, tell our caller that we'll finish async.  Their AppDomain
                // is about to go down anyways.  If we do, hold the lock until we've added helper to the
                // pendingNotifications list (if we're going to complete asynchronously).
                if (impendingAppDomainUnload)
                {
                    return(false);
                }

                err = UnsafeNetInfoNativeMethods.NotifyStableUnicastIpAddressTable(AddressFamily.Unspecified,
                                                                                   out table, helper.onStabilizedDelegate, IntPtr.Zero, out helper.cancelHandle);

                if (table != null)
                {
                    table.Dispose();
                }

                if (err == UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
                {
                    GlobalLog.Assert(!helper.cancelHandle.IsInvalid,
                                     "CancelHandle invalid despite returning ERROR_IO_PENDING");

                    // Async completion: add us to the pendingNotifications list so we'll be canceled in the
                    // event of an AppDomain unload.
                    pendingNotifications.Add(helper);
                    return(false);
                }
            }

            if (err != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
            {
                throw new Win32Exception((int)err);
            }

            return(true);
        }
Пример #17
0
 private void GetPerAdapterInfo(uint index)
 {
     if (index != 0)
     {
         uint          pOutBufLen      = 0;
         SafeLocalFree pPerAdapterInfo = null;
         uint          num2            = UnsafeNetInfoNativeMethods.GetPerAdapterInfo(index, SafeLocalFree.Zero, ref pOutBufLen);
         while (num2 == 0x6f)
         {
             try
             {
                 pPerAdapterInfo = SafeLocalFree.LocalAlloc((int)pOutBufLen);
                 num2            = UnsafeNetInfoNativeMethods.GetPerAdapterInfo(index, pPerAdapterInfo, ref pOutBufLen);
                 if (num2 == 0)
                 {
                     IpPerAdapterInfo info = (IpPerAdapterInfo)Marshal.PtrToStructure(pPerAdapterInfo.DangerousGetHandle(), typeof(IpPerAdapterInfo));
                     this.autoConfigEnabled = info.autoconfigEnabled;
                     this.autoConfigActive  = info.autoconfigActive;
                     this.dnsAddresses      = info.dnsServerList.ToIPAddressCollection();
                 }
                 continue;
             }
             finally
             {
                 if (this.dnsAddresses == null)
                 {
                     this.dnsAddresses = new IPAddressCollection();
                 }
                 if (pPerAdapterInfo != null)
                 {
                     pPerAdapterInfo.Close();
                 }
             }
         }
         if (this.dnsAddresses == null)
         {
             this.dnsAddresses = new IPAddressCollection();
         }
         if (num2 != 0)
         {
             throw new NetworkInformationException((int)num2);
         }
     }
 }
        // This callback gets run on a native worker thread, which we don't want to allow arbitrary user code to
        // execute on (it will block AppDomain unload, for one).  Free the MibTable and delegate (exactly once)
        // to the managed ThreadPool for the rest of the processing.
        //
        // We can't use SafeHandle here for table because the marshaller doesn't support them in reverse p/invokes.
        // We won't get an AppDomain unload here anyways, because OnAppDomainUnloaded will block until all of these
        // callbacks are done.
        private void OnStabilized(IntPtr context, IntPtr table)
        {
            UnsafeNetInfoNativeMethods.FreeMibTable(table);

            // Lock the TeredoHelper instance to ensure that only the first call to OnStabilized will get to call
            // RunCallback.  This is the only place that TeredoHelpers get locked, as individual instances are not
            // exposed to higher layers, so there's no chance for deadlock.
            if (!runCallbackCalled)
            {
                lock (this)
                {
                    if (!runCallbackCalled)
                    {
                        runCallbackCalled = true;
                        ThreadPool.UnsafeQueueUserWorkItem(RunCallback, null);
                    }
                }
            }
        }
Пример #19
0
        internal SystemTcpStatistics(AddressFamily family)
        {
            uint tcpStatistics;

            if (!ComNetOS.IsPostWin2K)
            {
                if (family != AddressFamily.InterNetwork)
                {
                    throw new PlatformNotSupportedException(SR.GetString("WinXPRequired"));
                }
                tcpStatistics = UnsafeNetInfoNativeMethods.GetTcpStatistics(out this.stats);
            }
            else
            {
                tcpStatistics = UnsafeNetInfoNativeMethods.GetTcpStatisticsEx(out this.stats, family);
            }
            if (tcpStatistics != 0)
            {
                throw new NetworkInformationException((int)tcpStatistics);
            }
        }
        private void GetPerAdapterInfo(uint index)
        {
            if (index != 0)
            {
                uint          size   = 0;
                SafeLocalFree buffer = null;

                uint result = UnsafeNetInfoNativeMethods.GetPerAdapterInfo(index, SafeLocalFree.Zero, ref size);
                while (result == IpHelperErrors.ErrorBufferOverflow)
                {
                    try {
                        //now we allocate the buffer and read the network parameters.
                        buffer = SafeLocalFree.LocalAlloc((int)size);
                        result = UnsafeNetInfoNativeMethods.GetPerAdapterInfo(index, buffer, ref size);
                        if (result == IpHelperErrors.Success)
                        {
                            IpPerAdapterInfo ipPerAdapterInfo = (IpPerAdapterInfo)Marshal.PtrToStructure(buffer.DangerousGetHandle(), typeof(IpPerAdapterInfo));

                            autoConfigEnabled = ipPerAdapterInfo.autoconfigEnabled;
                            autoConfigActive  = ipPerAdapterInfo.autoconfigActive;
                        }
                    }
                    finally {
                        if (buffer != null)
                        {
                            buffer.Close();
                        }
                    }
                }

                if (result != IpHelperErrors.Success)
                {
                    throw new NetworkInformationException((int)result);
                }
            }
        }
        public override IPEndPoint[] GetActiveUdpListeners()
        {
            uint              dwOutBufLen = 0;
            uint              num2        = 0;
            SafeLocalFree     pUdpTable   = null;
            List <IPEndPoint> list        = new List <IPEndPoint>();

            if (Socket.OSSupportsIPv4)
            {
                num2 = UnsafeNetInfoNativeMethods.GetUdpTable(SafeLocalFree.Zero, ref dwOutBufLen, true);
                while (num2 == 0x7a)
                {
                    try
                    {
                        pUdpTable = SafeLocalFree.LocalAlloc((int)dwOutBufLen);
                        num2      = UnsafeNetInfoNativeMethods.GetUdpTable(pUdpTable, ref dwOutBufLen, true);
                        if (num2 == 0)
                        {
                            IntPtr      handle = pUdpTable.DangerousGetHandle();
                            MibUdpTable table  = (MibUdpTable)Marshal.PtrToStructure(handle, typeof(MibUdpTable));
                            if (table.numberOfEntries > 0)
                            {
                                handle = (IntPtr)(((long)handle) + Marshal.SizeOf(table.numberOfEntries));
                                for (int i = 0; i < table.numberOfEntries; i++)
                                {
                                    MibUdpRow structure = (MibUdpRow)Marshal.PtrToStructure(handle, typeof(MibUdpRow));
                                    int       port      = (structure.localPort1 << 8) | structure.localPort2;
                                    list.Add(new IPEndPoint((long)structure.localAddr, port));
                                    handle = (IntPtr)(((long)handle) + Marshal.SizeOf(structure));
                                }
                            }
                        }
                        continue;
                    }
                    finally
                    {
                        if (pUdpTable != null)
                        {
                            pUdpTable.Close();
                        }
                    }
                }
                if ((num2 != 0) && (num2 != 0xe8))
                {
                    throw new NetworkInformationException((int)num2);
                }
            }
            if (Socket.OSSupportsIPv6)
            {
                dwOutBufLen = 0;
                num2        = UnsafeNetInfoNativeMethods.GetExtendedUdpTable(SafeLocalFree.Zero, ref dwOutBufLen, true, 0x17, UdpTableClass.UdpTableOwnerPid, 0);
                while (num2 == 0x7a)
                {
                    try
                    {
                        pUdpTable = SafeLocalFree.LocalAlloc((int)dwOutBufLen);
                        num2      = UnsafeNetInfoNativeMethods.GetExtendedUdpTable(pUdpTable, ref dwOutBufLen, true, 0x17, UdpTableClass.UdpTableOwnerPid, 0);
                        if (num2 == 0)
                        {
                            IntPtr ptr = pUdpTable.DangerousGetHandle();
                            MibUdp6TableOwnerPid pid = (MibUdp6TableOwnerPid)Marshal.PtrToStructure(ptr, typeof(MibUdp6TableOwnerPid));
                            if (pid.numberOfEntries > 0)
                            {
                                ptr = (IntPtr)(((long)ptr) + Marshal.SizeOf(pid.numberOfEntries));
                                for (int j = 0; j < pid.numberOfEntries; j++)
                                {
                                    MibUdp6RowOwnerPid pid2 = (MibUdp6RowOwnerPid)Marshal.PtrToStructure(ptr, typeof(MibUdp6RowOwnerPid));
                                    int num6 = (pid2.localPort1 << 8) | pid2.localPort2;
                                    list.Add(new IPEndPoint(new IPAddress(pid2.localAddr, (long)pid2.localScopeId), num6));
                                    ptr = (IntPtr)(((long)ptr) + Marshal.SizeOf(pid2));
                                }
                            }
                        }
                        continue;
                    }
                    finally
                    {
                        if (pUdpTable != null)
                        {
                            pUdpTable.Close();
                        }
                    }
                }
                if ((num2 != 0) && (num2 != 0xe8))
                {
                    throw new NetworkInformationException((int)num2);
                }
            }
            return(list.ToArray());
        }
        /// <summary>Gets the active udp listeners. Uses the native GetUdpTable api.</summary>
        public override IPEndPoint[] GetActiveUdpListeners()
        {
            uint              size         = 0;
            uint              result       = 0;
            SafeLocalFree     buffer       = null;
            List <IPEndPoint> udpListeners = new List <IPEndPoint>();

            // Check if it support IPv4 for IPv6 only modes.
            if (Socket.OSSupportsIPv4)
            {
                // Get the size of buffer needed
                result = UnsafeNetInfoNativeMethods.GetUdpTable(SafeLocalFree.Zero, ref size, true);
                while (result == IpHelperErrors.ErrorInsufficientBuffer)
                {
                    try {
                        //allocate the buffer and get the udptable
                        buffer = SafeLocalFree.LocalAlloc((int)size);
                        result = UnsafeNetInfoNativeMethods.GetUdpTable(buffer, ref size, true);

                        if (result == IpHelperErrors.Success)
                        {
                            //the table info just gives us the number of rows.
                            IntPtr      newPtr       = buffer.DangerousGetHandle();
                            MibUdpTable udpTableInfo = (MibUdpTable)Marshal.PtrToStructure(newPtr, typeof(MibUdpTable));

                            if (udpTableInfo.numberOfEntries > 0)
                            {
                                //we need to skip over the tableinfo to get the inline rows
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(udpTableInfo.numberOfEntries));
                                for (int i = 0; i < udpTableInfo.numberOfEntries; i++)
                                {
                                    MibUdpRow udpRow    = (MibUdpRow)Marshal.PtrToStructure(newPtr, typeof(MibUdpRow));
                                    int       localPort = udpRow.localPort1 << 8 | udpRow.localPort2;

                                    udpListeners.Add(new IPEndPoint(udpRow.localAddr, (int)localPort));

                                    //we increment the pointer to the next row
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(udpRow));
                                }
                            }
                        }
                    }
                    finally {
                        if (buffer != null)
                        {
                            buffer.Close();
                        }
                    }
                }
                // if we don't have any ipv4 interfaces detected, just continue
                if (result != IpHelperErrors.Success && result != IpHelperErrors.ErrorNoData)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            if (Socket.OSSupportsIPv6)
            {
                // Get the size of buffer needed
                size   = 0;
                result = UnsafeNetInfoNativeMethods.GetExtendedUdpTable(SafeLocalFree.Zero, ref size, true,
                                                                        (uint)AddressFamily.InterNetworkV6,
                                                                        UdpTableClass.UdpTableOwnerPid, 0);
                while (result == IpHelperErrors.ErrorInsufficientBuffer)
                {
                    try {
                        // Allocate the buffer and get the udptable
                        buffer = SafeLocalFree.LocalAlloc((int)size);
                        result = UnsafeNetInfoNativeMethods.GetExtendedUdpTable(buffer, ref size, true,
                                                                                (uint)AddressFamily.InterNetworkV6,
                                                                                UdpTableClass.UdpTableOwnerPid, 0);

                        if (result == IpHelperErrors.Success)
                        {
                            // The table info just gives us the number of rows.
                            IntPtr newPtr = buffer.DangerousGetHandle();
                            MibUdp6TableOwnerPid udp6TableOwnerPid
                                = (MibUdp6TableOwnerPid)Marshal.PtrToStructure(newPtr, typeof(MibUdp6TableOwnerPid));

                            if (udp6TableOwnerPid.numberOfEntries > 0)
                            {
                                // We need to skip over the tableinfo to get the inline rows
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(udp6TableOwnerPid.numberOfEntries));
                                for (int i = 0; i < udp6TableOwnerPid.numberOfEntries; i++)
                                {
                                    MibUdp6RowOwnerPid udp6RowOwnerPid
                                        = (MibUdp6RowOwnerPid)Marshal.PtrToStructure(newPtr,
                                                                                     typeof(MibUdp6RowOwnerPid));
                                    int localPort = udp6RowOwnerPid.localPort1 << 8 | udp6RowOwnerPid.localPort2;

                                    udpListeners.Add(new IPEndPoint(new IPAddress(udp6RowOwnerPid.localAddr,
                                                                                  udp6RowOwnerPid.localScopeId), localPort));

                                    // We increment the pointer to the next row
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(udp6RowOwnerPid));
                                }
                            }
                        }
                    }
                    finally {
                        if (buffer != null)
                        {
                            buffer.Close();
                        }
                    }
                }
                // If we don't have any ipv6 interfaces detected, just continue
                if (result != IpHelperErrors.Success && result != IpHelperErrors.ErrorNoData)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            return(udpListeners.ToArray());
        }
Пример #23
0
        // internal method responsible for sending echo request on win2k and higher

        private PingReply InternalSend(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool async)
        {
            ipv6     = (address.AddressFamily == AddressFamily.InterNetworkV6)?true:false;
            sendSize = buffer.Length;

            //get and cache correct handle
            if (!ipv6 && handlePingV4 == null)
            {
                handlePingV4 = UnsafeNetInfoNativeMethods.IcmpCreateFile();
                if (handlePingV4.IsInvalid)
                {
                    handlePingV4 = null;
                    throw new Win32Exception(); // Gets last error
                }
            }
            else if (ipv6 && handlePingV6 == null)
            {
                handlePingV6 = UnsafeNetInfoNativeMethods.Icmp6CreateFile();
                if (handlePingV6.IsInvalid)
                {
                    handlePingV6 = null;
                    throw new Win32Exception(); // Gets last error
                }
            }


            //setup the options
            IPOptions ipOptions = new IPOptions(options);

            //setup the reply buffer
            if (replyBuffer == null)
            {
                replyBuffer = SafeLocalFree.LocalAlloc(MaxUdpPacket);
            }

            //queue the event
            int error;

            try
            {
                if (async)
                {
                    if (pingEvent == null)
                    {
                        pingEvent = new ManualResetEvent(false);
                    }
                    else
                    {
                        pingEvent.Reset();
                    }

                    registeredWait = ThreadPool.RegisterWaitForSingleObject(pingEvent, new WaitOrTimerCallback(PingCallback), this, -1, true);
                }

                //Copy user dfata into the native world
                SetUnmanagedStructures(buffer);

                if (!ipv6)
                {
                    if (async)
                    {
                        error = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2(handlePingV4, pingEvent.SafeWaitHandle, IntPtr.Zero, IntPtr.Zero, (uint)address.m_Address, requestBuffer, (ushort)buffer.Length, ref ipOptions, replyBuffer, MaxUdpPacket, (uint)timeout);
                    }
                    else
                    {
                        error = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2(handlePingV4, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)address.m_Address, requestBuffer, (ushort)buffer.Length, ref ipOptions, replyBuffer, MaxUdpPacket, (uint)timeout);
                    }
                }
                else
                {
                    IPEndPoint    ep         = new IPEndPoint(address, 0);
                    SocketAddress remoteAddr = ep.Serialize();
                    byte[]        sourceAddr = new byte[28];
                    if (async)
                    {
                        error = (int)UnsafeNetInfoNativeMethods.Icmp6SendEcho2(handlePingV6, pingEvent.SafeWaitHandle, IntPtr.Zero, IntPtr.Zero, sourceAddr, remoteAddr.m_Buffer, requestBuffer, (ushort)buffer.Length, ref ipOptions, replyBuffer, MaxUdpPacket, (uint)timeout);
                    }
                    else
                    {
                        error = (int)UnsafeNetInfoNativeMethods.Icmp6SendEcho2(handlePingV6, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, sourceAddr, remoteAddr.m_Buffer, requestBuffer, (ushort)buffer.Length, ref ipOptions, replyBuffer, MaxUdpPacket, (uint)timeout);
                    }
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            //need this if something is bogus.
            if (error == 0)
            {
                error = (int)Marshal.GetLastWin32Error();

                // Only skip Async IO Pending error value
                if (async && error == UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
                {
                    return(null); // Expected async return value
                }
                // Cleanup
                FreeUnmanagedStructures();
                UnregisterWaitHandle();

                if (async || // No IPStatus async errors
                    error < (int)IPStatus.DestinationNetworkUnreachable || // Min
                    error > (int)IPStatus.DestinationScopeMismatch)    // Max // Out of IPStatus range
                {
                    throw new Win32Exception(error);
                }

                return(new PingReply((IPStatus)error)); // Synchronous IPStatus errors
            }

            if (async)
            {
                return(null);
            }

            FreeUnmanagedStructures();

            //return the reply
            PingReply reply;

            if (ipv6)
            {
                Icmp6EchoReply icmp6Reply = (Icmp6EchoReply)Marshal.PtrToStructure(replyBuffer.DangerousGetHandle(), typeof(Icmp6EchoReply));
                reply = new PingReply(icmp6Reply, replyBuffer.DangerousGetHandle(), sendSize);
            }
            else
            {
                IcmpEchoReply icmpReply = (IcmpEchoReply)Marshal.PtrToStructure(replyBuffer.DangerousGetHandle(), typeof(IcmpEchoReply));
                reply = new PingReply(icmpReply);
            }

            // IcmpEchoReply still has an unsafe IntPtr reference into replybuffer
            // and replybuffer was being freed prematurely by the GC, causing AccessViolationExceptions.
            GC.KeepAlive(replyBuffer);

            return(reply);
        }
Пример #24
0
        private PingReply InternalSend(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool async)
        {
            int       num;
            PingReply reply;

            this.ipv6     = address.AddressFamily == AddressFamily.InterNetworkV6;
            this.sendSize = buffer.Length;
            if (!this.ipv6 && (this.handlePingV4 == null))
            {
                this.handlePingV4 = UnsafeNetInfoNativeMethods.IcmpCreateFile();
                if (this.handlePingV4.IsInvalid)
                {
                    this.handlePingV4 = null;
                    throw new Win32Exception();
                }
            }
            else if (this.ipv6 && (this.handlePingV6 == null))
            {
                this.handlePingV6 = UnsafeNetInfoNativeMethods.Icmp6CreateFile();
                if (this.handlePingV6.IsInvalid)
                {
                    this.handlePingV6 = null;
                    throw new Win32Exception();
                }
            }
            IPOptions options2 = new IPOptions(options);

            if (this.replyBuffer == null)
            {
                this.replyBuffer = SafeLocalFree.LocalAlloc(0x100ff);
            }
            try
            {
                if (async)
                {
                    if (this.pingEvent == null)
                    {
                        this.pingEvent = new ManualResetEvent(false);
                    }
                    else
                    {
                        this.pingEvent.Reset();
                    }
                    this.registeredWait = ThreadPool.RegisterWaitForSingleObject(this.pingEvent, new WaitOrTimerCallback(Ping.PingCallback), this, -1, true);
                }
                this.SetUnmanagedStructures(buffer);
                if (!this.ipv6)
                {
                    if (async)
                    {
                        num = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2(this.handlePingV4, this.pingEvent.SafeWaitHandle, IntPtr.Zero, IntPtr.Zero, (uint)address.m_Address, this.requestBuffer, (ushort)buffer.Length, ref options2, this.replyBuffer, 0x100ff, (uint)timeout);
                    }
                    else
                    {
                        num = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2(this.handlePingV4, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)address.m_Address, this.requestBuffer, (ushort)buffer.Length, ref options2, this.replyBuffer, 0x100ff, (uint)timeout);
                    }
                }
                else
                {
                    SocketAddress address2            = new IPEndPoint(address, 0).Serialize();
                    byte[]        sourceSocketAddress = new byte[0x1c];
                    if (async)
                    {
                        num = (int)UnsafeNetInfoNativeMethods.Icmp6SendEcho2(this.handlePingV6, this.pingEvent.SafeWaitHandle, IntPtr.Zero, IntPtr.Zero, sourceSocketAddress, address2.m_Buffer, this.requestBuffer, (ushort)buffer.Length, ref options2, this.replyBuffer, 0x100ff, (uint)timeout);
                    }
                    else
                    {
                        num = (int)UnsafeNetInfoNativeMethods.Icmp6SendEcho2(this.handlePingV6, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, sourceSocketAddress, address2.m_Buffer, this.requestBuffer, (ushort)buffer.Length, ref options2, this.replyBuffer, 0x100ff, (uint)timeout);
                    }
                }
            }
            catch
            {
                this.UnregisterWaitHandle();
                throw;
            }
            if (num == 0)
            {
                num = Marshal.GetLastWin32Error();
                if (async && (num == 0x3e5L))
                {
                    return(null);
                }
                this.FreeUnmanagedStructures();
                this.UnregisterWaitHandle();
                if ((async || (num < 0x2afa)) || (num > 0x2b25))
                {
                    throw new Win32Exception(num);
                }
                return(new PingReply((IPStatus)num));
            }
            if (async)
            {
                return(null);
            }
            this.FreeUnmanagedStructures();
            if (this.ipv6)
            {
                Icmp6EchoReply reply2 = (Icmp6EchoReply)Marshal.PtrToStructure(this.replyBuffer.DangerousGetHandle(), typeof(Icmp6EchoReply));
                reply = new PingReply(reply2, this.replyBuffer.DangerousGetHandle(), this.sendSize);
            }
            else
            {
                IcmpEchoReply reply3 = (IcmpEchoReply)Marshal.PtrToStructure(this.replyBuffer.DangerousGetHandle(), typeof(IcmpEchoReply));
                reply = new PingReply(reply3);
            }
            GC.KeepAlive(this.replyBuffer);
            return(reply);
        }
        private static SystemNetworkInterface[] PostWin2KGetNetworkInterfaces(AddressFamily family)
        {
            FixedInfo fixedInfo = SystemIPGlobalProperties.GetFixedInfo();

            SystemNetworkInterface[] adaptersAddresses = null;
Label_0008:
            try
            {
                adaptersAddresses = GetAdaptersAddresses(family, fixedInfo);
            }
            catch (NetworkInformationException exception)
            {
                if (exception.ErrorCode != 1L)
                {
                    throw;
                }
                goto Label_0008;
            }
            if (Socket.OSSupportsIPv4)
            {
                uint          pOutBufLen   = 0;
                uint          adaptersInfo = 0;
                SafeLocalFree pAdapterInfo = null;
                if ((family == AddressFamily.Unspecified) || (family == AddressFamily.InterNetwork))
                {
                    adaptersInfo = UnsafeNetInfoNativeMethods.GetAdaptersInfo(SafeLocalFree.Zero, ref pOutBufLen);
                    int num3 = 0;
                    while (adaptersInfo == 0x6f)
                    {
                        try
                        {
                            pAdapterInfo = SafeLocalFree.LocalAlloc((int)pOutBufLen);
                            adaptersInfo = UnsafeNetInfoNativeMethods.GetAdaptersInfo(pAdapterInfo, ref pOutBufLen);
                            if (adaptersInfo == 0)
                            {
                                IntPtr handle = pAdapterInfo.DangerousGetHandle();
                                while (handle != IntPtr.Zero)
                                {
                                    IpAdapterInfo ipAdapterInfo = (IpAdapterInfo)Marshal.PtrToStructure(handle, typeof(IpAdapterInfo));
                                    for (int i = 0; i < adaptersAddresses.Length; i++)
                                    {
                                        if ((adaptersAddresses[i] != null) && (ipAdapterInfo.index == adaptersAddresses[i].index))
                                        {
                                            if (!adaptersAddresses[i].interfaceProperties.Update(fixedInfo, ipAdapterInfo))
                                            {
                                                adaptersAddresses[i] = null;
                                                num3++;
                                            }
                                            break;
                                        }
                                    }
                                    handle = ipAdapterInfo.Next;
                                }
                            }
                            continue;
                        }
                        finally
                        {
                            if (pAdapterInfo != null)
                            {
                                pAdapterInfo.Close();
                            }
                        }
                    }
                    if (num3 != 0)
                    {
                        SystemNetworkInterface[] interfaceArray2 = new SystemNetworkInterface[adaptersAddresses.Length - num3];
                        int num5 = 0;
                        for (int j = 0; j < adaptersAddresses.Length; j++)
                        {
                            if (adaptersAddresses[j] != null)
                            {
                                interfaceArray2[num5++] = adaptersAddresses[j];
                            }
                        }
                        adaptersAddresses = interfaceArray2;
                    }
                }
                if ((adaptersInfo != 0) && (adaptersInfo != 0xe8))
                {
                    throw new NetworkInformationException((int)adaptersInfo);
                }
            }
            return(adaptersAddresses);
        }
        /// <summary>
        /// Gets the active tcp connections. Uses the native GetTcpTable api.</summary>
        private List <SystemTcpConnectionInformation> GetAllTcpConnections()
        {
            uint          size   = 0;
            uint          result = 0;
            SafeLocalFree buffer = null;
            List <SystemTcpConnectionInformation> tcpConnections = new List <SystemTcpConnectionInformation>();

            // Check if it supports IPv4 for IPv6 only modes.
            if (Socket.OSSupportsIPv4)
            {
                // Get the size of buffer needed
                result = UnsafeNetInfoNativeMethods.GetTcpTable(SafeLocalFree.Zero, ref size, true);

                while (result == IpHelperErrors.ErrorInsufficientBuffer)
                {
                    try {
                        //allocate the buffer and get the tcptable
                        buffer = SafeLocalFree.LocalAlloc((int)size);
                        result = UnsafeNetInfoNativeMethods.GetTcpTable(buffer, ref size, true);

                        if (result == IpHelperErrors.Success)
                        {
                            //the table info just gives us the number of rows.
                            IntPtr      newPtr       = buffer.DangerousGetHandle();
                            MibTcpTable tcpTableInfo = (MibTcpTable)Marshal.PtrToStructure(newPtr, typeof(MibTcpTable));

                            if (tcpTableInfo.numberOfEntries > 0)
                            {
                                //we need to skip over the tableinfo to get the inline rows
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpTableInfo.numberOfEntries));

                                for (int i = 0; i < tcpTableInfo.numberOfEntries; i++)
                                {
                                    MibTcpRow tcpRow = (MibTcpRow)Marshal.PtrToStructure(newPtr, typeof(MibTcpRow));
                                    tcpConnections.Add(new SystemTcpConnectionInformation(tcpRow));

                                    //we increment the pointer to the next row
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpRow));
                                }
                            }
                        }
                    }
                    finally {
                        if (buffer != null)
                        {
                            buffer.Close();
                        }
                    }
                }

                // if we don't have any ipv4 interfaces detected, just continue
                if (result != IpHelperErrors.Success && result != IpHelperErrors.ErrorNoData)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            if (Socket.OSSupportsIPv6)
            {
                // IPv6 tcp connections
                // Get the size of buffer needed
                size   = 0;
                result = UnsafeNetInfoNativeMethods.GetExtendedTcpTable(SafeLocalFree.Zero, ref size, true,
                                                                        (uint)AddressFamily.InterNetworkV6,
                                                                        TcpTableClass.TcpTableOwnerPidAll, 0);

                while (result == IpHelperErrors.ErrorInsufficientBuffer)
                {
                    try {
                        // Allocate the buffer and get the tcptable
                        buffer = SafeLocalFree.LocalAlloc((int)size);
                        result = UnsafeNetInfoNativeMethods.GetExtendedTcpTable(buffer, ref size, true,
                                                                                (uint)AddressFamily.InterNetworkV6,
                                                                                TcpTableClass.TcpTableOwnerPidAll, 0);
                        if (result == IpHelperErrors.Success)
                        {
                            // The table info just gives us the number of rows.
                            IntPtr newPtr = buffer.DangerousGetHandle();

                            MibTcp6TableOwnerPid tcpTable6OwnerPid
                                = (MibTcp6TableOwnerPid)Marshal.PtrToStructure(newPtr, typeof(MibTcp6TableOwnerPid));

                            if (tcpTable6OwnerPid.numberOfEntries > 0)
                            {
                                // We need to skip over the tableinfo to get the inline rows
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpTable6OwnerPid.numberOfEntries));

                                for (int i = 0; i < tcpTable6OwnerPid.numberOfEntries; i++)
                                {
                                    MibTcp6RowOwnerPid tcp6RowOwnerPid
                                        = (MibTcp6RowOwnerPid)Marshal.PtrToStructure(newPtr,
                                                                                     typeof(MibTcp6RowOwnerPid));
                                    tcpConnections.Add(new SystemTcpConnectionInformation(tcp6RowOwnerPid));

                                    // We increment the pointer to the next row
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcp6RowOwnerPid));
                                }
                            }
                        }
                    }
                    finally {
                        if (buffer != null)
                        {
                            buffer.Close();
                        }
                    }
                }

                // If we don't have any ipv6 interfaces detected, just continue
                if (result != IpHelperErrors.Success && result != IpHelperErrors.ErrorNoData)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            return(tcpConnections);
        }
        private List <SystemTcpConnectionInformation> GetAllTcpConnections()
        {
            uint          dwOutBufLen = 0;
            uint          num2        = 0;
            SafeLocalFree pTcpTable   = null;
            List <SystemTcpConnectionInformation> list = new List <SystemTcpConnectionInformation>();

            if (Socket.OSSupportsIPv4)
            {
                num2 = UnsafeNetInfoNativeMethods.GetTcpTable(SafeLocalFree.Zero, ref dwOutBufLen, true);
                while (num2 == 0x7a)
                {
                    try
                    {
                        pTcpTable = SafeLocalFree.LocalAlloc((int)dwOutBufLen);
                        num2      = UnsafeNetInfoNativeMethods.GetTcpTable(pTcpTable, ref dwOutBufLen, true);
                        if (num2 == 0)
                        {
                            IntPtr      handle = pTcpTable.DangerousGetHandle();
                            MibTcpTable table  = (MibTcpTable)Marshal.PtrToStructure(handle, typeof(MibTcpTable));
                            if (table.numberOfEntries > 0)
                            {
                                handle = (IntPtr)(((long)handle) + Marshal.SizeOf(table.numberOfEntries));
                                for (int i = 0; i < table.numberOfEntries; i++)
                                {
                                    MibTcpRow row = (MibTcpRow)Marshal.PtrToStructure(handle, typeof(MibTcpRow));
                                    list.Add(new SystemTcpConnectionInformation(row));
                                    handle = (IntPtr)(((long)handle) + Marshal.SizeOf(row));
                                }
                            }
                        }
                        continue;
                    }
                    finally
                    {
                        if (pTcpTable != null)
                        {
                            pTcpTable.Close();
                        }
                    }
                }
                if ((num2 != 0) && (num2 != 0xe8))
                {
                    throw new NetworkInformationException((int)num2);
                }
            }
            if (Socket.OSSupportsIPv6)
            {
                dwOutBufLen = 0;
                num2        = UnsafeNetInfoNativeMethods.GetExtendedTcpTable(SafeLocalFree.Zero, ref dwOutBufLen, true, 0x17, TcpTableClass.TcpTableOwnerPidAll, 0);
                while (num2 == 0x7a)
                {
                    try
                    {
                        pTcpTable = SafeLocalFree.LocalAlloc((int)dwOutBufLen);
                        num2      = UnsafeNetInfoNativeMethods.GetExtendedTcpTable(pTcpTable, ref dwOutBufLen, true, 0x17, TcpTableClass.TcpTableOwnerPidAll, 0);
                        if (num2 == 0)
                        {
                            IntPtr ptr = pTcpTable.DangerousGetHandle();
                            MibTcp6TableOwnerPid pid = (MibTcp6TableOwnerPid)Marshal.PtrToStructure(ptr, typeof(MibTcp6TableOwnerPid));
                            if (pid.numberOfEntries > 0)
                            {
                                ptr = (IntPtr)(((long)ptr) + Marshal.SizeOf(pid.numberOfEntries));
                                for (int j = 0; j < pid.numberOfEntries; j++)
                                {
                                    MibTcp6RowOwnerPid pid2 = (MibTcp6RowOwnerPid)Marshal.PtrToStructure(ptr, typeof(MibTcp6RowOwnerPid));
                                    list.Add(new SystemTcpConnectionInformation(pid2));
                                    ptr = (IntPtr)(((long)ptr) + Marshal.SizeOf(pid2));
                                }
                            }
                        }
                        continue;
                    }
                    finally
                    {
                        if (pTcpTable != null)
                        {
                            pTcpTable.Close();
                        }
                    }
                }
                if ((num2 != 0) && (num2 != 0xe8))
                {
                    throw new NetworkInformationException((int)num2);
                }
            }
            return(list);
        }
 protected override bool ReleaseHandle()
 {
     UnsafeNetInfoNativeMethods.FreeMibTable(base.handle);
     base.handle = IntPtr.Zero;
     return(true);
 }
        internal static NetworkInterface[] GetNetworkInterfaces()
        {
            Contract.Ensures(Contract.Result <NetworkInterface[]>() != null);
            AddressFamily family     = AddressFamily.Unspecified;
            uint          bufferSize = 0;
            SafeLocalFree buffer     = null;
            FixedInfo     fixedInfo  = SystemIPGlobalProperties.GetFixedInfo();
            List <SystemNetworkInterface> interfaceList = new List <SystemNetworkInterface>();

            GetAdaptersAddressesFlags flags =
                GetAdaptersAddressesFlags.IncludeGateways
                | GetAdaptersAddressesFlags.IncludeWins;

            // Figure out the right buffer size for the adapter information
            uint result = UnsafeNetInfoNativeMethods.GetAdaptersAddresses(
                family, (uint)flags, IntPtr.Zero, SafeLocalFree.Zero, ref bufferSize);

            while (result == IpHelperErrors.ErrorBufferOverflow)
            {
                try {
                    // Allocate the buffer and get the adapter info
                    buffer = SafeLocalFree.LocalAlloc((int)bufferSize);
                    result = UnsafeNetInfoNativeMethods.GetAdaptersAddresses(
                        family, (uint)flags, IntPtr.Zero, buffer, ref bufferSize);

                    // If succeeded, we're going to add each new interface
                    if (result == IpHelperErrors.Success)
                    {
                        // Linked list of interfaces
                        IntPtr ptr = buffer.DangerousGetHandle();
                        while (ptr != IntPtr.Zero)
                        {
                            // Traverse the list, marshal in the native structures, and create new NetworkInterfaces
                            IpAdapterAddresses adapterAddresses =
                                (IpAdapterAddresses)Marshal.PtrToStructure(ptr, typeof(IpAdapterAddresses));
                            interfaceList.Add(new SystemNetworkInterface(fixedInfo, adapterAddresses));

                            ptr = adapterAddresses.next;
                        }
                    }
                }
                finally {
                    if (buffer != null)
                    {
                        buffer.Close();
                    }
                    buffer = null;
                }
            }

            // if we don't have any interfaces detected, return empty.
            if (result == IpHelperErrors.ErrorNoData || result == IpHelperErrors.ErrorInvalidParameter)
            {
                return(new SystemNetworkInterface[0]);
            }

            // Otherwise we throw on an error
            if (result != IpHelperErrors.Success)
            {
                throw new NetworkInformationException((int)result);
            }

            return(interfaceList.ToArray());
        }