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