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