Netdot
Netdot copied to clipboard
Teldat support
This is a plea for help, not an issue with netdot.
I'm trying to improve functionalities with Teldat routers.
As for SNMP teldat routers give interface information and most things quite nicely. But ip/mask information is missing, to obtain it for vrfs you need to use different communities/contexts, and this also give you access to a subset of the snmp trees with only ip/mask information for the interfaces present in relevant VRF. So I cannot just add each vrf as separate devices becouse snmp_info will fail (no descr etc). Also I counln't found a OID to retrieve the configured VRFs from the "general" no-VRF device either (so i could somehow walk the information on the different VRFs). So I gave up on the SNMP approach.
I'm trying to use the CLI for getting ARP and FWT, to prior add there a function to extract the ip/mask information and populate it in netdot database for that device, then get arp and fwt data for the now ip-enabled interfaces).
Maybe this could be made with something like it is done on Aironet.pm but to me all that is SNMP-based, so with my limited knowledge I'd thought to append my modifications on a Device/CLI/teldat.pm script.
As I'm making slow progess, now I'm stuck becouse as part of the Teldat privilege de-escalation i need to send CONTROL-P and I don't know how to do it.
Explanation: Teldat has 4 different privilege levels with different commands. Witch an example of a teldat session after just entering the generic un-privileged prompt:
ADM020 *p 4
ADM020 Config>feature vrf
-- VRF user configuration --
ADM020 VRF config>show config
; Showing Menu and Submenus Configuration for access-level 15 ...
; ATLAS60Router PMC 28 65 Version 11.01.00.20.24
vrf VoIP
vrf VPN_ADM
ADM020 VRF config>
****HERE YOU NEED TO SEND Control-p to get back to generic prompt and change privelege level to issue different commands
ADM020 *p 3
Console Operator
[...]
My question is I guess about Net::CLI::Interact probably, how can I send control characters?. I've tried with several variances of:
$s->cmd('\xa');
$s->cmd('\x0a');
$s->cmd('\\x0a');
$s->cmd('\\\x0a'); #yes, i know
$s->cmd('\010);
$s->cmd('\cP');
$s->cmd('^p');
but does not work. always get something like:
[ 0.854830] du SEEN:
\xa
CLI Error: Command error
ADM020 Config>
Edit: Found the solution to this, just needed to use " instead of '.
$s->cmd("\cP");
Does work. :-)
Also, is there an easy way to use phrasebook macros from Netdot CLI implementation?. If not... how can I change the prompt after changing a privilege level?.
ie:
$self->_cli_cmd(%$args, host=>$host, cmd=>'p 4', personality=>'teldat');
will change the prompt from generic to Config. But netdot keeps trying to match generic prompt, which fails.
I've done tests using Net::Appliance::Session directly and I'm doing this using:
$s->macro('begin_pfour');
And on teldat/pb
prompt generic
match /[\/a-zA-Z0-9._\[\]-]+ \* ?$/
prompt pfour
match /[Cc]onfig> ?$/
prompt pthree
match /[\/a-zA-Z0-9._\[\]-]+ \+ ?$/
prompt privileged
match /# ?$/
prompt configure
match /Config> ?$/
prompt user
match /[Uu]sername: ?$/
prompt pass
match /[Pp]assword: ?$/
macro paging
send
match generic
macro begin_pfour
send p 4
match pfour
macro begin_pthree
send p 3
match pthree
macro endp
send ^p
match generic
macro disconnect
send logout
follow /Do you wish to end connection \(Yes\/No\)\?/ with Yes\n
But without access to macros I don't know how to make my code aware of the prompt change.
About this I'm thinking about modifying CLI.pm either adding a new parameter $macro to _cli_cmd or maybe adding a new sub _cli_macro(), what do you think?.
Edit: I've make test adding $macro parameter to _cli_cmd and doing this (if $macro is present $cmd is ignored):
if ($macro) {
$logger->debug(sub{"$host: issuing CLI macro: '$macro' over $transport"});
@output = $s->macro($macro, {timeout=>$timeout});
$s->close();
}
So far it seems to be working, and not breaking anything but will need more testing.
My work in progess is in my own netdot fork , which contains a fork of latest cvicente repo + a merge of latest vink78 repo (to include PaloAlto API which I use). My changes include CLI supoprt for some more devices and my current tries at teldat, all of which I don't see ready for a pull request.
Thank you very much.
On Tue, Feb 1, 2022 at 3:34 AM Nicolás Victorero @.***> wrote:
This is a plea for help, not an issue with netdot.
I'm trying to improve functionalities with Teldat routers.
As for SNMP teldat routers give interface information and most things quite nicely. But ip/mask information is missing, to obtain it for vrfs you need to use different communities/contexts, and this also give you access to a subset of the snmp trees with only ip/mask information for the interfaces present in relevant VRF. So I cannot just add each vrf as separate devices becouse snmp_info will fail (no descr etc). Also I counln't found a OID to retrieve the configured VRFs from the "general" no-VRF device either (so i could somehow walk the information on the different VRFs). So I gave up on the SNMP approach.
I'm trying to use the CLI for getting ARP and FWT, to prior add there a function to extract the ip/mask information and populate it in netdot database for that device, then get arp and fwt data for the now ip-enabled interfaces).
Maybe this could be made with something like it is done on Aironet.pm but to me all that is SNMP-based, so with my limited knowledge I'd thought to append my modifications on a Device/CLI/teldat.pm script.
As I'm making slow progess, now I'm stuck becouse as part of the Teldat privilege de-escalation i need to send CONTROL-P and I don't know how to do it.
Explanation: Teldat has 4 different privilege levels with different commands. Witch an example of a teldat session after just entering the generic un-privileged prompt:
ADM020 *p 4
ADM020 Config>feature vrf
-- VRF user configuration -- ADM020 VRF config>show config ; Showing Menu and Submenus Configuration for access-level 15 ... ; ATLAS60Router PMC 28 65 Version 11.01.00.20.24
vrf VoIP vrf VPN_ADM
ADM020 VRF config>
****HERE YOU NEED TO SEND Control-p to get back to generic prompt and change privelege level to issue different commands
ADM020 *p 3 Console Operator
[...]
My question is I guess about Net::CLI::Interact probably, how can I send control characters?. I've tried with several variances of:
$s->cmd('\xa'); $s->cmd('\010); $s->cmd('\cP');
First try to send control characters in a regular perl script.
Maybe use, "chr". ie:
my $t = chr(10); print("$t\n");
will print two new-lines.
Control characters map to ASCII code points. From wikipedia we see the "caret notation" just counts up from Control-A at ASCII 0x01. ASCII 0x02 is then Control-B, etc.
So Control-P is 0x10 (decimal 16), Data Link Escape.
Maybe try something like:
s->cmd(chr(16));
[image: image.png]
-m Message ID: @.***>
Thank you Brian and mzgrave for the help. I closed this too fast.
Now I can send control-p using $s->cmd("\cP") just fine, problem is I cannot send it from macros. Using this macro has the same effect ans using $s->cmd('\cP')
macro disconnect
send \cP
send logout
follow /Do you wish to end connection \(Yes\/No\)\?/ with Yes\n
Error being:
[ 0.854116] du SEEN:
\cP
CLI Error: Command error
Just noticed yesterday that _cli_cmd is a "one line" command, handles change of privilege if needed, but every call to the function opens and closes Net::Appliance::Session session, so every call to it is atomic and unrelated to the last one.
To talk to teldat this doesn't suit my needs, as it needs several commands to get for example ip address.
I've made some modifications to _cli_cmd, to alllow the execution of custom macros and to be able to pass parameter (one for now) to that macros, with that I can make more or less complex macros to get to the point where i can execute my commands. Like for example:
my @output = $self->_cli_cmd(%$args, host=>$host, cmd=>'interface-addresses', macro=>'get_ip_vrf', personality=>'teldat', macro_param=>$line);
macro get_ip_vrf
send p 3
match p3
send protocol ip
match p3
send vrf %s
match p3
Just commited the new code to my repo on teldat branch.
I've make it to the point where I can add the ip information to the interfaces and get the relevant networks created using the update_ip function in Interface.pm. What update_ip seems not to provide is a way to assing the created subnet to a given site (in my case the same site where the device resides). I'm looking for a way to assign the subnet to the site afterwards, but cannot find a function/method like Ipblock->add_site or Site->assing_ipblock or something similar, anyone knows where does this kind of functionality reside?. I know the underneath database relation on sitesubnet table, but hope there was an already coded way to do it... somewhere. Also... is there a way to get to the IP assigned to an interface from the interface itself?. In ipblock table there's a device field, but on interface table there's no ipblock field, there is a physaddr I could start looking from there.
Solved the mac to IP thing with:
if ( my $phy = PhysAddr->search(address=>$ethernet)->first ) {
my (@arp) = $phy->get_last_n_arp(1);
my $ipb = Ipblock->retrieve($arp[0][0][1]);
$address = $ipb->full_address;
}
What still drives me crazy is how to enter a new sitesubnet relation. Or thigs like (where $dev is a instance of Netdot::Model::Device) $dev->interfaces beign used everywhere but there is no interfaces method defined in Device.pm or any other place I could fine, it seems to me after many tinkering that it is some kind of DBI abstraction probably related with the definitions on etc/netdot.meta that maps data on database to objects atributes. But still trying to figure it out.
In Ipblock.pm:search_like there are some references to site to subnet mapping but I cannot guess how to manipulate them from that code...
# Use the SiteSubnet relationship if available
map { $blocks{$_->subnet} = $_->subnet } map { $_->subnets } @sites;
# Add the entities related to the sites matching the criteria
map { push @ents, $_->entity } map { $_->entities } @sites;
# Get the Ipblocks related to those entities
map { $blocks{$_} = $_ }
map { $_->used_blocks, $_->owned_blocks } @ents;
Any help or pointers to documentation explaining how that parts works appreciated.
For those walking on my shoes, it seems that "hidden" methods corresponds to the DBI abstraction and how it converts data from the database into objects. Relations are defined on etc/netdot.meta
More information on how it all works on https://metacpan.org/pod/Class::DBI
For my adding to sitesubnet needs, this code will suffice, it yields errors if relation already exists, but will check beforehand if it exists and that'll suffice for my needs.
$newsubnet->add_to_sites({ site => $dev->site->id, subnet => $newsubnet->id,});