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 #include <linux/config.h>
40 #include <asm/system.h>
41 #include <asm/segment.h>
42 #include <linux/types.h>
43 #include <linux/sched.h>
44 #include <linux/errno.h>
45 #include <linux/timer.h>
46 #include <linux/mm.h>
47 #include <linux/kernel.h>
48 #include <linux/fcntl.h>
49 #include <linux/socket.h>
50 #include <linux/in.h>
51 #include <linux/inet.h>
52 #include <linux/netdevice.h>
53 #include <linux/mroute.h>
54 #include <net/ip.h>
55 #include <net/protocol.h>
56 #include <linux/skbuff.h>
57 #include <net/sock.h>
58 #include <net/icmp.h>
59 #include <net/udp.h>
60 #include <net/checksum.h>
61
62 #ifdef CONFIG_IP_MROUTE
63 struct sock *mroute_socket=NULL;
64 #endif
65
66 static inline unsigned long min(unsigned long a, unsigned long b)
67 {
68 if (a < b)
69 return(a);
70 return(b);
71 }
72
73
74
75
76
77
78 void raw_err (int type, int code, unsigned char *header, __u32 daddr,
79 __u32 saddr, struct inet_protocol *protocol)
80 {
81 struct sock *sk;
82
83 if (protocol == NULL)
84 return;
85 sk = (struct sock *) protocol->data;
86 if (sk == NULL)
87 return;
88
89
90 if (type == ICMP_SOURCE_QUENCH)
91 {
92 if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2;
93 return;
94 }
95
96 if(type == ICMP_PARAMETERPROB)
97 {
98 sk->err = EPROTO;
99 sk->error_report(sk);
100 }
101
102 if(code<13)
103 {
104 sk->err = icmp_err_convert[code & 0xff].errno;
105 sk->error_report(sk);
106 }
107
108 return;
109 }
110
111
112
113
114
115
116
117
118 int raw_rcv(struct sock *sk, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr)
119 {
120
121 skb->sk = sk;
122 skb_trim(skb,ntohs(skb->ip_hdr->tot_len));
123
124 skb->h.raw = (unsigned char *) skb->ip_hdr;
125 skb->dev = dev;
126 skb->saddr = daddr;
127 skb->daddr = saddr;
128
129 #if 0
130
131
132
133
134
135 if(sk->bsdism)
136 skb->ip_hdr->tot_len=ntohs(skb->ip_hdr->tot_len-4*skb->ip_hdr->ihl);
137 #endif
138
139
140
141 if(sock_queue_rcv_skb(sk,skb)<0)
142 {
143 ip_statistics.IpInDiscards++;
144 skb->sk=NULL;
145 kfree_skb(skb, FREE_READ);
146 return(0);
147 }
148
149 ip_statistics.IpInDelivers++;
150 release_sock(sk);
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->protocol;
223 sin.sin_addr.s_addr = sk->daddr;
224 }
225 if (sin.sin_port == 0)
226 sin.sin_port = sk->protocol;
227
228 if (sin.sin_addr.s_addr == INADDR_ANY)
229 sin.sin_addr.s_addr = ip_my_addr();
230
231 if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
232 return -EACCES;
233
234 if(sk->ip_hdrincl)
235 {
236 if(len>65535)
237 return -EMSGSIZE;
238 err=ip_build_xmit(sk, raw_getrawfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port, noblock);
239 }
240 else
241 {
242 if(len>65535-sizeof(struct iphdr))
243 return -EMSGSIZE;
244 err=ip_build_xmit(sk, raw_getfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port, noblock);
245 }
246 return err<0?err:len;
247 }
248
249
250
251
252
253 static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len, int noblock,
254 int flags)
255 {
256 if(msg->msg_iovlen==1)
257 return raw_sendto(sk,msg->msg_iov[0].iov_base,len, noblock, flags, msg->msg_name, msg->msg_namelen);
258 else
259 {
260
261
262
263
264
265
266 unsigned char *buf;
267 int fs;
268 int err;
269 if(len>65515)
270 return -EMSGSIZE;
271 buf=kmalloc(len, GFP_KERNEL);
272 if(buf==NULL)
273 return -ENOBUFS;
274 memcpy_fromiovec(buf, msg->msg_iov, len);
275 fs=get_fs();
276 set_fs(get_fs());
277 err=raw_sendto(sk,buf,len, noblock, flags, msg->msg_name, msg->msg_namelen);
278 set_fs(fs);
279 kfree_s(buf,len);
280 return err;
281 }
282 }
283
284 static void raw_close(struct sock *sk, int timeout)
285 {
286 sk->state = TCP_CLOSE;
287 #ifdef CONFIG_IP_MROUTE
288 if(sk==mroute_socket)
289 {
290 mroute_close(sk);
291 mroute_socket=NULL;
292 }
293 #endif
294 }
295
296
297 static int raw_init(struct sock *sk)
298 {
299 return(0);
300 }
301
302
303
304
305
306
307
308 int raw_recvmsg(struct sock *sk, struct msghdr *msg, int len,
309 int noblock, int flags,int *addr_len)
310 {
311 int copied=0;
312 struct sk_buff *skb;
313 int err;
314 struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name;
315
316 if (flags & MSG_OOB)
317 return -EOPNOTSUPP;
318
319 if (sk->shutdown & RCV_SHUTDOWN)
320 return(0);
321
322 if (addr_len)
323 *addr_len=sizeof(*sin);
324
325 skb=skb_recv_datagram(sk,flags,noblock,&err);
326 if(skb==NULL)
327 return err;
328
329 copied = min(len, skb->len);
330
331 skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
332 sk->stamp=skb->stamp;
333
334
335 if (sin)
336 {
337 sin->sin_family = AF_INET;
338 sin->sin_addr.s_addr = skb->daddr;
339 }
340 skb_free_datagram(skb);
341 release_sock(sk);
342 return (copied);
343 }
344
345
346 struct proto raw_prot = {
347 raw_close,
348 ip_build_header,
349 udp_connect,
350 NULL,
351 ip_queue_xmit,
352 NULL,
353 NULL,
354 NULL,
355 NULL,
356 datagram_select,
357 #ifdef CONFIG_IP_MROUTE
358 ipmr_ioctl,
359 #else
360 NULL,
361 #endif
362 raw_init,
363 NULL,
364 ip_setsockopt,
365 ip_getsockopt,
366 raw_sendmsg,
367 raw_recvmsg,
368 NULL,
369 128,
370 0,
371 "RAW",
372 0, 0,
373 {NULL,}
374 };