ipxfrm.c revision dcb283c300299d79a37fd386ea854b156fd503c5
1/* $USAGI: $ */ 2 3/* 4 * Copyright (C)2004 USAGI/WIDE Project 5 * 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. 10 * 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. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20/* 21 * based on ip.c, iproute.c 22 */ 23/* 24 * Authors: 25 * Masahide NAKAMURA @USAGI 26 */ 27 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31#include <sys/types.h> 32#include <sys/socket.h> 33#include <time.h> 34#include <netdb.h> 35#include <linux/netlink.h> 36#include <linux/rtnetlink.h> 37#include <linux/xfrm.h> 38 39#include "utils.h" 40#include "xfrm.h" 41 42#define STRBUF_SIZE (128) 43#define STRBUF_CAT(buf, str) \ 44 do { \ 45 int rest = sizeof(buf) - 1 - strlen(buf); \ 46 if (rest > 0) { \ 47 int len = strlen(str); \ 48 if (len > rest) \ 49 len = rest; \ 50 strncat(buf, str, len); \ 51 buf[sizeof(buf) - 1] = '\0'; \ 52 } \ 53 } while(0); 54 55struct xfrm_filter filter; 56 57static void usage(void) __attribute__((noreturn)); 58 59static void usage(void) 60{ 61 fprintf(stderr, 62 "Usage: ip xfrm XFRM_OBJECT { COMMAND | help }\n" 63 "where XFRM_OBJECT := { state | policy | monitor }\n"); 64 exit(-1); 65} 66 67/* This is based on utils.c(inet_addr_match) */ 68int xfrm_addr_match(xfrm_address_t *x1, xfrm_address_t *x2, int bits) 69{ 70 __u32 *a1 = (__u32 *)x1; 71 __u32 *a2 = (__u32 *)x2; 72 int words = bits >> 0x05; 73 74 bits &= 0x1f; 75 76 if (words) 77 if (memcmp(a1, a2, words << 2)) 78 return -1; 79 80 if (bits) { 81 __u32 w1, w2; 82 __u32 mask; 83 84 w1 = a1[words]; 85 w2 = a2[words]; 86 87 mask = htonl((0xffffffff) << (0x20 - bits)); 88 89 if ((w1 ^ w2) & mask) 90 return 1; 91 } 92 93 return 0; 94} 95 96int xfrm_xfrmproto_is_ipsec(__u8 proto) 97{ 98 return (proto == IPPROTO_ESP || 99 proto == IPPROTO_AH || 100 proto == IPPROTO_COMP); 101} 102 103int xfrm_xfrmproto_is_ro(__u8 proto) 104{ 105 return (proto == IPPROTO_ROUTING || 106 proto == IPPROTO_DSTOPTS); 107} 108 109struct typeent { 110 const char *t_name; 111 int t_type; 112}; 113 114static const struct typeent xfrmproto_types[]= { 115 { "esp", IPPROTO_ESP }, { "ah", IPPROTO_AH }, { "comp", IPPROTO_COMP }, 116 { "route2", IPPROTO_ROUTING }, { "hao", IPPROTO_DSTOPTS }, 117 { NULL, -1 } 118}; 119 120int xfrm_xfrmproto_getbyname(char *name) 121{ 122 int i; 123 124 for (i = 0; ; i++) { 125 const struct typeent *t = &xfrmproto_types[i]; 126 if (!t->t_name || t->t_type == -1) 127 break; 128 129 if (strcmp(t->t_name, name) == 0) 130 return t->t_type; 131 } 132 133 return -1; 134} 135 136const char *strxf_xfrmproto(__u8 proto) 137{ 138 int i; 139 140 for (i = 0; ; i++) { 141 const struct typeent *t = &xfrmproto_types[i]; 142 if (!t->t_name || t->t_type == -1) 143 break; 144 145 if (t->t_type == proto) 146 return t->t_name; 147 } 148 149 return NULL; 150} 151 152static const struct typeent algo_types[]= { 153 { "enc", XFRMA_ALG_CRYPT }, { "auth", XFRMA_ALG_AUTH }, 154 { "comp", XFRMA_ALG_COMP }, { NULL, -1 } 155}; 156 157int xfrm_algotype_getbyname(char *name) 158{ 159 int i; 160 161 for (i = 0; ; i++) { 162 const struct typeent *t = &algo_types[i]; 163 if (!t->t_name || t->t_type == -1) 164 break; 165 166 if (strcmp(t->t_name, name) == 0) 167 return t->t_type; 168 } 169 170 return -1; 171} 172 173const char *strxf_algotype(int type) 174{ 175 int i; 176 177 for (i = 0; ; i++) { 178 const struct typeent *t = &algo_types[i]; 179 if (!t->t_name || t->t_type == -1) 180 break; 181 182 if (t->t_type == type) 183 return t->t_name; 184 } 185 186 return NULL; 187} 188 189const char *strxf_mask8(__u8 mask) 190{ 191 static char str[16]; 192 const int sn = sizeof(mask) * 8 - 1; 193 __u8 b; 194 int i = 0; 195 196 for (b = (1 << sn); b > 0; b >>= 1) 197 str[i++] = ((b & mask) ? '1' : '0'); 198 str[i] = '\0'; 199 200 return str; 201} 202 203const char *strxf_mask32(__u32 mask) 204{ 205 static char str[16]; 206 207 sprintf(str, "%.8x", mask); 208 209 return str; 210} 211 212const char *strxf_share(__u8 share) 213{ 214 static char str[32]; 215 216 switch (share) { 217 case XFRM_SHARE_ANY: 218 strcpy(str, "any"); 219 break; 220 case XFRM_SHARE_SESSION: 221 strcpy(str, "session"); 222 break; 223 case XFRM_SHARE_USER: 224 strcpy(str, "user"); 225 break; 226 case XFRM_SHARE_UNIQUE: 227 strcpy(str, "unique"); 228 break; 229 default: 230 sprintf(str, "%u", share); 231 break; 232 } 233 234 return str; 235} 236 237const char *strxf_proto(__u8 proto) 238{ 239 static char buf[32]; 240 struct protoent *pp; 241 const char *p; 242 243 pp = getprotobynumber(proto); 244 if (pp) 245 p = pp->p_name; 246 else { 247 sprintf(buf, "%u", proto); 248 p = buf; 249 } 250 251 return p; 252} 253 254void xfrm_id_info_print(xfrm_address_t *saddr, struct xfrm_id *id, 255 __u8 mode, __u32 reqid, __u16 family, int force_spi, 256 FILE *fp, const char *prefix, const char *title) 257{ 258 char abuf[256]; 259 260 if (title) 261 fprintf(fp, title); 262 263 memset(abuf, '\0', sizeof(abuf)); 264 fprintf(fp, "src %s ", rt_addr_n2a(family, sizeof(*saddr), 265 saddr, abuf, sizeof(abuf))); 266 memset(abuf, '\0', sizeof(abuf)); 267 fprintf(fp, "dst %s", rt_addr_n2a(family, sizeof(id->daddr), 268 &id->daddr, abuf, sizeof(abuf))); 269 fprintf(fp, "%s", _SL_); 270 271 if (prefix) 272 fprintf(fp, prefix); 273 fprintf(fp, "\t"); 274 275 fprintf(fp, "proto %s ", strxf_xfrmproto(id->proto)); 276 277 if (show_stats > 0 || force_spi || id->spi) { 278 __u32 spi = ntohl(id->spi); 279 fprintf(fp, "spi 0x%08x", spi); 280 if (show_stats > 0) 281 fprintf(fp, "(%u)", spi); 282 fprintf(fp, " "); 283 } 284 285 fprintf(fp, "reqid %u", reqid); 286 if (show_stats > 0) 287 fprintf(fp, "(0x%08x)", reqid); 288 fprintf(fp, " "); 289 290 fprintf(fp, "mode "); 291 switch (mode) { 292 case XFRM_MODE_TRANSPORT: 293 fprintf(fp, "transport"); 294 break; 295 case XFRM_MODE_TUNNEL: 296 fprintf(fp, "tunnel"); 297 break; 298 case XFRM_MODE_ROUTEOPTIMIZATION: 299 fprintf(fp, "ro"); 300 break; 301 case XFRM_MODE_IN_TRIGGER: 302 fprintf(fp, "in_trigger"); 303 break; 304 case XFRM_MODE_BEET: 305 fprintf(fp, "beet"); 306 break; 307 default: 308 fprintf(fp, "%u", mode); 309 break; 310 } 311 fprintf(fp, "%s", _SL_); 312} 313 314static const char *strxf_limit(__u64 limit) 315{ 316 static char str[32]; 317 if (limit == XFRM_INF) 318 strcpy(str, "(INF)"); 319 else 320 sprintf(str, "%llu", (unsigned long long) limit); 321 322 return str; 323} 324 325void xfrm_stats_print(struct xfrm_stats *s, FILE *fp, const char *prefix) 326{ 327 if (prefix) 328 fprintf(fp, prefix); 329 fprintf(fp, "stats:"); 330 fprintf(fp, "%s", _SL_); 331 332 if (prefix) 333 fprintf(fp, prefix); 334 fprintf(fp, " "); 335 fprintf(fp, "replay-window %u ", s->replay_window); 336 fprintf(fp, "replay %u ", s->replay); 337 fprintf(fp, "failed %u", s->integrity_failed); 338 fprintf(fp, "%s", _SL_); 339} 340 341static const char *strxf_time(__u64 time) 342{ 343 static char str[32]; 344 345 if (time == 0) 346 strcpy(str, "-"); 347 else { 348 time_t t; 349 struct tm *tp; 350 351 /* XXX: treat time in the same manner of kernel's 352 * net/xfrm/xfrm_{user,state}.c 353 */ 354 t = (long)time; 355 tp = localtime(&t); 356 357 strftime(str, sizeof(str), "%Y-%m-%d %T", tp); 358 } 359 360 return str; 361} 362 363void xfrm_lifetime_print(struct xfrm_lifetime_cfg *cfg, 364 struct xfrm_lifetime_cur *cur, 365 FILE *fp, const char *prefix) 366{ 367 if (cfg) { 368 if (prefix) 369 fprintf(fp, prefix); 370 fprintf(fp, "lifetime config:"); 371 fprintf(fp, "%s", _SL_); 372 373 if (prefix) 374 fprintf(fp, prefix); 375 fprintf(fp, " "); 376 fprintf(fp, "limit: "); 377 fprintf(fp, "soft "); 378 fprintf(fp, strxf_limit(cfg->soft_byte_limit)); 379 fprintf(fp, "(bytes), hard "); 380 fprintf(fp, strxf_limit(cfg->hard_byte_limit)); 381 fprintf(fp, "(bytes)"); 382 fprintf(fp, "%s", _SL_); 383 384 if (prefix) 385 fprintf(fp, prefix); 386 fprintf(fp, " "); 387 fprintf(fp, "limit: "); 388 fprintf(fp, "soft "); 389 fprintf(fp, strxf_limit(cfg->soft_packet_limit)); 390 fprintf(fp, "(packets), hard "); 391 fprintf(fp, strxf_limit(cfg->hard_packet_limit)); 392 fprintf(fp, "(packets)"); 393 fprintf(fp, "%s", _SL_); 394 395 if (prefix) 396 fprintf(fp, prefix); 397 fprintf(fp, " "); 398 fprintf(fp, "expire add: "); 399 fprintf(fp, "soft "); 400 fprintf(fp, "%llu", (unsigned long long) cfg->soft_add_expires_seconds); 401 fprintf(fp, "(sec), hard "); 402 fprintf(fp, "%llu", (unsigned long long) cfg->hard_add_expires_seconds); 403 fprintf(fp, "(sec)"); 404 fprintf(fp, "%s", _SL_); 405 406 if (prefix) 407 fprintf(fp, prefix); 408 fprintf(fp, " "); 409 fprintf(fp, "expire use: "); 410 fprintf(fp, "soft "); 411 fprintf(fp, "%llu", (unsigned long long) cfg->soft_use_expires_seconds); 412 fprintf(fp, "(sec), hard "); 413 fprintf(fp, "%llu", (unsigned long long) cfg->hard_use_expires_seconds); 414 fprintf(fp, "(sec)"); 415 fprintf(fp, "%s", _SL_); 416 } 417 if (cur) { 418 if (prefix) 419 fprintf(fp, prefix); 420 fprintf(fp, "lifetime current:"); 421 fprintf(fp, "%s", _SL_); 422 423 if (prefix) 424 fprintf(fp, prefix); 425 fprintf(fp, " "); 426 fprintf(fp, "%llu(bytes), ", (unsigned long long) cur->bytes); 427 fprintf(fp, "%llu(packets)", (unsigned long long) cur->packets); 428 fprintf(fp, "%s", _SL_); 429 430 if (prefix) 431 fprintf(fp, prefix); 432 fprintf(fp, " "); 433 fprintf(fp, "add %s ", strxf_time(cur->add_time)); 434 fprintf(fp, "use %s", strxf_time(cur->use_time)); 435 fprintf(fp, "%s", _SL_); 436 } 437} 438 439void xfrm_selector_print(struct xfrm_selector *sel, __u16 family, 440 FILE *fp, const char *prefix) 441{ 442 char abuf[256]; 443 __u16 f; 444 445 f = sel->family; 446 if (f == AF_UNSPEC) 447 f = family; 448 if (f == AF_UNSPEC) 449 f = preferred_family; 450 451 if (prefix) 452 fprintf(fp, prefix); 453 454 memset(abuf, '\0', sizeof(abuf)); 455 fprintf(fp, "src %s/%u ", rt_addr_n2a(f, sizeof(sel->saddr), 456 &sel->saddr, abuf, sizeof(abuf)), 457 sel->prefixlen_s); 458 459 memset(abuf, '\0', sizeof(abuf)); 460 fprintf(fp, "dst %s/%u ", rt_addr_n2a(f, sizeof(sel->daddr), 461 &sel->daddr, abuf, sizeof(abuf)), 462 sel->prefixlen_d); 463 464 if (sel->proto) 465 fprintf(fp, "proto %s ", strxf_proto(sel->proto)); 466 switch (sel->proto) { 467 case IPPROTO_TCP: 468 case IPPROTO_UDP: 469 case IPPROTO_SCTP: 470 case IPPROTO_DCCP: 471 default: /* XXX */ 472 if (sel->sport_mask) 473 fprintf(fp, "sport %u ", ntohs(sel->sport)); 474 if (sel->dport_mask) 475 fprintf(fp, "dport %u ", ntohs(sel->dport)); 476 break; 477 case IPPROTO_ICMP: 478 case IPPROTO_ICMPV6: 479 /* type/code is stored at sport/dport in selector */ 480 if (sel->sport_mask) 481 fprintf(fp, "type %u ", ntohs(sel->sport)); 482 if (sel->dport_mask) 483 fprintf(fp, "code %u ", ntohs(sel->dport)); 484 break; 485 case IPPROTO_MH: 486 if (sel->sport_mask) 487 fprintf(fp, "type %u ", ntohs(sel->sport)); 488 if (sel->dport_mask) { 489 if (show_stats > 0) 490 fprintf(fp, "(dport) 0x%.4x ", sel->dport); 491 } 492 break; 493 } 494 495 if (sel->ifindex > 0) 496 fprintf(fp, "dev %s ", ll_index_to_name(sel->ifindex)); 497 498 if (show_stats > 0) 499 fprintf(fp, "uid %u", sel->user); 500 501 fprintf(fp, "%s", _SL_); 502} 503 504static void xfrm_algo_print(struct xfrm_algo *algo, int type, int len, 505 FILE *fp, const char *prefix) 506{ 507 int keylen; 508 int i; 509 510 if (prefix) 511 fprintf(fp, prefix); 512 513 fprintf(fp, "%s ", strxf_algotype(type)); 514 515 if (len < sizeof(*algo)) { 516 fprintf(fp, "(ERROR truncated)"); 517 goto fin; 518 } 519 len -= sizeof(*algo); 520 521 fprintf(fp, "%s ", algo->alg_name); 522 523 keylen = algo->alg_key_len / 8; 524 if (len < keylen) { 525 fprintf(fp, "(ERROR truncated)"); 526 goto fin; 527 } 528 529 fprintf(fp, "0x"); 530 for (i = 0; i < keylen; i ++) 531 fprintf(fp, "%.2x", (unsigned char)algo->alg_key[i]); 532 533 if (show_stats > 0) 534 fprintf(fp, " (%d bits)", algo->alg_key_len); 535 536 fin: 537 fprintf(fp, "%s", _SL_); 538} 539 540static void xfrm_tmpl_print(struct xfrm_user_tmpl *tmpls, int len, 541 __u16 family, FILE *fp, const char *prefix) 542{ 543 int ntmpls = len / sizeof(struct xfrm_user_tmpl); 544 int i; 545 546 if (ntmpls <= 0) { 547 if (prefix) 548 fprintf(fp, prefix); 549 fprintf(fp, "(ERROR \"tmpl\" truncated)"); 550 fprintf(fp, "%s", _SL_); 551 return; 552 } 553 554 for (i = 0; i < ntmpls; i++) { 555 struct xfrm_user_tmpl *tmpl = &tmpls[i]; 556 557 if (prefix) 558 fprintf(fp, prefix); 559 560 xfrm_id_info_print(&tmpl->saddr, &tmpl->id, tmpl->mode, 561 tmpl->reqid, family, 0, fp, prefix, "tmpl "); 562 563 if (show_stats > 0 || tmpl->optional) { 564 if (prefix) 565 fprintf(fp, prefix); 566 fprintf(fp, "\t"); 567 switch (tmpl->optional) { 568 case 0: 569 if (show_stats > 0) 570 fprintf(fp, "level required "); 571 break; 572 case 1: 573 fprintf(fp, "level use "); 574 break; 575 default: 576 fprintf(fp, "level %u ", tmpl->optional); 577 break; 578 } 579 580 if (show_stats > 0) 581 fprintf(fp, "share %s ", strxf_share(tmpl->share)); 582 583 fprintf(fp, "%s", _SL_); 584 } 585 586 if (show_stats > 0) { 587 if (prefix) 588 fprintf(fp, prefix); 589 fprintf(fp, "\t"); 590 fprintf(fp, "%s-mask %s ", 591 strxf_algotype(XFRMA_ALG_CRYPT), 592 strxf_mask32(tmpl->ealgos)); 593 fprintf(fp, "%s-mask %s ", 594 strxf_algotype(XFRMA_ALG_AUTH), 595 strxf_mask32(tmpl->aalgos)); 596 fprintf(fp, "%s-mask %s", 597 strxf_algotype(XFRMA_ALG_COMP), 598 strxf_mask32(tmpl->calgos)); 599 600 fprintf(fp, "%s", _SL_); 601 } 602 } 603} 604 605void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, 606 FILE *fp, const char *prefix) 607{ 608 if (tb[XFRMA_ALG_AUTH]) { 609 struct rtattr *rta = tb[XFRMA_ALG_AUTH]; 610 xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), 611 XFRMA_ALG_AUTH, RTA_PAYLOAD(rta), fp, prefix); 612 } 613 614 if (tb[XFRMA_ALG_CRYPT]) { 615 struct rtattr *rta = tb[XFRMA_ALG_CRYPT]; 616 xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), 617 XFRMA_ALG_CRYPT, RTA_PAYLOAD(rta), fp, prefix); 618 } 619 620 if (tb[XFRMA_ALG_COMP]) { 621 struct rtattr *rta = tb[XFRMA_ALG_COMP]; 622 xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), 623 XFRMA_ALG_COMP, RTA_PAYLOAD(rta), fp, prefix); 624 } 625 626 if (tb[XFRMA_ENCAP]) { 627 struct xfrm_encap_tmpl *e; 628 char abuf[256]; 629 630 if (prefix) 631 fprintf(fp, prefix); 632 fprintf(fp, "encap "); 633 634 if (RTA_PAYLOAD(tb[XFRMA_ENCAP]) < sizeof(*e)) { 635 fprintf(fp, "(ERROR truncated)"); 636 fprintf(fp, "%s", _SL_); 637 return; 638 } 639 e = (struct xfrm_encap_tmpl *) RTA_DATA(tb[XFRMA_ENCAP]); 640 641 fprintf(fp, "type "); 642 switch (e->encap_type) { 643 case 1: 644 fprintf(fp, "espinudp-nonike "); 645 break; 646 case 2: 647 fprintf(fp, "espinudp "); 648 break; 649 default: 650 fprintf(fp, "%u ", e->encap_type); 651 break; 652 } 653 fprintf(fp, "sport %u ", ntohs(e->encap_sport)); 654 fprintf(fp, "dport %u ", ntohs(e->encap_dport)); 655 656 memset(abuf, '\0', sizeof(abuf)); 657 fprintf(fp, "addr %s", 658 rt_addr_n2a(family, sizeof(e->encap_oa), 659 &e->encap_oa, abuf, sizeof(abuf))); 660 fprintf(fp, "%s", _SL_); 661 } 662 663 if (tb[XFRMA_TMPL]) { 664 struct rtattr *rta = tb[XFRMA_TMPL]; 665 xfrm_tmpl_print((struct xfrm_user_tmpl *) RTA_DATA(rta), 666 RTA_PAYLOAD(rta), family, fp, prefix); 667 } 668 669 if (tb[XFRMA_COADDR]) { 670 char abuf[256]; 671 xfrm_address_t *coa; 672 673 if (prefix) 674 fprintf(fp, prefix); 675 fprintf(fp, "coa "); 676 677 coa = (xfrm_address_t *)RTA_DATA(tb[XFRMA_COADDR]); 678 679 if (RTA_PAYLOAD(tb[XFRMA_COADDR]) < sizeof(*coa)) { 680 fprintf(fp, "(ERROR truncated)"); 681 fprintf(fp, "%s", _SL_); 682 return; 683 } 684 685 memset(abuf, '\0', sizeof(abuf)); 686 fprintf(fp, "%s", 687 rt_addr_n2a(family, sizeof(*coa), coa, 688 abuf, sizeof(abuf))); 689 fprintf(fp, "%s", _SL_); 690 } 691 692 if (tb[XFRMA_LASTUSED]) { 693 __u64 lastused; 694 695 if (prefix) 696 fprintf(fp, prefix); 697 fprintf(fp, "lastused "); 698 699 if (RTA_PAYLOAD(tb[XFRMA_LASTUSED]) < sizeof(lastused)) { 700 fprintf(fp, "(ERROR truncated)"); 701 fprintf(fp, "%s", _SL_); 702 return; 703 } 704 705 lastused = *(__u64 *)RTA_DATA(tb[XFRMA_LASTUSED]); 706 707 fprintf(fp, "%s", strxf_time(lastused)); 708 fprintf(fp, "%s", _SL_); 709 } 710} 711 712static int xfrm_selector_iszero(struct xfrm_selector *s) 713{ 714 struct xfrm_selector s0; 715 716 memset(&s0, 0, sizeof(s0)); 717 718 return (memcmp(&s0, s, sizeof(s0)) == 0); 719} 720 721void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo, 722 struct rtattr *tb[], FILE *fp, const char *prefix, 723 const char *title) 724{ 725 char buf[STRBUF_SIZE]; 726 int force_spi = xfrm_xfrmproto_is_ipsec(xsinfo->id.proto); 727 728 memset(buf, '\0', sizeof(buf)); 729 730 xfrm_id_info_print(&xsinfo->saddr, &xsinfo->id, xsinfo->mode, 731 xsinfo->reqid, xsinfo->family, force_spi, fp, 732 prefix, title); 733 734 if (prefix) 735 STRBUF_CAT(buf, prefix); 736 STRBUF_CAT(buf, "\t"); 737 738 fprintf(fp, buf); 739 fprintf(fp, "replay-window %u ", xsinfo->replay_window); 740 if (show_stats > 0) 741 fprintf(fp, "seq 0x%08u ", xsinfo->seq); 742 if (show_stats > 0 || xsinfo->flags) { 743 __u8 flags = xsinfo->flags; 744 745 fprintf(fp, "flag "); 746 XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_NOECN, "noecn"); 747 XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_DECAP_DSCP, "decap-dscp"); 748 XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_WILDRECV, "wildrecv"); 749 if (flags) 750 fprintf(fp, "%x", flags); 751 if (show_stats > 0) 752 fprintf(fp, " (0x%s)", strxf_mask8(flags)); 753 } 754 fprintf(fp, "%s", _SL_); 755 756 xfrm_xfrma_print(tb, xsinfo->family, fp, buf); 757 758 if (!xfrm_selector_iszero(&xsinfo->sel)) { 759 char sbuf[STRBUF_SIZE]; 760 761 memcpy(sbuf, buf, sizeof(sbuf)); 762 STRBUF_CAT(sbuf, "sel "); 763 764 xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, sbuf); 765 } 766 767 if (show_stats > 0) { 768 xfrm_lifetime_print(&xsinfo->lft, &xsinfo->curlft, fp, buf); 769 xfrm_stats_print(&xsinfo->stats, fp, buf); 770 } 771} 772 773void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo, 774 struct rtattr *tb[], FILE *fp, const char *prefix, 775 const char *title) 776{ 777 char buf[STRBUF_SIZE]; 778 __u8 ptype = XFRM_POLICY_TYPE_MAIN; 779 780 memset(buf, '\0', sizeof(buf)); 781 782 xfrm_selector_print(&xpinfo->sel, preferred_family, fp, title); 783 784 if (prefix) 785 STRBUF_CAT(buf, prefix); 786 STRBUF_CAT(buf, "\t"); 787 788 fprintf(fp, buf); 789 fprintf(fp, "dir "); 790 switch (xpinfo->dir) { 791 case XFRM_POLICY_IN: 792 fprintf(fp, "in"); 793 break; 794 case XFRM_POLICY_OUT: 795 fprintf(fp, "out"); 796 break; 797 case XFRM_POLICY_FWD: 798 fprintf(fp, "fwd"); 799 break; 800 default: 801 fprintf(fp, "%u", xpinfo->dir); 802 break; 803 } 804 fprintf(fp, " "); 805 806 switch (xpinfo->action) { 807 case XFRM_POLICY_ALLOW: 808 if (show_stats > 0) 809 fprintf(fp, "action allow "); 810 break; 811 case XFRM_POLICY_BLOCK: 812 fprintf(fp, "action block "); 813 break; 814 default: 815 fprintf(fp, "action %u ", xpinfo->action); 816 break; 817 } 818 819 if (show_stats) 820 fprintf(fp, "index %u ", xpinfo->index); 821 fprintf(fp, "priority %u ", xpinfo->priority); 822 823 fprintf(fp, "ptype "); 824 825 if (tb[XFRMA_POLICY_TYPE]) { 826 struct xfrm_userpolicy_type *upt; 827 828 if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt)) 829 fprintf(fp, "(ERROR truncated)"); 830 831 upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]); 832 ptype = upt->type; 833 } 834 835 switch (ptype) { 836 case XFRM_POLICY_TYPE_MAIN: 837 fprintf(fp, "main"); 838 break; 839 case XFRM_POLICY_TYPE_SUB: 840 fprintf(fp, "sub"); 841 break; 842 default: 843 fprintf(fp, "%u", ptype); 844 break; 845 } 846 fprintf(fp, " "); 847 848 if (show_stats > 0) { 849 fprintf(fp, "share %s ", strxf_share(xpinfo->share)); 850 fprintf(fp, "flag 0x%s", strxf_mask8(xpinfo->flags)); 851 } 852 fprintf(fp, "%s", _SL_); 853 854 if (show_stats > 0) 855 xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, buf); 856 857 xfrm_xfrma_print(tb, xpinfo->sel.family, fp, buf); 858} 859 860int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family, 861 int loose, int *argcp, char ***argvp) 862{ 863 int argc = *argcp; 864 char **argv = *argvp; 865 inet_prefix dst; 866 inet_prefix src; 867 868 memset(&dst, 0, sizeof(dst)); 869 memset(&src, 0, sizeof(src)); 870 871 while (1) { 872 if (strcmp(*argv, "src") == 0) { 873 NEXT_ARG(); 874 875 get_prefix(&src, *argv, preferred_family); 876 if (src.family == AF_UNSPEC) 877 invarg("\"src\" address family is AF_UNSPEC", *argv); 878 if (family) 879 *family = src.family; 880 881 memcpy(saddr, &src.data, sizeof(*saddr)); 882 883 filter.id_src_mask = src.bitlen; 884 885 } else if (strcmp(*argv, "dst") == 0) { 886 NEXT_ARG(); 887 888 get_prefix(&dst, *argv, preferred_family); 889 if (dst.family == AF_UNSPEC) 890 invarg("\"dst\" address family is AF_UNSPEC", *argv); 891 if (family) 892 *family = dst.family; 893 894 memcpy(&id->daddr, &dst.data, sizeof(id->daddr)); 895 896 filter.id_dst_mask = dst.bitlen; 897 898 } else if (strcmp(*argv, "proto") == 0) { 899 int ret; 900 901 NEXT_ARG(); 902 903 ret = xfrm_xfrmproto_getbyname(*argv); 904 if (ret < 0) 905 invarg("\"XFRM_PROTO\" is invalid", *argv); 906 907 id->proto = (__u8)ret; 908 909 filter.id_proto_mask = XFRM_FILTER_MASK_FULL; 910 911 } else if (strcmp(*argv, "spi") == 0) { 912 __u32 spi; 913 914 NEXT_ARG(); 915 if (get_u32(&spi, *argv, 0)) 916 invarg("\"SPI\" is invalid", *argv); 917 918 spi = htonl(spi); 919 id->spi = spi; 920 921 filter.id_spi_mask = XFRM_FILTER_MASK_FULL; 922 923 } else { 924 PREV_ARG(); /* back track */ 925 break; 926 } 927 928 if (!NEXT_ARG_OK()) 929 break; 930 NEXT_ARG(); 931 } 932 933 if (src.family && dst.family && (src.family != dst.family)) 934 invarg("the same address family is required between \"src\" and \"dst\"", *argv); 935 936 if (loose == 0 && id->proto == 0) 937 missarg("XFRM_PROTO"); 938 if (argc == *argcp) 939 missarg("ID"); 940 941 *argcp = argc; 942 *argvp = argv; 943 944 return 0; 945} 946 947int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp) 948{ 949 int argc = *argcp; 950 char **argv = *argvp; 951 952 if (matches(*argv, "transport") == 0) 953 *mode = XFRM_MODE_TRANSPORT; 954 else if (matches(*argv, "tunnel") == 0) 955 *mode = XFRM_MODE_TUNNEL; 956 else if (matches(*argv, "ro") == 0) 957 *mode = XFRM_MODE_ROUTEOPTIMIZATION; 958 else if (matches(*argv, "in_trigger") == 0) 959 *mode = XFRM_MODE_IN_TRIGGER; 960 else if (matches(*argv, "beet") == 0) 961 *mode = XFRM_MODE_BEET; 962 else 963 invarg("\"MODE\" is invalid", *argv); 964 965 *argcp = argc; 966 *argvp = argv; 967 968 return 0; 969} 970 971int xfrm_encap_type_parse(__u16 *type, int *argcp, char ***argvp) 972{ 973 int argc = *argcp; 974 char **argv = *argvp; 975 976 if (strcmp(*argv, "espinudp-nonike") == 0) 977 *type = 1; 978 else if (strcmp(*argv, "espinudp") == 0) 979 *type = 2; 980 else 981 invarg("\"ENCAP-TYPE\" is invalid", *argv); 982 983 *argcp = argc; 984 *argvp = argv; 985 986 return 0; 987} 988 989/* NOTE: reqid is used by host-byte order */ 990int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp) 991{ 992 int argc = *argcp; 993 char **argv = *argvp; 994 995 if (get_u32(reqid, *argv, 0)) 996 invarg("\"REQID\" is invalid", *argv); 997 998 *argcp = argc; 999 *argvp = argv; 1000 1001 return 0; 1002} 1003 1004static int xfrm_selector_upspec_parse(struct xfrm_selector *sel, 1005 int *argcp, char ***argvp) 1006{ 1007 int argc = *argcp; 1008 char **argv = *argvp; 1009 char *sportp = NULL; 1010 char *dportp = NULL; 1011 char *typep = NULL; 1012 char *codep = NULL; 1013 1014 while (1) { 1015 if (strcmp(*argv, "proto") == 0) { 1016 __u8 upspec; 1017 1018 NEXT_ARG(); 1019 1020 if (strcmp(*argv, "any") == 0) 1021 upspec = 0; 1022 else { 1023 struct protoent *pp; 1024 pp = getprotobyname(*argv); 1025 if (pp) 1026 upspec = pp->p_proto; 1027 else { 1028 if (get_u8(&upspec, *argv, 0)) 1029 invarg("\"PROTO\" is invalid", *argv); 1030 } 1031 } 1032 sel->proto = upspec; 1033 1034 filter.upspec_proto_mask = XFRM_FILTER_MASK_FULL; 1035 1036 } else if (strcmp(*argv, "sport") == 0) { 1037 sportp = *argv; 1038 1039 NEXT_ARG(); 1040 1041 if (get_u16(&sel->sport, *argv, 0)) 1042 invarg("\"PORT\" is invalid", *argv); 1043 sel->sport = htons(sel->sport); 1044 if (sel->sport) 1045 sel->sport_mask = ~((__u16)0); 1046 1047 filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL; 1048 1049 } else if (strcmp(*argv, "dport") == 0) { 1050 dportp = *argv; 1051 1052 NEXT_ARG(); 1053 1054 if (get_u16(&sel->dport, *argv, 0)) 1055 invarg("\"PORT\" is invalid", *argv); 1056 sel->dport = htons(sel->dport); 1057 if (sel->dport) 1058 sel->dport_mask = ~((__u16)0); 1059 1060 filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL; 1061 1062 } else if (strcmp(*argv, "type") == 0) { 1063 typep = *argv; 1064 1065 NEXT_ARG(); 1066 1067 if (get_u16(&sel->sport, *argv, 0) || 1068 (sel->sport & ~((__u16)0xff))) 1069 invarg("\"type\" value is invalid", *argv); 1070 sel->sport = htons(sel->sport); 1071 sel->sport_mask = ~((__u16)0); 1072 1073 filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL; 1074 1075 1076 } else if (strcmp(*argv, "code") == 0) { 1077 codep = *argv; 1078 1079 NEXT_ARG(); 1080 1081 if (get_u16(&sel->dport, *argv, 0) || 1082 (sel->dport & ~((__u16)0xff))) 1083 invarg("\"code\" value is invalid", *argv); 1084 sel->dport = htons(sel->dport); 1085 sel->dport_mask = ~((__u16)0); 1086 1087 filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL; 1088 1089 } else { 1090 PREV_ARG(); /* back track */ 1091 break; 1092 } 1093 1094 if (!NEXT_ARG_OK()) 1095 break; 1096 NEXT_ARG(); 1097 } 1098 if (argc == *argcp) 1099 missarg("UPSPEC"); 1100 if (sportp || dportp) { 1101 switch (sel->proto) { 1102 case IPPROTO_TCP: 1103 case IPPROTO_UDP: 1104 case IPPROTO_SCTP: 1105 case IPPROTO_DCCP: 1106 break; 1107 default: 1108 fprintf(stderr, "\"sport\" and \"dport\" are invalid with proto=%s\n", strxf_proto(sel->proto)); 1109 exit(1); 1110 } 1111 } 1112 if (typep || codep) { 1113 switch (sel->proto) { 1114 case IPPROTO_ICMP: 1115 case IPPROTO_ICMPV6: 1116 case IPPROTO_MH: 1117 break; 1118 default: 1119 fprintf(stderr, "\"type\" and \"code\" are invalid with proto=%s\n", strxf_proto(sel->proto)); 1120 exit(1); 1121 } 1122 } 1123 1124 *argcp = argc; 1125 *argvp = argv; 1126 1127 return 0; 1128} 1129 1130int xfrm_selector_parse(struct xfrm_selector *sel, int *argcp, char ***argvp) 1131{ 1132 int argc = *argcp; 1133 char **argv = *argvp; 1134 inet_prefix dst; 1135 inet_prefix src; 1136 char *upspecp = NULL; 1137 1138 memset(&dst, 0, sizeof(dst)); 1139 memset(&src, 0, sizeof(src)); 1140 1141 while (1) { 1142 if (strcmp(*argv, "src") == 0) { 1143 NEXT_ARG(); 1144 1145 get_prefix(&src, *argv, preferred_family); 1146 if (src.family == AF_UNSPEC) 1147 invarg("\"src\" address family is AF_UNSPEC", *argv); 1148 sel->family = src.family; 1149 1150 memcpy(&sel->saddr, &src.data, sizeof(sel->saddr)); 1151 sel->prefixlen_s = src.bitlen; 1152 1153 filter.sel_src_mask = src.bitlen; 1154 1155 } else if (strcmp(*argv, "dst") == 0) { 1156 NEXT_ARG(); 1157 1158 get_prefix(&dst, *argv, preferred_family); 1159 if (dst.family == AF_UNSPEC) 1160 invarg("\"dst\" address family is AF_UNSPEC", *argv); 1161 sel->family = dst.family; 1162 1163 memcpy(&sel->daddr, &dst.data, sizeof(sel->daddr)); 1164 sel->prefixlen_d = dst.bitlen; 1165 1166 filter.sel_dst_mask = dst.bitlen; 1167 1168 } else if (strcmp(*argv, "dev") == 0) { 1169 int ifindex; 1170 1171 NEXT_ARG(); 1172 1173 if (strcmp(*argv, "none") == 0) 1174 ifindex = 0; 1175 else { 1176 ifindex = ll_name_to_index(*argv); 1177 if (ifindex <= 0) 1178 invarg("\"DEV\" is invalid", *argv); 1179 } 1180 sel->ifindex = ifindex; 1181 1182 filter.sel_dev_mask = XFRM_FILTER_MASK_FULL; 1183 1184 } else { 1185 if (upspecp) { 1186 PREV_ARG(); /* back track */ 1187 break; 1188 } else { 1189 upspecp = *argv; 1190 xfrm_selector_upspec_parse(sel, &argc, &argv); 1191 } 1192 } 1193 1194 if (!NEXT_ARG_OK()) 1195 break; 1196 1197 NEXT_ARG(); 1198 } 1199 1200 if (src.family && dst.family && (src.family != dst.family)) 1201 invarg("the same address family is required between \"src\" and \"dst\"", *argv); 1202 1203 if (argc == *argcp) 1204 missarg("SELECTOR"); 1205 1206 *argcp = argc; 1207 *argvp = argv; 1208 1209 return 0; 1210} 1211 1212int xfrm_lifetime_cfg_parse(struct xfrm_lifetime_cfg *lft, 1213 int *argcp, char ***argvp) 1214{ 1215 int argc = *argcp; 1216 char **argv = *argvp; 1217 int ret; 1218 1219 if (strcmp(*argv, "time-soft") == 0) { 1220 NEXT_ARG(); 1221 ret = get_u64(&lft->soft_add_expires_seconds, *argv, 0); 1222 if (ret) 1223 invarg("\"time-soft\" value is invalid", *argv); 1224 } else if (strcmp(*argv, "time-hard") == 0) { 1225 NEXT_ARG(); 1226 ret = get_u64(&lft->hard_add_expires_seconds, *argv, 0); 1227 if (ret) 1228 invarg("\"time-hard\" value is invalid", *argv); 1229 } else if (strcmp(*argv, "time-use-soft") == 0) { 1230 NEXT_ARG(); 1231 ret = get_u64(&lft->soft_use_expires_seconds, *argv, 0); 1232 if (ret) 1233 invarg("\"time-use-soft\" value is invalid", *argv); 1234 } else if (strcmp(*argv, "time-use-hard") == 0) { 1235 NEXT_ARG(); 1236 ret = get_u64(&lft->hard_use_expires_seconds, *argv, 0); 1237 if (ret) 1238 invarg("\"time-use-hard\" value is invalid", *argv); 1239 } else if (strcmp(*argv, "byte-soft") == 0) { 1240 NEXT_ARG(); 1241 ret = get_u64(&lft->soft_byte_limit, *argv, 0); 1242 if (ret) 1243 invarg("\"byte-soft\" value is invalid", *argv); 1244 } else if (strcmp(*argv, "byte-hard") == 0) { 1245 NEXT_ARG(); 1246 ret = get_u64(&lft->hard_byte_limit, *argv, 0); 1247 if (ret) 1248 invarg("\"byte-hard\" value is invalid", *argv); 1249 } else if (strcmp(*argv, "packet-soft") == 0) { 1250 NEXT_ARG(); 1251 ret = get_u64(&lft->soft_packet_limit, *argv, 0); 1252 if (ret) 1253 invarg("\"packet-soft\" value is invalid", *argv); 1254 } else if (strcmp(*argv, "packet-hard") == 0) { 1255 NEXT_ARG(); 1256 ret = get_u64(&lft->hard_packet_limit, *argv, 0); 1257 if (ret) 1258 invarg("\"packet-hard\" value is invalid", *argv); 1259 } else 1260 invarg("\"LIMIT\" is invalid", *argv); 1261 1262 *argcp = argc; 1263 *argvp = argv; 1264 1265 return 0; 1266} 1267 1268int do_xfrm(int argc, char **argv) 1269{ 1270 memset(&filter, 0, sizeof(filter)); 1271 1272 if (argc < 1) 1273 usage(); 1274 1275 if (matches(*argv, "state") == 0 || 1276 matches(*argv, "sa") == 0) 1277 return do_xfrm_state(argc-1, argv+1); 1278 else if (matches(*argv, "policy") == 0) 1279 return do_xfrm_policy(argc-1, argv+1); 1280 else if (matches(*argv, "monitor") == 0) 1281 return do_xfrm_monitor(argc-1, argv+1); 1282 else if (matches(*argv, "help") == 0) { 1283 usage(); 1284 fprintf(stderr, "xfrm Object \"%s\" is unknown.\n", *argv); 1285 exit(-1); 1286 } 1287 usage(); 1288} 1289