File Coverage

blib/lib/Net/Frame/Layer/Syslog.pm
Criterion Covered Total %
statement 190 204 93.1
branch 26 46 56.5
condition 6 11 54.5
subroutine 48 49 97.9
pod 9 9 100.0
total 279 319 87.4


line stmt bran cond sub pod time code
1             #
2             # $Id: Syslog.pm 49 2012-11-19 13:15:34Z VinsWorldcom $
3             #
4             package Net::Frame::Layer::Syslog;
5 6     6   169201 use strict; use warnings;
  6     6   12  
  6         157  
  6         22  
  6         20  
  6         302  
6              
7             our $VERSION = '1.05';
8              
9 6     6   2543 use Net::Frame::Layer qw(:consts :subs);
  6         277412  
  6         1397  
10 6     6   60 use Exporter;
  6         7  
  6         860  
11             our @ISA = qw(Net::Frame::Layer Exporter);
12              
13             our %EXPORT_TAGS = (
14             consts => [qw(
15             NF_SYSLOG_FACILITY_KERNEL
16             NF_SYSLOG_FACILITY_USER
17             NF_SYSLOG_FACILITY_MAIL
18             NF_SYSLOG_FACILITY_SYSTEM
19             NF_SYSLOG_FACILITY_SECURITY
20             NF_SYSLOG_FACILITY_INTERNAL
21             NF_SYSLOG_FACILITY_PRINTER
22             NF_SYSLOG_FACILITY_NEWS
23             NF_SYSLOG_FACILITY_UUCP
24             NF_SYSLOG_FACILITY_CLOCK
25             NF_SYSLOG_FACILITY_SECURITY2
26             NF_SYSLOG_FACILITY_FTP
27             NF_SYSLOG_FACILITY_NTP
28             NF_SYSLOG_FACILITY_AUDIT
29             NF_SYSLOG_FACILITY_ALERT
30             NF_SYSLOG_FACILITY_CLOCK2
31             NF_SYSLOG_FACILITY_LOCAL0
32             NF_SYSLOG_FACILITY_LOCAL1
33             NF_SYSLOG_FACILITY_LOCAL2
34             NF_SYSLOG_FACILITY_LOCAL3
35             NF_SYSLOG_FACILITY_LOCAL4
36             NF_SYSLOG_FACILITY_LOCAL5
37             NF_SYSLOG_FACILITY_LOCAL6
38             NF_SYSLOG_FACILITY_LOCAL7
39             NF_SYSLOG_SEVERITY_EMERGENCY
40             NF_SYSLOG_SEVERITY_ALERT
41             NF_SYSLOG_SEVERITY_CRITICAL
42             NF_SYSLOG_SEVERITY_ERROR
43             NF_SYSLOG_SEVERITY_WARNING
44             NF_SYSLOG_SEVERITY_NOTICE
45             NF_SYSLOG_SEVERITY_INFORMATIONAL
46             NF_SYSLOG_SEVERITY_DEBUG
47             )],
48             subs => [qw(
49             priorityAton
50             priorityNtoa
51             )],
52             );
53             our @EXPORT_OK = (
54             @{$EXPORT_TAGS{consts}},
55             @{$EXPORT_TAGS{subs}},
56             );
57              
58 6     6   36 use constant NF_SYSLOG_FACILITY_KERNEL => 0;
  6         8  
  6         363  
59 6     6   29 use constant NF_SYSLOG_FACILITY_USER => 1;
  6         8  
  6         302  
60 6     6   25 use constant NF_SYSLOG_FACILITY_MAIL => 2;
  6         9  
  6         293  
61 6     6   23 use constant NF_SYSLOG_FACILITY_SYSTEM => 3;
  6         8  
  6         273  
62 6     6   35 use constant NF_SYSLOG_FACILITY_SECURITY => 4;
  6         8  
  6         246  
63 6     6   107 use constant NF_SYSLOG_FACILITY_INTERNAL => 5;
  6         9  
  6         287  
64 6     6   37 use constant NF_SYSLOG_FACILITY_PRINTER => 6;
  6         7  
  6         272  
65 6     6   24 use constant NF_SYSLOG_FACILITY_NEWS => 7;
  6         7  
  6         280  
66 6     6   26 use constant NF_SYSLOG_FACILITY_UUCP => 8;
  6         5  
  6         264  
67 6     6   30 use constant NF_SYSLOG_FACILITY_CLOCK => 9;
  6         7  
  6         323  
