Перейти к содержимому
Калькуляторы

DIR-100 - проблемы с telnet-ом Не работает telnet из perl-скрипта

Требуется удалённо переконфигурить некоторое кол-во DIR-100, прошитых в "свитч", Ver 2.01_sw.

Однако из скрипта на девайс даже не удается залогинится. В логе

Error2 negotiated with client

.

Аналогичным скриптом без проблем "общаемся" с DES-3526, DES-3200-10, DES-2108.

С консоли всё отрабатывает без проблем, здесь же не доходит даже до логина..

Вот скрипт(версия без команд конфигурирования, специально из веб предварительно установлен пароль):

#!/usr/bin/perl
use Net::Telnet ();
#
$host = '192.168.0.1';
$login = 'admin';
$pass = 'admin';
$file = '/command/dir-100/telnet.log';
#
$t = new Net::Telnet(Timeout => 10, Telnetmode => 0, Errmode => "return", Input_log => $file);
#
$t->open(Host => $host);
#
$t->waitfor('/login:/i');
$t->print($login);
$t->waitfor('/Password:/i');
$t->print($pass);
$t->waitfor('/CMD>/i');
#
$t->print('cfg');
$t->waitfor('/CFG>/i');
#
$t->print('prof show');
#
$t->print('quit');
#
@ls = $t->getlines;
print @ls;
#

Результат выше.. Пытался использовать вместо waitfor login и cmd - ни какой разницы..

Не пойму, в чём скрипт не может "договориться" с девайсом..

На форуме дилинка прокомментировали в стандартном стиле

Поддержка telnet в DIR-100 официально не документирована.

Может кому-то приходилось решать подобную задачку?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

$t->waitfor('/login:/i');

Может быть, не "login", а "username"?

А вообще у Net::Telnet есть метод login(), который перебирает все возможные варианты, поэтому изобретать собственный велосипед особо незачем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

$t->waitfor('/login:/i');

Может быть, не "login", а "username"?

nas-1# telnet 192.168.5.2

Trying 192.168.5.2...

Connected to 192.168.5.2.

Escape character is '^]'.

 

********************************************************************

D-Link DIR-100 Ver 2.01_sw Fri Oct 02 11:01:04 2009

********************************************************************

login:

А вообще у Net::Telnet есть метод login(), который перебирает все возможные варианты, поэтому изобретать собственный велосипед особо незачем.

.. Пытался использовать вместо waitfor login и cmd - ни какой разницы..

Такое ощущение, что скрипт "не видит" ответы DIR-а. Вот лог ответов девайса:

********************************************************************
D-Link DIR-100 Ver 2.01_sw Fri Oct 02 11:01:04 2009
********************************************************************
login: ...kjub...yxb...br
..
...gfhj...kmx...br
..
...cfg...
Password: ...***...***...***...
Login incorrect

login: ...qui...t

Т.е. такое ощущение, что waitfor просто не работает..

$t->login()

$t->cmd()

дают аналогичный результат.

P.S. Слышал, что похоже ведут себя некоторые циски из-за того что используют то ли нестандартный протокол обмена, то ли тип терминала им не нравится. Кстати, с типом терминала тоже пробовал играться, вот нагуглил здесь, ничего не помогает... :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тогда такой финт ушами:

$telnet->connect();

sleep 3;

$telnet->print("$login\n");

sleep 3;

$telnet->print("$password\n");

 

Кроме \n, попробуйте \r, \n\r и \r\n

 

Кстати, почему у Вас "Telnetmode => 0"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

$telnet->connect();

А разве у Net::Telnet есть такой метод??

sleep 3;

$telnet->print("$login\n");

sleep 3;

$telnet->print("$password\n");

 

Кроме \n, попробуйте \r, \n\r и \r\n

