File Coverage

blib/lib/Bot/Cobalt/Plugin/Extras/DNS.pm
Criterion Covered Total %
statement 13 79 16.4
branch 0 14 0.0
condition 0 6 0.0
subroutine 5 15 33.3
pod 0 9 0.0
total 18 123 14.6


line stmt bran cond sub pod time code
1             package Bot::Cobalt::Plugin::Extras::DNS;
2             $Bot::Cobalt::Plugin::Extras::DNS::VERSION = '0.021001';
3 1     1   1071 use Bot::Cobalt;
  1         1  
  1         6  
4 1     1   718 use Bot::Cobalt::Common;
  1         1  
  1         7  
5              
6 1     1   4 use POE;
  1         2  
  1         6  
7              
8 1     1   243 use Net::IP::Minimal qw/ip_is_ipv4 ip_is_ipv6/;
  1         1  
  1         870  
9              
10 1     1 0 334 sub new { bless [], shift }
11              
12             sub Cobalt_register {
13 0     0 0   my ($self, $core) = splice @_, 0, 2;
14            
15 0           POE::Session->create(
16             object_states => [
17             $self => [
18             '_start',
19             'dns_resp_recv',
20             'dns_issue_query',
21             ],
22             ],
23             );
24              
25 0           register( $self, 'SERVER',
26             qw/
27             public_cmd_dns
28             public_cmd_nslookup
29             public_cmd_hextoip
30             public_cmd_iptohex
31             /
32             );
33            
34 0           logger->info("Loaded: dns nslookup");
35              
36 0           return PLUGIN_EAT_NONE
37             }
38              
39             sub Cobalt_unregister {
40 0     0 0   my ($self, $core) = splice @_, 0, 2;
41              
42 0           $poe_kernel->alias_remove( 'p_'.$core->get_plugin_alias($self) );
43              
44 0           logger->info("Unloaded");
45              
46 0           return PLUGIN_EAT_NONE
47             }
48              
49 0     0 0   sub Bot_public_cmd_nslookup { Bot_public_cmd_dns(@_) }
50             sub Bot_public_cmd_dns {
51 0     0 0   my ($self, $core) = splice @_, 0, 2;
52 0           my $msg = ${ $_[0] };
  0            
53 0           my $context = $msg->context;
54            
55 0           my $channel = $msg->channel;
56            
57 0           my ($host, $type) = @{ $msg->message_array };
  0            
58            
59 0           $self->_run_query($context, $channel, $host, $type);
60            
61 0           return PLUGIN_EAT_ALL
62             }
63              
64             sub Bot_public_cmd_hextoip {
65 0     0 0   my ($self, $core) = splice @_, 0, 2;
66            
67 0           my $msg = ${ $_[0] };
  0            
68            
69 0           my $hexip = $msg->message_array->[0];
70            
71 0           my $ip = join '.', unpack "C*", pack "H*", $hexip;
72            
73 0           broadcast( 'message',
74             $msg->context,
75             $msg->channel,
76             "hex: $hexip --> ip: $ip"
77             );
78            
79 0           return PLUGIN_EAT_ALL
80             }
81              
82             sub Bot_public_cmd_iptohex {
83 0     0 0   my ($self, $core) = splice @_, 0, 2;
84            
85 0           my $msg = ${ $_[0] };
  0            
86            
87 0           my $ip = $msg->message_array->[0];
88            
89 0           my $hexip = unpack 'H*', pack 'C*', split(/\./, $ip);
90            
91 0           broadcast( 'message',
92             $msg->context,
93             $msg->channel,
94             "ip: $ip --> hex: $hexip"
95             );
96            
97 0           return PLUGIN_EAT_ALL
98             }
99              
100             sub _start {
101 0     0     my ($self, $kernel, $heap) = @_[OBJECT, KERNEL, HEAP];
102              
103 0           $kernel->alias_set( 'p_'. core()->get_plugin_alias($self) );
104              
105 0           logger->debug("Resolver-handling session spawned");
106             }
107              
108             sub dns_resp_recv {
109 0     0 0   my ($self, $kernel, $heap) = @_[OBJECT, KERNEL, HEAP];
110 0           my $response = $_[ARG0];
111 0           my $hints = $response->{context};
112              
113 0           my $context = $hints->{Context};
114 0           my $channel = $hints->{Channel};
115              
116 0           my $nsresp;
117 0 0         unless ($nsresp = $response->{response}) {
118 0           broadcast( 'message', $context, $channel,
119             "DNS error."
120             );
121             return
122 0           }
123            
124 0           my @send;
125 0           for my $ans ($nsresp->answer) {
126 0 0         if ($ans->type eq 'SOA') {
127 0           push @send, 'SOA=' . join ':',
128             $ans->mname, $ans->rname, $ans->serial, $ans->refresh,
129             $ans->retry, $ans->expire, $ans->minimum
130             } else {
131 0           push @send, join '=', $ans->type, $ans->rdatastr
132             }
133             }
134            
135 0           my $str;
136 0           my $host = $response->{host};
137 0 0         if (@send) {
138 0           $str = "nslookup: $host: ".join ' ', @send;
139             } else {
140 0           $str = "nslookup: No answer for $host";
141             }
142            
143 0 0         broadcast('message', $context, $channel, $str) if $str;
144             }
145              
146             sub _run_query {
147 0     0     my ($self, $context, $channel, $host, $type) = @_;
148            
149 0 0 0       $type = 'A' unless $type
150             and $type =~ /^(A|CNAME|NS|MX|PTR|TXT|AAAA|SRV|SOA)$/i;
151            
152 0 0 0       $type = 'PTR' if ip_is_ipv4($host) or ip_is_ipv6($host);
153            
154 0           logger->debug("issuing dns request: $host");
155              
156 0           $poe_kernel->post( 'p_'. core()->get_plugin_alias($self),
157             'dns_issue_query',
158             $context, $channel, $host, $type
159             );
160             }
161              
162             sub dns_issue_query {
163 0     0 0   my ($self, $kernel) = @_[OBJECT, KERNEL];
164 0           my ($context, $channel, $host, $type) = @_[ARG0 .. $#_];
165            
166 0           my $resp = core()->resolver->resolve(
167             event => 'dns_resp_recv',
168             host => $host,
169             type => $type,
170             context => { Context => $context, Channel => $channel },
171             );
172              
173 0 0         POE::Kernel->yield('dns_resp_recv', $resp) if $resp;
174              
175 0           return 1
176             }
177              
178             1;
179             __END__