along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: net.c,v 1.35.4.55 2000/10/29 22:10:42 guus Exp $
+ $Id: net.c,v 1.35.4.66 2000/11/04 20:44:26 guus Exp $
*/
#include "config.h"
#include <xalloc.h>
#include "conf.h"
+#include "connlist.h"
+#include "meta.h"
#include "net.h"
#include "netutl.h"
#include "protocol.h"
-#include "meta.h"
-#include "connlist.h"
#include "subnet.h"
#include "system.h"
int keyexpires = 0;
char *unknown = NULL;
+char *interface_name = NULL; /* Contains the name of the interface */
subnet_t mymac;
/*
- strip off the MAC adresses of an ethernet frame
+ Execute the given script.
+ This function doesn't really belong here.
*/
-void strip_mac_addresses(vpn_packet_t *p)
+int execute_script(const char* name)
{
-cp
- memmove(p->data, p->data + 12, p->len -= 12);
-cp
-}
+ char *scriptname;
+ pid_t pid;
+ char *s;
-/*
- reassemble MAC addresses
-*/
-void add_mac_addresses(vpn_packet_t *p)
-{
-cp
- memcpy(p->data + 12, p->data, p->len);
- p->len += 12;
- p->data[0] = p->data[6] = 0xfe;
- p->data[1] = p->data[7] = 0xfd;
- /* Really evil pointer stuff just below! */
- *((ip_t*)(&p->data[2])) = (ip_t)(htonl(myself->address));
- *((ip_t*)(&p->data[8])) = *((ip_t*)(&p->data[26]));
-cp
+ if((pid = fork()) < 0)
+ {
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "fork");
+ return -1;
+ }
+
+ if(pid)
+ {
+ return 0;
+ }
+
+ /* Child here */
+
+ asprintf(&scriptname, "%s/%s", confbase, name);
+ asprintf(&s, "IFNAME=%s", interface_name);
+ putenv(s);
+ free(s);
+
+ if(netname)
+ {
+ asprintf(&s, "NETNAME=%s", netname);
+ putenv(s);
+ free(s);
+ }
+ else
+ {
+ unsetenv("NETNAME");
+ }
+
+ if(chdir(confbase) < 0)
+ {
+ syslog(LOG_ERR, _("Couldn't chdir to `%s': %m"),
+ confbase);
+ }
+
+ 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);
}
int xsend(conn_list_t *cl, vpn_packet_t *inpkt)
total_socket_out += outlen;
- cl->want_ping = 1;
-
if((send(cl->socket, (char *) &(outpkt.len), outlen, 0)) < 0)
{
syslog(LOG_ERR, _("Error sending packet to %s (%s): %m"),
*/
if(debug_lvl >= DEBUG_TRAFFIC)
- syslog(LOG_ERR, _("Writing packet of %d (%d) bytes to tap device"),
+ syslog(LOG_ERR, _("Writing packet of %d bytes to tap device"),
outpkt.len, outlen);
/* Fix mac address */
}
return -1;
- }
+ }
cl = subnet->owner;
+ if(cl == myself)
+ {
+ if(debug_lvl >= DEBUG_TRAFFIC)
+ {
+ syslog(LOG_NOTICE, _("Packet with destination %d.%d.%d.%d is looping back to us!"),
+ IP_ADDR_V(to));
+ }
+
+ return -1;
+ }
+
/* If we ourselves have indirectdata flag set, we should send only to our uplink! */
/* FIXME - check for indirection and reprogram it The Right Way(tm) this time. */
int nfd;
const char *tapfname;
config_t const *cfg;
- char *envvar;
struct ifreq ifr;
cp
/* Add name of network interface to environment (for scripts) */
ioctl(tap_fd, SIOCGIFNAME, (void *) &ifr);
- asprintf(&envvar, "IFNAME=%s", ifr.ifr_name);
- putenv(envvar);
- free(envvar);
+ interface_name = xmalloc(strlen(ifr.ifr_name));
+ strcpy(interface_name, ifr.ifr_name);
cp
return 0;
if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
{
- syslog(LOG_ERR, _("setsockopt: %m"));
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "setsockopt");
return -1;
}
if(setsockopt(nfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)))
{
- syslog(LOG_ERR, _("setsockopt: %m"));
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "setsockopt");
return -1;
}
flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
{
- syslog(LOG_ERR, _("fcntl: %m"));
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "fcntl");
return -1;
}
if(listen(nfd, 3))
{
- syslog(LOG_ERR, _("listen: %m"));
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "listen");
return -1;
}
cp
if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
{
- syslog(LOG_ERR, _("setsockopt: %m"));
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "setsockopt");
return -1;
}
flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
{
- syslog(LOG_ERR, _("fcntl: %m"));
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "fcntl");
return -1;
}
{
conn_list_t *ncn;
struct hostent *h;
- config_t *cfg;
+ config_t const *cfg;
cp
if(check_id(name))
{
ncn->buffer = xmalloc(MAXBUFSIZE);
ncn->buflen = 0;
ncn->last_ping_time = time(NULL);
- ncn->want_ping = 0;
conn_list_add(ncn);
int setup_network_connections(void)
{
config_t const *cfg;
- char *scriptname;
cp
if((cfg = get_config_val(config, pingtimeout)) == NULL)
- timeout = 5;
+ timeout = 60;
else
- timeout = cfg->data.val;
+ {
+ timeout = cfg->data.val;
+ if(timeout < 1)
+ {
+ timeout = 86400;
+ }
+ }
if(setup_tap_fd() < 0)
return -1;
return -1;
/* Run tinc-up script to further initialize the tap interface */
-
- asprintf(&scriptname, "%s/tinc-up", confbase);
-
- if(!fork())
- {
-
- execl(scriptname, NULL);
-
- if(errno != ENOENT)
- syslog(LOG_WARNING, _("Error while executing %s: %m"), scriptname);
-
- exit(0);
- }
-
- free(scriptname);
-
+ execute_script("tinc-up");
+
if(!(cfg = get_config_val(config, connectto)))
/* No upstream IP given, we're listen only. */
return 0;
void close_network_connections(void)
{
conn_list_t *p;
- char *scriptname;
cp
for(p = conn_list; p != NULL; p = p->next)
{
myself = NULL;
}
- /* Execute tinc-down script right before shutting down the interface */
-
- asprintf(&scriptname, "%s/tinc-down", confbase);
-
- if(!fork())
- {
- execl(scriptname, NULL);
-
- if(errno != ENOENT)
- syslog(LOG_WARNING, _("Error while executing %s: %m"), scriptname);
+ close(tap_fd);
- exit(0);
- }
-
- free(scriptname);
+ /* Execute tinc-down script right after shutting down the interface */
+ execute_script("tinc-down");
- close(tap_fd);
destroy_conn_list();
syslog(LOG_NOTICE, _("Terminating"));
if(getpeername(sfd, &ci, &len) < 0)
{
- syslog(LOG_ERR, _("Error: getpeername: %m"));
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "getpeername");
return NULL;
}
p->buffer = xmalloc(MAXBUFSIZE);
p->buflen = 0;
p->last_ping_time = time(NULL);
- p->want_ping = 0;
if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Connection from %s port %d"),
{
if(p->last_ping_time + timeout < now)
{
- if(p->status.pinged && !p->status.got_pong)
+ if(p->status.pinged)
{
if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_INFO, _("%s (%s) didn't respond to PING"),
p->status.timeout = 1;
terminate_connection(p);
}
- else if(p->want_ping)
+ else
{
send_ping(p);
- p->last_ping_time = now;
- p->status.pinged = 1;
- p->status.got_pong = 0;
}
}
}