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 #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 <net/ip.h>
50 #include <net/protocol.h>
51 #include <linux/skbuff.h>
52 #include <net/sock.h>
53 #include <net/icmp.h>
54 #include <net/udp.h>
55 #include <net/checksum.h>
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_trim(skb,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
127
128
129
130 static void raw_getfrag(const void *p, int saddr, char *to, unsigned int offset, unsigned int fraglen)
131 {
132 memcpy_fromfs(to, (const unsigned char *)p+offset, fraglen);
133 }
134
135
136
137
138
139 static void raw_getrawfrag(const void *p, int saddr, char *to, unsigned int offset, unsigned int fraglen)
140 {
141 memcpy_fromfs(to, (const unsigned char *)p+offset, fraglen);
142 if(offset==0)
143 {
144 struct iphdr *iph=(struct iphdr *)to;
145 iph->saddr=saddr;
146 iph->check=0;
147 iph->tot_len=htons(fraglen);
148
149
150
151
152
153 iph->id = htons(ip_id_count++);
154 iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
155 }
156 }
157
158 static int raw_sendto(struct sock *sk, const unsigned char *from,
159 int len, int noblock, unsigned flags, struct sockaddr_in *usin, int addr_len)
160 {
161 int err;
162 struct sockaddr_in sin;
163
164
165
166
167
168 if (flags & MSG_OOB)
169 return -EOPNOTSUPP;
170
171 if (flags & ~MSG_DONTROUTE)
172 return(-EINVAL);
173
174
175
176
177 if (usin)
178 {
179 if (addr_len < sizeof(sin))
180 return(-EINVAL);
181 memcpy(&sin, usin, sizeof(sin));
182 if (sin.sin_family && sin.sin_family != AF_INET)
183 return(-EINVAL);
184 }
185 else
186 {
187 if (sk->state != TCP_ESTABLISHED)
188 return(-EINVAL);
189 sin.sin_family = AF_INET;
190 sin.sin_port = sk->protocol;
191 sin.sin_addr.s_addr = sk->daddr;
192 }
193 if (sin.sin_port == 0)
194 sin.sin_port = sk->protocol;
195
196 if (sin.sin_addr.s_addr == INADDR_ANY)
197 sin.sin_addr.s_addr = ip_my_addr();
198
199 if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
200 return -EACCES;
201
202 if(sk->num==IPPROTO_RAW)
203 err=ip_build_xmit(sk, raw_getrawfrag, from, len, sin.sin_addr.s_addr, flags, sin.sin_port);
204 else
205 err=ip_build_xmit(sk, raw_getfrag, from, len, sin.sin_addr.s_addr, flags, sin.sin_port);
206 return err<0?err:len;
207 }
208
209
210 static int raw_write(struct sock *sk, const unsigned char *buff, int len, int noblock,
211 unsigned flags)
212 {
213 return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
214 }
215
216
217 static void raw_close(struct sock *sk, int timeout)
218 {
219 sk->state = TCP_CLOSE;
220 }
221
222
223 static int raw_init(struct sock *sk)
224 {
225 return(0);
226 }
227
228
229
230
231
232
233
234 int raw_recvfrom(struct sock *sk, unsigned char *to, int len,
235 int noblock, unsigned flags, struct sockaddr_in *sin,
236 int *addr_len)
237 {
238 int copied=0;
239 struct sk_buff *skb;
240 int err;
241 int truesize;
242
243 if (flags & MSG_OOB)
244 return -EOPNOTSUPP;
245
246 if (sk->shutdown & RCV_SHUTDOWN)
247 return(0);
248
249 if (addr_len)
250 *addr_len=sizeof(*sin);
251
252 skb=skb_recv_datagram(sk,flags,noblock,&err);
253 if(skb==NULL)
254 return err;
255
256 truesize=skb->len;
257 copied = min(len, truesize);
258
259 skb_copy_datagram(skb, 0, to, copied);
260 sk->stamp=skb->stamp;
261
262
263 if (sin)
264 {
265 sin->sin_family = AF_INET;
266 sin->sin_addr.s_addr = skb->daddr;
267 }
268 skb_free_datagram(skb);
269 release_sock(sk);
270 return (truesize);
271 }
272
273
274 int raw_read (struct sock *sk, unsigned char *buff, int len, int noblock,unsigned flags)
275 {
276 return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
277 }
278
279
280 struct proto raw_prot = {
281 sock_wmalloc,
282 sock_rmalloc,
283 sock_wfree,
284 sock_rfree,
285 sock_rspace,
286 sock_wspace,
287 raw_close,
288 raw_read,
289 raw_write,
290 raw_sendto,
291 raw_recvfrom,
292 ip_build_header,
293 udp_connect,
294 NULL,
295 ip_queue_xmit,
296 NULL,
297 NULL,
298 NULL,
299 NULL,
300 datagram_select,
301 NULL,
302 raw_init,
303 NULL,
304 ip_setsockopt,
305 ip_getsockopt,
306 128,
307 0,
308 "RAW",
309 0, 0,
310 {NULL,}
311 };