line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
2
|
|
|
|
|
|
|
package LaBrea::Tarpit; |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# 2-5-05, michael@bizsystems.com |
5
|
|
|
|
|
|
|
# |
6
|
11
|
0
|
|
11
|
|
15526
|
BEGIN { $SIG{'__WARN__'} = sub { warn $_[0] if $DOWARN }} |
|
0
|
|
|
|
|
0
|
|
7
|
|
|
|
|
|
|
$__PACKAGE__::DOWARN = 1; |
8
|
11
|
|
|
11
|
|
84
|
use strict; |
|
11
|
|
|
|
|
22
|
|
|
11
|
|
|
|
|
410
|
|
9
|
|
|
|
|
|
|
#use diagnostics; |
10
|
11
|
|
|
11
|
|
56
|
use vars qw($VERSION @ISA @EXPORT_OK); |
|
11
|
|
|
|
|
20
|
|
|
11
|
|
|
|
|
1310
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
$VERSION = do { my @r = (q$Revision: 1.36 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; |
13
|
|
|
|
|
|
|
|
14
|
11
|
|
|
11
|
|
61
|
use Fcntl qw(:DEFAULT :flock); |
|
11
|
|
|
|
|
22
|
|
|
11
|
|
|
|
|
11351
|
|
15
|
11
|
|
|
11
|
|
11436
|
use AutoLoader 'AUTOLOAD'; |
|
11
|
|
|
|
|
18592
|
|
|
11
|
|
|
|
|
71
|
|
16
|
|
|
|
|
|
|
require Exporter; |
17
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
18
|
|
|
|
|
|
|
@EXPORT_OK = qw( |
19
|
|
|
|
|
|
|
recurse_hash2txt |
20
|
|
|
|
|
|
|
daemon |
21
|
|
|
|
|
|
|
bandwidth |
22
|
|
|
|
|
|
|
midnight |
23
|
|
|
|
|
|
|
timezone |
24
|
|
|
|
|
|
|
tz2_sec |
25
|
|
|
|
|
|
|
their_date |
26
|
|
|
|
|
|
|
restore_tarpit |
27
|
|
|
|
|
|
|
log2_mem |
28
|
|
|
|
|
|
|
process_log |
29
|
|
|
|
|
|
|
cull_threads |
30
|
|
|
|
|
|
|
write_cache_file |
31
|
|
|
|
|
|
|
prep_report |
32
|
|
|
|
|
|
|
find_old_threads |
33
|
|
|
|
|
|
|
array2_tarpit |
34
|
|
|
|
|
|
|
); |
35
|
|
|
|
|
|
|
|
36
|
11
|
|
|
|
|
906
|
use constant defaults => { # seconds |
37
|
|
|
|
|
|
|
'cull' => 600, # drop threads older than this |
38
|
|
|
|
|
|
|
'min_age' => 15, # don't cull for at least |
39
|
|
|
|
|
|
|
'auto_cull' => 900, # cull at least every |
40
|
|
|
|
|
|
|
's_timeout' => 0.1, # select timeout |
41
|
|
|
|
|
|
|
'sock_timeout' => 180, # give up on socket response |
42
|
11
|
|
|
11
|
|
1045
|
}; |
|
11
|
|
|
|
|
25
|
|
43
|
11
|
|
|
|
|
6953
|
use constant mon => { |
44
|
|
|
|
|
|
|
qw(jan 0 feb 1 mar 2 apr 3 may 4 jun 5 jul 6 aug 7 sep 8 oct 9 nov 10 dec 11) |
45
|
11
|
|
|
11
|
|
55
|
}; |
|
11
|
|
|
|
|
18
|
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=head1 NAME |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
LaBrea::Tarpit - Utilities and web displays for |
50
|
|
|
|
|
|
|
Tom Liston's LaBrea scanner/worm disruptor |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
See: http://sourceforge.net/projects/labrea/ |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=head1 SYNOPSIS |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
use LaBrea::Tarpit qw( [exportable functions] ); |
57
|
|
|
|
|
|
|
or |
58
|
|
|
|
|
|
|
require LaBrea::Tarpit; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
daemon(%hash or \%hash); |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
$bandwidth = bandwidth(\%tarpit); |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
$midnight = midnight($epoch_time,$tz); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
$timezone = timezone($now); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
$sec = $tz2_sec($tz); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
$time_string = their_date($gmtime,$tz); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
$rv = restore_tarpit(\%tarpit,path2cache_file); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
$rv = log2_mem(\%tarpit,log_line,is_daemon,port_intvls,DShield); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
$rv = process_log(\%tarpit,path2log_file,is_daemon,port_intvls); |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
$rv = cull_threads(\%tarpit,timeout,scanners,port_intvls,DShield); |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
$rv = write_cache_file(\%tarpit,path2cache_file,umask,flag); |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
prep_report(\%tarpit,\%hash); |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
$rv = find_old_threads(\%tarpit,\%report,$age); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=head1 INSTALL |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=over 4 |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=item * Package |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
Untar the package |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
perl Makefile.PL |
95
|
|
|
|
|
|
|
make |
96
|
|
|
|
|
|
|
make test |
97
|
|
|
|
|
|
|
make install |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
To use examples/daemon.pl, configure |
100
|
|
|
|
|
|
|
the array at the beginning of the script |
101
|
|
|
|
|
|
|
and set the locations for the cache files. |
102
|
|
|
|
|
|
|
...typically /var/tmp/labrea.cache |
103
|
|
|
|
|
|
|
and /var/tmp/DShield.cache |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=item * Report/examples/html_report.plx |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=item * Report/examples/paged_report.plx |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
B and B will run as a cgi scripts |
110
|
|
|
|
|
|
|
by simply renaming them B. It is highly recommend that |
111
|
|
|
|
|
|
|
you enable the file caching to minimize load on your system. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Read the comments in the file itself for configuration. |
114
|
|
|
|
|
|
|
The defaults should work fine, but you must create the |
115
|
|
|
|
|
|
|
temporary directory used for file caching AND it must |
116
|
|
|
|
|
|
|
be writable by the web server. |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
B and B are configured to provide B |
119
|
|
|
|
|
|
|
reporting. You must set up the cron job maintain the |
120
|
|
|
|
|
|
|
B file for reporting. B below: |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=item * Get/examples/web_scan.pl |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Run B from a cron job hourly or daily to |
125
|
|
|
|
|
|
|
update the statistics from all know sites running |
126
|
|
|
|
|
|
|
LaBrea::Tarpit. A report can then be generated showing |
127
|
|
|
|
|
|
|
the activity worldwide. |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# MIN HOUR DAY MONTH DAYOFWEEK COMMAND |
130
|
|
|
|
|
|
|
30 * * * * ./web_scan.pl ./other_sites.txt ./tmp/site_stats |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
Also see: LaBrea::Tarpit::Report::other_sites |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=item * examples/tell_me.pl AGE |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
Run B from a cron job daily to send yourself |
137
|
|
|
|
|
|
|
an email detailing teergrubed hosts that have been |
138
|
|
|
|
|
|
|
held longer than B days. You might actually want |
139
|
|
|
|
|
|
|
to tell the bad guys that they have a rogue machine. |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
# MIN HOUR DAY MONTH DAYOFWEEK COMMAND |
142
|
|
|
|
|
|
|
30 * * * * ./tell_me.pl 60 # default |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=item * DShield/examples/mail_dshield.pm |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Configure with your DShield UserID, email address, mail agent and |
147
|
|
|
|
|
|
|
the location of the daemon - DShield cache file, then run periodically from |
148
|
|
|
|
|
|
|
cron to send reports to DShield. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=back |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head1 DESCRIPTION - LaBrea::Tarpit |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
A comprehensive Hack Attack reporting module when used in conjunction with |
155
|
|
|
|
|
|
|
Tom Liston's LaBrea scanner/worm disruptor. When configured with reporting |
156
|
|
|
|
|
|
|
and stat collection it provides a detailed HTML page containing: |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=over 4 |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=item * Bandwidth consumed by attack/disruption daemon |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=item * Summary of previous 5 days of attack/disruption |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=item * All IP addresses currently attacking |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=item * IP address, port attacked/held, attack start time |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=item * As above, but history of terminated attacks |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=item * By day detail graphs on port attack intensity |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=item * Active summary of known LaBrea::Tarpit sites |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=back |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
For more information on B see: L |
177
|
|
|
|
|
|
|
or contact the author of LaBrea, Tom Liston L. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
The parsed output of either syslog data or STDOUT from LaBrea using -o or -O |
180
|
|
|
|
|
|
|
options is readily turned into text reports or an html output page. |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Basically there are two methods of operation. You can use the B mode |
183
|
|
|
|
|
|
|
to create an almost realtime cache that may be parsed using the report |
184
|
|
|
|
|
|
|
routines, or you can use the update and report routines to parse the syslog |
185
|
|
|
|
|
|
|
files on an as needed basis. If you plan to create web page reports, the |
186
|
|
|
|
|
|
|
daemon model will use less system resources in the long run and avoids |
187
|
|
|
|
|
|
|
running syslog with the high volume output of LaBrea. |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
Improvements VERSION 1.00 |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
As of version 1.00, B uses network sockets to provide data for |
192
|
|
|
|
|
|
|
the report modules. This means that the daemon can run on a remote machine |
193
|
|
|
|
|
|
|
and the report scripts and web server can be somewhere else. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
For those of you upgrading from older versions, you B upgrade all of |
196
|
|
|
|
|
|
|
your report scripts as well. Older versions use a pipe or FIFO and this is |
197
|
|
|
|
|
|
|
no longer supported as there were problems maintaining separate sessions. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=cut |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
# memory records are kept in the form: |
202
|
|
|
|
|
|
|
# |
203
|
|
|
|
|
|
|
# %tarpit # time is kept in seconds since epoch |
204
|
|
|
|
|
|
|
# {bw} -> bandwidth # bytes per second |
205
|
|
|
|
|
|
|
# |
206
|
|
|
|
|
|
|
# {tz} -> timezone # i.e. text string = -800 |
207
|
|
|
|
|
|
|
# |
208
|
|
|
|
|
|
|
# {now" -> epoch time # only used when writing cache, |
209
|
|
|
|
|
|
|
# # not current otherwise |
210
|
|
|
|
|
|
|
# active threads |
211
|
|
|
|
|
|
|
# {at} -> {srcIP_1} -> {sp1} -> {dip} -> destination IP |
212
|
|
|
|
|
|
|
# . (src_port1) {dp} -> destination port |
213
|
|
|
|
|
|
|
# . . {pst} -> protocol type (0,6=tcp) |
214
|
|
|
|
|
|
|
# for tcp = persistent [true/false] |
215
|
|
|
|
|
|
|
# . . {ct} -> capture time |
216
|
|
|
|
|
|
|
# . . {lc} -> last contact time |
217
|
|
|
|
|
|
|
# . . |
218
|
|
|
|
|
|
|
# . -> {sp2} -> {dip} -> destination IP |
219
|
|
|
|
|
|
|
# . (src_port2) {dp} -> destination port |
220
|
|
|
|
|
|
|
# . {pst} -> protocol type (0,6=tcp) |
221
|
|
|
|
|
|
|
# for tcp = persistent [true/false] |
222
|
|
|
|
|
|
|
# . {ct} -> capture time |
223
|
|
|
|
|
|
|
# . {lc} -> last contact time |
224
|
|
|
|
|
|
|
# . |
225
|
|
|
|
|
|
|
# {srcIP_2} -> etc... |
226
|
|
|
|
|
|
|
# dead threads |
227
|
|
|
|
|
|
|
# {dt} -> {srcIP} -> {dp} -> last destination port |
228
|
|
|
|
|
|
|
# {lc} -> last contact time |
229
|
|
|
|
|
|
|
# . |
230
|
|
|
|
|
|
|
# port stats |
231
|
|
|
|
|
|
|
# {ph} -> {timea} -> {port num.x} -> count |
232
|
|
|
|
|
|
|
# . -> {port num.y} -> count |
233
|
|
|
|
|
|
|
# . -> {port num.z} -> count |
234
|
|
|
|
|
|
|
# (timeb} -> etc... |
235
|
|
|
|
|
|
|
# |
236
|
|
|
|
|
|
|
# {pt} -> collection_interval |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
=over 2 |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
=item * recurse_hash2txt(\$txt_buffer,\%hash,$keys_so_far,flag) |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
Appends to txt_buffer. |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
Generates a text tree of a hash. |
245
|
|
|
|
|
|
|
%hash{lvl1}->{lvl2}->{lvl3} = 5; this real hash |
246
|
|
|
|
|
|
|
flag = 0, ksf = '' with this input |
247
|
|
|
|
|
|
|
lvl1:lvl2:lvl3:5 produces this text |
248
|
|
|
|
|
|
|
flag = 1, ksf = ptr this input |
249
|
|
|
|
|
|
|
ptr->{lvl1}->{lvl2}->{lvl3} = 5; this txt |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=cut |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
# input: txt out pointer, pointer to hash, keys so far, dump | debug |
254
|
|
|
|
|
|
|
# if the dod flag is 0, this is normal dump mode |
255
|
|
|
|
|
|
|
# else it's the fancy debug mode |
256
|
|
|
|
|
|
|
sub recurse_hash2txt { |
257
|
745
|
|
|
745
|
1
|
3350
|
my ($txp, $p, $ksf,$dod) = @_; |
258
|
745
|
|
|
|
|
944
|
foreach my $key (sort keys %{$p}) { |
|
745
|
|
|
|
|
2785
|
|
259
|
2537
|
|
|
|
|
2954
|
my $keysnow = $ksf; |
260
|
2537
|
100
|
|
|
|
5230
|
$keysnow .= ($dod) ? qq|->{$key}| |
|
|
100
|
|
|
|
|
|
261
|
|
|
|
|
|
|
: ($ksf) |
262
|
|
|
|
|
|
|
? ':'. $key |
263
|
|
|
|
|
|
|
: $key; |
264
|
2537
|
100
|
|
|
|
4477
|
if (ref $p->{$key}) { |
265
|
720
|
|
|
|
|
1518
|
&recurse_hash2txt($txp,$p->{$key},$keysnow,$dod); |
266
|
|
|
|
|
|
|
} else { |
267
|
1817
|
100
|
|
|
|
2812
|
$keysnow .= ($dod) ? ' = ' : ':'; |
268
|
1817
|
|
100
|
|
|
4452
|
$keysnow .= ($p->{$key} || 0) . "\n"; |
269
|
1817
|
|
|
|
|
4466
|
$$txp .= $keysnow; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=item * ($LBfh,$version,$kid) = lbd_open($LaBrea,$DEBUG); |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
Core daemon start routine. Not exported, but can |
277
|
|
|
|
|
|
|
be replaced externally with: |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
*LaBrea::Tarpit::lbd_open = sub { stuff }; |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
Returns the pid of the underlying process (if any) and the version number of |
282
|
|
|
|
|
|
|
that process. It also sets the command line shown by 'ps' like this: |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
$0 = 'stuff'; |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
input: path to daemon, |
287
|
|
|
|
|
|
|
STDERR switch |
288
|
|
|
|
|
|
|
returns: LaBrea file handle, |
289
|
|
|
|
|
|
|
version, |
290
|
|
|
|
|
|
|
pid of kid |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=cut |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub lbd_open { |
295
|
0
|
|
|
0
|
1
|
0
|
my($LaBrea,$DEBUG) = @_; |
296
|
0
|
|
|
|
|
0
|
local *LABREA; |
297
|
0
|
|
|
|
|
0
|
$LaBrea =~ /^([^\s]+)/; # bare path to LaBrea |
298
|
0
|
|
|
|
|
0
|
qx/$1 -V 2>&1/ =~ /(\d+\.[^\s]+)/; # get version |
299
|
0
|
|
|
|
|
0
|
my $version = $1; # save version |
300
|
|
|
|
|
|
|
# open LaBrea daemon |
301
|
0
|
|
|
|
|
0
|
my $kid = open(LABREA,$LaBrea .' |'); |
302
|
0
|
0
|
|
|
|
0
|
die "Can't open $LaBrea: $!" unless $kid; |
303
|
0
|
0
|
|
|
|
0
|
unless ($DEBUG) { |
304
|
0
|
0
|
|
|
|
0
|
open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; |
305
|
|
|
|
|
|
|
} |
306
|
0
|
|
|
|
|
0
|
$0 = __PACKAGE__.' '.$0; # set ps(1) name to package name |
307
|
0
|
|
|
|
|
0
|
return(*LABREA,$version,$kid); |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=item * lbd_close($LBfh,$kid); |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
Core daemon close routine, not exported but can be |
313
|
|
|
|
|
|
|
replaced externally with: |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
*LaBrea::Tarpit::lbd_close = sub { sutff }; |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
Close the daemon and kill off $kid with sig 15 |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
input: filehandle, |
320
|
|
|
|
|
|
|
pid of kid |
321
|
|
|
|
|
|
|
returns: nothing |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=cut |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
sub lbd_close { |
326
|
0
|
|
|
0
|
1
|
0
|
my($LBfh,$kid) = @_; |
327
|
0
|
|
|
|
|
0
|
kill 15, $kid; # kill LaBrea |
328
|
0
|
|
|
|
|
0
|
close $LBfh; |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
# autoload everything to keep daemon small |
332
|
|
|
|
|
|
|
sub daemon; |
333
|
|
|
|
|
|
|
sub bandwidth; |
334
|
|
|
|
|
|
|
sub midnight; |
335
|
|
|
|
|
|
|
sub timezone; |
336
|
|
|
|
|
|
|
sub restore_tarpit; |
337
|
|
|
|
|
|
|
sub log2_mem; |
338
|
|
|
|
|
|
|
sub process_log; |
339
|
|
|
|
|
|
|
sub cull_threads; |
340
|
|
|
|
|
|
|
sub write_cache_file; |
341
|
|
|
|
|
|
|
sub prep_report; |
342
|
|
|
|
|
|
|
sub find_old_threads; |
343
|
|
|
|
|
|
|
sub array2_tarpit; |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
# helper subroutines |
346
|
|
|
|
|
|
|
#sub _cullnsquish; |
347
|
|
|
|
|
|
|
sub _check4cull; |
348
|
|
|
|
|
|
|
sub _init_pt; |
349
|
|
|
|
|
|
|
sub _add_array; |
350
|
|
|
|
|
|
|
sub _cache2txt; |
351
|
|
|
|
|
|
|
sub _ex_append; |
352
|
|
|
|
|
|
|
sub _get_config; |
353
|
0
|
|
|
0
|
|
0
|
sub DESTROY {}; |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
1; |
356
|
|
|
|
|
|
|
__END__ |