]> git.proxmox.com Git - mirror_iproute2.git/blame - ip/xfrm_monitor.c
devlink: Introduce and use string to number mapper
[mirror_iproute2.git] / ip / xfrm_monitor.c
CommitLineData
f9cb3a2f 1/* $USAGI: $ */
2
3/*
4 * Copyright (C)2005 USAGI/WIDE Project
ae665a52 5 *
f9cb3a2f 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
ae665a52 10 *
f9cb3a2f 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
ae665a52 15 *
f9cb3a2f 16 * You should have received a copy of the GNU General Public License
4d98ab00 17 * along with this program; if not, see <http://www.gnu.org/licenses>.
f9cb3a2f 18 */
19/*
20 * based on ipmonitor.c
21 */
22/*
23 * Authors:
24 * Masahide NAKAMURA @USAGI
25 */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
93390779 30#include <netinet/in.h>
93390779 31
f9cb3a2f 32#include "utils.h"
33#include "xfrm.h"
34#include "ip_common.h"
35
36static void usage(void) __attribute__((noreturn));
fa92d8cb 37static int listen_all_nsid;
a6af9f2e 38static bool nokeys;
f9cb3a2f 39
40static void usage(void)
41{
8589eb4e
MC
42 fprintf(stderr,
43 "Usage: ip xfrm monitor [ nokeys ] [ all-nsid ] [ all | OBJECTS | help ]\n"
44 "OBJECTS := { acquire | expire | SA | aevent | policy | report }\n");
f9cb3a2f 45 exit(-1);
46}
47
cd554f2c 48static int xfrm_acquire_print(struct nlmsghdr *n, void *arg)
f9cb3a2f 49{
56f5daac 50 FILE *fp = (FILE *)arg;
f9cb3a2f 51 struct xfrm_user_acquire *xacq = NLMSG_DATA(n);
52 int len = n->nlmsg_len;
56f5daac 53 struct rtattr *tb[XFRMA_MAX+1];
f9cb3a2f 54 __u16 family;
55
f9cb3a2f 56 len -= NLMSG_LENGTH(sizeof(*xacq));
57 if (len < 0) {
58 fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
59 return -1;
60 }
61
62 parse_rtattr(tb, XFRMA_MAX, XFRMACQ_RTA(xacq), len);
90f93024 63
f9cb3a2f 64 family = xacq->sel.family;
65 if (family == AF_UNSPEC)
66 family = xacq->policy.sel.family;
67 if (family == AF_UNSPEC)
68 family = preferred_family;
69
70 fprintf(fp, "acquire ");
71
72 fprintf(fp, "proto %s ", strxf_xfrmproto(xacq->id.proto));
73 if (show_stats > 0 || xacq->id.spi) {
74 __u32 spi = ntohl(xacq->id.spi);
56f5daac 75
f9cb3a2f 76 fprintf(fp, "spi 0x%08x", spi);
77 if (show_stats > 0)
78 fprintf(fp, "(%u)", spi);
79 fprintf(fp, " ");
80 }
81 fprintf(fp, "%s", _SL_);
82
83 xfrm_selector_print(&xacq->sel, family, fp, " sel ");
84
85 xfrm_policy_info_print(&xacq->policy, tb, fp, " ", " policy ");
86
87 if (show_stats > 0)
88 fprintf(fp, " seq 0x%08u ", xacq->seq);
89 if (show_stats > 0) {
90 fprintf(fp, "%s-mask %s ",
91 strxf_algotype(XFRMA_ALG_CRYPT),
92 strxf_mask32(xacq->ealgos));
93 fprintf(fp, "%s-mask %s ",
94 strxf_algotype(XFRMA_ALG_AUTH),
95 strxf_mask32(xacq->aalgos));
96 fprintf(fp, "%s-mask %s",
97 strxf_algotype(XFRMA_ALG_COMP),
98 strxf_mask32(xacq->calgos));
99 }
100 fprintf(fp, "%s", _SL_);
101
102 if (oneline)
103 fprintf(fp, "\n");
669ae748 104 fflush(fp);
f9cb3a2f 105
106 return 0;
107}
108
cd554f2c 109static int xfrm_state_flush_print(struct nlmsghdr *n, void *arg)
efe69c1b 110{
56f5daac 111 FILE *fp = (FILE *)arg;
efe69c1b
MN
112 struct xfrm_usersa_flush *xsf = NLMSG_DATA(n);
113 int len = n->nlmsg_len;
114 const char *str;
115
116 len -= NLMSG_SPACE(sizeof(*xsf));
117 if (len < 0) {
118 fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
119 return -1;
120 }
121
122 fprintf(fp, "Flushed state ");
123
124 str = strxf_xfrmproto(xsf->proto);
125 if (str)
126 fprintf(fp, "proto %s", str);
127 else
128 fprintf(fp, "proto %u", xsf->proto);
129 fprintf(fp, "%s", _SL_);
130
131 if (oneline)
132 fprintf(fp, "\n");
133 fflush(fp);
134
135 return 0;
136}
137
cd554f2c 138static int xfrm_policy_flush_print(struct nlmsghdr *n, void *arg)
efe69c1b 139{
56f5daac
SH
140 struct rtattr *tb[XFRMA_MAX+1];
141 FILE *fp = (FILE *)arg;
efe69c1b
MN
142 int len = n->nlmsg_len;
143
144 len -= NLMSG_SPACE(0);
145 if (len < 0) {
146 fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
147 return -1;
148 }
149
150 fprintf(fp, "Flushed policy ");
151
152 parse_rtattr(tb, XFRMA_MAX, NLMSG_DATA(n), len);
153
154 if (tb[XFRMA_POLICY_TYPE]) {
155 struct xfrm_userpolicy_type *upt;
156
157 fprintf(fp, "ptype ");
158
159 if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt))
160 fprintf(fp, "(ERROR truncated)");
161
9f1370c0 162 upt = RTA_DATA(tb[XFRMA_POLICY_TYPE]);
efe69c1b
MN
163 fprintf(fp, "%s ", strxf_ptype(upt->type));
164 }
165
166 fprintf(fp, "%s", _SL_);
167
168 if (oneline)
169 fprintf(fp, "\n");
170 fflush(fp);
171
172 return 0;
173}
174
cd554f2c 175static int xfrm_report_print(struct nlmsghdr *n, void *arg)
c54f31ee 176{
56f5daac 177 FILE *fp = (FILE *)arg;
c54f31ee
MN
178 struct xfrm_user_report *xrep = NLMSG_DATA(n);
179 int len = n->nlmsg_len;
56f5daac 180 struct rtattr *tb[XFRMA_MAX+1];
c54f31ee
MN
181 __u16 family;
182
c54f31ee
MN
183 len -= NLMSG_LENGTH(sizeof(*xrep));
184 if (len < 0) {
185 fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
186 return -1;
187 }
188
189 family = xrep->sel.family;
190 if (family == AF_UNSPEC)
191 family = preferred_family;
192
193 fprintf(fp, "report ");
194
195 fprintf(fp, "proto %s ", strxf_xfrmproto(xrep->proto));
196 fprintf(fp, "%s", _SL_);
197
198 xfrm_selector_print(&xrep->sel, family, fp, " sel ");
199
200 parse_rtattr(tb, XFRMA_MAX, XFRMREP_RTA(xrep), len);
201
a6af9f2e 202 xfrm_xfrma_print(tb, family, fp, " ", nokeys);
c54f31ee
MN
203
204 if (oneline)
205 fprintf(fp, "\n");
206
207 return 0;
208}
209
d1f28cf1 210static void xfrm_ae_flags_print(__u32 flags, void *arg)
c9fd974b 211{
56f5daac
SH
212 FILE *fp = (FILE *)arg;
213
c9fd974b 214 fprintf(fp, " (0x%x) ", flags);
215 if (!flags)
216 return;
217 if (flags & XFRM_AE_CR)
218 fprintf(fp, " replay update ");
219 if (flags & XFRM_AE_CE)
220 fprintf(fp, " timer expired ");
221 if (flags & XFRM_AE_CU)
222 fprintf(fp, " policy updated ");
223
224}
225
598a42c0
FW
226static void xfrm_usersa_print(const struct xfrm_usersa_id *sa_id, __u32 reqid, FILE *fp)
227{
656111b2 228 fprintf(fp, "dst %s ",
2e96d2cc 229 rt_addr_n2a(sa_id->family, sizeof(sa_id->daddr), &sa_id->daddr));
598a42c0
FW
230
231 fprintf(fp, " reqid 0x%x", reqid);
232
233 fprintf(fp, " protocol %s ", strxf_proto(sa_id->proto));
234 fprintf(fp, " SPI 0x%x", ntohl(sa_id->spi));
235}
236
cd554f2c 237static int xfrm_ae_print(struct nlmsghdr *n, void *arg)
c9fd974b 238{
56f5daac 239 FILE *fp = (FILE *)arg;
c9fd974b 240 struct xfrm_aevent_id *id = NLMSG_DATA(n);
c9fd974b 241
242 fprintf(fp, "Async event ");
243 xfrm_ae_flags_print(id->flags, arg);
56f5daac 244 fprintf(fp, "\n\t");
26dcdf3a 245 fprintf(fp, "src %s ", rt_addr_n2a(id->sa_id.family,
2e96d2cc 246 sizeof(id->saddr), &id->saddr));
598a42c0
FW
247
248 xfrm_usersa_print(&id->sa_id, id->reqid, fp);
c9fd974b 249
250 fprintf(fp, "\n");
251 fflush(fp);
252
253 return 0;
254}
255
656111b2 256static void xfrm_print_addr(FILE *fp, int family, xfrm_address_t *a)
598a42c0 257{
2e96d2cc 258 fprintf(fp, "%s", rt_addr_n2a(family, sizeof(*a), a));
598a42c0
FW
259}
260
cd554f2c 261static int xfrm_mapping_print(struct nlmsghdr *n, void *arg)
598a42c0 262{
56f5daac 263 FILE *fp = (FILE *)arg;
598a42c0
FW
264 struct xfrm_user_mapping *map = NLMSG_DATA(n);
265
266 fprintf(fp, "Mapping change ");
656111b2 267 xfrm_print_addr(fp, map->id.family, &map->old_saddr);
598a42c0
FW
268
269 fprintf(fp, ":%d -> ", ntohs(map->old_sport));
656111b2 270 xfrm_print_addr(fp, map->id.family, &map->new_saddr);
598a42c0
FW
271 fprintf(fp, ":%d\n\t", ntohs(map->new_sport));
272
273 xfrm_usersa_print(&map->id, map->reqid, fp);
274
275 fprintf(fp, "\n");
276 fflush(fp);
277 return 0;
278}
279
cd554f2c 280static int xfrm_accept_msg(struct rtnl_ctrl_data *ctrl,
f9cb3a2f 281 struct nlmsghdr *n, void *arg)
282{
56f5daac 283 FILE *fp = (FILE *)arg;
f9cb3a2f 284
90f93024
SH
285 if (timestamp)
286 print_timestamp(fp);
287
b6ec53e3
ND
288 if (listen_all_nsid) {
289 if (ctrl == NULL || ctrl->nsid < 0)
290 fprintf(fp, "[nsid current]");
291 else
292 fprintf(fp, "[nsid %d]", ctrl->nsid);
293 }
294
efe69c1b
MN
295 switch (n->nlmsg_type) {
296 case XFRM_MSG_NEWSA:
297 case XFRM_MSG_DELSA:
298 case XFRM_MSG_UPDSA:
299 case XFRM_MSG_EXPIRE:
cd554f2c 300 xfrm_state_print(n, arg);
c595c790 301 return 0;
efe69c1b
MN
302 case XFRM_MSG_NEWPOLICY:
303 case XFRM_MSG_DELPOLICY:
304 case XFRM_MSG_UPDPOLICY:
305 case XFRM_MSG_POLEXPIRE:
cd554f2c 306 xfrm_policy_print(n, arg);
c595c790 307 return 0;
efe69c1b 308 case XFRM_MSG_ACQUIRE:
cd554f2c 309 xfrm_acquire_print(n, arg);
f9cb3a2f 310 return 0;
efe69c1b 311 case XFRM_MSG_FLUSHSA:
cd554f2c 312 xfrm_state_flush_print(n, arg);
f9cb3a2f 313 return 0;
efe69c1b 314 case XFRM_MSG_FLUSHPOLICY:
cd554f2c 315 xfrm_policy_flush_print(n, arg);
f9cb3a2f 316 return 0;
efe69c1b 317 case XFRM_MSG_REPORT:
cd554f2c 318 xfrm_report_print(n, arg);
c54f31ee 319 return 0;
efe69c1b 320 case XFRM_MSG_NEWAE:
cd554f2c 321 xfrm_ae_print(n, arg);
c9fd974b 322 return 0;
598a42c0 323 case XFRM_MSG_MAPPING:
cd554f2c 324 xfrm_mapping_print(n, arg);
598a42c0 325 return 0;
efe69c1b
MN
326 default:
327 break;
c9fd974b 328 }
efe69c1b 329
f9cb3a2f 330 if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
331 n->nlmsg_type != NLMSG_DONE) {
c595c790 332 fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n",
f9cb3a2f 333 n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
334 }
335 return 0;
336}
337
77219712
SH
338extern struct rtnl_handle rth;
339
f9cb3a2f 340int do_xfrm_monitor(int argc, char **argv)
341{
f9cb3a2f 342 char *file = NULL;
56f5daac
SH
343 unsigned int groups = ~((unsigned)0); /* XXX */
344 int lacquire = 0;
345 int lexpire = 0;
346 int laevent = 0;
347 int lpolicy = 0;
348 int lsa = 0;
349 int lreport = 0;
f9cb3a2f 350
77219712
SH
351 rtnl_close(&rth);
352
f9cb3a2f 353 while (argc > 0) {
354 if (matches(*argv, "file") == 0) {
355 NEXT_ARG();
356 file = *argv;
a6af9f2e
BW
357 } else if (strcmp(*argv, "nokeys") == 0) {
358 nokeys = true;
b8e77990
NH
359 } else if (strcmp(*argv, "all") == 0) {
360 /* fall out */
b6ec53e3
ND
361 } else if (matches(*argv, "all-nsid") == 0) {
362 listen_all_nsid = 1;
f9cb3a2f 363 } else if (matches(*argv, "acquire") == 0) {
56f5daac 364 lacquire = 1;
f9cb3a2f 365 groups = 0;
366 } else if (matches(*argv, "expire") == 0) {
56f5daac 367 lexpire = 1;
f9cb3a2f 368 groups = 0;
c595c790 369 } else if (matches(*argv, "SA") == 0) {
56f5daac 370 lsa = 1;
c595c790 371 groups = 0;
c9fd974b 372 } else if (matches(*argv, "aevent") == 0) {
56f5daac 373 laevent = 1;
c9fd974b 374 groups = 0;
c595c790 375 } else if (matches(*argv, "policy") == 0) {
56f5daac 376 lpolicy = 1;
c595c790 377 groups = 0;
c54f31ee 378 } else if (matches(*argv, "report") == 0) {
56f5daac 379 lreport = 1;
c54f31ee 380 groups = 0;
f9cb3a2f 381 } else if (matches(*argv, "help") == 0) {
382 usage();
b8e77990 383 } else {
f9cb3a2f 384 fprintf(stderr, "Argument \"%s\" is unknown, try \"ip xfrm monitor help\".\n", *argv);
385 exit(-1);
386 }
387 argc--; argv++;
388 }
389
390 if (lacquire)
7b822512 391 groups |= nl_mgrp(XFRMNLGRP_ACQUIRE);
f9cb3a2f 392 if (lexpire)
7b822512 393 groups |= nl_mgrp(XFRMNLGRP_EXPIRE);
c595c790 394 if (lsa)
7b822512 395 groups |= nl_mgrp(XFRMNLGRP_SA);
c595c790 396 if (lpolicy)
7b822512 397 groups |= nl_mgrp(XFRMNLGRP_POLICY);
c9fd974b 398 if (laevent)
7b822512 399 groups |= nl_mgrp(XFRMNLGRP_AEVENTS);
c54f31ee 400 if (lreport)
7b822512 401 groups |= nl_mgrp(XFRMNLGRP_REPORT);
f9cb3a2f 402
403 if (file) {
404 FILE *fp;
e49b51d6
SH
405 int err;
406
f9cb3a2f 407 fp = fopen(file, "r");
408 if (fp == NULL) {
409 perror("Cannot fopen");
410 exit(-1);
411 }
e49b51d6
SH
412 err = rtnl_from_file(fp, xfrm_accept_msg, stdout);
413 fclose(fp);
414 return err;
f9cb3a2f 415 }
416
c595c790
SH
417 if (rtnl_open_byproto(&rth, groups, NETLINK_XFRM) < 0)
418 exit(1);
b6ec53e3
ND
419 if (listen_all_nsid && rtnl_listen_all_nsid(&rth) < 0)
420 exit(1);
c595c790 421
56f5daac 422 if (rtnl_listen(&rth, xfrm_accept_msg, (void *)stdout) < 0)
f9cb3a2f 423 exit(2);
424
351efcde 425 return 0;
f9cb3a2f 426}