File Coverage

blib/lib/Net/SinFP3/Global.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             #
2             # $Id: Global.pm 2234 2014-04-08 13:05:14Z gomor $
3             #
4             package Net::SinFP3::Global;
5 1     1   654 use strict;
  1         1  
  1         45  
6 1     1   5 use warnings;
  1         1  
  1         37  
7              
8 1     1   58 use base qw(Class::Gomor::Array);
  1         2  
  1         197  
9             our @AS = qw(
10             log
11             job
12             next
13             input
14             db
15             mode
16             search
17             output
18              
19             target
20             targetIp
21             targetIpAsInt
22             targetReverse
23             targetList
24             targetListAsInt
25             targetCount
26             targetSubnet
27             targetHostname
28              
29             port
30             portList
31             portCount
32              
33             ipv6
34             jobs
35             macLookup
36             dnsReverse
37             worker
38             device
39             retry
40             timeout
41             pps
42             ip
43             ip6
44             mac
45             srcPort
46             subnet
47             subnet6
48             gatewayIp
49             gatewayIp6
50             gatewayMac
51             threshold
52             bestScore
53              
54             cacheArp
55             cacheDnsReverse
56             cacheDnsResolve
57              
58             data
59             );
60             our @AA = qw(
61             result
62             );
63             __PACKAGE__->cgBuildIndices;
64             __PACKAGE__->cgBuildAccessorsScalar(\@AS);
65             __PACKAGE__->cgBuildAccessorsArray (\@AA);
66              
67 1     1   7 use File::Glob ':globally';
  1         2  
  1         76  
68 1     1   1607 use IO::Socket::INET;
  1         22216  
  1         10  
69 1     1   1566 use IO::Socket::INET6;
  1         6496  
  1         11  
70 1     1   2903 use Net::Frame::Device;
  0            
  0            
