Человеческий скрипт для соединения

18.11.1999, © Igor Sysoev, igor@nitek.ru
 

Поскольку кермитовский скрипт никуда годен, напишем свой скрипт для соединения с провайдером. Вполне приличный скрипт для дозвонки можно сделать из подручных средств, например, с помощью chat, тем более, что man pppd именно его и рекомендует. chat идеально подходит для создания сценария диалога в стиле "чего ожидаем" - "и как на это реагируем".

Этот сценарий может быть записан в файле, и с помощью ключа -f мы можем указать chat имя этого файла, или же сценарий может находиться непосредственно в командной строке chat после всех ключей. Для начала мы рассмотрим первый способ - запишем в файл /etc/ppp/script следующее:

ABORT           "ERROR"
ABORT           "NO DIALTONE"
TIMEOUT         5
""              "AT"
"OK"-"+++"-""   "AT"
"OK"            "ATZ"
"OK"            "ATS7=120"
ABORT           "BUSY"
ABORT           "NO ANSWER"
ABORT           "NO CARRIER"
ABORT           "Login incorrect"
"OK"            "ATDP5551234"
TIMEOUT         125
"CONNECT"       "\c"
TIMEOUT         30
"ogin:"         "igor"
"assword:"      "1234567"
"}"              "\c"

Для удобства восприятия сценарий представлен в виде двух колонок - чего ждём из модема и как на это реагировать. Но, на самом деле, chat игнорирует все переносы строк и воспринимает сценарий в виде одной строки, состоящей из пар. Для управления диалогом существует несколько зарезервированных слов, таких как ABORT и TIMEOUT, воспринимаемых chat как команды. Эти команды должны находится на месте строк ожидания, иначе chat примет их за наш ответ. Ответы модема и нашу реакцию на них мы указали в кавычках, для того чтобы их было легче распознать среди команд.

На самом деле, кавычки не обязательны - они нужны только в том случае, если в строке встречается пробел или же строка совсем пустая. Я бы рекомендовал все же всегда использовать кавычки для улучшения читабельности и что бы избежать неприятностей с символами, к которым не равнодушен шелл, например, такими, как "&" и "*". Вместо двойных кавычек можно использовать одинарные.

Напротив команды ABORT указывается строка, встретив которую, chat завершит работу с ненулевым кодом выхода. В данном случае это строки "ERROR" и "NO DIALTONE". Команда TIMEOUT устанавливает время ожидания всех последующих за ней ответов модема. Если это время истекает, chat завершает работу с ненулевым кодом выхода. По умолчанию chat ждет 45 секунд. Это слишком много для ожидания результата "OK" из модема, поэтому мы уменьшаем это время до 5 секунд.

Пустая строка "" в первой колонке означает, что из модема ничего ждать не надо и можно сразу посласть в него "AT". После строки "AT" chat пошлет ещё и символ возврата каретки - CR (Carrige Return). Если же Вам не нужно заканчивать строку символом CR, то в конце строки укажите управляющий символ "\c".

Затем идет несколько странная строка. Работает она следующим образом. Мы ждём ответ "OK" и, если мы не получаем его в течение 5 секунд (наше время ожидания), то пишем в модем "+++" и, не дожидаясь ничего из модема (""), записываем туда "AT". Если же мы сразу получим ответ "OK", то альтернативная часть "-"+++"-""" просто игнорируется и сразу записывается "AT".

Дождавшись ответа "OK", мы сбрасываем модем - "ATZ" и записываем в него строку с нашими настройками - "ATS7=120". Вполне вероятно, что у Вас будет другая строка.

Затем, мы определяем ещё несколько строк, встретив которые, chat должен прекратить работу. Это строки "BUSY", "NO ANSWER", "NO CARRIER" и "Login incorrect". Последнюю строку Вам, возможно, придется заменить на строку, которой провайдер сообщает о неудачной попытке логина. В принципе, эти команды ABORT можно было бы разместить в начале сценария вместе с первыми двумя командами и это никак не повлияло бы на выполнения сценария.

