home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / net / inet / raw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-06  |  9.3 KB  |  411 lines

  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.  *        RAW - implementation of IP "raw" sockets.
  7.  *
  8.  * Version:    @(#)raw.c    1.0.4    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() fixed up
  15.  *        Alan Cox    :    ICMP error handling
  16.  *        Alan Cox    :    EMSGSIZE if you send too big a packet
  17.  *        Alan Cox    :     Now uses generic datagrams and shared skbuff
  18.  *                    library. No more peek crashes, no more backlogs
  19.  *        Alan Cox    :    Checks sk->broadcast.
  20.  *        Alan Cox    :    Uses skb_free_datagram/skb_copy_datagram
  21.  *        Alan Cox    :    Raw passes ip options too
  22.  *        Alan Cox    :    Setsocketopt added
  23.  *        Alan Cox    :    Fixed error return for broadcasts
  24.  *        Alan Cox    :    Removed wake_up calls
  25.  *        Alan Cox    :    Use ttl/tos
  26.  *
  27.  *        This program is free software; you can redistribute it and/or
  28.  *        modify it under the terms of the GNU General Public License
  29.  *        as published by the Free Software Foundation; either version
  30.  *        2 of the License, or (at your option) any later version.
  31.  */
  32. #include <asm/system.h>
  33. #include <asm/segment.h>
  34. #include <linux/types.h>
  35. #include <linux/sched.h>
  36. #include <linux/errno.h>
  37. #include <linux/timer.h>
  38. #include <linux/mm.h>
  39. #include <linux/kernel.h>
  40. #include <linux/fcntl.h>
  41. #include <linux/socket.h>
  42. #include <linux/in.h>
  43. #include "inet.h"
  44. #include "dev.h"
  45. #include "ip.h"
  46. #include "protocol.h"
  47. #include "tcp.h"
  48. #include "skbuff.h"
  49. #include "sock.h"
  50. #include "icmp.h"
  51. #include "udp.h"
  52.  
  53.  
  54. static unsigned long
  55. min(unsigned long a, unsigned long b)
  56. {
  57.   if (a < b) return(a);
  58.   return(b);
  59. }
  60.  
  61.  
  62. /* raw_err gets called by the icmp module. */
  63. void
  64. raw_err (int err, unsigned char *header, unsigned long daddr,
  65.      unsigned long saddr, struct inet_protocol *protocol)
  66. {
  67.   struct sock *sk;
  68.    
  69.   DPRINTF((DBG_RAW, "raw_err(err=%d, hdr=%X, daddr=%X, saddr=%X, protocl=%X)\n",
  70.         err, header, daddr, saddr, protocol));
  71.  
  72.   if (protocol == NULL) return;
  73.   sk = (struct sock *) protocol->data;
  74.   if (sk == NULL) return;
  75.  
  76.   /* This is meaningless in raw sockets. */
  77.   if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8)) {
  78.     if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2;
  79.     return;
  80.   }
  81.  
  82.   sk->err = icmp_err_convert[err & 0xff].errno;
  83.   sk->error_report(sk);
  84.   
  85.   return;
  86. }
  87.  
  88.  
  89. /*
  90.  * This should be the easiest of all, all we do is\
  91.  * copy it into a buffer.
  92.  */
  93. int
  94. raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
  95.     unsigned long daddr, unsigned short len, unsigned long saddr,
  96.     int redo, struct inet_protocol *protocol)
  97. {
  98.   struct sock *sk;
  99.  
  100.   DPRINTF((DBG_RAW, "raw_rcv(skb=%X, dev=%X, opt=%X, daddr=%X,\n"
  101.        "         len=%d, saddr=%X, redo=%d, protocol=%X)\n",
  102.        skb, dev, opt, daddr, len, saddr, redo, protocol));
  103.  
  104.   if (skb == NULL) return(0);
  105.   if (protocol == NULL) {
  106.     kfree_skb(skb, FREE_READ);
  107.     return(0);
  108.   }
  109.   sk = (struct sock *) protocol->data;
  110.   if (sk == NULL) {
  111.     kfree_skb(skb, FREE_READ);
  112.     return(0);
  113.   }
  114.  
  115.   /* Now we need to copy this into memory. */
  116.   skb->sk = sk;
  117.   skb->len = len + skb->ip_hdr->ihl*sizeof(long);
  118.   skb->h.raw = (unsigned char *) skb->ip_hdr;
  119.   skb->dev = dev;
  120.   skb->saddr = daddr;
  121.   skb->daddr = saddr;
  122.  
  123.   /* Charge it too the socket. */
  124.   if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) {
  125.     skb->sk = NULL;
  126.     kfree_skb(skb, FREE_READ);
  127.     return(0);
  128.   }
  129.   sk->rmem_alloc += skb->mem_len;
  130.   skb_queue_tail(&sk->rqueue,skb);
  131.   sk->data_ready(sk,skb->len);
  132.   release_sock(sk);
  133.   return(0);
  134. }
  135.  
  136.  
  137. /* This will do terrible things if len + ipheader + devheader > dev->mtu */
  138. static int
  139. raw_sendto(struct sock *sk, unsigned char *from, int len,
  140.        int noblock,
  141.        unsigned flags, struct sockaddr_in *usin, int addr_len)
  142. {
  143.   struct sk_buff *skb;
  144.   struct device *dev=NULL;
  145.   struct sockaddr_in sin;
  146.   int tmp;
  147.   int err;
  148.  
  149.   DPRINTF((DBG_RAW, "raw_sendto(sk=%X, from=%X, len=%d, noblock=%d, flags=%X,\n"
  150.        "            usin=%X, addr_len = %d)\n", sk, from, len, noblock,
  151.        flags, usin, addr_len));
  152.  
  153.   /* Check the flags. */
  154.   if (flags) return(-EINVAL);
  155.   if (len < 0) return(-EINVAL);
  156.  
  157.   err=verify_area(VERIFY_READ,from,len);
  158.   if(err)
  159.       return err;
  160.   /* Get and verify the address. */
  161.   if (usin) {
  162.     if (addr_len < sizeof(sin)) return(-EINVAL);
  163.     err=verify_area (VERIFY_READ, usin, sizeof (sin));
  164.     if(err)
  165.         return err;
  166.     memcpy_fromfs(&sin, usin, sizeof(sin));
  167.     if (sin.sin_family && sin.sin_family != AF_INET) return(-EINVAL);
  168.   } else {
  169.     if (sk->state != TCP_ESTABLISHED) return(-EINVAL);
  170.     sin.sin_family = AF_INET;
  171.     sin.sin_port = sk->protocol;
  172.     sin.sin_addr.s_addr = sk->daddr;
  173.   }
  174.   if (sin.sin_port == 0) sin.sin_port = sk->protocol;
  175.   
  176.   if (sk->broadcast == 0 && chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
  177.       return -EACCES;
  178.  
  179.   sk->inuse = 1;
  180.   skb = NULL;
  181.   while (skb == NULL) {
  182.       if(sk->err!=0)
  183.       {
  184.           err= -sk->err;
  185.           sk->err=0;
  186.           release_sock(sk);
  187.           return(err);
  188.       }
  189.       
  190.     skb = sk->prot->wmalloc(sk,
  191.             len+sizeof(*skb) + sk->prot->max_header,
  192.             0, GFP_KERNEL);
  193.     if (skb == NULL) {
  194.         int tmp;
  195.  
  196.         DPRINTF((DBG_RAW, "raw_sendto: write buffer full?\n"));
  197.         if (noblock) 
  198.             return(-EAGAIN);
  199.         tmp = sk->wmem_alloc;
  200.         release_sock(sk);
  201.         cli();
  202.         if (tmp <= sk->wmem_alloc) {
  203.             interruptible_sleep_on(sk->sleep);
  204.             if (current->signal & ~current->blocked) {
  205.                 sti();
  206.                 return(-ERESTARTSYS);
  207.             }
  208.         }
  209.         sk->inuse = 1;
  210.         sti();
  211.     }
  212.   }
  213.   skb->mem_addr = skb;
  214.   skb->mem_len = len + sizeof(*skb) +sk->prot->max_header;
  215.   skb->sk = sk;
  216.  
  217.   skb->free = 1; /* these two should be unecessary. */
  218.   skb->arp = 0;
  219.  
  220.   tmp = sk->prot->build_header(skb, sk->saddr, 
  221.                    sin.sin_addr.s_addr, &dev,
  222.                    sk->protocol, sk->opt, skb->mem_len, sk->ip_tos,sk->ip_ttl);
  223.   if (tmp < 0) {
  224.     DPRINTF((DBG_RAW, "raw_sendto: error building ip header.\n"));
  225.     kfree_skb(skb,FREE_WRITE);
  226.     release_sock(sk);
  227.     return(tmp);
  228.   }
  229.  
  230.   /* verify_area(VERIFY_WRITE, from, len);*/
  231.   memcpy_fromfs(skb->data + tmp, from, len);
  232.  
  233.   /* If we are using IPPROTO_RAW, we need to fill in the source address in
  234.      the IP header */
  235.  
  236.   if(sk->protocol==IPPROTO_RAW) {
  237.     unsigned char *buff;
  238.     struct iphdr *iph;
  239.  
  240.     buff = skb->data;
  241.     buff += tmp;
  242.     iph = (struct iphdr *)buff;
  243.     iph->saddr = sk->saddr;
  244.   }
  245.  
  246.   skb->len = tmp + len;
  247.   
  248.   if(dev!=NULL && skb->len > 4095)
  249.   {
  250.       kfree_skb(skb, FREE_WRITE);
  251.       release_sock(sk);
  252.       return(-EMSGSIZE);
  253.   }
  254.   
  255.   sk->prot->queue_xmit(sk, dev, skb, 1);
  256.   release_sock(sk);
  257.   return(len);
  258. }
  259.  
  260.  
  261. static int
  262. raw_write(struct sock *sk, unsigned char *buff, int len, int noblock,
  263.        unsigned flags)
  264. {
  265.   return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
  266. }
  267.  
  268.  
  269. static void
  270. raw_close(struct sock *sk, int timeout)
  271. {
  272.   sk->inuse = 1;
  273.   sk->state = TCP_CLOSE;
  274.  
  275.   DPRINTF((DBG_RAW, "raw_close: deleting protocol %d\n",
  276.        ((struct inet_protocol *)sk->pair)->protocol));
  277.  
  278.   if (inet_del_protocol((struct inet_protocol *)sk->pair) < 0)
  279.         DPRINTF((DBG_RAW, "raw_close: del_protocol failed.\n"));
  280.   kfree_s((void *)sk->pair, sizeof (struct inet_protocol));
  281.   sk->pair = NULL;
  282.   release_sock(sk);
  283. }
  284.  
  285.  
  286. static int
  287. raw_init(struct sock *sk)
  288. {
  289.   struct inet_protocol *p;
  290.  
  291.   p = (struct inet_protocol *) kmalloc(sizeof (*p), GFP_KERNEL);
  292.   if (p == NULL) return(-ENOMEM);
  293.  
  294.   p->handler = raw_rcv;
  295.   p->protocol = sk->protocol;
  296.   p->data = (void *)sk;
  297.   p->err_handler = raw_err;
  298.   p->name="USER";
  299.   p->frag_handler = NULL;    /* For now */
  300.   inet_add_protocol(p);
  301.    
  302.   /* We need to remember this somewhere. */
  303.   sk->pair = (struct sock *)p;
  304.  
  305.   DPRINTF((DBG_RAW, "raw init added protocol %d\n", sk->protocol));
  306.  
  307.   return(0);
  308. }
  309.  
  310.  
  311. /*
  312.  * This should be easy, if there is something there
  313.  * we return it, otherwise we block.
  314.  */
  315. int
  316. raw_recvfrom(struct sock *sk, unsigned char *to, int len,
  317.          int noblock, unsigned flags, struct sockaddr_in *sin,
  318.          int *addr_len)
  319. {
  320.   int copied=0;
  321.   struct sk_buff *skb;
  322.   int err;
  323.  
  324.   DPRINTF((DBG_RAW, "raw_recvfrom (sk=%X, to=%X, len=%d, noblock=%d, flags=%X,\n"
  325.        "              sin=%X, addr_len=%X)\n",
  326.         sk, to, len, noblock, flags, sin, addr_len));
  327.  
  328.   if (len == 0) return(0);
  329.   if (len < 0) return(-EINVAL);
  330.  
  331.   if (sk->shutdown & RCV_SHUTDOWN) return(0);
  332.   if (addr_len) {
  333.     err=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
  334.     if(err)
  335.         return err;
  336.     put_fs_long(sizeof(*sin), addr_len);
  337.   }
  338.   if(sin)
  339.   {
  340.       err=verify_area(VERIFY_WRITE, sin, sizeof(*sin));
  341.     if(err)
  342.         return err;
  343.   }
  344.   
  345.   err=verify_area(VERIFY_WRITE,to,len);
  346.   if(err)
  347.       return err;
  348.  
  349.   skb=skb_recv_datagram(sk,flags,noblock,&err);
  350.   if(skb==NULL)
  351.       return err;
  352.  
  353.   copied = min(len, skb->len);
  354.   
  355.   skb_copy_datagram(skb, 0, to, copied);
  356.  
  357.   /* Copy the address. */
  358.   if (sin) {
  359.     struct sockaddr_in addr;
  360.  
  361.     addr.sin_family = AF_INET;
  362.     addr.sin_addr.s_addr = skb->daddr;
  363.     memcpy_tofs(sin, &addr, sizeof(*sin));
  364.   }
  365.  
  366.   skb_free_datagram(skb);
  367.   release_sock(sk);
  368.   return (copied);
  369. }
  370.  
  371.  
  372. int
  373. raw_read (struct sock *sk, unsigned char *buff, int len, int noblock,
  374.       unsigned flags)
  375. {
  376.   return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
  377. }
  378.  
  379.  
  380. struct proto raw_prot = {
  381.   sock_wmalloc,
  382.   sock_rmalloc,
  383.   sock_wfree,
  384.   sock_rfree,
  385.   sock_rspace,
  386.   sock_wspace,
  387.   raw_close,
  388.   raw_read,
  389.   raw_write,
  390.   raw_sendto,
  391.   raw_recvfrom,
  392.   ip_build_header,
  393.   udp_connect,
  394.   NULL,
  395.   ip_queue_xmit,
  396.   ip_retransmit,
  397.   NULL,
  398.   NULL,
  399.   raw_rcv,
  400.   datagram_select,
  401.   NULL,
  402.   raw_init,
  403.   NULL,
  404.   ip_setsockopt,
  405.   ip_getsockopt,
  406.   128,
  407.   0,
  408.   {NULL,},
  409.   "RAW"
  410. };
  411.