首页 > 解决方案 > TunTap 设备接收 ping

问题描述

我正在尝试熟悉 tuntap 设备。我已阅读以下文章:

https://backreference.org/2010/03/26/tuntap-interface-tutorial/

但不知何故,文章中的代码不起作用。

我有这个代码:

  #include <sys/socket.h> //well get our socket
  #include <sys/ioctl.h> //thats our input output control
  #include <sys/time.h>
  #include <fcntl.h>


  #include <asm/types.h> //these are data types liked signed unsingend

  #include <math.h>
  #include <string.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h> //read write close and stuff
  #include <signal.h> //different signals

  #include <linux/if_packet.h> //interface for packets
  #include <linux/if_ether.h> //interface or ethernet frames
  #include <linux/if_arp.h> //interface for arp

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

  #include <arpa/inet.h>

  int tun_alloc(char *dev, int flags) {
    struct ifreq ifr;
    int fd, err;
    char *clonedev = "/dev/net/tun";

    /* Arguments taken by the function:
     *
     * char *dev: the name of an interface (or '\0'). MUST have enough
     *   space to hold the interface name if '\0' is passed
     * int flags: interface flags (eg, IFF_TUN etc.)
     */

     /* open the clone device */
     if( (fd = open(clonedev, O_RDWR)) < 0 ) {
       return fd;
     }

     /* preparation of the struct ifr, of type "struct ifreq" */
     memset(&ifr, 0, sizeof(ifr));

     ifr.ifr_flags = flags;   /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */

     if (*dev) {
       /* if a device name was specified, put it in the structure; otherwise,
        * the kernel will try to allocate the "next" device of the
        * specified type */
       strncpy(ifr.ifr_name, dev, IFNAMSIZ);
     }

     /* try to create the device */
     if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
       close(fd);
       return err;
     }

    /* if the operation was successful, write back the name of the
     * interface to the variable "dev", so the caller can know
     * it. Note that the caller MUST reserve space in *dev (see calling
     * code below) */
    strcpy(dev, ifr.ifr_name);

    /* this is the special file descriptor that the caller will use to talk
     * with the virtual interface */
    return fd;
  }

  int main(void){
    unsigned int seconds = 1;
    char tap_name[IFNAMSIZ];
    strcpy(tap_name, "tun0");
    printf("%s\n", tap_name);
    int tap_fd = tun_alloc(tap_name, IFF_TUN);
    void *buffer = (void *)(malloc(3000));
    printf("%s\n", tap_name);

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

    int nread;

    while(1){
      nread = read(tap_fd, buffer, sizeof(buffer));
      if (nread < 0){
        perror("Nread: ");
        close(tap_fd);
        free(buffer);
        exit(1);
      }

      printf("Read %d Bytes from devies %s \n", nread, tap_name);
      sleep(seconds);
    }


  }

我在一个终端上执行了这个程序,并从另一个终端ping了接口。

但是当我从命令行 ping 接口时(ping 192.168.0.24我已经将该 IP 分配给接口),在程序的终端上总是写着“从接口读取 8 个字节”,尽管当我 ping 时字节数应该有所不同界面。有没有人看到错误?

标签: cnetworking

解决方案


推荐阅读