/**
* The Linux Tun sample code comes
* Timeout
* Http://blog.csdn.net/Z_man/archive/2009/05/26/4216530.aspx
* If a tun0 virtual network card is created for communication, the program will disappear after it is closed.
* Ping 10.0.0.1
* Documentation/networking/tuntap.txt
* Br_select.c Bridge Based on select system call.
* Br_sigio.c Bridge Based on async Io and sigio signal.
* Http://hi.baidu.com/zkheartboy/blog/item/e96acf33508e4a40ad4b5f88.html
* Http://blogold.chinaunix.net/u3/114446/showart_2245279.html
* Http://www.ibm.com/developerworks/cn/linux/l-tuntap/index.html
*/
# Include <fcntl. h> <br/> # include <stdio. h> <br/> # include <string. h> <br/> # include <sys/socket. h> <br/> # include <sys/IOCTL. h> <br/> # include <Linux/if. h> <br/> # include <Linux/if_tun.h> <br/> # include <sys/types. h> <br/> # include <errno. h> <br/> # include <net/route. h> </P> <p>/** <br/> * activation interface <br/> */<br/> int interface_up (char * interface_name) <br/>{< br/> int s; </P> <p> If (S = socket (pf_inet, sock_stream, 0) <0) <br/>{< br/> printf ("error create socket: % M/N", errno); <br/> return-1; <br/>}</P> <p> struct ifreq IFR; <br/> strcpy (IFR. ifr_name, interface_name); </P> <p> short flag; <br/> flag = iff_up; <br/> If (IOCTL (S, siocgifflags, & IFR) <0) <br/> {<br/> printf ("error up % s: % M/N", interface_name, errno); <br/> return-1; <br/>}</P> <p> IFR. ifr_ifru.ifru_flags | = flag; </P> <p> If (IOCTL (S, siocsiff Lags, & IFR) <0) <br/>{< br/> printf ("error up % s: % M/N", interface_name, errno ); <br/> return-1; <br/>}</P> <p> return 0; </P> <p >}</P> <p>/** <br/> * set the interface IP address <br/> */<br/> int set_ipaddr (char * interface_name, char * IP) <br/>{< br/> int s; </P> <p> If (S = socket (pf_inet, sock_stream, 0) <0) <br/>{< br/> printf ("error up % s: % M/N", interface_name, errno); <br/> return-1; <br/>}</P> <p> struct IFR Eq ifr; <br/> strcpy (IFR. ifr_name, interface_name); </P> <p> struct sockaddr_in ADDR; <br/> bzero (& ADDR, sizeof (struct sockaddr_in); <br/> ADDR. sin_family = pf_inet; <br/> inet_aton (IP, & ADDR. sin_addr); </P> <p> memcpy (& IFR. ifr_ifru.ifru_addr, & ADDR, sizeof (struct sockaddr_in); </P> <p> If (IOCTL (S, siocsifaddr, & IFR) <0) <br/>{< br/> printf ("error set % s IP: % M/N", interface_name, errno); <br/> retur N-1; <br/>}</P> <p> return 0; <br/>}</P> <p>/** <br/> * Create an interface <br/> */<br/> int tun_create (char * Dev, int flags) <br/>{< br/> struct ifreq IFR; <br/> int FD, err; </P> <p> If (FD = open ("/dev/NET/TUN", o_rdwr) <0) <br/>{< br/> printf ("error: % M/N", errno); <br/> return-1; <br/>}</P> <p> memset (& IFR, 0, sizeof (IFR); <br/> IFR. ifr_flags | = flags; </P> <p> If (* Dev! = '/0') <br/>{< br/> strncpy (IFR. ifr_name, Dev, ifnamsiz); <br/>}</P> <p> If (ERR = IOCTL (FD, tunsetiff, (void *) & IFR )) <0) <br/>{< br/> printf ("error: % M/N", errno); <br/> close (FD ); <br/> return-1; <br/>}</P> <p> strcpy (Dev, IFR. ifr_name); </P> <p> return FD; <br/>}</P> <p>/** <br/> * Route entry to 10.0.0.1 <br/> * The same command: route add 10.0.0.1 Dev tun0 <br/> */<br/> int route_add (char * interface_name) <br/>{< br/> int skfd; <br/> struct rtentry RT; </P> <p> struct sockaddr_in DST; <br/> struct sockaddr_in GW; <br/> struct sockaddr_in genmask; </P> <p> memset (& RT, 0, sizeof (RT); </P> <p> genmask. sin_addr.s_addr = inet_addr ("255.255.255.255"); </P> <p> bzero (& DST, sizeof (struct sockaddr_in); <br/> DST. sin_family = pf_inet; <br/> DST. sin_addr.s_addr = inet_addr ("10.0.0.1"); </P> <p> RT. rt_metric = 0; <br/> RT. rt_dst = * (struct sockaddr *) & DST; <br/> RT. rt_genmask = * (struct sockaddr *) & genmask; </P> <p> RT. rt_dev = interface_name; <br/> RT. rt_flags = rtf_up | rtf_host; </P> <p> skfd = socket (af_inet, sock_dgram, 0); <br/> If (IOCTL (skfd, siocaddrt, & RT) <0) <br/> {<br/> printf ("error route Add: % M/N", errno); <br/> return-1; <br/>}< br/> int main (INT argc, char * argv []) <br/>{< br/> int Tun, RET; <br/> char tun_name [ifnamsiz]; <br/> unsigned char Buf [4096]; <br/> unsigned char IP [4]; </P> <p> tun_name [0] = '/0'; <br/> Tun = tun_create (tun_name, iff_tun | iff_no_pi ); <br/> If (Tun <0) <br/>{< br/> return 1; <br/>}< br/> printf ("tun name is % s/n", tun_name ); </P> <p> // activate the route from the virtual network card to the virtual network card <br/> interface_up (tun_name); <br/> route_add (tun_name ); </P> <p> while (1) {</P> <p> ret = read (Tun, Buf, sizeof (BUF )); <br/> printf ("read % d Bytes/N", RET); <br/> int I; <br/> for (I = 0; I <ret; I ++) <br/>{< br/> printf ("% 02x", Buf [I]); <br/>}< br/> printf ("/N"); <br/> If (Ret <0) <br/> break; <br/> memcpy (IP, & Buf [12], 4); <br/> memcpy (& Buf [12], & Buf [16], 4 ); <br/> memcpy (& Buf [16], IP, 4); <br/> Buf [20] = 0; <br/> * (unsigned short *) & Buf [22]) + = 8; <br/> ret = write (Tun, Buf, RET); <br/> printf ("write % d Bytes/N ", RET); <br/>}</P> <p> return 0; <br/>}
Test method:
1. Compile and run this program to listen for Data Reading and writing.
2. Open another terminal and run the ping command to send a local test package to 10.0.0.1.
The received and received packets are displayed.