OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [ipv4/] [udp.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 *              The User Datagram Protocol (UDP).
7
 *
8
 * Version:     $Id: udp.c,v 1.1.1.1 2004-04-15 01:13:35 phoenix Exp $
9
 *
10
 * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
11
 *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12
 *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
13
 *              Alan Cox, <Alan.Cox@linux.org>
14
 *
15
 * Fixes:
16
 *              Alan Cox        :       verify_area() calls
17
 *              Alan Cox        :       stopped close while in use off icmp
18
 *                                      messages. Not a fix but a botch that
19
 *                                      for udp at least is 'valid'.
20
 *              Alan Cox        :       Fixed icmp handling properly
21
 *              Alan Cox        :       Correct error for oversized datagrams
22
 *              Alan Cox        :       Tidied select() semantics.
23
 *              Alan Cox        :       udp_err() fixed properly, also now
24
 *                                      select and read wake correctly on errors
25
 *              Alan Cox        :       udp_send verify_area moved to avoid mem leak
26
 *              Alan Cox        :       UDP can count its memory
27
 *              Alan Cox        :       send to an unknown connection causes
28
 *                                      an ECONNREFUSED off the icmp, but
29
 *                                      does NOT close.
30
 *              Alan Cox        :       Switched to new sk_buff handlers. No more backlog!
31
 *              Alan Cox        :       Using generic datagram code. Even smaller and the PEEK
32
 *                                      bug no longer crashes it.
33
 *              Fred Van Kempen :       Net2e support for sk->broadcast.
34
 *              Alan Cox        :       Uses skb_free_datagram
35
 *              Alan Cox        :       Added get/set sockopt support.
36
 *              Alan Cox        :       Broadcasting without option set returns EACCES.
37
 *              Alan Cox        :       No wakeup calls. Instead we now use the callbacks.
38
 *              Alan Cox        :       Use ip_tos and ip_ttl
39
 *              Alan Cox        :       SNMP Mibs
40
 *              Alan Cox        :       MSG_DONTROUTE, and 0.0.0.0 support.
41
 *              Matt Dillon     :       UDP length checks.
42
 *              Alan Cox        :       Smarter af_inet used properly.
43
 *              Alan Cox        :       Use new kernel side addressing.
44
 *              Alan Cox        :       Incorrect return on truncated datagram receive.
45
 *      Arnt Gulbrandsen        :       New udp_send and stuff
46
 *              Alan Cox        :       Cache last socket
47
 *              Alan Cox        :       Route cache
48
 *              Jon Peatfield   :       Minor efficiency fix to sendto().
49
 *              Mike Shaver     :       RFC1122 checks.
50
 *              Alan Cox        :       Nonblocking error fix.
51
 *      Willy Konynenberg       :       Transparent proxying support.
52
 *              Mike McLagan    :       Routing by source
53
 *              David S. Miller :       New socket lookup architecture.
54
 *                                      Last socket cache retained as it
55
 *                                      does have a high hit rate.
56
 *              Olaf Kirch      :       Don't linearise iovec on sendmsg.
57
 *              Andi Kleen      :       Some cleanups, cache destination entry
58
 *                                      for connect.
59
 *      Vitaly E. Lavrov        :       Transparent proxy revived after year coma.
60
 *              Melvin Smith    :       Check msg_name not msg_namelen in sendto(),
61
 *                                      return ENOTCONN for unconnected sockets (POSIX)
62
 *              Janos Farkas    :       don't deliver multi/broadcasts to a different
63
 *                                      bound-to-device socket
64
 *      YOSHIFUJI Hideaki @USAGI and:   Support IPV6_V6ONLY socket option, which
65
 *      Alexey Kuznetsov:               allow both IPv4 and IPv6 sockets to bind
66
 *                                      a single port at the same time.
67
 *
68
 *
69
 *              This program is free software; you can redistribute it and/or
70
 *              modify it under the terms of the GNU General Public License
71
 *              as published by the Free Software Foundation; either version
72
 *              2 of the License, or (at your option) any later version.
73
 */
74
 
75
#include <asm/system.h>
76
#include <asm/uaccess.h>
77
#include <asm/ioctls.h>
78
#include <linux/types.h>
79
#include <linux/fcntl.h>
80
#include <linux/socket.h>
81
#include <linux/sockios.h>
82
#include <linux/in.h>
83
#include <linux/errno.h>
84
#include <linux/timer.h>
85
#include <linux/mm.h>
86
#include <linux/config.h>
87
#include <linux/inet.h>
88
#include <linux/netdevice.h>
89
#include <net/snmp.h>
90
#include <net/ip.h>
91
#include <net/ipv6.h>
92
#include <net/protocol.h>
93
#include <linux/skbuff.h>
94
#include <net/sock.h>
95
#include <net/udp.h>
96
#include <net/icmp.h>
97
#include <net/route.h>
98
#include <net/inet_common.h>
99
#include <net/checksum.h>
100
 
101
/*
102
 *      Snmp MIB for the UDP layer
103
 */
104
 
105
struct udp_mib          udp_statistics[NR_CPUS*2];
106
 
107
struct sock *udp_hash[UDP_HTABLE_SIZE];
108
rwlock_t udp_hash_lock = RW_LOCK_UNLOCKED;
109
 
110
/* Shared by v4/v6 udp. */
111
int udp_port_rover;
112
 
113
static int udp_v4_get_port(struct sock *sk, unsigned short snum)
114
{
115
        write_lock_bh(&udp_hash_lock);
116
        if (snum == 0) {
117
                int best_size_so_far, best, result, i;
118
 
119
                if (udp_port_rover > sysctl_local_port_range[1] ||
120
                    udp_port_rover < sysctl_local_port_range[0])
121
                        udp_port_rover = sysctl_local_port_range[0];
122
                best_size_so_far = 32767;
123
                best = result = udp_port_rover;
124
                for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
125
                        struct sock *sk;
126
                        int size;
127
 
128
                        sk = udp_hash[result & (UDP_HTABLE_SIZE - 1)];
129
                        if (!sk) {
130
                                if (result > sysctl_local_port_range[1])
131
                                        result = sysctl_local_port_range[0] +
132
                                                ((result - sysctl_local_port_range[0]) &
133
                                                 (UDP_HTABLE_SIZE - 1));
134
                                goto gotit;
135
                        }
136
                        size = 0;
137
                        do {
138
                                if (++size >= best_size_so_far)
139
                                        goto next;
140
                        } while ((sk = sk->next) != NULL);
141
                        best_size_so_far = size;
142
                        best = result;
143
                next:;
144
                }
145
                result = best;
146
                for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) {
147
                        if (result > sysctl_local_port_range[1])
148
                                result = sysctl_local_port_range[0]
149
                                        + ((result - sysctl_local_port_range[0]) &
150
                                           (UDP_HTABLE_SIZE - 1));
151
                        if (!udp_lport_inuse(result))
152
                                break;
153
                }
154
                if (i >= (1 << 16) / UDP_HTABLE_SIZE)
155
                        goto fail;
156
gotit:
157
                udp_port_rover = snum = result;
158
        } else {
159
                struct sock *sk2;
160
 
161
                for (sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
162
                     sk2 != NULL;
163
                     sk2 = sk2->next) {
164
                        if (sk2->num == snum &&
165
                            sk2 != sk &&
166
                            !ipv6_only_sock(sk2) &&
167
                            (!sk2->bound_dev_if ||
168
                             !sk->bound_dev_if ||
169
                             sk2->bound_dev_if == sk->bound_dev_if) &&
170
                            (!sk2->rcv_saddr ||
171
                             !sk->rcv_saddr ||
172
                             sk2->rcv_saddr == sk->rcv_saddr) &&
173
                            (!sk2->reuse || !sk->reuse))
174
                                goto fail;
175
                }
176
        }
