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 
  26 #include <asm/segment.h>
  27 #include <asm/system.h>
  28 #include <linux/types.h>
  29 #include <linux/kernel.h>
  30 #include <linux/sched.h>
  31 #include <linux/string.h>
  32 #include <linux/config.h>
  33 #include <linux/socket.h>
  34 #include <linux/in.h>
  35 #include <linux/inet.h>
  36 #include <linux/netdevice.h>
  37 #include <linux/timer.h>
  38 #include <net/ip.h>
  39 #include <net/protocol.h>
  40 #include <net/tcp.h>
  41 #include <linux/skbuff.h>
  42 #include <net/sock.h>
  43 #include <net/icmp.h>
  44 #include <net/udp.h>
  45 #include <net/ipip.h>
  46 #include <linux/igmp.h>
  47 
  48 
  49 #ifdef CONFIG_IP_FORWARD
  50 #ifdef CONFIG_NET_IPIP
  51 
  52 static struct inet_protocol ipip_protocol = 
  53 {
  54         ipip_rcv,             /* IPIP handler          */
  55         NULL,                 /* TUNNEL error control    */
  56         0,                    /* next                 */
  57         IPPROTO_IPIP,         /* protocol ID          */
  58         0,                    /* copy                 */
  59         NULL,                 /* data                 */
  60         "IPIP"                /* name                 */
  61 };
  62 
  63 
  64 #endif
  65 #endif
  66 
  67 static struct inet_protocol tcp_protocol = 
  68 {
  69         tcp_rcv,                /* TCP handler          */
  70         tcp_err,                /* TCP error control    */  
  71 #if defined(CONFIG_NET_IPIP) && defined(CONFIG_IP_FORWARD)
  72         &ipip_protocol,
  73 #else  
  74         NULL,                   /* next                 */
  75 #endif  
  76         IPPROTO_TCP,            /* protocol ID          */
  77         0,                      /* copy                 */
  78         NULL,                   /* data                 */
  79         "TCP"                   /* name                 */
  80 };
  81 
  82 
  83 static struct inet_protocol udp_protocol = 
  84 {
  85         udp_rcv,                /* UDP handler          */
  86         udp_err,                /* UDP error control    */
  87         &tcp_protocol,          /* next                 */
  88         IPPROTO_UDP,            /* protocol ID          */
  89         0,                      /* copy                 */
  90         NULL,                   /* data                 */
  91         "UDP"                   /* name                 */
  92 };
  93 
  94 
  95 static struct inet_protocol icmp_protocol = 
  96 {
  97         icmp_rcv,               /* ICMP handler         */
  98         NULL,                   /* ICMP error control   */
  99         &udp_protocol,          /* next                 */
 100         IPPROTO_ICMP,           /* protocol ID          */
 101         0,                      /* copy                 */
 102         NULL,                   /* data                 */
 103         "ICMP"                  /* name                 */
 104 };
 105 
 106 #ifndef CONFIG_IP_MULTICAST
 107 struct inet_protocol *inet_protocol_base = &icmp_protocol;
 108 #else
 109 static struct inet_protocol igmp_protocol = 
 110 {
 111         igmp_rcv,               /* IGMP handler         */
 112         NULL,                   /* IGMP error control   */
 113         &icmp_protocol,         /* next                 */
 114         IPPROTO_IGMP,           /* protocol ID          */
 115         0,                      /* copy                 */
 116         NULL,                   /* data                 */
 117         "IGMP"                  /* name                 */
 118 };
 119 
 120 struct inet_protocol *inet_protocol_base = &igmp_protocol;
 121 #endif
 122 
 123 struct inet_protocol *inet_protos[MAX_INET_PROTOS] = 
 124 {
 125         NULL
 126 };
 127 
 128 
 129 /*
 130  *      Find a protocol in the protocol tables given its
 131  *      IP type.
 132  */
 133 
 134 struct inet_protocol *inet_get_protocol(unsigned char prot)
     /* [previous][next][first][last][top][bottom][index][help] */
 135 {
 136         unsigned char hash;
 137         struct inet_protocol *p;
 138 
 139         hash = prot & (MAX_INET_PROTOS - 1);
 140         for (p = inet_protos[hash] ; p != NULL; p=p->next) 
 141         {
 142                 if (p->protocol == prot) 
 143                         return((struct inet_protocol *) p);
 144         }
 145         return(NULL);
 146 }
 147 
 148 /*
 149  *      Add a protocol handler to the hash tables
 150  */
 151 
 152 void inet_add_protocol(struct inet_protocol *prot)
     /* [previous][next][first][last][top][bottom][index][help] */
 153 {
 154         unsigned char hash;
 155         struct inet_protocol *p2;
 156 
 157         hash = prot->protocol & (MAX_INET_PROTOS - 1);
 158         prot ->next = inet_protos[hash];
 159         inet_protos[hash] = prot;
 160         prot->copy = 0;
 161 
 162         /*
 163          *      Set the copy bit if we need to. 
 164          */
 165          
 166         p2 = (struct inet_protocol *) prot->next;
 167         while(p2 != NULL) 
 168         {
 169                 if (p2->protocol == prot->protocol) 
 170                 {
 171                         prot->copy = 1;
 172                         break;
 173                 }
 174                 p2 = (struct inet_protocol *) p2->next;
 175         }
 176 }
 177 
 178 /*
 179  *      Remove a protocol from the hash tables.
 180  */
 181  
 182 int inet_del_protocol(struct inet_protocol *prot)
     /* [previous][next][first][last][top][bottom][index][help] */
 183 {
 184         struct inet_protocol *p;
 185         struct inet_protocol *lp = NULL;
 186         unsigned char hash;
 187 
 188         hash = prot->protocol & (MAX_INET_PROTOS - 1);
 189         if (prot == inet_protos[hash]) 
 190         {
 191                 inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next;
 192                 return(0);
 193         }
 194 
 195         p = (struct inet_protocol *) inet_protos[hash];
 196         while(p != NULL) 
 197         {
 198                 /*
 199                  * We have to worry if the protocol being deleted is
 200                  * the last one on the list, then we may need to reset
 201                  * someone's copied bit.
 202                  */
 203                 if (p->next != NULL && p->next == prot) 
 204                 {
 205                         /*
 206                          * if we are the last one with this protocol and
 207                          * there is a previous one, reset its copy bit.
 208                          */
 209                         if (p->copy == 0 && lp != NULL) 
 210                                 lp->copy = 0;
 211                         p->next = prot->next;
 212                         return(0);
 213                 }
 214                 if (p->next != NULL && p->next->protocol == prot->protocol) 
 215                         lp = p;
 216 
 217                 p = (struct inet_protocol *) p->next;
 218         }
 219         return(-1);
 220 }

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