diff options
author | Hans-Joerg Hoexer <hshoexer@cvs.openbsd.org> | 2006-03-29 20:21:46 +0000 |
---|---|---|
committer | Hans-Joerg Hoexer <hshoexer@cvs.openbsd.org> | 2006-03-29 20:21:46 +0000 |
commit | c865357eff6a85799d8ed04e2da7d69ca3bdea79 (patch) | |
tree | 0f0d7c9adf43e1b70ebd8d7161ad552742d2bf85 /sbin/route/show.c | |
parent | 2c4e387e4c351ddda64e0058d567b90f4c73ccb3 (diff) |
Use sysctl to get information about encap routes (aka ipsec). Now
you see something actually useful...
requested by and ok henning@
Diffstat (limited to 'sbin/route/show.c')
-rw-r--r-- | sbin/route/show.c | 211 |
1 files changed, 209 insertions, 2 deletions
diff --git a/sbin/route/show.c b/sbin/route/show.c index 384c8b47e40..54d6bd6abdc 100644 --- a/sbin/route/show.c +++ b/sbin/route/show.c @@ -1,4 +1,4 @@ -/* $OpenBSD: show.c,v 1.45 2006/03/23 13:38:27 mcbride Exp $ */ +/* $OpenBSD: show.c,v 1.46 2006/03/29 20:21:45 hshoexer Exp $ */ /* $NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $ */ /* @@ -39,6 +39,7 @@ #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> +#include <net/pfkeyv2.h> #include <net/route.h> #include <netinet/in.h> #include <netipx/ipx.h> @@ -68,6 +69,8 @@ extern int nflag; ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) +#define PFKEYV2_CHUNK sizeof(u_int64_t) + /* * Definitions for showing gateway flags. */ @@ -99,12 +102,18 @@ static const struct bits bits[] = { void pr_rthdr(int, int); void p_rtentry(struct rt_msghdr *, int); +void p_pfkentry(struct sadb_msg *); void pr_family(int); +void p_encap(struct sockaddr *, struct sockaddr *, int); +void p_protocol(struct sadb_protocol *, struct sockaddr *, struct + sadb_protocol *, int); void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int); void p_flags(int, char *); char *routename4(in_addr_t); char *routename6(struct sockaddr_in6 *); char *any_ntoa(const struct sockaddr *); +void index_pfk(struct sadb_msg *, void **); + /* * Print routing tables. @@ -113,6 +122,7 @@ void p_rttables(int af, int Aflag) { struct rt_msghdr *rtm; + struct sadb_msg *msg; char *buf = NULL, *next, *lim = NULL; size_t needed; int mib[6]; @@ -145,6 +155,37 @@ p_rttables(int af, int Aflag) p_rtentry(rtm, Aflag); } free(buf); + buf = NULL; + } + + printf("\nEncap:\n"); + + mib[0] = CTL_NET; + mib[1] = PF_KEY; + mib[2] = PF_KEY_V2; + mib[3] = NET_KEY_SPD_DUMP; + mib[4] = mib[5] = 0; + + if (sysctl(mib, 4, NULL, &needed, NULL, 0) == -1) + err(1, "spd-sysctl-estimate"); + if (needed > 0) { + if ((buf = malloc(needed)) == 0) + err(1, NULL); + if (sysctl(mib, 4, buf, &needed, NULL, 0) == -1) + err(1,"sysctl of spd"); + lim = buf + needed; + } + + if (buf) { + for (next = buf; next < lim; next += msg->sadb_msg_len * + PFKEYV2_CHUNK) { + msg = (struct sadb_msg *)next; + if (msg->sadb_msg_len == 0) + break; + p_pfkentry(msg); + } + free(buf); + buf = NULL; } } @@ -201,6 +242,8 @@ p_rtentry(struct rt_msghdr *rtm, int Aflag) struct sockaddr *mask, *rti_info[RTAX_MAX]; char ifbuf[IF_NAMESIZE]; + if (sa->sa_family == AF_KEY) + return; if (old_af != sa->sa_family) { old_af = sa->sa_family; @@ -227,6 +270,48 @@ p_rtentry(struct rt_msghdr *rtm, int Aflag) } /* + * Print a pfkey/encap entry. + */ +void +p_pfkentry(struct sadb_msg *msg) +{ + static int old = 0; + struct sadb_ext *ext; + struct sadb_address *saddr; + struct sadb_protocol *sap, *saft; + struct sockaddr *sa, *mask; + void *headers[SADB_EXT_MAX + 1]; + + if (!old) { + pr_rthdr(PF_KEY, 0); + old++; + } + + bzero(headers, sizeof(headers)); + index_pfk(msg, headers); + + saddr = headers[SADB_X_EXT_SRC_FLOW]; + sa = (struct sockaddr *)(saddr + 1); + saddr = headers[SADB_X_EXT_SRC_MASK]; + mask = (struct sockaddr *)(saddr + 1); + p_encap(sa, mask, WID_DST(sa->sa_family)); + + saddr = headers[SADB_X_EXT_DST_FLOW]; + sa = (struct sockaddr *)(saddr + 1); + saddr = headers[SADB_X_EXT_DST_MASK]; + mask = (struct sockaddr *)(saddr + 1); + p_encap(sa, mask, WID_DST(sa->sa_family)); + + sap = headers[SADB_X_EXT_PROTOCOL]; + saft = headers[SADB_X_EXT_FLOW_TYPE]; + saddr = headers[SADB_EXT_ADDRESS_DST]; + sa = (struct sockaddr *)(saddr + 1); + p_protocol(sap, sa, saft, msg->sadb_msg_satype); + + printf("\n"); +} + +/* * Print address family header before a section of the routing table. */ void @@ -261,6 +346,87 @@ pr_family(int af) } void +p_encap(struct sockaddr *sa, struct sockaddr *mask, int width) +{ + char *cp; + unsigned short port; + + switch (sa->sa_family) { + case AF_INET6: { + break; + } + default: + if (mask) + cp = netname(sa, mask); + else + cp = routename(sa); + port = ntohs(((struct sockaddr_in *)sa)->sin_port); + break; + } + if (width < 0) + printf("%s", cp); + else { + if (nflag) + printf("%-*s %-5u ", width, cp, port); + else + printf("%-*.*s %-5u ", width, width, cp, port); + } +} + +void +p_protocol(struct sadb_protocol *sap, struct sockaddr *sa, struct sadb_protocol + *saft, int proto) +{ + printf("%-5u", sap->sadb_protocol_proto); + p_sockaddr(sa, NULL, 0, -1); + + switch (proto) { + case SADB_SATYPE_ESP: + printf("/esp"); + break; + case SADB_SATYPE_AH: + printf("/ah"); + break; + case SADB_X_SATYPE_IPCOMP: + printf("/ipcomp"); + break; + case SADB_X_SATYPE_IPIP: + printf("/ipip"); + break; + default: + printf("/<unknown>"); + } + + switch(saft->sadb_protocol_proto) { + case SADB_X_FLOW_TYPE_USE: + printf("/use"); + break; + case SADB_X_FLOW_TYPE_REQUIRE: + printf("/require"); + break; + case SADB_X_FLOW_TYPE_DENY: + printf("/deny"); + break; + case SADB_X_FLOW_TYPE_BYPASS: + printf("/bypass"); + break; + default: + printf("/<unknown type>"); + } + + switch(saft->sadb_protocol_direction) { + case IPSP_DIRECTION_IN: + printf("/in"); + break; + case IPSP_DIRECTION_OUT: + printf("/out"); + break; + default: + printf("/<unknown>"); + } +} + +void p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) { char *cp; @@ -296,7 +462,7 @@ p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) break; } if (width < 0) - printf("%s ", cp); + printf("%s", cp); else { if (nflag) printf("%-*s ", width, cp); @@ -685,3 +851,44 @@ link_print(struct sockaddr *sa) } return (link_ntoa(sdl)); } + +void +index_pfk(struct sadb_msg *msg, void **headers) +{ + struct sadb_ext *ext; + + for (ext = (struct sadb_ext *)(msg + 1); + (size_t)((u_int8_t *)ext - (u_int8_t *)msg) < + msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0; + ext = (struct sadb_ext *)((u_int8_t *)ext + + ext->sadb_ext_len * PFKEYV2_CHUNK)) { + switch (ext->sadb_ext_type) { + case SADB_EXT_ADDRESS_SRC: + headers[SADB_EXT_ADDRESS_SRC] = (void *)ext; + break; + case SADB_EXT_ADDRESS_DST: + headers[SADB_EXT_ADDRESS_DST] = (void *)ext; + break; + case SADB_X_EXT_PROTOCOL: + headers[SADB_X_EXT_PROTOCOL] = (void *)ext; + break; + case SADB_X_EXT_SRC_FLOW: + headers[SADB_X_EXT_SRC_FLOW] = (void *)ext; + break; + case SADB_X_EXT_DST_FLOW: + headers[SADB_X_EXT_DST_FLOW] = (void *)ext; + break; + case SADB_X_EXT_SRC_MASK: + headers[SADB_X_EXT_SRC_MASK] = (void *)ext; + break; + case SADB_X_EXT_DST_MASK: + headers[SADB_X_EXT_DST_MASK] = (void *)ext; + break; + case SADB_X_EXT_FLOW_TYPE: + headers[SADB_X_EXT_FLOW_TYPE] = (void *)ext; + default: + /* Ignore. */ + break; + } + } +} |