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