【问题标题】:Telnet: How to remove NULL (0x00) after every CR (0x0d) on send, using char mode (interactive mode)?Telnet:如何使用字符模式(交互模式)在发送每个 CR(0x0d)后删除 NULL(0x00)?
【发布时间】:2015-11-24 20:27:31
【问题描述】:

我正在使用我的开源串行到 IP 转换器(串行网络接口,SNI)通过 ttyS0 控制台与无头 Slackware 服务器进行通信。连接期间的 SNI 发送回 Telnet 命令集ff fb 01 ff fb 03。这会将 Telnet 从 Line 模式转换为 Char 模式。但我注意到 Telnet 将我的 CR 按下 (0x0d) 替换(添加)为两个字符 0x0d 0x00。 Slackware 的 TTY 本身不受此影响,但我在它下运行的一些命令,至少 catmcedit 不是。所以我尝试执行以下操作:

  1. 在我的 SNI 中插入过滤器,这样它只会在 IP->Serial 方向丢弃 NULL。它可以工作,但很丑陋,因为不再允许二进制传输。
  2. 修改 Telnet 的源代码,去掉 addind NULL 到 CR:

    inetutils-1.9.4/telnet/telnet.c  from line 2294:
            case '\r':
              if (!crlf)
            {
              NETADD ('\r'); <-- added
    //        NET2ADD ('\r', '\0'); <-- removed
            }
              else
            {
              NET2ADD ('\r', '\n');
            }
              bol = flushline = 1;
              break;
    

它也有效,所以我确保我以正确的方式解决问题。 但由于多种原因,它也很丑陋,包括它非常不便携,并且我必须拥有自己的非标准 telnet 二进制文件。

所以问题是:可以命令 Telnet 不要修改我的 CR 吗? (看看这个源代码,原始代码根本不可能,但我确信我错过了一些东西,这应该可以在不修改源代码的情况下实现)。注意:将 0x0d 替换为 0x0d,0x0a(这存在于代码中)不适用于 Linux TTY:它将这解释为两个 CR。

子问题是:0x0d+0x00 到底在哪里使用?我根本不知道任何硬件设备、电传打字机等,以及任何 TTY,其中 CR 使用后为 NULL。谢谢。

