-
Notifications
You must be signed in to change notification settings - Fork 14
/
netmon.php
executable file
·128 lines (113 loc) · 3.04 KB
/
netmon.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env php
<?php
// This is a small script that writes a log to /dev/shm/netusage.
//
// It auto-exits if the file /dev/shm/running is more than 60 seconds
// old.
$outputfile = "/dev/shm/netusage";
$watchfile = "/dev/shm/running";
// If the output file already exists, we're already running!
if (file_exists($outputfile)) {
print "Output file already exists. Am I already running?\n";
exit(-1);
}
$fh = fopen($outputfile, "w");
chmod($outputfile, 0666);
// Figure out where 'ip' is
if (file_exists("/usr/sbin/ip")) {
$iploc = "/usr/sbin/ip";
} elseif (file_exists("/sbin/ip")) {
$iploc = "/sbin/ip";
} else {
// Hope for the best...
$iploc = "ip";
}
while (true) {
// Does our watchfile exist?
if (!file_exists($watchfile)) {
print "Watchfile doesn't exist. Exiting!\n";
@unlink($outputfile);
exit(-1);
}
// Is our watchfile more than 60 seconds old?
clearstatcache(); // lolphp
$stat = stat($watchfile);
if ($stat['mtime'] < time() - 60) {
print "Watchfile too old. Exiting.\n";
@unlink($outputfile);
exit(0);
}
// Is our OUTPUT file too big?
$stat = stat($outputfile);
if ($stat['size'] > 524288) { // 512kb
// Nuke it and start again.
ftruncate($fh, 0);
rewind($fh);
}
$execoutput = [];
exec("$iploc -s link", $execoutput, $ret);
if ($ret !== 0) {
print "Error running ip, can't continue\n";
@unlink($outputfile);
exit(-1);
}
try {
$conf = parse_ip_output($execoutput);
fwrite($fh, json_encode(["timestamp" => time(), "data" => $conf ])."\n");
fflush($fh);
} catch (\Exception $e) {
print "Error: ".$e->getMessage()."\n";
@unlink($outputfile);
exit(-1);
}
sleep(1);
}
function parse_ip_output($outarr) {
$ints = [];
$nextline = [];
$current = false;
foreach ($outarr as $line) {
if (!isset($line[0])) {
// Empty line?
continue;
}
// If the first char is NOT a space, it's a network name.
if ($line[0] !== " ") {
$intarr = explode(":", (string) $line);
$current = trim($intarr[1]);
// If it's actually 'lo', we never save that.
if ($current !== "lo") {
$ints[$current] = [ "intnum" => $intarr[0], "intname" => $current, "other" => $intarr[2] ];
}
continue;
}
$line = trim((string) $line);
// Does it start with 'link/ether'? We have a MAC
if (str_starts_with($line, "link/ether")) {
$tmparr = explode(" ", $line);
if (isset($tmparr[1])) {
$ints[$current]['mac'] = $tmparr[1];
}
continue;
}
// Is the SECOND char 'X'? As in 'TX' or 'RX'?
if ($line[1] === 'X') {
$nextline = preg_split("/\s+/", $line);
continue;
}
// Is the FIRST char a number? This means we actually have data!
if (is_numeric($line[1])) {
if (!isset($nextline[0])) {
throw new \Exception("Error parsing ip, number received before definition\n");
}
// Which line is this?
$type = strtolower(substr(array_shift($nextline), 0, 2)); // Converts 'RX:' to 'rx'
$data = preg_split("/\s+/", $line);
// If it's actually 'lo', we never save that.
if ($current !== "lo") {
$ints[$current][$type] = array_combine($nextline, $data);
}
}
}
return $ints;
}