68 6     6   24 use constant NF_SYSLOG_FACILITY_SECURITY2 => 10;
  6         8  
  6         294  
69 6     6   20 use constant NF_SYSLOG_FACILITY_FTP => 11;
  6         6  
  6         283  
70 6     6   24 use constant NF_SYSLOG_FACILITY_NTP => 12;
  6         6  
  6         258  
71 6     6   22 use constant NF_SYSLOG_FACILITY_AUDIT => 13;
  6         9  
  6         326  
72 6     6   35 use constant NF_SYSLOG_FACILITY_ALERT => 14;
  6         9  
  6         281  
73 6     6   31 use constant NF_SYSLOG_FACILITY_CLOCK2 => 15;
  6         6  
  6         272  
74 6     6   24 use constant NF_SYSLOG_FACILITY_LOCAL0 => 16;
  6         8  
  6         255  
75 6     6   21 use constant NF_SYSLOG_FACILITY_LOCAL1 => 17;
  6         6  
  6         251  
76 6     6   24 use constant NF_SYSLOG_FACILITY_LOCAL2 => 18;
  6         8  
  6         261  
77 6     6   24 use constant NF_SYSLOG_FACILITY_LOCAL3 => 19;
  6         7  
  6         332  
78 6     6   24 use constant NF_SYSLOG_FACILITY_LOCAL4 => 20;
  6         7  
  6         272  
79 6     6   24 use constant NF_SYSLOG_FACILITY_LOCAL5 => 21;
  6         6  
  6         254  
80 6     6   22 use constant NF_SYSLOG_FACILITY_LOCAL6 => 22;
  6         13  
  6         274  
81 6     6   31 use constant NF_SYSLOG_FACILITY_LOCAL7 => 23;
  6         8  
  6         326  
82 6     6   21 use constant NF_SYSLOG_SEVERITY_EMERGENCY => 0;
  6         5  
  6         258  
83 6     6   25 use constant NF_SYSLOG_SEVERITY_ALERT => 1;
  6         7  
  6         255  
84 6     6   25 use constant NF_SYSLOG_SEVERITY_CRITICAL => 2;
  6         74  
  6         289  
85 6     6   22 use constant NF_SYSLOG_SEVERITY_ERROR => 3;
  6         5  
  6         224  
86 6     6   21 use constant NF_SYSLOG_SEVERITY_WARNING => 4;
  6         14  
  6         283  
87 6     6   24 use constant NF_SYSLOG_SEVERITY_NOTICE => 5;
  6         6  
  6         288  
88 6     6   24 use constant NF_SYSLOG_SEVERITY_INFORMATIONAL => 6;
  6         28  
  6         334  
89 6     6   24 use constant NF_SYSLOG_SEVERITY_DEBUG => 7;
  6         7  
  6         738  
90              
91             our @FACILITY = qw(kernel user mail system security internal printer news uucp clock security2 FTP NTP audit alert clock2 local0 local1 local2 local3 local4 local5 local6 local7);
92             our @SEVERITY = qw(Emergency Alert Critical Error Warning Notice Informational Debug);
93              
94             our @AS = qw(
95             facility
96             severity
97             timestamp
98             host
99             tag
100             content
101             msg
102             );
103             __PACKAGE__->cgBuildIndices;
104             __PACKAGE__->cgBuildAccessorsScalar(\@AS);
105              
106             #no strict 'vars';
107              
108 6     6   3187 use Sys::Hostname;
  6         5695  
  6         8127  
