The addrstr is the tunnel address and must include the mask, eg: "192.168.2.0/24"
| 286 | |
| 287 | // The addrstr is the tunnel address and must include the mask, eg: "192.168.2.0/24" |
| 288 | EXPORT int ip_tun_open(const char *tname, const char *addrstr) // int32_t ipaddr, int maskbits) |
| 289 | { |
| 290 | struct ifreq ifr; |
| 291 | int fd; |
| 292 | const char *clonedev = "/dev/net/tun"; |
| 293 | if ((fd = open(clonedev,O_RDWR)) < 0) { |
| 294 | // Hmmph. Try to create the tunnel device. |
| 295 | runcmd("/sbin/modprobe","modprobe","tun",NULL); |
| 296 | runcmd("/sbin/modprobe","modprobe","ipip",NULL); |
| 297 | sleep(2); |
| 298 | } |
| 299 | if ((fd = open(clonedev,O_RDWR)) < 0) { |
| 300 | MGERROR("error: Could not open: %s\n",clonedev); |
| 301 | return -1; |
| 302 | } |
| 303 | |
| 304 | // This attaches to our existing mstun interface, if any, because |
| 305 | // of the magic TUNSETPERSIST flag. |
| 306 | memset(&ifr,0,sizeof(ifr)); |
| 307 | strcpy(ifr.ifr_name,tname); |
| 308 | ifr.ifr_flags = IFF_TUN | IFF_NO_PI; // Disable packet info. |
| 309 | if (ioctl(fd,TUNSETIFF,&ifr) < 0) { |
| 310 | MGERROR("could not create tunnel %s: ioctl error: %s\n",tname,strerror(errno)); |
| 311 | return -1; |
| 312 | } |
| 313 | if (ioctl(fd,TUNSETPERSIST,1) < 0) { |
| 314 | MGERROR("could not setpersist tunnel %s: ioctl error: %s\n",tname,strerror(errno)); |
| 315 | } |
| 316 | |
| 317 | // This (and only this) magic works: |
| 318 | // We invoke with: |
| 319 | // ./miniggsn -v -t 192.168.1.75/32 -f 192.168.1.75 router |
| 320 | // or: ./miniggsn -v -t 192.168.2.0/24 -f 192.168.2.1 router |
| 321 | runcmd("/sbin/ip","ip","link","set",tname,"up",NULL); |
| 322 | // TODO: Instead of individual routes, we can also do: |
| 323 | // ip route add to 192.168.3.0/24 dev mstun # Note you must use .0, not .1 |
| 324 | //runcmd("/sbin/ip","ip","route","add","to",options.from,"dev",tname,NULL); |
| 325 | runcmd("/sbin/ip","ip","route","add","to",addrstr,"dev",tname,NULL); |
| 326 | // Establishing a "forwarding route" causes linux proxy-arp to automagically add an ARP |
| 327 | // for mstun, even though it has the "NOARP" option set. What a mess. |
| 328 | |
| 329 | // Now we can set the interface addr using ip command. |
| 330 | //ip_add_addr(tname,ipaddr,maskbits); |
| 331 | // The addrstr must include the correct maskbits, like /24, or it just doesnt work. |
| 332 | // If you call any of these, the output is no longer routed unless |
| 333 | // you called TUNSETPERSIST first. |
| 334 | //runcmd("/sbin/ifconfig","ifconfig",tname,"arp",NULL); |
| 335 | //runcmd("/sbin/ip","ip","addr","add",addrstr,"dev",tname,NULL); |
| 336 | //runcmd("/sbin/iptables","iptables","-A","FORWARD","-i",tname,"-j","ACCEPT", NULL); |
| 337 | |
| 338 | |
| 339 | // todo #include <linux/sockios.h> |
| 340 | // SIOCADDRT struct ifreq* /* add routing table entry */ |
| 341 | // SIOCGIFADDR get interface address. |
| 342 | // SIOCADDRT add interface address. |
| 343 | // SIOCSIFADDR, SIOCSIFNETMASK |
| 344 | /* |
| 345 | if (set_ip_using(buf, SIOCSIFADDR, ip) == -1) { |
no test coverage detected