From maxime.baudin at ac-rennes.fr Mon Feb 3 15:26:04 2014 From: maxime.baudin at ac-rennes.fr (Maxime Baudin) Date: Mon, 03 Feb 2014 16:26:04 +0100 Subject: [rancid] Nortel Support In-Reply-To: <1F169C33264F9A43928391FE5D100EA6B47D87@MSG-P-VIR-M-62.mtolympus.partners.directs.com> References: <1F169C33264F9A43928391FE5D100EA6B47D87@MSG-P-VIR-M-62.mtolympus.partners.directs.com> Message-ID: <52EFB50C.8020006@ac-rennes.fr> Le 30/01/2014 17:38, AJ Schroeder a ?crit : > > Hello list, > Hello, > I finally got the Nortel switches in my environment backing up > properly with RANCID. > \o/ > I made separate scripts for the baystack and ERS switches in our > environment. As I was googling around I know that adding support for > these switches has been discussed in the past but I never saw an > answer. Would the devs of RANCID be interested in adding support for > these Nortel devices? > Don't know about de devs, but I'm really interested by the work you've done ! I have a lot of ERS switch and backup up is still a problem. Would you mind posting your scripts on the list ? Best regards, Maxime Baudin -------------- next part -------------- An HTML attachment was scrubbed... URL: From pc2_99 at hotmail.com Mon Feb 3 16:44:13 2014 From: pc2_99 at hotmail.com (Peter Conrad) Date: Mon, 3 Feb 2014 11:44:13 -0500 Subject: [rancid] VRF table-id 0 not active on Cisco IOS XE Switches Message-ID: Hi, I have quite a few Cisco 4500-E switches running IOS XE. Every time a switch is logged into, this line is in the next RANCID diff: ! config-register 0x2101 % VRF table-id 0 not active + % VRF table-id 0 not active ! The next run, the line is removed: ! config-register 0x2101 % VRF table-id 0 not active - % VRF table-id 0 not active ! This is rather annoying because I have other systems that login to the switches on a regular basis, so my RANCID diffs are full of this spam now. Is there any way to filter out the line "% VRF table-id 0 not active" so this doesn't happen again? Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.mckinnon at gmail.com Mon Feb 3 16:59:26 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Mon, 03 Feb 2014 18:59:26 +0200 Subject: [rancid] VRF table-id 0 not active on Cisco IOS XE Switches In-Reply-To: References: Message-ID: <52EFCAEE.1090500@gmail.com> That's very easy to do, rancid itself is full of such rules. For an example, look in sub ShowFlash for the script "rancid", you will see this near line 716: # Filter dhcp database next if (/dhcp_[^. ]*\.txt/); if the regular expression matches, the code branches to the next line in the input, effectively skipping over the unwanted input. Which IOS command returns your unwanted line? Find the command in @commandtable near the end of the script, it points to the sub that parses that command. Edit the sub by putting your custom code in it somewhere reasonable: next if (/VRF table-id 0 not active/); Almost all reasonable rancid installations acquire a collection of customizations like this, it's how we users make rancid do what we need it to do :-) You might want to tweak that regex a bit more, eg the 0 so probably use a /d+, I will leave that up to you. On 03/02/2014 18:44, Peter Conrad wrote: > Hi, I have quite a few Cisco 4500-E switches running IOS XE. Every time > a switch is logged into, this line is in the next RANCID diff: > > ! > > config-register 0x2101 > > % VRF table-id 0 not active > > + % VRF table-id 0 not active > > ! > > > > The next run, the line is removed: > > ! > > config-register 0x2101 > > % VRF table-id 0 not active > > - % VRF table-id 0 not active > > ! > > > > This is rather annoying because I have other systems that login to the > switches on a regular basis, so my RANCID diffs are full of this spam now. > > > > Is there any way to filter out the line ?% VRF table-id 0 not active? so > this doesn?t happen again? > > > > Thanks > > > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > -- Alan McKinnon alan.mckinnon at gmail.com From heas at shrubbery.net Mon Feb 3 17:51:49 2014 From: heas at shrubbery.net (heasley) Date: Mon, 3 Feb 2014 17:51:49 +0000 Subject: [rancid] VRF table-id 0 not active on Cisco IOS XE Switches In-Reply-To: <52EFCAEE.1090500@gmail.com> References: <52EFCAEE.1090500@gmail.com> Message-ID: <20140203175149.GG29867@shrubbery.net> Mon, Feb 03, 2014 at 06:59:26PM +0200, Alan McKinnon: > That's very easy to do, rancid itself is full of such rules. > > For an example, look in sub ShowFlash for the script "rancid", you will > see this near line 716: > > # Filter dhcp database > next if (/dhcp_[^. ]*\.txt/); > > if the regular expression matches, the code branches to the next line in > the input, effectively skipping over the unwanted input. > > Which IOS command returns your unwanted line? Find the command in > @commandtable near the end of the script, it points to the sub that > parses that command. Edit the sub by putting your custom code in it > somewhere reasonable: > > next if (/VRF table-id 0 not active/); > > Almost all reasonable rancid installations acquire a collection of > customizations like this, it's how we users make rancid do what we need > it to do :-) > > You might want to tweak that regex a bit more, eg the 0 so probably use > a /d+, I will leave that up to you. it could be from logging too; if logging is enabled on your vtys. > > > > On 03/02/2014 18:44, Peter Conrad wrote: > > Hi, I have quite a few Cisco 4500-E switches running IOS XE. Every time > > a switch is logged into, this line is in the next RANCID diff: > > > > ! > > > > config-register 0x2101 > > > > % VRF table-id 0 not active > > > > + % VRF table-id 0 not active > > > > ! > > > > > > > > The next run, the line is removed: > > > > ! > > > > config-register 0x2101 > > > > % VRF table-id 0 not active > > > > - % VRF table-id 0 not active > > > > ! > > > > > > > > This is rather annoying because I have other systems that login to the > > switches on a regular basis, so my RANCID diffs are full of this spam now. > > > > > > > > Is there any way to filter out the line ?% VRF table-id 0 not active? so > > this doesn?t happen again? > > > > > > > > Thanks > > > > > > > > _______________________________________________ > > Rancid-discuss mailing list > > Rancid-discuss at shrubbery.net > > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > > > > > -- > Alan McKinnon > alan.mckinnon at gmail.com > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss From AJ.Schroeder at directsupply.com Mon Feb 3 23:34:56 2014 From: AJ.Schroeder at directsupply.com (AJ Schroeder) Date: Mon, 3 Feb 2014 23:34:56 +0000 Subject: [rancid] Nortel Support In-Reply-To: <52EFB50C.8020006@ac-rennes.fr> References: <1F169C33264F9A43928391FE5D100EA6B47D87@MSG-P-VIR-M-62.mtolympus.partners.directs.com> <52EFB50C.8020006@ac-rennes.fr> Message-ID: <1F169C33264F9A43928391FE5D100EA6B58AA9@MSG-P-VIR-M-62.mtolympus.partners.directs.com> Hello, I have copies of the modified scripts here: https://github.com/ajschroeder/rancid/ Like I said, they aren't perfect, but the the 'passlogin' and 'passrancid' scripts backup the ERS 8300 and 8600 switches in our environment. We also have two Avaya 8800 switches here, but this script doesn't work with them at all. As for the 'nortellogin' and 'nortelrancid' scripts, I use those to backup our old Baystacks (460,470, 5510, 5520). The catch is that you need to make sure you have a late enough version of software loaded so you can disable the login banners and menus. I'll work on getting a README typed up at some point with some of this information. AJ From: rancid-discuss-bounces at shrubbery.net [mailto:rancid-discuss-bounces at shrubbery.net] On Behalf Of Maxime Baudin Sent: Monday, February 03, 2014 9:26 AM To: rancid-discuss at shrubbery.net Subject: Re: [rancid] Nortel Support Le 30/01/2014 17:38, AJ Schroeder a ?crit : Hello list, Hello, I finally got the Nortel switches in my environment backing up properly with RANCID. \o/ I made separate scripts for the baystack and ERS switches in our environment. As I was googling around I know that adding support for these switches has been discussed in the past but I never saw an answer. Would the devs of RANCID be interested in adding support for these Nortel devices? Don't know about de devs, but I'm really interested by the work you've done ! I have a lot of ERS switch and backup up is still a problem. Would you mind posting your scripts on the list ? Best regards, Maxime Baudin -------------- next part -------------- An HTML attachment was scrubbed... URL: From pc2_99 at hotmail.com Tue Feb 4 12:50:44 2014 From: pc2_99 at hotmail.com (Peter Conrad) Date: Tue, 4 Feb 2014 07:50:44 -0500 Subject: [rancid] VRF table-id 0 not active on Cisco IOS XE Switches In-Reply-To: References: , <52EFCAEE.1090500@gmail.com>, Message-ID: Thanks for the help. At line 1622 I added: # Filter IOS XE Bug next if (/VRF table-id 0 not active/); and it worked perfectly, no more annoying spam after logins to the switches. By the way, the command shows up in a sh run, so it went in the "WriteTerm" command subsection > Date: Mon, 3 Feb 2014 18:59:26 +0200 > From: alan.mckinnon at gmail.com > To: rancid-discuss at shrubbery.net > Subject: Re: [rancid] VRF table-id 0 not active on Cisco IOS XE Switches > > That's very easy to do, rancid itself is full of such rules. > > For an example, look in sub ShowFlash for the script "rancid", you will > see this near line 716: > > # Filter dhcp database > next if (/dhcp_[^. ]*\.txt/); > > if the regular expression matches, the code branches to the next line in > the input, effectively skipping over the unwanted input. > > Which IOS command returns your unwanted line? Find the command in > @commandtable near the end of the script, it points to the sub that > parses that command. Edit the sub by putting your custom code in it > somewhere reasonable: > > next if (/VRF table-id 0 not active/); > > Almost all reasonable rancid installations acquire a collection of > customizations like this, it's how we users make rancid do what we need > it to do :-) > > You might want to tweak that regex a bit more, eg the 0 so probably use > a /d+, I will leave that up to you. > > > > > On 03/02/2014 18:44, Peter Conrad wrote: > > Hi, I have quite a few Cisco 4500-E switches running IOS XE. Every time > > a switch is logged into, this line is in the next RANCID diff: > > > > ! > > > > config-register 0x2101 > > > > % VRF table-id 0 not active > > > > + % VRF table-id 0 not active > > > > ! > > > > > > > > The next run, the line is removed: > > > > ! > > > > config-register 0x2101 > > > > % VRF table-id 0 not active > > > > - % VRF table-id 0 not active > > > > ! > > > > > > > > This is rather annoying because I have other systems that login to the > > switches on a regular basis, so my RANCID diffs are full of this spam now. > > > > > > > > Is there any way to filter out the line ?% VRF table-id 0 not active? so > > this doesn?t happen again? > > > > > > > > Thanks > > > > > > > > _______________________________________________ > > Rancid-discuss mailing list > > Rancid-discuss at shrubbery.net > > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > > > > > -- > Alan McKinnon > alan.mckinnon at gmail.com > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss -------------- next part -------------- An HTML attachment was scrubbed... URL: From pawel.rzepa at gmail.com Thu Feb 6 07:44:01 2014 From: pawel.rzepa at gmail.com (=?UTF-8?B?UGF3ZcWCIFJ6ZXBh?=) Date: Thu, 6 Feb 2014 08:44:01 +0100 Subject: [rancid] hostname glob - regex? Message-ID: Hi, When I log into my devices to get configuration with rancid I must use two different users for two different groups of devices. I know that I can modify .cloginrc to achieve this: add user group-1-* {user1} add user group-2-* {user2} Unfortunately I am unable to describe groups of devices in such a consistent manner and now my .cloginrc looks like this: add user 192.168.1.* {user1} add password 192.168.1.* {pass1} add user 192.168.2.5 {user1} add password 192.168.2.5 {pass1} add user *-core-* {user1} add password *-core-* {pass1} add user 10.1.2.3 {user2} add user 10.1.5.* {user2} etc.. Is it possible to use regular expression to describe hostname? I'd love to specify them like that: add user {192.168.1.*|192.168.2.5|*-core-*} {user1} add password {192.168.1.*|192.168.2.5|*-core-*} {pass1} add user {10.1.2.3|10.1.5.*} {user2} ... Best regards, Pawel Rzepa From SAusten at lanecove.nsw.gov.au Fri Feb 7 05:47:24 2014 From: SAusten at lanecove.nsw.gov.au (Stephen Austen) Date: Fri, 7 Feb 2014 05:47:24 +0000 Subject: [rancid] HP Procurve 2920-48G-POE+ Stack and hrancid show stack command issue Message-ID: Hi, I am having an issue where config differs are being created every hour due to the response to "show stack" command in hrancid. The problem appears to be that "Uptime" in this command's response needs to be skipped/removed and my attempts at editing hrancid end up aborting due compile errors. --- networking/configs/X.X.X.X 2014/02/07 03:01:34 1.40 +++ networking/configs/ X.X.X.X 2014/02/07 04:01:36 1.42 @@ -34,7 +34,7 @@ ;MAC Address : 9cb654-d0638b ;Stack Topology : Chain ;Stack Status : Active -;Uptime : 48d 21h 20m +;Uptime : 48d 22h 20m ;Software Version : WB.15.11.0003 ; Mbr ; ID Mac Address Model Pri Status Would someone be so kind as to assist me in filtering out "Uptime" in hrancid, or elsewhere, to avoid unnecessary emails and CVS updates? System versions: rancid 2.3.8 on CentOS 5.9 Regards, Steve Austen
Walk Around The World
**********************************************************************
Looking for something in particular?
Visit our website: - www.lanecove.nsw.gov.au

**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
Lane Cove Council.

Information transmitted via email may be subject to corruption by the
process. Information contained in this email should not be relied upon 
where loss, damage or injury is possible. Verified information should
be obtained in writing directly from the authorised Council officers.

This footnote also confirms that this email message has been swept by
Sophos for the presence of computer viruses.

**********************************************************************

