Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/net/ipv4/raw.c (Version 2.6.25.8) and /linux/net/ipv4/raw.c (Version 2.6.11.8)


  1 /*                                                  1 /*
  2  * INET         An implementation of the TCP/I      2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
  3  *              operating system.  INET is imp      3  *              operating system.  INET is implemented using the  BSD Socket
  4  *              interface as the means of comm      4  *              interface as the means of communication with the user level.
  5  *                                                  5  *
  6  *              RAW - implementation of IP "ra      6  *              RAW - implementation of IP "raw" sockets.
  7  *                                                  7  *
  8  * Version:     $Id: raw.c,v 1.64 2002/02/01 2      8  * Version:     $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $
  9  *                                                  9  *
 10  * Authors:     Ross Biro                      !!  10  * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
 11  *              Fred N. van Kempen, <waltje@uW     11  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 12  *                                                 12  *
 13  * Fixes:                                          13  * Fixes:
 14  *              Alan Cox        :       verify     14  *              Alan Cox        :       verify_area() fixed up
 15  *              Alan Cox        :       ICMP e     15  *              Alan Cox        :       ICMP error handling
 16  *              Alan Cox        :       EMSGSI     16  *              Alan Cox        :       EMSGSIZE if you send too big a packet
 17  *              Alan Cox        :       Now us     17  *              Alan Cox        :       Now uses generic datagrams and shared
 18  *                                      skbuff     18  *                                      skbuff library. No more peek crashes,
 19  *                                      no mor     19  *                                      no more backlogs
 20  *              Alan Cox        :       Checks     20  *              Alan Cox        :       Checks sk->broadcast.
 21  *              Alan Cox        :       Uses s     21  *              Alan Cox        :       Uses skb_free_datagram/skb_copy_datagram
 22  *              Alan Cox        :       Raw pa     22  *              Alan Cox        :       Raw passes ip options too
 23  *              Alan Cox        :       Setsoc     23  *              Alan Cox        :       Setsocketopt added
 24  *              Alan Cox        :       Fixed      24  *              Alan Cox        :       Fixed error return for broadcasts
 25  *              Alan Cox        :       Remove     25  *              Alan Cox        :       Removed wake_up calls
 26  *              Alan Cox        :       Use tt     26  *              Alan Cox        :       Use ttl/tos
 27  *              Alan Cox        :       Cleane     27  *              Alan Cox        :       Cleaned up old debugging
 28  *              Alan Cox        :       Use ne     28  *              Alan Cox        :       Use new kernel side addresses
 29  *      Arnt Gulbrandsen        :       Fixed      29  *      Arnt Gulbrandsen        :       Fixed MSG_DONTROUTE in raw sockets.
 30  *              Alan Cox        :       BSD st     30  *              Alan Cox        :       BSD style RAW socket demultiplexing.
 31  *              Alan Cox        :       Beginn     31  *              Alan Cox        :       Beginnings of mrouted support.
 32  *              Alan Cox        :       Added      32  *              Alan Cox        :       Added IP_HDRINCL option.
 33  *              Alan Cox        :       Skip b     33  *              Alan Cox        :       Skip broadcast check if BSDism set.
 34  *              David S. Miller :       New so     34  *              David S. Miller :       New socket lookup architecture.
 35  *                                                 35  *
 36  *              This program is free software;     36  *              This program is free software; you can redistribute it and/or
 37  *              modify it under the terms of t     37  *              modify it under the terms of the GNU General Public License
 38  *              as published by the Free Softw     38  *              as published by the Free Software Foundation; either version
 39  *              2 of the License, or (at your      39  *              2 of the License, or (at your option) any later version.
 40  */                                                40  */
 41                                                !!  41  
 42 #include <linux/types.h>                       !!  42 #include <linux/config.h> 
 43 #include <asm/atomic.h>                            43 #include <asm/atomic.h>
 44 #include <asm/byteorder.h>                         44 #include <asm/byteorder.h>
 45 #include <asm/current.h>                           45 #include <asm/current.h>
 46 #include <asm/uaccess.h>                           46 #include <asm/uaccess.h>
 47 #include <asm/ioctls.h>                            47 #include <asm/ioctls.h>
                                                   >>  48 #include <linux/types.h>
 48 #include <linux/stddef.h>                          49 #include <linux/stddef.h>
 49 #include <linux/slab.h>                            50 #include <linux/slab.h>
 50 #include <linux/errno.h>                           51 #include <linux/errno.h>
 51 #include <linux/aio.h>                             52 #include <linux/aio.h>
 52 #include <linux/kernel.h>                          53 #include <linux/kernel.h>
 53 #include <linux/spinlock.h>                        54 #include <linux/spinlock.h>
 54 #include <linux/sockios.h>                         55 #include <linux/sockios.h>
 55 #include <linux/socket.h>                          56 #include <linux/socket.h>
 56 #include <linux/in.h>                              57 #include <linux/in.h>
 57 #include <linux/mroute.h>                          58 #include <linux/mroute.h>
 58 #include <linux/netdevice.h>                       59 #include <linux/netdevice.h>
 59 #include <linux/in_route.h>                        60 #include <linux/in_route.h>
 60 #include <linux/route.h>                           61 #include <linux/route.h>
                                                   >>  62 #include <linux/tcp.h>
 61 #include <linux/skbuff.h>                          63 #include <linux/skbuff.h>
 62 #include <net/net_namespace.h>                 << 
 63 #include <net/dst.h>                               64 #include <net/dst.h>
 64 #include <net/sock.h>                              65 #include <net/sock.h>
 65 #include <linux/gfp.h>                             66 #include <linux/gfp.h>
 66 #include <linux/ip.h>                              67 #include <linux/ip.h>
 67 #include <linux/net.h>                             68 #include <linux/net.h>
 68 #include <net/ip.h>                                69 #include <net/ip.h>
 69 #include <net/icmp.h>                              70 #include <net/icmp.h>
 70 #include <net/udp.h>                               71 #include <net/udp.h>
 71 #include <net/raw.h>                               72 #include <net/raw.h>
 72 #include <net/snmp.h>                              73 #include <net/snmp.h>
 73 #include <net/tcp_states.h>                    << 
 74 #include <net/inet_common.h>                       74 #include <net/inet_common.h>
 75 #include <net/checksum.h>                          75 #include <net/checksum.h>
 76 #include <net/xfrm.h>                              76 #include <net/xfrm.h>
 77 #include <linux/rtnetlink.h>                       77 #include <linux/rtnetlink.h>
 78 #include <linux/proc_fs.h>                         78 #include <linux/proc_fs.h>
 79 #include <linux/seq_file.h>                        79 #include <linux/seq_file.h>
 80 #include <linux/netfilter.h>                       80 #include <linux/netfilter.h>
 81 #include <linux/netfilter_ipv4.h>                  81 #include <linux/netfilter_ipv4.h>
 82                                                    82 
 83 static struct raw_hashinfo raw_v4_hashinfo = { !!  83 struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
 84         .lock = __RW_LOCK_UNLOCKED(),          !!  84 DEFINE_RWLOCK(raw_v4_lock);
 85 };                                             << 
 86                                                    85 
 87 void raw_hash_sk(struct sock *sk, struct raw_h !!  86 static void raw_v4_hash(struct sock *sk)
 88 {                                                  87 {
 89         struct hlist_head *head;               !!  88         struct hlist_head *head = &raw_v4_htable[inet_sk(sk)->num &
 90                                                !!  89                                                  (RAWV4_HTABLE_SIZE - 1)];
 91         head = &h->ht[inet_sk(sk)->num & (RAW_ << 
 92                                                    90 
 93         write_lock_bh(&h->lock);               !!  91         write_lock_bh(&raw_v4_lock);
 94         sk_add_node(sk, head);                     92         sk_add_node(sk, head);
 95         sock_prot_inuse_add(sk->sk_prot, 1);   !!  93         sock_prot_inc_use(sk->sk_prot);
 96         write_unlock_bh(&h->lock);             !!  94         write_unlock_bh(&raw_v4_lock);
 97 }                                              << 
 98 EXPORT_SYMBOL_GPL(raw_hash_sk);                << 
 99                                                << 
100 void raw_unhash_sk(struct sock *sk, struct raw << 
101 {                                              << 
102         write_lock_bh(&h->lock);               << 
103         if (sk_del_node_init(sk))              << 
104                 sock_prot_inuse_add(sk->sk_pro << 
105         write_unlock_bh(&h->lock);             << 
106 }                                              << 
107 EXPORT_SYMBOL_GPL(raw_unhash_sk);              << 
108                                                << 
109 static void raw_v4_hash(struct sock *sk)       << 
110 {                                              << 
111         raw_hash_sk(sk, &raw_v4_hashinfo);     << 
112 }                                                  95 }
113                                                    96 
114 static void raw_v4_unhash(struct sock *sk)         97 static void raw_v4_unhash(struct sock *sk)
115 {                                                  98 {
116         raw_unhash_sk(sk, &raw_v4_hashinfo);   !!  99         write_lock_bh(&raw_v4_lock);
                                                   >> 100         if (sk_del_node_init(sk))
                                                   >> 101                 sock_prot_dec_use(sk->sk_prot);
                                                   >> 102         write_unlock_bh(&raw_v4_lock);
117 }                                                 103 }
118                                                   104 
119 static struct sock *__raw_v4_lookup(struct net !! 105 struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
120                 unsigned short num, __be32 rad !! 106                              unsigned long raddr, unsigned long laddr,
                                                   >> 107                              int dif)
121 {                                                 108 {
122         struct hlist_node *node;                  109         struct hlist_node *node;
123                                                   110 
124         sk_for_each_from(sk, node) {              111         sk_for_each_from(sk, node) {
125                 struct inet_sock *inet = inet_    112                 struct inet_sock *inet = inet_sk(sk);
126                                                   113 
127                 if (sk->sk_net == net && inet- !! 114                 if (inet->num == num                                    &&
128                     !(inet->daddr && inet->dad    115                     !(inet->daddr && inet->daddr != raddr)              &&
129                     !(inet->rcv_saddr && inet-    116                     !(inet->rcv_saddr && inet->rcv_saddr != laddr)      &&
130                     !(sk->sk_bound_dev_if && s    117                     !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
131                         goto found; /* gotcha     118                         goto found; /* gotcha */
132         }                                         119         }
133         sk = NULL;                                120         sk = NULL;
134 found:                                            121 found:
135         return sk;                                122         return sk;
136 }                                                 123 }
137                                                   124 
138 /*                                                125 /*
139  *      0 - deliver                               126  *      0 - deliver
140  *      1 - block                                 127  *      1 - block
141  */                                               128  */
142 static __inline__ int icmp_filter(struct sock     129 static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
143 {                                                 130 {
144         int type;                                 131         int type;
145                                                   132 
146         if (!pskb_may_pull(skb, sizeof(struct     133         if (!pskb_may_pull(skb, sizeof(struct icmphdr)))
147                 return 1;                         134                 return 1;
148                                                   135 
149         type = icmp_hdr(skb)->type;            !! 136         type = skb->h.icmph->type;
150         if (type < 32) {                          137         if (type < 32) {
151                 __u32 data = raw_sk(sk)->filte    138                 __u32 data = raw_sk(sk)->filter.data;
152                                                   139 
153                 return ((1 << type) & data) !=    140                 return ((1 << type) & data) != 0;
154         }                                         141         }
155                                                   142 
156         /* Do not block unknown ICMP types */     143         /* Do not block unknown ICMP types */
157         return 0;                                 144         return 0;
158 }                                                 145 }
159                                                   146 
160 /* IP input processing comes here for RAW sock    147 /* IP input processing comes here for RAW socket delivery.
161  * Caller owns SKB, so we must make clones.       148  * Caller owns SKB, so we must make clones.
162  *                                                149  *
163  * RFC 1122: SHOULD pass TOS value up to the t    150  * RFC 1122: SHOULD pass TOS value up to the transport layer.
164  * -> It does. And not only TOS, but all IP he    151  * -> It does. And not only TOS, but all IP header.
165  */                                               152  */
166 static int raw_v4_input(struct sk_buff *skb, s !! 153 void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
167 {                                                 154 {
168         struct sock *sk;                          155         struct sock *sk;
169         struct hlist_head *head;                  156         struct hlist_head *head;
170         int delivered = 0;                     << 
171         struct net *net;                       << 
172                                                   157 
173         read_lock(&raw_v4_hashinfo.lock);      !! 158         read_lock(&raw_v4_lock);
174         head = &raw_v4_hashinfo.ht[hash];      !! 159         head = &raw_v4_htable[hash];
175         if (hlist_empty(head))                    160         if (hlist_empty(head))
176                 goto out;                         161                 goto out;
177                                                !! 162         sk = __raw_v4_lookup(__sk_head(head), iph->protocol,
178         net = skb->dev->nd_net;                << 
179         sk = __raw_v4_lookup(net, __sk_head(he << 
180                              iph->saddr, iph->    163                              iph->saddr, iph->daddr,
181                              skb->dev->ifindex    164                              skb->dev->ifindex);
182                                                   165 
183         while (sk) {                              166         while (sk) {
184                 delivered = 1;                 << 
185                 if (iph->protocol != IPPROTO_I    167                 if (iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) {
186                         struct sk_buff *clone     168                         struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
187                                                   169 
188                         /* Not releasing hash     170                         /* Not releasing hash table! */
189                         if (clone)                171                         if (clone)
190                                 raw_rcv(sk, cl    172                                 raw_rcv(sk, clone);
191                 }                                 173                 }
192                 sk = __raw_v4_lookup(net, sk_n !! 174                 sk = __raw_v4_lookup(sk_next(sk), iph->protocol,
193                                      iph->sadd    175                                      iph->saddr, iph->daddr,
194                                      skb->dev-    176                                      skb->dev->ifindex);
195         }                                         177         }
196 out:                                              178 out:
197         read_unlock(&raw_v4_hashinfo.lock);    !! 179         read_unlock(&raw_v4_lock);
198         return delivered;                      << 
199 }                                              << 
200                                                << 
201 int raw_local_deliver(struct sk_buff *skb, int << 
202 {                                              << 
203         int hash;                              << 
204         struct sock *raw_sk;                   << 
205                                                << 
206         hash = protocol & (RAW_HTABLE_SIZE - 1 << 
207         raw_sk = sk_head(&raw_v4_hashinfo.ht[h << 
208                                                << 
209         /* If there maybe a raw socket we must << 
210          * don't care less                     << 
211          */                                    << 
212         if (raw_sk && !raw_v4_input(skb, ip_hd << 
213                 raw_sk = NULL;                 << 
214                                                << 
215         return raw_sk != NULL;                 << 
216                                                << 
217 }                                                 180 }
218                                                   181 
219 static void raw_err(struct sock *sk, struct sk !! 182 void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
220 {                                                 183 {
221         struct inet_sock *inet = inet_sk(sk);     184         struct inet_sock *inet = inet_sk(sk);
222         const int type = icmp_hdr(skb)->type;  !! 185         int type = skb->h.icmph->type;
223         const int code = icmp_hdr(skb)->code;  !! 186         int code = skb->h.icmph->code;
224         int err = 0;                              187         int err = 0;
225         int harderr = 0;                          188         int harderr = 0;
226                                                   189 
227         /* Report error on raw socket, if:        190         /* Report error on raw socket, if:
228            1. User requested ip_recverr.          191            1. User requested ip_recverr.
229            2. Socket is connected (otherwise t    192            2. Socket is connected (otherwise the error indication
230               is useless without ip_recverr an    193               is useless without ip_recverr and error is hard.
231          */                                       194          */
232         if (!inet->recverr && sk->sk_state !=     195         if (!inet->recverr && sk->sk_state != TCP_ESTABLISHED)
233                 return;                           196                 return;
234                                                   197 
235         switch (type) {                           198         switch (type) {
236         default:                                  199         default:
237         case ICMP_TIME_EXCEEDED:                  200         case ICMP_TIME_EXCEEDED:
238                 err = EHOSTUNREACH;               201                 err = EHOSTUNREACH;
239                 break;                            202                 break;
240         case ICMP_SOURCE_QUENCH:                  203         case ICMP_SOURCE_QUENCH:
241                 return;                           204                 return;
242         case ICMP_PARAMETERPROB:                  205         case ICMP_PARAMETERPROB:
243                 err = EPROTO;                     206                 err = EPROTO;
244                 harderr = 1;                      207                 harderr = 1;
245                 break;                            208                 break;
246         case ICMP_DEST_UNREACH:                   209         case ICMP_DEST_UNREACH:
247                 err = EHOSTUNREACH;               210                 err = EHOSTUNREACH;
248                 if (code > NR_ICMP_UNREACH)       211                 if (code > NR_ICMP_UNREACH)
249                         break;                    212                         break;
250                 err = icmp_err_convert[code].e    213                 err = icmp_err_convert[code].errno;
251                 harderr = icmp_err_convert[cod    214                 harderr = icmp_err_convert[code].fatal;
252                 if (code == ICMP_FRAG_NEEDED)     215                 if (code == ICMP_FRAG_NEEDED) {
253                         harderr = inet->pmtudi    216                         harderr = inet->pmtudisc != IP_PMTUDISC_DONT;
254                         err = EMSGSIZE;           217                         err = EMSGSIZE;
255                 }                                 218                 }
256         }                                         219         }
257                                                   220 
258         if (inet->recverr) {                      221         if (inet->recverr) {
259                 struct iphdr *iph = (struct ip    222                 struct iphdr *iph = (struct iphdr*)skb->data;
260                 u8 *payload = skb->data + (iph    223                 u8 *payload = skb->data + (iph->ihl << 2);
261                                                   224 
262                 if (inet->hdrincl)                225                 if (inet->hdrincl)
263                         payload = skb->data;      226                         payload = skb->data;
264                 ip_icmp_error(sk, skb, err, 0,    227                 ip_icmp_error(sk, skb, err, 0, info, payload);
265         }                                         228         }
266                                                   229 
267         if (inet->recverr || harderr) {           230         if (inet->recverr || harderr) {
268                 sk->sk_err = err;                 231                 sk->sk_err = err;
269                 sk->sk_error_report(sk);          232                 sk->sk_error_report(sk);
270         }                                         233         }
271 }                                                 234 }
272                                                   235 
273 void raw_icmp_error(struct sk_buff *skb, int p << 
274 {                                              << 
275         int hash;                              << 
276         struct sock *raw_sk;                   << 
277         struct iphdr *iph;                     << 
278         struct net *net;                       << 
279                                                << 
280         hash = protocol & (RAW_HTABLE_SIZE - 1 << 
281                                                << 
282         read_lock(&raw_v4_hashinfo.lock);      << 
283         raw_sk = sk_head(&raw_v4_hashinfo.ht[h << 
284         if (raw_sk != NULL) {                  << 
285                 iph = (struct iphdr *)skb->dat << 
286                 net = skb->dev->nd_net;        << 
287                                                << 
288                 while ((raw_sk = __raw_v4_look << 
289                                                << 
290                                                << 
291                         raw_err(raw_sk, skb, i << 
292                         raw_sk = sk_next(raw_s << 
293                         iph = (struct iphdr *) << 
294                 }                              << 
295         }                                      << 
296         read_unlock(&raw_v4_hashinfo.lock);    << 
297 }                                              << 
298                                                << 
299 static int raw_rcv_skb(struct sock * sk, struc    236 static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
300 {                                                 237 {
301         /* Charge it to the socket. */            238         /* Charge it to the socket. */
302                                                !! 239         
303         if (sock_queue_rcv_skb(sk, skb) < 0) {    240         if (sock_queue_rcv_skb(sk, skb) < 0) {
304                 atomic_inc(&sk->sk_drops);     !! 241                 /* FIXME: increment a raw drops counter here */
305                 kfree_skb(skb);                   242                 kfree_skb(skb);
306                 return NET_RX_DROP;               243                 return NET_RX_DROP;
307         }                                         244         }
308                                                   245 
309         return NET_RX_SUCCESS;                    246         return NET_RX_SUCCESS;
310 }                                                 247 }
311                                                   248 
312 int raw_rcv(struct sock *sk, struct sk_buff *s    249 int raw_rcv(struct sock *sk, struct sk_buff *skb)
313 {                                                 250 {
314         if (!xfrm4_policy_check(sk, XFRM_POLIC    251         if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
315                 atomic_inc(&sk->sk_drops);     << 
316                 kfree_skb(skb);                   252                 kfree_skb(skb);
317                 return NET_RX_DROP;               253                 return NET_RX_DROP;
318         }                                         254         }
319         nf_reset(skb);                         << 
320                                                   255 
321         skb_push(skb, skb->data - skb_network_ !! 256         skb_push(skb, skb->data - skb->nh.raw);
322                                                   257 
323         raw_rcv_skb(sk, skb);                     258         raw_rcv_skb(sk, skb);
324         return 0;                                 259         return 0;
325 }                                                 260 }
326                                                   261 
327 static int raw_send_hdrinc(struct sock *sk, vo !! 262 static int raw_send_hdrinc(struct sock *sk, void *from, int length,
328                         struct rtable *rt,     !! 263                         struct rtable *rt, 
329                         unsigned int flags)       264                         unsigned int flags)
330 {                                                 265 {
331         struct inet_sock *inet = inet_sk(sk);     266         struct inet_sock *inet = inet_sk(sk);
332         int hh_len;                               267         int hh_len;
333         struct iphdr *iph;                        268         struct iphdr *iph;
334         struct sk_buff *skb;                      269         struct sk_buff *skb;
335         unsigned int iphlen;                   << 
336         int err;                                  270         int err;
337                                                   271 
338         if (length > rt->u.dst.dev->mtu) {        272         if (length > rt->u.dst.dev->mtu) {
339                 ip_local_error(sk, EMSGSIZE, r    273                 ip_local_error(sk, EMSGSIZE, rt->rt_dst, inet->dport,
340                                rt->u.dst.dev->    274                                rt->u.dst.dev->mtu);
341                 return -EMSGSIZE;                 275                 return -EMSGSIZE;
342         }                                         276         }
343         if (flags&MSG_PROBE)                      277         if (flags&MSG_PROBE)
344                 goto out;                         278                 goto out;
345                                                   279 
346         hh_len = LL_RESERVED_SPACE(rt->u.dst.d    280         hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
347                                                   281 
348         skb = sock_alloc_send_skb(sk, length+h    282         skb = sock_alloc_send_skb(sk, length+hh_len+15,
349                                   flags&MSG_DO    283                                   flags&MSG_DONTWAIT, &err);
350         if (skb == NULL)                          284         if (skb == NULL)
351                 goto error;                    !! 285                 goto error; 
352         skb_reserve(skb, hh_len);                 286         skb_reserve(skb, hh_len);
353                                                   287 
354         skb->priority = sk->sk_priority;          288         skb->priority = sk->sk_priority;
355         skb->mark = sk->sk_mark;               << 
356         skb->dst = dst_clone(&rt->u.dst);         289         skb->dst = dst_clone(&rt->u.dst);
357                                                   290 
358         skb_reset_network_header(skb);         !! 291         skb->nh.iph = iph = (struct iphdr *)skb_put(skb, length);
359         iph = ip_hdr(skb);                     << 
360         skb_put(skb, length);                  << 
361                                                   292 
362         skb->ip_summed = CHECKSUM_NONE;           293         skb->ip_summed = CHECKSUM_NONE;
363                                                   294 
364         skb->transport_header = skb->network_h !! 295         skb->h.raw = skb->nh.raw;
365         err = memcpy_fromiovecend((void *)iph,    296         err = memcpy_fromiovecend((void *)iph, from, 0, length);
366         if (err)                                  297         if (err)
367                 goto error_fault;                 298                 goto error_fault;
368                                                   299 
369         /* We don't modify invalid header */      300         /* We don't modify invalid header */
370         iphlen = iph->ihl * 4;                 !! 301         if (length >= sizeof(*iph) && iph->ihl * 4 <= length) {
371         if (iphlen >= sizeof(*iph) && iphlen < << 
372                 if (!iph->saddr)                  302                 if (!iph->saddr)
373                         iph->saddr = rt->rt_sr    303                         iph->saddr = rt->rt_src;
374                 iph->check   = 0;                 304                 iph->check   = 0;
375                 iph->tot_len = htons(length);     305                 iph->tot_len = htons(length);
376                 if (!iph->id)                     306                 if (!iph->id)
377                         ip_select_ident(iph, &    307                         ip_select_ident(iph, &rt->u.dst, NULL);
378                                                   308 
379                 iph->check = ip_fast_csum((uns    309                 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
380         }                                         310         }
381         if (iph->protocol == IPPROTO_ICMP)     << 
382                 icmp_out_count(((struct icmphd << 
383                         skb_transport_header(s << 
384                                                   311 
385         err = NF_HOOK(PF_INET, NF_INET_LOCAL_O !! 312         err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
386                       dst_output);                313                       dst_output);
387         if (err > 0)                              314         if (err > 0)
388                 err = inet->recverr ? net_xmit    315                 err = inet->recverr ? net_xmit_errno(err) : 0;
389         if (err)                                  316         if (err)
390                 goto error;                       317                 goto error;
391 out:                                              318 out:
392         return 0;                                 319         return 0;
393                                                   320 
394 error_fault:                                      321 error_fault:
395         err = -EFAULT;                            322         err = -EFAULT;
396         kfree_skb(skb);                           323         kfree_skb(skb);
397 error:                                            324 error:
398         IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS);    325         IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
399         return err;                            !! 326         return err; 
400 }                                                 327 }
401                                                   328 
402 static int raw_probe_proto_opt(struct flowi *f !! 329 static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
403 {                                                 330 {
404         struct iovec *iov;                        331         struct iovec *iov;
405         u8 __user *type = NULL;                   332         u8 __user *type = NULL;
406         u8 __user *code = NULL;                   333         u8 __user *code = NULL;
407         int probed = 0;                           334         int probed = 0;
408         unsigned int i;                        !! 335         int i;
409                                                   336 
410         if (!msg->msg_iov)                        337         if (!msg->msg_iov)
411                 return 0;                      !! 338                 return;
412                                                   339 
413         for (i = 0; i < msg->msg_iovlen; i++)     340         for (i = 0; i < msg->msg_iovlen; i++) {
414                 iov = &msg->msg_iov[i];           341                 iov = &msg->msg_iov[i];
415                 if (!iov)                         342                 if (!iov)
416                         continue;                 343                         continue;
417                                                   344 
418                 switch (fl->proto) {              345                 switch (fl->proto) {
419                 case IPPROTO_ICMP:                346                 case IPPROTO_ICMP:
420                         /* check if one-byte f    347                         /* check if one-byte field is readable or not. */
421                         if (iov->iov_base && i    348                         if (iov->iov_base && iov->iov_len < 1)
422                                 break;            349                                 break;
423                                                   350 
424                         if (!type) {              351                         if (!type) {
425                                 type = iov->io    352                                 type = iov->iov_base;
426                                 /* check if co    353                                 /* check if code field is readable or not. */
427                                 if (iov->iov_l    354                                 if (iov->iov_len > 1)
428                                         code =    355                                         code = type + 1;
429                         } else if (!code)         356                         } else if (!code)
430                                 code = iov->io    357                                 code = iov->iov_base;
431                                                   358 
432                         if (type && code) {       359                         if (type && code) {
433                                 if (get_user(f !! 360                                 get_user(fl->fl_icmp_type, type);
434                                     get_user(f !! 361                                 __get_user(fl->fl_icmp_code, code);
435                                         return << 
436                                 probed = 1;       362                                 probed = 1;
437                         }                         363                         }
438                         break;                    364                         break;
439                 default:                          365                 default:
440                         probed = 1;               366                         probed = 1;
441                         break;                    367                         break;
442                 }                                 368                 }
443                 if (probed)                       369                 if (probed)
444                         break;                    370                         break;
445         }                                         371         }
446         return 0;                              << 
447 }                                                 372 }
448                                                   373 
449 static int raw_sendmsg(struct kiocb *iocb, str    374 static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
450                        size_t len)                375                        size_t len)
451 {                                                 376 {
452         struct inet_sock *inet = inet_sk(sk);     377         struct inet_sock *inet = inet_sk(sk);
453         struct ipcm_cookie ipc;                   378         struct ipcm_cookie ipc;
454         struct rtable *rt = NULL;                 379         struct rtable *rt = NULL;
455         int free = 0;                             380         int free = 0;
456         __be32 daddr;                          !! 381         u32 daddr;
457         __be32 saddr;                          !! 382         u32 saddr;
458         u8  tos;                                  383         u8  tos;
459         int err;                                  384         int err;
460                                                   385 
461         err = -EMSGSIZE;                          386         err = -EMSGSIZE;
462         if (len > 0xFFFF)                      !! 387         if (len < 0 || len > 0xFFFF)
463                 goto out;                         388                 goto out;
464                                                   389 
465         /*                                        390         /*
466          *      Check the flags.                  391          *      Check the flags.
467          */                                       392          */
468                                                   393 
469         err = -EOPNOTSUPP;                        394         err = -EOPNOTSUPP;
470         if (msg->msg_flags & MSG_OOB)   /* Mir    395         if (msg->msg_flags & MSG_OOB)   /* Mirror BSD error message */
471                 goto out;               /* com    396                 goto out;               /* compatibility */
472                                                !! 397                          
473         /*                                        398         /*
474          *      Get and verify the address.    !! 399          *      Get and verify the address. 
475          */                                       400          */
476                                                   401 
477         if (msg->msg_namelen) {                   402         if (msg->msg_namelen) {
478                 struct sockaddr_in *usin = (st    403                 struct sockaddr_in *usin = (struct sockaddr_in*)msg->msg_name;
479                 err = -EINVAL;                    404                 err = -EINVAL;
480                 if (msg->msg_namelen < sizeof(    405                 if (msg->msg_namelen < sizeof(*usin))
481                         goto out;                 406                         goto out;
482                 if (usin->sin_family != AF_INE    407                 if (usin->sin_family != AF_INET) {
483                         static int complained;    408                         static int complained;
484                         if (!complained++)        409                         if (!complained++)
485                                 printk(KERN_IN    410                                 printk(KERN_INFO "%s forgot to set AF_INET in "
486                                                   411                                                  "raw sendmsg. Fix it!\n",
487                                                   412                                                  current->comm);
488                         err = -EAFNOSUPPORT;      413                         err = -EAFNOSUPPORT;
489                         if (usin->sin_family)     414                         if (usin->sin_family)
490                                 goto out;         415                                 goto out;
491                 }                                 416                 }
492                 daddr = usin->sin_addr.s_addr;    417                 daddr = usin->sin_addr.s_addr;
493                 /* ANK: I did not forget to ge    418                 /* ANK: I did not forget to get protocol from port field.
494                  * I just do not know, who use    419                  * I just do not know, who uses this weirdness.
495                  * IP_HDRINCL is much more con    420                  * IP_HDRINCL is much more convenient.
496                  */                               421                  */
497         } else {                                  422         } else {
498                 err = -EDESTADDRREQ;              423                 err = -EDESTADDRREQ;
499                 if (sk->sk_state != TCP_ESTABL !! 424                 if (sk->sk_state != TCP_ESTABLISHED) 
500                         goto out;                 425                         goto out;
501                 daddr = inet->daddr;              426                 daddr = inet->daddr;
502         }                                         427         }
503                                                   428 
504         ipc.addr = inet->saddr;                   429         ipc.addr = inet->saddr;
505         ipc.opt = NULL;                           430         ipc.opt = NULL;
506         ipc.oif = sk->sk_bound_dev_if;            431         ipc.oif = sk->sk_bound_dev_if;
507                                                   432 
508         if (msg->msg_controllen) {                433         if (msg->msg_controllen) {
509                 err = ip_cmsg_send(msg, &ipc);    434                 err = ip_cmsg_send(msg, &ipc);
510                 if (err)                          435                 if (err)
511                         goto out;                 436                         goto out;
512                 if (ipc.opt)                      437                 if (ipc.opt)
513                         free = 1;                 438                         free = 1;
514         }                                         439         }
515                                                   440 
516         saddr = ipc.addr;                         441         saddr = ipc.addr;
517         ipc.addr = daddr;                         442         ipc.addr = daddr;
518                                                   443 
519         if (!ipc.opt)                             444         if (!ipc.opt)
520                 ipc.opt = inet->opt;              445                 ipc.opt = inet->opt;
521                                                   446 
522         if (ipc.opt) {                            447         if (ipc.opt) {
523                 err = -EINVAL;                    448                 err = -EINVAL;
524                 /* Linux does not mangle heade    449                 /* Linux does not mangle headers on raw sockets,
525                  * so that IP options + IP_HDR    450                  * so that IP options + IP_HDRINCL is non-sense.
526                  */                               451                  */
527                 if (inet->hdrincl)                452                 if (inet->hdrincl)
528                         goto done;                453                         goto done;
529                 if (ipc.opt->srr) {               454                 if (ipc.opt->srr) {
530                         if (!daddr)               455                         if (!daddr)
531                                 goto done;        456                                 goto done;
532                         daddr = ipc.opt->faddr    457                         daddr = ipc.opt->faddr;
533                 }                                 458                 }
534         }                                         459         }
535         tos = RT_CONN_FLAGS(sk);               !! 460         tos = RT_TOS(inet->tos) | sk->sk_localroute;
536         if (msg->msg_flags & MSG_DONTROUTE)       461         if (msg->msg_flags & MSG_DONTROUTE)
537                 tos |= RTO_ONLINK;                462                 tos |= RTO_ONLINK;
538                                                   463 
539         if (ipv4_is_multicast(daddr)) {        !! 464         if (MULTICAST(daddr)) {
540                 if (!ipc.oif)                     465                 if (!ipc.oif)
541                         ipc.oif = inet->mc_ind    466                         ipc.oif = inet->mc_index;
542                 if (!saddr)                       467                 if (!saddr)
543                         saddr = inet->mc_addr;    468                         saddr = inet->mc_addr;
544         }                                         469         }
545                                                   470 
546         {                                         471         {
547                 struct flowi fl = { .oif = ipc    472                 struct flowi fl = { .oif = ipc.oif,
548                                     .mark = sk << 
549                                     .nl_u = {     473                                     .nl_u = { .ip4_u =
550                                                   474                                               { .daddr = daddr,
551                                                   475                                                 .saddr = saddr,
552                                                   476                                                 .tos = tos } },
553                                     .proto = i    477                                     .proto = inet->hdrincl ? IPPROTO_RAW :
554                                                !! 478                                                              sk->sk_protocol,
555                                   };              479                                   };
556                 if (!inet->hdrincl) {          !! 480                 if (!inet->hdrincl)
557                         err = raw_probe_proto_ !! 481                         raw_probe_proto_opt(&fl, msg);
558                         if (err)               << 
559                                 goto done;     << 
560                 }                              << 
561                                                   482 
562                 security_sk_classify_flow(sk,  !! 483                 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
563                 err = ip_route_output_flow(&in << 
564         }                                         484         }
565         if (err)                                  485         if (err)
566                 goto done;                        486                 goto done;
567                                                   487 
568         err = -EACCES;                            488         err = -EACCES;
569         if (rt->rt_flags & RTCF_BROADCAST && !    489         if (rt->rt_flags & RTCF_BROADCAST && !sock_flag(sk, SOCK_BROADCAST))
570                 goto done;                        490                 goto done;
571                                                   491 
572         if (msg->msg_flags & MSG_CONFIRM)         492         if (msg->msg_flags & MSG_CONFIRM)
573                 goto do_confirm;                  493                 goto do_confirm;
574 back_from_confirm:                                494 back_from_confirm:
575                                                   495 
576         if (inet->hdrincl)                        496         if (inet->hdrincl)
577                 err = raw_send_hdrinc(sk, msg- !! 497                 err = raw_send_hdrinc(sk, msg->msg_iov, len, 
578                                         rt, ms    498                                         rt, msg->msg_flags);
579                                                !! 499         
580          else {                                   500          else {
581                 if (!ipc.addr)                    501                 if (!ipc.addr)
582                         ipc.addr = rt->rt_dst;    502                         ipc.addr = rt->rt_dst;
583                 lock_sock(sk);                    503                 lock_sock(sk);
584                 err = ip_append_data(sk, ip_ge    504                 err = ip_append_data(sk, ip_generic_getfrag, msg->msg_iov, len, 0,
585                                         &ipc,     505                                         &ipc, rt, msg->msg_flags);
586                 if (err)                          506                 if (err)
587                         ip_flush_pending_frame    507                         ip_flush_pending_frames(sk);
588                 else if (!(msg->msg_flags & MS    508                 else if (!(msg->msg_flags & MSG_MORE))
589                         err = ip_push_pending_    509                         err = ip_push_pending_frames(sk);
590                 release_sock(sk);                 510                 release_sock(sk);
591         }                                         511         }
592 done:                                             512 done:
593         if (free)                                 513         if (free)
594                 kfree(ipc.opt);                   514                 kfree(ipc.opt);
595         ip_rt_put(rt);                            515         ip_rt_put(rt);
596                                                   516 
597 out:                                           !! 517 out:    return err < 0 ? err : len;
598         if (err < 0)                           << 
599                 return err;                    << 
600         return len;                            << 
601                                                   518 
602 do_confirm:                                       519 do_confirm:
603         dst_confirm(&rt->u.dst);                  520         dst_confirm(&rt->u.dst);
604         if (!(msg->msg_flags & MSG_PROBE) || l    521         if (!(msg->msg_flags & MSG_PROBE) || len)
605                 goto back_from_confirm;           522                 goto back_from_confirm;
606         err = 0;                                  523         err = 0;
607         goto done;                                524         goto done;
608 }                                                 525 }
609                                                   526 
610 static void raw_close(struct sock *sk, long ti    527 static void raw_close(struct sock *sk, long timeout)
611 {                                                 528 {
612         /*                                     !! 529         /*
613          * Raw sockets may have direct kernel     530          * Raw sockets may have direct kernel refereneces. Kill them.
614          */                                       531          */
615         ip_ra_control(sk, 0, NULL);               532         ip_ra_control(sk, 0, NULL);
616                                                   533 
617         sk_common_release(sk);                    534         sk_common_release(sk);
618 }                                                 535 }
619                                                   536 
620 /* This gets rid of all the nasties in af_inet    537 /* This gets rid of all the nasties in af_inet. -DaveM */
621 static int raw_bind(struct sock *sk, struct so    538 static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
622 {                                                 539 {
623         struct inet_sock *inet = inet_sk(sk);     540         struct inet_sock *inet = inet_sk(sk);
624         struct sockaddr_in *addr = (struct soc    541         struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
625         int ret = -EINVAL;                        542         int ret = -EINVAL;
626         int chk_addr_ret;                         543         int chk_addr_ret;
627                                                   544 
628         if (sk->sk_state != TCP_CLOSE || addr_    545         if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
629                 goto out;                         546                 goto out;
630         chk_addr_ret = inet_addr_type(sk->sk_n !! 547         chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
631         ret = -EADDRNOTAVAIL;                     548         ret = -EADDRNOTAVAIL;
632         if (addr->sin_addr.s_addr && chk_addr_    549         if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
633             chk_addr_ret != RTN_MULTICAST && c    550             chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
634                 goto out;                         551                 goto out;
635         inet->rcv_saddr = inet->saddr = addr->    552         inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
636         if (chk_addr_ret == RTN_MULTICAST || c    553         if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
637                 inet->saddr = 0;  /* Use devic    554                 inet->saddr = 0;  /* Use device */
638         sk_dst_reset(sk);                         555         sk_dst_reset(sk);
639         ret = 0;                                  556         ret = 0;
640 out:    return ret;                               557 out:    return ret;
641 }                                                 558 }
642                                                   559 
643 /*                                                560 /*
644  *      This should be easy, if there is somet    561  *      This should be easy, if there is something there
645  *      we return it, otherwise we block.         562  *      we return it, otherwise we block.
646  */                                               563  */
647                                                   564 
648 static int raw_recvmsg(struct kiocb *iocb, str    565 static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
649                        size_t len, int noblock    566                        size_t len, int noblock, int flags, int *addr_len)
650 {                                                 567 {
651         struct inet_sock *inet = inet_sk(sk);     568         struct inet_sock *inet = inet_sk(sk);
652         size_t copied = 0;                        569         size_t copied = 0;
653         int err = -EOPNOTSUPP;                    570         int err = -EOPNOTSUPP;
654         struct sockaddr_in *sin = (struct sock    571         struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
655         struct sk_buff *skb;                      572         struct sk_buff *skb;
656                                                   573 
657         if (flags & MSG_OOB)                      574         if (flags & MSG_OOB)
658                 goto out;                         575                 goto out;
659                                                   576 
660         if (addr_len)                             577         if (addr_len)
661                 *addr_len = sizeof(*sin);         578                 *addr_len = sizeof(*sin);
662                                                   579 
663         if (flags & MSG_ERRQUEUE) {               580         if (flags & MSG_ERRQUEUE) {
664                 err = ip_recv_error(sk, msg, l    581                 err = ip_recv_error(sk, msg, len);
665                 goto out;                         582                 goto out;
666         }                                         583         }
667                                                   584 
668         skb = skb_recv_datagram(sk, flags, nob    585         skb = skb_recv_datagram(sk, flags, noblock, &err);
669         if (!skb)                                 586         if (!skb)
670                 goto out;                         587                 goto out;
671                                                   588 
672         copied = skb->len;                        589         copied = skb->len;
673         if (len < copied) {                       590         if (len < copied) {
674                 msg->msg_flags |= MSG_TRUNC;      591                 msg->msg_flags |= MSG_TRUNC;
675                 copied = len;                     592                 copied = len;
676         }                                         593         }
677                                                   594 
678         err = skb_copy_datagram_iovec(skb, 0,     595         err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
679         if (err)                                  596         if (err)
680                 goto done;                        597                 goto done;
681                                                   598 
682         sock_recv_timestamp(msg, sk, skb);        599         sock_recv_timestamp(msg, sk, skb);
683                                                   600 
684         /* Copy the address. */                   601         /* Copy the address. */
685         if (sin) {                                602         if (sin) {
686                 sin->sin_family = AF_INET;        603                 sin->sin_family = AF_INET;
687                 sin->sin_addr.s_addr = ip_hdr( !! 604                 sin->sin_addr.s_addr = skb->nh.iph->saddr;
688                 sin->sin_port = 0;             << 
689                 memset(&sin->sin_zero, 0, size    605                 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
690         }                                         606         }
691         if (inet->cmsg_flags)                     607         if (inet->cmsg_flags)
692                 ip_cmsg_recv(msg, skb);           608                 ip_cmsg_recv(msg, skb);
693         if (flags & MSG_TRUNC)                    609         if (flags & MSG_TRUNC)
694                 copied = skb->len;                610                 copied = skb->len;
695 done:                                             611 done:
696         skb_free_datagram(sk, skb);               612         skb_free_datagram(sk, skb);
697 out:                                           !! 613 out:    return err ? err : copied;
698         if (err)                               << 
699                 return err;                    << 
700         return copied;                         << 
701 }                                                 614 }
702                                                   615 
703 static int raw_init(struct sock *sk)              616 static int raw_init(struct sock *sk)
704 {                                                 617 {
705         struct raw_sock *rp = raw_sk(sk);         618         struct raw_sock *rp = raw_sk(sk);
706                                                   619 
707         if (inet_sk(sk)->num == IPPROTO_ICMP)     620         if (inet_sk(sk)->num == IPPROTO_ICMP)
708                 memset(&rp->filter, 0, sizeof(    621                 memset(&rp->filter, 0, sizeof(rp->filter));
709         return 0;                                 622         return 0;
710 }                                                 623 }
711                                                   624 
712 static int raw_seticmpfilter(struct sock *sk,     625 static int raw_seticmpfilter(struct sock *sk, char __user *optval, int optlen)
713 {                                                 626 {
714         if (optlen > sizeof(struct icmp_filter    627         if (optlen > sizeof(struct icmp_filter))
715                 optlen = sizeof(struct icmp_fi    628                 optlen = sizeof(struct icmp_filter);
716         if (copy_from_user(&raw_sk(sk)->filter    629         if (copy_from_user(&raw_sk(sk)->filter, optval, optlen))
717                 return -EFAULT;                   630                 return -EFAULT;
718         return 0;                                 631         return 0;
719 }                                                 632 }
720                                                   633 
721 static int raw_geticmpfilter(struct sock *sk,     634 static int raw_geticmpfilter(struct sock *sk, char __user *optval, int __user *optlen)
722 {                                                 635 {
723         int len, ret = -EFAULT;                   636         int len, ret = -EFAULT;
724                                                   637 
725         if (get_user(len, optlen))                638         if (get_user(len, optlen))
726                 goto out;                         639                 goto out;
727         ret = -EINVAL;                            640         ret = -EINVAL;
728         if (len < 0)                              641         if (len < 0)
729                 goto out;                         642                 goto out;
730         if (len > sizeof(struct icmp_filter))     643         if (len > sizeof(struct icmp_filter))
731                 len = sizeof(struct icmp_filte    644                 len = sizeof(struct icmp_filter);
732         ret = -EFAULT;                            645         ret = -EFAULT;
733         if (put_user(len, optlen) ||              646         if (put_user(len, optlen) ||
734             copy_to_user(optval, &raw_sk(sk)->    647             copy_to_user(optval, &raw_sk(sk)->filter, len))
735                 goto out;                         648                 goto out;
736         ret = 0;                                  649         ret = 0;
737 out:    return ret;                               650 out:    return ret;
738 }                                                 651 }
739                                                   652 
740 static int do_raw_setsockopt(struct sock *sk,  !! 653 static int raw_setsockopt(struct sock *sk, int level, int optname, 
741                           char __user *optval,    654                           char __user *optval, int optlen)
742 {                                                 655 {
                                                   >> 656         if (level != SOL_RAW)
                                                   >> 657                 return ip_setsockopt(sk, level, optname, optval, optlen);
                                                   >> 658 
743         if (optname == ICMP_FILTER) {             659         if (optname == ICMP_FILTER) {
744                 if (inet_sk(sk)->num != IPPROT    660                 if (inet_sk(sk)->num != IPPROTO_ICMP)
745                         return -EOPNOTSUPP;       661                         return -EOPNOTSUPP;
746                 else                              662                 else
747                         return raw_seticmpfilt    663                         return raw_seticmpfilter(sk, optval, optlen);
748         }                                         664         }
749         return -ENOPROTOOPT;                      665         return -ENOPROTOOPT;
750 }                                                 666 }
751                                                   667 
752 static int raw_setsockopt(struct sock *sk, int !! 668 static int raw_getsockopt(struct sock *sk, int level, int optname, 
753                           char __user *optval, !! 669                           char __user *optval, int __user *optlen)
754 {                                              << 
755         if (level != SOL_RAW)                  << 
756                 return ip_setsockopt(sk, level << 
757         return do_raw_setsockopt(sk, level, op << 
758 }                                              << 
759                                                << 
760 #ifdef CONFIG_COMPAT                           << 
761 static int compat_raw_setsockopt(struct sock * << 
762                                  char __user * << 
763 {                                                 670 {
764         if (level != SOL_RAW)                     671         if (level != SOL_RAW)
765                 return compat_ip_setsockopt(sk !! 672                 return ip_getsockopt(sk, level, optname, optval, optlen);
766         return do_raw_setsockopt(sk, level, op << 
767 }                                              << 
768 #endif                                         << 
769                                                   673 
770 static int do_raw_getsockopt(struct sock *sk,  << 
771                           char __user *optval, << 
772 {                                              << 
773         if (optname == ICMP_FILTER) {             674         if (optname == ICMP_FILTER) {
774                 if (inet_sk(sk)->num != IPPROT    675                 if (inet_sk(sk)->num != IPPROTO_ICMP)
775                         return -EOPNOTSUPP;       676                         return -EOPNOTSUPP;
776                 else                              677                 else
777                         return raw_geticmpfilt    678                         return raw_geticmpfilter(sk, optval, optlen);
778         }                                         679         }
779         return -ENOPROTOOPT;                      680         return -ENOPROTOOPT;
780 }                                                 681 }
781                                                   682 
782 static int raw_getsockopt(struct sock *sk, int << 
783                           char __user *optval, << 
784 {                                              << 
785         if (level != SOL_RAW)                  << 
786                 return ip_getsockopt(sk, level << 
787         return do_raw_getsockopt(sk, level, op << 
788 }                                              << 
789                                                << 
790 #ifdef CONFIG_COMPAT                           << 
791 static int compat_raw_getsockopt(struct sock * << 
792                                  char __user * << 
793 {                                              << 
794         if (level != SOL_RAW)                  << 
795                 return compat_ip_getsockopt(sk << 
796         return do_raw_getsockopt(sk, level, op << 
797 }                                              << 
798 #endif                                         << 
799                                                << 
800 static int raw_ioctl(struct sock *sk, int cmd,    683 static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
801 {                                                 684 {
802         switch (cmd) {                            685         switch (cmd) {
803                 case SIOCOUTQ: {                  686                 case SIOCOUTQ: {
804                         int amount = atomic_re    687                         int amount = atomic_read(&sk->sk_wmem_alloc);
805                         return put_user(amount    688                         return put_user(amount, (int __user *)arg);
806                 }                                 689                 }
807                 case SIOCINQ: {                   690                 case SIOCINQ: {
808                         struct sk_buff *skb;      691                         struct sk_buff *skb;
809                         int amount = 0;           692                         int amount = 0;
810                                                   693 
811                         spin_lock_bh(&sk->sk_r !! 694                         spin_lock_irq(&sk->sk_receive_queue.lock);
812                         skb = skb_peek(&sk->sk    695                         skb = skb_peek(&sk->sk_receive_queue);
813                         if (skb != NULL)          696                         if (skb != NULL)
814                                 amount = skb->    697                                 amount = skb->len;
815                         spin_unlock_bh(&sk->sk !! 698                         spin_unlock_irq(&sk->sk_receive_queue.lock);
816                         return put_user(amount    699                         return put_user(amount, (int __user *)arg);
817                 }                                 700                 }
818                                                   701 
819                 default:                          702                 default:
820 #ifdef CONFIG_IP_MROUTE                           703 #ifdef CONFIG_IP_MROUTE
821                         return ipmr_ioctl(sk,     704                         return ipmr_ioctl(sk, cmd, (void __user *)arg);
822 #else                                             705 #else
823                         return -ENOIOCTLCMD;      706                         return -ENOIOCTLCMD;
824 #endif                                            707 #endif
825         }                                         708         }
826 }                                                 709 }
827                                                   710 
828 DEFINE_PROTO_INUSE(raw)                        << 
829                                                << 
830 struct proto raw_prot = {                         711 struct proto raw_prot = {
831         .name              = "RAW",            !! 712         .name =         "RAW",
832         .owner             = THIS_MODULE,      !! 713         .owner =        THIS_MODULE,
833         .close             = raw_close,        !! 714         .close =        raw_close,
834         .connect           = ip4_datagram_conn !! 715         .connect =      ip4_datagram_connect,
835         .disconnect        = udp_disconnect,   !! 716         .disconnect =   udp_disconnect,
836         .ioctl             = raw_ioctl,        !! 717         .ioctl =        raw_ioctl,
837         .init              = raw_init,         !! 718         .init =         raw_init,
838         .setsockopt        = raw_setsockopt,   !! 719         .setsockopt =   raw_setsockopt,
839         .getsockopt        = raw_getsockopt,   !! 720         .getsockopt =   raw_getsockopt,
840         .sendmsg           = raw_sendmsg,      !! 721         .sendmsg =      raw_sendmsg,
841         .recvmsg           = raw_recvmsg,      !! 722         .recvmsg =      raw_recvmsg,
842         .bind              = raw_bind,         !! 723         .bind =         raw_bind,
843         .backlog_rcv       = raw_rcv_skb,      !! 724         .backlog_rcv =  raw_rcv_skb,
844         .hash              = raw_v4_hash,      !! 725         .hash =         raw_v4_hash,
845         .unhash            = raw_v4_unhash,    !! 726         .unhash =       raw_v4_unhash,
846         .obj_size          = sizeof(struct raw !! 727         .slab_obj_size = sizeof(struct raw_sock),
847 #ifdef CONFIG_COMPAT                           << 
848         .compat_setsockopt = compat_raw_setsoc << 
849         .compat_getsockopt = compat_raw_getsoc << 
850 #endif                                         << 
851         REF_PROTO_INUSE(raw)                   << 
852 };                                                728 };
853                                                   729 
854 #ifdef CONFIG_PROC_FS                             730 #ifdef CONFIG_PROC_FS
                                                   >> 731 struct raw_iter_state {
                                                   >> 732         int bucket;
                                                   >> 733 };
                                                   >> 734 
                                                   >> 735 #define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private)
                                                   >> 736 
855 static struct sock *raw_get_first(struct seq_f    737 static struct sock *raw_get_first(struct seq_file *seq)
856 {                                                 738 {
857         struct sock *sk;                          739         struct sock *sk;
858         struct raw_iter_state* state = raw_seq    740         struct raw_iter_state* state = raw_seq_private(seq);
859                                                   741 
860         for (state->bucket = 0; state->bucket  !! 742         for (state->bucket = 0; state->bucket < RAWV4_HTABLE_SIZE; ++state->bucket) {
861                         ++state->bucket) {     << 
862                 struct hlist_node *node;          743                 struct hlist_node *node;
863                                                   744 
864                 sk_for_each(sk, node, &state-> !! 745                 sk_for_each(sk, node, &raw_v4_htable[state->bucket])
865                         if (sk->sk_net == stat !! 746                         if (sk->sk_family == PF_INET)
866                                 goto found;       747                                 goto found;
867         }                                         748         }
868         sk = NULL;                                749         sk = NULL;
869 found:                                            750 found:
870         return sk;                                751         return sk;
871 }                                                 752 }
872                                                   753 
873 static struct sock *raw_get_next(struct seq_fi    754 static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
874 {                                                 755 {
875         struct raw_iter_state* state = raw_seq    756         struct raw_iter_state* state = raw_seq_private(seq);
876                                                   757 
877         do {                                      758         do {
878                 sk = sk_next(sk);                 759                 sk = sk_next(sk);
879 try_again:                                        760 try_again:
880                 ;                                 761                 ;
881         } while (sk && sk->sk_net != state->p. !! 762         } while (sk && sk->sk_family != PF_INET);
882                                                   763 
883         if (!sk && ++state->bucket < RAW_HTABL !! 764         if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
884                 sk = sk_head(&state->h->ht[sta !! 765                 sk = sk_head(&raw_v4_htable[state->bucket]);
885                 goto try_again;                   766                 goto try_again;
886         }                                         767         }
887         return sk;                                768         return sk;
888 }                                                 769 }
889                                                   770 
890 static struct sock *raw_get_idx(struct seq_fil    771 static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
891 {                                                 772 {
892         struct sock *sk = raw_get_first(seq);     773         struct sock *sk = raw_get_first(seq);
893                                                   774 
894         if (sk)                                   775         if (sk)
895                 while (pos && (sk = raw_get_ne    776                 while (pos && (sk = raw_get_next(seq, sk)) != NULL)
896                         --pos;                    777                         --pos;
897         return pos ? NULL : sk;                   778         return pos ? NULL : sk;
898 }                                                 779 }
899                                                   780 
900 void *raw_seq_start(struct seq_file *seq, loff !! 781 static void *raw_seq_start(struct seq_file *seq, loff_t *pos)
901 {                                                 782 {
902         struct raw_iter_state *state = raw_seq !! 783         read_lock(&raw_v4_lock);
903                                                << 
904         read_lock(&state->h->lock);            << 
905         return *pos ? raw_get_idx(seq, *pos -     784         return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
906 }                                                 785 }
907 EXPORT_SYMBOL_GPL(raw_seq_start);              << 
908                                                   786 
909 void *raw_seq_next(struct seq_file *seq, void  !! 787 static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
910 {                                                 788 {
911         struct sock *sk;                          789         struct sock *sk;
912                                                   790 
913         if (v == SEQ_START_TOKEN)                 791         if (v == SEQ_START_TOKEN)
914                 sk = raw_get_first(seq);          792                 sk = raw_get_first(seq);
915         else                                      793         else
916                 sk = raw_get_next(seq, v);        794                 sk = raw_get_next(seq, v);
917         ++*pos;                                   795         ++*pos;
918         return sk;                                796         return sk;
919 }                                                 797 }
920 EXPORT_SYMBOL_GPL(raw_seq_next);               << 
921                                                   798 
922 void raw_seq_stop(struct seq_file *seq, void * !! 799 static void raw_seq_stop(struct seq_file *seq, void *v)
923 {                                                 800 {
924         struct raw_iter_state *state = raw_seq !! 801         read_unlock(&raw_v4_lock);
925                                                << 
926         read_unlock(&state->h->lock);          << 
927 }                                                 802 }
928 EXPORT_SYMBOL_GPL(raw_seq_stop);               << 
929                                                   803 
930 static void raw_sock_seq_show(struct seq_file  !! 804 static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
931 {                                                 805 {
932         struct inet_sock *inet = inet_sk(sp);     806         struct inet_sock *inet = inet_sk(sp);
933         __be32 dest = inet->daddr,             !! 807         unsigned int dest = inet->daddr,
934                src = inet->rcv_saddr;          !! 808                      src = inet->rcv_saddr;
935         __u16 destp = 0,                          809         __u16 destp = 0,
936               srcp  = inet->num;                  810               srcp  = inet->num;
937                                                   811 
938         seq_printf(seq, "%4d: %08X:%04X %08X:% !! 812         sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
939                 " %02X %08X:%08X %02X:%08lX %0 !! 813                 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
940                 i, src, srcp, dest, destp, sp- !! 814                 i, src, srcp, dest, destp, sp->sk_state, 
941                 atomic_read(&sp->sk_wmem_alloc    815                 atomic_read(&sp->sk_wmem_alloc),
942                 atomic_read(&sp->sk_rmem_alloc    816                 atomic_read(&sp->sk_rmem_alloc),
943                 0, 0L, 0, sock_i_uid(sp), 0, s    817                 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
944                 atomic_read(&sp->sk_refcnt), s !! 818                 atomic_read(&sp->sk_refcnt), sp);
                                                   >> 819         return tmpbuf;
945 }                                                 820 }
946                                                   821 
947 static int raw_seq_show(struct seq_file *seq,     822 static int raw_seq_show(struct seq_file *seq, void *v)
948 {                                                 823 {
                                                   >> 824         char tmpbuf[129];
                                                   >> 825 
949         if (v == SEQ_START_TOKEN)                 826         if (v == SEQ_START_TOKEN)
950                 seq_printf(seq, "  sl  local_a !! 827                 seq_printf(seq, "%-127s\n",
951                                 "rx_queue tr t !! 828                                "  sl  local_address rem_address   st tx_queue "
952                                 "inode  drops\ !! 829                                "rx_queue tr tm->when retrnsmt   uid  timeout "
953         else                                   !! 830                                "inode");
954                 raw_sock_seq_show(seq, v, raw_ !! 831         else {
                                                   >> 832                 struct raw_iter_state *state = raw_seq_private(seq);
                                                   >> 833 
                                                   >> 834                 seq_printf(seq, "%-127s\n",
                                                   >> 835                            get_raw_sock(v, tmpbuf, state->bucket));
                                                   >> 836         }
955         return 0;                                 837         return 0;
956 }                                                 838 }
957                                                   839 
958 static const struct seq_operations raw_seq_ops !! 840 static struct seq_operations raw_seq_ops = {
959         .start = raw_seq_start,                   841         .start = raw_seq_start,
960         .next  = raw_seq_next,                    842         .next  = raw_seq_next,
961         .stop  = raw_seq_stop,                    843         .stop  = raw_seq_stop,
962         .show  = raw_seq_show,                    844         .show  = raw_seq_show,
963 };                                                845 };
964                                                   846 
965 int raw_seq_open(struct inode *ino, struct fil !! 847 static int raw_seq_open(struct inode *inode, struct file *file)
966                  struct raw_hashinfo *h, const << 
967 {                                                 848 {
968         int err;                               !! 849         struct seq_file *seq;
969         struct raw_iter_state *i;              !! 850         int rc = -ENOMEM;
970                                                !! 851         struct raw_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
971         err = seq_open_net(ino, file, ops, siz << 
972         if (err < 0)                           << 
973                 return err;                    << 
974                                                   852 
975         i = raw_seq_private((struct seq_file * !! 853         if (!s)
976         i->h = h;                              !! 854                 goto out;
977         return 0;                              !! 855         rc = seq_open(file, &raw_seq_ops);
978 }                                              !! 856         if (rc)
979 EXPORT_SYMBOL_GPL(raw_seq_open);               !! 857                 goto out_kfree;
980                                                   858 
981 static int raw_v4_seq_open(struct inode *inode !! 859         seq = file->private_data;
982 {                                              !! 860         seq->private = s;
983         return raw_seq_open(inode, file, &raw_ !! 861         memset(s, 0, sizeof(*s));
                                                   >> 862 out:
                                                   >> 863         return rc;
                                                   >> 864 out_kfree:
                                                   >> 865         kfree(s);
                                                   >> 866         goto out;
984 }                                                 867 }
985                                                   868 
986 static const struct file_operations raw_seq_fo !! 869 static struct file_operations raw_seq_fops = {
987         .owner   = THIS_MODULE,                   870         .owner   = THIS_MODULE,
988         .open    = raw_v4_seq_open,            !! 871         .open    = raw_seq_open,
989         .read    = seq_read,                      872         .read    = seq_read,
990         .llseek  = seq_lseek,                     873         .llseek  = seq_lseek,
991         .release = seq_release_net,            !! 874         .release = seq_release_private,
992 };                                                875 };
993                                                   876 
994 static __net_init int raw_init_net(struct net  !! 877 int __init raw_proc_init(void)
995 {                                                 878 {
996         if (!proc_net_fops_create(net, "raw",  !! 879         if (!proc_net_fops_create("raw", S_IRUGO, &raw_seq_fops))
997                 return -ENOMEM;                   880                 return -ENOMEM;
998                                                << 
999         return 0;                                 881         return 0;
1000 }                                                882 }
1001                                                  883 
1002 static __net_exit void raw_exit_net(struct ne << 
1003 {                                             << 
1004         proc_net_remove(net, "raw");          << 
1005 }                                             << 
1006                                               << 
1007 static __net_initdata struct pernet_operation << 
1008         .init = raw_init_net,                 << 
1009         .exit = raw_exit_net,                 << 
1010 };                                            << 
1011                                               << 
1012 int __init raw_proc_init(void)                << 
1013 {                                             << 
1014         return register_pernet_subsys(&raw_ne << 
1015 }                                             << 
1016                                               << 
1017 void __init raw_proc_exit(void)                  884 void __init raw_proc_exit(void)
1018 {                                                885 {
1019         unregister_pernet_subsys(&raw_net_ops !! 886         proc_net_remove("raw");
1020 }                                                887 }
1021 #endif /* CONFIG_PROC_FS */                      888 #endif /* CONFIG_PROC_FS */
1022                                                  889 
  This page was automatically generated by the LXR engine.