71             use Net::Frame::Dump::Offline;
72             use Net::Frame::Dump::Online2;
73             use Net::Frame::Dump::Writer;
74             use Net::Frame::Layer qw(:subs);
75             use Net::Frame::Simple;
76             use Net::Netmask;
77             use Net::Write::Layer2;
78             use Net::Write::Layer3;
79             use Socket;
80             use Socket6 qw(inet_pton NI_NUMERICHOST NI_NUMERICSERV getnameinfo getaddrinfo);
81              
82             sub new {
83             my $self = shift->SUPER::new(
84             job => 0,
85             ipv6 => 0,
86             macLookup => 1,
87             dnsReverse => 0,
88             jobs => 10,
89             retry => 3,
90             timeout => 3,
91             pps => 200,
92             worker => 'Fork',
93             srcPort => 31337,
94             threshold => 0,
95             bestScore => 0,
96             port => 'top10',
97             targetReverse => 'unknown',
98             targetHostname => 'unknown',
99             result => [],
100             cacheArp => {},
101             @_,
102             );
103              
104             if (!defined($self->log)) {
105             die("[-] ".__PACKAGE__.": You must provide a log object\n");
106             }
107             my $log = $self->log;
108              
109             my $dev;
110             if ($self->target) {
111             my $ip = $self->_parseTarget;
112              
113             my %args = ();
114             $self->ipv6 ? ($args{target6} = $ip) : ($args{target} = $ip);
115             $self->device ? ($args{dev} = $self->device) : ();
116             $dev = Net::Frame::Device->new(%args);
117             if (!defined($dev)) {
118             $log->fatal("Unable to acquire device information from target [".
119             $self->target."]");
120             }
121             }
122             elsif ($self->device) {
123             $dev = Net::Frame::Device->new(dev => $self->device);
124             if (!defined($dev)) {
125             $log->fatal("Unable to acquire device information from device [".
126             $self->device."]");
127             }
128             }
129             else {
130             $dev = Net::Frame::Device->new;
131             if (!defined($dev)) {
132             $log->warning("Unable to get default device information");
133             }
134             }
135              
136             $self->_parsePort;
137              
138             $self->device($dev->dev) if !$self->device && $dev->dev;
139             $self->ip($dev->ip) if !$self->ip && $dev->ip;
140             $self->ip6($dev->ip6) if !$self->ip6 && $dev->ip6;
141             $self->mac($dev->mac) if !$self->mac && $dev->mac;
142             $self->subnet($dev->subnet) if !$self->subnet && $dev->subnet;
143             $self->gatewayIp($dev->gatewayIp) if !$self->gatewayIp && $dev->gatewayIp;
144             $self->gatewayIp6($dev->gatewayIp6) if !$self->gatewayIp6
145             && $dev->gatewayIp6;
146             $self->gatewayMac($dev->gatewayMac) if !$self->gatewayMac
147             && $dev->gatewayMac;
148              
149             $log->verbose("dev: ".$self->device) if $self->device;
150             $log->verbose("ip: ".$self->ip) if $self->ip;
151             $log->verbose("ip6: ".$self->ip6) if $self->ip6;
152             $log->verbose("mac: ".$self->mac) if $self->mac;
153             $log->verbose("subnet: ".$self->subnet) if $self->subnet;
154             $log->verbose("gatewayIp: ".$self->gatewayIp) if $self->gatewayIp;
155             $log->verbose("gatewayIp6: ".$self->gatewayIp6) if $self->gatewayIp6;
156             $log->verbose("gatewayMac: ".$self->gatewayMac) if $self->gatewayMac;
157              
158             return $self;
159             }
160              
161             sub _parseTarget {
162             my $self = shift;
163              
164             my $log = $self->log;
165              
166             my $target = $self->target;
167             if (! $target) {
168             return 1;
169             }
170              
171             # Possible formats
172             # FQDN => 0
173             # SUBNET => 1
174             # IP/32 => 2
175             # IP => 2
176              
177             $target =~ s/\/32$//;
178             $self->target($target);
179              
180             my $format = 0; # FQDN format by default
181             if ($target =~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/\d+$/) {
182             $format = 1; # Subnet format
183             }
184             elsif ($target =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) {
185             $format = 2; # Single IP format
186             }
187              
188             my $ip;
189             if ($format == 0) { # FQDN format
190             $ip = $self->getHostAddr(host => $target)
191             or $log->fatal("Unable to resolve target hostname: [$target]");
192              
193             $self->targetHostname($target);
194             $self->targetIp($ip);
195             $self->targetCount(1);
196             $self->targetList([ $ip ]);
197              
198             my $ipAsInt = $self->ipToInt(ip => $ip) or return;
199             $self->targetIpAsInt($ipAsInt);
200             $self->targetListAsInt([ $ipAsInt ]);
201             }
202             elsif ($format == 1) { # Subnet format
203             if ($self->ipv6) {
204             $log->fatal("IPv6 subnet scanning not supported (yet): [$target]");
205             }
206             else {
207             my $list = $self->expandSubnet(
208             subnet => $target,
209             asInt => 1,
210             ) or $log->fatal("Unable to parse this subnet: [$target]");
211              
212             $self->targetSubnet($target);
213              
214             my $size = scalar(@$list);
215             $self->targetCount($size);
216             if ($size > 1) { # Skip the network address
217             $self->targetIpAsInt($list->[1]);
218             $ip = $self->intToIp(int => $list->[1]) or return;
219             }
220             elsif ($size == 1) { # No network address here
221             $self->targetIpAsInt($list->[0]);
222             $ip = $self->intToIp(int => $list->[0]) or return;
223             }
224             else {
225             $log->fatal("Unable to analyze this subnet: [$target]");
226             }
227             $self->targetIp($ip);
228             # XXX: do we convert all IPs to ASCII format here? -> targetList
229             # No, it will take too much memory. Must be a user option.
230             $self->targetListAsInt($list);
231             }
232             }
233             elsif ($format == 2) { # Single IP format
234             $self->targetIp($target);
235             my $ipAsInt = $self->ipToInt(ip => $target) or return;
236             $self->targetIpAsInt($ipAsInt);
237             $self->targetCount(1);
238             $self->targetList([ $target ]);
239             $self->targetListAsInt([ $ipAsInt ]);
240             }
241             else {
242             $log->fatal("Unknown target format");
243             }
244              
245             #$log->debug("_parseTarget: target: ".($self->target || '(null)'));
246             #$log->debug("_parseTarget: targetIp: ".($self->targetIp || '(null)'));
247             #$log->debug("_parseTarget: targetIpAsInt: ".($self->targetIpAsInt || '(null)'));
248             #$log->debug("_parseTarget: targetCount: ".($self->targetCount || '(null)'));
249             #$log->debug("_parseTarget: targetSubnet: ".($self->targetSubnet || '(null)'));
250             #$log->debug("_parseTarget: targetHostname: ".($self->targetHostname || '(null)'));
251             #my $listAsInt = $self->targetListAsInt;
252             #my $first = $listAsInt->[0] || '(null)';
253             #$log->debug("_parseTarget: targetListAsInt first: $first");
254              
255             if ($self->dnsReverse) {
256             $self->targetReverse(
257             $self->getAddrReverse(addr => $self->targetIp) || 'unknown'
258             );
259             }
260              
261             return $self->targetIp;
262             }
263              
264             sub _parsePort {
265             my $self = shift;
266              
267             my $log = $self->log;
268              
269             # Valid port format
270             # Single port: 80
271             # Range port: 80-90
272             # Comma list: 80,81,82
273             # Mixed list: 80-90,100
274             # Fixed: top10, top100, top1000, all|full
275              
276             my $list = $self->expandPorts(ports => $self->port)
277             or $log->fatal("Unable to expand ports: [".$self->port."]");
278              
279             $self->portList($list);
280             $self->portCount(scalar(@$list));
281              
282             #$log->debug("_parsePort: portCount: ".scalar(@$list));
283             #$log->debug("_parsePort: portList first: ".$list->[0]);
284             ##$log->debug("_parsePort: portList: ".join(',', @$list));
285              
286             return 1;
287             }
288              
289             sub expandSubnet {
290             my $self = shift;
291             my %h = @_;
292              
293             my $log = $self->log;
294              
295             if (!defined($h{subnet})) {
296             $log->fatal("expandSubnet: You must provide subnet attribute");
297             }
298             my $subnet = $h{subnet};
299              
300             if ($subnet !~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/\d+$/) {
301             $log->fatal("expandSubnet: Invalid subnet format: [$subnet]");
302             }
303              
304             my $oNet = Net::Netmask->new2($subnet);
305             if (!defined($oNet)) {
306             $log->warning("expandSubnet: Net::Netmask error for subnet ".
307             "[$subnet]: $Net::Netmask::errstr");
308             return;
309             }
310              
311             $log->debug("Expanding subnet IP addresses, this may take a few seconds ...");
312              
313             my @list = ();
314             my $size = $oNet->size;
315             my $ibase = $oNet->{IBASE};
316             if ($h{asInt}) {
317             for my $i (0..$size-1) {
318             push @list, $ibase+$i;
319             }
320             }
321             else {
322             for my $i (0..$size-1) {
323             push @list, $self->intToIp(int => ($ibase + $i)) or return;
324             }
325             }
326              
327             $log->debug("Expanding subnet IP addresses: Done (count: ".scalar(@list).")");
328              
329             return \@list;
330             }
331              
332             sub expandPorts {
333             my $self = shift;
334             my %h = @_;
335              
336             my $log = $self->log;
337              
338             if (!defined($h{ports})) {
339             $log->fatal("expandPorts: You must provide ports attribute");
340             }
341             my $ports = $h{ports};
342              
343             #$log->debug("Expanding target ports, this may take a few seconds ...");
344              
345             if ($ports =~ /all|full/i) {
346             $ports = '0-65535';
347             }
348             elsif ($ports =~ /top10\s*$/i) {
349             $ports = '21,22,23,25,80,135,139,443,445,3389';
350             }
351             elsif ($ports =~ /top100\s*$/i) {
352             $ports = '7,9,13,21,22,23,25,26,37,53,79,80,81,88,106,110,111,113,119,135,139,143,144,179,199,389,427,443,444,445,465,513,514,515,543,544,548,554,587,631,646,873,990,993,995,1025,1026,1027,1028,1029,1110,1433,1720,1723,1755,1900,2000,2001,2049,2121,2717,3000,3128,3306,3389,3986,4899,5000,5009,5051,5060,5101,5190,5357,5432,5631,5666,5800,5900,6000,6001,6646,7070,8000,8008,8009,8080,8081,8443,8888,9100,9999,10000,32768,49152,49153,49154,49155,49156,49157';
353             }
354             elsif ($ports =~ /top1000\s*$/i) {
355             $ports = '1,3,4,6,7,9,13,17,19,20,21,22,23,24,25,26,30,32,33,37,42,43,49,53,70,79,80,81,82,83,84,85,88,89,90,99,100,106,109,110,111,113,119,125,135,139,143,144,146,161,163,179,199,211,212,222,254,255,256,259,264,280,301,306,311,340,366,389,406,407,416,417,425,427,443,444,445,458,464,465,481,497,500,512,513,514,515,524,541,543,544,545,548,554,555,563,587,593,616,617,625,631,636,646,648,666,667,668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800,801,808,843,873,880,888,898,900,901,902,903,911,912,981,987,990,992,993,995,999,1000,1001,1002,1007,1009,1010,1011,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1102,1104,1105,1106,1107,1108,1110,1111,1112,1113,1114,1117,1119,1121,1122,1123,1124,1126,1130,1131,1132,1137,1138,1141,1145,1147,1148,1149,1151,1152,1154,1163,1164,1165,1166,1169,1174,1175,1183,1185,1186,1187,1192,1198,1199,1201,1213,1216,1217,1218,1233,1234,1236,1244,1247,1248,1259,1271,1272,1277,1287,1296,1300,1301,1309,1310,1311,1322,1328,1334,1352,1417,1433,1434,1443,1455,1461,1494,1500,1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687,1688,1700,1717,1718,1719,1720,1721,1723,1755,1761,1782,1783,1801,1805,1812,1839,1840,1862,1863,1864,1875,1900,1914,1935,1947,1971,1972,1974,1984,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013,2020,2021,2022,2030,2033,2034,2035,2038,2040,2041,2042,2043,2045,2046,2047,2048,2049,2065,2068,2099,2100,2103,2105,2106,2107,2111,2119,2121,2126,2135,2144,2160,2161,2170,2179,2190,2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381,2382,2383,2393,2394,2399,2401,2492,2500,2522,2525,2557,2601,2602,2604,2605,2607,2608,2638,2701,2702,2710,2717,2718,2725,2800,2809,2811,2869,2875,2909,2910,2920,2967,2968,2998,3000,3001,3003,3005,3006,3007,3011,3013,3017,3030,3031,3050,3052,3071,3077,3128,3168,3211,3221,3260,3261,3268,3269,3283,3300,3301,3306,3322,3323,3324,3325,3333,3351,3367,3369,3370,3371,3372,3389,3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689,3690,3703,3737,3766,3784,3800,3801,3809,3814,3826,3827,3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000,4001,4002,4003,4004,4005,4006,4045,4111,4125,4126,4129,4224,4242,4279,4321,4343,4443,4444,4445,4446,4449,4550,4567,4662,4848,4899,4900,4998,5000,5001,5002,5003,5004,5009,5030,5033,5050,5051,5054,5060,5061,5080,5087,5100,5101,5102,5120,5190,5200,5214,5221,5222,5225,5226,5269,5280,5298,5357,5405,5414,5431,5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678,5679,5718,5730,5800,5801,5802,5810,5811,5815,5822,5825,5850,5859,5862,5877,5900,5901,5902,5903,5904,5906,5907,5910,5911,5915,5922,5925,5950,5952,5959,5960,5961,5962,5963,5987,5988,5989,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6009,6025,6059,6100,6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565,6566,6567,6580,6646,6666,6667,6668,6669,6689,6692,6699,6779,6788,6789,6792,6839,6881,6901,6969,7000,7001,7002,7004,7007,7019,7025,7070,7100,7103,7106,7200,7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777,7778,7800,7911,7920,7921,7937,7938,7999,8000,8001,8002,8007,8008,8009,8010,8011,8021,8022,8031,8042,8045,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8093,8099,8100,8180,8181,8192,8193,8194,8200,8222,8254,8290,8291,8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651,8652,8654,8701,8800,8873,8888,8899,8994,9000,9001,9002,9003,9009,9010,9011,9040,9050,9071,9080,9081,9090,9091,9099,9100,9101,9102,9103,9110,9111,9200,9207,9220,9290,9415,9418,9485,9500,9502,9503,9535,9575,9593,9594,9595,9618,9666,9876,9877,9878,9898,9900,9917,9943,9944,9968,9998,9999,10000,10001,10002,10003,10004,10009,10010,10012,10024,10025,10082,10180,10215,10243,10566,10616,10617,10621,10626,10628,10629,10778,11110,11111,11967,12000,12174,12265,12345,13456,13722,13782,13783,14000,14238,14441,14442,15000,15002,15003,15004,15660,15742,16000,16001,16012,16016,16018,16080,16113,16992,16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221,20222,20828,21571,22939,23502,24444,24800,25734,25735,26214,27000,27352,27353,27355,27356,27715,28201,30000,30718,30951,31038,31337,32768,32769,32770,32771,32772,32773,32774,32775,32776,32777,32778,32779,32780,32781,32782,32783,32784,32785,33354,33899,34571,34572,34573,35500,38292,40193,40911,41511,42510,44176,44442,44443,44501,45100,48080,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49163,49165,49167,49175,49176,49400,49999,50000,50001,50002,50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055,55056,55555,55600,56737,56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389';
356             }
357             elsif ($ports !~ /^[0-9,-]+$/) {
358             $log->fatal("Invalid port range for -port argument: [$ports]");
359             }
360              
361             my @ports = ();
362             for my $c (split(',', $ports)) {
363             $c =~ s/-/../g;
364             for my $p (eval($c)) {
365             push @ports, $p;
366             }
367             }
368              
369             #$log->debug("Expanding target ports: Done (count: ".scalar(@ports).")");
370              
371             return \@ports;
372             }
373              
374             sub expandFiles {
375             my $self = shift;
376             my %h = @_;
377              
378             my $log = $self->log;
379              
380             if (!defined($h{files})) {
381             $log->fatal("expandFiles: You must provide files attribute");
382             }
383             my $files = $h{files};
384              
385             my @list = <{$files}>;
386             if (@list == 0) {
387             $log->warning("expandFiles: no file found");
388             return;
389             }
390              
391             return \@list;
392             }
393              
394             sub lookupMac {
395             my $self = shift;
396              
397             my $log = $self->log;
398              
399             if (! $self->macLookup) {
400             $log->verbose("MAC lookup disabled");
401             return;
402             }
403              
404             print "XXX: TODO\n";
405              
406             return;
407             }
408              
409             sub lookupMac6 {
410             my $self = shift;
411             my %h = @_;
412              
413             my $log = $self->log;
414              
415             if (! $self->macLookup) {
416             $log->verbose("MAC lookup disabled");
417             return;
418             }
419              
420             if (!defined($h{ipv6})) {
421             $log->fatal("lookupMac6: You must provide ipv6 attribute");
422             }
423             my $ipv6 = $h{ipv6};
424              
425             $log->verbose("Trying to find MAC address for target IPv6: [$ipv6]");
426              
427             my $cacheArp = $self->cacheArp;
428              
429             my $mac;
430             if (defined($cacheArp->{$ipv6})) {
431             $mac = $cacheArp->{$ipv6};
432             $log->verbose("Found MAC address: [$mac] from cache");
433             }
434             else {
435             my $dev = Net::Frame::Device->new(
436             target6 => $ipv6,
437             dev => $self->device,
438             );
439             if (!defined($dev)) {
440             $log->fatal("lookupMac6: unable to acquire device for target6 [".
441             $ipv6."]");
442             return;
443             }
444              
445             $mac = $dev->lookupMac6($ipv6, $self->retry, $self->timeout);
446             if (!defined($mac)) {
447             $log->fatal("lookupMac6: unable to get MAC address for IPv6 [".
448             $ipv6."]");
449             return;
450             }
451             $cacheArp->{$ipv6} = $mac;
452             $log->verbose("Found MAC address: [$mac] from lookup");
453             }
454              
455             return $mac;
456             }
457              
458             sub _getHostIpv6Addr {
459             my ($host) = @_;
460              
461             if (Net::IPv6Addr::is_ipv6($host)) {
462             return $host;
463             }
464              
465             my @res = getaddrinfo($host, 'ssh', Socket6::AF_INET6(), SOCK_STREAM);
466             if (@res >= 5) {
467             my ($ipv6) = getnameinfo($res[3], NI_NUMERICHOST | NI_NUMERICSERV);
468             $ipv6 =~ s/%.*$//;
469             return $ipv6;
470             }
471              
472             return;
473             }
474              
475             sub _getHostIpv4Addr {
476             my ($host) = @_;
477              
478             if ($host =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
479             return $host;
480             }
481              
482             my @addrs = (gethostbyname($host))[4];
483             return @addrs ? join('.', CORE::unpack('C4', $addrs[0]))
484             : undef;
485             }
486              
487             sub getHostAddr {
488             my $self = shift;
489             my %h = @_;
490              
491             my $log = $self->log;
492              
493             if (!defined($h{host})) {
494             $log->fatal("getHostAddr: You must provide host attribute");
495             }
496             my $host = $h{host};
497              
498             my $ip = $self->ipv6 ? _getHostIpv6Addr($host) : _getHostIpv4Addr($host);
499             if (!defined($ip)) {
500             $log->warning("getHostAddr: unable to resolve ".
501             ($self->ipv6 ? 'IPv6' : 'IPv4').
502             " address for hostname [$host]");
503             return;
504             }
505              
506             return $ip;
507             }
508              
509             sub getAddrReverse {
510             my $self = shift;
511             my %h = @_;
512              
513             my $log = $self->log;
514              
515             if (!defined($h{addr})) {
516             $log->fatal("getAddrReverse: You must provide addr attribute");
517             }
518             my $addr = $h{addr};
519              
520             $log->verbose("Trying reverse lookup for IP [$addr]");
521              
522             my $reverse;
523             if ($self->ipv6) {
524             my $inet = inet_pton(Socket6::AF_INET6(), $addr);
525             if (!defined($inet)) {
526             $log->warning("getAddrReverse: unable to get reverse on IPv6 ".
527             "[$addr]");
528             return;
529             }
530             $reverse = gethostbyaddr($inet, Socket6::AF_INET6());
531             }
532             else {
533             my $inet = inet_aton($addr);
534             if (!defined($inet)) {
535             $log->warning("getAddrReverse: unable to get reverse on IPv4 ".
536             "[$addr]");
537             return;
538             }
539             $reverse = gethostbyaddr($inet, AF_INET);
540             }
541              
542             if ($reverse) {
543             $log->verbose("Reverse lookup gave: [$reverse]");
544             }
545             else {
546             $log->verbose("Reverse lookup gave nothing");
547             }
548              
549             return $reverse;
550             }
551              
552             sub ipToInt {
553             my $self = shift;
554             my %h = @_;
555              
556             my $log = $self->log;
557              
558             if (! defined($h{ip})) {
559             $log->fatal("ipToInt: You must provide `ip' attribute");
560             }
561             my $ip = $h{ip};
562              
563             if ($self->ipv6) {
564             # XXX: Should use inet_pton for IPv6 support
565             $log->warning("IPv6 to Int not supported, doing nothing");
566             return $ip;
567             }
568              
569             my $int = $ip;
570             # Is this not yet in Int format?
571             if ($ip !~ /^\d+$/) {
572             $int = unpack('N', inet_aton($ip));
573             if (! defined($int)) {
574             $log->error("Unable to IP to Int address: [$ip]: $!");
575             return;
576             }
577             }
578              
579             return $int;
580             }
581              
582             sub intToIp {
583             my $self = shift;
584             my %h = @_;
585              
586             my $log = $self->log;
587              
588             if (! defined($h{int})) {
589             $log->fatal("intToIp: You must provide `int' attribute");
590             }
591             my $int = $h{int};
592              
593             if ($self->ipv6) {
594             # XXX: Should use inet_ntop for IPv6 support
595             $log->warning("Int to IPv6 not supported, doing nothing");
596             return $int;
597             }
598              
599             my $ip = $int;
600             # Is this in Int format?
601             if ($int =~ /^\d+$/) {
602             $ip = inet_ntoa(pack('N', $int));
603             if (! defined($ip)) {
604             $log->error("Unable to Int to IP address: [$int]: $!");
605             return;
606             }
607             }
608              
609             return $ip;
610             }
611              
612             sub getDumpOnline {
613             my $self = shift;
614             my %h = @_;
615              
616             if (defined($h{filter})) {
617             $self->log->verbose("getDumpOnline: Using filter [$h{filter}]")
618             }
619              
620             my $oDump = Net::Frame::Dump::Online2->new(
621             dev => $self->device,
622             timeoutOnNext => $self->timeout,
623             %h,
624             );
625              
626             return $oDump;
627             }
628              
629             sub getDumpOffline {
630             my $self = shift;
631             my %h = @_;
632              
633             my $log = $self->log;
634              
635             if (!defined($h{file})) {
636             $log->fatal("getDumpOffline: You must provide file attribute");
637             }
638              
639             if (!-f $h{file}) {
640             $log->warning("getDumpOffline: File [$h{file}] not found");
641             return;
642             }
643              
644             if (defined($h{filter})) {
645             $log->verbose("getDumpOffline: Using filter [$h{filter}]")
646             }
647              
648             my $oDump = Net::Frame::Dump::Offline->new(%h);
649              
650             return $oDump;
651             }
652              
653             sub getDumpWriter {
654             my $self = shift;
655             my %h = @_;
656              
657             my $oDump = Net::Frame::Dump::Writer->new(%h);
658              
659             return $oDump;
660             }
661              
662             sub getWriteL2 {
663             my $self = shift;
664              
665             my $oWrite = Net::Write::Layer2->new(dev => $self->device);
666              
667             return $oWrite;
668             }
669              
670             sub getWriteL3 {
671             my $self = shift;
672             my %h = @_;
673              
674             my $log = $self->log;
675              
676             if (!defined($h{dst})) {
677             $log->fatal("getWriteL3: You must provide dst attribute");
678             }
679              
680             my $oWrite = Net::Write::Layer3->new(%h);
681              
682             return $oWrite;
683             }
684              
685             sub getWrite {
686             my $self = shift;
687             my %h = @_;
688              
689             return $self->ipv6 ? $self->getWriteL2(%h)
690             : $self->getWriteL3(%h);
691              
692             return;
693             }
694              
695             sub tcpConnect {
696             my $self = shift;
697             my %h = @_;
698              
699             my $log = $self->log;
700              
701             if (!defined($h{ip})) {
702             $log->fatal("tcpConnect: You must provide ip attribute");
703             }
704             if (!defined($h{port})) {
705             $log->fatal("tcpConnect: You must provide port attribute");
706             }
707              
708             my $mod = $self->ipv6 ? 'IO::Socket::INET6' : 'IO::Socket::INET';
709             my $socket = $mod->new(
710             PeerHost => $h{ip},
711             PeerPort => $h{port},
712             Proto => 'tcp',
713             Timeout => $self->timeout,
714             );
715             if (!defined($socket)) {
716             $log->warning("tcpConnect: [$h{ip}]:$h{port}: $!");
717             return;
718             }
719              
720             $socket->blocking(0);
721             $socket->autoflush(1);
722              
723             return $socket;
724             }
725              
726             1;
727              
728             __END__