TAPデバイス間のブリッジ転送
昨日TAPデバイスが認識出来たので2つのTAPデバイスをブリッジさせるコードを書いた。昔作ったツールの評価用にこれが欲しかったのだ。
書いてみると今度はさくっと動いた。コードは以下のような感じ
#include <net/if.h> #include <linux/if_tun.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define max(a,b) ((a)>(b) ? (a):(b)) int tap_alloc(char *dev) { struct ifreq ifr; int fd, err; if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) return -1; memset(&ifr, 0, sizeof(ifr)); /* Flags: IFF_TUN - TUN device (no Ethernet headers) * IFF_TAP - TAP device * * IFF_NO_PI - Do not provide packet information */ ifr.ifr_flags = IFF_TAP; if( *dev ) strncpy(ifr.ifr_name, dev, IFNAMSIZ); if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ close(fd); return err; } strcpy(dev, ifr.ifr_name); return fd; } int main() { char ifname0[] = "tap0"; char ifname1[] = "tap1"; int fd0; int fd1; int fm; fd_set fds; int len; char buf[1024]; fd0 = tap_alloc(ifname0); fd1 = tap_alloc(ifname1); fm = max(fd0, fd1) + 1; while(1) { FD_ZERO(&fds); FD_SET(fd0,&fds); FD_SET(fd1,&fds); select(fm,&fds, NULL, NULL, NULL); if(FD_ISSET(fd0, &fds)){ len = read(fd0,buf,sizeof(buf)); write(fd1,buf,len); } if(FD_ISSET(fd1, &fds)){ len = read(fd1,buf,sizeof(buf)); write(fd0,buf,len); } } }
確認方法
- 前もって/sbin/modprobe tunでtunモジュールを立ち上げておく
- 本プログラムを実行
- /sbin/ifconfig -aでtap0とtap1が見えることを確認
- ifconfigでtap0とtap1にIPアドレスを割り当て
- tap0のIPアドレスにARPエントリを登録しておいて、tap0の同一ネットワークの別IPにtelnetを仕掛けてみる
- tap1側はtcpdumpを流しておく
- 結果は以下。tap0から送出されたSYNパケットがtap1にブリッジされていることが確認出来る
10:25:49.011218 IP 192.168.2.1.2304 > 192.168.2.100.telnet: S 2006705718:2006705718(0) win 58400x0000: 4510 003c fc4d 4000 4006 b8a8 c0a8 0201 E..<.M@.@....... 0x0010: c0a8 0264 0900 0017 779b e636 0000 0000 ...d....w..6.... 0x0020: a002 16d0 1e54 0000 0204 05b4 0402 080a .....T.......... 0x0030: 000f 2632 0000 0000 0103 0303 ..&2........
I made a code to bridge between two tap devices. This code will help evaluating my networking tool.