1<?php
2/*
3 * Kewlio Looking Glass, klg_router_functions.php
4 *
5 * Copyright (c) 2012, Daniel Austin MBCS <daniel@kewlio.net>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without modification,
9 * are permitted provided that the following conditions are met:
10 *
11 *  * Redistributions of source code must retain the above copyright notice, this
12 *    list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above copyright notice,
14 *    this list of conditions and the following disclaimer in the documentation
15 *    and/or other materials provided with the distribution.
16 *  * Neither the name of the Daniel Austin MBCS nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software without
18 *    specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33	Function KLG_Execute_Command($cmd, $alt_port = false)
34	{
35		Global $ssh_id, $lg_server, $lg_port, $lg_port2, $lg_type, $lg_login, $lg_ssh, $lg_ssh_user, $lg_ssh_pass, $config;
36
37		$ssh_id = $fd = -1;
38
39		if ($lg_ssh)
40		{
41			/* ssh session */
42			$ssh_id = @ssh2_connect($lg_server,$lg_port);
43			if (!$ssh_id)
44				return $fd;
45			if (!@ssh2_auth_password($ssh_id, $lg_ssh_user, $lg_ssh_pass))
46				return $fd;
47			$fd = @ssh2_shell($ssh_id, 'xterm', null, 200, 200, SSH2_TERM_UNIT_CHARS);
48			stream_set_blocking($fd, true);
49		} else {
50			/* telnet session */
51			$fd = @fsockopen($lg_server,$alt_port?$lg_port2:$lg_port,$errno,$errmsg);
52			if ($fd)
53			{
54				KLG_Send_Telnet_Negotiation($fd);
55				@fwrite($fd, "$lg_login\n");
56			}
57		}
58		if ($fd)
59		{
60			if ($lg_type=="juniper")
61				@fwrite($fd, "set cli screen-length 0\nset cli prompt cli>\n$cmd | no-more\nexit\n");
62			else
63				@fwrite($fd, "terminal length 0\n$cmd\nquit\n");
64		}
65		/* return the stream resource back */
66		return $fd;
67	}
68
69	Function KLG_Send_Telnet_Negotiation($fd)
70	{
71		/* send negotiation information to $fd socket */
72		fputs($fd,chr(0xFF).chr(0xFB).chr(0x1F).chr(0xFF).chr(0xFB).
73		chr(0x20).chr(0xFF).chr(0xFB).chr(0x18).chr(0xFF).chr(0xFB).
74		chr(0x27).chr(0xFF).chr(0xFD).chr(0x01).chr(0xFF).chr(0xFB).
75		chr(0x03).chr(0xFF).chr(0xFD).chr(0x03).chr(0xFF).chr(0xFC).
76		chr(0x23).chr(0xFF).chr(0xFC).chr(0x24).chr(0xFF).chr(0xFA).
77		chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18).chr(0xFF).
78		chr(0xF0).chr(0xFF).chr(0xFA).chr(0x20).chr(0x00).chr(0x33).
79		chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0x2C).chr(0x33).
80		chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0xFF).chr(0xF0).
81		chr(0xFF).chr(0xFA).chr(0x27).chr(0x00).chr(0xFF).chr(0xF0).
82		chr(0xFF).chr(0xFA).chr(0x18).chr(0x00).chr(0x58).chr(0x54).
83		chr(0x45).chr(0x52).chr(0x4D).chr(0xFF).chr(0xF0));
84		usleep(125000);
85
86		fputs($fd,chr(0xFF).chr(0xFC).chr(0x01).chr(0xFF).chr(0xFC).
87		chr(0x22).chr(0xFF).chr(0xFE).chr(0x05).chr(0xFF).chr(0xFC).chr(0x21));
88		usleep(125000);
89
90		return;
91	}
92
93	Function KLG_Router_Generic_BGP_Command($cmd)
94	{
95		/* run a generic BGP command (output all data after "BGP") */
96		Global $lg_server, $lg_port, $lg_type, $lg_login, $lg_ssh, $lg_ssh_user, $lg_ssh_pass, $klg_output, $config;
97
98		$klg_output .= "<pre><span style=\"font-family: " . $config["output_font"] . "; font-size: 2; color: black;\">";
99		$fd = KLG_Execute_Command($cmd);
100		if ($fd)
101		{
102			$start = 0;
103			while ($buf = @fgets($fd, 8192))
104			{
105				$buf = str_replace("\r","",$buf);
106				$buf = str_replace("\n","",$buf);
107				if ($start==0)
108				{
109					if (substr($buf, 0, 4)=="BGP ")
110					{
111						$start = 1;
112						$klg_output .= CleanOutput(htmlentities($buf) . "\n");
113					}
114				} else {
115					$klg_output .= CleanOutput(htmlentities($buf) . "\n");
116				}
117			}
118		}
119		fclose($fd);
120		$klg_output .= "</span></pre>\n";
121	}
122
123	Function KLG_Router_Generic_Command($cmd)
124	{
125		/* Run a generic command, output raw data */
126		Global $lg_server, $lg_port2, $lg_type, $lg_login, $lg_ssh, $lg_ssh_user, $lg_ssh_pass, $klg_output, $config;
127
128		$klg_output .= "<pre><span style=\"font-family: " . $config["output_font"] . "; font-size: 2; color: black;\">";
129		$fd = KLG_Execute_Command($cmd, true);
130		if ($fd)
131		{
132			if ($lg_type=="juniper")
133			{
134				while ($buf = @fgets($fd, 8192))
135				{
136					if (strpos($buf, "cli>") > 0)
137						break;
138				}
139			}
140			$start = 0;
141			while ($buf = @fgets($fd, 8192))
142			{
143				$buf = str_replace("\r","",$buf);
144				$buf = str_replace("\n","",$buf);
145				if ($start==0)
146				{
147					if (strpos($buf, ">")>0)
148						$start = 1;
149				} else {
150					if ($lg_type != "juniper")
151					{
152						if (strpos($buf, "uccess")>0)
153							@fwrite($fd, "quit\n");
154						if (strpos($buf, ">")>0)
155							@fwrite($fd, "quit\n");
156					}
157					if (substr($buf, -4, 4) == "exit")
158						continue;
159					$klg_output .= CleanOutput(htmlentities($buf) . "\n");
160				}
161			}
162		}
163		fclose($fd);
164		$klg_output .= "</span></pre>\n";
165	}
166
167	Function KLG_Router_Juniper_BGP_Formatted_Command($cmd)
168	{
169		/* Run a BGP command, format the output (JunOS) */
170		Global $lg_server, $lg_port, $lg_login, $lg_ssh, $lg_ssh_user, $lg_ssh_pass, $klg_output, $config;
171
172		$klg_output .= "<pre><span style=\"font-family: " . $config["output_font"] . "; font-size: 2; color: black;\">";
173		$fd = KLG_Execute_Command($cmd);
174		if ($fd)
175		{
176			$start = 0;
177			$bestpath = 0;
178			while ($buf = @fgets($fd, 8192))
179			{
180				$buf = str_replace("\r","",$buf);
181				$buf = str_replace("\n","",$buf);
182				if ($start==0)
183				{
184					if (strpos($buf, $cmd)>0)
185					{
186						$start = 1;
187						@fwrite($fd, "exit\n");
188					}
189				} else {
190					if (strpos($buf, "Preference")>0)
191					{
192						if ((strpos($buf, "*BGP")>0 || strpos($buf, "*Static")) && ($bestpath==0))
193						{
194							/* bestpath */
195							$bestpath = 1;
196							$klg_output .= "<span style=\"color: red;\">";
197							$klg_output .= CleanOutput(htmlentities($buf) . "\n");
198							continue;
199						}
200						if ((strpos($buf, "BGP")>0 || strpos($buf, "Static")) && ($bestpath==1))
201						{
202							/* end of bestpath, got a new bestpath */
203							$bestpath = 0;
204							$klg_output .= "</span>";
205							$klg_output .= CleanOutput(htmlentities($buf) . "\n");
206							continue;
207						}
208					}
209					if ((strpos($buf, "announced)")>0) && ($bestpath==1))
210					{
211						/* new prefix, reset bestpath variable */
212						$bestpath = 0;
213						$klg_output .= "</span>";
214					}
215					if (strpos($buf, "AS path: ")>0)
216					{
217						/* do AS path translation */
218						$tmpout = "";
219						$tmp = substr($buf, strpos($buf, ":")+2, strlen($buf));
220						$asnums = preg_split("/ /", $tmp);
221						for ($i=0; $i<count($asnums); $i++)
222						{
223							/* ensure as number is valid */
224							$temp = $asnums[$i];
225							settype($temp, "integer");
226							if ($temp==$asnums[$i])
227								$as_name = LookupAS($asnums[$i]);
228							else
229								$as_name = "";
230							if ($as_name!="")
231								$asname = "$as_name [" . $asnums[$i] . "]";
232							else
233								$asname = $asnums[$i];
234							$tmpout .= $asname . " ";
235						}
236						while (substr($tmpout, -1, 1)==" ")
237							$tmpout = substr($tmpout, 0, strlen($tmpout)-1);
238						$tmpout = substr($buf, 0, strpos($buf, ":")+2) . $tmpout;
239						$klg_output .= CleanOutput(htmlentities($tmpout) . "\n");
240						continue;
241					}
242					if (strpos($buf, "Communities: ")>0)
243					{
244						/* do community lookups */
245						$tmpout = "";
246						$tmp = substr($buf, strpos($buf, ":")+2, strlen($buf));
247						$comms = preg_split("/ /", $tmp);
248						for ($i=0; $i<count($comms); $i++)
249						{
250							$community = preg_split("/\:/", $comms[$i]);
251							$tmp3 = LookupCommunity($community[0], $community[1]);
252							if ($tmp3=="")
253							{
254								$tmpout .= " " . $comms[$i];
255							} else {
256								$tmpout .= " " . LookupAS($community[0]) . ":" . $tmp3 . " [" . $comms[$i] . "]";
257							}
258						}
259						if (substr($tmpout, 0, 1)==" ")
260							$tmpout = substr($tmpout, 1, strlen($tmpout));
261						$tmpout = substr($buf, 0, strpos($buf, ":")+2) . $tmpout;
262						$klg_output .= CleanOutput(htmlentities($tmpout) . "\n");
263						continue;
264					}
265					$klg_output .= CleanOutput(htmlentities($buf) . "\n");
266				}
267			}
268		}
269		/* if we end on a bestpath, close span tag */
270		if ($bestpath==1)
271			$klg_output .= "</span>";
272		$klg_output .= "</span></pre>\n";
273	}
274
275	Function KLG_Router_BGP_Formatted_Command($cmd)
276	{
277		/* Run a BGP command, format the output */
278		Global $lg_server, $lg_port, $lg_login, $lg_ssh, $lg_ssh_user, $lg_ssh_pass, $klg_output, $config;
279
280		$klg_output .= "<pre><span style=\"font-family: " . $config["output_font"] . "; font-size: 2; color: black;\">";
281		$fd = KLG_Execute_Command($cmd);
282		if ($fd)
283		{
284			$start = 0;
285			$showingbestpath=0;
286			while ($buf = @fgets($fd, 8192))
287			{
288				$buf = str_replace("\r","",$buf);
289				$buf = str_replace("\n","",$buf);
290				if ($start==0)
291				{
292					if (substr($buf, 0, 4)=="BGP " || substr($buf, 0, 1)=="%")
293					{
294						$start = 1;
295						$klg_output .= CleanOutput(htmlentities($buf) . "\n");
296					}
297				} else {
298					if (strpos($buf, "Community: ")>0)
299					{
300						/* community entry */
301						$tmp = substr($buf, 0, strpos($buf, ":")+2);
302						$tmp2 = substr($buf, strpos($buf, ":")+2, strlen($buf));
303						$comms = preg_split("/ /", $tmp2);
304						for ($i=0; $i<count($comms); $i++)
305						{
306							$community = preg_split("/\:/", $comms[$i]);
307							$tmp3 = LookupCommunity($community[0], $community[1]);
308							if ($tmp3=="")
309							{
310								$tmp .= " " . $comms[$i];
311							} else {
312								$tmp .= " " . LookupAS($community[0]) . ":" . $tmp3 . " [" . $comms[$i] . "]";
313							}
314						}
315						$buf = CleanOutput(htmlentities($tmp));
316					}
317					if (substr($buf, 0, 7)=="Paths: ")
318					{
319						$tmp = substr($buf, 0, strpos($buf, "best #"));
320						$tmp .= "<span style=\"color: red; font-weight: bold;\">";
321						$tmp2 = substr($buf, strpos($buf, "best #"), strlen($buf));
322						$bestpath = substr($tmp2, strpos($tmp2, "#")+1, strlen($tmp2));
323						$bestpath = substr($bestpath, 0, strpos($bestpath, ","));
324						settype($bestpath, "integer");
325						$tmp .= substr($tmp2, 0, strpos($tmp2, ","));
326						$tmp .= "</span>";
327						$tmp .= substr($tmp2, strpos($tmp2, ","), strlen($tmp2));
328						$buf = $tmp;
329						$count = 0;
330					}
331					if ((substr($buf, 0, 2)=="  ") && (substr($buf, 2, 1)!=" ") &&
332						(substr($buf, 2, 1)!="A") && (substr($buf, 2, 1)!="N") &&
333						((strpos($buf, ".")<1 && strpos($buf, "2001:")<1 && strpos(strtolower($buf), "3ffe:")<1) || (strpos($buf,")")>0)))
334					{
335						$count++;
336						if ($count==$bestpath)
337						{
338							$tmpout = "<span style=\"color: red;\">";
339							$showingbestpath=1;
340						} else {
341							if ($showingbestpath==1)
342							{
343								$tmpout = "</span>";
344								$showingbestpath=0;
345							} else {
346								$tmpout = "";
347							}
348						}
349						if (strpos($buf, ",")>0)
350						{
351							$tmp = substr($buf, 2, strpos($buf, ",")-2);
352							$tmpleft = substr($buf, strpos($buf, ","), strlen($buf));
353						} else {
354							$tmp = substr($buf, 2, strlen($buf));
355							$tmpleft = "";
356						}
357						$asnums = preg_split("/ /", $tmp);
358						$tmpout .= "  ";
359						for ($i=0; $i<count($asnums); $i++)
360						{
361							$as_name = LookupAS($asnums[$i]);
362							if ($as_name!="")
363								$asname = "$as_name [" . $asnums[$i] . "]";
364							else
365								$asname = $asnums[$i];
366							$tmpout .= $asname . " ";
367						}
368						while (substr($tmpout, strlen($tmpout)-1, 1)==" ")
369							$tmpout = substr($tmpout, 0, strlen($tmpout)-1);
370						$buf = $tmpout . $tmpleft;
371					}
372					if ($buf!="")
373						$klg_output .= CleanOutput($buf . "\n");
374					else
375						$klg_output .= "<br />\n";
376				}
377			}
378		}
379		$klg_output .= "</span></span></pre>\n";
380	}
381?>
382