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 を直接設定しようとしましたが、無視されているようです。
何か案は?