X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ip%2Fxfrm_monitor.c;fp=ip%2Fxfrm_monitor.c;h=153621f741593a02437e942c45ffa9285436ac2f;hb=fcabec0aee42af28e2846ef3674ed7ba7be72c42;hp=0000000000000000000000000000000000000000;hpb=cb820e861caa85bb3942ab0c673e04b9408be0ad;p=iproute2.git diff --git a/ip/xfrm_monitor.c b/ip/xfrm_monitor.c new file mode 100644 index 0000000..153621f --- /dev/null +++ b/ip/xfrm_monitor.c @@ -0,0 +1,218 @@ +/* $USAGI: $ */ + +/* + * Copyright (C)2005 USAGI/WIDE Project + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * based on ipmonitor.c + */ +/* + * Authors: + * Masahide NAKAMURA @USAGI + */ + +#include +#include +#include +#include +#include "utils.h" +#include "xfrm.h" +#include "ip_common.h" + +static void usage(void) __attribute__((noreturn)); + +static void usage(void) +{ + fprintf(stderr, "Usage: ip xfrm monitor [ all | LISTofOBJECTS ]\n"); + exit(-1); +} + +static int xfrm_acquire_print(const struct sockaddr_nl *who, + struct nlmsghdr *n, void *arg) +{ + FILE *fp = (FILE*)arg; + struct xfrm_user_acquire *xacq = NLMSG_DATA(n); + int len = n->nlmsg_len; + struct rtattr * tb[XFRMA_MAX+1]; + __u16 family; + + if (n->nlmsg_type != XFRM_MSG_ACQUIRE) { + fprintf(stderr, "Not an acquire: %08x %08x %08x\n", + n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); + return 0; + } + + len -= NLMSG_LENGTH(sizeof(*xacq)); + if (len < 0) { + fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); + return -1; + } + + parse_rtattr(tb, XFRMA_MAX, XFRMACQ_RTA(xacq), len); + + family = xacq->sel.family; + if (family == AF_UNSPEC) + family = xacq->policy.sel.family; + if (family == AF_UNSPEC) + family = preferred_family; + + fprintf(fp, "acquire "); + + fprintf(fp, "proto %s ", strxf_xfrmproto(xacq->id.proto)); + if (show_stats > 0 || xacq->id.spi) { + __u32 spi = ntohl(xacq->id.spi); + fprintf(fp, "spi 0x%08x", spi); + if (show_stats > 0) + fprintf(fp, "(%u)", spi); + fprintf(fp, " "); + } + fprintf(fp, "%s", _SL_); + + xfrm_selector_print(&xacq->sel, family, fp, " sel "); + + xfrm_policy_info_print(&xacq->policy, tb, fp, " ", " policy "); + + if (show_stats > 0) + fprintf(fp, " seq 0x%08u ", xacq->seq); + if (show_stats > 0) { + fprintf(fp, "%s-mask %s ", + strxf_algotype(XFRMA_ALG_CRYPT), + strxf_mask32(xacq->ealgos)); + fprintf(fp, "%s-mask %s ", + strxf_algotype(XFRMA_ALG_AUTH), + strxf_mask32(xacq->aalgos)); + fprintf(fp, "%s-mask %s", + strxf_algotype(XFRMA_ALG_COMP), + strxf_mask32(xacq->calgos)); + } + fprintf(fp, "%s", _SL_); + + if (oneline) + fprintf(fp, "\n"); + fflush(fp); + + return 0; +} + +static int xfrm_accept_msg(const struct sockaddr_nl *who, + struct nlmsghdr *n, void *arg) +{ + FILE *fp = (FILE*)arg; + + if (timestamp) + print_timestamp(fp); + + if (n->nlmsg_type == XFRM_MSG_NEWSA || + n->nlmsg_type == XFRM_MSG_DELSA || + n->nlmsg_type == XFRM_MSG_UPDSA || + n->nlmsg_type == XFRM_MSG_EXPIRE) { + xfrm_state_print(who, n, arg); + return 0; + } + if (n->nlmsg_type == XFRM_MSG_NEWPOLICY || + n->nlmsg_type == XFRM_MSG_DELPOLICY || + n->nlmsg_type == XFRM_MSG_UPDPOLICY || + n->nlmsg_type == XFRM_MSG_POLEXPIRE) { + xfrm_policy_print(who, n, arg); + return 0; + } + + if (n->nlmsg_type == XFRM_MSG_ACQUIRE) { + xfrm_acquire_print(who, n, arg); + return 0; + } + if (n->nlmsg_type == XFRM_MSG_FLUSHSA) { + /* XXX: Todo: show proto in xfrm_usersa_flush */ + fprintf(fp, "Flushed state\n"); + return 0; + } + if (n->nlmsg_type == XFRM_MSG_FLUSHPOLICY) { + fprintf(fp, "Flushed policy\n"); + return 0; + } + if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && + n->nlmsg_type != NLMSG_DONE) { + fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n", + n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); + } + return 0; +} + +int do_xfrm_monitor(int argc, char **argv) +{ + struct rtnl_handle rth; + char *file = NULL; + unsigned groups = ~((unsigned)0); /* XXX */ + int lacquire=0; + int lexpire=0; + int lpolicy=0; + int lsa=0; + + while (argc > 0) { + if (matches(*argv, "file") == 0) { + NEXT_ARG(); + file = *argv; + } else if (matches(*argv, "acquire") == 0) { + lacquire=1; + groups = 0; + } else if (matches(*argv, "expire") == 0) { + lexpire=1; + groups = 0; + } else if (matches(*argv, "SA") == 0) { + lsa=1; + groups = 0; + } else if (matches(*argv, "policy") == 0) { + lpolicy=1; + groups = 0; + } else if (matches(*argv, "help") == 0) { + usage(); + } else { + fprintf(stderr, "Argument \"%s\" is unknown, try \"ip xfrm monitor help\".\n", *argv); + exit(-1); + } + argc--; argv++; + } + + if (lacquire) + groups |= XFRMGRP_ACQUIRE; + if (lexpire) + groups |= XFRMGRP_EXPIRE; + if (lsa) + groups |= XFRMGRP_SA; + if (lpolicy) + groups |= XFRMGRP_POLICY; + + if (file) { + FILE *fp; + fp = fopen(file, "r"); + if (fp == NULL) { + perror("Cannot fopen"); + exit(-1); + } + return rtnl_from_file(fp, xfrm_accept_msg, (void*)stdout); + } + + //ll_init_map(&rth); + + if (rtnl_open_byproto(&rth, groups, NETLINK_XFRM) < 0) + exit(1); + + if (rtnl_listen(&rth, xfrm_accept_msg, (void*)stdout) < 0) + exit(2); + + return 0; +}