root/net/inet/packet.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. min
  2. packet_rcv
  3. packet_sendto
  4. packet_write
  5. packet_close
  6. packet_init
  7. packet_recvfrom
  8. packet_read

   1 /*
   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  * Version:     @(#)packet.c    1.0.6   05/25/93
   9  *
  10  * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
  11  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12  *
  13  * Fixes:       
  14  *              Alan Cox        :       verify_area() now used correctly
  15  *              Alan Cox        :       new skbuff lists, look ma no backlogs!
  16  *              Alan Cox        :       tidied skbuff lists.
  17  *              Alan Cox        :       Now uses generic datagram routines I
  18  *                                      added. Also fixed the peek/read crash
  19  *                                      from all old Linux datagram code.
  20  *              Alan Cox        :       Uses the improved datagram code.
  21  *              Alan Cox        :       Added NULL's for socket options.
  22  *
  23  *
  24  *              This program is free software; you can redistribute it and/or
  25  *              modify it under the terms of the GNU General Public License
  26  *              as published by the Free Software Foundation; either version
  27  *              2 of the License, or (at your option) any later version.
  28  */
  29 #include <linux/types.h>
  30 #include <linux/sched.h>
  31 #include <linux/fcntl.h>
  32 #include <linux/socket.h>
  33 #include <linux/in.h>
  34 #include "inet.h"
  35 #include "dev.h"
  36 #include "ip.h"
  37 #include "protocol.h"
  38 #include "tcp.h"
  39 #include "skbuff.h"
  40 #include "sock.h"
  41 #include <linux/errno.h>
  42 #include <linux/timer.h>
  43 #include <asm/system.h>
  44 #include <asm/segment.h>
  45 #include "udp.h"
  46 #include "raw.h"
  47 
  48 
  49 static unsigned long
  50 min(unsigned long a, unsigned long b)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52   if (a < b) return(a);
  53   return(b);
  54 }
  55 
  56 
  57 /* This should be the easiest of all, all we do is copy it into a buffer. */
  58 int
  59 packet_rcv(struct sk_buff *skb, struct device *dev,  struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
  60 {
  61   struct sock *sk;
  62 
  63   sk = (struct sock *) pt->data;
  64   skb->dev = dev;
  65   skb->len += dev->hard_header_len;
  66 
  67   skb->sk = sk;
  68 
  69   /* Charge it too the socket. */
  70   if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) {
  71         skb->sk = NULL;
  72         kfree_skb(skb, FREE_READ);
  73         return(0);
  74   }
  75   sk->rmem_alloc += skb->mem_len;
  76   skb_queue_tail(&sk->rqueue,skb);
  77   wake_up_interruptible(sk->sleep);
  78   release_sock(sk);
  79   return(0);
  80 }
  81 
  82 
  83 /* This will do terrible things if len + ipheader + devheader > dev->mtu */
  84 static int
  85 packet_sendto(struct sock *sk, unsigned char *from, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
  86               int noblock, unsigned flags, struct sockaddr_in *usin,
  87               int addr_len)
  88 {
  89   struct sk_buff *skb;
  90   struct device *dev;
  91   struct sockaddr saddr;
  92   int err;
  93 
  94   /* Check the flags. */
  95   if (flags) return(-EINVAL);
  96   if (len < 0) return(-EINVAL);
  97 
  98   /* Get and verify the address. */
  99   if (usin) {
 100         if (addr_len < sizeof(saddr)) return(-EINVAL);
 101         err=verify_area(VERIFY_READ, usin, sizeof(saddr));
 102         if(err)
 103                 return err;
 104         memcpy_fromfs(&saddr, usin, sizeof(saddr));
 105   } else
 106         return(-EINVAL);
 107         
 108   err=verify_area(VERIFY_READ,from,len);
 109   if(err)
 110         return(err);
 111 /* Find the device first to size check it */
 112 
 113   saddr.sa_data[13] = 0;
 114   dev = dev_get(saddr.sa_data);
 115   if (dev == NULL) {
 116         return(-ENXIO);
 117   }
 118   if(len>dev->mtu)
 119         return -EMSGSIZE;
 120 
 121 /* Now allocate the buffer, knowing 4K pagelimits wont break this line */  
 122   skb = sk->prot->wmalloc(sk, len+sizeof(*skb), 0, GFP_KERNEL);
 123 
 124   /* This shouldn't happen, but it could. */
 125   if (skb == NULL) {
 126         DPRINTF((DBG_PKT, "packet_sendto: write buffer full?\n"));
 127         return(-ENOMEM);
 128   }
 129   /* Fill it in */
 130   skb->mem_addr = skb;
 131   skb->mem_len = len + sizeof(*skb);
 132   skb->sk = sk;
 133   skb->free = 1;
 134   memcpy_fromfs(skb->data, from, len);
 135   skb->len = len;
 136   skb->next = NULL;
 137   skb->arp = 1;
 138   if (dev->flags & IFF_UP) dev->queue_xmit(skb, dev, sk->priority);
 139     else kfree_skb(skb, FREE_WRITE);
 140   return(len);
 141 }
 142 
 143 
 144 static int
 145 packet_write(struct sock *sk, unsigned char *buff, 
     /* [previous][next][first][last][top][bottom][index][help] */
 146              int len, int noblock,  unsigned flags)
 147 {
 148   return(packet_sendto(sk, buff, len, noblock, flags, NULL, 0));
 149 }
 150 
 151 
 152 static void
 153 packet_close(struct sock *sk, int timeout)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155   sk->inuse = 1;
 156   sk->state = TCP_CLOSE;
 157   dev_remove_pack((struct packet_type *)sk->pair);
 158   kfree_s((void *)sk->pair, sizeof(struct packet_type));
 159   sk->pair = NULL;
 160   release_sock(sk);
 161 }
 162 
 163 
 164 static int
 165 packet_init(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167   struct packet_type *p;
 168 
 169   p = (struct packet_type *) kmalloc(sizeof(*p), GFP_KERNEL);
 170   if (p == NULL) return(-ENOMEM);
 171 
 172   p->func = packet_rcv;
 173   p->type = sk->num;
 174   p->data = (void *)sk;
 175   dev_add_pack(p);
 176    
 177   /* We need to remember this somewhere. */
 178   sk->pair = (struct sock *)p;
 179 
 180   return(0);
 181 }
 182 
 183 
 184 /*
 185  * This should be easy, if there is something there
 186  * we return it, otherwise we block.
 187  */
 188 int
 189 packet_recvfrom(struct sock *sk, unsigned char *to, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 190                 int noblock, unsigned flags, struct sockaddr_in *sin,
 191                 int *addr_len)
 192 {
 193   int copied=0;
 194   struct sk_buff *skb;
 195   struct sockaddr *saddr;
 196   int err;
 197 
 198   saddr = (struct sockaddr *)sin;
 199   if (len == 0) return(0);
 200   if (len < 0) return(-EINVAL);
 201 
 202   if (sk->shutdown & RCV_SHUTDOWN) return(0);
 203   if (addr_len) {
 204           err=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
 205           if(err)
 206                 return err;
 207           put_fs_long(sizeof(*saddr), addr_len);
 208   }
 209   
 210   err=verify_area(VERIFY_WRITE,to,len);
 211   if(err)
 212         return err;
 213   skb=skb_recv_datagram(sk,flags,noblock,&err);
 214   if(skb==NULL)
 215         return err;
 216   copied = min(len, skb->len);
 217 
 218   memcpy_tofs(to, skb->data, copied);   /* Don't use skb_copy_datagram here: We can't get frag chains */
 219 
 220   /* Copy the address. */
 221   if (saddr) {
 222         struct sockaddr addr;
 223 
 224         addr.sa_family = skb->dev->type;
 225         memcpy(addr.sa_data,skb->dev->name, 14);
 226         verify_area(VERIFY_WRITE, saddr, sizeof(*saddr));
 227         memcpy_tofs(saddr, &addr, sizeof(*saddr));
 228   }
 229 
 230   skb_free_datagram(skb);               /* Its either been used up, or its a peek_copy anyway */
 231 
 232   release_sock(sk);
 233   return(copied);
 234 }
 235 
 236 
 237 int
 238 packet_read(struct sock *sk, unsigned char *buff,
     /* [previous][next][first][last][top][bottom][index][help] */
 239             int len, int noblock, unsigned flags)
 240 {
 241   return(packet_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
 242 }
 243 
 244 
 245 struct proto packet_prot = {
 246   sock_wmalloc,
 247   sock_rmalloc,
 248   sock_wfree,
 249   sock_rfree,
 250   sock_rspace,
 251   sock_wspace,
 252   packet_close,
 253   packet_read,
 254   packet_write,
 255   packet_sendto,
 256   packet_recvfrom,
 257   ip_build_header,
 258   udp_connect,
 259   NULL,
 260   ip_queue_xmit,
 261   ip_retransmit,
 262   NULL,
 263   NULL,
 264   NULL, 
 265   datagram_select,
 266   NULL,
 267   packet_init,
 268   NULL,
 269   NULL, /* No set/get socket options */
 270   NULL,
 271   128,
 272   0,
 273   {NULL,},
 274   "PACKET"
 275 };

/* [previous][next][first][last][top][bottom][index][help] */