Esempio n. 1
0
        /// <summary>
        /// Sends an <see cref="ISnmpMessage"/>.
        /// </summary>
        /// <param name="message">The <see cref="ISnmpMessage"/>.</param>
        /// <param name="manager">Manager</param>
        /// <param name="socket">The socket.</param>
        public static void Send(this ISnmpMessage message, EndPoint manager, Socket socket)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }

            if (manager == null)
            {
                throw new ArgumentNullException("manager");
            }

            var code = message.TypeCode();

            if ((code != SnmpType.TrapV1Pdu && code != SnmpType.TrapV2Pdu) && code != SnmpType.ReportPdu)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "not a trap message: {0}", code));
            }

            var bytes = message.ToBytes();

            socket.SendTo(bytes, 0, bytes.Length, SocketFlags.None, manager);
        }
Esempio n. 2
0
        private void AsyncReceive(Socket socket)
        {
            while (true)
            {
                // If no more active, then stop.
                if (Interlocked.Exchange(ref _active, _active) == Inactive)
                {
                    return;
                }

                try
                {
                    var      buffer = new byte[_bufferSize];
                    EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
                    var      count  = socket.ReceiveFrom(buffer, ref remote);
                    Task.Factory.StartNew(() => HandleMessage(buffer, count, (IPEndPoint)remote));
                }
                catch (SocketException ex)
                {
                    if (ex.SocketErrorCode != SocketError.ConnectionReset)
                    {
                        // If the SnmpTrapListener was active, marks it as stopped and call HandleException.
                        // If it was inactive, the exception is likely to result from this, and we raise nothing.
                        var activeBefore = Interlocked.CompareExchange(ref _active, Inactive, Active);
                        if (activeBefore == Active)
                        {
                            HandleException(ex);
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        private void CreatePortMapAsync(object obj)
        {
            CreatePortMapAsyncState state = obj as CreatePortMapAsyncState;

            UdpClient udpClient = new UdpClient();
            CreatePortMapListenState listenState = new CreatePortMapListenState(state, udpClient);

            int attempt = 0;
            int delay   = PmpConstants.RetryDelay;

            ThreadPool.QueueUserWorkItem(new WaitCallback(CreatePortMapListen), listenState);

            while (attempt < PmpConstants.RetryAttempts && !listenState.Success)
            {
                udpClient.Send(state.Buffer, state.Buffer.Length, new IPEndPoint(localAddress, PmpConstants.ServerPort));
                listenState.UdpClientReady.Set();

                attempt++;
                delay *= 2;
#if SSHARP
                CrestronEnvironment.Sleep(delay);
#else
                Thread.Sleep(delay);
#endif
            }

            state.Success = listenState.Success;

            udpClient.Close();
            state.ResetEvent.Set();
        }
Esempio n. 4
0
        /// <summary>
        /// Discovers agents of the specified version in a specific time interval.
        /// </summary>
        /// <param name="version">The version.</param>
        /// <param name="broadcastAddress">The broadcast address.</param>
        /// <param name="community">The community.</param>
        /// <param name="interval">The discovering time interval, in milliseconds.</param>
        /// <remarks><paramref name="broadcastAddress"/> must be an IPv4 address. IPv6 is not yet supported here.</remarks>
        public async Task DiscoverAsync(VersionCode version, IPEndPoint broadcastAddress, OctetString community, int interval)
        {
            if (broadcastAddress == null)
            {
                throw new ArgumentNullException("broadcastAddress");
            }

            if (version != VersionCode.V3 && community == null)
            {
                throw new ArgumentNullException("community");
            }

            var addressFamily = broadcastAddress.AddressFamily;

            if (addressFamily == AddressFamily.InterNetworkV6)
            {
                throw new ArgumentException("IP v6 is not yet supported", "broadcastAddress");
            }

            byte[] bytes;
            _requestId = Messenger.NextRequestId;
            if (version == VersionCode.V3)
            {
                // throw new NotSupportedException("SNMP v3 is not supported");
                var discovery = new Discovery(Messenger.NextMessageId, _requestId, Messenger.MaxMessageSize);
                bytes = discovery.ToBytes();
            }
            else
            {
                var message = new GetRequestMessage(_requestId, version, community, _defaultVariables);
                bytes = message.ToBytes();
            }

            using (var udp = new Socket(addressFamily, SocketType.Dgram, ProtocolType.Udp))
            {
                var info = SocketExtension.EventArgsFactory.Create();
                info.RemoteEndPoint = broadcastAddress;
                info.SetBuffer(bytes, 0, bytes.Length);
                using (var awaitable1 = new SocketAwaitable(info))
                {
                    await udp.SendToAsync(awaitable1);
                }

                var activeBefore = Interlocked.CompareExchange(ref _active, Active, Inactive);
                if (activeBefore == Active)
                {
                    // If already started, we've nothing to do.
                    return;
                }

                _bufferSize = udp.ReceiveBufferSize;
                await ReceiveAsync(udp).ConfigureAwait(false);

                await Task.Delay(interval).ConfigureAwait(false);

                Interlocked.CompareExchange(ref _active, Inactive, Active);
                udp.Shutdown(SocketShutdown.Both);
            }
        }
Esempio n. 5
0
 public SnmpMessageAsyncResult(IAsyncResult inner, Socket socket, UserRegistry users, IPEndPoint receiver, byte[] buffer)
 {
     _buffer    = buffer;
     WorkSocket = socket;
     Users      = users;
     Receiver   = receiver;
     Inner      = inner;
 }
Esempio n. 6
0
        /// <summary>
        /// Begins to asynchronously send an <see cref="ISnmpMessage"/> to an <see cref="IPEndPoint"/>.
        /// </summary>
        /// <param name="request">The <see cref="ISnmpMessage"/>.</param>
        /// <param name="receiver">Agent.</param>
        /// <param name="registry">The user registry.</param>
        /// <param name="udpSocket">The UDP <see cref="Socket"/> to use to send/receive.</param>
        /// <param name="callback">The callback.</param>
        /// <param name="state">The state object.</param>
        /// <returns></returns>
        public static IAsyncResult BeginGetResponse(
            this ISnmpMessage request, IPEndPoint receiver, UserRegistry registry, Socket udpSocket, AsyncCallback callback, object state)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (udpSocket == null)
            {
                throw new ArgumentNullException("udpSocket");
            }

            if (receiver == null)
            {
                throw new ArgumentNullException("receiver");
            }

            if (registry == null)
            {
                throw new ArgumentNullException("registry");
            }

            var requestCode = request.TypeCode();

            if (requestCode == SnmpType.TrapV1Pdu || requestCode == SnmpType.TrapV2Pdu || requestCode == SnmpType.ReportPdu)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "not a request message: {0}", requestCode));
            }

            // Whatever you change, try to keep the Send and the Receive close to each other.
            udpSocket.SendTo(request.ToBytes(), receiver);
#if CF
            var bufferSize = 8192;
#elif SSHARP
            var bufferSize = 16384;
#else
            var bufferSize = udpSocket.ReceiveBufferSize = Messenger.MaxMessageSize;
#endif
            var buffer = new byte[bufferSize];

            // https://sharpsnmplib.codeplex.com/workitem/7234
            if (callback != null)
            {
                AsyncCallback wrapped = callback;
                callback = asyncResult =>
                {
                    var result = new SnmpMessageAsyncResult(asyncResult, udpSocket, registry, receiver, buffer);
                    wrapped(result);
                };
            }

            var ar = udpSocket.BeginReceive(buffer, 0, bufferSize, SocketFlags.None, callback, state);
            return(new SnmpMessageAsyncResult(ar, udpSocket, registry, receiver, buffer));
        }
Esempio n. 7
0
        /// <summary>
        /// Starts this instance.
        /// </summary>
        /// <exception cref="PortInUseException"/>
        public async Task StartAsync()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            var addressFamily = Endpoint.AddressFamily;

            if (addressFamily == AddressFamily.InterNetwork && !Socket.OSSupportsIPv4)
            {
                throw new InvalidOperationException(Listener.ErrorIPv4NotSupported);
            }

            if (addressFamily == AddressFamily.InterNetworkV6 && !Socket.OSSupportsIPv6)
            {
                throw new InvalidOperationException(Listener.ErrorIPv6NotSupported);
            }

            var activeBefore = Interlocked.CompareExchange(ref _active, Active, Inactive);

            if (activeBefore == Active)
            {
                // If already started, we've nothing to do.
                return;
            }

            _socket = new Socket(addressFamily, SocketType.Dgram, ProtocolType.Udp);

            try
            {
                _socket.Bind(Endpoint);
            }
            catch (SocketException ex)
            {
                Interlocked.Exchange(ref _active, Inactive);
                if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
                {
                    throw new PortInUseException("Endpoint is already in use", ex)
                          {
                              Endpoint = Endpoint
                          };
                }

                throw;
            }

            _bufferSize = _socket.ReceiveBufferSize;
            await ReceiveAsync();
        }
