1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 <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#define IPPROTO_PREVIOUS NULL
49
50#ifdef CONFIG_IP_MULTICAST
51
52static struct inet_protocol igmp_protocol =
53{
54 igmp_rcv,
55 NULL,
56 IPPROTO_PREVIOUS,
57 IPPROTO_IGMP,
58 0,
59 NULL,
60 "IGMP"
61};
62
63#undef IPPROTO_PREVIOUS
64#define IPPROTO_PREVIOUS &igmp_protocol
65
66#endif
67
68static struct inet_protocol tcp_protocol =
69{
70 tcp_v4_rcv,
71 tcp_v4_err,
72 IPPROTO_PREVIOUS,
73 IPPROTO_TCP,
74 0,
75 NULL,
76 "TCP"
77};
78
79#undef IPPROTO_PREVIOUS
80#define IPPROTO_PREVIOUS &tcp_protocol
81
82static struct inet_protocol udp_protocol =
83{
84 udp_rcv,
85 udp_err,
86 IPPROTO_PREVIOUS,
87 IPPROTO_UDP,
88 0,
89 NULL,
90 "UDP"
91};
92
93#undef IPPROTO_PREVIOUS
94#define IPPROTO_PREVIOUS &udp_protocol
95
96
97static struct inet_protocol icmp_protocol =
98{
99 icmp_rcv,
100 NULL,
101 IPPROTO_PREVIOUS,
102 IPPROTO_ICMP,
103 0,
104 NULL,
105 "ICMP"
106};
107
108#undef IPPROTO_PREVIOUS
109#define IPPROTO_PREVIOUS &icmp_protocol
110
111
112struct inet_protocol *inet_protocol_base = IPPROTO_PREVIOUS;
113
114struct inet_protocol *inet_protos[MAX_INET_PROTOS] =
115{
116 NULL
117};
118
119
120
121
122
123
124
125struct inet_protocol *inet_get_protocol(unsigned char prot)
126{
127 unsigned char hash;
128 struct inet_protocol *p;
129
130 hash = prot & (MAX_INET_PROTOS - 1);
131 for (p = inet_protos[hash] ; p != NULL; p=p->next)
132 {
133 if (p->protocol == prot)
134 return((struct inet_protocol *) p);
135 }
136 return(NULL);
137}
138
139
140
141
142
143void inet_add_protocol(struct inet_protocol *prot)
144{
145 unsigned char hash;
146 struct inet_protocol *p2;
147
148 hash = prot->protocol & (MAX_INET_PROTOS - 1);
149 prot ->next = inet_protos[hash];
150 inet_protos[hash] = prot;
151 prot->copy = 0;
152
153
154
155
156
157 p2 = (struct inet_protocol *) prot->next;
158 while(p2 != NULL)
159 {
160 if (p2->protocol == prot->protocol)
161 {
162 prot->copy = 1;
163 break;
164 }
165 p2 = (struct inet_protocol *) p2->next;
166 }
167}
168
169
170
171
172
173int inet_del_protocol(struct inet_protocol *prot)
174{
175 struct inet_protocol *p;
176 struct inet_protocol *lp = NULL;
177 unsigned char hash;
178
179 hash = prot->protocol & (MAX_INET_PROTOS - 1);
180 if (prot == inet_protos[hash])
181 {
182 inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next;
183 return(0);
184 }
185
186 p = (struct inet_protocol *) inet_protos[hash];
187 while(p != NULL)
188 {
189
190
191
192
193
194 if (p->next != NULL && p->next == prot)
195 {
196
197
198
199
200 if (p->copy == 0 && lp != NULL)
201 lp->copy = 0;
202 p->next = prot->next;
203 return(0);
204 }
205 if (p->next != NULL && p->next->protocol == prot->protocol)
206 lp = p;
207
208 p = (struct inet_protocol *) p->next;
209 }
210 return(-1);
211}
212