0001
0002 #include <linux/module.h>
0003 #include <linux/sock_diag.h>
0004 #include <linux/net.h>
0005 #include <linux/netdevice.h>
0006 #include <linux/packet_diag.h>
0007 #include <linux/percpu.h>
0008 #include <net/net_namespace.h>
0009 #include <net/sock.h>
0010
0011 #include "internal.h"
0012
0013 static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
0014 {
0015 struct packet_diag_info pinfo;
0016
0017 pinfo.pdi_index = po->ifindex;
0018 pinfo.pdi_version = po->tp_version;
0019 pinfo.pdi_reserve = po->tp_reserve;
0020 pinfo.pdi_copy_thresh = po->copy_thresh;
0021 pinfo.pdi_tstamp = po->tp_tstamp;
0022
0023 pinfo.pdi_flags = 0;
0024 if (po->running)
0025 pinfo.pdi_flags |= PDI_RUNNING;
0026 if (po->auxdata)
0027 pinfo.pdi_flags |= PDI_AUXDATA;
0028 if (po->origdev)
0029 pinfo.pdi_flags |= PDI_ORIGDEV;
0030 if (po->has_vnet_hdr)
0031 pinfo.pdi_flags |= PDI_VNETHDR;
0032 if (po->tp_loss)
0033 pinfo.pdi_flags |= PDI_LOSS;
0034
0035 return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo);
0036 }
0037
0038 static int pdiag_put_mclist(const struct packet_sock *po, struct sk_buff *nlskb)
0039 {
0040 struct nlattr *mca;
0041 struct packet_mclist *ml;
0042
0043 mca = nla_nest_start_noflag(nlskb, PACKET_DIAG_MCLIST);
0044 if (!mca)
0045 return -EMSGSIZE;
0046
0047 rtnl_lock();
0048 for (ml = po->mclist; ml; ml = ml->next) {
0049 struct packet_diag_mclist *dml;
0050
0051 dml = nla_reserve_nohdr(nlskb, sizeof(*dml));
0052 if (!dml) {
0053 rtnl_unlock();
0054 nla_nest_cancel(nlskb, mca);
0055 return -EMSGSIZE;
0056 }
0057
0058 dml->pdmc_index = ml->ifindex;
0059 dml->pdmc_type = ml->type;
0060 dml->pdmc_alen = ml->alen;
0061 dml->pdmc_count = ml->count;
0062 BUILD_BUG_ON(sizeof(dml->pdmc_addr) != sizeof(ml->addr));
0063 memcpy(dml->pdmc_addr, ml->addr, sizeof(ml->addr));
0064 }
0065
0066 rtnl_unlock();
0067 nla_nest_end(nlskb, mca);
0068
0069 return 0;
0070 }
0071
0072 static int pdiag_put_ring(struct packet_ring_buffer *ring, int ver, int nl_type,
0073 struct sk_buff *nlskb)
0074 {
0075 struct packet_diag_ring pdr;
0076
0077 if (!ring->pg_vec)
0078 return 0;
0079
0080 pdr.pdr_block_size = ring->pg_vec_pages << PAGE_SHIFT;
0081 pdr.pdr_block_nr = ring->pg_vec_len;
0082 pdr.pdr_frame_size = ring->frame_size;
0083 pdr.pdr_frame_nr = ring->frame_max + 1;
0084
0085 if (ver > TPACKET_V2) {
0086 pdr.pdr_retire_tmo = ring->prb_bdqc.retire_blk_tov;
0087 pdr.pdr_sizeof_priv = ring->prb_bdqc.blk_sizeof_priv;
0088 pdr.pdr_features = ring->prb_bdqc.feature_req_word;
0089 } else {
0090 pdr.pdr_retire_tmo = 0;
0091 pdr.pdr_sizeof_priv = 0;
0092 pdr.pdr_features = 0;
0093 }
0094
0095 return nla_put(nlskb, nl_type, sizeof(pdr), &pdr);
0096 }
0097
0098 static int pdiag_put_rings_cfg(struct packet_sock *po, struct sk_buff *skb)
0099 {
0100 int ret;
0101
0102 mutex_lock(&po->pg_vec_lock);
0103 ret = pdiag_put_ring(&po->rx_ring, po->tp_version,
0104 PACKET_DIAG_RX_RING, skb);
0105 if (!ret)
0106 ret = pdiag_put_ring(&po->tx_ring, po->tp_version,
0107 PACKET_DIAG_TX_RING, skb);
0108 mutex_unlock(&po->pg_vec_lock);
0109
0110 return ret;
0111 }
0112
0113 static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb)
0114 {
0115 int ret = 0;
0116
0117 mutex_lock(&fanout_mutex);
0118 if (po->fanout) {
0119 u32 val;
0120
0121 val = (u32)po->fanout->id | ((u32)po->fanout->type << 16);
0122 ret = nla_put_u32(nlskb, PACKET_DIAG_FANOUT, val);
0123 }
0124 mutex_unlock(&fanout_mutex);
0125
0126 return ret;
0127 }
0128
0129 static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
0130 struct packet_diag_req *req,
0131 bool may_report_filterinfo,
0132 struct user_namespace *user_ns,
0133 u32 portid, u32 seq, u32 flags, int sk_ino)
0134 {
0135 struct nlmsghdr *nlh;
0136 struct packet_diag_msg *rp;
0137 struct packet_sock *po = pkt_sk(sk);
0138
0139 nlh = nlmsg_put(skb, portid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rp), flags);
0140 if (!nlh)
0141 return -EMSGSIZE;
0142
0143 rp = nlmsg_data(nlh);
0144 rp->pdiag_family = AF_PACKET;
0145 rp->pdiag_type = sk->sk_type;
0146 rp->pdiag_num = ntohs(po->num);
0147 rp->pdiag_ino = sk_ino;
0148 sock_diag_save_cookie(sk, rp->pdiag_cookie);
0149
0150 if ((req->pdiag_show & PACKET_SHOW_INFO) &&
0151 pdiag_put_info(po, skb))
0152 goto out_nlmsg_trim;
0153
0154 if ((req->pdiag_show & PACKET_SHOW_INFO) &&
0155 nla_put_u32(skb, PACKET_DIAG_UID,
0156 from_kuid_munged(user_ns, sock_i_uid(sk))))
0157 goto out_nlmsg_trim;
0158
0159 if ((req->pdiag_show & PACKET_SHOW_MCLIST) &&
0160 pdiag_put_mclist(po, skb))
0161 goto out_nlmsg_trim;
0162
0163 if ((req->pdiag_show & PACKET_SHOW_RING_CFG) &&
0164 pdiag_put_rings_cfg(po, skb))
0165 goto out_nlmsg_trim;
0166
0167 if ((req->pdiag_show & PACKET_SHOW_FANOUT) &&
0168 pdiag_put_fanout(po, skb))
0169 goto out_nlmsg_trim;
0170
0171 if ((req->pdiag_show & PACKET_SHOW_MEMINFO) &&
0172 sock_diag_put_meminfo(sk, skb, PACKET_DIAG_MEMINFO))
0173 goto out_nlmsg_trim;
0174
0175 if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
0176 sock_diag_put_filterinfo(may_report_filterinfo, sk, skb,
0177 PACKET_DIAG_FILTER))
0178 goto out_nlmsg_trim;
0179
0180 nlmsg_end(skb, nlh);
0181 return 0;
0182
0183 out_nlmsg_trim:
0184 nlmsg_cancel(skb, nlh);
0185 return -EMSGSIZE;
0186 }
0187
0188 static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
0189 {
0190 int num = 0, s_num = cb->args[0];
0191 struct packet_diag_req *req;
0192 struct net *net;
0193 struct sock *sk;
0194 bool may_report_filterinfo;
0195
0196 net = sock_net(skb->sk);
0197 req = nlmsg_data(cb->nlh);
0198 may_report_filterinfo = netlink_net_capable(cb->skb, CAP_NET_ADMIN);
0199
0200 mutex_lock(&net->packet.sklist_lock);
0201 sk_for_each(sk, &net->packet.sklist) {
0202 if (!net_eq(sock_net(sk), net))
0203 continue;
0204 if (num < s_num)
0205 goto next;
0206
0207 if (sk_diag_fill(sk, skb, req,
0208 may_report_filterinfo,
0209 sk_user_ns(NETLINK_CB(cb->skb).sk),
0210 NETLINK_CB(cb->skb).portid,
0211 cb->nlh->nlmsg_seq, NLM_F_MULTI,
0212 sock_i_ino(sk)) < 0)
0213 goto done;
0214 next:
0215 num++;
0216 }
0217 done:
0218 mutex_unlock(&net->packet.sklist_lock);
0219 cb->args[0] = num;
0220
0221 return skb->len;
0222 }
0223
0224 static int packet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
0225 {
0226 int hdrlen = sizeof(struct packet_diag_req);
0227 struct net *net = sock_net(skb->sk);
0228 struct packet_diag_req *req;
0229
0230 if (nlmsg_len(h) < hdrlen)
0231 return -EINVAL;
0232
0233 req = nlmsg_data(h);
0234
0235 if (req->sdiag_protocol)
0236 return -EINVAL;
0237
0238 if (h->nlmsg_flags & NLM_F_DUMP) {
0239 struct netlink_dump_control c = {
0240 .dump = packet_diag_dump,
0241 };
0242 return netlink_dump_start(net->diag_nlsk, skb, h, &c);
0243 } else
0244 return -EOPNOTSUPP;
0245 }
0246
0247 static const struct sock_diag_handler packet_diag_handler = {
0248 .family = AF_PACKET,
0249 .dump = packet_diag_handler_dump,
0250 };
0251
0252 static int __init packet_diag_init(void)
0253 {
0254 return sock_diag_register(&packet_diag_handler);
0255 }
0256
0257 static void __exit packet_diag_exit(void)
0258 {
0259 sock_diag_unregister(&packet_diag_handler);
0260 }
0261
0262 module_init(packet_diag_init);
0263 module_exit(packet_diag_exit);
0264 MODULE_LICENSE("GPL");
0265 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 17 );