Issues (2963)

LibreNMS/Util/Snmpsim.php (1 issue)

Severity
1
<?php
2
/**
3
 * Snmpsim.php
4
 *
5
 * Light wrapper around Snmpsim
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 *
20
 * @link       https://www.librenms.org
21
 *
22
 * @copyright  2017 Tony Murray
23
 * @author     Tony Murray <[email protected]>
24
 */
25
26
namespace LibreNMS\Util;
27
28
use App;
29
use LibreNMS\Config;
30
use LibreNMS\Proc;
31
32
class Snmpsim
33
{
34
    private $snmprec_dir;
35
    private $ip;
36
    private $port;
37
    private $log;
38
    /** @var Proc */
39
    private $proc;
40
41
    public function __construct($ip = '127.1.6.1', $port = 1161, $log = '/tmp/snmpsimd.log')
42
    {
43
        $this->ip = $ip;
44
        $this->port = $port;
45
        $this->log = $log;
46
        $this->snmprec_dir = Config::get('install_dir') . '/tests/snmpsim/';
47
    }
48
49
    /**
50
     * Run snmpsimd and fork it into the background
51
     * Captures all output to the log
52
     *
53
     * @param  int  $wait  Wait for x seconds after starting before returning
54
     */
55
    public function fork($wait = 2)
56
    {
57
        if ($this->isRunning()) {
58
            echo "Snmpsim is already running!\n";
59
60
            return;
61
        }
62
63
        $cmd = $this->getCmd();
64
65
        if (App::runningInConsole()) {
66
            echo "Starting snmpsim listening on {$this->ip}:{$this->port}... \n";
67
            d_echo($cmd);
68
        }
69
70
        $this->proc = new Proc($cmd);
71
72
        if ($wait) {
73
            sleep($wait);
74
        }
75
76
        if (App::runningInConsole() && ! $this->proc->isRunning()) {
77
            // if starting failed, run snmpsim again and output to the console and validate the data
78
            passthru($this->getCmd(false) . ' --validate-data');
79
80
            if (! is_executable($this->findSnmpsimd())) {
81
                echo "\nCould not find snmpsim, you can install it with 'pip install snmpsim'.  If it is already installed, make sure snmpsimd or snmpsimd.py is in PATH\n";
82
            } else {
83
                echo "\nFailed to start Snmpsim. Scroll up for error.\n";
84
            }
85
            exit(1);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
86
        }
87
    }
88
89
    /**
90
     * Stop and start the running snmpsim process
91
     */
92
    public function restart()
93
    {
94
        $this->stop();
95
        $this->proc = new Proc($this->getCmd());
96
    }
97
98
    public function stop()
99
    {
100
        if (isset($this->proc)) {
101
            if ($this->proc->isRunning()) {
102
                $this->proc->terminate();
103
            }
104
            unset($this->proc);
105
        }
106
    }
107
108
    /**
109
     * Run snmpsimd but keep it in the foreground
110
     * Outputs to stdout
111
     */
112
    public function run()
113
    {
114
        echo "Starting snmpsim listening on {$this->ip}:{$this->port}... \n";
115
        shell_exec($this->getCmd(false));
116
    }
117
118
    public function isRunning()
119
    {
120
        if (isset($this->proc)) {
121
            return $this->proc->isRunning();
122
        }
123
124
        return false;
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function getDir()
131
    {
132
        return $this->snmprec_dir;
133
    }
134
135
    /**
136
     * @return string
137
     */
138
    public function getIp()
139
    {
140
        return $this->ip;
141
    }
142
143
    /**
144
     * @return int
145
     */
146
    public function getPort()
147
    {
148
        return $this->port;
149
    }
150
151
    /**
152
     * Generate the command for snmpsimd
153
     *
154
     * @param  bool  $with_log
155
     * @return string
156
     */
157
    private function getCmd($with_log = true)
158
    {
159
        $cmd = $this->findSnmpsimd();
160
161
        $cmd .= " --data-dir={$this->snmprec_dir} --agent-udpv4-endpoint={$this->ip}:{$this->port}";
162
163
        if (is_null($this->log)) {
164
            $cmd .= ' --logging-method=null';
165
        } elseif ($with_log) {
166
            $cmd .= " --logging-method=file:{$this->log}";
167
        }
168
169
        return $cmd;
170
    }
171
172
    public function __destruct()
173
    {
174
        // unset $this->proc to make sure it isn't referenced
175
        unset($this->proc);
176
    }
177
178
    public function findSnmpsimd()
179
    {
180
        $cmd = Config::locateBinary('snmpsimd');
181
        if (! is_executable($cmd)) {
182
            $cmd = Config::locateBinary('snmpsimd.py');
183
        }
184
185
        return $cmd;
186
    }
187
}
188