1 /* 2 * inet_diag.c Module for monitoring INET transport protocols sockets. 3 * 4 * Version: $Id: inet_diag.c,v 1.3 2002/02/01 22:01:04 davem Exp $ 5 * 6 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 11 * 2 of the License, or (at your option) any later version. 12 */ 13 14 #include <linux/config.h> 15 #include <linux/module.h> 16 #include <linux/types.h> 17 #include <linux/fcntl.h> 18 #include <linux/random.h> 19 #include <linux/cache.h> 20 #include <linux/init.h> 21 #include <linux/time.h> 22 23 #include <net/icmp.h> 24 #include <net/tcp.h> 25 #include <net/ipv6.h> 26 #include <net/inet_common.h> 27 #include <net/inet_connection_sock.h> 28 #include <net/inet_hashtables.h> 29 #include <net/inet_timewait_sock.h> 30 #include <net/inet6_hashtables.h> 31 32 #include <linux/inet.h> 33 #include <linux/stddef.h> 34 35 #include <linux/inet_diag.h> 36 37 static const struct inet_diag_handler **inet_diag_table; 38 39 struct inet_diag_entry { 40 u32 *saddr; 41 u32 *daddr; 42 u16 sport; 43 u16 dport; 44 u16 family; 45 u16 userlocks; 46 }; 47 48 static struct sock *idiagnl; 49 50 #define INET_DIAG_PUT(skb, attrtype, attrlen) \ 51 RTA_DATA(__RTA_PUT(skb, attrtype, attrlen)) 52 53 static int inet_diag_fill(struct sk_buff *skb, struct sock *sk, 54 int ext, u32 pid, u32 seq, u16 nlmsg_flags, 55 const struct nlmsghdr *unlh) 56 { 57 const struct inet_sock *inet = inet_sk(sk); 58 const struct inet_connection_sock *icsk = inet_csk(sk); 59 struct inet_diag_msg *r; 60 struct nlmsghdr *nlh; 61 void *info = NULL; 62 struct inet_diag_meminfo *minfo = NULL; 63 unsigned char *b = skb->tail; 64 const struct inet_diag_handler *handler; 65 66 handler = inet_diag_table[unlh->nlmsg_type]; 67 BUG_ON(handler == NULL); 68 69 nlh = NLMSG_PUT(skb, pid, seq, unlh->nlmsg_type, sizeof(*r)); 70 nlh->nlmsg_flags = nlmsg_flags; 71 72 r = NLMSG_DATA(nlh); 73 BUG_ON(sk->sk_state == TCP_TIME_WAIT); 74 75 if (ext & (1 << (INET_DIAG_MEMINFO - 1))) 76 minfo = INET_DIAG_PUT(skb, INET_DIAG_MEMINFO, sizeof(*minfo)); 77 78 if (ext & (1 << (INET_DIAG_INFO - 1))) 79 info = INET_DIAG_PUT(skb, INET_DIAG_INFO, 80 handler->idiag_info_size); 81 82 if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) { 83 const size_t len = strlen(icsk->icsk_ca_ops->name); 84 85 strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1), 86 icsk->icsk_ca_ops->name); 87 } 88 89 r->idiag_family = sk->sk_family; 90 r->idiag_state = sk->sk_state; 91 r->idiag_timer = 0; 92 r->idiag_retrans = 0; 93 94 r->id.idiag_if = sk->sk_bound_dev_if; 95 r->id.idiag_cookie[0] = (u32)(unsigned long)sk; 96 r->id.idiag_cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1); 97 98 r->id.idiag_sport = inet->sport; 99 r->id.idiag_dport = inet->dport; 100 r->id.idiag_src[0] = inet->rcv_saddr; 101 r->id.idiag_dst[0] = inet->daddr; 102 103 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 104 if (r->idiag_family == AF_INET6) { 105 struct ipv6_pinfo *np = inet6_sk(sk); 106 107 ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, 108 &np->rcv_saddr); 109 ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, 110 &np->daddr); 111 } 112 #endif 113 114 #define EXPIRES_IN_MS(tmo) ((tmo - jiffies) * 1000 + HZ - 1) / HZ 115 116 if (icsk->icsk_pending == ICSK_TIME_RETRANS) { 117 r->idiag_timer = 1; 118 r->idiag_retrans = icsk->icsk_retransmits; 119 r->idiag_expires = EXPIRES_IN_MS(icsk->icsk_timeout); 120 } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) { 121 r->idiag_timer = 4; 122 r->idiag_retrans = icsk->icsk_probes_out; 123 r->idiag_expires = EXPIRES_IN_MS(icsk->icsk_timeout); 124 } else if (timer_pending(&sk->sk_timer)) { 125 r->idiag_timer = 2; 126 r->idiag_retrans = icsk->icsk_probes_out; 127 r->idiag_expires = EXPIRES_IN_MS(sk->sk_timer.expires); 128 } else { 129 r->idiag_timer = 0; 130 r->idiag_expires = 0; 131 } 132 #undef EXPIRES_IN_MS 133 134 r->idiag_uid = sock_i_uid(sk); 135 r->idiag_inode = sock_i_ino(sk); 136 137 if (minfo) { 138 minfo->idiag_rmem = atomic_read(&sk->sk_rmem_alloc); 139 minfo->idiag_wmem = sk->sk_wmem_queued; 140 minfo->idiag_fmem = sk->sk_forward_alloc; 141 minfo->idiag_tmem = atomic_read(&sk->sk_wmem_alloc); 142 } 143 144 handler->idiag_get_info(sk, r, info); 145 146 if (sk->sk_state < TCP_TIME_WAIT && 147 icsk->icsk_ca_ops && icsk->icsk_ca_ops->get_info) 148 icsk->icsk_ca_ops->get_info(sk, ext, skb); 149 150 nlh->nlmsg_len = skb->tail - b; 151 return skb->len; 152 153 rtattr_failure: 154 nlmsg_failure: 155 skb_trim(skb, b - skb->data); 156 return -1; 157 } 158 159 static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, 160 struct sk_buff *skb, int ext, u32 pid, 161 u32 seq, u16 nlmsg_flags, 162 const struct nlmsghdr *unlh) 163 { 164 long tmo; 165 struct inet_diag_msg *r; 166 const unsigned char *previous_tail = skb->tail; 167 struct nlmsghdr *nlh = NLMSG_PUT(skb, pid, seq, 168 unlh->nlmsg_type, sizeof(*r)); 169 170 r = NLMSG_DATA(nlh); 171 BUG_ON(tw->tw_state != TCP_TIME_WAIT); 172 173 nlh->nlmsg_flags = nlmsg_flags; 174 175 tmo = tw->tw_ttd - jiffies; 176 if (tmo < 0) 177 tmo = 0; 178 179 r->idiag_family = tw->tw_family; 180 r->idiag_state = tw->tw_state; 181 r->idiag_timer = 0; 182 r->idiag_retrans = 0; 183 r->id.idiag_if = tw->tw_bound_dev_if; 184 r->id.idiag_cookie[0] = (u32)(unsigned long)tw; 185 r->id.idiag_cookie[1] = (u32)(((unsigned long)tw >> 31) >> 1); 186 r->id.idiag_sport = tw->tw_sport; 187 r->id.idiag_dport = tw->tw_dport; 188 r->id.idiag_src[0] = tw->tw_rcv_saddr; 189 r->id.idiag_dst[0] = tw->tw_daddr; 190 r->idiag_state = tw->tw_substate; 191 r->idiag_timer = 3; 192 r->idiag_expires = (tmo * 1000 + HZ - 1) / HZ; 193 r->idiag_rqueue = 0; 194 r->idiag_wqueue = 0; 195 r->idiag_uid = 0; 196 r->idiag_inode = 0; 197 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 198 if (tw->tw_family == AF_INET6) { 199 const struct inet6_timewait_sock *tw6 = 200 inet6_twsk((struct sock *)tw); 201 202 ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, 203 &tw6->tw_v6_rcv_saddr); 204 ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, 205 &tw6->tw_v6_daddr); 206 } 207 #endif 208 nlh->nlmsg_len = skb->tail - previous_tail; 209 return skb->len; 210 nlmsg_failure: 211 skb_trim(skb, previous_tail - skb->data); 212 return -1; 213 } 214 215 static int inet_diag_get_exact(struct sk_buff *in_skb, 216 const struct nlmsghdr *nlh) 217 { 218 int err; 219 struct sock *sk; 220 struct inet_diag_req *req = NLMSG_DATA(nlh); 221 struct sk_buff *rep; 222 struct inet_hashinfo *hashinfo; 223 const struct inet_diag_handler *handler; 224 225 handler = inet_diag_table[nlh->nlmsg_type]; 226 BUG_ON(handler == NULL); 227 hashinfo = handler->idiag_hashinfo; 228 229 if (req->idiag_family == AF_INET) { 230 sk = inet_lookup(hashinfo, req->id.idiag_dst[0], 231 req->id.idiag_dport, req->id.idiag_src[0], 232 req->id.idiag_sport, req->id.idiag_if); 233 } 234 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 235 else if (req->idiag_family == AF_INET6) { 236 sk = inet6_lookup(hashinfo, 237 (struct in6_addr *)req->id.idiag_dst, 238 req->id.idiag_dport, 239 (struct in6_addr *)req->id.idiag_src, 240 req->id.idiag_sport, 241 req->id.idiag_if); 242 } 243 #endif 244 else { 245 return -EINVAL; 246 } 247 248 if (sk == NULL) 249 return -ENOENT; 250 251 err = -ESTALE; 252 if ((req->id.idiag_cookie[0] != INET_DIAG_NOCOOKIE || 253 req->id.idiag_cookie[1] != INET_DIAG_NOCOOKIE) && 254 ((u32)(unsigned long)sk != req->id.idiag_cookie[0] || 255 (u32)((((unsigned long)sk) >> 31) >> 1) != req->id.idiag_cookie[1])) 256 goto out; 257 258 err = -ENOMEM; 259 rep = alloc_skb(NLMSG_SPACE((sizeof(struct inet_diag_msg) + 260 sizeof(struct inet_diag_meminfo) + 261 handler->idiag_info_size + 64)), 262 GFP_KERNEL); 263 if (!rep) 264 goto out; 265 266 if (inet_diag_fill(rep, sk, req->idiag_ext, 267 NETLINK_CB(in_skb).pid, 268 nlh->nlmsg_seq, 0, nlh) <= 0) 269 BUG(); 270 271 err = netlink_unicast(idiagnl, rep, NETLINK_CB(in_skb).pid, 272 MSG_DONTWAIT); 273 if (err > 0) 274 err = 0; 275 276 out: 277 if (sk) { 278 if (sk->sk_state == TCP_TIME_WAIT) 279 inet_twsk_put((struct inet_timewait_sock *)sk); 280 else 281 sock_put(sk); 282 } 283 return err; 284 } 285 286 static int bitstring_match(const u32 *a1, const u32 *a2, int bits) 287 { 288 int words = bits >> 5; 289 290 bits &= 0x1f; 291 292 if (words) { 293 if (memcmp(a1, a2, words << 2)) 294 return 0; 295 } 296 if (bits) { 297 __u32 w1, w2; 298 __u32 mask; 299 300 w1 = a1[words]; 301 w2 = a2[words]; 302 303 mask = htonl((0xffffffff) << (32 - bits)); 304 305 if ((w1 ^ w2) & mask) 306 return 0; 307 } 308 309 return 1; 310 } 311 312 313 static int inet_diag_bc_run(const void *bc, int len, 314 const struct inet_diag_entry *entry) 315 { 316 while (len > 0) { 317 int yes = 1; 318 const struct inet_diag_bc_op *op = bc; 319 320 switch (op->code) { 321 case INET_DIAG_BC_NOP: 322 break; 323 case INET_DIAG_BC_JMP: 324 yes = 0; 325 break; 326 case INET_DIAG_BC_S_GE: 327 yes = entry->sport >= op[1].no; 328 break; 329 case INET_DIAG_BC_S_LE: 330 yes = entry->dport <= op[1].no; 331 break; 332 case INET_DIAG_BC_D_GE: 333 yes = entry->dport >= op[1].no; 334 break; 335 case INET_DIAG_BC_D_LE: 336 yes = entry->dport <= op[1].no; 337 break; 338 case INET_DIAG_BC_AUTO: 339 yes = !(entry->userlocks & SOCK_BINDPORT_LOCK); 340 break; 341 case INET_DIAG_BC_S_COND: 342 case INET_DIAG_BC_D_COND: { 343 struct inet_diag_hostcond *cond; 344 u32 *addr; 345 346 cond = (struct inet_diag_hostcond *)(op + 1); 347 if (cond->port != -1 && 348 cond->port != (op->code == INET_DIAG_BC_S_COND ? 349 entry->sport : entry->dport)) { 350 yes = 0; 351 break; 352 } 353 354 if (cond->prefix_len == 0) 355 break; 356 357 if (op->code == INET_DIAG_BC_S_COND) 358 addr = entry->saddr; 359 else 360 addr = entry->daddr; 361 362 if (bitstring_match(addr, cond->addr, 363 cond->prefix_len)) 364 break; 365 if (entry->family == AF_INET6 && 366 cond->family == AF_INET) { 367 if (addr[0] == 0 && addr[1] == 0 && 368 addr[2] == htonl(0xffff) && 369 bitstring_match(addr + 3, cond->addr, 370 cond->prefix_len)) 371 break; 372 } 373 yes = 0; 374 break; 375 } 376 } 377 378 if (yes) { 379 len -= op->yes; 380 bc += op->yes; 381 } else { 382 len -= op->no; 383 bc += op->no; 384 } 385 } 386 return (len == 0); 387 } 388 389 static int valid_cc(const void *bc, int len, int cc) 390 { 391 while (len >= 0) { 392 const struct inet_diag_bc_op *op = bc; 393 394 if (cc > len) 395 return 0; 396 if (cc == len) 397 return 1; 398 if (op->yes < 4) 399 return 0; 400 len -= op->yes; 401 bc += op->yes; 402 } 403 return 0; 404 } 405 406 static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) 407 { 408 const unsigned char *bc = bytecode; 409 int len = bytecode_len; 410 411 while (len > 0) { 412 struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)bc; 413 414 //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); 415 switch (op->code) { 416 case INET_DIAG_BC_AUTO: 417 case INET_DIAG_BC_S_COND: 418 case INET_DIAG_BC_D_COND: 419 case INET_DIAG_BC_S_GE: 420 case INET_DIAG_BC_S_LE: 421 case INET_DIAG_BC_D_GE: 422 case INET_DIAG_BC_D_LE: 423 if (op->yes < 4 || op->yes > len + 4) 424 return -EINVAL; 425 case INET_DIAG_BC_JMP: 426 if (op->no < 4 || op->no > len + 4) 427 return -EINVAL; 428 if (op->no < len && 429 !valid_cc(bytecode, bytecode_len, len - op->no)) 430 return -EINVAL; 431 break; 432 case INET_DIAG_BC_NOP: 433 if (op->yes < 4 || op->yes > len + 4) 434 return -EINVAL; 435 break; 436 default: 437 return -EINVAL; 438 } 439 bc += op->yes; 440 len -= op->yes; 441 } 442 return len == 0 ? 0 : -EINVAL; 443 } 444 445 static int inet_diag_dump_sock(struct sk_buff *skb, struct sock *sk, 446 struct netlink_callback *cb) 447 { 448 struct inet_diag_req *r = NLMSG_DATA(cb->nlh); 449 450 if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { 451 struct inet_diag_entry entry; 452 struct rtattr *bc = (struct rtattr *)(r + 1); 453 struct inet_sock *inet = inet_sk(sk); 454 455 entry.family = sk->sk_family; 456 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 457 if (entry.family == AF_INET6) { 458 struct ipv6_pinfo *np = inet6_sk(sk); 459 460 entry.saddr = np->rcv_saddr.s6_addr32; 461 entry.daddr = np->daddr.s6_addr32; 462 } else 463 #endif 464 { 465 entry.saddr = &inet->rcv_saddr; 466 entry.daddr = &inet->daddr; 467 } 468 entry.sport = inet->num; 469 entry.dport = ntohs(inet->dport); 470 entry.userlocks = sk->sk_userlocks; 471 472 if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) 473 return 0; 474 } 475 476 return inet_diag_fill(skb, sk, r->idiag_ext, NETLINK_CB(cb->skb).pid, 477 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); 478 } 479 480 static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, 481 struct sk_buff *skb, 482 struct netlink_callback *cb) 483 { 484 struct inet_diag_req *r = NLMSG_DATA(cb->nlh); 485 486 if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { 487 struct inet_diag_entry entry; 488 struct rtattr *bc = (struct rtattr *)(r + 1); 489 490 entry.family = tw->tw_family; 491 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 492 if (tw->tw_family == AF_INET6) { 493 struct inet6_timewait_sock *tw6 = 494 inet6_twsk((struct sock *)tw); 495 entry.saddr = tw6->tw_v6_rcv_saddr.s6_addr32; 496 entry.daddr = tw6->tw_v6_daddr.s6_addr32; 497 } else 498 #endif 499 { 500 entry.saddr = &tw->tw_rcv_saddr; 501 entry.daddr = &tw->tw_daddr; 502 } 503 entry.sport = tw->tw_num; 504 entry.dport = ntohs(tw->tw_dport); 505 entry.userlocks = 0; 506 507 if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) 508 return 0; 509 } 510 511 return inet_twsk_diag_fill(tw, skb, r->idiag_ext, 512 NETLINK_CB(cb->skb).pid, 513 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); 514 } 515 516 static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, 517 struct request_sock *req, u32 pid, u32 seq, 518 const struct nlmsghdr *unlh) 519 { 520 const struct inet_request_sock *ireq = inet_rsk(req); 521 struct inet_sock *inet = inet_sk(sk); 522 unsigned char *b = skb->tail; 523 struct inet_diag_msg *r; 524 struct nlmsghdr *nlh; 525 long tmo; 526 527 nlh = NLMSG_PUT(skb, pid, seq, unlh->nlmsg_type, sizeof(*r)); 528 nlh->nlmsg_flags = NLM_F_MULTI; 529 r = NLMSG_DATA(nlh); 530 531 r->idiag_family = sk->sk_family; 532 r->idiag_state = TCP_SYN_RECV; 533 r->idiag_timer = 1; 534 r->idiag_retrans = req->retrans; 535 536 r->id.idiag_if = sk->sk_bound_dev_if; 537 r->id.idiag_cookie[0] = (u32)(unsigned long)req; 538 r->id.idiag_cookie[1] = (u32)(((unsigned long)req >> 31) >> 1); 539 540 tmo = req->expires - jiffies; 541 if (tmo < 0) 542 tmo = 0; 543 544 r->id.idiag_sport = inet->sport; 545 r->id.idiag_dport = ireq->rmt_port; 546 r->id.idiag_src[0] = ireq->loc_addr; 547 r->id.idiag_dst[0] = ireq->rmt_addr; 548 r->idiag_expires = jiffies_to_msecs(tmo); 549 r->idiag_rqueue = 0; 550 r->idiag_wqueue = 0; 551 r->idiag_uid = sock_i_uid(sk); 552 r->idiag_inode = 0; 553 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 554 if (r->idiag_family == AF_INET6) { 555 ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, 556 &inet6_rsk(req)->loc_addr); 557 ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, 558 &inet6_rsk(req)->rmt_addr); 559 } 560 #endif 561 nlh->nlmsg_len = skb->tail - b; 562 563 return skb->len; 564 565 nlmsg_failure: 566 skb_trim(skb, b - skb->data); 567 return -1; 568 } 569 570 static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, 571 struct netlink_callback *cb) 572 { 573 struct inet_diag_entry entry; 574 struct inet_diag_req *r = NLMSG_DATA(cb->nlh); 575 struct inet_connection_sock *icsk = inet_csk(sk); 576 struct listen_sock *lopt; 577 struct rtattr *bc = NULL; 578 struct inet_sock *inet = inet_sk(sk); 579 int j, s_j; 580 int reqnum, s_reqnum; 581 int err = 0; 582 583 s_j = cb->args[3]; 584 s_reqnum = cb->args[4]; 585 586 if (s_j > 0) 587 s_j--; 588 589 entry.family = sk->sk_family; 590 591 read_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock); 592 593 lopt = icsk->icsk_accept_queue.listen_opt; 594 if (!lopt || !lopt->qlen) 595 goto out; 596 597 if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { 598 bc = (struct rtattr *)(r + 1); 599 entry.sport = inet->num; 600 entry.userlocks = sk->sk_userlocks; 601 } 602 603 for (j = s_j; j < lopt->nr_table_entries; j++) { 604 struct request_sock *req, *head = lopt->syn_table[j]; 605 606 reqnum = 0; 607 for (req = head; req; reqnum++, req = req->dl_next) { 608 struct inet_request_sock *ireq = inet_rsk(req); 609 610 if (reqnum < s_reqnum) 611 continue; 612 if (r->id.idiag_dport != ireq->rmt_port && 613 r->id.idiag_dport) 614 continue; 615 616 if (bc) { 617 entry.saddr = 618 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 619 (entry.family == AF_INET6) ? 620 inet6_rsk(req)->loc_addr.s6_addr32 : 621 #endif 622 &ireq->loc_addr; 623 entry.daddr = 624 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 625 (entry.family == AF_INET6) ? 626 inet6_rsk(req)->rmt_addr.s6_addr32 : 627 #endif 628 &ireq->rmt_addr; 629 entry.dport = ntohs(ireq->rmt_port); 630 631 if (!inet_diag_bc_run(RTA_DATA(bc), 632 RTA_PAYLOAD(bc), &entry)) 633 continue; 634 } 635 636 err = inet_diag_fill_req(skb, sk, req, 637 NETLINK_CB(cb->skb).pid, 638 cb->nlh->nlmsg_seq, cb->nlh); 639 if (err < 0) { 640 cb->args[3] = j + 1; 641 cb->args[4] = reqnum; 642 goto out; 643 } 644 } 645 646 s_reqnum = 0; 647 } 648 649 out: 650 read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); 651 652 return err; 653 } 654 655 static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) 656 { 657 int i, num; 658 int s_i, s_num; 659 struct inet_diag_req *r = NLMSG_DATA(cb->nlh); 660 const struct inet_diag_handler *handler; 661 struct inet_hashinfo *hashinfo; 662 663 handler = inet_diag_table[cb->nlh->nlmsg_type]; 664 BUG_ON(handler == NULL); 665 hashinfo = handler->idiag_hashinfo; 666 667 s_i = cb->args[1]; 668 s_num = num = cb->args[2]; 669 670 if (cb->args[0] == 0) { 671 if (!(r->idiag_states & (TCPF_LISTEN | TCPF_SYN_RECV))) 672 goto skip_listen_ht; 673 674 inet_listen_lock(hashinfo); 675 for (i = s_i; i < INET_LHTABLE_SIZE; i++) { 676 struct sock *sk; 677 struct hlist_node *node; 678 679 num = 0; 680 sk_for_each(sk, node, &hashinfo->listening_hash[i]) { 681 struct inet_sock *inet = inet_sk(sk); 682 683 if (num < s_num) { 684 num++; 685 continue; 686 } 687 688 if (r->id.idiag_sport != inet->sport && 689 r->id.idiag_sport) 690 goto next_listen; 691 692 if (!(r->idiag_states & TCPF_LISTEN) || 693 r->id.idiag_dport || 694 cb->args[3] > 0) 695 goto syn_recv; 696 697 if (inet_diag_dump_sock(skb, sk, cb) < 0) { 698 inet_listen_unlock(hashinfo); 699 goto done; 700 } 701 702 syn_recv: 703 if (!(r->idiag_states & TCPF_SYN_RECV)) 704 goto next_listen; 705 706 if (inet_diag_dump_reqs(skb, sk, cb) < 0) { 707 inet_listen_unlock(hashinfo); 708 goto done; 709 } 710 711 next_listen: 712 cb->args[3] = 0; 713 cb->args[4] = 0; 714 ++num; 715 } 716 717 s_num = 0; 718 cb->args[3] = 0; 719 cb->args[4] = 0; 720 } 721 inet_listen_unlock(hashinfo); 722 skip_listen_ht: 723 cb->args[0] = 1; 724 s_i = num = s_num = 0; 725 } 726 727 if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV))) 728 return skb->len; 729 730 for (i = s_i; i < hashinfo->ehash_size; i++) { 731 struct inet_ehash_bucket *head = &hashinfo->ehash[i]; 732 struct sock *sk; 733 struct hlist_node *node; 734 735 if (i > s_i) 736 s_num = 0; 737 738 read_lock_bh(&head->lock); 739 num = 0; 740 sk_for_each(sk, node, &head->chain) { 741 struct inet_sock *inet = inet_sk(sk); 742 743 if (num < s_num) 744 goto next_normal; 745 if (!(r->idiag_states & (1 << sk->sk_state))) 746 goto next_normal; 747 if (r->id.idiag_sport != inet->sport && 748 r->id.idiag_sport) 749 goto next_normal; 750 if (r->id.idiag_dport != inet->dport && 751 r->id.idiag_dport) 752 goto next_normal; 753 if (inet_diag_dump_sock(skb, sk, cb) < 0) { 754 read_unlock_bh(&head->lock); 755 goto done; 756 } 757 next_normal: 758 ++num; 759 } 760 761 if (r->idiag_states & TCPF_TIME_WAIT) { 762 struct inet_timewait_sock *tw; 763 764 inet_twsk_for_each(tw, node, 765 &hashinfo->ehash[i + hashinfo->ehash_size].chain) { 766 767 if (num < s_num) 768 goto next_dying; 769 if (r->id.idiag_sport != tw->tw_sport && 770 r->id.idiag_sport) 771 goto next_dying; 772 if (r->id.idiag_dport != tw->tw_dport && 773 r->id.idiag_dport) 774 goto next_dying; 775 if (inet_twsk_diag_dump(tw, skb, cb) < 0) { 776 read_unlock_bh(&head->lock); 777 goto done; 778 } 779 next_dying: 780 ++num; 781 } 782 } 783 read_unlock_bh(&head->lock); 784 } 785 786 done: 787 cb->args[1] = i; 788 cb->args[2] = num; 789 return skb->len; 790 } 791 792 static inline int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 793 { 794 if (!(nlh->nlmsg_flags&NLM_F_REQUEST)) 795 return 0; 796 797 if (nlh->nlmsg_type >= INET_DIAG_GETSOCK_MAX) 798 goto err_inval; 799 800 if (inet_diag_table[nlh->nlmsg_type] == NULL) 801 return -ENOENT; 802 803 if (NLMSG_LENGTH(sizeof(struct inet_diag_req)) > skb->len) 804 goto err_inval; 805 806 if (nlh->nlmsg_flags&NLM_F_DUMP) { 807 if (nlh->nlmsg_len > 808 (4 + NLMSG_SPACE(sizeof(struct inet_diag_req)))) { 809 struct rtattr *rta = (void *)(NLMSG_DATA(nlh) + 810 sizeof(struct inet_diag_req)); 811 if (rta->rta_type != INET_DIAG_REQ_BYTECODE || 812 rta->rta_len < 8 || 813 rta->rta_len > 814 (nlh->nlmsg_len - 815 NLMSG_SPACE(sizeof(struct inet_diag_req)))) 816 goto err_inval; 817 if (inet_diag_bc_audit(RTA_DATA(rta), RTA_PAYLOAD(rta))) 818 goto err_inval; 819 } 820 return netlink_dump_start(idiagnl, skb, nlh, 821 inet_diag_dump, NULL); 822 } else 823 return inet_diag_get_exact(skb, nlh); 824 825 err_inval: 826 return -EINVAL; 827 } 828 829 830 static inline void inet_diag_rcv_skb(struct sk_buff *skb) 831 { 832 if (skb->len >= NLMSG_SPACE(0)) { 833 int err; 834 struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data; 835 836 if (nlh->nlmsg_len < sizeof(*nlh) || 837 skb->len < nlh->nlmsg_len) 838 return; 839 err = inet_diag_rcv_msg(skb, nlh); 840 if (err || nlh->nlmsg_flags & NLM_F_ACK) 841 netlink_ack(skb, nlh, err); 842 } 843 } 844 845 static void inet_diag_rcv(struct sock *sk, int len) 846 { 847 struct sk_buff *skb; 848 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); 849 850 while (qlen-- && (skb = skb_dequeue(&sk->sk_receive_queue))) { 851 inet_diag_rcv_skb(skb); 852 kfree_skb(skb); 853 } 854 } 855 856 static DEFINE_SPINLOCK(inet_diag_register_lock); 857 858 int inet_diag_register(const struct inet_diag_handler *h) 859 { 860 const __u16 type = h->idiag_type; 861 int err = -EINVAL; 862 863 if (type >= INET_DIAG_GETSOCK_MAX) 864 goto out; 865 866 spin_lock(&inet_diag_register_lock); 867 err = -EEXIST; 868 if (inet_diag_table[type] == NULL) { 869 inet_diag_table[type] = h; 870 err = 0; 871 } 872 spin_unlock(&inet_diag_register_lock); 873 out: 874 return err; 875 } 876 EXPORT_SYMBOL_GPL(inet_diag_register); 877 878 void inet_diag_unregister(const struct inet_diag_handler *h) 879 { 880 const __u16 type = h->idiag_type; 881 882 if (type >= INET_DIAG_GETSOCK_MAX) 883 return; 884 885 spin_lock(&inet_diag_register_lock); 886 inet_diag_table[type] = NULL; 887 spin_unlock(&inet_diag_register_lock); 888 889 synchronize_rcu(); 890 } 891 EXPORT_SYMBOL_GPL(inet_diag_unregister); 892 893 static int __init inet_diag_init(void) 894 { 895 const int inet_diag_table_size = (INET_DIAG_GETSOCK_MAX * 896 sizeof(struct inet_diag_handler *)); 897 int err = -ENOMEM; 898 899 inet_diag_table = kmalloc(inet_diag_table_size, GFP_KERNEL); 900 if (!inet_diag_table) 901 goto out; 902 903 memset(inet_diag_table, 0, inet_diag_table_size); 904 idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv, 905 THIS_MODULE); 906 if (idiagnl == NULL) 907 goto out_free_table; 908 err = 0; 909 out: 910 return err; 911 out_free_table: 912 kfree(inet_diag_table); 913 goto out; 914 } 915 916 static void __exit inet_diag_exit(void) 917 { 918 sock_release(idiagnl->sk_socket); 919 kfree(inet_diag_table); 920 } 921 922 module_init(inet_diag_init); 923 module_exit(inet_diag_exit); 924 MODULE_LICENSE("GPL"); 925