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