line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package IO::Socket::Multicast;
|
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
78274
|
use 5.005;
|
|
3
|
|
|
|
|
13
|
|
|
3
|
|
|
|
|
127
|
|
4
|
3
|
|
|
3
|
|
19
|
use strict;
|
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
120
|
|
5
|
3
|
|
|
3
|
|
26
|
use Carp 'croak';
|
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
226
|
|
6
|
3
|
|
|
3
|
|
25
|
use Exporter ();
|
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
64
|
|
7
|
3
|
|
|
3
|
|
13
|
use DynaLoader ();
|
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
61
|
|
8
|
3
|
|
|
3
|
|
3458
|
use IO::Socket;
|
|
3
|
|
|
|
|
161466
|
|
|
3
|
|
|
|
|
16
|
|
9
|
|
|
|
|
|
|
BEGIN {
|
10
|
3
|
|
|
3
|
|
2364
|
eval "use IO::Interface 0.94 'IFF_MULTICAST';";
|
|
3
|
|
|
3
|
|
4454
|
|
|
3
|
|
|
|
|
29897
|
|
|
3
|
|
|
|
|
409
|
|
11
|
|
|
|
|
|
|
}
|
12
|
3
|
|
|
3
|
|
31
|
use vars qw(@ISA @EXPORT_OK @EXPORT %EXPORT_TAGS $VERSION);
|
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
514
|
|
13
|
|
|
|
|
|
|
BEGIN {
|
14
|
3
|
|
|
3
|
|
12
|
my @functions = qw(
|
15
|
|
|
|
|
|
|
mcast_add
|
16
|
|
|
|
|
|
|
mcast_drop
|
17
|
|
|
|
|
|
|
mcast_if
|
18
|
|
|
|
|
|
|
mcast_loopback
|
19
|
|
|
|
|
|
|
mcast_ttl
|
20
|
|
|
|
|
|
|
mcast_dest
|
21
|
|
|
|
|
|
|
mcast_send
|
22
|
|
|
|
|
|
|
);
|
23
|
3
|
|
|
|
|
7
|
$VERSION = '1.12';
|
24
|
3
|
|
|
|
|
114
|
@ISA = qw(
|
25
|
|
|
|
|
|
|
Exporter
|
26
|
|
|
|
|
|
|
DynaLoader
|
27
|
|
|
|
|
|
|
IO::Socket::INET
|
28
|
|
|
|
|
|
|
);
|
29
|
3
|
|
|
|
|
1118
|
@EXPORT = ( );
|
30
|
3
|
|
|
|
|
14
|
%EXPORT_TAGS = (
|
31
|
|
|
|
|
|
|
'all' => \@functions,
|
32
|
|
|
|
|
|
|
'functions' => \@functions,
|
33
|
|
|
|
|
|
|
);
|
34
|
3
|
|
|
|
|
7
|
@EXPORT_OK = @{ $EXPORT_TAGS{'all'} };
|
|
3
|
|
|
|
|
2557
|
|
35
|
|
|
|
|
|
|
}
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
my $IP = '\d+\.\d+\.\d+\.\d+';
|
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub import {
|
40
|
3
|
|
|
3
|
|
2473
|
Socket->export_to_level(1,@_);
|
41
|
3
|
|
|
|
|
9164
|
IO::Socket::Multicast->export_to_level(1,@_);
|
42
|
|
|
|
|
|
|
}
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub new {
|
45
|
1
|
|
|
1
|
1
|
21
|
my $class = shift;
|
46
|
1
|
50
|
|
|
|
5
|
unshift @_,(Proto => 'udp') unless @_;
|
47
|
1
|
|
|
|
|
28
|
$class->SUPER::new(@_);
|
48
|
|
|
|
|
|
|
}
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub configure {
|
51
|
1
|
|
|
1
|
0
|
139
|
my($self,$arg) = @_;
|
52
|
1
|
|
50
|
|
|
10
|
$arg->{Proto} ||= 'udp';
|
53
|
1
|
|
|
|
|
11
|
$self->SUPER::configure($arg);
|
54
|
|
|
|
|
|
|
}
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub mcast_add {
|
57
|
0
|
|
|
0
|
1
|
0
|
my $sock = shift;
|
58
|
0
|
|
0
|
|
|
0
|
my $group = shift || croak 'usage: $sock->mcast_add($mcast_addr [,$interface])';
|
59
|
0
|
0
|
|
|
|
0
|
$group = inet_ntoa($group) unless $group =~ /^$IP$/o;
|
60
|
0
|
|
|
|
|
0
|
my $interface = get_if_addr($sock,shift);
|
61
|
0
|
|
|
|
|
0
|
return $sock->_mcast_add($group,$interface);
|
62
|
|
|
|
|
|
|
}
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub mcast_drop {
|
65
|
1
|
|
|
1
|
1
|
10191
|
my $sock = shift;
|
66
|
1
|
|
33
|
|
|
20
|
my $group = shift || croak 'usage: $sock->mcast_add($mcast_addr [,$interface])';
|
67
|
1
|
50
|
|
|
|
46
|
$group = inet_ntoa($group) unless $group =~ /^$IP$/o;
|
68
|
1
|
|
|
|
|
10
|
my $interface = get_if_addr($sock,shift);
|
69
|
1
|
|
|
|
|
52
|
return $sock->_mcast_drop($group,$interface);
|
70
|
|
|
|
|
|
|
}
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub mcast_if {
|
73
|
0
|
|
|
0
|
1
|
0
|
my $sock = shift;
|
74
|
|
|
|
|
|
|
|
75
|
0
|
|
|
|
|
0
|
my $previous = $sock->_mcast_if;
|
76
|
0
|
0
|
|
|
|
0
|
$previous = $sock->addr_to_interface($previous)
|
77
|
|
|
|
|
|
|
if $sock->can('addr_to_interface');
|
78
|
0
|
0
|
|
|
|
0
|
return $previous unless @_;
|
79
|
|
|
|
|
|
|
|
80
|
0
|
|
|
|
|
0
|
my $interface = get_if_addr($sock,shift);
|
81
|
0
|
0
|
|
|
|
0
|
return $sock->_mcast_if($interface) ? $previous : undef;
|
82
|
|
|
|
|
|
|
}
|
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub get_if_addr {
|
85
|
1
|
|
|
1
|
0
|
5
|
my $sock = shift;
|
86
|
1
|
50
|
|
|
|
11
|
return '0.0.0.0' unless defined (my $interface = shift);
|
87
|
0
|
0
|
|
|
|
|
return $interface if $interface =~ /^$IP$/;
|
88
|
0
|
0
|
|
|
|
|
return $interface if length $interface == 16;
|
89
|
0
|
0
|
|
|
|
|
croak "IO::Interface module not available; use IP addr for interface"
|
90
|
|
|
|
|
|
|
unless $sock->can('if_addr');
|
91
|
0
|
0
|
|
|
|
|
croak "unknown or unconfigured interace $interface"
|
92
|
|
|
|
|
|
|
unless my $addr = $sock->if_addr($interface);
|
93
|
0
|
0
|
0
|
|
|
|
croak "interface is not multicast capable"
|
94
|
|
|
|
|
|
|
unless $interface eq 'any' or ($sock->if_flags($interface) & IFF_MULTICAST());
|
95
|
0
|
|
|
|
|
|
return $addr;
|
96
|
|
|
|
|
|
|
}
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub mcast_dest {
|
99
|
0
|
|
|
0
|
1
|
|
my $sock = shift;
|
100
|
0
|
|
|
|
|
|
my $prev = ${*$sock}{'io_socket_mcast_dest'};
|
|
0
|
|
|
|
|
|
|
101
|
0
|
0
|
|
|
|
|
if (my $dest = shift) {
|
102
|
0
|
0
|
|
|
|
|
$dest = sockaddr_in($2,inet_aton($1)) if $dest =~ /^($IP):(\d+)$/;
|
103
|
0
|
0
|
|
|
|
|
croak "invalid destination address" unless length($dest) == 16;
|
104
|
0
|
|
|
|
|
|
${*$sock}{'io_socket_mcast_dest'} = $dest;
|
|
0
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
}
|
106
|
0
|
|
|
|
|
|
return $prev;
|
107
|
|
|
|
|
|
|
}
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub mcast_send {
|
110
|
0
|
|
|
0
|
1
|
|
my $sock = shift;
|
111
|
0
|
|
0
|
|
|
|
my $data = shift || croak 'usage: $sock->mcast_send($data [,$address])';
|
112
|
0
|
0
|
|
|
|
|
$sock->mcast_dest(shift) if @_;
|
113
|
0
|
|
0
|
|
|
|
my $dest = $sock->mcast_dest || croak "no destination specified with mcast_send() or mcast_dest()";
|
114
|
0
|
|
|
|
|
|
return send($sock,$data,0,$dest);
|
115
|
|
|
|
|
|
|
}
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
bootstrap IO::Socket::Multicast $VERSION;
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
1;
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
__END__
|