root/net/ipv4/protocol.c

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

DEFINITIONS

This source file includes following definitions.
  1. inet_get_protocol
  2. inet_add_protocol
  3. inet_del_protocol

   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  *              Richard Colella : Hang on hash collision
  19  *
  20  *              This program is free software; you can redistribute it and/or
  21  *              modify it under the terms of the GNU General Public License
  22  *              as published by the Free Software Foundation; either version
  23  *              2 of the License, or (at your option) any later version.
  24  */
  25 #include <asm/segment.h>
  26 #include <asm/system.h>
  27 #include <linux/types.h>
  28 #include <linux/kernel.h>
  29 #include <linux/sched.h>
  30 #include <linux/string.h>
  31 #include <linux/config.h>
  32 #include <linux/socket.h>
  33 #include <linux/in.h>
  34 #include <linux/inet.h>
  35 #include <linux/netdevice.h>
  36 #include <linux/timer.h>
  37 #include <net/ip.h>
  38 #include <net/protocol.h>
  39 #include <net/tcp.h>
  40 #include <linux/skbuff.h>
  41 #include <net/sock.h>
  42 #include <net/icmp.h>
  43 #include <net/udp.h>
  44 #include <net/ipip.h>
  45 #include <linux/igmp.h>
  46 
  47 
  48 #ifdef CONFIG_IP_FORWARD
  49 #ifdef CONFIG_NET_IPIP
  50 
  51 static struct inet_protocol ipip_protocol = {
  52   ipip_rcv,             /* IPIP handler          */
  53   NULL,                 /* Will be UDP fraglist handler */
  54   NULL,                 /* TUNNEL error control    */
  55   0,                    /* next                 */
  56   IPPROTO_IPIP,         /* protocol ID          */
  57   0,                    /* copy                 */
  58   NULL,                 /* data                 */
  59   "IPIP"                /* name                 */
  60 };
  61 
  62 
  63 #endif
  64 #endif
  65 
  66 static struct inet_protocol tcp_protocol = {
  67   tcp_rcv,              /* TCP handler          */
  68   NULL,                 /* No fragment handler (and won't be for a long time) */
  69   tcp_err,              /* TCP error control    */  
  70 #if defined(CONFIG_NET_IPIP) && defined(CONFIG_IP_FORWARD)
  71   &ipip_protocol,
  72 #else  
  73   NULL,                 /* next                 */
  74 #endif  
  75   IPPROTO_TCP,          /* protocol ID          */
  76   0,                    /* copy                 */
  77   NULL,                 /* data                 */
  78   "TCP"                 /* name                 */
  79 };
  80 
  81 
  82 static struct inet_protocol udp_protocol = {
  83   udp_rcv,              /* UDP handler          */
  84   NULL,                 /* Will be UDP fraglist handler */
  85   udp_err,              /* UDP error control    */
  86   &tcp_protocol,        /* next                 */
  87   IPPROTO_UDP,          /* protocol ID          */
  88   0,                    /* copy                 */
  89   NULL,                 /* data                 */
  90   "UDP"                 /* name                 */
  91 };
  92 
  93 
  94 static struct inet_protocol icmp_protocol = {
  95   icmp_rcv,             /* ICMP handler         */
  96   NULL,                 /* ICMP never fragments anyway */
  97   NULL,                 /* ICMP error control   */
  98   &udp_protocol,        /* next                 */
  99   IPPROTO_ICMP,         /* protocol ID          */
 100   0,                    /* copy                 */
 101   NULL,                 /* data                 */
 102   "ICMP"                /* name                 */
 103 };
 104 
 105 #ifndef CONFIG_IP_MULTICAST
 106 struct inet_protocol *inet_protocol_base = &icmp_protocol;
 107 #else
 108 static struct inet_protocol igmp_protocol = {
 109   igmp_rcv,             /* IGMP handler         */
 110   NULL,                 /* IGMP never fragments anyway */
 111   NULL,                 /* IGMP error control   */
 112   &icmp_protocol,       /* next                 */
 113   IPPROTO_IGMP,         /* protocol ID          */
 114   0,                    /* copy                 */
 115   NULL,                 /* data                 */
 116   "IGMP"                /* name                 */
 117 };
 118 
 119 struct inet_protocol *inet_protocol_base = &igmp_protocol;
 120 #endif
 121 
 122 struct inet_protocol *inet_protos[MAX_INET_PROTOS] = {
 123   NULL
 124 };
 125 
 126 
 127 struct inet_protocol *
 128 inet_get_protocol(unsigned char prot)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130   unsigned char hash;
 131   struct inet_protocol *p;
 132 
 133   hash = prot & (MAX_INET_PROTOS - 1);
 134   for (p = inet_protos[hash] ; p != NULL; p=p->next) {
 135         if (p->protocol == prot) return((struct inet_protocol *) p);
 136   }
 137   return(NULL);
 138 }
 139 
 140 
 141 void
 142 inet_add_protocol(struct inet_protocol *prot)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144   unsigned char hash;
 145   struct inet_protocol *p2;
 146 
 147   hash = prot->protocol & (MAX_INET_PROTOS - 1);
 148   prot ->next = inet_protos[hash];
 149   inet_protos[hash] = prot;
 150   prot->copy = 0;
 151 
 152   /* Set the copy bit if we need to. */
 153   p2 = (struct inet_protocol *) prot->next;
 154   while(p2 != NULL) {
 155         if (p2->protocol == prot->protocol) {
 156                 prot->copy = 1;
 157                 break;
 158         }
 159         p2 = (struct inet_protocol *) p2->next;
 160   }
 161 }
 162 
 163 
 164 int
 165 inet_del_protocol(struct inet_protocol *prot)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167   struct inet_protocol *p;
 168   struct inet_protocol *lp = NULL;
 169   unsigned char hash;
 170 
 171   hash = prot->protocol & (MAX_INET_PROTOS - 1);
 172   if (prot == inet_protos[hash]) {
 173         inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next;
 174         return(0);
 175   }
 176 
 177   p = (struct inet_protocol *) inet_protos[hash];
 178   while(p != NULL) {
 179         /*
 180          * We have to worry if the protocol being deleted is
 181          * the last one on the list, then we may need to reset
 182          * someone's copied bit.
 183          */
 184         if (p->next != NULL && p->next == prot) {
 185                 /*
 186                  * if we are the last one with this protocol and
 187                  * there is a previous one, reset its copy bit.
 188                  */
 189              if (p->copy == 0 && lp != NULL) lp->copy = 0;
 190              p->next = prot->next;
 191              return(0);
 192         }
 193 
 194         if (p->next != NULL && p->next->protocol == prot->protocol) {
 195                 lp = p;
 196         }
 197 
 198         p = (struct inet_protocol *) p->next;
 199   }
 200   return(-1);
 201 }

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