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