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