# 30.3.PPP 连接的故障排除

本节介绍使用调制解调器进行 PPP 连接时可能出现的一些问题。某些 ISP 会显示 `ssword` 提示符，而另一些则会显示 `password`。如果 `ppp` 脚本没有相应设置，登录尝试将失败。调试 `ppp` 连接最常见的方法是手动连接，下面将进行详细说明。

## 30.3.1. 检查设备节点

使用自定义内核时，请确保在内核配置文件中包含以下行：

```sh
device   uart
```

**uart** 设备已包含在 `GENERIC` 内核中，因此在这种情况下无需额外操作。只需通过以下命令检查 `dmesg` 输出中是否识别到了调制解调器设备：

```sh
# dmesg | grep uart
```

这应会显示一些关于 **uart** 设备的相关输出。它们即我们所需的 COM 端口。如果调制解调器表现得像一个标准串口，它通常会列在 **uart1**，也就是 **COM2**。如果确实如此，就不需要重建内核。当设备为 **uart1** 时，其设备文件应为 **/dev/cuau1**。

## 30.3.2. 手动连接

通过手动控制 `ppp` 连接到互联网是快速、简便、有效的调试方式，也有助于了解 ISP 是如何处理 `ppp` 客户端连接的。下面我们从命令行启动 PPP。以下示例中，运行 PPP 的主机名为 *example*。

首先启动 `ppp`：

```sh
# ppp
```

设置调制解调器设备：

```sh
ppp ON example> set device /dev/cuau1
```

设置连接速率为 115200 kbps：

```sh
ppp ON example> set speed 115200
```

启用 DNS 配置功能：

```sh
ppp ON example> enable dns
```

这会让 `ppp` 配置解析器并将 nameserver 条目添加到 **/etc/resolv.conf** 中。如果 `ppp` 无法识别主机名，可稍后手动设置。

进入“终端”模式以手动控制调制解调器：

```sh
ppp ON example> term
```

```sh
deflink: Entering terminal mode on /dev/cuau1
type '~h' for help
```

初始化调制解调器并拨号：

```sh
at
OK
atdt123456789
```

使用 `at` 初始化调制解调器，使用 `atdt` 加上 ISP 的电话号码发起拨号过程。

成功连接后，屏幕上会显示：

```sh
CONNECT
```

若存在与硬件无关的连接问题，通常会在此阶段显现。

输入 ISP 提供的用户名：

```sh
ISP Login:myusername
```

输入 ISP 提供的密码（输入时不会回显）：

```sh
ISP Pass:mypassword
```

可能会出现询问是否使用 shell 或启动 `ppp` 的提示：

```sh
Shell or PPP:ppp
```

在此示例中选择 `ppp` 以建立互联网连接。

成功连接后提示符会显示为：

```sh
Ppp ON example>
```

注意首字母 P 被大写，表示已成功连接 ISP。

等待分配 IP 地址：

```sh
Ppp ON example>
```

成功完成连接后：

```sh
PPP ON example>
```

添加默认路由，使系统能够访问外部网络：

```sh
PPP ON example> add default HISADDR
```

请务必在能连接外界前添加默认路由，否则系统当前只和对端建立了连接。如果由于已有路由而添加失败，可在 `add` 前加 `!` 字符跳过错误。或者在建立连接前设置此命令，以便自动协商路由。

如果一切顺利，现在系统应已成功连接互联网。可通过 `CTRL + z` 将连接转入后台。

若提示符从 `PPP` 返回为 `ppp`，则说明连接已断开。这一点非常实用，因为提示符中大写 P 表示已连接 ISP，小写 p 则表示连接已丢失。

## 30.3.3. 调试

如果无法建立连接，可使用 `set ctsrts off` 来关闭硬件流控 CTS/RTS。这个问题主要出现在连接某些支持 PPP 的终端服务器时，在这种情况下 PPP 在尝试向通信链路写入数据时会挂起，并等待永远不会到来的 CTS（Clear To Send）信号。使用此选项时，还应加上 `set accmap`，这在需要绕过依赖特定字符（如 XON/XOFF）端到端传输的硬件时非常有用。有关此选项及其使用方式的更多信息，请参阅 [ppp(8)](https://man.freebsd.org/cgi/man.cgi?query=ppp\&sektion=8\&format=html)。

对于老式调制解调器，可能需要使用 `set parity even`。默认情况下奇偶校验设置为 none，但在老式设备中可用作错误检测，尽管这会显著增加数据流量。

若 `ppp` 无法返回命令模式，通常是由于协商错误，可能是 ISP 正在等待协商开始。此时可输入 `~p` 强制 `ppp` 开始发送配置信息。

如果始终未出现登录提示符，可能是需要 PAP 或 CHAP 认证。要启用 PAP 或 CHAP，可在进入终端模式前添加以下设置：

```sh
ppp ON example> set authname 用户名
```

其中 *用户名* 应替换为 ISP 分配的用户名。

```sh
ppp ON example> set authkey 密码
```

其中 *密码* 应替换为 ISP 分配的密码。

如果连接建立了，但无法解析域名，可尝试使用 [ping(8)](https://man.freebsd.org/cgi/man.cgi?query=ping\&sektion=8\&format=html) 命令直接 ping 一个 IP 地址。如果出现百分之百的数据包丢失，可能是默认路由没有设置。请检查是否已在连接期间设置 `add default HISADDR`。如果能成功连接远程 IP，但仍无法解析域名，可能是没有向 **/etc/resolv.conf** 添加 DNS 解析器地址。该文件应类似如下格式：

```ini
domain example.com
nameserver x.x.x.x
nameserver y.y.y.y
```

其中 *x.x.x.x* 和 *y.y.y.y* 应替换为 ISP 提供的 DNS 服务器的 IP 地址。

要让 [syslog(3)](https://man.freebsd.org/cgi/man.cgi?query=syslog\&sektion=3\&format=html) 记录 PPP 连接日志，请确保 **/etc/syslog.conf** 中存在以下行：

```sh
!ppp
*.*     /var/log/ppp.log
```
