line  
 stmt  
 bran  
 cond  
 sub  
 pod  
 time  
 code  
 
1 
 
  
 
   
 
 
 
 
 
 
 
 
 
 
 
 #  
 
2 
 
 
 
 
 
 
 
 
 
 
 
 
 
 # $Id: Env.pm,v 1.2.2.8 2006/06/04 13:45:18 gomor Exp $  
 
3 
 
 
 
 
 
 
 
 
 
 
 
 
 
 #  
 
4 
 
 
 
 
 
 
 
 
 
 
 
 
 
 package Net::Packet::Env;  
 
5 
 
28
 
 
 
 
 
  
28
   
 
 
 
172
 
 use strict;  
 
  
 
28
 
 
 
 
 
 
 
 
 
63
 
    
 
  
 
28
 
 
 
 
 
 
 
 
 
721
 
    
 
6 
 
28
 
 
 
 
 
  
28
   
 
 
 
139
 
 use warnings;  
 
  
 
28
 
 
 
 
 
 
 
 
 
55
 
    
 
  
 
28
 
 
 
 
 
 
 
 
 
1732
 
    
 
7 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
8 
 
 
 
 
 
 
 
 
 
 
 
 
 
 require Exporter;  
 
9 
 
 
 
 
 
 
 
 
 
 
 
 
 
 require Class::Gomor::Array;  
 
10 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our @ISA = qw(Exporter Class::Gomor::Array);  
 
11 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our @EXPORT_OK = qw($Env);  
 
12 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
13 
 
28
 
 
 
 
 
  
28
   
 
 
 
24792
 
 use Net::Libdnet;  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
    
 
  
 
0
 
 
 
 
 
 
 
 
 
 
 
    
 
14 
 
 
 
 
 
 
 
 
 
 
 
 
 
 require Net::IPv6Addr;  
 
15 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
16 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our @AS = qw(  
 
17 
 
 
 
 
 
 
 
 
 
 
 
 
 
    dev  
 
18 
 
 
 
 
 
 
 
 
 
 
 
 
 
    ip  
 
19 
 
 
 
 
 
 
 
 
 
 
 
 
 
    ip6  
 
20 
 
 
 
 
 
 
 
 
 
 
 
 
 
    mac  
 
21 
 
 
 
 
 
 
 
 
 
 
 
 
 
    desc  
 
22 
 
 
 
 
 
 
 
 
 
 
 
 
 
    dump  
 
23 
 
 
 
 
 
 
 
 
 
 
 
 
 
    err  
 
24 
 
 
 
 
 
 
 
 
 
 
 
 
 
    errString  
 
25 
 
 
 
 
 
 
 
 
 
 
 
 
 
    noFrameAutoDesc  
 
26 
 
 
 
 
 
 
 
 
 
 
 
 
 
    noFrameAutoDump  
 
27 
 
 
 
 
 
 
 
 
 
 
 
 
 
    noDumpAutoSet  
 
28 
 
 
 
 
 
 
 
 
 
 
 
 
 
    noDescAutoSet  
 
29 
 
 
 
 
 
 
 
 
 
 
 
 
 
    _dnet  
 
30 
 
 
 
 
 
 
 
 
 
 
 
 
 
 );  
 
31 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our @AO = qw(  
 
32 
 
 
 
 
 
 
 
 
 
 
 
 
 
    debug  
 
33 
 
 
 
 
 
 
 
 
 
 
 
 
 
 );  
 
34 
 
 
 
 
 
 
 
 
 
 
 
 
 
 __PACKAGE__->cgBuildIndices;  
 
35 
 
 
 
 
 
 
 
 
 
 
 
 
 
 __PACKAGE__->cgBuildAccessorsScalar(\@AS);  
 
36 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
37 
 
 
 
 
 
 
 
 
 
 
 
 
 
 no strict 'vars';  
 
38 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
39 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our $Env = __PACKAGE__->new;  
 
40 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
41 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub new {  
 
42 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $self = shift->SUPER::new(  
 
43 
 
 
 
 
 
 
 
 
 
 
 
 
 
       debug           => 0,  
 
44 
 
 
 
 
 
 
 
 
 
 
 
 
 
       noFrameAutoDesc => 0,  
 
45 
 
 
 
 
 
 
 
 
 
 
 
 
 
       noFrameAutoDump => 0,  
 
46 
 
 
 
 
 
 
 
 
 
 
 
 
 
       noDumpAutoSet   => 0,  
 
47 
 
 
 
 
 
 
 
 
 
 
 
 
 
       noDescAutoSet   => 0,  
 
48 
 
 
 
 
 
 
 
 
 
 
 
 
 
       err             => 0,  
 
49 
 
 
 
 
 
 
 
 
 
 
 
 
 
       errString       => '',  
 
50 
 
 
 
 
 
 
 
 
 
 
 
 
 
       @_,  
 
51 
 
 
 
 
 
 
 
 
 
 
 
 
 
    );  
 
52 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
53 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$__dev]  
 
