void actionInit(Json::Value &data, std::shared_ptr<typename WsServer::Connection> &connection, WsPacket<WsServer> &) { // LOG(INFO) << "running actionInit JSON"; IfAddrs ifAddrs; if (!IfAddrs::fromJson(data, ifAddrs)) { LOG(ERROR) << "can't parse ifAddrs"; return; } // LOG(INFO) << ifAddrs.asCommands(std::string()); std::shared_ptr<TunDevice> tun( new TunDevice(ifAddrs, tunaTor.getMtu(), tunaTor.getQsize())); if (!tun->start()) { LOG(ERROR) << "can't start tun device"; sendTun("init-res", tun, connection); return; } if (!startStatThread(tun, connection)) { tun->stop(); sendTun("init-res", tun, connection); return; } if (!startRecvThread(tun, connection)) { tun->stop(); sendTun("init-res", tun, connection); return; } tunDevices.insert(std::make_pair(connection, tun)); // Create TunDevice sendTun("init-res", tun, connection); }
uint ip6_tunnels::get(const ip::address_v6& remote) { map::iterator i = _tunnels.find(remote); if (i != _tunnels.end()) { if (++i->second->refcount == 1) _gc.erase(remote); return i->second->tunnel.get_device_id(); } std::auto_ptr<entry> tun(new entry(_io_service)); std::pair<map::iterator, bool> res = _tunnels.insert(remote, tun); try { res.first->second->tunnel.open("", _local.scope_id(), _local, remote); res.first->second->tunnel.set_enable(true); if (_global_address == true) res.first->second->tunnel.add_address(_local, 64); // TODO make this prefix configurable else {} } catch (...) { _tunnels.erase(res.first); throw; } return res.first->second->tunnel.get_device_id(); }
void tun_serv(struct arguments *args) { int fd_udp = 0, fd_tun = 0; /* init server state */ struct tun_state *state = init_tun_state(args); /* create tun if and sockets */ tun(state, &fd_tun); fd_udp = udp_sock(state->public_port, 1, state->public_addr); /* run capture threads */ xthread_create(capture_notun, (void *) state, 1); if (!args->capture_notun_only) xthread_create(capture_tun, (void *) state, 1); synchronize(); /* run server */ debug_print("running serv ...\n"); xthread_create(serv_thread, (void*) state, 1); /* init select loop */ fd_set input_set; struct timeval tv; int sel = 0, fd_max = 0; char buf[BUFF_SIZE], *buffer; buffer = buf; if (state->planetlab) { buffer[0]=0;buffer[1]=0; buffer[2]=8;buffer[3]=0; buffer+=4; } fd_max=max(fd_tun,fd_udp); loop=1; signal(SIGINT, serv_shutdown); signal(SIGTERM, serv_shutdown); while (loop) { FD_ZERO(&input_set); FD_SET(fd_udp, &input_set); FD_SET(fd_tun, &input_set); sel = xselect(&input_set, fd_max, &tv, state->inactivity_timeout); if (sel == 0) { debug_print("timeout\n"); break; } else if (sel > 0) { if (FD_ISSET(fd_udp, &input_set)) tun_serv_out(fd_udp, fd_tun, state, buffer); if (FD_ISSET(fd_tun, &input_set)) tun_serv_in(fd_udp, fd_tun, state, buffer); } } }
int main (int argc, char **argv) { int utunfd = tun (); if (utunfd == -1) { fprintf(stderr,"Unable to establish UTUN descriptor - aborting\n"); exit(1); } fprintf(stderr,"Utun interface is up.. Configure IPv4 using \"ifconfig utun1 _ipA_ _ipB_\"\n"); fprintf(stderr," Configure IPv6 using \"ifconfig utun1 inet6 _ip6_\"\n"); fprintf(stderr,"Then (e.g.) ping _ipB_ (IPv6 will automatically generate ND messages)\n"); // PoC - Just dump the packets... for (;;) { unsigned char c[1500]; int len; int i; len = read (utunfd,c, 1500); // First 4 bytes of read data are the AF: 2 for AF_INET, 1E for AF_INET6, etc.. for (i = 4; i< len; i++) { printf ("%02x ", c[i]); if ( (i-4)%16 ==15) printf("\n"); } printf ("\n"); } return(0); }
int main(int argc, char *argv[]) { int header = 4; int mtu = 1500; int debug = 0; char *hostname; char *path; int port; int noDelayFlag = 0; int tid; int ch; int utunfd; int remoteFd; pid_t pid; while ((ch = getopt(argc, argv, "h:m:np:t:u:v")) != -1) switch (ch) { case 'h': hostname = optarg; break; case 'm': mtu = atoi(optarg) + header; break; case 'n': noDelayFlag = 1; break; case 'p': port = atoi(optarg); break; case 't': tid = atoi(optarg) + 1; break; case 'u': path = optarg; break; case 'v': debug++; break; default: usage(argv[0]); } int max = mtu + header; utunfd = tun(tid); if (port > 0) { remoteFd = tcp(hostname, port, noDelayFlag); } else { remoteFd = unix(path); } fd_set readset; int maxfd = remoteFd; if (maxfd < utunfd) maxfd = utunfd; if (utunfd == -1 || remoteFd == -1) { fprintf(stderr, "Unable to establish UTUN/IPC descriptors - aborting\n"); exit(1); } unsigned char fromRemote[max]; unsigned char fromTun[max]; int len; int expected = 0; int totalLen = 0; int remaining = 0; for (;;) { FD_ZERO(&readset); FD_SET(utunfd, &readset); FD_SET(remoteFd, &readset); select(maxfd + 1, &readset, NULL, NULL, NULL); if (FD_ISSET(utunfd, &readset)) { len = read(utunfd, fromTun, max); if (len > 0) { if (debug) { printSome(fromTun, len, ">>"); } //set frame fromTun[0] = 0; fromTun[1] = 0; fromTun[2] = 8; fromTun[3] = 0; write(remoteFd, fromTun, len); } else if (len == 0) { break; } } if (FD_ISSET(remoteFd, &readset)) { //we always have remaining, set to header length if (!expected && !remaining && !totalLen) { //frame + packet header remaining = 8; } len = read(remoteFd, &fromRemote[totalLen], remaining); remaining = remaining - len; totalLen += len; //got it all, but just the header, parse expected if (!expected && !remaining) { remaining = expected = (fromRemote[6] << 8) | (fromRemote[7] & 0xff); remaining = remaining - header; if (debug) { fprintf(stderr, "Finished reading header totalLen %i pExpected %i remaining %i\n", totalLen, expected, remaining); printSome(fromRemote, totalLen, "<<"); } } //really got it all, ship it else if (expected && !remaining) { if (debug) { fprintf(stderr, "Finished reading packet totalLen %i pExpected %i remaining %i\n", totalLen, expected, remaining); printSome(fromRemote, totalLen, "<<"); } //set frame fromRemote[0] = 0; fromRemote[1] = 0; fromRemote[2] = 0; fromRemote[3] = 2; write(utunfd, fromRemote, totalLen); //we just completed a packet, so reset expected = totalLen = remaining = 0; } else if (len == 0) { break; } else if (debug) { fprintf(stderr, "Keep reading packet totalLen %i pExpected %i remaining %i\n", totalLen, expected, remaining); } } } close(utunfd); close(remoteFd); return (0); }