【问题讨论】:

    标签: linux console serial-port telnet tty


    【解决方案1】:

    所以我进行了一些调查,看看应该如何正确解决这个问题,不滥用软件,找到正确的工具,或者清楚地表明目前没有这样的工具。

    首先,我展示了为什么我的设置与现在完全一样,以及为什么它使用(或不使用)标准工具。

    我的目标对于 Linux 世界来说是非常普遍和必不可少的(正如我之前所想的那样)。因为 Linux 是网络操作系统,Linux 机器应该可以通过网络完全配置(所以可以/应该在无头时完全有用,即没有显示器)。但是在 Lilo/Grub 启动的时候,没有网络。此时只有串行端口可用(并且 Lilo/Grub 支持它)。为什么此时远程控制很重要?仅仅因为您可以(远程)为您的 Slackware 机器编译新的自定义内核,并且想要对其进行测试,将其作为第二个选项添加到 Lilo 列表中,并且即使远程机器在启动时卡住也想要返回到原始内核,所以无法远程编辑/调整 Lilo 选项。

    但是串行控制台对于 Linux 机器来说确实是更强大的工具。 它显示无法通过 ssh 看到的启动消息和关闭消息,因为此时网络尚未初始化。 (请记住,我们没有显示器)。 它可以让您(突然或有意)放弃所有网络接口,而不必担心在距离您很远的地方丢失您的机器。

    注意:串行控制台不能开箱即用,但可以以众所周知的标准方式进行配置,并在许多地方进行了描述。例如http://docs.slackware.com/howtos:general_admin:serial_console

    注意:串行端口应该被 BIOS 识别,即完全板载存在问题。当 Lilo/Grub 启动时,USB 和 PCIE 设备将永远无法工作。幸运的是,有一个好消息。硬件串行端口现在(慢慢地)返回到主板。我为我的服务器测试了新的现代华硕 J1900I-C,它有两个 rs232 端口,一切正常。

    要远程使用串行控制台的好处,应该使用某种 SNI,串行网络接口(这是唯一的方法,AFAIK)。 SNI 通常包含(最简单的)TCP 侦听服务器和原始 IP 到串行双工转换器。当 Lantronix X-Port 发明时,我开始研究和使用 SNI。那是在 2006 年,在 Slackware 盒子上运行良好。 (我不记得 XPort 是否存在\r\0 问题,但让我们继续吧)。 XPort太贵了,当 Wiznet W5100 发布时立即被我自己的开源 SNI 取代。 (真的,还有其他基本问题,为什么我需要更换 Lantronix。它不能按主板上的重置或电源按钮,而我的设备可以,现在服务器完全处于完全远程控制之下,即使在内核崩溃之后;但它这里是题外话)。现在网上商店也有很多便宜的无名 SNI;我不测试这些。

    所有这些时间我都在使用telnet 连接到 SNI。主要原因是 XPort 文档有这样的例子。而且,大多数时候它都有效;我不能说\r\0 问题停止了我的工作。大多数时候它根本不引人注意(例如,mc 指挥官对NULL 的抗拒)。但是mcedit 害怕 NULL。最近我开始发现这个问题,所以这个问题就来了。 (现在请从线程的开头重新阅读)。

    现在我试着回答我自己的问题。所有这些时间我都在滥用该软件。 Telnet 不是为人类交流而编写的;相反,Telnet(突然)使用 Telnet 协议,而不是 Raw 协议;和\r\0s 可能是协议的一部分。 (可能是因为 RFC 没有说明任何地方都需要 NULL)。 虽然 Telnet 和 Raw 协议看起来很接近,但它们并不匹配,所以有时应该可以工作,但有时不能。 使用蛮力和重新编译二进制文件,我证明 Telnet 可以很容易地转换为原始模式;但之后是非标准软件,没有机会推送到全球repos。

    所以我搜索原始实用程序。 netcatncat 没有 Char 模式,只有 Line 模式,所以只能使用纯控制台,没有 ANSI 颜色、mc、密码等。Putty 太复杂并且使用 GUI。而且......我没有找到更多的实用程序!这很奇怪也很烦人…… 然后我尝试使用最初基于字符的终端,minicomgtkterm。它们都不允许提要ip:port 结构而不是ttyS* 名称。但是存在数据翻译器,我尝试socat。它连接到 SNI 服务器并创建虚拟串口;然后字符终端软件连接到该端口。

    最后,它起作用了。哇。 但是这个链条中有很多缺点;复杂、难记的命令,不能写在一行中;当 SNI 断开 TCP 连接时,无法看到/捕获它; socat 在连接时向虚拟端口发出大量垃圾(我数了 457 个数据包!)。下面是一些勇敢的人的命令,他们可能会觉得我的工作很有用。

    sudo socat pty,link=/dev/ttyMYPORT,raw tcp:10.1.1.11:10001 &
    then
    sudo chmod a+rw /dev/ttyMYPORT; gtkterm -p /dev/ttyMYPORT
    or 
    sudo chmod a+rw /dev/ttyMYPORT; minicom -o --color=on -D /dev/ttyMYPORT
    

    最后,我现在还没有找到任何简单的软件,可以直接使用人类原始字符模式通过网桥与串口进行通信。 (请提出一些建议)。谢谢。

    【讨论】:

      【解决方案2】:

      我相信您正在寻找的解决方案要高出几行:

      if (!crlf)
      

      如果我们设置crlf = true,那么我们将得到\r\n 而不是\r\0。这可能对猫和朋友有用。

      查看 telnet 源代码,crlf 似乎是某种“切换”选项。查看man telnet 和一些谷歌搜索,看来您可以运行something like this

      $ telnet
      telnet> toggle crlf
      

      ...从那时起,您将收到\r\n

      【讨论】:

      • 是的,toggle crlf 像你描述的那样工作,但是 unf。这对我没有帮助:正如我之前提到的,linux TTY 将 \r\n 解释为两个 CR(现在我测试 cat 命令,它的行为是相同的)。我仍然想知道\r\0 在哪里使用,是否应该在全球范围内修复 Telnet 应用程序,然后会发生什么。谢谢你的回答。
      • 我确信 telnet 人员有充分的理由发送 \r\0\r\n,它可能不应该“固定”到 \r。我认为真正的问题可能不在 telnet 之外:为什么在按 Enter 时发送\r\n?如果您只发送\n,您的问题将得到解决,我认为这是 telnet 所期望的。也许您可以在某些终端设置或 Windows 设置中解决此问题。
      • 我当前的 Telnet 设置(Ubuntu,英文 UTF8 控制台)仅发送到 telnet \r 代码。 Telnet 目前由于未知原因不能只转移\r 不变,而是替换为\r\0\r\n。所以我没有发送\r\n,而是 Telnet 发送。使用\n 作为 CR 是个好主意,但看起来很难获得这个,因为我什至无法想象在哪里搜索、驱动程序、控制台等的软件级别(我只使用 Linux 机器)。这远不是 rs232 控制台的标准,至少因为 键的代码为 0x0d,而不是 0x0a,在全球范围内,至少半个世纪以来,AFAIK...
      猜你喜欢
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      相关资源
      最近更新 更多