- if(chdir(confbase) < 0)
- /* This cannot fail since we already read config files from this
- directory. - Guus */
- /* Yes this can fail, somebody could have removed this directory
- when we didn't pay attention. - Ivo */
- {
- if(chdir("/") < 0)
- /* Now if THIS fails, something wicked is going on. - Ivo */
- syslog(LOG_ERR, _("Couldn't chdir to `/': %m"));
-
- /* Continue anyway. */
- }
-
- asprintf(&scriptname, "%s/%s", confbase, name);
-
- /* Close all file descriptors */
- closelog();
- fcloseall();
-
- /* Open standard input */
- if(open("/dev/null", O_RDONLY) < 0)
- {
- syslog(LOG_ERR, _("Opening `/dev/null' failed: %m"));
- error = 1;
- }
-
- if(!error)
- {
- /* Standard output directly goes to syslog */
- openlog(name, LOG_CONS | LOG_PID, LOG_DAEMON);
- /* Standard error as well */
- if(dup2(1, 2) < 0)
- {
- syslog(LOG_ERR, _("System call `%s' failed: %m"),
- "dup2");
- error = 1;
- }
- }
-
- if(error && debug_lvl > 1)
- syslog(LOG_INFO, _("This means that any output the script generates will not be shown in syslog."));
-
- execl(scriptname, NULL);
- /* No return on success */
-
- if(errno != ENOENT) /* Ignore if the file does not exist */
- syslog(LOG_WARNING, _("Error executing `%s': %m"), scriptname);
-
- /* No need to free things */
- exit(0);
-}
-
-/*
- Execute the given script.
- This function doesn't really belong here.
-*/
-int execute_script(const char *name)
-{
- pid_t pid;
-
- if((pid = fork()) < 0)
- {
- syslog(LOG_ERR, _("System call `%s' failed: %m"),
- "fork");
- return -1;
- }
-
- if(pid)
- {
- list_append(child_pids, pid);
- return 0;
- }
-
- /* Child here */
-
- _execute_script(name);
-}
-
-int check_child(void *data)
-{
- pid_t pid;
- int status;
-
- pid = (pid_t) data;
- pid = waitpid(pid, &status, WNOHANG);
- if(WIFEXITED(status))
- {
- if(WIFSIGNALED(status)) /* Child was killed by a signal */
- {
- syslog(LOG_ERR, _("Child with PID %d was killed by signal %d (%s)"),
- pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
- return -1;
- }
- if(WEXITSTATUS(status) != 0)
- {
- syslog(LOG_INFO, _("Child with PID %d exited with code %d"),
- WEXITSTATUS(status));
- }
- return -1;
- }
-}
-
-void check_children(void)
-{
- list_forall_nodes(child_pids, check_child);
-}
-
-int xsend(conn_list_t *cl, vpn_packet_t *inpkt)
-{
- vpn_packet_t outpkt;
- int outlen, outpad;
- EVP_CIPHER_CTX ctx;
-cp
- outpkt.len = inpkt->len;
-
- /* Encrypt the packet */
-
- EVP_EncryptInit(&ctx, cl->cipher_pkttype, cl->cipher_pktkey, cl->cipher_pktkey + cl->cipher_pkttype->key_len);
- EVP_EncryptUpdate(&ctx, outpkt.data, &outlen, inpkt->data, inpkt->len);
- EVP_EncryptFinal(&ctx, outpkt.data + outlen, &outpad);
- outlen += outpad + 2;
-
-/* Bypass
- outlen = outpkt.len + 2;
- memcpy(&outpkt, inpkt, outlen);
-*/
-
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
- outlen, cl->name, cl->hostname);
-
- total_socket_out += outlen;
-
- if((send(cl->socket, (char *) &(outpkt.len), outlen, 0)) < 0)
- {
- syslog(LOG_ERR, _("Error sending packet to %s (%s): %m"),
- cl->name, cl->hostname);
- return -1;
- }
-cp
- return 0;
-}
-
-int xrecv(conn_list_t *cl, vpn_packet_t *inpkt)
-{
- vpn_packet_t outpkt;
- int outlen, outpad;
- EVP_CIPHER_CTX ctx;
-cp
- outpkt.len = inpkt->len;
-
- /* Decrypt the packet */
-
- EVP_DecryptInit(&ctx, myself->cipher_pkttype, myself->cipher_pktkey, myself->cipher_pktkey + myself->cipher_pkttype->key_len);
- EVP_DecryptUpdate(&ctx, outpkt.data, &outlen, inpkt->data, inpkt->len + 8);
- EVP_DecryptFinal(&ctx, outpkt.data + outlen, &outpad);
- outlen += outpad;
-
-/* Bypass
- outlen = outpkt.len+2;
- memcpy(&outpkt, inpkt, outlen);
-*/
-
- if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_ERR, _("Writing packet of %d bytes to tap device"),
- outpkt.len, outlen);
-
- /* Fix mac address */
-
- memcpy(outpkt.data, mymac.net.mac.address.x, 6);
-
- if(taptype == TAP_TYPE_TUNTAP)
- {
- if(write(tap_fd, outpkt.data, outpkt.len) < 0)
- syslog(LOG_ERR, _("Can't write to tun/tap device: %m"));
- else
- total_tap_out += outpkt.len;
- }
- else /* ethertap */
- {
- if(write(tap_fd, outpkt.data - 2, outpkt.len + 2) < 0)
- syslog(LOG_ERR, _("Can't write to ethertap device: %m"));
- else
- total_tap_out += outpkt.len + 2;
- }
-cp
- return 0;
-}
-
-/*
- add the given packet of size s to the
- queue q, be it the send or receive queue
-*/
-void add_queue(packet_queue_t **q, void *packet, size_t s)
-{
- queue_element_t *e;
-cp
- e = xmalloc(sizeof(*e));
- e->packet = xmalloc(s);
- memcpy(e->packet, packet, s);
-
- if(!*q)
- {
- *q = xmalloc(sizeof(**q));
- (*q)->head = (*q)->tail = NULL;
- }
-
- e->next = NULL; /* We insert at the tail */
-
- if((*q)->tail) /* Do we have a tail? */
- {
- (*q)->tail->next = e;
- e->prev = (*q)->tail;
- }
- else /* No tail -> no head too */
- {
- (*q)->head = e;
- e->prev = NULL;
- }
-
- (*q)->tail = e;
-cp
-}
-
-/* Remove a queue element */
-void del_queue(packet_queue_t **q, queue_element_t *e)
-{
-cp
- free(e->packet);
-
- if(e->next) /* There is a successor, so we are not tail */
- {
- if(e->prev) /* There is a predecessor, so we are not head */
- {
- e->next->prev = e->prev;
- e->prev->next = e->next;
- }
- else /* We are head */
- {
- e->next->prev = NULL;
- (*q)->head = e->next;
- }
- }
- else /* We are tail (or all alone!) */
- {
- if(e->prev) /* We are not alone :) */
- {
- e->prev->next = NULL;
- (*q)->tail = e->prev;
- }
- else /* Adieu */
- {
- free(*q);
- *q = NULL;
- }
- }
-
- free(e);
-cp
-}
-
-/*
- flush a queue by calling function for
- each packet, and removing it when that
- returned a zero exit code
-*/
-void flush_queue(conn_list_t *cl, packet_queue_t **pq,
- int (*function)(conn_list_t*,vpn_packet_t*))
-{
- queue_element_t *p, *next = NULL;
-cp
- for(p = (*pq)->head; p != NULL; )
- {
- next = p->next;