예제 #1
0
        private IList <IPAddress> GetIpAddresses(Sockaddr ipSockaddr, Sockaddr maskSockaddr)
        {
            var ipAddresses           = new List <IPAddress>();
            var ipAddressBytes        = ipSockaddr.ipAddress.GetAddressBytes();
            var networkMaskBytes      = maskSockaddr.ipAddress.GetAddressBytes();
            var subnetAddressBytes    = new byte[ipAddressBytes.Length];
            var broadcastAddressBytes = new byte[ipAddressBytes.Length];

            for (int i = 0; i < ipAddressBytes.Length; i++)
            {
                subnetAddressBytes[i] = (byte)(ipAddressBytes[i] & networkMaskBytes[i]);
            }

            for (int i = 0; i < ipAddressBytes.Length; i++)
            {
                broadcastAddressBytes[i] = (byte)(subnetAddressBytes[i] | (networkMaskBytes[i] ^ 0xFF));
            }

            var subnetAddress    = new IPAddress(subnetAddressBytes);
            var broadcastAddress = new IPAddress(broadcastAddressBytes);
            var currentIpAddress = new IPAddress(subnetAddressBytes);

            do
            {
                currentIpAddress = this.GetNextIpAddress(currentIpAddress, 1);
                ipAddresses.Add(currentIpAddress);
            } while (currentIpAddress.ToString() != broadcastAddress.ToString());

            return(ipAddresses);
        }
예제 #2
0
        public void SockaddrInTest()
        {
            var address1 = new SockaddrIn {
                sin_family = UnixAddressFamily.AF_INET,
                sin_port   = Syscall.htons(5678),
                sin_addr   = NativeConvert.ToInAddr(IPAddress.Loopback),
            };

            var storage  = address1.ToSockaddrStorage();
            var address2 = SockaddrIn.FromSockaddrStorage(storage);

            Assert.AreEqual(address1, address2);

            var sockaddr = Sockaddr.FromSockaddrStorage(storage);

            Assert.AreEqual(sockaddr.sa_family, address1.sa_family);

            var storage2 = storage.ToSockaddrStorage();

            Assert.AreEqual(storage, storage2);

            var storage3 = new SockaddrStorage(123);

            storage2.CopyTo(storage3);
            Assert.AreEqual(storage, storage3);

            Assert.AreEqual("{sin_family=AF_INET, sin_port=htons(5678), sin_addr=127.0.0.1}", address1.ToString());
        }
예제 #3
0
        public void SockaddrIn6Test()
        {
            if (!Socket.OSSupportsIPv6)
            {
                Assert.Ignore("OS does not support IPv6.");
            }

            var address1 = new SockaddrIn6 {
                sin6_family   = UnixAddressFamily.AF_INET6,
                sin6_port     = Syscall.htons(1234),
                sin6_flowinfo = 2,
                sin6_addr     = NativeConvert.ToIn6Addr(IPAddress.IPv6Loopback),
                sin6_scope_id = 3
            };

            var storage  = address1.ToSockaddrStorage();
            var address2 = SockaddrIn6.FromSockaddrStorage(storage);

            Assert.AreEqual(address1, address2);

            var sockaddr = Sockaddr.FromSockaddrStorage(storage);

            Assert.AreEqual(sockaddr.sa_family, address1.sa_family);

            Assert.AreEqual("{sin6_family=AF_INET6, sin6_port=htons(1234), sin6_flowinfo=2, sin6_addr=::1, sin6_scope_id=3}", address1.ToString());
        }
