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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [net/] [ipv4/] [packet.c] - Blame information for rev 1772

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

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 * INET         An implementation of the TCP/IP protocol suite for the LINUX
3
 *              operating system.  INET is implemented using the  BSD Socket
4
 *              interface as the means of communication with the user level.
5
 *
6
 *              PACKET - implements raw packet sockets.
7
 *
8
 *              Doesn't belong in IP but it's currently too hooked into ip
9
 *              to separate.
10
 *
11
 * Version:     @(#)packet.c    1.0.6   05/25/93
12
 *
13
 * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
14
 *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
15
 *              Alan Cox, <gw4pts@gw4pts.ampr.org>
16
 *
17
 * Fixes:
18
 *              Alan Cox        :       verify_area() now used correctly
19
 *              Alan Cox        :       new skbuff lists, look ma no backlogs!
20
 *              Alan Cox        :       tidied skbuff lists.
21
 *              Alan Cox        :       Now uses generic datagram routines I
22
 *                                      added. Also fixed the peek/read crash
23
 *                                      from all old Linux datagram code.
24
 *              Alan Cox        :       Uses the improved datagram code.
25
 *              Alan Cox        :       Added NULL's for socket options.
26
 *              Alan Cox        :       Re-commented the code.
27
 *              Alan Cox        :       Use new kernel side addressing
28
 *              Rob Janssen     :       Correct MTU usage.
29
 *              Dave Platt      :       Counter leaks caused by incorrect
30
 *                                      interrupt locking and some slightly
31
 *                                      dubious gcc output. Can you read
32
 *                                      compiler: it said _VOLATILE_
33
 *      Richard Kooijman        :       Timestamp fixes.
34
 *              Alan Cox        :       New buffers. Use sk->mac.raw.
35
 *              Alan Cox        :       sendmsg/recvmsg support.
36
 *              Alan Cox        :       Protocol setting support
37
 *
38
 *              This program is free software; you can redistribute it and/or
39
 *              modify it under the terms of the GNU General Public License
40
 *              as published by the Free Software Foundation; either version
41
 *              2 of the License, or (at your option) any later version.
42
 *
43
 */
44
 
45
#include <linux/types.h>
46
#include <linux/sched.h>
47
#include <linux/mm.h>
48
#include <linux/fcntl.h>
49
#include <linux/socket.h>
50
#include <linux/in.h>
51
#include <linux/inet.h>
52
#include <linux/netdevice.h>
53
#include <linux/if_packet.h>
54
#include <net/ip.h>
55
#include <net/protocol.h>
56
#include <linux/skbuff.h>
57
#include <net/sock.h>
58
#include <linux/errno.h>
59
#include <linux/timer.h>
60
#include <asm/system.h>
61
#include <asm/segment.h>
62
 
63
/*
64
 *      We really ought to have a single public _inline_ min function!
65
 */
66
 
67
static unsigned long min(unsigned long a, unsigned long b)
68
{
69
        if (a < b)
70
                return(a);
71
        return(b);
72
}
73
 
74
 
75
/*
76
 *      This should be the easiest of all, all we do is copy it into a buffer.
77
 */
78
 
79
int packet_rcv(struct sk_buff *skb, struct device *dev,  struct packet_type *pt)
80
{
81
        struct sock *sk;
82
 
83
        /*
84
         *      When we registered the protocol we saved the socket in the data
85
         *      field for just this event.
86
         */
87
 
88
        sk = (struct sock *) pt->data;
89
 
90
        /*
91
         *      Yank back the headers [hope the device set this
92
         *      right or kerboom...]
93
         */
94
 
95
        skb_push(skb,skb->data-skb->mac.raw);
96
 
97
        /*
98
         *      The SOCK_PACKET socket receives _all_ frames.
99
         */
100
 
101
        skb->dev = dev;
102
 
103
        /*
104
         *      Charge the memory to the socket. This is done specifically
105
         *      to prevent sockets using all the memory up.
106
         */
107
 
108
        if(sock_queue_rcv_skb(sk,skb)<0)
109
        {
110
                skb->sk = NULL;
111
                kfree_skb(skb, FREE_READ);
112
                return 0;
113
        }
114
        /*
115
         *      Processing complete.
116
         */
117
 
118
        return(0);
119
}
120
 
121
 
122
/*
123
 *      Output a raw packet to a device layer. This bypasses all the other
124
 *      protocol layers and you must therefore supply it with a complete frame
125
 */
126
 
127
static int packet_sendmsg(struct sock *sk, struct msghdr *msg, int len,
128
              int noblock, int flags)
129
{
130
        struct sk_buff *skb;
131
        struct device *dev;
132
        struct sockaddr_pkt *saddr=(struct sockaddr_pkt *)msg->msg_name;
133
        unsigned short proto=0;
134
 
135
        /*
136
         *      Check the flags.
137
         */
138
 
139
        if (flags)
140
                return(-EINVAL);
141
 
142
        /*
143
         *      Get and verify the address.
144
         */
145
 
146
        if (saddr)
147
        {
148
                if (msg->msg_namelen < sizeof(struct sockaddr))
149
                        return(-EINVAL);
150
                if (msg->msg_namelen==sizeof(struct sockaddr_pkt))
151
                        proto=saddr->spkt_protocol;
152
        }
153
        else
154
                return(-ENOTCONN);      /* SOCK_PACKET must be sent giving an address */
155
 
156
        /*
157
         *      Find the device first to size check it
158
         */
159
 
160
        saddr->spkt_device[13] = 0;
161
        dev = dev_get(saddr->spkt_device);
162
        if (dev == NULL)
163
        {
164
                return(-ENODEV);
165
        }
166
 
167
        /*
168
         *      You may not queue a frame bigger than the mtu. This is the lowest level
169
         *      raw protocol and you must do your own fragmentation at this level.
170
         */
171
 
172
        if ((dev->flags & IFF_SOFTHEADERS && len>dev->mtu)
173
        || len>dev->mtu+dev->hard_header_len)
174
                return -EMSGSIZE;
175
 
176
        skb = sock_wmalloc(sk, len+dev->hard_header_len, 0, GFP_KERNEL);
177
 
178
        /*
179
         *      If the write buffer is full, then tough. At this level the user gets to
180
         *      deal with the problem - do your own algorithmic backoffs. That's far
181
         *      more flexible.
182
         */
183
 
184
        if (skb == NULL)
185
        {
186
                return(-ENOBUFS);
187
        }
188
 
189
        /*
190
         *      Fill it in
191
         */
192
 
193
        skb->sk = sk;
194
        skb->free = 1;
195
        if (dev->flags & IFF_SOFTHEADERS) {
196
                /* Do the hard header calls for drivers that must set the
197
                 * headers at transmission time by themselves. PPP and ISDN
198
                 * are the notable offenders here. A proper fix requires some
199
                 * changes at the device driver level, but that is a 2.1 issue.
200
                 */
201
                skb_reserve(skb,dev->hard_header_len);
202
                if (dev->hard_header)
203
                        dev->hard_header(skb,dev,ETH_P_IP,NULL,NULL,len);
204
        }
205
        memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
206
        skb->arp = 1;           /* No ARP needs doing on this (complete) frame */
207
        skb->protocol = proto;
208
 
209
        /*
210
         *      Now send it
211
         */
212
 
213
        if (dev->flags & IFF_UP)
214
                dev_queue_xmit(skb, dev, sk->priority);
215
        else
216
                kfree_skb(skb, FREE_WRITE);
217
        return(len);
218
}
219
 
220
/*
221
 *      Close a SOCK_PACKET socket. This is fairly simple. We immediately go
222
 *      to 'closed' state and remove our protocol entry in the device list.
223
 *      The release_sock() will destroy the socket if a user has closed the
224
 *      file side of the object.
225
 */
226
 
227
static void packet_close(struct sock *sk, unsigned long timeout)
228
{
229
        /*
230
         *      Stop more data and kill the socket off.
231
         */
232
 
233
        lock_sock(sk);
234
        sk->state = TCP_CLOSE;
235
 
236
        /*
237
         *      Unhook the notifier
238
         */
239
 
240
        unregister_netdevice_notifier(&sk->protinfo.af_packet.notifier);
241
 
242
        if(sk->protinfo.af_packet.prot_hook)
243
        {
244
                /*
245
                 *      Remove the protocol hook
246
                 */
247
 
248
                dev_remove_pack((struct packet_type *)sk->protinfo.af_packet.prot_hook);
249
 
250
                /*
251
                 *      Dispose of litter carefully.
252
                 */
253
 
254
                kfree_s((void *)sk->protinfo.af_packet.prot_hook, sizeof(struct packet_type));
255
                sk->protinfo.af_packet.prot_hook = NULL;
256
        }
257
 
258
        release_sock(sk);
259
        destroy_sock(sk);
260
}
261
 
262
/*
263
 *      Attach a packet hook to a device.
264
 */
265
 
266
int packet_attach(struct sock *sk, struct device *dev)
267
{
268
        struct packet_type *p = (struct packet_type *) kmalloc(sizeof(*p), GFP_KERNEL);
269
        if (p == NULL)
270
                return(-ENOMEM);
271
 
272
        p->func = packet_rcv;
273
        p->type = sk->num;
274
        p->data = (void *)sk;
275
        p->dev = dev;
276
        dev_add_pack(p);
277
 
278
        /*
279
         *      We need to remember this somewhere.
280
         */
281
 
282
        sk->protinfo.af_packet.prot_hook = p;
283
        sk->protinfo.af_packet.bound_dev = dev;
284
        return 0;
285
}
286
 
287
/*
288
 *      Bind a packet socket to a device
289
 */
290
 
291
static int packet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
292
{
293
        char name[15];
294
        struct device *dev;
295
 
296
        /*
297
         *      Check legality
298
         */
299
 
300
        if(addr_len!=sizeof(struct sockaddr))
301
                return -EINVAL;
302
        strncpy(name,uaddr->sa_data,14);
303
        name[14]=0;
304
 
305
        /*
306
         *      Lock the device chain while we sanity check
307
         *      the bind request.
308
         */
309
 
310
        dev_lock_list();
311
        dev=dev_get(name);
312
        if(dev==NULL)
313
        {
314
                dev_unlock_list();
315
                return -ENODEV;
316
        }
317
 
318
        if(!(dev->flags&IFF_UP))
319
        {
320
                dev_unlock_list();
321
                return -ENETDOWN;
322
        }
323
 
324
        /*
325
         *      Perform the request.
326
         */
327
 
328
        memcpy(sk->protinfo.af_packet.device_name,name,15);
329
 
330
        /*
331
         *      Rewrite an existing hook if present.
332
         */
333
 
334
        if(sk->protinfo.af_packet.prot_hook)
335
        {
336
                dev_remove_pack(sk->protinfo.af_packet.prot_hook);
337
                sk->protinfo.af_packet.prot_hook->dev=dev;
338
                sk->protinfo.af_packet.bound_dev=dev;
339
                dev_add_pack(sk->protinfo.af_packet.prot_hook);
340
        }
341
        else
342
        {
343
                int err=packet_attach(sk, dev);
344
                if(err)
345
                {
346
                        dev_unlock_list();
347
                        return err;
348
                }
349
        }
350
        /*
351
         *      Now the notifier is set up right this lot is safe.
352
         */
353
        dev_unlock_list();
354
        return 0;
355
}
356
 
357
/*
358
 *      This hook is called when a device goes up or down so that
359
 *      SOCK_PACKET sockets can come unbound properly.
360
 */
361
 
362
static int packet_unbind(struct notifier_block *this, unsigned long msg, void *data)
363
{
364
        struct inet_packet_opt *ipo=(struct inet_packet_opt *)this;
365
        if(msg==NETDEV_DOWN && data==ipo->bound_dev)
366
        {
367
                /*
368
                 *      Our device has gone down.
369
                 */
370
                ipo->bound_dev=NULL;
371
                dev_remove_pack(ipo->prot_hook);
372
                kfree(ipo->prot_hook);
373
                ipo->prot_hook=NULL;
374
        }
375
        return NOTIFY_DONE;
376
}
377
 
378
 
379
/*
380
 *      Create a packet of type SOCK_PACKET.
381
 */
382
 
383
static int packet_init(struct sock *sk)
384
{
385
        /*
386
         *      Attach a protocol block
387
         */
388
 
389
        int err=packet_attach(sk, NULL);
390
        if(err)
391
                return err;
392
 
393
        /*
394
         *      Set up the per socket notifier.
395
         */
396
 
397
        sk->protinfo.af_packet.notifier.notifier_call=packet_unbind;
398
        sk->protinfo.af_packet.notifier.priority=0;
399
 
400
        register_netdevice_notifier(&sk->protinfo.af_packet.notifier);
401
 
402
        return(0);
403
}
404
 
405
 
406
/*
407
 *      Pull a packet from our receive queue and hand it to the user.
408
 *      If necessary we block.
409
 */
410
 
411
int packet_recvmsg(struct sock *sk, struct msghdr *msg, int len,
412
                int noblock, int flags,int *addr_len)
413
{
414
        int copied=0;
415
        struct sk_buff *skb;
416
        struct sockaddr_pkt *saddr=(struct sockaddr_pkt *)msg->msg_name;
417
        int err;
418
 
419
        if (sk->shutdown & RCV_SHUTDOWN)
420
                return(0);
421
 
422
        /*
423
         *      If there is no protocol hook then the device is down.
424
         */
425
 
426
        if(sk->protinfo.af_packet.prot_hook==NULL)
427
                return -ENETDOWN;
428
 
429
        /*
430
         *      If the address length field is there to be filled in, we fill
431
         *      it in now.
432
         */
433
 
434
        if (addr_len)
435
                *addr_len=sizeof(*saddr);
436
 
437
        /*
438
         *      Call the generic datagram receiver. This handles all sorts
439
         *      of horrible races and re-entrancy so we can forget about it
440
         *      in the protocol layers.
441
         */
442
 
443
        skb=skb_recv_datagram(sk,flags,noblock,&err);
444
 
445
        /*
446
         *      An error occurred so return it. Because skb_recv_datagram()
447
         *      handles the blocking we don't see and worry about blocking
448
         *      retries.
449
         */
450
 
451
        if(skb==NULL)
452
                return err;
453
 
454
        /*
455
         *      You lose any data beyond the buffer you gave. If it worries a
456
         *      user program they can ask the device for its MTU anyway.
457
         */
458
 
459
        copied = min(len, skb->len);
460
 
461
        memcpy_toiovec(msg->msg_iov, skb->data, copied);        /* We can't use skb_copy_datagram here */
462
        sk->stamp=skb->stamp;
463
 
464
        /*
465
         *      Copy the address.
466
         */
467
 
468
        if (saddr)
469
        {
470
                saddr->spkt_family = skb->dev->type;
471
                strncpy(saddr->spkt_device,skb->dev->name, 15);
472
                saddr->spkt_protocol = skb->protocol;
473
        }
474
 
475
        /*
476
         *      Free or return the buffer as appropriate. Again this hides all the
477
         *      races and re-entrancy issues from us.
478
         */
479
 
480
        skb_free_datagram(sk, skb);
481
 
482
        return(copied);
483
}
484
 
485
/*
486
 *      This structure declares to the lower layer socket subsystem currently
487
 *      incorrectly embedded in the IP code how to behave. This interface needs
488
 *      a lot of work and will change.
489
 */
490
 
491
struct proto packet_prot =
492
{
493
        (struct sock *)&packet_prot,    /* sklist_next */
494
        (struct sock *)&packet_prot,    /* sklist_prev */
495
        packet_close,                   /* close */
496
        ip_build_header,                /* build_header, Not actually used */
497
        NULL,                           /* connect */
498
        NULL,                           /* accept */
499
        ip_queue_xmit,                  /* queue_xmit, These two are not actually used */
500
        NULL,                           /* retransmit */
501
        NULL,                           /* write_wakeup */
502
        NULL,                           /* read_wakeup */
503
        NULL,                           /* rcv */
504
        datagram_select,                /* select */
505
        NULL,                           /* ioctl, No ioctl */
506
        packet_init,                    /* init */
507
        NULL,                           /* shutdown */
508
        NULL,                           /* setsockopt, No set/get socket options */
509
        NULL,                           /* getsockopt */
510
        packet_sendmsg,                 /* sendmsg */
511
        packet_recvmsg,                 /* recvmsg */
512
        packet_bind,                    /* bind */
513
        NULL,                           /* hash */
514
        NULL,                           /* unhash */
515
        NULL,                           /* rehash */
516
        NULL,                           /* good_socknum */
517
        NULL,                           /* verify_bind */
518
        128,                            /* max_header */
519
        0,                               /* retransmits */
520
        "PACKET",                       /* name */
521
        0,                               /* inuse */
522
 
523
};

powered by: WebSVN 2.1.0

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