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()); }
[ExpectedException(typeof(ArgumentOutOfRangeException))] // IPPROTO_UDP not supported #endif public unsafe void SendMsgRecvMsgAddress() { WithSockets(UnixAddressFamily.AF_INET, UnixSocketType.SOCK_DGRAM, UnixSocketProtocol.IPPROTO_UDP, (so1, so2) => { // Bind UDP socket so1 to 127.0.0.1 with dynamic port var address = new SockaddrIn { sin_family = UnixAddressFamily.AF_INET, sin_port = Syscall.htons(0), sin_addr = new InAddr(127, 0, 0, 1), }; if (Syscall.bind(so1, address) < 0) { UnixMarshal.ThrowExceptionForLastError(); } // Get actual port number using getsockname() var actualAddress = new SockaddrIn(); if (Syscall.getsockname(so1, actualAddress) < 0) { UnixMarshal.ThrowExceptionForLastError(); } Assert.AreEqual(actualAddress.sa_family, UnixAddressFamily.AF_INET); var port = Syscall.ntohs(actualAddress.sin_port); Assert.IsTrue(port != 0); var remoteAddress = new SockaddrIn { sin_family = UnixAddressFamily.AF_INET, sin_port = Syscall.htons(port), sin_addr = new InAddr(127, 0, 0, 1), }; // Send and receive a few bytes long ret; var buffer1 = new byte[] { 42, 43, 44 }; fixed(byte *ptr_buffer1 = buffer1) { var iovecs1 = new Iovec[] { new Iovec { iov_base = (IntPtr)ptr_buffer1, iov_len = (ulong)buffer1.Length, }, }; var msghdr1 = new Msghdr { msg_name = remoteAddress, msg_iov = iovecs1, msg_iovlen = 1, }; ret = Syscall.sendmsg(so2, msghdr1, 0); msghdr1.msg_name = remoteAddress.ToSockaddrStorage(); if (ret >= 0) { ret = Syscall.sendmsg(so2, msghdr1, 0); } } if (ret < 0) { UnixMarshal.ThrowExceptionForLastError(); } var senderAddress = new SockaddrIn(); var senderAddressStorage = new SockaddrStorage(); var buffer2 = new byte[1024]; var buffer3 = new byte[1024]; fixed(byte *ptr_buffer2 = buffer2, ptr_buffer3 = buffer3) { var iovecs2 = new Iovec[] { new Iovec { iov_base = (IntPtr)ptr_buffer2, iov_len = (ulong)buffer2.Length, }, }; var msghdr2 = new Msghdr { msg_name = senderAddress, msg_iov = iovecs2, msg_iovlen = 1, }; ret = Syscall.recvmsg(so1, msghdr2, 0); msghdr2.msg_name = senderAddressStorage; iovecs2[0].iov_base = (IntPtr)ptr_buffer3; if (ret >= 0) { ret = Syscall.recvmsg(so1, msghdr2, 0); } } if (ret < 0) { UnixMarshal.ThrowExceptionForLastError(); } Assert.AreEqual(senderAddress.sa_family, UnixAddressFamily.AF_INET); Assert.AreEqual(senderAddress.sin_addr, new InAddr(127, 0, 0, 1)); var senderAddress2 = SockaddrIn.FromSockaddrStorage(senderAddressStorage); Assert.AreEqual(senderAddress2.sa_family, UnixAddressFamily.AF_INET); Assert.AreEqual(senderAddress2.sin_addr, new InAddr(127, 0, 0, 1)); Assert.AreEqual(buffer1.Length, ret); for (int i = 0; i < buffer1.Length; i++) { Assert.AreEqual(buffer1[i], buffer2[i]); } for (int i = 0; i < buffer1.Length; i++) { Assert.AreEqual(buffer1[i], buffer3[i]); } }); }