7.4. 使用 dip

现在这相当简单。然而,您可能希望自动化之前描述的步骤。如果有一个简单的命令可以执行所有必要的步骤,例如打开串行设备、使调制解调器拨号到提供商、登录、启用 SLIP 线路规程以及配置网络接口,那就更好了。 这就是 dip 命令的用途。

dip 的意思是 拨号 IP (Dialup IP)。它由 Fred van Kempen 编写,并被许多人大量修补。如今,几乎每个人都在使用一个分支:版本dip337p-uri,它包含在大多数现代 Linux 发行版中,或者可以从 metalab.unc.edu FTP 存档中获得。

dip 为一种简单的脚本语言提供了解释器,该脚本语言可以为您处理调制解调器,将线路转换为 SLIP 模式,并配置接口。 该脚本语言功能强大,足以满足大多数配置。

为了能够配置 SLIP 接口,dip 需要 root 权限。现在很想将 dip 设置为 setuid root,以便所有用户都可以拨号连接到某些 SLIP 服务器,而无需授予他们 root 访问权限。 然而,这非常危险,因为使用 dip 设置虚假接口和默认路由可能会扰乱您网络上的路由。 更糟糕的是,此操作将使您的用户能够连接到任何 SLIP 服务器,并对您的网络发起危险的攻击。 如果您想允许您的用户启动 SLIP 连接,请为每个潜在的 SLIP 服务器编写小型包装程序,并让这些包装程序使用建立连接的特定脚本调用 dip。 仔细编写的包装程序可以安全地设置为 setuid root[1] 另一种更灵活的方法是使用像 sudo 这样的程序,向受信任的用户授予对 dip 的 root 访问权限。

7.4.1. 示例脚本

假设我们要建立 SLIP 连接的主机是 cowslip,并且我们已经为 dip 编写了一个名为cowslip.dip的脚本来建立我们的连接。 我们使用脚本名称作为参数调用 dip
# dip cowslip.dip
DIP: Dialup IP Protocol Driver version 3.3.7 (12/13/93)
Written by Fred N. van Kempen, MicroWalt Corporation.
connected to cowslip.moo.com with addr 192.168.5.74
#

脚本本身在 示例 7-1 中显示。

示例 7-1. 示例 dip 脚本

# Sample dip script for dialing up cowslip
# Set local and remote name and address
	get $local vlager-slip
	get $remote cowslip
	port ttyS3                # choose a serial port
	speed 38400              # set speed to max
	modem HAYES              # set modem type
	reset                    # reset modem and tty
	flush                    # flush out modem response
# Prepare for dialing.
	send ATQ0V1E1X1\r
	wait OK 2
	if $errlvl != 0 goto error
	dial 41988
	if $errlvl != 0 goto error
	wait CONNECT 60
	if $errlvl != 0 goto error
# Okay, we're connected now
	sleep 3
	send \r\n\r\n
	wait ogin: 10
	if $errlvl != 0 goto error
	send Svlager\n
	wait ssword: 5
	if $errlvl != 0 goto error
	send knockknock\n
	wait running 30
	if $errlvl != 0 goto error
# We have logged in, and the remote side is firing up SLIP.
	print Connected to $remote with address $rmtip
	default                  # Make this link our default route
	mode SLIP                # We go to SLIP mode, too
# fall through in case of error
error:
	print SLIP to $remote failed.

连接到 cowslip 并启用 SLIP 后,dip 将从终端分离并转到后台运行。 然后,您可以开始在 SLIP 链路上使用正常的网络服务。 要终止连接,只需使用–k选项调用 dip。 这会向 dip 发送挂断信号,使用 dip 记录在/etc/dip.pid:
# dip -k

中的进程 ID。 在 dip 的脚本语言中,以美元符号为前缀的关键字表示变量名。 dip 有一组预定义的变量,将在下面列出。 例如,$remote$local 包含 SLIP 链路中涉及的远程主机和本地主机的主机名。

