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