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