「ip tuntap add mode tap」を使用して生成されたインターフェイス名を取得する方法

「ip tuntap add mode tap」を使用して生成されたインターフェイス名を取得する方法

sudoを使用してTapを作成し、ここにユーザースペースプログラム(ssh)をリンクしたいと思います。

複数のユーザーがインターフェイス名を使用しているため、インターフェイス名をハードコードしたくないので、インターフェイス名を動的に生成したいと思います。

だから私は次のように蛇口を作ります。

sudo ip tuntap add mode tap user $USER

sshに渡すために使用できるように生成されたインターフェイスの名前を返すipコマンドを取得するにはどうすればよいですか?

ベストアンサー1

このtuntapデバイスのLinuxプログラミングインタフェースはここに文書化されています(サンプルコードを含む)。tuntap.rst。インターフェイス名を要求してから、最初の呼び出しに渡された構造を使用して取得できますioctl(fd, TUNSETIFF, ...)ip tuntap名前は表示されないため、このコマンドだけでは有益ではありません。

これを行う方法は2つあります。

図書館ラッパー

libcラッパーを追加できます。ioctl()この特定のターゲットの場合は、実行時に使用できますLD_PRELOADこれにより、元のツールを変更する必要がなくなります。これはその目的のラッパーで、ioctl()次に印刷されます。標準出力作成したばかりのインターフェイスの名前です。 OPのip tuntap例を考えると、3回だけ使用されますioctl()蛇口ioctl()すべての用途に常に同じ数のパラメータがあるわけではありませんが、非常に安全なインタフェースです(ここではパラメータを3つとします)。

wraptuntap.c:

#define _GNU_SOURCE
#include <dlfcn.h>

#include <linux/if.h>
#include <linux/if_tun.h>

#define ioctl ioctl_diverted
#include <sys/ioctl.h>
#undef ioctl

#include <stdio.h>

int ioctl(int fd, unsigned long request, void *p) {
        int ret;

        int (*orig_ioctl)(int, unsigned long, void *)=dlsym(RTLD_NEXT,"ioctl");
        if ((ret=orig_ioctl(fd, request, p)) != -1 )
                if (request == TUNSETIFF)
                        printf("%s\n",((struct ifreq *)p)->ifr_name);
        return ret;
}

コメント:

  • <sys/ioctl.h>正しく定義する必要がありますTUNSETIFFが、同時にそれを行うことはできませんioctl()。それ以外の場合は、ラッパー定義が競合します。初期定義は次に送信されます。このSO Q / Aメソッド
  • ifr_name保証済みカーネル4.13以降、nullが終了しました。そうでなければ…まあ、それは粗末な包装紙です。

たとえば、次のようにコンパイルします。

gcc -shared -fPIC -o /tmp/wraptuntap.so wraptuntap.c -ldl

次に、次のように使用します。

# LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000
tap0
# LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000
tap1
# LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000 name foo%d
foo0
# LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000 name foo%d
foo1

またはより便利に:

# mytun=$(LD_PRELOAD=/tmp/wraptuntap.so ip tuntap add mode tap user 1000 name foo%d)
# ip link show dev "$mytun"
11: foo2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ae:99:4a:2b:1f:6b brd ff:ff:ff:ff:ff:ff

これらのインターフェイスを作成することはそれほど難しくありません。本番用に使用するには、専用のツールを作成するか、そのインターフェイスの名前を表示できる他のツールを使用することをお勧めします。

長老tunctl(のみ蛇口相互作用):

UMLユーティリティで提供される以前の(したがって一般的には使用されません)tunctlツールは、使用されたインターフェイス名を含む文を表示しますが、パターンのみを生成します。蛇口(レイヤ2)インタフェース(OPが探しているもの)の代わりにトゥエン(レイヤ3)インターフェイス。

例:

# tunctl -u 1000 -t foo%d
Set 'foo3' persistent and owned by uid 1000
# tunctl -u 1000 -t foo%d | sed -E "s/^Set '([^']+)' .*\$/\1/"
foo4
# ip -d link show dev foo4 # this is a "type tap" interface
13: foo4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether c2:05:de:78:16:a3 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65521 
    tun type tap pi off vnet_hdr off persist on user 1000 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 

おすすめ記事