歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux下實現虛擬網卡

Linux下實現虛擬網卡

日期:2017/2/28 16:14:15   编辑:Linux教程
我們在使用VMware的虛擬化軟件時經常會發現它們能都能虛擬出一個網卡,貌似很神奇的技術,其實在Linux下很簡單,有兩種虛擬設 備,TUN時點對點的設備,tap表示以太網設備的,做為虛擬網卡驅動,Tun/tap驅動程序的數據接收和發送並不直接和真實網卡打交道,而是通 過用戶態來轉交。在linux下,要實現核心態和用戶態數據的交互,有多種方式:可以通用socket創建特殊套接字,利用套接字實現數據交 互;通過proc文件系統創建文件來進行數據交互;還可以使用設備文件的方式,訪問設備文件會調用設備驅動相應的例程,設備驅動本身就 是核心態和用戶態的一個接口,Tun/tap驅動就是利用設備文件實現用戶態和核心態的數據交互。
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <curses.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <signal.h>
  10. #include <unistd.h>
  11. #include <linux/if_tun.h>
  12. #include <netinet/in.h>
  13. #include <sys/ioctl.h>
  14. #include <sys/time.h>
  15. #include <linux/if.h>
  16. #include <netinet/in.h>
  17. #include <arpa/inet.h>
  18. #include <errno.h>
  19. #include <fcntl.h>
  20. int tun_creat(char *dev,int flags)
  21. {
  22. struct ifreq ifr;
  23. int fd,err;
  24. assert(dev != NULL);
  25. if((fd = open ("/dev/net/tun",O_RDWR))<0) //you can replace it to tap to create tap device.
  26. return fd;
  27. memset(&ifr,0,sizeof (ifr));
  28. ifr.ifr_flags|=flags;
  29. if(*dev != '\0')
  30. strncpy(ifr.ifr_name,dev,IFNAMSIZ);
  31. if((err = ioctl(fd,TUNSETIFF,(void *)&ifr))<0)
  32. {
  33. close (fd);
  34. return err;
  35. }
  36. strcpy(dev,ifr.ifr_name);
  37. return fd;
  38. }
  39. int main()
  40. {
  41. int tun,ret;
  42. char tun_name[IFNAMSIZ];
  43. unsigned char buf[4096];
  44. tun_name[0]='\0';
  45. tun = tun_creat(tun_name,IFF_TAP|IFF_NO_PI);//如果需要配置tun設備,則把"IFF_TAP"改成“IFF_TUN”
  46. if(tun<0)
  47. {
  48. perror("tun_create");
  49. return 1;
  50. }
  51. printf("TUN name is %s\n",tun_name);
  52. while (1) {
  53. unsigned char ip[4];
  54. ret = read(tun, buf, sizeof(buf));
  55. if (ret < 0)
  56. break;
  57. memcpy(ip, &buf[12], 4);
  58. memcpy(&buf[12], &buf[16], 4);
  59. memcpy(&buf[16], ip, 4);
  60. buf[20] = 0;
  61. *((unsigned short*)&buf[22]) += 8;
  62. printf("read %d bytes\n", ret);
  63. ret = write(tun, buf, ret);
  64. printf("write %d bytes\n", ret);
  65. }
  66. return 0;
  67. }

另開啟一個終端

路由配置:

ifconfig devname 10.0.0.1 up; //10.0.0.1是本虛擬網卡的IP地址,uP是激活該網卡

route add -net 10.0.0.2 netmask 255.255.255.255 dev devname

ping 10.0.0.2

開始測試

Copyright © Linux教程網 All Rights Reserved