Files
strongswan-ext/src/starter/interfaces.c
T
2007-10-08 19:57:54 +00:00

153 lines
3.7 KiB
C

/* strongSwan IPsec interfaces management
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* RCSID $Id$
*/
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <freeswan.h>
#include <ipsec_tunnel.h>
#include <constants.h>
#include <defs.h>
#include <log.h>
#include "interfaces.h"
#include "exec.h"
#include "files.h"
/*
* discover the default route via /proc/net/route
*/
void
get_defaultroute(defaultroute_t *defaultroute)
{
FILE *fd;
char line[BUF_LEN];
bool first = TRUE;
memset(defaultroute, 0, sizeof(defaultroute_t));
fd = fopen("/proc/net/route", "r");
if (!fd)
{
plog("could not open 'proc/net/route'");
return;
}
while (fgets(line, sizeof(line), fd) != 0)
{
char iface[11];
char destination[9];
char gateway[11];
char flags[5];
char mask[9];
int refcnt;
int use;
int metric;
int items;
/* proc/net/route returns IP addresses in host order */
strcpy(gateway, "0h");
/* skip the header line */
if (first)
{
first = FALSE;
continue;
}
/* parsing a single line of proc/net/route */
items = sscanf(line, "%10s\t%8s\t%8s\t%5s\t%d\t%d\t%d\t%8s\t"
, iface, destination, gateway+2, flags, &refcnt, &use, &metric, mask);
if (items < 8)
{
plog("parsing error while scanning /proc/net/route");
continue;
}
/* check for defaultroute (destination 0.0.0.0 and mask 0.0.0.0) */
if (streq(destination, "00000000") && streq(mask, "00000000"))
{
if (defaultroute->defined)
{
plog("multiple default routes - cannot cope with %%defaultroute!!!");
defaultroute->defined = FALSE;
fclose(fd);
return;
}
ttoaddr(gateway, strlen(gateway), AF_INET, &defaultroute->nexthop);
strncpy(defaultroute->iface, iface, IFNAMSIZ);
defaultroute->defined = TRUE;
}
}
fclose(fd);
if (!defaultroute->defined)
{
plog("no default route - cannot cope with %%defaultroute!!!");
}
else
{
char addr_buf[20], nexthop_buf[20];
struct ifreq physreq;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
/* determine IP address of iface */
if (sock < 0)
{
plog("could not open SOCK_DGRAM socket");
defaultroute->defined = FALSE;
return;
}
memset ((void*)&physreq, 0, sizeof(physreq));
strncpy(physreq.ifr_name, defaultroute->iface, IFNAMSIZ);
ioctl(sock, SIOCGIFADDR, &physreq);
close(sock);
defaultroute->addr.u.v4 = *((struct sockaddr_in *)&physreq.ifr_addr);
addrtot(&defaultroute->addr, 0, addr_buf, sizeof(addr_buf));
addrtot(&defaultroute->nexthop, 0, nexthop_buf, sizeof(nexthop_buf));
DBG(DBG_CONTROL,
DBG_log("Default route found: iface=%s, addr=%s, nexthop=%s"
, defaultroute->iface, addr_buf, nexthop_buf)
)
/* for backwards-compatibility with the awk shell scripts
* store the defaultroute in /var/run/ipsec.info
*/
fd = fopen(INFO_FILE, "w");
if (fd)
{
fprintf(fd, "defaultroutephys=%s\n", defaultroute->iface );
fprintf(fd, "defaultroutevirt=ipsec0\n");
fprintf(fd, "defaultrouteaddr=%s\n", addr_buf);
fprintf(fd, "defaultroutenexthop=%s\n", nexthop_buf);
fclose(fd);
}
}
return;
}