<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Networking Blog &#187; perl</title>
	<atom:link href="http://blog.webdir.bg/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.webdir.bg</link>
	<description>Networking - Cisco, Juniper, Linux</description>
	<lastBuildDate>Thu, 02 Feb 2012 21:09:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>PERL Apache Realtime Output From Script</title>
		<link>http://blog.webdir.bg/perl-apache-realtime-output-from-script/</link>
		<comments>http://blog.webdir.bg/perl-apache-realtime-output-from-script/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 13:10:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://blog.webdir.bg/?p=325</guid>
		<description><![CDATA[PERL Apache Realtime Output From Script, using  Net::Telnet]]></description>
			<content:encoded><![CDATA[<p>As of Apache 1.3, CGI scripts are essentially not buffered. Every time your script does a &#8220;flush&#8221; to output data, that data gets relayed on to the client. Some scripting languages, for example Perl, have their own buffering for output &#8211; this can be disabled by setting the $| special variable to 1. Of course this does increase the overall number of packets being transmitted, which can result in a sense of slowness for the end user.<br />
CGI scripts that generate their own headers are called nph  (non-parsed headers) scripts. The server must know in advance whether the particular CGI script intends to return a complete set of headers. Web servers handle this differently, but most recognize CGI scripts with a nph- prefix in their filename.<br />
When sending complete headers, you must at least send the   status line plus the Content-type and Server headers. You must print the entire status line; you should not print the Status header. As you will recall, the status line includes the protocol and version string (e.g., &#8220;HTTP/1.1&#8243;), but as you should recall, CGI provides this to you in the environment variable SERVER_PROTOCOL. Always use this variable in your CGI scripts, instead of hardcoding it, because the version in the SERVER_PROTOCOL may vary for older clients.<br />
For example the next perl script, is using telnet to connect to remote host and is executing traceroute. ( The source of this script is taken from freshmeat&#8217;s looking glass project). The most important lines are from 2 to 5. This script is using &#8220;Content-type: text/plain&#8221;, if you plan to use html tags chenged to &#8220;Content-type: text/html&#8221;.<br />
$| &#8211; If set to nonzero, forces a flush after every write or print.<br />
Example of nph-realtime-output.pl</p>
<pre class="brush: perl; title: ; notranslate">
#!/usr/bin/perl
print &quot;$ENV{SERVER_PROTOCOL} 200 OK\n&quot;;
print &quot;Server: $ENV{SERVER_SOFTWARE}\n&quot;;
print &quot;Content-type: text/plain\n\n&quot;;
$|=1;
use Net::Telnet;
$login=&quot;MyLogin&quot;;
$password=&quot;MySecret&quot;;
$port=&quot;23&quot;;
$host=&quot;xxx.xxx.xxx.xxx&quot;;
$command=&quot;traceroute www.google.com | no-more&quot;;
$telnet = new Net::Telnet;
$telnet-&gt;errmode( sub { print &quot;ERROR:&quot; . join('|', @_) . &quot;\n&quot;; } );
$telnet-&gt;timeout('10');
$telnet-&gt;option_callback( sub { return; } );
$telnet-&gt;option_accept(Do =&gt; 31);
$telnet-&gt;open(Host =&gt; $host, Port =&gt; $port);
if ($login ne &quot;&quot;) {
  $telnet-&gt;waitfor('/(ogin|name|word):.*$/');
  $telnet-&gt;print(&quot;$login&quot;);
}
if ($password ne &quot;&quot;) {
    $telnet-&gt;waitfor('/word:.*$/');
    $telnet-&gt;print(&quot;$password&quot;);
}
$telnet-&gt;waitfor(Match =&gt; '/.*[\$%&gt;] {0,1}$/',
                 Match =&gt; '/^[^#]*[\$%#&gt;] {0,1}$/');
$telnet-&gt;telnetmode(0);
$telnet-&gt;put(pack(&quot;C9&quot;,
                  255,                  # TELNET_IAC
                  250,                  # TELNET_SB
                  31, 0, 200, 0, 0,     # TELOPT_NAWS
                  255,                  # TELNET_IAC
                  240));                # TELNET_SE
$telnet-&gt;telnetmode(1);
my $telnetcmd = $command;
$telnet-&gt;print(&quot;$telnetcmd&quot;);
$telnet-&gt;getline;               # read out command line
while (1) {
  if ($#output &gt;= 0) {
    $_ = shift (@output);
  }
  elsif (! $telnet-&gt;eof) {
    my ($prematch, $match) = $telnet-&gt;waitfor(Match =&gt; '/\n/',
                                              Match =&gt; '/[\$%#&gt;] {0,1}$/',
                                              Errmode =&gt; &quot;return&quot;)
    or do {
    };
    if ($match =~ /[\$%#&gt;] {0,1}$/) {
      $telnet-&gt;print(&quot;quit&quot;);
      $telnet-&gt;close;
      last;
    }
    push @output, $prematch . $match;
    next;
  }
  else {
    last;
  }
  print $_;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.webdir.bg/perl-apache-realtime-output-from-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>cisco backup configuration</title>
		<link>http://blog.webdir.bg/cisco-backup-configuration/</link>
		<comments>http://blog.webdir.bg/cisco-backup-configuration/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 09:28:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Cisco]]></category>
		<category><![CDATA[backup config]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[snmp]]></category>

		<guid isPermaLink="false">http://blog.webdir.bg/?p=97</guid>
		<description><![CDATA[Detail tutorial how to automate backup of Cisco switch configuration, using MySQL, SNMP and PERL.]]></description>
			<content:encoded><![CDATA[<p>One simple method to backup Cisco&#8217;s configuration using SNMP and PERL. Download manually  from search.cpan.org  PERL library Cisco::CopyConfig  . Another way of installing:</p>
<pre>perl -MCPAN -e 'install Cisco::CopyConfig'</pre>
<p>Cisco::CopyConfig provides methods for manipulating the running-config of devices running IOS via SNMP directed TFTP. This module is essentially a wrapper for Net::SNMP and the CISCO-CONFIG-COPY-MIB-V1SMI.my MIB schema.<br />
It&#8217;s a good idea to store switch&#8217;s ip address ( if you have more switches ) in database like MySQL. The following perl script uses MySQL database. In MySQL database we store switch&#8217;s ip and snmp community.<br />
MySQL table:<span id="more-97"></span></p>
<pre> CREATE TABLE `sw_backup`.`switches` (
`id` BIGINT( 128 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`description` VARCHAR( 128 ) NOT NULL ,
`ip_address` VARCHAR( 128 ) NOT NULL ,
`community` VARCHAR( 128 ) NOT NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_bin

insert into switches values('','core-switch','192.168.200.251','SNMPconfigCommunity1');
insert into switches values('','access-switch','192.168.200.252','SNMPconfigCommunity2');

mysql&gt; select * from switches;
+----+---------------+-----------------+----------------------+
| id | description   | ip_address      | community            |
+----+---------------+-----------------+----------------------+
|  1 | core-switch   | 192.168.200.251 | SNMPconfigCommunity1 |
|  2 | access-switch | 192.168.200.252 | SNMPconfigCommunity2 |
+----+---------------+-----------------+----------------------+
2 rows in set (0.00 sec)</pre>
<p>We need to istall TFTP server:</p>
<pre>on Debian: apt-get install atftp</pre>
<p>TFTP config file (/etc/default/atftpd):</p>
<pre>USE_INETD=true
OPTIONS="--tftpd-timeout 300 --retry-timeout 5  --maxthread 100 --verbose=5 /backup_switch"</pre>
<p>TFTP working directory is /backup_switch<br />
Configuring Cisco switch ( tested on C2960G, C3750G, 3400G ):<br />
A read-write SNMP community needs to be defined on each device, which allows the setting of parameters to copy or merge a running-config. Below is an example configuration that attempts to restrict read-write access to only the 192.168.200.10 (tftp server) host :</p>
<pre>access-list 70 remark tft-server-list
access-list 70 permit 192.168.200.10
access-list 70 deny   any</pre>
<p>SNMP configuration:</p>
<pre>snmp-server tftp-server-list 70
snmp-server view backup ciscoMgmt.96.1.1.1.1 included
snmp-server community SNMPconfigCommunity1 view backup RW 70</pre>
<p>Variables used in cisco backup script:<br />
/backup_switch &#8211; tftp root directory<br />
/storage/backup/daily/switches/ &#8211; backup directory<br />
Backup script:</p>
<pre class="brush: perl; title: ; notranslate">
#!/usr/bin/perl
use DBI;
use Cisco::CopyConfig;

my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)=localtime(time);
$year+=1900;
$mon  = sprintf(&quot;%02d&quot;,$mon+1);
$mday = sprintf(&quot;%02d&quot;,$mday);
$hour = sprintf(&quot;%02d&quot;,$hour);
$min  = sprintf(&quot;%02d&quot;,$min);
$sec  = sprintf(&quot;%02d&quot;,$sec);
$date_format=&quot;$mday.$mon.$year&quot;;

$sql=&quot;select ip_address,community,description from switches order by inet_aton(ip_address) asc&quot;;
$dbh = DBI-&gt;connect(&quot;dbi:mysql:sw_backup:xxx.xxx.xxx.xxx&quot;,&quot;username&quot;,&quot;password&quot;) or die &quot;Can't connect to MySQL: $DBI::errstr\n&quot;;
$sth = $dbh-&gt;prepare($sql);
$sth-&gt;execute();

$tftp_address   = '192.168.200.10';

while (@row=$sth-&gt;fetchrow_array) {
 $config     = Cisco::CopyConfig-&gt;new(
 Host =&gt; $row[0],   # host
 Comm =&gt; $row[1], # community
 Tmout =&gt; '10',       # timeout
 Retry =&gt; '2'           # retry
 );

 $tftp_file = &quot;$row[2].$date_format.conf&quot;;

 if ($config-&gt;copy($tftp_address, $tftp_file) ) {
 print &quot;OK -&gt; switch ip: $row[0], file: $tftp_file\n&quot;; }
 else {
 print &quot;ERROR -&gt; switch ip: $row[0], no backup file\n&quot;;
 }

}

system(&quot;mkdir /storage/backup/daily/switches/$date_format&quot;);
system(&quot;cp /backup_switch/cisco-* /storage/backup/daily/switches/$date_format&quot;);
</pre>
<p>Result:</p>
<pre>sns ~ # perl cisco-backup.pl
OK -&gt; switch ip: 192.168.200.251, file: core-switch.19.01.2010.conf
OK -&gt; switch ip: 192.168.200.252, file: access-switch.19.01.2010.conf

sns ~ # tail -n 100 /var/log/syslog | grep tftp
Jan 19 15:56:53 sns atftpd[7848]: Fetching from 192.168.200.251 to core-switch.19.01.2010.conf
Jan 19 15:56:55 sns atftpd[7848]: Fetching from 192.168.200.252 to access-switch.19.01.2010.conf</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.webdir.bg/cisco-backup-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