Esempio n. 8
0
        private async Task ReceiveAsync(Socket socket)
        {
            EndPoint remote = new IPEndPoint(IPAddress.Any, 0);

            while (true)
            {
                // If no more active, then stop.
                if (Interlocked.Exchange(ref _active, _active) == Inactive)
                {
                    return;
                }

                int count;
                var reply = new byte[_bufferSize];
                var args  = SocketExtension.EventArgsFactory.Create();
                try
                {
                    args.RemoteEndPoint = remote;
                    args.SetBuffer(reply, 0, _bufferSize);
                    using (var awaitable = new SocketAwaitable(args))
                    {
                        count = await socket.ReceiveAsync(awaitable);
                    }

                    await Task.Factory.StartNew(() => HandleMessage(reply, count, (IPEndPoint)remote)).ConfigureAwait(false);
                }
                catch (SocketException ex)
                {
                    if (ex.SocketErrorCode != SocketError.ConnectionReset)
                    {
                        // If the SnmpTrapListener was active, marks it as stopped and call HandleException.
                        // If it was inactive, the exception is likely to result from this, and we raise nothing.
                        var activeBefore = Interlocked.CompareExchange(ref _active, Inactive, Active);
                        if (activeBefore == Active)
                        {
                            HandleException(ex);
                        }
                    }
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Stops.
        /// </summary>
        /// <exception cref="ObjectDisposedException"/>
        public void Stop()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            var activeBefore = Interlocked.CompareExchange(ref _active, Inactive, Active);

            if (activeBefore != Active)
            {
                return;
            }

            this._socket.Shutdown(SocketShutdown.Both);              // Note that closing the socket releases the _socket.ReceiveFrom call.
#if SSHARP
            this._socket.Close();
#else
            this._socket.Dispose();
#endif
            _socket = null;
        }
Esempio n. 10
0
        private void AsyncBeginReceive(Socket socket)
        {
#endif
            while (true)
            {
                // If no more active, then stop.
                if (Interlocked.Exchange(ref _active, _active) == Inactive)
                {
                    return;
                }

                byte[]       buffer = new byte[_bufferSize];
                IPEndPoint   remote = new IPEndPoint(IPAddress.Any, 0);
                IAsyncResult iar    = null;
                try
                {
                    iar = socket.BeginReceiveFrom(buffer, 0, _bufferSize, SocketFlags.None, ref remote, AsyncEndReceive, new Tuple <Socket, byte[]> (socket, buffer));
                }
                catch (SocketException ex)
                {
                    // ignore WSAECONNRESET, http://bytes.com/topic/c-sharp/answers/237558-strange-udp-socket-problem
                    if (ex.SocketErrorCode != SocketError.ConnectionReset)
                    {
                        // If the SnmpTrapListener was active, marks it as stopped and call HandleException.
                        // If it was inactive, the exception is likely to result from this, and we raise nothing.
                        long activeBefore = Interlocked.CompareExchange(ref _active, Inactive, Active);
                        if (activeBefore == Active)
                        {
                            HandleException(ex);
                        }
                    }
                }

                if (iar != null)
                {
                    iar.AsyncWaitHandle.WaitOne();
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.ComponentModel.Component"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        private void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            if (disposing)
            {
                _active = Inactive;
                if (_socket != null)
                {
                    this._socket.Shutdown(SocketShutdown.Both);                      // Note that closing the socket releases the _socket.ReceiveFrom call.
#if SSHARP
                    _socket.Close();
#else
                    _socket.Dispose();
#endif
                    _socket = null;
                }
            }

            _disposed = true;
        }
Esempio n. 12
0
        /// <summary>
        /// Sends an <see cref="ISnmpMessage"/>.
        /// </summary>
        /// <param name="message">The <see cref="ISnmpMessage"/>.</param>
        /// <param name="manager">Manager</param>
        /// <param name="socket">The socket.</param>
        public static async Task SendAsync(this ISnmpMessage message, EndPoint manager, Socket socket)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }

            if (manager == null)
            {
                throw new ArgumentNullException("manager");
            }

            var code = message.TypeCode();

            if ((code != SnmpType.TrapV1Pdu && code != SnmpType.TrapV2Pdu) && code != SnmpType.ReportPdu)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "not a trap message: {0}", code));
            }

            var bytes = message.ToBytes();
            var info  = SocketExtension.EventArgsFactory.Create();

            info.RemoteEndPoint = manager;
            info.SetBuffer(bytes, 0, bytes.Length);
            using (var awaitable1 = new SocketAwaitable(info))
            {
                await socket.SendToAsync(awaitable1);
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Starts this instance.
        /// </summary>
        /// <exception cref="PortInUseException"/>
        public void Start()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            var addressFamily = Endpoint.AddressFamily;

#if !CF && !NETCF
            if (addressFamily == AddressFamily.InterNetwork && !Socket.OSSupportsIPv4)
            {
                throw new InvalidOperationException(Listener.ErrorIPv4NotSupported);
            }

            if (addressFamily == AddressFamily.InterNetworkV6 && !Socket.OSSupportsIPv6)
            {
                throw new InvalidOperationException(Listener.ErrorIPv6NotSupported);
            }
#endif
            var activeBefore = Interlocked.CompareExchange(ref _active, Active, Inactive);
            if (activeBefore == Active)
            {
                // If already started, we've nothing to do.
                return;
            }

#if CF
            _socket = new Socket(addressFamily, SocketType.Dgram, ProtocolType.Udp);
#else
#if SSHARP
            _socket = new Socket(addressFamily, SocketType.Dgram, ProtocolType.Udp, 16384);
#else
            _socket = new Socket(addressFamily, SocketType.Dgram, ProtocolType.Udp)
            {
                ExclusiveAddressUse = true
            };
#endif
#endif

            try
            {
                _socket.Bind(Endpoint);
            }
            catch (SocketException ex)
            {
                Interlocked.Exchange(ref _active, Inactive);
                if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
                {
                    throw new PortInUseException("Endpoint is already in use", ex)
                          {
                              Endpoint = Endpoint
                          }
                }
                ;

                throw;
            }

#if CF
            _bufferSize = 8192;
#elif SSHARP
            _bufferSize = 16384;
#else
            _bufferSize = _socket.ReceiveBufferSize = Messenger.MaxMessageSize;
#endif

#if ASYNC
#if NETCF
            ThreadPool.QueueUserWorkItem((o) => AsyncBeginReceive());
#if SSHARP
            CrestronEnvironment.Sleep(1);
#endif
#else
            Task.Factory.StartNew(() => AsyncBeginReceive());
#endif
#else
            Task.Factory.StartNew(() => AsyncReceive());
#endif
        }