示例脚本中的前两个语句是 get 命令,这是 dip 设置变量的方式。 在这里,本地和远程主机名分别设置为 vlagercowslip

接下来的五个语句设置终端线路和调制解调器。reset 向调制解调器发送重置字符串。 下一个语句清除调制解调器响应,以便接下来几行的登录对话能够正常工作。 此对话非常简单:它只是拨打 cowslip 的电话号码 41988,并使用密码 knockknock 登录到帐户 Svlagerwait 命令使 dip 等待作为其第一个参数给定的字符串; 作为其第二个参数给出的数字使等待时间在该秒数后超时(如果未收到此类字符串)。 穿插在登录过程中的 if 命令检查执行命令时是否发生任何错误。

登录后执行的最终命令是 default,它使 SLIP 链路成为所有主机的默认路由,以及 mode,它在线路上启用 SLIP 模式,并为您配置接口和路由表。

7.4.2. dip 参考

在本节中,我们将为大多数 dip 命令提供参考。 您可以通过在测试模式下调用 dip 并输入 help 命令来概览它提供的所有命令。 要了解命令的语法,您可以输入不带任何参数的命令。 请记住,这不适用于不带参数的命令。 以下示例说明了 help 命令

# dip -t
DIP: Dialup IP Protocol Driver version 3.3.7p-uri (25 Dec 96)
Written by Fred N. van Kempen, MicroWalt Corporation.
Debian version 3.3.7p-2 (debian).

DIP> help
DIP knows about the following commands:

	beep         bootp        break        chatkey      config       
	databits     dec          default      dial         echo         
	flush        get          goto         help         if           
	inc          init         mode         modem        netmask      
	onexit       parity       password     proxyarp     print        
	psend        port         quit         reset        securidfixed 
	securid      send         shell        skey         sleep        
	speed        stopbits     term         timeout      wait         

DIP> echo
Usage: echo on|off
DIP>

在以下部分中,显示 DIP > 提示符的示例显示了如何在测试模式下输入命令以及它产生的输出。 缺少此提示符的示例应被视为脚本摘录。

7.4.2.1. 调制解调器命令

dip 提供了许多配置串行线路和调制解调器的命令。 其中一些是显而易见的,例如 port(选择串行端口)和 speeddatabitsstopbitsparity(设置常用线路参数)。 modem 命令选择调制解调器类型。 目前,唯一支持的类型是 HAYES(需要大写)。 您必须为 dip 提供调制解调器类型,否则它将拒绝执行 dialreset 命令。 reset 命令向调制解调器发送重置字符串; 使用的字符串取决于所选的调制解调器类型。 对于 Hayes 兼容的调制解调器,此字符串为 ATZ

flush 代码可用于清除调制解调器到目前为止发送的所有响应。 否则,reset 之后的聊天脚本可能会感到困惑,因为它会读取来自早期命令的 OK 响应。

init 命令选择要在拨号前传递给调制解调器的初始化字符串。 Hayes 调制解调器的默认值为“ATE0 Q0 V1 X1”,它启用命令回显和长结果代码,并选择盲拨号(不检查拨号音)。 现代调制解调器具有良好的出厂默认配置,因此这有点不必要,尽管它没有坏处。

dial 命令将初始化字符串发送到调制解调器并拨号连接到远程系统。 Hayes 调制解调器的默认拨号命令是 ATD

7.4.2.2. echo 命令

echo 命令用作调试辅助工具。 调用 echo on 使 dip 将其发送到串行设备的所有内容回显到控制台。 可以通过调用 echo off 再次将其关闭。

dip 还允许您暂时离开脚本模式并进入终端模式。 在此模式下,您可以像任何普通终端程序一样使用 dip,将您键入的字符写入串行线路,从串行线路读取数据,并显示字符。 要离开此模式,请输入 Ctrl-]。

7.4.2.3. get 命令

get 命令是 dip 设置变量的方式。 最简单的形式是将变量设置为常量,就像我们在cowslip.dip中所做的那样。 但是,您也可以通过指定关键字 ask 而不是值来提示用户输入
DIP> get $local ask
Enter the value for $local: _

