Пример #1
0
        private UnixStream OpenSocket(uint?mtu)
        {
            sockaddr_ll sa = new sockaddr_ll();

            sa.sll_family   = AF_PACKET;
            sa.sll_protocol = (ushort)IPAddress.HostToNetworkOrder((short)Protocol);
            sa.sll_ifindex  = if_nametoindex(Interface);

            if (sa.sll_ifindex == 0)
            {
                throw new ArgumentException("The interface \"" + Interface + "\" is not valid.");
            }

            int fd = -1, ret = -1;

            try
            {
                fd = socket(AF_PACKET, SOCK_RAW, sa.sll_protocol);
                UnixMarshal.ThrowExceptionForLastErrorIf(fd);

                ret = bind(fd, ref sa, Marshal.SizeOf(sa));
                UnixMarshal.ThrowExceptionForLastErrorIf(ret);

                ifreq ifr = new ifreq(Interface);

                if (orig_mtu == 0)
                {
                    ret = ioctl(fd, SIOCGIFMTU, ref ifr);
                    UnixMarshal.ThrowExceptionForLastErrorIf(ret);
                    orig_mtu = ifr.ifru_mtu;
                }

                if (mtu != null)
                {
                    ifr.ifru_mtu = mtu.Value;
                    ret          = ioctl(fd, SIOCSIFMTU, ref ifr);
                    UnixMarshal.ThrowExceptionForLastErrorIf(ret);
                }

                ret = ioctl(fd, SIOCGIFMTU, ref ifr);
                UnixMarshal.ThrowExceptionForLastErrorIf(ret);

                if (mtu != null && ifr.ifru_mtu != mtu.Value)
                {
                    throw new PeachException("MTU change did not take effect.");
                }

                _mtu = ifr.ifru_mtu;

                if (ifr.ifru_mtu > (MaxMTU - EthernetHeaderSize))
                {
                    _bufferSize = (int)MaxMTU;
                }
                else
                {
                    _bufferSize = (int)(ifr.ifru_mtu + EthernetHeaderSize);
                }

                var stream = new UnixStream(fd);
                fd = -1;

                return(stream);
            }
            catch (InvalidOperationException ex)
            {
                if (ex.InnerException != null)
                {
                    var inner = ex.InnerException as UnixIOException;
                    if (inner != null && inner.ErrorCode == Errno.EPERM)
                    {
                        throw new PeachException("Access denied when opening the raw ethernet publisher.  Ensure the user has the appropriate permissions.", ex);
                    }
                }

                throw;
            }
            finally
            {
                if (fd != -1)
                {
                    Syscall.close(fd);
                }
            }
        }
Пример #2
0
 private static extern int bind(int fd, ref sockaddr_ll addr, int addrlen);