Esempio n. 14
0
        /// <summary>
        /// Sends an <see cref="ISnmpMessage"/> and handles the response from agent.
        /// </summary>
        /// <param name="request">The <see cref="ISnmpMessage"/>.</param>
        /// <param name="receiver">Agent.</param>
        /// <param name="udpSocket">The UDP <see cref="Socket"/> to use to send/receive.</param>
        /// <param name="registry">The user registry.</param>
        /// <returns></returns>
        public static async Task <ISnmpMessage> GetResponseAsync(this ISnmpMessage request, IPEndPoint receiver, UserRegistry registry, Socket udpSocket)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (udpSocket == null)
            {
                throw new ArgumentNullException("udpSocket");
            }

            if (receiver == null)
            {
                throw new ArgumentNullException("receiver");
            }

            if (registry == null)
            {
                throw new ArgumentNullException("registry");
            }

            var requestCode = request.TypeCode();

            if (requestCode == SnmpType.TrapV1Pdu || requestCode == SnmpType.TrapV2Pdu || requestCode == SnmpType.ReportPdu)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "not a request message: {0}", requestCode));
            }

            var bytes   = request.ToBytes();
            var bufSize = udpSocket.ReceiveBufferSize = Messenger.MaxMessageSize;

            // Whatever you change, try to keep the Send and the Receive close to each other.
            var info = SocketExtension.EventArgsFactory.Create();

            info.RemoteEndPoint = receiver;
            info.SetBuffer(bytes, 0, bytes.Length);
            using (var awaitable1 = new SocketAwaitable(info))
            {
                await udpSocket.SendToAsync(awaitable1);
            }

            int count;
            var reply = new byte[bufSize];

            // IMPORTANT: follow http://blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx
            var      args   = SocketExtension.EventArgsFactory.Create();
            EndPoint remote = new IPEndPoint(IPAddress.Any, 0);

            try
            {
                args.RemoteEndPoint = remote;
                args.SetBuffer(reply, 0, bufSize);
                using (var awaitable = new SocketAwaitable(args))
                {
                    count = await udpSocket.ReceiveAsync(awaitable);
                }
            }
            catch (SocketException ex)
            {
                // FIXME: If you use a Mono build without the fix for this issue (https://bugzilla.novell.com/show_bug.cgi?id=599488), please uncomment this code.

                /*
                 * if (SnmpMessageExtension.IsRunningOnMono && ex.ErrorCode == 10035)
                 * {
                 * throw TimeoutException.Create(receiver.Address, timeout);
                 * }
                 * // */

                if (ex.SocketErrorCode == SocketError.TimedOut)
                {
                    throw TimeoutException.Create(receiver.Address, 0);
                }

                throw;
            }

            // Passing 'count' is not necessary because ParseMessages should ignore it, but it offer extra safety (and would avoid an issue if parsing >1 response).
            var response     = MessageFactory.ParseMessages(reply, 0, count, registry)[0];
            var responseCode = response.TypeCode();

            if (responseCode == SnmpType.ResponsePdu || responseCode == SnmpType.ReportPdu)
            {
                var requestId  = request.MessageId();
                var responseId = response.MessageId();
                if (responseId != requestId)
                {
                    throw OperationException.Create(
                              string.Format(CultureInfo.InvariantCulture, "wrong response sequence: expected {0}, received {1}", requestId, responseId), receiver.Address);
                }

                return(response);
            }

            throw OperationException.Create(string.Format(CultureInfo.InvariantCulture, "wrong response type: {0}", responseCode), receiver.Address);
        }
