File Coverage

blib/lib/IO/Socket/Multicast.pm
Criterion Covered Total %
statement 47 78 60.2
branch 3 32 9.3
condition 2 17 11.7
subroutine 15 19 78.9
pod 6 8 75.0
total 73 154 47.4


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__