summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-05-27 15:27:28 +0000
committerHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-05-27 15:27:28 +0000
commit45ed825c6673c028cc4a4fd2c1f90f698421ca98 (patch)
tree76180ae33b2f81628f42b1455eb0f88724425467 /sys/net
parent97ce1d95f3e68a1652e4cdbd461f1dfb0d94cd23 (diff)
Add export_flow()
ok ho markus
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/pfkeyv2_convert.c96
1 files changed, 95 insertions, 1 deletions
diff --git a/sys/net/pfkeyv2_convert.c b/sys/net/pfkeyv2_convert.c
index 43b24904338..129083c2aa5 100644
--- a/sys/net/pfkeyv2_convert.c
+++ b/sys/net/pfkeyv2_convert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2_convert.c,v 1.24 2005/05/25 05:47:53 markus Exp $ */
+/* $OpenBSD: pfkeyv2_convert.c,v 1.25 2005/05/27 15:27:27 hshoexer Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@keromytis.org)
*
@@ -522,6 +522,100 @@ import_flow(struct sockaddr_encap *flow, struct sockaddr_encap *flowmask,
}
/*
+ * Helper to export addresses from an struct sockaddr_encap.
+ */
+static void
+export_encap(void **p, struct sockaddr_encap *encap, int type)
+{
+ struct sadb_address *saddr = (struct sadb_address *)*p;
+ union sockaddr_union *sunion;
+
+ *p += sizeof(struct sadb_address);
+ sunion = (union sockaddr_union *)*p;
+
+ switch (encap->sen_type) {
+ case SENT_IP4:
+ saddr->sadb_address_len = (sizeof(struct sadb_address) +
+ PADUP(sizeof(struct sockaddr_in))) / sizeof(uint64_t);
+ sunion->sa.sa_len = sizeof(struct sockaddr_in);
+ sunion->sa.sa_family = AF_INET;
+ if (type == SADB_X_EXT_SRC_FLOW ||
+ type == SADB_X_EXT_SRC_MASK) {
+ sunion->sin.sin_addr = encap->sen_ip_src;
+ sunion->sin.sin_port = encap->sen_sport;
+ } else {
+ sunion->sin.sin_addr = encap->sen_ip_dst;
+ sunion->sin.sin_port = encap->sen_dport;
+ }
+ *p += PADUP(sizeof(struct sockaddr_in));
+ break;
+ case SENT_IP6:
+ saddr->sadb_address_len = (sizeof(struct sadb_address)
+ + PADUP(sizeof(struct sockaddr_in6))) / sizeof(uint64_t);
+ sunion->sa.sa_len = sizeof(struct sockaddr_in6);
+ sunion->sa.sa_family = AF_INET6;
+ if (type == SADB_X_EXT_SRC_FLOW ||
+ type == SADB_X_EXT_SRC_MASK) {
+ sunion->sin6.sin6_addr = encap->sen_ip6_src;
+ sunion->sin6.sin6_port = encap->sen_ip6_sport;
+ } else {
+ sunion->sin6.sin6_addr = encap->sen_ip6_dst;
+ sunion->sin6.sin6_port = encap->sen_ip6_dport;
+ }
+ *p += PADUP(sizeof(struct sockaddr_in6));
+ break;
+ }
+}
+
+/*
+ * Export flow information from two struct sockaddr_encap's.
+ */
+void
+export_flow(void **p, u_int8_t ftype, struct sockaddr_encap *flow,
+ struct sockaddr_encap *flowmask, void **headers)
+{
+ struct sadb_protocol *sab;
+
+ headers[SADB_X_EXT_FLOW_TYPE] = *p;
+ sab = (struct sadb_protocol *)*p;
+ sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
+ sizeof(uint64_t);
+ sab->sadb_protocol_proto = ftype;
+ switch (flow->sen_type) {
+#ifdef INET
+ case SENT_IP4:
+ sab->sadb_protocol_direction = flow->sen_direction;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case SENT_IP6:
+ sab->sadb_protocol_direction = flow->sen_ip6_direction;
+ break;
+#endif /* INET6 */
+ }
+ *p += sizeof(struct sadb_protocol);
+
+ headers[SADB_X_EXT_PROTOCOL] = *p;
+ sab = (struct sadb_protocol *)*p;
+ sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
+ sizeof(uint64_t);
+ sab->sadb_protocol_proto = flow->sen_proto;
+ *p += sizeof(struct sadb_protocol);
+
+ headers[SADB_X_EXT_SRC_FLOW] = *p;
+ export_encap(p, flow, SADB_X_EXT_SRC_FLOW);
+
+ headers[SADB_X_EXT_SRC_MASK] = *p;
+ export_encap(p, flowmask, SADB_X_EXT_SRC_MASK);
+
+ headers[SADB_X_EXT_DST_FLOW] = *p;
+ export_encap(p, flow, SADB_X_EXT_DST_FLOW);
+
+ headers[SADB_X_EXT_DST_MASK] = *p;
+ export_encap(p, flowmask, SADB_X_EXT_DST_MASK);
+}
+
+/*
* Copy an SADB_ADDRESS payload to a struct sockaddr.
*/
void