2

AX.25 カプセル化を使用して TUN ネットワーク デバイスを作成しようとしています。機能するのは: - デバイスの作成 - そのカプセル化を ax25 に設定する

うまくいかないのは、ハードウェアアドレスの設定です。これは、ノードを一意にアドレス指定するために使用されるため、ax.25 通信では重要です。

まず、TUN デバイスを作成します。

    struct ifreq ifr = { 0 };

    const char *clone_dev = "/dev/net/tun";
    if ((fd = open(clone_dev, O_RDWR)) == -1)
            error_exit(true, "Failed opening %s for tun device %s", clone_dev, dev_name);

    ifr.ifr_flags = IFF_TUN;

    strncpy(ifr.ifr_name, dev_name, IFNAMSIZ);

    if (ioctl(fd, TUNSETIFF, (void *)&ifr) == -1)
            error_exit(true, "Failed creating tun device %s", dev_name);

これにより、次の結果が得られます。

root@travelmate:/home/folkert# ifconfig bla
bla       Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

次に、インターフェイスを AX.25 カプセル化に設定します。

    if (ioctl(fd, TUNSETLINK, ARPHRD_AX25) == -1)
            error_exit(true, "Failed setting tun device %s to ARPHRD_AX25", dev_name);

これにより、次の結果が得られます。

root@travelmate:/home/folkert# ifconfig bla
bla       Link encap:AMPR AX.25  HWaddr   
          POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

あとはハードウェアアドレスの設定です。ハードウェア アドレスは次のような文字列です。 FH1GOU-1 まず、このアドレスの各バイトを 1 ビット右にシフトする必要があります。次に、ioctl-magic。これは常に失敗します。また、tun-device を作成してから ifconfig を呼び出してみましたが、「サポートされていません」というエラーが発生しました。もちろん、tun デバイスに ax.25 ハードウェア アドレスを設定することは不可能である可能性がありますが、なぜ ax.25 カプセル化を設定できるのでしょうか?

    struct sockaddr *sa = &ifr.ifr_ifru.ifru_addr;

    struct sockaddr_ax25 *sap25 = (struct sockaddr_ax25 *)sa;
    memset(sap25, 0x00, sizeof(struct sockaddr_ax25));

    // tried AF_AX25 as well
    sa->sa_family = ARPHRD_AX25;

    char *min = strchr(hwaddr, '-');
    *min = 0x00;

    unsigned int hwaddr_len = strlen(hwaddr);

    char *call_str = sap25->sax25_call.ax25_call;

    unsigned int main_addr_size = sizeof(ax25_address) - 1;
    for(unsigned int idx=0; idx<main_addr_size; idx++)
    {
            int c = idx < hwaddr_len ? toupper(hwaddr[idx]) : ' ';

            call_str[idx] = (c << 1) & 0xfe;
    }

    if (min)
            call_str[main_addr_size] = (atoi(min + 1) << 1) & 0xfe;
    else
            call_str[main_addr_size] = 0x00;

    free(hwaddr);

    printf("%d\n", ioctl(fd, SIOCSIFHWADDR, &ifr));

ioctl を含む最後の行では、常に -1 (=エラー) が出力されます。

また、TUNSETIFF ioctl を使用して hw-address を直接設定しようとしましたが、無視されているようです。

何か案は?

4

5 に答える 5

1

ところで、私が試したこと:単にイーサネットカプセル化されたタップデバイスを開いて起動し、bpq ax.25 'secondary interface' を与えるイーサネットポートと見なすように bpq を強制することは機能しません。bpq エイリアス インターフェイスのパケットは、tap デバイスのファイル記述子には到達しません。

しかし、タップデバイスのカプセル化を変更するだけでうまくいくようです。

とにかく、Linux での「大規模なセットアップ」の ax.25 処理は壊れています。プロセスは、異なるコールサインの同じマシン内の他のプロセスに接続できません。ドキュメントの半分が欠落しているか、三脚のないサイトを持つ人々が死亡したときにhudiniに行きました. 後でカーネル スタックの修正に取り掛かります :P すべてが、同じ机のコンピュータに 1 つのトランシーバと 1 つのターミナル プログラムしかない人々によって作成されたようです :P

于 2016-05-30T13:25:38.547 に答える
0

タップデバイスでそれを実行しただけで(不要な場合は、パケットの最終的なハードウェアレイヤーを削除するだけです)、正常に動作します。(編集:コールサインビットを設定するだけで、ランダムに正常に動作するようにし、最後の回答で説明されているいくつかのバグのために動作を停止しました;)

root@user-X551MA:/home/user# ifconfig cb3rob0
cb3rob0   Link encap:AMPR AX.25  HWaddr CB3ROB 

タップではなくツンで機能するにもかかわらず

TAP デバイス自体がファイル ハンドルとして開かれていることに注意してください。( open()) ハードウェア アドレスを設定するには ( =callsign) 一時的なネットワーク ソケット ハンドルを作成する必要があります ( socket())

インターフェイスを起動するためのソケット ハンドルも必要です (IFF_UP | IFF_RUNNING) ブロードキャストと arp を無効にし、mtu をデフォルトの 1500 ではなく 256 など、もう少し「AX.25 っぽい」ものに設定します。

サポートされていると思われるプロトコルファミリでソケットを開きます (PF_PACKET は、少なくともルートに対しては正常に動作し、ifr 名フィールドが既に作成されたタップ (tun?) デバイスの名前に設定された ioctl を実行します)。

その後、ソケットを再度閉じます。設定以外のタップデバイスでの操作中は必要ありません。

于 2016-05-30T13:18:18.293 に答える