openwrtのhanstunnelを修正(ネットワークパケットのチェックサムを計算)

みなさんこんにちは。 おそらく、ここの多くはhanstunnelプログラムを知っているので、ICMPまたはpingでトンネルを上げることができます。 私はルーターにopenwrtの下に置くことにしました。 組み立て、開始...動作しません。 症状は単純でした。パケットはルーターから外部ネットワークに送られますが、受信者には届きませんが、すべてがホームLANで機能します。 同時に、ホームコンピューターで実行されている同じハンが問題なく接続されます。 openwrtの下でhansパッケージをビルドする方法と、それを機能させる方法を誰が気にしますか?







最初の段階はアセンブリです。 私のマシンでビルド環境を上げる方法は、 openwrt Webサイト自体とさまざまな記事によく書かれているので、この記事は舞台裏に置いておきます。 ツールチェーンが組み込まれた環境があり、標準のopenwrtパッケージをビルドできるとします。

パッケージをビルドするには、 ここで取得できるhanstunnelソースと、パッケージの説明を含むMakefile、configファイル、initスクリプトファイルが必要です。 パッチの説明としてここで最後の3つを偶然見つけました。 誰かが直接リンクを見つけるかもしれませんが、とにかく私に合っていました。 パッケージをビルドするには、カスタムなどの何らかの種類のフォルダーを作成し、将来のパッケージのフォルダーをその中に入れ、そこにパッケージ/フィード/パッケージからのリンクを入れます。 パッケージのMakefileをわずかにファイルし、その横にあるsrcフォルダーのソースコードを収集し、
それが起こったことです
 #著作権(C)2006 OpenWrt.org
 #
 #これは、GNU General Public License v2の下でライセンスされたフリーソフトウェアです。
 #詳細については、/ライセンスを参照してください。
 #
 #$ Id:Makefile 6008 2007-01-06 18:39:10Z nbd $

 include $(TOPDIR)/rules.mk

 PKG_NAME:= hanstunnel
 PKG_VERSION:= 0.4.3
 PKG_RELEASE:= 1

 PKG_BUILD_DIR:= $(BUILD_DIR)/ $(PKG_NAME)-$(PKG_VERSION)

 include $(INCLUDE_DIR)/package.mk

パッケージ/ hanstunnelを定義する
        セクション:= net
        カテゴリー:=ネットワーク
        サブメニュー:=ファイアウォールトンネル
        依存:= + libstdcpp + kmod-tun
        タイトル:= Hans IP over ICMP
         URL:= http://code.gerade.org/hans/
エンデフ

パッケージ/ hanstunnel /説明の定義
         Hansは、ICMPエコーパケットを介してIPv4をトンネリングすることを可能にし、
        したがって、pingトンネルと呼ぶことができます。 これは次の場合に便利です。
        インターネットにアクセスできる状況にいる
        ファイアウォールで保護されていますが、pingは許可されています。 エンデフ
エンデフ

