总述
这次也是参考网上的相关代码跟链接,在代码里面去配置tun网卡的IP,掩码,路由等,然后类似于实现一个自发自收的tun网卡。
过程
先加载驱动,以下用tun0网卡为例,tap0其实也大差不差

然后ip link查看,这个时候是没有tun/tap网卡的,上一个文章提到需要ip命令添加tun/tap网卡,这次我们直接在代码里面配置。(具体怎么配置的下面再详细解释代码)

编译下面的代码,得到icmpecho可执行程序,这个程序会给tun配上IP(192.168.0.1),路由,网关,然后也是去读写/dev/tun的文件描述符。
执行icmpecho,就会一直read这个fd,就跟我们socket read差不多,等数据来,是阻塞的。
当我们去ping 192.168.0.3的时候,ping命令会,ping程序自己构造了一个icmp request的包,根据默认的路由,会通过tun0网卡发出,虽然是socket,本质上也可以理解为去write这个tun0网卡。
而前面我们的icmpecho程序一直在阻塞的read,一旦ping启动,则读到数据,然后icmpecho程序读到后将收到的数据打印出来,同时交换目的地址跟源地址,计算校验和,修改为echo报文,(后面代码可以看到)然后再write回去,这时候ping就会收到echo而现实可以ping通。
整个过程流程图大概如下:(个人理解)

驱动底层函数如下


大概知道代码在干嘛后,实际操作,第一个窗口,执行icmpecho

执行后可以看到代码中的tun_alloc函数已经帮我们配好IP(192.168.0.1),路由,网关

路由表如下

此时第二个窗口,执行ping 192.168.0.3

第一个窗口icmpecho的打印

于此同时我们进行抓包

从抓包的101901.pcap文件中可以看出,都是IP报文 ,是没有二层网卡的头部的,因为tun工作在第三层,但是tap工作在第二层,如果是tap的数据就可以看到以太网帧头部。

代码
代码也是参考网上的,传了一份在github上了,包括前面的网卡抓包文件。