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

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