Esempio n. 15
0
        /// <summary>
        /// Sends this <see cref="ISnmpMessage"/> and handles the response from agent.
        /// </summary>
        /// <param name="request">The <see cref="ISnmpMessage"/>.</param>
        /// <param name="receiver">Agent.</param>
        /// <param name="udpSocket">The UDP <see cref="Socket"/> to use to send/receive.</param>
        /// <returns></returns>
        public static async Task <ISnmpMessage> GetResponseAsync(this ISnmpMessage request, IPEndPoint receiver, Socket udpSocket)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (receiver == null)
            {
                throw new ArgumentNullException("receiver");
            }

            if (udpSocket == null)
            {
                throw new ArgumentNullException("udpSocket");
            }

            var registry = new UserRegistry();

            if (request.Version == VersionCode.V3)
            {
                registry.Add(request.Parameters.UserName, request.Privacy);
            }

            return(await request.GetResponseAsync(receiver, registry, udpSocket).ConfigureAwait(false));
        }
Esempio n. 16
0
        private void CreatePortMapListen(object obj)
        {
            CreatePortMapListenState state = obj as CreatePortMapListenState;

            UdpClient udpClient = state.UdpClient;

            state.UdpClientReady.WaitOne();              // Evidently UdpClient has some lazy-init Send/Receive race?
            IPEndPoint endPoint = new IPEndPoint(localAddress, PmpConstants.ServerPort);

            while (!state.Success)
            {
                byte[] data;
                try
                {
                    data = udpClient.Receive(ref endPoint);
                }
                catch (SocketException)
                {
                    state.Success = false;
                    return;
                }

                if (data.Length < 16)
                {
                    continue;
                }

                if (data[0] != PmpConstants.Version)
                {
                    continue;
                }

                byte opCode = (byte)(data[1] & (byte)127);

                Protocol protocol = Protocol.Tcp;
                if (opCode == PmpConstants.OperationCodeUdp)
                {
                    protocol = Protocol.Udp;
                }

                short resultCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 2));
                uint  epoch      = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));

                int privatePort = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 8));
                int publicPort  = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 10));

                uint lifetime = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 12));

                if (resultCode != PmpConstants.ResultCodeSuccess)
                {
                    state.Success = false;
                    return;
                }

                if (lifetime == 0)
                {
                    //mapping was deleted
                    state.Success = true;
                    state.Mapping = null;
                    return;
                }
                else
                {
                    //mapping was created
                    //TODO: verify that the private port+protocol are a match
                    Mapping mapping = state.Mapping;
                    mapping.PublicPort = publicPort;
                    mapping.Protocol   = protocol;
                    mapping.Expiration = DateTime.Now.AddSeconds(lifetime);

                    state.Success = true;
                }
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Sends an  <see cref="ISnmpMessage"/> and handles the response from agent.
        /// </summary>
        /// <param name="request">The <see cref="ISnmpMessage"/>.</param>
        /// <param name="timeout">The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period.</param>
        /// <param name="receiver">Agent.</param>
        /// <param name="udpSocket">The UDP <see cref="Socket"/> to use to send/receive.</param>
        /// <param name="registry">The user registry.</param>
        /// <returns></returns>
        public static ISnmpMessage GetResponse(this ISnmpMessage request, int timeout, IPEndPoint receiver, UserRegistry registry, Socket udpSocket)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (udpSocket == null)
            {
                throw new ArgumentNullException("udpSocket");
            }

            if (receiver == null)
            {
                throw new ArgumentNullException("receiver");
            }

            if (registry == null)
            {
                throw new ArgumentNullException("registry");
            }

            var requestCode = request.TypeCode();

            if (requestCode == SnmpType.TrapV1Pdu || requestCode == SnmpType.TrapV2Pdu || requestCode == SnmpType.ReportPdu)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "not a request message: {0}", requestCode));
            }

            var bytes = request.ToBytes();

