blob: db792e02a37feec8b65d9c61976cf69f49c3b140 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * PACKET - implements raw packet sockets.
7 *
Jesper Juhl02c30a82005-05-05 16:16:16 -07008 * Authors: Ross Biro
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
10 * Alan Cox, <gw4pts@gw4pts.ampr.org>
11 *
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +090012 * Fixes:
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * Alan Cox : verify_area() now used correctly
14 * Alan Cox : new skbuff lists, look ma no backlogs!
15 * Alan Cox : tidied skbuff lists.
16 * Alan Cox : Now uses generic datagram routines I
17 * added. Also fixed the peek/read crash
18 * from all old Linux datagram code.
19 * Alan Cox : Uses the improved datagram code.
20 * Alan Cox : Added NULL's for socket options.
21 * Alan Cox : Re-commented the code.
22 * Alan Cox : Use new kernel side addressing
23 * Rob Janssen : Correct MTU usage.
24 * Dave Platt : Counter leaks caused by incorrect
25 * interrupt locking and some slightly
26 * dubious gcc output. Can you read
27 * compiler: it said _VOLATILE_
28 * Richard Kooijman : Timestamp fixes.
29 * Alan Cox : New buffers. Use sk->mac.raw.
30 * Alan Cox : sendmsg/recvmsg support.
31 * Alan Cox : Protocol setting support
32 * Alexey Kuznetsov : Untied from IPv4 stack.
33 * Cyrus Durgin : Fixed kerneld for kmod.
34 * Michal Ostrowski : Module initialization cleanup.
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +090035 * Ulises Alonso : Frame number limit removal and
Linus Torvalds1da177e2005-04-16 15:20:36 -070036 * packet_set_ring memory leak.
Eric W. Biederman0fb375f2005-09-21 00:11:37 -070037 * Eric Biederman : Allow for > 8 byte hardware addresses.
38 * The convention is that longer addresses
39 * will simply extend the hardware address
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +090040 * byte arrays at the end of sockaddr_ll
Eric W. Biederman0fb375f2005-09-21 00:11:37 -070041 * and packet_mreq.
Linus Torvalds1da177e2005-04-16 15:20:36 -070042 *
43 * This program is free software; you can redistribute it and/or
44 * modify it under the terms of the GNU General Public License
45 * as published by the Free Software Foundation; either version
46 * 2 of the License, or (at your option) any later version.
47 *
48 */
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +090049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <linux/types.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <linux/mm.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080052#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#include <linux/fcntl.h>
54#include <linux/socket.h>
55#include <linux/in.h>
56#include <linux/inet.h>
57#include <linux/netdevice.h>
58#include <linux/if_packet.h>
59#include <linux/wireless.h>
Herbert Xuffbc6112007-02-04 23:33:10 -080060#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#include <linux/kmod.h>
Eric W. Biederman457c4cb2007-09-12 12:01:34 +020062#include <net/net_namespace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#include <net/ip.h>
64#include <net/protocol.h>
65#include <linux/skbuff.h>
66#include <net/sock.h>
67#include <linux/errno.h>
68#include <linux/timer.h>
69#include <asm/system.h>
70#include <asm/uaccess.h>
71#include <asm/ioctls.h>
72#include <asm/page.h>
Al Viroa1f8e7f72006-10-19 16:08:53 -040073#include <asm/cacheflush.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070074#include <asm/io.h>
75#include <linux/proc_fs.h>
76#include <linux/seq_file.h>
77#include <linux/poll.h>
78#include <linux/module.h>
79#include <linux/init.h>
80
81#ifdef CONFIG_INET
82#include <net/inet_common.h>
83#endif
84
Linus Torvalds1da177e2005-04-16 15:20:36 -070085/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 Assumptions:
87 - if device has no dev->hard_header routine, it adds and removes ll header
88 inside itself. In this case ll header is invisible outside of device,
89 but higher levels still should reserve dev->hard_header_len.
90 Some devices are enough clever to reallocate skb, when header
91 will not fit to reserved space (tunnel), another ones are silly
92 (PPP).
93 - packet socket receives packets with pulled ll header,
94 so that SOCK_RAW should push it back.
95
96On receive:
97-----------
98
99Incoming, dev->hard_header!=NULL
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700100 mac_header -> ll header
101 data -> data
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103Outgoing, dev->hard_header!=NULL
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700104 mac_header -> ll header
105 data -> ll header
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
107Incoming, dev->hard_header==NULL
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700108 mac_header -> UNKNOWN position. It is very likely, that it points to ll
109 header. PPP makes it, that is wrong, because introduce
YOSHIFUJI Hideakidb0c58f2007-07-19 10:44:35 +0900110 assymetry between rx and tx paths.
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700111 data -> data
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
113Outgoing, dev->hard_header==NULL
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700114 mac_header -> data. ll header is still not built!
115 data -> data
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
117Resume
118 If dev->hard_header==NULL we are unlikely to restore sensible ll header.
119
120
121On transmit:
122------------
123
124dev->hard_header != NULL
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700125 mac_header -> ll header
126 data -> ll header
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
128dev->hard_header == NULL (ll header is added by device, we cannot control it)
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700129 mac_header -> data
130 data -> data
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
132 We should set nh.raw on output to correct posistion,
133 packet classifier depends on it.
134 */
135
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136/* Private packet socket structures. */
137
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138struct packet_mclist
139{
140 struct packet_mclist *next;
141 int ifindex;
142 int count;
143 unsigned short type;
144 unsigned short alen;
Eric W. Biederman0fb375f2005-09-21 00:11:37 -0700145 unsigned char addr[MAX_ADDR_LEN];
146};
147/* identical to struct packet_mreq except it has
148 * a longer address field.
149 */
150struct packet_mreq_max
151{
152 int mr_ifindex;
153 unsigned short mr_type;
154 unsigned short mr_alen;
155 unsigned char mr_address[MAX_ADDR_LEN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156};
David S. Millera2efcfa2007-05-29 13:12:50 -0700157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158#ifdef CONFIG_PACKET_MMAP
159static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing);
160#endif
161
162static void packet_flush_mclist(struct sock *sk);
163
164struct packet_sock {
165 /* struct sock has to be the first member of packet_sock */
166 struct sock sk;
167 struct tpacket_stats stats;
168#ifdef CONFIG_PACKET_MMAP
169 char * *pg_vec;
170 unsigned int head;
171 unsigned int frames_per_block;
172 unsigned int frame_size;
173 unsigned int frame_max;
174 int copy_thresh;
175#endif
176 struct packet_type prot_hook;
177 spinlock_t bind_lock;
Herbert Xu8dc41942007-02-04 23:31:32 -0800178 unsigned int running:1, /* prot_hook is attached*/
Peter P. Waskiewicz Jr80feaac2007-04-20 16:05:39 -0700179 auxdata:1,
180 origdev:1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 int ifindex; /* bound device */
Al Viro0e11c912006-11-08 00:26:29 -0800182 __be16 num;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 struct packet_mclist *mclist;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184#ifdef CONFIG_PACKET_MMAP
185 atomic_t mapped;
186 unsigned int pg_vec_order;
187 unsigned int pg_vec_pages;
188 unsigned int pg_vec_len;
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700189 enum tpacket_versions tp_version;
190 unsigned int tp_hdrlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191#endif
192};
193
Herbert Xuffbc6112007-02-04 23:33:10 -0800194struct packet_skb_cb {
195 unsigned int origlen;
196 union {
197 struct sockaddr_pkt pkt;
198 struct sockaddr_ll ll;
199 } sa;
200};
201
202#define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb))
Herbert Xu8dc41942007-02-04 23:31:32 -0800203
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204#ifdef CONFIG_PACKET_MMAP
205
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700206static void *packet_lookup_frame(struct packet_sock *po, unsigned int position,
207 int status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208{
209 unsigned int pg_vec_pos, frame_offset;
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700210 union {
211 struct tpacket_hdr *h1;
212 struct tpacket2_hdr *h2;
213 void *raw;
214 } h;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
216 pg_vec_pos = position / po->frames_per_block;
217 frame_offset = position % po->frames_per_block;
218
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700219 h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
220 switch (po->tp_version) {
221 case TPACKET_V1:
222 if (status != h.h1->tp_status ? TP_STATUS_USER :
223 TP_STATUS_KERNEL)
224 return NULL;
225 break;
226 case TPACKET_V2:
227 if (status != h.h2->tp_status ? TP_STATUS_USER :
228 TP_STATUS_KERNEL)
229 return NULL;
230 break;
231 }
232 return h.raw;
233}
234
235static void __packet_set_status(struct packet_sock *po, void *frame, int status)
236{
237 union {
238 struct tpacket_hdr *h1;
239 struct tpacket2_hdr *h2;
240 void *raw;
241 } h;
242
243 h.raw = frame;
244 switch (po->tp_version) {
245 case TPACKET_V1:
246 h.h1->tp_status = status;
247 break;
248 case TPACKET_V2:
249 h.h2->tp_status = status;
250 break;
251 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252}
253#endif
254
255static inline struct packet_sock *pkt_sk(struct sock *sk)
256{
257 return (struct packet_sock *)sk;
258}
259
260static void packet_sock_destruct(struct sock *sk)
261{
262 BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
263 BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
264
265 if (!sock_flag(sk, SOCK_DEAD)) {
266 printk("Attempt to release alive packet socket: %p\n", sk);
267 return;
268 }
269
Pavel Emelyanov17ab56a2007-11-10 21:38:48 -0800270 sk_refcnt_debug_dec(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271}
272
273
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800274static const struct proto_ops packet_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800276static const struct proto_ops packet_ops_spkt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
David S. Millerf2ccd8f2005-08-09 19:34:12 -0700278static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279{
280 struct sock *sk;
281 struct sockaddr_pkt *spkt;
282
283 /*
284 * When we registered the protocol we saved the socket in the data
285 * field for just this event.
286 */
287
288 sk = pt->af_packet_priv;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900289
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 /*
291 * Yank back the headers [hope the device set this
292 * right or kerboom...]
293 *
294 * Incoming packets have ll header pulled,
295 * push it back.
296 *
Arnaldo Carvalho de Melo98e399f2007-03-19 15:33:04 -0700297 * For outgoing ones skb->data == skb_mac_header(skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 * so that this procedure is noop.
299 */
300
301 if (skb->pkt_type == PACKET_LOOPBACK)
302 goto out;
303
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900304 if (dev_net(dev) != sock_net(sk))
Denis V. Lunevd12d01d2007-11-19 22:28:35 -0800305 goto out;
306
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
308 goto oom;
309
310 /* drop any routing info */
311 dst_release(skb->dst);
312 skb->dst = NULL;
313
Phil Oester84531c22005-07-12 11:57:52 -0700314 /* drop conntrack reference */
315 nf_reset(skb);
316
Herbert Xuffbc6112007-02-04 23:33:10 -0800317 spkt = &PACKET_SKB_CB(skb)->sa.pkt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318
Arnaldo Carvalho de Melo98e399f2007-03-19 15:33:04 -0700319 skb_push(skb, skb->data - skb_mac_header(skb));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320
321 /*
322 * The SOCK_PACKET socket receives _all_ frames.
323 */
324
325 spkt->spkt_family = dev->type;
326 strlcpy(spkt->spkt_device, dev->name, sizeof(spkt->spkt_device));
327 spkt->spkt_protocol = skb->protocol;
328
329 /*
330 * Charge the memory to the socket. This is done specifically
331 * to prevent sockets using all the memory up.
332 */
333
334 if (sock_queue_rcv_skb(sk,skb) == 0)
335 return 0;
336
337out:
338 kfree_skb(skb);
339oom:
340 return 0;
341}
342
343
344/*
345 * Output a raw packet to a device layer. This bypasses all the other
346 * protocol layers and you must therefore supply it with a complete frame
347 */
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900348
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
350 struct msghdr *msg, size_t len)
351{
352 struct sock *sk = sock->sk;
353 struct sockaddr_pkt *saddr=(struct sockaddr_pkt *)msg->msg_name;
354 struct sk_buff *skb;
355 struct net_device *dev;
Al Viro0e11c912006-11-08 00:26:29 -0800356 __be16 proto=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 int err;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900358
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 /*
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900360 * Get and verify the address.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 */
362
363 if (saddr)
364 {
365 if (msg->msg_namelen < sizeof(struct sockaddr))
366 return(-EINVAL);
367 if (msg->msg_namelen==sizeof(struct sockaddr_pkt))
368 proto=saddr->spkt_protocol;
369 }
370 else
371 return(-ENOTCONN); /* SOCK_PACKET must be sent giving an address */
372
373 /*
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900374 * Find the device first to size check it
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 */
376
377 saddr->spkt_device[13] = 0;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900378 dev = dev_get_by_name(sock_net(sk), saddr->spkt_device);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 err = -ENODEV;
380 if (dev == NULL)
381 goto out_unlock;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900382
David S. Millerd5e76b02007-01-25 19:30:36 -0800383 err = -ENETDOWN;
384 if (!(dev->flags & IFF_UP))
385 goto out_unlock;
386
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 /*
388 * You may not queue a frame bigger than the mtu. This is the lowest level
389 * raw protocol and you must do your own fragmentation at this level.
390 */
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900391
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 err = -EMSGSIZE;
Kris Katterjohn8ae55f02006-01-23 16:28:02 -0800393 if (len > dev->mtu + dev->hard_header_len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 goto out_unlock;
395
396 err = -ENOBUFS;
397 skb = sock_wmalloc(sk, len + LL_RESERVED_SPACE(dev), 0, GFP_KERNEL);
398
399 /*
400 * If the write buffer is full, then tough. At this level the user gets to
401 * deal with the problem - do your own algorithmic backoffs. That's far
402 * more flexible.
403 */
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900404
405 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 goto out_unlock;
407
408 /*
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900409 * Fill it in
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 */
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900411
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 /* FIXME: Save some space for broken drivers that write a
413 * hard header at transmission time by themselves. PPP is the
414 * notable one here. This should really be fixed at the driver level.
415 */
416 skb_reserve(skb, LL_RESERVED_SPACE(dev));
Arnaldo Carvalho de Meloc1d2bbe2007-04-10 20:45:18 -0700417 skb_reset_network_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
419 /* Try to align data part correctly */
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700420 if (dev->header_ops) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 skb->data -= dev->hard_header_len;
422 skb->tail -= dev->hard_header_len;
423 if (len < dev->hard_header_len)
Arnaldo Carvalho de Meloc1d2bbe2007-04-10 20:45:18 -0700424 skb_reset_network_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 }
426
427 /* Returns -EFAULT on error */
428 err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
429 skb->protocol = proto;
430 skb->dev = dev;
431 skb->priority = sk->sk_priority;
432 if (err)
433 goto out_free;
434
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 /*
436 * Now send it
437 */
438
439 dev_queue_xmit(skb);
440 dev_put(dev);
441 return(len);
442
443out_free:
444 kfree_skb(skb);
445out_unlock:
446 if (dev)
447 dev_put(dev);
448 return err;
449}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450
David S. Millerdbcb5852007-01-24 15:21:02 -0800451static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
452 unsigned int res)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453{
454 struct sk_filter *filter;
455
Dmitry Mishinfda9ef52006-08-31 15:28:39 -0700456 rcu_read_lock_bh();
457 filter = rcu_dereference(sk->sk_filter);
David S. Millerdbcb5852007-01-24 15:21:02 -0800458 if (filter != NULL)
459 res = sk_run_filter(skb, filter->insns, filter->len);
Dmitry Mishinfda9ef52006-08-31 15:28:39 -0700460 rcu_read_unlock_bh();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461
David S. Millerdbcb5852007-01-24 15:21:02 -0800462 return res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463}
464
465/*
466 This function makes lazy skb cloning in hope that most of packets
467 are discarded by BPF.
468
469 Note tricky part: we DO mangle shared skb! skb->data, skb->len
470 and skb->cb are mangled. It works because (and until) packets
471 falling here are owned by current CPU. Output packets are cloned
472 by dev_queue_xmit_nit(), input packets are processed by net_bh
473 sequencially, so that if we return skb to original state on exit,
474 we will not harm anyone.
475 */
476
David S. Millerf2ccd8f2005-08-09 19:34:12 -0700477static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478{
479 struct sock *sk;
480 struct sockaddr_ll *sll;
481 struct packet_sock *po;
482 u8 * skb_head = skb->data;
483 int skb_len = skb->len;
David S. Millerdbcb5852007-01-24 15:21:02 -0800484 unsigned int snaplen, res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485
486 if (skb->pkt_type == PACKET_LOOPBACK)
487 goto drop;
488
489 sk = pt->af_packet_priv;
490 po = pkt_sk(sk);
491
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900492 if (dev_net(dev) != sock_net(sk))
Denis V. Lunevd12d01d2007-11-19 22:28:35 -0800493 goto drop;
494
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 skb->dev = dev;
496
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700497 if (dev->header_ops) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 /* The device has an explicit notion of ll header,
499 exported to higher levels.
500
501 Otherwise, the device hides datails of it frame
502 structure, so that corresponding packet head
503 never delivered to user.
504 */
505 if (sk->sk_type != SOCK_DGRAM)
Arnaldo Carvalho de Melo98e399f2007-03-19 15:33:04 -0700506 skb_push(skb, skb->data - skb_mac_header(skb));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 else if (skb->pkt_type == PACKET_OUTGOING) {
508 /* Special case: outgoing packets have ll header at head */
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -0300509 skb_pull(skb, skb_network_offset(skb));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
511 }
512
513 snaplen = skb->len;
514
David S. Millerdbcb5852007-01-24 15:21:02 -0800515 res = run_filter(skb, sk, snaplen);
516 if (!res)
Dmitry Mishinfda9ef52006-08-31 15:28:39 -0700517 goto drop_n_restore;
David S. Millerdbcb5852007-01-24 15:21:02 -0800518 if (snaplen > res)
519 snaplen = res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
521 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
522 (unsigned)sk->sk_rcvbuf)
523 goto drop_n_acct;
524
525 if (skb_shared(skb)) {
526 struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
527 if (nskb == NULL)
528 goto drop_n_acct;
529
530 if (skb_head != skb->data) {
531 skb->data = skb_head;
532 skb->len = skb_len;
533 }
534 kfree_skb(skb);
535 skb = nskb;
536 }
537
Herbert Xuffbc6112007-02-04 23:33:10 -0800538 BUILD_BUG_ON(sizeof(*PACKET_SKB_CB(skb)) + MAX_ADDR_LEN - 8 >
539 sizeof(skb->cb));
540
541 sll = &PACKET_SKB_CB(skb)->sa.ll;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 sll->sll_family = AF_PACKET;
543 sll->sll_hatype = dev->type;
544 sll->sll_protocol = skb->protocol;
545 sll->sll_pkttype = skb->pkt_type;
Peter P Waskiewicz Jr8032b462007-11-10 22:03:25 -0800546 if (unlikely(po->origdev))
Peter P. Waskiewicz Jr80feaac2007-04-20 16:05:39 -0700547 sll->sll_ifindex = orig_dev->ifindex;
548 else
549 sll->sll_ifindex = dev->ifindex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
Stephen Hemmingerb95cce32007-09-26 22:13:38 -0700551 sll->sll_halen = dev_parse_header(skb, sll->sll_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
Herbert Xuffbc6112007-02-04 23:33:10 -0800553 PACKET_SKB_CB(skb)->origlen = skb->len;
Herbert Xu8dc41942007-02-04 23:31:32 -0800554
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 if (pskb_trim(skb, snaplen))
556 goto drop_n_acct;
557
558 skb_set_owner_r(skb, sk);
559 skb->dev = NULL;
560 dst_release(skb->dst);
561 skb->dst = NULL;
562
Phil Oester84531c22005-07-12 11:57:52 -0700563 /* drop conntrack reference */
564 nf_reset(skb);
565
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 spin_lock(&sk->sk_receive_queue.lock);
567 po->stats.tp_packets++;
568 __skb_queue_tail(&sk->sk_receive_queue, skb);
569 spin_unlock(&sk->sk_receive_queue.lock);
570 sk->sk_data_ready(sk, skb->len);
571 return 0;
572
573drop_n_acct:
574 spin_lock(&sk->sk_receive_queue.lock);
575 po->stats.tp_drops++;
576 spin_unlock(&sk->sk_receive_queue.lock);
577
578drop_n_restore:
579 if (skb_head != skb->data && skb_shared(skb)) {
580 skb->data = skb_head;
581 skb->len = skb_len;
582 }
583drop:
584 kfree_skb(skb);
585 return 0;
586}
587
588#ifdef CONFIG_PACKET_MMAP
David S. Millerf2ccd8f2005-08-09 19:34:12 -0700589static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590{
591 struct sock *sk;
592 struct packet_sock *po;
593 struct sockaddr_ll *sll;
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700594 union {
595 struct tpacket_hdr *h1;
596 struct tpacket2_hdr *h2;
597 void *raw;
598 } h;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 u8 * skb_head = skb->data;
600 int skb_len = skb->len;
David S. Millerdbcb5852007-01-24 15:21:02 -0800601 unsigned int snaplen, res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700603 unsigned short macoff, netoff, hdrlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 struct sk_buff *copy_skb = NULL;
Eric Dumazetb7aa0bf2007-04-19 16:16:32 -0700605 struct timeval tv;
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700606 struct timespec ts;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
608 if (skb->pkt_type == PACKET_LOOPBACK)
609 goto drop;
610
611 sk = pt->af_packet_priv;
612 po = pkt_sk(sk);
613
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900614 if (dev_net(dev) != sock_net(sk))
Denis V. Lunevd12d01d2007-11-19 22:28:35 -0800615 goto drop;
616
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700617 if (dev->header_ops) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 if (sk->sk_type != SOCK_DGRAM)
Arnaldo Carvalho de Melo98e399f2007-03-19 15:33:04 -0700619 skb_push(skb, skb->data - skb_mac_header(skb));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 else if (skb->pkt_type == PACKET_OUTGOING) {
621 /* Special case: outgoing packets have ll header at head */
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -0300622 skb_pull(skb, skb_network_offset(skb));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 }
624 }
625
Herbert Xu8dc41942007-02-04 23:31:32 -0800626 if (skb->ip_summed == CHECKSUM_PARTIAL)
627 status |= TP_STATUS_CSUMNOTREADY;
628
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 snaplen = skb->len;
630
David S. Millerdbcb5852007-01-24 15:21:02 -0800631 res = run_filter(skb, sk, snaplen);
632 if (!res)
Dmitry Mishinfda9ef52006-08-31 15:28:39 -0700633 goto drop_n_restore;
David S. Millerdbcb5852007-01-24 15:21:02 -0800634 if (snaplen > res)
635 snaplen = res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636
637 if (sk->sk_type == SOCK_DGRAM) {
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700638 macoff = netoff = TPACKET_ALIGN(po->tp_hdrlen) + 16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 } else {
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -0300640 unsigned maclen = skb_network_offset(skb);
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700641 netoff = TPACKET_ALIGN(po->tp_hdrlen +
642 (maclen < 16 ? 16 : maclen));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 macoff = netoff - maclen;
644 }
645
646 if (macoff + snaplen > po->frame_size) {
647 if (po->copy_thresh &&
648 atomic_read(&sk->sk_rmem_alloc) + skb->truesize <
649 (unsigned)sk->sk_rcvbuf) {
650 if (skb_shared(skb)) {
651 copy_skb = skb_clone(skb, GFP_ATOMIC);
652 } else {
653 copy_skb = skb_get(skb);
654 skb_head = skb->data;
655 }
656 if (copy_skb)
657 skb_set_owner_r(copy_skb, sk);
658 }
659 snaplen = po->frame_size - macoff;
660 if ((int)snaplen < 0)
661 snaplen = 0;
662 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663
664 spin_lock(&sk->sk_receive_queue.lock);
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700665 h.raw = packet_lookup_frame(po, po->head, TP_STATUS_KERNEL);
666 if (!h.raw)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 goto ring_is_full;
668 po->head = po->head != po->frame_max ? po->head+1 : 0;
669 po->stats.tp_packets++;
670 if (copy_skb) {
671 status |= TP_STATUS_COPY;
672 __skb_queue_tail(&sk->sk_receive_queue, copy_skb);
673 }
674 if (!po->stats.tp_drops)
675 status &= ~TP_STATUS_LOSING;
676 spin_unlock(&sk->sk_receive_queue.lock);
677
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700678 skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700680 switch (po->tp_version) {
681 case TPACKET_V1:
682 h.h1->tp_len = skb->len;
683 h.h1->tp_snaplen = snaplen;
684 h.h1->tp_mac = macoff;
685 h.h1->tp_net = netoff;
686 if (skb->tstamp.tv64)
687 tv = ktime_to_timeval(skb->tstamp);
688 else
689 do_gettimeofday(&tv);
690 h.h1->tp_sec = tv.tv_sec;
691 h.h1->tp_usec = tv.tv_usec;
692 hdrlen = sizeof(*h.h1);
693 break;
694 case TPACKET_V2:
695 h.h2->tp_len = skb->len;
696 h.h2->tp_snaplen = snaplen;
697 h.h2->tp_mac = macoff;
698 h.h2->tp_net = netoff;
699 if (skb->tstamp.tv64)
700 ts = ktime_to_timespec(skb->tstamp);
701 else
702 getnstimeofday(&ts);
703 h.h2->tp_sec = ts.tv_sec;
704 h.h2->tp_nsec = ts.tv_nsec;
Patrick McHardy393e52e2008-07-14 22:50:39 -0700705 h.h2->tp_vlan_tci = skb->vlan_tci;
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700706 hdrlen = sizeof(*h.h2);
707 break;
708 default:
709 BUG();
710 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700712 sll = h.raw + TPACKET_ALIGN(hdrlen);
Stephen Hemmingerb95cce32007-09-26 22:13:38 -0700713 sll->sll_halen = dev_parse_header(skb, sll->sll_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 sll->sll_family = AF_PACKET;
715 sll->sll_hatype = dev->type;
716 sll->sll_protocol = skb->protocol;
717 sll->sll_pkttype = skb->pkt_type;
Peter P Waskiewicz Jr8032b462007-11-10 22:03:25 -0800718 if (unlikely(po->origdev))
Peter P. Waskiewicz Jr80feaac2007-04-20 16:05:39 -0700719 sll->sll_ifindex = orig_dev->ifindex;
720 else
721 sll->sll_ifindex = dev->ifindex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700723 __packet_set_status(po, h.raw, status);
Ralf Baechlee16aa202006-12-07 00:11:33 -0800724 smp_mb();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725
726 {
727 struct page *p_start, *p_end;
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700728 u8 *h_end = h.raw + macoff + snaplen - 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
Patrick McHardybbd6ef82008-07-14 22:50:15 -0700730 p_start = virt_to_page(h.raw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 p_end = virt_to_page(h_end);
732 while (p_start <= p_end) {
733 flush_dcache_page(p_start);
734 p_start++;
735 }
736 }
737
738 sk->sk_data_ready(sk, 0);
739
740drop_n_restore:
741 if (skb_head != skb->data && skb_shared(skb)) {
742 skb->data = skb_head;
743 skb->len = skb_len;
744 }
745drop:
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900746 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 return 0;
748
749ring_is_full:
750 po->stats.tp_drops++;
751 spin_unlock(&sk->sk_receive_queue.lock);
752
753 sk->sk_data_ready(sk, 0);
754 if (copy_skb)
755 kfree_skb(copy_skb);
756 goto drop_n_restore;
757}
758
759#endif
760
761
762static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
763 struct msghdr *msg, size_t len)
764{
765 struct sock *sk = sock->sk;
766 struct sockaddr_ll *saddr=(struct sockaddr_ll *)msg->msg_name;
767 struct sk_buff *skb;
768 struct net_device *dev;
Al Viro0e11c912006-11-08 00:26:29 -0800769 __be16 proto;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 unsigned char *addr;
771 int ifindex, err, reserve = 0;
772
773 /*
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900774 * Get and verify the address.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 */
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900776
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 if (saddr == NULL) {
778 struct packet_sock *po = pkt_sk(sk);
779
780 ifindex = po->ifindex;
781 proto = po->num;
782 addr = NULL;
783 } else {
784 err = -EINVAL;
785 if (msg->msg_namelen < sizeof(struct sockaddr_ll))
786 goto out;
Eric W. Biederman0fb375f2005-09-21 00:11:37 -0700787 if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr)))
788 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 ifindex = saddr->sll_ifindex;
790 proto = saddr->sll_protocol;
791 addr = saddr->sll_addr;
792 }
793
794
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900795 dev = dev_get_by_index(sock_net(sk), ifindex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 err = -ENXIO;
797 if (dev == NULL)
798 goto out_unlock;
799 if (sock->type == SOCK_RAW)
800 reserve = dev->hard_header_len;
801
David S. Millerd5e76b02007-01-25 19:30:36 -0800802 err = -ENETDOWN;
803 if (!(dev->flags & IFF_UP))
804 goto out_unlock;
805
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 err = -EMSGSIZE;
807 if (len > dev->mtu+reserve)
808 goto out_unlock;
809
Johannes Bergf5184d22008-05-12 20:48:31 -0700810 skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 msg->msg_flags & MSG_DONTWAIT, &err);
812 if (skb==NULL)
813 goto out_unlock;
814
815 skb_reserve(skb, LL_RESERVED_SPACE(dev));
Arnaldo Carvalho de Meloc1d2bbe2007-04-10 20:45:18 -0700816 skb_reset_network_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
Stephen Hemminger0c4e8582007-10-09 01:36:32 -0700818 err = -EINVAL;
819 if (sock->type == SOCK_DGRAM &&
820 dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len) < 0)
821 goto out_free;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
823 /* Returns -EFAULT on error */
824 err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
825 if (err)
826 goto out_free;
827
828 skb->protocol = proto;
829 skb->dev = dev;
830 skb->priority = sk->sk_priority;
831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 /*
833 * Now send it
834 */
835
836 err = dev_queue_xmit(skb);
837 if (err > 0 && (err = net_xmit_errno(err)) != 0)
838 goto out_unlock;
839
840 dev_put(dev);
841
842 return(len);
843
844out_free:
845 kfree_skb(skb);
846out_unlock:
847 if (dev)
848 dev_put(dev);
849out:
850 return err;
851}
852
853/*
854 * Close a PACKET socket. This is fairly simple. We immediately go
855 * to 'closed' state and remove our protocol entry in the device list.
856 */
857
858static int packet_release(struct socket *sock)
859{
860 struct sock *sk = sock->sk;
861 struct packet_sock *po;
Denis V. Lunevd12d01d2007-11-19 22:28:35 -0800862 struct net *net;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863
864 if (!sk)
865 return 0;
866
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900867 net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 po = pkt_sk(sk);
869
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -0800870 write_lock_bh(&net->packet.sklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 sk_del_node_init(sk);
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -0800872 write_unlock_bh(&net->packet.sklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
874 /*
875 * Unhook packet receive handler.
876 */
877
878 if (po->running) {
879 /*
880 * Remove the protocol hook
881 */
882 dev_remove_pack(&po->prot_hook);
883 po->running = 0;
884 po->num = 0;
885 __sock_put(sk);
886 }
887
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 packet_flush_mclist(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889
890#ifdef CONFIG_PACKET_MMAP
891 if (po->pg_vec) {
892 struct tpacket_req req;
893 memset(&req, 0, sizeof(req));
894 packet_set_ring(sk, &req, 1);
895 }
896#endif
897
898 /*
899 * Now the socket is dead. No more input will appear.
900 */
901
902 sock_orphan(sk);
903 sock->sk = NULL;
904
905 /* Purge queues */
906
907 skb_queue_purge(&sk->sk_receive_queue);
Pavel Emelyanov17ab56a2007-11-10 21:38:48 -0800908 sk_refcnt_debug_release(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909
910 sock_put(sk);
911 return 0;
912}
913
914/*
915 * Attach a packet hook.
916 */
917
Al Viro0e11c912006-11-08 00:26:29 -0800918static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919{
920 struct packet_sock *po = pkt_sk(sk);
921 /*
922 * Detach an existing hook if present.
923 */
924
925 lock_sock(sk);
926
927 spin_lock(&po->bind_lock);
928 if (po->running) {
929 __sock_put(sk);
930 po->running = 0;
931 po->num = 0;
932 spin_unlock(&po->bind_lock);
933 dev_remove_pack(&po->prot_hook);
934 spin_lock(&po->bind_lock);
935 }
936
937 po->num = protocol;
938 po->prot_hook.type = protocol;
939 po->prot_hook.dev = dev;
940
941 po->ifindex = dev ? dev->ifindex : 0;
942
943 if (protocol == 0)
944 goto out_unlock;
945
Urs Thuermannbe85d4a2007-11-12 21:05:20 -0800946 if (!dev || (dev->flags & IFF_UP)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 dev_add_pack(&po->prot_hook);
948 sock_hold(sk);
949 po->running = 1;
Urs Thuermannbe85d4a2007-11-12 21:05:20 -0800950 } else {
951 sk->sk_err = ENETDOWN;
952 if (!sock_flag(sk, SOCK_DEAD))
953 sk->sk_error_report(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 }
955
956out_unlock:
957 spin_unlock(&po->bind_lock);
958 release_sock(sk);
959 return 0;
960}
961
962/*
963 * Bind a packet socket to a device
964 */
965
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int addr_len)
967{
968 struct sock *sk=sock->sk;
969 char name[15];
970 struct net_device *dev;
971 int err = -ENODEV;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900972
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 /*
974 * Check legality
975 */
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +0900976
Kris Katterjohn8ae55f02006-01-23 16:28:02 -0800977 if (addr_len != sizeof(struct sockaddr))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 return -EINVAL;
979 strlcpy(name,uaddr->sa_data,sizeof(name));
980
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900981 dev = dev_get_by_name(sock_net(sk), name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 if (dev) {
983 err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
984 dev_put(dev);
985 }
986 return err;
987}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988
989static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
990{
991 struct sockaddr_ll *sll = (struct sockaddr_ll*)uaddr;
992 struct sock *sk=sock->sk;
993 struct net_device *dev = NULL;
994 int err;
995
996
997 /*
998 * Check legality
999 */
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001000
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 if (addr_len < sizeof(struct sockaddr_ll))
1002 return -EINVAL;
1003 if (sll->sll_family != AF_PACKET)
1004 return -EINVAL;
1005
1006 if (sll->sll_ifindex) {
1007 err = -ENODEV;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001008 dev = dev_get_by_index(sock_net(sk), sll->sll_ifindex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 if (dev == NULL)
1010 goto out;
1011 }
1012 err = packet_do_bind(sk, dev, sll->sll_protocol ? : pkt_sk(sk)->num);
1013 if (dev)
1014 dev_put(dev);
1015
1016out:
1017 return err;
1018}
1019
1020static struct proto packet_proto = {
1021 .name = "PACKET",
1022 .owner = THIS_MODULE,
1023 .obj_size = sizeof(struct packet_sock),
1024};
1025
1026/*
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001027 * Create a packet of type SOCK_PACKET.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 */
1029
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -07001030static int packet_create(struct net *net, struct socket *sock, int protocol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031{
1032 struct sock *sk;
1033 struct packet_sock *po;
Al Viro0e11c912006-11-08 00:26:29 -08001034 __be16 proto = (__force __be16)protocol; /* weird, but documented */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 int err;
1036
1037 if (!capable(CAP_NET_RAW))
1038 return -EPERM;
David S. Millerbe020972007-05-29 13:16:31 -07001039 if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
1040 sock->type != SOCK_PACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 return -ESOCKTNOSUPPORT;
1042
1043 sock->state = SS_UNCONNECTED;
1044
1045 err = -ENOBUFS;
Pavel Emelyanov6257ff22007-11-01 00:39:31 -07001046 sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 if (sk == NULL)
1048 goto out;
1049
1050 sock->ops = &packet_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 if (sock->type == SOCK_PACKET)
1052 sock->ops = &packet_ops_spkt;
David S. Millerbe020972007-05-29 13:16:31 -07001053
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 sock_init_data(sock, sk);
1055
1056 po = pkt_sk(sk);
1057 sk->sk_family = PF_PACKET;
Al Viro0e11c912006-11-08 00:26:29 -08001058 po->num = proto;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060 sk->sk_destruct = packet_sock_destruct;
Pavel Emelyanov17ab56a2007-11-10 21:38:48 -08001061 sk_refcnt_debug_inc(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062
1063 /*
1064 * Attach a protocol block
1065 */
1066
1067 spin_lock_init(&po->bind_lock);
1068 po->prot_hook.func = packet_rcv;
David S. Millerbe020972007-05-29 13:16:31 -07001069
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 if (sock->type == SOCK_PACKET)
1071 po->prot_hook.func = packet_rcv_spkt;
David S. Millerbe020972007-05-29 13:16:31 -07001072
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 po->prot_hook.af_packet_priv = sk;
1074
Al Viro0e11c912006-11-08 00:26:29 -08001075 if (proto) {
1076 po->prot_hook.type = proto;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 dev_add_pack(&po->prot_hook);
1078 sock_hold(sk);
1079 po->running = 1;
1080 }
1081
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -08001082 write_lock_bh(&net->packet.sklist_lock);
1083 sk_add_node(sk, &net->packet.sklist);
1084 write_unlock_bh(&net->packet.sklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 return(0);
1086out:
1087 return err;
1088}
1089
1090/*
1091 * Pull a packet from our receive queue and hand it to the user.
1092 * If necessary we block.
1093 */
1094
1095static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
1096 struct msghdr *msg, size_t len, int flags)
1097{
1098 struct sock *sk = sock->sk;
1099 struct sk_buff *skb;
1100 int copied, err;
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001101 struct sockaddr_ll *sll;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
1103 err = -EINVAL;
1104 if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
1105 goto out;
1106
1107#if 0
1108 /* What error should we return now? EUNATTACH? */
1109 if (pkt_sk(sk)->ifindex < 0)
1110 return -ENODEV;
1111#endif
1112
1113 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 * Call the generic datagram receiver. This handles all sorts
1115 * of horrible races and re-entrancy so we can forget about it
1116 * in the protocol layers.
1117 *
1118 * Now it will return ENETDOWN, if device have just gone down,
1119 * but then it will block.
1120 */
1121
1122 skb=skb_recv_datagram(sk,flags,flags&MSG_DONTWAIT,&err);
1123
1124 /*
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001125 * An error occurred so return it. Because skb_recv_datagram()
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 * handles the blocking we don't see and worry about blocking
1127 * retries.
1128 */
1129
Kris Katterjohn8ae55f02006-01-23 16:28:02 -08001130 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 goto out;
1132
1133 /*
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001134 * If the address length field is there to be filled in, we fill
1135 * it in now.
1136 */
1137
Herbert Xuffbc6112007-02-04 23:33:10 -08001138 sll = &PACKET_SKB_CB(skb)->sa.ll;
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001139 if (sock->type == SOCK_PACKET)
1140 msg->msg_namelen = sizeof(struct sockaddr_pkt);
1141 else
1142 msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
1143
1144 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 * You lose any data beyond the buffer you gave. If it worries a
1146 * user program they can ask the device for its MTU anyway.
1147 */
1148
1149 copied = skb->len;
1150 if (copied > len)
1151 {
1152 copied=len;
1153 msg->msg_flags|=MSG_TRUNC;
1154 }
1155
1156 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
1157 if (err)
1158 goto out_free;
1159
1160 sock_recv_timestamp(msg, sk, skb);
1161
1162 if (msg->msg_name)
Herbert Xuffbc6112007-02-04 23:33:10 -08001163 memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
1164 msg->msg_namelen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165
Herbert Xu8dc41942007-02-04 23:31:32 -08001166 if (pkt_sk(sk)->auxdata) {
Herbert Xuffbc6112007-02-04 23:33:10 -08001167 struct tpacket_auxdata aux;
1168
1169 aux.tp_status = TP_STATUS_USER;
1170 if (skb->ip_summed == CHECKSUM_PARTIAL)
1171 aux.tp_status |= TP_STATUS_CSUMNOTREADY;
1172 aux.tp_len = PACKET_SKB_CB(skb)->origlen;
1173 aux.tp_snaplen = skb->len;
1174 aux.tp_mac = 0;
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03001175 aux.tp_net = skb_network_offset(skb);
Patrick McHardy393e52e2008-07-14 22:50:39 -07001176 aux.tp_vlan_tci = skb->vlan_tci;
Herbert Xuffbc6112007-02-04 23:33:10 -08001177
1178 put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
Herbert Xu8dc41942007-02-04 23:31:32 -08001179 }
1180
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 /*
1182 * Free or return the buffer as appropriate. Again this
1183 * hides all the races and re-entrancy issues from us.
1184 */
1185 err = (flags&MSG_TRUNC) ? skb->len : copied;
1186
1187out_free:
1188 skb_free_datagram(sk, skb);
1189out:
1190 return err;
1191}
1192
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
1194 int *uaddr_len, int peer)
1195{
1196 struct net_device *dev;
1197 struct sock *sk = sock->sk;
1198
1199 if (peer)
1200 return -EOPNOTSUPP;
1201
1202 uaddr->sa_family = AF_PACKET;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001203 dev = dev_get_by_index(sock_net(sk), pkt_sk(sk)->ifindex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 if (dev) {
1205 strlcpy(uaddr->sa_data, dev->name, 15);
1206 dev_put(dev);
1207 } else
1208 memset(uaddr->sa_data, 0, 14);
1209 *uaddr_len = sizeof(*uaddr);
1210
1211 return 0;
1212}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213
1214static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
1215 int *uaddr_len, int peer)
1216{
1217 struct net_device *dev;
1218 struct sock *sk = sock->sk;
1219 struct packet_sock *po = pkt_sk(sk);
1220 struct sockaddr_ll *sll = (struct sockaddr_ll*)uaddr;
1221
1222 if (peer)
1223 return -EOPNOTSUPP;
1224
1225 sll->sll_family = AF_PACKET;
1226 sll->sll_ifindex = po->ifindex;
1227 sll->sll_protocol = po->num;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001228 dev = dev_get_by_index(sock_net(sk), po->ifindex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 if (dev) {
1230 sll->sll_hatype = dev->type;
1231 sll->sll_halen = dev->addr_len;
1232 memcpy(sll->sll_addr, dev->dev_addr, dev->addr_len);
1233 dev_put(dev);
1234 } else {
1235 sll->sll_hatype = 0; /* Bad: we have no ARPHRD_UNSPEC */
1236 sll->sll_halen = 0;
1237 }
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001238 *uaddr_len = offsetof(struct sockaddr_ll, sll_addr) + sll->sll_halen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
1240 return 0;
1241}
1242
Wang Chen2aeb0b82008-07-14 20:49:46 -07001243static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
1244 int what)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245{
1246 switch (i->type) {
1247 case PACKET_MR_MULTICAST:
1248 if (what > 0)
1249 dev_mc_add(dev, i->addr, i->alen, 0);
1250 else
1251 dev_mc_delete(dev, i->addr, i->alen, 0);
1252 break;
1253 case PACKET_MR_PROMISC:
Wang Chen2aeb0b82008-07-14 20:49:46 -07001254 return dev_set_promiscuity(dev, what);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 break;
1256 case PACKET_MR_ALLMULTI:
Wang Chen2aeb0b82008-07-14 20:49:46 -07001257 return dev_set_allmulti(dev, what);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 break;
1259 default:;
1260 }
Wang Chen2aeb0b82008-07-14 20:49:46 -07001261 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262}
1263
1264static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what)
1265{
1266 for ( ; i; i=i->next) {
1267 if (i->ifindex == dev->ifindex)
1268 packet_dev_mc(dev, i, what);
1269 }
1270}
1271
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001272static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273{
1274 struct packet_sock *po = pkt_sk(sk);
1275 struct packet_mclist *ml, *i;
1276 struct net_device *dev;
1277 int err;
1278
1279 rtnl_lock();
1280
1281 err = -ENODEV;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001282 dev = __dev_get_by_index(sock_net(sk), mreq->mr_ifindex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283 if (!dev)
1284 goto done;
1285
1286 err = -EINVAL;
1287 if (mreq->mr_alen > dev->addr_len)
1288 goto done;
1289
1290 err = -ENOBUFS;
Kris Katterjohn8b3a7002006-01-11 15:56:43 -08001291 i = kmalloc(sizeof(*i), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 if (i == NULL)
1293 goto done;
1294
1295 err = 0;
1296 for (ml = po->mclist; ml; ml = ml->next) {
1297 if (ml->ifindex == mreq->mr_ifindex &&
1298 ml->type == mreq->mr_type &&
1299 ml->alen == mreq->mr_alen &&
1300 memcmp(ml->addr, mreq->mr_address, ml->alen) == 0) {
1301 ml->count++;
1302 /* Free the new element ... */
1303 kfree(i);
1304 goto done;
1305 }
1306 }
1307
1308 i->type = mreq->mr_type;
1309 i->ifindex = mreq->mr_ifindex;
1310 i->alen = mreq->mr_alen;
1311 memcpy(i->addr, mreq->mr_address, i->alen);
1312 i->count = 1;
1313 i->next = po->mclist;
1314 po->mclist = i;
Wang Chen2aeb0b82008-07-14 20:49:46 -07001315 err = packet_dev_mc(dev, i, 1);
1316 if (err) {
1317 po->mclist = i->next;
1318 kfree(i);
1319 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320
1321done:
1322 rtnl_unlock();
1323 return err;
1324}
1325
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001326static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327{
1328 struct packet_mclist *ml, **mlp;
1329
1330 rtnl_lock();
1331
1332 for (mlp = &pkt_sk(sk)->mclist; (ml = *mlp) != NULL; mlp = &ml->next) {
1333 if (ml->ifindex == mreq->mr_ifindex &&
1334 ml->type == mreq->mr_type &&
1335 ml->alen == mreq->mr_alen &&
1336 memcmp(ml->addr, mreq->mr_address, ml->alen) == 0) {
1337 if (--ml->count == 0) {
1338 struct net_device *dev;
1339 *mlp = ml->next;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001340 dev = dev_get_by_index(sock_net(sk), ml->ifindex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 if (dev) {
1342 packet_dev_mc(dev, ml, -1);
1343 dev_put(dev);
1344 }
1345 kfree(ml);
1346 }
1347 rtnl_unlock();
1348 return 0;
1349 }
1350 }
1351 rtnl_unlock();
1352 return -EADDRNOTAVAIL;
1353}
1354
1355static void packet_flush_mclist(struct sock *sk)
1356{
1357 struct packet_sock *po = pkt_sk(sk);
1358 struct packet_mclist *ml;
1359
1360 if (!po->mclist)
1361 return;
1362
1363 rtnl_lock();
1364 while ((ml = po->mclist) != NULL) {
1365 struct net_device *dev;
1366
1367 po->mclist = ml->next;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001368 if ((dev = dev_get_by_index(sock_net(sk), ml->ifindex)) != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 packet_dev_mc(dev, ml, -1);
1370 dev_put(dev);
1371 }
1372 kfree(ml);
1373 }
1374 rtnl_unlock();
1375}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376
1377static int
1378packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
1379{
1380 struct sock *sk = sock->sk;
Herbert Xu8dc41942007-02-04 23:31:32 -08001381 struct packet_sock *po = pkt_sk(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 int ret;
1383
1384 if (level != SOL_PACKET)
1385 return -ENOPROTOOPT;
1386
1387 switch(optname) {
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001388 case PACKET_ADD_MEMBERSHIP:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 case PACKET_DROP_MEMBERSHIP:
1390 {
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001391 struct packet_mreq_max mreq;
1392 int len = optlen;
1393 memset(&mreq, 0, sizeof(mreq));
1394 if (len < sizeof(struct packet_mreq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 return -EINVAL;
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001396 if (len > sizeof(mreq))
1397 len = sizeof(mreq);
1398 if (copy_from_user(&mreq,optval,len))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 return -EFAULT;
Eric W. Biederman0fb375f2005-09-21 00:11:37 -07001400 if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))
1401 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 if (optname == PACKET_ADD_MEMBERSHIP)
1403 ret = packet_mc_add(sk, &mreq);
1404 else
1405 ret = packet_mc_drop(sk, &mreq);
1406 return ret;
1407 }
David S. Millera2efcfa2007-05-29 13:12:50 -07001408
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409#ifdef CONFIG_PACKET_MMAP
1410 case PACKET_RX_RING:
1411 {
1412 struct tpacket_req req;
1413
1414 if (optlen<sizeof(req))
1415 return -EINVAL;
1416 if (copy_from_user(&req,optval,sizeof(req)))
1417 return -EFAULT;
1418 return packet_set_ring(sk, &req, 0);
1419 }
1420 case PACKET_COPY_THRESH:
1421 {
1422 int val;
1423
1424 if (optlen!=sizeof(val))
1425 return -EINVAL;
1426 if (copy_from_user(&val,optval,sizeof(val)))
1427 return -EFAULT;
1428
1429 pkt_sk(sk)->copy_thresh = val;
1430 return 0;
1431 }
Patrick McHardybbd6ef82008-07-14 22:50:15 -07001432 case PACKET_VERSION:
1433 {
1434 int val;
1435
1436 if (optlen != sizeof(val))
1437 return -EINVAL;
1438 if (po->pg_vec)
1439 return -EBUSY;
1440 if (copy_from_user(&val, optval, sizeof(val)))
1441 return -EFAULT;
1442 switch (val) {
1443 case TPACKET_V1:
1444 case TPACKET_V2:
1445 po->tp_version = val;
1446 return 0;
1447 default:
1448 return -EINVAL;
1449 }
1450 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451#endif
Herbert Xu8dc41942007-02-04 23:31:32 -08001452 case PACKET_AUXDATA:
1453 {
1454 int val;
1455
1456 if (optlen < sizeof(val))
1457 return -EINVAL;
1458 if (copy_from_user(&val, optval, sizeof(val)))
1459 return -EFAULT;
1460
1461 po->auxdata = !!val;
1462 return 0;
1463 }
Peter P. Waskiewicz Jr80feaac2007-04-20 16:05:39 -07001464 case PACKET_ORIGDEV:
1465 {
1466 int val;
1467
1468 if (optlen < sizeof(val))
1469 return -EINVAL;
1470 if (copy_from_user(&val, optval, sizeof(val)))
1471 return -EFAULT;
1472
1473 po->origdev = !!val;
1474 return 0;
1475 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 default:
1477 return -ENOPROTOOPT;
1478 }
1479}
1480
1481static int packet_getsockopt(struct socket *sock, int level, int optname,
1482 char __user *optval, int __user *optlen)
1483{
1484 int len;
Herbert Xu8dc41942007-02-04 23:31:32 -08001485 int val;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 struct sock *sk = sock->sk;
1487 struct packet_sock *po = pkt_sk(sk);
Herbert Xu8dc41942007-02-04 23:31:32 -08001488 void *data;
1489 struct tpacket_stats st;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490
1491 if (level != SOL_PACKET)
1492 return -ENOPROTOOPT;
1493
Kris Katterjohn8ae55f02006-01-23 16:28:02 -08001494 if (get_user(len, optlen))
1495 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496
1497 if (len < 0)
1498 return -EINVAL;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001499
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 switch(optname) {
1501 case PACKET_STATISTICS:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 if (len > sizeof(struct tpacket_stats))
1503 len = sizeof(struct tpacket_stats);
1504 spin_lock_bh(&sk->sk_receive_queue.lock);
1505 st = po->stats;
1506 memset(&po->stats, 0, sizeof(st));
1507 spin_unlock_bh(&sk->sk_receive_queue.lock);
1508 st.tp_packets += st.tp_drops;
1509
Herbert Xu8dc41942007-02-04 23:31:32 -08001510 data = &st;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 break;
Herbert Xu8dc41942007-02-04 23:31:32 -08001512 case PACKET_AUXDATA:
1513 if (len > sizeof(int))
1514 len = sizeof(int);
1515 val = po->auxdata;
1516
1517 data = &val;
1518 break;
Peter P. Waskiewicz Jr80feaac2007-04-20 16:05:39 -07001519 case PACKET_ORIGDEV:
1520 if (len > sizeof(int))
1521 len = sizeof(int);
1522 val = po->origdev;
1523
1524 data = &val;
1525 break;
Patrick McHardybbd6ef82008-07-14 22:50:15 -07001526#ifdef CONFIG_PACKET_MMAP
1527 case PACKET_VERSION:
1528 if (len > sizeof(int))
1529 len = sizeof(int);
1530 val = po->tp_version;
1531 data = &val;
1532 break;
1533 case PACKET_HDRLEN:
1534 if (len > sizeof(int))
1535 len = sizeof(int);
1536 if (copy_from_user(&val, optval, len))
1537 return -EFAULT;
1538 switch (val) {
1539 case TPACKET_V1:
1540 val = sizeof(struct tpacket_hdr);
1541 break;
1542 case TPACKET_V2:
1543 val = sizeof(struct tpacket2_hdr);
1544 break;
1545 default:
1546 return -EINVAL;
1547 }
1548 data = &val;
1549 break;
1550#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 default:
1552 return -ENOPROTOOPT;
1553 }
1554
Kris Katterjohn8ae55f02006-01-23 16:28:02 -08001555 if (put_user(len, optlen))
1556 return -EFAULT;
Herbert Xu8dc41942007-02-04 23:31:32 -08001557 if (copy_to_user(optval, data, len))
1558 return -EFAULT;
Kris Katterjohn8ae55f02006-01-23 16:28:02 -08001559 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560}
1561
1562
1563static int packet_notifier(struct notifier_block *this, unsigned long msg, void *data)
1564{
1565 struct sock *sk;
1566 struct hlist_node *node;
Jason Lunzad930652007-02-20 23:19:54 -08001567 struct net_device *dev = data;
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +09001568 struct net *net = dev_net(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -08001570 read_lock(&net->packet.sklist_lock);
1571 sk_for_each(sk, node, &net->packet.sklist) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572 struct packet_sock *po = pkt_sk(sk);
1573
1574 switch (msg) {
1575 case NETDEV_UNREGISTER:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 if (po->mclist)
1577 packet_dev_mclist(dev, po->mclist, -1);
David S. Millera2efcfa2007-05-29 13:12:50 -07001578 /* fallthrough */
1579
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 case NETDEV_DOWN:
1581 if (dev->ifindex == po->ifindex) {
1582 spin_lock(&po->bind_lock);
1583 if (po->running) {
1584 __dev_remove_pack(&po->prot_hook);
1585 __sock_put(sk);
1586 po->running = 0;
1587 sk->sk_err = ENETDOWN;
1588 if (!sock_flag(sk, SOCK_DEAD))
1589 sk->sk_error_report(sk);
1590 }
1591 if (msg == NETDEV_UNREGISTER) {
1592 po->ifindex = -1;
1593 po->prot_hook.dev = NULL;
1594 }
1595 spin_unlock(&po->bind_lock);
1596 }
1597 break;
1598 case NETDEV_UP:
1599 spin_lock(&po->bind_lock);
1600 if (dev->ifindex == po->ifindex && po->num &&
1601 !po->running) {
1602 dev_add_pack(&po->prot_hook);
1603 sock_hold(sk);
1604 po->running = 1;
1605 }
1606 spin_unlock(&po->bind_lock);
1607 break;
1608 }
1609 }
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -08001610 read_unlock(&net->packet.sklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 return NOTIFY_DONE;
1612}
1613
1614
1615static int packet_ioctl(struct socket *sock, unsigned int cmd,
1616 unsigned long arg)
1617{
1618 struct sock *sk = sock->sk;
1619
1620 switch(cmd) {
1621 case SIOCOUTQ:
1622 {
1623 int amount = atomic_read(&sk->sk_wmem_alloc);
1624 return put_user(amount, (int __user *)arg);
1625 }
1626 case SIOCINQ:
1627 {
1628 struct sk_buff *skb;
1629 int amount = 0;
1630
1631 spin_lock_bh(&sk->sk_receive_queue.lock);
1632 skb = skb_peek(&sk->sk_receive_queue);
1633 if (skb)
1634 amount = skb->len;
1635 spin_unlock_bh(&sk->sk_receive_queue.lock);
1636 return put_user(amount, (int __user *)arg);
1637 }
1638 case SIOCGSTAMP:
1639 return sock_get_timestamp(sk, (struct timeval __user *)arg);
Eric Dumazetae40eb12007-03-18 17:33:16 -07001640 case SIOCGSTAMPNS:
1641 return sock_get_timestampns(sk, (struct timespec __user *)arg);
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001642
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643#ifdef CONFIG_INET
1644 case SIOCADDRT:
1645 case SIOCDELRT:
1646 case SIOCDARP:
1647 case SIOCGARP:
1648 case SIOCSARP:
1649 case SIOCGIFADDR:
1650 case SIOCSIFADDR:
1651 case SIOCGIFBRDADDR:
1652 case SIOCSIFBRDADDR:
1653 case SIOCGIFNETMASK:
1654 case SIOCSIFNETMASK:
1655 case SIOCGIFDSTADDR:
1656 case SIOCSIFDSTADDR:
1657 case SIOCSIFFLAGS:
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001658 if (sock_net(sk) != &init_net)
Denis V. Lunevd12d01d2007-11-19 22:28:35 -08001659 return -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 return inet_dgram_ops.ioctl(sock, cmd, arg);
1661#endif
1662
1663 default:
Christoph Hellwigb5e5fa52006-01-03 14:18:33 -08001664 return -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 }
1666 return 0;
1667}
1668
1669#ifndef CONFIG_PACKET_MMAP
1670#define packet_mmap sock_no_mmap
1671#define packet_poll datagram_poll
1672#else
1673
1674static unsigned int packet_poll(struct file * file, struct socket *sock,
1675 poll_table *wait)
1676{
1677 struct sock *sk = sock->sk;
1678 struct packet_sock *po = pkt_sk(sk);
1679 unsigned int mask = datagram_poll(file, sock, wait);
1680
1681 spin_lock_bh(&sk->sk_receive_queue.lock);
1682 if (po->pg_vec) {
1683 unsigned last = po->head ? po->head-1 : po->frame_max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
Patrick McHardybbd6ef82008-07-14 22:50:15 -07001685 if (packet_lookup_frame(po, last, TP_STATUS_USER))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 mask |= POLLIN | POLLRDNORM;
1687 }
1688 spin_unlock_bh(&sk->sk_receive_queue.lock);
1689 return mask;
1690}
1691
1692
1693/* Dirty? Well, I still did not learn better way to account
1694 * for user mmaps.
1695 */
1696
1697static void packet_mm_open(struct vm_area_struct *vma)
1698{
1699 struct file *file = vma->vm_file;
Eric Dumazetb69aee02005-09-06 14:42:45 -07001700 struct socket * sock = file->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001702
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 if (sk)
1704 atomic_inc(&pkt_sk(sk)->mapped);
1705}
1706
1707static void packet_mm_close(struct vm_area_struct *vma)
1708{
1709 struct file *file = vma->vm_file;
Eric Dumazetb69aee02005-09-06 14:42:45 -07001710 struct socket * sock = file->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001712
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 if (sk)
1714 atomic_dec(&pkt_sk(sk)->mapped);
1715}
1716
1717static struct vm_operations_struct packet_mmap_ops = {
1718 .open = packet_mm_open,
1719 .close =packet_mm_close,
1720};
1721
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001722static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723{
1724 int i;
1725
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001726 for (i = 0; i < len; i++) {
1727 if (likely(pg_vec[i]))
1728 free_pages((unsigned long) pg_vec[i], order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 }
1730 kfree(pg_vec);
1731}
1732
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001733static inline char *alloc_one_pg_vec_page(unsigned long order)
1734{
1735 return (char *) __get_free_pages(GFP_KERNEL | __GFP_COMP | __GFP_ZERO,
1736 order);
1737}
1738
1739static char **alloc_pg_vec(struct tpacket_req *req, int order)
1740{
1741 unsigned int block_nr = req->tp_block_nr;
1742 char **pg_vec;
1743 int i;
1744
1745 pg_vec = kzalloc(block_nr * sizeof(char *), GFP_KERNEL);
1746 if (unlikely(!pg_vec))
1747 goto out;
1748
1749 for (i = 0; i < block_nr; i++) {
1750 pg_vec[i] = alloc_one_pg_vec_page(order);
1751 if (unlikely(!pg_vec[i]))
1752 goto out_free_pgvec;
1753 }
1754
1755out:
1756 return pg_vec;
1757
1758out_free_pgvec:
1759 free_pg_vec(pg_vec, order, block_nr);
1760 pg_vec = NULL;
1761 goto out;
1762}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763
1764static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing)
1765{
1766 char **pg_vec = NULL;
1767 struct packet_sock *po = pkt_sk(sk);
Al Viro0e11c912006-11-08 00:26:29 -08001768 int was_running, order = 0;
1769 __be16 num;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 int err = 0;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001771
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 if (req->tp_block_nr) {
Jiri Olsa2a706ec2008-03-23 22:42:34 -07001773 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774
1775 /* Sanity tests and some calculations */
1776
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001777 if (unlikely(po->pg_vec))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 return -EBUSY;
1779
Patrick McHardybbd6ef82008-07-14 22:50:15 -07001780 switch (po->tp_version) {
1781 case TPACKET_V1:
1782 po->tp_hdrlen = TPACKET_HDRLEN;
1783 break;
1784 case TPACKET_V2:
1785 po->tp_hdrlen = TPACKET2_HDRLEN;
1786 break;
1787 }
1788
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001789 if (unlikely((int)req->tp_block_size <= 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 return -EINVAL;
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001791 if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 return -EINVAL;
Patrick McHardybbd6ef82008-07-14 22:50:15 -07001793 if (unlikely(req->tp_frame_size < po->tp_hdrlen))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 return -EINVAL;
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001795 if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 return -EINVAL;
1797
1798 po->frames_per_block = req->tp_block_size/req->tp_frame_size;
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001799 if (unlikely(po->frames_per_block <= 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 return -EINVAL;
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001801 if (unlikely((po->frames_per_block * req->tp_block_nr) !=
1802 req->tp_frame_nr))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804
1805 err = -ENOMEM;
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001806 order = get_order(req->tp_block_size);
1807 pg_vec = alloc_pg_vec(req, order);
1808 if (unlikely(!pg_vec))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001811 for (i = 0; i < req->tp_block_nr; i++) {
Patrick McHardybbd6ef82008-07-14 22:50:15 -07001812 void *ptr = pg_vec[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 int k;
1814
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001815 for (k = 0; k < po->frames_per_block; k++) {
Patrick McHardybbd6ef82008-07-14 22:50:15 -07001816 __packet_set_status(po, ptr, TP_STATUS_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 ptr += req->tp_frame_size;
1818 }
1819 }
1820 /* Done */
1821 } else {
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001822 if (unlikely(req->tp_frame_nr))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 return -EINVAL;
1824 }
1825
1826 lock_sock(sk);
1827
1828 /* Detach socket from network */
1829 spin_lock(&po->bind_lock);
1830 was_running = po->running;
1831 num = po->num;
1832 if (was_running) {
1833 __dev_remove_pack(&po->prot_hook);
1834 po->num = 0;
1835 po->running = 0;
1836 __sock_put(sk);
1837 }
1838 spin_unlock(&po->bind_lock);
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001839
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 synchronize_net();
1841
1842 err = -EBUSY;
1843 if (closing || atomic_read(&po->mapped) == 0) {
1844 err = 0;
1845#define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
1846
1847 spin_lock_bh(&sk->sk_receive_queue.lock);
1848 pg_vec = XC(po->pg_vec, pg_vec);
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001849 po->frame_max = (req->tp_frame_nr - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 po->head = 0;
1851 po->frame_size = req->tp_frame_size;
1852 spin_unlock_bh(&sk->sk_receive_queue.lock);
1853
1854 order = XC(po->pg_vec_order, order);
1855 req->tp_block_nr = XC(po->pg_vec_len, req->tp_block_nr);
1856
1857 po->pg_vec_pages = req->tp_block_size/PAGE_SIZE;
1858 po->prot_hook.func = po->pg_vec ? tpacket_rcv : packet_rcv;
1859 skb_queue_purge(&sk->sk_receive_queue);
1860#undef XC
1861 if (atomic_read(&po->mapped))
1862 printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped));
1863 }
1864
1865 spin_lock(&po->bind_lock);
1866 if (was_running && !po->running) {
1867 sock_hold(sk);
1868 po->running = 1;
1869 po->num = num;
1870 dev_add_pack(&po->prot_hook);
1871 }
1872 spin_unlock(&po->bind_lock);
1873
1874 release_sock(sk);
1875
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 if (pg_vec)
1877 free_pg_vec(pg_vec, order, req->tp_block_nr);
1878out:
1879 return err;
1880}
1881
1882static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma)
1883{
1884 struct sock *sk = sock->sk;
1885 struct packet_sock *po = pkt_sk(sk);
1886 unsigned long size;
1887 unsigned long start;
1888 int err = -EINVAL;
1889 int i;
1890
1891 if (vma->vm_pgoff)
1892 return -EINVAL;
1893
1894 size = vma->vm_end - vma->vm_start;
1895
1896 lock_sock(sk);
1897 if (po->pg_vec == NULL)
1898 goto out;
1899 if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE)
1900 goto out;
1901
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 start = vma->vm_start;
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001903 for (i = 0; i < po->pg_vec_len; i++) {
1904 struct page *page = virt_to_page(po->pg_vec[i]);
1905 int pg_num;
1906
1907 for (pg_num = 0; pg_num < po->pg_vec_pages; pg_num++, page++) {
1908 err = vm_insert_page(vma, start, page);
1909 if (unlikely(err))
1910 goto out;
1911 start += PAGE_SIZE;
1912 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 }
David S. Miller4ebf0ae2005-12-06 16:38:35 -08001914 atomic_inc(&po->mapped);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 vma->vm_ops = &packet_mmap_ops;
1916 err = 0;
1917
1918out:
1919 release_sock(sk);
1920 return err;
1921}
1922#endif
1923
1924
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001925static const struct proto_ops packet_ops_spkt = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 .family = PF_PACKET,
1927 .owner = THIS_MODULE,
1928 .release = packet_release,
1929 .bind = packet_bind_spkt,
1930 .connect = sock_no_connect,
1931 .socketpair = sock_no_socketpair,
1932 .accept = sock_no_accept,
1933 .getname = packet_getname_spkt,
1934 .poll = datagram_poll,
1935 .ioctl = packet_ioctl,
1936 .listen = sock_no_listen,
1937 .shutdown = sock_no_shutdown,
1938 .setsockopt = sock_no_setsockopt,
1939 .getsockopt = sock_no_getsockopt,
1940 .sendmsg = packet_sendmsg_spkt,
1941 .recvmsg = packet_recvmsg,
1942 .mmap = sock_no_mmap,
1943 .sendpage = sock_no_sendpage,
1944};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001946static const struct proto_ops packet_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 .family = PF_PACKET,
1948 .owner = THIS_MODULE,
1949 .release = packet_release,
1950 .bind = packet_bind,
1951 .connect = sock_no_connect,
1952 .socketpair = sock_no_socketpair,
1953 .accept = sock_no_accept,
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09001954 .getname = packet_getname,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 .poll = packet_poll,
1956 .ioctl = packet_ioctl,
1957 .listen = sock_no_listen,
1958 .shutdown = sock_no_shutdown,
1959 .setsockopt = packet_setsockopt,
1960 .getsockopt = packet_getsockopt,
1961 .sendmsg = packet_sendmsg,
1962 .recvmsg = packet_recvmsg,
1963 .mmap = packet_mmap,
1964 .sendpage = sock_no_sendpage,
1965};
1966
1967static struct net_proto_family packet_family_ops = {
1968 .family = PF_PACKET,
1969 .create = packet_create,
1970 .owner = THIS_MODULE,
1971};
1972
1973static struct notifier_block packet_netdev_notifier = {
1974 .notifier_call =packet_notifier,
1975};
1976
1977#ifdef CONFIG_PROC_FS
Denis V. Lunevd12d01d2007-11-19 22:28:35 -08001978static inline struct sock *packet_seq_idx(struct net *net, loff_t off)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979{
1980 struct sock *s;
1981 struct hlist_node *node;
1982
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -08001983 sk_for_each(s, node, &net->packet.sklist) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 if (!off--)
1985 return s;
1986 }
1987 return NULL;
1988}
1989
1990static void *packet_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet40ccbf52008-01-07 22:39:57 -08001991 __acquires(seq_file_net(seq)->packet.sklist_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992{
Denis V. Luneve372c412007-11-19 22:31:54 -08001993 struct net *net = seq_file_net(seq);
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -08001994 read_lock(&net->packet.sklist_lock);
Denis V. Lunevd12d01d2007-11-19 22:28:35 -08001995 return *pos ? packet_seq_idx(net, *pos - 1) : SEQ_START_TOKEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996}
1997
1998static void *packet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1999{
Herbert Xu1bf40952007-12-16 14:04:02 -08002000 struct net *net = seq_file_net(seq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001 ++*pos;
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09002002 return (v == SEQ_START_TOKEN)
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -08002003 ? sk_head(&net->packet.sklist)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 : sk_next((struct sock*)v) ;
2005}
2006
2007static void packet_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet40ccbf52008-01-07 22:39:57 -08002008 __releases(seq_file_net(seq)->packet.sklist_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009{
Herbert Xu1bf40952007-12-16 14:04:02 -08002010 struct net *net = seq_file_net(seq);
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -08002011 read_unlock(&net->packet.sklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012}
2013
YOSHIFUJI Hideaki1ce4f282007-02-09 23:25:10 +09002014static int packet_seq_show(struct seq_file *seq, void *v)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015{
2016 if (v == SEQ_START_TOKEN)
2017 seq_puts(seq, "sk RefCnt Type Proto Iface R Rmem User Inode\n");
2018 else {
2019 struct sock *s = v;
2020 const struct packet_sock *po = pkt_sk(s);
2021
2022 seq_printf(seq,
2023 "%p %-6d %-4d %04x %-5d %1d %-6u %-6u %-6lu\n",
2024 s,
2025 atomic_read(&s->sk_refcnt),
2026 s->sk_type,
2027 ntohs(po->num),
2028 po->ifindex,
2029 po->running,
2030 atomic_read(&s->sk_rmem_alloc),
2031 sock_i_uid(s),
2032 sock_i_ino(s) );
2033 }
2034
2035 return 0;
2036}
2037
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002038static const struct seq_operations packet_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 .start = packet_seq_start,
2040 .next = packet_seq_next,
2041 .stop = packet_seq_stop,
2042 .show = packet_seq_show,
2043};
2044
2045static int packet_seq_open(struct inode *inode, struct file *file)
2046{
Denis V. Luneve372c412007-11-19 22:31:54 -08002047 return seq_open_net(inode, file, &packet_seq_ops,
2048 sizeof(struct seq_net_private));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049}
2050
Arjan van de Venda7071d2007-02-12 00:55:36 -08002051static const struct file_operations packet_seq_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052 .owner = THIS_MODULE,
2053 .open = packet_seq_open,
2054 .read = seq_read,
2055 .llseek = seq_lseek,
Denis V. Luneve372c412007-11-19 22:31:54 -08002056 .release = seq_release_net,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057};
2058
2059#endif
2060
Denis V. Lunevd12d01d2007-11-19 22:28:35 -08002061static int packet_net_init(struct net *net)
2062{
Denis V. Lunev2aaef4e2007-12-11 04:19:54 -08002063 rwlock_init(&net->packet.sklist_lock);
2064 INIT_HLIST_HEAD(&net->packet.sklist);
Denis V. Lunevd12d01d2007-11-19 22:28:35 -08002065
2066 if (!proc_net_fops_create(net, "packet", 0, &packet_seq_fops))
2067 return -ENOMEM;
2068
2069 return 0;
2070}
2071
2072static void packet_net_exit(struct net *net)
2073{
2074 proc_net_remove(net, "packet");
2075}
2076
2077static struct pernet_operations packet_net_ops = {
2078 .init = packet_net_init,
2079 .exit = packet_net_exit,
2080};
2081
2082
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083static void __exit packet_exit(void)
2084{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 unregister_netdevice_notifier(&packet_netdev_notifier);
Denis V. Lunevd12d01d2007-11-19 22:28:35 -08002086 unregister_pernet_subsys(&packet_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 sock_unregister(PF_PACKET);
2088 proto_unregister(&packet_proto);
2089}
2090
2091static int __init packet_init(void)
2092{
2093 int rc = proto_register(&packet_proto, 0);
2094
2095 if (rc != 0)
2096 goto out;
2097
2098 sock_register(&packet_family_ops);
Denis V. Lunevd12d01d2007-11-19 22:28:35 -08002099 register_pernet_subsys(&packet_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100 register_netdevice_notifier(&packet_netdev_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101out:
2102 return rc;
2103}
2104
2105module_init(packet_init);
2106module_exit(packet_exit);
2107MODULE_LICENSE("GPL");
2108MODULE_ALIAS_NETPROTO(PF_PACKET);