通过 Linux 串行默认值 shell 的 IP 隧道

IP tunnel over Linux serial default shell

这是 this 问题的更严格的版本:

我有一个嵌入式 ARM 设备运行使用 Linux 3.10.0 内核的自定义映像。

唯一的物理接口(没有,USB,没有以太网)是默认的 Linux shell,它连接到串行接口之一。

我的问题是:是否有任何内置或外部工具可以通过此连接打开 IP 隧道?

我看到一些一般性问题:

实际要求是,我可以从通过串行电缆连接到嵌入式设备的计算机访问嵌入式设备上 运行ning 的 REST 接口。

这已经适用于具有物理以太网或 USB 以太网的设备,但此设备不提供。

[更新] 如前所述,socat 目前在我们的嵌入式设备上不可用,因此作为第一次尝试,我使用了以下内容:

注意: 我在一侧使用 Windows 笔记本电脑,因为我们将在 Linux 上安装 socat 客户端 运行ning (很遗憾)。

  1. 直接 STDIO 连接

服务器

socat stdio file:/dev/ttyS0,b115200

客户端

socat file:/dev/ttyS4,b115200 stdio

在 cygwin 中,ttyS0COM1ttyS4 在这种情况下是 COM5

使用这些,socat 就像一个小聊天程序一样工作。为什么我在一侧输入是在另一侧输出,反之亦然。

  1. TCP 连接

下一步是使用 TCP 连接。

服务器

socat /dev/ttyS0,b115200,crtscts=1,raw,echo=0 tcp-connect:localhost:80

客户端

socat -T2 file:/dev/ttyS4,b115200,crtscts=1,raw,echo=0 tcp-l:7777,reuseaddr

我指定了波特率 (115200),使用原始传输,没有回显(否则 HTTP 请求将被发送回请求者)使用硬件流控制。 Pus 我不得不使用超时 -T2 在 2 秒后终止连接。否则,curl 也不会终止并等待更多数据。

当我在 windows 计算机上使用 curl 时,它通过串行连接成功传输了请求,并且 returns Linux 计算机上 HTTP 服务器的完整 HTTP 响应:

curl localhost:7777/index.html

但是,它只能工作一次。请求完成后,socat客户端和服务器都终止。

此外,当我使用浏览器 (Chorme) 时,它使用最有可能发送二进制字符的 g-zip 编码。这些字符之一将是一个 EOF 字符,它在完成 request/response 之前再次终止 socat

然后我尝试将fork添加到服务器:

socat /dev/ttyS0,b115200,crtscts=1,raw,echo=0 tcp-connect:localhost:80,fork

这使服务器保持活动状态,但是 curl returns 400 Bad Request。因此,似乎 socat 服务器为每一行或块发起了一个请求,因为它不理解 HTTP。

  1. IP 连接

然后就想到再往下一层,用TUN连接。然而,这在 socat.

的 Windows 版本上没有实现
  1. HTTP 连接

如果我错了请纠正我,但据我了解,socat不提供真正理解 HTTP 并能够通过串行连接正确序列化它的连接类型。

所以,我找不到任何稳定的方式来启动客户端和服务器以及通过串行连接 运行 多个 HTTP 请求。

在正常 linux 上,您可以使用 socat

此程序允许您连接多种流类型(文件、套接字、tcp、udp 等)。在您的情况下,它将是 tcp to file 或更准确地说是端口 xx 到 /dev/ttyUSB1 的 tcp 套接字。你应该在两侧启动 socat 来建立隧道。

编辑 1:
对不起,我也对 socat 感到失望。我找不到让我的 TCP 侦听器在多个连续连接中保持活动状态但一次只处理一个连接的解决方案。

我的解决方案是使用 4 个线程的简单 C# 程序: 1. 等待 stdin 的输入,例如退出命令 2.TCP监听器 3. 用于活动连接的 TCP 工作线程 4. 如果 TCP 开启,则为 COM

开启另一个线程

线程 3 从 TCP 读取并写入 COM,线程 4 从 COM 读取并写入 TCP。如果线程收到 TCP 关闭事件,它将停止关闭 COMx 的线程 4,并自行退出。现在线程 2 可以接受一个新的连接。如果线程 1 在 stdin 上读取退出,它会向所有线程传递一条消息以停止和关闭。

也许你可以在没有socat的嵌入式系统上用pthreads用C实现这么短的程序。

EOF问题: 我尝试 google 用于转义特殊字符或将数据流从 ASCII 重新编码为 ANSI 或 base64 或其他任何内容的程序......如果你能找到这样的程序或用 C 编写它,你可以通过管道传输它中间

Server <=> reencode <=> socat <--serial--> socat <=> reencode <=> client

我们现在已经使用 pppd. As it turns out, even Windows supports ppp 中途解决了问题。与 socat 相比,pppd 实际上使用了一种包含错误检测的协议,它会自动在 Linux 和 Windows 系统上创建网络设备。

唯一的问题是,pppd 需要访问串行设备。没有 ppp 工具提供的直接模式。

我们现在按需禁用 shell,重新启动到 IP-over-serial 模式。完成后,我们重新启动系统,系统会使用串行线自动切换回 getty

这不是最漂亮的解决方案,但现在看来可行。