linux/net/ipv4/inet_diag.c
<<
>>
Prefs
   1/*
   2 * inet_diag.c  Module for monitoring INET transport protocols sockets.
   3 *
   4 * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
   5 *
   6 *      This program is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU General Public License
   8 *      as published by the Free Software Foundation; either version
   9 *      2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/types.h>
  15#include <linux/fcntl.h>
  16#include <linux/random.h>
  17#include <linux/slab.h>
  18#include <linux/cache.h>
  19#include <linux/init.h>
  20#include <linux/time.h>
  21
  22#include <net/icmp.h>
  23#include <net/tcp.h>
  24#include <net/ipv6.h>
  25#include <net/inet_common.h>
  26#include <net/inet_connection_sock.h>
  27#include <net/inet_hashtables.h>
  28#include <net/inet_timewait_sock.h>
  29#include <net/inet6_hashtables.h>
  30#include <net/netlink.h>
  31
  32#include <linux/inet.h>
  33#include <linux/stddef.h>
  34
  35#include <linux/inet_diag.h>
  36#include <linux/sock_diag.h>
  37
  38static const struct inet_diag_handler **inet_diag_table;
  39
  40struct inet_diag_entry {
  41        __be32 *saddr;
  42        __be32 *daddr;
  43        u16 sport;
  44        u16 dport;
  45        u16 family;
  46        u16 userlocks;
  47#if IS_ENABLED(CONFIG_IPV6)
  48        struct in6_addr saddr_storage;  /* for IPv4-mapped-IPv6 addresses */
  49        struct in6_addr daddr_storage;  /* for IPv4-mapped-IPv6 addresses */
  50#endif
  51};
  52
  53static DEFINE_MUTEX(inet_diag_table_mutex);
  54
  55static const struct inet_diag_handler *inet_diag_lock_handler(int proto)
  56{
  57        if (!inet_diag_table[proto])
  58                request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK,
  59                               NETLINK_SOCK_DIAG, AF_INET, proto);
  60
  61        mutex_lock(&inet_diag_table_mutex);
  62        if (!inet_diag_table[proto])
  63                return ERR_PTR(-ENOENT);
  64
  65        return inet_diag_table[proto];
  66}
  67
  68static inline void inet_diag_unlock_handler(
  69        const struct inet_diag_handler *handler)
  70{
  71        mutex_unlock(&inet_diag_table_mutex);
  72}
  73
  74static size_t inet_sk_attr_size(void)
  75{
  76        return    nla_total_size(sizeof(struct tcp_info))
  77                + nla_total_size(1) /* INET_DIAG_SHUTDOWN */
  78                + nla_total_size(1) /* INET_DIAG_TOS */
  79                + nla_total_size(1) /* INET_DIAG_TCLASS */
  80                + nla_total_size(sizeof(struct inet_diag_meminfo))
  81                + nla_total_size(sizeof(struct inet_diag_msg))
  82                + nla_total_size(SK_MEMINFO_VARS * sizeof(u32))
  83                + nla_total_size(TCP_CA_NAME_MAX)
  84                + nla_total_size(sizeof(struct tcpvegas_info))
  85                + 64;
  86}
  87
  88int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
  89                              struct sk_buff *skb, struct inet_diag_req_v2 *req,
  90                              struct user_namespace *user_ns,                   
  91                              u32 portid, u32 seq, u16 nlmsg_flags,
  92                              const struct nlmsghdr *unlh)
  93{
  94        const struct inet_sock *inet = inet_sk(sk);
  95        struct inet_diag_msg *r;
  96        struct nlmsghdr  *nlh;
  97        struct nlattr *attr;
  98        void *info = NULL;
  99        const struct inet_diag_handler *handler;
 100        int ext = req->idiag_ext;
 101
 102        handler = inet_diag_table[req->sdiag_protocol];
 103        BUG_ON(handler == NULL);
 104
 105        nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
 106                        nlmsg_flags);
 107        if (!nlh)
 108                return -EMSGSIZE;
 109
 110        r = nlmsg_data(nlh);
 111        BUG_ON(sk->sk_state == TCP_TIME_WAIT);
 112
 113        r->idiag_family = sk->sk_family;
 114        r->idiag_state = sk->sk_state;
 115        r->idiag_timer = 0;
 116        r->idiag_retrans = 0;
 117
 118        r->id.idiag_if = sk->sk_bound_dev_if;
 119        sock_diag_save_cookie(sk, r->id.idiag_cookie);
 120
 121        r->id.idiag_sport = inet->inet_sport;
 122        r->id.idiag_dport = inet->inet_dport;
 123
 124        memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
 125        memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
 126
 127        r->id.idiag_src[0] = inet->inet_rcv_saddr;
 128        r->id.idiag_dst[0] = inet->inet_daddr;
 129
 130        if (nla_put_u8(skb, INET_DIAG_SHUTDOWN, sk->sk_shutdown))
 131                goto errout;
 132
 133        /* IPv6 dual-stack sockets use inet->tos for IPv4 connections,
 134         * hence this needs to be included regardless of socket family.
 135         */
 136        if (ext & (1 << (INET_DIAG_TOS - 1)))
 137                if (nla_put_u8(skb, INET_DIAG_TOS, inet->tos) < 0)
 138                        goto errout;
 139
 140#if IS_ENABLED(CONFIG_IPV6)
 141        if (r->idiag_family == AF_INET6) {
 142
 143                *(struct in6_addr *)r->id.idiag_src = sk->sk_v6_rcv_saddr;
 144                *(struct in6_addr *)r->id.idiag_dst = sk->sk_v6_daddr;
 145
 146                if (ext & (1 << (INET_DIAG_TCLASS - 1)))
 147                        if (nla_put_u8(skb, INET_DIAG_TCLASS,
 148                                       inet6_sk(sk)->tclass) < 0)
 149                                goto errout;
 150        }
 151#endif
 152
 153        r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
 154        r->idiag_inode = sock_i_ino(sk);
 155
 156        if (ext & (1 << (INET_DIAG_MEMINFO - 1))) {
 157                struct inet_diag_meminfo minfo = {
 158                        .idiag_rmem = sk_rmem_alloc_get(sk),
 159                        .idiag_wmem = sk->sk_wmem_queued,
 160                        .idiag_fmem = sk->sk_forward_alloc,
 161                        .idiag_tmem = sk_wmem_alloc_get(sk),
 162                };
 163
 164                if (nla_put(skb, INET_DIAG_MEMINFO, sizeof(minfo), &minfo) < 0)
 165                        goto errout;
 166        }
 167
 168        if (ext & (1 << (INET_DIAG_SKMEMINFO - 1)))
 169                if (sock_diag_put_meminfo(sk, skb, INET_DIAG_SKMEMINFO))
 170                        goto errout;
 171
 172        if (icsk == NULL) {
 173                handler->idiag_get_info(sk, r, NULL);
 174                goto out;
 175        }
 176
 177#define EXPIRES_IN_MS(tmo)  DIV_ROUND_UP((tmo - jiffies) * 1000, HZ)
 178
 179        if (icsk->icsk_pending == ICSK_TIME_RETRANS ||
 180            icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
 181            icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
 182                r->idiag_timer = 1;
 183                r->idiag_retrans = icsk->icsk_retransmits;
 184                r->idiag_expires = EXPIRES_IN_MS(icsk->icsk_timeout);
 185        } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
 186                r->idiag_timer = 4;
 187                r->idiag_retrans = icsk->icsk_probes_out;
 188                r->idiag_expires = EXPIRES_IN_MS(icsk->icsk_timeout);
 189        } else if (timer_pending(&sk->sk_timer)) {
 190                r->idiag_timer = 2;
 191                r->idiag_retrans = icsk->icsk_probes_out;
 192                r->idiag_expires = EXPIRES_IN_MS(sk->sk_timer.expires);
 193        } else {
 194                r->idiag_timer = 0;
 195                r->idiag_expires = 0;
 196        }
 197#undef EXPIRES_IN_MS
 198
 199        if (ext & (1 << (INET_DIAG_INFO - 1))) {
 200                attr = nla_reserve(skb, INET_DIAG_INFO,
 201                                   sizeof(struct tcp_info));
 202                if (!attr)
 203                        goto errout;
 204
 205                info = nla_data(attr);
 206        }
 207
 208        if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops)
 209                if (nla_put_string(skb, INET_DIAG_CONG,
 210                                   icsk->icsk_ca_ops->name) < 0)
 211                        goto errout;
 212
 213        handler->idiag_get_info(sk, r, info);
 214
 215        if (sk->sk_state < TCP_TIME_WAIT &&
 216            icsk->icsk_ca_ops && icsk->icsk_ca_ops->get_info)
 217                icsk->icsk_ca_ops->get_info(sk, ext, skb);
 218
 219out:
 220        nlmsg_end(skb, nlh);
 221        return 0;
 222
 223errout:
 224        nlmsg_cancel(skb, nlh);
 225        return -EMSGSIZE;
 226}
 227EXPORT_SYMBOL_GPL(inet_sk_diag_fill);
 228
 229static int inet_csk_diag_fill(struct sock *sk,
 230                              struct sk_buff *skb, struct inet_diag_req_v2 *req,
 231                              struct user_namespace *user_ns,
 232                              u32 portid, u32 seq, u16 nlmsg_flags,
 233                              const struct nlmsghdr *unlh)
 234{
 235        return inet_sk_diag_fill(sk, inet_csk(sk),
 236                        skb, req, user_ns, portid, seq, nlmsg_flags, unlh);
 237}
 238
 239static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
 240                               struct sk_buff *skb, struct inet_diag_req_v2 *req,
 241                               u32 portid, u32 seq, u16 nlmsg_flags,
 242                               const struct nlmsghdr *unlh)
 243{
 244        s32 tmo;
 245        struct inet_diag_msg *r;
 246        struct nlmsghdr *nlh;
 247
 248        nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
 249                        nlmsg_flags);
 250        if (!nlh)
 251                return -EMSGSIZE;
 252
 253        r = nlmsg_data(nlh);
 254        BUG_ON(tw->tw_state != TCP_TIME_WAIT);
 255
 256        tmo = tw->tw_ttd - inet_tw_time_stamp();
 257        if (tmo < 0)
 258                tmo = 0;
 259
 260        r->idiag_family       = tw->tw_family;
 261        r->idiag_retrans      = 0;
 262
 263        r->id.idiag_if        = tw->tw_bound_dev_if;
 264        sock_diag_save_cookie(tw, r->id.idiag_cookie);
 265
 266        r->id.idiag_sport     = tw->tw_sport;
 267        r->id.idiag_dport     = tw->tw_dport;
 268
 269        memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
 270        memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
 271
 272        r->id.idiag_src[0]    = tw->tw_rcv_saddr;
 273        r->id.idiag_dst[0]    = tw->tw_daddr;
 274
 275        r->idiag_state        = tw->tw_substate;
 276        r->idiag_timer        = 3;
 277        r->idiag_expires      = jiffies_to_msecs(tmo);
 278        r->idiag_rqueue       = 0;
 279        r->idiag_wqueue       = 0;
 280        r->idiag_uid          = 0;
 281        r->idiag_inode        = 0;
 282#if IS_ENABLED(CONFIG_IPV6)
 283        if (tw->tw_family == AF_INET6) {
 284                *(struct in6_addr *)r->id.idiag_src = tw->tw_v6_rcv_saddr;
 285                *(struct in6_addr *)r->id.idiag_dst = tw->tw_v6_daddr;
 286        }
 287#endif
 288
 289        nlmsg_end(skb, nlh);
 290        return 0;
 291}
 292
 293static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
 294                        struct inet_diag_req_v2 *r,
 295                        struct user_namespace *user_ns,
 296                        u32 portid, u32 seq, u16 nlmsg_flags,
 297                        const struct nlmsghdr *unlh)
 298{
 299        if (sk->sk_state == TCP_TIME_WAIT)
 300                return inet_twsk_diag_fill(inet_twsk(sk), skb, r, portid, seq,
 301                                           nlmsg_flags, unlh);
 302
 303        return inet_csk_diag_fill(sk, skb, r, user_ns, portid, seq,
 304                                  nlmsg_flags, unlh);
 305}
 306
 307int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
 308                const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req)
 309{
 310        int err;
 311        struct sock *sk;
 312        struct sk_buff *rep;
 313        struct net *net = sock_net(in_skb->sk);
 314
 315        err = -EINVAL;
 316        if (req->sdiag_family == AF_INET) {
 317                sk = inet_lookup(net, hashinfo, req->id.idiag_dst[0],
 318                                 req->id.idiag_dport, req->id.idiag_src[0],
 319                                 req->id.idiag_sport, req->id.idiag_if);
 320        }
 321#if IS_ENABLED(CONFIG_IPV6)
 322        else if (req->sdiag_family == AF_INET6) {
 323                sk = inet6_lookup(net, hashinfo,
 324                                  (struct in6_addr *)req->id.idiag_dst,
 325                                  req->id.idiag_dport,
 326                                  (struct in6_addr *)req->id.idiag_src,
 327                                  req->id.idiag_sport,
 328                                  req->id.idiag_if);
 329        }
 330#endif
 331        else {
 332                goto out_nosk;
 333        }
 334
 335        err = -ENOENT;
 336        if (sk == NULL)
 337                goto out_nosk;
 338
 339        err = sock_diag_check_cookie(sk, req->id.idiag_cookie);
 340        if (err)
 341                goto out;
 342
 343        rep = nlmsg_new(inet_sk_attr_size(), GFP_KERNEL);
 344        if (!rep) {
 345                err = -ENOMEM;
 346                goto out;
 347        }
 348
 349        err = sk_diag_fill(sk, rep, req,
 350                           sk_user_ns(NETLINK_CB(in_skb).sk),
 351                           NETLINK_CB(in_skb).portid,
 352                           nlh->nlmsg_seq, 0, nlh);
 353        if (err < 0) {
 354                WARN_ON(err == -EMSGSIZE);
 355                nlmsg_free(rep);
 356                goto out;
 357        }
 358        err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
 359                              MSG_DONTWAIT);
 360        if (err > 0)
 361                err = 0;
 362
 363out:
 364        if (sk)
 365                sock_gen_put(sk);
 366
 367out_nosk:
 368        return err;
 369}
 370EXPORT_SYMBOL_GPL(inet_diag_dump_one_icsk);
 371
 372static int inet_diag_get_exact(struct sk_buff *in_skb,
 373                               const struct nlmsghdr *nlh,
 374                               struct inet_diag_req_v2 *req)
 375{
 376        const struct inet_diag_handler *handler;
 377        int err;
 378
 379        handler = inet_diag_lock_handler(req->sdiag_protocol);
 380        if (IS_ERR(handler))
 381                err = PTR_ERR(handler);
 382        else
 383                err = handler->dump_one(in_skb, nlh, req);
 384        inet_diag_unlock_handler(handler);
 385
 386        return err;
 387}
 388
 389static int bitstring_match(const __be32 *a1, const __be32 *a2, int bits)
 390{
 391        int words = bits >> 5;
 392
 393        bits &= 0x1f;
 394
 395        if (words) {
 396                if (memcmp(a1, a2, words << 2))
 397                        return 0;
 398        }
 399        if (bits) {
 400                __be32 w1, w2;
 401                __be32 mask;
 402
 403                w1 = a1[words];
 404                w2 = a2[words];
 405
 406                mask = htonl((0xffffffff) << (32 - bits));
 407
 408                if ((w1 ^ w2) & mask)
 409                        return 0;
 410        }
 411
 412        return 1;
 413}
 414
 415
 416static int inet_diag_bc_run(const struct nlattr *_bc,
 417                const struct inet_diag_entry *entry)
 418{
 419        const void *bc = nla_data(_bc);
 420        int len = nla_len(_bc);
 421
 422        while (len > 0) {
 423                int yes = 1;
 424                const struct inet_diag_bc_op *op = bc;
 425
 426                switch (op->code) {
 427                case INET_DIAG_BC_NOP:
 428                        break;
 429                case INET_DIAG_BC_JMP:
 430                        yes = 0;
 431                        break;
 432                case INET_DIAG_BC_S_GE:
 433                        yes = entry->sport >= op[1].no;
 434                        break;
 435                case INET_DIAG_BC_S_LE:
 436                        yes = entry->sport <= op[1].no;
 437                        break;
 438                case INET_DIAG_BC_D_GE:
 439                        yes = entry->dport >= op[1].no;
 440                        break;
 441                case INET_DIAG_BC_D_LE:
 442                        yes = entry->dport <= op[1].no;
 443                        break;
 444                case INET_DIAG_BC_AUTO:
 445                        yes = !(entry->userlocks & SOCK_BINDPORT_LOCK);
 446                        break;
 447                case INET_DIAG_BC_S_COND:
 448                case INET_DIAG_BC_D_COND: {
 449                        struct inet_diag_hostcond *cond;
 450                        __be32 *addr;
 451
 452                        cond = (struct inet_diag_hostcond *)(op + 1);
 453                        if (cond->port != -1 &&
 454                            cond->port != (op->code == INET_DIAG_BC_S_COND ?
 455                                             entry->sport : entry->dport)) {
 456                                yes = 0;
 457                                break;
 458                        }
 459
 460                        if (op->code == INET_DIAG_BC_S_COND)
 461                                addr = entry->saddr;
 462                        else
 463                                addr = entry->daddr;
 464
 465                        if (cond->family != AF_UNSPEC &&
 466                            cond->family != entry->family) {
 467                                if (entry->family == AF_INET6 &&
 468                                    cond->family == AF_INET) {
 469                                        if (addr[0] == 0 && addr[1] == 0 &&
 470                                            addr[2] == htonl(0xffff) &&
 471                                            bitstring_match(addr + 3,
 472                                                            cond->addr,
 473                                                            cond->prefix_len))
 474                                                break;
 475                                }
 476                                yes = 0;
 477                                break;
 478                        }
 479
 480                        if (cond->prefix_len == 0)
 481                                break;
 482                        if (bitstring_match(addr, cond->addr,
 483                                            cond->prefix_len))
 484                                break;
 485                        yes = 0;
 486                        break;
 487                }
 488                }
 489
 490                if (yes) {
 491                        len -= op->yes;
 492                        bc += op->yes;
 493                } else {
 494                        len -= op->no;
 495                        bc += op->no;
 496                }
 497        }
 498        return len == 0;
 499}
 500
 501int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk)
 502{
 503        struct inet_diag_entry entry;
 504        struct inet_sock *inet = inet_sk(sk);
 505
 506        if (bc == NULL)
 507                return 1;
 508
 509        entry.family = sk->sk_family;
 510#if IS_ENABLED(CONFIG_IPV6)
 511        if (entry.family == AF_INET6) {
 512
 513                entry.saddr = sk->sk_v6_rcv_saddr.s6_addr32;
 514                entry.daddr = sk->sk_v6_daddr.s6_addr32;
 515        } else
 516#endif
 517        {
 518                entry.saddr = &inet->inet_rcv_saddr;
 519                entry.daddr = &inet->inet_daddr;
 520        }
 521        entry.sport = inet->inet_num;
 522        entry.dport = ntohs(inet->inet_dport);
 523        entry.userlocks = sk->sk_userlocks;
 524
 525        return inet_diag_bc_run(bc, &entry);
 526}
 527EXPORT_SYMBOL_GPL(inet_diag_bc_sk);
 528
 529static int valid_cc(const void *bc, int len, int cc)
 530{
 531        while (len >= 0) {
 532                const struct inet_diag_bc_op *op = bc;
 533
 534                if (cc > len)
 535                        return 0;
 536                if (cc == len)
 537                        return 1;
 538                if (op->yes < 4 || op->yes & 3)
 539                        return 0;
 540                len -= op->yes;
 541                bc  += op->yes;
 542        }
 543        return 0;
 544}
 545
 546/* Validate an inet_diag_hostcond. */
 547static bool valid_hostcond(const struct inet_diag_bc_op *op, int len,
 548                           int *min_len)
 549{
 550        int addr_len;
 551        struct inet_diag_hostcond *cond;
 552
 553        /* Check hostcond space. */
 554        *min_len += sizeof(struct inet_diag_hostcond);
 555        if (len < *min_len)
 556                return false;
 557        cond = (struct inet_diag_hostcond *)(op + 1);
 558
 559        /* Check address family and address length. */
 560        switch (cond->family) {
 561        case AF_UNSPEC:
 562                addr_len = 0;
 563                break;
 564        case AF_INET:
 565                addr_len = sizeof(struct in_addr);
 566                break;
 567        case AF_INET6:
 568                addr_len = sizeof(struct in6_addr);
 569                break;
 570        default:
 571                return false;
 572        }
 573        *min_len += addr_len;
 574        if (len < *min_len)
 575                return false;
 576
 577        /* Check prefix length (in bits) vs address length (in bytes). */
 578        if (cond->prefix_len > 8 * addr_len)
 579                return false;
 580
 581        return true;
 582}
 583
 584/* Validate a port comparison operator. */
 585static inline bool valid_port_comparison(const struct inet_diag_bc_op *op,
 586                                         int len, int *min_len)
 587{
 588        /* Port comparisons put the port in a follow-on inet_diag_bc_op. */
 589        *min_len += sizeof(struct inet_diag_bc_op);
 590        if (len < *min_len)
 591                return false;
 592        return true;
 593}
 594
 595static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
 596{
 597        const void *bc = bytecode;
 598        int  len = bytecode_len;
 599
 600        while (len > 0) {
 601                const struct inet_diag_bc_op *op = bc;
 602                int min_len = sizeof(struct inet_diag_bc_op);
 603
 604//printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len);
 605                switch (op->code) {
 606                case INET_DIAG_BC_S_COND:
 607                case INET_DIAG_BC_D_COND:
 608                        if (!valid_hostcond(bc, len, &min_len))
 609                                return -EINVAL;
 610                        break;
 611                case INET_DIAG_BC_S_GE:
 612                case INET_DIAG_BC_S_LE:
 613                case INET_DIAG_BC_D_GE:
 614                case INET_DIAG_BC_D_LE:
 615                        if (!valid_port_comparison(bc, len, &min_len))
 616                                return -EINVAL;
 617                        break;
 618                case INET_DIAG_BC_AUTO:
 619                case INET_DIAG_BC_JMP:
 620                case INET_DIAG_BC_NOP:
 621                        break;
 622                default:
 623                        return -EINVAL;
 624                }
 625
 626                if (op->code != INET_DIAG_BC_NOP) {
 627                        if (op->no < min_len || op->no > len + 4 || op->no & 3)
 628                                return -EINVAL;
 629                        if (op->no < len &&
 630                            !valid_cc(bytecode, bytecode_len, len - op->no))
 631                                return -EINVAL;
 632                }
 633
 634                if (op->yes < min_len || op->yes > len + 4 || op->yes & 3)
 635                        return -EINVAL;
 636                bc  += op->yes;
 637                len -= op->yes;
 638        }
 639        return len == 0 ? 0 : -EINVAL;
 640}
 641
 642static int inet_csk_diag_dump(struct sock *sk,
 643                              struct sk_buff *skb,
 644                              struct netlink_callback *cb,
 645                              struct inet_diag_req_v2 *r,
 646                              const struct nlattr *bc)
 647{
 648        if (!inet_diag_bc_sk(bc, sk))
 649                return 0;
 650
 651        return inet_csk_diag_fill(sk, skb, r,
 652                                  sk_user_ns(NETLINK_CB(cb->skb).sk),
 653                                  NETLINK_CB(cb->skb).portid,
 654                                  cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 655}
 656
 657static int inet_twsk_diag_dump(struct sock *sk,
 658                               struct sk_buff *skb,
 659                               struct netlink_callback *cb,
 660                               struct inet_diag_req_v2 *r,
 661                               const struct nlattr *bc)
 662{
 663        struct inet_timewait_sock *tw = inet_twsk(sk);
 664
 665        if (bc != NULL) {
 666                struct inet_diag_entry entry;
 667
 668                entry.family = tw->tw_family;
 669#if IS_ENABLED(CONFIG_IPV6)
 670                if (tw->tw_family == AF_INET6) {
 671                        entry.saddr = tw->tw_v6_rcv_saddr.s6_addr32;
 672                        entry.daddr = tw->tw_v6_daddr.s6_addr32;
 673                } else
 674#endif
 675                {
 676                        entry.saddr = &tw->tw_rcv_saddr;
 677                        entry.daddr = &tw->tw_daddr;
 678                }
 679                entry.sport = tw->tw_num;
 680                entry.dport = ntohs(tw->tw_dport);
 681                entry.userlocks = 0;
 682
 683                if (!inet_diag_bc_run(bc, &entry))
 684                        return 0;
 685        }
 686
 687        return inet_twsk_diag_fill(tw, skb, r,
 688                                   NETLINK_CB(cb->skb).portid,
 689                                   cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 690}
 691
 692/* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses
 693 * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6.
 694 */
 695static inline void inet_diag_req_addrs(const struct sock *sk,
 696                                       const struct request_sock *req,
 697                                       struct inet_diag_entry *entry)
 698{
 699        struct inet_request_sock *ireq = inet_rsk(req);
 700
 701#if IS_ENABLED(CONFIG_IPV6)
 702        if (sk->sk_family == AF_INET6) {
 703                if (req->rsk_ops->family == AF_INET6) {
 704                        entry->saddr = ireq->ir_v6_loc_addr.s6_addr32;
 705                        entry->daddr = ireq->ir_v6_rmt_addr.s6_addr32;
 706                } else if (req->rsk_ops->family == AF_INET) {
 707                        ipv6_addr_set_v4mapped(ireq->ir_loc_addr,
 708                                               &entry->saddr_storage);
 709                        ipv6_addr_set_v4mapped(ireq->ir_rmt_addr,
 710                                               &entry->daddr_storage);
 711                        entry->saddr = entry->saddr_storage.s6_addr32;
 712                        entry->daddr = entry->daddr_storage.s6_addr32;
 713                }
 714        } else
 715#endif
 716        {
 717                entry->saddr = &ireq->ir_loc_addr;
 718                entry->daddr = &ireq->ir_rmt_addr;
 719        }
 720}
 721
 722static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
 723                              struct request_sock *req,
 724                              struct user_namespace *user_ns,
 725                              u32 portid, u32 seq,
 726                              const struct nlmsghdr *unlh)
 727{
 728        const struct inet_request_sock *ireq = inet_rsk(req);
 729        struct inet_sock *inet = inet_sk(sk);
 730        struct inet_diag_msg *r;
 731        struct nlmsghdr *nlh;
 732        long tmo;
 733
 734        nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
 735                        NLM_F_MULTI);
 736        if (!nlh)
 737                return -EMSGSIZE;
 738
 739        r = nlmsg_data(nlh);
 740        r->idiag_family = sk->sk_family;
 741        r->idiag_state = TCP_SYN_RECV;
 742        r->idiag_timer = 1;
 743        r->idiag_retrans = req->num_retrans;
 744
 745        r->id.idiag_if = sk->sk_bound_dev_if;
 746        sock_diag_save_cookie(req, r->id.idiag_cookie);
 747
 748        tmo = req->expires - jiffies;
 749        if (tmo < 0)
 750                tmo = 0;
 751
 752        r->id.idiag_sport = inet->inet_sport;
 753        r->id.idiag_dport = ireq->ir_rmt_port;
 754
 755        memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
 756        memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
 757
 758        r->id.idiag_src[0] = ireq->ir_loc_addr;
 759        r->id.idiag_dst[0] = ireq->ir_rmt_addr;
 760
 761        r->idiag_expires = jiffies_to_msecs(tmo);
 762        r->idiag_rqueue = 0;
 763        r->idiag_wqueue = 0;
 764        r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
 765        r->idiag_inode = 0;
 766#if IS_ENABLED(CONFIG_IPV6)
 767        if (r->idiag_family == AF_INET6) {
 768                struct inet_diag_entry entry;
 769                inet_diag_req_addrs(sk, req, &entry);
 770                memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr));
 771                memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr));
 772        }
 773#endif
 774
 775        nlmsg_end(skb, nlh);
 776        return 0;
 777}
 778
 779static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
 780                               struct netlink_callback *cb,
 781                               struct inet_diag_req_v2 *r,
 782                               const struct nlattr *bc)
 783{
 784        struct inet_diag_entry entry;
 785        struct inet_connection_sock *icsk = inet_csk(sk);
 786        struct listen_sock *lopt;
 787        struct inet_sock *inet = inet_sk(sk);
 788        int j, s_j;
 789        int reqnum, s_reqnum;
 790        int err = 0;
 791
 792        s_j = cb->args[3];
 793        s_reqnum = cb->args[4];
 794
 795        if (s_j > 0)
 796                s_j--;
 797
 798        entry.family = sk->sk_family;
 799
 800        read_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
 801
 802        lopt = icsk->icsk_accept_queue.listen_opt;
 803        if (!lopt || !lopt->qlen)
 804                goto out;
 805
 806        if (bc != NULL) {
 807                entry.sport = inet->inet_num;
 808                entry.userlocks = sk->sk_userlocks;
 809        }
 810
 811        for (j = s_j; j < lopt->nr_table_entries; j++) {
 812                struct request_sock *req, *head = lopt->syn_table[j];
 813
 814                reqnum = 0;
 815                for (req = head; req; reqnum++, req = req->dl_next) {
 816                        struct inet_request_sock *ireq = inet_rsk(req);
 817
 818                        if (reqnum < s_reqnum)
 819                                continue;
 820                        if (r->id.idiag_dport != ireq->ir_rmt_port &&
 821                            r->id.idiag_dport)
 822                                continue;
 823
 824                        if (bc) {
 825                                inet_diag_req_addrs(sk, req, &entry);
 826                                entry.dport = ntohs(ireq->ir_rmt_port);
 827
 828                                if (!inet_diag_bc_run(bc, &entry))
 829                                        continue;
 830                        }
 831
 832                        err = inet_diag_fill_req(skb, sk, req,
 833                                               sk_user_ns(NETLINK_CB(cb->skb).sk),
 834                                               NETLINK_CB(cb->skb).portid,
 835                                               cb->nlh->nlmsg_seq, cb->nlh);
 836                        if (err < 0) {
 837                                cb->args[3] = j + 1;
 838                                cb->args[4] = reqnum;
 839                                goto out;
 840                        }
 841                }
 842
 843                s_reqnum = 0;
 844        }
 845
 846out:
 847        read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
 848
 849        return err;
 850}
 851
 852void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
 853                struct netlink_callback *cb, struct inet_diag_req_v2 *r, struct nlattr *bc)
 854{
 855        int i, num;
 856        int s_i, s_num;
 857        struct net *net = sock_net(skb->sk);
 858
 859        s_i = cb->args[1];
 860        s_num = num = cb->args[2];
 861
 862        if (cb->args[0] == 0) {
 863                if (!(r->idiag_states & (TCPF_LISTEN | TCPF_SYN_RECV)))
 864                        goto skip_listen_ht;
 865
 866                for (i = s_i; i < INET_LHTABLE_SIZE; i++) {
 867                        struct sock *sk;
 868                        struct hlist_nulls_node *node;
 869                        struct inet_listen_hashbucket *ilb;
 870
 871                        num = 0;
 872                        ilb = &hashinfo->listening_hash[i];
 873                        spin_lock_bh(&ilb->lock);
 874                        sk_nulls_for_each(sk, node, &ilb->head) {
 875                                struct inet_sock *inet = inet_sk(sk);
 876
 877                                if (!net_eq(sock_net(sk), net))
 878                                        continue;
 879
 880                                if (num < s_num) {
 881                                        num++;
 882                                        continue;
 883                                }
 884
 885                                if (r->sdiag_family != AF_UNSPEC &&
 886                                                sk->sk_family != r->sdiag_family)
 887                                        goto next_listen;
 888
 889                                if (r->id.idiag_sport != inet->inet_sport &&
 890                                    r->id.idiag_sport)
 891                                        goto next_listen;
 892
 893                                if (!(r->idiag_states & TCPF_LISTEN) ||
 894                                    r->id.idiag_dport ||
 895                                    cb->args[3] > 0)
 896                                        goto syn_recv;
 897
 898                                if (inet_csk_diag_dump(sk, skb, cb, r, bc) < 0) {
 899                                        spin_unlock_bh(&ilb->lock);
 900                                        goto done;
 901                                }
 902
 903syn_recv:
 904                                if (!(r->idiag_states & TCPF_SYN_RECV))
 905                                        goto next_listen;
 906
 907                                if (inet_diag_dump_reqs(skb, sk, cb, r, bc) < 0) {
 908                                        spin_unlock_bh(&ilb->lock);
 909                                        goto done;
 910                                }
 911
 912next_listen:
 913                                cb->args[3] = 0;
 914                                cb->args[4] = 0;
 915                                ++num;
 916                        }
 917                        spin_unlock_bh(&ilb->lock);
 918
 919                        s_num = 0;
 920                        cb->args[3] = 0;
 921                        cb->args[4] = 0;
 922                }
 923skip_listen_ht:
 924                cb->args[0] = 1;
 925                s_i = num = s_num = 0;
 926        }
 927
 928        if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV)))
 929                goto out;
 930
 931        for (i = s_i; i <= hashinfo->ehash_mask; i++) {
 932                struct inet_ehash_bucket *head = &hashinfo->ehash[i];
 933                spinlock_t *lock = inet_ehash_lockp(hashinfo, i);
 934                struct sock *sk;
 935                struct hlist_nulls_node *node;
 936
 937                num = 0;
 938
 939                if (hlist_nulls_empty(&head->chain))
 940                        continue;
 941
 942                if (i > s_i)
 943                        s_num = 0;
 944
 945                spin_lock_bh(lock);
 946                sk_nulls_for_each(sk, node, &head->chain) {
 947                        int res;
 948                        int state;
 949
 950                        if (!net_eq(sock_net(sk), net))
 951                                continue;
 952                        if (num < s_num)
 953                                goto next_normal;
 954                        state = (sk->sk_state == TCP_TIME_WAIT) ?
 955                                inet_twsk(sk)->tw_substate : sk->sk_state;
 956                        if (!(r->idiag_states & (1 << state)))
 957                                goto next_normal;
 958                        if (r->sdiag_family != AF_UNSPEC &&
 959                            sk->sk_family != r->sdiag_family)
 960                                goto next_normal;
 961                        if (r->id.idiag_sport != htons(sk->sk_num) &&
 962                            r->id.idiag_sport)
 963                                goto next_normal;
 964                        if (r->id.idiag_dport != sk->sk_dport &&
 965                            r->id.idiag_dport)
 966                                goto next_normal;
 967                        if (sk->sk_state == TCP_TIME_WAIT)
 968                                res = inet_twsk_diag_dump(sk, skb, cb, r, bc);
 969                        else
 970                                res = inet_csk_diag_dump(sk, skb, cb, r, bc);
 971                        if (res < 0) {
 972                                spin_unlock_bh(lock);
 973                                goto done;
 974                        }
 975next_normal:
 976                        ++num;
 977                }
 978
 979                spin_unlock_bh(lock);
 980        }
 981
 982done:
 983        cb->args[1] = i;
 984        cb->args[2] = num;
 985out:
 986        ;
 987}
 988EXPORT_SYMBOL_GPL(inet_diag_dump_icsk);
 989
 990static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
 991                struct inet_diag_req_v2 *r, struct nlattr *bc)
 992{
 993        const struct inet_diag_handler *handler;
 994        int err = 0;
 995
 996        handler = inet_diag_lock_handler(r->sdiag_protocol);
 997        if (!IS_ERR(handler))
 998                handler->dump(skb, cb, r, bc);
 999        else
1000                err = PTR_ERR(handler);
1001        inet_diag_unlock_handler(handler);
1002
1003        return err ? : skb->len;
1004}
1005
1006static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
1007{
1008        struct nlattr *bc = NULL;
1009        int hdrlen = sizeof(struct inet_diag_req_v2);
1010
1011        if (nlmsg_attrlen(cb->nlh, hdrlen))
1012                bc = nlmsg_find_attr(cb->nlh, hdrlen, INET_DIAG_REQ_BYTECODE);
1013
1014        return __inet_diag_dump(skb, cb, nlmsg_data(cb->nlh), bc);
1015}
1016
1017static inline int inet_diag_type2proto(int type)
1018{
1019        switch (type) {
1020        case TCPDIAG_GETSOCK:
1021                return IPPROTO_TCP;
1022        case DCCPDIAG_GETSOCK:
1023                return IPPROTO_DCCP;
1024        default:
1025                return 0;
1026        }
1027}
1028
1029static int inet_diag_dump_compat(struct sk_buff *skb, struct netlink_callback *cb)
1030{
1031        struct inet_diag_req *rc = nlmsg_data(cb->nlh);
1032        struct inet_diag_req_v2 req;
1033        struct nlattr *bc = NULL;
1034        int hdrlen = sizeof(struct inet_diag_req);
1035
1036        req.sdiag_family = AF_UNSPEC; /* compatibility */
1037        req.sdiag_protocol = inet_diag_type2proto(cb->nlh->nlmsg_type);
1038        req.idiag_ext = rc->idiag_ext;
1039        req.idiag_states = rc->idiag_states;
1040        req.id = rc->id;
1041
1042        if (nlmsg_attrlen(cb->nlh, hdrlen))
1043                bc = nlmsg_find_attr(cb->nlh, hdrlen, INET_DIAG_REQ_BYTECODE);
1044
1045        return __inet_diag_dump(skb, cb, &req, bc);
1046}
1047
1048static int inet_diag_get_exact_compat(struct sk_buff *in_skb,
1049                               const struct nlmsghdr *nlh)
1050{
1051        struct inet_diag_req *rc = nlmsg_data(nlh);
1052        struct inet_diag_req_v2 req;
1053
1054        req.sdiag_family = rc->idiag_family;
1055        req.sdiag_protocol = inet_diag_type2proto(nlh->nlmsg_type);
1056        req.idiag_ext = rc->idiag_ext;
1057        req.idiag_states = rc->idiag_states;
1058        req.id = rc->id;
1059
1060        return inet_diag_get_exact(in_skb, nlh, &req);
1061}
1062
1063static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh)
1064{
1065        int hdrlen = sizeof(struct inet_diag_req);
1066        struct net *net = sock_net(skb->sk);
1067
1068        if (nlh->nlmsg_type >= INET_DIAG_GETSOCK_MAX ||
1069            nlmsg_len(nlh) < hdrlen)
1070                return -EINVAL;
1071
1072        if (nlh->nlmsg_flags & NLM_F_DUMP) {
1073                if (nlmsg_attrlen(nlh, hdrlen)) {
1074                        struct nlattr *attr;
1075
1076                        attr = nlmsg_find_attr(nlh, hdrlen,
1077                                               INET_DIAG_REQ_BYTECODE);
1078                        if (attr == NULL ||
1079                            nla_len(attr) < sizeof(struct inet_diag_bc_op) ||
1080                            inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
1081                                return -EINVAL;
1082                }
1083                {
1084                        struct netlink_dump_control c = {
1085                                .dump = inet_diag_dump_compat,
1086                        };
1087                        return netlink_dump_start(net->diag_nlsk, skb, nlh, &c);
1088                }
1089        }
1090
1091        return inet_diag_get_exact_compat(skb, nlh);
1092}
1093
1094static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
1095{
1096        int hdrlen = sizeof(struct inet_diag_req_v2);
1097        struct net *net = sock_net(skb->sk);
1098
1099        if (nlmsg_len(h) < hdrlen)
1100                return -EINVAL;
1101
1102        if (h->nlmsg_flags & NLM_F_DUMP) {
1103                if (nlmsg_attrlen(h, hdrlen)) {
1104                        struct nlattr *attr;
1105                        attr = nlmsg_find_attr(h, hdrlen,
1106                                               INET_DIAG_REQ_BYTECODE);
1107                        if (attr == NULL ||
1108                            nla_len(attr) < sizeof(struct inet_diag_bc_op) ||
1109                            inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
1110                                return -EINVAL;
1111                }
1112                {
1113                        struct netlink_dump_control c = {
1114                                .dump = inet_diag_dump,
1115                        };
1116                        return netlink_dump_start(net->diag_nlsk, skb, h, &c);
1117                }
1118        }
1119
1120        return inet_diag_get_exact(skb, h, nlmsg_data(h));
1121}
1122
1123static const struct sock_diag_handler inet_diag_handler = {
1124        .family = AF_INET,
1125        .dump = inet_diag_handler_dump,
1126};
1127
1128static const struct sock_diag_handler inet6_diag_handler = {
1129        .family = AF_INET6,
1130        .dump = inet_diag_handler_dump,
1131};
1132
1133int inet_diag_register(const struct inet_diag_handler *h)
1134{
1135        const __u16 type = h->idiag_type;
1136        int err = -EINVAL;
1137
1138        if (type >= IPPROTO_MAX)
1139                goto out;
1140
1141        mutex_lock(&inet_diag_table_mutex);
1142        err = -EEXIST;
1143        if (inet_diag_table[type] == NULL) {
1144                inet_diag_table[type] = h;
1145                err = 0;
1146        }
1147        mutex_unlock(&inet_diag_table_mutex);
1148out:
1149        return err;
1150}
1151EXPORT_SYMBOL_GPL(inet_diag_register);
1152
1153void inet_diag_unregister(const struct inet_diag_handler *h)
1154{
1155        const __u16 type = h->idiag_type;
1156
1157        if (type >= IPPROTO_MAX)
1158                return;
1159
1160        mutex_lock(&inet_diag_table_mutex);
1161        inet_diag_table[type] = NULL;
1162        mutex_unlock(&inet_diag_table_mutex);
1163}
1164EXPORT_SYMBOL_GPL(inet_diag_unregister);
1165
1166static int __init inet_diag_init(void)
1167{
1168        const int inet_diag_table_size = (IPPROTO_MAX *
1169                                          sizeof(struct inet_diag_handler *));
1170        int err = -ENOMEM;
1171
1172        inet_diag_table = kzalloc(inet_diag_table_size, GFP_KERNEL);
1173        if (!inet_diag_table)
1174                goto out;
1175
1176        err = sock_diag_register(&inet_diag_handler);
1177        if (err)
1178                goto out_free_nl;
1179
1180        err = sock_diag_register(&inet6_diag_handler);
1181        if (err)
1182                goto out_free_inet;
1183
1184        sock_diag_register_inet_compat(inet_diag_rcv_msg_compat);
1185out:
1186        return err;
1187
1188out_free_inet:
1189        sock_diag_unregister(&inet_diag_handler);
1190out_free_nl:
1191        kfree(inet_diag_table);
1192        goto out;
1193}
1194
1195static void __exit inet_diag_exit(void)
1196{
1197        sock_diag_unregister(&inet6_diag_handler);
1198        sock_diag_unregister(&inet_diag_handler);
1199        sock_diag_unregister_inet_compat(inet_diag_rcv_msg_compat);
1200        kfree(inet_diag_table);
1201}
1202
1203module_init(inet_diag_init);
1204module_exit(inet_diag_exit);
1205MODULE_LICENSE("GPL");
1206MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 2 /* AF_INET */);
1207MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 10 /* AF_INET6 */);
1208