177
        sk->num = snum;
178
        if (sk->pprev == NULL) {
179
                struct sock **skp = &udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
180
                if ((sk->next = *skp) != NULL)
181
                        (*skp)->pprev = &sk->next;
182
                *skp = sk;
183
                sk->pprev = skp;
184
                sock_prot_inc_use(sk->prot);
185
                sock_hold(sk);
186
        }
187
        write_unlock_bh(&udp_hash_lock);
188
        return 0;
189
 
190
fail:
191
        write_unlock_bh(&udp_hash_lock);
192
        return 1;
193
}
194
 
195
static void udp_v4_hash(struct sock *sk)
196
{
197
        BUG();
198
}
199
 
200
static void udp_v4_unhash(struct sock *sk)
201
{
202
        write_lock_bh(&udp_hash_lock);
203
        if (sk->pprev) {
204
                if (sk->next)
205
                        sk->next->pprev = sk->pprev;
206
                *sk->pprev = sk->next;
207
                sk->pprev = NULL;
208
                sk->num = 0;
209
                sock_prot_dec_use(sk->prot);
210
                __sock_put(sk);
211
        }
212
        write_unlock_bh(&udp_hash_lock);
213
}
214
 
215
/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
216
 * harder than this. -DaveM
217
 */
218
struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
219
{
220
        struct sock *sk, *result = NULL;
221
        unsigned short hnum = ntohs(dport);
222
        int badness = -1;
223
 
224
        for(sk = udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]; sk != NULL; sk = sk->next) {
225
                if(sk->num == hnum && !ipv6_only_sock(sk)) {
226
                        int score;
227
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
228
                        score = sk->family == PF_INET ? 1 : 0;
229
#else
230
                        score = 1;
231
#endif
232
                        if(sk->rcv_saddr) {
233
                                if(sk->rcv_saddr != daddr)
234
                                        continue;
235
                                score+=2;
236
                        }
237
                        if(sk->daddr) {
238
                                if(sk->daddr != saddr)
239
                                        continue;
240
                                score+=2;
241
                        }
242
                        if(sk->dport) {
243
                                if(sk->dport != sport)
244
                                        continue;
245
                                score+=2;
246
                        }
247
                        if(sk->bound_dev_if) {
248
                                if(sk->bound_dev_if != dif)
249
                                        continue;
250
                                score+=2;
251
                        }
252
                        if(score == 9) {
253
                                result = sk;
254
                                break;
255
                        } else if(score > badness) {
256
                                result = sk;
257
                                badness = score;
258
                        }
259
                }
260
        }
