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