RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1173533
Accepted
Zigzag_Makryak
Zigzag_Makryak
Asked:2020-09-02 23:11:29 +0000 UTC2020-09-02 23:11:29 +0000 UTC 2020-09-02 23:11:29 +0000 UTC

无法通过 TAP 设备接收以太网数据包(使用 TunTap 功能)

  • 772

同事们,下午好。请帮助我了解以下情况。我想在用户空间处理以太网帧。要“接收”一帧,我想使用 Tap-device (这样的任务,Raw-socket 不适合这种情况)。其实是一个问题。我使用以下命令创建 Tap-device:

sudo ip tuntap add dev tap0 mode tap
sudo ip address add 10.10.10.3/30 dev tap0

我在间隔中启动了一个自写的软件部分(关于它在下面)。接下来做

sudo ip link set tap0 up
ip address show tap0

结果,我在控制台中得到以下输出:

7: tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether ba:ba:18:ce:bb:66 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.3/30 scope global tap0
       valid_lft forever preferred_lft forever

同时,使用该程序,我将创建的 tap-device 与“/dev/net/tun”文件相关联。程序文本:

#include <arpa/inet.h>

#include <cstring>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>

#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/if_tun.h>

#include <net/if.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>

#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stropts.h>

#include <syslog.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <unistd.h>

int tun_alloc(char *dev, short flags);

int main() {

  char tun_name[IFNAMSIZ];
  char buffer[1500];
  printf("Programm is starting\n");

  /* Подключаюсь к tap-device */
  strcpy(tun_name, "tap0");
  int tun_fd = tun_alloc(tun_name, IFF_TAP); /* tun interface */

  if (tun_fd < 0) {
    perror("Allocating interface");
    exit(1);
  }

  printf("Interface number = %d \n", tun_fd);

  printf("Start reading loop \n");
  while (1) {

    printf("Whating for data... \n");
    int nread = read(tun_fd, buffer, sizeof(buffer));
    if (nread < 0) {
      perror("Reading from interface");
      close(tun_fd);
      exit(1);
    }

    /* Здесь обрабатывать полученный фрейм */
    printf("Read %d bytes from device %s\n", nread, tun_name);
  }

  return 0;
}

int tun_alloc(char *dev, short flags) {
  printf("Entering tun_allocate...\n");
  struct ifreq ifr;
  int fd, err;
  char *clonedev = "/dev/net/tun";

  /* Открываем файловый дескриптор вирт.устройства,
    с которого ожидаю получить Ethernet-frame*/
  if ((fd = open(clonedev, O_RDWR)) < 0) {
    perror("open(clonedev, O_RDWR)");
    return fd;
  }

  memset(&ifr, 0, sizeof(ifr));

  ifr.ifr_flags = flags;
  if (*dev) {
    strncpy(ifr.ifr_name, dev, IFNAMSIZ);
  }

  /* пытаюсь увязать файл и Tap-device */
  if ((err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0) {
    close(fd);
    perror("ioctl(fd, TUNSETIFF, (void *)&ifr)");
    return err;
  }
  strcpy(dev, ifr.ifr_name);
  printf("Everything seems OK! \n");
  return fd;
}

在启动时,我开始收到一堆服务以太网帧,也就是说,一切似乎都在工作。但最好分析“the”数据包。

为此,我启动了一个简单的 UDP 发送器,我将它放在地址为 192.168.44.128:9999 的设备上,并开始向 10.10.10.3:9999 发送数据。

Eeeee ...在打开的文件描述符fd上我什么也没得到。同时,为了好玩,我尝试使用 UDP-listener 程序(通常的 open ... bind ... read ... cout 集)收听 10.10.10.3:9999。所有数据都在那里。

我不明白为什么我在fd上没有收到以太网帧,尽管根据 TunTap 手册,我应该收到它们,据我所知。

请告知为什么会这样。我有错误的代码吗?我误解了 TunTap 的概念吗?Tap-device的错误创建?误解了网络堆栈?

我尝试通过创建 Tun-device 来解决类似的问题,结果类似。所有变态都发生在 VM Ware Workstation 15 +5.4.0-42-generic #46~18.04.1-Ubuntu SMP Fri Jul 10 07:21:24 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux 下。

linux
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Fat-Zer
    2020-09-03T06:17:58Z2020-09-03T06:17:58Z

    我误解了 TunTap 的概念吗?

    是的。Tun/Tap 用于创建 VPN 连接。发送到分配给 tap 接口的 L3 地址的数据包实际上并没有进入它:它们由内核处理并立即传送到它们所寻址的程序(如果有的话)。需要此地址才能从 VPN 连接的另一端接收数据。

    那些。为了通过 tap 接口发送某些内容,您需要将数据发送到它后面的子网 ( 10.10.10.0/30),例如,发送到10.10.10.1.

    但是由于 tap 模拟 L2 接口,那么 UDP/IP 数据包也不会“就这样”消失:为了将其发送到内核,您不仅需要知道 L3(IP)地址,还需要知道 L2( MAC) 向其发送数据包的接口的地址。为了找出答案,使用了ARP协议。那。在当前版本中,这只会导致发送一些 arp 请求,当然,这些请求仍然没有得到答复。要在接口上查看 UDP 数据包本身,您可以,例如:

    • 与另一台主机建立真正的 VPN 连接。¹
    • 模拟对 ARP 请求的响应。

    ¹ 请参阅此处的 Google 膝盖示例。

    • 1

相关问题

  • 如果 fuser -k number/tcp 没有帮助,如何在 Debian 中释放端口?

  • Ubuntu。startx 不起作用。黑屏

  • --syn 在 iptables 中有什么作用?

  • 为什么需要iso格式?

  • C程序中没有密码的sudo

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5