261
        return result;
262
}
263
 
264
__inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
265
{
266
        struct sock *sk;
267
 
268
        read_lock(&udp_hash_lock);
269
        sk = udp_v4_lookup_longway(saddr, sport, daddr, dport, dif);
270
        if (sk)
271
                sock_hold(sk);
272
        read_unlock(&udp_hash_lock);
273
        return sk;
274
}
275
 
276
extern int ip_mc_sf_allow(struct sock *sk, u32 local, u32 rmt, int dif);
277
 
278
static inline struct sock *udp_v4_mcast_next(struct sock *sk,
279
                                             u16 loc_port, u32 loc_addr,
280
                                             u16 rmt_port, u32 rmt_addr,
281
                                             int dif)
282
{
283
        struct sock *s = sk;
284
        unsigned short hnum = ntohs(loc_port);
285
        for(; s; s = s->next) {
286
                if ((s->num != hnum)                                    ||
287
                    (s->daddr && s->daddr!=rmt_addr)                    ||
288
                    (s->dport != rmt_port && s->dport != 0)                      ||
289
                    (s->rcv_saddr  && s->rcv_saddr != loc_addr)         ||
290
                    ipv6_only_sock(s)                                   ||
291
                    (s->bound_dev_if && s->bound_dev_if != dif))
292
                        continue;
293
                if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif))
294
                        continue;
295
                break;
296
        }
297
        return s;
298
}
299
 
300
/*
301
 * This routine is called by the ICMP module when it gets some
302
 * sort of error condition.  If err < 0 then the socket should
303
 * be closed and the error returned to the user.  If err > 0
304
 * it's just the icmp type << 8 | icmp code.
305
 * Header points to the ip header of the error packet. We move
306
 * on past this. Then (as it used to claim before adjustment)
307
 * header points to the first 8 bytes of the udp header.  We need
308
 * to find the appropriate port.
309
 */
310
 
311
void udp_err(struct sk_buff *skb, u32 info)
312
{
313
        struct iphdr *iph = (struct iphdr*)skb->data;
314
        struct udphdr *uh = (struct udphdr*)(skb->data+(iph->ihl<<2));
315
        int type = skb->h.icmph->type;
316
        int code = skb->h.icmph->code;
317
        struct sock *sk;
318
        int harderr;
319
        int err;
320
 
321
        sk = udp_v4_lookup(iph->daddr, uh->dest, iph->saddr, uh->source, skb->dev->ifindex);
322
        if (sk == NULL) {
323
                ICMP_INC_STATS_BH(IcmpInErrors);
324
                return; /* No socket for error */
325
        }
326
 
327
        err = 0;
328
        harderr = 0;
329
 
330
        switch (type) {
331
        default:
332
        case ICMP_TIME_EXCEEDED:
333
                err = EHOSTUNREACH;
334
                break;
335
        case ICMP_SOURCE_QUENCH:
336
                goto out;
337
        case ICMP_PARAMETERPROB:
338
                err = EPROTO;
339
                harderr = 1;
340
                break;
341
        case ICMP_DEST_UNREACH:
342
                if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
343
                        if (sk->protinfo.af_inet.pmtudisc != IP_PMTUDISC_DONT) {
344
                                err = EMSGSIZE;
345
                                harderr = 1;
346
                                break;
347
                        }
348
                        goto out;
349
                }
350
                err = EHOSTUNREACH;
351
                if (code <= NR_ICMP_UNREACH) {
352
                        harderr = icmp_err_convert[code].fatal;
353
                        err = icmp_err_convert[code].errno;
354
                }
355
                break;
356
        }
357
 
358
        /*
359
         *      RFC1122: OK.  Passes ICMP errors back to application, as per
360
         *      4.1.3.3.
361
         */
362
        if (!sk->protinfo.af_inet.recverr) {
363
                if (!harderr || sk->state != TCP_ESTABLISHED)
364
                        goto out;
365
        } else {
366
                ip_icmp_error(sk, skb, err, uh->dest, info, (u8*)(uh+1));
367
        }