54 
 
 
 
 
 
 
 
 
 
 
 
 
 
       ? do { $self->[$__dev] = $self->getDevInfoFor($self->[$__dev]) }  
 
55 
 
 
 
 
 
 
 
 
 
 
 
 
 
       : do { $self->[$__dev] = $self->getDevInfo                     };  
 
56 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
57 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$__mac] = $self->getMac unless $self->[$__mac];  
 
58 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$__ip]  = $self->getIp  unless $self->[$__ip];  
 
59 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$__ip6] = $self->getIp6 unless $self->[$__ip6];  
 
60 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
61 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self;  
 
62 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
63 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
64 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub getDevInfo {  
 
65 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $self = shift;  
 
66 
 
 
 
 
 
 
 
 
 
 
 
 
 
    # By default, we take outgoing device to Internet  
 
67 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$___dnet] = Net::Libdnet::intf_get_dst(shift() || '1.1.1.1');  
 
68 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->getDev;  
 
69 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
70 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
71 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub getDevInfoFor {  
 
72 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $self = shift;  
 
73 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$___dnet] = Net::Libdnet::intf_get(shift());  
 
74 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->getDev;  
 
75 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
76 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
77 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub updateDevInfo {  
 
78 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $self = shift;  
 
79 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->getDevInfo(shift());  
 
80 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$__dev] = $self->getDev;  
 
81 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$__ip]  = $self->getIp;  
 
82 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$__ip6] = $self->getIp6;  
 
83 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->[$__mac] = $self->getMac;  
 
84 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
85 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
86 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub getDev { shift->[$___dnet]->{name} || (($^O eq 'linux') ? 'lo' : 'lo0') }  
 
87 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
88 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub getMac { shift->[$___dnet]->{link_addr} || 'ff:ff:ff:ff:ff:ff' }  
 
