This source file includes following definitions.
- min
- raw_err
- raw_rcv
- raw_getfrag
- raw_getrawfrag
- raw_sendto
- raw_write
- raw_close
- raw_init
- raw_recvmsg
- raw_recvfrom
- raw_read
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
27
28
29
30
31
32
33
34
35
36
37
38 #include <asm/system.h>
39 #include <asm/segment.h>
40 #include <linux/types.h>
41 #include <linux/sched.h>
42 #include <linux/errno.h>
43 #include <linux/timer.h>
44 #include <linux/mm.h>
45 #include <linux/kernel.h>
46 #include <linux/fcntl.h>
47 #include <linux/socket.h>
48 #include <linux/in.h>
49 #include <linux/inet.h>
50 #include <linux/netdevice.h>
51 #include <linux/mroute.h>
52 #include <net/ip.h>
53 #include <net/protocol.h>
54 #include <linux/skbuff.h>
55 #include <net/sock.h>
56 #include <net/icmp.h>
57 #include <net/udp.h>
58 #include <net/checksum.h>
59
60 #ifdef CONFIG_IP_MROUTE
61 struct sock *mroute_socket=NULL;
62 #endif
63
64 static inline unsigned long min(unsigned long a, unsigned long b)
65 {
66 if (a < b)
67 return(a);
68 return(b);
69 }
70
71
72
73
74
75
76 void raw_err (int type, int code, unsigned char *header, __u32 daddr,
77 __u32 saddr, struct inet_protocol *protocol)
78 {
79 struct sock *sk;
80
81 if (protocol == NULL)
82 return;
83 sk = (struct sock *) protocol->data;
84 if (sk == NULL)
85 return;
86
87
88 if (type == ICMP_SOURCE_QUENCH)
89 {
90 if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2;
91 return;
92 }
93
94 if(type == ICMP_PARAMETERPROB)
95 {
96 sk->err = EPROTO;
97 sk->error_report(sk);
98 }
99
100 if(code<13)
101 {
102 sk->err = icmp_err_convert[code & 0xff].errno;
103 sk->error_report(sk);
104 }
105
106 return;
107 }
108
109
110
111
112
113
114
115
116 int raw_rcv(struct sock *sk, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr)
117 {
118
119 skb->sk = sk;
120 skb_trim(skb,ntohs(skb->ip_hdr->tot_len));
121
122 skb->h.raw = (unsigned char *) skb->ip_hdr;
123 skb->dev = dev;
124 skb->saddr = daddr;
125 skb->daddr = saddr;
126
127
128
129 if(sock_queue_rcv_skb(sk,skb)<0)
130 {
131 ip_statistics.IpInDiscards++;
132 skb->sk=NULL;
133 kfree_skb(skb, FREE_READ);
134 return(0);
135 }
136
137 ip_statistics.IpInDelivers++;
138 release_sock(sk);
139 return(0);
140 }
141
142
143
144
145
146
147
148
149
150 static void raw_getfrag(const void *p, __u32 saddr, char *to, unsigned int offset, unsigned int fraglen)
151 {
152 memcpy_fromfs(to, (const unsigned char *)p+offset, fraglen);
153 }
154
155
156
157
158
159 static void raw_getrawfrag(const void *p, __u32 saddr, char *to, unsigned int offset, unsigned int fraglen)
160 {
161 memcpy_fromfs(to, (const unsigned char *)p+offset, fraglen);
162 if(offset==0)
163 {
164 struct iphdr *iph=(struct iphdr *)to;
165 iph->saddr=saddr;
166 iph->check=0;
167 iph->tot_len=htons(fraglen);
168
169
170
171
172
173 iph->id = htons(ip_id_count++);
174 iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
175 }
176 }
177
178 static int raw_sendto(struct sock *sk, const unsigned char *from,
179 int len, int noblock, unsigned flags, struct sockaddr_in *usin, int addr_len)
180 {
181 int err;
182 struct sockaddr_in sin;
183
184
185
186
187
188 if (flags & MSG_OOB)
189 return -EOPNOTSUPP;
190
191 if (flags & ~MSG_DONTROUTE)
192 return(-EINVAL);
193
194
195
196
197 if (usin)
198 {
199 if (addr_len < sizeof(sin))
200 return(-EINVAL);
201 memcpy(&sin, usin, sizeof(sin));
202 if (sin.sin_family && sin.sin_family != AF_INET)
203 return(-EINVAL);
204 }
205 else
206 {
207 if (sk->state != TCP_ESTABLISHED)
208 return(-EINVAL);
209 sin.sin_family = AF_INET;
210 sin.sin_port = sk->protocol;
211 sin.sin_addr.s_addr = sk->daddr;
212 }
213 if (sin.sin_port == 0)
214 sin.sin_port = sk->protocol;
215
216 if (sin.sin_addr.s_addr == INADDR_ANY)
217 sin.sin_addr.s_addr = ip_my_addr();
218
219 if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
220 return -EACCES;
221
222 if(sk->ip_hdrincl)
223 {
224 if(len>65535)
225 return -EMSGSIZE;
226 err=ip_build_xmit(sk, raw_getrawfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port, noblock);
227 }
228 else
229 {
230 if(len>65535-sizeof(struct iphdr))
231 return -EMSGSIZE;
232 err=ip_build_xmit(sk, raw_getfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port, noblock);
233 }
234 return err<0?err:len;
235 }
236
237
238 static int raw_write(struct sock *sk, const unsigned char *buff, int len, int noblock,
239 unsigned flags)
240 {
241 return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
242 }
243
244
245 static void raw_close(struct sock *sk, int timeout)
246 {
247 sk->state = TCP_CLOSE;
248 #ifdef CONFIG_IP_MROUTE
249 if(sk==mroute_socket)
250 {
251 mroute_close(sk);
252 mroute_socket=NULL;
253 }
254 #endif
255 }
256
257
258 static int raw_init(struct sock *sk)
259 {
260 return(0);
261 }
262
263
264
265
266
267
268
269 int raw_recvmsg(struct sock *sk, struct msghdr *msg, int len,
270 int noblock, int flags,int *addr_len)
271 {
272 int copied=0;
273 struct sk_buff *skb;
274 int err;
275 struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name;
276
277 if (flags & MSG_OOB)
278 return -EOPNOTSUPP;
279
280 if (sk->shutdown & RCV_SHUTDOWN)
281 return(0);
282
283 if (addr_len)
284 *addr_len=sizeof(*sin);
285
286 skb=skb_recv_datagram(sk,flags,noblock,&err);
287 if(skb==NULL)
288 return err;
289
290 copied = min(len, skb->len);
291
292 skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
293 sk->stamp=skb->stamp;
294
295
296 if (sin)
297 {
298 sin->sin_family = AF_INET;
299 sin->sin_addr.s_addr = skb->daddr;
300 }
301 skb_free_datagram(skb);
302 release_sock(sk);
303 return (copied);
304 }
305
306
307 static int raw_recvfrom(struct sock *sk, unsigned char *ubuf, int size, int noblock, unsigned flags,
308 struct sockaddr_in *sa, int *addr_len)
309 {
310 struct iovec iov;
311 struct msghdr msg;
312
313 iov.iov_base = ubuf;
314 iov.iov_len = size;
315
316 msg.msg_name = (void *)sa;
317 msg.msg_namelen = 0;
318 if (addr_len)
319 msg.msg_namelen = *addr_len;
320 msg.msg_accrights = NULL;
321 msg.msg_iov = &iov;
322 msg.msg_iovlen = 1;
323
324 return raw_recvmsg(sk, &msg, size, noblock, flags, addr_len);
325 }
326
327 int raw_read (struct sock *sk, unsigned char *buff, int len, int noblock, unsigned flags)
328 {
329 return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
330 }
331
332
333 struct proto raw_prot = {
334 raw_close,
335 raw_read,
336 raw_write,
337 raw_sendto,
338 raw_recvfrom,
339 ip_build_header,
340 udp_connect,
341 NULL,
342 ip_queue_xmit,
343 NULL,
344 NULL,
345 NULL,
346 NULL,
347 datagram_select,
348 #ifdef CONFIG_IP_MROUTE
349 ipmr_ioctl,
350 #else
351 NULL,
352 #endif
353 raw_init,
354 NULL,
355 ip_setsockopt,
356 ip_getsockopt,
357 NULL,
358 raw_recvmsg,
359 128,
360 0,
361 "RAW",
362 0, 0,
363 {NULL,}
364 };