line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Bot::Cobalt::Plugin::Extras::DNS; |
2
|
|
|
|
|
|
|
$Bot::Cobalt::Plugin::Extras::DNS::VERSION = '0.021003'; |
3
|
1
|
|
|
1
|
|
1325
|
use Bot::Cobalt; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
7
|
|
4
|
1
|
|
|
1
|
|
692
|
use Bot::Cobalt::Common; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
8
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
5
|
use POE; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
300
|
use Net::IP::Minimal qw/ip_is_ipv4 ip_is_ipv6/; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
983
|
|
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
0
|
331
|
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__ |