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