ビルドの定義/準備
         echo PREPARE PREPARE
         mkdir -p $(PKG_BUILD_DIR)
         cp -r ./src/* $(PKG_BUILD_DIR)/
エンデフ

ビルドの定義/コンパイル 
         $(メイク)-C $(PKG_BUILD_DIR)GCC = $(TARGET_CC)GPP = $(TARGET_CXX)
エンデフ 

 
パッケージ/ hanstunnel / installを定義します
         $(INSTALL_DIR)$(1)/ usr / sbin
         $(INSTALL_BIN)$(PKG_BUILD_DIR)/ hans $(1)/ usr / sbin /
         $(INSTALL_DIR)$(1)/etc/init.d
         $(INSTALL_BIN)./files/hans.init $(1)/etc/init.d/hans
         $(INSTALL_DIR)$(1)/ etc / config
         $(INSTALL_CONF)./files/hans.config $(1)/ etc / config / hans
エンデフ

 $(eval $(BuildPackage、hanstunnelを呼び出す))






ビルドファイルの頭も少しファイルする必要がありました

Makefileアセンブリ
 #LDFLAGS + = `sh osflags ld $(MODE)`
 CFLAGS + = -c -g -DLINUX -DHAVE_LINUX_IF_TUN_H
 TUN_DEV_FILE = src / tun_dev_linux.c
 #GCC = gcc
 #GPP = g ++

 .PHONY:ディレクトリ

すべて:ハンス

ディレクトリ:build_dir

 build_dir:
	 mkdir -pビルド

 tunemu.o:ディレクトリbuild / tunemu.o

 hans:ディレクトリbuild / tun.o build / sha1.o build / main.o build / client.o build / server.o build / auth.o build / worker.o build / time.o build / tun_dev.o build / echo.o build / exception.o build / utility.o
	 $(GPP)-o hans build / tun.o build / sha1.o build / main.o build / client.o build / server.o build / auth.o build / worker.o build / time.o build / tun_dev .o build / echo.o build / exception.o build / utility.o $(LDFLAGS)

 build / utility.o:src / utility.cpp src / utility.h
	 $(GPP)-c src / utility.cpp -o $ @ -o $ @ $(CFLAGS)

 build / exception.o:src / exception.cpp src / exception.h
	 $(GPP)-c src / exception.cpp -o $ @ $(CFLAGS)

 build / echo.o:src / echo.cpp src / echo.h src / exception.h
	 $(GPP)-c src / echo.cpp -o $ @ $(CFLAGS)

 build / tun.o:src / tun.cpp src / tun.h src / exception.h src / utility.h src / tun_dev.h
	 $(GPP)-c src / tun.cpp -o $ @ $(CFLAGS)

 build / tun_dev.o:
	 $(GCC)-c $(TUN_DEV_FILE)-o build / tun_dev.o -o $ @ $(CFLAGS)

 build / sha1.o:src / sha1.cpp src / sha1.h
	 $(GPP)-c src / sha1.cpp -o $ @ $(CFLAGS)

 build / main.o:src / main.cpp src / client.h src / server.h src / exception.h src / worker.h src / auth.h src / time.h src / echo.h src / tun。 h src / tun_dev.h
	 $(GPP)-c src / main.cpp -o $ @ $(CFLAGS)

 build / client.o:src / client.cpp src / client.h src / server.h src / exception.h src / config.h src / worker.h src / auth.h src / time.h src / echo h src / tun.h src / tun_dev.h
	 $(GPP)-c src / client.cpp -o $ @ $(CFLAGS)

 build / server.o:src / server.cpp src / server.h src / client.h src / utility.h src / config.h src / worker.h src / auth.h src / time.h src / echo h src / tun.h src / tun_dev.h
	 $(GPP)-c src / server.cpp -o $ @ $(CFLAGS)

ビルド/ auth.o:src / auth.cpp src / auth.h src / sha1.h src / utility.h
	 $(GPP)-c src / auth.cpp -o $ @ $(CFLAGS)

 build / worker.o:src / worker.cpp src / worker.h src / tun.h src / exception.h src / time.h src / echo.h src / tun_dev.h src / config.h
	 $(GPP)-c src / worker.cpp -o $ @ $(CFLAGS)

 build / time.o:src / time.cpp src / time.h
	 $(GPP)-c src / time.cpp -o $ @ $(CFLAGS)

きれいな:
	 rm -f build / tun.o build / sha1.o build / main.o build / client.o build / server.o build / auth.o build / worker.o build / time.o build / tun_dev.o build / echo.oビルド/ exception.oビルド/ utility.oビルド/ tunemu.o hans
	 rm -dfビルド

 build / tunemu.o:src / tunemu.h src / tunemu.c
	 $(GCC)-c src / tunemu.c -o build / tunemu.o






ファイルを所定の場所に配置すると、次のようになります。



 $ ls -Rカスタム 
カスタム:
ハンストンネル

カスタム/ハンストン:
ファイルMakefile src

 custom / hanstunnel / files:
 hans.config hans.init

 custom / hanstunnel / src:
 Makefile osflags src

 custom / hanstunnel / src / src:
 auth.cpp client.h echo.h main.cpp sha1.cpp time.cpp tun_dev_darwin_emu.c tun_dev.h tun_dev_svr4.c tun.h worker.cpp
 auth.h config.h exception.cpp server.cpp sha1.h time.h tun_dev_freebsd.c tun_dev_linux.c tunemu.c utility.cpp worker.h
 client.cpp echo.cpp exception.h server.h sha1_license.txt tun.cpp tun_dev_generic.c tun_dev_openbsd.c tunemu.h utility.h




次に、buildrootのルートに移動して、楽しく入力します

 $ make package / feeds / packages / hanstunnel / compile -j5
  make [1]パッケージ/フィード/パッケージ/ hanstunnel /コンパイル
  make [2] -Cパッケージ/カーネル/ linuxコンパイル
  make [2] -C package / libs / toolchain compile
  make [2] -C custom / hanstunnel compile




パッケージの準備はすべて整いました。残りの隣のbinフォルダーにあります。



確認する必要があります。 ここで私を待っていたのは残念です。 私のコンピューターが自宅のLANにあるため、トンネルは問題なくすぐに上がりました。 喜んで外部から接続を確認しに行ったのは私だけでしたが、上記のように、openwrtを含むパッケージは残っていましたが、受信者はそれらを見ませんでした。 クライアントモードのルーターでhansを実行しているときにも同じ状況が発生しました。 よく考えた結果、ICMPダンプを削除して、ルーターとコンピューターからの接続の違いを探すことにしました。 問題はICMPチェックサムにあり、wiresharkは私に喜んで知らせてくれました。 私は正直に計算機を取り、私自身はecho.cppで規定されているアルゴリズムに従って量を手動で計算しました。これは公式のものと非常に似ています。 何でも判明しましたが、必要なものではありませんでした。 その結果、問題は奇数のパケット長とMIPSアーキテクチャにあることが判明しました。 RFCの良い人は、合計に最後のバイトを追加するだけでよいと書いていますが、実際はそうではありません。 最後のバイトではなく、2バイトを追加する必要があります。2番目のバイトは0です。ビッグエンディアンアーキテクチャでは、バイトを256倍した値になります。

icmpChecksum関数の結果は次のとおりです。



 uint16_t Echo :: icmpChecksum(const char * data、int length)
 {
     uint16_t * data16 =(uint16_t *)データ;
     uint32_t sum = 0;

     for(合計= 0;長さ> 1;長さ-= 2)
         sum + = * data16 ++;


     if(長さ== 1)
     {
         unsigned char tail [2] = {*(unsigned char *)data16、0};
         sum + = *(uint16_t *)テール;
     }
     while(合計>> 16)
         sum =(sum >> 16)+(sum&0xffff);

     return〜sum;
 }




彼女と一緒に、最終的にすべてが正常に機能しました。 ハッピーエンド。



UPDjcmvbkbcのより美しいバージョンのテールを修正



All Articles