-#include "system.h"
-
-int tap_fd = -1;
-int taptype = TAP_TYPE_ETHERTAP;
-int total_tap_in = 0;
-int total_tap_out = 0;
-int total_socket_in = 0;
-int total_socket_out = 0;
-
-int seconds_till_retry = 5;
-
-int keylifetime = 0;
-int keyexpires = 0;
-
-void send_udppacket(connection_t *cl, vpn_packet_t *inpkt)
-{
- vpn_packet_t outpkt;
- int outlen, outpad;
- EVP_CIPHER_CTX ctx;
- struct sockaddr_in to;
- socklen_t tolen = sizeof(to);
- vpn_packet_t *copy;
-cp
- if(!cl->status.validkey)
- {
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_INFO, _("No valid key known yet for %s (%s), queueing packet"),
- cl->name, cl->hostname);
-
- /* Since packet is on the stack of handle_tap_input(),
- we have to make a copy of it first. */
-
- copy = xmalloc(sizeof(vpn_packet_t));
- memcpy(copy, inpkt, sizeof(vpn_packet_t));
-
- list_insert_tail(cl->queue, copy);
-
- if(!cl->status.waitingforkey)
- send_req_key(myself, cl);
- return;
- }
-
- /* Encrypt the packet. */
-
- RAND_pseudo_bytes(inpkt->salt, sizeof(inpkt->salt));
-
- EVP_EncryptInit(&ctx, cl->cipher_pkttype, cl->cipher_pktkey, cl->cipher_pktkey + cl->cipher_pkttype->key_len);
- EVP_EncryptUpdate(&ctx, outpkt.salt, &outlen, inpkt->salt, inpkt->len + sizeof(inpkt->salt));
- EVP_EncryptFinal(&ctx, outpkt.salt + outlen, &outpad);
- outlen += outpad;
-
- total_socket_out += outlen;
-
- to.sin_family = AF_INET;
- to.sin_addr.s_addr = htonl(cl->address);
- to.sin_port = htons(cl->port);
-
- if((sendto(myself->socket, (char *) outpkt.salt, outlen, 0, (const struct sockaddr *)&to, tolen)) < 0)
- {
- syslog(LOG_ERR, _("Error sending packet to %s (%s): %m"),
- cl->name, cl->hostname);
- return;
- }
-cp
-}
-
-void receive_packet(connection_t *cl, vpn_packet_t *packet)
-{
-cp
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"), packet->len, cl->name, cl->hostname);
-
- route_incoming(cl, packet);
-cp
-}
-
-void receive_udppacket(connection_t *cl, vpn_packet_t *inpkt)
-{
- vpn_packet_t outpkt;
- int outlen, outpad;
- EVP_CIPHER_CTX ctx;
-cp
- /* Decrypt the packet */
-
- EVP_DecryptInit(&ctx, myself->cipher_pkttype, myself->cipher_pktkey, myself->cipher_pktkey + myself->cipher_pkttype->key_len);
- EVP_DecryptUpdate(&ctx, outpkt.salt, &outlen, inpkt->salt, inpkt->len);
- EVP_DecryptFinal(&ctx, outpkt.salt + outlen, &outpad);
- outlen += outpad;
- outpkt.len = outlen - sizeof(outpkt.salt);
-
- total_socket_in += outlen;
-
- receive_packet(cl, &outpkt);
-cp
-}
-
-void receive_tcppacket(connection_t *cl, char *buffer, int len)
-{
- vpn_packet_t outpkt;
-cp
- outpkt.len = len;
- memcpy(outpkt.data, buffer, len);
-
- receive_packet(cl, &outpkt);
-cp
-}
-
-void accept_packet(vpn_packet_t *packet)
-{
-cp
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_DEBUG, _("Writing packet of %d bytes to tap device"),
- packet->len);
-
-#ifdef HAVE_SOLARIS
- if(write(tap_fd, packet->data + 14, packet->len - 14) < 0)
- syslog(LOG_ERR, _("Can't write to tun/tap device: %m"));
- else
- total_tap_out += packet->len;
-#else
- if(taptype == TAP_TYPE_TUNTAP)
- {
- if(write(tap_fd, packet->data, packet->len) < 0)
- syslog(LOG_ERR, _("Can't write to tun/tap device: %m"));
- else
- total_tap_out += packet->len;
- }
- else /* ethertap */
- {
- if(write(tap_fd, packet->data - 2, packet->len + 2) < 0)
- syslog(LOG_ERR, _("Can't write to ethertap device: %m"));
- else
- total_tap_out += packet->len;
- }
-#endif
-cp
-}
-
-/*
- send a packet to the given vpn ip.
-*/
-void send_packet(connection_t *cl, vpn_packet_t *packet)
-{
- connection_t *hop;
-cp
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
- packet->len, cl->name, cl->hostname);
-
- if(cl == myself)
- {
- if(debug_lvl >= DEBUG_TRAFFIC)
- {
- syslog(LOG_NOTICE, _("Packet is looping back to us!"));
- }
-
- return;
- }
-
- if(!cl->status.active)
- {
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_INFO, _("%s (%s) is not active, dropping packet"),
- cl->name, cl->hostname);
-
- return;
- }
-
- if(myself->options & OPTION_TCPONLY)
- {
- if(send_tcppacket(cl->nexthop, packet))
- terminate_connection(cl->nexthop, 1);
- }
- else
- {
- if(myself->options & OPTION_INDIRECT)
- send_udppacket(cl->nexthop, packet);
- else
- {
- hop = cl;
-
- while(hop->options & OPTION_INDIRECT)
- if(hop->lastbutonehop == myself)
- break;
- else
- hop = hop->lastbutonehop;
-
- send_udppacket(hop, packet);
- }
- }
-}
-
-/* Broadcast a packet to all active direct connections */