89 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
90 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub getIp {  
 
91 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $ip = shift->[$___dnet]->{addr} || '127.0.0.1';  
 
92 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $ip =~ s/\/\d+$//;  
 
93 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $ip;  
 
94 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
95 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
96 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _getIp6 {  
 
97 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $self = shift;  
 
98 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $dev = $self->[$__dev];  
 
99 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $mac = $self->[$__mac];  
 
100 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $buf = `/sbin/ifconfig $dev 2> /dev/null`;  
 
101 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $buf =~ s/$dev//;  
 
102 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $buf =~ s/$mac//i;  
 
103 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my ($ip6) = ($buf =~ /((?:[a-f0-9]{1,4}(?::|%|\/){1,2})+)/i); # XXX: better  
 
104 
 
 
 
 
 
 
 
 
 
 
 
 
 
    if ($ip6) {  
 
105 
 
 
 
 
 
 
 
 
 
 
 
 
 
       $ip6 =~ s/%|\///g;  
 
106 
 
 
 
 
 
 
 
 
 
 
 
 
 
       $ip6 = lc($ip6);  
 
107 
 
 
 
 
 
 
 
 
 
 
 
 
 
    }  
 
108 
 
 
 
 
 
 
 
 
 
 
 
 
 
    ($ip6 && Net::IPv6Addr::ipv6_chkip($ip6) && $ip6) || '::1';  
 
109 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
110 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
111 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub getIp6 {  
 
112 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $self = shift;  
 
113 
 
 
 
 
 
 
 
 
 
 
 
 
 
    $self->_getIp6($self->[$__dev]);  
 
114 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
115 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
116 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub debug {  
 
117 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $self = shift;  
 
118 
 
 
 
 
 
 
 
 
 
 
 
 
 
    @_ ? do { $self->[$__debug] = $Class::Gomor::Debug = shift }  
 
119 
 
 
 
 
 
 
 
 
 
 
 
 
 
       : $self->[$__debug];  
 
120 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
121 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
122 
 
 
 
 
 
 
 
 
 
 
 
 
 
 1;  
 
123 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
124 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 NAME  
 
125 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
126 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Net::Packet::Env - environment object used for frame capture/injection  
 
127 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
128 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 SYNOPSIS  
 
129 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
130 
 
 
 
 
 
 
 
 
 
 
 
 
 
    use Net::Packet::Env;  
 
131 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
132 
 
 
 
 
 
 
 
 
 
 
 
 
 
    # Get default values from system  
 
133 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $env = Net::Packet::Env->new;  
 
134 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
135 
 
 
 
 
 
 
 
 
 
 
 
 
 
    # Get values from a specific device  
 
136 
 
 
 
 
 
 
 
 
 
 
 
 
 
    my $env2 = Net::Packet::Env->new(dev => 'vmnet1');  
 
137 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
138 
 
 
 
 
 
 
 
 
 
 
 
 
 
    print "dev: ", $env->dev, "\n";  
 
139 
 
 
 
 
 
 
 
 
 
 
 
 
 
    print "mac: ", $env->mac, "\n";  
 
140 
 
 
 
 
 
 
 
 
 
 
 
 
 
    print "ip : ", $env->ip,  "\n" if $env->ip;  
 
141 
 
 
 
 
 
 
 
 
 
 
 
 
 
    print "ip6: ", $env->ip6, "\n" if $env->ip6;  
 
142 
 
 
 
 
 
 
 
 
 
 
 
 
 
    print "promisc: ", $env->promisc, "\n";  
 
143 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
144 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 DESCRIPTION  
 
145 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
146 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Basically, this module is used to tell where to inject a frame, and how to capture a frame.  
 
147 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
148 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 ATTRIBUTES  
 
149 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
150 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
151 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
152 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
153 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
154 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The device on which frames will be injected/captured.  
 
155 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
156 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
157 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
158 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The MAC address used to build injected frames.  
 
159 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
160 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
161 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
162 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The IPv4 address used to build injected frames.  
 
163 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
164 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
165 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
166 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The IPv6 address used to build injected frames.  
 
167 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
168 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B 
 
169 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
170 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The link type of the capturing process (see B). It will be set automatically when a capturing device is open. Usually used internally.   
 
171 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
172 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
173 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
174 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The B object used to inject frames to network.   
 
175 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
176 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
177 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
178 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The B object used to receive frames from network.   
 
179 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
180 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
181 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
182 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This one is used to tell the tcpdump-like process (see B) to go into promiscuous mode or not. Note: the device may be already in promiscuous mode, so even when you set it to 0, you may be in the situation to capture in promiscuous mode.   
 
183 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
184 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
185 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
186 
 
 
 
 
 
 
 
 
 
 
 
 
 
 When set, the pcap filter that'll be used for packet captures will be this one. It must be manually set if you want this feature. Default is to capture all traffic.  
 
187 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
188 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
189 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
190 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The environment debug directive. Set it to a number greater than 0 to increase the level of debug messages. Up to 3, default 0.  
 
191 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
192 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
193 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
194 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 METHODS  
 
195 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
196 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
197 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
198 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item B   
 
199 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
200 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Object constructor. You can pass attributes that will overwrite default ones. Default values:  
 
201 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
202 
 
 
 
 
 
 
 
 
 
 
 
 
 
 dev: autoDev() - the one tcpdump get without -i parameter.  
 
203 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
204 
 
 
 
 
 
 
 
 
 
 
 
 
 
 mac: autoMac() - from dev, MAC address the default device has.  
 
205 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
206 
 
 
 
 
 
 
 
 
 
 
 
 
 
 ip: autoIp() - from dev, IPv4 address the default device has.  
 
207 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
208 
 
 
 
 
 
 
 
 
 
 
 
 
 
 ip6: autoIp6() - from dev, IPv6 address the default device has.  
 
209 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
210 
 
 
 
 
 
 
 
 
 
 
 
 
 
 promisc: 0  
 
211 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
212 
 
 
 
 
 
 
 
 
 
 
 
 
 
 link: undef  
 
213 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
214 
 
 
 
 
 
 
 
 
 
 
 
 
 
 See B for more about auto* sub routines.   
 
215 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
216 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
217 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
218 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 AUTHOR  
 
219 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
220 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Patrice EGomoRE Auffret    
 
221 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
222 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 COPYRIGHT AND LICENSE  
 
223 
 
 
 
 
 
 
 
 
 
 
 
 
 
      
 
224 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Copyright (c) 2004-2006, Patrice EGomoRE Auffret    
 
225 
 
 
 
 
 
 
 
 
 
 
 
 
 
      
 
226 
 
 
 
 
 
 
 
 
 
 
 
 
 
 You may distribute this module under the terms of the Artistic license.  
 
227 
 
 
 
 
 
 
 
 
 
 
 
 
 
 See LICENSE.Artistic file in the source distribution archive.  
 
228 
 
 
 
 
 
 
 
 
 
 
 
 
 
         
 
229 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 RELATED MODULES  
 
230 
 
 
 
 
 
 
 
 
 
 
 
 
 
            
 
231 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L, L, L     
 
232 
 
 
 
 
 
 
 
 
 
 
 
 
 
         
 
233 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut