===
character generator protocol (chargen) 是在 rfc 864 中由 jon postel 定义的 internet protocol suite 中的一个服务。主要用于测试、调试,以及测量的目的。该协议很少被使用,因为其固有的设计缺陷容易导致误用和攻击。
任意 host 都可以通过 tcp 或 udp 方式连接到支持 character generator protocol 并启用了该服务的服务器上,默认端口号为 19。当采用 tcp 方式成功连接时,服务器端将开始连续不断的发送任意字符到该连接上的 host,直到 host 主动关闭该连接为止。当采用 udp 方式时,服务器端会在每一次收到来自 host 的数据报时,回复包含随机数(0~512)的字符形式 udp 数据报。服务器接收到的任何数据均会被丢弃。
在大多数类 unix 操作系统上,chargen 服务被放置在 inetd 或 xinetd 守护进程中。chargen 服务器通常默认情况下不被使能。
chargen 服务可以作为产生字节流的源用于调试 tcp 网络程序代码,比如,边界检查和缓存管理。该服务同样可以作为带宽测量或 qos 调优的通用负载产生的源。
典型的 chargen 服务会话看起来如下:用于通过 telnet 客户端连接到(提供该服务的)服务器上,用户连续不断的接收来自服务端的字节流。尽管在 rfc 864 里没有指定字节流的数据格式,但推荐的格式为(事实上的标准)循环左移含有 72 个 ascii 字符的行。
<a href="http://my.oschina.net/moooofly/blog/265332#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<code>$ telnet localhost chargen</code>
<code>trying 127.0.0.1...</code>
<code>connected to localhost.</code>
<code>escape character is</code><code>'^]'</code><code>.</code>
<code>!"</code><code>#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefgh</code>
<code>"</code><code>#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghi</code>
<code>#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghij</code>
<code>$%&'()*+,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijk</code>
<code>%&'()*+,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijkl</code>
<code>&'()*+,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklm</code>
<code>'()*+,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmn</code>
<code>()*+,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmno</code>
<code>)*+,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnop</code>
<code>*+,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopq</code>
<code>+,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqr</code>
<code>,-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrs</code>
<code>-.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrst</code>
<code>.</code><code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstu</code>
<code>/0123456789</code><code>:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuv</code>
<code>^]</code>
<code>telnet> quit</code>
<code>connection closed.</code>
这个数据将一直持续到当前 tcp 连接被关闭为止(比如上面通过 ^] 来停止 telnet 会话)。
附:网上找的一个用 erlang 实现的 chargen 服务的程序。
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<code>-module(chargen).</code>
<code>-author(</code><code>'jesse e.i. farmer <[email protected]>'</code><code>).</code>
<code>-</code><code>export</code><code>([listen</code><code>/1</code><code>]).</code>
<code>-define(start_char, 33).</code>
<code>-define(end_char, 127).</code>
<code>-define(line_length, 72).</code>
<code>-define(tcp_options, [binary, {packet, 0}, {active,</code><code>false</code><code>}, {reuseaddr,</code><code>true</code><code>}]).</code>
<code>% call chargen:listen(port) to start the service.</code>
<code>listen(port) -></code>
<code> </code><code>{ok, lsocket} = gen_tcp:listen(port, ?tcp_options),</code>
<code> </code><code>accept(lsocket).</code>
<code>% wait</code><code>for</code> <code>incoming connections and spawn the chargen loop when we get one.</code>
<code>accept(lsocket) -></code>
<code> </code><code>{ok, socket} = gen_tcp:accept(lsocket),</code>
<code> </code><code>spawn(fun() -> loop(socket) end),</code>
<code>loop(socket) -></code>
<code> </code><code>loop(socket, ?start_char).</code>
<code>loop(socket, ?end_char) -></code>
<code> </code><code>loop(socket, ?start_char);</code>
<code>loop(socket, startchar) -></code>
<code> </code><code>line = make_line(startchar),</code>
<code> </code><code>case</code> <code>gen_tcp:send(socket, line) of</code>
<code> </code><code>{error, _reason} -></code>
<code> </code><code>exit</code><code>(normal);</code>
<code> </code><code>ok -></code>
<code> </code><code>loop(socket, startchar+1)</code>
<code> </code><code>end.</code>
<code>make_line(startchar) -></code>
<code> </code><code>make_line(startchar, 0).</code>
<code>% generate a new chargen line -- [13, 10] is crlf.</code>
<code>make_line(_, ?line_length) -></code>
<code> </code><code>[13, 10];</code>
<code>make_line(?end_char, pos) -></code>
<code> </code><code>make_line(?start_char, pos);</code>
<code>make_line(startchar, pos) -></code>
<code> </code><code>[startchar | make_line(startchar + 1, pos + 1)].</code>