File: ip-addr-to-if-index

package info (click to toggle)
libsnmp-session-perl 1.14~git20221124T101957-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,104 kB
  • sloc: perl: 11,920; ansic: 25; makefile: 15
file content (141 lines) | stat: -rwxr-xr-x 3,553 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/local/bin/perl -w
## Name:	test/ip-addr-to-if-index
## Author:	Simon Leinen  <simon@switch.ch>
## Description:	Find ifIndex for given IP address
######################################################################
## Usage: test/ip-addr-to-if-index [-q] community@hostname ipaddr...
##
## This script finds the interface indices corresponding to the given
## IP addresses on the node.
##
## Example: 
##
## $ ./test/ip-addr-to-if-index public@babar 127.0.0.1 130.59.4.2
## 127.0.0.1       lo0        1
## 130.59.4.2      hme0       2
##
## The `-q' form suppresses the IP addresses and interface
## description:
##
## $ ./test/ip-addr-to-if-index -q public@babar 127.0.0.1 130.59.4.2
## 1
## 2
######################################################################

require 5.002;
use strict;
use SNMP_Session;
use BER;

sub usage();
sub ether_hex($ );
sub ifDescr($ $ );

my ($hostname,$community,$quiet);
$quiet = 0;
while ($ARGV[0] =~ /^-/) {
    if ($ARGV[0] eq '-q') {
	$quiet = 1;
	shift @ARGV;
    } else {
	usage ();
    }
}
$hostname = shift @ARGV || usage();
($community,$hostname) = ($hostname =~ /^(.*)@(.*)$/);

my $session;

die "Couldn't open SNMP session to $hostname"
    unless ($session = SNMP_Session->open ($hostname, $community, 161));

my $ip_address;
while ($ip_address = shift @ARGV) {
    my ($ip1,$ip2,$ip3,$ip4);
    usage()
	unless (($ip1,$ip2,$ip3,$ip4)
		= $ip_address =~ m/^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/);

    my @ifIndex_OID = qw(1 3 6 1 2 1 4 20 1 2);
    push @ifIndex_OID, $ip1;
    push @ifIndex_OID, $ip2;
    push @ifIndex_OID, $ip3;
    push @ifIndex_OID, $ip4;

    my @oids = (encode_oid (@ifIndex_OID));

    if ($session->get_request_response (@oids)) {
	my $response = $session->pdu_buffer;
	my ($bindings, $binding, $oid, $value);
	my ($ifIndex);

	($bindings) = $session->decode_get_response ($response);

	## IfIndex
	($binding,$bindings) = decode_sequence ($bindings);
	($oid,$value) = decode_by_template ($binding, "%O%@");
	$ifIndex = pretty_print ($value);

	if (!$quiet) {
	    printf STDOUT ("%-15s %-10s ", $ip_address,
			   &ifDescr ($ifIndex, $session));
	}
	printf STDOUT ("%d\n", $ifIndex);

    } else {
	die "No response received.\n";
    }
}

$session->close ();

1;

sub usage ()
{
    die "usage: $0 community\@hostname ipaddr...";
}

## ether_hex (HEX_STRING)
##
## Converts a raw hex representation into the common form used in
## Ethernet addresses, e.g. "080020830069" becomes
## "08:00:20:83:00:69".
##
sub ether_hex ($ )
{
    my ($string) = @_;
    $string =~ s/([0-9a-f][0-9a-f])/$1:/g;
    $string =~ s/:$//;
    $string;
}

my %ifDescrCache;

## ifDescr (IFINDEX, SESSION)
##
## Return the interface description associated with the given
## IFINDEX.  Uses SESSION as the destination for SNMP request.
## Results are cached in %ifDescrCache to avoid sending the same SNMP
## request more than once.
##
sub ifDescr($ $ )
{
    my @ifDescr = split ('\.','1.3.6.1.2.1.2.2.1.2');
    my ($ifIndex, $session) = @_;

    return $ifDescrCache{$ifIndex,$session}
    if defined ($ifDescrCache{$ifIndex,$session});
    push @ifDescr,$ifIndex;
    if ($session->get_request_response (encode_oid (@ifDescr))) {
	my $response = $session->pdu_buffer;
	my ($bindings, $binding, $oid, $value);

	($bindings) = $session->decode_get_response ($response);
	($binding,$bindings) = decode_sequence ($bindings);
	($oid,$value) = decode_by_template ($binding, "%O%@");
	return $ifDescrCache{$ifIndex,$session} = pretty_print ($value);
    } else {
	return "if#".$ifIndex;
    }
}