1 /* 2 * ss.c "sockstat", socket statistics 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Authors: Alexey Kuznetsov, <kuznet (at) ms2.inr.ac.ru> 10 */ 11 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <unistd.h> 15 #include <syslog.h> 16 #include <fcntl.h> 17 #include <sys/ioctl.h> 18 #include <sys/socket.h> 19 #include <sys/uio.h> 20 #include <netinet/in.h> 21 #include <string.h> 22 #include <errno.h> 23 #include <netdb.h> 24 #include <arpa/inet.h> 25 #include <dirent.h> 26 #include <fnmatch.h> 27 #include <getopt.h> 28 #include <stdbool.h> 29 30 #include "utils.h" 31 #include "rt_names.h" 32 #include "ll_map.h" 33 #include "libnetlink.h" 34 #include "namespace.h" 35 #include "SNAPSHOT.h" 36 37 #include <linux/tcp.h> 38 #include <linux/sock_diag.h> 39 #include <linux/inet_diag.h> 40 #include <linux/unix_diag.h> 41 #include <linux/netdevice.h> /* for MAX_ADDR_LEN */ 42 #include <linux/filter.h> 43 #include <linux/packet_diag.h> 44 #include <linux/netlink_diag.h> 45 46 #define MAGIC_SEQ 123456 47 48 #define DIAG_REQUEST(_req, _r) \ 49 struct { \ 50 struct nlmsghdr nlh; \ 51 _r; \ 52 } _req = { \ 53 .nlh = { \ 54 .nlmsg_type = SOCK_DIAG_BY_FAMILY, \ 55 .nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST,\ 56 .nlmsg_seq = MAGIC_SEQ, \ 57 .nlmsg_len = sizeof(_req), \ 58 }, \ 59 } 60 61 #if HAVE_SELINUX 62 #include <selinux/selinux.h> 63 #else 64 /* Stubs for SELinux functions */ 65 static int is_selinux_enabled(void) 66 { 67 return -1; 68 } 69 70 static int getpidcon(pid_t pid, char **context) 71 { 72 *context = NULL; 73 return -1; 74 } 75 76 static int getfilecon(char *path, char **context) 77 { 78 *context = NULL; 79 return -1; 80 } 81 82 static int security_get_initial_context(char *name, char **context) 83 { 84 *context = NULL; 85 return -1; 86 } 87 #endif 88 89 int resolve_hosts = 0; 90 int resolve_services = 1; 91 int preferred_family = AF_UNSPEC; 92 int show_options = 0; 93 int show_details = 0; 94 int show_users = 0; 95 int show_mem = 0; 96 int show_tcpinfo = 0; 97 int show_bpf = 0; 98 int show_proc_ctx = 0; 99 int show_sock_ctx = 0; 100 /* If show_users & show_proc_ctx only do user_ent_hash_build() once */ 101 int user_ent_hash_build_init = 0; 102 int follow_events = 0; 103 104 int netid_width; 105 int state_width; 106 int addrp_width; 107 int addr_width; 108 int serv_width; 109 int screen_width; 110 111 static const char *TCP_PROTO = "tcp"; 112 static const char *UDP_PROTO = "udp"; 113 static const char *RAW_PROTO = "raw"; 114 static const char *dg_proto = NULL; 115 116 enum 117 { 118 TCP_DB, 119 DCCP_DB, 120 UDP_DB, 121 RAW_DB, 122 UNIX_DG_DB, 123 UNIX_ST_DB, 124 UNIX_SQ_DB, 125 PACKET_DG_DB, 126 PACKET_R_DB, 127 NETLINK_DB, 128 MAX_DB 129 }; 130 131 #define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB)) 132 #define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB)) 133 #define ALL_DB ((1<<MAX_DB)-1) 134 #define INET_DBM ((1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<RAW_DB)) 135 136 enum { 137 SS_UNKNOWN, 138 SS_ESTABLISHED, 139 SS_SYN_SENT, 140 SS_SYN_RECV, 141 SS_FIN_WAIT1, 142 SS_FIN_WAIT2, 143 SS_TIME_WAIT, 144 SS_CLOSE, 145 SS_CLOSE_WAIT, 146 SS_LAST_ACK, 147 SS_LISTEN, 148 SS_CLOSING, 149 SS_MAX 150 }; 151 152 #define SS_ALL ((1 << SS_MAX) - 1) 153 #define SS_CONN (SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV))) 154 155 #include "ssfilter.h" 156 157 struct filter 158 { 159 int dbs; 160 int states; 161 int families; 162 struct ssfilter *f; 163 bool kill; 164 }; 165 166 static const struct filter default_dbs[MAX_DB] = { 167 [TCP_DB] = { 168 .states = SS_CONN, 169 .families = (1 << AF_INET) | (1 << AF_INET6), 170 }, 171 [DCCP_DB] = { 172 .states = SS_CONN, 173 .families = (1 << AF_INET) | (1 << AF_INET6), 174 }, 175 [UDP_DB] = { 176 .states = (1 << SS_ESTABLISHED), 177 .families = (1 << AF_INET) | (1 << AF_INET6), 178 }, 179 [RAW_DB] = { 180 .states = (1 << SS_ESTABLISHED), 181 .families = (1 << AF_INET) | (1 << AF_INET6), 182 }, 183 [UNIX_DG_DB] = { 184 .states = (1 << SS_CLOSE), 185 .families = (1 << AF_UNIX), 186 }, 187 [UNIX_ST_DB] = { 188 .states = SS_CONN, 189 .families = (1 << AF_UNIX), 190 }, 191 [UNIX_SQ_DB] = { 192 .states = SS_CONN, 193 .families = (1 << AF_UNIX), 194 }, 195 [PACKET_DG_DB] = { 196 .states = (1 << SS_CLOSE), 197 .families = (1 << AF_PACKET), 198 }, 199 [PACKET_R_DB] = { 200 .states = (1 << SS_CLOSE), 201 .families = (1 << AF_PACKET), 202 }, 203 [NETLINK_DB] = { 204 .states = (1 << SS_CLOSE), 205 .families = (1 << AF_NETLINK), 206 }, 207 }; 208 209 static const struct filter default_afs[AF_MAX] = { 210 [AF_INET] = { 211 .dbs = INET_DBM, 212 .states = SS_CONN, 213 }, 214 [AF_INET6] = { 215 .dbs = INET_DBM, 216 .states = SS_CONN, 217 }, 218 [AF_UNIX] = { 219 .dbs = UNIX_DBM, 220 .states = SS_CONN, 221 }, 222 [AF_PACKET] = { 223 .dbs = PACKET_DBM, 224 .states = (1 << SS_CLOSE), 225 }, 226 [AF_NETLINK] = { 227 .dbs = (1 << NETLINK_DB), 228 .states = (1 << SS_CLOSE), 229 }, 230 }; 231 232 static int do_default = 1; 233 static struct filter current_filter; 234 235 static void filter_db_set(struct filter *f, int db) 236 { 237 f->states |= default_dbs[db].states; 238 f->dbs |= 1 << db; 239 do_default = 0; 240 } 241 242 static void filter_af_set(struct filter *f, int af) 243 { 244 f->states |= default_afs[af].states; 245 f->families |= 1 << af; 246 do_default = 0; 247 preferred_family = af; 248 } 249 250 static int filter_af_get(struct filter *f, int af) 251 { 252 return f->families & (1 << af); 253 } 254 255 static void filter_default_dbs(struct filter *f) 256 { 257 filter_db_set(f, UDP_DB); 258 filter_db_set(f, DCCP_DB); 259 filter_db_set(f, TCP_DB); 260 filter_db_set(f, RAW_DB); 261 filter_db_set(f, UNIX_ST_DB); 262 filter_db_set(f, UNIX_DG_DB); 263 filter_db_set(f, UNIX_SQ_DB); 264 filter_db_set(f, PACKET_R_DB); 265 filter_db_set(f, PACKET_DG_DB); 266 filter_db_set(f, NETLINK_DB); 267 } 268 269 static void filter_states_set(struct filter *f, int states) 270 { 271 if (states) 272 f->states = (f->states | states) & states; 273 } 274 275 static void filter_merge_defaults(struct filter *f) 276 { 277 int db; 278 int af; 279 280 for (db = 0; db < MAX_DB; db++) { 281 if (!(f->dbs & (1 << db))) 282 continue; 283 284 if (!(default_dbs[db].families & f->families)) 285 f->families |= default_dbs[db].families; 286 } 287 for (af = 0; af < AF_MAX; af++) { 288 if (!(f->families & (1 << af))) 289 continue; 290 291 if (!(default_afs[af].dbs & f->dbs)) 292 f->dbs |= default_afs[af].dbs; 293 } 294 } 295 296 static FILE *generic_proc_open(const char *env, const char *name) 297 { 298 const char *p = getenv(env); 299 char store[128]; 300 301 if (!p) { 302 p = getenv("PROC_ROOT") ? : "/proc"; 303 snprintf(store, sizeof(store)-1, "%s/%s", p, name); 304 p = store; 305 } 306 307 return fopen(p, "r"); 308 } 309 310 static FILE *net_tcp_open(void) 311 { 312 return generic_proc_open("PROC_NET_TCP", "net/tcp"); 313 } 314 315 static FILE *net_tcp6_open(void) 316 { 317 return generic_proc_open("PROC_NET_TCP6", "net/tcp6"); 318 } 319 320 static FILE *net_udp_open(void) 321 { 322 return generic_proc_open("PROC_NET_UDP", "net/udp"); 323 } 324 325 static FILE *net_udp6_open(void) 326 { 327 return generic_proc_open("PROC_NET_UDP6", "net/udp6"); 328 } 329 330 static FILE *net_raw_open(void) 331 { 332 return generic_proc_open("PROC_NET_RAW", "net/raw"); 333 } 334 335 static FILE *net_raw6_open(void) 336 { 337 return generic_proc_open("PROC_NET_RAW6", "net/raw6"); 338 } 339 340 static FILE *net_unix_open(void) 341 { 342 return generic_proc_open("PROC_NET_UNIX", "net/unix"); 343 } 344 345 static FILE *net_packet_open(void) 346 { 347 return generic_proc_open("PROC_NET_PACKET", "net/packet"); 348 } 349 350 static FILE *net_netlink_open(void) 351 { 352 return generic_proc_open("PROC_NET_NETLINK", "net/netlink"); 353 } 354 355 static FILE *slabinfo_open(void) 356 { 357 return generic_proc_open("PROC_SLABINFO", "slabinfo"); 358 } 359 360 static FILE *net_sockstat_open(void) 361 { 362 return generic_proc_open("PROC_NET_SOCKSTAT", "net/sockstat"); 363 } 364 365 static FILE *net_sockstat6_open(void) 366 { 367 return generic_proc_open("PROC_NET_SOCKSTAT6", "net/sockstat6"); 368 } 369 370 static FILE *net_snmp_open(void) 371 { 372 return generic_proc_open("PROC_NET_SNMP", "net/snmp"); 373 } 374 375 static FILE *ephemeral_ports_open(void) 376 { 377 return generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", "sys/net/ipv4/ip_local_port_range"); 378 } 379 380 struct user_ent { 381 struct user_ent *next; 382 unsigned int ino; 383 int pid; 384 int fd; 385 char *process; 386 char *process_ctx; 387 char *socket_ctx; 388 }; 389 390 #define USER_ENT_HASH_SIZE 256 391 struct user_ent *user_ent_hash[USER_ENT_HASH_SIZE]; 392 393 static int user_ent_hashfn(unsigned int ino) 394 { 395 int val = (ino >> 24) ^ (ino >> 16) ^ (ino >> 8) ^ ino; 396 397 return val & (USER_ENT_HASH_SIZE - 1); 398 } 399 400 static void user_ent_add(unsigned int ino, char *process, 401 int pid, int fd, 402 char *proc_ctx, 403 char *sock_ctx) 404 { 405 struct user_ent *p, **pp; 406 407 p = malloc(sizeof(struct user_ent)); 408 if (!p) { 409 fprintf(stderr, "ss: failed to malloc buffer\n"); 410 abort(); 411 } 412 p->next = NULL; 413 p->ino = ino; 414 p->pid = pid; 415 p->fd = fd; 416 p->process = strdup(process); 417 p->process_ctx = strdup(proc_ctx); 418 p->socket_ctx = strdup(sock_ctx); 419 420 pp = &user_ent_hash[user_ent_hashfn(ino)]; 421 p->next = *pp; 422 *pp = p; 423 } 424 425 static void user_ent_destroy(void) 426 { 427 struct user_ent *p, *p_next; 428 int cnt = 0; 429 430 while (cnt != USER_ENT_HASH_SIZE) { 431 p = user_ent_hash[cnt]; 432 while (p) { 433 free(p->process); 434 free(p->process_ctx); 435 free(p->socket_ctx); 436 p_next = p->next; 437 free(p); 438 p = p_next; 439 } 440 cnt++; 441 } 442 } 443 444 static void user_ent_hash_build(void) 445 { 446 const char *root = getenv("PROC_ROOT") ? : "/proc/"; 447 struct dirent *d; 448 char name[1024]; 449 int nameoff; 450 DIR *dir; 451 char *pid_context; 452 char *sock_context; 453 const char *no_ctx = "unavailable"; 454 455 /* If show_users & show_proc_ctx set only do this once */ 456 if (user_ent_hash_build_init != 0) 457 return; 458 459 user_ent_hash_build_init = 1; 460 461 strncpy(name, root, sizeof(name)-1); 462 name[sizeof(name)-1] = 0; 463 464 if (strlen(name) == 0 || name[strlen(name)-1] != '/') 465 strcat(name, "/"); 466 467 nameoff = strlen(name); 468 469 dir = opendir(name); 470 if (!dir) 471 return; 472 473 while ((d = readdir(dir)) != NULL) { 474 struct dirent *d1; 475 char process[16]; 476 char *p; 477 int pid, pos; 478 DIR *dir1; 479 char crap; 480 481 if (sscanf(d->d_name, "%d%c", &pid, &crap) != 1) 482 continue; 483 484 if (getpidcon(pid, &pid_context) != 0) 485 pid_context = strdup(no_ctx); 486 487 snprintf(name + nameoff, sizeof(name) - nameoff, "%d/fd/", pid); 488 pos = strlen(name); 489 if ((dir1 = opendir(name)) == NULL) { 490 free(pid_context); 491 continue; 492 } 493 494 process[0] = '\0'; 495 p = process; 496 497 while ((d1 = readdir(dir1)) != NULL) { 498 const char *pattern = "socket:["; 499 unsigned int ino; 500 char lnk[64]; 501 int fd; 502 ssize_t link_len; 503 char tmp[1024]; 504 505 if (sscanf(d1->d_name, "%d%c", &fd, &crap) != 1) 506 continue; 507 508 snprintf(name+pos, sizeof(name) - pos, "%d", fd); 509 510 link_len = readlink(name, lnk, sizeof(lnk)-1); 511 if (link_len == -1) 512 continue; 513 lnk[link_len] = '\0'; 514 515 if (strncmp(lnk, pattern, strlen(pattern))) 516 continue; 517 518 sscanf(lnk, "socket:[%u]", &ino); 519 520 snprintf(tmp, sizeof(tmp), "%s/%d/fd/%s", 521 root, pid, d1->d_name); 522 523 if (getfilecon(tmp, &sock_context) <= 0) 524 sock_context = strdup(no_ctx); 525 526 if (*p == '\0') { 527 FILE *fp; 528 529 snprintf(tmp, sizeof(tmp), "%s/%d/stat", 530 root, pid); 531 if ((fp = fopen(tmp, "r")) != NULL) { 532 if (fscanf(fp, "%*d (%[^)])", p) < 1) 533 ; /* ignore */ 534 fclose(fp); 535 } 536 } 537 user_ent_add(ino, p, pid, fd, 538 pid_context, sock_context); 539 free(sock_context); 540 } 541 free(pid_context); 542 closedir(dir1); 543 } 544 closedir(dir); 545 } 546 547 enum entry_types { 548 USERS, 549 PROC_CTX, 550 PROC_SOCK_CTX 551 }; 552 553 #define ENTRY_BUF_SIZE 512 554 static int find_entry(unsigned ino, char **buf, int type) 555 { 556 struct user_ent *p; 557 int cnt = 0; 558 char *ptr; 559 char *new_buf; 560 int len, new_buf_len; 561 int buf_used = 0; 562 int buf_len = 0; 563 564 if (!ino) 565 return 0; 566 567 p = user_ent_hash[user_ent_hashfn(ino)]; 568 ptr = *buf = NULL; 569 while (p) { 570 if (p->ino != ino) 571 goto next; 572 573 while (1) { 574 ptr = *buf + buf_used; 575 switch (type) { 576 case USERS: 577 len = snprintf(ptr, buf_len - buf_used, 578 "(\"%s\",pid=%d,fd=%d),", 579 p->process, p->pid, p->fd); 580 break; 581 case PROC_CTX: 582 len = snprintf(ptr, buf_len - buf_used, 583 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d),", 584 p->process, p->pid, 585 p->process_ctx, p->fd); 586 break; 587 case PROC_SOCK_CTX: 588 len = snprintf(ptr, buf_len - buf_used, 589 "(\"%s\",pid=%d,proc_ctx=%s,fd=%d,sock_ctx=%s),", 590 p->process, p->pid, 591 p->process_ctx, p->fd, 592 p->socket_ctx); 593 break; 594 default: 595 fprintf(stderr, "ss: invalid type: %d\n", type); 596 abort(); 597 } 598 599 if (len < 0 || len >= buf_len - buf_used) { 600 new_buf_len = buf_len + ENTRY_BUF_SIZE; 601 new_buf = realloc(*buf, new_buf_len); 602 if (!new_buf) { 603 fprintf(stderr, "ss: failed to malloc buffer\n"); 604 abort(); 605 } 606 *buf = new_buf; 607 buf_len = new_buf_len; 608 continue; 609 } else { 610 buf_used += len; 611 break; 612 } 613 } 614 cnt++; 615 next: 616 p = p->next; 617 } 618 if (buf_used) { 619 ptr = *buf + buf_used; 620 ptr[-1] = '\0'; 621 } 622 return cnt; 623 } 624 625 /* Get stats from slab */ 626 627 struct slabstat 628 { 629 int socks; 630 int tcp_ports; 631 int tcp_tws; 632 int tcp_syns; 633 int skbs; 634 }; 635 636 static struct slabstat slabstat; 637 638 static const char *slabstat_ids[] = 639 { 640 "sock", 641 "tcp_bind_bucket", 642 "tcp_tw_bucket", 643 "tcp_open_request", 644 "skbuff_head_cache", 645 }; 646 647 static int get_slabstat(struct slabstat *s) 648 { 649 char buf[256]; 650 FILE *fp; 651 int cnt; 652 static int slabstat_valid; 653 654 if (slabstat_valid) 655 return 0; 656 657 memset(s, 0, sizeof(*s)); 658 659 fp = slabinfo_open(); 660 if (!fp) 661 return -1; 662 663 cnt = sizeof(*s)/sizeof(int); 664 665 if (!fgets(buf, sizeof(buf), fp)) { 666 fclose(fp); 667 return -1; 668 } 669 while(fgets(buf, sizeof(buf), fp) != NULL) { 670 int i; 671 for (i=0; i<sizeof(slabstat_ids)/sizeof(slabstat_ids[0]); i++) { 672 if (memcmp(buf, slabstat_ids[i], strlen(slabstat_ids[i])) == 0) { 673 sscanf(buf, "%*s%d", ((int *)s) + i); 674 cnt--; 675 break; 676 } 677 } 678 if (cnt <= 0) 679 break; 680 } 681 682 slabstat_valid = 1; 683 684 fclose(fp); 685 return 0; 686 } 687 688 static unsigned long long cookie_sk_get(const uint32_t *cookie) 689 { 690 return (((unsigned long long)cookie[1] << 31) << 1) | cookie[0]; 691 } 692 693 static const char *sstate_name[] = { 694 "UNKNOWN", 695 [SS_ESTABLISHED] = "ESTAB", 696 [SS_SYN_SENT] = "SYN-SENT", 697 [SS_SYN_RECV] = "SYN-RECV", 698 [SS_FIN_WAIT1] = "FIN-WAIT-1", 699 [SS_FIN_WAIT2] = "FIN-WAIT-2", 700 [SS_TIME_WAIT] = "TIME-WAIT", 701 [SS_CLOSE] = "UNCONN", 702 [SS_CLOSE_WAIT] = "CLOSE-WAIT", 703 [SS_LAST_ACK] = "LAST-ACK", 704 [SS_LISTEN] = "LISTEN", 705 [SS_CLOSING] = "CLOSING", 706 }; 707 708 static const char *sstate_namel[] = { 709 "UNKNOWN", 710 [SS_ESTABLISHED] = "established", 711 [SS_SYN_SENT] = "syn-sent", 712 [SS_SYN_RECV] = "syn-recv", 713 [SS_FIN_WAIT1] = "fin-wait-1", 714 [SS_FIN_WAIT2] = "fin-wait-2", 715 [SS_TIME_WAIT] = "time-wait", 716 [SS_CLOSE] = "unconnected", 717 [SS_CLOSE_WAIT] = "close-wait", 718 [SS_LAST_ACK] = "last-ack", 719 [SS_LISTEN] = "listening", 720 [SS_CLOSING] = "closing", 721 }; 722 723 struct sockstat 724 { 725 struct sockstat *next; 726 unsigned int type; 727 uint16_t prot; 728 inet_prefix local; 729 inet_prefix remote; 730 int lport; 731 int rport; 732 int state; 733 int rq, wq; 734 unsigned ino; 735 unsigned uid; 736 int refcnt; 737 unsigned int iface; 738 unsigned long long sk; 739 char *name; 740 char *peer_name; 741 __u32 mark; 742 }; 743 744 struct dctcpstat 745 { 746 unsigned int ce_state; 747 unsigned int alpha; 748 unsigned int ab_ecn; 749 unsigned int ab_tot; 750 bool enabled; 751 }; 752 753 struct tcpstat 754 { 755 struct sockstat ss; 756 int timer; 757 int timeout; 758 int probes; 759 char cong_alg[16]; 760 double rto, ato, rtt, rttvar; 761 int qack, cwnd, ssthresh, backoff; 762 double send_bps; 763 int snd_wscale; 764 int rcv_wscale; 765 int mss; 766 unsigned int lastsnd; 767 unsigned int lastrcv; 768 unsigned int lastack; 769 double pacing_rate; 770 double pacing_rate_max; 771 unsigned long long bytes_acked; 772 unsigned long long bytes_received; 773 unsigned int segs_out; 774 unsigned int segs_in; 775 unsigned int unacked; 776 unsigned int retrans; 777 unsigned int retrans_total; 778 unsigned int lost; 779 unsigned int sacked; 780 unsigned int fackets; 781 unsigned int reordering; 782 double rcv_rtt; 783 int rcv_space; 784 bool has_ts_opt; 785 bool has_sack_opt; 786 bool has_ecn_opt; 787 bool has_ecnseen_opt; 788 bool has_fastopen_opt; 789 bool has_wscale_opt; 790 struct dctcpstat *dctcp; 791 }; 792 793 static void sock_state_print(struct sockstat *s, const char *sock_name) 794 { 795 if (netid_width) 796 printf("%-*s ", netid_width, sock_name); 797 if (state_width) 798 printf("%-*s ", state_width, sstate_name[s->state]); 799 800 printf("%-6d %-6d ", s->rq, s->wq); 801 } 802 803 static void sock_details_print(struct sockstat *s) 804 { 805 if (s->uid) 806 printf(" uid:%u", s->uid); 807 808 printf(" ino:%u", s->ino); 809 printf(" sk:%llx", s->sk); 810 811 if (s->mark) 812 printf(" fwmark:0x%x", s->mark); 813 } 814 815 static void sock_addr_print_width(int addr_len, const char *addr, char *delim, 816 int port_len, const char *port, const char *ifname) 817 { 818 if (ifname) { 819 printf("%*s%%%s%s%-*s ", addr_len, addr, ifname, delim, 820 port_len, port); 821 } 822 else { 823 printf("%*s%s%-*s ", addr_len, addr, delim, port_len, port); 824 } 825 } 826 827 static void sock_addr_print(const char *addr, char *delim, const char *port, 828 const char *ifname) 829 { 830 sock_addr_print_width(addr_width, addr, delim, serv_width, port, ifname); 831 } 832 833 static const char *tmr_name[] = { 834 "off", 835 "on", 836 "keepalive", 837 "timewait", 838 "persist", 839 "unknown" 840 }; 841 842 static const char *print_ms_timer(int timeout) 843 { 844 static char buf[64]; 845 int secs, msecs, minutes; 846 if (timeout < 0) 847 timeout = 0; 848 secs = timeout/1000; 849 minutes = secs/60; 850 secs = secs%60; 851 msecs = timeout%1000; 852 buf[0] = 0; 853 if (minutes) { 854 msecs = 0; 855 snprintf(buf, sizeof(buf)-16, "%dmin", minutes); 856 if (minutes > 9) 857 secs = 0; 858 } 859 if (secs) { 860 if (secs > 9) 861 msecs = 0; 862 sprintf(buf+strlen(buf), "%d%s", secs, msecs ? "." : "sec"); 863 } 864 if (msecs) 865 sprintf(buf+strlen(buf), "%03dms", msecs); 866 return buf; 867 } 868 869 struct scache { 870 struct scache *next; 871 int port; 872 char *name; 873 const char *proto; 874 }; 875 876 struct scache *rlist; 877 878 static void init_service_resolver(void) 879 { 880 char buf[128]; 881 FILE *fp = popen("/usr/sbin/rpcinfo -p 2>/dev/null", "r"); 882 883 if (!fp) 884 return; 885 886 if (!fgets(buf, sizeof(buf), fp)) { 887 pclose(fp); 888 return; 889 } 890 while (fgets(buf, sizeof(buf), fp) != NULL) { 891 unsigned int progn, port; 892 char proto[128], prog[128] = "rpc."; 893 struct scache *c; 894 895 if (sscanf(buf, "%u %*d %s %u %s", 896 &progn, proto, &port, prog+4) != 4) 897 continue; 898 899 if (!(c = malloc(sizeof(*c)))) 900 continue; 901 902 c->port = port; 903 c->name = strdup(prog); 904 if (strcmp(proto, TCP_PROTO) == 0) 905 c->proto = TCP_PROTO; 906 else if (strcmp(proto, UDP_PROTO) == 0) 907 c->proto = UDP_PROTO; 908 else 909 c->proto = NULL; 910 c->next = rlist; 911 rlist = c; 912 } 913 pclose(fp); 914 } 915 916 /* Even do not try default linux ephemeral port ranges: 917 * default /etc/services contains so much of useless crap 918 * wouldbe "allocated" to this area that resolution 919 * is really harmful. I shrug each time when seeing 920 * "socks" or "cfinger" in dumps. 921 */ 922 static int is_ephemeral(int port) 923 { 924 static int min = 0, max = 0; 925 926 if (!min) { 927 FILE *f = ephemeral_ports_open(); 928 if (!f || fscanf(f, "%d %d", &min, &max) < 2) { 929 min = 1024; 930 max = 4999; 931 } 932 if (f) 933 fclose(f); 934 } 935 return port >= min && port <= max; 936 } 937 938 939 static const char *__resolve_service(int port) 940 { 941 struct scache *c; 942 943 for (c = rlist; c; c = c->next) { 944 if (c->port == port && c->proto == dg_proto) 945 return c->name; 946 } 947 948 if (!is_ephemeral(port)) { 949 static int notfirst; 950 struct servent *se; 951 if (!notfirst) { 952 setservent(1); 953 notfirst = 1; 954 } 955 se = getservbyport(htons(port), dg_proto); 956 if (se) 957 return se->s_name; 958 } 959 960 return NULL; 961 } 962 963 #define SCACHE_BUCKETS 1024 964 static struct scache *cache_htab[SCACHE_BUCKETS]; 965 966 static const char *resolve_service(int port) 967 { 968 static char buf[128]; 969 struct scache *c; 970 const char *res; 971 int hash; 972 973 if (port == 0) { 974 buf[0] = '*'; 975 buf[1] = 0; 976 return buf; 977 } 978 979 if (!resolve_services) 980 goto do_numeric; 981 982 if (dg_proto == RAW_PROTO) 983 return inet_proto_n2a(port, buf, sizeof(buf)); 984 985 986 hash = (port^(((unsigned long)dg_proto)>>2)) % SCACHE_BUCKETS; 987 988 for (c = cache_htab[hash]; c; c = c->next) { 989 if (c->port == port && c->proto == dg_proto) 990 goto do_cache; 991 } 992 993 c = malloc(sizeof(*c)); 994 if (!c) 995 goto do_numeric; 996 res = __resolve_service(port); 997 c->port = port; 998 c->name = res ? strdup(res) : NULL; 999 c->proto = dg_proto; 1000 c->next = cache_htab[hash]; 1001 cache_htab[hash] = c; 1002 1003 do_cache: 1004 if (c->name) 1005 return c->name; 1006 1007 do_numeric: 1008 sprintf(buf, "%u", port); 1009 return buf; 1010 } 1011 1012 static void inet_addr_print(const inet_prefix *a, int port, unsigned int ifindex) 1013 { 1014 char buf[1024]; 1015 const char *ap = buf; 1016 int est_len = addr_width; 1017 const char *ifname = NULL; 1018 1019 if (a->family == AF_INET) { 1020 if (a->data[0] == 0) { 1021 buf[0] = '*'; 1022 buf[1] = 0; 1023 } else { 1024 ap = format_host(AF_INET, 4, a->data, buf, sizeof(buf)); 1025 } 1026 } else { 1027 ap = format_host(a->family, 16, a->data, buf, sizeof(buf)); 1028 est_len = strlen(ap); 1029 if (est_len <= addr_width) 1030 est_len = addr_width; 1031 else 1032 est_len = addr_width + ((est_len-addr_width+3)/4)*4; 1033 } 1034 1035 if (ifindex) { 1036 ifname = ll_index_to_name(ifindex); 1037 est_len -= strlen(ifname) + 1; /* +1 for percent char */ 1038 if (est_len < 0) 1039 est_len = 0; 1040 } 1041 1042 sock_addr_print_width(est_len, ap, ":", serv_width, resolve_service(port), 1043 ifname); 1044 } 1045 1046 struct aafilter 1047 { 1048 inet_prefix addr; 1049 int port; 1050 __u32 mark; 1051 __u32 mask; 1052 struct aafilter *next; 1053 }; 1054 1055 static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p, 1056 int plen) 1057 { 1058 if (!inet_addr_match(a, p, plen)) 1059 return 0; 1060 1061 /* Cursed "v4 mapped" addresses: v4 mapped socket matches 1062 * pure IPv4 rule, but v4-mapped rule selects only v4-mapped 1063 * sockets. Fair? */ 1064 if (p->family == AF_INET && a->family == AF_INET6) { 1065 if (a->data[0] == 0 && a->data[1] == 0 && 1066 a->data[2] == htonl(0xffff)) { 1067 inet_prefix tmp = *a; 1068 tmp.data[0] = a->data[3]; 1069 return inet_addr_match(&tmp, p, plen); 1070 } 1071 } 1072 return 1; 1073 } 1074 1075 static int unix_match(const inet_prefix *a, const inet_prefix *p) 1076 { 1077 char *addr, *pattern; 1078 memcpy(&addr, a->data, sizeof(addr)); 1079 memcpy(&pattern, p->data, sizeof(pattern)); 1080 if (pattern == NULL) 1081 return 1; 1082 if (addr == NULL) 1083 addr = ""; 1084 return !fnmatch(pattern, addr, 0); 1085 } 1086 1087 static int run_ssfilter(struct ssfilter *f, struct sockstat *s) 1088 { 1089 switch (f->type) { 1090 case SSF_S_AUTO: 1091 { 1092 if (s->local.family == AF_UNIX) { 1093 char *p; 1094 memcpy(&p, s->local.data, sizeof(p)); 1095 return p == NULL || (p[0] == '@' && strlen(p) == 6 && 1096 strspn(p+1, "0123456789abcdef") == 5); 1097 } 1098 if (s->local.family == AF_PACKET) 1099 return s->lport == 0 && s->local.data[0] == 0; 1100 if (s->local.family == AF_NETLINK) 1101 return s->lport < 0; 1102 1103 return is_ephemeral(s->lport); 1104 } 1105 case SSF_DCOND: 1106 { 1107 struct aafilter *a = (void*)f->pred; 1108 if (a->addr.family == AF_UNIX) 1109 return unix_match(&s->remote, &a->addr); 1110 if (a->port != -1 && a->port != s->rport) 1111 return 0; 1112 if (a->addr.bitlen) { 1113 do { 1114 if (!inet2_addr_match(&s->remote, &a->addr, a->addr.bitlen)) 1115 return 1; 1116 } while ((a = a->next) != NULL); 1117 return 0; 1118 } 1119 return 1; 1120 } 1121 case SSF_SCOND: 1122 { 1123 struct aafilter *a = (void*)f->pred; 1124 if (a->addr.family == AF_UNIX) 1125 return unix_match(&s->local, &a->addr); 1126 if (a->port != -1 && a->port != s->lport) 1127 return 0; 1128 if (a->addr.bitlen) { 1129 do { 1130 if (!inet2_addr_match(&s->local, &a->addr, a->addr.bitlen)) 1131 return 1; 1132 } while ((a = a->next) != NULL); 1133 return 0; 1134 } 1135 return 1; 1136 } 1137 case SSF_D_GE: 1138 { 1139 struct aafilter *a = (void*)f->pred; 1140 return s->rport >= a->port; 1141 } 1142 case SSF_D_LE: 1143 { 1144 struct aafilter *a = (void*)f->pred; 1145 return s->rport <= a->port; 1146 } 1147 case SSF_S_GE: 1148 { 1149 struct aafilter *a = (void*)f->pred; 1150 return s->lport >= a->port; 1151 } 1152 case SSF_S_LE: 1153 { 1154 struct aafilter *a = (void*)f->pred; 1155 return s->lport <= a->port; 1156 } 1157 case SSF_MARKMASK: 1158 { 1159 struct aafilter *a = (void *)f->pred; 1160 1161 return (s->mark & a->mask) == a->mark; 1162 } 1163 /* Yup. It is recursion. Sorry. */ 1164 case SSF_AND: 1165 return run_ssfilter(f->pred, s) && run_ssfilter(f->post, s); 1166 case SSF_OR: 1167 return run_ssfilter(f->pred, s) || run_ssfilter(f->post, s); 1168 case SSF_NOT: 1169 return !run_ssfilter(f->pred, s); 1170 default: 1171 abort(); 1172 } 1173 } 1174 1175 /* Relocate external jumps by reloc. */ 1176 static void ssfilter_patch(char *a, int len, int reloc) 1177 { 1178 while (len > 0) { 1179 struct inet_diag_bc_op *op = (struct inet_diag_bc_op*)a; 1180 if (op->no == len+4) 1181 op->no += reloc; 1182 len -= op->yes; 1183 a += op->yes; 1184 } 1185 if (len < 0) 1186 abort(); 1187 } 1188 1189 static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode) 1190 { 1191 switch (f->type) { 1192 case SSF_S_AUTO: 1193 { 1194 if (!(*bytecode=malloc(4))) abort(); 1195 ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_AUTO, 4, 8 }; 1196 return 4; 1197 } 1198 case SSF_DCOND: 1199 case SSF_SCOND: 1200 { 1201 struct aafilter *a = (void*)f->pred; 1202 struct aafilter *b; 1203 char *ptr; 1204 int code = (f->type == SSF_DCOND ? INET_DIAG_BC_D_COND : INET_DIAG_BC_S_COND); 1205 int len = 0; 1206 1207 for (b=a; b; b=b->next) { 1208 len += 4 + sizeof(struct inet_diag_hostcond); 1209 if (a->addr.family == AF_INET6) 1210 len += 16; 1211 else 1212 len += 4; 1213 if (b->next) 1214 len += 4; 1215 } 1216 if (!(ptr = malloc(len))) abort(); 1217 *bytecode = ptr; 1218 for (b=a; b; b=b->next) { 1219 struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)ptr; 1220 int alen = (a->addr.family == AF_INET6 ? 16 : 4); 1221 int oplen = alen + 4 + sizeof(struct inet_diag_hostcond); 1222 struct inet_diag_hostcond *cond = (struct inet_diag_hostcond*)(ptr+4); 1223 1224 *op = (struct inet_diag_bc_op){ code, oplen, oplen+4 }; 1225 cond->family = a->addr.family; 1226 cond->port = a->port; 1227 cond->prefix_len = a->addr.bitlen; 1228 memcpy(cond->addr, a->addr.data, alen); 1229 ptr += oplen; 1230 if (b->next) { 1231 op = (struct inet_diag_bc_op *)ptr; 1232 *op = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, len - (ptr-*bytecode)}; 1233 ptr += 4; 1234 } 1235 } 1236 return ptr - *bytecode; 1237 } 1238 case SSF_D_GE: 1239 { 1240 struct aafilter *x = (void*)f->pred; 1241 if (!(*bytecode=malloc(8))) abort(); 1242 ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_GE, 8, 12 }; 1243 ((struct inet_diag_bc_op*)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port }; 1244 return 8; 1245 } 1246 case SSF_D_LE: 1247 { 1248 struct aafilter *x = (void*)f->pred; 1249 if (!(*bytecode=malloc(8))) abort(); 1250 ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_LE, 8, 12 }; 1251 ((struct inet_diag_bc_op*)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port }; 1252 return 8; 1253 } 1254 case SSF_S_GE: 1255 { 1256 struct aafilter *x = (void*)f->pred; 1257 if (!(*bytecode=malloc(8))) abort(); 1258 ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_GE, 8, 12 }; 1259 ((struct inet_diag_bc_op*)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port }; 1260 return 8; 1261 } 1262 case SSF_S_LE: 1263 { 1264 struct aafilter *x = (void*)f->pred; 1265 if (!(*bytecode=malloc(8))) abort(); 1266 ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_LE, 8, 12 }; 1267 ((struct inet_diag_bc_op*)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port }; 1268 return 8; 1269 } 1270 1271 case SSF_AND: 1272 { 1273 char *a1, *a2, *a; 1274 int l1, l2; 1275 l1 = ssfilter_bytecompile(f->pred, &a1); 1276 l2 = ssfilter_bytecompile(f->post, &a2); 1277 if (!(a = malloc(l1+l2))) abort(); 1278 memcpy(a, a1, l1); 1279 memcpy(a+l1, a2, l2); 1280 free(a1); free(a2); 1281 ssfilter_patch(a, l1, l2); 1282 *bytecode = a; 1283 return l1+l2; 1284 } 1285 case SSF_OR: 1286 { 1287 char *a1, *a2, *a; 1288 int l1, l2; 1289 l1 = ssfilter_bytecompile(f->pred, &a1); 1290 l2 = ssfilter_bytecompile(f->post, &a2); 1291 if (!(a = malloc(l1+l2+4))) abort(); 1292 memcpy(a, a1, l1); 1293 memcpy(a+l1+4, a2, l2); 1294 free(a1); free(a2); 1295 *(struct inet_diag_bc_op*)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, l2+4 }; 1296 *bytecode = a; 1297 return l1+l2+4; 1298 } 1299 case SSF_NOT: 1300 { 1301 char *a1, *a; 1302 int l1; 1303 l1 = ssfilter_bytecompile(f->pred, &a1); 1304 if (!(a = malloc(l1+4))) abort(); 1305 memcpy(a, a1, l1); 1306 free(a1); 1307 *(struct inet_diag_bc_op*)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, 8 }; 1308 *bytecode = a; 1309 return l1+4; 1310 } 1311 case SSF_MARKMASK: 1312 { 1313 struct aafilter *a = (void *)f->pred; 1314 struct instr { 1315 struct inet_diag_bc_op op; 1316 struct inet_diag_markcond cond; 1317 }; 1318 int inslen = sizeof(struct instr); 1319 1320 if (!(*bytecode = malloc(inslen))) abort(); 1321 ((struct instr *)*bytecode)[0] = (struct instr) { 1322 { INET_DIAG_BC_MARK_COND, inslen, inslen + 4 }, 1323 { a->mark, a->mask}, 1324 }; 1325 1326 return inslen; 1327 } 1328 default: 1329 abort(); 1330 } 1331 } 1332 1333 static int remember_he(struct aafilter *a, struct hostent *he) 1334 { 1335 char **ptr = he->h_addr_list; 1336 int cnt = 0; 1337 int len; 1338 1339 if (he->h_addrtype == AF_INET) 1340 len = 4; 1341 else if (he->h_addrtype == AF_INET6) 1342 len = 16; 1343 else 1344 return 0; 1345 1346 while (*ptr) { 1347 struct aafilter *b = a; 1348 if (a->addr.bitlen) { 1349 if ((b = malloc(sizeof(*b))) == NULL) 1350 return cnt; 1351 *b = *a; 1352 b->next = a->next; 1353 a->next = b; 1354 } 1355 memcpy(b->addr.data, *ptr, len); 1356 b->addr.bytelen = len; 1357 b->addr.bitlen = len*8; 1358 b->addr.family = he->h_addrtype; 1359 ptr++; 1360 cnt++; 1361 } 1362 return cnt; 1363 } 1364 1365 static int get_dns_host(struct aafilter *a, const char *addr, int fam) 1366 { 1367 static int notfirst; 1368 int cnt = 0; 1369 struct hostent *he; 1370 1371 a->addr.bitlen = 0; 1372 if (!notfirst) { 1373 sethostent(1); 1374 notfirst = 1; 1375 } 1376 he = gethostbyname2(addr, fam == AF_UNSPEC ? AF_INET : fam); 1377 if (he) 1378 cnt = remember_he(a, he); 1379 if (fam == AF_UNSPEC) { 1380 he = gethostbyname2(addr, AF_INET6); 1381 if (he) 1382 cnt += remember_he(a, he); 1383 } 1384 return !cnt; 1385 } 1386 1387 static int xll_initted = 0; 1388 1389 static void xll_init(void) 1390 { 1391 struct rtnl_handle rth; 1392 if (rtnl_open(&rth, 0) < 0) 1393 exit(1); 1394 1395 ll_init_map(&rth); 1396 rtnl_close(&rth); 1397 xll_initted = 1; 1398 } 1399 1400 static const char *xll_index_to_name(int index) 1401 { 1402 if (!xll_initted) 1403 xll_init(); 1404 return ll_index_to_name(index); 1405 } 1406 1407 static int xll_name_to_index(const char *dev) 1408 { 1409 if (!xll_initted) 1410 xll_init(); 1411 return ll_name_to_index(dev); 1412 } 1413 1414 void *parse_hostcond(char *addr, bool is_port) 1415 { 1416 char *port = NULL; 1417 struct aafilter a = { .port = -1 }; 1418 struct aafilter *res; 1419 int fam = preferred_family; 1420 struct filter *f = ¤t_filter; 1421 1422 if (fam == AF_UNIX || strncmp(addr, "unix:", 5) == 0) { 1423 char *p; 1424 a.addr.family = AF_UNIX; 1425 if (strncmp(addr, "unix:", 5) == 0) 1426 addr+=5; 1427 p = strdup(addr); 1428 a.addr.bitlen = 8*strlen(p); 1429 memcpy(a.addr.data, &p, sizeof(p)); 1430 fam = AF_UNIX; 1431 goto out; 1432 } 1433 1434 if (fam == AF_PACKET || strncmp(addr, "link:", 5) == 0) { 1435 a.addr.family = AF_PACKET; 1436 a.addr.bitlen = 0; 1437 if (strncmp(addr, "link:", 5) == 0) 1438 addr+=5; 1439 port = strchr(addr, ':'); 1440 if (port) { 1441 *port = 0; 1442 if (port[1] && strcmp(port+1, "*")) { 1443 if (get_integer(&a.port, port+1, 0)) { 1444 if ((a.port = xll_name_to_index(port+1)) <= 0) 1445 return NULL; 1446 } 1447 } 1448 } 1449 if (addr[0] && strcmp(addr, "*")) { 1450 unsigned short tmp; 1451 a.addr.bitlen = 32; 1452 if (ll_proto_a2n(&tmp, addr)) 1453 return NULL; 1454 a.addr.data[0] = ntohs(tmp); 1455 } 1456 fam = AF_PACKET; 1457 goto out; 1458 } 1459 1460 if (fam == AF_NETLINK || strncmp(addr, "netlink:", 8) == 0) { 1461 a.addr.family = AF_NETLINK; 1462 a.addr.bitlen = 0; 1463 if (strncmp(addr, "netlink:", 8) == 0) 1464 addr+=8; 1465 port = strchr(addr, ':'); 1466 if (port) { 1467 *port = 0; 1468 if (port[1] && strcmp(port+1, "*")) { 1469 if (get_integer(&a.port, port+1, 0)) { 1470 if (strcmp(port+1, "kernel") == 0) 1471 a.port = 0; 1472 else 1473 return NULL; 1474 } 1475 } 1476 } 1477 if (addr[0] && strcmp(addr, "*")) { 1478 a.addr.bitlen = 32; 1479 if (nl_proto_a2n(&a.addr.data[0], addr) == -1) 1480 return NULL; 1481 } 1482 fam = AF_NETLINK; 1483 goto out; 1484 } 1485 1486 if (fam == AF_INET || !strncmp(addr, "inet:", 5)) { 1487 fam = AF_INET; 1488 if (!strncmp(addr, "inet:", 5)) 1489 addr += 5; 1490 } else if (fam == AF_INET6 || !strncmp(addr, "inet6:", 6)) { 1491 fam = AF_INET6; 1492 if (!strncmp(addr, "inet6:", 6)) 1493 addr += 6; 1494 } 1495 1496 /* URL-like literal [] */ 1497 if (addr[0] == '[') { 1498 addr++; 1499 if ((port = strchr(addr, ']')) == NULL) 1500 return NULL; 1501 *port++ = 0; 1502 } else if (addr[0] == '*') { 1503 port = addr+1; 1504 } else { 1505 port = strrchr(strchr(addr, '/') ? : addr, ':'); 1506 } 1507 1508 if (is_port) 1509 port = addr; 1510 1511 if (port && *port) { 1512 if (*port == ':') 1513 *port++ = 0; 1514 1515 if (*port && *port != '*') { 1516 if (get_integer(&a.port, port, 0)) { 1517 struct servent *se1 = NULL; 1518 struct servent *se2 = NULL; 1519 if (current_filter.dbs&(1<<UDP_DB)) 1520 se1 = getservbyname(port, UDP_PROTO); 1521 if (current_filter.dbs&(1<<TCP_DB)) 1522 se2 = getservbyname(port, TCP_PROTO); 1523 if (se1 && se2 && se1->s_port != se2->s_port) { 1524 fprintf(stderr, "Error: ambiguous port \"%s\".\n", port); 1525 return NULL; 1526 } 1527 if (!se1) 1528 se1 = se2; 1529 if (se1) { 1530 a.port = ntohs(se1->s_port); 1531 } else { 1532 struct scache *s; 1533 for (s = rlist; s; s = s->next) { 1534 if ((s->proto == UDP_PROTO && 1535 (current_filter.dbs&(1<<UDP_DB))) || 1536 (s->proto == TCP_PROTO && 1537 (current_filter.dbs&(1<<TCP_DB)))) { 1538 if (s->name && strcmp(s->name, port) == 0) { 1539 if (a.port > 0 && a.port != s->port) { 1540 fprintf(stderr, "Error: ambiguous port \"%s\".\n", port); 1541 return NULL; 1542 } 1543 a.port = s->port; 1544 } 1545 } 1546 } 1547 if (a.port <= 0) { 1548 fprintf(stderr, "Error: \"%s\" does not look like a port.\n", port); 1549 return NULL; 1550 } 1551 } 1552 } 1553 } 1554 } 1555 if (!is_port && addr && *addr && *addr != '*') { 1556 if (get_prefix_1(&a.addr, addr, fam)) { 1557 if (get_dns_host(&a, addr, fam)) { 1558 fprintf(stderr, "Error: an inet prefix is expected rather than \"%s\".\n", addr); 1559 return NULL; 1560 } 1561 } 1562 } 1563 1564 out: 1565 if (fam != AF_UNSPEC) { 1566 f->families = 0; 1567 filter_af_set(f, fam); 1568 filter_states_set(f, 0); 1569 } 1570 1571 res = malloc(sizeof(*res)); 1572 if (res) 1573 memcpy(res, &a, sizeof(a)); 1574 return res; 1575 } 1576 1577 void *parse_markmask(const char *markmask) 1578 { 1579 struct aafilter a, *res; 1580 1581 if (strchr(markmask, '/')) { 1582 if (sscanf(markmask, "%i/%i", &a.mark, &a.mask) != 2) 1583 return NULL; 1584 } else { 1585 a.mask = 0xffffffff; 1586 if (sscanf(markmask, "%i", &a.mark) != 1) 1587 return NULL; 1588 } 1589 1590 res = malloc(sizeof(*res)); 1591 if (res) 1592 memcpy(res, &a, sizeof(a)); 1593 return res; 1594 } 1595 1596 static char *proto_name(int protocol) 1597 { 1598 switch (protocol) { 1599 case 0: 1600 return "raw"; 1601 case IPPROTO_UDP: 1602 return "udp"; 1603 case IPPROTO_TCP: 1604 return "tcp"; 1605 case IPPROTO_DCCP: 1606 return "dccp"; 1607 } 1608 1609 return "???"; 1610 } 1611 1612 static void inet_stats_print(struct sockstat *s, int protocol) 1613 { 1614 char *buf = NULL; 1615 1616 sock_state_print(s, proto_name(protocol)); 1617 1618 inet_addr_print(&s->local, s->lport, s->iface); 1619 inet_addr_print(&s->remote, s->rport, 0); 1620 1621 if (show_proc_ctx || show_sock_ctx) { 1622 if (find_entry(s->ino, &buf, 1623 (show_proc_ctx & show_sock_ctx) ? 1624 PROC_SOCK_CTX : PROC_CTX) > 0) { 1625 printf(" users:(%s)", buf); 1626 free(buf); 1627 } 1628 } else if (show_users) { 1629 if (find_entry(s->ino, &buf, USERS) > 0) { 1630 printf(" users:(%s)", buf); 1631 free(buf); 1632 } 1633 } 1634 } 1635 1636 static int proc_parse_inet_addr(char *loc, char *rem, int family, struct 1637 sockstat *s) 1638 { 1639 s->local.family = s->remote.family = family; 1640 if (family == AF_INET) { 1641 sscanf(loc, "%x:%x", s->local.data, (unsigned*)&s->lport); 1642 sscanf(rem, "%x:%x", s->remote.data, (unsigned*)&s->rport); 1643 s->local.bytelen = s->remote.bytelen = 4; 1644 return 0; 1645 } else { 1646 sscanf(loc, "%08x%08x%08x%08x:%x", 1647 s->local.data, 1648 s->local.data + 1, 1649 s->local.data + 2, 1650 s->local.data + 3, 1651 &s->lport); 1652 sscanf(rem, "%08x%08x%08x%08x:%x", 1653 s->remote.data, 1654 s->remote.data + 1, 1655 s->remote.data + 2, 1656 s->remote.data + 3, 1657 &s->rport); 1658 s->local.bytelen = s->remote.bytelen = 16; 1659 return 0; 1660 } 1661 return -1; 1662 } 1663 1664 static int proc_inet_split_line(char *line, char **loc, char **rem, char **data) 1665 { 1666 char *p; 1667 1668 if ((p = strchr(line, ':')) == NULL) 1669 return -1; 1670 1671 *loc = p+2; 1672 if ((p = strchr(*loc, ':')) == NULL) 1673 return -1; 1674 1675 p[5] = 0; 1676 *rem = p+6; 1677 if ((p = strchr(*rem, ':')) == NULL) 1678 return -1; 1679 1680 p[5] = 0; 1681 *data = p+6; 1682 return 0; 1683 } 1684 1685 static char *sprint_bw(char *buf, double bw) 1686 { 1687 if (bw > 1000000.) 1688 sprintf(buf,"%.1fM", bw / 1000000.); 1689 else if (bw > 1000.) 1690 sprintf(buf,"%.1fK", bw / 1000.); 1691 else 1692 sprintf(buf, "%g", bw); 1693 1694 return buf; 1695 } 1696 1697 static void tcp_stats_print(struct tcpstat *s) 1698 { 1699 char b1[64]; 1700 1701 if (s->has_ts_opt) 1702 printf(" ts"); 1703 if (s->has_sack_opt) 1704 printf(" sack"); 1705 if (s->has_ecn_opt) 1706 printf(" ecn"); 1707 if (s->has_ecnseen_opt) 1708 printf(" ecnseen"); 1709 if (s->has_fastopen_opt) 1710 printf(" fastopen"); 1711 if (s->cong_alg[0]) 1712 printf(" %s", s->cong_alg); 1713 if (s->has_wscale_opt) 1714 printf(" wscale:%d,%d", s->snd_wscale, s->rcv_wscale); 1715 if (s->rto) 1716 printf(" rto:%g", s->rto); 1717 if (s->backoff) 1718 printf(" backoff:%u", s->backoff); 1719 if (s->rtt) 1720 printf(" rtt:%g/%g", s->rtt, s->rttvar); 1721 if (s->ato) 1722 printf(" ato:%g", s->ato); 1723 1724 if (s->qack) 1725 printf(" qack:%d", s->qack); 1726 if (s->qack & 1) 1727 printf(" bidir"); 1728 1729 if (s->mss) 1730 printf(" mss:%d", s->mss); 1731 if (s->cwnd) 1732 printf(" cwnd:%d", s->cwnd); 1733 if (s->ssthresh) 1734 printf(" ssthresh:%d", s->ssthresh); 1735 1736 if (s->bytes_acked) 1737 printf(" bytes_acked:%llu", s->bytes_acked); 1738 if (s->bytes_received) 1739 printf(" bytes_received:%llu", s->bytes_received); 1740 if (s->segs_out) 1741 printf(" segs_out:%u", s->segs_out); 1742 if (s->segs_in) 1743 printf(" segs_in:%u", s->segs_in); 1744 1745 if (s->dctcp && s->dctcp->enabled) { 1746 struct dctcpstat *dctcp = s->dctcp; 1747 1748 printf(" dctcp:(ce_state:%u,alpha:%u,ab_ecn:%u,ab_tot:%u)", 1749 dctcp->ce_state, dctcp->alpha, dctcp->ab_ecn, 1750 dctcp->ab_tot); 1751 } else if (s->dctcp) { 1752 printf(" dctcp:fallback_mode"); 1753 } 1754 1755 if (s->send_bps) 1756 printf(" send %sbps", sprint_bw(b1, s->send_bps)); 1757 if (s->lastsnd) 1758 printf(" lastsnd:%u", s->lastsnd); 1759 if (s->lastrcv) 1760 printf(" lastrcv:%u", s->lastrcv); 1761 if (s->lastack) 1762 printf(" lastack:%u", s->lastack); 1763 1764 if (s->pacing_rate) { 1765 printf(" pacing_rate %sbps", sprint_bw(b1, s->pacing_rate)); 1766 if (s->pacing_rate_max) 1767 printf("/%sbps", sprint_bw(b1, 1768 s->pacing_rate_max)); 1769 } 1770 1771 if (s->unacked) 1772 printf(" unacked:%u", s->unacked); 1773 if (s->retrans || s->retrans_total) 1774 printf(" retrans:%u/%u", s->retrans, s->retrans_total); 1775 if (s->lost) 1776 printf(" lost:%u", s->lost); 1777 if (s->sacked && s->ss.state != SS_LISTEN) 1778 printf(" sacked:%u", s->sacked); 1779 if (s->fackets) 1780 printf(" fackets:%u", s->fackets); 1781 if (s->reordering != 3) 1782 printf(" reordering:%d", s->reordering); 1783 if (s->rcv_rtt) 1784 printf(" rcv_rtt:%g", s->rcv_rtt); 1785 if (s->rcv_space) 1786 printf(" rcv_space:%d", s->rcv_space); 1787 } 1788 1789 static void tcp_timer_print(struct tcpstat *s) 1790 { 1791 if (s->timer) { 1792 if (s->timer > 4) 1793 s->timer = 5; 1794 printf(" timer:(%s,%s,%d)", 1795 tmr_name[s->timer], 1796 print_ms_timer(s->timeout), 1797 s->retrans); 1798 } 1799 } 1800 1801 static int tcp_show_line(char *line, const struct filter *f, int family) 1802 { 1803 int rto = 0, ato = 0; 1804 struct tcpstat s = {}; 1805 char *loc, *rem, *data; 1806 char opt[256]; 1807 int n; 1808 int hz = get_user_hz(); 1809 1810 if (proc_inet_split_line(line, &loc, &rem, &data)) 1811 return -1; 1812 1813 int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0'); 1814 if (!(f->states & (1 << state))) 1815 return 0; 1816 1817 proc_parse_inet_addr(loc, rem, family, &s.ss); 1818 1819 if (f->f && run_ssfilter(f->f, &s.ss) == 0) 1820 return 0; 1821 1822 opt[0] = 0; 1823 n = sscanf(data, "%x %x:%x %x:%x %x %d %d %u %d %llx %d %d %d %d %d %[^\n]\n", 1824 &s.ss.state, &s.ss.wq, &s.ss.rq, 1825 &s.timer, &s.timeout, &s.retrans, &s.ss.uid, &s.probes, 1826 &s.ss.ino, &s.ss.refcnt, &s.ss.sk, &rto, &ato, &s.qack, &s.cwnd, 1827 &s.ssthresh, opt); 1828 1829 if (n < 17) 1830 opt[0] = 0; 1831 1832 if (n < 12) { 1833 rto = 0; 1834 s.cwnd = 2; 1835 s.ssthresh = -1; 1836 ato = s.qack = 0; 1837 } 1838 1839 s.retrans = s.timer != 1 ? s.probes : s.retrans; 1840 s.timeout = (s.timeout * 1000 + hz - 1) / hz; 1841 s.ato = (double)ato / hz; 1842 s.qack /= 2; 1843 s.rto = (double)rto; 1844 s.ssthresh = s.ssthresh == -1 ? 0 : s.ssthresh; 1845 s.rto = s.rto != 3 * hz ? s.rto / hz : 0; 1846 1847 inet_stats_print(&s.ss, IPPROTO_TCP); 1848 1849 if (show_options) 1850 tcp_timer_print(&s); 1851 1852 if (show_details) { 1853 sock_details_print(&s.ss); 1854 if (opt[0]) 1855 printf(" opt:\"%s\"", opt); 1856 } 1857 1858 if (show_tcpinfo) 1859 tcp_stats_print(&s); 1860 1861 printf("\n"); 1862 return 0; 1863 } 1864 1865 static int generic_record_read(FILE *fp, 1866 int (*worker)(char*, const struct filter *, int), 1867 const struct filter *f, int fam) 1868 { 1869 char line[256]; 1870 1871 /* skip header */ 1872 if (fgets(line, sizeof(line), fp) == NULL) 1873 goto outerr; 1874 1875 while (fgets(line, sizeof(line), fp) != NULL) { 1876 int n = strlen(line); 1877 if (n == 0 || line[n-1] != '\n') { 1878 errno = -EINVAL; 1879 return -1; 1880 } 1881 line[n-1] = 0; 1882 1883 if (worker(line, f, fam) < 0) 1884 return 0; 1885 } 1886 outerr: 1887 1888 return ferror(fp) ? -1 : 0; 1889 } 1890 1891 static void print_skmeminfo(struct rtattr *tb[], int attrtype) 1892 { 1893 const __u32 *skmeminfo; 1894 1895 if (!tb[attrtype]) { 1896 if (attrtype == INET_DIAG_SKMEMINFO) { 1897 if (!tb[INET_DIAG_MEMINFO]) 1898 return; 1899 1900 const struct inet_diag_meminfo *minfo = 1901 RTA_DATA(tb[INET_DIAG_MEMINFO]); 1902 1903 printf(" mem:(r%u,w%u,f%u,t%u)", 1904 minfo->idiag_rmem, 1905 minfo->idiag_wmem, 1906 minfo->idiag_fmem, 1907 minfo->idiag_tmem); 1908 } 1909 return; 1910 } 1911 1912 skmeminfo = RTA_DATA(tb[attrtype]); 1913 1914 printf(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u", 1915 skmeminfo[SK_MEMINFO_RMEM_ALLOC], 1916 skmeminfo[SK_MEMINFO_RCVBUF], 1917 skmeminfo[SK_MEMINFO_WMEM_ALLOC], 1918 skmeminfo[SK_MEMINFO_SNDBUF], 1919 skmeminfo[SK_MEMINFO_FWD_ALLOC], 1920 skmeminfo[SK_MEMINFO_WMEM_QUEUED], 1921 skmeminfo[SK_MEMINFO_OPTMEM]); 1922 1923 if (RTA_PAYLOAD(tb[attrtype]) >= 1924 (SK_MEMINFO_BACKLOG + 1) * sizeof(__u32)) 1925 printf(",bl%u", skmeminfo[SK_MEMINFO_BACKLOG]); 1926 1927 printf(")"); 1928 } 1929 1930 #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt)) 1931 1932 static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r, 1933 struct rtattr *tb[]) 1934 { 1935 double rtt = 0; 1936 struct tcpstat s = {}; 1937 1938 s.ss.state = r->idiag_state; 1939 1940 print_skmeminfo(tb, INET_DIAG_SKMEMINFO); 1941 1942 if (tb[INET_DIAG_INFO]) { 1943 struct tcp_info *info; 1944 int len = RTA_PAYLOAD(tb[INET_DIAG_INFO]); 1945 1946 /* workaround for older kernels with less fields */ 1947 if (len < sizeof(*info)) { 1948 info = alloca(sizeof(*info)); 1949 memcpy(info, RTA_DATA(tb[INET_DIAG_INFO]), len); 1950 memset((char *)info + len, 0, sizeof(*info) - len); 1951 } else 1952 info = RTA_DATA(tb[INET_DIAG_INFO]); 1953 1954 if (show_options) { 1955 s.has_ts_opt = TCPI_HAS_OPT(info, TCPI_OPT_TIMESTAMPS); 1956 s.has_sack_opt = TCPI_HAS_OPT(info, TCPI_OPT_SACK); 1957 s.has_ecn_opt = TCPI_HAS_OPT(info, TCPI_OPT_ECN); 1958 s.has_ecnseen_opt = TCPI_HAS_OPT(info, TCPI_OPT_ECN_SEEN); 1959 s.has_fastopen_opt = TCPI_HAS_OPT(info, TCPI_OPT_SYN_DATA); 1960 } 1961 1962 if (tb[INET_DIAG_CONG]) 1963 strncpy(s.cong_alg, 1964 rta_getattr_str(tb[INET_DIAG_CONG]), 1965 sizeof(s.cong_alg) - 1); 1966 1967 if (TCPI_HAS_OPT(info, TCPI_OPT_WSCALE)) { 1968 s.has_wscale_opt = true; 1969 s.snd_wscale = info->tcpi_snd_wscale; 1970 s.rcv_wscale = info->tcpi_rcv_wscale; 1971 } 1972 1973 if (info->tcpi_rto && info->tcpi_rto != 3000000) 1974 s.rto = (double)info->tcpi_rto / 1000; 1975 1976 s.backoff = info->tcpi_backoff; 1977 s.rtt = (double)info->tcpi_rtt / 1000; 1978 s.rttvar = (double)info->tcpi_rttvar / 1000; 1979 s.ato = (double)info->tcpi_ato / 1000; 1980 s.mss = info->tcpi_snd_mss; 1981 s.rcv_space = info->tcpi_rcv_space; 1982 s.rcv_rtt = (double)info->tcpi_rcv_rtt / 1000; 1983 s.lastsnd = info->tcpi_last_data_sent; 1984 s.lastrcv = info->tcpi_last_data_recv; 1985 s.lastack = info->tcpi_last_ack_recv; 1986 s.unacked = info->tcpi_unacked; 1987 s.retrans = info->tcpi_retrans; 1988 s.retrans_total = info->tcpi_total_retrans; 1989 s.lost = info->tcpi_lost; 1990 s.sacked = info->tcpi_sacked; 1991 s.reordering = info->tcpi_reordering; 1992 s.rcv_space = info->tcpi_rcv_space; 1993 s.cwnd = info->tcpi_snd_cwnd; 1994 1995 if (info->tcpi_snd_ssthresh < 0xFFFF) 1996 s.ssthresh = info->tcpi_snd_ssthresh; 1997 1998 rtt = (double) info->tcpi_rtt; 1999 if (tb[INET_DIAG_VEGASINFO]) { 2000 const struct tcpvegas_info *vinfo 2001 = RTA_DATA(tb[INET_DIAG_VEGASINFO]); 2002 2003 if (vinfo->tcpv_enabled && 2004 vinfo->tcpv_rtt && vinfo->tcpv_rtt != 0x7fffffff) 2005 rtt = vinfo->tcpv_rtt; 2006 } 2007 2008 if (tb[INET_DIAG_DCTCPINFO]) { 2009 struct dctcpstat *dctcp = malloc(sizeof(struct 2010 dctcpstat)); 2011 2012 const struct tcp_dctcp_info *dinfo 2013 = RTA_DATA(tb[INET_DIAG_DCTCPINFO]); 2014 2015 dctcp->enabled = !!dinfo->dctcp_enabled; 2016 dctcp->ce_state = dinfo->dctcp_ce_state; 2017 dctcp->alpha = dinfo->dctcp_alpha; 2018 dctcp->ab_ecn = dinfo->dctcp_ab_ecn; 2019 dctcp->ab_tot = dinfo->dctcp_ab_tot; 2020 s.dctcp = dctcp; 2021 } 2022 2023 if (rtt > 0 && info->tcpi_snd_mss && info->tcpi_snd_cwnd) { 2024 s.send_bps = (double) info->tcpi_snd_cwnd * 2025 (double)info->tcpi_snd_mss * 8000000. / rtt; 2026 } 2027 2028 if (info->tcpi_pacing_rate && 2029 info->tcpi_pacing_rate != ~0ULL) { 2030 s.pacing_rate = info->tcpi_pacing_rate * 8.; 2031 2032 if (info->tcpi_max_pacing_rate && 2033 info->tcpi_max_pacing_rate != ~0ULL) 2034 s.pacing_rate_max = info->tcpi_max_pacing_rate * 8.; 2035 } 2036 s.bytes_acked = info->tcpi_bytes_acked; 2037 s.bytes_received = info->tcpi_bytes_received; 2038 s.segs_out = info->tcpi_segs_out; 2039 s.segs_in = info->tcpi_segs_in; 2040 tcp_stats_print(&s); 2041 free(s.dctcp); 2042 } 2043 } 2044 2045 static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol) 2046 { 2047 struct rtattr * tb[INET_DIAG_MAX+1]; 2048 struct inet_diag_msg *r = NLMSG_DATA(nlh); 2049 struct sockstat s = {}; 2050 2051 parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr*)(r+1), 2052 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); 2053 2054 s.state = r->idiag_state; 2055 s.local.family = s.remote.family = r->idiag_family; 2056 s.lport = ntohs(r->id.idiag_sport); 2057 s.rport = ntohs(r->id.idiag_dport); 2058 s.wq = r->idiag_wqueue; 2059 s.rq = r->idiag_rqueue; 2060 s.ino = r->idiag_inode; 2061 s.uid = r->idiag_uid; 2062 s.iface = r->id.idiag_if; 2063 s.sk = cookie_sk_get(&r->id.idiag_cookie[0]); 2064 2065 s.mark = 0; 2066 if (tb[INET_DIAG_MARK]) 2067 s.mark = *(__u32 *) RTA_DATA(tb[INET_DIAG_MARK]); 2068 2069 if (s.local.family == AF_INET) { 2070 s.local.bytelen = s.remote.bytelen = 4; 2071 } else { 2072 s.local.bytelen = s.remote.bytelen = 16; 2073 } 2074 2075 memcpy(s.local.data, r->id.idiag_src, s.local.bytelen); 2076 memcpy(s.remote.data, r->id.idiag_dst, s.local.bytelen); 2077 2078 if (f && f->f && run_ssfilter(f->f, &s) == 0) 2079 return 0; 2080 2081 if (tb[INET_DIAG_PROTOCOL]) 2082 protocol = *(__u8 *)RTA_DATA(tb[INET_DIAG_PROTOCOL]); 2083 2084 inet_stats_print(&s, protocol); 2085 2086 if (show_options) { 2087 struct tcpstat t = {}; 2088 2089 t.timer = r->idiag_timer; 2090 t.timeout = r->idiag_expires; 2091 t.retrans = r->idiag_retrans; 2092 tcp_timer_print(&t); 2093 } 2094 2095 if (show_details) { 2096 sock_details_print(&s); 2097 if (s.local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY]) { 2098 unsigned char v6only; 2099 v6only = *(__u8 *)RTA_DATA(tb[INET_DIAG_SKV6ONLY]); 2100 printf(" v6only:%u", v6only); 2101 } 2102 if (tb[INET_DIAG_SHUTDOWN]) { 2103 unsigned char mask; 2104 mask = *(__u8 *)RTA_DATA(tb[INET_DIAG_SHUTDOWN]); 2105 printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>'); 2106 } 2107 } 2108 2109 if (show_mem || show_tcpinfo) { 2110 printf("\n\t"); 2111 tcp_show_info(nlh, r, tb); 2112 } 2113 2114 printf("\n"); 2115 return 0; 2116 } 2117 2118 static int tcpdiag_send(int fd, int protocol, struct filter *f) 2119 { 2120 struct sockaddr_nl nladdr; 2121 struct { 2122 struct nlmsghdr nlh; 2123 struct inet_diag_req r; 2124 } req; 2125 char *bc = NULL; 2126 int bclen; 2127 struct msghdr msg; 2128 struct rtattr rta; 2129 struct iovec iov[3]; 2130 2131 if (protocol == IPPROTO_UDP) 2132 return -1; 2133 2134 memset(&nladdr, 0, sizeof(nladdr)); 2135 nladdr.nl_family = AF_NETLINK; 2136 2137 req.nlh.nlmsg_len = sizeof(req); 2138 if (protocol == IPPROTO_TCP) 2139 req.nlh.nlmsg_type = TCPDIAG_GETSOCK; 2140 else 2141 req.nlh.nlmsg_type = DCCPDIAG_GETSOCK; 2142 req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; 2143 req.nlh.nlmsg_pid = 0; 2144 req.nlh.nlmsg_seq = MAGIC_SEQ; 2145 memset(&req.r, 0, sizeof(req.r)); 2146 req.r.idiag_family = AF_INET; 2147 req.r.idiag_states = f->states; 2148 if (show_mem) { 2149 req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1)); 2150 req.r.idiag_ext |= (1<<(INET_DIAG_SKMEMINFO-1)); 2151 } 2152 2153 if (show_tcpinfo) { 2154 req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1)); 2155 req.r.idiag_ext |= (1<<(INET_DIAG_VEGASINFO-1)); 2156 req.r.idiag_ext |= (1<<(INET_DIAG_CONG-1)); 2157 } 2158 2159 iov[0] = (struct iovec){ 2160 .iov_base = &req, 2161 .iov_len = sizeof(req) 2162 }; 2163 if (f->f) { 2164 bclen = ssfilter_bytecompile(f->f, &bc); 2165 rta.rta_type = INET_DIAG_REQ_BYTECODE; 2166 rta.rta_len = RTA_LENGTH(bclen); 2167 iov[1] = (struct iovec){ &rta, sizeof(rta) }; 2168 iov[2] = (struct iovec){ bc, bclen }; 2169 req.nlh.nlmsg_len += RTA_LENGTH(bclen); 2170 } 2171 2172 msg = (struct msghdr) { 2173 .msg_name = (void*)&nladdr, 2174 .msg_namelen = sizeof(nladdr), 2175 .msg_iov = iov, 2176 .msg_iovlen = f->f ? 3 : 1, 2177 }; 2178 2179 if (sendmsg(fd, &msg, 0) < 0) { 2180 close(fd); 2181 return -1; 2182 } 2183 2184 return 0; 2185 } 2186 2187 static int sockdiag_send(int family, int fd, int protocol, struct filter *f) 2188 { 2189 struct sockaddr_nl nladdr; 2190 DIAG_REQUEST(req, struct inet_diag_req_v2 r); 2191 char *bc = NULL; 2192 int bclen; 2193 struct msghdr msg; 2194 struct rtattr rta; 2195 struct iovec iov[3]; 2196 2197 if (family == PF_UNSPEC) 2198 return tcpdiag_send(fd, protocol, f); 2199 2200 memset(&nladdr, 0, sizeof(nladdr)); 2201 nladdr.nl_family = AF_NETLINK; 2202 2203 memset(&req.r, 0, sizeof(req.r)); 2204 req.r.sdiag_family = family; 2205 req.r.sdiag_protocol = protocol; 2206 req.r.idiag_states = f->states; 2207 if (show_mem) { 2208 req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1)); 2209 req.r.idiag_ext |= (1<<(INET_DIAG_SKMEMINFO-1)); 2210 } 2211 2212 if (show_tcpinfo) { 2213 req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1)); 2214 req.r.idiag_ext |= (1<<(INET_DIAG_VEGASINFO-1)); 2215 req.r.idiag_ext |= (1<<(INET_DIAG_CONG-1)); 2216 } 2217 2218 iov[0] = (struct iovec){ 2219 .iov_base = &req, 2220 .iov_len = sizeof(req) 2221 }; 2222 if (f->f) { 2223 bclen = ssfilter_bytecompile(f->f, &bc); 2224 rta.rta_type = INET_DIAG_REQ_BYTECODE; 2225 rta.rta_len = RTA_LENGTH(bclen); 2226 iov[1] = (struct iovec){ &rta, sizeof(rta) }; 2227 iov[2] = (struct iovec){ bc, bclen }; 2228 req.nlh.nlmsg_len += RTA_LENGTH(bclen); 2229 } 2230 2231 msg = (struct msghdr) { 2232 .msg_name = (void*)&nladdr, 2233 .msg_namelen = sizeof(nladdr), 2234 .msg_iov = iov, 2235 .msg_iovlen = f->f ? 3 : 1, 2236 }; 2237 2238 if (sendmsg(fd, &msg, 0) < 0) { 2239 close(fd); 2240 return -1; 2241 } 2242 2243 return 0; 2244 } 2245 2246 struct inet_diag_arg { 2247 struct filter *f; 2248 int protocol; 2249 struct rtnl_handle *rth; 2250 }; 2251 2252 static int kill_inet_sock(const struct sockaddr_nl *addr, 2253 struct nlmsghdr *h, void *arg) 2254 { 2255 struct inet_diag_msg *d = NLMSG_DATA(h); 2256 struct inet_diag_arg *diag_arg = arg; 2257 struct rtnl_handle *rth = diag_arg->rth; 2258 DIAG_REQUEST(req, struct inet_diag_req_v2 r); 2259 2260 req.nlh.nlmsg_type = SOCK_DESTROY; 2261 req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; 2262 req.nlh.nlmsg_seq = ++rth->seq; 2263 req.r.sdiag_family = d->idiag_family; 2264 req.r.sdiag_protocol = diag_arg->protocol; 2265 req.r.id = d->id; 2266 2267 return rtnl_talk(rth, &req.nlh, NULL, 0); 2268 } 2269 2270 static int show_one_inet_sock(const struct sockaddr_nl *addr, 2271 struct nlmsghdr *h, void *arg) 2272 { 2273 int err; 2274 struct inet_diag_arg *diag_arg = arg; 2275 struct inet_diag_msg *r = NLMSG_DATA(h); 2276 2277 if (!(diag_arg->f->families & (1 << r->idiag_family))) 2278 return 0; 2279 if (diag_arg->f->kill && kill_inet_sock(addr, h, arg) != 0) { 2280 if (errno == EOPNOTSUPP || errno == ENOENT) { 2281 /* Socket can't be closed, or is already closed. */ 2282 return 0; 2283 } else { 2284 perror("SOCK_DESTROY answers"); 2285 return -1; 2286 } 2287 } 2288 if ((err = inet_show_sock(h, diag_arg->f, diag_arg->protocol)) < 0) 2289 return err; 2290 2291 return 0; 2292 } 2293 2294 static int inet_show_netlink(struct filter *f, FILE *dump_fp, int protocol) 2295 { 2296 int err = 0; 2297 struct rtnl_handle rth, rth2; 2298 int family = PF_INET; 2299 struct inet_diag_arg arg = { .f = f, .protocol = protocol }; 2300 2301 if (rtnl_open_byproto(&rth, 0, NETLINK_SOCK_DIAG)) 2302 return -1; 2303 2304 if (f->kill) { 2305 if (rtnl_open_byproto(&rth2, 0, NETLINK_SOCK_DIAG)) { 2306 rtnl_close(&rth); 2307 return -1; 2308 } 2309 arg.rth = &rth2; 2310 } 2311 2312 rth.dump = MAGIC_SEQ; 2313 rth.dump_fp = dump_fp; 2314 if (preferred_family == PF_INET6) 2315 family = PF_INET6; 2316 2317 again: 2318 if ((err = sockdiag_send(family, rth.fd, protocol, f))) 2319 goto Exit; 2320 2321 if ((err = rtnl_dump_filter(&rth, show_one_inet_sock, &arg))) { 2322 if (family != PF_UNSPEC) { 2323 family = PF_UNSPEC; 2324 goto again; 2325 } 2326 goto Exit; 2327 } 2328 if (family == PF_INET && preferred_family != PF_INET) { 2329 family = PF_INET6; 2330 goto again; 2331 } 2332 2333 Exit: 2334 rtnl_close(&rth); 2335 if (arg.rth) 2336 rtnl_close(arg.rth); 2337 return err; 2338 } 2339 2340 static int tcp_show_netlink_file(struct filter *f) 2341 { 2342 FILE *fp; 2343 char buf[16384]; 2344 2345 if ((fp = fopen(getenv("TCPDIAG_FILE"), "r")) == NULL) { 2346 perror("fopen($TCPDIAG_FILE)"); 2347 return -1; 2348 } 2349 2350 while (1) { 2351 int status, err; 2352 struct nlmsghdr *h = (struct nlmsghdr*)buf; 2353 2354 status = fread(buf, 1, sizeof(*h), fp); 2355 if (status < 0) { 2356 perror("Reading header from $TCPDIAG_FILE"); 2357 return -1; 2358 } 2359 if (status != sizeof(*h)) { 2360 perror("Unexpected EOF reading $TCPDIAG_FILE"); 2361 return -1; 2362 } 2363 2364 status = fread(h+1, 1, NLMSG_ALIGN(h->nlmsg_len-sizeof(*h)), fp); 2365 2366 if (status < 0) { 2367 perror("Reading $TCPDIAG_FILE"); 2368 return -1; 2369 } 2370 if (status + sizeof(*h) < h->nlmsg_len) { 2371 perror("Unexpected EOF reading $TCPDIAG_FILE"); 2372 return -1; 2373 } 2374 2375 /* The only legal exit point */ 2376 if (h->nlmsg_type == NLMSG_DONE) 2377 return 0; 2378 2379 if (h->nlmsg_type == NLMSG_ERROR) { 2380 struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); 2381 if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { 2382 fprintf(stderr, "ERROR truncated\n"); 2383 } else { 2384 errno = -err->error; 2385 perror("TCPDIAG answered"); 2386 } 2387 return -1; 2388 } 2389 2390 err = inet_show_sock(h, f, IPPROTO_TCP); 2391 if (err < 0) 2392 return err; 2393 } 2394 } 2395 2396 static int tcp_show(struct filter *f, int socktype) 2397 { 2398 FILE *fp = NULL; 2399 char *buf = NULL; 2400 int bufsize = 64*1024; 2401 2402 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6)) 2403 return 0; 2404 2405 dg_proto = TCP_PROTO; 2406 2407 if (getenv("TCPDIAG_FILE")) 2408 return tcp_show_netlink_file(f); 2409 2410 if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT") 2411 && inet_show_netlink(f, NULL, socktype) == 0) 2412 return 0; 2413 2414 /* Sigh... We have to parse /proc/net/tcp... */ 2415 2416 2417 /* Estimate amount of sockets and try to allocate 2418 * huge buffer to read all the table at one read. 2419 * Limit it by 16MB though. The assumption is: as soon as 2420 * kernel was able to hold information about N connections, 2421 * it is able to give us some memory for snapshot. 2422 */ 2423 if (1) { 2424 get_slabstat(&slabstat); 2425 2426 int guess = slabstat.socks+slabstat.tcp_syns; 2427 if (f->states&(1<<SS_TIME_WAIT)) 2428 guess += slabstat.tcp_tws; 2429 if (guess > (16*1024*1024)/128) 2430 guess = (16*1024*1024)/128; 2431 guess *= 128; 2432 if (guess > bufsize) 2433 bufsize = guess; 2434 } 2435 while (bufsize >= 64*1024) { 2436 if ((buf = malloc(bufsize)) != NULL) 2437 break; 2438 bufsize /= 2; 2439 } 2440 if (buf == NULL) { 2441 errno = ENOMEM; 2442 return -1; 2443 } 2444 2445 if (f->families & (1<<AF_INET)) { 2446 if ((fp = net_tcp_open()) == NULL) 2447 goto outerr; 2448 2449 setbuffer(fp, buf, bufsize); 2450 if (generic_record_read(fp, tcp_show_line, f, AF_INET)) 2451 goto outerr; 2452 fclose(fp); 2453 } 2454 2455 if ((f->families & (1<<AF_INET6)) && 2456 (fp = net_tcp6_open()) != NULL) { 2457 setbuffer(fp, buf, bufsize); 2458 if (generic_record_read(fp, tcp_show_line, f, AF_INET6)) 2459 goto outerr; 2460 fclose(fp); 2461 } 2462 2463 free(buf); 2464 return 0; 2465 2466 outerr: 2467 do { 2468 int saved_errno = errno; 2469 free(buf); 2470 if (fp) 2471 fclose(fp); 2472 errno = saved_errno; 2473 return -1; 2474 } while (0); 2475 } 2476 2477 2478 static int dgram_show_line(char *line, const struct filter *f, int family) 2479 { 2480 struct sockstat s = {}; 2481 char *loc, *rem, *data; 2482 char opt[256]; 2483 int n; 2484 2485 if (proc_inet_split_line(line, &loc, &rem, &data)) 2486 return -1; 2487 2488 int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0'); 2489 if (!(f->states & (1 << state))) 2490 return 0; 2491 2492 proc_parse_inet_addr(loc, rem, family, &s); 2493 2494 if (f->f && run_ssfilter(f->f, &s) == 0) 2495 return 0; 2496 2497 opt[0] = 0; 2498 n = sscanf(data, "%x %x:%x %*x:%*x %*x %d %*d %u %d %llx %[^\n]\n", 2499 &s.state, &s.wq, &s.rq, 2500 &s.uid, &s.ino, 2501 &s.refcnt, &s.sk, opt); 2502 2503 if (n < 9) 2504 opt[0] = 0; 2505 2506 inet_stats_print(&s, dg_proto == UDP_PROTO ? IPPROTO_UDP : 0); 2507 2508 if (show_details && opt[0]) 2509 printf(" opt:\"%s\"", opt); 2510 2511 printf("\n"); 2512 return 0; 2513 } 2514 2515 static int udp_show(struct filter *f) 2516 { 2517 FILE *fp = NULL; 2518 2519 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6)) 2520 return 0; 2521 2522 dg_proto = UDP_PROTO; 2523 2524 if (!getenv("PROC_NET_UDP") && !getenv("PROC_ROOT") 2525 && inet_show_netlink(f, NULL, IPPROTO_UDP) == 0) 2526 return 0; 2527 2528 if (f->families&(1<<AF_INET)) { 2529 if ((fp = net_udp_open()) == NULL) 2530 goto outerr; 2531 if (generic_record_read(fp, dgram_show_line, f, AF_INET)) 2532 goto outerr; 2533 fclose(fp); 2534 } 2535 2536 if ((f->families&(1<<AF_INET6)) && 2537 (fp = net_udp6_open()) != NULL) { 2538 if (generic_record_read(fp, dgram_show_line, f, AF_INET6)) 2539 goto outerr; 2540 fclose(fp); 2541 } 2542 return 0; 2543 2544 outerr: 2545 do { 2546 int saved_errno = errno; 2547 if (fp) 2548 fclose(fp); 2549 errno = saved_errno; 2550 return -1; 2551 } while (0); 2552 } 2553 2554 static int raw_show(struct filter *f) 2555 { 2556 FILE *fp = NULL; 2557 2558 if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6)) 2559 return 0; 2560 2561 dg_proto = RAW_PROTO; 2562 2563 if (f->families&(1<<AF_INET)) { 2564 if ((fp = net_raw_open()) == NULL) 2565 goto outerr; 2566 if (generic_record_read(fp, dgram_show_line, f, AF_INET)) 2567 goto outerr; 2568 fclose(fp); 2569 } 2570 2571 if ((f->families&(1<<AF_INET6)) && 2572 (fp = net_raw6_open()) != NULL) { 2573 if (generic_record_read(fp, dgram_show_line, f, AF_INET6)) 2574 goto outerr; 2575 fclose(fp); 2576 } 2577 return 0; 2578 2579 outerr: 2580 do { 2581 int saved_errno = errno; 2582 if (fp) 2583 fclose(fp); 2584 errno = saved_errno; 2585 return -1; 2586 } while (0); 2587 } 2588 2589 int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT, 2590 SS_ESTABLISHED, SS_CLOSING }; 2591 2592 #define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat)) 2593 2594 static void unix_list_free(struct sockstat *list) 2595 { 2596 while (list) { 2597 struct sockstat *s = list; 2598 2599 list = list->next; 2600 free(s->name); 2601 free(s); 2602 } 2603 } 2604 2605 static const char *unix_netid_name(int type) 2606 { 2607 const char *netid; 2608 2609 switch (type) { 2610 case SOCK_STREAM: 2611 netid = "u_str"; 2612 break; 2613 case SOCK_SEQPACKET: 2614 netid = "u_seq"; 2615 break; 2616 case SOCK_DGRAM: 2617 default: 2618 netid = "u_dgr"; 2619 break; 2620 } 2621 return netid; 2622 } 2623 2624 static bool unix_type_skip(struct sockstat *s, struct filter *f) 2625 { 2626 if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB))) 2627 return true; 2628 if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB))) 2629 return true; 2630 if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB))) 2631 return true; 2632 return false; 2633 } 2634 2635 static bool unix_use_proc(void) 2636 { 2637 return getenv("PROC_NET_UNIX") || getenv("PROC_ROOT"); 2638 } 2639 2640 static void unix_stats_print(struct sockstat *list, struct filter *f) 2641 { 2642 struct sockstat *s; 2643 char *peer; 2644 char *ctx_buf = NULL; 2645 bool use_proc = unix_use_proc(); 2646 char port_name[30] = {}; 2647 2648 for (s = list; s; s = s->next) { 2649 if (!(f->states & (1 << s->state))) 2650 continue; 2651 if (unix_type_skip(s, f)) 2652 continue; 2653 2654 peer = "*"; 2655 if (s->peer_name) 2656 peer = s->peer_name; 2657 2658 if (s->rport && use_proc) { 2659 struct sockstat *p; 2660 2661 for (p = list; p; p = p->next) { 2662 if (s->rport == p->lport) 2663 break; 2664 } 2665 2666 if (!p) { 2667 peer = "?"; 2668 } else { 2669 peer = p->name ? : "*"; 2670 } 2671 } 2672 2673 if (use_proc && f->f) { 2674 struct sockstat st; 2675 st.local.family = AF_UNIX; 2676 st.remote.family = AF_UNIX; 2677 memcpy(st.local.data, &s->name, sizeof(s->name)); 2678 if (strcmp(peer, "*") == 0) 2679 memset(st.remote.data, 0, sizeof(peer)); 2680 else 2681 memcpy(st.remote.data, &peer, sizeof(peer)); 2682 if (run_ssfilter(f->f, &st) == 0) 2683 continue; 2684 } 2685 2686 sock_state_print(s, unix_netid_name(s->type)); 2687 2688 sock_addr_print(s->name ?: "*", " ", 2689 int_to_str(s->lport, port_name), NULL); 2690 sock_addr_print(peer, " ", int_to_str(s->rport, port_name), 2691 NULL); 2692 2693 if (show_proc_ctx || show_sock_ctx) { 2694 if (find_entry(s->ino, &ctx_buf, 2695 (show_proc_ctx & show_sock_ctx) ? 2696 PROC_SOCK_CTX : PROC_CTX) > 0) { 2697 printf(" users:(%s)", ctx_buf); 2698 free(ctx_buf); 2699 } 2700 } else if (show_users) { 2701 if (find_entry(s->ino, &ctx_buf, USERS) > 0) { 2702 printf(" users:(%s)", ctx_buf); 2703 free(ctx_buf); 2704 } 2705 } 2706 printf("\n"); 2707 } 2708 } 2709 2710 static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh, 2711 void *arg) 2712 { 2713 struct filter *f = (struct filter *)arg; 2714 struct unix_diag_msg *r = NLMSG_DATA(nlh); 2715 struct rtattr *tb[UNIX_DIAG_MAX+1]; 2716 char name[128]; 2717 struct sockstat stat = { .name = "*", .peer_name = "*" }; 2718 2719 parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1), 2720 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); 2721 2722 stat.type = r->udiag_type; 2723 stat.state = r->udiag_state; 2724 stat.ino = stat.lport = r->udiag_ino; 2725 stat.local.family = stat.remote.family = AF_UNIX; 2726 2727 if (unix_type_skip(&stat, f)) 2728 return 0; 2729 2730 if (tb[UNIX_DIAG_RQLEN]) { 2731 struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]); 2732 stat.rq = rql->udiag_rqueue; 2733 stat.wq = rql->udiag_wqueue; 2734 } 2735 if (tb[UNIX_DIAG_NAME]) { 2736 int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]); 2737 2738 memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len); 2739 name[len] = '\0'; 2740 if (name[0] == '\0') 2741 name[0] = '@'; 2742 stat.name = &name[0]; 2743 memcpy(stat.local.data, &stat.name, sizeof(stat.name)); 2744 } 2745 if (tb[UNIX_DIAG_PEER]) 2746 stat.rport = rta_getattr_u32(tb[UNIX_DIAG_PEER]); 2747 2748 if (f->f && run_ssfilter(f->f, &stat) == 0) 2749 return 0; 2750 2751 unix_stats_print(&stat, f); 2752 2753 if (show_mem) { 2754 printf("\t"); 2755 print_skmeminfo(tb, UNIX_DIAG_MEMINFO); 2756 } 2757 if (show_details) { 2758 if (tb[UNIX_DIAG_SHUTDOWN]) { 2759 unsigned char mask; 2760 mask = *(__u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]); 2761 printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>'); 2762 } 2763 } 2764 if (show_mem || show_details) 2765 printf("\n"); 2766 2767 return 0; 2768 } 2769 2770 static int handle_netlink_request(struct filter *f, struct nlmsghdr *req, 2771 size_t size, rtnl_filter_t show_one_sock) 2772 { 2773 int ret = -1; 2774 struct rtnl_handle rth; 2775 2776 if (rtnl_open_byproto(&rth, 0, NETLINK_SOCK_DIAG)) 2777 return -1; 2778 2779 rth.dump = MAGIC_SEQ; 2780 2781 if (rtnl_send(&rth, req, size) < 0) 2782 goto Exit; 2783 2784 if (rtnl_dump_filter(&rth, show_one_sock, f)) 2785 goto Exit; 2786 2787 ret = 0; 2788 Exit: 2789 rtnl_close(&rth); 2790 return ret; 2791 } 2792 2793 static int unix_show_netlink(struct filter *f) 2794 { 2795 DIAG_REQUEST(req, struct unix_diag_req r); 2796 2797 req.r.sdiag_family = AF_UNIX; 2798 req.r.udiag_states = f->states; 2799 req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN; 2800 if (show_mem) 2801 req.r.udiag_show |= UDIAG_SHOW_MEMINFO; 2802 2803 return handle_netlink_request(f, &req.nlh, sizeof(req), unix_show_sock); 2804 } 2805 2806 static int unix_show(struct filter *f) 2807 { 2808 FILE *fp; 2809 char buf[256]; 2810 char name[128]; 2811 int newformat = 0; 2812 int cnt; 2813 struct sockstat *list = NULL; 2814 2815 if (!filter_af_get(f, AF_UNIX)) 2816 return 0; 2817 2818 if (!unix_use_proc() && unix_show_netlink(f) == 0) 2819 return 0; 2820 2821 if ((fp = net_unix_open()) == NULL) 2822 return -1; 2823 if (!fgets(buf, sizeof(buf), fp)) { 2824 fclose(fp); 2825 return -1; 2826 } 2827 2828 if (memcmp(buf, "Peer", 4) == 0) 2829 newformat = 1; 2830 cnt = 0; 2831 2832 while (fgets(buf, sizeof(buf), fp)) { 2833 struct sockstat *u, **insp; 2834 int flags; 2835 2836 if (!(u = calloc(1, sizeof(*u)))) 2837 break; 2838 u->name = NULL; 2839 u->peer_name = NULL; 2840 2841 if (sscanf(buf, "%x: %x %x %x %x %x %d %s", 2842 &u->rport, &u->rq, &u->wq, &flags, &u->type, 2843 &u->state, &u->ino, name) < 8) 2844 name[0] = 0; 2845 2846 u->lport = u->ino; 2847 u->local.family = u->remote.family = AF_UNIX; 2848 2849 if (flags & (1 << 16)) { 2850 u->state = SS_LISTEN; 2851 } else { 2852 u->state = unix_state_map[u->state-1]; 2853 if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport) 2854 u->state = SS_ESTABLISHED; 2855 } 2856 2857 if (!newformat) { 2858 u->rport = 0; 2859 u->rq = 0; 2860 u->wq = 0; 2861 } 2862 2863 insp = &list; 2864 while (*insp) { 2865 if (u->type < (*insp)->type || 2866 (u->type == (*insp)->type && 2867 u->ino < (*insp)->ino)) 2868 break; 2869 insp = &(*insp)->next; 2870 } 2871 u->next = *insp; 2872 *insp = u; 2873 2874 if (name[0]) { 2875 if ((u->name = malloc(strlen(name)+1)) == NULL) 2876 break; 2877 strcpy(u->name, name); 2878 } 2879 if (++cnt > MAX_UNIX_REMEMBER) { 2880 unix_stats_print(list, f); 2881 unix_list_free(list); 2882 list = NULL; 2883 cnt = 0; 2884 } 2885 } 2886 fclose(fp); 2887 if (list) { 2888 unix_stats_print(list, f); 2889 unix_list_free(list); 2890 list = NULL; 2891 cnt = 0; 2892 } 2893 2894 return 0; 2895 } 2896 2897 static int packet_stats_print(struct sockstat *s, const struct filter *f) 2898 { 2899 char *buf = NULL; 2900 const char *addr, *port; 2901 char ll_name[16]; 2902 2903 if (f->f) { 2904 s->local.family = AF_PACKET; 2905 s->remote.family = AF_PACKET; 2906 s->local.data[0] = s->prot; 2907 if (run_ssfilter(f->f, s) == 0) 2908 return 1; 2909 } 2910 2911 sock_state_print(s, s->type == SOCK_RAW ? "p_raw" : "p_dgr"); 2912 2913 if (s->prot == 3) 2914 addr = "*"; 2915 else 2916 addr = ll_proto_n2a(htons(s->prot), ll_name, sizeof(ll_name)); 2917 2918 if (s->iface == 0) 2919 port = "*"; 2920 else 2921 port = xll_index_to_name(s->iface); 2922 2923 sock_addr_print(addr, ":", port, NULL); 2924 sock_addr_print("", "*", "", NULL); 2925 2926 if (show_proc_ctx || show_sock_ctx) { 2927 if (find_entry(s->ino, &buf, 2928 (show_proc_ctx & show_sock_ctx) ? 2929 PROC_SOCK_CTX : PROC_CTX) > 0) { 2930 printf(" users:(%s)", buf); 2931 free(buf); 2932 } 2933 } else if (show_users) { 2934 if (find_entry(s->ino, &buf, USERS) > 0) { 2935 printf(" users:(%s)", buf); 2936 free(buf); 2937 } 2938 } 2939 2940 if (show_details) 2941 sock_details_print(s); 2942 2943 return 0; 2944 } 2945 2946 static void packet_show_ring(struct packet_diag_ring *ring) 2947 { 2948 printf("blk_size:%d", ring->pdr_block_size); 2949 printf(",blk_nr:%d", ring->pdr_block_nr); 2950 printf(",frm_size:%d", ring->pdr_frame_size); 2951 printf(",frm_nr:%d", ring->pdr_frame_nr); 2952 printf(",tmo:%d", ring->pdr_retire_tmo); 2953 printf(",features:0x%x", ring->pdr_features); 2954 } 2955 2956 static int packet_show_sock(const struct sockaddr_nl *addr, 2957 struct nlmsghdr *nlh, void *arg) 2958 { 2959 const struct filter *f = arg; 2960 struct packet_diag_msg *r = NLMSG_DATA(nlh); 2961 struct packet_diag_info *pinfo = NULL; 2962 struct packet_diag_ring *ring_rx = NULL, *ring_tx = NULL; 2963 struct rtattr *tb[PACKET_DIAG_MAX+1]; 2964 struct sockstat stat = {}; 2965 uint32_t fanout = 0; 2966 bool has_fanout = false; 2967 2968 parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr*)(r+1), 2969 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); 2970 2971 /* use /proc/net/packet if all info are not available */ 2972 if (!tb[PACKET_DIAG_MEMINFO]) 2973 return -1; 2974 2975 stat.type = r->pdiag_type; 2976 stat.prot = r->pdiag_num; 2977 stat.ino = r->pdiag_ino; 2978 stat.state = SS_CLOSE; 2979 stat.sk = cookie_sk_get(&r->pdiag_cookie[0]); 2980 2981 if (tb[PACKET_DIAG_MEMINFO]) { 2982 __u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]); 2983 stat.rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC]; 2984 } 2985 2986 if (tb[PACKET_DIAG_INFO]) { 2987 pinfo = RTA_DATA(tb[PACKET_DIAG_INFO]); 2988 stat.lport = stat.iface = pinfo->pdi_index; 2989 } 2990 2991 if (tb[PACKET_DIAG_UID]) 2992 stat.uid = *(__u32 *)RTA_DATA(tb[PACKET_DIAG_UID]); 2993 2994 if (tb[PACKET_DIAG_RX_RING]) 2995 ring_rx = RTA_DATA(tb[PACKET_DIAG_RX_RING]); 2996 2997 if (tb[PACKET_DIAG_TX_RING]) 2998 ring_tx = RTA_DATA(tb[PACKET_DIAG_TX_RING]); 2999 3000 if (tb[PACKET_DIAG_FANOUT]) { 3001 has_fanout = true; 3002 fanout = *(uint32_t *)RTA_DATA(tb[PACKET_DIAG_FANOUT]); 3003 } 3004 3005 if (packet_stats_print(&stat, f)) 3006 return 0; 3007 3008 if (show_details) { 3009 if (pinfo) { 3010 printf("\n\tver:%d", pinfo->pdi_version); 3011 printf(" cpy_thresh:%d", pinfo->pdi_copy_thresh); 3012 printf(" flags( "); 3013 if (pinfo->pdi_flags & PDI_RUNNING) 3014 printf("running"); 3015 if (pinfo->pdi_flags & PDI_AUXDATA) 3016 printf(" auxdata"); 3017 if (pinfo->pdi_flags & PDI_ORIGDEV) 3018 printf(" origdev"); 3019 if (pinfo->pdi_flags & PDI_VNETHDR) 3020 printf(" vnethdr"); 3021 if (pinfo->pdi_flags & PDI_LOSS) 3022 printf(" loss"); 3023 if (!pinfo->pdi_flags) 3024 printf("0"); 3025 printf(" )"); 3026 } 3027 if (ring_rx) { 3028 printf("\n\tring_rx("); 3029 packet_show_ring(ring_rx); 3030 printf(")"); 3031 } 3032 if (ring_tx) { 3033 printf("\n\tring_tx("); 3034 packet_show_ring(ring_tx); 3035 printf(")"); 3036 } 3037 if (has_fanout) { 3038 uint16_t type = (fanout >> 16) & 0xffff; 3039 3040 printf("\n\tfanout("); 3041 printf("id:%d,", fanout & 0xffff); 3042 printf("type:"); 3043 3044 if (type == 0) 3045 printf("hash"); 3046 else if (type == 1) 3047 printf("lb"); 3048 else if (type == 2) 3049 printf("cpu"); 3050 else if (type == 3) 3051 printf("roll"); 3052 else if (type == 4) 3053 printf("random"); 3054 else if (type == 5) 3055 printf("qm"); 3056 else 3057 printf("0x%x", type); 3058 3059 printf(")"); 3060 } 3061 } 3062 3063 if (show_bpf && tb[PACKET_DIAG_FILTER]) { 3064 struct sock_filter *fil = 3065 RTA_DATA(tb[PACKET_DIAG_FILTER]); 3066 int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) / 3067 sizeof(struct sock_filter); 3068 3069 printf("\n\tbpf filter (%d): ", num); 3070 while (num) { 3071 printf(" 0x%02x %u %u %u,", 3072 fil->code, fil->jt, fil->jf, fil->k); 3073 num--; 3074 fil++; 3075 } 3076 } 3077 printf("\n"); 3078 return 0; 3079 } 3080 3081 static int packet_show_netlink(struct filter *f) 3082 { 3083 DIAG_REQUEST(req, struct packet_diag_req r); 3084 3085 req.r.sdiag_family = AF_PACKET; 3086 req.r.pdiag_show = PACKET_SHOW_INFO | PACKET_SHOW_MEMINFO | 3087 PACKET_SHOW_FILTER | PACKET_SHOW_RING_CFG | PACKET_SHOW_FANOUT; 3088 3089 return handle_netlink_request(f, &req.nlh, sizeof(req), packet_show_sock); 3090 } 3091 3092 static int packet_show_line(char *buf, const struct filter *f, int fam) 3093 { 3094 unsigned long long sk; 3095 struct sockstat stat = {}; 3096 int type, prot, iface, state, rq, uid, ino; 3097 3098 sscanf(buf, "%llx %*d %d %x %d %d %u %u %u", 3099 &sk, 3100 &type, &prot, &iface, &state, 3101 &rq, &uid, &ino); 3102 3103 if (stat.type == SOCK_RAW && !(f->dbs&(1<<PACKET_R_DB))) 3104 return 0; 3105 if (stat.type == SOCK_DGRAM && !(f->dbs&(1<<PACKET_DG_DB))) 3106 return 0; 3107 3108 stat.type = type; 3109 stat.prot = prot; 3110 stat.lport = stat.iface = iface; 3111 stat.state = state; 3112 stat.rq = rq; 3113 stat.uid = uid; 3114 stat.ino = ino; 3115 stat.state = SS_CLOSE; 3116 3117 if (packet_stats_print(&stat, f)) 3118 return 0; 3119 3120 printf("\n"); 3121 return 0; 3122 } 3123 3124 static int packet_show(struct filter *f) 3125 { 3126 FILE *fp; 3127 int rc = 0; 3128 3129 if (!filter_af_get(f, AF_PACKET) || !(f->states & (1 << SS_CLOSE))) 3130 return 0; 3131 3132 if (!getenv("PROC_NET_PACKET") && !getenv("PROC_ROOT") && 3133 packet_show_netlink(f) == 0) 3134 return 0; 3135 3136 if ((fp = net_packet_open()) == NULL) 3137 return -1; 3138 if (generic_record_read(fp, packet_show_line, f, AF_PACKET)) 3139 rc = -1; 3140 3141 fclose(fp); 3142 return rc; 3143 } 3144 3145 static int netlink_show_one(struct filter *f, 3146 int prot, int pid, unsigned groups, 3147 int state, int dst_pid, unsigned dst_group, 3148 int rq, int wq, 3149 unsigned long long sk, unsigned long long cb) 3150 { 3151 struct sockstat st; 3152 SPRINT_BUF(prot_buf) = {}; 3153 const char *prot_name; 3154 char procname[64] = {}; 3155 3156 st.state = SS_CLOSE; 3157 st.rq = rq; 3158 st.wq = wq; 3159 3160 if (f->f) { 3161 st.local.family = AF_NETLINK; 3162 st.remote.family = AF_NETLINK; 3163 st.rport = -1; 3164 st.lport = pid; 3165 st.local.data[0] = prot; 3166 if (run_ssfilter(f->f, &st) == 0) 3167 return 1; 3168 } 3169 3170 sock_state_print(&st, "nl"); 3171 3172 if (resolve_services) 3173 prot_name = nl_proto_n2a(prot, prot_buf, sizeof(prot_buf)); 3174 else 3175 prot_name = int_to_str(prot, prot_buf); 3176 3177 if (pid == -1) { 3178 procname[0] = '*'; 3179 } else if (resolve_services) { 3180 int done = 0; 3181 if (!pid) { 3182 done = 1; 3183 strncpy(procname, "kernel", 6); 3184 } else if (pid > 0) { 3185 FILE *fp; 3186 snprintf(procname, sizeof(procname), "%s/%d/stat", 3187 getenv("PROC_ROOT") ? : "/proc", pid); 3188 if ((fp = fopen(procname, "r")) != NULL) { 3189 if (fscanf(fp, "%*d (%[^)])", procname) == 1) { 3190 snprintf(procname+strlen(procname), 3191 sizeof(procname)-strlen(procname), 3192 "/%d", pid); 3193 done = 1; 3194 } 3195 fclose(fp); 3196 } 3197 } 3198 if (!done) 3199 int_to_str(pid, procname); 3200 } else { 3201 int_to_str(pid, procname); 3202 } 3203 3204 sock_addr_print(prot_name, ":", procname, NULL); 3205 3206 if (state == NETLINK_CONNECTED) { 3207 char dst_group_buf[30]; 3208 char dst_pid_buf[30]; 3209 sock_addr_print(int_to_str(dst_group, dst_group_buf), ":", 3210 int_to_str(dst_pid, dst_pid_buf), NULL); 3211 } else { 3212 sock_addr_print("", "*", "", NULL); 3213 } 3214 3215 char *pid_context = NULL; 3216 if (show_proc_ctx) { 3217 /* The pid value will either be: 3218 * 0 if destination kernel - show kernel initial context. 3219 * A valid process pid - use getpidcon. 3220 * A unique value allocated by the kernel or netlink user 3221 * to the process - show context as "not available". 3222 */ 3223 if (!pid) 3224 security_get_initial_context("kernel", &pid_context); 3225 else if (pid > 0) 3226 getpidcon(pid, &pid_context); 3227 3228 if (pid_context != NULL) { 3229 printf("proc_ctx=%-*s ", serv_width, pid_context); 3230 free(pid_context); 3231 } else { 3232 printf("proc_ctx=%-*s ", serv_width, "unavailable"); 3233 } 3234 } 3235 3236 if (show_details) { 3237 printf(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups); 3238 } 3239 printf("\n"); 3240 3241 return 0; 3242 } 3243 3244 static int netlink_show_sock(const struct sockaddr_nl *addr, 3245 struct nlmsghdr *nlh, void *arg) 3246 { 3247 struct filter *f = (struct filter *)arg; 3248 struct netlink_diag_msg *r = NLMSG_DATA(nlh); 3249 struct rtattr *tb[NETLINK_DIAG_MAX+1]; 3250 int rq = 0, wq = 0; 3251 unsigned long groups = 0; 3252 3253 parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr*)(r+1), 3254 nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); 3255 3256 if (tb[NETLINK_DIAG_GROUPS] && RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS])) 3257 groups = *(unsigned long *) RTA_DATA(tb[NETLINK_DIAG_GROUPS]); 3258 3259 if (tb[NETLINK_DIAG_MEMINFO]) { 3260 const __u32 *skmeminfo; 3261 skmeminfo = RTA_DATA(tb[NETLINK_DIAG_MEMINFO]); 3262 3263 rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC]; 3264 wq = skmeminfo[SK_MEMINFO_WMEM_ALLOC]; 3265 } 3266 3267 if (netlink_show_one(f, r->ndiag_protocol, r->ndiag_portid, groups, 3268 r->ndiag_state, r->ndiag_dst_portid, r->ndiag_dst_group, 3269 rq, wq, 0, 0)) { 3270 return 0; 3271 } 3272 3273 if (show_mem) { 3274 printf("\t"); 3275 print_skmeminfo(tb, NETLINK_DIAG_MEMINFO); 3276 printf("\n"); 3277 } 3278 3279 return 0; 3280 } 3281 3282 static int netlink_show_netlink(struct filter *f) 3283 { 3284 DIAG_REQUEST(req, struct netlink_diag_req r); 3285 3286 req.r.sdiag_family = AF_NETLINK; 3287 req.r.sdiag_protocol = NDIAG_PROTO_ALL; 3288 req.r.ndiag_show = NDIAG_SHOW_GROUPS | NDIAG_SHOW_MEMINFO; 3289 3290 return handle_netlink_request(f, &req.nlh, sizeof(req), netlink_show_sock); 3291 } 3292 3293 static int netlink_show(struct filter *f) 3294 { 3295 FILE *fp; 3296 char buf[256]; 3297 int prot, pid; 3298 unsigned groups; 3299 int rq, wq, rc; 3300 unsigned long long sk, cb; 3301 3302 if (!filter_af_get(f, AF_NETLINK) || !(f->states & (1 << SS_CLOSE))) 3303 return 0; 3304 3305 if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") && 3306 netlink_show_netlink(f) == 0) 3307 return 0; 3308 3309 if ((fp = net_netlink_open()) == NULL) 3310 return -1; 3311 if (!fgets(buf, sizeof(buf), fp)) { 3312 fclose(fp); 3313 return -1; 3314 } 3315 3316 while (fgets(buf, sizeof(buf), fp)) { 3317 sscanf(buf, "%llx %d %d %x %d %d %llx %d", 3318 &sk, 3319 &prot, &pid, &groups, &rq, &wq, &cb, &rc); 3320 3321 netlink_show_one(f, prot, pid, groups, 0, 0, 0, rq, wq, sk, cb); 3322 } 3323 3324 fclose(fp); 3325 return 0; 3326 } 3327 3328 struct sock_diag_msg { 3329 __u8 sdiag_family; 3330 }; 3331 3332 static int generic_show_sock(const struct sockaddr_nl *addr, 3333 struct nlmsghdr *nlh, void *arg) 3334 { 3335 struct sock_diag_msg *r = NLMSG_DATA(nlh); 3336 struct inet_diag_arg inet_arg = { .f = arg, .protocol = IPPROTO_MAX }; 3337 3338 switch (r->sdiag_family) { 3339 case AF_INET: 3340 case AF_INET6: 3341 return show_one_inet_sock(addr, nlh, &inet_arg); 3342 case AF_UNIX: 3343 return unix_show_sock(addr, nlh, arg); 3344 case AF_PACKET: 3345 return packet_show_sock(addr, nlh, arg); 3346 case AF_NETLINK: 3347 return netlink_show_sock(addr, nlh, arg); 3348 default: 3349 return -1; 3350 } 3351 } 3352 3353 static int handle_follow_request(struct filter *f) 3354 { 3355 int ret = -1; 3356 int groups = 0; 3357 struct rtnl_handle rth; 3358 3359 if (f->families & (1 << AF_INET) && f->dbs & (1 << TCP_DB)) 3360 groups |= 1 << (SKNLGRP_INET_TCP_DESTROY - 1); 3361 if (f->families & (1 << AF_INET) && f->dbs & (1 << UDP_DB)) 3362 groups |= 1 << (SKNLGRP_INET_UDP_DESTROY - 1); 3363 if (f->families & (1 << AF_INET6) && f->dbs & (1 << TCP_DB)) 3364 groups |= 1 << (SKNLGRP_INET6_TCP_DESTROY - 1); 3365 if (f->families & (1 << AF_INET6) && f->dbs & (1 << UDP_DB)) 3366 groups |= 1 << (SKNLGRP_INET6_UDP_DESTROY - 1); 3367 3368 if (groups == 0) 3369 return -1; 3370 3371 if (rtnl_open_byproto(&rth, groups, NETLINK_SOCK_DIAG)) 3372 return -1; 3373 3374 rth.dump = 0; 3375 rth.local.nl_pid = 0; 3376 3377 if (rtnl_dump_filter(&rth, generic_show_sock, f)) 3378 goto Exit; 3379 3380 ret = 0; 3381 Exit: 3382 rtnl_close(&rth); 3383 return ret; 3384 } 3385 3386 struct snmpstat 3387 { 3388 int tcp_estab; 3389 }; 3390 3391 static int get_snmp_int(char *proto, char *key, int *result) 3392 { 3393 char buf[1024]; 3394 FILE *fp; 3395 int protolen = strlen(proto); 3396 int keylen = strlen(key); 3397 3398 *result = 0; 3399 3400 if ((fp = net_snmp_open()) == NULL) 3401 return -1; 3402 3403 while (fgets(buf, sizeof(buf), fp) != NULL) { 3404 char *p = buf; 3405 int pos = 0; 3406 if (memcmp(buf, proto, protolen)) 3407 continue; 3408 while ((p = strchr(p, ' ')) != NULL) { 3409 pos++; 3410 p++; 3411 if (memcmp(p, key, keylen) == 0 && 3412 (p[keylen] == ' ' || p[keylen] == '\n')) 3413 break; 3414 } 3415 if (fgets(buf, sizeof(buf), fp) == NULL) 3416 break; 3417 if (memcmp(buf, proto, protolen)) 3418 break; 3419 p = buf; 3420 while ((p = strchr(p, ' ')) != NULL) { 3421 p++; 3422 if (--pos == 0) { 3423 sscanf(p, "%d", result); 3424 fclose(fp); 3425 return 0; 3426 } 3427 } 3428 } 3429 3430 fclose(fp); 3431 errno = ESRCH; 3432 return -1; 3433 } 3434 3435 3436 /* Get stats from sockstat */ 3437 3438 struct ssummary 3439 { 3440 int socks; 3441 int tcp_mem; 3442 int tcp_total; 3443 int tcp_orphans; 3444 int tcp_tws; 3445 int tcp4_hashed; 3446 int udp4; 3447 int raw4; 3448 int frag4; 3449 int frag4_mem; 3450 int tcp6_hashed; 3451 int udp6; 3452 int raw6; 3453 int frag6; 3454 int frag6_mem; 3455 }; 3456 3457 static void get_sockstat_line(char *line, struct ssummary *s) 3458 { 3459 char id[256], rem[256]; 3460 3461 if (sscanf(line, "%[^ ] %[^\n]\n", id, rem) != 2) 3462 return; 3463 3464 if (strcmp(id, "sockets:") == 0) 3465 sscanf(rem, "%*s%d", &s->socks); 3466 else if (strcmp(id, "UDP:") == 0) 3467 sscanf(rem, "%*s%d", &s->udp4); 3468 else if (strcmp(id, "UDP6:") == 0) 3469 sscanf(rem, "%*s%d", &s->udp6); 3470 else if (strcmp(id, "RAW:") == 0) 3471 sscanf(rem, "%*s%d", &s->raw4); 3472 else if (strcmp(id, "RAW6:") == 0) 3473 sscanf(rem, "%*s%d", &s->raw6); 3474 else if (strcmp(id, "TCP6:") == 0) 3475 sscanf(rem, "%*s%d", &s->tcp6_hashed); 3476 else if (strcmp(id, "FRAG:") == 0) 3477 sscanf(rem, "%*s%d%*s%d", &s->frag4, &s->frag4_mem); 3478 else if (strcmp(id, "FRAG6:") == 0) 3479 sscanf(rem, "%*s%d%*s%d", &s->frag6, &s->frag6_mem); 3480 else if (strcmp(id, "TCP:") == 0) 3481 sscanf(rem, "%*s%d%*s%d%*s%d%*s%d%*s%d", 3482 &s->tcp4_hashed, 3483 &s->tcp_orphans, &s->tcp_tws, &s->tcp_total, &s->tcp_mem); 3484 } 3485 3486 static int get_sockstat(struct ssummary *s) 3487 { 3488 char buf[256]; 3489 FILE *fp; 3490 3491 memset(s, 0, sizeof(*s)); 3492 3493 if ((fp = net_sockstat_open()) == NULL) 3494 return -1; 3495 while(fgets(buf, sizeof(buf), fp) != NULL) 3496 get_sockstat_line(buf, s); 3497 fclose(fp); 3498 3499 if ((fp = net_sockstat6_open()) == NULL) 3500 return 0; 3501 while(fgets(buf, sizeof(buf), fp) != NULL) 3502 get_sockstat_line(buf, s); 3503 fclose(fp); 3504 3505 return 0; 3506 } 3507 3508 static int print_summary(void) 3509 { 3510 struct ssummary s; 3511 struct snmpstat sn; 3512 3513 if (get_sockstat(&s) < 0) 3514 perror("ss: get_sockstat"); 3515 if (get_snmp_int("Tcp:", "CurrEstab", &sn.tcp_estab) < 0) 3516 perror("ss: get_snmpstat"); 3517 3518 get_slabstat(&slabstat); 3519 3520 printf("Total: %d (kernel %d)\n", s.socks, slabstat.socks); 3521 3522 printf("TCP: %d (estab %d, closed %d, orphaned %d, synrecv %d, timewait %d/%d), ports %d\n", 3523 s.tcp_total + slabstat.tcp_syns + s.tcp_tws, 3524 sn.tcp_estab, 3525 s.tcp_total - (s.tcp4_hashed+s.tcp6_hashed-s.tcp_tws), 3526 s.tcp_orphans, 3527 slabstat.tcp_syns, 3528 s.tcp_tws, slabstat.tcp_tws, 3529 slabstat.tcp_ports 3530 ); 3531 3532 printf("\n"); 3533 printf("Transport Total IP IPv6\n"); 3534 printf("* %-9d %-9s %-9s\n", slabstat.socks, "-", "-"); 3535 printf("RAW %-9d %-9d %-9d\n", s.raw4+s.raw6, s.raw4, s.raw6); 3536 printf("UDP %-9d %-9d %-9d\n", s.udp4+s.udp6, s.udp4, s.udp6); 3537 printf("TCP %-9d %-9d %-9d\n", s.tcp4_hashed+s.tcp6_hashed, s.tcp4_hashed, s.tcp6_hashed); 3538 printf("INET %-9d %-9d %-9d\n", 3539 s.raw4+s.udp4+s.tcp4_hashed+ 3540 s.raw6+s.udp6+s.tcp6_hashed, 3541 s.raw4+s.udp4+s.tcp4_hashed, 3542 s.raw6+s.udp6+s.tcp6_hashed); 3543 printf("FRAG %-9d %-9d %-9d\n", s.frag4+s.frag6, s.frag4, s.frag6); 3544 3545 printf("\n"); 3546 3547 return 0; 3548 } 3549 3550 static void _usage(FILE *dest) 3551 { 3552 fprintf(dest, 3553 "Usage: ss [ OPTIONS ]\n" 3554 " ss [ OPTIONS ] [ FILTER ]\n" 3555 " -h, --help this message\n" 3556 " -V, --version output version information\n" 3557 " -n, --numeric don't resolve service names\n" 3558 " -r, --resolve resolve host names\n" 3559 " -a, --all display all sockets\n" 3560 " -l, --listening display listening sockets\n" 3561 " -o, --options show timer information\n" 3562 " -e, --extended show detailed socket information\n" 3563 " -m, --memory show socket memory usage\n" 3564 " -p, --processes show process using socket\n" 3565 " -i, --info show internal TCP information\n" 3566 " -s, --summary show socket usage summary\n" 3567 " -b, --bpf show bpf filter socket information\n" 3568 " -E, --events continually display sockets as they are destroyed\n" 3569 " -Z, --context display process SELinux security contexts\n" 3570 " -z, --contexts display process and socket SELinux security contexts\n" 3571 " -N, --net switch to the specified network namespace name\n" 3572 "\n" 3573 " -4, --ipv4 display only IP version 4 sockets\n" 3574 " -6, --ipv6 display only IP version 6 sockets\n" 3575 " -0, --packet display PACKET sockets\n" 3576 " -t, --tcp display only TCP sockets\n" 3577 " -u, --udp display only UDP sockets\n" 3578 " -d, --dccp display only DCCP sockets\n" 3579 " -w, --raw display only RAW sockets\n" 3580 " -x, --unix display only Unix domain sockets\n" 3581 " -f, --family=FAMILY display sockets of type FAMILY\n" 3582 "\n" 3583 " -K, --kill forcibly close sockets, display what was closed\n" 3584 "\n" 3585 " -A, --query=QUERY, --socket=QUERY\n" 3586 " QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink}[,QUERY]\n" 3587 "\n" 3588 " -D, --diag=FILE Dump raw information about TCP sockets to FILE\n" 3589 " -F, --filter=FILE read filter information from FILE\n" 3590 " FILTER := [ state STATE-FILTER ] [ EXPRESSION ]\n" 3591 " STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}\n" 3592 " TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listen|closing}\n" 3593 " connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n" 3594 " synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}\n" 3595 " bucket := {syn-recv|time-wait}\n" 3596 " big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listen|closing}\n" 3597 ); 3598 } 3599 3600 static void help(void) __attribute__((noreturn)); 3601 static void help(void) 3602 { 3603 _usage(stdout); 3604 exit(0); 3605 } 3606 3607 static void usage(void) __attribute__((noreturn)); 3608 static void usage(void) 3609 { 3610 _usage(stderr); 3611 exit(-1); 3612 } 3613 3614 3615 static int scan_state(const char *state) 3616 { 3617 int i; 3618 if (strcasecmp(state, "close") == 0 || 3619 strcasecmp(state, "closed") == 0) 3620 return (1<<SS_CLOSE); 3621 if (strcasecmp(state, "syn-rcv") == 0) 3622 return (1<<SS_SYN_RECV); 3623 if (strcasecmp(state, "established") == 0) 3624 return (1<<SS_ESTABLISHED); 3625 if (strcasecmp(state, "all") == 0) 3626 return SS_ALL; 3627 if (strcasecmp(state, "connected") == 0) 3628 return SS_ALL & ~((1<<SS_CLOSE)|(1<<SS_LISTEN)); 3629 if (strcasecmp(state, "synchronized") == 0) 3630 return SS_ALL & ~((1<<SS_CLOSE)|(1<<SS_LISTEN)|(1<<SS_SYN_SENT)); 3631 if (strcasecmp(state, "bucket") == 0) 3632 return (1<<SS_SYN_RECV)|(1<<SS_TIME_WAIT); 3633 if (strcasecmp(state, "big") == 0) 3634 return SS_ALL & ~((1<<SS_SYN_RECV)|(1<<SS_TIME_WAIT)); 3635 for (i=0; i<SS_MAX; i++) { 3636 if (strcasecmp(state, sstate_namel[i]) == 0) 3637 return (1<<i); 3638 } 3639 3640 fprintf(stderr, "ss: wrong state name: %s\n", state); 3641 exit(-1); 3642 } 3643 3644 static const struct option long_opts[] = { 3645 { "numeric", 0, 0, 'n' }, 3646 { "resolve", 0, 0, 'r' }, 3647 { "options", 0, 0, 'o' }, 3648 { "extended", 0, 0, 'e' }, 3649 { "memory", 0, 0, 'm' }, 3650 { "info", 0, 0, 'i' }, 3651 { "processes", 0, 0, 'p' }, 3652 { "bpf", 0, 0, 'b' }, 3653 { "events", 0, 0, 'E' }, 3654 { "dccp", 0, 0, 'd' }, 3655 { "tcp", 0, 0, 't' }, 3656 { "udp", 0, 0, 'u' }, 3657 { "raw", 0, 0, 'w' }, 3658 { "unix", 0, 0, 'x' }, 3659 { "all", 0, 0, 'a' }, 3660 { "listening", 0, 0, 'l' }, 3661 { "ipv4", 0, 0, '4' }, 3662 { "ipv6", 0, 0, '6' }, 3663 { "packet", 0, 0, '0' }, 3664 { "family", 1, 0, 'f' }, 3665 { "socket", 1, 0, 'A' }, 3666 { "query", 1, 0, 'A' }, 3667 { "summary", 0, 0, 's' }, 3668 { "diag", 1, 0, 'D' }, 3669 { "filter", 1, 0, 'F' }, 3670 { "version", 0, 0, 'V' }, 3671 { "help", 0, 0, 'h' }, 3672 { "context", 0, 0, 'Z' }, 3673 { "contexts", 0, 0, 'z' }, 3674 { "net", 1, 0, 'N' }, 3675 { "kill", 0, 0, 'K' }, 3676 { 0 } 3677 3678 }; 3679 3680 int main(int argc, char *argv[]) 3681 { 3682 int saw_states = 0; 3683 int saw_query = 0; 3684 int do_summary = 0; 3685 const char *dump_tcpdiag = NULL; 3686 FILE *filter_fp = NULL; 3687 int ch; 3688 int state_filter = 0; 3689 3690 while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbEf:miA:D:F:vVzZN:K", 3691 long_opts, NULL)) != EOF) { 3692 switch(ch) { 3693 case 'n': 3694 resolve_services = 0; 3695 break; 3696 case 'r': 3697 resolve_hosts = 1; 3698 break; 3699 case 'o': 3700 show_options = 1; 3701 break; 3702 case 'e': 3703 show_options = 1; 3704 show_details++; 3705 break; 3706 case 'm': 3707 show_mem = 1; 3708 break; 3709 case 'i': 3710 show_tcpinfo = 1; 3711 break; 3712 case 'p': 3713 show_users++; 3714 user_ent_hash_build(); 3715 break; 3716 case 'b': 3717 show_options = 1; 3718 show_bpf++; 3719 break; 3720 case 'E': 3721 follow_events = 1; 3722 break; 3723 case 'd': 3724 filter_db_set(¤t_filter, DCCP_DB); 3725 break; 3726 case 't': 3727 filter_db_set(¤t_filter, TCP_DB); 3728 break; 3729 case 'u': 3730 filter_db_set(¤t_filter, UDP_DB); 3731 break; 3732 case 'w': 3733 filter_db_set(¤t_filter, RAW_DB); 3734 break; 3735 case 'x': 3736 filter_af_set(¤t_filter, AF_UNIX); 3737 break; 3738 case 'a': 3739 state_filter = SS_ALL; 3740 break; 3741 case 'l': 3742 state_filter = (1 << SS_LISTEN) | (1 << SS_CLOSE); 3743 break; 3744 case '4': 3745 filter_af_set(¤t_filter, AF_INET); 3746 break; 3747 case '6': 3748 filter_af_set(¤t_filter, AF_INET6); 3749 break; 3750 case '0': 3751 filter_af_set(¤t_filter, AF_PACKET); 3752 break; 3753 case 'f': 3754 if (strcmp(optarg, "inet") == 0) 3755 filter_af_set(¤t_filter, AF_INET); 3756 else if (strcmp(optarg, "inet6") == 0) 3757 filter_af_set(¤t_filter, AF_INET6); 3758 else if (strcmp(optarg, "link") == 0) 3759 filter_af_set(¤t_filter, AF_PACKET); 3760 else if (strcmp(optarg, "unix") == 0) 3761 filter_af_set(¤t_filter, AF_UNIX); 3762 else if (strcmp(optarg, "netlink") == 0) 3763 filter_af_set(¤t_filter, AF_NETLINK); 3764 else if (strcmp(optarg, "help") == 0) 3765 help(); 3766 else { 3767 fprintf(stderr, "ss: \"%s\" is invalid family\n", 3768 optarg); 3769 usage(); 3770 } 3771 break; 3772 case 'A': 3773 { 3774 char *p, *p1; 3775 if (!saw_query) { 3776 current_filter.dbs = 0; 3777 state_filter = state_filter ? 3778 state_filter : SS_CONN; 3779 saw_query = 1; 3780 do_default = 0; 3781 } 3782 p = p1 = optarg; 3783 do { 3784 if ((p1 = strchr(p, ',')) != NULL) 3785 *p1 = 0; 3786 if (strcmp(p, "all") == 0) { 3787 filter_default_dbs(¤t_filter); 3788 } else if (strcmp(p, "inet") == 0) { 3789 filter_db_set(¤t_filter, UDP_DB); 3790 filter_db_set(¤t_filter, DCCP_DB); 3791 filter_db_set(¤t_filter, TCP_DB); 3792 filter_db_set(¤t_filter, RAW_DB); 3793 } else if (strcmp(p, "udp") == 0) { 3794 filter_db_set(¤t_filter, UDP_DB); 3795 } else if (strcmp(p, "dccp") == 0) { 3796 filter_db_set(¤t_filter, DCCP_DB); 3797 } else if (strcmp(p, "tcp") == 0) { 3798 filter_db_set(¤t_filter, TCP_DB); 3799 } else if (strcmp(p, "raw") == 0) { 3800 filter_db_set(¤t_filter, RAW_DB); 3801 } else if (strcmp(p, "unix") == 0) { 3802 filter_db_set(¤t_filter, UNIX_ST_DB); 3803 filter_db_set(¤t_filter, UNIX_DG_DB); 3804 filter_db_set(¤t_filter, UNIX_SQ_DB); 3805 } else if (strcasecmp(p, "unix_stream") == 0 || 3806 strcmp(p, "u_str") == 0) { 3807 filter_db_set(¤t_filter, UNIX_ST_DB); 3808 } else if (strcasecmp(p, "unix_dgram") == 0 || 3809 strcmp(p, "u_dgr") == 0) { 3810 filter_db_set(¤t_filter, UNIX_DG_DB); 3811 } else if (strcasecmp(p, "unix_seqpacket") == 0 || 3812 strcmp(p, "u_seq") == 0) { 3813 filter_db_set(¤t_filter, UNIX_SQ_DB); 3814 } else if (strcmp(p, "packet") == 0) { 3815 filter_db_set(¤t_filter, PACKET_R_DB); 3816 filter_db_set(¤t_filter, PACKET_DG_DB); 3817 } else if (strcmp(p, "packet_raw") == 0 || 3818 strcmp(p, "p_raw") == 0) { 3819 filter_db_set(¤t_filter, PACKET_R_DB); 3820 } else if (strcmp(p, "packet_dgram") == 0 || 3821 strcmp(p, "p_dgr") == 0) { 3822 filter_db_set(¤t_filter, PACKET_DG_DB); 3823 } else if (strcmp(p, "netlink") == 0) { 3824 filter_db_set(¤t_filter, NETLINK_DB); 3825 } else { 3826 fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p); 3827 usage(); 3828 } 3829 p = p1 + 1; 3830 } while (p1); 3831 break; 3832 } 3833 case 's': 3834 do_summary = 1; 3835 break; 3836 case 'D': 3837 dump_tcpdiag = optarg; 3838 break; 3839 case 'F': 3840 if (filter_fp) { 3841 fprintf(stderr, "More than one filter file\n"); 3842 exit(-1); 3843 } 3844 if (optarg[0] == '-') 3845 filter_fp = stdin; 3846 else 3847 filter_fp = fopen(optarg, "r"); 3848 if (!filter_fp) { 3849 perror("fopen filter file"); 3850 exit(-1); 3851 } 3852 break; 3853 case 'v': 3854 case 'V': 3855 printf("ss utility, iproute2-ss%s\n", SNAPSHOT); 3856 exit(0); 3857 case 'z': 3858 show_sock_ctx++; 3859 case 'Z': 3860 if (is_selinux_enabled() <= 0) { 3861 fprintf(stderr, "ss: SELinux is not enabled.\n"); 3862 exit(1); 3863 } 3864 show_proc_ctx++; 3865 user_ent_hash_build(); 3866 break; 3867 case 'N': 3868 if (netns_switch(optarg)) 3869 exit(1); 3870 break; 3871 case 'K': 3872 current_filter.kill = 1; 3873 break; 3874 case 'h': 3875 help(); 3876 case '?': 3877 default: 3878 usage(); 3879 } 3880 } 3881 3882 argc -= optind; 3883 argv += optind; 3884 3885 if (do_summary) { 3886 print_summary(); 3887 if (do_default && argc == 0) 3888 exit(0); 3889 } 3890 3891 while (argc > 0) { 3892 if (strcmp(*argv, "state") == 0) { 3893 NEXT_ARG(); 3894 if (!saw_states) 3895 state_filter = 0; 3896 state_filter |= scan_state(*argv); 3897 saw_states = 1; 3898 } else if (strcmp(*argv, "exclude") == 0 || 3899 strcmp(*argv, "excl") == 0) { 3900 NEXT_ARG(); 3901 if (!saw_states) 3902 state_filter = SS_ALL; 3903 state_filter &= ~scan_state(*argv); 3904 saw_states = 1; 3905 } else { 3906 break; 3907 } 3908 argc--; argv++; 3909 } 3910 3911 if (do_default) { 3912 state_filter = state_filter ? state_filter : SS_CONN; 3913 filter_default_dbs(¤t_filter); 3914 } 3915 3916 filter_states_set(¤t_filter, state_filter); 3917 filter_merge_defaults(¤t_filter); 3918 3919 if (resolve_services && resolve_hosts && 3920 (current_filter.dbs&(UNIX_DBM|(1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)))) 3921 init_service_resolver(); 3922 3923 3924 if (current_filter.dbs == 0) { 3925 fprintf(stderr, "ss: no socket tables to show with such filter.\n"); 3926 exit(0); 3927 } 3928 if (current_filter.families == 0) { 3929 fprintf(stderr, "ss: no families to show with such filter.\n"); 3930 exit(0); 3931 } 3932 if (current_filter.states == 0) { 3933 fprintf(stderr, "ss: no socket states to show with such filter.\n"); 3934 exit(0); 3935 } 3936 3937 if (dump_tcpdiag) { 3938 FILE *dump_fp = stdout; 3939 if (!(current_filter.dbs & (1<<TCP_DB))) { 3940 fprintf(stderr, "ss: tcpdiag dump requested and no tcp in filter.\n"); 3941 exit(0); 3942 } 3943 if (dump_tcpdiag[0] != '-') { 3944 dump_fp = fopen(dump_tcpdiag, "w"); 3945 if (!dump_tcpdiag) { 3946 perror("fopen dump file"); 3947 exit(-1); 3948 } 3949 } 3950 inet_show_netlink(¤t_filter, dump_fp, IPPROTO_TCP); 3951 fflush(dump_fp); 3952 exit(0); 3953 } 3954 3955 if (ssfilter_parse(¤t_filter.f, argc, argv, filter_fp)) 3956 usage(); 3957 3958 netid_width = 0; 3959 if (current_filter.dbs&(current_filter.dbs-1)) 3960 netid_width = 5; 3961 3962 state_width = 0; 3963 if (current_filter.states&(current_filter.states-1)) 3964 state_width = 10; 3965 3966 screen_width = 80; 3967 if (isatty(STDOUT_FILENO)) { 3968 struct winsize w; 3969 3970 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) { 3971 if (w.ws_col > 0) 3972 screen_width = w.ws_col; 3973 } 3974 } 3975 3976 addrp_width = screen_width; 3977 addrp_width -= netid_width+1; 3978 addrp_width -= state_width+1; 3979 addrp_width -= 14; 3980 3981 if (addrp_width&1) { 3982 if (netid_width) 3983 netid_width++; 3984 else if (state_width) 3985 state_width++; 3986 } 3987 3988 addrp_width /= 2; 3989 addrp_width--; 3990 3991 serv_width = resolve_services ? 7 : 5; 3992 3993 if (addrp_width < 15+serv_width+1) 3994 addrp_width = 15+serv_width+1; 3995 3996 addr_width = addrp_width - serv_width - 1; 3997 3998 if (netid_width) 3999 printf("%-*s ", netid_width, "Netid"); 4000 if (state_width) 4001 printf("%-*s ", state_width, "State"); 4002 printf("%-6s %-6s ", "Recv-Q", "Send-Q"); 4003 4004 /* Make enough space for the local/remote port field */ 4005 addr_width -= 13; 4006 serv_width += 13; 4007 4008 printf("%*s:%-*s %*s:%-*s\n", 4009 addr_width, "Local Address", serv_width, "Port", 4010 addr_width, "Peer Address", serv_width, "Port"); 4011 4012 fflush(stdout); 4013 4014 if (follow_events) 4015 exit(handle_follow_request(¤t_filter)); 4016 4017 if (current_filter.dbs & (1<<NETLINK_DB)) 4018 netlink_show(¤t_filter); 4019 if (current_filter.dbs & PACKET_DBM) 4020 packet_show(¤t_filter); 4021 if (current_filter.dbs & UNIX_DBM) 4022 unix_show(¤t_filter); 4023 if (current_filter.dbs & (1<<RAW_DB)) 4024 raw_show(¤t_filter); 4025 if (current_filter.dbs & (1<<UDP_DB)) 4026 udp_show(¤t_filter); 4027 if (current_filter.dbs & (1<<TCP_DB)) 4028 tcp_show(¤t_filter, IPPROTO_TCP); 4029 if (current_filter.dbs & (1<<DCCP_DB)) 4030 tcp_show(¤t_filter, IPPROTO_DCCP); 4031 4032 if (show_users || show_proc_ctx || show_sock_ctx) 4033 user_ent_destroy(); 4034 4035 return 0; 4036 } 4037