1178825Sdfr#! /usr/pkg/bin/perl
2178825Sdfr# -*- mode: perl; perl-indent-level: 8 -*-
3178825Sdfr#
4233294Sstas# Copyright (c) 2003 Kungliga Tekniska H��gskolan
5178825Sdfr# (Royal Institute of Technology, Stockholm, Sweden).
6178825Sdfr# All rights reserved.
7178825Sdfr#
8178825Sdfr# Redistribution and use in source and binary forms, with or without
9178825Sdfr# modification, are permitted provided that the following conditions
10178825Sdfr# are met:
11178825Sdfr#
12178825Sdfr# 1. Redistributions of source code must retain the above copyright
13178825Sdfr#    notice, this list of conditions and the following disclaimer.
14178825Sdfr#
15178825Sdfr# 2. Redistributions in binary form must reproduce the above copyright
16178825Sdfr#    notice, this list of conditions and the following disclaimer in the
17178825Sdfr#    documentation and/or other materials provided with the distribution.
18178825Sdfr#
19178825Sdfr# 3. Neither the name of the Institute nor the names of its contributors
20178825Sdfr#    may be used to endorse or promote products derived from this software
21178825Sdfr#    without specific prior written permission.
22178825Sdfr#
23178825Sdfr# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24178825Sdfr# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25178825Sdfr# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26178825Sdfr# ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27178825Sdfr# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28178825Sdfr# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29178825Sdfr# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30178825Sdfr# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31178825Sdfr# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32178825Sdfr# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33178825Sdfr# SUCH DAMAGE.
34178825Sdfr#
35233294Sstas# $Id$
36178825Sdfr#
37178825Sdfr# kdc-log-analyze - Analyze a KDC log file and give a report on the contents
38178825Sdfr#
39178825Sdfr# Note: The parts you want likely want to customize are the variable $notlocal,
40178825Sdfr# the array @local_network_re and the array @local_realms.
41178825Sdfr#
42178825Sdfr# Idea and implemetion for MIT Kerberos was done first by
43178825Sdfr# Ken Hornstein <kenh@cmf.nrl.navy.mil>, this program wouldn't exists
44178825Sdfr# without his help.
45178825Sdfr#
46178825Sdfr
47178825Sdfruse strict;
48178825Sdfruse Sys::Hostname;
49178825Sdfr
50178825Sdfrmy $notlocal = 'not SU';
51178825Sdfrmy @local_realms = ( "SU.SE" );
52178825Sdfrmy @local_networks_re =
53178825Sdfr    (
54178825Sdfr      "130\.237",
55178825Sdfr      "193\.11\.3[0-9]\.",
56178825Sdfr      "130.242.128",
57178825Sdfr      "2001:6b0:5:"
58178825Sdfr      );
59178825Sdfr
60178825Sdfrmy $as_req = 0;
61178825Sdfrmy %as_req_addr;
62178825Sdfrmy %as_req_addr_nonlocal;
63178825Sdfrmy %as_req_client;
64178825Sdfrmy %as_req_server;
65178825Sdfrmy %addr_uses_des;
66178825Sdfrmy %princ_uses_des;
67178825Sdfrmy $five24_req = 0;
68178825Sdfrmy %five24_req_addr;
69178825Sdfrmy %five24_req_addr_nonlocal;
70178825Sdfrmy %five24_req_server;
71178825Sdfrmy %five24_req_client;
72178825Sdfrmy $as_req_successful = 0;
73178825Sdfrmy $as_req_error = 0;
74178825Sdfrmy $no_such_princ = 0;
75178825Sdfrmy %no_such_princ_princ;
76178825Sdfrmy %no_such_princ_addr;
77178825Sdfrmy %no_such_princ_addr_nonlocal;
78178825Sdfrmy $as_req_etype_odd = 0;
79178825Sdfrmy %bw_addr;
80178825Sdfrmy $pa_alt_princ_request = 0;
81178825Sdfrmy $pa_alt_princ_verify = 0;
82178825Sdfrmy $tgs_req = 0;
83178825Sdfrmy %tgs_req_addr;
84178825Sdfrmy %tgs_req_addr_nonlocal;
85178825Sdfrmy %tgs_req_client;
86178825Sdfrmy %tgs_req_server;
87178825Sdfrmy $tgs_xrealm_out = 0;
88178825Sdfrmy %tgs_xrealm_out_realm;
89178825Sdfrmy %tgs_xrealm_out_princ;
90178825Sdfrmy $tgs_xrealm_in = 0;
91178825Sdfrmy %tgs_xrealm_in_realm;
92178825Sdfrmy %tgs_xrealm_in_princ;
93178825Sdfrmy %enctype_session;
94178825Sdfrmy %enctype_ticket;
95178825Sdfrmy $restarts = 0;
96178825Sdfrmy $forward_non_forward = 0;
97178825Sdfrmy $v4_req = 0;
98178825Sdfrmy %v4_req_addr;
99178825Sdfrmy %v4_req_addr_nonlocal;
100178825Sdfrmy $v4_cross = 0;
101178825Sdfrmy %v4_cross_realm;
102178825Sdfrmy $v5_cross = 0;
103178825Sdfrmy %v5_cross_realm;
104178825Sdfrmy $referrals = 0;
105178825Sdfrmy %referral_princ;
106178825Sdfrmy %referral_realm;
107178825Sdfrmy %strange_tcp_data;
108178825Sdfrmy $http_malformed = 0;
109178825Sdfrmy %http_malformed_addr;
110178825Sdfrmy $http_non_kdc = 0;
111178825Sdfrmy %http_non_kdc_addr;
112178825Sdfrmy $tcp_conn_timeout = 0;
113178825Sdfrmy %tcp_conn_timeout_addr;
114178825Sdfrmy $failed_processing = 0;
115178825Sdfrmy %failed_processing_addr;
116178825Sdfrmy $connection_closed = 0;
117178825Sdfrmy %connection_closed_addr;
118178825Sdfrmy $pa_failed = 0;
119178825Sdfrmy %pa_failed_princ;
120178825Sdfrmy %pa_failed_addr;
121178825Sdfrmy %ip;
122178825Sdfr
123178825Sdfr$ip{'4'} = $ip{'6'} = 0;
124178825Sdfr
125178825Sdfrwhile (<>) {
126178825Sdfr	process_line($_);
127178825Sdfr}
128178825Sdfr
129178825Sdfrprint "Kerberos KDC Log Report for ",
130178825Sdfr    hostname, " on ", scalar localtime, "\n\n";
131178825Sdfr
132178825Sdfrprint "General Statistics\n\n";
133178825Sdfr
134178825Sdfrprint "\tNumber of IPv4 requests: $ip{'4'}\n";
135178825Sdfrprint "\tNumber of IPv6 requests: $ip{'6'}\n\n";
136178825Sdfr
137178825Sdfrprint "\tNumber of restarts: $restarts\n";
138178825Sdfrprint "\tNumber of V4 requests: $v4_req\n";
139178825Sdfrif ($v4_req > 0) {
140178825Sdfr	print "\tTop ten IP addresses performing V4 requests:\n";
141178825Sdfr	topten(\%v4_req_addr);
142178825Sdfr}
143178825Sdfrif (int(keys %v4_req_addr_nonlocal) > 0) {
144178825Sdfr	print "\tTop ten $notlocal IP addresses performing V4 requests:\n";
145178825Sdfr	topten(\%v4_req_addr_nonlocal);
146178825Sdfr
147178825Sdfr}
148178825Sdfrprint "\n";
149178825Sdfr
150178825Sdfrprint "\tNumber of V4 cross realms (krb4 and 524) requests: $v4_cross\n";
151178825Sdfrif ($v4_cross > 0) {
152178825Sdfr	print "\tTop ten realms performing V4 cross requests:\n";
153178825Sdfr	topten(\%v4_cross_realm);
154178825Sdfr}
155178825Sdfrprint "\n";
156178825Sdfr
157178825Sdfrprint "\tNumber of V45 cross realms requests: $v5_cross\n";
158178825Sdfrif ($v5_cross > 0) {
159178825Sdfr	print "\tTop ten realms performing V4 cross requests:\n";
160178825Sdfr	topten(\%v5_cross_realm);
161178825Sdfr}
162178825Sdfrprint "\n";
163178825Sdfr
164178825Sdfrprint "\tNumber of failed lookups: $no_such_princ\n";
165178825Sdfrif ($no_such_princ > 0) {
166178825Sdfr	print "\tTop ten IP addresses failing to find principal:\n";
167178825Sdfr	topten(\%no_such_princ_addr);
168178825Sdfr	print "\tTop ten $notlocal IP addresses failing find principal:\n";
169178825Sdfr	topten(\%no_such_princ_addr_nonlocal);
170178825Sdfr	print "\tTop ten failed to find principals\n";
171178825Sdfr	topten(\%no_such_princ_princ);
172178825Sdfr}
173178825Sdfrprint "\n";
174178825Sdfr
175178825Sdfrprint "\tBandwidth pigs:\n";
176178825Sdfrtopten(\%bw_addr);
177178825Sdfrprint "\n";
178178825Sdfr
179178825Sdfrprint "\tStrange TCP data clients: ", int(keys %strange_tcp_data),"\n";
180178825Sdfrtopten(\%strange_tcp_data);
181178825Sdfrprint "\n";
182178825Sdfr
183178825Sdfrprint "\tTimeout waiting on TCP requests: ", $tcp_conn_timeout,"\n";
184178825Sdfrif ($tcp_conn_timeout > 0) {
185178825Sdfr	print "\tTop ten TCP timeout request clients\n";
186178825Sdfr	topten(\%tcp_conn_timeout_addr);
187178825Sdfr}
188178825Sdfrprint "\n";
189178825Sdfr
190178825Sdfrprint "\tFailed processing requests: ", $failed_processing,"\n";
191178825Sdfrif ($failed_processing > 0) {
192178825Sdfr	print "\tTop ten failed processing request clients\n";
193178825Sdfr	topten(\%failed_processing_addr);
194178825Sdfr}
195178825Sdfrprint "\n";
196178825Sdfr
197178825Sdfrprint "\tConnection closed requests: ", $connection_closed,"\n";
198178825Sdfrif ($connection_closed > 0) {
199178825Sdfr	print "\tTop ten connection closed request clients\n";
200178825Sdfr	topten(\%connection_closed_addr);
201178825Sdfr}
202178825Sdfrprint "\n";
203178825Sdfr
204178825Sdfrprint "\tMalformed HTTP requests: ", $http_malformed,"\n";
205178825Sdfrif ($http_malformed > 0) {
206178825Sdfr	print "\tTop ten malformed HTTP request clients\n";
207178825Sdfr	topten(\%http_malformed_addr);
208178825Sdfr}
209178825Sdfrprint "\n";
210178825Sdfr
211178825Sdfrprint "\tHTTP non kdc requests: ", $http_non_kdc,"\n";
212178825Sdfrif ($http_non_kdc > 0) {
213178825Sdfr	print "\tTop ten HTTP non KDC request clients\n";
214178825Sdfr	topten(\%http_non_kdc_addr);
215178825Sdfr}
216178825Sdfrprint "\n";
217178825Sdfr
218178825Sdfrprint "Report on AS_REQ requests\n\n";
219178825Sdfrprint "Overall AS_REQ statistics\n\n";
220178825Sdfr
221178825Sdfrprint "\tTotal number: $as_req\n";
222178825Sdfr
223178825Sdfrprint "\nAS_REQ client/server statistics\n\n";
224178825Sdfr
225178825Sdfrprint "\tDistinct IP Addresses performing requests: ",
226178825Sdfr    int(keys %as_req_addr),"\n";
227178825Sdfrprint "\tOverall top ten IP addresses\n";
228178825Sdfrtopten(\%as_req_addr);
229178825Sdfr
230178825Sdfrprint "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
231178825Sdfr					int(keys %as_req_addr_nonlocal), "\n";
232178825Sdfrprint "\tTop ten non-local ($notlocal) IP address:\n";
233178825Sdfrtopten(\%as_req_addr_nonlocal);
234178825Sdfr
235178825Sdfrprint "\n\tPreauth failed for for: ", $pa_failed, " requests\n";
236178825Sdfrif ($pa_failed) {
237178825Sdfr	print "\tPreauth failed top ten IP addresses:\n";
238178825Sdfr	topten(\%pa_failed_addr);
239178825Sdfr	print "\tPreauth failed top ten principals:\n";
240178825Sdfr	topten(\%pa_failed_princ);
241178825Sdfr}
242178825Sdfr
243178825Sdfrprint "\n\tDistinct clients performing requests: ",
244178825Sdfr    int(keys %as_req_client), "\n";
245178825Sdfrprint "\tTop ten clients:\n";
246178825Sdfrtopten(\%as_req_client);
247178825Sdfr
248178825Sdfrprint "\tDistinct services requested: ", int(keys %as_req_server), "\n";
249178825Sdfrprint "\tTop ten requested services:\n";
250178825Sdfrtopten(\%as_req_server);
251178825Sdfr
252178825Sdfrprint "\n\n\nReport on TGS_REQ requests:\n\n";
253178825Sdfrprint "Overall TGS_REQ statistics\n\n";
254178825Sdfrprint "\tTotal number: $tgs_req\n";
255178825Sdfr
256178825Sdfrprint "\nTGS_REQ client/server statistics\n\n";
257178825Sdfrprint "\tDistinct IP addresses performing requests: ",
258178825Sdfr				int(keys %tgs_req_addr), "\n";
259178825Sdfrprint "\tOverall top ten IP addresses\n";
260178825Sdfrtopten(\%tgs_req_addr);
261178825Sdfr
262178825Sdfrprint "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
263178825Sdfr				int(keys %tgs_req_addr_nonlocal), "\n";
264178825Sdfrprint "\tTop ten non-local ($notlocal) IP address:\n";
265178825Sdfrtopten(\%tgs_req_addr_nonlocal);
266178825Sdfr
267178825Sdfrprint "\tDistinct clients performing requests: ",
268178825Sdfr				int(keys %tgs_req_client), "\n";
269178825Sdfrprint "\tTop ten clients:\n";
270178825Sdfrtopten(\%tgs_req_client);
271178825Sdfr
272178825Sdfrprint "\tDistinct services requested: ", int(keys %tgs_req_server), "\n";
273178825Sdfrprint "\tTop ten requested services:\n";
274178825Sdfrtopten(\%tgs_req_server);
275178825Sdfr
276178825Sdfrprint "\n\n\nReport on 524_REQ requests:\n\n";
277178825Sdfr
278178825Sdfrprint "\t524_REQ client/server statistics\n\n";
279178825Sdfr
280178825Sdfrprint "\tDistinct IP Addresses performing requests: ",
281178825Sdfr    int(keys %five24_req_addr),"\n";
282178825Sdfrprint "\tOverall top ten IP addresses\n";
283178825Sdfrtopten(\%five24_req_addr);
284178825Sdfr
285178825Sdfrprint "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
286178825Sdfr					int(keys %five24_req_addr_nonlocal), "\n";
287178825Sdfrprint "\tTop ten non-local ($notlocal) IP address:\n";
288178825Sdfrtopten(\%five24_req_addr_nonlocal);
289178825Sdfr
290178825Sdfrprint "\tDistinct clients performing requests: ", int(keys %five24_req_client), "\n";
291178825Sdfrprint "\tTop ten clients:\n";
292178825Sdfrtopten(\%five24_req_client);
293178825Sdfr
294178825Sdfrprint "\tDistinct services requested: ", int(keys %five24_req_server), "\n";
295178825Sdfrprint "\tTop ten requested services:\n";
296178825Sdfrtopten(\%five24_req_server);
297178825Sdfrprint "\n";
298178825Sdfr
299178825Sdfrprint "Cross realm statistics\n\n";
300178825Sdfr
301178825Sdfrprint "\tNumber of cross-realm tgs out: $tgs_xrealm_out\n";
302178825Sdfrif ($tgs_xrealm_out > 0) {
303178825Sdfr	print "\tTop ten realms used for out cross-realm:\n";
304178825Sdfr	topten(\%tgs_xrealm_out_realm);
305178825Sdfr	print "\tTop ten principals use out cross-realm:\n";
306178825Sdfr	topten(\%tgs_xrealm_out_princ);
307178825Sdfr}
308178825Sdfrprint "\tNumber of cross-realm tgs in: $tgs_xrealm_in\n";
309178825Sdfrif ($tgs_xrealm_in > 0) {
310178825Sdfr	print "\tTop ten realms used for in cross-realm:\n";
311178825Sdfr	topten(\%tgs_xrealm_in_realm);
312178825Sdfr	print "\tTop ten principals use in cross-realm:\n";
313178825Sdfr	topten(\%tgs_xrealm_in_princ);
314178825Sdfr}
315178825Sdfr
316178825Sdfrprint "\n\nReport on referral:\n\n";
317178825Sdfr
318178825Sdfrprint "\tNumber of referrals: $referrals\n";
319178825Sdfrif ($referrals > 0) {
320178825Sdfr	print "\tTop ten referral-ed principals:\n";
321178825Sdfr	topten(\%referral_princ);
322178825Sdfr	print "\tTop ten to realm referrals:\n";
323178825Sdfr	topten(\%referral_realm);
324178825Sdfr}
325178825Sdfr
326178825Sdfrprint "\n\nEnctype Statistics:\n\n";
327178825Sdfrprint "\tTop ten session enctypes:\n";
328178825Sdfrtopten(\%enctype_session);
329178825Sdfrprint "\tTop ten ticket enctypes:\n";
330178825Sdfrtopten(\%enctype_ticket);
331178825Sdfr
332178825Sdfrprint "\tDistinct IP addresses using DES: ", int(keys %addr_uses_des), "\n";
333178825Sdfrprint "\tTop IP addresses using DES:\n";
334178825Sdfrtopten(\%addr_uses_des);
335178825Sdfrprint "\tDistinct principals using DES: ", int(keys %princ_uses_des), "\n";
336178825Sdfrprint "\tTop ten principals using DES:\n";
337178825Sdfrtopten(\%princ_uses_des);
338178825Sdfr
339178825Sdfrprint "\n";
340178825Sdfr
341178825Sdfrprintf("Requests to forward non-forwardable ticket: $forward_non_forward\n");
342178825Sdfr
343178825Sdfr
344178825Sdfrexit 0;
345178825Sdfr
346178825Sdfrmy $last_addr = "";
347178825Sdfrmy $last_principal = "";
348178825Sdfr
349178825Sdfrsub process_line {
350178825Sdfr	local($_) = @_;
351178825Sdfr	#
352178825Sdfr	# Eat these lines that are output as a result of startup (but
353178825Sdfr	# log the number of restarts)
354178825Sdfr	#
355178825Sdfr	if (/AS-REQ \(krb4\) (.*) from IPv([46]):([0-9\.:a-fA-F]+) for krbtgt.*$/){
356178825Sdfr		$v4_req++;
357178825Sdfr		$v4_req_addr{$3}++;
358178825Sdfr		$v4_req_addr_nonlocal{$3}++ if (!islocaladdr($3));
359178825Sdfr		$last_addr = $3;
360178825Sdfr		$last_principal = $1;
361178825Sdfr		$ip{$2}++;
362178825Sdfr	} elsif (/AS-REQ (.*) from IPv([46]):([0-9\.:a-fA-F]+) for (.*)$/) {
363178825Sdfr		$as_req++;
364178825Sdfr		$as_req_client{$1}++;
365178825Sdfr		$as_req_server{$4}++;
366178825Sdfr		$as_req_addr{$3}++;
367178825Sdfr		$as_req_addr_nonlocal{$3}++ if (!islocaladdr($3));
368178825Sdfr		$last_addr = $3;
369178825Sdfr		$last_principal = $1;
370178825Sdfr		$ip{$2}++;
371178825Sdfr	} elsif (/TGS-REQ \(krb4\)/) {
372178825Sdfr		#Nothing
373178825Sdfr	} elsif (/TGS-REQ (.+) from IPv([46]):([0-9\.:a-fA-F]+) for (.*?)( \[.*\]){0,1}$/) {
374178825Sdfr		$tgs_req++;
375178825Sdfr		$tgs_req_client{$1}++;
376178825Sdfr		$tgs_req_server{$4}++;
377178825Sdfr		$tgs_req_addr{$3}++;
378178825Sdfr		$tgs_req_addr_nonlocal{$3}++ if (!islocaladdr($3));
379178825Sdfr		$last_addr = $3;
380178825Sdfr		$last_principal = $1;
381178825Sdfr		$ip{$2}++;
382178825Sdfr
383178825Sdfr		my $source = $1;
384178825Sdfr		my $dest = $4;
385178825Sdfr
386178825Sdfr		if (!islocalrealm($source)) {
387178825Sdfr			$tgs_xrealm_in++;
388178825Sdfr			$tgs_xrealm_in_princ{$source}++;
389178825Sdfr			if ($source =~ /[^@]+@([^@]+)/ ) {
390178825Sdfr				$tgs_xrealm_in_realm{$1}++;
391178825Sdfr			}
392178825Sdfr		}
393178825Sdfr		if ($dest =~ /krbtgt\/([^@]+)@[^@]+/) {
394178825Sdfr			if (!islocalrealm($1)) {
395178825Sdfr				$tgs_xrealm_out++;
396178825Sdfr				$tgs_xrealm_out_realm{$1}++;
397178825Sdfr				$tgs_xrealm_out_princ{$source}++;
398178825Sdfr			}
399178825Sdfr		}
400178825Sdfr	} elsif (/524-REQ (.*) from IPv([46]):([0-9\.:a-fA-F]+) for (.*)$/) {
401178825Sdfr		$five24_req++;
402178825Sdfr		$five24_req_client{$1}++;
403178825Sdfr		$five24_req_server{$4}++;
404178825Sdfr		$five24_req_addr{$3}++;
405178825Sdfr		$five24_req_addr_nonlocal{$3}++ if (!islocaladdr($3));
406178825Sdfr		$last_addr = $3;
407178825Sdfr		$last_principal = $1;
408178825Sdfr		$ip{$2}++;
409178825Sdfr	} elsif (/TCP data of strange type from IPv[46]:([0-9\.:a-fA-F]+)/) {
410178825Sdfr		$strange_tcp_data{$1}++;
411178825Sdfr	} elsif (/Lookup (.*) failed: No such entry in the database/) {
412178825Sdfr		$no_such_princ++;
413178825Sdfr		$no_such_princ_addr{$last_addr}++;
414178825Sdfr		$no_such_princ_addr_nonlocal{$last_addr}++ if (!islocaladdr($last_addr));
415178825Sdfr		$no_such_princ_princ{$1}++;
416178825Sdfr	} elsif (/Lookup .* succeeded$/) {
417178825Sdfr		# Nothing
418178825Sdfr	} elsif (/Malformed HTTP request from IPv[46]:([0-9\.:a-fA-F]+)$/) {
419178825Sdfr		$http_malformed++;
420178825Sdfr		$http_malformed_addr{$1}++;
421178825Sdfr	} elsif (/TCP-connection from IPv[46]:([0-9\.:a-fA-F]+) expired after [0-9]+ bytes/) {
422178825Sdfr		$tcp_conn_timeout++;
423178825Sdfr		$tcp_conn_timeout_addr{$1}++;
424178825Sdfr	} elsif (/Failed processing [0-9]+ byte request from IPv[46]:([0-9\.:a-fA-F]+)/) {
425178825Sdfr		$failed_processing++;
426178825Sdfr		$failed_processing_addr{$1}++;
427178825Sdfr	} elsif (/connection closed before end of data after [0-9]+ bytes from IPv[46]:([0-9\.:a-fA-F]+)/) {
428178825Sdfr		$connection_closed++;
429178825Sdfr		$connection_closed_addr{$1}++;
430178825Sdfr	} elsif (/HTTP request from IPv[46]:([0-9\.:a-fA-F]+) is non KDC request/) {
431178825Sdfr		$http_non_kdc++;
432178825Sdfr		$http_non_kdc_addr{$1}++;
433178825Sdfr	} elsif (/returning a referral to realm (.*) for server (.*) that was not found/) {
434178825Sdfr		$referrals++;
435178825Sdfr		$referral_princ{$2}++;
436178825Sdfr		$referral_realm{$1}++;
437178825Sdfr	} elsif (/krb4 Cross-realm (.*) -> (.*) disabled/) {
438178825Sdfr		$v4_cross++;
439178825Sdfr		$v4_cross_realm{$1."->".$2}++;
440178825Sdfr	} elsif (/524 cross-realm (.*) -> (.*) disabled/) {
441178825Sdfr		$v4_cross++;
442178825Sdfr		$v4_cross_realm{$1."->".$2}++;
443178825Sdfr	} elsif (/cross-realm (.*) -> (.*): no transit through realm (.*)/) {
444178825Sdfr	} elsif (/cross-realm (.*) -> (.*) via \[([^\]]+)\]/) {
445178825Sdfr		$v5_cross++;
446178825Sdfr		$v5_cross_realm{$1."->".$2}++;
447178825Sdfr	} elsif (/cross-realm (.*) -> (.*)/) {
448178825Sdfr		$v5_cross++;
449178825Sdfr		$v5_cross_realm{$1."->".$2}++;
450178825Sdfr	} elsif (/sending ([0-9]+) bytes to IPv[46]:([0-9\.:a-fA-F]+)/) {
451178825Sdfr		$bw_addr{$2} += $1;
452178825Sdfr	} elsif (/Using ([-a-z0-9]+)\/([-a-z0-9]+)/) {
453178825Sdfr		$enctype_ticket{$1}++;
454178825Sdfr		$enctype_session{$2}++;
455178825Sdfr
456178825Sdfr		my $ticket = $1;
457178825Sdfr		my $session = $2;
458178825Sdfr
459178825Sdfr		if ($ticket =~ /des-cbc-(crc|md4|md5)/) {
460178825Sdfr			$addr_uses_des{$last_addr}++;
461178825Sdfr			$princ_uses_des{$last_principal}++;
462178825Sdfr		}
463178825Sdfr
464178825Sdfr	} elsif (/Failed to decrypt PA-DATA -- (.+)$/) {
465178825Sdfr		$pa_failed++;
466178825Sdfr		$pa_failed_princ{$last_principal}++;
467178825Sdfr		$pa_failed_addr{$last_addr}++;
468178825Sdfr
469178825Sdfr	} elsif (/Request to forward non-forwardable ticket/) {
470178825Sdfr		$forward_non_forward++;
471178825Sdfr	} elsif (/HTTP request:/) {
472178825Sdfr	} elsif (/krb_rd_req: Incorrect network address/) {
473178825Sdfr	} elsif (/krb_rd_req: Ticket expired \(krb_rd_req\)/) {
474178825Sdfr	} elsif (/Ticket expired \(.*\)/) {
475178825Sdfr	} elsif (/krb_rd_req: Can't decode authenticator \(krb_rd_req\)/) {
476178825Sdfr	} elsif (/Request from wrong address/) {
477178825Sdfr		# XXX
478178825Sdfr	} elsif (/UNKNOWN --/) {
479178825Sdfr		# XXX
480178825Sdfr	} elsif (/Too large time skew -- (.*)$/) {
481178825Sdfr		# XXX
482178825Sdfr	} elsif (/No PA-ENC-TIMESTAMP --/) {
483178825Sdfr		# XXX
484178825Sdfr	} elsif (/Looking for pa-data --/) {
485178825Sdfr		# XXX
486178825Sdfr	} elsif (/Pre-authentication succeded -- (.+)$/) {
487178825Sdfr		# XXX
488178825Sdfr	} elsif (/Bad request for ([,a-zA-Z0-9]+) ticket/) {
489178825Sdfr		# XXX
490178825Sdfr	} elsif (/Failed to verify AP-REQ: Ticket expired/) {
491178825Sdfr		# XXX
492178825Sdfr	} elsif (/Client not found in database:/) {
493178825Sdfr		# XXX
494178825Sdfr	} elsif (/Server not found in database \(krb4\)/) {
495178825Sdfr	} elsif (/Server not found in database:/) {
496178825Sdfr		# XXX
497178825Sdfr	} elsif (/newsyslog.*logfile turned over/) {
498178825Sdfr		# Nothing
499178825Sdfr	} elsif (/Requested flags:/) {
500178825Sdfr		# Nothing
501178825Sdfr	} elsif (/shutting down/) {
502178825Sdfr		# Nothing
503178825Sdfr	} elsif (/listening on IP/) {
504178825Sdfr		# Nothing
505178825Sdfr	} elsif (/commencing operation/) {
506178825Sdfr		$restarts++;
507178825Sdfr	}
508178825Sdfr	#
509178825Sdfr	# Log it if we didn't parse the line
510178825Sdfr	#
511178825Sdfr	else {
512178825Sdfr		print "Unknown log file line: $_";
513178825Sdfr	}
514178825Sdfr}
515178825Sdfr
516178825Sdfrsub topten {
517178825Sdfr	my ($list) = @_;
518178825Sdfr	my @keys;
519178825Sdfr
520178825Sdfr	my $key;
521178825Sdfr
522178825Sdfr	@keys = (sort {$$list{$b} <=> $$list{$a}} (keys %{$list}));
523178825Sdfr	splice @keys, 10;
524178825Sdfr
525178825Sdfr	foreach $key (@keys) {
526178825Sdfr		print "\t\t$key - $$list{$key}\n";
527178825Sdfr	}
528178825Sdfr}
529178825Sdfr
530178825Sdfrsub islocaladdr (\$) {
531178825Sdfr	my ($addr) = @_;
532178825Sdfr	my $net;
533178825Sdfr
534178825Sdfr	foreach $net (@local_networks_re) {
535178825Sdfr		return 1 if ($addr =~ /$net/);
536178825Sdfr	}
537178825Sdfr	return 0;
538178825Sdfr}
539178825Sdfr
540178825Sdfrsub islocalrealm (\$) {
541178825Sdfr	my ($princ) = @_;
542178825Sdfr	my $realm;
543178825Sdfr
544178825Sdfr	foreach $realm (@local_realms) {
545178825Sdfr		return 1 if ($princ eq $realm);
546178825Sdfr		return 1 if ($princ =~ /[^@]+\@${realm}/);
547178825Sdfr	}
548178825Sdfr	return 0;
549178825Sdfr}
550