#if CF
            int bufSize = 8192;
#elif SSHARP
            int bufSize = 16384;
#else
            var bufSize = udpSocket.ReceiveBufferSize = Messenger.MaxMessageSize;
#endif
            var reply = new byte[bufSize];

            // Whatever you change, try to keep the Send and the Receive close to each other.
            udpSocket.SendTo(bytes, receiver);
#if !CF
            udpSocket.ReceiveTimeout = timeout;
#endif
            int count;
            try
            {
                count = udpSocket.Receive(reply, 0, bufSize, SocketFlags.None);
            }
            catch (SocketException ex)
            {
                // FIXME: If you use a Mono build without the fix for this issue (https://bugzilla.novell.com/show_bug.cgi?id=599488), please uncomment this code.

                /*
                 * if (SnmpMessageExtension.IsRunningOnMono && ex.ErrorCode == 10035)
                 * {
                 * throw TimeoutException.Create(receiver.Address, timeout);
                 * }
                 * // */

                if (ex.SocketErrorCode == SocketError.TimedOut)
                {
                    throw TimeoutException.Create(receiver.Address, timeout);
                }

                throw;
            }

            // Passing 'count' is not necessary because ParseMessages should ignore it, but it offer extra safety (and would avoid an issue if parsing >1 response).
            var response     = MessageFactory.ParseMessages(reply, 0, count, registry)[0];
            var responseCode = response.TypeCode();
            if (responseCode == SnmpType.ResponsePdu || responseCode == SnmpType.ReportPdu)
            {
                var requestId  = request.MessageId();
                var responseId = response.MessageId();
                if (responseId != requestId)
                {
                    throw OperationException.Create(
                              string.Format(CultureInfo.InvariantCulture, "wrong response sequence: expected {0}, received {1}", requestId, responseId), receiver.Address);
                }

                return(response);
            }

            throw OperationException.Create(string.Format(CultureInfo.InvariantCulture, "wrong response type: {0}", responseCode), receiver.Address);
        }
