Annotation of linux/net/tcp/packet.c, revision 1.1

1.1     ! root        1: /* packet.c - implements raw packet sockets. */
        !             2: /*
        !             3:     Copyright (C) 1992  Ross Biro
        !             4: 
        !             5:     This program is free software; you can redistribute it and/or modify
        !             6:     it under the terms of the GNU General Public License as published by
        !             7:     the Free Software Foundation; either version 2, or (at your option)
        !             8:     any later version.
        !             9: 
        !            10:     This program is distributed in the hope that it will be useful,
        !            11:     but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            12:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            13:     GNU General Public License for more details.
        !            14: 
        !            15:     You should have received a copy of the GNU General Public License
        !            16:     along with this program; if not, write to the Free Software
        !            17:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
        !            18: 
        !            19:     The Author may be reached as [email protected] or
        !            20:     C/O Department of Mathematics; Stanford University; Stanford, CA 94305
        !            21: */
        !            22: 
        !            23: #include <linux/types.h>
        !            24: #include <linux/sched.h>
        !            25: #include <linux/fcntl.h>
        !            26: #include <linux/socket.h>
        !            27: #include <netinet/in.h>
        !            28: #include "timer.h"
        !            29: #include "ip.h"
        !            30: #include "tcp.h"
        !            31: #include "sock.h"
        !            32: #include <linux/errno.h>
        !            33: #include <linux/timer.h>
        !            34: #include <asm/system.h>
        !            35: #include <asm/segment.h>
        !            36: #include "../kern_sock.h" /* for PRINTK */
        !            37: 
        !            38: extern struct proto raw_prot;
        !            39: 
        !            40: static  unsigned long
        !            41: min(unsigned long a, unsigned long b)
        !            42: {
        !            43:    if (a < b) return (a);
        !            44:    return (b);
        !            45: }
        !            46: 
        !            47: /* this should be the easiest of all, all we do is copy it into
        !            48:    a buffer. */
        !            49: int
        !            50: packet_rcv (struct sk_buff *skb, struct device *dev,  struct packet_type *pt)
        !            51: {
        !            52:    volatile struct sock *sk;
        !            53: 
        !            54:    sk = pt->data;
        !            55:    skb->dev = dev;
        !            56:    skb->len += dev->hard_header_len;
        !            57: 
        !            58:    /* now see if we are in use. */
        !            59:    cli();
        !            60:    if (sk->inuse)
        !            61:      {
        !            62:        sti();
        !            63:        /* drop any packets if we can't currently deal with them.
        !            64:           Assume that the other end will retransmit if it was
        !            65:           important. */
        !            66:        skb->sk = NULL;
        !            67:        free_skb (skb, FREE_READ);
        !            68:        return (0);
        !            69: 
        !            70:      }
        !            71:    sk->inuse = 1;
        !            72:    sti ();
        !            73: 
        !            74:    skb->sk = sk;
        !            75: 
        !            76:    /* charge it too the socket. */
        !            77:    if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX)
        !            78:      {
        !            79:        skb->sk = NULL;
        !            80:        free_skb (skb, FREE_READ);
        !            81:        return (0);
        !            82:      }
        !            83:             
        !            84:    sk->rmem_alloc += skb->mem_len;
        !            85: 
        !            86:    /* now just put it onto the queue. */
        !            87:    if (sk->rqueue == NULL)
        !            88:      {
        !            89:        sk->rqueue = skb;
        !            90:        skb->next = skb;
        !            91:        skb->prev = skb;
        !            92:      }
        !            93:    else
        !            94:      {
        !            95:        skb->next = sk->rqueue;
        !            96:        skb->prev = sk->rqueue->prev;
        !            97:        skb->prev->next = skb;
        !            98:        skb->next->prev = skb;
        !            99:      }
        !           100:    wake_up (sk->sleep);
        !           101:    release_sock (sk);
        !           102:    return (0);
        !           103: }
        !           104: 
        !           105: /* this will do terrible things if len + ipheader + devheader > dev->mtu */
        !           106: static int
        !           107: packet_sendto (volatile struct sock *sk, unsigned char *from, int len,
        !           108:               int noblock,
        !           109:               unsigned flags, struct sockaddr_in *usin, int addr_len)
        !           110: {
        !           111:    struct sk_buff *skb;
        !           112:    struct device *dev;
        !           113:    struct sockaddr saddr;
        !           114: 
        !           115:    /* check the flags. */
        !           116:    if (flags) return (-EINVAL);
        !           117:    if (len < 0) return (-EINVAL);
        !           118: 
        !           119:    /* get and verify the address. */
        !           120:    if (usin)
        !           121:      {
        !           122:        if (addr_len < sizeof (saddr))
        !           123:          return (-EINVAL);
        !           124:        verify_area (usin, sizeof (saddr));
        !           125:        memcpy_fromfs (&saddr, usin, sizeof(saddr));
        !           126:      }
        !           127:    else
        !           128:      return (-EINVAL);
        !           129: 
        !           130:    skb = sk->prot->wmalloc (sk, len+sizeof (*skb) + sk->prot->max_header, 0);
        !           131:    /* this shouldn't happen, but it could. */
        !           132:    if (skb == NULL)
        !           133:      {
        !           134:        PRINTK ("packet_sendto: write buffer full?\n");
        !           135:        print_sk (sk);
        !           136:        return (-EAGAIN);
        !           137:      }
        !           138:    skb->mem_addr = skb;
        !           139:    skb->mem_len = len + sizeof (*skb) +sk->prot->max_header;
        !           140:    skb->sk = sk;
        !           141:    skb->free = 1;
        !           142:    saddr.sa_data[13] = 0;
        !           143:    dev = get_dev (saddr.sa_data);
        !           144:    if (dev == NULL)
        !           145:      {
        !           146:        sk->prot->wfree (sk, skb->mem_addr, skb->mem_len);
        !           147:        return (-ENXIO);
        !           148:      }
        !           149:    verify_area (from, len);
        !           150:    memcpy_fromfs (skb+1, from, len);
        !           151:    skb->len = len;
        !           152:    skb->next = NULL;
        !           153:    if (dev->up)
        !           154:      dev->queue_xmit (skb, dev, sk->priority);
        !           155:    else
        !           156:      free_skb (skb, FREE_WRITE);
        !           157:    return (len);
        !           158: }
        !           159: 
        !           160: static int
        !           161: packet_write (volatile struct sock *sk, unsigned char *buff, 
        !           162:              int len, int noblock,  unsigned flags)
        !           163: {
        !           164:    return (packet_sendto (sk, buff, len, noblock, flags, NULL, 0));
        !           165: }
        !           166: 
        !           167: static void
        !           168: packet_close (volatile struct sock *sk, int timeout)
        !           169: {
        !           170:    sk->inuse = 1;
        !           171:    sk->state = TCP_CLOSE;
        !           172:    dev_remove_pack ((struct packet_type *)sk->pair);
        !           173:    free_s ((void *)sk->pair, sizeof (struct packet_type));
        !           174:    release_sock (sk);
        !           175: }
        !           176: 
        !           177: static int
        !           178: packet_init (volatile struct sock *sk)
        !           179: {
        !           180:    struct packet_type *p;
        !           181:    p = malloc (sizeof (*p));
        !           182:    if (p == NULL) return (-ENOMEM);
        !           183: 
        !           184:    p->func = packet_rcv;
        !           185:    p->type = sk->num;
        !           186:    p->data = (void *)sk;
        !           187:    dev_add_pack (p);
        !           188:    
        !           189:    /* we need to remember this somewhere. */
        !           190:    sk->pair = (volatile struct sock *)p;
        !           191: 
        !           192:    return (0);
        !           193: }
        !           194: 
        !           195: 
        !           196: int
        !           197: packet_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
        !           198:              int noblock,
        !           199:              unsigned flags, struct sockaddr_in *sin, int *addr_len)
        !           200: {
        !           201:        /* this should be easy, if there is something there we
        !           202:           return it, otherwise we block. */
        !           203:        int copied=0;
        !           204:        struct sk_buff *skb;
        !           205:        struct sockaddr *saddr;
        !           206:        saddr = (struct sockaddr *)sin;
        !           207: 
        !           208:        if (len == 0) return (0);
        !           209:        if (len < 0) return (-EINVAL);
        !           210:        if (addr_len)
        !           211:          {
        !           212:                  verify_area (addr_len, sizeof(*addr_len));
        !           213:                  put_fs_long (sizeof (*saddr), addr_len);
        !           214:          }
        !           215: 
        !           216:        sk->inuse = 1;
        !           217:        while (sk->rqueue == NULL)
        !           218:          {
        !           219:             if (noblock)
        !           220:               {
        !           221:                  release_sock (sk);
        !           222:                  return (-EAGAIN);
        !           223:               }
        !           224:             release_sock (sk);
        !           225:             cli();
        !           226:             if (sk->rqueue == NULL)
        !           227:               {
        !           228:                  interruptible_sleep_on (sk->sleep);
        !           229:                  if (current->signal & ~current->blocked)
        !           230:                    {
        !           231:                       return (-ERESTARTSYS);
        !           232:                    }
        !           233:               }
        !           234:             sti();
        !           235:          }
        !           236:        skb = sk->rqueue;
        !           237: 
        !           238:        if (!(flags & MSG_PEEK))
        !           239:          {
        !           240:                  if (skb->next == skb )
        !           241:                    {
        !           242:                            sk->rqueue = NULL;
        !           243:                    }
        !           244:                  else
        !           245:                    {
        !           246:                            sk->rqueue = sk->rqueue ->next;
        !           247:                            skb->prev->next = skb->next;
        !           248:                            skb->next->prev = skb->prev;
        !           249:                    }
        !           250:          }
        !           251:        copied = min (len, skb->len);
        !           252:        verify_area (to, copied);
        !           253:        memcpy_tofs (to, skb+1,  copied);
        !           254:        /* copy the address. */
        !           255:        if (saddr)
        !           256:          {
        !           257:                  struct sockaddr addr;
        !           258:                  addr.sa_family = skb->dev->type;
        !           259:                  memcpy (addr.sa_data,skb->dev->name, 14);
        !           260:                  verify_area (saddr, sizeof (*saddr));
        !           261:                  memcpy_tofs(saddr, &addr, sizeof (*saddr));
        !           262:          }
        !           263: 
        !           264:        if (!(flags & MSG_PEEK))
        !           265:          {
        !           266:             free_skb (skb, FREE_READ);
        !           267:          }
        !           268: 
        !           269:        release_sock (sk);
        !           270:        return (copied);
        !           271: 
        !           272: }
        !           273: 
        !           274: int
        !           275: packet_read (volatile struct sock *sk, unsigned char *buff,
        !           276:             int len, int noblock, unsigned flags)
        !           277: {
        !           278:        return (packet_recvfrom (sk, buff, len, noblock, flags, NULL, NULL));
        !           279: }
        !           280: 
        !           281: 
        !           282: int udp_connect (volatile struct sock *sk, struct sockaddr_in *usin,
        !           283:                 int addr_len);
        !           284: 
        !           285: int udp_select (volatile struct sock *sk, int sel_type, select_table *wait);
        !           286: 
        !           287: 
        !           288: struct proto packet_prot =
        !           289: {
        !           290:   sock_wmalloc,
        !           291:   sock_rmalloc,
        !           292:   sock_wfree,
        !           293:   sock_rfree,
        !           294:   sock_rspace,
        !           295:   sock_wspace,
        !           296:   packet_close,
        !           297:   packet_read,
        !           298:   packet_write,
        !           299:   packet_sendto,
        !           300:   packet_recvfrom,
        !           301:   ip_build_header,
        !           302:   udp_connect,
        !           303:   NULL,
        !           304:   ip_queue_xmit,
        !           305:   ip_retransmit,
        !           306:   NULL,
        !           307:   NULL,
        !           308:   NULL, 
        !           309:   udp_select,
        !           310:   NULL,
        !           311:   packet_init,
        !           312:   128,
        !           313:   0,
        !           314:   {NULL,}
        !           315: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.