368
        sk->err = err;
369
        sk->error_report(sk);
370
out:
371
        sock_put(sk);
372
}
373
 
374
 
375
static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr, unsigned long base)
376
{
377
        return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base));
378
}
379
 
380
struct udpfakehdr
381
{
382
        struct udphdr uh;
383
        u32 saddr;
384
        u32 daddr;
385
        struct iovec *iov;
386
        u32 wcheck;
387
};
388
 
389
/*
390
 *      Copy and checksum a UDP packet from user space into a buffer.
391
 */
392
 
393
static int udp_getfrag(const void *p, char * to, unsigned int offset, unsigned int fraglen)
394
{
395
        struct udpfakehdr *ufh = (struct udpfakehdr *)p;
396
        if (offset==0) {
397
                if (csum_partial_copy_fromiovecend(to+sizeof(struct udphdr), ufh->iov, offset,
398
                                                   fraglen-sizeof(struct udphdr), &ufh->wcheck))
399
                        return -EFAULT;
400
                ufh->wcheck = csum_partial((char *)ufh, sizeof(struct udphdr),
401
                                           ufh->wcheck);
402
                ufh->uh.check = csum_tcpudp_magic(ufh->saddr, ufh->daddr,
403
                                          ntohs(ufh->uh.len),
404
                                          IPPROTO_UDP, ufh->wcheck);
405
                if (ufh->uh.check == 0)
406
                        ufh->uh.check = -1;
407
                memcpy(to, ufh, sizeof(struct udphdr));
408
                return 0;
409
        }
410
        if (csum_partial_copy_fromiovecend(to, ufh->iov, offset-sizeof(struct udphdr),
411
                                           fraglen, &ufh->wcheck))
412
                return -EFAULT;
413
        return 0;
414
}
415
 
416
/*
417
 *      Copy a UDP packet from user space into a buffer without checksumming.
418
 */
419
 
420
static int udp_getfrag_nosum(const void *p, char * to, unsigned int offset, unsigned int fraglen)
421
{
422
        struct udpfakehdr *ufh = (struct udpfakehdr *)p;
423
 
424
        if (offset==0) {
425
                memcpy(to, ufh, sizeof(struct udphdr));
426
                return memcpy_fromiovecend(to+sizeof(struct udphdr), ufh->iov, offset,
427
                                           fraglen-sizeof(struct udphdr));
428
        }
429
        return memcpy_fromiovecend(to, ufh->iov, offset-sizeof(struct udphdr),
430
                                   fraglen);
431
}
432
 
