(Logical change 1.175)
This commit is contained in:
parent
bf82c4c0d3
commit
f9cb3a2fe2
|
|
@ -0,0 +1,266 @@
|
|||
/* $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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <linux/xfrm.h>
|
||||
#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");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xfrm_state_expire_print(const struct sockaddr_nl *who,
|
||||
struct nlmsghdr *n, void *arg)
|
||||
{
|
||||
FILE *fp = (FILE*)arg;
|
||||
struct xfrm_user_expire *xexp = NLMSG_DATA(n);
|
||||
int len = n->nlmsg_len;
|
||||
struct rtattr * tb[XFRMA_MAX+1];
|
||||
|
||||
if (n->nlmsg_type != XFRM_MSG_EXPIRE) {
|
||||
fprintf(stderr, "Not an expire: %08x %08x %08x\n",
|
||||
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len -= NLMSG_LENGTH(sizeof(*xexp));
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
parse_rtattr(tb, XFRMA_MAX, XFRMEXP_RTA(xexp), len);
|
||||
|
||||
fprintf(fp, "Expired ");
|
||||
|
||||
xfrm_state_info_print(&xexp->state, tb, fp, NULL, NULL);
|
||||
|
||||
fprintf(fp, "\t");
|
||||
fprintf(fp, "hard %u", xexp->hard);
|
||||
fprintf(fp, "%s", _SL_);
|
||||
|
||||
if (oneline)
|
||||
fprintf(fp, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xfrm_policy_expire_print(const struct sockaddr_nl *who,
|
||||
struct nlmsghdr *n, void *arg)
|
||||
{
|
||||
FILE *fp = (FILE*)arg;
|
||||
struct xfrm_user_polexpire *xpexp = NLMSG_DATA(n);
|
||||
int len = n->nlmsg_len;
|
||||
struct rtattr * tb[XFRMA_MAX+1];
|
||||
|
||||
if (n->nlmsg_type != XFRM_MSG_POLEXPIRE) {
|
||||
fprintf(stderr, "Not a polexpire: %08x %08x %08x\n",
|
||||
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len -= NLMSG_LENGTH(sizeof(*xpexp));
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
parse_rtattr(tb, XFRMA_MAX, XFRMPEXP_RTA(xpexp), len);
|
||||
|
||||
fprintf(fp, "Expired ");
|
||||
xfrm_policy_info_print(&xpexp->pol, tb, fp, NULL, NULL);
|
||||
|
||||
fprintf(fp, "\t");
|
||||
fprintf(fp, "hard %u", xpexp->hard);
|
||||
fprintf(fp, "%s", _SL_);
|
||||
|
||||
if (oneline)
|
||||
fprintf(fp, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xfrm_accept_msg(const struct sockaddr_nl *who,
|
||||
struct nlmsghdr *n, void *arg)
|
||||
{
|
||||
FILE *fp = (FILE*)arg;
|
||||
|
||||
if (n->nlmsg_type == XFRM_MSG_ACQUIRE) {
|
||||
xfrm_acquire_print(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == XFRM_MSG_EXPIRE) {
|
||||
xfrm_state_expire_print(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
|
||||
xfrm_policy_expire_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: %08x %08x %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;
|
||||
|
||||
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, "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 (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);
|
||||
}
|
||||
|
||||
if (rtnl_open_byproto(&rth, groups, NETLINK_XFRM) < 0)
|
||||
exit(1);
|
||||
|
||||
//ll_init_map(&rth);
|
||||
|
||||
if (rtnl_listen(&rth, xfrm_accept_msg, (void*)stdout) < 0)
|
||||
exit(2);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
Loading…
Reference in New Issue