109              
110             $Net::Frame::Layer::UDP::Next->{514} = "Syslog";
111              
112             sub new {
113 3     3 1 1492 my $time = _getTime();
114 3         7 my $host = _getHost();
115 3         37 my $tag = _getTag();
116              
117             shift->SUPER::new(
118 3         32 facility => NF_SYSLOG_FACILITY_LOCAL7,
119             severity => NF_SYSLOG_SEVERITY_INFORMATIONAL,
120             timestamp => $time,
121             host => $host,
122             tag => $tag,
123             content => 'syslog message',
124             @_,
125             );
126             }
127              
128             sub message {
129 1     1 1 16 my $time = _getTime();
130 1         2 my $host = _getHost();
131 1         5 my $tag = _getTag();
132              
133             shift->SUPER::new(
134 1         7 msg => "<190>$time $host $tag syslog message",
135             @_,
136             );
137             }
138              
139             sub getLength {
140 0     0 1 0 my $self = shift;
141              
142 0 0       0 if (defined($self->msg)) {
143 0         0 return length($self->msg)
144             } else {
145              
146 0         0 my $priority = priorityAton($self->facility, $self->severity);
147 0         0 my $len =
148             length($priority) +
149             length($self->timestamp) +
150             length($self->host) +
151             length($self->tag) +
152             length($self->content) +
153             5;
154              
155 0         0 return $len
156             }
157             }
158              
159             sub pack {
160 3     3 1 680 my $self = shift;
161              
162 3         3 my $raw;
163 3 100       11 if (defined($self->msg)) {
164 1 50       14 $raw = $self->SUPER::pack('a*',
165             $self->msg
166             ) or return;
167             } else {
168 2         39 my $priority = priorityAton($self->facility, $self->severity);
169              
170 2 50       11 $raw = $self->SUPER::pack('a*',
171             "<" .
172             $priority .
173             ">" .
174             $self->timestamp .
175             " " .
176             $self->host .
177             " " .
178             $self->tag .
179             " " .
180             $self->content
181             ) or return;
182             }
183              
184 3         133 return $self->raw($raw);
185             }
186              
187             sub unpack {
188 1     1 1 10 my $self = shift;
189              
190 1 50       4 my ($payload) =
191             $self->SUPER::unpack('a*', $self->raw)
192             or return;
193              
194 1         26 my $regex = '<(\d{1,3})>[\d{1,}: \*]*((?:[JFMASONDjfmasond]\w\w) {1,2}(?:\d+)(?: \d{4})? (?:\d{2}:\d{2}:\d{2}[\.\d{1,3}]*)(?: [A-Z]{1,3}:)?)?:?\s*(?:((?:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})|(?:[a-zA-Z0-9\-]+)|(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}(?:[0-9A-Fa-f]{1,4}|:))|(?:(?:[0-9A-Fa-f]{1,4}:){6}(?::[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){5}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){4}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,3})|(?:(?::[0-9A-Fa-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9A-Fa-f]{1,4}:){3}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,4})|(?:(?::[0-9A-Fa-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9A-Fa-f]{1,4}:){2}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,5})|(?:(?::[0-9A-Fa-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9A-Fa-f]{1,4}:){1}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,6})|(?:(?::[0-9A-Fa-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9A-Fa-f]{1,4}){1,7})|(?:(?::[0-9A-Fa-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?) )?(.*)';
195             # my $regex = '<(\d{1,3})>[\d{1,}: \*]*((?:[JFMASONDjfmasond]\w\w) {1,2}(?:\d+)(?: \d{4})* (?:\d{2}:\d{2}:\d{2}[\.\d{1,3}]*)(?: [A-Z]{1,3})*)?:*\s*(?:((?:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})|(?:[a-zA-Z\-]+)|(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}(?:[0-9A-Fa-f]{1,4}|:))|(?:(?:[0-9A-Fa-f]{1,4}:){6}(?::[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){5}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){4}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,3})|(?:(?::[0-9A-Fa-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9A-Fa-f]{1,4}:){3}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,4})|(?:(?::[0-9A-Fa-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9A-Fa-f]{1,4}:){2}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,5})|(?:(?::[0-9A-Fa-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9A-Fa-f]{1,4}:){1}(?:(?:(?::[0-9A-Fa-f]{1,4}){1,6})|(?:(?::[0-9A-Fa-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9A-Fa-f]{1,4}){1,7})|(?:(?::[0-9A-Fa-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?) )?(.*)';
196 1         253 my $Cregex = qr/$regex/;
197              
198 1 50       18 if ($payload =~ /$Cregex/) {
199              
200 1         3 my $priority = $1;
201 1   50     4 my $timestamp = $2 || '0';
202 1   50     4 my $hostname = $3 || '0';
203 1         3 my $message = $4;
204 1         2 my ($facility, $severity) = priorityNtoa($priority);
205              
206 1         8 $self->facility($facility);
207 1         11 $self->severity($severity);
208 1         8 $self->timestamp($timestamp);
209              
210 1         7 $hostname =~ s/\s+//;
211 1         2 $self->host($hostname);
212              
213 1         6 my %chars;
214 1         4 $chars{bracket} = index($message,"]");
215 1         2 $chars{colon} = index($message,":");
216 1         2 $chars{space} = index($message," ");
217 1         9 my $win = 0;
218 1         5 foreach my $ch (sort {$chars{$b} cmp $chars{$a}} keys %chars) {
  3         7  
219 3 100       7 if ($chars{$ch} > 0) {
220 2         3 $win = $ch
221             }
222             }
223 1 50       4 if ($chars{$win} > 0) {
224 1   50     4 my $tag = substr($message, 0, $chars{$win}+1) || '0';
225 1   50     3 my $content = substr($message, $chars{$win}+1) || '0';
226 1         4 $self->tag($tag);
227 1         8 $self->content($content)
228             } else {
229 0         0 $self->tag('0');
230 0         0 $self->content($message)
231             }
232              
233 1         8 my $msg = substr $payload, index($payload,">")+1;
234 1         2 $self->msg($msg)
235              
236             } else {
237 0         0 $self->facility(undef);
238 0         0 $self->severity(undef);
239 0         0 $self->content(undef);
240 0         0 $self->msg($payload)
241             }
242              
243 1         10 return $self;
244             }
245              
246             sub encapsulate {
247 1     1 1 4 my $self = shift;
248              
249 1 50       5 return $self->nextLayer if $self->nextLayer;
250              
251             # Needed?
252 1 50       13 if ($self->payload) {
253 0         0 return 'Syslog';
254             }
255              
256 1         10 NF_LAYER_NONE;
257             }
258              
259             sub print {
260 3     3 1 414 my $self = shift;
261              
262 3         20 my $l = $self->layer;
263 3         51 my $buf;
264              
265 3 100 66     10 if (defined($self->facility) && defined($self->severity)) {
266 2 50       60 $buf = sprintf
    50          
267             "$l: facility:%d %s severity:%d %s\n",
268             $self->facility,
269             (defined $FACILITY[$self->facility]) ? "($FACILITY[$self->facility])" : '',
270             $self->severity,
271             (defined $SEVERITY[$self->severity]) ? "($SEVERITY[$self->severity])" : '';
272             }
273              
274 3 100       106 if (not defined($self->content)) {
275 1         20 $buf .= sprintf
276             "$l: message:%s",
277             $self->msg;
278             } else {
279 2         43 $buf .= sprintf
280             "$l: timestamp:%s host:%s\n".
281             "$l: tag:%s\n".
282             "$l: content:%s",
283             $self->timestamp, $self->host,
284             $self->tag,
285             $self->content;
286             }
287              
288 3         622 return $buf;
289             }
290              
291             ####
292              
293             sub priorityAton {
294 3     3 1 52 my ($fac, $sev) = @_;
295              
296 3 50       13 return undef if not defined $sev;
297 3         8 return (($fac << 3) | $sev)
298             }
299              
300             sub priorityNtoa {
301 3     3 1 803 my ($pri, $flag) = @_;
302              
303 3 50       9 return undef if not defined $pri;
304 3         9 my $sev = $pri % 8;
305 3         7 my $fac = ($pri - $sev) / 8;
306              
307 3 100       9 if (defined($flag)) {
308 1         6 return ($FACILITY[$fac], $SEVERITY[$sev])
309             } else {
310 2         7 return ($fac, $sev)
311             }
312             }
313              
314             sub _getTime {
315 4     4   20 my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
316 4         105 my @time = localtime();
317 4 50       54 my $ts =
    50          
    50          
    50          
318             $month[ $time[4] ] . " "
319             . ( ( $time[3] < 10 ) ? ( " " . $time[3] ) : $time[3] ) . " "
320             . ( ( $time[2] < 10 ) ? ( "0" . $time[2] ) : $time[2] ) . ":"
321             . ( ( $time[1] < 10 ) ? ( "0" . $time[1] ) : $time[1] ) . ":"
322             . ( ( $time[0] < 10 ) ? ( "0" . $time[0] ) : $time[0] );
323              
324 4         12 return $ts
325             }
326              
327             sub _getHost {
328 4     4   11 return Sys::Hostname::hostname;
329             }
330              
331             sub _getTag {
332 4     4   8 my $name = $0;
333 4 50       26 if ($name =~ /.+\/(.+)/) {
    0          
334 4         11 $name = $1;
335             } elsif ($name =~ /.+\\(.+)/) {
336 0         0 $name = $1;
337             }
338              
339 4         36 return $name . "[" . $$ . "]"
340             }
341              
342             1;
343              
344             __END__