diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/ipv4/icmp.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r-- | net/ipv4/icmp.c | 1143 |
1 files changed, 1143 insertions, 0 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c new file mode 100644 index 000000000000..85bf0d3e294b --- /dev/null +++ b/net/ipv4/icmp.c | |||
@@ -0,0 +1,1143 @@ | |||
1 | /* | ||
2 | * NET3: Implementation of the ICMP protocol layer. | ||
3 | * | ||
4 | * Alan Cox, <alan@redhat.com> | ||
5 | * | ||
6 | * Version: $Id: icmp.c,v 1.85 2002/02/01 22:01:03 davem Exp $ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * Some of the function names and the icmp unreach table for this | ||
14 | * module were derived from [icmp.c 1.0.11 06/02/93] by | ||
15 | * Ross Biro, Fred N. van Kempen, Mark Evans, Alan Cox, Gerhard Koerting. | ||
16 | * Other than that this module is a complete rewrite. | ||
17 | * | ||
18 | * Fixes: | ||
19 | * Clemens Fruhwirth : introduce global icmp rate limiting | ||
20 | * with icmp type masking ability instead | ||
21 | * of broken per type icmp timeouts. | ||
22 | * Mike Shaver : RFC1122 checks. | ||
23 | * Alan Cox : Multicast ping reply as self. | ||
24 | * Alan Cox : Fix atomicity lockup in ip_build_xmit | ||
25 | * call. | ||
26 | * Alan Cox : Added 216,128 byte paths to the MTU | ||
27 | * code. | ||
28 | * Martin Mares : RFC1812 checks. | ||
29 | * Martin Mares : Can be configured to follow redirects | ||
30 | * if acting as a router _without_ a | ||
31 | * routing protocol (RFC 1812). | ||
32 | * Martin Mares : Echo requests may be configured to | ||
33 | * be ignored (RFC 1812). | ||
34 | * Martin Mares : Limitation of ICMP error message | ||
35 | * transmit rate (RFC 1812). | ||
36 | * Martin Mares : TOS and Precedence set correctly | ||
37 | * (RFC 1812). | ||
38 | * Martin Mares : Now copying as much data from the | ||
39 | * original packet as we can without | ||
40 | * exceeding 576 bytes (RFC 1812). | ||
41 | * Willy Konynenberg : Transparent proxying support. | ||
42 | * Keith Owens : RFC1191 correction for 4.2BSD based | ||
43 | * path MTU bug. | ||
44 | * Thomas Quinot : ICMP Dest Unreach codes up to 15 are | ||
45 | * valid (RFC 1812). | ||
46 | * Andi Kleen : Check all packet lengths properly | ||
47 | * and moved all kfree_skb() up to | ||
48 | * icmp_rcv. | ||
49 | * Andi Kleen : Move the rate limit bookkeeping | ||
50 | * into the dest entry and use a token | ||
51 | * bucket filter (thanks to ANK). Make | ||
52 | * the rates sysctl configurable. | ||
53 | * Yu Tianli : Fixed two ugly bugs in icmp_send | ||
54 | * - IP option length was accounted wrongly | ||
55 | * - ICMP header length was not accounted | ||
56 | * at all. | ||
57 | * Tristan Greaves : Added sysctl option to ignore bogus | ||
58 | * broadcast responses from broken routers. | ||
59 | * | ||
60 | * To Fix: | ||
61 | * | ||
62 | * - Should use skb_pull() instead of all the manual checking. | ||
63 | * This would also greatly simply some upper layer error handlers. --AK | ||
64 | * | ||
65 | */ | ||
66 | |||
67 | #include <linux/config.h> | ||
68 | #include <linux/module.h> | ||
69 | #include <linux/types.h> | ||
70 | #include <linux/jiffies.h> | ||
71 | #include <linux/kernel.h> | ||
72 | #include <linux/fcntl.h> | ||
73 | #include <linux/socket.h> | ||
74 | #include <linux/in.h> | ||
75 | #include <linux/inet.h> | ||
76 | #include <linux/netdevice.h> | ||
77 | #include <linux/string.h> | ||
78 | #include <linux/netfilter_ipv4.h> | ||
79 | #include <net/snmp.h> | ||
80 | #include <net/ip.h> | ||
81 | #include <net/route.h> | ||
82 | #include <net/protocol.h> | ||
83 | #include <net/icmp.h> | ||
84 | #include <net/tcp.h> | ||
85 | #include <net/udp.h> | ||
86 | #include <net/raw.h> | ||
87 | #include <linux/skbuff.h> | ||
88 | #include <net/sock.h> | ||
89 | #include <linux/errno.h> | ||
90 | #include <linux/timer.h> | ||
91 | #include <linux/init.h> | ||
92 | #include <asm/system.h> | ||
93 | #include <asm/uaccess.h> | ||
94 | #include <net/checksum.h> | ||
95 | |||
96 | /* | ||
97 | * Build xmit assembly blocks | ||
98 | */ | ||
99 | |||
100 | struct icmp_bxm { | ||
101 | struct sk_buff *skb; | ||
102 | int offset; | ||
103 | int data_len; | ||
104 | |||
105 | struct { | ||
106 | struct icmphdr icmph; | ||
107 | __u32 times[3]; | ||
108 | } data; | ||
109 | int head_len; | ||
110 | struct ip_options replyopts; | ||
111 | unsigned char optbuf[40]; | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * Statistics | ||
116 | */ | ||
117 | DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics); | ||
118 | |||
119 | /* An array of errno for error messages from dest unreach. */ | ||
120 | /* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */ | ||
121 | |||
122 | struct icmp_err icmp_err_convert[] = { | ||
123 | { | ||
124 | .errno = ENETUNREACH, /* ICMP_NET_UNREACH */ | ||
125 | .fatal = 0, | ||
126 | }, | ||
127 | { | ||
128 | .errno = EHOSTUNREACH, /* ICMP_HOST_UNREACH */ | ||
129 | .fatal = 0, | ||
130 | }, | ||
131 | { | ||
132 | .errno = ENOPROTOOPT /* ICMP_PROT_UNREACH */, | ||
133 | .fatal = 1, | ||
134 | }, | ||
135 | { | ||
136 | .errno = ECONNREFUSED, /* ICMP_PORT_UNREACH */ | ||
137 | .fatal = 1, | ||
138 | }, | ||
139 | { | ||
140 | .errno = EMSGSIZE, /* ICMP_FRAG_NEEDED */ | ||
141 | .fatal = 0, | ||
142 | }, | ||
143 | { | ||
144 | .errno = EOPNOTSUPP, /* ICMP_SR_FAILED */ | ||
145 | .fatal = 0, | ||
146 | }, | ||
147 | { | ||
148 | .errno = ENETUNREACH, /* ICMP_NET_UNKNOWN */ | ||
149 | .fatal = 1, | ||
150 | }, | ||
151 | { | ||
152 | .errno = EHOSTDOWN, /* ICMP_HOST_UNKNOWN */ | ||
153 | .fatal = 1, | ||
154 | }, | ||
155 | { | ||
156 | .errno = ENONET, /* ICMP_HOST_ISOLATED */ | ||
157 | .fatal = 1, | ||
158 | }, | ||
159 | { | ||
160 | .errno = ENETUNREACH, /* ICMP_NET_ANO */ | ||
161 | .fatal = 1, | ||
162 | }, | ||
163 | { | ||
164 | .errno = EHOSTUNREACH, /* ICMP_HOST_ANO */ | ||
165 | .fatal = 1, | ||
166 | }, | ||
167 | { | ||
168 | .errno = ENETUNREACH, /* ICMP_NET_UNR_TOS */ | ||
169 | .fatal = 0, | ||
170 | }, | ||
171 | { | ||
172 | .errno = EHOSTUNREACH, /* ICMP_HOST_UNR_TOS */ | ||
173 | .fatal = 0, | ||
174 | }, | ||
175 | { | ||
176 | .errno = EHOSTUNREACH, /* ICMP_PKT_FILTERED */ | ||
177 | .fatal = 1, | ||
178 | }, | ||
179 | { | ||
180 | .errno = EHOSTUNREACH, /* ICMP_PREC_VIOLATION */ | ||
181 | .fatal = 1, | ||
182 | }, | ||
183 | { | ||
184 | .errno = EHOSTUNREACH, /* ICMP_PREC_CUTOFF */ | ||
185 | .fatal = 1, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | /* Control parameters for ECHO replies. */ | ||
190 | int sysctl_icmp_echo_ignore_all; | ||
191 | int sysctl_icmp_echo_ignore_broadcasts; | ||
192 | |||
193 | /* Control parameter - ignore bogus broadcast responses? */ | ||
194 | int sysctl_icmp_ignore_bogus_error_responses; | ||
195 | |||
196 | /* | ||
197 | * Configurable global rate limit. | ||
198 | * | ||
199 | * ratelimit defines tokens/packet consumed for dst->rate_token bucket | ||
200 | * ratemask defines which icmp types are ratelimited by setting | ||
201 | * it's bit position. | ||
202 | * | ||
203 | * default: | ||
204 | * dest unreachable (3), source quench (4), | ||
205 | * time exceeded (11), parameter problem (12) | ||
206 | */ | ||
207 | |||
208 | int sysctl_icmp_ratelimit = 1 * HZ; | ||
209 | int sysctl_icmp_ratemask = 0x1818; | ||
210 | |||
211 | /* | ||
212 | * ICMP control array. This specifies what to do with each ICMP. | ||
213 | */ | ||
214 | |||
215 | struct icmp_control { | ||
216 | int output_entry; /* Field for increment on output */ | ||
217 | int input_entry; /* Field for increment on input */ | ||
218 | void (*handler)(struct sk_buff *skb); | ||
219 | short error; /* This ICMP is classed as an error message */ | ||
220 | }; | ||
221 | |||
222 | static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; | ||
223 | |||
224 | /* | ||
225 | * The ICMP socket(s). This is the most convenient way to flow control | ||
226 | * our ICMP output as well as maintain a clean interface throughout | ||
227 | * all layers. All Socketless IP sends will soon be gone. | ||
228 | * | ||
229 | * On SMP we have one ICMP socket per-cpu. | ||
230 | */ | ||
231 | static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL; | ||
232 | #define icmp_socket __get_cpu_var(__icmp_socket) | ||
233 | |||
234 | static __inline__ int icmp_xmit_lock(void) | ||
235 | { | ||
236 | local_bh_disable(); | ||
237 | |||
238 | if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) { | ||
239 | /* This can happen if the output path signals a | ||
240 | * dst_link_failure() for an outgoing ICMP packet. | ||
241 | */ | ||
242 | local_bh_enable(); | ||
243 | return 1; | ||
244 | } | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static void icmp_xmit_unlock(void) | ||
249 | { | ||
250 | spin_unlock_bh(&icmp_socket->sk->sk_lock.slock); | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * Send an ICMP frame. | ||
255 | */ | ||
256 | |||
257 | /* | ||
258 | * Check transmit rate limitation for given message. | ||
259 | * The rate information is held in the destination cache now. | ||
260 | * This function is generic and could be used for other purposes | ||
261 | * too. It uses a Token bucket filter as suggested by Alexey Kuznetsov. | ||
262 | * | ||
263 | * Note that the same dst_entry fields are modified by functions in | ||
264 | * route.c too, but these work for packet destinations while xrlim_allow | ||
265 | * works for icmp destinations. This means the rate limiting information | ||
266 | * for one "ip object" is shared - and these ICMPs are twice limited: | ||
267 | * by source and by destination. | ||
268 | * | ||
269 | * RFC 1812: 4.3.2.8 SHOULD be able to limit error message rate | ||
270 | * SHOULD allow setting of rate limits | ||
271 | * | ||
272 | * Shared between ICMPv4 and ICMPv6. | ||
273 | */ | ||
274 | #define XRLIM_BURST_FACTOR 6 | ||
275 | int xrlim_allow(struct dst_entry *dst, int timeout) | ||
276 | { | ||
277 | unsigned long now; | ||
278 | int rc = 0; | ||
279 | |||
280 | now = jiffies; | ||
281 | dst->rate_tokens += now - dst->rate_last; | ||
282 | dst->rate_last = now; | ||
283 | if (dst->rate_tokens > XRLIM_BURST_FACTOR * timeout) | ||
284 | dst->rate_tokens = XRLIM_BURST_FACTOR * timeout; | ||
285 | if (dst->rate_tokens >= timeout) { | ||
286 | dst->rate_tokens -= timeout; | ||
287 | rc = 1; | ||
288 | } | ||
289 | return rc; | ||
290 | } | ||
291 | |||
292 | static inline int icmpv4_xrlim_allow(struct rtable *rt, int type, int code) | ||
293 | { | ||
294 | struct dst_entry *dst = &rt->u.dst; | ||
295 | int rc = 1; | ||
296 | |||
297 | if (type > NR_ICMP_TYPES) | ||
298 | goto out; | ||
299 | |||
300 | /* Don't limit PMTU discovery. */ | ||
301 | if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) | ||
302 | goto out; | ||
303 | |||
304 | /* No rate limit on loopback */ | ||
305 | if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) | ||
306 | goto out; | ||
307 | |||
308 | /* Limit if icmp type is enabled in ratemask. */ | ||
309 | if ((1 << type) & sysctl_icmp_ratemask) | ||
310 | rc = xrlim_allow(dst, sysctl_icmp_ratelimit); | ||
311 | out: | ||
312 | return rc; | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Maintain the counters used in the SNMP statistics for outgoing ICMP | ||
317 | */ | ||
318 | static void icmp_out_count(int type) | ||
319 | { | ||
320 | if (type <= NR_ICMP_TYPES) { | ||
321 | ICMP_INC_STATS(icmp_pointers[type].output_entry); | ||
322 | ICMP_INC_STATS(ICMP_MIB_OUTMSGS); | ||
323 | } | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * Checksum each fragment, and on the first include the headers and final | ||
328 | * checksum. | ||
329 | */ | ||
330 | static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, | ||
331 | struct sk_buff *skb) | ||
332 | { | ||
333 | struct icmp_bxm *icmp_param = (struct icmp_bxm *)from; | ||
334 | unsigned int csum; | ||
335 | |||
336 | csum = skb_copy_and_csum_bits(icmp_param->skb, | ||
337 | icmp_param->offset + offset, | ||
338 | to, len, 0); | ||
339 | |||
340 | skb->csum = csum_block_add(skb->csum, csum, odd); | ||
341 | if (icmp_pointers[icmp_param->data.icmph.type].error) | ||
342 | nf_ct_attach(skb, icmp_param->skb); | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static void icmp_push_reply(struct icmp_bxm *icmp_param, | ||
347 | struct ipcm_cookie *ipc, struct rtable *rt) | ||
348 | { | ||
349 | struct sk_buff *skb; | ||
350 | |||
351 | ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, | ||
352 | icmp_param->data_len+icmp_param->head_len, | ||
353 | icmp_param->head_len, | ||
354 | ipc, rt, MSG_DONTWAIT); | ||
355 | |||
356 | if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { | ||
357 | struct icmphdr *icmph = skb->h.icmph; | ||
358 | unsigned int csum = 0; | ||
359 | struct sk_buff *skb1; | ||
360 | |||
361 | skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) { | ||
362 | csum = csum_add(csum, skb1->csum); | ||
363 | } | ||
364 | csum = csum_partial_copy_nocheck((void *)&icmp_param->data, | ||
365 | (char *)icmph, | ||
366 | icmp_param->head_len, csum); | ||
367 | icmph->checksum = csum_fold(csum); | ||
368 | skb->ip_summed = CHECKSUM_NONE; | ||
369 | ip_push_pending_frames(icmp_socket->sk); | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * Driving logic for building and sending ICMP messages. | ||
375 | */ | ||
376 | |||
377 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | ||
378 | { | ||
379 | struct sock *sk = icmp_socket->sk; | ||
380 | struct inet_sock *inet = inet_sk(sk); | ||
381 | struct ipcm_cookie ipc; | ||
382 | struct rtable *rt = (struct rtable *)skb->dst; | ||
383 | u32 daddr; | ||
384 | |||
385 | if (ip_options_echo(&icmp_param->replyopts, skb)) | ||
386 | goto out; | ||
387 | |||
388 | if (icmp_xmit_lock()) | ||
389 | return; | ||
390 | |||
391 | icmp_param->data.icmph.checksum = 0; | ||
392 | icmp_out_count(icmp_param->data.icmph.type); | ||
393 | |||
394 | inet->tos = skb->nh.iph->tos; | ||
395 | daddr = ipc.addr = rt->rt_src; | ||
396 | ipc.opt = NULL; | ||
397 | if (icmp_param->replyopts.optlen) { | ||
398 | ipc.opt = &icmp_param->replyopts; | ||
399 | if (ipc.opt->srr) | ||
400 | daddr = icmp_param->replyopts.faddr; | ||
401 | } | ||
402 | { | ||
403 | struct flowi fl = { .nl_u = { .ip4_u = | ||
404 | { .daddr = daddr, | ||
405 | .saddr = rt->rt_spec_dst, | ||
406 | .tos = RT_TOS(skb->nh.iph->tos) } }, | ||
407 | .proto = IPPROTO_ICMP }; | ||
408 | if (ip_route_output_key(&rt, &fl)) | ||
409 | goto out_unlock; | ||
410 | } | ||
411 | if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type, | ||
412 | icmp_param->data.icmph.code)) | ||
413 | icmp_push_reply(icmp_param, &ipc, rt); | ||
414 | ip_rt_put(rt); | ||
415 | out_unlock: | ||
416 | icmp_xmit_unlock(); | ||
417 | out:; | ||
418 | } | ||
419 | |||
420 | |||
421 | /* | ||
422 | * Send an ICMP message in response to a situation | ||
423 | * | ||
424 | * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. | ||
425 | * MAY send more (we do). | ||
426 | * MUST NOT change this header information. | ||
427 | * MUST NOT reply to a multicast/broadcast IP address. | ||
428 | * MUST NOT reply to a multicast/broadcast MAC address. | ||
429 | * MUST reply to only the first fragment. | ||
430 | */ | ||
431 | |||
432 | void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info) | ||
433 | { | ||
434 | struct iphdr *iph; | ||
435 | int room; | ||
436 | struct icmp_bxm icmp_param; | ||
437 | struct rtable *rt = (struct rtable *)skb_in->dst; | ||
438 | struct ipcm_cookie ipc; | ||
439 | u32 saddr; | ||
440 | u8 tos; | ||
441 | |||
442 | if (!rt) | ||
443 | goto out; | ||
444 | |||
445 | /* | ||
446 | * Find the original header. It is expected to be valid, of course. | ||
447 | * Check this, icmp_send is called from the most obscure devices | ||
448 | * sometimes. | ||
449 | */ | ||
450 | iph = skb_in->nh.iph; | ||
451 | |||
452 | if ((u8 *)iph < skb_in->head || (u8 *)(iph + 1) > skb_in->tail) | ||
453 | goto out; | ||
454 | |||
455 | /* | ||
456 | * No replies to physical multicast/broadcast | ||
457 | */ | ||
458 | if (skb_in->pkt_type != PACKET_HOST) | ||
459 | goto out; | ||
460 | |||
461 | /* | ||
462 | * Now check at the protocol level | ||
463 | */ | ||
464 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) | ||
465 | goto out; | ||
466 | |||
467 | /* | ||
468 | * Only reply to fragment 0. We byte re-order the constant | ||
469 | * mask for efficiency. | ||
470 | */ | ||
471 | if (iph->frag_off & htons(IP_OFFSET)) | ||
472 | goto out; | ||
473 | |||
474 | /* | ||
475 | * If we send an ICMP error to an ICMP error a mess would result.. | ||
476 | */ | ||
477 | if (icmp_pointers[type].error) { | ||
478 | /* | ||
479 | * We are an error, check if we are replying to an | ||
480 | * ICMP error | ||
481 | */ | ||
482 | if (iph->protocol == IPPROTO_ICMP) { | ||
483 | u8 _inner_type, *itp; | ||
484 | |||
485 | itp = skb_header_pointer(skb_in, | ||
486 | skb_in->nh.raw + | ||
487 | (iph->ihl << 2) + | ||
488 | offsetof(struct icmphdr, | ||
489 | type) - | ||
490 | skb_in->data, | ||
491 | sizeof(_inner_type), | ||
492 | &_inner_type); | ||
493 | if (itp == NULL) | ||
494 | goto out; | ||
495 | |||
496 | /* | ||
497 | * Assume any unknown ICMP type is an error. This | ||
498 | * isn't specified by the RFC, but think about it.. | ||
499 | */ | ||
500 | if (*itp > NR_ICMP_TYPES || | ||
501 | icmp_pointers[*itp].error) | ||
502 | goto out; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | if (icmp_xmit_lock()) | ||
507 | return; | ||
508 | |||
509 | /* | ||
510 | * Construct source address and options. | ||
511 | */ | ||
512 | |||
513 | saddr = iph->daddr; | ||
514 | if (!(rt->rt_flags & RTCF_LOCAL)) | ||
515 | saddr = 0; | ||
516 | |||
517 | tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) | | ||
518 | IPTOS_PREC_INTERNETCONTROL) : | ||
519 | iph->tos; | ||
520 | |||
521 | if (ip_options_echo(&icmp_param.replyopts, skb_in)) | ||
522 | goto ende; | ||
523 | |||
524 | |||
525 | /* | ||
526 | * Prepare data for ICMP header. | ||
527 | */ | ||
528 | |||
529 | icmp_param.data.icmph.type = type; | ||
530 | icmp_param.data.icmph.code = code; | ||
531 | icmp_param.data.icmph.un.gateway = info; | ||
532 | icmp_param.data.icmph.checksum = 0; | ||
533 | icmp_param.skb = skb_in; | ||
534 | icmp_param.offset = skb_in->nh.raw - skb_in->data; | ||
535 | icmp_out_count(icmp_param.data.icmph.type); | ||
536 | inet_sk(icmp_socket->sk)->tos = tos; | ||
537 | ipc.addr = iph->saddr; | ||
538 | ipc.opt = &icmp_param.replyopts; | ||
539 | |||
540 | { | ||
541 | struct flowi fl = { | ||
542 | .nl_u = { | ||
543 | .ip4_u = { | ||
544 | .daddr = icmp_param.replyopts.srr ? | ||
545 | icmp_param.replyopts.faddr : | ||
546 | iph->saddr, | ||
547 | .saddr = saddr, | ||
548 | .tos = RT_TOS(tos) | ||
549 | } | ||
550 | }, | ||
551 | .proto = IPPROTO_ICMP, | ||
552 | .uli_u = { | ||
553 | .icmpt = { | ||
554 | .type = type, | ||
555 | .code = code | ||
556 | } | ||
557 | } | ||
558 | }; | ||
559 | if (ip_route_output_key(&rt, &fl)) | ||
560 | goto out_unlock; | ||
561 | } | ||
562 | |||
563 | if (!icmpv4_xrlim_allow(rt, type, code)) | ||
564 | goto ende; | ||
565 | |||
566 | /* RFC says return as much as we can without exceeding 576 bytes. */ | ||
567 | |||
568 | room = dst_mtu(&rt->u.dst); | ||
569 | if (room > 576) | ||
570 | room = 576; | ||
571 | room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen; | ||
572 | room -= sizeof(struct icmphdr); | ||
573 | |||
574 | icmp_param.data_len = skb_in->len - icmp_param.offset; | ||
575 | if (icmp_param.data_len > room) | ||
576 | icmp_param.data_len = room; | ||
577 | icmp_param.head_len = sizeof(struct icmphdr); | ||
578 | |||
579 | icmp_push_reply(&icmp_param, &ipc, rt); | ||
580 | ende: | ||
581 | ip_rt_put(rt); | ||
582 | out_unlock: | ||
583 | icmp_xmit_unlock(); | ||
584 | out:; | ||
585 | } | ||
586 | |||
587 | |||
588 | /* | ||
589 | * Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, and ICMP_QUENCH. | ||
590 | */ | ||
591 | |||
592 | static void icmp_unreach(struct sk_buff *skb) | ||
593 | { | ||
594 | struct iphdr *iph; | ||
595 | struct icmphdr *icmph; | ||
596 | int hash, protocol; | ||
597 | struct net_protocol *ipprot; | ||
598 | struct sock *raw_sk; | ||
599 | u32 info = 0; | ||
600 | |||
601 | /* | ||
602 | * Incomplete header ? | ||
603 | * Only checks for the IP header, there should be an | ||
604 | * additional check for longer headers in upper levels. | ||
605 | */ | ||
606 | |||
607 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
608 | goto out_err; | ||
609 | |||
610 | icmph = skb->h.icmph; | ||
611 | iph = (struct iphdr *)skb->data; | ||
612 | |||
613 | if (iph->ihl < 5) /* Mangled header, drop. */ | ||
614 | goto out_err; | ||
615 | |||
616 | if (icmph->type == ICMP_DEST_UNREACH) { | ||
617 | switch (icmph->code & 15) { | ||
618 | case ICMP_NET_UNREACH: | ||
619 | case ICMP_HOST_UNREACH: | ||
620 | case ICMP_PROT_UNREACH: | ||
621 | case ICMP_PORT_UNREACH: | ||
622 | break; | ||
623 | case ICMP_FRAG_NEEDED: | ||
624 | if (ipv4_config.no_pmtu_disc) { | ||
625 | LIMIT_NETDEBUG( | ||
626 | printk(KERN_INFO "ICMP: %u.%u.%u.%u: " | ||
627 | "fragmentation needed " | ||
628 | "and DF set.\n", | ||
629 | NIPQUAD(iph->daddr))); | ||
630 | } else { | ||
631 | info = ip_rt_frag_needed(iph, | ||
632 | ntohs(icmph->un.frag.mtu)); | ||
633 | if (!info) | ||
634 | goto out; | ||
635 | } | ||
636 | break; | ||
637 | case ICMP_SR_FAILED: | ||
638 | LIMIT_NETDEBUG( | ||
639 | printk(KERN_INFO "ICMP: %u.%u.%u.%u: Source " | ||
640 | "Route Failed.\n", | ||
641 | NIPQUAD(iph->daddr))); | ||
642 | break; | ||
643 | default: | ||
644 | break; | ||
645 | } | ||
646 | if (icmph->code > NR_ICMP_UNREACH) | ||
647 | goto out; | ||
648 | } else if (icmph->type == ICMP_PARAMETERPROB) | ||
649 | info = ntohl(icmph->un.gateway) >> 24; | ||
650 | |||
651 | /* | ||
652 | * Throw it at our lower layers | ||
653 | * | ||
654 | * RFC 1122: 3.2.2 MUST extract the protocol ID from the passed | ||
655 | * header. | ||
656 | * RFC 1122: 3.2.2.1 MUST pass ICMP unreach messages to the | ||
657 | * transport layer. | ||
658 | * RFC 1122: 3.2.2.2 MUST pass ICMP time expired messages to | ||
659 | * transport layer. | ||
660 | */ | ||
661 | |||
662 | /* | ||
663 | * Check the other end isnt violating RFC 1122. Some routers send | ||
664 | * bogus responses to broadcast frames. If you see this message | ||
665 | * first check your netmask matches at both ends, if it does then | ||
666 | * get the other vendor to fix their kit. | ||
667 | */ | ||
668 | |||
669 | if (!sysctl_icmp_ignore_bogus_error_responses && | ||
670 | inet_addr_type(iph->daddr) == RTN_BROADCAST) { | ||
671 | if (net_ratelimit()) | ||
672 | printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP " | ||
673 | "type %u, code %u " | ||
674 | "error to a broadcast: %u.%u.%u.%u on %s\n", | ||
675 | NIPQUAD(skb->nh.iph->saddr), | ||
676 | icmph->type, icmph->code, | ||
677 | NIPQUAD(iph->daddr), | ||
678 | skb->dev->name); | ||
679 | goto out; | ||
680 | } | ||
681 | |||
682 | /* Checkin full IP header plus 8 bytes of protocol to | ||
683 | * avoid additional coding at protocol handlers. | ||
684 | */ | ||
685 | if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) | ||
686 | goto out; | ||
687 | |||
688 | iph = (struct iphdr *)skb->data; | ||
689 | protocol = iph->protocol; | ||
690 | |||
691 | /* | ||
692 | * Deliver ICMP message to raw sockets. Pretty useless feature? | ||
693 | */ | ||
694 | |||
695 | /* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */ | ||
696 | hash = protocol & (MAX_INET_PROTOS - 1); | ||
697 | read_lock(&raw_v4_lock); | ||
698 | if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) { | ||
699 | while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, | ||
700 | iph->saddr, | ||
701 | skb->dev->ifindex)) != NULL) { | ||
702 | raw_err(raw_sk, skb, info); | ||
703 | raw_sk = sk_next(raw_sk); | ||
704 | iph = (struct iphdr *)skb->data; | ||
705 | } | ||
706 | } | ||
707 | read_unlock(&raw_v4_lock); | ||
708 | |||
709 | rcu_read_lock(); | ||
710 | ipprot = rcu_dereference(inet_protos[hash]); | ||
711 | if (ipprot && ipprot->err_handler) | ||
712 | ipprot->err_handler(skb, info); | ||
713 | rcu_read_unlock(); | ||
714 | |||
715 | out: | ||
716 | return; | ||
717 | out_err: | ||
718 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | ||
719 | goto out; | ||
720 | } | ||
721 | |||
722 | |||
723 | /* | ||
724 | * Handle ICMP_REDIRECT. | ||
725 | */ | ||
726 | |||
727 | static void icmp_redirect(struct sk_buff *skb) | ||
728 | { | ||
729 | struct iphdr *iph; | ||
730 | unsigned long ip; | ||
731 | |||
732 | if (skb->len < sizeof(struct iphdr)) | ||
733 | goto out_err; | ||
734 | |||
735 | /* | ||
736 | * Get the copied header of the packet that caused the redirect | ||
737 | */ | ||
738 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
739 | goto out; | ||
740 | |||
741 | iph = (struct iphdr *)skb->data; | ||
742 | ip = iph->daddr; | ||
743 | |||
744 | switch (skb->h.icmph->code & 7) { | ||
745 | case ICMP_REDIR_NET: | ||
746 | case ICMP_REDIR_NETTOS: | ||
747 | /* | ||
748 | * As per RFC recommendations now handle it as a host redirect. | ||
749 | */ | ||
750 | case ICMP_REDIR_HOST: | ||
751 | case ICMP_REDIR_HOSTTOS: | ||
752 | ip_rt_redirect(skb->nh.iph->saddr, ip, skb->h.icmph->un.gateway, | ||
753 | iph->saddr, iph->tos, skb->dev); | ||
754 | break; | ||
755 | } | ||
756 | out: | ||
757 | return; | ||
758 | out_err: | ||
759 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | ||
760 | goto out; | ||
761 | } | ||
762 | |||
763 | /* | ||
764 | * Handle ICMP_ECHO ("ping") requests. | ||
765 | * | ||
766 | * RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo | ||
767 | * requests. | ||
768 | * RFC 1122: 3.2.2.6 Data received in the ICMP_ECHO request MUST be | ||
769 | * included in the reply. | ||
770 | * RFC 1812: 4.3.3.6 SHOULD have a config option for silently ignoring | ||
771 | * echo requests, MUST have default=NOT. | ||
772 | * See also WRT handling of options once they are done and working. | ||
773 | */ | ||
774 | |||
775 | static void icmp_echo(struct sk_buff *skb) | ||
776 | { | ||
777 | if (!sysctl_icmp_echo_ignore_all) { | ||
778 | struct icmp_bxm icmp_param; | ||
779 | |||
780 | icmp_param.data.icmph = *skb->h.icmph; | ||
781 | icmp_param.data.icmph.type = ICMP_ECHOREPLY; | ||
782 | icmp_param.skb = skb; | ||
783 | icmp_param.offset = 0; | ||
784 | icmp_param.data_len = skb->len; | ||
785 | icmp_param.head_len = sizeof(struct icmphdr); | ||
786 | icmp_reply(&icmp_param, skb); | ||
787 | } | ||
788 | } | ||
789 | |||
790 | /* | ||
791 | * Handle ICMP Timestamp requests. | ||
792 | * RFC 1122: 3.2.2.8 MAY implement ICMP timestamp requests. | ||
793 | * SHOULD be in the kernel for minimum random latency. | ||
794 | * MUST be accurate to a few minutes. | ||
795 | * MUST be updated at least at 15Hz. | ||
796 | */ | ||
797 | static void icmp_timestamp(struct sk_buff *skb) | ||
798 | { | ||
799 | struct timeval tv; | ||
800 | struct icmp_bxm icmp_param; | ||
801 | /* | ||
802 | * Too short. | ||
803 | */ | ||
804 | if (skb->len < 4) | ||
805 | goto out_err; | ||
806 | |||
807 | /* | ||
808 | * Fill in the current time as ms since midnight UT: | ||
809 | */ | ||
810 | do_gettimeofday(&tv); | ||
811 | icmp_param.data.times[1] = htonl((tv.tv_sec % 86400) * 1000 + | ||
812 | tv.tv_usec / 1000); | ||
813 | icmp_param.data.times[2] = icmp_param.data.times[1]; | ||
814 | if (skb_copy_bits(skb, 0, &icmp_param.data.times[0], 4)) | ||
815 | BUG(); | ||
816 | icmp_param.data.icmph = *skb->h.icmph; | ||
817 | icmp_param.data.icmph.type = ICMP_TIMESTAMPREPLY; | ||
818 | icmp_param.data.icmph.code = 0; | ||
819 | icmp_param.skb = skb; | ||
820 | icmp_param.offset = 0; | ||
821 | icmp_param.data_len = 0; | ||
822 | icmp_param.head_len = sizeof(struct icmphdr) + 12; | ||
823 | icmp_reply(&icmp_param, skb); | ||
824 | out: | ||
825 | return; | ||
826 | out_err: | ||
827 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | ||
828 | goto out; | ||
829 | } | ||
830 | |||
831 | |||
832 | /* | ||
833 | * Handle ICMP_ADDRESS_MASK requests. (RFC950) | ||
834 | * | ||
835 | * RFC1122 (3.2.2.9). A host MUST only send replies to | ||
836 | * ADDRESS_MASK requests if it's been configured as an address mask | ||
837 | * agent. Receiving a request doesn't constitute implicit permission to | ||
838 | * act as one. Of course, implementing this correctly requires (SHOULD) | ||
839 | * a way to turn the functionality on and off. Another one for sysctl(), | ||
840 | * I guess. -- MS | ||
841 | * | ||
842 | * RFC1812 (4.3.3.9). A router MUST implement it. | ||
843 | * A router SHOULD have switch turning it on/off. | ||
844 | * This switch MUST be ON by default. | ||
845 | * | ||
846 | * Gratuitous replies, zero-source replies are not implemented, | ||
847 | * that complies with RFC. DO NOT implement them!!! All the idea | ||
848 | * of broadcast addrmask replies as specified in RFC950 is broken. | ||
849 | * The problem is that it is not uncommon to have several prefixes | ||
850 | * on one physical interface. Moreover, addrmask agent can even be | ||
851 | * not aware of existing another prefixes. | ||
852 | * If source is zero, addrmask agent cannot choose correct prefix. | ||
853 | * Gratuitous mask announcements suffer from the same problem. | ||
854 | * RFC1812 explains it, but still allows to use ADDRMASK, | ||
855 | * that is pretty silly. --ANK | ||
856 | * | ||
857 | * All these rules are so bizarre, that I removed kernel addrmask | ||
858 | * support at all. It is wrong, it is obsolete, nobody uses it in | ||
859 | * any case. --ANK | ||
860 | * | ||
861 | * Furthermore you can do it with a usermode address agent program | ||
862 | * anyway... | ||
863 | */ | ||
864 | |||
865 | static void icmp_address(struct sk_buff *skb) | ||
866 | { | ||
867 | #if 0 | ||
868 | if (net_ratelimit()) | ||
869 | printk(KERN_DEBUG "a guy asks for address mask. Who is it?\n"); | ||
870 | #endif | ||
871 | } | ||
872 | |||
873 | /* | ||
874 | * RFC1812 (4.3.3.9). A router SHOULD listen all replies, and complain | ||
875 | * loudly if an inconsistency is found. | ||
876 | */ | ||
877 | |||
878 | static void icmp_address_reply(struct sk_buff *skb) | ||
879 | { | ||
880 | struct rtable *rt = (struct rtable *)skb->dst; | ||
881 | struct net_device *dev = skb->dev; | ||
882 | struct in_device *in_dev; | ||
883 | struct in_ifaddr *ifa; | ||
884 | |||
885 | if (skb->len < 4 || !(rt->rt_flags&RTCF_DIRECTSRC)) | ||
886 | goto out; | ||
887 | |||
888 | in_dev = in_dev_get(dev); | ||
889 | if (!in_dev) | ||
890 | goto out; | ||
891 | rcu_read_lock(); | ||
892 | if (in_dev->ifa_list && | ||
893 | IN_DEV_LOG_MARTIANS(in_dev) && | ||
894 | IN_DEV_FORWARD(in_dev)) { | ||
895 | u32 _mask, *mp; | ||
896 | |||
897 | mp = skb_header_pointer(skb, 0, sizeof(_mask), &_mask); | ||
898 | if (mp == NULL) | ||
899 | BUG(); | ||
900 | for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { | ||
901 | if (*mp == ifa->ifa_mask && | ||
902 | inet_ifa_match(rt->rt_src, ifa)) | ||
903 | break; | ||
904 | } | ||
905 | if (!ifa && net_ratelimit()) { | ||
906 | printk(KERN_INFO "Wrong address mask %u.%u.%u.%u from " | ||
907 | "%s/%u.%u.%u.%u\n", | ||
908 | NIPQUAD(*mp), dev->name, NIPQUAD(rt->rt_src)); | ||
909 | } | ||
910 | } | ||
911 | rcu_read_unlock(); | ||
912 | in_dev_put(in_dev); | ||
913 | out:; | ||
914 | } | ||
915 | |||
916 | static void icmp_discard(struct sk_buff *skb) | ||
917 | { | ||
918 | } | ||
919 | |||
920 | /* | ||
921 | * Deal with incoming ICMP packets. | ||
922 | */ | ||
923 | int icmp_rcv(struct sk_buff *skb) | ||
924 | { | ||
925 | struct icmphdr *icmph; | ||
926 | struct rtable *rt = (struct rtable *)skb->dst; | ||
927 | |||
928 | ICMP_INC_STATS_BH(ICMP_MIB_INMSGS); | ||
929 | |||
930 | switch (skb->ip_summed) { | ||
931 | case CHECKSUM_HW: | ||
932 | if (!(u16)csum_fold(skb->csum)) | ||
933 | break; | ||
934 | NETDEBUG(if (net_ratelimit()) | ||
935 | printk(KERN_DEBUG "icmp v4 hw csum failure\n")); | ||
936 | case CHECKSUM_NONE: | ||
937 | if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) | ||
938 | goto error; | ||
939 | default:; | ||
940 | } | ||
941 | |||
942 | if (!pskb_pull(skb, sizeof(struct icmphdr))) | ||
943 | goto error; | ||
944 | |||
945 | icmph = skb->h.icmph; | ||
946 | |||
947 | /* | ||
948 | * 18 is the highest 'known' ICMP type. Anything else is a mystery | ||
949 | * | ||
950 | * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently | ||
951 | * discarded. | ||
952 | */ | ||
953 | if (icmph->type > NR_ICMP_TYPES) | ||
954 | goto error; | ||
955 | |||
956 | |||
957 | /* | ||
958 | * Parse the ICMP message | ||
959 | */ | ||
960 | |||
961 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { | ||
962 | /* | ||
963 | * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be | ||
964 | * silently ignored (we let user decide with a sysctl). | ||
965 | * RFC 1122: 3.2.2.8 An ICMP_TIMESTAMP MAY be silently | ||
966 | * discarded if to broadcast/multicast. | ||
967 | */ | ||
968 | if (icmph->type == ICMP_ECHO && | ||
969 | sysctl_icmp_echo_ignore_broadcasts) { | ||
970 | goto error; | ||
971 | } | ||
972 | if (icmph->type != ICMP_ECHO && | ||
973 | icmph->type != ICMP_TIMESTAMP && | ||
974 | icmph->type != ICMP_ADDRESS && | ||
975 | icmph->type != ICMP_ADDRESSREPLY) { | ||
976 | goto error; | ||
977 | } | ||
978 | } | ||
979 | |||
980 | ICMP_INC_STATS_BH(icmp_pointers[icmph->type].input_entry); | ||
981 | icmp_pointers[icmph->type].handler(skb); | ||
982 | |||
983 | drop: | ||
984 | kfree_skb(skb); | ||
985 | return 0; | ||
986 | error: | ||
987 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | ||
988 | goto drop; | ||
989 | } | ||
990 | |||
991 | /* | ||
992 | * This table is the definition of how we handle ICMP. | ||
993 | */ | ||
994 | static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { | ||
995 | [ICMP_ECHOREPLY] = { | ||
996 | .output_entry = ICMP_MIB_OUTECHOREPS, | ||
997 | .input_entry = ICMP_MIB_INECHOREPS, | ||
998 | .handler = icmp_discard, | ||
999 | }, | ||
1000 | [1] = { | ||
1001 | .output_entry = ICMP_MIB_DUMMY, | ||
1002 | .input_entry = ICMP_MIB_INERRORS, | ||
1003 | .handler = icmp_discard, | ||
1004 | .error = 1, | ||
1005 | }, | ||
1006 | [2] = { | ||
1007 | .output_entry = ICMP_MIB_DUMMY, | ||
1008 | .input_entry = ICMP_MIB_INERRORS, | ||
1009 | .handler = icmp_discard, | ||
1010 | .error = 1, | ||
1011 | }, | ||
1012 | [ICMP_DEST_UNREACH] = { | ||
1013 | .output_entry = ICMP_MIB_OUTDESTUNREACHS, | ||
1014 | .input_entry = ICMP_MIB_INDESTUNREACHS, | ||
1015 | .handler = icmp_unreach, | ||
1016 | .error = 1, | ||
1017 | }, | ||
1018 | [ICMP_SOURCE_QUENCH] = { | ||
1019 | .output_entry = ICMP_MIB_OUTSRCQUENCHS, | ||
1020 | .input_entry = ICMP_MIB_INSRCQUENCHS, | ||
1021 | .handler = icmp_unreach, | ||
1022 | .error = 1, | ||
1023 | }, | ||
1024 | [ICMP_REDIRECT] = { | ||
1025 | .output_entry = ICMP_MIB_OUTREDIRECTS, | ||
1026 | .input_entry = ICMP_MIB_INREDIRECTS, | ||
1027 | .handler = icmp_redirect, | ||
1028 | .error = 1, | ||
1029 | }, | ||
1030 | [6] = { | ||
1031 | .output_entry = ICMP_MIB_DUMMY, | ||
1032 | .input_entry = ICMP_MIB_INERRORS, | ||
1033 | .handler = icmp_discard, | ||
1034 | .error = 1, | ||
1035 | }, | ||
1036 | [7] = { | ||
1037 | .output_entry = ICMP_MIB_DUMMY, | ||
1038 | .input_entry = ICMP_MIB_INERRORS, | ||
1039 | .handler = icmp_discard, | ||
1040 | .error = 1, | ||
1041 | }, | ||
1042 | [ICMP_ECHO] = { | ||
1043 | .output_entry = ICMP_MIB_OUTECHOS, | ||
1044 | .input_entry = ICMP_MIB_INECHOS, | ||
1045 | .handler = icmp_echo, | ||
1046 | }, | ||
1047 | [9] = { | ||
1048 | .output_entry = ICMP_MIB_DUMMY, | ||
1049 | .input_entry = ICMP_MIB_INERRORS, | ||
1050 | .handler = icmp_discard, | ||
1051 | .error = 1, | ||
1052 | }, | ||
1053 | [10] = { | ||
1054 | .output_entry = ICMP_MIB_DUMMY, | ||
1055 | .input_entry = ICMP_MIB_INERRORS, | ||
1056 | .handler = icmp_discard, | ||
1057 | .error = 1, | ||
1058 | }, | ||
1059 | [ICMP_TIME_EXCEEDED] = { | ||
1060 | .output_entry = ICMP_MIB_OUTTIMEEXCDS, | ||
1061 | .input_entry = ICMP_MIB_INTIMEEXCDS, | ||
1062 | .handler = icmp_unreach, | ||
1063 | .error = 1, | ||
1064 | }, | ||
1065 | [ICMP_PARAMETERPROB] = { | ||
1066 | .output_entry = ICMP_MIB_OUTPARMPROBS, | ||
1067 | .input_entry = ICMP_MIB_INPARMPROBS, | ||
1068 | .handler = icmp_unreach, | ||
1069 | .error = 1, | ||
1070 | }, | ||
1071 | [ICMP_TIMESTAMP] = { | ||
1072 | .output_entry = ICMP_MIB_OUTTIMESTAMPS, | ||
1073 | .input_entry = ICMP_MIB_INTIMESTAMPS, | ||
1074 | .handler = icmp_timestamp, | ||
1075 | }, | ||
1076 | [ICMP_TIMESTAMPREPLY] = { | ||
1077 | .output_entry = ICMP_MIB_OUTTIMESTAMPREPS, | ||
1078 | .input_entry = ICMP_MIB_INTIMESTAMPREPS, | ||
1079 | .handler = icmp_discard, | ||
1080 | }, | ||
1081 | [ICMP_INFO_REQUEST] = { | ||
1082 | .output_entry = ICMP_MIB_DUMMY, | ||
1083 | .input_entry = ICMP_MIB_DUMMY, | ||
1084 | .handler = icmp_discard, | ||
1085 | }, | ||
1086 | [ICMP_INFO_REPLY] = { | ||
1087 | .output_entry = ICMP_MIB_DUMMY, | ||
1088 | .input_entry = ICMP_MIB_DUMMY, | ||
1089 | .handler = icmp_discard, | ||
1090 | }, | ||
1091 | [ICMP_ADDRESS] = { | ||
1092 | .output_entry = ICMP_MIB_OUTADDRMASKS, | ||
1093 | .input_entry = ICMP_MIB_INADDRMASKS, | ||
1094 | .handler = icmp_address, | ||
1095 | }, | ||
1096 | [ICMP_ADDRESSREPLY] = { | ||
1097 | .output_entry = ICMP_MIB_OUTADDRMASKREPS, | ||
1098 | .input_entry = ICMP_MIB_INADDRMASKREPS, | ||
1099 | .handler = icmp_address_reply, | ||
1100 | }, | ||
1101 | }; | ||
1102 | |||
1103 | void __init icmp_init(struct net_proto_family *ops) | ||
1104 | { | ||
1105 | struct inet_sock *inet; | ||
1106 | int i; | ||
1107 | |||
1108 | for (i = 0; i < NR_CPUS; i++) { | ||
1109 | int err; | ||
1110 | |||
1111 | if (!cpu_possible(i)) | ||
1112 | continue; | ||
1113 | |||
1114 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, | ||
1115 | &per_cpu(__icmp_socket, i)); | ||
1116 | |||
1117 | if (err < 0) | ||
1118 | panic("Failed to create the ICMP control socket.\n"); | ||
1119 | |||
1120 | per_cpu(__icmp_socket, i)->sk->sk_allocation = GFP_ATOMIC; | ||
1121 | |||
1122 | /* Enough space for 2 64K ICMP packets, including | ||
1123 | * sk_buff struct overhead. | ||
1124 | */ | ||
1125 | per_cpu(__icmp_socket, i)->sk->sk_sndbuf = | ||
1126 | (2 * ((64 * 1024) + sizeof(struct sk_buff))); | ||
1127 | |||
1128 | inet = inet_sk(per_cpu(__icmp_socket, i)->sk); | ||
1129 | inet->uc_ttl = -1; | ||
1130 | inet->pmtudisc = IP_PMTUDISC_DONT; | ||
1131 | |||
1132 | /* Unhash it so that IP input processing does not even | ||
1133 | * see it, we do not wish this socket to see incoming | ||
1134 | * packets. | ||
1135 | */ | ||
1136 | per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk); | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | EXPORT_SYMBOL(icmp_err_convert); | ||
1141 | EXPORT_SYMBOL(icmp_send); | ||
1142 | EXPORT_SYMBOL(icmp_statistics); | ||
1143 | EXPORT_SYMBOL(xrlim_allow); | ||