创建具有 AX.25 封装的 TUN 网络设备

标签 c linux sockets tun

我正在尝试创建具有 AX.25 封装的 TUN 网络设备。 有效的是: - 创 build 备 - 将其封装设置为 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)

然后我将接口(interface)设置为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 首先,您需要将该地址的每个字节向右移动一位。然后,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 设置硬件地址,但这似乎被忽略了。

有什么想法吗?

最佳答案

我认为问题出在“ifr.ifr_flags = IFF_TUN” 如果您计划创建 TAP 设备,请使用 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;

不确定这是否对您有帮助。

关于创建具有 AX.25 封装的 TUN 网络设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22465138/

相关文章:

linux - BlueZ:从命令行发送 LE 定向广告

ruby-on-rails - 环境从 Windows 更改为 Linux 后 Gem 安装编码错误

从函数指针调用函数而不分配?

sockets - BSD 套接字的文件描述符错误

c - 找到边界元素之和最大的方子矩阵

c - 如何从合法的未知值类型中提取标准注册表值类型?

c - 线程执行时陷入无限循环

python - 程序停止运行是由python udp 停留在一个地方引起的

c - 用户在一行中键入一个单词和一个数字。将它们读入提供的变量中。然后打印

c - 在特定接收器传输了多少数据