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