summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-11-12 21:49:39 +0000
committerHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-11-12 21:49:39 +0000
commit0c3991668d23194a6dbdf569b163148b143b9eab (patch)
treebc77f01b0eb2902fdc925fe59164dcd23d23f3f9
parent13b0631dc99e0e78b876bf22b11c3bc7b14a2fc9 (diff)
add support for interface names as host specifications
-rw-r--r--sbin/ipsecctl/ipsecctl.h9
-rw-r--r--sbin/ipsecctl/parse.y127
2 files changed, 131 insertions, 5 deletions
diff --git a/sbin/ipsecctl/ipsecctl.h b/sbin/ipsecctl/ipsecctl.h
index 7a7b9ee7781..f0340cf6e06 100644
--- a/sbin/ipsecctl/ipsecctl.h
+++ b/sbin/ipsecctl/ipsecctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecctl.h,v 1.22 2005/11/12 16:43:11 deraadt Exp $ */
+/* $OpenBSD: ipsecctl.h,v 1.23 2005/11/12 21:49:38 hshoexer Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -155,6 +155,13 @@ struct ipsecctl {
struct ipsec_rule_queue rule_queue;
};
+struct addr_node {
+ struct ipsec_addr_wrap addr;
+ sa_family_t af;
+ struct addr_node *next;
+ struct addr_node *tail;
+};
+
int parse_rules(FILE *, struct ipsecctl *);
int ipsecctl_add_rule(struct ipsecctl * ipsec, struct ipsec_rule *);
void ipsecctl_get_rules(struct ipsecctl *);
diff --git a/sbin/ipsecctl/parse.y b/sbin/ipsecctl/parse.y
index cef3c212032..bfe2648245c 100644
--- a/sbin/ipsecctl/parse.y
+++ b/sbin/ipsecctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.38 2005/11/12 17:22:23 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.39 2005/11/12 21:49:38 hshoexer Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -22,9 +22,11 @@
%{
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip_ipsp.h>
#include <arpa/inet.h>
@@ -33,6 +35,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <ifaddrs.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
@@ -113,6 +116,10 @@ struct ipsec_key *parsekey(unsigned char *, size_t);
struct ipsec_key *parsekeyfile(char *);
struct ipsec_addr_wrap *host(const char *);
struct ipsec_addr_wrap *host_v4(const char *, int);
+struct ipsec_addr_wrap *host_if(const char *, int);
+void ifa_load(void);
+int ifa_exists(const char *);
+struct ipsec_addr_wrap *ifa_lookup(const char *ifa_name);
void set_ipmask(struct ipsec_addr_wrap *, u_int8_t);
struct ipsec_addr_wrap *copyhost(const struct ipsec_addr_wrap *);
const struct ipsec_xf *parse_xf(const char *, const struct ipsec_xf *);
@@ -1045,11 +1052,9 @@ host(const char *s)
mask = -1;
}
-#if notyet
/* Does interface with this name exist? */
if (cont && (ipa = host_if(ps, mask)) != NULL)
cont = 0;
-#endif
/* IPv4 address? */
if (cont && (ipa = host_v4(s, mask)) != NULL)
@@ -1057,7 +1062,7 @@ host(const char *s)
#if notyet
/* IPv6 address? */
- if (cont && (ipa = host_dsn(ps, v4mask, 0)) != NULL)
+ if (cont && (ipa = host_dns(ps, v4mask, 0)) != NULL)
cont = 0;
#endif
free(ps);
@@ -1102,6 +1107,120 @@ host_v4(const char *s, int mask)
return (ipa);
}
+struct ipsec_addr_wrap *
+host_if(const char *s, int mask)
+{
+ struct ipsec_addr_wrap *ipa = NULL;
+ char *ps;
+
+ if ((ps = strdup(s)) == NULL)
+ err(1, "host_if: strdup");
+
+ if (ifa_exists(ps))
+ ipa = ifa_lookup(ps);
+
+ free(ps);
+ return (ipa);
+}
+
+/* interface lookup routintes */
+
+struct addr_node *iftab;
+
+void
+ifa_load(void)
+{
+ struct ifaddrs *ifap, *ifa;
+ struct addr_node *n = NULL, *h = NULL;
+
+ if (getifaddrs(&ifap) < 0)
+ err(1, "ifa_load: getiffaddrs");
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (!(ifa->ifa_addr->sa_family == AF_INET ||
+ ifa->ifa_addr->sa_family == AF_INET6 ||
+ ifa->ifa_addr->sa_family == AF_LINK))
+ continue;
+ n = calloc(1, sizeof(struct addr_node));
+ if (n == NULL)
+ err(1, "ifa_load: calloc");
+ n->af = ifa->ifa_addr->sa_family;
+ if ((n->addr.name = strdup(ifa->ifa_name)) == NULL)
+ err(1, "ifa_load: strdup");
+ if (n->af == AF_INET) {
+ n->addr.af = AF_INET;
+ memcpy(&n->addr.address.v4, &((struct sockaddr_in *)
+ ifa->ifa_addr)->sin_addr.s_addr,
+ sizeof(struct in_addr));
+ memcpy(&n->addr.mask.v4, &((struct sockaddr_in *)
+ ifa->ifa_netmask)->sin_addr.s_addr,
+ sizeof(struct in_addr));
+ } else if (n->af == AF_INET6) {
+ n->addr.af = AF_INET6;
+ memcpy(&n->addr.address.v6, &((struct sockaddr_in6 *)
+ ifa->ifa_addr)->sin6_addr.s6_addr,
+ sizeof(struct in6_addr));
+ memcpy(&n->addr.mask.v6, &((struct sockaddr_in6 *)
+ ifa->ifa_netmask)->sin6_addr.s6_addr,
+ sizeof(struct in6_addr));
+ }
+ if ((n->addr.name = strdup(ifa->ifa_name)) == NULL)
+ err(1, "ifa_load: strdup");
+ n->next = NULL;
+ n->tail = n;
+ if (h == NULL)
+ h = n;
+ else {
+ h->tail->next = n;
+ h->tail = n;
+ }
+ }
+
+ iftab = h;
+ freeifaddrs(ifap);
+}
+
+int
+ifa_exists(const char *ifa_name)
+{
+ struct addr_node *n;
+
+ if (iftab == NULL)
+ ifa_load();
+
+ for (n = iftab; n; n = n->next) {
+ if (n->af == AF_LINK && !strncmp(n->addr.name, ifa_name,
+ IFNAMSIZ))
+ return (1);
+ }
+
+ return (0);
+}
+
+struct ipsec_addr_wrap *
+ifa_lookup(const char *ifa_name)
+{
+ struct addr_node *p = NULL;
+ struct ipsec_addr_wrap *ipa = NULL;
+
+ if (iftab == NULL)
+ ifa_load();
+
+ for (p = iftab; p; p = p->next) {
+ if (p->af != AF_INET)
+ continue;
+ if (strncmp(p->addr.name, ifa_name, IFNAMSIZ))
+ continue;
+ ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
+ if (ipa == NULL)
+ err(1, "ifa_lookup: calloc");
+ memcpy(ipa, &p->addr, sizeof(struct ipsec_addr_wrap));
+ break;
+ }
+
+ return (ipa);
+}
+
void
set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b)
{