예제 #4
0
        public void IPv6()
        {
            if (!Socket.OSSupportsIPv6)
            {
                Assert.Ignore("OS does not support IPv6.");
            }

            var address = new SockaddrIn6 {
                sin6_family = UnixAddressFamily.AF_INET6,
                sin6_port   = Syscall.htons(0),
                sin6_addr   = NativeConvert.ToIn6Addr(IPAddress.IPv6Loopback),
            };

            WithSockets(UnixAddressFamily.AF_INET6, UnixSocketType.SOCK_STREAM, 0, (so1, so2) => {
                if (Syscall.bind(so1, address) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                var address1Stor = new SockaddrStorage();
                if (Syscall.getsockname(so1, address1Stor) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                var address1 = new SockaddrIn6();
                address1Stor.CopyTo(address1);

                // Check getsockname(socket, null)
                if (Syscall.getsockname(so1, null) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                var address2 = new SockaddrIn6();
                if (Syscall.getsockname(so1, address2) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                Assert.AreEqual(address1, address2);
                Assert.IsTrue(Syscall.ntohs(address1.sin6_port) != 0);
                address1.sin6_port = 0;
                Assert.AreEqual(address, address1);

                var address3 = new Sockaddr();
                if (Syscall.getsockname(so1, address3) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(address.sa_family, address3.sa_family);

                // Try to store a sockaddr_in6 into a Sockaddr. Should fail because sockaddr_in6 should be larger than sockaddr_in
                var address4 = new SockaddrIn();
                if (Syscall.getsockname(so1, address4) == 0)
                {
                    Assert.Fail("getsockname() should have failed");
                }
                Assert.AreEqual(Errno.ENOBUFS, Stdlib.GetLastError());
            });
        }
예제 #5
0
        public static bool TryDeleteDomainSocket(Sockaddr servaddr, string path)
        {
            // Make sure we only proceed with a potential domain socket entry
            if (!string.IsNullOrWhiteSpace(path) && File.Exists(path) && new FileInfo(path).Length == 0)
            {
                // Ensure that no other process is using the socket
                var csock = Syscall.socket(UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0);
                var ret   = Syscall.connect(csock, servaddr);
                Syscall.close(csock);

                // If we cannot connect, assume it is broken
                if (ret != 0)
                {
                    // Try to remove the file
                    var failed = false;
                    try { File.Delete(path); }
                    catch { failed = true; }

                    // If the file is removed, try binding again
                    return(!failed);
                }
            }

            return(false);
        }
        private WinPcapDevice getWinPcapDeviceByIP(string ip)
        {
            // Retrieve the device list
            var devices = WinPcapDeviceList.Instance;

            // If no devices were found print an error
            if (devices.Count < 1)
            {
                Console.WriteLine("No devices were found on this machine");
                return(null);
            }

            // Find WinPcapDevice that contains input IP address
            foreach (WinPcapDevice device in devices)
            {
                ReadOnlyCollection <PcapAddress> addresses = device.Addresses;
                foreach (var pcapAddr in addresses)
                {
                    Sockaddr addr = pcapAddr.Addr;
                    if (addr.ToString() == ip)
                    {
                        return(device);
                    }
                }
            }

            return(null);
        }
예제 #7
0
        private void SendARPIps(IPAddress ip, Sockaddr netmask)
        {
            IPAddress firstIP = new IPAddress(ip.Address & netmask.ipAddress.Address);
            IPAddress lastIP  = new IPAddress((uint)((int)ip.Address | (int)~netmask.ipAddress.Address));

            SendARPIps(firstIP, lastIP);
        }
예제 #8
0
        private void HostDiscoveryArpIpRange(IPAddress ipFrom, IPAddress ipTo)
        {
            IPAddress localIpv4 = Program.CurrentProject.data.GetIPv4FromDevice(Program.CurrentProject.data.GetDevice());

            if ((Program.CurrentProject.data.GetDevice() == null) || (localIpv4 == null))
            {
#if DEBUG
                MessageBox.Show("Debug: La interfaz no tiene dirección IPv4", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
#endif
                return;
            }

            Sockaddr netmask = Program.CurrentProject.data.GetNetmaskFromIP(Program.CurrentProject.data.GetDevice(), localIpv4);
            SendARPIps(ipFrom, ipTo);
        }
예제 #9
0
        public static unsafe bool TryCopy(IntPtr source, long size, Sockaddr destination)
        {
            if (destination == null)
            {
                throw new ArgumentNullException("destination");
            }
            byte[] array = Sockaddr.GetDynamicData(destination);
            fixed(SockaddrType *addr = &Sockaddr.GetAddress (destination).type)
            fixed(byte *data = Sockaddr.GetDynamicData(destination))
            {
                var dyn = new _SockaddrDynamic(destination, data, useMaxLength: true);
                var r   = ToSockaddr(source, size, Sockaddr.GetNative(&dyn, addr));

                dyn.Update(destination);
                // SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place
                if (r == 0 && destination.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped))
                {
                    Marshal.Copy(source, array, 0, (int)destination.GetDynamicLength());
                }
                return(r == 0);
            }
        }
예제 #10
0
        public static unsafe bool TryCopy(Sockaddr source, IntPtr destination)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            byte[] array = Sockaddr.GetDynamicData(source);
            // SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place
            if (source.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped))
            {
                Marshal.Copy(array, 0, destination, (int)source.GetDynamicLength());
                return(true);
            }

            fixed(SockaddrType *addr = &Sockaddr.GetAddress (source).type)
            fixed(byte *data = array)
            {
                var dyn = new _SockaddrDynamic(source, data, useMaxLength: false);

                return(FromSockaddr(Sockaddr.GetNative(&dyn, addr), destination) == 0);
            }
        }
예제 #11
0
        public int OnReadReady()
        {
            int ret = 0;

            while (ret >= 0)
            {
                // Try to read; we a non-blocking
                var addr = new Sockaddr();
                ret = Syscall.accept4(listenerSocket, addr, UnixSocketFlags.SOCK_NONBLOCK);

                // If we did not get a socket
                if (ret < 0)
                {
                    var errno = Stdlib.GetLastError();
                    if (errno == Errno.EAGAIN || errno == Errno.EWOULDBLOCK)
                    {
                        return(1);
                    }
                    Log.Error($"Failed to accept socket: {errno}");
                    return(-1);
                }

                // got a new socket, create a new connection
                if (ret >= 0)
                {
                    var socketHandle = ret;
                    Log.Epoll("Accepted socket {0}", socketHandle);
                    var handler = server.GetHandler(ret);
                    handler.OnAttach(socketHandle);

                    // subsctibe the new socket to Epoll events
                    Add(socketHandle, handler.GetEvents());
                }
            }
            return(1);
        }
예제 #12
0
        public void SockaddrUnTest()
        {
            var address1 = new SockaddrUn("/tmp/foo");

            Assert.AreEqual(address1.Path, "/tmp/foo");
            Assert.IsFalse(address1.IsLinuxAbstractNamespace);

            var storage  = address1.ToSockaddrStorage();
            var address2 = SockaddrUn.FromSockaddrStorage(storage);

            Assert.AreEqual(address1, address2);

            var sockaddr = Sockaddr.FromSockaddrStorage(storage);

            Assert.AreEqual(sockaddr.sa_family, address1.sa_family);

            var address3 = new SockaddrUn("/tmp/bar", linuxAbstractNamespace: true);

            Assert.AreEqual(address3.Path, "/tmp/bar");
            Assert.IsTrue(address3.IsLinuxAbstractNamespace);

            var address4 = new SockaddrUn(new string ('X', 9000));

            Assert.AreEqual(address4.Path, new string ('X', 9000));
            Assert.IsFalse(address4.IsLinuxAbstractNamespace);
            var storage2 = address4.ToSockaddrStorage();
            var address5 = SockaddrUn.FromSockaddrStorage(storage2);

            Assert.AreEqual(address4, address5);
            // Test the malloc() path for long SockaddrUn adresses (the syscalls will fail because the fd is invalid and because the path is too long)
            Syscall.bind(-1, address4);
            Syscall.getsockname(-1, address4);

            Assert.AreEqual("{sa_family=AF_UNIX, sun_path=\"/tmp/foo\"}", address1.ToString());
            Assert.AreEqual("{sa_family=AF_UNIX, sun_path=\"\\0/tmp/bar\"}", address3.ToString());
        }
예제 #13
0
        /// <summary>
        /// Waits for a connection and accepts the socket
        /// </summary>
        /// <returns>The socket and endpoint.</returns>
        /// <param name="cancellationToken">Cancellation token.</param>
        public async Task <KeyValuePair <long, EndPoint> > AcceptAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                // Try to read; we a non-blocking
                var addr = new Sockaddr();
                var ret  = Syscall.accept(m_socket, addr);

                // If we did not get a socket
                if (ret < 0)
                {
                    var errno = Stdlib.GetLastError();
                    if (errno == Errno.EAGAIN || errno == Errno.EWOULDBLOCK)
                    {
                        await m_handle.WaitForReadAsync;

                        // Error code is normal operation code
                        continue;
                    }

                    throw new IOException($"Failed to accept socket: {errno}");
                }

                // Dummy endpoint
                var endpoint = new IPEndPoint(IPAddress.Any, 0);
                // If we get a real endpoint, use that
                if (addr is SockaddrIn sain)
                {
                    endpoint = new IPEndPoint((long)sain.sin_addr.s_addr, sain.sin_port);
                }

                return(new KeyValuePair <long, EndPoint>(ret, endpoint));
            }

            throw new TaskCanceledException();
        }
예제 #14
0
파일: SocketTest.cs 프로젝트: ZZHGit/mono
		public void IPv6 ()
		{
			if (!Socket.OSSupportsIPv6)
				Assert.Ignore ("OS does not support IPv6.");

			var address = new SockaddrIn6 {
				sin6_family = UnixAddressFamily.AF_INET6,
				sin6_port = Syscall.htons (0),
				sin6_addr = NativeConvert.ToIn6Addr (IPAddress.IPv6Loopback),
			};
			WithSockets (UnixAddressFamily.AF_INET6, UnixSocketType.SOCK_STREAM, 0, (so1, so2) => {
				if (Syscall.bind (so1, address) < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				var address1Stor = new SockaddrStorage ();
				if (Syscall.getsockname (so1, address1Stor) < 0)
					UnixMarshal.ThrowExceptionForLastError ();
				var address1 = new SockaddrIn6 ();
				address1Stor.CopyTo (address1);

				// Check getsockname(socket, null)
				if (Syscall.getsockname (so1, null) < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				var address2 = new SockaddrIn6 ();
				if (Syscall.getsockname (so1, address2) < 0)
					UnixMarshal.ThrowExceptionForLastError ();

				Assert.AreEqual (address1, address2);
				Assert.IsTrue (Syscall.ntohs (address1.sin6_port) != 0);
				address1.sin6_port = 0;
				Assert.AreEqual (address, address1);

				var address3 = new Sockaddr ();
				if (Syscall.getsockname (so1, address3) < 0)
					UnixMarshal.ThrowExceptionForLastError ();
				Assert.AreEqual (address.sa_family, address3.sa_family);

				// Try to store a sockaddr_in6 into a Sockaddr. Should fail because sockaddr_in6 should be larger than sockaddr_in
				var address4 = new SockaddrIn ();
				if (Syscall.getsockname (so1, address4) == 0)
					Assert.Fail ("getsockname() should have failed");
				Assert.AreEqual (Errno.ENOBUFS, Stdlib.GetLastError ());
			});
		}
예제 #15
0
		public static unsafe bool TryCopy (IntPtr source, long size, Sockaddr destination)
		{
			if (destination == null)
				throw new ArgumentNullException ("destination");
			byte[] array = Sockaddr.GetDynamicData (destination);
			fixed (SockaddrType* addr = &Sockaddr.GetAddress (destination).type)
			fixed (byte* data = Sockaddr.GetDynamicData (destination)) {
				var dyn = new _SockaddrDynamic (destination, data, useMaxLength: true);
				var r = ToSockaddr (source, size, Sockaddr.GetNative (&dyn, addr));
				dyn.Update (destination);
				// SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place
				if (r == 0 && destination.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped)) {
					Marshal.Copy (source, array, 0, (int) destination.GetDynamicLength ());
				}
				return r == 0;
			}
		}
예제 #16
0
		public static unsafe bool TryCopy (Sockaddr source, IntPtr destination)
		{
			if (source == null)
				throw new ArgumentNullException ("source");
			byte[] array = Sockaddr.GetDynamicData (source);
			// SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place
			if (source.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped)) {
				Marshal.Copy (array, 0, destination, (int) source.GetDynamicLength ());
				return true;
			}
			fixed (SockaddrType* addr = &Sockaddr.GetAddress (source).type)
			fixed (byte* data = array) {
				var dyn = new _SockaddrDynamic (source, data, useMaxLength: false);
				return FromSockaddr (Sockaddr.GetNative (&dyn, addr), destination) == 0;
			}
		}