This source file includes following definitions.
- min
- raw_err
- 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
113
114
115
116
117
118
119 int raw_rcv(struct sock *sk, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr)
120 {
121
122 skb->sk = sk;
123 skb_trim(skb,ntohs(skb->ip_hdr->tot_len));
124
125 skb->h.raw = (unsigned char *) skb->ip_hdr;
126 skb->dev = dev;
127 skb->saddr = daddr;
128 skb->daddr = saddr;
129
130 #if 0
131
132
133
134
135
136 if(sk->bsdism)
137 skb->ip_hdr->tot_len=ntohs(skb->ip_hdr->tot_len-4*skb->ip_hdr->ihl);
138 #endif
139
140
141
142 if(sock_queue_rcv_skb(sk,skb)<0)
143 {
144 ip_statistics.IpInDiscards++;
145 skb->sk=NULL;
146 kfree_skb(skb, FREE_READ);
147 return(0);
148 }
149
150 ip_statistics.IpInDelivers++;
151 return 0;
152 }
153
154
155
156
157
158
159
160
161
162 static void raw_getfrag(const void *p, __u32 saddr, char *to, unsigned int offset, unsigned int fraglen)
163 {
164 memcpy_fromfs(to, (const unsigned char *)p+offset, fraglen);
165 }
166
167
168
169
170
171 static void raw_getrawfrag(const void *p, __u32 saddr, char *to, unsigned int offset, unsigned int fraglen)
172 {
173 memcpy_fromfs(to, (const unsigned char *)p+offset, fraglen);
174 if(offset==0)
175 {
176 struct iphdr *iph=(struct iphdr *)to;
177 iph->saddr=saddr;
178 iph->check=0;
179 iph->tot_len=htons(fraglen);
180
181
182
183
184
185 iph->id = htons(ip_id_count++);
186 iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
187 }
188 }
189
190 static int raw_sendto(struct sock *sk, const unsigned char *from,
191 int len, int noblock, unsigned flags, struct sockaddr_in *usin, int addr_len)
192 {
193 int err;
194 struct sockaddr_in sin;
195
196
197
198
199
200 if (flags & MSG_OOB)
201 return -EOPNOTSUPP;
202
203 if (flags & ~MSG_DONTROUTE)
204 return(-EINVAL);
205
206
207
208
209 if (usin)
210 {
211 if (addr_len < sizeof(sin))
212 return(-EINVAL);
213 memcpy(&sin, usin, sizeof(sin));
214 if (sin.sin_family && sin.sin_family != AF_INET)
215 return(-EINVAL);
216 }
217 else
218 {
219 if (sk->state != TCP_ESTABLISHED)
220 return(-EINVAL);
221 sin.sin_family = AF_INET;
222 sin.sin_port = sk->num;
223 sin.sin_addr.s_addr = sk->daddr;
224 }
225 if (sin.sin_port == 0)
226 sin.sin_port = sk->num;
227
228 if (sin.sin_addr.s_addr == INADDR_ANY)
229 sin.sin_addr.s_addr = ip_my_addr();
230
231
232
233
234
235 if (!sk->bsdism && sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
236 return -EACCES;
237
238 if(sk->ip_hdrincl)
239 {
240 if(len>65535)
241 return -EMSGSIZE;
242 err=ip_build_xmit(sk, raw_getrawfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port, noblock);
243 }
244 else
245 {
246 if(len>65535-sizeof(struct iphdr))
247 return -EMSGSIZE;
248 err=ip_build_xmit(sk, raw_getfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port, noblock);
249 }
250 return err<0?err:len;
251 }
252
253
254
255
256
257 static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len, int noblock,
258 int flags)
259 {
260 if(msg->msg_iovlen==1)
261 return raw_sendto(sk,msg->msg_iov[0].iov_base,len, noblock, flags, msg->msg_name, msg->msg_namelen);
262 else
263 {
264
265
266
267
268
269
270 unsigned char *buf;
271 int fs;
272 int err;
273 if(len>65515)
274 return -EMSGSIZE;
275 buf=kmalloc(len, GFP_KERNEL);
276 if(buf==NULL)
277 return -ENOBUFS;
278 memcpy_fromiovec(buf, msg->msg_iov, len);
279 fs=get_fs();
280 set_fs(get_ds());
281 err=raw_sendto(sk,buf,len, noblock, flags, msg->msg_name, msg->msg_namelen);
282 set_fs(fs);
283 kfree_s(buf,len);
284 return err;
285 }
286 }
287
288 static void raw_close(struct sock *sk, int timeout)
289 {
290 sk->state = TCP_CLOSE;
291 #ifdef CONFIG_IP_MROUTE
292 if(sk==mroute_socket)
293 {
294 mroute_close(sk);
295 mroute_socket=NULL;
296 }
297 #endif
298 }
299
300
301 static int raw_init(struct sock *sk)
302 {
303 return(0);
304 }
305
306
307
308
309
310
311
312 int raw_recvmsg(struct sock *sk, struct msghdr *msg, int len,
313 int noblock, int flags,int *addr_len)
314 {
315 int copied=0;
316 struct sk_buff *skb;
317 int err;
318 struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name;
319
320 if (flags & MSG_OOB)
321 return -EOPNOTSUPP;
322
323 if (sk->shutdown & RCV_SHUTDOWN)
324 return(0);
325
326 if (addr_len)
327 *addr_len=sizeof(*sin);
328
329 skb=skb_recv_datagram(sk,flags,noblock,&err);
330 if(skb==NULL)
331 return err;
332
333 copied = min(len, skb->len);
334
335 skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
336 sk->stamp=skb->stamp;
337
338
339 if (sin)
340 {
341 sin->sin_family = AF_INET;
342 sin->sin_addr.s_addr = skb->daddr;
343 }
344 skb_free_datagram(sk, skb);
345 return (copied);
346 }
347
348
349 struct proto raw_prot = {
350 raw_close,
351 ip_build_header,
352 udp_connect,
353 NULL,
354 ip_queue_xmit,
355 NULL,
356 NULL,
357 NULL,
358 NULL,
359 datagram_select,
360 #ifdef CONFIG_IP_MROUTE
361 ipmr_ioctl,
362 #else
363 NULL,
364 #endif
365 raw_init,
366 NULL,
367 ip_setsockopt,
368 ip_getsockopt,
369 raw_sendmsg,
370 raw_recvmsg,
371 NULL,
372 128,
373 0,
374 "RAW",
375 0, 0,
376 {NULL,}
377 };