Esempio n. 18
0
        /// <summary>
        /// Sends this <see cref="ISnmpMessage"/> and handles the response from agent.
        /// </summary>
        /// <param name="request">The <see cref="ISnmpMessage"/>.</param>
        /// <param name="timeout">The time-out value, in milliseconds. The default value is 0, which indicates an infinite time-out period. Specifying -1 also indicates an infinite time-out period.</param>
        /// <param name="receiver">Agent.</param>
        /// <param name="udpSocket">The UDP <see cref="Socket"/> to use to send/receive.</param>
        /// <returns></returns>
        public static ISnmpMessage GetResponse(this ISnmpMessage request, int timeout, IPEndPoint receiver, Socket udpSocket)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (receiver == null)
            {
                throw new ArgumentNullException("receiver");
            }

            if (udpSocket == null)
            {
                throw new ArgumentNullException("udpSocket");
            }

            var registry = new UserRegistry();

            if (request.Version == VersionCode.V3)
            {
                registry.Add(request.Parameters.UserName, request.Privacy);
            }

            return(request.GetResponse(timeout, receiver, registry, udpSocket));
        }
Esempio n. 19
0
        /// <summary>
        /// Discovers agents of the specified version in a specific time interval.
        /// </summary>
        /// <param name="version">The version.</param>
        /// <param name="broadcastAddress">The broadcast address.</param>
        /// <param name="community">The community.</param>
        /// <param name="interval">The discovering time interval, in milliseconds.</param>
        /// <remarks><paramref name="broadcastAddress"/> must be an IPv4 address. IPv6 is not yet supported here.</remarks>
        public void Discover(VersionCode version, IPEndPoint broadcastAddress, OctetString community, int interval)
        {
            if (broadcastAddress == null)
            {
                throw new ArgumentNullException("broadcastAddress");
            }

            if (version != VersionCode.V3 && community == null)
            {
                throw new ArgumentNullException("community");
            }

            var addressFamily = broadcastAddress.AddressFamily;

            if (addressFamily == AddressFamily.InterNetworkV6)
            {
                throw new ArgumentException("IP v6 is not yet supported", "broadcastAddress");
            }

            byte[] bytes;
            _requestId = Messenger.NextRequestId;
            if (version == VersionCode.V3)
            {
                // throw new NotSupportedException("SNMP v3 is not supported");
                var discovery = new Discovery(Messenger.NextMessageId, _requestId, Messenger.MaxMessageSize);
                bytes = discovery.ToBytes();
            }
            else
            {
                var message = new GetRequestMessage(_requestId, version, community, _defaultVariables);
                bytes = message.ToBytes();
            }

#if SSHARP
            using (var udp = new UdpClient())
#else
            using (var udp = new UdpClient(addressFamily))
#endif
            {
#if !CF && !NETCF
                udp.EnableBroadcast = true;
#endif
#if !NETSTANDARD
                udp.Send(bytes, bytes.Length, broadcastAddress);
#else
                AsyncHelper.RunSync(() => udp.SendAsync(bytes, bytes.Length, broadcastAddress));
#endif

                var activeBefore = Interlocked.CompareExchange(ref _active, Active, Inactive);
                if (activeBefore == Active)
                {
                    // If already started, we've nothing to do.
                    return;
                }

#if CF
                _bufferSize = 8192;
#elif SSHARP
                _bufferSize = 16384;
#else
                _bufferSize = udp.Client.ReceiveBufferSize = Messenger.MaxMessageSize;
#endif

#if ASYNC
#if SSHARP
                ThreadPool.QueueUserWorkItem(AsyncBeginReceive, udp);
#else
                Task.Factory.StartNew(() => AsyncBeginReceive(udp.Client));
#endif
#else
                Task.Factory.StartNew(() => AsyncReceive(udp.Client));
#endif

#if SSHARP
                CrestronEnvironment.Sleep(interval);
#else
                Thread.Sleep(interval);
#endif
                Interlocked.CompareExchange(ref _active, Inactive, Active);
                udp.Close();
            }
        }
Esempio n. 20
0
 internal CreatePortMapListenState(CreatePortMapAsyncState state, UdpClient client)
 {
     Mapping        = state.Mapping;
     UdpClient      = client;
     UdpClientReady = new ManualResetEvent(false);
 }
Esempio n. 21
0
 private void AsyncBeginReceive(object state)
 {
     Socket socket = (Socket)state;