~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/ipv4/protocol.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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:     $Id: protocol.c,v 1.12 2000/10/03 07:29:00 anton Exp $
  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/uaccess.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 <linux/brlock.h>
 39 #include <net/ip.h>
 40 #include <net/protocol.h>
 41 #include <net/tcp.h>
 42 #include <linux/skbuff.h>
 43 #include <net/sock.h>
 44 #include <net/icmp.h>
 45 #include <net/udp.h>
 46 #include <net/ipip.h>
 47 #include <linux/igmp.h>
 48 
 49 #define IPPROTO_PREVIOUS NULL
 50 
 51 #ifdef CONFIG_IP_MULTICAST
 52 
 53 static struct inet_protocol igmp_protocol = 
 54 {
 55         igmp_rcv,               /* IGMP handler         */
 56         NULL,                   /* IGMP error control   */
 57         IPPROTO_PREVIOUS,       /* next                 */
 58         IPPROTO_IGMP,           /* protocol ID          */
 59         0,                      /* copy                 */
 60         NULL,                   /* data                 */
 61         "IGMP"                  /* name                 */
 62 };
 63 
 64 #undef  IPPROTO_PREVIOUS
 65 #define IPPROTO_PREVIOUS &igmp_protocol
 66 
 67 #endif
 68 
 69 static struct inet_protocol tcp_protocol = 
 70 {
 71         tcp_v4_rcv,             /* TCP handler          */
 72         tcp_v4_err,             /* TCP error control    */  
 73         IPPROTO_PREVIOUS,
 74         IPPROTO_TCP,            /* protocol ID          */
 75         0,                      /* copy                 */
 76         NULL,                   /* data                 */
 77         "TCP"                   /* name                 */
 78 };
 79 
 80 #undef  IPPROTO_PREVIOUS
 81 #define IPPROTO_PREVIOUS &tcp_protocol
 82 
 83 static struct inet_protocol udp_protocol = 
 84 {
 85         udp_rcv,                /* UDP handler          */
 86         udp_err,                /* UDP error control    */
 87         IPPROTO_PREVIOUS,       /* next                 */
 88         IPPROTO_UDP,            /* protocol ID          */
 89         0,                      /* copy                 */
 90         NULL,                   /* data                 */
 91         "UDP"                   /* name                 */
 92 };
 93 
 94 #undef  IPPROTO_PREVIOUS
 95 #define IPPROTO_PREVIOUS &udp_protocol
 96 
 97 
 98 static struct inet_protocol icmp_protocol = 
 99 {
100         icmp_rcv,               /* ICMP handler         */
101         NULL,                   /* ICMP error control   */
102         IPPROTO_PREVIOUS,       /* next                 */
103         IPPROTO_ICMP,           /* protocol ID          */
104         0,                      /* copy                 */
105         NULL,                   /* data                 */
106         "ICMP"                  /* name                 */
107 };
108 
109 #undef  IPPROTO_PREVIOUS
110 #define IPPROTO_PREVIOUS &icmp_protocol
111 
112 
113 struct inet_protocol *inet_protocol_base = IPPROTO_PREVIOUS;
114 
115 struct inet_protocol *inet_protos[MAX_INET_PROTOS];
116 
117 /*
118  *      Add a protocol handler to the hash tables
119  */
120 
121 void inet_add_protocol(struct inet_protocol *prot)
122 {
123         unsigned char hash;
124         struct inet_protocol *p2;
125 
126         hash = prot->protocol & (MAX_INET_PROTOS - 1);
127         br_write_lock_bh(BR_NETPROTO_LOCK);
128         prot ->next = inet_protos[hash];
129         inet_protos[hash] = prot;
130         prot->copy = 0;
131 
132         /*
133          *      Set the copy bit if we need to. 
134          */
135          
136         p2 = (struct inet_protocol *) prot->next;
137         while(p2 != NULL) 
138         {
139                 if (p2->protocol == prot->protocol) 
140                 {
141                         prot->copy = 1;
142                         break;
143                 }
144                 p2 = (struct inet_protocol *) p2->next;
145         }
146         br_write_unlock_bh(BR_NETPROTO_LOCK);
147 }
148 
149 /*
150  *      Remove a protocol from the hash tables.
151  */
152  
153 int inet_del_protocol(struct inet_protocol *prot)
154 {
155         struct inet_protocol *p;
156         struct inet_protocol *lp = NULL;
157         unsigned char hash;
158 
159         hash = prot->protocol & (MAX_INET_PROTOS - 1);
160         br_write_lock_bh(BR_NETPROTO_LOCK);
161         if (prot == inet_protos[hash]) 
162         {
163                 inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next;
164                 br_write_unlock_bh(BR_NETPROTO_LOCK);
165                 return(0);
166         }
167 
168         p = (struct inet_protocol *) inet_protos[hash];
169         while(p != NULL) 
170         {
171                 /*
172                  * We have to worry if the protocol being deleted is
173                  * the last one on the list, then we may need to reset
174                  * someone's copied bit.
175                  */
176                 if (p->next != NULL && p->next == prot) 
177                 {
178                         /*
179                          * if we are the last one with this protocol and
180                          * there is a previous one, reset its copy bit.
181                          */
182                         if (p->copy == 0 && lp != NULL) 
183                                 lp->copy = 0;
184                         p->next = prot->next;
185                         br_write_unlock_bh(BR_NETPROTO_LOCK);
186                         return(0);
187                 }
188                 if (p->next != NULL && p->next->protocol == prot->protocol) 
189                         lp = p;
190 
191                 p = (struct inet_protocol *) p->next;
192         }
193         br_write_unlock_bh(BR_NETPROTO_LOCK);
194         return(-1);
195 }
196 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.