1package bigip;
2##
3## @PACKAGE@ @VERSION@
4@copyright@
5#
6#  RANCID - Really Awesome New Cisco confIg Differ
7#
8#  bigip.pm - F5 BIG-IP >= v11 rancid procedures
9
10use 5.010;
11use strict 'vars';
12use warnings;
13no warnings 'uninitialized';
14require(Exporter);
15our @ISA = qw(Exporter);
16
17use rancid @VERSION@;
18
19@ISA = qw(Exporter rancid main);
20#XXX @Exporter::EXPORT = qw($VERSION @commandtable %commands @commands);
21
22# load-time initialization
23sub import {
24    # force a terminal type so as not to confuse the POS
25    $ENV{'TERM'} = "vt100";
26
27    0;
28}
29
30# post-open(collection file) initialization
31sub init {
32    # add content lines and separators
33    ProcessHistory("","","","!RANCID-CONTENT-TYPE: $devtype\n!\n");
34    ProcessHistory("COMMENTS","keysort","A1","#\n");
35    ProcessHistory("COMMENTS","keysort","B0","#\n");
36    ProcessHistory("COMMENTS","keysort","C0","#\n");
37
38    0;
39}
40
41# main loop of input of device output
42sub inloop {
43    my($INPUT, $OUTPUT) = @_;
44    my($cmd, $rval);
45
46TOP: while(<$INPUT>) {
47	tr/\015//d;
48	if (/^Error:/) {
49	    print STDOUT ("$host clogin error: $_");
50	    print STDERR ("$host clogin error: $_") if ($debug);
51	    $clean_run=0;
52	    last;
53	}
54	while (/#\s*($cmds_regexp)\s*$/) {
55	    $cmd = $1;
56	    if (!defined($prompt)) {
57		$prompt = ($_ =~ /^([^#]+#)/)[0];
58		$prompt =~ s/([][}{)(\\])/\\$1/g;
59		print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
60	    }
61	    print STDERR ("HIT COMMAND:$_") if ($debug);
62	    if (! defined($commands{$cmd})) {
63		print STDERR "$host: found unexpected command - \"$cmd\"\n";
64		$clean_run = 0;
65		last TOP;
66	    }
67	    $rval = &{$commands{$cmd}}($INPUT, $OUTPUT, $cmd);
68	    delete($commands{$cmd});
69	    if ($rval == -1) {
70		$clean_run = 0;
71		last TOP;
72	    }
73	}
74	if (/\#\s?exit$/) {
75	    $clean_run=1;
76	    last;
77	}
78    }
79}
80
81# This routine parses a single command that returns no required info.  The
82# output is discarded.
83sub RunCommandTMSH {
84    my($INPUT, $OUTPUT, $cmd) = @_;
85    print STDERR "    In RunCommandTMSH: $_" if ($debug);
86
87    while (<$INPUT>) {
88	tr/\015//d;
89	# Needed for when our prompt changes due to our executed command (for
90	# example, after executing 'cd /')
91	$prompt = ($_ =~ /^([^#]+#)/)[0];
92	$prompt =~ s/([][}{)(\\])/\\$1/g;
93	last if (/^$prompt/);
94    }
95    return(0);
96}
97
98# This routine parses "tmsh show /sys version"
99sub ShowVersion {
100    my($INPUT, $OUTPUT, $cmd) = @_;
101    print STDERR "    In ShowVersion: $_" if ($debug);
102
103    while (<$INPUT>) {
104	tr/\015//d;
105	last if (/^$prompt/);
106	next if (/^(\s*|\s*$cmd\s*)$/);
107	return(-1) if (/command authorization failed/i);
108
109	/^kernel:/i && ($_ = <$INPUT>) &&
110	    ProcessHistory("COMMENTS","keysort","A3","#Image: Kernel: $_") &&
111	    next;
112	if (/^package:/i) {
113	    my($line);
114
115	    while ($_ = <$INPUT>) {
116		tr/\015//d;
117		last if (/:/);
118		last if (/^$prompt/);
119		chomp;
120		$line .= " $_";
121	    }
122	    ProcessHistory("COMMENTS","keysort","A2",
123			   "#Image: Package:$line\n");
124	}
125
126	if (/:/) {
127	    ProcessHistory("COMMENTS","keysort","C1","#$_");
128	} else {
129	    ProcessHistory("COMMENTS","keysort","C1","#\t$_");
130	}
131    }
132    return(0);
133}
134
135# This routine parses "tmsh show /sys hardware"
136sub ShowHardware {
137    my($INPUT, $OUTPUT, $cmd) = @_;
138    print STDERR "    In ShowHardware: $_" if ($debug);
139
140    while (<$INPUT>) {
141        tr/\015//d;
142        last if (/^$prompt/);
143        next if (/^(\s*|\s*$cmd\s*)$/);
144        return(1) if /^\s*\^\s*$/;
145        return(1) if /(Invalid input detected|Type help or )/;
146        return(-1) if (/command authorization failed/i);
147
148        s/\d+rpm//ig;
149        s/^\|//;
150        s/^\ \ ([0-9]+)(\ +).*up.*[0-9]/  $1$2up REMOVED/i;
151        s/^\ \ ([0-9]+)(\ +).*Air\ Inlet/  $1$2REMOVED Air Inlet/i;
152        s/^\ \ ([0-9]+)(\ +).*HSBe/  $1$2REMOVED HSBe/i;
153        s/^\ \ ([0-9]+)(\ +).*TMP421 on die/  $1$2REMOVED TMP421 on die/i;
154        s/^\ \ ([0-9]+)(\ +)[0-9]+\ +[0-9]+/  $1$2REMOVED     REMOVED/;
155        /Type: / && ProcessHistory("COMMENTS","keysort","A0",
156                                   "#Chassis type: $'");
157
158        ProcessHistory("COMMENTS","keysort","B1","#$_") && next;
159    }
160    return(0);
161}
162
163# This routine parses "tmsh show /sys license"
164sub ShowLicense {
165    my($INPUT, $OUTPUT, $cmd) = @_;
166    my($line) = (0);
167    print STDERR "    In ShowLicense: $_" if ($debug);
168
169    while (<$INPUT>) {
170	tr/\015//d;
171	# v9 software license does not have CR at EOF
172	s/^#-+($prompt.*)/$1/;
173	last if (/^$prompt/);
174	next if (/^(\s*|\s*$cmd\s*)$/);
175	return(1) if /^\s*\^\s*$/;
176	return(1) if /(Invalid input detected|Type help or )/;
177	return(-1) if (/command authorization failed/i);
178
179	if (!$line++) {
180	    ProcessHistory("LICENSE","","","#\n#/config/bigip.license:\n");
181	}
182	ProcessHistory("LICENSE","","","# $_") && next;
183    }
184    return(0);
185}
186
187# This routine parses "tmsh show /net route static"
188sub ShowRouteStatic {
189    my($INPUT, $OUTPUT, $cmd) = @_;
190    print STDERR "    In ShowRouteStatic: $_" if ($debug);
191
192    while (<$INPUT>) {
193	tr/\015//d;
194	last if (/^$prompt/);
195	next if (/^(\s*|\s*$cmd\s*)$/);
196	return(1) if /^\s*\^\s*$/;
197	return(1) if /(Invalid input detected|Type help or )/;
198	return(-1) if (/command authorization failed/i);
199
200	ProcessHistory("ROUTE","",""," $_") && next;
201    }
202    return(0);
203}
204
205# This routine parses "cat /config/ZebOS.conf"
206sub ShowZebOSconf {
207    my($INPUT, $OUTPUT, $cmd) = @_;
208    my($line) = (0);
209    print STDERR "    In ShowZebOSconf: $_" if ($debug);
210
211    while (<$INPUT>) {
212        tr/\015//d;
213        last if (/^$prompt/);
214        next if (/^(\s*|\s*$cmd\s*)$/);
215        return(1) if /^\s*\^\s*$/;
216        return(1) if /(Invalid input detected|Type help or )/;
217        return(-1) if (/command authorization failed/i);
218
219        if (!$line++) {
220            ProcessHistory("ZEBOSCONF","","","#\n#/config/ZebOS.conf:\n");
221        }
222        ProcessHistory("ZEBOSCONF","","","# $_") && next;
223    }
224    return(0);
225}
226
227# This routine parses "lsof -n -i :179"
228sub ShowZebOSsockets {
229    my($INPUT, $OUTPUT, $cmd) = @_;
230    my($line) = (0);
231    print STDERR "    In ShowZebOSsockets: $_" if ($debug);
232
233    while (<$INPUT>) {
234        tr/\015//d;
235        last if (/^$prompt/);
236        next if (/^(\s*|\s*$cmd\s*)$/);
237        return(1) if /^\s*\^\s*$/;
238        return(1) if /(Invalid input detected|Type help or )/;
239        return(-1) if (/command authorization failed/i);
240
241        if (!$line++) {
242            ProcessHistory("ZEBOSSOCKETS","","","#\n#lsof -n -i :179:\n");
243        }
244        ProcessHistory("ZEBOSSOCKETS","","","# $_") && next;
245    }
246    return(0);
247}
248
249# This routine processes a "tmsh -q list"
250sub WriteTerm {
251    my($INPUT, $OUTPUT, $cmd) = @_;
252    my($lines) = 0;
253    print STDERR "    In WriteTerm: $_" if ($debug);
254
255    while (<$INPUT>) {
256        tr/\015//d;
257        next if (/^\s*$/);
258
259        # Ignore monitor down state, save the config as up.
260        s/state down$/state up/i;
261
262        # end of config - hopefully.  f5 does not have a reliable end-of-config
263        # tag.
264        if (/^$prompt/) {
265            $found_end++;
266            last;
267        }
268        return(-1) if (/command authorization failed/i);
269
270        $lines++;
271
272        if (/(bind-pw|encrypted-password|user-password-encrypted|passphrase) / && $filter_pwds >= 1) {
273            ProcessHistory("ENABLE","","","# $1 <removed>\n");
274            next;
275        }
276        if (/(auth-password-encrypted) / &&
277	    ($filter_osc || $filter_pwds > 1)) {
278            ProcessHistory("ENABLE","","","# $1 <removed>\n");
279            next;
280        }
281
282        # catch anything that wasnt matched above.
283        ProcessHistory("","","","$_");
284    }
285
286    if ($lines < 3) {
287        printf(STDERR "ERROR: $host configuration appears truncated.\n");
288        $found_end = 0;
289        return(-1);
290    }
291
292    return(0);
293}
294
2951;
296