summaryrefslogtreecommitdiffstats
path: root/lib/Smokeping/probes/SendEmail.pm
blob: 947e3c5c149bc8da84378880402dfc438eb0ff08 (plain)
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;