_____________________________________________________________________ This e-mail has been scanned for viruses by MCI's Internet Managed Scanning Services on behalf of Lane Cove Council - powered by MessageLabs. For further information visit http://www.mci.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.mckinnon at gmail.com Fri Feb 7 06:57:02 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Fri, 07 Feb 2014 08:57:02 +0200 Subject: [rancid] HP Procurve 2920-48G-POE+ Stack and hrancid show stack command issue In-Reply-To: References: Message-ID: <52F483BE.5070704@gmail.com> On 07/02/2014 07:47, Stephen Austen wrote: > Hi, > > > > I am having an issue where config differs are being created every hour > due to the response to ?show stack? command in hrancid. > > > > The problem appears to be that ?Uptime? in this command?s response needs > to be skipped/removed and my attempts at editing hrancid end up aborting > due compile errors. > > > > --- networking/configs/X.X.X.X 2014/02/07 > 03:01:34 1.40 > > +++ networking/configs/ X.X.X.X 2014/02/07 04:01:36 1.42 > > @@ -34,7 +34,7 @@ > > ;MAC Address : 9cb654-d0638b > > ;Stack Topology : Chain > > ;Stack Status : Active > > -;Uptime : 48d 21h 20m > > +;Uptime : 48d 22h 20m > > ;Software Version : WB.15.11.0003 > > ; > Mbr > > ; ID Mac Address Model Pri > Status > > > > Would someone be so kind as to assist me in filtering out ?Uptime? in > hrancid, or elsewhere, to avoid unnecessary emails and CVS updates? Add this to sub ShowStack(), directly after the 2 return statements is a good place: next if (/^Uptime/); That will remove any line starting with "Uptime", which I imagine will suit your needs. -- Alan McKinnon alan.mckinnon at gmail.com From Douglas.Hughes at DEShawResearch.com Fri Feb 7 13:52:11 2014 From: Douglas.Hughes at DEShawResearch.com (Hughes, Doug) Date: Fri, 7 Feb 2014 13:52:11 +0000 Subject: [rancid] HP Procurve 2920-48G-POE+ Stack and hrancid show stack command issue In-Reply-To: References: Message-ID: Yeah, if you check the mail list archives you will find that about 1/3 of the requests are similar in nature. The gist is, edit the hrancid file, find the routine that collects Uptime (it's one of the commandtable callbacks) and add a next if /;Uptime/; command in there near the other 'next if' commands. It's very easy. From: rancid-discuss-bounces at shrubbery.net [mailto:rancid-discuss-bounces at shrubbery.net] On Behalf Of Stephen Austen Sent: Friday, February 07, 2014 12:47 AM To: rancid-discuss at shrubbery.net Subject: [rancid] HP Procurve 2920-48G-POE+ Stack and hrancid show stack command issue Hi, I am having an issue where config differs are being created every hour due to the response to "show stack" command in hrancid. The problem appears to be that "Uptime" in this command's response needs to be skipped/removed and my attempts at editing hrancid end up aborting due compile errors. --- networking/configs/X.X.X.X 2014/02/07 03:01:34 1.40 +++ networking/configs/ X.X.X.X 2014/02/07 04:01:36 1.42 @@ -34,7 +34,7 @@ ;MAC Address : 9cb654-d0638b ;Stack Topology : Chain ;Stack Status : Active -;Uptime : 48d 21h 20m +;Uptime : 48d 22h 20m ;Software Version : WB.15.11.0003 ; Mbr ; ID Mac Address Model Pri Status Would someone be so kind as to assist me in filtering out "Uptime" in hrancid, or elsewhere, to avoid unnecessary emails and CVS updates? System versions: rancid 2.3.8 on CentOS 5.9 Regards, Steve Austen [Walk Around The World] ********************************************************************** Looking for something in particular? Visit our website: - www.lanecove.nsw.gov.au ********************************************************************** This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify Lane Cove Council. Information transmitted via email may be subject to corruption by the process. Information contained in this email should not be relied upon where loss, damage or injury is possible. Verified information should be obtained in writing directly from the authorised Council officers. This footnote also confirms that this email message has been swept by Sophos for the presence of computer viruses. ********************************************************************** _____________________________________________________________________ This e-mail has been scanned for viruses by MCI's Internet Managed Scanning Services on behalf of Lane Cove Council - powered by MessageLabs. For further information visit http://www.mci.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian at wadsworth.org Thu Feb 6 18:52:55 2014 From: brian at wadsworth.org (Brian Cuttler) Date: Thu, 6 Feb 2014 13:52:55 -0500 Subject: [rancid] Rancid 2.3.8, update issue Message-ID: <20140206185254.GA20403@nnewton.wadsworth.org> Hello, I am running Rancid 2.3.8 on a debian platform. It was setup some time ago by someone else (not available) and I've trying to configure and add a couple of new switches. I'd thought I had the (pretty simple) procedure worked out and had a added a switch a few weeks back, but in the more recent attempt I seem to have induced some CVS errors. I have renamed my switches, added them again with new names, actually saw the "switch being removed" message in the logs, but this error now persists. I am attaching two recently produced log files, and will abreviate to remove numerous similar lines. The problem seems to me to be in the CVS rather than the rancid side of things, but I haven't (after spending quite a bit of time on it) the foggiest. Thanks in advance for your help. This is the first run after I renamed the switches, removed the trans* switches in favor of the name d5862810* ------------------------------- starting: Thu Feb 6 13:14:35 EST 2014 cvs add: scheduling file `d5862810-1' for addition cvs add: use `cvs commit' to add this file permanently /home/rancid/var/rancid/CVS/ESP/configs/d5862810-1,v <-- d5862810-1 initial revision: 1.1 Added d5862810-1 cvs remove: scheduling `d5862810-2' for removal cvs remove: use `cvs commit' to remove this file permanently /home/rancid/var/rancid/CVS/ESP/configs/d5862810-2,v <-- d5862810-2 new revision: delete; previous revision: 1.1 Deleted d5862810-2 cvs remove: removed `trans2810-2' cvs commit: nothing known about `trans2810-2' cvs [commit aborted]: correct above errors first! Deleted trans2810-2 cvs remove: removed `trans2810-1' cvs commit: Up-to-date check failed for `trans2810-1' cvs [commit aborted]: correct above errors first! Deleted trans2810-1 -------- This is the second run. BTW: I will be restoring d5862810-2 to rancid, I just plan to model it on d5862810-1, now that its config is in fact available in rancid. I'll be my first restore test. -------- starting: Thu Feb 6 13:14:35 EST 2014 cvs add: scheduling file `d5862810-1' for addition cvs add: use `cvs commit' to add this file permanently /home/rancid/var/rancid/CVS/ESP/configs/d5862810-1,v <-- d5862810-1 initial revision: 1.1 Added d5862810-1 cvs remove: scheduling `d5862810-2' for removal cvs remove: use `cvs commit' to remove this file permanently /home/rancid/var/rancid/CVS/ESP/configs/d5862810-2,v <-- d5862810-2 new revision: delete; previous revision: 1.1 Deleted d5862810-2 cvs remove: removed `trans2810-2' cvs commit: nothing known about `trans2810-2' cvs [commit aborted]: correct above errors first! Deleted trans2810-2 cvs remove: removed `trans2810-1' cvs commit: Up-to-date check failed for `trans2810-1' cvs [commit aborted]: correct above errors first! Deleted trans2810-1 Trying to get all of the configs. root at dnix:/home/rancid/var/rancid/logs# cat ESP.20140206.131435 starting: Thu Feb 6 13:14:35 EST 2014 cvs add: scheduling file `d5862810-1' for addition cvs add: use `cvs commit' to add this file permanently /home/rancid/var/rancid/CVS/ESP/configs/d5862810-1,v <-- d5862810-1 initial revision: 1.1 Added d5862810-1 cvs remove: scheduling `d5862810-2' for removal cvs remove: use `cvs commit' to remove this file permanently /home/rancid/var/rancid/CVS/ESP/configs/d5862810-2,v <-- d5862810-2 new revision: delete; previous revision: 1.1 Deleted d5862810-2 cvs remove: removed `trans2810-2' cvs commit: nothing known about `trans2810-2' cvs [commit aborted]: correct above errors first! Deleted trans2810-2 cvs remove: removed `trans2810-1' cvs commit: Up-to-date check failed for `trans2810-1' cvs [commit aborted]: correct above errors first! Deleted trans2810-1 Trying to get all of the configs. All routers sucessfully completed. cvs diff: Diffing . cvs diff: Diffing configs cvs commit: Examining . cvs commit: Examining configs cvs commit: Up-to-date check failed for `configs/b10002650-1' cvs commit: Up-to-date check failed for `configs/b10122650-1' cvs commit: Up-to-date check failed for `configs/b10122650-2' < many lines removed from this section> cvs commit: Up-to-date check failed for `configs/wclr2821' cvs commit: Up-to-date check failed for `configs/wclrgw' cvs commit: Up-to-date check failed for `configs/wclrgwfail' cvs [commit aborted]: correct above errors first! ending: Thu Feb 6 13:18:02 EST 2014 --- Brian R Cuttler brian.cuttler at wadsworth.org Computer Systems Support (v) 518 486-1697 Wadsworth Center (f) 518 473-6384 NYS Department of Health Help Desk 518 473-0773 From brian at wadsworth.org Fri Feb 7 15:57:08 2014 From: brian at wadsworth.org (Brian Cuttler) Date: Fri, 7 Feb 2014 10:57:08 -0500 Subject: [rancid] Rancid 2.3.8, update issue In-Reply-To: <20140206185254.GA20403@nnewton.wadsworth.org> References: <20140206185254.GA20403@nnewton.wadsworth.org> Message-ID: <20140207155708.GG20403@nnewton.wadsworth.org> The most recent rancid run did not have any specific meantion of the trans2810* switches, but did have an uncomfortably large number of instances of the word "failed". Do I need to take an action? If so, can you please step me through what that action sequence might be? thank you, Brian This file is unabridged. # cat ESP.20140207.102001 starting: Fri Feb 7 10:20:01 EST 2014 Trying to get all of the configs. All routers sucessfully completed. cvs diff: Diffing . cvs diff: Diffing configs cvs commit: Examining . cvs commit: Examining configs cvs commit: Up-to-date check failed for `configs/b10002650-1' cvs commit: Up-to-date check failed for `configs/b10122650-1' cvs commit: Up-to-date check failed for `configs/b10122650-2' cvs commit: Up-to-date check failed for `configs/c2802626-1' cvs commit: Up-to-date check failed for `configs/c280dcrack2650-1' cvs commit: Up-to-date check failed for `configs/c280dcrack2810-1' cvs commit: Up-to-date check failed for `configs/c280dcrack2810-172' cvs commit: Up-to-date check failed for `configs/c280rack12650-1' cvs commit: Up-to-date check failed for `configs/c280rack12810-1' cvs commit: Up-to-date check failed for `configs/c280rack12810-2' cvs commit: Up-to-date check failed for `configs/c280rack42810-1' cvs commit: Up-to-date check failed for `configs/c280rack42810-2' cvs commit: Up-to-date check failed for `configs/c280rack4n-1' cvs commit: Up-to-date check failed for `configs/c280rack52650-1' cvs commit: Up-to-date check failed for `configs/c280rack52810-1' cvs commit: Up-to-date check failed for `configs/c280rack52810-2' cvs commit: Up-to-date check failed for `configs/c280rack72650-1' cvs commit: Up-to-date check failed for `configs/c280rack72810-1' cvs commit: Up-to-date check failed for `configs/c6b2626-1' cvs commit: Up-to-date check failed for `configs/d10a2650-1' cvs commit: Up-to-date check failed for `configs/d10b2650-1' cvs commit: Up-to-date check failed for `configs/d12650-1' cvs commit: Up-to-date check failed for `configs/d12650-2' cvs commit: Up-to-date check failed for `configs/d132650-1' cvs commit: Up-to-date check failed for `configs/d132650-2' cvs commit: Up-to-date check failed for `configs/d1462650-1' cvs commit: Up-to-date check failed for `configs/d172650-1' cvs commit: Up-to-date check failed for `configs/d172650-2' cvs commit: Up-to-date check failed for `configs/d22650-1' cvs commit: Up-to-date check failed for `configs/d22650-2' cvs commit: Up-to-date check failed for `configs/d2452650-1' cvs commit: Up-to-date check failed for `configs/d32650-1' cvs commit: Up-to-date check failed for `configs/d32650-2' cvs commit: Up-to-date check failed for `configs/d42650-1' cvs commit: Up-to-date check failed for `configs/d42650-2' cvs commit: Up-to-date check failed for `configs/d42650-3' cvs commit: Up-to-date check failed for `configs/d4862650-1' cvs commit: Up-to-date check failed for `configs/d52650-1' cvs commit: Up-to-date check failed for `configs/d52650-2' cvs commit: Up-to-date check failed for `configs/d5862650-1' cvs commit: Up-to-date check failed for `configs/d6b2610-2' cvs commit: Up-to-date check failed for `configs/d6b2610-3' cvs commit: Up-to-date check failed for `configs/d6b2610-4' cvs commit: Up-to-date check failed for `configs/d6b2650-1' cvs commit: Up-to-date check failed for `configs/d6b2810-1' cvs commit: Up-to-date check failed for `configs/d7b2650-1' cvs commit: Up-to-date check failed for `configs/d7b2650-2' cvs commit: Up-to-date check failed for `configs/d7b5308-1' cvs commit: Up-to-date check failed for `configs/d82650-1' cvs commit: Up-to-date check failed for `configs/d9a2650-1' cvs commit: Up-to-date check failed for `configs/d9a2650-2' cvs commit: Up-to-date check failed for `configs/d9b2650-1' cvs commit: Up-to-date check failed for `configs/dlc2650-1' cvs commit: Up-to-date check failed for `configs/dlc2650-2' cvs commit: Up-to-date check failed for `configs/dmz162626-1' cvs commit: Up-to-date check failed for `configs/dmz192626-1' cvs commit: Up-to-date check failed for `configs/dmzapoa2626-1' cvs commit: Up-to-date check failed for `configs/e10002650-1' cvs commit: Up-to-date check failed for `configs/exec2626-1' cvs commit: Up-to-date check failed for `configs/exec2810-1' cvs commit: Up-to-date check failed for `configs/frank2650-1' cvs commit: Up-to-date check failed for `configs/gerwin2810-1' cvs commit: Up-to-date check failed for `configs/ids2650-1' cvs commit: Up-to-date check failed for `configs/libceiling2626-1' cvs commit: Up-to-date check failed for `configs/libe2626-1' cvs commit: Up-to-date check failed for `configs/librefdesk2626-1' cvs commit: Up-to-date check failed for `configs/mgtsrv2650-1' cvs commit: Up-to-date check failed for `configs/notes2626-1' cvs commit: Up-to-date check failed for `configs/wceport' cvs commit: Up-to-date check failed for `configs/wclr-oft-2821' cvs commit: Up-to-date check failed for `configs/wclr2626' cvs commit: Up-to-date check failed for `configs/wclr2821' cvs commit: Up-to-date check failed for `configs/wclrgw' cvs commit: Up-to-date check failed for `configs/wclrgwfail' cvs [commit aborted]: correct above errors first! ending: Fri Feb 7 10:23:17 EST 2014 --- Brian R Cuttler brian.cuttler at wadsworth.org Computer Systems Support (v) 518 486-1697 Wadsworth Center (f) 518 473-6384 NYS Department of Health Help Desk 518 473-0773 From brian at wadsworth.org Fri Feb 7 21:11:43 2014 From: brian at wadsworth.org (Brian Cuttler) Date: Fri, 7 Feb 2014 16:11:43 -0500 Subject: [rancid] [heas@shrubbery.net: Re: Rancid 2.3.8, update issue] Message-ID: <20140207211143.GI20403@nnewton.wadsworth.org> Heasley, # you need to fix the cvs. cd group; rm configs/*; cvs update I'm a little afraid your overestimating what I know about rancid and cvs. group would be CVSROOT//configs where the site is one of several config directories I have, in this case "ESP"? Or is it that other data tree that rancid seems to communicate with? There is some client server thing going on here? on a single machine. I (just now) # cd'd to that directory and run the cvs update, first time cvs has run without error, so I must be in a better (if not actually correct) spot. Ah, the new run of rancid has produced that looks like a much cleaner output. I think that was it, unless you tell me I still have problems. So, the delete cleans up the unlocked retrieved cvs files? The committed files are in this directory, and bear a resemblance to RCS files? Then the update does what, restore/non-locking from cvs? Sorry - just trying to figure out what I did, I'll help me the next time I find or induce an error. many thanks, Brian # /data1/rancid/CVS/ESP/configs$ ls Attic d10a2650-1,v d52650-2,v e10002650-1,v b10002650-1,v d10b2650-1,v d52650-3,v e2502626-1,v b10122650-1,v d12650-1,v d5862650-1,v exec2626-1,v b10122650-2,v d12650-2,v d6b2610-2,v exec2810-1,v c2802626-1,v d132650-1,v d6b2610-3,v frank2650-1,v c280dcrack2650-1,v d132650-2,v d6b2610-4,v gerwin2810-1,v c280dcrack2810-172,v d1462650-1,v d6b2650-1,v ids2650-1,v c280dcrack2810-1,v d172650-1,v d6b2810-1,v libceiling2626-1,v c280rack12650-1,v d172650-2,v d7b2650-1,v libe2626-1,v c280rack12810-1,v d172810-1,v d7b2650-2,v librefdesk2626-1,v c280rack12810-2,v d22650-1,v d7b5308-1,v mgtsrv2650-1,v c280rack42810-1,v d22650-2,v d82650-1,v notes2626-1,v c280rack42810-2,v d2452650-1,v d9a2650-1,v test2626-1,v c280rack4n-1,v d32650-1,v d9a2650-2,v wceport,v c280rack52650-1,v d32650-2,v d9b2650-1,v wclr2626,v c280rack52810-1,v d42650-1,v dlc2650-1,v wclr2821,v c280rack52810-2,v d42650-2,v dlc2650-2,v wclrgwfail,v c280rack72650-1,v d42650-3,v dmz162626-1,v wclrgw,v c280rack72810-1,v d4862650-1,v dmz192626-1,v wclr-oft-2821,v c6b2626-1,v d52650-1,v dmzapoa2626-1,v # cat ESP.20140207.160131 starting: Fri Feb 7 16:01:31 EST 2014 cvs remove: scheduling `trans2810-1' for removal cvs remove: use `cvs commit' to remove this file permanently /home/rancid/var/rancid/CVS/ESP/configs/trans2810-1,v <-- trans2810-1 new revision: delete; previous revision: 1.25 Deleted trans2810-1 Trying to get all of the configs. All routers sucessfully completed. cvs diff: Diffing . cvs diff: Diffing configs cvs commit: Examining . cvs commit: Examining configs /home/rancid/var/rancid/CVS/ESP/router.db,v <-- router.db new revision: 1.6; previous revision: 1.5 /home/rancid/var/rancid/CVS/ESP/configs/d172650-2,v <-- configs/d172650-2 new revision: 1.14; previous revision: 1.13 /home/rancid/var/rancid/CVS/ESP/configs/d172810-1,v <-- configs/d172810-1 new revision: 1.2; previous revision: 1.1 /home/rancid/var/rancid/CVS/ESP/configs/d5862650-1,v <-- configs/d5862650-1 new revision: 1.12; previous revision: 1.11 /home/rancid/var/rancid/CVS/ESP/configs/test2626-1,v <-- configs/test2626-1 new revision: 1.26; previous revision: 1.25 /home/rancid/var/rancid/CVS/ESP/configs/wclr2821,v <-- configs/wclr2821 new revision: 1.9; previous revision: 1.8 ending: Fri Feb 7 16:04:42 EST 2014 ----- Forwarded message from heasley ----- X-Sieve: CMU Sieve 2.4 Date: Fri, 7 Feb 2014 20:41:58 +0000 From: heasley To: Brian Cuttler Subject: Re: [rancid] Rancid 2.3.8, update issue In-Reply-To: <20140207155708.GG20403 at nnewton.wadsworth.org> X-PGPkey: http://www.shrubbery.net/~heas/public-key.asc X-note: live free, or die! X-homer: i just want to have a beer while i am caring. X-Claimation: an engineer needs a manager like a fish needs a bicycle X-reality: only YOU can put an end to the embarrassment that is Tom Cruise User-Agent: Mutt/1.5.21 (2010-09-15) X-Wadsworth-MailScanner-Information: Please contact the ITG for more information X-Wadsworth-MailScanner-ID: s17KgKeM017705 X-Wadsworth-MailScanner: Found to be clean X-Wadsworth-MailScanner-SpamCheck: not spam, SpamAssassin (not cached, score=0, required 5, autolearn=not spam) X-Wadsworth-MailScanner-From: heas at shrubbery.net X-Spam-Status: No Fri, Feb 07, 2014 at 10:57:08AM -0500, Brian Cuttler: > > The most recent rancid run did not have any specific meantion of > the trans2810* switches, but did have an uncomfortably large number > of instances of the word "failed". > > Do I need to take an action? If so, can you please step me through > what that action sequence might be? you need to fix the cvs. cd group; rm configs/*; cvs update > thank you, > > Brian > > This file is unabridged. > > # cat ESP.20140207.102001 > starting: Fri Feb 7 10:20:01 EST 2014 > > > > Trying to get all of the configs. > All routers sucessfully completed. > > cvs diff: Diffing . > cvs diff: Diffing configs > cvs commit: Examining . > cvs commit: Examining configs > cvs commit: Up-to-date check failed for `configs/b10002650-1' > cvs commit: Up-to-date check failed for `configs/b10122650-1' > cvs commit: Up-to-date check failed for `configs/b10122650-2' > cvs commit: Up-to-date check failed for `configs/c2802626-1' > cvs commit: Up-to-date check failed for `configs/c280dcrack2650-1' > cvs commit: Up-to-date check failed for `configs/c280dcrack2810-1' > cvs commit: Up-to-date check failed for `configs/c280dcrack2810-172' > cvs commit: Up-to-date check failed for `configs/c280rack12650-1' > cvs commit: Up-to-date check failed for `configs/c280rack12810-1' > cvs commit: Up-to-date check failed for `configs/c280rack12810-2' > cvs commit: Up-to-date check failed for `configs/c280rack42810-1' > cvs commit: Up-to-date check failed for `configs/c280rack42810-2' > cvs commit: Up-to-date check failed for `configs/c280rack4n-1' > cvs commit: Up-to-date check failed for `configs/c280rack52650-1' > cvs commit: Up-to-date check failed for `configs/c280rack52810-1' > cvs commit: Up-to-date check failed for `configs/c280rack52810-2' > cvs commit: Up-to-date check failed for `configs/c280rack72650-1' > cvs commit: Up-to-date check failed for `configs/c280rack72810-1' > cvs commit: Up-to-date check failed for `configs/c6b2626-1' > cvs commit: Up-to-date check failed for `configs/d10a2650-1' > cvs commit: Up-to-date check failed for `configs/d10b2650-1' > cvs commit: Up-to-date check failed for `configs/d12650-1' > cvs commit: Up-to-date check failed for `configs/d12650-2' > cvs commit: Up-to-date check failed for `configs/d132650-1' > cvs commit: Up-to-date check failed for `configs/d132650-2' > cvs commit: Up-to-date check failed for `configs/d1462650-1' > cvs commit: Up-to-date check failed for `configs/d172650-1' > cvs commit: Up-to-date check failed for `configs/d172650-2' > cvs commit: Up-to-date check failed for `configs/d22650-1' > cvs commit: Up-to-date check failed for `configs/d22650-2' > cvs commit: Up-to-date check failed for `configs/d2452650-1' > cvs commit: Up-to-date check failed for `configs/d32650-1' > cvs commit: Up-to-date check failed for `configs/d32650-2' > cvs commit: Up-to-date check failed for `configs/d42650-1' > cvs commit: Up-to-date check failed for `configs/d42650-2' > cvs commit: Up-to-date check failed for `configs/d42650-3' > cvs commit: Up-to-date check failed for `configs/d4862650-1' > cvs commit: Up-to-date check failed for `configs/d52650-1' > cvs commit: Up-to-date check failed for `configs/d52650-2' > cvs commit: Up-to-date check failed for `configs/d5862650-1' > cvs commit: Up-to-date check failed for `configs/d6b2610-2' > cvs commit: Up-to-date check failed for `configs/d6b2610-3' > cvs commit: Up-to-date check failed for `configs/d6b2610-4' > cvs commit: Up-to-date check failed for `configs/d6b2650-1' > cvs commit: Up-to-date check failed for `configs/d6b2810-1' > cvs commit: Up-to-date check failed for `configs/d7b2650-1' > cvs commit: Up-to-date check failed for `configs/d7b2650-2' > cvs commit: Up-to-date check failed for `configs/d7b5308-1' > cvs commit: Up-to-date check failed for `configs/d82650-1' > cvs commit: Up-to-date check failed for `configs/d9a2650-1' > cvs commit: Up-to-date check failed for `configs/d9a2650-2' > cvs commit: Up-to-date check failed for `configs/d9b2650-1' > cvs commit: Up-to-date check failed for `configs/dlc2650-1' > cvs commit: Up-to-date check failed for `configs/dlc2650-2' > cvs commit: Up-to-date check failed for `configs/dmz162626-1' > cvs commit: Up-to-date check failed for `configs/dmz192626-1' > cvs commit: Up-to-date check failed for `configs/dmzapoa2626-1' > cvs commit: Up-to-date check failed for `configs/e10002650-1' > cvs commit: Up-to-date check failed for `configs/exec2626-1' > cvs commit: Up-to-date check failed for `configs/exec2810-1' > cvs commit: Up-to-date check failed for `configs/frank2650-1' > cvs commit: Up-to-date check failed for `configs/gerwin2810-1' > cvs commit: Up-to-date check failed for `configs/ids2650-1' > cvs commit: Up-to-date check failed for `configs/libceiling2626-1' > cvs commit: Up-to-date check failed for `configs/libe2626-1' > cvs commit: Up-to-date check failed for `configs/librefdesk2626-1' > cvs commit: Up-to-date check failed for `configs/mgtsrv2650-1' > cvs commit: Up-to-date check failed for `configs/notes2626-1' > cvs commit: Up-to-date check failed for `configs/wceport' > cvs commit: Up-to-date check failed for `configs/wclr-oft-2821' > cvs commit: Up-to-date check failed for `configs/wclr2626' > cvs commit: Up-to-date check failed for `configs/wclr2821' > cvs commit: Up-to-date check failed for `configs/wclrgw' > cvs commit: Up-to-date check failed for `configs/wclrgwfail' > cvs [commit aborted]: correct above errors first! > > ending: Fri Feb 7 10:23:17 EST 2014 > > > --- > Brian R Cuttler brian.cuttler at wadsworth.org > Computer Systems Support (v) 518 486-1697 > Wadsworth Center (f) 518 473-6384 > NYS Department of Health Help Desk 518 473-0773 > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss ----- End forwarded message ----- --- Brian R Cuttler brian.cuttler at wadsworth.org Computer Systems Support (v) 518 486-1697 Wadsworth Center (f) 518 473-6384 NYS Department of Health Help Desk 518 473-0773 From pawel.rzepa at gmail.com Sun Feb 9 23:01:34 2014 From: pawel.rzepa at gmail.com (=?UTF-8?B?UGF3ZcWCIFJ6ZXBh?=) Date: Mon, 10 Feb 2014 00:01:34 +0100 Subject: [rancid] hostname glob - regex? In-Reply-To: References: Message-ID: <52F808CE.6060206@gmail.com> W dniu 06.02.2014 08:44, Pawel Rzepa pisze: Hi, Any help? I've digged into this a little and found that .cloginrc is interpreted by expect. I'm not very familiar with expect, tried some regexps with braces, escaped braces etc and no success. Is it impossible to use regexp in this context? Regards, Pawel Rzepa > Hi, > When I log into my devices to get configuration with rancid I must use > two different users for two different groups of devices. I know that I > can modify .cloginrc to achieve this: > > add user group-1-* {user1} > add user group-2-* {user2} > > Unfortunately I am unable to describe groups of devices in such a > consistent manner and now my .cloginrc looks like this: > > add user 192.168.1.* {user1} > add password 192.168.1.* {pass1} > add user 192.168.2.5 {user1} > add password 192.168.2.5 {pass1} > add user *-core-* {user1} > add password *-core-* {pass1} > > add user 10.1.2.3 {user2} > add user 10.1.5.* {user2} > etc.. > > Is it possible to use regular expression to describe hostname? I'd > love to specify them like that: > > add user {192.168.1.*|192.168.2.5|*-core-*} {user1} > add password {192.168.1.*|192.168.2.5|*-core-*} {pass1} > > add user {10.1.2.3|10.1.5.*} {user2} > ... > > Best regards, > Pawel Rzepa From heas at shrubbery.net Mon Feb 10 17:30:57 2014 From: heas at shrubbery.net (heasley) Date: Mon, 10 Feb 2014 17:30:57 +0000 Subject: [rancid] hostname glob - regex? In-Reply-To: <52F808CE.6060206@gmail.com> References: <52F808CE.6060206@gmail.com> Message-ID: <20140210173057.GC22932@shrubbery.net> Mon, Feb 10, 2014 at 12:01:34AM +0100, Pawe?? Rzepa: > W dniu 06.02.2014 08:44, Pawel Rzepa pisze: > > Hi, > Any help? I've digged into this a little and found that .cloginrc is > interpreted by expect. I'm not very familiar with expect, tried some > regexps with braces, escaped braces etc and no success. Is it impossible > to use regexp in this context? no; if it were, the manpage would have read regex, not glob. regex would be useful; though i'm not sure how to implement it, since glob and regex are not complatible. perhaps a global knob in cloginrc that switches the format to regex? or an regex-specific version of the 'add' function and search regexes before globs? Per Olaf, ideas? > Regards, > Pawel Rzepa > > > Hi, > > When I log into my devices to get configuration with rancid I must use > > two different users for two different groups of devices. I know that I > > can modify .cloginrc to achieve this: > > > > add user group-1-* {user1} > > add user group-2-* {user2} > > > > Unfortunately I am unable to describe groups of devices in such a > > consistent manner and now my .cloginrc looks like this: > > > > add user 192.168.1.* {user1} > > add password 192.168.1.* {pass1} > > add user 192.168.2.5 {user1} > > add password 192.168.2.5 {pass1} > > add user *-core-* {user1} > > add password *-core-* {pass1} > > > > add user 10.1.2.3 {user2} > > add user 10.1.5.* {user2} > > etc.. > > > > Is it possible to use regular expression to describe hostname? I'd > > love to specify them like that: > > > > add user {192.168.1.*|192.168.2.5|*-core-*} {user1} > > add password {192.168.1.*|192.168.2.5|*-core-*} {pass1} > > > > add user {10.1.2.3|10.1.5.*} {user2} > > ... > > > > Best regards, > > Pawel Rzepa > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss From feld at FreeBSD.org Tue Feb 11 18:39:29 2014 From: feld at FreeBSD.org (Mark Felder) Date: Tue, 11 Feb 2014 12:39:29 -0600 Subject: [rancid] rancid 2.3.8.p4 = rancid 2.3.9? Message-ID: <1392143969.7549.82141153.56B99AFA@webmail.messagingengine.com> Is there a formal release of rancid 2.3.9? I notice the 4 patches on the ftp (rancid 2.3.8.p1-p4) update the CHANGES file to say 2.3.9, so is 2.3.9 an official "thing" yet? Those patches look nice, and if they're meant to be consumed I'd love to add them to the FreeBSD port. If someone could roll them into a 2.3.9 tarball that would be great too. I'm not subscribed, so please CC me. Thanks! From heas at shrubbery.net Tue Feb 11 22:47:20 2014 From: heas at shrubbery.net (heasley) Date: Tue, 11 Feb 2014 22:47:20 +0000 Subject: [rancid] rancid 2.3.8.p4 = rancid 2.3.9? In-Reply-To: <1392143969.7549.82141153.56B99AFA@webmail.messagingengine.com> References: <1392143969.7549.82141153.56B99AFA@webmail.messagingengine.com> Message-ID: <20140211224720.GB86600@shrubbery.net> Tue, Feb 11, 2014 at 12:39:29PM -0600, Mark Felder: > Is there a formal release of rancid 2.3.9? I notice the 4 patches on the > ftp (rancid 2.3.8.p1-p4) update the CHANGES file to say 2.3.9, so is > 2.3.9 an official "thing" yet? Those patches look nice, and if they're > meant to be consumed I'd love to add them to the FreeBSD port. If > someone could roll them into a 2.3.9 tarball that would be great too. there was not; we were going in that direction, but it will ultimately be 3.0. see ftp://ftp.shrubbery.net/pub/rancid/alpha. perhaps just go for 3.0. From andrew.ohnstad at gmail.com Thu Feb 13 12:03:28 2014 From: andrew.ohnstad at gmail.com (Andrew Ohnstad) Date: Thu, 13 Feb 2014 07:03:28 -0500 Subject: [rancid] Scripting clogin with bash and username/password Message-ID: I'm not sure if I'm asking more of the tool than what's possible, or if I'm just missing the secret sauce. I've got rancid set up and working for archiving configs. I'm now trying to use clogin as part of a bash shell script to push configuration changes to a bunch of devices. The catch is that the devices are a) only reachable through ssh, and b) clogin must use a username and password provided as command line arguments and NOT any credentials stored in a .cloginrc file. This is a requirement so that the user pushing the updates can be logged. Is there a set of arguments to clogin that will tell it to ignore the username and password? I can get it to pass the specified username with the -u command, but by running with debugging turned on, I saw that it was still using the password in the .cloginrc file for all the logins. It seems to ignore every password related command line argument. Thanks in advance for any advice you can provide. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.mckinnon at gmail.com Thu Feb 13 12:49:46 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Thu, 13 Feb 2014 14:49:46 +0200 Subject: [rancid] Scripting clogin with bash and username/password In-Reply-To: References: Message-ID: <52FCBF6A.7060809@gmail.com> On 13/02/2014 14:03, Andrew Ohnstad wrote: > I'm not sure if I'm asking more of the tool than what's possible, or if > I'm just missing the secret sauce. > > I've got rancid set up and working for archiving configs. I'm now trying > to use clogin as part of a bash shell script to push configuration > changes to a bunch of devices. The catch is that the devices are a) only > reachable through ssh, and b) clogin must use a username and password > provided as command line arguments and NOT any credentials stored in a > .cloginrc file. This is a requirement so that the user pushing the > updates can be logged. > > Is there a set of arguments to clogin that will tell it to ignore the > username and password? I can get it to pass the specified username with > the -u command, but by running with debugging turned on, I saw that it > was still using the password in the .cloginrc file for all the logins. > It seems to ignore every password related command line argument. > > Thanks in advance for any advice you can provide. Did you use this syntax: clogin -u -p -e -c routername a) is not a problem. if you have method in .cloginrc as "telnet ssh" and telnet fails, it tries ssh. b) Personally I wouldn't use -p or -e, I'd let .cloginrc deal with that. When a password is on the command line and visible to ps, or logged in a log file, I consider that to be situation=game_over, but your needs may be different -- Alan McKinnon alan.mckinnon at gmail.com From andrew.ohnstad at gmail.com Thu Feb 13 08:02:57 2014 From: andrew.ohnstad at gmail.com (Andrew Ohnstad) Date: Thu, 13 Feb 2014 03:02:57 -0500 Subject: [rancid] Scripting clogin with ash and username/password Message-ID: I'm not sure if I'm asking more of the tool than what's possible, or if I'm just missing the secret sauce. I've got rancid set up and working for archiving configs. I'm now trying to use clogin as part of a bash shell script to push configuration changes to a bunch of devices. The catch is that the devices are a) only reachable through ssh, and b) clogin must use a username and password provided as command line arguments and NOT any credentials stored in a .cloginrc file. This is a requirement so that the user pushing the updates can be logged. Is there a set of arguments to clogin that will tell it to ignore the username and password? I can get it to pass the specified username with the -u command, but by running with debugging turned on, I saw that it was still using the password in the .cloginrc file for all the logins. It seems to ignore every password related command line argument. Thanks in advance for any advice you can provide. -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.ohnstad at gmail.com Thu Feb 13 15:22:11 2014 From: andrew.ohnstad at gmail.com (Andrew Ohnstad) Date: Thu, 13 Feb 2014 10:22:11 -0500 Subject: [rancid] Scripting clogin with bash and username/password In-Reply-To: <52FCBF6A.7060809@gmail.com> References: <52FCBF6A.7060809@gmail.com> Message-ID: Thanks for the response. The full command line I am using is (I automatically am enabled via TACACS+): sudo -u rancid /usr/libexec/rancid/clogin -u -p -c where If I add the -d argument to see the expect debugging, I can see that it launches the ssh spawn with the correct username, but it is blatantly disregarding the password supplied on the command line... spawn ssh -c 3des -x -l .... .... .... expect: set expect_out(buffer) "User Access Verification\r\nPassword:" send: sending to { exp4 } expect: continuing expect So it really looks to me like clogin is just ignoring the password on the command line. I tried -p -r and -v. None of them have any effect. I am doing it this way because this server and the routers being managed all authenticate from the same Active Directory server. Rancid is installed on a shared administrator server and the rancid user is the only one with a .cloginrc. The rancid user's .cloginrc file is configured with the username and password of an account defined in AD which only gets access (through TACACS) to the few commands that rancid needs in order to complete its runs. The administrators who share this box all have sudo access and can theoretically see each other's home directories if they want. So having individual admin's passwords stored in a text file is not going to happen, even if they are chmod 600. So in order for the admins to use clogin/rancid to push configs, they need to be able to interactively authenticate their own account. I agree that having the password on the command line is also bad, but in my opinion, it's better than having it in a text file, as it's exposed for less time (assuming the shared sudo access which exists here). I do ask for it interactively as part of the script, so it doesn't show up in anyone's command history or on their screen. Yes, it would be visible through a 'ps' while clogin is running, but it's the best I could come up with. If anyone has any suggestions on the technical problem I'm facing with clogin, or a better method altogether to get what I need done, then I'd appreciate any assistance or advice you can give! On Thu, Feb 13, 2014 at 7:49 AM, Alan McKinnon wrote: > On 13/02/2014 14:03, Andrew Ohnstad wrote: > > I'm not sure if I'm asking more of the tool than what's possible, or if > > I'm just missing the secret sauce. > > > > I've got rancid set up and working for archiving configs. I'm now trying > > to use clogin as part of a bash shell script to push configuration > > changes to a bunch of devices. The catch is that the devices are a) only > > reachable through ssh, and b) clogin must use a username and password > > provided as command line arguments and NOT any credentials stored in a > > .cloginrc file. This is a requirement so that the user pushing the > > updates can be logged. > > > > Is there a set of arguments to clogin that will tell it to ignore the > > username and password? I can get it to pass the specified username with > > the -u command, but by running with debugging turned on, I saw that it > > was still using the password in the .cloginrc file for all the logins. > > It seems to ignore every password related command line argument. > > > > Thanks in advance for any advice you can provide. > > > Did you use this syntax: > > clogin -u -p -e -c > routername > > a) is not a problem. if you have method in .cloginrc as "telnet ssh" and > telnet fails, it tries ssh. > > b) Personally I wouldn't use -p or -e, I'd let .cloginrc deal with that. > When a password is on the command line and visible to ps, or logged in a > log file, I consider that to be situation=game_over, but your needs may > be different > > > > -- > Alan McKinnon > alan.mckinnon at gmail.com > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: From heas at shrubbery.net Thu Feb 13 15:40:58 2014 From: heas at shrubbery.net (heasley) Date: Thu, 13 Feb 2014 15:40:58 +0000 Subject: [rancid] Scripting clogin with bash and username/password In-Reply-To: References: <52FCBF6A.7060809@gmail.com> Message-ID: <20140213154058.GC70191@shrubbery.net> Thu, Feb 13, 2014 at 10:22:11AM -0500, Andrew Ohnstad: > Thanks for the response. The full command line I am using is (I > automatically am enabled via TACACS+): > > sudo -u rancid /usr/libexec/rancid/clogin -u -p > -c where > > If I add the -d argument to see the expect debugging, I can see that it > launches the ssh spawn with the correct username, but it is blatantly > disregarding the password supplied on the command line... > > spawn ssh -c 3des -x -l this should work; what version of rancid? From peo at chalmers.se Thu Feb 13 16:06:31 2014 From: peo at chalmers.se (Per-Olof Olsson) Date: Thu, 13 Feb 2014 17:06:31 +0100 Subject: [rancid] Scripting clogin with bash and username/password In-Reply-To: <20140213154058.GC70191@shrubbery.net> References: <52FCBF6A.7060809@gmail.com> <20140213154058.GC70191@shrubbery.net> Message-ID: <52FCED87.5020801@chalmers.se> heasley wrote 2014-02-13 16:40: > Thu, Feb 13, 2014 at 10:22:11AM -0500, Andrew Ohnstad: >> Thanks for the response. The full command line I am using is (I >> automatically am enabled via TACACS+): >> >> sudo -u rancid /usr/libexec/rancid/clogin -u -p >> -c where >> >> If I add the -d argument to see the expect debugging, I can see that it >> launches the ssh spawn with the correct username, but it is blatantly >> disregarding the password supplied on the command line... >> >> spawn ssh -c 3des -x -l > > this should work; what version of rancid? > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > sudo -l[l] [-AknS] [-g group name | #gid] [-p prompt] [-U user name] [-u user name | #uid] [command] is sudo using -p option for it's on to set a prompt? -u for own username... test "sudo -u rancid -- /usr/libexec/rancid/clogin -u -p -c where " From sudo man page ... -- The -- option indicates that sudo should stop processing command line arguments. ... Have seen this before to ssh/telnet commands /Peo ---------------------------------------------------------- Per-Olof Olsson Email: peo at chalmers.se Chalmers tekniska h?gskola IT-service Arvid Hedvalls backe 6 412 96 G?teborg Tel: 031/772 6738 Fax: 031/772 8680 ---------------------------------------------------------- From daniel.schmidt at wyo.gov Thu Feb 13 18:51:19 2014 From: daniel.schmidt at wyo.gov (Daniel Schmidt) Date: Thu, 13 Feb 2014 11:51:19 -0700 Subject: [rancid] Scripting clogin with bash and username/password In-Reply-To: <52FCED87.5020801@chalmers.se> References: <52FCBF6A.7060809@gmail.com> <20140213154058.GC70191@shrubbery.net> <52FCED87.5020801@chalmers.se> Message-ID: Why not use tacacs accounting to log everything the user does, script or no script? Why not use ciscocmd, iosrun or some other pre-made free tool to do this? I've written little python snippets to do exactly this: ask a user what he wants to do, ssh or telnet, what text file has his list, what text file has your routers/commands/etc which I would share, but that they were done in haste and look like they were coded by drunken monkeys. I'd be happy to give pointers though. On Thu, Feb 13, 2014 at 9:06 AM, Per-Olof Olsson wrote: > heasley wrote 2014-02-13 16:40: > > Thu, Feb 13, 2014 at 10:22:11AM -0500, Andrew Ohnstad: >> >>> Thanks for the response. The full command line I am using is (I >>> automatically am enabled via TACACS+): >>> >>> sudo -u rancid /usr/libexec/rancid/clogin -u -p >>> -c where >>> >>> If I add the -d argument to see the expect debugging, I can see that it >>> launches the ssh spawn with the correct username, but it is blatantly >>> disregarding the password supplied on the command line... >>> >>> spawn ssh -c 3des -x -l >>> >> >> this should work; what version of rancid? >> _______________________________________________ >> Rancid-discuss mailing list >> Rancid-discuss at shrubbery.net >> http://www.shrubbery.net/mailman/listinfo/rancid-discuss >> >> > sudo -l[l] [-AknS] [-g group name | #gid] [-p prompt] [-U user name] [-u > user name | #uid] [command] > is sudo using -p option for it's on to set a prompt? -u for own username... > > test > "sudo -u rancid -- /usr/libexec/rancid/clogin -u > -p -c where " > > From sudo man page > ... > -- The -- option indicates that sudo should stop processing > command line arguments. > ... > > Have seen this before to ssh/telnet commands > > > /Peo > ---------------------------------------------------------- > Per-Olof Olsson Email: peo at chalmers.se > Chalmers tekniska h?gskola IT-service > Arvid Hedvalls backe 6 412 96 G?teborg > Tel: 031/772 6738 Fax: 031/772 8680 > ---------------------------------------------------------- > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > E-Mail to and from me, in connection with the transaction of public business, is subject to the Wyoming Public Records Act and may be disclosed to third parties. -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.ohnstad at gmail.com Thu Feb 13 17:19:03 2014 From: andrew.ohnstad at gmail.com (Andrew Ohnstad) Date: Thu, 13 Feb 2014 12:19:03 -0500 Subject: [rancid] Scripting clogin with bash and username/password In-Reply-To: <52FCED87.5020801@chalmers.se> References: <52FCBF6A.7060809@gmail.com> <20140213154058.GC70191@shrubbery.net> <52FCED87.5020801@chalmers.se> Message-ID: I was hopeful about this, as it sounded good, but no luck. Adding the -- option didn't help, and even su'ing into an interactive shell for the rancid user and running the command without the sudo didn't help. Thanks for the suggestion, though! On Thu, Feb 13, 2014 at 11:06 AM, Per-Olof Olsson wrote: > heasley wrote 2014-02-13 16:40: > >> Thu, Feb 13, 2014 at 10:22:11AM -0500, Andrew Ohnstad: >> >>> Thanks for the response. The full command line I am using is (I >>> automatically am enabled via TACACS+): >>> >>> sudo -u rancid /usr/libexec/rancid/clogin -u -p >>> -c where >>> >>> If I add the -d argument to see the expect debugging, I can see that it >>> launches the ssh spawn with the correct username, but it is blatantly >>> disregarding the password supplied on the command line... >>> >>> spawn ssh -c 3des -x -l >>> >> >> this should work; what version of rancid? >> _______________________________________________ >> Rancid-discuss mailing list >> Rancid-discuss at shrubbery.net >> http://www.shrubbery.net/mailman/listinfo/rancid-discuss >> >> > sudo -l[l] [-AknS] [-g group name | #gid] [-p prompt] [-U user name] [-u > user name | #uid] [command] > is sudo using -p option for it's on to set a prompt? -u for own username... > > test > "sudo -u rancid -- /usr/libexec/rancid/clogin -u > -p -c where " > > From sudo man page > ... > -- The -- option indicates that sudo should stop processing > command line arguments. > ... > > Have seen this before to ssh/telnet commands > > > /Peo > ---------------------------------------------------------- > Per-Olof Olsson Email: peo at chalmers.se > Chalmers tekniska h?gskola IT-service > Arvid Hedvalls backe 6 412 96 G?teborg > Tel: 031/772 6738 Fax: 031/772 8680 > ---------------------------------------------------------- > -------------- next part -------------- An HTML attachment was scrubbed... URL: From skyeh at uidaho.edu Thu Feb 13 23:50:29 2014 From: skyeh at uidaho.edu (Hagen, Skye (skyeh@uidaho.edu)) Date: Thu, 13 Feb 2014 23:50:29 +0000 Subject: [rancid] Scripting clogin with bash and username/password In-Reply-To: References: <52FCBF6A.7060809@gmail.com> <20140213154058.GC70191@shrubbery.net> <52FCED87.5020801@chalmers.se> Message-ID: How about approaching this from a different direction? Instead of specifying the username and password on the command line, you specify an alternate cloginrc file, using the -f option? The alternate cloginrc file could have different user names and passwords. Skye. From: Andrew Ohnstad > Date: Thursday, February 13, 2014 9:19 AM To: "rancid-discuss at shrubbery.net" > Subject: Re: [rancid] Scripting clogin with bash and username/password I was hopeful about this, as it sounded good, but no luck. Adding the -- option didn't help, and even su'ing into an interactive shell for the rancid user and running the command without the sudo didn't help. Thanks for the suggestion, though! On Thu, Feb 13, 2014 at 11:06 AM, Per-Olof Olsson > wrote: heasley wrote 2014-02-13 16:40: Thu, Feb 13, 2014 at 10:22:11AM -0500, Andrew Ohnstad: Thanks for the response. The full command line I am using is (I automatically am enabled via TACACS+): sudo -u rancid /usr/libexec/rancid/clogin -u -p -c where If I add the -d argument to see the expect debugging, I can see that it launches the ssh spawn with the correct username, but it is blatantly disregarding the password supplied on the command line... spawn ssh -c 3des -x -l this should work; what version of rancid? _______________________________________________ Rancid-discuss mailing list Rancid-discuss at shrubbery.net http://www.shrubbery.net/mailman/listinfo/rancid-discuss sudo -l[l] [-AknS] [-g group name | #gid] [-p prompt] [-U user name] [-u user name | #uid] [command] is sudo using -p option for it's on to set a prompt? -u for own username... test "sudo -u rancid -- /usr/libexec/rancid/clogin -u -p -c where " >From sudo man page ... -- The -- option indicates that sudo should stop processing command line arguments. ... Have seen this before to ssh/telnet commands /Peo ---------------------------------------------------------- Per-Olof Olsson Email: peo at chalmers.se Chalmers tekniska h?gskola IT-service Arvid Hedvalls backe 6 412 96 G?teborg Tel: 031/772 6738 Fax: 031/772 8680 ---------------------------------------------------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: From v.briolet at hotmail.fr Mon Feb 17 16:25:26 2014 From: v.briolet at hotmail.fr (Vianney Briolet) Date: Mon, 17 Feb 2014 17:25:26 +0100 Subject: [rancid] Question about " How to configure RANCID on CentOS " In-Reply-To: References: , , , <20140217160729.GC17991@shrubbery.net>, Message-ID: From: v.briolet at hotmail.fr To: rancid at shrubbery.net Subject: RE: Question about " How to configure RANCID on CentOS " Date: Mon, 17 Feb 2014 17:21:16 +0100 Ok, thanks for your help. So, when i type clogin It shown before the router text: spawn ssh -c 3des -x -l rancid Besides, I try a ssh session to my router on this virtual machine and it works with the router user rancid. Finally, I check the password on my .cloginrc file and it's right. I precise that I set autoenable option too. > Date: Mon, 17 Feb 2014 16:07:29 +0000 > From: rancid at shrubbery.net > To: v.briolet at hotmail.fr > CC: rancid at shrubbery.net > Subject: Re: FW: Question about " How to configure RANCID on CentOS " > > Mon, Feb 17, 2014 at 11:15:57AM +0100, Vianney Briolet: > > Hello, > > > > > > > > I contact you about a tutorial about Rancid: > > http://www.ispexperts.com.np/?page_id=556 > > > > It helps me a lot as I want to configure a Rancid server on a Centos 6 Virtual Machine. I follow every steps and adapt it for my network. However, I have a problem on step 18). Maybe you can help me :) > > > > Indeed, when i type in bin/clogin It shows my "connection text" (like "Welcome on Network01" that i configure on my router. Then, it writes Password. And, 3-4 seconds later it writes Password again. Finallay, nothing happens. > > you probably have the password wrong (use clogin -d to see what it is sending) > or you have a special character in your password that needs to be escaped (see > cloginrc(5)). that is the wrong password is sent, and the device re-prompts > for it, like if you had made a typographical error interactively. > > you should post help questions to rancid-discuss at shrubbery.net in the future. > > > I really don't understand the issue. I do the procedure twice and I have this exact same problem again... > > > > Thanks a lot for your help. > > > > Vianney Briolet, > > > > French IT engineer > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.mckinnon at gmail.com Mon Feb 17 20:08:19 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Mon, 17 Feb 2014 22:08:19 +0200 Subject: [rancid] Question about " How to configure RANCID on CentOS " In-Reply-To: References: , , , <20140217160729.GC17991@shrubbery.net>, Message-ID: <53026C33.1060605@gmail.com> You ssh to the router and enter the correct username and password, it works. You clogin to the router and believe the username and password are correct it .cloginrc but it fails. Therefore clogin is not doing what you think it is doing, it is doing something else. For us to help you, you must supply more information. All you have said so far is that your config is correct but it doesn't work, and that's not enough information to help you at all. autoenable is not relevant here, when you get multiple password prompts it is your username/password that is wrong, and autoenable comes later. Examine .cloginrc very carefully and keep in mind these facts: 1. it's first match wins. So if you have this add password * my-pass add passward my-router.example.com my-other-pass the first line is used as it matches everything. 2. Passwords often have special characters that must be quoted using {} like this: add password my-router.example.com {my-other-pass} Finally, when there is no obvious problem with .cloginrc. run clogin with the -d option to get a debug output. Then you can see what the software is really doing.. On 17/02/2014 18:25, Vianney Briolet wrote: > > > ------------------------------------------------------------------------ > From: v.briolet at hotmail.fr > To: rancid at shrubbery.net > Subject: RE: Question about " How to configure RANCID on CentOS " > Date: Mon, 17 Feb 2014 17:21:16 +0100 > > Ok, thanks for your help. > > So, when i type clogin > > It shown before the router text: > spawn ssh -c 3des -x -l rancid > > > Besides, I try a ssh session to my router on this virtual machine and it > works with the router user rancid. > > Finally, I check the password on my .cloginrc file and it's right. I > precise that I set autoenable option too. > > >> Date: Mon, 17 Feb 2014 16:07:29 +0000 >> From: rancid at shrubbery.net >> To: v.briolet at hotmail.fr >> CC: rancid at shrubbery.net >> Subject: Re: FW: Question about " How to configure RANCID on CentOS " >> >> Mon, Feb 17, 2014 at 11:15:57AM +0100, Vianney Briolet: >> > Hello, >> > >> > >> > >> > I contact you about a tutorial about Rancid: >> > http://www.ispexperts.com.np/?page_id=556 >> > >> > It helps me a lot as I want to configure a Rancid server on a Centos > 6 Virtual Machine. I follow every steps and adapt it for my network. > However, I have a problem on step 18). Maybe you can help me :) >> > >> > Indeed, when i type in bin/clogin It shows my > "connection text" (like "Welcome on Network01" that i configure on my > router. Then, it writes Password. And, 3-4 seconds later it writes > Password again. Finallay, nothing happens. >> >> you probably have the password wrong (use clogin -d to see what it is > sending) >> or you have a special character in your password that needs to be > escaped (see >> cloginrc(5)). that is the wrong password is sent, and the device > re-prompts >> for it, like if you had made a typographical error interactively. >> >> you should post help questions to rancid-discuss at shrubbery.net in the > future. >> >> > I really don't understand the issue. I do the procedure twice and I > have this exact same problem again... >> > >> > Thanks a lot for your help. >> > >> > Vianney Briolet, >> > >> > French IT engineer >> > > > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > -- Alan McKinnon alan.mckinnon at gmail.com From OUzzaman at cvent.com Tue Feb 18 22:19:51 2014 From: OUzzaman at cvent.com (Uzzaman, Obaid) Date: Tue, 18 Feb 2014 22:19:51 +0000 Subject: [rancid] Need help on Rancid on how to install ssl certificate and setup an authentication Message-ID: <3742FF769551DB41B81FAE5F6F9EAFA6A4C8D7@HQ04HQMX002.cvent.net> Hello, Any help will be greatly appreciated if you could please provide any information on how to install a SSL certificate on Rancid (OS - Debian) and setup an authentication to access Rancid. Sincerely, Obaid -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.mckinnon at gmail.com Tue Feb 18 23:12:13 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Wed, 19 Feb 2014 01:12:13 +0200 Subject: [rancid] Need help on Rancid on how to install ssl certificate and setup an authentication In-Reply-To: <3742FF769551DB41B81FAE5F6F9EAFA6A4C8D7@HQ04HQMX002.cvent.net> References: <3742FF769551DB41B81FAE5F6F9EAFA6A4C8D7@HQ04HQMX002.cvent.net> Message-ID: <5303E8CD.4040702@gmail.com> On 19/02/2014 00:19, Uzzaman, Obaid wrote: > Hello, > > > > Any help will be greatly appreciated if you could please provide any > information on how to install a SSL certificate on Rancid (OS ? Debian) > and setup an authentication to access Rancid. Please be more specific. What are you trying to achieve? Access to the rancid cvs repo using rancid-web and https? Shell access to the unix host itself using ssh? Something else? Your question as stated is too vague to be answered. -- Alan McKinnon alan.mckinnon at gmail.com From david.gomez at grupoversia.com Wed Feb 19 11:27:05 2014 From: david.gomez at grupoversia.com (David Gomez) Date: Wed, 19 Feb 2014 11:27:05 +0000 (UTC) Subject: [rancid] BNT help? References: <4F834195.2050403@renci.org> <4F83455B.8040209@renci.org>, <5B17DFA4-385A-4ED2-B455-4F8DAE8378C7@antinode.net> Message-ID: Jonathan Mills renci.org> writes: > > It is using a # > Hi Jonathan, I am in your same situation. ?Did you finally get how to get the rackswitch configuration with rancid? Greetings! From David.Gomez at grupoversia.com Wed Feb 19 11:40:50 2014 From: David.Gomez at grupoversia.com (David Gomez) Date: Wed, 19 Feb 2014 12:40:50 +0100 Subject: [rancid] How to get running config from IBM Rackswitch Message-ID: <53049842.1010406@grupoversia.com> Hi, Does anyone knows how to get the running config of this devices with Rancid? IBM Networking Operating System RackSwitch G8124-E Greetings! -- ______________________________ *______________________________* *David G?mez* EXTERNAL Grupo Versia Telf.: 94 472 34 99 / 628 324 683 / 22017 _david.gomez at grupoversia.com _ Pol. Inbisa 20B 48510 Valle de Tr?paga _www.grupoversia.com _ -------------- next part -------------- An HTML attachment was scrubbed... URL: From ml at t-b-o-h.net Thu Feb 20 17:52:12 2014 From: ml at t-b-o-h.net (Tuc) Date: Thu, 20 Feb 2014 12:52:12 -0500 Subject: [rancid] Possible buffering issue Message-ID: <3c2916c3286bb3b7dc0fbc2356818063@vjofn.tucs-beachin-obx-house.com> Hi, We have an F5 that we are trying to capture the output from. We have a modified version of the f5tmshrancid running. We're running into an issue where we have a pretty huge "send" line for a ltm monitor https . Its 5190 characters. We seem to be running into the issue where every it seems to drop characters one run, get some/most back the next run. Its pretty annoying to constantly get the emails about it. Any ideas how to resolve this? Should I be sticking a terminal length in somewhere? Thanks, Tuc From aamsaleg at diademys.com Thu Feb 20 17:22:52 2014 From: aamsaleg at diademys.com (Alexandre Amsaleg) Date: Thu, 20 Feb 2014 18:22:52 +0100 Subject: [rancid] How to get running config from IBM Rackswitch In-Reply-To: <53049842.1010406@grupoversia.com> References: <53049842.1010406@grupoversia.com> Message-ID: <530639EC.4060204@diademys.com> Hi all. Bellow what I'have done. It's working for me for TOR model and BladeCenter/Purflex switches : add in rancid-fe : 'ibmbnt' => 'bntrancid', new file in $rancid-home/bin : bntrancid with 755 #! /usr/bin/perl ## ## $Id: rancid.in 2272 2011-01-10 20:01:58Z heas $ ## ## rancid 2.3.6 ## Copyright (c) 1997-2009 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "rancid 2.3.6\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $proc = ""; $ios = "IOS"; $clean_run = 0; $found_end = 0; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # bntlogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($config_register); # configuration register value my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode # This routine is used to print out the router configuration sub ProcessHistory { my($new_hist_tag,$new_command,$command_string, at string) = (@_); if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command)) && scalar(%history)) { print eval "$command \%history"; undef %history; } if (($new_hist_tag) && ($new_command) && ($command_string)) { if ($history{$command_string}) { $history{$command_string} = "$history{$command_string}@string"; } else { $history{$command_string} = "@string"; } } elsif (($new_hist_tag) && ($new_command)) { $history{++$#history} = "@string"; } else { print "@string"; } $hist_tag = $new_hist_tag; $command = $new_command; 1; } sub numerically { $a <=> $b; } # This is a sort routine that will sort numerically on the # keys of a hash as if it were a normal array. sub keynsort { local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort numerically keys(%lines)) { $sorted_lines[$i] = $lines{$key}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # keys of a hash as if it were a normal array. sub keysort { local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort keys(%lines)) { $sorted_lines[$i] = $lines{$key}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # values of a hash as if it were a normal array. sub valsort{ local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort values %lines) { $sorted_lines[$i] = $key; $i++; } @sorted_lines; } # This is a numerical sort routine (ascending). sub numsort { local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $num (sort {$a <=> $b} keys %lines) { $sorted_lines[$i] = $lines{$num}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # ip address when the ip address is anywhere in # the strings. sub ipsort { local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $addr (sort sortbyipaddr keys %lines) { $sorted_lines[$i] = $lines{$addr}; $i++; } @sorted_lines; } # These two routines will sort based upon IP addresses sub ipaddrval { my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#); $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0])); } sub sortbyipaddr { &ipaddrval($a) <=> &ipaddrval($b); } # This routine parses "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); my($slaveslot); while () { tr/\015//d; if (/^$prompt/) { $found_version = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(0) if ($found_version); # Only do this routine once return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^Slave in slot (\d+) is running/) { $slave = " Slave:"; $slaveslot = ", slot $1"; next; } if (/cisco ios .* IOS-XE/i) { $ios = "XE"; } if (/^Application and Content Networking .*Software/) { $type = "CE"; } # treat the ACE like the Content Engines for matching endofconfig if (/^Cisco Application Control Software/) { $type = "CE"; } if (/^Cisco Storage Area Networking Operating System/) { $type = "SAN";} if (/^Cisco Nexus Operating System/) { $type = "NXOS";} /^Application and Content Networking Software Release /i && ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next; /^Cisco Secure PIX /i && ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next; # ASA "time-based licenses" - eg: bot-net /^This (PIX|platform) has a time-based license that will expire in\s+(\d{2,})\s+day.*$/ && ProcessHistory("COMMENTS","keysort","D1", "!This $1 has a time-based license\n") && next; # PIX 6 fail-over license, as in "This PIX has an Unrestricted (UR) # license." PIX 7 as "his platform has ..." /^This (PIX|platform) has an?\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","D1", "!$_") && next; /^(Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image:$slave Software: $2, $3\n") && next; /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ && ProcessHistory("COMMENTS","keysort","F2", "!Image:$slave $1 Synced to mainline version: $2\n") && next; /^Compiled (.*)$/ && ProcessHistory("COMMENTS","keysort","F3", "!Image:$slave Compiled: $1\n") && next; /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G1", "!ROM Bootstrap: $3\n") && next; if (/^Hardware:\s+(.*), (.* RAM), CPU (.*)$/) { ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $1 - a PIX\n"); ProcessHistory("COMMENTS","keysort","A2", "!CPU: $3\n"); ProcessHistory("COMMENTS","keysort","B1", "!Memory: $2\n"); } /^serial number:\s+(.*)$/i && ProcessHistory("COMMENTS","keysort","C1", "!Serial Number: $1") && next; # More PIX stuff /^Encryption hardware device\s+:\s+(.*)/ && ProcessHistory("COMMENTS","keysort","A3", "!Encryption: $1\n") && next; /^running activation key\s*:\s+(.*)/i && ProcessHistory("COMMENTS","keysort","D2", "!Key: $1\n") && next; # Flash on the PIX or FWSM (FireWall Switch Module) /^Flash(\s+\S+)+ \@ 0x\S+,\s+(\S+)/ && ProcessHistory("COMMENTS","keysort","B2", "!Memory: Flash $2\n") && next; # CatOS 3500xl stuff /^system serial number\s*:\s+(.*)$/i && ProcessHistory("COMMENTS","keysort","C1", "!Serial Number: $1\n") && next; /^Model / && ProcessHistory("COMMENTS","keysort","C2", "!$_") && next; /^Motherboard / && ProcessHistory("COMMENTS","keysort","C3", "!$_") && next; /^Power supply / && ProcessHistory("COMMENTS","keysort","C4", "!$_") && next; /^Activation Key:\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","C2", "!$_") && next; /^ROM: \d+ Bootstrap .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G2", "!ROM Image: Bootstrap $1\n!\n") && next; /^ROM: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && next; /^BOOTFLASH: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && next; /^BOOTLDR: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G4","!BOOTLDR: $1\n") && next; /^System image file is "([^\"]*)", booted via (\S*)/ && # removed the booted source due to # CSCdk28131: cycling info in 'sh ver' # ProcessHistory("COMMENTS","keysort","F4","!Image: booted via $2, $1\n") && ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") && next; /^System image file is "([^\"]*)"$/ && ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next; if (/(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i) { $proc = $1; my($cpu) = $2; my($mem) = $3; my($device) = "router"; # the next line ought to be the more specific cpu info, grab it. # yet, some boards/IOS vers have a processor ID line between these # two. grrr. make sure we dont grab the "software" junk that # follows these lines by looking for "CPU at " or the 2600s # "processor: " unique string. there are undoubtedly many other # incantations. for a slave, we dont get this info, its just a # blank line. $_ = ; if (/processor board id/i) { my($sn); if (/processor board id (\S+)/i) { $sn = $1; $sn =~ s/,$//; ProcessHistory("COMMENTS","keysort","D9", "!Processor ID: $sn\n"); } $_ = ; } $_ = "" if (! /(cpu at |processor: |$cpu processor,)/i); tr/\015//d; s/implementation/impl/i; if ($_ !~ /^\s*$/) { chomp; s/^/, /; } if ($proc eq "CSC") { $type = "AGS"; } elsif ($proc eq "CSC4") { $type = "AGS+"; } elsif ($proc =~ /1900/) { $type = "1900"; $device = "switch"; } elsif ($proc =~ /^(AS)?25[12][12]/) { $type = "2500"; } elsif ($proc =~ /261[01]/ || $proc =~ /262[01]/ ) { $type = "2600"; } elsif ($proc =~ /WS-C29/) { $type = "2900XL"; $device = "switch"; } elsif ($proc =~ /WS-C355/) { $type = "3550"; $device = "switch"; } elsif ($proc =~ /WS-C35/) { $type = "3500XL"; $device = "switch"; } elsif ($proc =~ /^36[0246][0-9]/) { $type = "3600"; } elsif ($proc =~ /^37/) { $type = "3700"; } elsif ($proc =~ /^38/) { $type = "3800"; } elsif ($proc =~ /WS-C45/) { $type = "4500"; $device = "switch"; } elsif ( $proc =~ /^AS5300/) { $type = "AS5300"; } elsif ( $proc =~ /^AS5350/) { $type = "AS5350"; } elsif ( $proc =~ /^AS5400/) { $type = "AS5400"; } elsif ($proc =~ /6000/) { $type = "6000"; $device = "switch"; } elsif ($proc eq "WK-C65") { $type = "6500"; } elsif ($proc eq "RP") { $type = "7000"; } elsif ($proc eq "RP1") { $type = "7000"; } elsif ($proc =~ /720[246]/) { $type = "7200"; } elsif ( $proc =~ /^73/) { $type = "7300"; } elsif ($proc eq "RSP7000") { $type = "7500"; } elsif ($proc =~ /RSP\d/) { $type = "7500"; } elsif ($proc =~ /OSR-76/) { $type = "7600"; } elsif ($proc =~ /CISCO76/) { $type = "7600"; } elsif ($proc =~ /1200[48]\/(GRP|PRP)/ || $proc =~ /1201[26]\/(GRP|PRP)/) { $type = "12000"; } elsif ($proc =~ /1201[26]-8R\/(GRP|PRP)/) { $type = "12000"; } elsif ($proc =~ /1240[48]\/(GRP|PRP)/ || $proc =~ /1241[06]\/(GRP|PRP)/) { $type = "12400"; } else { $type = $proc; } print STDERR "TYPE = $type\n" if ($debug); ProcessHistory("COMMENTS","keysort","A1", "!Chassis type:$slave $proc - a $type $device\n"); ProcessHistory("COMMENTS","keysort","B1", "!Memory:$slave main $mem\n"); if (defined($cpu)) { ProcessHistory("COMMENTS","keysort","A3", "!CPU:$slave $cpu$_$slaveslot\n"); } next; } if (/(\S+) Silicon\s*Switch Processor/) { if (!defined($C0)) { $C0 = 1; ProcessHistory("COMMENTS","keysort","C0","!\n"); } ProcessHistory("COMMENTS","keysort","C2","!SSP: $1\n"); $ssp = 1; $sspmem = $1; next; } /^(\d+[kK]) bytes of multibus/ && ProcessHistory("COMMENTS","keysort","B2", "!Memory: multibus $1\n") && next; /^(\d+[kK]) bytes of (non-volatile|NVRAM)/ && ProcessHistory("COMMENTS","keysort","B3", "!Memory: nvram $1\n") && next; /^(\d+[kK]) bytes of flash memory/ && ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") && next; /^(\d+[kK]) bytes of .*flash partition/ && ProcessHistory("COMMENTS","keysort","B6", "!Memory: flash partition $1\n") && next; /^(\d+[kK]) bytes of Flash internal/ && ProcessHistory("COMMENTS","keysort","B4", "!Memory: bootflash $1\n") && next; if (/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i) { ProcessHistory("COMMENTS","keysort","B7", "!Memory: pcmcia $2 $3$4 $1\n"); next; } if (/^(\d+[kK]) bytes of (slot|disk)(\d)/i) { ProcessHistory("COMMENTS","keysort","B7", "!Memory: pcmcia $2$3 $1\n"); next; } if (/^WARNING/) { if (!defined($I0)) { $I0 = 1; ProcessHistory("COMMENTS","keysort","I0","!\n"); } ProcessHistory("COMMENTS","keysort","I1","! $_"); } if (/^Configuration register is (.*)$/) { $config_register = $1; next; } if (/^Configuration register on node \S+ is (.*)$/) { $config_register = $1 if (length($config_register) < 1); next; } } return(0); } # This routine parses "show redundancy" sub ShowRedundancy { print STDERR " In ShowRedundancy: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^Version information for secondary in slot (\d+):/) { $slave = " Slave:"; $slaveslot = ", slot $1"; next; } /^IOS .* Software \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image:$slave Software: $1, $2\n") && next; /^Compiled (.*)$/ && ProcessHistory("COMMENTS","keysort","F3", "!Image:$slave Compiled: $1\n") && next; } return(0); } # This routine parses "show IDprom" sub ShowIDprom { my($tmp); print STDERR " In ShowIDprom: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /FRU is .(.*)\'/ && ($tmp = $1); /Product Number = .(.*)\'/ && ProcessHistory("COMMENTS","keysort","D0", "!Catalyst Chassis type: $1, $tmp\n"); /Serial Number = .([0-9A-Za-z]+)/ && ProcessHistory("COMMENTS","keysort","D1", "!Catalyst Chassis S/N: $1\n"); /Manufacturing Assembly Number = .([-0-9]+)/ && ($tmp = $1); /Manufacturing Assembly Revision = .(.*)\'/ && ($tmp .= ", rev " . $1); /Hardware Revision = ([0-9.]+)/ && ProcessHistory("COMMENTS","keysort","D2", "!Catalyst Chassis assembly: $tmp, ver $1\n"); } return(0); } # This routine parses "show install active" sub ShowInstallActive { print STDERR " In ShowInstallActive: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } ProcessHistory("COMMENTS","keysort","F5","!Image: $_") && next; } return(0); } # This routine parses "show env all" sub ShowEnv { # Skip if this is not a 7500, 7200, or 7000. print STDERR " In ShowEnv: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_env = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); #return(1) if ($type !~ /^7/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(0) if ($found_env); # Only do this routine once return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (!defined($E0)) { $E0 = 1; ProcessHistory("COMMENTS","keysort","E0","!\n"); } if (/^Arbiter type (\d), backplane type (\S+)/) { if (!defined($C0)) { $C0 = 1; ProcessHistory("COMMENTS","keysort","C0","!\n"); } ProcessHistory("COMMENTS","keysort","C1", "!Enviromental Arbiter Type: $1\n"); ProcessHistory("COMMENTS","keysort","A2", "!Chassis type: $2 backplane\n"); next; } /^Power Supply Information$/ && next; /^\s*Power Module\s+Voltage\s+Current$/ && next; /^\s*(Power [^:\n]+)$/ && ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && next; /^\s*(Lower Power .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; /^\s*(redundant .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; /^\s*(RPS is .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show rsp chassis-info" for the rsp # This will create arrays for hw info. sub ShowRSP { print STDERR " In ShowRSP: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # return(1) if ($type !~ /^12[40]/); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /^$/ && next; /^\s+Chassis model: (\S+)/ && ProcessHistory("COMMENTS","keysort","D1", "!RSP Chassis model: $1\n") && next; /^\s+Chassis S\/N: (.*)$/ && ProcessHistory("COMMENTS","keysort","D2", "!RSP Chassis S/N: $1\n") && next; } return(0); } # This routine parses "show gsr chassis-info" for the gsr # This will create arrays for hw info. sub ShowGSR { # Skip if this is not a 1200n. print STDERR " In ShowGSR: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # return(1) if ($type !~ /^12[40]/); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /^$/ && next; /^\s+Chassis: type (\S+) Fab Ver: (\S+)/ && ProcessHistory("COMMENTS","keysort","D1", "!GSR Chassis type: $1 Fab Ver: $2\n") && next; /^\s+Chassis S\/N: (.*)$/ && ProcessHistory("COMMENTS","keysort","D2", "!GSR Chassis S/N: $1\n") && next; /^\s+PCA: (\S+)\s*rev: (\S+)\s*dev: \S+\s*HW ver: (\S+)$/ && ProcessHistory("COMMENTS","keysort","D3", "!GSR Backplane PCA: $1, rev $2, ver $3\n") && next; /^\s+Backplane S\/N: (\S+)$/ && ProcessHistory("COMMENTS","keysort","D4", "!GSR Backplane S/N: $1\n") && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show boot" sub ShowBoot { # Pick up boot variables if 7000/7200/7500/12000/2900/3500; # otherwise pick up bootflash. print STDERR " In ShowBoot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } next if /CONFGEN variable/; if (!defined($H0)) { $H0 = 1; ProcessHistory("COMMENTS","keysort","H0","!\n"); } if ($type !~ /^(12[04]|7)/) { if ($type !~ /^(29|35)00/) { ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_"); } else { ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); } } elsif (/(variable|register)/) { ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); } } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show flash" sub ShowFlash { # skip if this is 7000, 7200, 7500, or 12000; else we end up with # redundant data from dir /all slot0: print STDERR " In ShowFlash: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type =~ /^(12[40]|7)/); return(1) if ($ios eq "XE"); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } # Filter dhcp database next if (/dhcp_[^. ]*\.txt/); /\s+(multiple-fs|nv_hdr|vlan\.dat)$/ && next; ProcessHistory("FLASH","","","!Flash: $_"); } ProcessHistory("","","","!\n"); return; } # This routine parses "dir /all ((disk|slot)N|bootflash|nvram):" sub DirSlotN { print STDERR " In DirSlotN: $_" if ($debug); my($dev) = (/\s([^\s]+):/); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/(No such device|Error Sending Request)/i); return(1) if (/\%Error: No such file or directory/); return(1) if (/No space information available/); # Corrupt flash /\%Error calling getdents / && ProcessHistory("FLASH","","","!Flash: $dev: $_") && next; return(-1) if (/\%Error calling/); return(-1) if (/(: device being squeezed|ATA_Status time out)/i); # busy return(-1) if (/\%Error opening \S+:\S+ \(Device or resource busy\)/i); return(-1) if (/command authorization failed/i); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); # filter frequently changing files from IOX bootflash if ($dev =~ /bootflash/) { next if (/temp_cont\s*$/); next if (/uptime_cont\s*$/); } # Filter dhcp database next if (/dhcp_[^. ]*\.txt/); if ($ios eq "XE" && /.*\((\d+) bytes free\)/) { my($tmp) = $1; if ($tmp >= (1024 * 1024 * 1024)) { $tmp = int($tmp / (1024 * 1024 * 1024)); s/$1 bytes free/$tmp GB free/; } else { $tmp = int($tmp / (1024 * 1024)); s/$1 bytes free/$tmp MB free/; } } if ($ios eq "XE" && /^((\s+)?\d+\s+\S+)\s+\d+.*(tracelogs$)/) { $_ = "$1" . sprintf("%43s", "") . "$3\n"; } if ($ios eq "IOS" && /^((\s+)?\d+\s+\S+)\s+\d+.*(sflog$)/) { $_ = "$1" . sprintf("%43s", "") . "$3\n"; } # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } ProcessHistory("FLASH","","","!Flash: $dev: $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine parses "show controllers" sub ShowContAll { # Skip if this is a 70[01]0, 7500, or 12000. print STDERR " In ShowContAll: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); # return(1) if ($type =~ /^(12[40]|7[05])/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; } /^(BRI unit \d)/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /^LANCE unit \d, NIM/ && ProcessHistory("INT","","","!Interface: $_") && next; /^(LANCE unit \d)/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /(Media Type is \S+),/ && ProcessHistory("INT","","","!\t$1\n"); if (/(M\dT[^ :]*:) show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr $_"); } if (/^(\S+) : show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr: $_"); } /^(HD unit \d), idb/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /^HD unit \d, NIM/ && ProcessHistory("INT","","","!Interface: $_") && next; /^buffer size \d+ HD unit \d, (.*)/ && ProcessHistory("INT","","","!\t$1\n") && next; /^AM79970 / && ProcessHistory("INT","","","!Interface: $_") && next; /^buffer size \d+ (Universal Serial: .*)/ && ProcessHistory("INT","","","!\t$1\n") && next; /^Hardware is (.*)/ && ProcessHistory("INT","","","!Interface: $INT$1\n") && next; /^(QUICC Serial unit \d),/ && ProcessHistory("INT","","","!$1\n") && next; /^QUICC Ethernet .*/ && ProcessHistory("INT","","","!$_") && next; /^DTE .*\.$/ && ProcessHistory("INT","","","!\t$_") && next; /^(cable type :.*),/ && ProcessHistory("INT","","","!\t$1\n") && next; /^(.* cable.*), received clockrate \d+$/ && ProcessHistory("INT","","","!\t$1\n") && next; /^.* cable.*$/ && ProcessHistory("INT","","","!\t$_") && next; } return(0); } # This routine parses "show controllers cbus" # Some of this is printed out in ShowDiagbus. sub ShowContCbus { # Skip if this is not a 7000 or 7500. print STDERR " In ShowContCbus: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); #return(1) if ($type !~ /^7[05]0/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^\s*slot(\d+): ([^,]+), hw (\S+), sw (\S+), ccb/) { $slot = $1; $board{$slot} = $2; $hwver{$slot} = $3; $hwucode{$slot} = $4; } elsif (/^\s*(\S+) (\d+), hardware version (\S+), microcode version (\S+)/) { $slot = $2; $board{$slot} = $1; $hwver{$slot} = $3; $hwucode{$slot} = $4; } elsif (/(Microcode .*)/) { $ucode{$slot} = $1; } elsif (/(software loaded .*)/) { $ucode{$slot} = $1; } elsif (/(\d+) Kbytes of main memory, (\d+) Kbytes cache memory/) { $hwmemd{$slot} = $1; $hwmemc{$slot} = $2; } elsif (/byte buffers/) { chop; s/^\s*//; $hwbuf{$slot} = $_; } elsif (/Interface (\d+) - (\S+ \S+),/) { $interface = $1; ProcessHistory("HW","","", "!\n!Int $interface: in slot $slot, named $2\n"); next; } elsif (/(\d+) buffer RX queue threshold, (\d+) buffer TX queue limit, buffer size (\d+)/) { ProcessHistory("HW","","","!Int $interface: rxq $1, txq $2, bufsize $3\n"); next; } } return(0); } # This routine parses "show debug" sub ShowDebug { print STDERR " In ShowDebug: $_" if ($debug); my($lines) = 0; while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /^No matching debug flags set$/ && next; /^No debug flags set$/ && next; ProcessHistory("COMMENTS","keysort","J1","!DEBUG: $_"); $lines++; } if ($lines) { ProcessHistory("COMMENTS","keysort","J0","!\n"); } return(0); } # This routine parses "show diagbus" # This will create arrays for hw info. sub ShowDiagbus { # Skip if this is not a 7000, 70[01]0, or 7500. print STDERR " In ShowDiagbus: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); #return(1) if ($type !~ /^7[05]/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^\s*Slot (\d+):/i) { $slot = $1; next; } elsif (/^\s*Slot (\d+) \(virtual\):/i) { $slot = $1; next; } elsif (/^\s*(.*Processor.*|.*controller|.*controler|.*Chassis Interface)(, FRU\s?:.*)?, HW rev (\S+), board revision (\S+)/i) { $board = $1; $hwver = $3; $boardrev = $4; if ($board =~ /Processor/) { if ($board =~ /7000 Route\/Switch/) { $board = "RSP7000"; } elsif ($board =~ /Route\/Switch Processor (\d)/) { $board = "RSP$1"; } elsif ($board =~ /Route/) { $board = "RP"; } elsif ($board =~ /Silicon Switch/) { $board = "SSP"; } elsif ($board =~ /Switch/) { $board = "SP"; $board = "SSP $sspmem" if $ssp; } elsif ($board =~ /ATM/) { $board = "AIP"; } } elsif ($board =~ /(.*) controller/i) { $board = $1; } # hwucode{$slot} defined in ShowContCbus if (defined $hwucode{$slot}) { ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev ucode $hwucode{$slot}\n"); } else { ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev\n"); } # These are also from the ShowContCbus ProcessHistory("SLOT","","","!Slot $slot/$board: $ucode{$slot}\n") if (defined $ucode{$slot}); ProcessHistory("SLOT","","","!Slot $slot/$board: memd $hwmemd{$slot}, cache $hwmemc{$slot}\n") if ((defined $hwmemd{$slot}) && (defined $hwmemc{$slot})); ProcessHistory("SLOT","","","!Slot $slot/$board: $hwbuf{$slot}\n") if (defined $hwbuf{$slot}); next; } /Serial number: (\S+)\s*Part number: (\S+)/ && ProcessHistory("SLOT","","", "!Slot $slot/$board: part $2, serial $1\n") && next; /^\s*Controller Memory Size: (.*)$/ && ProcessHistory("SLOT","","","!Slot $slot/$board: $1\n") && next; if (/PA Bay (\d) Information/) { $pano = $1; if ("PA" =~ /$board/) { ($s,$c) = split(/\//,$board); $board = "$s/$c/PA $pano"; } else { $board =~ s/\/PA \d//; $board = "$board/PA $pano"; } next; } /\s+(.*) (IP|PA), (\d) ports?,( \S+,)? (FRU\s?: )?(\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: type $6, $3 ports\n") && next; /\s+(.*) (IP|PA)( \(\S+\))?, (\d) ports?/ && ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$3, $4 ports\n") && next; /^\s*HW rev (\S+), Board revision (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: hvers $1 rev $2\n") && next; /Serial number: (\S+)\s*Part number: (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: part $2, serial $1\n") && next; } return(0); } # This routine parses "show diag" for the gsr, 7200, 3700, 3600, 2600. # This will create arrays for hw info. sub ShowDiag { print STDERR " In ShowDiag: $_" if ($debug); while () { REDUX: tr/\015//d; if (/^$prompt/) { $found_diag = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(0) if ($found_diag); # Only do this routine once return(-1) if (/command authorization failed/i); /^$/ && next; # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } s/Port Packet Over SONET/POS/; if (/^\s*SLOT\s+(\d+)\s+\((.*)\): (.*)/) { $slot = $1; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: $3\n"); next; } if (/^\s*NODE\s+(\S+) : (.*)/) { $slot = $1; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n"); next; } if (/^\s*PLIM\s+(\S+) : (.*)/) { $slot = $1 . " PLIM"; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n"); next; } if (/^\s*RACK\s+(\S+) : (.*)/) { $slot = "Rack/" . $1; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n"); next; } if (/^\s+MAIN:\s* type \S+,\s+(.*)/) { local($part) = $1; $_ = ; if (/^\s+(HW version|Design Release) (\S+)\s+S\/N (\S+)/i) { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, serial $3\n"); ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: hvers $2\n"); } else { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part\n"); goto REDUX; } next; } if (/^\s+MAIN:\s* board type \S+$/) { $_ = ; tr/\015//d; if (/^\s+(.+)$/) { local($part) = $1; $_ = ; tr/\015//d; if (/^\s+dev (.*)$/) { local($dev) = $1; $_ = ; if (/^\s+S\/N (\S+)/) { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, dev $dev, serial $1\n"); } else { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, dev $dev\n"); goto REDUX; } } else { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part\n"); goto REDUX; } } else { goto REDUX; } next; } if (/^c3700\s+(io-board|mid-plane)/i) { $slot = $1; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: part $1\n"); next; } if (/ Engine:\s+(.*)/) { ProcessHistory("SLOT","keysort","AE","!Slot $slot/Engine: $1\n"); } if (/FRU:\s+Linecard\/Module:\s+(\S+)/) { ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Linecard/Module: $1\n"); next; } if (/\s+Processor Memory:\s+(\S+)/) { ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Processor Memory: $1\n"); next; } if (/\s+Packet Memory:\s+(\S+)/) { ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Packet Memory: $1\n"); next; } if (/\s+Route Memory:\s+(\S+)/) { ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Route Memory: $1\n"); next; } if (/^\s+PCA:\s+(.*)/) { local($part) = $1; $_ = ; if (/^\s+(HW version|design release) (\S+)\s+S\/N (\S+)/i) { ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part, serial $3\n"); ProcessHistory("SLOT","keysort","C2","!Slot $slot/PCA: hvers $2\n"); } else { ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part\n"); goto REDUX; } next; } if (/^\s+MBUS: .*\)\s+(.*)/) { local($tmp) = "!Slot $slot/MBUS: part $1"; $_ = ; /^\s+HW version (\S+)\s+S\/N (\S+)/ && ProcessHistory("SLOT","keysort","MB1","$tmp, serial $2\n") && ProcessHistory("SLOT","keysort","MB2","!Slot $slot/MBUS: hvers $1\n"); next; } if (/^\s+MBUS Agent Software version (.*)/) { ProcessHistory("SLOT","keysort","MB3","!Slot $slot/MBUS: software $1\n"); next; } if (/^\s+PLD: (.*)/) { ProcessHistory("SLOT","keysort","P","!Slot $slot/PLD: $1\n"); next; } if (/^\s+MONLIB: (.*)/) { ProcessHistory("SLOT","keysort","Q","!Slot $slot/MONLIB: $1\n"); next; } if (/^\s+ROM Monitor version (.*)/) { ProcessHistory("SLOT","keysort","R","!Slot $slot/ROM Monitor: version $1\n"); next; } if (/^\s+ROMMON: Version (.*)/) { ProcessHistory("SLOT","keysort","R","!Slot $slot/ROMMON: version $1\n"); next; } if (/^\s+Fabric Downloader version used (.*)/) { ProcessHistory("SLOT","keysort","Z","!Slot $slot/Fabric Downloader: version $1\n"); next; } if (/^\s+DRAM size: (\d+)/) { local($dram) = $1 / 1048576; $_ = ; if (/^\s+FrFab SDRAM size: (\d+)/) { ProcessHistory("SLOT","keysort","MB4","!Slot $slot/MBUS: $dram Mbytes DRAM, " . $1 / 1024 . " Kbytes SDRAM\n"); } else { ProcessHistory("SLOT","keysort","MB4","!Slot $slot/MBUS: $dram Mbytes DRAM\n"); goto REDUX; } next; } # 7200, 3600, 2600, and 1700 stuff if (/^(Slot)\s+(\d+(\/\d+)?):/ || /^\s+(WIC|VIC|WIC\/VIC) Slot (\d):/ || /^(Encryption AIM) (\d):/) { if ($1 eq "WIC") { $WIC = "/$2"; } elsif ($1 eq "VIC") { $WIC = "/$2"; } elsif ($1 eq "WIC/VIC") { $WIC = "/$2"; } elsif ($1 eq "DSP") { $WIC = "/$2"; } elsif ($1 eq "Encryption AIM") { $slot = "$2"; undef($WIC); ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1\n"); next; } else { $slot = $2; undef($WIC); } $_ = ; tr/\015//d; # clean up hideous 7200/etc formats to look more like 7500 output s/Fast-ethernet on C7200 I\/O card/FE-IO/; s/ with MII or RJ45/-TX/; s/Fast-ethernet /100Base/; s/[)(]//g; s/intermediate reach/IR/i; ProcessHistory("SLOT","","","!\n"); /\s+(.*) port adapter,?\s+(\d+)\s+/i && ProcessHistory("SLOT","keysort","B", "!Slot $slot: type $1, $2 ports\n") && next; # I/O controller with no interfaces /\s+(.*)\s+port adapter\s*$/i && ProcessHistory("SLOT","keysort","B", "!Slot $slot: type $1, 0 ports\n") && next; /\s+(.*)\s+daughter card(.*)$/ && ProcessHistory("SLOT","keysort","B", "!Slot $slot$WIC: type $1$2\n") && next; /\s+(FT1)$/ && ProcessHistory("SLOT","keysort","B", "!Slot $slot$WIC: type $1\n") && next; # AS5300/5400 handling /^Hardware is\s+(.*)$/i && ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1\n") && next; /^DFC type is\s+(.*)$/i && ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1\n") && next; # # handle WICs lacking "daughter card" in the 2nd line of their # show diag o/p if (defined($WIC)) { s/^\s+//; ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $_"); } next; } elsif (/^\s+(.* (DSP) Module) Slot (\d):/) { # The 1760 (at least) has yet another format...where it has two # dedicated DSP slots, and thus two slot 0s. my($TYPE) = $1; $WIC = "/$3"; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","B", "!Slot $slot$WIC: type $TYPE\n"); next; } # yet another format. seen on 2600s w/ 12.1, but appears to be all # 12.1, including 7200s & 3700s. Sometimes the PCB serial appears # before the hardware revision. if (/(pcb serial number|hardware revision)\s+:\s+(\S+)$/i) { my($hw, $pn, $rev, $sn); if ($1 =~ /^pcb/i) { $sn = $2; } else { $hw = $2; } while () { tr/\015//d; # Sometimes "show diag" just ends while we are # trying to process this pcb stuff. Check for a # prompt so we can get out. if (/^$prompt/) { $found_diag=1; goto PerlSucks; } if (/0x..: / || /^$/) { # no effing idea why break does not work there goto PerlSucks; } if (/hardware revision\s+:\s+(\S+)/i) { $hw = $1; } if (/part number\s+:\s+(\S+)/i) { $pn = $1; } if (/board revision\s+:\s+(\S+)/i) { $rev = $1; } if (/pcb serial number\s+:\s+(\S+)/i) { $sn = $1; } # fru/pid bits, true Cisco evolving "standard", hopefully # "show inventory" will be "the way" soon. # if (/product \(fru\) number\s+:\s+(\S+)/i) { $fn = $1; } if (/product number\s+:\s+(\S+)/i) { $fn = $1; } if (/product\s+identifier\s+\(PID\)\s+:\s+(\S+)/i) { $fn = $1; } if (/fru\s+part\s+number\s+(\S+)/i) { $fn = $1; } } PerlSucks: # fru/pid bits ProcessHistory("SLOT","keysort","AG","!Slot $slot$WIC: fru $fn\n"); # ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: hvers $hw rev $rev\n"); ProcessHistory("SLOT","keysort","C","!Slot $slot$WIC: part $pn, serial $sn\n"); # If we saw the prompt, then we are done. last if $found_diag; } /revision\s+(\S+).*revision\s+(\S+)/ && ProcessHistory("SLOT","keysort","C","!Slot $slot$WIC: hvers $1 rev $2\n") && next; /number\s+(\S+)\s+Part number\s+(\S+)/ && ProcessHistory("SLOT","keysort","D","!Slot $slot$WIC: part $2, serial $1\n") && next; # AS5x00 bits /^\ Board Revision\s+(\S+),\s+Serial Number\s+(\S+),/ && ProcessHistory("SLOT","keysort","D", "!Slot $slot$WIC: rev $1, serial $2\n") && next; /^\ Board Hardware Version\s+(\S+),\s+Item Number\s+(\S+),/ && ProcessHistory("SLOT","keysort","D", "!Slot $slot$WIC: hvers $1, part $2\n") && next; /^Motherboard Info:/ && ProcessHistory("SLOT","keysort","D", "!Slot $slot$WIC: Motherboard\n") && next; # } ProcessHistory("SLOT","","","!\n"); return(0); } # This routine parses "show inventory". sub ShowInventory { print STDERR " In ShowInventory: $_" if ($debug); while () { tr/\015//d; return if (/^\s*\^$/); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^(NAME: "[^"]*",) (DESCR: "[^"]+")/) { ProcessHistory("INVENTORY","","", sprintf("!%-30s %s\n", $1, $2)); next; } # split PID/VID/SN line if (/^PID: (\S*)\s*,\s*VID: (\S*)\s*,\s*SN: (\S*)\s*$/) { my($entries) = ""; $entries .= "!PID: $1\n" if ($1); $entries .= "!VID: $2\n" if ($2); $entries .= "!SN: $3\n" if ($3); ProcessHistory("INVENTORY","","", "$entries"); next; } ProcessHistory("INVENTORY","","","!$_"); } ProcessHistory("INVENTORY","","","!\n"); return(0); } # This routine parses "show module". sub ShowModule { print STDERR " In ShowModule: $_" if ($debug); my(@lines); my($slot, $pa); while () { tr/\015//d; return if (/^\s*\^$/); last if (/online diag status/i); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } # match slot/card info line if (/^ *(\d+)\s+(\d+)\s+(.*)\s+(\S+)\s+(\S+)\s*$/) { $lines[$1 * 1000] .= "!Slot $1: type $3, $2 ports\n!Slot $1: part $4, serial $5\n"; $lines[$1 * 1000] =~ s/\s+,/,/g; next; } # now match the Revs in the second paragraph of o/p and stick it in # the array with the previous bits...grumble. if (/^ *(\d+)\s+\S+\s+to\s+\S+\s+(\S+)\s+(\S*)\s+(\S+)(\s+\S+)?\s*$/) { $lines[$1 * 1000] .= "!Slot $1: hvers $2, firmware $3, sw $4\n"; $lines[$1 * 1000] =~ s/\s+,/,/g; next; } # grab the sub-modules, if any if (/^\s+(\d+)\s(.*)\s+(\S+)\s+(\S+)\s+(\S+)\s+\S+\s*$/) { my($idx); $pa = 0 if ($1 != $slot); $slot = $1; $idx = $1 * 1000 + $1 * 10 + $pa; $lines[$idx] .= "!Slot $1/$pa: type $2\n"; $lines[$idx] .= "!Slot $slot/$pa: part $3, serial $4\n"; $lines[$idx] .= "!Slot $slot/$pa: hvers $5\n"; $pa++; } } foreach $slot (@lines) { next if ($slot =~ /^\s*$/); ProcessHistory("Module","","","$slot!\n"); } return(0); } # This routine parses "show spe version". sub ShowSpeVersion { print STDERR " In ShowSpeVersion: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); ProcessHistory("MODEM","","","!Modem: $_") && next; } ProcessHistory("MODEM","","","!\n"); return(0); } # This routine parses "show c7200" for the 7200 # This will create arrays for hw info. sub ShowC7200 { # Skip if this is not a 7200. print STDERR " In ShowC7200: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); #return(1) if ($type !~ /^72/); return(-1) if (/command authorization failed/i); /^$/ && next; # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^(C7200 )?Midplane EEPROM:/) { $_ = ; /revision\s+(\S+).*revision\s+(\S+)/; ProcessHistory("SLOT","","","!Slot Midplane: hvers $1 rev $2\n"); $_ = ; /number\s+(\S+)\s+Part number\s+(\S+)/; ProcessHistory("SLOT","","","!Slot Midplane: part $2, serial $1\n!\n"); next; } if (/C720\d(VXR)? CPU EEPROM:/) { my ($hvers,$rev,$part,$serial); # npe400s report their cpu eeprom info differently w/ 12.0.21S while () { /Hardware Revision\s+: (\S+)/ && ($hvers = $1) && next; /Board Revision\s+: (\S+)/ && ($rev = $1) && next; /Part Number\s+: (\S+)/ && ($part = $1) && next; /Serial Number\s+: (\S+)/ && ($serial = $1) && next; /revision\s+(\S+).*revision\s+(\S+)/ && ($hvers = $1, $rev = $2) && next; /number\s+(\S+)\s+Part number\s+(\S+)/ && ($serial = $1, $part = $2) && next; /^\s*$/ && last; } ProcessHistory("SLOT","","","!Slot CPU: hvers $hvers rev $rev\n"); ProcessHistory("SLOT","","","!Slot CPU: part $part, serial $serial\n!\n"); next; } } return(0); } # This routine parses "show vtp status" sub ShowVTP { print STDERR " In ShowVTP: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); #return(1) if ($type !~ /^(2900XL|3500XL|6000)$/); return(-1) if (/command authorization failed/i); next if (/^Configuration last modified by/); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^VTP Operating Mode\s+:\s+(Transparent|Server)/) { $DO_SHOW_VLAN = 1; } ProcessHistory("COMMENTS","keysort","I0","!VTP: $_"); } ProcessHistory("COMMENTS","keysort","I0","!\n"); return(0); } # This routine parses "show vlan" sub ShowVLAN { print STDERR " In ShowVLAN: $_" if ($debug); ($_ = , return(1)) if (!$DO_SHOW_VLAN); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } ProcessHistory("COMMENTS","keysort","IO","!VLAN: $_"); } ProcessHistory("COMMENTS","keysort","IO","!\n"); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); my($lineauto,$comment,$linecnt) = (0,0,0); while () { tr/\015//d; last if (/^$prompt/); return(1) if (!$linecnt && /^\s+\^\s*$/); next if (/^\s*$cmd\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/\%Error: No such file or directory/); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); return(0) if ($found_end); # Only do this routine once return(-1) if (/command authorization failed/i); return(-1) if (/% ?configuration buffer full/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /^! no configuration change since last restart/i && next; # skip emtpy lines at the beginning if (!$linecnt && /^\s*$/) { next; } if (!$linecnt && defined($config_register)) { ProcessHistory("","","", "!\nconfig-register $config_register\n"); } /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked /% Configuration buffer full, / && return(-1); # buffer is in use $linecnt++; $lineauto = 0 if (/^[^ ]/); # skip the crap if (/^(##+|(building|current) configuration)/i) { while () { next if (/^Current configuration\s*:/i); next if (/^:/); next if (/^([%!].*|\s*)$/); next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S last; } tr/\015//d; } # skip ASA 5520 configuration author line /^: written by /i && next; # some versions have other crap mixed in with the bits in the # block above /^! (Last configuration|NVRAM config last)/ && next; # and for the ASA /^: (Written by \S+ at|Saved)/ && next; # skip consecutive comment lines to avoid oscillating extra comment # line on some access servers. grrr. if (/^!\s*$/) { next if ($comment); ProcessHistory("","","",$_); $comment++; next; } $comment = 0; # Dog gone Cool matches to process the rest of the config /^tftp-server flash / && next; # kill any tftp remains /^ntp clock-period / && next; # kill ntp clock-period /^ length / && next; # kill length on serial lines /^ width / && next; # kill width on serial lines $lineauto = 1 if /^ modem auto/; /^ speed / && $lineauto && next; # kill speed on serial lines /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable )?(password|passwd)( level \d+)? / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2$3 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? secret /) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 secret \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } elsif ($filter_pwds >= 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } # cisco AP w/ IOS if (/^(wlccp \S+ username (\S+)(\s.*)? password) (\d \S+|\S+)/) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$2","!$1 \n"); } else { ProcessHistory("USER","keysort","$2","$_"); } next; } # filter auto "rogue ap" configuration lines /^rogue ap classify / && next; if (/^( set session-key (in|out)bound ah \d+ )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1\n"); next; } if (/^( set session-key (in|out)bound esp \d+ (authenticator|cypher) )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1\n"); next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^(\s*)secret / && $filter_pwds >= 2) { ProcessHistory("LINE-PASS","","","!$1secret \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^(ip ftp password) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # isis passwords appear to be completely plain-text if (/^\s+isis password (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!isis password $2\n"); next; } if (/^\s+(domain-password|area-password) (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $3\n"); next; } # this is reversable, despite 'md5' in the cmd if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this is also reversable, despite 'md5 encrypted' in the cmd if (/^( message-digest-key \d+ md5 (7|encrypted)) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # filter HSRP passwords if (/^(\s+standby \d+ authentication) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this appears in "measurement/sla" images if (/^(\s+key-string \d?)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( l2tp tunnel \S+ password)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # i am told these are plain-text on the PIX if (/^(vpdn username (\S+) password)/) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$2","!$1 \n"); } else { ProcessHistory("USER","keysort","$2","$_"); } next; } # ASA/PIX keys in more system:running-config if (/^( pre-shared-key | key |failover key ).*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } if (/(\s+ldap-login-password )\S+(.*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # if (/^( cable shared-secret )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } /fair-queue individual-limit/ && next; # sort ip explicit-paths. if (/^ip explicit-path name (\S+)/) { my($key) = $1; my($expath) = $_; while () { tr/\015//d; last if (/^$prompt/); last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/); if (/^ip explicit-path name (\S+)/) { ProcessHistory("EXPATH","keysort","$key","$expath"); $key = $1; $expath = $_; } else { $expath .= $_; } } ProcessHistory("EXPATH","keysort","$key","$expath"); } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip(v6)? prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\S+)(\/.*)$/ && ProcessHistory("PACL $2 $4","$aclsort","$5", "ip$1 prefix-list $2 $4 $5$6\n") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); if ($token eq '3') { $line .= " " . join(' ', ($token, shift(@tokens))); } } elsif ($token eq 'vrf') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ', at tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_", "!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys if (/^((tacacs|radius)-server\s(\w*[-\s(\s\S+])*\s?key) (\d )?\w+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host statements /^ip host (\S+) / && ProcessHistory("IPHOST","keysort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # order atm map-list statements /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # order ip rcmd lines /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; # system controller /^syscon address (\S*) (\S*)/ && ProcessHistory("","","","!syscon address $1 \n") && next; if (/^syscon password (\S*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!syscon password \n"); next; } /^ *Cryptochecksum:/ && next; # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. the ": " game is for the PIX #if (/^(: +)?end$/) { if (/^end$/) { $found_end = 1; return(0); } } # The ContentEngine lacks a definitive "end of config" marker. If we # know that it is a CE, SAN, or NXOS and we have seen at least 5 lines # of write term output, we can be reasonably sure that we got the config. if (($type == "CE" || $type == "SAN" || $type == "NXOS" ) && $linecnt > 5) { $found_end = 1; return(0); } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show vlan' => 'ShowVLAN'}, {'show running-config' => 'WriteTerm'}, ); # Use an array to preserve the order of the commands and a hash for mapping # commands to the subroutine and track commands that have been completed. @commands = map(keys(%$_), @commandtable); %commands = map(%$_, @commandtable); $cisco_cmds = join(";", at commands); $cmds_regexp = join("|", map quotemeta($_), @commands); if (length($host) == 0) { if ($file) { print(STDERR "Too few arguments: file name required\n"); exit(1); } else { print(STDERR "Too few arguments: host name required\n"); exit(1); } } open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n"; select(OUTPUT); # make OUTPUT unbuffered if debugging if ($debug) { $| = 1; } if ($file) { print STDERR "opening file $host\n" if ($debug); print STDOUT "opening file $host\n" if ($log); open(INPUT,"<$host") || die "open failed for $host: $!\n"; } else { print STDERR "executing bntlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing bntlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE})) { system "bntlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "bntlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "bntlogin failed for $host: $!\n"; } else { open(INPUT,"bntlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/[>#]\s?exit/) { $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host bntlogin error: $_"); print STDERR ("$host bntlogin error: $_") if ($debug); $clean_run = 0; last; } while (/[>#]\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#>]+[#>])/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; print STDERR ("PROMPT MATCH: $prompt\n") if ($debug); } print STDERR ("HIT COMMAND:$_") if ($debug); if (! defined($commands{$cmd})) { print STDERR "$host: found unexpected command - \"$cmd\"\n"; $clean_run = 0; last TOP; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE})) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$clean_run || !$found_end) { if (scalar(%commands)) { printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands))); printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug); } if (!$clean_run || !$found_end) { print STDOUT "$host: End of run not found\n"; print STDERR "$host: End of run not found\n" if ($debug); system("/usr/bin/tail -1 $host.new"); } unlink "$host.new" if (! $debug); } new file in $rancid-home/bin : bntlogin with 755 #! /usr/bin/expect -- ## ## $Id: clogin.in 2255 2010-10-06 20:31:24Z heas $ ## ## rancid 2.3.6 ## Copyright (c) 1997-2009 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # clogin - Cisco login # # Most options are intuitive for logging into a Cisco router. # The default is to enable (thus -noenable). Some folks have # setup tacacs to have a user login at priv-lvl = 15 (enabled) # so the -autoenable flag was added for this case (don't go through # the process of enabling and the prompt will be the "#" prompt. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-r passphrase\] \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-x command-file\] \ \[-y ssh_cypher_type\] router \[router...\]\n" # env(CLOGIN) may contain: # x == do not set xterm banner or name # Password file set password_file $env(HOME)/.cloginrc # Default is to login to the router set do_command 0 set do_script 0 # The default is to automatically enable set avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 0 # The default is to look in the password file to find the passwords. This # tracks if we receive them on the command line. set do_passwd 1 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # set send_human {.4 .4 .7 .3 5} # new option to provide "login" command capabilities set loginonly 0 # Find the user in the ENV, or use the unix userid. if {[ info exists env(CISCO_USER) ]} { set default_user $env(CISCO_USER) } elseif {[ info exists env(USER) ]} { set default_user $env(USER) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } else { # This uses "id" which I think is portable. At least it has existed # (without options) on all machines/OSes I've been on recently - # unlike whoami or id -nu. if [ catch {exec id} reason ] { send_error "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { if {! [ regexp .\[rR\](.+) $arg ignore passphrase]} { incr i set vapassphrase [ lindex $argv $i ] } # VTY Password } -v* { if {! [regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "rancid 2.3.6\n" exit 0 # Enable Username } -w* { if {! [regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [ lindex $argv $i ] } # Environment variable to pass to -s scripts } -E* { if {[regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] } set do_enapasswd 0 # Command to run. } -c* { if {! [regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -x* { if {! [regexp .\[xX\](.+) $arg ignore cmd_file]} { incr i set cmd_file [ lindex $argv $i ] } if [ catch {set cmd_fd [open $cmd_file r]} reason ] { send_user "\nError: $reason\n" exit 1 } set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] set do_command 1 # Do we enable? } -noenable { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $usage" } # Only be quiet if we are running a script (it can log its output # on its own) if { $do_script } { log_user 0 } else { log_user 1 } # # Done configuration/variable setting. Now run with it... # # Sets Xterm title if interactive...if its an xterm and the user cares proc label { host } { global env # if CLOGIN has an 'x' in it, don't set the xterm name/banner if [info exists env(CLOGIN)] { if {[string first "x" $env(CLOGIN)] != -1} { return } } # take host from ENV(TERM) if [info exists env(TERM)] { if [ regexp \^(xterm|vs) $env(TERM) ignore ] { send_user "\033]1;[lindex [split $host "."] 0]\a" send_user "\033]2;$host\a" } } } # This is a helper function to make the password file easier to # maintain. Using this the password file has the form: # add password sl* pete cow # add password at* steve # add password * hanky-pie proc add {var args} { global int_$var ; lappend int_$var $args} proc include {args} { global env regsub -all "(^{|}$)" $args {} args if { [ regexp "^/" $args ignore ] == 0 } { set args $env(HOME)/$args } source_password_file $args } proc find {var router} { upvar int_$var list if { [info exists list] } { foreach line $list { if { [string match [lindex $line 0] $router ] } { return [lrange $line 1 end] } } } return {} } # Loads the password file. Note that as this file is tcl, and that # it is sourced, the user better know what to put in there, as it # could install more than just password info... I will assume however, # that a "bad guy" could just as easy put such code in the clogin # script, so I will leave .cloginrc as just an extention of that script proc source_password_file { password_file } { global env if { ! [file exists $password_file] } { send_user "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure, -1 if rsh was used successfully proc login { router user userpswd passwd enapasswd cmethod cyphertype identfile } { global command spawn_id in_proc do_command do_script platform passphrase global prompt prompt_match u_prompt p_prompt e_prompt sshcmd set in_proc 1 set uprompt_seen 0 # try each of the connection methods in $cmethod until one is successful set progs [llength $cmethod] foreach prog [lrange $cmethod 0 end] { incr progs -1 if [string match "telnet*" $prog] { regexp {telnet(:([^[:space:]]+))*} $prog methcmd suffix port if {"$port" == ""} { set retval [ catch {spawn telnet $router} reason ] } else { set retval [ catch {spawn telnet $router $port} reason ] } if { $retval } { send_user "\nError: telnet failed: $reason\n" return 1 } } elseif [string match "ssh*" $prog] { # ssh to the router & try to login with or without an identfile. regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd [join [lindex $sshcmd 0] " "] if {"$port" != ""} { set cmd "$cmd -p $port" } if {"$identfile" != ""} { set cmd "$cmd -i $identfile" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $sshcmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { if { ! $do_command } { if { [llength $cmethod] == 1 } { send_user "\nError: rsh is an invalid method for -x and " send_user "interactive logins\n" } if { $progs == 0 } { return 1 } continue; } set commands [split $command \;] set num_commands [llength $commands] set rshfail 0 for {set i 0} {$i < $num_commands && !$rshfail} { incr i} { log_user 0 set retval [ catch {spawn rsh $user@$router [lindex $commands $i] } reason ] if { $retval } { send_user "\nError: rsh failed: $reason\n" log_user 1; return 1 } send_user "$router# [lindex $commands $i]\n" # rcmd does not get a pager and no prompts, so we just have to # look for failures & lines. expect { "Connection refused" { catch {close}; catch {wait}; send_user "\nError: Connection\ Refused ($prog): $router\n" set rshfail 1 } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; send_user "\nError: Connection\ closed ($prog): $router\n" set rshfail 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable:\ $router\n" set rshfail 1 } "No address associated with" { catch {close}; catch {wait}; send_user "\nError: Unknown host\ $router\n" set rshfail 1 } -re "\b+" { exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } timeout { catch {close}; catch {wait}; send_user "\nError: TIMEOUT reached\n" set rshfail 1 } eof { catch {close}; catch {wait}; } } log_user 1 } if { $rshfail } { if { !$progs } { return 1 } else { continue } } # fake the end of the session for rancid. send_user "$router# exit\n" # return rsh "success" return -1 } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } "Host is unreachable" { send_user "\nError: Host Unreachable: $router\n"; catch {close}; catch {wait}; return 1 } "No address associated with name" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } -re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "Offending key for .* \(yes\/no\)\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Press any key to continue" { # send_user "Pressing the ANY key\n" send "\r" exp_continue } -re "Enter Selection: " { # Catalyst 1900s have some lame menu. Enter # K to reach a command-line. send "K\r" exp_continue } -re "Last login:" { exp_continue } -re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } -re "Enter passphrase.*: " { # sleep briefly to allow time for stty -echo sleep .3 send -- "$passphrase\r" exp_continue } -re "$u_prompt" { send -- "$user\r" set uprompt_seen 1 exp_continue } -re "$p_prompt" { sleep 1 if {$uprompt_seen == 1} { send -- "$userpswd\r" } else { send -- "$passwd\r" } exp_continue } -re "$prompt" { set prompt_match $expect_out(0,string); break; } "Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; catch {wait}; return 1 } } } set in_proc 0 return 0 } # New subroutine to provide "login" command capabilities, using the enable user and enable password # Login proc do_login { enauser enapasswd } { global prompt in_proc global u_prompt e_prompt set in_proc 1 send "login\r" expect { -re "$u_prompt" { send "$enauser\r"; exp_continue} -re "$e_prompt" { send "$enapasswd\r"; exp_continue} "#" { set prompt "#" } "(login)" { set prompt "> (login) " } -re "(denied|Sorry|Incorrect)" { # % Access denied - from local auth and poss. others send_user "\nError: Check your Login passwd\n"; return 1 } "% Error in authentication" { send_user "\nError: Check your Login passwd\n" return 1 } "% Bad passwords" { send_user "\nError: Check your Login passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global do_saveconfig in_proc global prompt u_prompt e_prompt set in_proc 1 send "enable\r" expect { -re "$u_prompt" { send -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } "(enable)" { set prompt "> \\(enable\\) " } -re "(denied|Sorry|Incorrect)" { # % Access denied - from local auth and poss. others send_user "\nError: Check your Enable passwd\n"; return 1 } "% Error in authentication" { send_user "\nError: Check your Enable passwd\n" return 1 } "% Bad passwords" { send_user "\nError: Check your Enable passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. set in_proc 0 return 0 } # Run commands given on the command line. proc run_commands { prompt command } { global do_saveconfig in_proc platform set in_proc 1 # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "terminal length 0". # skip if its an extreme (since the pager can not be disabled on a # per-vty basis). if { [ string compare "extreme" "$platform" ] } { if [ regexp -- ".*> .*enable" "$prompt" ] { send "set length 0\r" # This is ugly, but reduces code duplication, allowing the # subsequent expects to handle everything as normal. set command "set logging session disable;$command" } else { send "terminal-length 0\r" } # match cisco config mode prompts too, such as router(config-if)#, # but catalyst does not change in this fashion. regsub -all {^(.{1,11}).*([#>])$} $prompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt expect { -re $reprompt {} -re "\[\n\r]+" { exp_continue } } } else { set reprompt $prompt } # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # the pager can not be turned off on the PIX, so we have to look # for the "More" prompt. the extreme is equally obnoxious, with a # global switch in the config. for {set i 0} {$i < $num_commands} { incr i} { send -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "\b+" { exp_continue } -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" } -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } -re "^--More--\[\r\n]+" { # specific match c1900 pager send " " exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " # bloody ^[[2K after " " expect { -re "^\[^\r\n]*\r" {} } exp_continue } -re "^ *--More--\[^\n\r]*" { send " " exp_continue } -re "^<-+ More -+>\[^\n\r]*" { send_user -- "$expect_out(buffer)" send " " exp_continue } } } log_user 1 if { [ string compare "extreme" "$platform" ] } { send -h "exit\r" } else { send -h "quit\r" } expect { -re "^\[^\n\r *]*$reprompt" { # the Cisco CE and Jnx ERX # return to non-enabled mode # on exit in enabled mode. send -h "exit\r" exp_continue; } "The system has unsaved changes" { # Force10 SFTOS if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Would you like to save them now" { # Force10 if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } -re "(Profile|Configuration) changes have occurred.*" { # Cisco CSS if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Do you wish to save your configuration changes" { if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } -re "\[\n\r]+" { exp_continue } timeout { catch {close}; catch {wait}; return 0 } eof { return 0 } } set in_proc 0 } # # For each router... (this is main loop) # source_password_file $password_file set in_proc 0 set exitval 0 set prompt_match "" set enable 0 foreach router [lrange $argv $i end] { set router [string tolower $router] # attempt at platform switching. set platform "" send_user -- "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Default prompt. set prompt "(>|#| \\(enable\\))" # If a "login" option is used, no "enable" will be required # look for login option in .cloginrc if { [find login $router] != "" } { set enable 0 set loginonly 1 } # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user -- "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user -- "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [find user $router] ""] if { "$ruser" == "" } { set ruser $default_user } } # Figure out username's password (if different from the vty password) if {[info exists userpasswd]} { # command line username set userpswd $userpasswd } else { set userpswd [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name|User):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd|Enter password for \[^ :]+):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # Figure out identity file to use set identfile [join [lindex [find identity $router] 0] ""] # Figure out passphrase to use if {[info exists avpassphrase]} { set passphrase $avpassphrase } else { set passphrase [join [lindex [find passphrase $router] 0] ""] } if { ! [string length "$passphrase"]} { set passphrase $passwd } # Figure out cypher type if {[info exists cypher]} { # command line cypher type set cyphertype $cypher } else { set cyphertype [find cyphertype $router] if { "$cyphertype" == "" } { set cyphertype "3des" } } # Figure out connection method set cmethod [find method $router] if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} } # Figure out the SSH executable name set sshcmd [find sshcmd $router] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype $identfile]} { incr exitval # if login failed or rsh was unsuccessful, move on to the next device continue } # Figure out the prompt. if { [regexp -- "(#| \\(enable\\))" $prompt_match junk] == 1 } { set enable 0 } else { if { $avenable == 0 } { set enable 0 } else { set ne [find noenable $router] set ae [find autoenable $router] if { "$ne" == "1" || "$ae" == "1" || $avautoenable } { set enable 0 } else { set enable 1 } } } # login required? if { $loginonly } { if {[do_login $enauser $enapasswd]} { if { $do_command || $do_script } { close; wait continue } } } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^(.+\[:.])1 ($prompt)" { # stoopid extreme cmd-line numbers and # prompt based on state of config changes, # which may have an * at the beginning. set junk $expect_out(1,string) regsub -all "^\\\* " $expect_out(1,string) {} junk regsub -all "\[\]\[\(\)]" $junk {\\&} junk; set prompt ".? ?$junk\[0-9]+ $expect_out(2,string)"; set platform "extreme" } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[\(\)]" $junk {\\&} prompt; } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "terminal length 0". if [ regexp -- ".*> .*enable" "$prompt" ] { send "set length 0\r" expect -re $prompt {} send "set width 80\r" expect -re $prompt {} send "set logging session disable\r" } else { send "terminal-length 0\r" expect -re $prompt {} send "terminal width 80\r" } expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval And in .cloginrc #Auth method is radius. add method x.y.z.t {your protocol} add user x.y.z.t {your user} add userprompt x.y.z.t {"Enter\ radius\ username:"} add passprompt x.y.z.T {"Enter\ radius\ password:"} add password x.y.z.t {your password} Signature de Alexandre AMSALEG Le 19/02/14 12:40, David Gomez a ?crit : > Hi, > > Does anyone knows how to get the running config of this devices with > Rancid? > > IBM Networking Operating System RackSwitch G8124-E > > Greetings! > > -- > ______________________________ > > > > *______________________________* > > *David G?mez* > > EXTERNAL Grupo Versia > > Telf.: 94 472 34 99 / 628 324 683 / 22017 > > _david.gomez at grupoversia.com _ > > > Pol. Inbisa 20B > > 48510 Valle de Tr?paga > > _www.grupoversia.com _ > > > > > > > > > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss -------------- next part -------------- An HTML attachment was scrubbed... URL: From campee at gmail.com Thu Feb 20 19:45:49 2014 From: campee at gmail.com (Eric) Date: Thu, 20 Feb 2014 11:45:49 -0800 Subject: [rancid] Suppress disk space usage output Message-ID: Rancid is notifying me every night that my Brocade load balancers have slightly less free space available due to their local system log increasing in size. Is there a way to tell it to not check for disk usage or suppress this output? Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From Douglas.Hughes at DEShawResearch.com Fri Feb 21 01:08:03 2014 From: Douglas.Hughes at DEShawResearch.com (Hughes, Doug) Date: Fri, 21 Feb 2014 01:08:03 +0000 Subject: [rancid] Suppress disk space usage output In-Reply-To: References: Message-ID: You need to edit the brocade rancid file, find the stanza where it collects that config information (usually preceeded by a series of ! or other comment characters near the beginning of the section in the output that gives you a clue, you can search for this in the rancid file.) Then, where you see the rest of the 'next if' lines add another one that matches the line you want to elide from the output. It's pretty easy. (see the archives for more examples of this. It's an FAQ) From: rancid-discuss-bounces at shrubbery.net [mailto:rancid-discuss-bounces at shrubbery.net] On Behalf Of Eric Sent: Thursday, February 20, 2014 2:46 PM To: rancid-discuss at shrubbery.net Subject: [rancid] Suppress disk space usage output Rancid is notifying me every night that my Brocade load balancers have slightly less free space available due to their local system log increasing in size. Is there a way to tell it to not check for disk usage or suppress this output? Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mcmyst at hotmail.fr Fri Feb 21 11:19:04 2014 From: mcmyst at hotmail.fr (matthieu flye) Date: Fri, 21 Feb 2014 12:19:04 +0100 Subject: [rancid] Alulogin for Alcatel 7750 SR-7 Message-ID: Hello, In my office we have 8 Alcatel 7750 SR-7.Rancid is doing well backing up the configuration. We use alulogin/alurancid from this website to do the work:https://code.google.com/p/alurancid/source/browse/alulogin I would like to use alulogin to send multiple command in order to do some automatic provisioning like:./alulogin -f .cloginrc -c ?configure; service; bla; bla; bla;? But it hangs after sending the first command:expect alulogin -f /var/lib/rancid/.cloginrc -c "configure;service" 10.0.0.110.0.0.1spawn ssh -c 3des -x -l root 10.0.0.1 Network Device Restricted accessroot at 10.0.0.1's password: A:RTR_08_0001# A:RTR_08_0001# environment no more A:RTR_08_0001# configure But whenever I stay out of the ? configure ? mode, I can run multiple commands like:-c "admin display-config;admin save;admin display-config;" When I enter in configure mode, the prompt change in:A:RTR_08_0001# configure A:RTR_08_0001>config# Here is the debug output when trying to enter in configure mode. Basically it should be the same on every Alcatel router with SR-OS. Regards expect -d alulogin -f /var/lib/rancid/.cloginrc -c "configure;service" 10.0.0.1 expect version 5.44.1.14argv[0] = expect argv[1] = -d argv[2] = alulogin argv[3] = -f argv[4] = /var/lib/rancid/.cloginrc argv[5] = -c argv[6] = configure;service argv[7] = 10.0.0.1 set argc 5set argv0 "alulogin"set argv "-f /var/lib/rancid/.cloginrc -c {configure;service} 10.0.0.1"executing commands from command file aluloginparent: waiting for sync byteparent: telling child to go aheadparent: now unsynchronized from childspawn: returns {27774}Gate keeper glob pattern for '(Connection refused|Secure connection [^]+ refused)' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '(Connection closed by|Connection to [^]+ closed)' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '(Host key not found |The authenticity of host .* be established).*(yes/no)?' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for 'HOST IDENTIFICATION HAS CHANGED.* (yes/no)?' is 'HOST IDENTIFICATION HAS CHANGED* *'. Activating booster.Gate keeper glob pattern for 'Offending key for .* (yes/no)?' is 'Offending key for * *'. Activating booster.Gate keeper glob pattern for '(denied|Sorry)' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '% (Bad passwords|Authentication failed)' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for 'Enter Selection: ' is 'Enter Selection: '. Activating booster.Gate keeper glob pattern for 'Last login:' is 'Last login:'. Activating booster.Gate keeper glob pattern for '@[^]+ ([Pp]assword|passwd):|Mot de passe:' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '(Username|Login|login|user name|User):' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '([Pp]assword|passwd):|Mot de passe:' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '(#| \(enable\))' is ''. Not usable, disabling the performance booster. expect: does "" (spawn_id exp6) match regular expression "(Connection refused|Secure connection [^\n\r]+ refused)"? (No Gate, RE only) gate=yes re=no"(Connection closed by|Connection to [^\n\r]+ closed)"? (No Gate, RE only) gate=yes re=no expect: does "" (spawn_id exp6) match glob pattern "unknown host\r"? no expect: does "" (spawn_id exp6) match glob pattern "Host is unreachable"? no"No address associated with name"? no"(Host key not found |The authenticity of host .* be established).*(yes/no)?"? (No Gate, RE only) gate=yes re=no"HOST IDENTIFICATION HAS CHANGED.* (yes/no)?"? Gate "HOST IDENTIFICATION HAS CHANGED* *"? gate=no"Offending key for .* (yes/no)?"? Gate "Offending key for * *"? gate=no"(denied|Sorry)"? (No Gate, RE only) gate=yes re=no"Login failed"? no"% (Bad passwords|Authentication failed)"? (No Gate, RE only) gate=yes re=no"Press any key to continue"? no"Enter Selection: "? Gate "Enter Selection: "? gate=no"Last login:"? Gate "Last login:"? gate=no"@[^\r\n]+ ([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(Username|Login|login|user name|User):"? (No Gate, RE only) gate=yes re=no"([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(#| \(enable\))"? (No Gate, RE only) gate=yes re=no"Login invalid"? no expect: does " Network Device Restricted access\r\r\nroot at 10.0.0.1's password: " (spawn_id exp6) match regular expression "(Connection refused|Secure connection [^\n\r]+ refused)"? (No Gate, RE only) gate=yes re=no"(Connection closed by|Connection to [^\n\r]+ closed)"? (No Gate, RE only) gate=yes re=no expect: does " Network Device Restricted access\r\r\nroot at 10.0.0.1's password: " (spawn_id exp6) match glob pattern "unknown host\r"? no expect: does " Network Device Restricted access\r\r\nroot at 10.0.0.1's password: " (spawn_id exp6) match glob pattern "Host is unreachable"? no"No address associated with name"? no"(Host key not found |The authenticity of host .* be established).*(yes/no)?"? (No Gate, RE only) gate=yes re=no"HOST IDENTIFICATION HAS CHANGED.* (yes/no)?"? Gate "HOST IDENTIFICATION HAS CHANGED* *"? gate=no"Offending key for .* (yes/no)?"? Gate "Offending key for * *"? gate=no"(denied|Sorry)"? (No Gate, RE only) gate=yes re=no"Login failed"? no"% (Bad passwords|Authentication failed)"? (No Gate, RE only) gate=yes re=no"Press any key to continue"? no"Enter Selection: "? Gate "Enter Selection: "? gate=no"Last login:"? Gate "Last login:"? gate=no"@[^\r\n]+ ([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=yesexpect: set expect_out(0,string) "@10.0.0.1's password:"expect: set expect_out(1,string) "password"expect: set expect_out(spawn_id) "exp6"expect: set expect_out(buffer) " Network Device Restricted access\r\r\nroot at 10.0.0.1's password:"send: sending ? pwd\r ? to { exp6 }expect: continuing expect expect: does " " (spawn_id exp6) match regular expression "(Connection refused|Secure connection [^\n\r]+ refused)"? (No Gate, RE only) gate=yes re=no"(Connection closed by|Connection to [^\n\r]+ closed)"? (No Gate, RE only) gate=yes re=no expect: does " " (spawn_id exp6) match glob pattern "unknown host\r"? no expect: does " " (spawn_id exp6) match glob pattern "Host is unreachable"? no"No address associated with name"? no"(Host key not found |The authenticity of host .* be established).*(yes/no)?"? (No Gate, RE only) gate=yes re=no"HOST IDENTIFICATION HAS CHANGED.* (yes/no)?"? Gate "HOST IDENTIFICATION HAS CHANGED* *"? gate=no"Offending key for .* (yes/no)?"? Gate "Offending key for * *"? gate=no"(denied|Sorry)"? (No Gate, RE only) gate=yes re=no"Login failed"? no"% (Bad passwords|Authentication failed)"? (No Gate, RE only) gate=yes re=no"Press any key to continue"? no"Enter Selection: "? Gate "Enter Selection: "? gate=no"Last login:"? Gate "Last login:"? gate=no"@[^\r\n]+ ([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(Username|Login|login|user name|User):"? (No Gate, RE only) gate=yes re=no"([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(#| \(enable\))"? (No Gate, RE only) gate=yes re=no"Login invalid"? no expect: does " \r\n" (spawn_id exp6) match regular expression "(Connection refused|Secure connection [^\n\r]+ refused)"? (No Gate, RE only) gate=yes re=no"(Connection closed by|Connection to [^\n\r]+ closed)"? (No Gate, RE only) gate=yes re=no expect: does " \r\n" (spawn_id exp6) match glob pattern "unknown host\r"? no expect: does " \r\n" (spawn_id exp6) match glob pattern "Host is unreachable"? no"No address associated with name"? no"(Host key not found |The authenticity of host .* be established).*(yes/no)?"? (No Gate, RE only) gate=yes re=no"HOST IDENTIFICATION HAS CHANGED.* (yes/no)?"? Gate "HOST IDENTIFICATION HAS CHANGED* *"? gate=no"Offending key for .* (yes/no)?"? Gate "Offending key for * *"? gate=no"(denied|Sorry)"? (No Gate, RE only) gate=yes re=no"Login failed"? no"% (Bad passwords|Authentication failed)"? (No Gate, RE only) gate=yes re=no"Press any key to continue"? no"Enter Selection: "? Gate "Enter Selection: "? gate=no"Last login:"? Gate "Last login:"? gate=no"@[^\r\n]+ ([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(Username|Login|login|user name|User):"? (No Gate, RE only) gate=yes re=no"([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(#| \(enable\))"? (No Gate, RE only) gate=yes re=no"Login invalid"? no expect: does " \r\n\r\n" (spawn_id exp6) match regular expression "(Connection refused|Secure connection [^\n\r]+ refused)"? (No Gate, RE only) gate=yes re=no"(Connection closed by|Connection to [^\n\r]+ closed)"? (No Gate, RE only) gate=yes re=no expect: does " \r\n\r\n" (spawn_id exp6) match glob pattern "unknown host\r"? no expect: does " \r\n\r\n" (spawn_id exp6) match glob pattern "Host is unreachable"? no"No address associated with name"? no"(Host key not found |The authenticity of host .* be established).*(yes/no)?"? (No Gate, RE only) gate=yes re=no"HOST IDENTIFICATION HAS CHANGED.* (yes/no)?"? Gate "HOST IDENTIFICATION HAS CHANGED* *"? gate=no"Offending key for .* (yes/no)?"? Gate "Offending key for * *"? gate=no"(denied|Sorry)"? (No Gate, RE only) gate=yes re=no"Login failed"? no"% (Bad passwords|Authentication failed)"? (No Gate, RE only) gate=yes re=no"Press any key to continue"? no"Enter Selection: "? Gate "Enter Selection: "? gate=no"Last login:"? Gate "Last login:"? gate=no"@[^\r\n]+ ([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(Username|Login|login|user name|User):"? (No Gate, RE only) gate=yes re=no"([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(#| \(enable\))"? (No Gate, RE only) gate=yes re=no"Login invalid"? no expect: does " \r\n\r\n\r\n" (spawn_id exp6) match regular expression "(Connection refused|Secure connection [^\n\r]+ refused)"? (No Gate, RE only) gate=yes re=no"(Connection closed by|Connection to [^\n\r]+ closed)"? (No Gate, RE only) gate=yes re=no expect: does " \r\n\r\n\r\n" (spawn_id exp6) match glob pattern "unknown host\r"? no expect: does " \r\n\r\n\r\n" (spawn_id exp6) match glob pattern "Host is unreachable"? no"No address associated with name"? no"(Host key not found |The authenticity of host .* be established).*(yes/no)?"? (No Gate, RE only) gate=yes re=no"HOST IDENTIFICATION HAS CHANGED.* (yes/no)?"? Gate "HOST IDENTIFICATION HAS CHANGED* *"? gate=no"Offending key for .* (yes/no)?"? Gate "Offending key for * *"? gate=no"(denied|Sorry)"? (No Gate, RE only) gate=yes re=no"Login failed"? no"% (Bad passwords|Authentication failed)"? (No Gate, RE only) gate=yes re=no"Press any key to continue"? no"Enter Selection: "? Gate "Enter Selection: "? gate=no"Last login:"? Gate "Last login:"? gate=no"@[^\r\n]+ ([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(Username|Login|login|user name|User):"? (No Gate, RE only) gate=yes re=no"([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(#| \(enable\))"? (No Gate, RE only) gate=yes re=no"Login invalid"? no expect: does " \r\n\r\n\r\nA:RTR_08_0001# " (spawn_id exp6) match regular expression "(Connection refused|Secure connection [^\n\r]+ refused)"? (No Gate, RE only) gate=yes re=no"(Connection closed by|Connection to [^\n\r]+ closed)"? (No Gate, RE only) gate=yes re=no expect: does " \r\n\r\n\r\nA:RTR_08_0001# " (spawn_id exp6) match glob pattern "unknown host\r"? no expect: does " \r\n\r\n\r\nA:RTR_08_0001# " (spawn_id exp6) match glob pattern "Host is unreachable"? no"No address associated with name"? no"(Host key not found |The authenticity of host .* be established).*(yes/no)?"? (No Gate, RE only) gate=yes re=no"HOST IDENTIFICATION HAS CHANGED.* (yes/no)?"? Gate "HOST IDENTIFICATION HAS CHANGED* *"? gate=no"Offending key for .* (yes/no)?"? Gate "Offending key for * *"? gate=no"(denied|Sorry)"? (No Gate, RE only) gate=yes re=no"Login failed"? no"% (Bad passwords|Authentication failed)"? (No Gate, RE only) gate=yes re=no"Press any key to continue"? no"Enter Selection: "? Gate "Enter Selection: "? gate=no"Last login:"? Gate "Last login:"? gate=no"@[^\r\n]+ ([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(Username|Login|login|user name|User):"? (No Gate, RE only) gate=yes re=no"([Pp]assword|passwd):|Mot de passe:"? (No Gate, RE only) gate=yes re=no"(#| \(enable\))"? (No Gate, RE only) gate=yes re=yesexpect: set expect_out(0,string) "#"expect: set expect_out(1,string) "#"expect: set expect_out(spawn_id) "exp6"expect: set expect_out(buffer) " \r\n\r\n\r\nA:RTR_08_0001#"send: sending "\r" to { exp6 }Gate keeper glob pattern for '[]+' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '^.+(#| \(enable\))' is ''. Not usable, disabling the performance booster. expect: does " " (spawn_id exp6) match regular expression "[\r\n]+"? (No Gate, RE only) gate=yes re=no"^.+(#| \(enable\))"? (No Gate, RE only) gate=yes re=no expect: does " \r\n" (spawn_id exp6) match regular expression "[\r\n]+"? (No Gate, RE only) gate=yes re=yesexpect: set expect_out(0,string) "\r\n"expect: set expect_out(spawn_id) "exp6"expect: set expect_out(buffer) " \r\n"expect: continuing expect expect: does "" (spawn_id exp6) match regular expression "[\r\n]+"? (No Gate, RE only) gate=yes re=no"^.+(#| \(enable\))"? (No Gate, RE only) gate=yes re=no expect: does "A:RTR_08_0001# " (spawn_id exp6) match regular expression "[\r\n]+"? (No Gate, RE only) gate=yes re=no"^.+(#| \(enable\))"? (No Gate, RE only) gate=yes re=yesexpect: set expect_out(0,string) "A:RTR_08_0001#"expect: set expect_out(1,string) "#"expect: set expect_out(spawn_id) "exp6"expect: set expect_out(buffer) "A:RTR_08_0001#"send: sending "environment no more\r" to { exp6 }Gate keeper glob pattern for 'A\:RTR_08_0001#' is 'A:RTR_08_0001#'. Activating booster. expect: does " " (spawn_id exp6) match regular expression "A\:RTR_08_0001#"? Gate "A:RTR_08_0001#"? gate=no expect: does " environmen" (spawn_id exp6) match regular expression "A\:RTR_08_0001#"? Gate "A:RTR_08_0001#"? gate=no expect: does " environment no more \r\n" (spawn_id exp6) match regular expression "A\:RTR_08_0001#"? Gate "A:RTR_08_0001#"? gate=no expect: does " environment no more \r\nA:RTR_08_0001# " (spawn_id exp6) match regular expression "A\:RTR_08_0001#"? Gate "A:RTR_08_0001#"? gate=yes re=yesexpect: set expect_out(0,string) "A:RTR_08_0001#"expect: set expect_out(spawn_id) "exp6"expect: set expect_out(buffer) " environment no more \r\nA:RTR_08_0001#"send: sending "configure\r" to { exp6 }Gate keeper glob pattern for +' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '^[^ *]*A\:RTR_08_0001#' is '*A:RTR_08_0001#'. Activating booster.Gate keeper glob pattern for '^[^]*A\:RTR_08_0001#.' is '*A:RTR_08_0001#?'. Activating booster.Gate keeper glob pattern for '^--More--[]+' is '--More--*'. Activating booster.Gate keeper glob pattern for '[]+' is ''. Not usable, disabling the performance booster.Gate keeper glob pattern for '[^]*Press to cont[^]*' is '*Press to cont*'. Activating booster.Gate keeper glob pattern for 'Press any key to continue (Q to quit)[^]*' is 'Press any key to continue Q to quit*'. Activating booster.Gate keeper glob pattern for '^ *--More--[^]*' is '*--More--*'. Activating booster.Gate keeper glob pattern for '^<-+ More -+>[^]*' is '<* More *>*'. Activating booster. expect: does " " (spawn_id exp6) match regular expression "\u0008+"? (No Gate, RE only) gate=yes re=no"^[^\n\r *]*A\:RTR_08_0001#"? Gate "*A:RTR_08_0001#"? gate=no"^[^\n\r]*A\:RTR_08_0001#."? Gate "*A:RTR_08_0001#?"? gate=no"^--More--[\r\n]+"? Gate "--More--*"? gate=no"[\n\r]+"? (No Gate, RE only) gate=yes re=no"[^\r\n]*Press to cont[^\r\n]*"? Gate "*Press to cont*"? gate=no"Press any key to continue (Q to quit)[^\r\n]*"? Gate "Press any key to continue Q to quit*"? gate=no"^ *--More--[^\n\r]*"? Gate "*--More--*"? gate=no"^<-+ More -+>[^\n\r]*"? Gate "<* More *>*"? gate=no expect: does " configure" (spawn_id exp6) match regular expression "\u0008+"? (No Gate, RE only) gate=yes re=no"^[^\n\r *]*A\:RTR_08_0001#"? Gate "*A:RTR_08_0001#"? gate=no"^[^\n\r]*A\:RTR_08_0001#."? Gate "*A:RTR_08_0001#?"? gate=no"^--More--[\r\n]+"? Gate "--More--*"? gate=no"[\n\r]+"? (No Gate, RE only) gate=yes re=no"[^\r\n]*Press to cont[^\r\n]*"? Gate "*Press to cont*"? gate=no"Press any key to continue (Q to quit)[^\r\n]*"? Gate "Press any key to continue Q to quit*"? gate=no"^ *--More--[^\n\r]*"? Gate "*--More--*"? gate=no"^<-+ More -+>[^\n\r]*"? Gate "<* More *>*"? gate=no expect: does " configure \r\n" (spawn_id exp6) match regular expression "\u0008+"? (No Gate, RE only) gate=yes re=no"^[^\n\r *]*A\:RTR_08_0001#"? Gate "*A:RTR_08_0001#"? gate=no"^[^\n\r]*A\:RTR_08_0001#."? Gate "*A:RTR_08_0001#?"? gate=no"^--More--[\r\n]+"? Gate "--More--*"? gate=no"[\n\r]+"? (No Gate, RE only) gate=yes re=yesexpect: set expect_out(0,string) "\r\n"expect: set expect_out(spawn_id) "exp6"expect: set expect_out(buffer) " configure \r\n"expect: continuing expect expect: does "" (spawn_id exp6) match regular expression "\u0008+"? (No Gate, RE only) gate=yes re=no"^[^\n\r *]*A\:RTR_08_0001#"? Gate "*A:RTR_08_0001#"? gate=no"^[^\n\r]*A\:RTR_08_0001#."? Gate "*A:RTR_08_0001#?"? gate=no"^--More--[\r\n]+"? Gate "--More--*"? gate=no"[\n\r]+"? (No Gate, RE only) gate=yes re=no"[^\r\n]*Press to cont[^\r\n]*"? Gate "*Press to cont*"? gate=no"Press any key to continue (Q to quit)[^\r\n]*"? Gate "Press any key to continue Q to quit*"? gate=no"^ *--More--[^\n\r]*"? Gate "*--More--*"? gate=no"^<-+ More -+>[^\n\r]*"? Gate "<* More *>*"? gate=no expect: does "A:RTR_08_0001>config# " (spawn_id exp6) match regular expression "\u0008+"? (No Gate, RE only) gate=yes re=no"^[^\n\r *]*A\:RTR_08_0001#"? Gate "*A:RTR_08_0001#"? gate=no"^[^\n\r]*A\:RTR_08_0001#."? Gate "*A:RTR_08_0001#?"? gate=no"^--More--[\r\n]+"? Gate "--More--*"? gate=no"[\n\r]+"? (No Gate, RE only) gate=yes re=no"[^\r\n]*Press to cont[^\r\n]*"? Gate "*Press to cont*"? gate=no"Press any key to continue (Q to quit)[^\r\n]*"? Gate "Press any key to continue Q to quit*"? gate=no"^ *--More--[^\n\r]*"? Gate "*--More--*"? gate=no"^<-+ More -+>[^\n\r]*"? Gate "<* More *>*"? gate=no^Csighandler: handling signal(2)async event handler: Tcl_Eval(exit 130) -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.mckinnon at gmail.com Sat Feb 22 07:02:16 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Sat, 22 Feb 2014 09:02:16 +0200 Subject: [rancid] Dealing with rancid dying under heavy load Message-ID: <53084B78.2020905@gmail.com> Hi, Recently I had a moment of over-zealous enthusiasm and turned PAR_COUNT up higher (from 30 to 50) to get rancid-run to complete quicker. Sadly, about 1 in 10 instances of rancid started failing mysteriously. The logs mostly just give the dreaded "End of run not found" message, a few have strange password errors for a device that is configured correctly. Running rancid on these manually where the host is idle always completes correctly. In each case I find that the *rancid parser did run and minimally launched *clogin, so I suspect memory or IO issues under load causing scripts to fail. I want to patch the code to trap and report these errors if possible. We all know how tricky this can get, anyone in a position to discuss how best to proceed? I'll do the heavy lifting of coding and testing, I do want to pick other's brains first :-) Background info: FreeBSD 8.0-STABLE perl-5.8.9 expect-5.44.1.15 rancid-2.3.8 rancid hosts are VMs on ESXi-4-something, 1 cpu, 1 nic, 1g RAM the NIC is gigaBit full-duplex. "load" tends to run rather high, easily getting to 10+ and frightening newbie sysadmins, but this has never been a problem in the past as rancid is IO-bound anyway and scripts tend to spin along till they complete. 4M Total, 28K Used, 1024M Free -- Alan McKinnon alan.mckinnon at gmail.com From heas at shrubbery.net Sat Feb 22 07:35:23 2014 From: heas at shrubbery.net (heasley) Date: Sat, 22 Feb 2014 07:35:23 +0000 Subject: [rancid] Dealing with rancid dying under heavy load In-Reply-To: <53084B78.2020905@gmail.com> References: <53084B78.2020905@gmail.com> Message-ID: <20140222073523.GB29015@shrubbery.net> Sat, Feb 22, 2014 at 09:02:16AM +0200, Alan McKinnon: > Hi, > > Recently I had a moment of over-zealous enthusiasm and turned PAR_COUNT > up higher (from 30 to 50) to get rancid-run to complete quicker. Sadly, > about 1 in 10 instances of rancid started failing mysteriously. The logs > mostly just give the dreaded "End of run not found" message, a few have > strange password errors for a device that is configured correctly. > Running rancid on these manually where the host is idle always completes > correctly. > > In each case I find that the *rancid parser did run and minimally > launched *clogin, so I suspect memory or IO issues under load causing > scripts to fail. I want to patch the code to trap and report these > errors if possible. > > We all know how tricky this can get, anyone in a position to discuss how > best to proceed? I'll do the heavy lifting of coding and testing, I do > want to pick other's brains first :-) > > > > Background info: > > FreeBSD 8.0-STABLE > perl-5.8.9 > expect-5.44.1.15 > rancid-2.3.8 > rancid hosts are VMs on ESXi-4-something, 1 cpu, 1 nic, 1g RAM > the NIC is gigaBit full-duplex. > > "load" tends to run rather high, easily getting to 10+ and frightening > newbie sysadmins, but this has never been a problem in the past as > rancid is IO-bound anyway and scripts tend to spin along till they complete. > 4M Total, 28K Used, 1024M Free the targets are VMs or the rancid host is a VM? unless the host can't keep up with the expect processes well enough to stay within the login script's timeout period (or what you've set in cloginrc), it should not fail - but i havent tried 30 or 40, usually kern.smp.cpus if the rancid host is a VM and assuming it is timing out, but plenty of spare cpu and net; figure out if its actually timing out due to wall clock time, vs. missing interrupts for example. From alan.mckinnon at gmail.com Sat Feb 22 08:44:40 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Sat, 22 Feb 2014 10:44:40 +0200 Subject: [rancid] Dealing with rancid dying under heavy load In-Reply-To: <20140222073523.GB29015@shrubbery.net> References: <53084B78.2020905@gmail.com> <20140222073523.GB29015@shrubbery.net> Message-ID: <53086378.10504@gmail.com> On 22/02/2014 09:35, heasley wrote: > Sat, Feb 22, 2014 at 09:02:16AM +0200, Alan McKinnon: >> Hi, >> >> Recently I had a moment of over-zealous enthusiasm and turned PAR_COUNT >> up higher (from 30 to 50) to get rancid-run to complete quicker. Sadly, >> about 1 in 10 instances of rancid started failing mysteriously. The logs >> mostly just give the dreaded "End of run not found" message, a few have >> strange password errors for a device that is configured correctly. >> Running rancid on these manually where the host is idle always completes >> correctly. >> >> In each case I find that the *rancid parser did run and minimally >> launched *clogin, so I suspect memory or IO issues under load causing >> scripts to fail. I want to patch the code to trap and report these >> errors if possible. >> >> We all know how tricky this can get, anyone in a position to discuss how >> best to proceed? I'll do the heavy lifting of coding and testing, I do >> want to pick other's brains first :-) >> >> >> >> Background info: >> >> FreeBSD 8.0-STABLE >> perl-5.8.9 >> expect-5.44.1.15 >> rancid-2.3.8 >> rancid hosts are VMs on ESXi-4-something, 1 cpu, 1 nic, 1g RAM >> the NIC is gigaBit full-duplex. >> >> "load" tends to run rather high, easily getting to 10+ and frightening >> newbie sysadmins, but this has never been a problem in the past as >> rancid is IO-bound anyway and scripts tend to spin along till they complete. >> 4M Total, 28K Used, 1024M Free > > the targets are VMs or the rancid host is a VM? The rancid host is a VM. The targets are Cisco kit. > unless the host can't keep up with the expect processes well enough to stay > within the login script's timeout period (or what you've set in cloginrc), > it should not fail - but i havent tried 30 or 40, usually kern.smp.cpus That was my thought too - it shouldn't fail and timeouts shouldn't happen. These targets are all on fast networks (usually GigaBit, some 100M and all respond quickly). I might have hit a threshold on the ESXi host; I don't have visibility into that environment and can't see what else it's hosting. > if the rancid host is a VM and assuming it is timing out, but plenty of > spare cpu and net; figure out if its actually timing out due to wall clock > time, vs. missing interrupts for example. I'll look into that. I'd discounted simple timeouts as another rancid system that deals with kit out in the field has PAR_COUNT=50 and it's been tested as high as 100. Some of that kit is stupid slow, I've seen show runs take 10 minutes to complete and the system just deals with it as expected. Both systems have the same OS config and both run as VMs in the same environment. I think step one is to get monitoring graphs out of the VMWare team. -- Alan McKinnon alan.mckinnon at gmail.com From heas at shrubbery.net Sat Feb 22 16:04:58 2014 From: heas at shrubbery.net (heasley) Date: Sat, 22 Feb 2014 16:04:58 +0000 Subject: [rancid] Dealing with rancid dying under heavy load In-Reply-To: <53086378.10504@gmail.com> References: <53084B78.2020905@gmail.com> <20140222073523.GB29015@shrubbery.net> <53086378.10504@gmail.com> Message-ID: <20140222160458.GC29015@shrubbery.net> Sat, Feb 22, 2014 at 10:44:40AM +0200, Alan McKinnon: > > unless the host can't keep up with the expect processes well enough to stay > > within the login script's timeout period (or what you've set in cloginrc), > > it should not fail - but i havent tried 30 or 40, usually kern.smp.cpus > > That was my thought too - it shouldn't fail and timeouts shouldn't > happen. These targets are all on fast networks (usually GigaBit, some > 100M and all respond quickly). > > I might have hit a threshold on the ESXi host; I don't have visibility > into that environment and can't see what else it's hosting. the first vm provided to me had 6 cpu and 8G; I couldnt figure out why the performance of our multithreaded application, also i/o bound, was so horrible - they'd limited the vm to ~512Mhz, so i had a 1989 vm. > > if the rancid host is a VM and assuming it is timing out, but plenty of > > spare cpu and net; figure out if its actually timing out due to wall clock > > time, vs. missing interrupts for example. > > I'll look into that. I'd discounted simple timeouts as another rancid > system that deals with kit out in the field has PAR_COUNT=50 and it's > been tested as high as 100. Some of that kit is stupid slow, I've seen > show runs take 10 minutes to complete and the system just deals with it > as expected. lack of memory seems to be a big one for VMs; esp. VirtualBox and similar VM systems. but, my experience with vmware is that disk i/o performance is poor. that might be their drivers for the controllers i've had, but it was bad enough that i moved to VBox. > Both systems have the same OS config and both run as VMs in the same > environment. I think step one is to get monitoring graphs out of the > VMWare team. thats a good indicator; when retrieving data, rancid spends most of its time waiting on the device. if you use NOPIPE=YES in rancid.conf, you decouple the retrieval from the processing/reformatting. From peo at chalmers.se Sun Feb 23 10:04:47 2014 From: peo at chalmers.se (Per-Olof Olsson) Date: Sun, 23 Feb 2014 11:04:47 +0100 Subject: [rancid] hostname glob - regex? In-Reply-To: <20140210173057.GC22932@shrubbery.net> References: <52F808CE.6060206@gmail.com> <20140210173057.GC22932@shrubbery.net> Message-ID: <5309C7BF.3050808@chalmers.se> heasley wrote 2014-02-10 18:30: > Mon, Feb 10, 2014 at 12:01:34AM +0100, Pawe?? Rzepa: >> W dniu 06.02.2014 08:44, Pawel Rzepa pisze: >> >> Hi, >> Any help? I've digged into this a little and found that .cloginrc is >> interpreted by expect. I'm not very familiar with expect, tried some >> regexps with braces, escaped braces etc and no success. Is it impossible >> to use regexp in this context? > > no; if it were, the manpage would have read regex, not glob. regex would > be useful; though i'm not sure how to implement it, since glob and regex > are not complatible. perhaps a global knob in cloginrc that switches the > format to regex? or an regex-specific version of the 'add' function and > search regexes before globs? > > Per Olaf, ideas? > Just replace "string match" with "regexp" will make a big format change in cloginrc. Think it's just to look for $ ( ) ^ | + or "\." ("([$)(^|+]|\\\.)+" in regexp) to determining if it is regexp or not. Possible it will give some false match and cloginrc need to be written more strict. ... >>> add user {192.168.1.*|192.168.2.5|*-core-*} {user1} >>> add password {192.168.1.*|192.168.2.5|*-core-*} {pass1} >>> >>> add user {10.1.2.3|10.1.5.*} {user2} ... Just not that simple when you say regexp. add user {^(192\.168\.1\..*|192\.168\.2\.5|.*-core-.*)$} {user1} ".*" for numbers? Why not "[0-9]+". add user {^(192\.168\.1\.[0-9]+|192\.168\.2\.5|.*-core-.*)$} {user1} Is this a possible way? cloginrc in my test. ------cloginrc--------------------------------- add password {sw1.aaa.domain.se} x x add method {10\.10\.1\.1|10\.10\.3\.[0-9]+|sw1\.aaa\.domain\.se} ssh add password {10\.10\.1\.1|10\.10\.4\.[0-9]+} x x add identity {^(10\.10\.1\.1|10\.10\.3\.[0-9]+|sw1\.aaa\.domain\.se)$} /home/rancid/.ssh/ssh_key add autoenable {10\.10\.1\.1|10\.10\.3\.[0-9]+|sw1\.aaa\.domain\.se} 1 add password * y y ----------------------------------------------- $ ./hlogin +debug_rc +debug_rc -c "show term" -f cloginrc -banner 10.10.3.74 10.10.3.74 Match regexp: 10.10.3.74 autoenable {10\.10\.1\.1|10\.10\.3\.[0-9]+|sw1\.aaa\.domain\.se} 1 No match : 10.10.3.74 password sw1.aaa.domain.se x x No match : 10.10.3.74 password {10\.10\.1\.1|10\.10\.4\.[0-9]+} x x Match : 10.10.3.74 password * y y Match regexp: 10.10.3.74 identity {^(10\.10\.1\.1|10\.10\.3\.[0-9]+|sw1\.aaa\.domain\.se)$} /home/rancid/.ssh/ssh_key Match regexp: 10.10.3.74 method {10\.10\.1\.1|10\.10\.3\.[0-9]+|sw1\.aaa\.domain\.se} ssh spawn hpuifilter -- ssh -i /home/rancid/.ssh/ssh_key -c 3des -x -l rancid 10.10.3.74 switch.aaa.domain.s# no page switch.aaa.domain.s# show term Terminal width: 132 length: 24 switch.aaa.domain.s#logout Do you want to log out [y/n]? y Connection to 10.10.3.74 closed. Have tested same update on clogin and hlogin 2.3.8 ---------------------------------------- *** clogin 2014-02-21 11:03:17.903550570 +0100 --- clogin_new 2014-02-23 08:36:49.088227859 +0100 *************** *** 54,59 **** --- 54,60 ---- # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ + \[+debug_rc\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-r passphrase\] \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-x command-file\] \ *************** *** 76,81 **** --- 77,84 ---- # tracks if we receive them on the command line. set do_passwd 1 set do_enapasswd 1 + # debug matching cloginrc file + set debug_rc 0 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) *************** *** 112,117 **** --- 115,124 ---- # Expect debug mode -d* { exp_internal 1 + # debug matching cloginrc file + # option twice, also show "No match" + } +debug_rc* { + set debug_rc [expr {$debug_rc + 1}] # Username } -u* { if {! [regexp .\[uU\](.+) $arg ignore user]} { *************** *** 282,292 **** proc find {var router} { upvar int_$var list if { [info exists list] } { foreach line $list { ! if { [string match [lindex $line 0] $router] } { ! return [lrange $line 1 end] } } } return {} --- 289,311 ---- proc find {var router} { upvar int_$var list + global debug_rc + set match_regexp 0 if { [info exists list] } { foreach line $list { ! if { [ regexp {([$)(^|+]|\\\.)+} [lindex $line 0] ] } { ! catch { set match_regexp [regexp [lindex $line 0] $router] } reason ! if { $match_regexp != 0 } { ! if { $debug_rc } {send_user "Match regexp: $router $var $line\n"} ! return [lrange $line 1 end] ! } ! } else { ! if { [string match [lindex $line 0] $router] } { ! if { $debug_rc } { send_user "Match : $router $var $line\n" } ! return [lrange $line 1 end] ! } } + if { $debug_rc >= 2 } {send_user "No match : $router $var $line\n"} } } return {} ----------------------------------------- >> Regards, >> Pawel Rzepa >> >>> Hi, >>> When I log into my devices to get configuration with rancid I must use >>> two different users for two different groups of devices. I know that I >>> can modify .cloginrc to achieve this: >>> >>> add user group-1-* {user1} >>> add user group-2-* {user2} >>> >>> Unfortunately I am unable to describe groups of devices in such a >>> consistent manner and now my .cloginrc looks like this: >>> >>> add user 192.168.1.* {user1} >>> add password 192.168.1.* {pass1} >>> add user 192.168.2.5 {user1} >>> add password 192.168.2.5 {pass1} >>> add user *-core-* {user1} >>> add password *-core-* {pass1} >>> >>> add user 10.1.2.3 {user2} >>> add user 10.1.5.* {user2} >>> etc.. >>> >>> Is it possible to use regular expression to describe hostname? I'd >>> love to specify them like that: >>> >>> add user {192.168.1.*|192.168.2.5|*-core-*} {user1} >>> add password {192.168.1.*|192.168.2.5|*-core-*} {pass1} >>> >>> add user {10.1.2.3|10.1.5.*} {user2} >>> ... >>> >>> Best regards, >>> Pawel Rzepa >> >> _______________________________________________ >> Rancid-discuss mailing list >> Rancid-discuss at shrubbery.net >> http://www.shrubbery.net/mailman/listinfo/rancid-discuss > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > /Peo ---------------------------------------------------------- Per-Olof Olsson Email: peo at chalmers.se Chalmers tekniska h?gskola IT-service Arvid Hedvalls backe 6 412 96 G?teborg Tel: 031/772 6738 Fax: 031/772 8680 ---------------------------------------------------------- From alan.mckinnon at gmail.com Sun Feb 23 15:51:39 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Sun, 23 Feb 2014 17:51:39 +0200 Subject: [rancid] hostname glob - regex? In-Reply-To: <5309C7BF.3050808@chalmers.se> References: <52F808CE.6060206@gmail.com> <20140210173057.GC22932@shrubbery.net> <5309C7BF.3050808@chalmers.se> Message-ID: <530A190B.9050104@gmail.com> On 23/02/2014 12:04, Per-Olof Olsson wrote: > heasley wrote 2014-02-10 18:30: >> Mon, Feb 10, 2014 at 12:01:34AM +0100, Pawe?? Rzepa: >>> W dniu 06.02.2014 08:44, Pawel Rzepa pisze: >>> >>> Hi, >>> Any help? I've digged into this a little and found that .cloginrc is >>> interpreted by expect. I'm not very familiar with expect, tried some >>> regexps with braces, escaped braces etc and no success. Is it impossible >>> to use regexp in this context? >> >> no; if it were, the manpage would have read regex, not glob. regex would >> be useful; though i'm not sure how to implement it, since glob and regex >> are not complatible. perhaps a global knob in cloginrc that switches the >> format to regex? or an regex-specific version of the 'add' function and >> search regexes before globs? >> >> Per Olaf, ideas? >> > > Just replace "string match" with "regexp" will make a big format change > in cloginrc. I would strongly recommend not implementing regexp in .cloginrc: - regexps are heard to read and hard to debug - users can apply them in a needlessly overcomplicated fashion - when a regexp that describes a general case is early in the list and a more specific match is later, the first match wins and this is really really hard to debug, simply because there's no log to say which line in .cloginrc was matched. The principle use case for regexps over globs seems to be the | operator, something like this: add username 192.168.(0|1|2|3|4).* {username1} add username 192.168.* {username2} The first line can always be expanded to 5 individual lines with the current syntax - less verbose but more explicit and fewer mistakes. -- Alan McKinnon alan.mckinnon at gmail.com From jethro.binks at strath.ac.uk Mon Feb 24 00:21:22 2014 From: jethro.binks at strath.ac.uk (Jethro R Binks) Date: Mon, 24 Feb 2014 00:21:22 +0000 (GMT) Subject: [rancid] Blade Network Tech switches (BNT/IBM/HP c-Class/etc) Message-ID: Hi, In recent times there have been a few queries about rancid support for the switches that Blade Network Technologies make, now apparently owned by IBM. Attached are modules I wrote today based on rancid 2.3.8 (and throwing away all the cisco command processing). I would be interested to see how these work for others. Mine are actually being tested against switches in HP c-class blade enclosures (v2 and v5) - no access to any IBM ones. In particular, it needs them to be operating in ISCLI mode, not the old Alteon/Nortel WebOS mode - try alogin/arancid for those. You will need to set the appropriate paths for perl and expect on the first lines, set your devices as type "bnt" in your router.db, and add the following line to your rancid-fe: 'bnt' => 'bntrancid', Jethro. . . . . . . . . . . . . . . . . . . . . . . . . . Jethro R Binks, Network Manager, Information Services Directorate, University Of Strathclyde, Glasgow, UK The University of Strathclyde is a charitable body, registered in Scotland, number SC015263. -------------- next part -------------- #! /usr/local/bin/expect -- ## ## Based on $Id: clogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # bntlogin - Blade Network Technologies login (ISCLI mode) # # Most options are intuitive for logging into a Cisco router. # The default is to enable (thus -noenable). Some folks have # setup tacacs to have a user login at priv-lvl = 15 (enabled) # so the -autoenable flag was added for this case (don't go through # the process of enabling and the prompt will be the "#" prompt. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-r passphrase\] \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-x command-file\] \ \[-y ssh_cypher_type\] router \[router...\]\n" # env(CLOGIN) may contain: # x == do not set xterm banner or name # Password file set password_file $env(HOME)/.cloginrc # Default is to login to the router set do_command 0 set do_script 0 # The default is to automatically enable set avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 0 # The default is to look in the password file to find the passwords. This # tracks if we receive them on the command line. set do_passwd 1 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # set send_human {.4 .4 .7 .3 5} # Find the user in the ENV, or use the unix userid. if {[info exists env(CISCO_USER)]} { set default_user $env(CISCO_USER) } elseif {[info exists env(USER)]} { set default_user $env(USER) } elseif {[info exists env(LOGNAME)]} { set default_user $env(LOGNAME) } else { # This uses "id" which I think is portable. At least it has existed # (without options) on all machines/OSes I've been on recently - # unlike whoami or id -nu. if [catch {exec id} reason] { send_error "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[info exists env(CLOGINRC)]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [regexp .\[uU\](.+) $arg ignore user]} { incr i set username [lindex $argv $i] } # VTY Password } -p* { if {! [regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [lindex $argv $i] } set do_passwd 0 # ssh passphrase } -r* { if {! [regexp .\[rR\](.+) $arg ignore passphrase]} { incr i set vapassphrase [lindex $argv $i] } # VTY Password } -v* { if {! [regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [lindex $argv $i] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { if {! [regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [lindex $argv $i] } # Environment variable to pass to -s scripts } -E* { if {[regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [lindex $argv $i] } set do_enapasswd 0 # Command to run. } -c* { if {! [regexp .\[cC\](.+) $arg ignore command]} { incr i set command [lindex $argv $i] } set do_command 1 # Expect script to run. } -s* { if {! [regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [lindex $argv $i] } if { ! [file readable $sfile] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [lindex $argv $i] } # alternate cloginrc file } -f* { if {! [regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [lindex $argv $i] } # Timeout } -t* { if {! [regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [lindex $argv $i] } # Command file } -x* { if {! [regexp .\[xX\](.+) $arg ignore cmd_file]} { incr i set cmd_file [lindex $argv $i] } if [catch {set cmd_fd [open $cmd_file r]} reason] { send_user "\nError: $reason\n" exit 1 } set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] set do_command 1 # Do we enable? } -noenable { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $usage" } # Only be quiet if we are running a script (it can log its output # on its own) if { $do_script } { log_user 0 } else { log_user 1 } # # Done configuration/variable setting. Now run with it... # # Sets Xterm title if interactive...if its an xterm and the user cares proc label { host } { global env # if CLOGIN has an 'x' in it, don't set the xterm name/banner if [info exists env(CLOGIN)] { if {[string first "x" $env(CLOGIN)] != -1} { return } } # take host from ENV(TERM) if [info exists env(TERM)] { if [regexp \^(xterm|vs) $env(TERM) ignore] { send_user "\033]1;[lindex [split $host "."] 0]\a" send_user "\033]2;$host\a" } } } # This is a helper function to make the password file easier to # maintain. Using this the password file has the form: # add password sl* pete cow # add password at* steve # add password * hanky-pie proc add {var args} { global int_$var ; lappend int_$var $args} proc include {args} { global env regsub -all "(^{|}$)" $args {} args if { [regexp "^/" $args ignore] == 0 } { set args $env(HOME)/$args } source_password_file $args } proc find {var router} { upvar int_$var list if { [info exists list] } { foreach line $list { if { [string match [lindex $line 0] $router] } { return [lrange $line 1 end] } } } return {} } # Loads the password file. Note that as this file is tcl, and that # it is sourced, the user better know what to put in there, as it # could install more than just password info... I will assume however, # that a "bad guy" could just as easy put such code in the clogin # script, so I will leave .cloginrc as just an extention of that script proc source_password_file { password_file } { global env if { ! [file exists $password_file] } { send_user "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [catch {source $password_file} reason] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure, -1 if rsh was used successfully proc login { router user userpswd passwd enapasswd cmethod cyphertype identfile } { global command spawn_id in_proc do_command do_script platform passphrase global prompt prompt_match u_prompt p_prompt e_prompt sshcmd set in_proc 1 set uprompt_seen 0 # try each of the connection methods in $cmethod until one is successful set progs [llength $cmethod] foreach prog [lrange $cmethod 0 end] { incr progs -1 if [string match "telnet*" $prog] { regexp {telnet(:([^[:space:]]+))*} $prog methcmd suffix port if {"$port" == ""} { set retval [catch {spawn telnet $router} reason] } else { set retval [catch {spawn telnet $router $port} reason] } if { $retval } { send_user "\nError: telnet failed: $reason\n" return 1 } } elseif [string match "ssh*" $prog] { # ssh to the router & try to login with or without an identfile. regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } if {"$identfile" != ""} { set cmd "$cmd -i $identfile" } set retval [catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { if { ! $do_command } { if { [llength $cmethod] == 1 } { send_user "\nError: rsh is an invalid method for -x and " send_user "interactive logins\n" } if { $progs == 0 } { return 1 } continue; } set commands [split $command \;] set num_commands [llength $commands] set rshfail 0 for {set i 0} {$i < $num_commands && !$rshfail} { incr i} { log_user 0 set retval [catch {spawn rsh $user@$router [lindex $commands $i] } reason] if { $retval } { send_user "\nError: rsh failed: $reason\n" log_user 1; return 1 } send_user "$router# [lindex $commands $i]\n" # rcmd does not get a pager and no prompts, so we just have to # look for failures & lines. expect { "Connection refused" { catch {close}; catch {wait}; send_user "\nError: Connection\ Refused ($prog): $router\n" set rshfail 1 } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; send_user "\nError: Connection\ closed ($prog): $router\n" set rshfail 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable:\ $router\n" set rshfail 1 } "No address associated with" { catch {close}; catch {wait}; send_user "\nError: Unknown host\ $router\n" set rshfail 1 } -re "\b+" { exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } timeout { catch {close}; catch {wait}; send_user "\nError: TIMEOUT reached\n" set rshfail 1 } eof { catch {close}; catch {wait}; } } log_user 1 } if { $rshfail } { if { !$progs } { return 1 } else { continue } } # fake the end of the session for rancid. send_user "$router# exit\n" # return rsh "success" return -1 } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "^<-+ More -+>\[^\n\r]*" { # ASA will use the pager for long banners send " "; exp_continue } -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } "Host is unreachable" { send_user "\nError: Host Unreachable: $router\n"; catch {close}; catch {wait}; return 1 } "No address associated with name" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Press any key to continue" { # send_user "Pressing the ANY key\n" send "\r" exp_continue } -re "Enter Selection: " { # Catalyst 1900s have some lame menu. Enter # K to reach a command-line. send "K\r" exp_continue } -re "Last login:" { exp_continue } -re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } -re "Enter passphrase.*: " { # sleep briefly to allow time for stty -echo sleep .3 send -- "$passphrase\r" exp_continue } -re "$u_prompt" { send -- "$user\r" set uprompt_seen 1 exp_continue } -re "$p_prompt" { sleep 1 if {$uprompt_seen == 1} { send -- "$userpswd\r" } else { send -- "$passwd\r" } exp_continue } -re "$prompt" { set prompt_match $expect_out(0,string); break; } "Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; catch {wait}; return 1 } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global do_saveconfig in_proc global prompt u_prompt e_prompt set in_proc 1 send "enable\r" expect { -re "$u_prompt" { send -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } "(enable)" { set prompt "> \\(enable\\) " } -re "(denied|Sorry|Incorrect)" { # % Access denied - from local auth and poss. others send_user "\nError: Check your Enable passwd\n"; return 1 } "% Error in authentication" { send_user "\nError: Check your Enable passwd\n" return 1 } "% Bad passwords" { send_user "\nError: Check your Enable passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. set in_proc 0 return 0 } # Run commands given on the command line. proc run_commands { prompt command } { global do_saveconfig in_proc platform set in_proc 1 # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "terminal length 0". # skip if its an extreme (since the pager can not be disabled on a # per-vty basis). if { [string compare "extreme" "$platform"] } { # match cisco config mode prompts too, such as router(config-if)#, # but catalyst does not change in this fashion. regsub -all {^(.{1,11}).*([#>])$} $prompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt } else { set reprompt $prompt } # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # the pager can not be turned off on the PIX, so we have to look # for the "More" prompt. the extreme is equally obnoxious in pre-12.3 XOS, # with a global switch in the config. for {set i 0} {$i < $num_commands} { incr i} { send -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "\b+" { exp_continue } -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" } -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } -re "^--More--\[\r\n]+" { # specific match c1900 pager send " " exp_continue } -re "\[^\r\n]*\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " # bloody ^[[2K after " " expect { -re "^\[^\r\n]*\r" {} } exp_continue } -re "^ *--More--\[^\n\r]*" { send " " exp_continue } -re "^<-+ More -+>\[^\n\r]*" { send_user -- "$expect_out(buffer)" send " " exp_continue } } } log_user 1 if { [string compare "extreme" "$platform"] } { send -h "exit\r" } else { send -h "quit\r" } expect { -re "^\[^\n\r *]*$reprompt" { # the Cisco CE and Jnx ERX # return to non-enabled mode # on exit in enabled mode. send -h "exit\r" exp_continue; } "The system has unsaved changes" { # Force10 SFTOS if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Would you like to save them now" { # Force10 if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } -re "(Profile|Configuration) changes have occurred.*" { # Cisco CSS if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Do you wish to save your configuration changes" { if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Confirm operation without saving running-config to startup-config (y/n) \?" { # BNT if {$do_saveconfig} { # we should send 'n' and then send # save command here! #catch {send "y\r"} send "n\r" expect "Exit canceled" send "copy running-config startup-config\r" expect -re "$reprompt" catch {send "exit\r"} } else { catch {send "y\r"} } exp_continue } -re "\[\n\r]+" { exp_continue } timeout { catch {close}; catch {wait}; return 0 } eof { return 0 } } set in_proc 0 } # # For each router... (this is main loop) # source_password_file $password_file set in_proc 0 set exitval 0 set prompt_match "" set enable 0 foreach router [lrange $argv $i end] { set router [string tolower $router] # attempt at platform switching. set platform "" send_user -- "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Default prompt. set prompt "(>|#| \\(enable\\))" # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user -- "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user -- "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [find user $router] ""] if { "$ruser" == "" } { set ruser $default_user } } # Figure out username's password (if different from the vty password) if {[info exists userpasswd]} { # command line username set userpswd $userpasswd } else { set userpswd [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name|User|username):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd|Enter password for \[^ :]+):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # Figure out identity file to use set identfile [join [lindex [find identity $router] 0] ""] # Figure out passphrase to use if {[info exists avpassphrase]} { set passphrase $avpassphrase } else { set passphrase [join [lindex [find passphrase $router] 0] ""] } if { ! [string length "$passphrase"]} { set passphrase $passwd } # Figure out cypher type if {[info exists cypher]} { # command line cypher type set cyphertype $cypher } else { set cyphertype [find cyphertype $router] if { "$cyphertype" == "" } { set cyphertype "3des" } } # Figure out connection method set cmethod [find method $router] if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype $identfile]} { incr exitval # if login failed or rsh was unsuccessful, move on to the next device continue } # Figure out the prompt. if { [regexp -- "(#| \\(enable\\))" $prompt_match junk] == 1 } { set enable 0 } else { if { $avenable == 0 } { set enable 0 } else { set ne [find noenable $router] set ae [find autoenable $router] if { "$ne" == "1" || "$ae" == "1" || $avautoenable } { set enable 0 } else { set enable 1 } } } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^(.+\[:.])1 ($prompt)" { # stoopid extreme cmd-line numbers and # prompt based on state of config changes, # which may have an * at the beginning. set junk $expect_out(1,string) regsub -all "^\\\* " $expect_out(1,string) {} junk regsub -all "\[\]\[\(\)]" $junk {\\&} junk; set prompt ".? ?$junk\[0-9]+ $expect_out(2,string)"; set platform "extreme" } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[\(\)]" $junk {\\&} prompt; } } if { $do_command || $do_script } { if { [ string compare "extreme" "$platform" ] } { # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "terminal length 0". if [regexp -- ".*> .*enable" "$prompt"] { send "set length 0\r" expect -re $prompt {} send "set width 132\r" expect -re $prompt {} send "set logging session disable\r" } else { send "terminal-length 0\r" #expect -re $prompt {} #send "terminal width 132\r" } expect -re $prompt {} } else { send "disable clipaging\r" expect -re $prompt {} } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval -------------- next part -------------- #! /usr/bin/perl5 ## ## Based on: $Id: rancid.in 2377 2012-01-31 22:55:13Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2009 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: bntrancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $proc = ""; $ios = "IOS"; $clean_run = 0; $found_end = 0; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # bntlogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($config_register); # configuration register value my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode my($supbootdisk) = 0; # skip sup-bootflash if sup-bootdisk # worked # This routine is used to print out the router configuration sub ProcessHistory { my($new_hist_tag,$new_command,$command_string, at string) = (@_); if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command)) && scalar(%history)) { print eval "$command \%history"; undef %history; } if (($new_hist_tag) && ($new_command) && ($command_string)) { if ($history{$command_string}) { $history{$command_string} = "$history{$command_string}@string"; } else { $history{$command_string} = "@string"; } } elsif (($new_hist_tag) && ($new_command)) { $history{++$#history} = "@string"; } else { print "@string"; } $hist_tag = $new_hist_tag; $command = $new_command; 1; } sub numerically { $a <=> $b; } # This is a sort routine that will sort numerically on the # keys of a hash as if it were a normal array. sub keynsort { local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort numerically keys(%lines)) { $sorted_lines[$i] = $lines{$key}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # keys of a hash as if it were a normal array. sub keysort { local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort keys(%lines)) { $sorted_lines[$i] = $lines{$key}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # values of a hash as if it were a normal array. sub valsort{ local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort values %lines) { $sorted_lines[$i] = $key; $i++; } @sorted_lines; } # This is a numerical sort routine (ascending). sub numsort { local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $num (sort {$a <=> $b} keys %lines) { $sorted_lines[$i] = $lines{$num}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # ip address when the ip address is anywhere in # the strings. sub ipsort { local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $addr (sort sortbyipaddr keys %lines) { $sorted_lines[$i] = $lines{$addr}; $i++; } @sorted_lines; } # These two routines will sort based upon IP addresses sub ipaddrval { my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#); $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0])); } sub sortbyipaddr { &ipaddrval($a) <=> &ipaddrval($b); } ## This routine processes general output of "display" commands sub CommentOutput { print STDERR " In CommentOutput: $_" if ($debug); chomp; # Display the command we're processing in the output: #s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; #ProcessHistory("COMMENTS", "", "", "! $_\n!\n"); #(my $cmd = $_) =~ s/^[\[<].*?[\]>]\a?\s?(.*)/$1/g; ProcessHistory("COMMENTS", "", "", "!\n! '$cmd':\n!\n"); while () { tr/\015//d; # If we find the prompt, we're done last if(/^\s*$prompt/); chomp; # filter out some junk #$_ = filter_lines($_); # Some commands are not supported on some models or versions # of code. These lines simply remove the associated error # messages: return(1) if ( /^\s+\^$/ || /% Invalid input detected at '\^' marker./ || /% Incomplete command. See '\^' marker./ ); # Now we skip or modify some lines from various commands to # remove irrelevant content, or to avoid insignificant diffs # 'show sys-info': next if (/^System Information at/); next if (/^Switch has been up for/); # 'show layer3': next if (/^Lease (Obtained|Expires):/); # 'show snmp-server': if ( $filter_commstr && /^ (Read community string:\s+)(\S+)/ || /^ (Write community string:\s+)(\S+)/ ) { ProcessHistory("","","","! $1$'"); next; } # Add the processed lines to the output buffer: ProcessHistory("COMMENTS","","","! $_\n"); } # Add a blank comment line to the output buffer ProcessHistory("COMMENTS", "", "", "!\n"); return(0); } ## This routine processes a "show running-config" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); # We aren't chomping these lines while () { tr/\015//d; last if(/^\s*$prompt/); #$_ = filter_lines($_); return(0) if ($found_end); # Filter out some sensitive data: if ( $filter_commstr && /^(snmp-server (read|write)-community )(\S+)/ ) { ProcessHistory("","","","! $1$'"); next; } if ( $filter_pwds >= 1 && /^(access user (\d+ password|administrator-password|operator-password) )(\S+)/ || /^(radius-server \S+ \S+ ekey )(\S+)/ ) { ProcessHistory("","","","! $1$'"); next; } next if (/^Current configuration:/); ProcessHistory("", "", "", "$_"); # end of config if (/^end$/) { $found_end = 1; return(0); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( # Commands relating to the operating system/version: {'show sys-info' => 'CommentOutput'}, # Commands relating to the hardware: {'show boot' => 'CommentOutput'}, {'show transceiver' => 'CommentOutput'}, # Commands relating to system state: {'show layer2' => 'CommentOutput'}, {'show layer3' => 'CommentOutput'}, {'show ssh' => 'CommentOutput'}, {'show ntp' => 'CommentOutput'}, {'show snmp-server' => 'CommentOutput'}, {'show radius-server' => 'CommentOutput'}, {'show ufd' => 'CommentOutput'}, {'show vlan' => 'CommentOutput'}, # And the system config itself: {'show running-config' => 'WriteTerm'}, ); # Use an array to preserve the order of the commands and a hash for mapping # commands to the subroutine and track commands that have been completed. @commands = map(keys(%$_), @commandtable); %commands = map(%$_, @commandtable); $cisco_cmds = join(";", at commands); $cmds_regexp = join("|", map quotemeta($_), @commands); if (length($host) == 0) { if ($file) { print(STDERR "Too few arguments: file name required\n"); exit(1); } else { print(STDERR "Too few arguments: host name required\n"); exit(1); } } open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n"; select(OUTPUT); # make OUTPUT unbuffered if debugging if ($debug) { $| = 1; } if ($file) { print STDERR "opening file $host\n" if ($debug); print STDOUT "opening file $host\n" if ($log); open(INPUT,"<$host") || die "open failed for $host: $!\n"; } else { print STDERR "executing bntlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing bntlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "bntlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "bntlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "bntlogin failed for $host: $!\n"; } else { open(INPUT,"bntlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; # We removed the $ from exit here as when using ssh, we get # disconnected sharpish and don't see a newline it seems if (/[>#]\s?exit/) { $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host bntlogin error: $_"); print STDERR ("$host bntlogin error: $_") if ($debug); $clean_run = 0; last; } while (/[>#]\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#>]+[#>])/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; print STDERR ("PROMPT MATCH: $prompt\n") if ($debug); } print STDERR ("HIT COMMAND:$_") if ($debug); if (! defined($commands{$cmd})) { print STDERR "$host: found unexpected command - \"$cmd\"\n"; $clean_run = 0; last TOP; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$clean_run || !$found_end) { if (scalar(%commands)) { printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands))); printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug); } if (!$clean_run || !$found_end) { print STDOUT "$host: End of run not found\n"; print STDERR "$host: End of run not found\n" if ($debug); system("/usr/bin/tail -1 $host.new"); } unlink "$host.new" if (! $debug); } From campee at gmail.com Mon Feb 24 23:27:34 2014 From: campee at gmail.com (Eric) Date: Mon, 24 Feb 2014 15:27:34 -0800 Subject: [rancid] Suppress disk space usage output In-Reply-To: References: Message-ID: I tried looking in http://www.shrubbery.net/rancid/FAQ and couldn't find anything relevant. Can you tell me the name of the file that I should be looking at editing or point me to a URL that could help? Thanks. On Thu, Feb 20, 2014 at 5:08 PM, Hughes, Doug < Douglas.Hughes at deshawresearch.com> wrote: > You need to edit the brocade rancid file, find the stanza where it > collects that config information (usually preceeded by a series of ! or > other comment characters near the beginning of the section in the output > that gives you a clue, you can search for this in the rancid file.) > > > > Then, where you see the rest of the 'next if' lines add another one that > matches the line you want to elide from the output. It's pretty easy. (see > the archives for more examples of this. It's an FAQ) > > > > > > *From:* rancid-discuss-bounces at shrubbery.net [mailto: > rancid-discuss-bounces at shrubbery.net] *On Behalf Of *Eric > *Sent:* Thursday, February 20, 2014 2:46 PM > *To:* rancid-discuss at shrubbery.net > *Subject:* [rancid] Suppress disk space usage output > > > > Rancid is notifying me every night that my Brocade load balancers have > slightly less free space available due to their local system log increasing > in size. Is there a way to tell it to not check for disk usage or suppress > this output? Thanks. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From barry at vibecommunications.co.nz Wed Feb 26 08:48:19 2014 From: barry at vibecommunications.co.nz (Barry Murphy) Date: Wed, 26 Feb 2014 08:48:19 +0000 Subject: [rancid] Trying to get a vendortable working but it just won't work for alurancid Message-ID: Hey guys, spent the last few hours trying to get this to work but it continues to try clogin rather than alulogin / alurancid like it should: I have edited rancid-fe and added: 'alcatel' => 'alurancid', rancid at watcher:~/bin$ more ../data/vibecore-alcatel/router.db mdr-tr1:alcatel:up As you can see its using clogin commands rather than the alcatel commands which are in alurancid / alulogin. I obtained the ALU scripts from https://code.google.com/p/alurancid/ rancid at watcher:~/bin$ env NOPIPE=y PATH=${PATH}:/home/rancid/bin rancid -d mdr-tr1 executing clogin -t 90 -c"admin show version;show version;show redundancy secondary;show idprom backplane;show install active;admin show env all;show env all;show rsp chassis-info;show gsr chassis;show diag chassis-info;show boot;admin show variables boot;show variables boot;dir /all nvram:;dir /all slot0:;dir /all disk0:;dir /all slot1:;dir /all disk1:;dir /all slot2:;dir /all disk2:;dir /all harddisk:;dir /all harddiska:;dir /all harddiskb:;dir /all sup-bootflash:;dir /all sup-microcode:;dir /all slavenvram:;dir /all slavebootflash:;dir /all slaveslot0:;dir /all slavedisk0:;dir /all slaveslot1:;dir /all slavedisk1:;dir /all slaveslot2:;dir /all slavedisk2:;dir /all slavesup-bootflash:;dir /all sec-nvram:;dir /all sec-bootflash:;dir /all sec-slot0:;dir /all sec-disk0:;dir /all sec-slot1:;dir /all sec-disk1:;dir /all sec-slot2:;dir /all sec-disk2:;show controllers;show controllers cbus;show diagbus;admin show diag;show diag;show module;show spe version;show c7200;show inventory raw;show vtp status;show vlan;show vlan-switch;show debug;more system:running-config;show running-config;write term" mdr-tr1 mdr-tr1 clogin error: Error: Bad command. mdr-tr1 clogin error: Error: Bad command. mdr-tr1: missed cmd(s): admin show diag,dir /all slavedisk2:,show rsp chassis-info,dir /all sec-slot2:,show diag,dir /all disk1:,show gsr chassis,dir /all sec-nvram:,show diag chassis-info,dir /all disk2:,dir /all sec-bootflash:,show spe version,dir /all slaveslot2:,dir /all disk0:,show install active,dir /all slaveslot0:,dir /all sec-slot1:,dir /all harddiska:,dir /all slavenvram:,dir /all sec-disk2:,dir /all slavesup-bootflash:,dir /all sec-disk0:,dir /all harddiskb:,show variables boot,show boot,show inventory raw,dir /all slavedisk1:,show env all,show module,admin show env all,show controllers,admin show version,show diagbus,more system:running-config,dir /all slavedisk0:,show debug,show idprom backplane,dir /all sec-slot0:,dir /all sec-disk1:,write term,show vtp status,dir /all sup-bootflash:,dir /all slot2:,dir /all harddisk:,dir /all slot0:,dir /all sup-microcode:,show vlan,dir /all slavebootflash:,show controllers cbus,dir /all slaveslot1:,dir /all nvram:,show version,show vlan-switch,admin show variables boot,show redundancy secondary,show running-config,show c7200,dir /all slot1: mdr-tr1: missed cmd(s): admin show diag,dir /all slavedisk2:,show rsp chassis-info,dir /all sec-slot2:,show diag,dir /all disk1:,show gsr chassis,dir /all sec-nvram:,show diag chassis-info,dir /all disk2:,dir /all sec-bootflash:,show spe version,dir /all slaveslot2:,dir /all disk0:,show install active,dir /all slaveslot0:,dir /all sec-slot1:,dir /all harddiska:,dir /all slavenvram:,dir /all sec-disk2:,dir /all slavesup-bootflash:,dir /all sec-disk0:,dir /all harddiskb:,show variables boot,show boot,show inventory raw,dir /all slavedisk1:,show env all,show module,admin show env all,show controllers,admin show version,show diagbus,more system:running-config,dir /all slavedisk0:,show debug,show idprom backplane,dir /all sec-slot0:,dir /all sec-disk1:,write term,show vtp status,dir /all sup-bootflash:,dir /all slot2:,dir /all harddisk:,dir /all slot0:,dir /all sup-microcode:,show vlan,dir /all slavebootflash:,show controllers cbus,dir /all slaveslot1:,dir /all nvram:,show version,show vlan-switch,admin show variables boot,show redundancy secondary,show running-config,show c7200,dir /all slot1: mdr-tr1: End of run not found mdr-tr1: End of run not found Any help would be much appreciated. Regards -- Barry Murphy | barry at vibecommunications.co.nz | Chief Operating Officer | Vibe Communications Limited | Mobile: 0274 909 712 Unit A7, 1 Beresford Square, Auckland Central 1010 | PO Box 68707, Newton, Auckland 1145 | Phone: 09 222 0000 Ext 6 | 0800 842326 | Fax: 0800 842327 WEB: http://www.vibecommunications.co.nz Peering: http://as45177.peeringdb.com/ [Description: Description: Description: cid:image001.png at 01CB9D57.2FAB9280] "Solution specialists achieving great results within economic realities" This communication, including any attachments, is confidential. If you are not the intended recipient, you should not read it - please contact me immediately, destroy it, and do not copy or use any part of this communication or disclose anything about it. Thank you. Please note that this communication does not designate an information system for the purposes of the Electronic Transactions Act 2002. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: AFF6A554-E76E-45C9-B432-32799E9B13F6[122].png Type: image/png Size: 5072 bytes Desc: AFF6A554-E76E-45C9-B432-32799E9B13F6[122].png URL: From alan.mckinnon at gmail.com Wed Feb 26 14:57:21 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Wed, 26 Feb 2014 16:57:21 +0200 Subject: [rancid] Trying to get a vendortable working but it just won't work for alurancid In-Reply-To: References: Message-ID: <530E00D1.6040606@gmail.com> You are telling it to run the rancid script which runs clogin. "rancid" is not the controller script that calls rancid-fe and decides what to use, it really is the IOS parser. An unfortunate legacy name choice, but it is the way things are. Do this: rancid-run -r To debug the alcatel parser itself, you must do "alurancid -d " On 26/02/2014 10:48, Barry Murphy wrote: > Hey guys, spent the last few hours trying to get this to work but it > continues to try clogin rather than alulogin / alurancid like it should: > > I have edited rancid-fe and added: > 'alcatel' => 'alurancid', > > rancid at watcher:~/bin$ more ../data/vibecore-alcatel/router.db > mdr-tr1:alcatel:up > > As you can see its using clogin commands rather than the alcatel > commands which are in alurancid / alulogin. > > I obtained the ALU scripts from https://code.google.com/p/alurancid/ > > rancid at watcher:~/bin$ env NOPIPE=y PATH=${PATH}:/home/rancid/bin rancid > -d mdr-tr1 > executing clogin -t 90 -c"admin show version;show version;show > redundancy secondary;show idprom backplane;show install active;admin > show env all;show env all;show rsp chassis-info;show gsr chassis;show > diag chassis-info;show boot;admin show variables boot;show variables > boot;dir /all nvram:;dir /all slot0:;dir /all disk0:;dir /all slot1:;dir > /all disk1:;dir /all slot2:;dir /all disk2:;dir /all harddisk:;dir /all > harddiska:;dir /all harddiskb:;dir /all sup-bootflash:;dir /all > sup-microcode:;dir /all slavenvram:;dir /all slavebootflash:;dir /all > slaveslot0:;dir /all slavedisk0:;dir /all slaveslot1:;dir /all > slavedisk1:;dir /all slaveslot2:;dir /all slavedisk2:;dir /all > slavesup-bootflash:;dir /all sec-nvram:;dir /all sec-bootflash:;dir /all > sec-slot0:;dir /all sec-disk0:;dir /all sec-slot1:;dir /all > sec-disk1:;dir /all sec-slot2:;dir /all sec-disk2:;show controllers;show > controllers cbus;show diagbus;admin show diag;show diag;show module;show > spe version;show c7200;show inventory raw;show vtp status;show vlan;show > vlan-switch;show debug;more system:running-config;show > running-config;write term" mdr-tr1 > mdr-tr1 clogin error: Error: Bad command. > mdr-tr1 clogin error: Error: Bad command. > mdr-tr1: missed cmd(s): admin show diag,dir /all slavedisk2:,show rsp > chassis-info,dir /all sec-slot2:,show diag,dir /all disk1:,show gsr > chassis,dir /all sec-nvram:,show diag chassis-info,dir /all disk2:,dir > /all sec-bootflash:,show spe version,dir /all slaveslot2:,dir /all > disk0:,show install active,dir /all slaveslot0:,dir /all sec-slot1:,dir > /all harddiska:,dir /all slavenvram:,dir /all sec-disk2:,dir /all > slavesup-bootflash:,dir /all sec-disk0:,dir /all harddiskb:,show > variables boot,show boot,show inventory raw,dir /all slavedisk1:,show > env all,show module,admin show env all,show controllers,admin show > version,show diagbus,more system:running-config,dir /all > slavedisk0:,show debug,show idprom backplane,dir /all sec-slot0:,dir > /all sec-disk1:,write term,show vtp status,dir /all sup-bootflash:,dir > /all slot2:,dir /all harddisk:,dir /all slot0:,dir /all > sup-microcode:,show vlan,dir /all slavebootflash:,show controllers > cbus,dir /all slaveslot1:,dir /all nvram:,show version,show > vlan-switch,admin show variables boot,show redundancy secondary,show > running-config,show c7200,dir /all slot1: > mdr-tr1: missed cmd(s): admin show diag,dir /all slavedisk2:,show rsp > chassis-info,dir /all sec-slot2:,show diag,dir /all disk1:,show gsr > chassis,dir /all sec-nvram:,show diag chassis-info,dir /all disk2:,dir > /all sec-bootflash:,show spe version,dir /all slaveslot2:,dir /all > disk0:,show install active,dir /all slaveslot0:,dir /all sec-slot1:,dir > /all harddiska:,dir /all slavenvram:,dir /all sec-disk2:,dir /all > slavesup-bootflash:,dir /all sec-disk0:,dir /all harddiskb:,show > variables boot,show boot,show inventory raw,dir /all slavedisk1:,show > env all,show module,admin show env all,show controllers,admin show > version,show diagbus,more system:running-config,dir /all > slavedisk0:,show debug,show idprom backplane,dir /all sec-slot0:,dir > /all sec-disk1:,write term,show vtp status,dir /all sup-bootflash:,dir > /all slot2:,dir /all harddisk:,dir /all slot0:,dir /all > sup-microcode:,show vlan,dir /all slavebootflash:,show controllers > cbus,dir /all slaveslot1:,dir /all nvram:,show version,show > vlan-switch,admin show variables boot,show redundancy secondary,show > running-config,show c7200,dir /all slot1: > mdr-tr1: End of run not found > mdr-tr1: End of run not found > > Any help would be much appreciated. > > Regards > > -- > > *Barry Murphy* | barry at vibecommunications.co.nz > | Chief Operating Officer > | *Vibe Communications Limited *| Mobile: 0274 909 712 > > Unit A7, 1 Beresford Square, Auckland Central 1010 | PO Box 68707, > Newton, Auckland 1145 | Phone: 09 222 0000 Ext 6 | 0800 842326 | Fax: > 0800 842327 > > WEB: http://www.vibecommunications.co.nz > > Peering: http://as45177.peeringdb.com/ > > > Description: Description: Description: cid:image001.png at 01CB9D57.2FAB9280 > > /?Solution specialists achieving great results within economic realities?/ > > / > / > > /This communication, including any attachments, is confidential. If you > are not the intended recipient, you should not read it - please contact > me immediately, destroy it, and do not copy or use any part of this > communication or disclose anything about it. Thank you. Please note that > this communication does not designate an information system for the > purposes of the Electronic Transactions Act 2002./ > > > > _______________________________________________ > Rancid-discuss mailing list > Rancid-discuss at shrubbery.net > http://www.shrubbery.net/mailman/listinfo/rancid-discuss > -- Alan McKinnon alan.mckinnon at gmail.com From barry at vibecommunications.co.nz Wed Feb 26 20:07:18 2014 From: barry at vibecommunications.co.nz (Barry Murphy) Date: Wed, 26 Feb 2014 20:07:18 +0000 Subject: [rancid] Trying to get a vendortable working but it just won't work for alurancid In-Reply-To: <530E00D1.6040606@gmail.com> Message-ID: Hi, Thanks for that, it was getting late in the day and I was starting to test with the wrong command :) I executed: rancid at watcher:~/bin$ env NOPIPE=y PATH=${PATH}:/home/rancid/bin alurancid -d mdr-tr1 And received 2 files rancid at watcher:~/bin$ ls -al mdr-tr1.* -rw-r--r-- 1 rancid rancid 29658 2014-02-27 09:02 mdr-tr1.new -rw-r--r-- 1 rancid rancid 31293 2014-02-27 09:02 mdr-tr1.raw The files look correct however my rancid is still not generating files: rancid at watcher:~$ ls data/vibecore-alcatel/configs/ CVS I have configured my router.db as follows: rancid at watcher:~$ cat data/vibecore-alcatel/router.db mdr-tr1:alcatel:up mdr-tr2:alcatel:up sy3-tr1:alcatel:up sy3-tr2:alcatel:up sv1-tr1:alcatel:up sv1-tr2:alcatel:up I have also configured .cloginrc correctly else the debug mode wouldn't know the login details for the routers. I have tried running: rancid at watcher:~/bin$ env NOPIPE=y PATH=${PATH}:/home/rancid/bin rancid-run -r mdr-tr1 rancid at watcher:~/bin$ However I don't see anything happen, when I pressed enter on the above command it immediately went to the next line. Any assistance would be great. Thanks -- Barry Murphy | barry at vibecommunications.co.nz | Chief Operating Officer | Vibe Communications Limited | Mobile: 0274 909 712 Unit A7, 1 Beresford Square, Auckland Central 1010 | PO Box 68707, Newton, Auckland 1145 | Phone: 09 222 0000 Ext 6 | 0800 842326 | Fax: 0800 842327 WEB: http://www.vibecommunications.co.nz Peering: http://as45177.peeringdb.com/ ?Solution specialists achieving great results within economic realities? This communication, including any attachments, is confidential. If you are not the intended recipient, you should not read it - please contact me immediately, destroy it, and do not copy or use any part of this communication or disclose anything about it. Thank you. Please note that this communication does not designate an information system for the purposes of the Electronic Transactions Act 2002. On 27/02/14 3:57 AM, "Alan McKinnon" wrote: >You are telling it to run the rancid script which runs clogin. > >"rancid" is not the controller script that calls rancid-fe and decides >what to use, it really is the IOS parser. An unfortunate legacy name >choice, but it is the way things are. > >Do this: > >rancid-run -r > >To debug the alcatel parser itself, you must do >"alurancid -d " > > > > >On 26/02/2014 10:48, Barry Murphy wrote: >> Hey guys, spent the last few hours trying to get this to work but it >> continues to try clogin rather than alulogin / alurancid like it should: >> >> I have edited rancid-fe and added: >> 'alcatel' => 'alurancid', >> >> rancid at watcher:~/bin$ more ../data/vibecore-alcatel/router.db >> mdr-tr1:alcatel:up >> >> As you can see its using clogin commands rather than the alcatel >> commands which are in alurancid / alulogin. >> >> I obtained the ALU scripts from https://code.google.com/p/alurancid/ >> >> rancid at watcher:~/bin$ env NOPIPE=y PATH=${PATH}:/home/rancid/bin rancid >> -d mdr-tr1 >> executing clogin -t 90 -c"admin show version;show version;show >> redundancy secondary;show idprom backplane;show install active;admin >> show env all;show env all;show rsp chassis-info;show gsr chassis;show >> diag chassis-info;show boot;admin show variables boot;show variables >> boot;dir /all nvram:;dir /all slot0:;dir /all disk0:;dir /all slot1:;dir >> /all disk1:;dir /all slot2:;dir /all disk2:;dir /all harddisk:;dir /all >> harddiska:;dir /all harddiskb:;dir /all sup-bootflash:;dir /all >> sup-microcode:;dir /all slavenvram:;dir /all slavebootflash:;dir /all >> slaveslot0:;dir /all slavedisk0:;dir /all slaveslot1:;dir /all >> slavedisk1:;dir /all slaveslot2:;dir /all slavedisk2:;dir /all >> slavesup-bootflash:;dir /all sec-nvram:;dir /all sec-bootflash:;dir /all >> sec-slot0:;dir /all sec-disk0:;dir /all sec-slot1:;dir /all >> sec-disk1:;dir /all sec-slot2:;dir /all sec-disk2:;show controllers;show >> controllers cbus;show diagbus;admin show diag;show diag;show module;show >> spe version;show c7200;show inventory raw;show vtp status;show vlan;show >> vlan-switch;show debug;more system:running-config;show >> running-config;write term" mdr-tr1 >> mdr-tr1 clogin error: Error: Bad command. >> mdr-tr1 clogin error: Error: Bad command. >> mdr-tr1: missed cmd(s): admin show diag,dir /all slavedisk2:,show rsp >> chassis-info,dir /all sec-slot2:,show diag,dir /all disk1:,show gsr >> chassis,dir /all sec-nvram:,show diag chassis-info,dir /all disk2:,dir >> /all sec-bootflash:,show spe version,dir /all slaveslot2:,dir /all >> disk0:,show install active,dir /all slaveslot0:,dir /all sec-slot1:,dir >> /all harddiska:,dir /all slavenvram:,dir /all sec-disk2:,dir /all >> slavesup-bootflash:,dir /all sec-disk0:,dir /all harddiskb:,show >> variables boot,show boot,show inventory raw,dir /all slavedisk1:,show >> env all,show module,admin show env all,show controllers,admin show >> version,show diagbus,more system:running-config,dir /all >> slavedisk0:,show debug,show idprom backplane,dir /all sec-slot0:,dir >> /all sec-disk1:,write term,show vtp status,dir /all sup-bootflash:,dir >> /all slot2:,dir /all harddisk:,dir /all slot0:,dir /all >> sup-microcode:,show vlan,dir /all slavebootflash:,show controllers >> cbus,dir /all slaveslot1:,dir /all nvram:,show version,show >> vlan-switch,admin show variables boot,show redundancy secondary,show >> running-config,show c7200,dir /all slot1: >> mdr-tr1: missed cmd(s): admin show diag,dir /all slavedisk2:,show rsp >> chassis-info,dir /all sec-slot2:,show diag,dir /all disk1:,show gsr >> chassis,dir /all sec-nvram:,show diag chassis-info,dir /all disk2:,dir >> /all sec-bootflash:,show spe version,dir /all slaveslot2:,dir /all >> disk0:,show install active,dir /all slaveslot0:,dir /all sec-slot1:,dir >> /all harddiska:,dir /all slavenvram:,dir /all sec-disk2:,dir /all >> slavesup-bootflash:,dir /all sec-disk0:,dir /all harddiskb:,show >> variables boot,show boot,show inventory raw,dir /all slavedisk1:,show >> env all,show module,admin show env all,show controllers,admin show >> version,show diagbus,more system:running-config,dir /all >> slavedisk0:,show debug,show idprom backplane,dir /all sec-slot0:,dir >> /all sec-disk1:,write term,show vtp status,dir /all sup-bootflash:,dir >> /all slot2:,dir /all harddisk:,dir /all slot0:,dir /all >> sup-microcode:,show vlan,dir /all slavebootflash:,show controllers >> cbus,dir /all slaveslot1:,dir /all nvram:,show version,show >> vlan-switch,admin show variables boot,show redundancy secondary,show >> running-config,show c7200,dir /all slot1: >> mdr-tr1: End of run not found >> mdr-tr1: End of run not found >> >> Any help would be much appreciated. >> >> Regards >> >> -- >> >> *Barry Murphy* | barry at vibecommunications.co.nz >> | Chief Operating Officer >> | *Vibe Communications Limited *| Mobile: 0274 909 712 >> >> Unit A7, 1 Beresford Square, Auckland Central 1010 | PO Box 68707, >> Newton, Auckland 1145 | Phone: 09 222 0000 Ext 6 | 0800 842326 | Fax: >> 0800 842327 >> >> WEB: http://www.vibecommunications.co.nz >> >> Peering: http://as45177.peeringdb.com/ >> >> >> Description: Description: Description: >>cid:image001.png at 01CB9D57.2FAB9280 >> >> /?Solution specialists achieving great results within economic >>realities?/ >> >> / >> / >> >> /This communication, including any attachments, is confidential. If you >> are not the intended recipient, you should not read it - please contact >> me immediately, destroy it, and do not copy or use any part of this >> communication or disclose anything about it. Thank you. Please note that >> this communication does not designate an information system for the >> purposes of the Electronic Transactions Act 2002./ >> >> >> >> _______________________________________________ >> Rancid-discuss mailing list >> Rancid-discuss at shrubbery.net >> http://www.shrubbery.net/mailman/listinfo/rancid-discuss >> > > >-- >Alan McKinnon >alan.mckinnon at gmail.com > >_______________________________________________ >Rancid-discuss mailing list >Rancid-discuss at shrubbery.net >http://www.shrubbery.net/mailman/listinfo/rancid-discuss From alan.mckinnon at gmail.com Thu Feb 27 04:45:25 2014 From: alan.mckinnon at gmail.com (Alan McKinnon) Date: Thu, 27 Feb 2014 06:45:25 +0200 Subject: [rancid] Trying to get a vendortable working but it just won't work for alurancid In-Reply-To: References: Message-ID: <530EC2E5.3050606@gmail.com> On 26/02/2014 22:07, Barry Murphy wrote: > Hi, > > Thanks for that, it was getting late in the day and I was starting to test > with the wrong command :) > > I executed: > rancid at watcher:~/bin$ env NOPIPE=y PATH=${PATH}:/home/rancid/bin alurancid > -d mdr-tr1 > And received 2 files > > rancid at watcher:~/bin$ ls -al mdr-tr1.* > -rw-r--r-- 1 rancid rancid 29658 2014-02-27 09:02 mdr-tr1.new > -rw-r--r-- 1 rancid rancid 31293 2014-02-27 09:02 mdr-tr1.raw That's correct. Data was collected and processed > The files look correct however my rancid is still not generating files: > > rancid at watcher:~$ ls data/vibecore-alcatel/configs/ > CVS > > I have configured my router.db as follows: > > rancid at watcher:~$ cat data/vibecore-alcatel/router.db > mdr-tr1:alcatel:up > mdr-tr2:alcatel:up > sy3-tr1:alcatel:up > sy3-tr2:alcatel:up > sv1-tr1:alcatel:up > sv1-tr2:alcatel:up > > I have also configured .cloginrc correctly else the debug mode wouldn't > know the login details for the routers. > > > I have tried running: > rancid at watcher:~/bin$ env NOPIPE=y PATH=${PATH}:/home/rancid/bin > rancid-run -r mdr-tr1 > rancid at watcher:~/bin$ > > However I don't see anything happen, when I pressed enter on the above > command it immediately went to the next line. > > > Any assistance would be great. > > Thanks > What's in your logs for that last call to rancid-run? -- Alan McKinnon alan.mckinnon at gmail.com From Bertrand.Kurtzemann at stef.com Wed Feb 26 16:33:59 2014 From: Bertrand.Kurtzemann at stef.com (Bertrand Kurtzemann) Date: Wed, 26 Feb 2014 16:33:59 +0000 Subject: [rancid] rancid not writing configurations to /config/ file Message-ID: Hello, I installed some "5800AF-48G" and "5500-48G EI" Switches and I need to save the config in Rancid. Can you tell me where can I download the h3clogin and h3crancid files ?? Thanks a lot !! Cordialement, Kind regards, Mit freundlichen Gr??en, [Description?: 2012-STEF-signature] Bertrand Kurtzemann Service Informatique - Responsable EDI STEF Transport Direction R?gionale EST 108, rte de JOUY 57160 Moulins-L?s-Metz +33 3 87 56 52 23 (fax +33 3.87.169.630) +33 6 20 73 58 82 bertrand.kurtzemann at stef.com ? Avant d'imprimer ce mail, pensez ? l'environnement ! AVIS : Ce message (y compris toutes pièces jointes) peut contenir des informations privées, conafidentielles et est pour l'usage du(es) seul(s) destinataire(s). Si vous avez reçu ce message par erreur, merci d′en avertir l′expéditeur par retour d′email immediatement et de procéder à la destruction de l′ensemble des éléments reçus, dont vous ne devez garder aucune copie. Toute diffusion, utilisation ou copie de ce message ou des renseignements qu′il contient par une personne autre que le(les) destinataire(s) désigné(s) est interdite. STEF ne garantit pas l′intégrité de cette transmission et ne saurait etre tenu responsable du message, de son contenu, de toute modification ou falsification, déune interception ou de dégats à votre système. NOTICE : This e-mail (including any attachments) may contain information that is private, confidential or legally privileged information or material and is intended solely for the use of the addressee(s). If you receive this e-mail in error, please delete it from your system without copying it and immediately notify the sender(s) by reply e-mail. Any unauthorized use or disclosure of this message is strictly prohibited. STEF does not guarantee the integrity of this transmission and may therefore never be liable if the message is altered or falsified nor for any virus, interception or damage to your system. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image003.jpg Type: image/x-citrix-jpeg Size: 2566 bytes Desc: image003.jpg URL: From opensource at macht-blau.org Thu Feb 27 15:34:16 2014 From: opensource at macht-blau.org (C. Handel) Date: Thu, 27 Feb 2014 16:34:16 +0100 Subject: [rancid] rancid not writing configurations to /config/ file In-Reply-To: References: Message-ID: 2014-02-26 17:33 GMT+01:00 Bertrand Kurtzemann : > Hello, > > > > I installed some "5800AF-48G" and "5500-48G EI" Switches and I need to > save the config in Rancid. > > > > Can you tell me where can I download the h3clogin and h3crancid files ?? > https://sites.google.com/site/jrbinks/code/rancid/h3c Greetings Christoph -------------- next part -------------- An HTML attachment was scrubbed... URL: From heas at shrubbery.net Fri Feb 28 07:30:29 2014 From: heas at shrubbery.net (heasley) Date: Fri, 28 Feb 2014 07:30:29 +0000 Subject: [rancid] Possible buffering issue In-Reply-To: <3c2916c3286bb3b7dc0fbc2356818063@vjofn.tucs-beachin-obx-house.com> References: <3c2916c3286bb3b7dc0fbc2356818063@vjofn.tucs-beachin-obx-house.com> Message-ID: <20140228073029.GA13511@shrubbery.net> Thu, Feb 20, 2014 at 12:52:12PM -0500, Tuc: > Hi, > > We have an F5 that we are trying to capture the output from. We have a > modified version of the f5tmshrancid running. We're running into an > issue where we have a pretty huge "send" line for a ltm monitor https . > Its 5190 characters. We seem to be running into the issue where every > it seems to drop characters one run, get some/most back the next run. > Its pretty annoying to constantly get the emails about it. > > Any ideas how to resolve this? Should I be sticking a terminal length > in somewhere? what does the script use to login? i can only imagine a) old version of hpuifilter, b) its spitting out terminal manipulation control characters that are trashing the output. debug the latter with NOPIPE=YES and -d to the rancid script; then look at the output in the .raw file. if it has control characters, try using hpuifilter like hrancid does. From jethro.binks at strath.ac.uk Fri Feb 28 08:43:32 2014 From: jethro.binks at strath.ac.uk (Jethro R Binks) Date: Fri, 28 Feb 2014 08:43:32 +0000 (GMT) Subject: [rancid] rancid not writing configurations to /config/ file In-Reply-To: References: Message-ID: On Thu, 27 Feb 2014, C. Handel wrote: > 2014-02-26 17:33 GMT+01:00 Bertrand Kurtzemann >: > > I installed some "5800AF-48G" and "5500-48G EI" Switches and I need to > > save the config in Rancid. > > > > Can you tell me where can I download the h3clogin and h3crancid files ?? > > https://sites.google.com/site/jrbinks/code/rancid/h3c Thanks Christoph, I've attached later versions that will handle Comware 7 better. I'd sent these to a few correspondents for testing and feedback, although I don't think I got much back. But, they are working well for me so am likely to upload them anyway. Jethro. . . . . . . . . . . . . . . . . . . . . . . . . . Jethro R Binks, Network Manager, Information Services Directorate, University Of Strathclyde, Glasgow, UK The University of Strathclyde is a charitable body, registered in Scotland, number SC015263. -------------- next part -------------- #! /usr/local/bin/expect -- ## ## $Id: $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # h3clogin # # h3clogin/h3crancid covers the following product ranges: # # * 3Com SuperStack 4 (post-joint venture with Huawei) # * H3C # * HP Networking ('A' & some 'E' portfolio, post 2010 3Com acquitision) # # They may also work with some Huawei equipment. # # https://sites.google.com/site/jrbinks/code/rancid/h3c # # Set to 1 to enable some debugging, or pass "-d" on command line exp_internal 0 # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-r passphrase\] \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-x command-file\] \ \[-y ssh_cypher_type\] router \[router...\]\n" # env(CLOGIN) may contain: # x == do not set xterm banner or name # Password file set password_file $env(HOME)/.cloginrc # Default is to login to the router set do_command 0 set do_script 0 # The default is to automatically enable set avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 0 # The default is to look in the password file to find the passwords. This # tracks if we receive them on the command line. set do_passwd 1 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # set send_human {.1 .3 .7 .05 2} # spawn tty options set spawnopts {} # H3C: set the platform # Platform switching: # If we explcitly want to state the platform, then set default_platform. # If we want the script to do magic to try and work it out, then set it # to "". # We might also consider passing the platform as a command-line parameter, # or by reading it as a hint from .cloginrc. set default_platform "h3c" # H3C: some models don't like "3des"; specify "aes128-cbc" in .cloginrc set default_cyphertype "3des" # H3C: most H3C-derived models use "super" to elevate privileges # However MA5600 uses "enable" set enacmd "super" set enacmd_alt "enable" # H3C: command to exit from device set exitcmd "quit" # Find the user in the ENV, or use the unix userid. if {[info exists env(CISCO_USER)]} { set default_user $env(CISCO_USER) } elseif {[info exists env(USER)]} { set default_user $env(USER) } elseif {[info exists env(LOGNAME)]} { set default_user $env(LOGNAME) } else { # This uses "id" which I think is portable. At least it has existed # (without options) on all machines/OSes I've been on recently - # unlike whoami or id -nu. if [catch {exec id} reason] { send_error "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[info exists env(CLOGINRC)]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [regexp .\[uU\](.+) $arg ignore user]} { incr i set username [lindex $argv $i] } # VTY Password } -p* { if {! [regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [lindex $argv $i] } set do_passwd 0 # ssh passphrase } -r* { if {! [regexp .\[rR\](.+) $arg ignore passphrase]} { incr i set vapassphrase [lindex $argv $i] } # VTY Password } -v* { if {! [regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [lindex $argv $i] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { if {! [regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [lindex $argv $i] } # Environment variable to pass to -s scripts } -E* { if {[regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [lindex $argv $i] } set do_enapasswd 0 # Command to run. } -c* { if {! [regexp .\[cC\](.+) $arg ignore command]} { incr i set command [lindex $argv $i] } set do_command 1 # Expect script to run. } -s* { if {! [regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [lindex $argv $i] } if { ! [file readable $sfile] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [lindex $argv $i] } # alternate cloginrc file } -f* { if {! [regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [lindex $argv $i] } # Timeout } -t* { if {! [regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [lindex $argv $i] } # Command file } -x* { if {! [regexp .\[xX\](.+) $arg ignore cmd_file]} { incr i set cmd_file [lindex $argv $i] } if [catch {set cmd_fd [open $cmd_file r]} reason] { send_user "\nError: $reason\n" exit 1 } set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] set do_command 1 # Do we enable? } -noenable { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $usage" } # Only be quiet if we are running a script (it can log its output # on its own) if { $do_script } { log_user 0 } else { log_user 1 } # # Done configuration/variable setting. Now run with it... # # Sets Xterm title if interactive...if its an xterm and the user cares proc label { host } { global env # if CLOGIN has an 'x' in it, don't set the xterm name/banner if [info exists env(CLOGIN)] { if {[string first "x" $env(CLOGIN)] != -1} { return } } # take host from ENV(TERM) if [info exists env(TERM)] { if [regexp \^(xterm|vs) $env(TERM) ignore] { send_user "\033]1;[lindex [split $host "."] 0]\a" send_user "\033]2;$host\a" } } } # This is a helper function to make the password file easier to # maintain. Using this the password file has the form: # add password sl* pete cow # add password at* steve # add password * hanky-pie proc add {var args} { global int_$var ; lappend int_$var $args} proc include {args} { global env regsub -all "(^{|}$)" $args {} args if { [regexp "^/" $args ignore] == 0 } { set args $env(HOME)/$args } source_password_file $args } proc find {var router} { upvar int_$var list if { [info exists list] } { foreach line $list { if { [string match [lindex $line 0] $router] } { return [lrange $line 1 end] } } } return {} } # Loads the password file. Note that as this file is tcl, and that # it is sourced, the user better know what to put in there, as it # could install more than just password info... I will assume however, # that a "bad guy" could just as easy put such code in the clogin # script, so I will leave .cloginrc as just an extention of that script proc source_password_file { password_file } { global env if { ! [file exists $password_file] } { send_user "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [catch {source $password_file} reason] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure, -1 if rsh was used successfully proc login { router user userpswd passwd enapasswd cmethod cyphertype identfile } { global command spawn_id in_proc do_command do_script platform passphrase global prompt prompt_match u_prompt p_prompt e_prompt sshcmd spawnopts set in_proc 1 set uprompt_seen 0 # try each of the connection methods in $cmethod until one is successful set progs [llength $cmethod] foreach prog [lrange $cmethod 0 end] { incr progs -1 if [string match "telnet*" $prog] { regexp {telnet(:([^[:space:]]+))*} $prog methcmd suffix port if {"$port" == ""} { #set retval [catch {spawn telnet $router} reason] set cmd "telnet $router" } else { #set retval [catch {spawn telnet $router $port} reason] set cmd "telnet $router $port" } set retval [catch {eval spawn $spawnopts [split $cmd { }]} reason] if { $retval } { send_user "\nError: telnet failed: $reason\n" return 1 } } elseif [string match "ssh*" $prog] { # ssh to the router & try to login with or without an identfile. regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } if {"$identfile" != ""} { set cmd "$cmd -i $identfile" } set retval [catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { if { ! $do_command } { if { [llength $cmethod] == 1 } { send_user "\nError: rsh is an invalid method for -x and " send_user "interactive logins\n" } if { $progs == 0 } { return 1 } continue; } set commands [split $command \;] set num_commands [llength $commands] set rshfail 0 for {set i 0} {$i < $num_commands && !$rshfail} { incr i} { log_user 0 set retval [catch {spawn rsh $user@$router [lindex $commands $i] } reason] if { $retval } { send_user "\nError: rsh failed: $reason\n" log_user 1; return 1 } send_user "$router# [lindex $commands $i]\n" # rcmd does not get a pager and no prompts, so we just have to # look for failures & lines. expect { "Connection refused" { catch {close}; catch {wait}; send_user "\nError: Connection\ Refused ($prog): $router\n" set rshfail 1 } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; send_user "\nError: Connection\ closed ($prog): $router\n" set rshfail 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable:\ $router\n" set rshfail 1 } "No address associated with" { catch {close}; catch {wait}; send_user "\nError: Unknown host\ $router\n" set rshfail 1 } -re "\b+" { exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } timeout { catch {close}; catch {wait}; send_user "\nError: TIMEOUT reached\n" set rshfail 1 } eof { catch {close}; catch {wait}; } } log_user 1 } if { $rshfail } { if { !$progs } { return 1 } else { continue } } # fake the end of the session for rancid. send_user "$router# exit\n" # return rsh "success" return -1 } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "^<-+ More -+>\[^\n\r]*" { # ASA will use the pager for long banners send " "; exp_continue } -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } "Host is unreachable" { send_user "\nError: Host Unreachable: $router\n"; catch {close}; catch {wait}; return 1 } "No address associated with name" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes\/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes\/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes\/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Press any key to continue" { # send_user "Pressing the ANY key\n" send "\r" exp_continue } -re "Enter Selection: " { # Catalyst 1900s have some lame menu. Enter # K to reach a command-line. send "K\r" exp_continue } -re "Last login:" { exp_continue } -re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } -re "Enter passphrase.*: " { # sleep briefly to allow time for stty -echo sleep .3 send -- "$passphrase\r" exp_continue } -re "$u_prompt" { send -- "$user\r" set uprompt_seen 1 exp_continue } -re "$p_prompt" { sleep 1 if {$uprompt_seen == 1} { send -- "$userpswd\r" } else { send -- "$passwd\r" } exp_continue } -re "$prompt" { set prompt_match $expect_out(0,string); break; } "Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; catch {wait}; return 1 } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global do_saveconfig in_proc global prompt u_prompt e_prompt global enacmd enacmd_alt set in_proc 1 # Try and determine a bit more about this device to modify behaviour. # We are careful to use "dis version " rather than the full length # "display version" to prevent h3crancid matching it. # (Thx Andrea Gabellini) send -h "dis version\r" expect { -re "\{ .* \}:" { send -h -- "\r"; exp_continue } "VERSION : MA5600" { set enacmd $enacmd_alt; exp_continue } -re $prompt {} } send -h "$enacmd\r" expect { -re "Please input the password to change the privilege level, press CTRL_C to abort.\n" { exp_continue } -re "$u_prompt" { send -h -- "$enauser\r"; exp_continue } -re "$e_prompt" { send -h -- "$enapasswd\r"; exp_continue } -re ">" { set prompt ">" } -re "#" { set prompt "#" } # MA5600 "% Password is not set." { # H3C send_user "\nError: No 'super' password set for device\n" return 1 } "% Authenticate failed." { # H3C send_user "\nError: Check your enable password for 'super'\n" return 1 } # ciscoisms: # "#" { set prompt "#" } # "(enable)" { set prompt "> \\(enable\\) " } # -re "(denied|Sorry|Incorrect)" { # # % Access denied - from local auth and poss. others # send_user "\nError: Check your Enable passwd\n"; # return 1 # } # "% Error in authentication" { # send_user "\nError: Check your Enable passwd\n" # return 1 # } # "% Bad passwords" { # send_user "\nError: Check your Enable passwd\n" # return 1 # } } # We set the prompt variable (above) so script files don't need # to know what it is. set in_proc 0 return 0 } # Run commands given on the command line. proc run_commands { prompt command } { global do_saveconfig in_proc platform global exitcmd set in_proc 1 # clogin has this beast: #regsub -all {^(.{1,11}).*([#>])$} $prompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt # If platform H3C: # Note that if the "system-view" command is sent to go into configuration # mode, the prompt changes from to [prompt], so we need to ensure # that $reprompt will handle either. send_user -- "Prompt: $prompt\n" # Strip inital and leading <> regsub -all {^<} $prompt {} prompt regsub -all {>\a?$} $prompt {} prompt #send_user -- "Prompt: $prompt\n" # Escape special characters to be treated as literals regsub -all {[][)(]} $prompt {\\&} prompt # Prefix and suffix with regexps to match the sets <[ and ]> set xlist [list {[<[]} $prompt {.*[]>]\a?}] set reprompt [join $xlist ""] send_user -- "REPrompt: $reprompt\n" expect { -re ($reprompt|$prompt) { } -re "\[\n\r]+" { exp_continue } } # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # The pager can not be turned off on some 3Com/H3C, so we have to look # for the "More" prompt. for {set i 0} {$i < $num_commands} { incr i} { send -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "\b+" { exp_continue } -re "^\[^\n\r *]*($reprompt|$prompt)" { send_user -- "$expect_out(buffer)" } -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } -re "^ {0,2}-+ More .*-+.*\[^\n\r]*" { # H3C pager prompt sleep 0.1 send " " exp_continue } -re "^---- More ----\[^\n\r]*" { # Comware7 pager prompt sleep 0.1 send " " exp_continue } } } # clogin has introduced this change to the "\[\n\r]+" clause above in r2313 # June2011: # "trying to make sure it pulls full lines each time." # -re "\[^\r\n]*\[\n\r]+" log_user 1 send -h "$exitcmd\r" expect { # -re "^\[^\n\r *]*$reprompt" { # # H3C: # # they return to non-enabled # # mode with "exit" from # # enabled mode. # send -h "$exitcmd\r" # exp_continue; # } # TODO: we will need to do this too: # "Do you wish to save your configuration changes" { # send -h "n\r" # exp_continue # } -re "\[\n\r]+" { exp_continue } # variant from hwlogin: -re "\[^\n\r *]Note:" { return 0 } timeout { catch {close}; catch {wait}; return 0 } eof { return 0 } } set in_proc 0 } # # For each router... (this is main loop) # source_password_file $password_file set in_proc 0 set exitval 0 set prompt_match "" set enable 0 # if we have dont have a tty, we need some additional terminal settings if [catch {stty} reason] { # no tty, ie: cron set spawnopts "-nottycopy" set stty_init "cols 132" } foreach router [lrange $argv $i end] { set router [string tolower $router] # attempt at platform switching. set platform "" send_user -- "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Default prompt. #set prompt "(>|#| \\(enable\\))" # H3C: Could we be logged in already in a privilged ("super") mode, # with the "[....]" prompt? If so, then this might be: #set prompt "(>|])\a?" set prompt ">\a?" # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user -- "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user -- "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [find user $router] ""] if { "$ruser" == "" } { set ruser $default_user } } # Figure out username's password (if different from the vty password) if {[info exists userpasswd]} { # command line username set userpswd $userpasswd } else { set userpswd [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name|User|User name):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd|Enter password for \[^ :]+):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # Figure out identity file to use set identfile [join [lindex [find identity $router] 0] ""] # Figure out passphrase to use if {[info exists avpassphrase]} { set passphrase $avpassphrase } else { set passphrase [join [lindex [find passphrase $router] 0] ""] } if { ! [string length "$passphrase"]} { set passphrase $passwd } # Figure out cypher type if {[info exists cypher]} { # command line cypher type set cyphertype $cypher } else { set cyphertype [find cyphertype $router] if { "$cyphertype" == "" } { set cyphertype "$default_cyphertype" } } # Figure out connection method set cmethod [find method $router] if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype $identfile]} { incr exitval # if login failed or rsh was unsuccessful, move on to the next device continue } # Figure out the prompt. # H3C: this is what we used to have, now should be obsolete: # # Since autoenable is off by default, if we have it defined, it # # was done on the command line. If it is not specifically set on the # # command line, check the password file. # if $avautoenable { # set autoenable 1 # set enable 0 ## hwlogin: # #set prompt "(#| \\(enable\\))" # set prompt ">\a?" # } else { # set ae [find autoenable $router] # if { "$ae" == "1" } { # set autoenable 1 # set enable 0 ## hwlogin: # set prompt ">\a?" # } else { # set autoenable 0 # set enable $avenable # set prompt ">\a?" # } # } # # # look for noenable option in .cloginrc # if { [find noenable $router] == "1" } { # set enable 0 # } ## clogin has: ## # look for noenable option in .cloginrc ## if | [find noenable $router] != "" | { ## set enable 0 ## } # !! H3C does not appear to have a different prompt between lower # privilege and higher privilege users, so the following test is # not applicable # if { [regexp -- "(#| \\(enable\\))" $prompt_match junk] == 1 } { # set enable 0 # } else { if { $avenable == 0 } { set enable 0 } else { set ne [find noenable $router] set ae [find autoenable $router] if { "$ne" == "1" || "$ae" == "1" || $avautoenable } { set enable 0 } else { set enable 1 } } # } # Disable smart and interactive before send others commands # (MA5600) send -h "undo smart\r" expect -re $prompt {} send -h "undo interactive\r" expect -re $prompt {} if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[\(\)]" $junk {\\&} prompt; } } # H3C: # Disable log junk being sent to terminal: must be done before $enacmd # is run. It would be nice for this to be setable in .cloginrc send -h "undo terminal monitor\r" expect -re $prompt {} # Turn session paging off # Comware 5 only. # Comware 3 models have a screen-length command that only works on # a vty basis # clogin does this only within the do_script clause below, but I can't # see why you wouldn't want it here, covering do_command too send -h "screen-length disable\r" #expect -re $prompt {} if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval -------------- next part -------------- #! /usr/bin/perl5 ## ## $Id: $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # h3crancid # # h3clogin/h3crancid covers the following product ranges: # # * 3Com SuperStack 4 (from 'joint venture' with Huawei) # * H3C # * HP Networking ('A' & some 'E' portfolio, post-2010 3Com acquitision) # # They may also work with some Huawei equipment. # # https://sites.google.com/site/jrbinks/code/rancid/h3c # # Usage: h3crancid [-dltCV] [-f filename | hostname] # # You can modify the behaviour by changing the variables listed in # 'END-USER TWEAKS', below. # Notable changes from standard *rancid programs: # # * abstracted path to the 'tail' utility # * altered "cisco_cmds" to be "device_cmds" # * define and use $logincmd # * abstracted $rancid_type # TODO: # # It may be useful to pull common subroutines like the sorting ones into # a library for use by all the *rancid programs. # # abstract the comment-out char (i.e., '!' here and cisco, '#' on Juniper) # to a variable. # NOTES: # # * the dir commands need a user greater than at least level 1 on some # platforms ############################################################################ # END-USER TWEAKS # The login program to use. If no path is given, $PATH is searched: my $logincmd = "h3clogin"; #my $logincmd = "/usr/local/libexec/h3clogin"; # my $TAIL = "/usr/bin/tail"; # # Enable display of the FIB: my $display_fib = 1; # # Enable display of the routing table: my $display_iproutes = 1; # # Enable display of the vlans: my $display_vlan_all = 1; # # Enable display of STP root: my $display_stproot = 1; # # Enable display of transceiver interface: my $display_xcvr_int = 0; # END OF END-USER TWEAKS ############################################################################# my $rancid_type = 'h3c'; use Getopt::Std; getopts('dflt:CV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $clean_run = 0; $found_end = 0; #$timeo = 90; # login command timeout in seconds $timeo = 20; # login command timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode # This routine is used to print out the router configuration sub ProcessHistory { my($new_hist_tag,$new_command,$command_string, at string)=(@_); if((($new_hist_tag ne $hist_tag) || ($new_command ne $command)) && scalar %history) { print eval "$command \%history"; undef %history; } if (($new_hist_tag) && ($new_command) && ($command_string)) { if ($history{$command_string}) { $history{$command_string} = "$history{$command_string}@string"; } else { $history{$command_string} = "@string"; } } elsif (($new_hist_tag) && ($new_command)) { $history{++$#history} = "@string"; } else { print "@string"; } $hist_tag = $new_hist_tag; $command = $new_command; 1; } sub numerically { $a <=> $b; } # This is a sort routine that will sort numerically on the # keys of a hash as if it were a normal array. sub keynsort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $key (sort numerically keys(%lines)) { $sorted_lines[$i] = $lines{$key}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # keys of a hash as if it were a normal array. sub keysort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $key (sort keys(%lines)) { $sorted_lines[$i] = $lines{$key}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # values of a hash as if it were a normal array. sub valsort{ local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $key (sort values %lines) { $sorted_lines[$i] = $key; $i++; } @sorted_lines; } # This is a numerical sort routine (ascending). sub numsort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $num (sort {$a <=> $b} keys %lines) { $sorted_lines[$i] = $lines{$num}; $i++; } @sorted_lines; } # This is a sort routine that will sort on the # ip address when the ip address is anywhere in # the strings. sub ipsort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $addr (sort sortbyipaddr keys %lines) { $sorted_lines[$i] = $lines{$addr}; $i++; } @sorted_lines; } # These two routines will sort based upon IP addresses sub ipaddrval { my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#); $a[3] + 256 * ($a[2] + 256 * ($a[1] + 256 * $a[0])); } sub sortbyipaddr { &ipaddrval($a) <=> &ipaddrval($b); } # This is a sort routine that will sort on the # ip route when the ip route is anywhere in # the strings. sub iproutesort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $iproute (sort sortbyiproute keys %lines) { $sorted_lines[$i] = $lines{$iproute}; $i++; } @sorted_lines; } # These two routines will sort based upon IP route sub iprouteval { my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)$#); $a[4] + ($a[3] + 256 * ($a[2] + 256 * ($a[1] + 256 * $a[0]))); } sub sortbyiproute { &iprouteval($a) <=> &iprouteval($b); } sub filter_lines { my ($l) = (@_); # Filter out some ANSI crud as a result of us not being able to turn # off per-session terminal paging: #s/^\033\[42D +\033\[42D(.+)$/$1/; # hwlogin+mods: #s/\033\133\064\062\104\s*\033\133\064\062\104//g; $l =~ s/\033\133\064\062\104\s+\033\133\064\062\104//g; $l =~ s/\033\133\061\066\104\s+\033\133\061\066\104//g; $l =~ s/\033\133\064\062\104//g; $l =~ s/\033\133\061\062\104//g; $l =~ s/.*\[37D(.*)/$1/g; # MA5600 # Probably not needed: $l =~ s/\s*---- More ----\s*//; $l =~ s/^ //; # Comware7 $l =~ s/Synchronization is finished.//g; return $l; } sub DisplayFib { print STDERR " In DisplayFib: $_" if ($debug); chomp; # Display the command we're processing in the output: #s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; ProcessHistory("FIB","","","!\n! '$cmd':\n!\n"); while () { tr/\015//d; last if(/^\s*$prompt/); chomp; $_ = filter_lines($_); return(1) if ( /^\s+\^$/ || /% Too many parameters found at '\^' position/ || /% Unrecognized command found at '\^' position/ || /(% )?Wrong parameter found at '\^' position/ || /% Wrong device .+/ || /Permission denied\./ ); next if /^$/; next if /^Destination count: \d+ FIB entry count: \d+/; # Chop out some detail that changes over time (Comware 3): s/(\s+)TimeStamp\s+/$1/; # TimeStamp column heading ProcessHistory("FIB","","","! $_\n"); if ( m,Destination/Mask, ) { while () { tr/\015//d; last if(/^\s*$prompt/); chomp; $_ = filter_lines($_); # Chop out some detail that changes over time (Comware 3): s/(\s+)t\[\d+\]\s+/$1/; # TimeStamp data # "display fib" on comware7 shows host entries for things # learned via arp too. For a distribution router, that's all # the devices on subnets routed by it! # If we filter out all "UH" entries that are NOT InLoop, we # get acceptable output. # # So we want to keep: # # 0.0.0.0/32 127.0.0.1 UH InLoop0 Null # # but reject: # # 130.159.44.161/32 130.159.44.161 UH Vlan44 Null # # However I've a feeling that this is a problematic # solution, and some object to the notion that rancid # should be representing such potentially dynamic data in # the first place, which is why we created the # $display_fib flag. ($dest, $nexthop, $flag, $outint, $label) = split; next if ( $flag eq 'UH' && $outint !~ /InLoop/ ); ProcessHistory("FIB", "iproutesort", "$dest", "! $_\n"); } ProcessHistory("FIB", "", "", "!\n"); # return here to ensure that we don't keep swallowing the # next command's output by returning to the surrounding # while loop return(0); } } return(0); } sub DisplayIPRoutes { print STDERR " In DisplayIPRoutes: $_" if ($debug); chomp; # Display the command we're processing in the output: #s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; ProcessHistory("IPR","","","!\n! '$cmd':\n!\n"); while () { tr/\015//d; last if(/^\s*$prompt/); chomp; $_ = filter_lines($_); return(1) if ( /^\s+\^$/ || /% Too many parameters found at '\^' position/ || /% Unrecognized command found at '\^' position/ || /(% )?Wrong parameter found at '\^' position/ || /% Wrong device .+/ || /Permission denied\./ ); ProcessHistory("IPR","","","! $_\n"); if ( m,Destination/Mask, ) { my $lastkey = ""; my $lastspaces = ""; while () { tr/\015//d; last if(/^\s*$prompt/); chomp; $_ = filter_lines($_); # If the key is blank, indicating multiple nexthops for # a particular route, then we use the previous one if ( m/^\s+(.+)/ ) { $key = $lastkey; $line = $key . $lastspaces . $1; ProcessHistory("IPR", "iproutesort", "$key", "! $line\n"); # $lastkey and $lastspaces are retained in case # they are needed for an additional line } if ( m/^(\S+)(\s+).+/ ) { $key = $1; $line = $_; $spaces = $2; ProcessHistory("IPR", "iproutesort", "$key", "! $line\n"); $lastkey = $key; $lastspaces = $spaces; } } # This isn't quite right; for example, it messes up oddities like this: # ... # 130.159.2.84/30 OSPF 10 1010 10.159.2.53 Vlan3660 # 130.159.2.88/30 OSPF 10 1100 10.159.2.53 Vlan3660 # OSPF 10 1100 10.159.2.49 Vlan3661 # 130.159.2.92/30 OSPF 10 1015 10.159.2.53 Vlan3660 # ... ProcessHistory("IPR", "", "", "!\n"); # return here to ensure that we don't keep swallowing the # next command's output by returning to the surrounding # while loop return(0); } } return(0); } #sub DisplayTransInt { # print STDERR " In DisplayTransInt: $_" if ($debug); # # chomp; # # # Display the command we're processing in the output: # s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; # ProcessHistory("TRINT","","","! $_\n!\n"); # # while () { # tr/\015//d; # last if(/^\s*$prompt/); # chomp; # $_ = filter_lines($_); # return(1) if ( # /^\s+\^$/ || # /% Too many parameters found at '\^' position/ || # /% Unrecognized command found at '\^' position/ || # /(% )?Wrong parameter found at '\^' position/ || # /% Wrong device .+/ || # /Permission denied\./ # ); # # # ProcessHistory("TRINT","","","! $_\n"); # } # ProcessHistory("TRINT","","","!\n"); # return(0); #} #sub DisplayNTPStatus { # print STDERR " In DisplayNTPStatus: $_" if ($debug); # # chomp; # # # Display the command we're processing in the output: # s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; # ProcessHistory("NTP","","","! $_\n!\n"); # # while () { # tr/\015//d; # last if(/^\s*$prompt/); # chomp; # $_ = filter_lines($_); # return(1) if ( # /^\s+\^$/ || # /% Too many parameters found at '\^' position/ || # /% Unrecognized command found at '\^' position/ || # /(% ?)Wrong parameter found at '\^' position/ || # /% Wrong device .+/ || # /Permission denied\./ # ); # # next unless m/(Clock status|Clock stratum|Reference clock ID)/; # # ProcessHistory("NTP","","","! $_\n"); # } # ProcessHistory("NTP","","","!\n"); # return(0); #} ## This routine processes general output of "display" commands sub CommentOutput { print STDERR " In CommentOutput: $_" if ($debug); chomp; # Display the command we're processing in the output: #s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; #ProcessHistory("COMMENTS", "", "", "! $_\n!\n"); #(my $cmd = $_) =~ s/^[\[<].*?[\]>]\a?\s?(.*)/$1/g; ProcessHistory("COMMENTS", "", "", "!\n! '$cmd':\n!\n"); while () { tr/\015//d; # If we find the prompt, we're done # Ordinarily this matches from the start of the line, however # we've seen circumstances at least in Comware7 where the # prompt is preceded by whitespace, like so: # ^M^M ^Mdisplay boot-loader^M last if(/^\s*$prompt/); chomp; # filter out some junk $_ = filter_lines($_); # Some commands are not supported on some models or versions # of code. These lines simply remove the associated error # messages: return(1) if ( /^\s+\^$/ || /% Too many parameters found at '\^' position/ || /% Unrecognized command found at '\^' position/ || /(% )?Wrong parameter found at '\^' position/ || /% Wrong device .+/ || /Permission denied\./ ); # Now we skip or modify some lines from various commands to # remove irrelevant content, or to avoid insignificant diffs # 'display local-user': s/\s+Current AccessNum:.+$//; # 'display version': next if (/^(Uptime is \d|.+ [Uu]ptime is \d).+$/); # No longer necessary since skipping the whole Uptime line: # Mangle these lines: #s/(.*)[Uu]ptime.*.weeks.*.days*.*hours*.*minutes*(.*)/$1 $2/; #s/(.*)[Uu]ptime.*days*.*hours*.*minutes*(.*)/$1 $2/; # MSRs display a 'last reboot' time, but sometimes the seconds # vary by one or two (presumably internal rounding), so simply make # the last digit a fixed '0'. It would probably be safer to make # the last two digits a fixed '00'. # (Thx Alexander Belokopytov) s/(^Last reboot.+)\d$/${1}0/; # Remove filenames that are updated frequently if ( $cmd =~ /^dir / ) { next if ( /logfile\.log$/ || /private-data\.txt$/ || /.+ KB total \(.+ KB free/ || /.+ KB total \(.+ KB free/ || /\.trash/ ); } if ( $cmd eq 'display power' ) { next if (/^(\s+Input Power).+$/); } if ( $cmd eq 'display poe powersupply' ) { next if (/^(PSE Total Power Consumption|PSE Available Power|PSE Peak Value|PSE Average Value).+$/); } if ( $cmd eq 'display ntp-service status' ) { next unless m/(Clock status|Clock stratum|Reference clock ID)/i; } if ( $cmd eq 'display transceiver interface' ) { s/^(\S+ transceiver information:).+$/$1/; # filter random garbage s/^Error: The transceiver is absent.$/ No transceiver present./; s/^Error: The combo port is inactive.$/ Inactive combo port./; } # Add the processed lines to the output buffer: ProcessHistory("COMMENTS","","","! $_\n"); } # Add a blank comment line to the output buffer ProcessHistory("COMMENTS", "", "", "!\n"); return(0); } ## This routine processes a "display current" sub DisplayCurrent { print STDERR " In DisplayCurrent: $_" if ($debug); # We aren't chomping these lines while () { tr/\015//d; last if(/^\s*$prompt/); $_ = filter_lines($_); return(0) if ($found_end); # Filter out some sensitive data: if ( $filter_commstr && /^ ?(snmp-agent (usm-user|community (read|write)) )(\S+)/ ) { ProcessHistory("","","","! $1$'"); next; } if ( $filter_pwds >= 1 && /^ ?(password (?:simple|cipher) )(\S+)/ || /^ ?(super password( level \d)? (cipher|simple)) (\S+)/ || /^ ?(set authentication password (cipher|simple)) (\S+)/ || /^ ?(key (?:authentication|accounting) )(\S+)/ ) { ProcessHistory("","","","! $1$'"); next; } # Filter mac addresses dynamically added to config next if (/^ ?mac-address security.+$/); ProcessHistory("", "", "", "$_"); # end of config if (/^return/) { $found_end = 1; return(0); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main ## Not all commands are supported on all models and code versions ## Not all of these should necessarily be included @commandtable = ( # Commands relating to the operating system/version: {'display version' => 'CommentOutput'}, {'display boot-loader' => 'CommentOutput'}, {'display startup' => 'CommentOutput'}, {'dir /all' => 'CommentOutput'}, {'dir /all unit2>flash:/' => 'CommentOutput'}, {'dir /all slot2#flash:/' => 'CommentOutput'}, {'dir /all unit3>flash:/' => 'CommentOutput'}, {'dir /all slot3#flash:/' => 'CommentOutput'}, {'dir /all unit4>flash:/' => 'CommentOutput'}, {'dir /all slot4#flash:/' => 'CommentOutput'}, {'dir /all unit5>flash:/' => 'CommentOutput'}, {'dir /all slot5#flash:/' => 'CommentOutput'}, {'dir /all unit6>flash:/' => 'CommentOutput'}, {'dir /all slot6#flash:/' => 'CommentOutput'}, {'dir /all unit7>flash:/' => 'CommentOutput'}, {'dir /all slot7#flash:/' => 'CommentOutput'}, {'dir /all unit8>flash:/' => 'CommentOutput'}, {'dir /all slot8#flash:/' => 'CommentOutput'}, # Commands relating to the hardware: {'display device' => 'CommentOutput'}, {'display device manuinfo' => 'CommentOutput'}, {'display fan' => 'CommentOutput'}, {'display power' => 'CommentOutput'}, {'display poe powersupply' => 'CommentOutput'}, {'display poe temperature-protection' => 'CommentOutput'}, {'display transceiver interface' => 'CommentOutput'}, # Commands relating to authentication: {'display cluster' => 'CommentOutput'}, {'display domain' => 'CommentOutput'}, {'display local-user' => 'CommentOutput'}, {'display password-control' => 'CommentOutput'}, {'display password-control super' => 'CommentOutput'}, {'display ssh server status' => 'CommentOutput'}, # Commands relating to system state: {'display irf' => 'CommentOutput'}, {'display xrn-fabric' => 'CommentOutput'}, {'display ftm topology-database' => 'CommentOutput'}, {'display fib' => 'DisplayFib'}, {'display ip routing-table' => 'DisplayIPRoutes'}, {'display vlan all' => 'CommentOutput'}, {'display lacp sys' => 'CommentOutput'}, {'display link-aggregation summary' => 'CommentOutput'}, {'display link-aggregation verbose' => 'CommentOutput'}, {'display mirror all' => 'CommentOutput'}, {'display ntp-service status' => 'CommentOutput'}, {'display stp root' => 'CommentOutput'}, # And the system config itself: {'display current-configuration' => 'DisplayCurrent'}, ); # Remove some commands from the comman table if the user has toggled the # options not to execute them if ($display_fib == 0) { grep(delete $$_{'display fib'} , @commandtable) }; if ($display_iproutes == 0) { grep(delete $$_{'display ip routing-table'} , @commandtable) }; if ($display_vlan_all == 0) { grep(delete $$_{'display vlan all'} , @commandtable) }; if ($display_stproot == 0) { grep(delete $$_{'display stp root'} , @commandtable) }; if ($display_xcvr_int == 0) { grep(delete $$_{'display transceiver interface'} , @commandtable) }; # Use an array to preserve the order of the commands and a hash for mapping # commands to the subroutine and track commands that have been completed. @commands = map(keys(%$_), @commandtable); %commands = map(%$_, @commandtable); $commandcnt = scalar(keys %commands); $device_cmds=join(";", at commands); $cmds_regexp=join("|", map quotemeta($_), @commands); if (length($host) == 0) { if ($file) { print(STDERR "Too few arguments: file name required\n"); exit(1); } else { print(STDERR "Too few arguments: host name required\n"); exit(1); } } if ($opt_C) { print "$logincmd -t $timeo -c\'$commandstr\' $host\n"; exit(0); } open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n"; select(OUTPUT); # make OUTPUT unbuffered if debugging if ($debug) { $| = 1; } if ($file) { print STDERR "opening file $host\n" if ($debug); print STDOUT "opening file $host\n" if ($log); open(INPUT,"<$host") || die "open failed for $host: $!\n"; } else { print STDERR "executing $logincmd -t $timeo -c\"$device_cmds\" $host\n" if ($debug); print STDOUT "executing $logincmd -t $timeo -c\"$device_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { # system "$logincmd -noenable -t $timeo -c \"$device_cmds\" $host $host.raw 2>&1" || die "$logincmd failed for $host: $!\n"; # system "$logincmd -t $timeo -c \"$device_cmds\" $host $host.raw 2>&1" || die "$logincmd failed for $host: $!\n"; system "$logincmd -t $timeo -c \"$device_cmds\" $host $host.raw 2>&1" || die "$logincmd failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "$logincmd failed for $host: $!\n"; } else { # open(INPUT,"$logincmd -noenable -t $timeo -c \"$device_cmds\" $host ) { tr/\015//d; # h3c: # Look for the command at the end of the output # if (/\#exit$/) { # if (/\#quit$/) { # h3c: if (/[\]>#]\a?\s*quit/) { # if (/^[\[<].*[\]>]\a?\s?quit/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host $logincmd error: $_"); print STDERR ("$host $logincmd error: $_") if ($debug); $clean_run=0; last; } # while (/#\s*($cmds_regexp)\s*$/) { # h3c: while (/[\]>#]\a?\s*($cmds_regexp)\s*$/) { # while (/^[\[<].*[\]>]\a?\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { # h3c: # Extract the prompt: look for something not [ or < at the start # of the line, until either ] or > or # is reached: #$prompt = ($_ =~ /^([^#]+#)/)[0]; #$prompt =~ s/([][}{)(\\])/\\$1/g; #$prompt = ($_ =~ /^([^\]>]+[\]>]\007?)/)[0]; $prompt = ($_ =~ /^([^\]>#]+[\]>]\a?)/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; print STDERR ("PROMPT MATCH: $prompt\n") if ($debug); } print STDERR ("HIT COMMAND:$_") if ($debug); if (! defined($commands{$cmd})) { print STDERR "$host: found unexpected command - \"$cmd\"\n"; $clean_run = 0; last TOP; } $rval = &{$commands{$cmd}}(*INPUT, *OUTPUT, $cmd); delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } printf(STDOUT "$host: clean_run=$clean_run found_end=$found_end\n") if ($debug); # check for completeness if (scalar(%commands) || !$clean_run || !$found_end) { if (scalar(keys %commands) eq $commandcnt) { printf(STDERR "$host: missed cmd(s): all commands\n"); } elsif (scalar(%commands)) { printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands))); printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug); } if (!$clean_run || !$found_end) { print STDOUT "$host: End of run not found\n"; print STDERR "$host: End of run not found\n" if ($debug); system("$TAIL -1 $host.new"); } unlink "$host.new" if (! $debug); }