第三种方法是从远程主机获取值。 乍一看似乎很奇怪,但在某些情况下这非常有用。 某些 SLIP 服务器不允许您在 SLIP 链路上使用自己的 IP 地址,而是在您拨入时从地址池中为您分配一个地址,并打印一些消息来告知您已分配的地址。 如果消息看起来像 “您的地址: 192.168.5.74”,以下 dip 代码片段将允许您获取地址
# finish login
wait address: 10
get $locip remote

7.4.2.4. print 命令

这是用于从启动 dip 的控制台回显文本的命令。 任何 dip 的变量都可以在 print 命令中使用。 这是一个例子
DIP> print Using port $port at speed $speed
Using port ttyS3 at speed 38400

7.4.2.5. 变量名

dip 仅理解一组预定义的变量。 变量名始终以美元符号开头,并且必须以小写字母书写。

$local$locip 变量包含本地主机的主机名和 IP 地址。 当您将规范主机名存储在 $local 中时,dip 将自动尝试将主机名解析为 IP 地址并将其存储在 $locip 变量中。 当您将 IP 地址分配给 $locip 变量时,会发生类似但相反的过程; dip 将尝试执行反向查找以识别主机的名称并将其存储在 $local 变量中。

$remote$rmtip 变量以相同的方式操作远程主机的主机名和地址。$mtu 包含连接的 MTU 值。

这五个变量是唯一可以使用 get 命令直接赋值的变量。 许多其他变量是由于具有相同名称的配置命令而设置的,但可以在 print 语句中使用; 这些变量是 $modem$port$speed

$errlvl 是您可以通过它访问上次执行的命令结果的变量。 错误级别为 0 表示成功,而非零值表示错误。

7.4.2.6. if 和 goto 命令

if 命令是一个条件分支,而不是功能齐全的编程 if 语句。 其语法为
if var op number goto label

表达式必须是 $errlvl$locip$rmtip 变量之一之间的简单比较。var必须是整数; 运算符op可以是以下之一==, !=, <, >, <=,和>=.

goto 命令使脚本的执行在带有label的行之后的行继续。 标签必须是行中的第一个单词,并且必须紧跟一个冒号。

7.4.2.7. send, wait 和 sleep

这些命令有助于在 dip 中实现简单的聊天脚本。send 命令将其参数输出到串行线路。 它不支持变量,但理解所有 C 风格的反斜杠字符序列,例如换行符 \n 和退格符 \b。 波浪号 (~) 可以用作回车符/换行符的缩写。

wait 命令接受一个单词作为参数,并将读取串行线路上的所有输入,直到检测到与该单词匹配的字符序列。 单词本身可能不包含任何空格。 可选地,您可以为 wait 提供超时值作为第二个参数; 如果在这么多秒内未收到预期的单词,则命令将返回 $errlvl 值为 1。 此命令用于检测登录和其他提示符。

sleep 命令可用于等待一定的时间量; 例如,耐心等待任何登录序列完成。 同样,时间间隔以秒为单位指定。

7.4.2.8. mode 和 default

这些命令用于将串行线路切换到 SLIP 模式并配置接口。

mode 命令是 dip 在进入守护进程模式之前执行的最后一个命令。 除非发生错误,否则该命令不会返回。

mode 接受协议名称作为参数。 dip 当前识别 SLIPCSLIPSLIP6CSLIP6PPPTERM 作为有效名称。 但是,当前版本的 dip 不理解自适应 SLIP。

在串行线路上启用 SLIP 模式后,dip 执行 ifconfig 以将接口配置为点对点链路,并调用 route 以设置到远程主机的路由。

此外,如果脚本在 mode 之前执行 default 命令,则 dip 会创建一个指向 SLIP 链路的默认路由。

注释

[1]

diplogin 也必须以 setuid root 身份运行。 请参阅本章末尾的部分。