| 早 |
く |
ハ |
ッ |
カ |
ー |
に |
な |
り |
た |
- |
- |
- |
- |
> |
い |
TCP Moe オプションの実装(2001/11/11)
というか TCP ってすでに決められて、そこにあるものとか考えられてはいませんか?せっかく FreeBSD を使っていることもあり、がんがんバカみたいなオプションを作って、組み立てて、有効にしていくのが面白いですよね。
最初から飛ばしてますが、要するに TCP の独自機能を新しく実装することはみなさんの自由ですし、そのために OS の TCP のコードを書き換えることも自由です。もし、自分で定義した TCP オプションが有効でなかった場合、このホストと通信をうち切るなんてことも可能です。というか、せっかくあるんだから、どんどんバカなものを使え作れというのが僕のコンセプトです。
で、TCP Moe Option です。
1. Introduction
TCP Moe Option とは、TCP Option 領域に自分が萌えているキャラクターの名前を入れて送信します。萌えの定義が何であるかは google で調べて下さい。別に moe じゃなくて、メッセージを使って送信してもらっても構わないです。
TCP Moe Option は、コネクション確立時に送信される TCP SYN フラグの付与されたセグメントに対して適応されます。この TCP Moe Option を受け取ったサーバの動作は特に規定していません。
2. Option Format
オプションのフォーマットは以下の通りになっています。
+---------+---------+-------------------+
| Kind=20 |Length=16| MOE String |
+---------+---------+-------------------+
| |
+---------------------------------------+
| |
+---------------------------------------+
| |
+---------------------------------------+
オプション番号は 20、オプション長さは16バイトです。
Mail ヘッダにありがちな X-Moe フィールドとの最大の違いは、萌え対象の名前を入れる文字列が14バイトまでとなっていることにあります。(全角で7バイト)。このため、クリスティーナ・マッケンジーなどの長い文字列を入れるとはできません。
3. Implementation
実装は FreeBSD 4.4 Release 上で行いました。
以下はソースの解説です。
(1) /usr/src/sys/conf/options の変更
--- conf/options.orig Fri Aug 3 09:47:27 2001
+++ conf/options Tue Nov 6 18:05:25 2001
@@ -271,6 +271,7 @@
SLIP_IFF_OPTS opt_slip.h
TCPDEBUG
TCP_DROP_SYNFIN opt_tcp_input.h
+TCP_MOE opt_tcp_moe.h
※ KERNEL のコンフィグファイルに options TCP_MOE と指定できるように変更
なお、指定されていた場合に opt_tcp_moe.h に #define TCP_MOE 1 と記述
XBONEHACK
# Netgraph(4). Use option NETGRAPH to enable the base netgraph code.
(2) /usr/src/sys/netinet/tcp.h の変更
--- netinet/tcp.h.orig Fri Mar 2 07:08:42 2001
+++ netinet/tcp.h Tue Nov 6 17:11:07 2001
@@ -99,6 +99,10 @@
#define TCPOPT_CC_HDR(ccopt) \
(TCPOPT_NOP<<24|TCPOPT_NOP<<16|(ccopt)<<8|TCPOLEN_CC)
+#define TCPOPT_MOE 20
※ TCP MOE オプションはオプション番号20ですにょ、と定義
+#define TCPOLEN_MOE 16
※ TCP MOE オプションの長さは16ですにょ、と定義
+#define TCPOLEN_MOESTRING (TCPOLEN_MOE - 2)
※ オプションの長さ 16 - オプション番号格納場所(1バイト) -
オプションの長さ情報格納場所(1バイト) = 14 バイトが萌え対象を格納できる場所ですにょ、と定義
+
/*
* Default maximum segment size for TCP.
* With an IP MSS of 576, this is 536,
(3) /usr/src/sys/netinet/tcp_output.c の変更
--- netinet/tcp_output.c.orig Sat Jul 7 13:30:38 2001
+++ netinet/tcp_output.c Wed Nov 7 11:06:44 2001
@@ -37,6 +37,7 @@
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_tcpdebug.h"
※ (1) /usr/src/sys/conf/options の変更箇所を参照
config コマンドの結果が反映される opt_tcp_moe.h を参照して、
TCP_MOE が define されているか否かを読みに行く
+#include "opt_tcp_moe.h"
#include
#include
@@ -96,6 +97,17 @@
int tcp_do_newreno = 1;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, newreno, CTLFLAG_RW, &tcp_do_newreno,
0, "Enable NewReno Algorithms");
※ カーネルに options TCP_MOE と書いてあったら、
config コマンドの結果 opt_tcp_moe.h に #define TCP_MOE 1 と記述されるので、
この ifdef 〜 endif 句が真になる
+
+#ifdef TCP_MOE
※ TCP Moe Option を有効にするかどうか、システムの稼働中に動的に切り替える設計
カーネル変数 tcp_moe を用意し、sysctl コマンドで変更できるようにする。
このため net.inet.tcp.moe タプルを追加している
+int tcp_moe = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, moe, CTLFLAG_RW,
+ &tcp_moe, 0, "Enable TCP Moe Option");
+
※ Moe 対象を、システムの稼働中に動的に切り替える設計
カーネル変数 tcp_moe_string を用意し、sysctl コマンドで変更できるようにする。
このため net.inet.tcp.moe_string タプルを追加している
+char tcp_moe_string[TCPOLEN_MOESTRING + 1];
+SYSCTL_STRING(_net_inet_tcp, OID_AUTO, moe_string, CTLFLAG_RW,
+ tcp_moe_string, sizeof(tcp_moe_string), "TCP Moe String");
+#endif
+
/*
* Tcp output routine: figure out what should be sent and send it.
*/
@@ -495,6 +507,22 @@
break;
}
}
+
※ TCP Moe オプションが有効であるとき、
+#ifdef TCP_MOE
※ カーネル変数 tcp_moe が真であり、
※ かつ、TCP フラグに SYN がセットされているとき、
+ if (tcp_moe && (flags & TH_SYN)){
※ まず TCP Moe オプション番号の 20(= TCPOPT_MOE) をセット
+ opt[optlen++] = TCPOPT_MOE;
※ 続いて TCP Moe オプションの長さの 16 (= TCPOLEN_MOE) をセット
+ opt[optlen++] = TCPOLEN_MOE;
※ 残りのオプション領域を前もって初期化
+ memset((void *)&opt[optlen], 0, TCPOLEN_MOESTRING);
※ tcp_moe_string の内容を TCP Moe Option として格納
※ TCP Moe String が長い時は TCP_MOE_STRING 分だけコピー(安全対策)
+ memcpy((void *)&opt[optlen], tcp_moe_string,
+ strlen(tcp_moe_string) > TCPOLEN_MOESTRING ?
+ TCPOLEN_MOESTRING : strlen(tcp_moe_string));
※ オプションを 14 バイト分、ポインタ移動( = TCP Moe Option の終端に移動)
+ optlen += TCPOLEN_MOESTRING;
+ }
+#endif
hdrlen += optlen;
(4) /usr/src/sys/netinet/tcp_input.c の変更
--- netinet/tcp_input.c.orig Wed Aug 22 09:59:12 2001
+++ netinet/tcp_input.c Wed Nov 7 10:59:23 2001
@@ -39,6 +39,7 @@
#include "opt_ipsec.h"
#include "opt_tcpdebug.h"
#include "opt_tcp_input.h"
+#include "opt_tcp_moe.h"
#include
#include
@@ -125,6 +126,12 @@
&tcp_lq_overflow, 0,
"Listen Queue Overflow");
※ 以下は、受信した TCP Moe Option の内容を表示するか否かを設定するカーネル変数
tcp_moe_display を作成し、この値を SYSCTL コマンドで変更できるように設定+#ifdef TCP_MOE
+int tcp_moe_display = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, moe_display, CTLFLAG_RW,
+ &tcp_moe_display, 0, "Display TCP Moe Option");
+#endif
+
#ifdef TCP_DROP_SYNFIN
static int drop_synfin = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_RW,
@@ -2392,6 +2399,10 @@
u_short mss = 0;
int opt, optlen;
※ 受信した TCP Moe オプションの内容を格納するバッファ
+#ifdef TCP_MOE
+ char moebuf[TCPOLEN_MOESTRING+1];
+#endif
for (; cnt > 0; cnt -= optlen, cp += optlen) {
opt = cp[0];
if (opt == TCPOPT_EOL)
@@ -2488,6 +2499,20 @@
(char *)&to->to_ccecho, sizeof(to->to_ccecho));
NTOHL(to->to_ccecho);
break;
※ TCP Moe オプションが有効であるとき、
+#ifdef TCP_MOE
※ もし、オプション種別が 20 ( = TCP Moe Option であった場合)
+ case TCPOPT_MOE:
※ 長さが 16 バイト (TCP Moe Option の長さ)でなかった場合、無視
+ if (optlen != TCPOLEN_MOE)
+ continue;
※ このセグメントに SYN フラグが付与されていない場合も、無視
+ if (!(th->th_flags & TH_SYN))
+ continue;
※ もし tcp_moe_display が真である場合、
+ if (tcp_moe_display){
※ TCP Moe オプションを格納するバッファをクリア
+ bzero(moebuf, sizeof(moebuf));
※ 現在のポインタの場所より +2 (現在は TCP Option、+1 して Option 長さを格納する領域、
+2 して TCP Moe Option のスタートする領域)の場所をバッファにコピー
+ bcopy((char *)cp + 2,
+ (char *)moebuf, TCPOLEN_MOESTRING);
※ コンソールに表示……いつの時代も printf
+ printf("%s\n", moebuf);
+ }
+ break;
+#endif
}
}
if (th->th_flags & TH_SYN)
というか、詳しくわかりやすく書こうとして失敗している例かもしれませんが、これを読めばおおなるほどとか考えて、もっとマニアックな TCP Option がたくさん出てくれるハズと信じてます。
4. Configure
設定方法です。
付属の README(README.JP) からの転載です。
(1) パッチをあてる
% cd /usr/src/sys/
% su
> patch < tcpmoe.patch
(2) カーネルを設定(options TCP_MOE というのをカーネルに追加)
> cd /usr/src/sys/i386/conf
> echo options TCP_MOE >> YOURKERNEL
(3) カーネルを再構築
> config YOURKERNEL
> cd ../../compile/YOURKERNEL
> make depend
> make
> make install
(4) 再起動
> fastboot
(5) 設定を行う
有効にするには
> sysctl -w net.inet.tcp.moe=1
(無効にするには 0 を指定してください)
萌え対象を変更するには
> sysctl -w net.inet.tcp.moe_string="sakuratan"
受信したセグメントの萌え対象を表示するには
> sysctl -w net.inet.tcp.moe_display=1
(表示しないようにするには 0 を指定してください)
と、わりとありがちなインタフェースです。
というわけで、
| tcpmoe.tar.gz |
FreeBSD 4.4 OK |
Cygunus B20 NG |
| カーネルに TCP Moe Option を実装する
|
真面目な Internet Draft を書かれた先輩に、「は、Joke RFC?でもこれ us の人たち笑ってくれないよ?」と厳しく突っ込まれました……。
<-- 1つ前に戻る
<-- トップページに戻る