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  *              This program is free software; you can redistribute it and/or
  14  *              modify it under the terms of the GNU General Public License
  15  *              as published by the Free Software Foundation; either version
  16  *              2 of the License, or (at your option) any later version.
  17  */
  18 #include <linux/types.h>
  19 #include <linux/sched.h>
  20 #include <linux/fcntl.h>
  21 #include <linux/socket.h>
  22 #include <linux/in.h>
  23 #include "inet.h"
  24 #include "timer.h"
  25 #include "dev.h"
  26 #include "ip.h"
  27 #include "protocol.h"
  28 #include "tcp.h"
  29 #include "skbuff.h"
  30 #include "sock.h"
  31 #include <linux/errno.h>
  32 #include <linux/timer.h>
  33 #include <asm/system.h>
  34 #include <asm/segment.h>
  35 #include "udp.h"
  36 #include "raw.h"
  37 
  38 
  39 static unsigned long
  40 min(unsigned long a, unsigned long b)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42   if (a < b) return(a);
  43   return(b);
  44 }
  45 
  46 
  47 /* This should be the easiest of all, all we do is copy it into a buffer. */
  48 int
  49 packet_rcv(struct sk_buff *skb, struct device *dev,  struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51   struct sock *sk;
  52 
  53   sk = (struct sock *) pt->data;
  54   skb->dev = dev;
  55   skb->len += dev->hard_header_len;
  56 
  57   /* Now see if we are in use. */
  58   cli();
  59   if (sk->inuse) {
  60         sti();
  61         /*
  62          * Drop any packets if we can't currently deal with
  63          * them. Assume that the other end will retransmit
  64          * if it was important.
  65          */
  66         skb->sk = NULL;
  67         kfree_skb(skb, FREE_READ);
  68         return(0);
  69   }
  70   sk->inuse = 1;
  71   sti();
  72   skb->sk = sk;
  73 
  74   /* Charge it too the socket. */
  75   if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX) {
  76         skb->sk = NULL;
  77         kfree_skb(skb, FREE_READ);
  78         return(0);
  79   }
  80   sk->rmem_alloc += skb->mem_len;
  81 
  82   /* Now just put it onto the queue. */
  83   if (sk->rqueue == NULL) {
  84         sk->rqueue = skb;
  85         skb->next = skb;
  86         skb->prev = skb;
  87   } else {
  88         skb->next = sk->rqueue;
  89         skb->prev = sk->rqueue->prev;
  90         skb->prev->next = skb;
  91         skb->next->prev = skb;
  92   }
  93   wake_up(sk->sleep);
  94   release_sock(sk);
  95   return(0);
  96 }
  97 
  98 
  99 /* This will do terrible things if len + ipheader + devheader > dev->mtu */
 100 static int
 101 packet_sendto(struct sock *sk, unsigned char *from, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 102               int noblock, unsigned flags, struct sockaddr_in *usin,
 103               int addr_len)
 104 {
 105   struct sk_buff *skb;
 106   struct device *dev;
 107   struct sockaddr saddr;
 108 
 109   /* Check the flags. */
 110   if (flags) return(-EINVAL);
 111   if (len < 0) return(-EINVAL);
 112 
 113   /* Get and verify the address. */
 114   if (usin) {
 115         if (addr_len < sizeof(saddr)) return(-EINVAL);
 116         /* verify_area(VERIFY_WRITE, usin, sizeof(saddr));*/
 117         memcpy_fromfs(&saddr, usin, sizeof(saddr));
 118   } else
 119         return(-EINVAL);
 120 
 121   skb = (struct sk_buff *) sk->prot->wmalloc(sk, len+sizeof(*skb), 0, GFP_KERNEL);
 122 
 123   /* This shouldn't happen, but it could. */
 124   if (skb == NULL) {
 125         DPRINTF((DBG_PKT, "packet_sendto: write buffer full?\n"));
 126         return(-EAGAIN);
 127   }
 128   skb->lock = 0;
 129   skb->mem_addr = skb;
 130   skb->mem_len = len + sizeof(*skb);
 131   skb->sk = sk;
 132   skb->free = 1;
 133   saddr.sa_data[13] = 0;
 134   dev = dev_get(saddr.sa_data);
 135   if (dev == NULL) {
 136         sk->prot->wfree(sk, skb->mem_addr, skb->mem_len);
 137         return(-ENXIO);
 138   }
 139   /* verify_area(VERIFY_WRITE, from, len);*/
 140   memcpy_fromfs (skb+1, from, len);
 141   skb->len = len;
 142   skb->next = NULL;
 143   if (dev->flags & IFF_UP) dev->queue_xmit(skb, dev, sk->priority);
 144     else kfree_skb(skb, FREE_WRITE);
 145   return(len);
 146 }
 147 
 148 
 149 static int
 150 packet_write(struct sock *sk, unsigned char *buff, 
     /* [previous][next][first][last][top][bottom][index][help] */
 151              int len, int noblock,  unsigned flags)
 152 {
 153   return(packet_sendto(sk, buff, len, noblock, flags, NULL, 0));
 154 }
 155 
 156 
 157 static void
 158 packet_close(struct sock *sk, int timeout)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160   sk->inuse = 1;
 161   sk->state = TCP_CLOSE;
 162   dev_remove_pack((struct packet_type *)sk->pair);
 163   kfree_s((void *)sk->pair, sizeof(struct packet_type));
 164   sk->pair = NULL;
 165   release_sock(sk);
 166 }
 167 
 168 
 169 static int
 170 packet_init(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172   struct packet_type *p;
 173 
 174   p = (struct packet_type *) kmalloc(sizeof(*p), GFP_KERNEL);
 175   if (p == NULL) return(-ENOMEM);
 176 
 177   p->func = packet_rcv;
 178   p->type = sk->num;
 179   p->data = (void *)sk;
 180   dev_add_pack(p);
 181    
 182   /* We need to remember this somewhere. */
 183   sk->pair = (struct sock *)p;
 184 
 185   return(0);
 186 }
 187 
 188 
 189 /*
 190  * This should be easy, if there is something there
 191  * we return it, otherwise we block.
 192  */
 193 int
 194 packet_recvfrom(struct sock *sk, unsigned char *to, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 195                 int noblock, unsigned flags, struct sockaddr_in *sin,
 196                 int *addr_len)
 197 {
 198   int copied=0;
 199   struct sk_buff *skb;
 200   struct sockaddr *saddr;
 201 
 202   saddr = (struct sockaddr *)sin;
 203   if (len == 0) return(0);
 204   if (len < 0) return(-EINVAL);
 205 
 206   if (sk->shutdown & RCV_SHUTDOWN) return(0);
 207   if (addr_len) {
 208           verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
 209           put_fs_long(sizeof(*saddr), addr_len);
 210   }
 211   sk->inuse = 1;
 212   while (sk->rqueue == NULL) {
 213         if (noblock) {
 214                 release_sock(sk);
 215                 return(-EAGAIN);
 216         }
 217         release_sock(sk);
 218         cli();
 219         if (sk->rqueue == NULL) {
 220                 interruptible_sleep_on(sk->sleep);
 221                 if (current->signal & ~current->blocked) {
 222                         return(-ERESTARTSYS);
 223                 }
 224         }
 225         sk->inuse = 1;
 226         sti();
 227   }
 228   skb = sk->rqueue;
 229 
 230   if (!(flags & MSG_PEEK)) {
 231         if (skb->next == skb) {
 232                 sk->rqueue = NULL;
 233         } else {
 234                 sk->rqueue = (struct sk_buff *)sk->rqueue ->next;
 235                 skb->prev->next = skb->next;
 236                 skb->next->prev = skb->prev;
 237         }
 238   }
 239   copied = min(len, skb->len);
 240   verify_area(VERIFY_WRITE, to, copied);
 241   memcpy_tofs(to, skb+1, copied);
 242 
 243   /* Copy the address. */
 244   if (saddr) {
 245         struct sockaddr addr;
 246 
 247         addr.sa_family = skb->dev->type;
 248         memcpy(addr.sa_data,skb->dev->name, 14);
 249         verify_area(VERIFY_WRITE, saddr, sizeof(*saddr));
 250         memcpy_tofs(saddr, &addr, sizeof(*saddr));
 251   }
 252 
 253   if (!(flags & MSG_PEEK)) {
 254         kfree_skb(skb, FREE_READ);
 255   }
 256 
 257   release_sock(sk);
 258   return(copied);
 259 }
 260 
 261 
 262 int
 263 packet_read(struct sock *sk, unsigned char *buff,
     /* [previous][next][first][last][top][bottom][index][help] */
 264             int len, int noblock, unsigned flags)
 265 {
 266   return(packet_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
 267 }
 268 
 269 
 270 struct proto packet_prot = {
 271   sock_wmalloc,
 272   sock_rmalloc,
 273   sock_wfree,
 274   sock_rfree,
 275   sock_rspace,
 276   sock_wspace,
 277   packet_close,
 278   packet_read,
 279   packet_write,
 280   packet_sendto,
 281   packet_recvfrom,
 282   ip_build_header,
 283   udp_connect,
 284   NULL,
 285   ip_queue_xmit,
 286   ip_retransmit,
 287   NULL,
 288   NULL,
 289   NULL, 
 290   udp_select,
 291   NULL,
 292   packet_init,
 293   NULL,
 294   128,
 295   0,
 296   {NULL,},
 297   "PACKET"
 298 };

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