1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
package Smokeping::probes::SendEmail;
# Copyright (c) 2012 Florian Coulmier <florian@coulmier.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. 1
#
=head1 301 Moved Permanently
This is a Smokeping probe module. Please use the command
C<smokeping -man Smokeping::probes::skel>
to view the documentation or the command
C<smokeping -makepod Smokeping::probes::skel>
to generate the POD document.
=cut
use strict;
use base qw(Smokeping::probes::basefork);
use Carp;
use Sys::Hostname;
use Time::HiRes;
use Net::SMTP;
sub pod_hash {
return {
name => <<DOC,
Smokeping::probes::SendEmail - a Smokeping probe that measure time neeed to send an mail
DOC
description => <<DOC,
This probe actually send a mail to a MX server and measure time it took. You can choose the sender and recipient adress as well as the size of the mail.
DOC
authors => <<'DOC',
Florian Coulmier <florian@coulmier.fr>,
DOC
see_also => <<DOC
L<smokeping_extend>
DOC
};
}
sub new($$$)
{
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = $class->SUPER::new(@_);
# no need for this if we run as a cgi
unless ( $ENV{SERVER_SOFTWARE} ) {
# if you have to test the program output
# or something like that, do it here
# and bail out if necessary
};
return $self;
}
# Probe-specific variables declaration
sub probevars {
my $class = shift;
return $class->_makevars($class->SUPER::probevars, {
_mandatory => [ 'from', 'to' ],
from => {
_doc => "Mail from address",
_example => 'test@test.com',
},
to => {
_doc => "Rcpt to address",
_exemple => 'test@test.com',
},
subject => {
_doc => "Subject of the mail",
_exemple => "Test Smokeping",
_default => "Test",
},
bodysize => {
_doc => "Size of the mail to send in bytes. If set to 0, a default mail content will be set. Note that mail always contain From, To and Subject headers.",
_exemple => "1024",
_default => "0",
}
});
}
# Target-specific variables declaration
sub targetvars {
my $class = shift;
return $class->_makevars($class->SUPER::targetvars, {
port => { _doc => "Port of the SMTP server to reach",
_exemple => 25,
_default => 25,
},
});
}
sub ProbeDesc($){
my $self = shift;
return "Measure time to send a complete email";
}
# this is where the actual stuff happens
sub pingone ($){
my $self = shift;
my $target = shift;
my @times;
# Retrieve probe-specific and target-specific variables
my $count = $self->pings($target);
my $from = $self->{properties}{from};
my $to = $self->{properties}{to};
my $subject = $self->{properties}{subject} || "Smokeping Test";
my $bodysize = $self->{properties}{bodysize} || 0;
my $host = $target->{addr};
my $port = $target->{vars}{port} || 25;
# Get Hostname
my $hostname = hostname();
# Send a mail as many times as requested
for (1..$count) {
# Start counting time
my $start = Time::HiRes::gettimeofday();
# Open the connection and then send the mail
my $smtp = new Net::SMTP("$host:$port", Timeout => 5, Hello => $hostname);
next if (!$smtp);
$smtp->mail($from) || next;
$smtp->to($to, { Notify => ['NEVER'] }) || next;
$smtp->data() || next;
$smtp->datasend("From: <$from>\n");
$smtp->datasend("To: <$to>\n");
$smtp->datasend("Subject: $subject\n");
$smtp->datasend("\n");
# If user specified a bodysize for the probe, send the request number of characters instead of the default content.
if ($bodysize > 0) {
my $nbLines = $bodysize / 80;
for (1..$nbLines) {
$smtp->datasend(sprintf("%s\n", "A" x 79));
}
$smtp->datasend(sprintf("%s\n", "A" x ($bodysize % 80)));
} else {
$smtp->datasend("This is a test email sent by Smokeping to check speed of mx server $host.\n");
$smtp->datasend("If you receive this mail in your mailbox, you are likely to be spammed in just few minutes!\n");
}
$smtp->dataend() || next;
$smtp->quit();
# End measure of time and save it
my $end = Time::HiRes::gettimeofday();
push(@times, $end - $start);
}
return sort {$a <=> $b } @times;
}
# That's all, folks!
1;
|