433
int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len)
434
{
435
        int ulen = len + sizeof(struct udphdr);
436
        struct ipcm_cookie ipc;
437
        struct udpfakehdr ufh;
438
        struct rtable *rt = NULL;
439
        int free = 0;
440
        int connected = 0;
441
        u32 daddr;
442
        u8  tos;
443
        int err;
444
 
445
        /* This check is ONLY to check for arithmetic overflow
446
           on integer(!) len. Not more! Real check will be made
447
           in ip_build_xmit --ANK
448
 
449
           BTW socket.c -> af_*.c -> ... make multiple
450
           invalid conversions size_t -> int. We MUST repair it f.e.
451
           by replacing all of them with size_t and revise all
452
           the places sort of len += sizeof(struct iphdr)
453
           If len was ULONG_MAX-10 it would be cathastrophe  --ANK
454
         */
455
 
456
        if (len < 0 || len > 0xFFFF)
457
                return -EMSGSIZE;
458
 
459
        /*
460
         *      Check the flags.
461
         */
462
 
463
        if (msg->msg_flags&MSG_OOB)     /* Mirror BSD error message compatibility */
464
                return -EOPNOTSUPP;
465
 
466
        /*
467
         *      Get and verify the address.
468
         */
469
 
470
        if (msg->msg_name) {
471
                struct sockaddr_in * usin = (struct sockaddr_in*)msg->msg_name;
472
                if (msg->msg_namelen < sizeof(*usin))
473
                        return -EINVAL;
474
                if (usin->sin_family != AF_INET) {
475
                        if (usin->sin_family != AF_UNSPEC)
476
                                return -EINVAL;
477
                }
478
 
479
                ufh.daddr = usin->sin_addr.s_addr;
480
                ufh.uh.dest = usin->sin_port;
481
                if (ufh.uh.dest == 0)
482
                        return -EINVAL;
483
        } else {
484
                if (sk->state != TCP_ESTABLISHED)
485
                        return -EDESTADDRREQ;
486
                ufh.daddr = sk->daddr;
487
                ufh.uh.dest = sk->dport;
488
                /* Open fast path for connected socket.
489
                   Route will not be used, if at least one option is set.
490
                 */
491
                connected = 1;
492
        }
493
        ipc.addr = sk->saddr;
494
        ufh.uh.source = sk->sport;
495
 
496
        ipc.opt = NULL;
497
        ipc.oif = sk->bound_dev_if;
498
        if (msg->msg_controllen) {
499
                err = ip_cmsg_send(msg, &ipc);
500
                if (err)
501
                        return err;
502
                if (ipc.opt)
503
                        free = 1;
504
                connected = 0;
505
        }
506
        if (!ipc.opt)
507
                ipc.opt = sk->protinfo.af_inet.opt;
508
 
509
        ufh.saddr = ipc.addr;
510
        ipc.addr = daddr = ufh.daddr;
511
 
512
        if (ipc.opt && ipc.opt->srr) {
513
                if (!daddr)
514
                        return -EINVAL;
515
                daddr = ipc.opt->faddr;
516
                connected = 0;
517
        }
518
        tos = RT_TOS(sk->protinfo.af_inet.tos);
519
        if (sk->localroute || (msg->msg_flags&MSG_DONTROUTE) ||
520
            (ipc.opt && ipc.opt->is_strictroute)) {
521
                tos |= RTO_ONLINK;
522
                connected = 0;
523
        }
524
 
525
        if (MULTICAST(daddr)) {
526
                if (!ipc.oif)
527
                        ipc.oif = sk->protinfo.af_inet.mc_index;
528
                if (!ufh.saddr)
529
                        ufh.saddr = sk->protinfo.af_inet.mc_addr;
530
                connected = 0;
531
        }
532
 
533
        if (connected)
534
                rt = (struct rtable*)sk_dst_check(sk, 0);
535
 
536
        if (rt == NULL) {
537
                err = ip_route_output(&rt, daddr, ufh.saddr, tos, ipc.oif);
538
                if (err)
539
                        goto out;
540
 
541
                err = -EACCES;
542
                if (rt->rt_flags&RTCF_BROADCAST && !sk->broadcast)
543
                        goto out;
544
                if (connected)
545
                        sk_dst_set(sk, dst_clone(&rt->u.dst));
546
        }
547
 
548
        if (msg->msg_flags&MSG_CONFIRM)
549
                goto do_confirm;
550
back_from_confirm:
551
 
552
        ufh.saddr = rt->rt_src;
553
        if (!ipc.addr)
554
                ufh.daddr = ipc.addr = rt->rt_dst;
555
        ufh.uh.len = htons(ulen);
556
        ufh.uh.check = 0;
557
        ufh.iov = msg->msg_iov;
558
        ufh.wcheck = 0;
559
 
560
        /* RFC1122: OK.  Provides the checksumming facility (MUST) as per */
561
        /* 4.1.3.4. It's configurable by the application via setsockopt() */
562
        /* (MAY) and it defaults to on (MUST). */
563
 
564
        err = ip_build_xmit(sk,
565
                            (sk->no_check == UDP_CSUM_NOXMIT ?
566
                             udp_getfrag_nosum :
567
                             udp_getfrag),
568
                            &ufh, ulen, &ipc, rt, msg->msg_flags);
569
 
570
out:
571
        ip_rt_put(rt);
572
        if (free)
573
                kfree(ipc.opt);
574
        if (!err) {
575
                UDP_INC_STATS_USER(UdpOutDatagrams);
576
                return len;
577
        }
578
        return err;
579
 
580
do_confirm:
581
        dst_confirm(&rt->u.dst);
582
        if (!(msg->msg_flags&MSG_PROBE) || len)
583
                goto back_from_confirm;
584
        err = 0;
585
        goto out;
586
}
587
 
588
/*
589
 *      IOCTL requests applicable to the UDP protocol
590
 */
591
 
592
int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
593
{
594
        switch(cmd)
595
        {
596
                case SIOCOUTQ:
597
                {
598
                        int amount = atomic_read(&sk->wmem_alloc);
599
                        return put_user(amount, (int *)arg);
600
                }
601
 
602
                case SIOCINQ:
603
                {
604
                        struct sk_buff *skb;
605
                        unsigned long amount;
606
 
607
                        amount = 0;
608
                        spin_lock_irq(&sk->receive_queue.lock);
609
                        skb = skb_peek(&sk->receive_queue);
610
                        if (skb != NULL) {
611
                                /*
612
                                 * We will only return the amount
613
                                 * of this packet since that is all
614
                                 * that will be read.
615
                                 */
616
                                amount = skb->len - sizeof(struct udphdr);
617
                        }
618
                        spin_unlock_irq(&sk->receive_queue.lock);
619
                        return put_user(amount, (int *)arg);
620
                }
621
 
622
                default:
623
                        return -ENOIOCTLCMD;
624
        }
625
        return(0);
626
}
627
 
628
static __inline__ int __udp_checksum_complete(struct sk_buff *skb)
629
{
630
        return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
631
}
632
 
