File Coverage

blib/lib/BGPmon/Translator/XFB2PerlHash/Simpler.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package BGPmon::Translator::XFB2PerlHash::Simpler;
2 1     1   52113 use strict;
  1         2  
  1         49  
3 1     1   7 use warnings;
  1         3  
  1         37  
4 1     1   6 use constant FALSE => 0;
  1         2  
  1         99  
5 1     1   5 use constant TRUE => 1;
  1         2  
  1         62  
6 1     1   712 use BGPmon::Translator::XFB2BGPdump qw(translate_message);
  0            
  0            
7             use List::MoreUtils qw(uniq);
8              
9              
10             BEGIN{
11             require Exporter;
12             our $VERSION = '2.00';
13             our $AUTOLOAD;
14             our @ISA = qw(Exporter);
15             our @EXPORT_OK = qw(
16             get_error_msg get_error_code parse_xml_msg
17             extract_sender_addr extract_sender_port extract_sender_asn
18             extract_withdraw extract_nlri extract_mpreach_nlri
19             extract_mpunreach_nlri extract_aspath extract_as4path
20             extract_origin);
21             }
22              
23              
24             # Variables to keep parsed data in
25             my $msgHash = undef;;
26              
27              
28             # Variables to hold error codes and messages
29             my %error_code = ();
30             my %error_msg = ();
31              
32             use constant NO_ERROR_CODE => 0;
33             use constant NO_ERROR_MSG => 'No Error. Relax with some tea.';
34              
35             use constant NO_MESSAGE_GIVEN => 200;
36             use constant NO_MESSAGE_GIVEN_MSG => "There was no XML message given.";
37             use constant BLANK_MESSAGE_GIVEN => 201;
38             use constant BLANK_MESSAGE_GIVEN_MSG => "The XML message given was blank.";
39              
40              
41             =head1 NAME
42              
43             BGPmon::Translator::XFB2PerlHash::Simpler - a cleaner interface to extract
44             commonly-used information from XFB messages that, unline XFB2PerlHash::Simple,
45             will ignore xml attributes.
46              
47             =head1 SYNOPSIS
48              
49             use BGPmon::Translator::XFB2PerlHash::Simpler;
50              
51             my $xml_message = "...
52              
53             if(BGPmon::Translator::XFB2PerlHash::Simpler::parse_xml_msg($xml_message)){
54              
55             print BGPmon::Translator::SFB2PerlHash::get_error_msg('parse_xml_msg')."\n";
56              
57             exit 1;
58              
59             }
60              
61             my @withdrawn_prefixes = BGPmon::Translator::XFB2PerlHash::get_withdraw();
62              
63             foreach(@withdrawn_prefixes){
64              
65             ...
66              
67             }
68              
69             my $peer_address = BGPmon::Translator::XFB2PerlHash::extract_sender_addr();
70              
71             print "Seen at peer $peer_address\n";
72              
73             =head1 EXPORT
74              
75             get_error_msg get_error_code parse_xml_msg extract_sender_addr
76             extract_sender_port extract_sender_asn extract_withdraw extract_nlri
77             extract_mpreach_nlri extract_mpunreach_nlri extract_aspath extract_as4path
78             extract_origin
79              
80              
81              
82              
83             =head1 SUBROUTINES/METHODS
84              
85              
86             =head2 get_error_msg
87              
88             Will return the error message of the given function name.
89              
90             Input: A string that contains the function name where an error occured.
91              
92             Output: The message which represents the error stored from that function.
93              
94             =cut
95             sub get_error_msg{
96             my $str = shift;
97             my $fname = 'get_error_msg';
98             my $toReturn = $error_msg{$str};
99             return $toReturn;
100             }
101              
102             =head2 get_error_code
103              
104             Will return the error code of the given function name.
105              
106             Input: A string that represents the function name where an error occured.
107              
108             Output: The code which represents the error stored from that function.
109              
110             =cut
111             sub get_error_code{
112             my $str = shift;
113             my $fname = 'get_error_code';
114             my $toReturn = $error_code{$str};
115             return $toReturn;
116             }
117              
118              
119             #comment
120             #
121             #Will reset the most recently filtered prefixes and AS numbers, parse the
122             #message that was sent to it, and store a unique set of prefixes and
123             #AS numbers.
124             #
125             #cut
126             =head2 parse_xml_msg
127              
128             Will translate an XML message from a string to a perl hash
129              
130             Input: An XML string from a BGPmon source
131              
132             Output: 0 if parsing completed successfully
133              
134             =cut
135             sub parse_xml_msg{
136              
137             my $fname = 'parse_xml_msg';
138             my $xmlMsg = shift;
139              
140             if(!defined($xmlMsg)){
141             $error_code{$fname} = NO_MESSAGE_GIVEN;
142             $error_msg{$fname} = NO_MESSAGE_GIVEN_MSG;
143             return 1;
144             }
145              
146             if($xmlMsg eq ""){
147             $error_code{$fname} = BLANK_MESSAGE_GIVEN;
148             $error_msg{$fname} = BLANK_MESSAGE_GIVEN_MSG;
149             return 1;
150             }
151              
152             $msgHash = BGPmon::Translator::XFB2PerlHash::translate_msg($xmlMsg);
153              
154             $error_code{$fname} = NO_ERROR_CODE;
155             $error_msg{$fname} = NO_ERROR_MSG;
156              
157             return 0;
158             }
159              
160              
161             =head2 extract_sender_addr
162              
163             Will extract a sender's IP address from the parsed XML mesage.
164              
165             Input: None
166              
167             Output: IPv4/6 Address if successful; undef if not.
168              
169             =cut
170             sub extract_sender_addr{
171              
172             my $fname = 'extract_sender_addr';
173             my $hashRes = BGPmon::Translator::XFB2PerlHash::get_content(
174             '/BGP_MONITOR_MESSAGE/SOURCE/ADDRESS/content');
175             $error_code{$fname} = NO_ERROR_CODE;
176             $error_msg{$fname} = NO_ERROR_MSG;
177             return $hashRes;
178             }
179              
180             =head2 extract_sender_port
181              
182             Will extract a sender's port number from the parsed XML mesage.
183              
184             Input: None
185              
186             Output: Port number if successful; undef if not.
187              
188             =cut
189             sub extract_sender_port{
190              
191             my $fname = 'extract_sender_port';
192             my $hashRes = BGPmon::Translator::XFB2PerlHash::get_content(
193             '/BGP_MONITOR_MESSAGE/SOURCE/PORT/content');
194             $error_code{$fname} = NO_ERROR_CODE;
195             $error_msg{$fname} = NO_ERROR_MSG;
196             return $hashRes;
197              
198             }
199              
200             =head2 extract_sender_asn
201              
202             Will extract a sender's ASN number from the parsed XML mesage.
203              
204             Input: None
205              
206             Output: ASN number if successful; undef if not.
207              
208             =cut
209             sub extract_sender_asn{
210              
211             my $fname = 'extract_sender_asn';
212             my $hashRes2 = BGPmon::Translator::XFB2PerlHash::get_content(
213             '/BGP_MONITOR_MESSAGE/SOURCE/ASN2/content');
214             my $hashRes4 = BGPmon::Translator::XFB2PerlHash::get_content(
215             '/BGP_MONITOR_MESSAGE/SOURCE/ASN4/content');
216             $error_code{$fname} = NO_ERROR_CODE;
217             $error_msg{$fname} = NO_ERROR_MSG;
218              
219             if(defined($hashRes2) and $hashRes2 ne ""){
220             return $hashRes2;
221             }
222             elsif(defined($hashRes4) and $hashRes4 ne ""){
223             return $hashRes4;
224             }
225             else{
226             return undef;
227             }
228             }
229              
230              
231             =head2 extract_withdraw
232              
233             Will extract all the withdrawn prefixes from the parsed XML mesage.
234              
235             Input: None
236              
237             Output: Array of IPv4/6 prefixes that were seen to have been withdrawn.
238              
239             =cut
240             sub extract_withdraw{
241              
242             my $fname = 'extract_withdarw';
243             $error_code{$fname} = NO_ERROR_CODE;
244             $error_msg{$fname} = NO_ERROR_MSG;
245              
246             #Getting Withdraws
247             my @with_prefs = ();
248             my $hashRes = BGPmon::Translator::XFB2PerlHash::get_content(
249             '/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:WITHDRAW/');
250              
251             if(ref($hashRes) eq "ARRAY"){
252             foreach my $res (@$hashRes){
253             push(@with_prefs, $res->{'content'});
254             }
255             }
256             elsif(ref($hashRes) eq "HASH"){
257             push(@with_prefs, $hashRes->{'content'});
258             }
259              
260             #Uniqueing
261             @with_prefs = uniq(@with_prefs);
262            
263             return @with_prefs;
264             }
265              
266             =head2 extract_nlri
267              
268             Will extract all the prefixes in NLRI areas from the parsed XML mesage.
269              
270             Input: None
271              
272             Output: Array of IPv4 prefixes that were seen in NLRIs.
273              
274             =cut
275             sub extract_nlri{
276              
277             my $fname = 'extract_nlri';
278             $error_code{$fname} = NO_ERROR_CODE;
279             $error_msg{$fname} = NO_ERROR_MSG;
280            
281             #Getting NLRI's
282             my @nlris = ();
283              
284             #Getting NLRI announcements
285             my @nlri_prefs = ();
286             my $hashRes = BGPmon::Translator::XFB2PerlHash::get_content(
287             '/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:NLRI/');
288              
289             if(ref($hashRes) eq "ARRAY"){
290             foreach my $res (@$hashRes){
291             push(@nlris, $res->{'content'});
292             }
293             }
294             elsif(ref($hashRes) eq "HASH"){
295             push(@nlris, $hashRes->{'content'});
296             }
297              
298             #Uniqueing
299             @nlris = uniq(@nlris);
300              
301             return @nlris;
302             }
303              
304             =head2 extract_mpreach_nlri
305              
306             Will extract all the IPv4/6 prefixes announced in MP_REACH_NLRI's from
307             the parsed XML mesage. This will exclude the MP_REACH NEXT_HOP.
308              
309             Input: None
310              
311             Output: Array of IPv4/6 prefixes that were seen in MP_REACH_NLRI's
312              
313             =cut
314             sub extract_mpreach_nlri{
315              
316             my $fname = 'extract_mpreach_nlri';
317             $error_code{$fname} = NO_ERROR_CODE;
318             $error_msg{$fname} = NO_ERROR_MSG;
319              
320             #Getting mp_reach_nlris
321             my @mpnlri_prefs = ();
322             my $hashRes = BGPmon::Translator::XFB2PerlHash::get_content(
323             '/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:MP_REACH_NLRI/bgp:MP_NLRI/');
324            
325             if(ref($hashRes) eq "ARRAY"){
326             foreach my $res (@$hashRes){
327             push(@mpnlri_prefs, $res->{'content'});
328             }
329             }
330             elsif(ref($hashRes) eq "HASH"){
331             push(@mpnlri_prefs, $hashRes->{'content'});
332             }
333            
334             #Uniqueing
335             @mpnlri_prefs = uniq(@mpnlri_prefs);
336              
337             return @mpnlri_prefs;
338             }
339              
340             =head2 extract_mpunreach_nlri
341              
342             Will extract all the IPv4/6 prefixes withdrawn in MP_UNREACH_NLRI's from
343             the parsed XML mesage.
344              
345             Input: None
346              
347             Output: Array of IPv4/6 prefixes that were seen in MP_UNREACH_NLRI's
348              
349             =cut
350             sub extract_mpunreach_nlri{
351              
352             my $fname = 'extract_mpunreach_nlri';
353             $error_code{$fname} = NO_ERROR_CODE;
354             $error_msg{$fname} = NO_ERROR_MSG;
355              
356             #Getting mp_unreach_nlris
357             my @toReturn = ();
358             my $hashRes = BGPmon::Translator::XFB2PerlHash::get_content(
359             '/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:MP_UNREACH_NLRI/bgp:MP_NLRI/');
360            
361             if(ref($hashRes) eq "ARRAY"){
362             foreach my $res (@$hashRes){
363             push(@toReturn, $res->{'content'});
364             }
365             }
366             elsif(ref($hashRes) eq "HASH"){
367             push(@toReturn,$hashRes->{'content'});
368             }
369              
370             #Uniquing
371             @toReturn = uniq(@toReturn);
372              
373             return @toReturn;
374             }
375              
376              
377             =head2 extract_aspath
378              
379             Will extract all the ASNs found in either AS_PATH/AS_SET or AS_PATH/AS_SEQUENCE
380             from the parsed XML mesage.
381              
382             Input: None
383              
384             Output: Array of ASNs found in the AS_PATH path attribute.
385              
386             =cut
387             sub extract_aspath{
388             my $fname = 'extract_aspath';
389             $error_code{$fname} = NO_ERROR_CODE;
390             $error_msg{$fname} = NO_ERROR_MSG;
391              
392             #Checking for AS numbers in the AS_Path attribute
393             my @toReturn = ();
394             my $hashRes = BGPmon::Translator::XFB2PerlHash::get_content(
395             '/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:AS_PATH/bgp:AS_SEQUENCE/bgp:ASN2/');
396             if(ref($hashRes) eq "ARRAY"){
397             foreach my $res (@$hashRes){
398             push(@toReturn, $res->{'content'});
399             }
400             }
401             elsif(ref($hashRes) eq "HASH"){
402             push(@toReturn,$hashRes->{'content'});
403             }
404              
405             #If we have the data already, return!
406             my $size = scalar(@toReturn);
407             return @toReturn if($size !=0);
408              
409             $hashRes = BGPmon::Translator::XFB2PerlHash::get_content(
410             '/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:AS_PATH/bgp:AS_SEQUENCE/bgp:ASN4/');
411            
412             if(ref($hashRes) eq "ARRAY"){
413             foreach my $res (@$hashRes){
414             push(@toReturn, $res->{'content'});
415             }
416             }
417             elsif(ref($hashRes) eq "HASH"){
418             push(@toReturn,$hashRes->{'content'});
419             }
420              
421             return @toReturn;
422             }
423              
424             =head2 extract_as4path
425              
426             Will extract all the ASNs found in either AS4_PATH/AS_SET or
427             AS4_PATH/AS_SEQUENCE from the parsed XML mesage.
428              
429             Input: None
430              
431             Output: Array of ASNs found in the AS4_PATH path attribute.
432              
433             =cut
434             sub extract_as4path{
435             my $fname = 'extract_as4path';
436             $error_code{$fname} = NO_ERROR_CODE;
437             $error_msg{$fname} = NO_ERROR_MSG;
438             my @areas = (
439             "/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:AS4_PATH/bgp:AS_SEQUENCE/bgp:ASN2/",
440             "/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:AS4_PATH/bgp:AS_SEQUENCE/bgp:ASN4/",
441             "/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:AS4_PATH/bgp:AS4_SEQUENCE/bgp:ASN2/",
442             "/BGP_MONITOR_MESSAGE/bgp:UPDATE/bgp:AS4_PATH/bgp:AS4_SEQUENCE/bgp:ASN4/");
443            
444              
445             my @toReturn = ();
446             foreach(@areas){
447             my $hashRes = BGPmon::Translator::XFB2PerlHash::get_content($_);
448              
449             if(ref($hashRes) eq "ARRAY"){
450             foreach my $res (@$hashRes){
451             push(@toReturn, $res->{'content'});
452             }
453             }
454             elsif(ref($hashRes) eq "HASH"){
455             push(@toReturn,$hashRes->{'content'});
456             }
457              
458             #if we have the data, return it!
459             my $size = scalar(@toReturn);
460             return @toReturn if($size > 0);
461             }
462             return @toReturn;
463             }
464              
465              
466             =head2 extract_origin
467              
468             Will extract the ASN where the message was announced
469             from within the parsed XML mesage.
470              
471             Input: None
472              
473             Output: The ASN of the origin AS; undef if there is none.
474              
475             =cut
476             sub extract_origin{
477             my $fname = 'extract_origin';
478             $error_code{$fname} = NO_ERROR_CODE;
479             $error_msg{$fname} = NO_ERROR_MSG;
480              
481             my @aspath = extract_aspath();
482             if(scalar(@aspath) == 0){
483             @aspath = extract_as4path();
484             }
485             if(scalar(@aspath) == 0){
486             return undef;
487             }
488              
489             return $aspath[-1];
490             }
491              
492              
493             1;
494             __END__