This source file includes following definitions.
- min
- raw_err
- raw_rcv
- raw_sendto
- raw_write
- raw_close
- raw_init
- raw_recvfrom
- raw_read
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 #include <asm/system.h>
34 #include <asm/segment.h>
35 #include <linux/types.h>
36 #include <linux/sched.h>
37 #include <linux/errno.h>
38 #include <linux/timer.h>
39 #include <linux/mm.h>
40 #include <linux/kernel.h>
41 #include <linux/fcntl.h>
42 #include <linux/socket.h>
43 #include <linux/in.h>
44 #include <linux/inet.h>
45 #include <linux/netdevice.h>
46 #include "ip.h"
47 #include "protocol.h"
48 #include <linux/skbuff.h>
49 #include "sock.h"
50 #include "icmp.h"
51 #include "udp.h"
52
53
54 static unsigned long
55 min(unsigned long a, unsigned long b)
56 {
57 if (a < b) return(a);
58 return(b);
59 }
60
61
62
63 void
64 raw_err (int err, unsigned char *header, unsigned long daddr,
65 unsigned long saddr, struct inet_protocol *protocol)
66 {
67 struct sock *sk;
68
69 if (protocol == NULL) return;
70 sk = (struct sock *) protocol->data;
71 if (sk == NULL) return;
72
73
74 if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8)) {
75 if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2;
76 return;
77 }
78
79 sk->err = icmp_err_convert[err & 0xff].errno;
80 sk->error_report(sk);
81
82 return;
83 }
84
85
86
87
88
89
90 int
91 raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
92 unsigned long daddr, unsigned short len, unsigned long saddr,
93 int redo, struct inet_protocol *protocol)
94 {
95 struct sock *sk;
96
97 if (skb == NULL)
98 return(0);
99
100 if (protocol == NULL)
101 {
102 kfree_skb(skb, FREE_READ);
103 return(0);
104 }
105
106 sk = (struct sock *) protocol->data;
107 if (sk == NULL)
108 {
109 kfree_skb(skb, FREE_READ);
110 return(0);
111 }
112
113
114 skb->sk = sk;
115 skb->len = len + skb->ip_hdr->ihl*sizeof(long);
116 skb->h.raw = (unsigned char *) skb->ip_hdr;
117 skb->dev = dev;
118 skb->saddr = daddr;
119 skb->daddr = saddr;
120
121
122 if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) {
123 ip_statistics.IpInDiscards++;
124 skb->sk=NULL;
125 kfree_skb(skb, FREE_READ);
126 return(0);
127 }
128 sk->rmem_alloc += skb->mem_len;
129 ip_statistics.IpInDelivers++;
130 skb_queue_tail(&sk->receive_queue,skb);
131 sk->data_ready(sk,skb->len);
132 release_sock(sk);
133 return(0);
134 }
135
136
137
138
139
140 static int raw_sendto(struct sock *sk, unsigned char *from,
141 int len, int noblock, unsigned flags, struct sockaddr_in *usin, int addr_len)
142 {
143 struct sk_buff *skb;
144 struct device *dev=NULL;
145 struct sockaddr_in sin;
146 int tmp;
147 int err;
148
149
150
151
152
153 if (flags&MSG_DONTROUTE)
154 return(-EINVAL);
155
156
157
158
159 if (usin)
160 {
161 if (addr_len < sizeof(sin))
162 return(-EINVAL);
163 err=verify_area (VERIFY_READ, usin, sizeof (sin));
164 if(err)
165 return err;
166 memcpy_fromfs(&sin, usin, sizeof(sin));
167 if (sin.sin_family && sin.sin_family != AF_INET)
168 return(-EINVAL);
169 }
170 else
171 {
172 if (sk->state != TCP_ESTABLISHED)
173 return(-EINVAL);
174 sin.sin_family = AF_INET;
175 sin.sin_port = sk->protocol;
176 sin.sin_addr.s_addr = sk->daddr;
177 }
178 if (sin.sin_port == 0)
179 sin.sin_port = sk->protocol;
180
181 if (sin.sin_addr.s_addr == INADDR_ANY)
182 sin.sin_addr.s_addr = ip_my_addr();
183
184 if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
185 return -EACCES;
186
187 sk->inuse = 1;
188 skb = NULL;
189 while (skb == NULL)
190 {
191 if(sk->err!=0)
192 {
193 err= -sk->err;
194 sk->err=0;
195 release_sock(sk);
196 return(err);
197 }
198
199 skb = sk->prot->wmalloc(sk,
200 len + sk->prot->max_header,
201 0, GFP_KERNEL);
202 if (skb == NULL)
203 {
204 int tmp;
205
206 if (noblock)
207 return(-EAGAIN);
208 tmp = sk->wmem_alloc;
209 release_sock(sk);
210 cli();
211 if (tmp <= sk->wmem_alloc) {
212 interruptible_sleep_on(sk->sleep);
213 if (current->signal & ~current->blocked) {
214 sti();
215 return(-ERESTARTSYS);
216 }
217 }
218 sk->inuse = 1;
219 sti();
220 }
221 }
222 skb->sk = sk;
223 skb->free = 1;
224 skb->localroute = sk->localroute | (flags&MSG_DONTROUTE);
225
226 tmp = sk->prot->build_header(skb, sk->saddr,
227 sin.sin_addr.s_addr, &dev,
228 sk->protocol, sk->opt, skb->mem_len, sk->ip_tos,sk->ip_ttl);
229 if (tmp < 0)
230 {
231 kfree_skb(skb,FREE_WRITE);
232 release_sock(sk);
233 return(tmp);
234 }
235
236 memcpy_fromfs(skb->data + tmp, from, len);
237
238
239
240
241
242
243 if(sk->protocol==IPPROTO_RAW)
244 {
245 unsigned char *buff;
246 struct iphdr *iph;
247
248 buff = skb->data;
249 buff += tmp;
250
251 iph = (struct iphdr *)buff;
252 iph->saddr = sk->saddr;
253 }
254
255 skb->len = tmp + len;
256
257 sk->prot->queue_xmit(sk, dev, skb, 1);
258 release_sock(sk);
259 return(len);
260 }
261
262
263 static int raw_write(struct sock *sk, unsigned char *buff, int len, int noblock,
264 unsigned flags)
265 {
266 return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
267 }
268
269
270 static void raw_close(struct sock *sk, int timeout)
271 {
272 sk->inuse = 1;
273 sk->state = TCP_CLOSE;
274
275 inet_del_protocol((struct inet_protocol *)sk->pair);
276 kfree_s((void *)sk->pair, sizeof (struct inet_protocol));
277 sk->pair = NULL;
278 release_sock(sk);
279 }
280
281
282 static int
283 raw_init(struct sock *sk)
284 {
285 struct inet_protocol *p;
286
287 p = (struct inet_protocol *) kmalloc(sizeof (*p), GFP_KERNEL);
288 if (p == NULL) return(-ENOMEM);
289
290 p->handler = raw_rcv;
291 p->protocol = sk->protocol;
292 p->data = (void *)sk;
293 p->err_handler = raw_err;
294 p->name="USER";
295 p->frag_handler = NULL;
296 inet_add_protocol(p);
297
298
299 sk->pair = (struct sock *)p;
300
301 return(0);
302 }
303
304
305
306
307
308
309 int
310 raw_recvfrom(struct sock *sk, unsigned char *to, int len,
311 int noblock, unsigned flags, struct sockaddr_in *sin,
312 int *addr_len)
313 {
314 int copied=0;
315 struct sk_buff *skb;
316 int err;
317
318 if (len == 0) return(0);
319 if (len < 0) return(-EINVAL);
320
321 if (sk->shutdown & RCV_SHUTDOWN) return(0);
322 if (addr_len) {
323 err=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
324 if(err)
325 return err;
326 put_fs_long(sizeof(*sin), addr_len);
327 }
328 if(sin)
329 {
330 err=verify_area(VERIFY_WRITE, sin, sizeof(*sin));
331 if(err)
332 return err;
333 }
334
335 err=verify_area(VERIFY_WRITE,to,len);
336 if(err)
337 return err;
338
339 skb=skb_recv_datagram(sk,flags,noblock,&err);
340 if(skb==NULL)
341 return err;
342
343 copied = min(len, skb->len);
344
345 skb_copy_datagram(skb, 0, to, copied);
346 sk->stamp=skb->stamp;
347
348
349 if (sin) {
350 struct sockaddr_in addr;
351
352 addr.sin_family = AF_INET;
353 addr.sin_addr.s_addr = skb->daddr;
354 memcpy_tofs(sin, &addr, sizeof(*sin));
355 }
356
357 skb_free_datagram(skb);
358 release_sock(sk);
359 return (copied);
360 }
361
362
363 int
364 raw_read (struct sock *sk, unsigned char *buff, int len, int noblock,
365 unsigned flags)
366 {
367 return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
368 }
369
370
371 struct proto raw_prot = {
372 sock_wmalloc,
373 sock_rmalloc,
374 sock_wfree,
375 sock_rfree,
376 sock_rspace,
377 sock_wspace,
378 raw_close,
379 raw_read,
380 raw_write,
381 raw_sendto,
382 raw_recvfrom,
383 ip_build_header,
384 udp_connect,
385 NULL,
386 ip_queue_xmit,
387 ip_retransmit,
388 NULL,
389 NULL,
390 raw_rcv,
391 datagram_select,
392 NULL,
393 raw_init,
394 NULL,
395 ip_setsockopt,
396 ip_getsockopt,
397 128,
398 0,
399 {NULL,},
400 "RAW"
401 };