633
static __inline__ int udp_checksum_complete(struct sk_buff *skb)
634
{
635
        return skb->ip_summed != CHECKSUM_UNNECESSARY &&
636
                __udp_checksum_complete(skb);
637
}
638
 
639
/*
640
 *      This should be easy, if there is something there we
641
 *      return it, otherwise we block.
642
 */
643
 
644
int udp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
645
                int noblock, int flags, int *addr_len)
646
{
647
        struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
648
        struct sk_buff *skb;
649
        int copied, err;
650
 
651
        /*
652
         *      Check any passed addresses
653
         */
654
        if (addr_len)
655
                *addr_len=sizeof(*sin);
656
 
657
        if (flags & MSG_ERRQUEUE)
658
                return ip_recv_error(sk, msg, len);
659
 
660
try_again:
661
        skb = skb_recv_datagram(sk, flags, noblock, &err);
662
        if (!skb)
663
                goto out;
664
 
665
        copied = skb->len - sizeof(struct udphdr);
666
        if (copied > len) {
667
                copied = len;
668
                msg->msg_flags |= MSG_TRUNC;
669
        }
670
 
671
        if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
672
                err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
673
                                              copied);
674
        } else if (msg->msg_flags&MSG_TRUNC) {
675
                if (__udp_checksum_complete(skb))
676
                        goto csum_copy_err;
677
                err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
678
                                              copied);
679
        } else {
680
                err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
681
 
682
                if (err == -EINVAL)
683
                        goto csum_copy_err;
684
        }
685
 
686
        if (err)
687
                goto out_free;
688
 
689
        sock_recv_timestamp(msg, sk, skb);
690
 
691
        /* Copy the address. */
692
        if (sin)
693
        {
694
                sin->sin_family = AF_INET;
695
                sin->sin_port = skb->h.uh->source;
696
                sin->sin_addr.s_addr = skb->nh.iph->saddr;
697
                memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
698
        }
699
        if (sk->protinfo.af_inet.cmsg_flags)
700
                ip_cmsg_recv(msg, skb);
701
        err = copied;
702
 
703
out_free:
704
        skb_free_datagram(sk, skb);
705
out:
706
        return err;
707
 
708
csum_copy_err:
709
        UDP_INC_STATS_BH(UdpInErrors);
710
 
711
        /* Clear queue. */
712
        if (flags&MSG_PEEK) {
713
                int clear = 0;
714
                spin_lock_irq(&sk->receive_queue.lock);
715
                if (skb == skb_peek(&sk->receive_queue)) {
716
                        __skb_unlink(skb, &sk->receive_queue);
717
                        clear = 1;
718
                }
719
                spin_unlock_irq(&sk->receive_queue.lock);
720
                if (clear)
721
                        kfree_skb(skb);
722
        }
723
 
724
        skb_free_datagram(sk, skb);
725
 
726
        if (noblock)
727
                return -EAGAIN;
728
        goto try_again;
729
}
730
 
731
int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
732
{
733
        struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
734
        struct rtable *rt;
735
        u32 saddr;
736
        int oif;
737
        int err;
738
 
739
 
740
        if (addr_len < sizeof(*usin))
741
                return -EINVAL;
742
 
743
        if (usin->sin_family != AF_INET)
744
                return -EAFNOSUPPORT;
745
 
746
        sk_dst_reset(sk);
747
 
748
        oif = sk->bound_dev_if;
749
        saddr = sk->saddr;
750
        if (MULTICAST(usin->sin_addr.s_addr)) {
751
                if (!oif)
752
                        oif = sk->protinfo.af_inet.mc_index;
753
                if (!saddr)
754
                        saddr = sk->protinfo.af_inet.mc_addr;
755
        }
756
        err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr,
757
                               RT_CONN_FLAGS(sk), oif);
758
        if (err)
759
                return err;
760
        if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) {
761
                ip_rt_put(rt);
762
                return -EACCES;
763
        }
764
        if(!sk->saddr)
765
                sk->saddr = rt->rt_src;         /* Update source address */
766
        if(!sk->rcv_saddr)
767
                sk->rcv_saddr = rt->rt_src;
768
        sk->daddr = rt->rt_dst;
769
        sk->dport = usin->sin_port;
770
        sk->state = TCP_ESTABLISHED;
771
        sk->protinfo.af_inet.id = jiffies;
772
 
773
        sk_dst_set(sk, &rt->u.dst);
774
        return(0);
775
}
776
 
777
int udp_disconnect(struct sock *sk, int flags)
778
{
779
        /*
780
         *      1003.1g - break association.
781
         */
782
 
783
        sk->state = TCP_CLOSE;
784
        sk->daddr = 0;
785
        sk->dport = 0;
786
        sk->bound_dev_if = 0;
787
        if (!(sk->userlocks&SOCK_BINDADDR_LOCK)) {
788
                sk->rcv_saddr = 0;
789
                sk->saddr = 0;
790
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
791
                memset(&sk->net_pinfo.af_inet6.saddr, 0, 16);
792
                memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, 16);
793
#endif
794
        }