Перепробовал всё из вышеописанного, кроме connect() (не понимаю, где его использовать). А со всем остальным наигрался до блевоты.. :(

Что-то тут другое.. Вот на форуме дилинка высказали такое предположение

Причина может быть в том, telnet-соединение и raw-соединение не совсем одно и тоже. Есть здесь две кошки SCE, так вот одна понимает "тупой коннект" на 23-й порт, а другая ждет согласования типа терминала и т.д., соответственно скрипт, вываливающий данные, не ожидая приглашения, не отрабатывает корректно.

но решения не предложили..

Кстати, почему у Вас "Telnetmode => 0"?

Это один из вариантов "игр" с девайсом, естественно начинал с дефолтным Telnetmode (включеным).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Была точно такая же проблема с коммутатором EdgeCore ES3528M, насколько я понял, это происходило из-за того, что он слал какие-то спецсимволы, которые стандартные telnet-классы не переваривали, плюнул на это дело и написал баш-скриптик такого вида:

 

(sleep 3;echo LOGIN;sleep 2;echo PASS;sleep 2;echo "cmd";...;sleep 2) | telnet $1

 

это если надо тупо что-то выполнить на железке. А если надо ещё и смотреть, что железка вернула и в зависимости от этого что-то делать, то можно использовать утилиту expect

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

это если надо тупо что-то выполнить на железке. А если надо ещё и смотреть, что железка вернула и в зависимости от этого что-то делать, то можно использовать утилиту expect

"Тупо выполнить", не посмотрев даже, скушала ли железка то что ей предложили? Типа "чукча не читатель, чукча писатель". Неее, не вариант..

С expect-ом как-то имел дело.. Душа не приняла.. :) Уж шибко мудрёно в нём всё. Как говориться, "не для средних умов". :) Хотя возможно, он и станет "осознанной неизбежностью".. Пока всё же не теряю надежды с помощью "перловых гуру", разрулить проблемку на Net::Telnet. Чую, что всё гениальное, как обычно просто.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

С expect-ом как-то имел дело.. Душа не приняла.. :) Уж шибко мудрёно в нём всё. Как говориться, "не для средних умов". :)

 

А собственно в чём разница между

$t->waitfor('/login:/i');
$t->print($login);

и

expect "login:"
send "$login\r"

?

 

По поводу чукчи, то тут зависит от задачи. Если надо тупо перепрошивать или проводить первоначальную настройку перед тем как отдать абоненту, то способ с чукчей-писателем подойдёт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может я конечно что-то не так делаю, но и в expect результат аналогичный - вылет по таймауту на этапе логина..

Сделал логирование процесса. Получил абракадабру такого вида

ЪЩ.ЪШ.ЪШ.

,что в HEX формате выглядит так

00000000 FF FD 18 FF │ FB 01 FF FB │ 03                                                                                 ЪЩ.ЪШ.ЪШ.

Похоже девайс вместо \n (0d-0a) отправляет Ctrl-C(03), что по-видимому вводит в ступор скрипт..

Как бы это правильно обработать?

Изменено пользователем AlKov

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Причину проблемы ориентировочно нашел - несогласованность "переговоров" свитча и терминала.

Вот запись "переговоров" с *nix терминала, где всё работает (192.168.5.10 - свитч, 10.254.213.1 - терминал)

1.	10.254.213.1 [telnet WILL AUTHENTICATION, DO ENCRYPT, WILL ENCRYPT, DO SUPPRESS GO AHEAD, WILL TERMINAL TYPE, WILL NAWS, WILL TSPEED, WILL LFLOW, WILL LINEMODE, WILL NEW-ENVIRON]
2.	192.168.5.10 [telnet DO TERMINAL TYPE]                                             (ff fd 18)
3.	192.168.5.10 [telnet WILL ECHO]                                                    (ff fb 01)
4.	10.254.213.1 [telnet DO ECHO]                                                      (ff fd 01)
5.	192.168.5.10 [telnet WILL SUPPRESS GO AHEAD]                                       (ff fb 03)
6.	192.168.5.10 [telnet SB TERMINAL TYPE SEND SE]                                     (ff fa 18 01 ff f0) запрос типа терминала
7.	10.254.213.1 [telnet SB TERMINAL TYPE IS 0x58 0x54 0x45 0x52 0x4d SE]    (XTERM)   (ff fa 18 00 58 54 45 52 4d ff f0)
8.	192.168.5.10 [telnet DONT NAWS]
9.	192.168.5.10 [telnet DONT TSPEED]
10.	192.168.5.10 [telnet DONT LFLOW]
11.	192.168.5.10 [telnet DONT LINEMODE]
12.	192.168.5.10 [telnet DONT NEW-ENVIRON]
13.	192.168.5.10 [telnet WONT STATUS]
14.	дальше вывод *** и прочей инфы от свитча, заканчивая login:(пробел)

