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 / protocol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  3.9 KB  |  162 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.  *        INET protocol dispatch tables.
  7.  *
  8.  * Version:    @(#)protocol.c    1.0.5    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    : Ahah! udp icmp errors don't work because
  15.  *                  udp_err is never called!
  16.  *        Alan Cox    : Added new fields for init and ready for
  17.  *                  proper fragmentation (_NO_ 4K limits!)
  18.  *
  19.  *        This program is free software; you can redistribute it and/or
  20.  *        modify it under the terms of the GNU General Public License
  21.  *        as published by the Free Software Foundation; either version
  22.  *        2 of the License, or (at your option) any later version.
  23.  */
  24. #include <asm/segment.h>
  25. #include <asm/system.h>
  26. #include <linux/types.h>
  27. #include <linux/kernel.h>
  28. #include <linux/sched.h>
  29. #include <linux/string.h>
  30. #include <linux/socket.h>
  31. #include <linux/in.h>
  32. #include "inet.h"
  33. #include "dev.h"
  34. #include "ip.h"
  35. #include "protocol.h"
  36. #include "tcp.h"
  37. #include "skbuff.h"
  38. #include "sock.h"
  39. #include "icmp.h"
  40. #include "udp.h"
  41.  
  42.  
  43. static struct inet_protocol tcp_protocol = {
  44.   tcp_rcv,        /* TCP handler        */
  45.   NULL,            /* No fragment handler (and won't be for a long time) */
  46.   tcp_err,        /* TCP error control    */
  47.   NULL,            /* next            */
  48.   IPPROTO_TCP,        /* protocol ID        */
  49.   0,            /* copy            */
  50.   NULL,            /* data            */
  51.   "TCP"            /* name            */
  52. };
  53.  
  54.  
  55. static struct inet_protocol udp_protocol = {
  56.   udp_rcv,        /* UDP handler        */
  57.   NULL,            /* Will be UDP fraglist handler */
  58.   udp_err,        /* UDP error control    */
  59.   &tcp_protocol,    /* next            */
  60.   IPPROTO_UDP,        /* protocol ID        */
  61.   0,            /* copy            */
  62.   NULL,            /* data            */
  63.   "UDP"            /* name            */
  64. };
  65.  
  66.  
  67. static struct inet_protocol icmp_protocol = {
  68.   icmp_rcv,        /* ICMP handler        */
  69.   NULL,            /* ICMP never fragments anyway */
  70.   NULL,            /* ICMP error control    */
  71.   &udp_protocol,    /* next            */
  72.   IPPROTO_ICMP,        /* protocol ID        */
  73.   0,            /* copy            */
  74.   NULL,            /* data            */
  75.   "ICMP"        /* name            */
  76. };
  77.  
  78.  
  79. struct inet_protocol *inet_protocol_base = &icmp_protocol;
  80. struct inet_protocol *inet_protos[MAX_INET_PROTOS] = {
  81.   NULL
  82. };
  83.  
  84.  
  85. struct inet_protocol *
  86. inet_get_protocol(unsigned char prot)
  87. {
  88.   unsigned char hash;
  89.   struct inet_protocol *p;
  90.  
  91.   DPRINTF((DBG_PROTO, "get_protocol (%d)\n ", prot));
  92.   hash = prot & (MAX_INET_PROTOS - 1);
  93.   for (p = inet_protos[hash] ; p != NULL; p=p->next) {
  94.     DPRINTF((DBG_PROTO, "trying protocol %d\n", p->protocol));
  95.     if (p->protocol == prot) return((struct inet_protocol *) p);
  96.   }
  97.   return(NULL);
  98. }
  99.  
  100.  
  101. void
  102. inet_add_protocol(struct inet_protocol *prot)
  103. {
  104.   unsigned char hash;
  105.   struct inet_protocol *p2;
  106.  
  107.   hash = prot->protocol & (MAX_INET_PROTOS - 1);
  108.   prot ->next = inet_protos[hash];
  109.   inet_protos[hash] = prot;
  110.   prot->copy = 0;
  111.  
  112.   /* Set the copy bit if we need to. */
  113.   p2 = (struct inet_protocol *) prot->next;
  114.   while(p2 != NULL) {
  115.     if (p2->protocol == prot->protocol) {
  116.         prot->copy = 1;
  117.         break;
  118.     }
  119.     p2 = (struct inet_protocol *) prot->next;
  120.   }
  121. }
  122.  
  123.  
  124. int
  125. inet_del_protocol(struct inet_protocol *prot)
  126. {
  127.   struct inet_protocol *p;
  128.   struct inet_protocol *lp = NULL;
  129.   unsigned char hash;
  130.  
  131.   hash = prot->protocol & (MAX_INET_PROTOS - 1);
  132.   if (prot == inet_protos[hash]) {
  133.     inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next;
  134.     return(0);
  135.   }
  136.  
  137.   p = (struct inet_protocol *) inet_protos[hash];
  138.   while(p != NULL) {
  139.     /*
  140.      * We have to worry if the protocol being deleted is
  141.      * the last one on the list, then we may need to reset
  142.      * someones copied bit.
  143.      */
  144.     if (p->next != NULL && p->next == prot) {
  145.         /*
  146.          * if we are the last one with this protocol and
  147.          * there is a previous one, reset its copy bit.
  148.          */
  149.          if (p->copy == 0 && lp != NULL) lp->copy = 0;
  150.          p->next = prot->next;
  151.          return(0);
  152.     }
  153.  
  154.     if (p->next != NULL && p->next->protocol == prot->protocol) {
  155.         lp = p;
  156.     }
  157.  
  158.     p = (struct inet_protocol *) p->next;
  159.   }
  160.   return(-1);
  161. }
  162.