0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/module.h>
0018 #include <linux/inet_diag.h>
0019 #include <linux/sock_diag.h>
0020 #include <net/sctp/sctp.h>
0021
0022 static void sctp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
0023 void *info);
0024
0025
0026 static void inet_diag_msg_sctpasoc_fill(struct inet_diag_msg *r,
0027 struct sock *sk,
0028 struct sctp_association *asoc)
0029 {
0030 union sctp_addr laddr, paddr;
0031 struct dst_entry *dst;
0032 struct timer_list *t3_rtx = &asoc->peer.primary_path->T3_rtx_timer;
0033
0034 laddr = list_entry(asoc->base.bind_addr.address_list.next,
0035 struct sctp_sockaddr_entry, list)->a;
0036 paddr = asoc->peer.primary_path->ipaddr;
0037 dst = asoc->peer.primary_path->dst;
0038
0039 r->idiag_family = sk->sk_family;
0040 r->id.idiag_sport = htons(asoc->base.bind_addr.port);
0041 r->id.idiag_dport = htons(asoc->peer.port);
0042 r->id.idiag_if = dst ? dst->dev->ifindex : 0;
0043 sock_diag_save_cookie(sk, r->id.idiag_cookie);
0044
0045 #if IS_ENABLED(CONFIG_IPV6)
0046 if (sk->sk_family == AF_INET6) {
0047 *(struct in6_addr *)r->id.idiag_src = laddr.v6.sin6_addr;
0048 *(struct in6_addr *)r->id.idiag_dst = paddr.v6.sin6_addr;
0049 } else
0050 #endif
0051 {
0052 memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
0053 memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
0054
0055 r->id.idiag_src[0] = laddr.v4.sin_addr.s_addr;
0056 r->id.idiag_dst[0] = paddr.v4.sin_addr.s_addr;
0057 }
0058
0059 r->idiag_state = asoc->state;
0060 if (timer_pending(t3_rtx)) {
0061 r->idiag_timer = SCTP_EVENT_TIMEOUT_T3_RTX;
0062 r->idiag_retrans = asoc->rtx_data_chunks;
0063 r->idiag_expires = jiffies_to_msecs(t3_rtx->expires - jiffies);
0064 }
0065 }
0066
0067 static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb,
0068 struct list_head *address_list)
0069 {
0070 struct sctp_sockaddr_entry *laddr;
0071 int addrlen = sizeof(struct sockaddr_storage);
0072 int addrcnt = 0;
0073 struct nlattr *attr;
0074 void *info = NULL;
0075
0076 list_for_each_entry_rcu(laddr, address_list, list)
0077 addrcnt++;
0078
0079 attr = nla_reserve(skb, INET_DIAG_LOCALS, addrlen * addrcnt);
0080 if (!attr)
0081 return -EMSGSIZE;
0082
0083 info = nla_data(attr);
0084 list_for_each_entry_rcu(laddr, address_list, list) {
0085 memcpy(info, &laddr->a, sizeof(laddr->a));
0086 memset(info + sizeof(laddr->a), 0, addrlen - sizeof(laddr->a));
0087 info += addrlen;
0088 }
0089
0090 return 0;
0091 }
0092
0093 static int inet_diag_msg_sctpaddrs_fill(struct sk_buff *skb,
0094 struct sctp_association *asoc)
0095 {
0096 int addrlen = sizeof(struct sockaddr_storage);
0097 struct sctp_transport *from;
0098 struct nlattr *attr;
0099 void *info = NULL;
0100
0101 attr = nla_reserve(skb, INET_DIAG_PEERS,
0102 addrlen * asoc->peer.transport_count);
0103 if (!attr)
0104 return -EMSGSIZE;
0105
0106 info = nla_data(attr);
0107 list_for_each_entry(from, &asoc->peer.transport_addr_list,
0108 transports) {
0109 memcpy(info, &from->ipaddr, sizeof(from->ipaddr));
0110 memset(info + sizeof(from->ipaddr), 0,
0111 addrlen - sizeof(from->ipaddr));
0112 info += addrlen;
0113 }
0114
0115 return 0;
0116 }
0117
0118
0119 static int inet_sctp_diag_fill(struct sock *sk, struct sctp_association *asoc,
0120 struct sk_buff *skb,
0121 const struct inet_diag_req_v2 *req,
0122 struct user_namespace *user_ns,
0123 int portid, u32 seq, u16 nlmsg_flags,
0124 const struct nlmsghdr *unlh,
0125 bool net_admin)
0126 {
0127 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
0128 struct list_head *addr_list;
0129 struct inet_diag_msg *r;
0130 struct nlmsghdr *nlh;
0131 int ext = req->idiag_ext;
0132 struct sctp_infox infox;
0133 void *info = NULL;
0134
0135 nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
0136 nlmsg_flags);
0137 if (!nlh)
0138 return -EMSGSIZE;
0139
0140 r = nlmsg_data(nlh);
0141 BUG_ON(!sk_fullsock(sk));
0142
0143 r->idiag_timer = 0;
0144 r->idiag_retrans = 0;
0145 r->idiag_expires = 0;
0146 if (asoc) {
0147 inet_diag_msg_sctpasoc_fill(r, sk, asoc);
0148 } else {
0149 inet_diag_msg_common_fill(r, sk);
0150 r->idiag_state = sk->sk_state;
0151 }
0152
0153 if (inet_diag_msg_attrs_fill(sk, skb, r, ext, user_ns, net_admin))
0154 goto errout;
0155
0156 if (ext & (1 << (INET_DIAG_SKMEMINFO - 1))) {
0157 u32 mem[SK_MEMINFO_VARS];
0158 int amt;
0159
0160 if (asoc && asoc->ep->sndbuf_policy)
0161 amt = asoc->sndbuf_used;
0162 else
0163 amt = sk_wmem_alloc_get(sk);
0164 mem[SK_MEMINFO_WMEM_ALLOC] = amt;
0165 if (asoc && asoc->ep->rcvbuf_policy)
0166 amt = atomic_read(&asoc->rmem_alloc);
0167 else
0168 amt = sk_rmem_alloc_get(sk);
0169 mem[SK_MEMINFO_RMEM_ALLOC] = amt;
0170 mem[SK_MEMINFO_RCVBUF] = sk->sk_rcvbuf;
0171 mem[SK_MEMINFO_SNDBUF] = sk->sk_sndbuf;
0172 mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc;
0173 mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued;
0174 mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc);
0175 mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len);
0176 mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops);
0177
0178 if (nla_put(skb, INET_DIAG_SKMEMINFO, sizeof(mem), &mem) < 0)
0179 goto errout;
0180 }
0181
0182 if (ext & (1 << (INET_DIAG_INFO - 1))) {
0183 struct nlattr *attr;
0184
0185 attr = nla_reserve_64bit(skb, INET_DIAG_INFO,
0186 sizeof(struct sctp_info),
0187 INET_DIAG_PAD);
0188 if (!attr)
0189 goto errout;
0190
0191 info = nla_data(attr);
0192 }
0193 infox.sctpinfo = (struct sctp_info *)info;
0194 infox.asoc = asoc;
0195 sctp_diag_get_info(sk, r, &infox);
0196
0197 addr_list = asoc ? &asoc->base.bind_addr.address_list
0198 : &ep->base.bind_addr.address_list;
0199 if (inet_diag_msg_sctpladdrs_fill(skb, addr_list))
0200 goto errout;
0201
0202 if (asoc && (ext & (1 << (INET_DIAG_CONG - 1))))
0203 if (nla_put_string(skb, INET_DIAG_CONG, "reno") < 0)
0204 goto errout;
0205
0206 if (asoc && inet_diag_msg_sctpaddrs_fill(skb, asoc))
0207 goto errout;
0208
0209 nlmsg_end(skb, nlh);
0210 return 0;
0211
0212 errout:
0213 nlmsg_cancel(skb, nlh);
0214 return -EMSGSIZE;
0215 }
0216
0217
0218 struct sctp_comm_param {
0219 struct sk_buff *skb;
0220 struct netlink_callback *cb;
0221 const struct inet_diag_req_v2 *r;
0222 const struct nlmsghdr *nlh;
0223 bool net_admin;
0224 };
0225
0226 static size_t inet_assoc_attr_size(struct sctp_association *asoc)
0227 {
0228 int addrlen = sizeof(struct sockaddr_storage);
0229 int addrcnt = 0;
0230 struct sctp_sockaddr_entry *laddr;
0231
0232 list_for_each_entry_rcu(laddr, &asoc->base.bind_addr.address_list,
0233 list)
0234 addrcnt++;
0235
0236 return nla_total_size(sizeof(struct sctp_info))
0237 + nla_total_size(addrlen * asoc->peer.transport_count)
0238 + nla_total_size(addrlen * addrcnt)
0239 + nla_total_size(sizeof(struct inet_diag_msg))
0240 + inet_diag_msg_attrs_size()
0241 + nla_total_size(sizeof(struct inet_diag_meminfo))
0242 + 64;
0243 }
0244
0245 static int sctp_sock_dump_one(struct sctp_endpoint *ep, struct sctp_transport *tsp, void *p)
0246 {
0247 struct sctp_association *assoc = tsp->asoc;
0248 struct sctp_comm_param *commp = p;
0249 struct sock *sk = ep->base.sk;
0250 const struct inet_diag_req_v2 *req = commp->r;
0251 struct sk_buff *skb = commp->skb;
0252 struct sk_buff *rep;
0253 int err;
0254
0255 err = sock_diag_check_cookie(sk, req->id.idiag_cookie);
0256 if (err)
0257 return err;
0258
0259 rep = nlmsg_new(inet_assoc_attr_size(assoc), GFP_KERNEL);
0260 if (!rep)
0261 return -ENOMEM;
0262
0263 lock_sock(sk);
0264 if (ep != assoc->ep) {
0265 err = -EAGAIN;
0266 goto out;
0267 }
0268
0269 err = inet_sctp_diag_fill(sk, assoc, rep, req, sk_user_ns(NETLINK_CB(skb).sk),
0270 NETLINK_CB(skb).portid, commp->nlh->nlmsg_seq, 0,
0271 commp->nlh, commp->net_admin);
0272 if (err < 0) {
0273 WARN_ON(err == -EMSGSIZE);
0274 goto out;
0275 }
0276 release_sock(sk);
0277
0278 return nlmsg_unicast(sock_net(skb->sk)->diag_nlsk, rep, NETLINK_CB(skb).portid);
0279
0280 out:
0281 release_sock(sk);
0282 kfree_skb(rep);
0283 return err;
0284 }
0285
0286 static int sctp_sock_dump(struct sctp_endpoint *ep, struct sctp_transport *tsp, void *p)
0287 {
0288 struct sctp_comm_param *commp = p;
0289 struct sock *sk = ep->base.sk;
0290 struct sk_buff *skb = commp->skb;
0291 struct netlink_callback *cb = commp->cb;
0292 const struct inet_diag_req_v2 *r = commp->r;
0293 struct sctp_association *assoc;
0294 int err = 0;
0295
0296 lock_sock(sk);
0297 if (ep != tsp->asoc->ep)
0298 goto release;
0299 list_for_each_entry(assoc, &ep->asocs, asocs) {
0300 if (cb->args[4] < cb->args[1])
0301 goto next;
0302
0303 if (r->id.idiag_sport != htons(assoc->base.bind_addr.port) &&
0304 r->id.idiag_sport)
0305 goto next;
0306 if (r->id.idiag_dport != htons(assoc->peer.port) &&
0307 r->id.idiag_dport)
0308 goto next;
0309
0310 if (!cb->args[3] &&
0311 inet_sctp_diag_fill(sk, NULL, skb, r,
0312 sk_user_ns(NETLINK_CB(cb->skb).sk),
0313 NETLINK_CB(cb->skb).portid,
0314 cb->nlh->nlmsg_seq,
0315 NLM_F_MULTI, cb->nlh,
0316 commp->net_admin) < 0) {
0317 err = 1;
0318 goto release;
0319 }
0320 cb->args[3] = 1;
0321
0322 if (inet_sctp_diag_fill(sk, assoc, skb, r,
0323 sk_user_ns(NETLINK_CB(cb->skb).sk),
0324 NETLINK_CB(cb->skb).portid,
0325 cb->nlh->nlmsg_seq, 0, cb->nlh,
0326 commp->net_admin) < 0) {
0327 err = 1;
0328 goto release;
0329 }
0330 next:
0331 cb->args[4]++;
0332 }
0333 cb->args[1] = 0;
0334 cb->args[3] = 0;
0335 cb->args[4] = 0;
0336 release:
0337 release_sock(sk);
0338 return err;
0339 }
0340
0341 static int sctp_sock_filter(struct sctp_endpoint *ep, struct sctp_transport *tsp, void *p)
0342 {
0343 struct sctp_comm_param *commp = p;
0344 struct sock *sk = ep->base.sk;
0345 const struct inet_diag_req_v2 *r = commp->r;
0346 struct sctp_association *assoc =
0347 list_entry(ep->asocs.next, struct sctp_association, asocs);
0348
0349
0350 if (tsp->asoc != assoc)
0351 return 0;
0352
0353 if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family)
0354 return 0;
0355
0356 return 1;
0357 }
0358
0359 static int sctp_ep_dump(struct sctp_endpoint *ep, void *p)
0360 {
0361 struct sctp_comm_param *commp = p;
0362 struct sock *sk = ep->base.sk;
0363 struct sk_buff *skb = commp->skb;
0364 struct netlink_callback *cb = commp->cb;
0365 const struct inet_diag_req_v2 *r = commp->r;
0366 struct net *net = sock_net(skb->sk);
0367 struct inet_sock *inet = inet_sk(sk);
0368 int err = 0;
0369
0370 if (!net_eq(sock_net(sk), net))
0371 goto out;
0372
0373 if (cb->args[4] < cb->args[1])
0374 goto next;
0375
0376 if (!(r->idiag_states & TCPF_LISTEN) && !list_empty(&ep->asocs))
0377 goto next;
0378
0379 if (r->sdiag_family != AF_UNSPEC &&
0380 sk->sk_family != r->sdiag_family)
0381 goto next;
0382
0383 if (r->id.idiag_sport != inet->inet_sport &&
0384 r->id.idiag_sport)
0385 goto next;
0386
0387 if (r->id.idiag_dport != inet->inet_dport &&
0388 r->id.idiag_dport)
0389 goto next;
0390
0391 if (inet_sctp_diag_fill(sk, NULL, skb, r,
0392 sk_user_ns(NETLINK_CB(cb->skb).sk),
0393 NETLINK_CB(cb->skb).portid,
0394 cb->nlh->nlmsg_seq, NLM_F_MULTI,
0395 cb->nlh, commp->net_admin) < 0) {
0396 err = 2;
0397 goto out;
0398 }
0399 next:
0400 cb->args[4]++;
0401 out:
0402 return err;
0403 }
0404
0405
0406 static void sctp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
0407 void *info)
0408 {
0409 struct sctp_infox *infox = (struct sctp_infox *)info;
0410
0411 if (infox->asoc) {
0412 r->idiag_rqueue = atomic_read(&infox->asoc->rmem_alloc);
0413 r->idiag_wqueue = infox->asoc->sndbuf_used;
0414 } else {
0415 r->idiag_rqueue = READ_ONCE(sk->sk_ack_backlog);
0416 r->idiag_wqueue = READ_ONCE(sk->sk_max_ack_backlog);
0417 }
0418 if (infox->sctpinfo)
0419 sctp_get_sctp_info(sk, infox->asoc, infox->sctpinfo);
0420 }
0421
0422 static int sctp_diag_dump_one(struct netlink_callback *cb,
0423 const struct inet_diag_req_v2 *req)
0424 {
0425 struct sk_buff *skb = cb->skb;
0426 struct net *net = sock_net(skb->sk);
0427 const struct nlmsghdr *nlh = cb->nlh;
0428 union sctp_addr laddr, paddr;
0429 struct sctp_comm_param commp = {
0430 .skb = skb,
0431 .r = req,
0432 .nlh = nlh,
0433 .net_admin = netlink_net_capable(skb, CAP_NET_ADMIN),
0434 };
0435
0436 if (req->sdiag_family == AF_INET) {
0437 laddr.v4.sin_port = req->id.idiag_sport;
0438 laddr.v4.sin_addr.s_addr = req->id.idiag_src[0];
0439 laddr.v4.sin_family = AF_INET;
0440
0441 paddr.v4.sin_port = req->id.idiag_dport;
0442 paddr.v4.sin_addr.s_addr = req->id.idiag_dst[0];
0443 paddr.v4.sin_family = AF_INET;
0444 } else {
0445 laddr.v6.sin6_port = req->id.idiag_sport;
0446 memcpy(&laddr.v6.sin6_addr, req->id.idiag_src,
0447 sizeof(laddr.v6.sin6_addr));
0448 laddr.v6.sin6_family = AF_INET6;
0449
0450 paddr.v6.sin6_port = req->id.idiag_dport;
0451 memcpy(&paddr.v6.sin6_addr, req->id.idiag_dst,
0452 sizeof(paddr.v6.sin6_addr));
0453 paddr.v6.sin6_family = AF_INET6;
0454 }
0455
0456 return sctp_transport_lookup_process(sctp_sock_dump_one,
0457 net, &laddr, &paddr, &commp);
0458 }
0459
0460 static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
0461 const struct inet_diag_req_v2 *r)
0462 {
0463 u32 idiag_states = r->idiag_states;
0464 struct net *net = sock_net(skb->sk);
0465 struct sctp_comm_param commp = {
0466 .skb = skb,
0467 .cb = cb,
0468 .r = r,
0469 .net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN),
0470 };
0471 int pos = cb->args[2];
0472
0473
0474
0475
0476
0477
0478
0479 if (cb->args[0] == 0) {
0480 if (!(idiag_states & TCPF_LISTEN))
0481 goto skip;
0482 if (sctp_for_each_endpoint(sctp_ep_dump, &commp))
0483 goto done;
0484 skip:
0485 cb->args[0] = 1;
0486 cb->args[1] = 0;
0487 cb->args[4] = 0;
0488 }
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
0499 goto done;
0500
0501 sctp_transport_traverse_process(sctp_sock_filter, sctp_sock_dump,
0502 net, &pos, &commp);
0503 cb->args[2] = pos;
0504
0505 done:
0506 cb->args[1] = cb->args[4];
0507 cb->args[4] = 0;
0508 }
0509
0510 static const struct inet_diag_handler sctp_diag_handler = {
0511 .dump = sctp_diag_dump,
0512 .dump_one = sctp_diag_dump_one,
0513 .idiag_get_info = sctp_diag_get_info,
0514 .idiag_type = IPPROTO_SCTP,
0515 .idiag_info_size = sizeof(struct sctp_info),
0516 };
0517
0518 static int __init sctp_diag_init(void)
0519 {
0520 return inet_diag_register(&sctp_diag_handler);
0521 }
0522
0523 static void __exit sctp_diag_exit(void)
0524 {
0525 inet_diag_unregister(&sctp_diag_handler);
0526 }
0527
0528 module_init(sctp_diag_init);
0529 module_exit(sctp_diag_exit);
0530 MODULE_LICENSE("GPL");
0531 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 2-132);