1#
2# $Id: Libdnet.pm,v c0d1c989fec0 2018/09/18 15:03:40 gomor $
3#
4# Copyright (c) 2004 Vlad Manilici
5# Copyright (c) 2008-2012 Patrice <GomoR> Auffret
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10#
11# 1. Redistributions of source code must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13#
14# 2. Redistributions in binary form must reproduce the above copyright
15#    notice, this list of conditions and the following disclaimer in
16#    the documentation and/or other materials provided with the
17#    distribution.
18#
19# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31package Net::Libdnet;
32use strict; use warnings;
33
34use base qw(Exporter DynaLoader);
35
36our $VERSION = '0.99';
37
38our %EXPORT_TAGS = (
39   obsolete => [qw(
40      addr_cmp
41      addr_bcast
42      addr_net
43      arp_add
44      arp_delete
45      arp_get
46      intf_get
47      intf_get_src
48      intf_get_dst
49      route_add
50      route_delete
51      route_get
52   )],
53   route => [qw(
54      dnet_route_open
55      dnet_route_add
56      dnet_route_delete
57      dnet_route_get
58      dnet_route_loop
59      dnet_route_close
60   )],
61   intf => [qw(
62      dnet_intf_open
63      dnet_intf_get
64      dnet_intf_get_src
65      dnet_intf_get_dst
66      dnet_intf_set
67      dnet_intf_loop
68      dnet_intf_close
69   )],
70   arp => [qw(
71      dnet_arp_open
72      dnet_arp_add
73      dnet_arp_delete
74      dnet_arp_get
75      dnet_arp_loop
76      dnet_arp_close
77   )],
78   fw => [qw(
79      dnet_fw_open
80      dnet_fw_add
81      dnet_fw_delete
82      dnet_fw_loop
83      dnet_fw_close
84   )],
85   tun => [qw(
86      dnet_tun_open
87      dnet_tun_fileno
88      dnet_tun_name
89      dnet_tun_send
90      dnet_tun_recv
91      dnet_tun_close
92   )],
93   eth => [qw(
94      dnet_eth_open
95      dnet_eth_get
96      dnet_eth_set
97      dnet_eth_send
98      dnet_eth_close
99   )],
100   ip => [qw(
101      dnet_ip_open
102      dnet_ip_checksum
103      dnet_ip_send
104      dnet_ip_close
105   )],
106   consts => [qw(
107      DNET_ADDR_TYPE_NONE
108      DNET_ADDR_TYPE_ETH
109      DNET_ADDR_TYPE_IP
110      DNET_ADDR_TYPE_IP6
111      DNET_FW_OP_ALLOW
112      DNET_FW_OP_BLOCK
113      DNET_FW_DIR_IN
114      DNET_FW_DIR_OUT
115      DNET_INTF_TYPE_OTHER
116      DNET_INTF_TYPE_ETH
117      DNET_INTF_TYPE_LOOPBACK
118      DNET_INTF_TYPE_TUN
119      DNET_INTF_FLAG_UP
120      DNET_INTF_FLAG_LOOPBACK
121      DNET_INTF_FLAG_POINTOPOINT
122      DNET_INTF_FLAG_NOARP
123      DNET_INTF_FLAG_BROADCAST
124      DNET_INTF_FLAG_MULTICAST
125   )],
126);
127our @EXPORT = (
128   @{$EXPORT_TAGS{consts}},
129   @{$EXPORT_TAGS{obsolete}},
130   @{$EXPORT_TAGS{route}},
131   @{$EXPORT_TAGS{intf}},
132   @{$EXPORT_TAGS{arp}},
133   @{$EXPORT_TAGS{fw}},
134   @{$EXPORT_TAGS{tun}},
135   @{$EXPORT_TAGS{eth}},
136   @{$EXPORT_TAGS{ip}},
137);
138
139__PACKAGE__->bootstrap($VERSION);
140
141use constant DNET_ADDR_TYPE_NONE => 0;
142use constant DNET_ADDR_TYPE_ETH  => 1;
143use constant DNET_ADDR_TYPE_IP   => 2;
144use constant DNET_ADDR_TYPE_IP6  => 3;
145
146use constant DNET_FW_OP_ALLOW => 1;
147use constant DNET_FW_OP_BLOCK => 2;
148use constant DNET_FW_DIR_IN   => 1;
149use constant DNET_FW_DIR_OUT  => 2;
150
151use constant DNET_INTF_TYPE_OTHER       => 1;
152use constant DNET_INTF_TYPE_ETH         => 6;
153use constant DNET_INTF_TYPE_LOOPBACK    => 24;
154use constant DNET_INTF_TYPE_TUN         => 53;
155use constant DNET_INTF_FLAG_UP          => 0x01;
156use constant DNET_INTF_FLAG_LOOPBACK    => 0x02;
157use constant DNET_INTF_FLAG_POINTOPOINT => 0x04;
158use constant DNET_INTF_FLAG_NOARP       => 0x08;
159use constant DNET_INTF_FLAG_BROADCAST   => 0x10;
160use constant DNET_INTF_FLAG_MULTICAST   => 0x20;
161
162sub addr_cmp     { _obsolete_addr_cmp    (@_) }
163sub addr_bcast   { _obsolete_addr_bcast  (@_) }
164sub addr_net     { _obsolete_addr_net    (@_) }
165sub arp_add      { _obsolete_arp_add     (@_) }
166sub arp_delete   { _obsolete_arp_delete  (@_) }
167sub arp_get      { _obsolete_arp_get     (@_) }
168sub intf_get     { _obsolete_intf_get    (@_) }
169sub intf_get_src { _obsolete_intf_get_src(@_) }
170sub intf_get_dst { _obsolete_intf_get_dst(@_) }
171sub route_add    { _obsolete_route_add   (@_) }
172sub route_delete { _obsolete_route_delete(@_) }
173sub route_get    { _obsolete_route_get   (@_) }
174
1751;
176
177__END__
178
179=head1 NAME
180
181Net::Libdnet - binding for Dug Song's libdnet
182
183=head1 SYNOPSIS
184
185   #
186   # This will just import every functions and constants
187   #
188   use Net::Libdnet;
189
190   #
191   # Network interface manipulation
192   #
193   # !!! ADVICE: you should use Net::Libdnet::Intf instead
194   #
195   use Net::Libdnet qw(:intf);
196   my $intf = dnet_intf_open();
197
198   my $eth  = dnet_intf_get($intf, { intf_name => 'eth0' });
199   print "IP:  ".$eth->{intf_addr}."\n";
200   print "MAC: ".$eth->{intf_link_addr}."\n";
201
202   my $dst  = dnet_intf_get_dst($intf, '192.168.0.10');
203   print "Name: ".$dst->{intf_name}."\n";
204   print "IP:   ".$dst->{intf_addr}."\n";
205   print "MAC:  ".$dst->{intf_link_addr}."\n";
206
207   my $src = dnet_intf_get_src($intf, '192.168.0.1');
208   print "Name: ".$src->{intf_name}."\n";
209   print "IP:   ".$src->{intf_addr}."\n";
210   print "MAC:  ".$src->{intf_link_addr}."\n";
211
212   dnet_intf_close($intf);
213
214   #
215   # Arp cache manipulation
216   #
217   # !!! ADVICE: you should use Net::Libdnet::Arp instead
218   #
219   use Net::Libdnet qw(:arp);
220   my $arp   = dnet_arp_open();
221
222   my $entry = dnet_arp_get($arp, {arp_pa => '10.0.0.1'});
223   print "MAC: ".$entry->{arp_ha}."\n";
224
225   dnet_arp_add   ($arp,
226      {arp_ha => '00:11:22:33:44:55', arp_pa => '10.0.0.10'});
227   dnet_arp_delete($arp,
228      {arp_ha => '00:11:22:33:44:55', arp_pa => '10.0.0.10'});
229   dnet_arp_close($arp);
230
231   #
232   # Route table manipulation
233   #
234   # !!! ADVICE: you should use Net::Libdnet::Route instead
235   #
236   use Net::Libdnet qw(:route);
237   my $route = dnet_route_open();
238   dnet_route_add   ($route,
239      {route_gw => '10.0.0.1', route_dst => '192.168.0.1'});
240   dnet_route_delete($route,
241      {route_gw => '10.0.0.1', route_dst => '192.168.0.1'});
242
243   my $get = dnet_route_get($route, {route_dst => '192.168.0.10'});
244   print "GW: ".$get->{route_gw}."\n";
245
246   dnet_route_close($route);
247
248   #
249   # Firewall rules manipulation
250   #
251   # !!! ADVICE: you should use Net::Libdnet::Fw instead
252   #
253   use Net::Libdnet qw(:fw :consts);
254   my $fw = dnet_fw_open();
255   # This is quite complex. This rule blocks TCP as input to 10.0.0.1
256   # You should really use Net::Libdnet::Fw instead.
257   dnet_fw_add   ($fw,
258      {fw_op => FW_DIR_IN, fw_proto => 6, fw_dst => '10.0.0.1'});
259   dnet_fw_delete($fw,
260      {fw_op => FW_DIR_IN, fw_proto => 6, fw_dst => '10.0.0.1'});
261   dnet_fw_close($fw);
262
263   #
264   # Send at IP level
265   #
266   # !!! ADVICE: you should use Net::Libdnet::Ip instead
267   #
268   use Net::Libdnet qw(:ip);
269   my $ip = dnet_ip_open();
270   my $raw = "\x47\x47\x47\x47";
271   dnet_ip_send($ip, $raw, length($raw));
272   dnet_ip_close($ip);
273
274   #
275   # Send at Ethernet level
276   #
277   # !!! ADVICE: you should use Net::Libdnet::Eth instead
278   #
279   use Net::Libdnet qw(:eth);
280   my $eth = dnet_eth_open('eth0');
281   dnet_eth_send($eth, $raw, length($raw));
282   dnet_eth_close($eth);
283
284   #
285   # Traffic interception
286   #
287   # !!! ADVICE: you should use Net::Libdnet::Tun instead
288   #
289   use Net::Libdnet qw(:tun);
290   my $tun = dnet_tun_open('10.0.0.10', '192.168.0.10', 1500);
291   my $buf = dnet_tun_recv($tun, 1500);
292   # Do stuff with $buf
293   dnet_tun_send($tun, $buf, length($buf));
294   dnet_tun_close($tun);
295
296   #
297   # hash refs in dnet format
298   #
299   my $intf = {
300      intf_alias_num   => 1,
301      intf_mtu         => 1500,
302      intf_len         => 112,
303      intf_type        => 6,
304      intf_name        => 'eth0',
305      intf_dst_addr    => undef,
306      intf_link_addr   => '00:11:22:33:44:55',
307      intf_flags       => 49,
308      intf_addr        => '10.100.0.10/24',
309      intf_alias_addrs => [ 'fe80::211:2ff:fe33:4455/64' ]
310   };
311   my $arp = {
312      arp_pa => '10.100.0.1',
313      arp_ha => '11:22:33:44:55:66'
314   };
315   my $route = {
316      route_gw  => '10.100.0.1',
317      route_dst => '0.0.0.0/0'
318   };
319   my $fw = {
320      fw_dir    => 2,
321      fw_sport  => [ 0, 0 ],
322      fw_dport  => [ 0, 0 ],
323      fw_src    => '0.0.0.0/0',
324      fw_dst    => '0.0.0.0/0',
325      fw_proto  => 6,
326      fw_device => 'eth0',
327      fw_op     => 2
328   };
329
330=head1 DESCRIPTION
331
332Net::Libdnet provides a simplified, portable interface to several low-level networking routines, including network address manipulation, kernel arp cache and route table lookup and manipulation, network firewalling, network interface lookup and manipulation, network traffic interception via tunnel interfaces, and raw IP packet and Ethernet frame transmission. It is intended to complement the functionality provided by libpcap.
333
334All the original and obsolete functions return I<undef> and print a warning message to the standard error when a problem occurs. The obsolete functions are: B<addr_cmp>, B<addr_bcast>, B<addr_net>, B<arp_add>, B<arp_delete>, B<arp_get>, B<intf_get>, B<intf_get_src>, B<intf_get_dst>, B<route_add>, B<route_delete>, B<route_get>.
335
336These obsolete functions will continue to work, to keep backward compatibility, but should not be used anymore. The new APIs should be preferred. There are two new APIs, one is the low-level one, matching libdnet functions, and the other one is a high-level API, matching a more Perl object oriented programming. This latest one is highly preferred.
337
338Net::Libdnet module implements the low-level API. The high-level API is accessible by using the following modules: B<Net::Libdnet::Intf>, B<Net::Libdnet::Route>, B<Net::Libdnet::Fw>, B<Net::Libdnet::Arp>, B<Net::Libdnet::Eth>, B<Net::Libdnet::Ip> and B<Net::Libdnet::Tun>.
339
340=head1 WHAT IS IMPLEMENTED
341
342=over 4
343
344=item B<Network addressing>
345
346Nothing as of now.
347
348=item B<Address Resolution Protocol>
349
350All functions: arp_open, arp_add, arp_delete, arp_get, arp_loop, arp_close.
351
352=item B<Binary buffers>
353
354Nothing as of now.
355
356=item B<Ethernet>
357
358All functions: eth_open, eth_get, eth_set, eth_send, eth_close.
359
360=item B<Firewalling>
361
362All functions: fw_open, fw_add, fw_delete, fw_loop, fw_close.
363
364=item B<Network interface>
365
366All functions: intf_open, intf_get_set, intf_get_dst, intf_set, intf_loop, intf_close.
367
368=item B<Internet Protocol>
369
370All functions: ip_open, ip_checksum, ip_send, ip_close.
371
372Except: ip_add_option.
373
374=item B<Internet Protocol Version 6>
375
376Nothing as of now.
377
378=item B<Random number generation>
379
380Nothing as of now.
381
382=item B<Routing>
383
384All functions: route_open, route_add, route_delete, route_get, route_loop, route_close.
385
386=item B<Tunnel interface>
387
388All functions: tun_open, tun_fileno, tun_name, tun_send, tun_recv, tun_close.
389
390=back
391
392=head1 SUBROUTINES
393
394=over 4
395
396=item B<dnet_intf_open> ()
397
398Opens an interface handle. Returns a handle on success, undef on error.
399
400=item B<dnet_intf_get> (scalar, hashref)
401
402Takes an intf handle, and a hash ref in dnet format as parameters. Returns a hash in dnet format on success, undef on error.
403
404=item B<dnet_intf_get_src> (scalar, scalar)
405
406Takes an intf handle, and an IP address as parameters. Returns a hash in dnet format on success, undef on error.
407
408=item B<dnet_intf_get_dst> (scalar, scalar)
409
410Takes an intf handle, and an IP address as parameters. Returns a hash in dnet format on success, undef on error.
411
412=item B<dnet_intf_set> (scalar, scalar)
413
414Takes an intf handle, and a hash ref in dnet format as parameters. Returns 1 on success, undef on error.
415
416=item B<dnet_intf_loop> (scalar, subref, scalarref)
417
418Takes an intf handle, a subref, and a scalar ref as parameters. Returns 1 on success, undef on error. The subref will be called with an intf hash ref in dnet format, and the scalar ref as parameters.
419
420=item B<dnet_intf_close> (scalar)
421
422Takes an intf handle as parameter. Returns the handle on success, undef on error.
423
424=item B<dnet_route_open> ()
425
426Opens a route handle. Returns a handle on success, undef on error.
427
428=item B<dnet_route_add> (scalar, hashref)
429
430Takes a route handle, and a hash ref in dnet format as parameters. Returns 1 on success, undef on error.
431
432=item B<dnet_route_delete> (scalar, hashref)
433
434Takes a route handle, and a hash ref in dnet format as parameters. Returns 1 on success, undef on error.
435
436=item B<dnet_route_get> (scalar, hashref)
437
438Takes a route handle, and a hash ref in dnet format as parameters. Returns a hash ref in dnet format on success, undef on error.
439
440=item B<dnet_route_loop> (scalar, subref, scalarref)
441
442Takes a route handle, a subref, and a scalar ref as parameters. Returns 1 on success, undef on error. The subref will be called with a route hash ref in dnet format, and the scalar ref as parameters.
443
444=item B<dnet_route_close> (scalar)
445
446Takes a route handle as parameter. Returns the handle on success, undef on error.
447
448=item B<dnet_arp_open> ()
449
450Opens an arp handle. Returns a handle on success, undef on error.
451
452=item B<dnet_arp_add> (scalar, hashref)
453
454Takes an arp handle, and a hash ref in dnet format as parameters. Returns 1 on success, undef on error.
455
456=item B<dnet_arp_delete> (scalar, hashref)
457
458Takes an arp handle, and a hash ref in dnet format as parameters. Returns 1 on success, undef on error.
459
460=item B<dnet_arp_get> (scalar, hashref)
461
462Takes an arp handle, and a hash ref in dnet format as parameters. Returns a hash ref in dnet format on success, undef on error.
463
464=item B<dnet_arp_loop> (scalar, subref, scalarref)
465
466Takes an arp handle, a subref, and a scalar ref as parameters. Returns 1 on success, undef on error. The subref will be called with an arp hash ref in dnet format, and the scalar ref as parameters.
467
468=item B<dnet_arp_close> (scalar)
469
470Takes an arp handle as parameter. Returns the handle on success, undef on error.
471
472=item B<dnet_fw_open> ()
473
474Opens a fw handle. Returns a handle on success, undef on error.
475
476=item B<dnet_fw_add> (scalar, hashref)
477
478Takes a fw handle, and a hash ref in dnet format as parameters. Returns 1 on success, undef on error.
479
480=item B<dnet_fw_delete> (scalar, hashref)
481
482Takes a fw handle, and a hash ref in dnet format as parameters. Returns 1 on success, undef on error.
483
484=item B<dnet_fw_loop> (scalar, subref, scalarref)
485
486Takes a fw handle, a subref, and a scalar ref as parameters. Returns 1 on success, undef on error. The subref will be called with a fw hash ref in dnet format, and the scalar ref as parameters.
487
488=item B<dnet_fw_close> (scalar)
489
490Takes a fw handle as parameter. Returns the handle on success, undef on error.
491
492=item B<dnet_tun_open> (scalar, scalar, scalar)
493
494Creates a tunnel between src and dst IP addresses. Captured packets will have specified size. First argument is the source IP address, second the destination IP address, and the third is the cpature size. Returns a handle on success, undef on error.
495
496=item B<dnet_tun_fileno> (scalar)
497
498Takes a tun handle as parameter. Returns the file number on success, undef on error.
499
500=item B<dnet_tun_name> (scalar)
501
502Takes a tun handle as parameter. Returns the interface name on success, undef on error.
503
504=item B<dnet_tun_send> (scalar, scalar, scalar)
505
506Takes a tun handle, the raw data to send, and its size as parameters. Returns the number of bytes sent on success, undef on error.
507
508=item B<dnet_tun_recv> (scalar, scalar)
509
510Takes a tun handle, and the maximum size to read as parameters. Returns the read buffer on success, undef on error.
511
512=item B<dnet_tun_close> (scalar)
513
514Takes a tun handle as parameter. Returns the handle on success, undef on error.
515
516=item B<dnet_eth_open> (scalar)
517
518Opens an eth handle. Takes an interface name as parameter. Returns a handle on success, undef on error.
519
520=item B<dnet_eth_get> (scalar)
521
522Takes an eth handle as parameter. Returns the hardware address of currently opened eth handle on success, undef on error.
523
524=item B<dnet_eth_set> (scalar, scalar)
525
526Takes an eth handle, and the hardware address to set as parameters. Returns 1 on success, undef on error.
527
528=item B<dnet_eth_send> (scalar, scalar, scalar)
529
530Takes an eth handle, the raw data to send, and its size as parameters. Returns the number of bytes sent on success, undef on error.
531
532=item B<dnet_eth_close> (scalar)
533
534Takes an eth handle as parameter. Returns the handle on success, undef on error.
535
536=item B<dnet_ip_open> ()
537
538Opens an ip handle. Returns a handle on success, undef on error.
539
540=item B<dnet_ip_checksum> (scalar, scalar)
541
542Takes a raw IPv4 frame as the first parameter, and its size as a second parameter. It then updates the frame with the good checksum. Returns nothing.
543
544=item B<dnet_ip_send> (scalar, scalar, scalar)
545
546Takes an ip handle, the raw data to send, and its size as parameters. Returns the number of bytes sent on success, undef on error.
547
548=item B<dnet_ip_close> (scalar)
549
550Takes an ip handle as parameter. Returns the handle on success, undef on error.
551
552=back
553
554=head1 OBSOLETE FUNCTIONS
555
556They should not be used anymore. You have been warned.
557
558=over 4
559
560=item B<addr_bcast>
561
562=item B<addr_cmp>
563
564=item B<addr_net>
565
566=item B<arp_add>
567
568=item B<arp_delete>
569
570=item B<arp_get>
571
572=item B<intf_get>
573
574=item B<intf_get_dst>
575
576=item B<intf_get_src>
577
578=item B<route_add>
579
580=item B<route_delete>
581
582=item B<route_get>
583
584=back
585
586=head1 CONSTANTS
587
588=over 4
589
590=item B<DNET_ADDR_TYPE_NONE>
591
592=item B<DNET_ADDR_TYPE_ETH>
593
594=item B<DNET_ADDR_TYPE_IP>
595
596=item B<DNET_ADDR_TYPE_IP6>
597
598=item B<DNET_FW_OP_ALLOW>
599
600=item B<DNET_FW_OP_BLOCK>
601
602=item B<DNET_FW_DIR_IN>
603
604=item B<DNET_FW_DIR_OUT>
605
606=item B<DNET_INTF_TYPE_OTHER>
607
608=item B<DNET_INTF_TYPE_ETH>
609
610=item B<DNET_INTF_TYPE_LOOPBACK>
611
612=item B<DNET_INTF_TYPE_TUN>
613
614=item B<DNET_INTF_FLAG_UP>
615
616=item B<DNET_INTF_FLAG_LOOPBACK>
617
618=item B<DNET_INTF_FLAG_POINTOPOINT>
619
620=item B<DNET_INTF_FLAG_NOARP>
621
622=item B<DNET_INTF_FLAG_BROADCAST>
623
624=item B<DNET_INTF_FLAG_MULTICAST>
625
626=back
627
628=head1 COPYRIGHT AND LICENSE
629
630You may distribute this module under the terms of the BSD license. See LICENSE file in the source distribution archive.
631
632Copyright (c) 2004, Vlad Manilici
633
634Copyright (c) 2008-2012, Patrice <GomoR> Auffret
635
636=head1 SEE ALSO
637
638L<dnet(3)>
639
640=cut
641