А вот запись "переговоров" с Net::Telnet

1.	192.168.5.10 [telnet DO TERMINAL TYPE]
2.	10.254.213.1 [telnet WILL TERMINAL TYPE]
3.	192.168.5.10 [telnet WILL ECHO]
4.	10.254.213.1 [telnet DONT ECHO]
5.	192.168.5.10 [telnet WILL SUPPRESS GO AHEAD]
6.	10.254.213.1 [telnet DONT SUPPRESS GO AHEAD]
7.	192.168.5.10 [telnet SB TERMINAL TYPE SEND SE]
8.	10.254.213.1 [telnet SB TERMINAL TYPE IS 0x58 0x54 0x45 0x52 0x4d SE]
9.	дальше вывод *** и прочей инфы от свитча, заканчивая login:(пробел)

Предполагаю что проблема либо здесь -

192.168.5.10 [telnet WILL SUPPRESS GO AHEAD]
10.254.213.1 [telnet DONT SUPPRESS GO AHEAD]

, либо здесь -

192.168.5.10 [telnet WILL ECHO]
10.254.213.1 [telnet DONT ECHO]

А вот как "научить" Net::Telnet делать то что нужно, не знаю.. Пытаюсь решить с помощью Net::Telnet::Options, но пока никак не могу въехать, как из скрипта отправить нужный ответ.. :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Попробовать binmode(0/1)

Аналогично.. Забил на телнет, сделал "заливку" готового конфига через веб на php curl. Как оказалось, девайс сохраняет конфиг в текстовом виде, хотя расширение у файла - bin.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тоже понадобилось логиниться на DIR-100 с помощью Net::Telnet. В моем случае проблема была в том, что DIR-100 просит клиента сообщить тип терминала, а Net::Telnet отказывает в этом

RCVD DO TERMINAL TYPE
SENT WONT TERMINAL TYPE
RCVD WILL ECHO
SENT DO ECHO
RCVD WILL SUPPRESS GO AHEAD
SENT DO SUPPRESS GO AHEAD

 

Дальше я нагуглил эту тему - Managing TERM TYPE Option Requests with Net::Telnet и смог подключиться к DIR-100

use Net::Telnet;
use Net::Telnet::Options;

my %options = (
   'TTYPE' => { 'DO' => sub {} },
   'ECHO'  => { 'DO' => sub {} },
   'SUPPRESS-GO-AHEAD' => { 'DO' => sub {} },
);
my $nto = Net::Telnet::Options->new(%options);

my $t = new Net::Telnet( Timeout => '4' );

$t->telnetmode(0);

$t->open('10.10.10.10');

my $data;
recv($t, $data, 1024, 0);
$nto->answerTelnetOpts($t, $data);
$nto->sendOpt($t, 'SB', 24, 'IS', 'xterm');
recv($t, $data, 1024, 0);
$nto->answerTelnetOpts($t, $data);
recv($t, $data, 1024, 0);
$nto->answerTelnetOpts($t, $data);

$t->telnetmode(1);

my $content;
while (my $line = $t->getline() ) {
   print $line;
}

...
********************************************************************
D-Link DIR-100 Ver 2.01_sw Fri Oct 02 11:01:04 2009
********************************************************************
...

Изменено пользователем Painter

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.