795
        if (!(sk->userlocks&SOCK_BINDPORT_LOCK)) {
796
                sk->prot->unhash(sk);
797
                sk->sport = 0;
798
        }
799
        sk_dst_reset(sk);
800
        return 0;
801
}
802
 
803
static void udp_close(struct sock *sk, long timeout)
804
{
805
        inet_sock_release(sk);
806
}
807
 
808
static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
809
{
810
        /*
811
         *      Charge it to the socket, dropping if the queue is full.
812
         */
813
 
814
#if defined(CONFIG_FILTER)
815
        if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
816
                if (__udp_checksum_complete(skb)) {
817
                        UDP_INC_STATS_BH(UdpInErrors);
818
                        IP_INC_STATS_BH(IpInDiscards);
819
                        ip_statistics[smp_processor_id()*2].IpInDelivers--;
820
                        kfree_skb(skb);
821
                        return -1;
822
                }
823
                skb->ip_summed = CHECKSUM_UNNECESSARY;
824
        }
825
#endif
826
 
827
        if (sock_queue_rcv_skb(sk,skb)<0) {
828
                UDP_INC_STATS_BH(UdpInErrors);
829
                IP_INC_STATS_BH(IpInDiscards);
830
                ip_statistics[smp_processor_id()*2].IpInDelivers--;
831
                kfree_skb(skb);
832
                return -1;
833
        }
834
        UDP_INC_STATS_BH(UdpInDatagrams);
835
        return 0;
836
}
837
 
838
/*
839
 *      Multicasts and broadcasts go to each listener.
840
 *
841
 *      Note: called only from the BH handler context,
842
 *      so we don't need to lock the hashes.
843
 */
844
static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
845
                                 u32 saddr, u32 daddr)
846
{
847
        struct sock *sk;
848
        int dif;
849
 
850
        read_lock(&udp_hash_lock);
851
        sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)];
852
        dif = skb->dev->ifindex;
853
        sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
854
        if (sk) {
855
                struct sock *sknext = NULL;
856
 
857
                do {
858
                        struct sk_buff *skb1 = skb;
859
 
860
                        sknext = udp_v4_mcast_next(sk->next, uh->dest, daddr,
861
                                                   uh->source, saddr, dif);
862
                        if(sknext)
863
                                skb1 = skb_clone(skb, GFP_ATOMIC);
864
 
865
                        if(skb1)
866
                                udp_queue_rcv_skb(sk, skb1);
867
                        sk = sknext;
868
                } while(sknext);
869
        } else
870
                kfree_skb(skb);
871
        read_unlock(&udp_hash_lock);
872
        return 0;
873
}
874
 
875
/* Initialize UDP checksum. If exited with zero value (success),
876
 * CHECKSUM_UNNECESSARY means, that no more checks are required.
877
 * Otherwise, csum completion requires chacksumming packet body,
878
 * including udp header and folding it to skb->csum.
879
 */
880
static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
881
                             unsigned short ulen, u32 saddr, u32 daddr)
882
{
883
        if (uh->check == 0) {
884
                skb->ip_summed = CHECKSUM_UNNECESSARY;
885
        } else if (skb->ip_summed == CHECKSUM_HW) {
886
                skb->ip_summed = CHECKSUM_UNNECESSARY;
887
                if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
888
                        return 0;
889
                NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v4 hw csum failure.\n"));
890
                skb->ip_summed = CHECKSUM_NONE;
891
        }
892
        if (skb->ip_summed != CHECKSUM_UNNECESSARY)
893
                skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
894
        /* Probably, we should checksum udp header (it should be in cache
895
         * in any case) and data in tiny packets (< rx copybreak).
896
         */
897
        return 0;
898
}
899
 
900
/*
901
 *      All we need to do is get the socket, and then do a checksum.
902
 */
903
 
904
int udp_rcv(struct sk_buff *skb)
905
{
906
        struct sock *sk;
907
        struct udphdr *uh;
908
        unsigned short ulen;
909
        struct rtable *rt = (struct rtable*)skb->dst;
910
        u32 saddr = skb->nh.iph->saddr;
911
        u32 daddr = skb->nh.iph->daddr;
912
        int len = skb->len;
913
 
914
        IP_INC_STATS_BH(IpInDelivers);
915
 
916
        /*
917
         *      Validate the packet and the UDP length.
918
         */
919
        if (!pskb_may_pull(skb, sizeof(struct udphdr)))
920
                goto no_header;
921
 
922
        uh = skb->h.uh;
923
 
924
        ulen = ntohs(uh->len);
925
 
926
        if (ulen > len || ulen < sizeof(*uh))
927
                goto short_packet;
928
 
929
        if (pskb_trim(skb, ulen))
930
                goto short_packet;
931
 
932
        if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
933
                goto csum_error;
934
 
935
        if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
936
                return udp_v4_mcast_deliver(skb, uh, saddr, daddr);
937
 
938
        sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex);
