void process_incoming_tun (struct context *c) { struct gc_arena gc = gc_new (); perf_push (PERF_PROC_IN_TUN); if (c->c2.buf.len > 0) c->c2.tun_read_bytes += c->c2.buf.len; #ifdef LOG_RW if (c->c2.log_rw && c->c2.buf.len > 0) fprintf (stderr, "r"); #endif /* Show packet content */ dmsg (D_TUN_RW, "TUN READ [%d]", BLEN (&c->c2.buf)); if (c->c2.buf.len > 0) { if ((c->options.mode == MODE_POINT_TO_POINT) && (!c->options.allow_recursive_routing)) drop_if_recursive_routing (c, &c->c2.buf); /* * The --passtos and --mssfix options require * us to examine the IP header (IPv4 or IPv6). */ process_ip_header (c, PIPV4_PASSTOS|PIP_MSSFIX|PIPV4_CLIENT_NAT, &c->c2.buf); #ifdef PACKET_TRUNCATION_CHECK /* if (c->c2.buf.len > 1) --c->c2.buf.len; */ ipv4_packet_size_verify (BPTR (&c->c2.buf), BLEN (&c->c2.buf), TUNNEL_TYPE (c->c1.tuntap), "PRE_ENCRYPT", &c->c2.n_trunc_pre_encrypt); #endif encrypt_sign (c, true); } else { buf_reset (&c->c2.to_link); } perf_pop (); gc_free (&gc); }
void process_outgoing_tun (struct context *c) { struct gc_arena gc = gc_new (); /* * Set up for write() call to TUN/TAP * device. */ if (c->c2.to_tun.len <= 0) return; perf_push (PERF_PROC_OUT_TUN); /* * The --mssfix option requires * us to examine the IP header (IPv4 or IPv6). */ process_ip_header (c, PIP_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER|PIPV4_CLIENT_NAT|PIPV4_OUTGOING, &c->c2.to_tun); if (c->c2.to_tun.len <= MAX_RW_SIZE_TUN (&c->c2.frame)) { /* * Write to TUN/TAP device. */ int size; #ifdef LOG_RW if (c->c2.log_rw) fprintf (stderr, "w"); #endif dmsg (D_TUN_RW, "TUN WRITE [%d]", BLEN (&c->c2.to_tun)); #ifdef PACKET_TRUNCATION_CHECK ipv4_packet_size_verify (BPTR (&c->c2.to_tun), BLEN (&c->c2.to_tun), TUNNEL_TYPE (c->c1.tuntap), "WRITE_TUN", &c->c2.n_trunc_tun_write); #endif #ifdef TUN_PASS_BUFFER size = write_tun_buffered (c->c1.tuntap, &c->c2.to_tun); #else size = write_tun (c->c1.tuntap, BPTR (&c->c2.to_tun), BLEN (&c->c2.to_tun)); #endif if (size > 0) c->c2.tun_write_bytes += size; check_status (size, "write to TUN/TAP", NULL, c->c1.tuntap); /* check written packet size */ if (size > 0) { /* Did we write a different size packet than we intended? */ if (size != BLEN (&c->c2.to_tun)) msg (D_LINK_ERRORS, "TUN/TAP packet was destructively fragmented on write to %s (tried=%d,actual=%d)", c->c1.tuntap->actual_name, BLEN (&c->c2.to_tun), size); /* indicate activity regarding --inactive parameter */ register_activity (c, size); } } else { /* * This should never happen, probably indicates some kind * of MTU mismatch. */ msg (D_LINK_ERRORS, "tun packet too large on write (tried=%d,max=%d)", c->c2.to_tun.len, MAX_RW_SIZE_TUN (&c->c2.frame)); } buf_reset (&c->c2.to_tun); perf_pop (); gc_free (&gc); }