App-DHCPClientUtils

 view release on metacpan or  search on metacpan

scripts/multi-homed-routing.pl  view on Meta::CPAN

#!/usr/bin/env perl

# vim: tabstop=4 shiftwidth=4 softtabstop=4 expandtab:

use 5.014;
use strict;
use warnings;


=head1 NAME

multi-homed-routing.pl - Policy-based IPv4 routing generator

=head1 VERSION

Version 0.07

=cut

our $VERSION = '0.07';

=head1 SYNOPSIS

App::DHCPClientUtils - Working with non-static IP-addresses can become tricky.
This set of tools was written to automate the IP-address handling when it changes.
Typical way sysadmins approach the dynamic IP-addresses is to manually configure
everything, and react after it changes.
That is, if/when they notice the address change occurred.

=head1 UTILITIES

=head1 AUTHOR

Jari Turkia, C<< <jatu at hqcodeshop.fi> >>

=head1 BUGS

Please report any bugs or feature requests to GitHub https://github.com/HQJaTu/App-DHCPClientUtils.
I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

=cut


use Net::Interface qw(:afs :iffs :iffIN6);
use Net::IP;
use Net::ISC::DHCPClient;
use POSIX qw();
use Template;
use Template::Constants qw( :chomp );
use Getopt::Long;
use Pod::Usage;
use Cwd qw ( realpath );



my @paths_to_attempt = ('/var/lib/dhclient', '/var/lib/dhcp', '/var/lib/NetworkManager');
my $rt_table_path = '/etc/iproute2/rt_tables';
my $rt_table_start_number = 10;
my $rt_rule_start_number = 50;
my @orig_args;
my $bash_reserved_characters_re = qr([ !"#\$&'()*;<>?\[\\`{|~\t\n]);

use constant POLICY_EQUAL    => 'equal';

scripts/multi-homed-routing.pl  view on Meta::CPAN

            my $table_name = "Table_" . $if->name;
            warn sprintf("Suggestion: Edit file %s, and add following lines:\n", $rt_table_path) if ($first_suggestion);
            $first_suggestion = 0;
            warn sprintf("%d %s\n", $rt_table_idx, $table_name);
            push(@cmd, $if->name . "=$rt_table_idx");
        }

        ++$rt_table_idx;
    }
    
    die "Detect failed!" if (!@cmd);

    print "\n" if (!$first_suggestion);
    printf("Run commad:\n%s %s\n", $0, join(' ', @cmd));
}


sub _read_routing_tables()
{
    # For table syntax, see: http://linux-ip.net/html/routing-tables.html
    my $tables = {};
    my $rt_table_re = qr/^\s*(\d+)\s+(\S+)/;
    open(RT_TABLE, $rt_table_path) or
        die "Failed to read IProuting2 table! Error: $!";
    while (<RT_TABLE>) {
        chomp();
        next if (!/$rt_table_re/);
        my $table_nro = $1;
        my $table_name = $2;
        next if ($table_nro <= 0 || $table_nro >= 253);
        if ($table_nro < 0 || $table_nro > 255) {
            die sprintf("IP route2 table %s contains invalid value %d in line '%s'",
                        $rt_table_path, $table_nro, $_);
        }
        if (defined($tables->{$table_nro})) {
            die sprintf("IP route2 table %s contains has value %d twice. Second line is '%s'",
                        $rt_table_path, $table_nro, $_);
        }
        $tables->{$table_nro} = $table_name;
    }
    close(RT_TABLE);

    return $tables;
}


#
# @param    $interfaces
#           Array of interface-objects:
#           device =>   Interface device name, eg. eth0
#           table =>    Routing-table to use from /etc/iproute2/rt_tables
#           address =>  IPv4 address of the interface
#           network =>  Network of the interface in the form, IPv4-address/netmask
#           gateway =>  IPv4 address of the gateway
#           weight =>   Weight of the route
sub routing_rules($$$)
{
    my ($interfaces, $default_policy, $single_policy_default_interface) = @_;

    my $config = {
        INTERPOLATE => 1,               # expand "$var" in plain text
        EVAL_PERL   => 1,               # evaluate Perl code blocks
        PRE_CHOMP   => 0,
        POST_CHOMP  => 1 # CHOMP_GREEDY,
    };

    # create Template object
    my $tt = Template->new($config);
    my $template = <<END_OF_FILE
#!/bin/bash

# vim: tabstop=4 shiftwidth=4 softtabstop=4 expandtab:


# This script is auto-generated output of command:
# \\\$ [% cmd_line %]


# This script can be called as part of SysV initscripts.
# For example, in RedHat Linux, symlink this as file /sbin/ifup-local
# See Red Hat Enterprise Linux7 Networking Guide for details.

# This script can be called as a NetworkManager dispatcher.
# Symlink this script in directory /etc/NetworkManager/dispatcher.d/



# Agument handling:
IFUP_DEVICE=
if [ \\\$# -gt 0 ]; then
    # Check if --argument or inteface name
    if [[ \\\$1 != --* ]]; then
        # Assume SysV init or Networkmanager interface name
        IFUP_DEVICE=\\\$1
        shift

        # Networkmanager?
        if [ \\\$# -gt 0 ]; then
            ACTION=\\\$1
            shift
            if [ "\\\$ACTION" != "up" ]; then
                # Run only on interface-up.
                exit
            fi
        fi
    fi
fi

# Id for this ruleset:
RULES_ID="[% rules_id %]"
RULES_DIR="/var/cache/routing-rules"
IP_TOOL=/sbin/ip

# Set up my interfaces
[% FOREACH if IN interfaces %]
IF[% if.table %]_DEVICE=[% if.device %]

IF[% if.table %]_IP=[% if.address %]

IF[% if.table %]_NET=[% if.network %]

[% IF if.gateway %]
IF[% if.table %]_GW=[% if.gateway %]

[% END %]
[% IF if.weight %]
IF[% if.table %]_WEIGHT=[% if.weight %]

[% END %]

[% END %]



( run in 1.243 second using v1.01-cache-2.11-cpan-97f6503c9c8 )