939
 
940
        if (sk != NULL) {
941
                udp_queue_rcv_skb(sk, skb);
942
                sock_put(sk);
943
                return 0;
944
        }
945
 
946
        /* No socket. Drop packet silently, if checksum is wrong */
947
        if (udp_checksum_complete(skb))
948
                goto csum_error;
949
 
950
        UDP_INC_STATS_BH(UdpNoPorts);
951
        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
952
 
953
        /*
954
         * Hmm.  We got an UDP packet to a port to which we
955
         * don't wanna listen.  Ignore it.
956
         */
957
        kfree_skb(skb);
958
        return(0);
959
 
960
short_packet:
961
        NETDEBUG(if (net_ratelimit())
962
                 printk(KERN_DEBUG "UDP: short packet: %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",
963
                        NIPQUAD(saddr),
964
                        ntohs(uh->source),
965
                        ulen,
966
                        len,
967
                        NIPQUAD(daddr),
968
                        ntohs(uh->dest)));
969
no_header:
970
        UDP_INC_STATS_BH(UdpInErrors);
971
        kfree_skb(skb);
972
        return(0);
973
 
974
csum_error:
975
        /*
976
         * RFC1122: OK.  Discards the bad packet silently (as far as
977
         * the network is concerned, anyway) as per 4.1.3.4 (MUST).
978
         */
979
        NETDEBUG(if (net_ratelimit())
980
                 printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
981
                        NIPQUAD(saddr),
982
                        ntohs(uh->source),
983
                        NIPQUAD(daddr),
984
                        ntohs(uh->dest),
985
                        ulen));
986
        UDP_INC_STATS_BH(UdpInErrors);
987
        kfree_skb(skb);
988
        return(0);
989
}
990
 
991
static void get_udp_sock(struct sock *sp, char *tmpbuf, int i)
992
{
993
        unsigned int dest, src;
994
        __u16 destp, srcp;
995
 
996
        dest  = sp->daddr;
997
        src   = sp->rcv_saddr;
998
        destp = ntohs(sp->dport);
999
        srcp  = ntohs(sp->sport);
1000
        sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
1001
                " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
1002
                i, src, srcp, dest, destp, sp->state,
1003
                atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
1004
                0, 0L, 0,
1005
                sock_i_uid(sp), 0,
1006
                sock_i_ino(sp),
1007
                atomic_read(&sp->refcnt), sp);
1008
}
1009
 
1010
int udp_get_info(char *buffer, char **start, off_t offset, int length)
1011
{
1012
        int len = 0, num = 0, i;
1013
        off_t pos = 0;
1014
        off_t begin;
1015
        char tmpbuf[129];
1016
 
1017
        if (offset < 128)
1018
                len += sprintf(buffer, "%-127s\n",
1019
                               "  sl  local_address rem_address   st tx_queue "
1020
                               "rx_queue tr tm->when retrnsmt   uid  timeout inode");
1021
        pos = 128;
1022
        read_lock(&udp_hash_lock);
1023
        for (i = 0; i < UDP_HTABLE_SIZE; i++) {
1024
                struct sock *sk;
1025
 
1026
                for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
1027
                        if (sk->family != PF_INET)
1028
                                continue;
1029
                        pos += 128;
1030
                        if (pos <= offset)
1031
                                continue;
1032
                        get_udp_sock(sk, tmpbuf, i);
1033
                        len += sprintf(buffer+len, "%-127s\n", tmpbuf);
1034
                        if(len >= length)
1035
                                goto out;
1036
                }
1037
        }
1038
out:
1039
        read_unlock(&udp_hash_lock);
1040
        begin = len - (pos - offset);
1041
        *start = buffer + begin;
1042
        len -= begin;
1043
        if(len > length)
1044
                len = length;
1045
        if (len < 0)
1046
                len = 0;
1047
        return len;
1048
}
1049
 
1050
struct proto udp_prot = {
1051
        name:           "UDP",
1052
        close:          udp_close,
1053
        connect:        udp_connect,
1054
        disconnect:     udp_disconnect,
1055
        ioctl:          udp_ioctl,
1056
        setsockopt:     ip_setsockopt,
1057
        getsockopt:     ip_getsockopt,
1058
        sendmsg:        udp_sendmsg,
1059
        recvmsg:        udp_recvmsg,
1060
        backlog_rcv:    udp_queue_rcv_skb,
1061
        hash:           udp_v4_hash,
1062
        unhash:         udp_v4_unhash,
1063
        get_port:       udp_v4_get_port,
1064
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.