После этого мы начинаем набирать номер и устанавливаем время ожидания строки "CONNECT" 125 секунд. Обратите внимание, что указать это время ожидания только для chat недостаточно, необходимо, что бы и модем знал о времени, в течение которго он будет ждать соединения. У большинства модемов это время равно 60 секундам и изменить его можно с помощью команды "ATS7=120", что мы и делаем сразу после сброса модема. Я бы рекомендовал устанавливать время ожидания соединения для pppd на пару-тройку секунд больше, чем у модема. В данном случае это не критично, но для набора нескольких номеров это необходимо.

После получения строки "CONNECT" мы уменьшаем время ожидания приглашения провайдера до 30 секунд. Строка "\c" во второй колонке означает, что писать в модем ничего не надо и можно стразу переходить к следующей строке ожидания - "ogin:". В этот момент перед взором chat предстает примерно такая картина (критичные для нашего сценария строки выделены):

CONNECT 14400/ARQ/V42b

       Cool Connection Internet Service Provider

login:

В ответ на "ogin:" мы вводим своё имя - "igor", которое у Вас будет, естественно, другим. После этого мы ждём строку "assword:" и в ответ вводим наш пароль "1234567". Вместо строк "ogin:" и "assword:" можно ожидать и полные варианты - "login:" и "Password:", если, конечно, Вы уверены, что они выглядят именно таким образом.

После ввода пароля мы получим либо фразу о том, что "Login incorrect", и chat прекратит работу с ненулевым кодом выхода, либо на той стороне появится что-то PPP-образное, радующее нас примерно вот такими зюками:

~Ъ}#ю!}!}!} }.}%}&SЫы(}'}"}(}"Ё[~

При появлении первой из таких зюк - "}", наш сценарий закончится, chat тоже завершит работу и выйдет с кодом "0".

Отладить этот скрипт можно, даже не используя pppd, не соединясь с провайдером и, более того, даже не имея модема. Дело в том, что chat считывает из стандартного потока ввода - stdin, а выводит в стандартный поток вывода - stdout. Кроме того, у chat есть ключ -V, который указывает chat всё, что он прочитал и вывел, выводить в стандартный поток вывода ошибок - stderr. Более подробную информацию о ходе выполнения сценария дает ключ -v (буква "v" строчная), но в этом случае вся информация выводится через syslogd. Поэтому вторым ключом -s мы можем указывать chat выводить её в stderr, а не через syslogd.

Итак, запустив

chat -v -s -f /etc/ppp/script

мы можем отладить наш сценарий, даже не имея модема. Как то же самое будет выглядить с модемом и живым провайдером, мы увидим в статье Звоним провайдеру.

Если Вы попробовали отладить наш сценарий, с ключём -v, то могли заметить, что chat показывает пароль в виде "send (1234567^M)", что, в принципе, неплохо на этапе отладки, но совершенно не обязательно в рабочем режиме, если вы планируете вести полные журналы соединения, используя ключ -v. Для этого Вы можете использовать управляющий символ "\q" и chat заменит пароль символами "??????":

"ogin:"         "igor"
"assword:"      "\q1234567"
"}"             "\c"

В нашем сценарии мы предполагали, что после ввода пароля на удалённой стороне должно появится что-то, понимающее PPP. Но если Вы залогинились на машину, на которой работает FreeBSD, и в качестве шелла у Вас указан не /usr/sbin/pppd, а, например, /usr/local/bin/bash, то скрипт необходимо изменить, что бы он в ответ на приглашение bash - "$" вызывал exec /usr/sbin/pppd:

"ogin:"         "igor"
"assword:"      "1234567"
"$"             "exec /usr/sbin/pppd"
"}"             "\c"

В принципе, можно вызывать просто /usr/sbin/pppd, не используя exec. В этом случае, bash вызовет /usr/sbin/pppd, а сам будет дожидатся его завершения. Если произойдет обрыв соединения, ядро завершит процессы pppd и bash. Но при определённых настройках порта на удалённой стороне bash может не выйти и остаться висеть на линии. В такой ситуации нужно использовать exec, поскольку в этом случае pppd замещает собой bash.

 


Наш баннер
Вы можете установить наш баннер на своем сайте или блоге, скопировав этот код:
RSS новости