1 /*
2 * NET3: Implementation of the ICMP protocol layer.
3 *
4 * Alan Cox, <alan@cymru.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * Some of the function names and the icmp unreach table for this
12 * module were derived from [icmp.c 1.0.11 06/02/93] by
13 * Ross Biro, Fred N. van Kempen, Mark Evans, Alan Cox, Gerhard Koerting.
14 * Other than that this module is a complete rewrite.
15 *
16 * Fixes:
17 * Mike Shaver : RFC1122 checks.
18 * Alan Cox : Multicast ping reply as self.
19 * Alan Cox : Fix atomicity lockup in ip_build_xmit call
20 * Alan Cox : Added 216,128 byte paths to the MTU code.
21 *
22 *
23 *
24 * RFC1122 Status: (boy, are there a lot of rules for ICMP)
25 * 3.2.2 (Generic ICMP stuff)
26 * MUST discard messages of unknown type. (OK)
27 * MUST copy at least the first 8 bytes from the offending packet
28 * when sending ICMP errors. (OK)
29 * MUST pass received ICMP errors up to protocol level. (OK)
30 * SHOULD send ICMP errors with TOS == 0. (OK)
31 * MUST NOT send ICMP errors in reply to:
32 * ICMP errors (OK)
33 * Broadcast/multicast datagrams (OK)
34 * MAC broadcasts (OK)
35 * Non-initial fragments (OK)
36 * Datagram with a source address that isn't a single host. (OK)
37 * 3.2.2.1 (Destination Unreachable)
38 * All the rules govern the IP layer, and are dealt with in ip.c, not here.
39 * 3.2.2.2 (Redirect)
40 * Host SHOULD NOT send ICMP_REDIRECTs. (OK)
41 * MUST update routing table in response to host or network redirects.
42 * (host OK, network NOT YET) [Intentionally -- AC]
43 * SHOULD drop redirects if they're not from directly connected gateway
44 * (OK -- we drop it if it's not from our old gateway, which is close
45 * enough)
46 * 3.2.2.3 (Source Quench)
47 * MUST pass incoming SOURCE_QUENCHs to transport layer (OK)
48 * Other requirements are dealt with at the transport layer.
49 * 3.2.2.4 (Time Exceeded)
50 * MUST pass TIME_EXCEEDED to transport layer (OK)
51 * Other requirements dealt with at IP (generating TIME_EXCEEDED).
52 * 3.2.2.5 (Parameter Problem)
53 * SHOULD generate these, but it doesn't say for what. So we're OK. =)
54 * MUST pass received PARAMPROBLEM to transport layer (NOT YET)
55 * [Solaris 2.X seems to assert EPROTO when this occurs] -- AC
56 * 3.2.2.6 (Echo Request/Reply)
57 * MUST reply to ECHO_REQUEST, and give app to do ECHO stuff (OK, OK)
58 * MAY discard broadcast ECHO_REQUESTs. (We don't, but that's OK.)
59 * MUST reply using same source address as the request was sent to.
60 * We're OK for unicast ECHOs, and it doesn't say anything about
61 * how to handle broadcast ones, since it's optional.
62 * MUST copy data from REQUEST to REPLY (OK)
63 * unless it would require illegal fragmentation (N/A)
64 * MUST pass REPLYs to transport/user layer (OK)
65 * MUST use any provided source route (reversed) for REPLY. (NOT YET)
66 * 3.2.2.7 (Information Request/Reply)
67 * MUST NOT implement this. (I guess that means silently discard...?) (OK)
68 * 3.2.2.8 (Timestamp Request/Reply)
69 * MAY implement (OK)
70 * SHOULD be in-kernel for "minimum variability" (OK)
71 * MAY discard broadcast REQUESTs. (OK, but see source for inconsistency)
72 * MUST reply using same source address as the request was sent to. (OK)
73 * MUST reverse source route, as per ECHO (NOT YET)
74 * MUST pass REPLYs to transport/user layer (requires RAW, just like ECHO) (OK)
75 * MUST update clock for timestamp at least 15 times/sec (OK)
76 * MUST be "correct within a few minutes" (OK)
77 * 3.2.2.9 (Address Mask Request/Reply)
78 * MAY implement (OK)
79 * MUST send a broadcast REQUEST if using this system to set netmask
80 * (OK... we don't use it)
81 * MUST discard received REPLYs if not using this system (OK)
82 * MUST NOT send replies unless specifically made agent for this sort
83 * of thing. (OK)
84 */
85
86 #include <linux/config.h>
87 #include <linux/types.h>
88 #include <linux/sched.h>
89 #include <linux/kernel.h>
90 #include <linux/fcntl.h>
91 #include <linux/socket.h>
92 #include <linux/in.h>
93 #include <linux/inet.h>
94 #include <linux/netdevice.h>
95 #include <linux/string.h>
96 #include <net/snmp.h>
97 #include <net/ip.h>
98 #include <net/route.h>
99 #include <net/protocol.h>
100 #include <net/icmp.h>
101 #include <net/tcp.h>
102 #include <net/snmp.h>
103 #include <linux/skbuff.h>
104 #include <net/sock.h>
105 #include <linux/errno.h>
106 #include <linux/timer.h>
107 #include <asm/system.h>
108 #include <asm/segment.h>
109 #include <net/checksum.h>
110
111 #define min(a,b) ((a)<(b)?(a):(b))
112
113 /*
114 * Statistics
115 */
116
117 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, HOS_UNREACH and SR_FAIELD MUST be considered 'transient errs'. */
121
122 struct icmp_err icmp_err_convert[] = {
123 { ENETUNREACH, 0 }, /* ICMP_NET_UNREACH */
124 { EHOSTUNREACH, 0 }, /* ICMP_HOST_UNREACH */
125 { ENOPROTOOPT, 1 }, /* ICMP_PROT_UNREACH */
126 { ECONNREFUSED, 1 }, /* ICMP_PORT_UNREACH */
127 { EOPNOTSUPP, 0 }, /* ICMP_FRAG_NEEDED */
128 { EOPNOTSUPP, 0 }, /* ICMP_SR_FAILED */
129 { ENETUNREACH, 1 }, /* ICMP_NET_UNKNOWN */
130 { EHOSTDOWN, 1 }, /* ICMP_HOST_UNKNOWN */
131 { ENONET, 1 }, /* ICMP_HOST_ISOLATED */
132 { ENETUNREACH, 1 }, /* ICMP_NET_ANO */
133 { EHOSTUNREACH, 1 }, /* ICMP_HOST_ANO */
134 { EOPNOTSUPP, 0 }, /* ICMP_NET_UNR_TOS */
135 { EOPNOTSUPP, 0 } /* ICMP_HOST_UNR_TOS */
136 };
137
138 /*
139 * A spare long used to speed up statistics updating
140 */
141
142 unsigned long dummy;
143
144 /*
145 * ICMP control array. This specifies what to do with each ICMP.
146 */
147
148 struct icmp_control
149 {
150 unsigned long *output; /* Address to increment on output */
151 unsigned long *input; /* Address to increment on input */
152 void (*handler)(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len);
153 unsigned long error; /* This ICMP is classed as an error message */
154 };
155
156 static struct icmp_control icmp_pointers[19];
157
158 /*
159 * Build xmit assembly blocks
160 */
161
162 struct icmp_bxm
163 {
164 void *data_ptr;
165 int data_len;
166 struct icmphdr icmph;
167 unsigned long csum;
168 struct options replyopts;
169 unsigned char optbuf[40];
170 };
171
172 /*
173 * The ICMP socket. This is the most convenient way to flow control
174 * our ICMP output as well as maintain a clean interface throughout
175 * all layers. All Socketless IP sends will soon be gone.
176 */
177
178 struct socket icmp_socket;
179
180 /*
181 * Send an ICMP frame.
182 */
183
184
185 /*
186 * Maintain the counters used in the SNMP statistics for outgoing ICMP
187 */
188
189 static void icmp_out_count(int type)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
190 {
191 if(type>18)
192 return;
193 (*icmp_pointers[type].output)++;
194 icmp_statistics.IcmpOutMsgs++;
195 }
196
197 /*
198 * Checksum each fragment, and on the first include the headers and final checksum.
199 */
200
201 static void icmp_glue_bits(const void *p, __u32 saddr, char *to, unsigned int offset, unsigned int fraglen)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
202 {
203 struct icmp_bxm *icmp_param = (struct icmp_bxm *)p;
204 struct icmphdr *icmph;
205 unsigned long csum;
206
207 if (offset) {
208 icmp_param->csum=csum_partial_copy(icmp_param->data_ptr+offset-sizeof(struct icmphdr),
209 to, fraglen,icmp_param->csum);
210 return;
211 }
212
213 /*
214 * First fragment includes header. Note that we've done
215 * the other fragments first, so that we get the checksum
216 * for the whole packet here.
217 */
218 csum = csum_partial_copy((void *)&icmp_param->icmph,
219 to, sizeof(struct icmphdr),
220 icmp_param->csum);
221 csum = csum_partial_copy(icmp_param->data_ptr,
222 to+sizeof(struct icmphdr),
223 fraglen-sizeof(struct icmphdr), csum);
224 icmph=(struct icmphdr *)to;
225 icmph->checksum = csum_fold(csum);
226 }
227
228 /*
229 * Driving logic for building and sending ICMP messages.
230 */
231
232 static void icmp_build_xmit(struct icmp_bxm *icmp_param, __u32 saddr, __u32 daddr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
233 {
234 struct sock *sk=icmp_socket.data;
235 icmp_param->icmph.checksum=0;
236 icmp_param->csum=0;
237 icmp_out_count(icmp_param->icmph.type);
238 ip_build_xmit(sk, icmp_glue_bits, icmp_param,
239 icmp_param->data_len+sizeof(struct icmphdr),
240 daddr, saddr, &icmp_param->replyopts, 0, IPPROTO_ICMP, 1);
241 }
242
243
244 /*
245 * Send an ICMP message in response to a situation
246 *
247 * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. MAY send more (we don't).
248 * MUST NOT change this header information.
249 * MUST NOT reply to a multicast/broadcast IP address.
250 * MUST NOT reply to a multicast/broadcast MAC address.
251 * MUST reply to only the first fragment.
252 */
253
254 void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
255 {
256 struct iphdr *iph;
257 struct icmphdr *icmph;
258 int atype;
259 struct icmp_bxm icmp_param;
260 __u32 saddr;
261
262 /*
263 * Find the original header
264 */
265
266 iph = skb_in->ip_hdr;
267
268 /*
269 * No replies to physical multicast/broadcast
270 */
271
272 if(skb_in->pkt_type!=PACKET_HOST)
273 return;
274
275 /*
276 * Now check at the protocol level
277 */
278
279 atype=ip_chk_addr(iph->daddr);
280 if(atype==IS_BROADCAST||atype==IS_MULTICAST)
281 return;
282
283 /*
284 * Only reply to fragment 0. We byte re-order the constant
285 * mask for efficiency.
286 */
287
288 if(iph->frag_off&htons(IP_OFFSET))
289 return;
290
291 /*
292 * If we send an ICMP error to an ICMP error a mess would result..
293 */
294
295 if(icmp_pointers[type].error)
296 {
297 /*
298 * We are an error, check if we are replying to an ICMP error
299 */
300
301 if(iph->protocol==IPPROTO_ICMP)
302 {
303 icmph = (struct icmphdr *)((char *)iph + (iph->ihl<<2));
304 /*
305 * Assume any unknown ICMP type is an error. This isn't
306 * specified by the RFC, but think about it..
307 */
308 if(icmph->type>18 || icmp_pointers[icmph->type].error)
309 return;
310 }
311 }
312
313 /*
314 * Tell our driver what to send
315 */
316
317 saddr=iph->daddr;
318 if(saddr!=dev->pa_addr && ip_chk_addr(saddr)!=IS_MYADDR)
319 saddr=dev->pa_addr;
320
321 icmp_param.icmph.type=type;
322 icmp_param.icmph.code=code;
323 icmp_param.icmph.un.gateway = info;
324 icmp_param.data_ptr=iph;
325 icmp_param.data_len=(iph->ihl<<2)+8; /* RFC says return header + 8 bytes */
326
327 /*
328 * Set it to build.
329 */
330
331 if (ip_options_echo(&icmp_param.replyopts, NULL, saddr, iph->saddr, skb_in) == 0)
332 icmp_build_xmit(&icmp_param, saddr, iph->saddr);
333 }
334
335
336 /*
337 * Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, and ICMP_QUENCH.
338 */
339
340 static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
341 {
342 struct iphdr *iph;
343 int hash;
344 struct inet_protocol *ipprot;
345 unsigned char *dp;
346
347 iph = (struct iphdr *) (icmph + 1);
348
349 dp= ((unsigned char *)iph)+(iph->ihl<<2);
350
351 if(icmph->type==ICMP_DEST_UNREACH)
352 {
353 switch(icmph->code & 15)
354 {
355 case ICMP_NET_UNREACH:
356 break;
357 case ICMP_HOST_UNREACH:
358 break;
359 case ICMP_PROT_UNREACH:
360 /* printk(KERN_INFO "ICMP: %s:%d: protocol unreachable.\n",
361 in_ntoa(iph->daddr), (int)iph->protocol);*/
362 break;
363 case ICMP_PORT_UNREACH:
364 break;
365 case ICMP_FRAG_NEEDED:
366 #ifdef CONFIG_NO_PATH_MTU_DISCOVERY
367 printk(KERN_INFO "ICMP: %s: fragmentation needed and DF set.\n",
368 in_ntoa(iph->daddr));
369 break;
370 #else
371 {
372 unsigned short old_mtu = ntohs(iph->tot_len);
373 unsigned short new_mtu = ntohs(icmph->un.echo.sequence);
374
375 if (new_mtu < 68 || new_mtu >= old_mtu)
376 {
377 /*
378 * It is either dumb router, which does not
379 * understand Path MTU Disc. protocol
380 * or broken (f.e. Linux<=1.3.37 8) router.
381 * Try to guess...
382 * The table is taken from RFC-1191.
383 */
384 if (old_mtu > 32000)
385 new_mtu = 32000;
386 else if (old_mtu > 17914)
387 new_mtu = 17914;
388 else if (old_mtu > 8166)
389 new_mtu = 8166;
390 else if (old_mtu > 4352)
391 new_mtu = 4352;
392 else if (old_mtu > 2002)
393 new_mtu = 2002;
394 else if (old_mtu > 1492)
395 new_mtu = 1492;
396 else if (old_mtu > 576)
397 new_mtu = 576;
398 else if (old_mtu > 296)
399 new_mtu = 296;
400 /*
401 * These two are not from the RFC but
402 * are needed for AMPRnet AX.25 paths.
403 */
404 else if (old_mtu > 216)
405 new_mtu = 216;
406 else if (old_mtu > 128)
407 new_mtu = 128;
408 else
409 /*
410 * Despair..
411 */
412 new_mtu = 68;
413 }
414 /*
415 * Ugly trick to pass MTU to protocol layer.
416 * Really we should add argument "info" to error handler.
417 */
418 iph->id = htons(new_mtu);
419 break;
420 }
421 #endif
422 case ICMP_SR_FAILED:
423 printk(KERN_INFO "ICMP: %s: Source Route Failed.\n", in_ntoa(iph->daddr));
424 break;
425 default:
426 break;
427 }
428 if(icmph->code>12) /* Invalid type */
429 return;
430 }
431
432 /*
433 * Throw it at our lower layers
434 *
435 * RFC 1122: 3.2.2 MUST extract the protocol ID from the passed header.
436 * RFC 1122: 3.2.2.1 MUST pass ICMP unreach messages to the transport layer.
437 * RFC 1122: 3.2.2.2 MUST pass ICMP time expired messages to transport layer.
438 */
439
440 /*
441 * Get the protocol(s).
442 */
443
444 hash = iph->protocol & (MAX_INET_PROTOS -1);
445
446 /*
447 * This can't change while we are doing it.
448 *
449 * FIXME: Deliver to appropriate raw sockets too.
450 */
451
452 ipprot = (struct inet_protocol *) inet_protos[hash];
453 while(ipprot != NULL)
454 {
455 struct inet_protocol *nextip;
456
457 nextip = (struct inet_protocol *) ipprot->next;
458
459 /*
460 * Pass it off to everyone who wants it.
461 */
462
463 /* RFC1122: OK. Passes appropriate ICMP errors to the */
464 /* appropriate protocol layer (MUST), as per 3.2.2. */
465
466 if (iph->protocol == ipprot->protocol && ipprot->err_handler)
467 {
468 ipprot->err_handler(icmph->type, icmph->code, dp,
469 iph->daddr, iph->saddr, ipprot);
470 }
471
472 ipprot = nextip;
473 }
474 kfree_skb(skb, FREE_READ);
475 }
476
477
478 /*
479 * Handle ICMP_REDIRECT.
480 */
481
482 static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 source, __u32 daddr, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
483 {
484 struct iphdr *iph;
485 unsigned long ip;
486
487 /*
488 * Get the copied header of the packet that caused the redirect
489 */
490
491 iph = (struct iphdr *) (icmph + 1);
492 ip = iph->daddr;
493
494 #ifdef CONFIG_IP_FORWARD
495 /*
496 * We are a router. Routers should not respond to ICMP_REDIRECT messages.
497 */
498 printk(KERN_INFO "icmp: ICMP redirect ignored. dest = %s, "
499 "orig gw = %s, \"new\" gw = %s, device = %s.\n", in_ntoa(ip),
500 in_ntoa(source), in_ntoa(icmph->un.gateway), dev->name);
501 #else
502 switch(icmph->code & 7)
503 {
504 case ICMP_REDIR_NET:
505 /*
506 * This causes a problem with subnetted networks. What we should do
507 * is use ICMP_ADDRESS to get the subnet mask of the problem route
508 * and set both. But we don't..
509 */
510 #ifdef not_a_good_idea
511 ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY),
512 ip, 0, icmph->un.gateway, dev,0, 0, 0);
513 #endif
514 /*
515 * As per RFC recommendations now handle it as
516 * a host redirect.
517 */
518
519 case ICMP_REDIR_HOST:
520 /*
521 * Add better route to host.
522 * But first check that the redirect
523 * comes from the old gateway..
524 * And make sure it's an ok host address
525 * (not some confused thing sending our
526 * address)
527 */
528 printk(KERN_INFO "ICMP redirect from %s\n", in_ntoa(source));
529 ip_rt_redirect(source, ip, icmph->un.gateway, dev);
530 break;
531 case ICMP_REDIR_NETTOS:
532 case ICMP_REDIR_HOSTTOS:
533 printk(KERN_INFO "ICMP: cannot handle TOS redirects yet!\n");
534 break;
535 default:
536 break;
537 }
538 #endif
539 /*
540 * Discard the original packet
541 */
542
543 kfree_skb(skb, FREE_READ);
544 }
545
546 /*
547 * Handle ICMP_ECHO ("ping") requests.
548 *
549 * RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo requests.
550 * RFC 1122: 3.2.2.6 Data received in the ICMP_ECHO request MUST be included in the reply.
551 * See also WRT handling of options once they are done and working.
552 */
553
554 static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
555 {
556 struct icmp_bxm icmp_param;
557 icmp_param.icmph=*icmph;
558 icmp_param.icmph.type=ICMP_ECHOREPLY;
559 icmp_param.data_ptr=(icmph+1);
560 icmp_param.data_len=len;
561 if (ip_options_echo(&icmp_param.replyopts, NULL, daddr, saddr, skb)==0)
562 icmp_build_xmit(&icmp_param, daddr, saddr);
563 kfree_skb(skb, FREE_READ);
564 }
565
566 /*
567 * Handle ICMP Timestamp requests.
568 * RFC 1122: 3.2.2.8 MAY implement ICMP timestamp requests.
569 * SHOULD be in the kernel for minimum random latency.
570 * MUST be accurate to a few minutes.
571 * MUST be updated at least at 15Hz.
572 */
573
574 static void icmp_timestamp(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
575 {
576 __u32 times[3]; /* So the new timestamp works on ALPHA's.. */
577 struct icmp_bxm icmp_param;
578
579 /*
580 * Too short.
581 */
582
583 if(len<12)
584 {
585 icmp_statistics.IcmpInErrors++;
586 kfree_skb(skb, FREE_READ);
587 return;
588 }
589
590 /*
591 * Fill in the current time as ms since midnight UT:
592 */
593
594 {
595 struct timeval tv;
596 do_gettimeofday(&tv);
597 times[1] = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
598 }
599 times[2] = times[1];
600 memcpy((void *)×[0], icmph+1, 4); /* Incoming stamp */
601 icmp_param.icmph=*icmph;
602 icmp_param.icmph.type=ICMP_TIMESTAMPREPLY;
603 icmp_param.icmph.code=0;
604 icmp_param.data_ptr=×
605 icmp_param.data_len=12;
606 if (ip_options_echo(&icmp_param.replyopts, NULL, daddr, saddr, skb)==0)
607 icmp_build_xmit(&icmp_param, daddr, saddr);
608 kfree_skb(skb,FREE_READ);
609 }
610
611
612 /*
613 * Handle ICMP_ADDRESS_MASK requests. (RFC950)
614 *
615 * RFC1122 (3.2.2.9). A host MUST only send replies to
616 * ADDRESS_MASK requests if it's been configured as an address mask
617 * agent. Receiving a request doesn't constitute implicit permission to
618 * act as one. Of course, implementing this correctly requires (SHOULD)
619 * a way to turn the functionality on and off. Another one for sysctl(),
620 * I guess. -- MS
621 * Botched with a CONFIG option for now - Linus add scts sysctl please..
622 */
623
624 static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
625 {
626 #ifdef CONFIG_IP_ADDR_AGENT
627 __u32 answer;
628 struct icmp_bxm icmp_param;
629 icmp_param.icmph.type=ICMP_ADDRESSREPLY;
630 icmp_param.icmph.code=0;
631 icmp_param.icmph.un.echo.id = icmph->un.echo.id;
632 icmp_param.icmph.un.echo.sequence = icmph->un.echo.sequence;
633 icmp_param.data_ptr=&dev->pa_mask;
634 icmp_param.data_len=4;
635 if (ip_options_echo(&icmp_param.replyopts, NULL, daddr, saddr, skb)==0)
636 icmp_build_xmit(&icmp_param, daddr, saddr);
637 #endif
638 kfree_skb(skb, FREE_READ);
639 }
640
641 static void icmp_discard(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
642 {
643 kfree_skb(skb, FREE_READ);
644 }
645
646 /*
647 * Deal with incoming ICMP packets.
648 */
649
650 int icmp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
651 __u32 daddr, unsigned short len,
652 __u32 saddr, int redo, struct inet_protocol *protocol)
653 {
654 struct icmphdr *icmph=(void *)skb->h.raw;
655 icmp_statistics.IcmpInMsgs++;
656
657 /*
658 * Validate the packet
659 */
660
661 if (ip_compute_csum((unsigned char *) icmph, len))
662 {
663 /* Failed checksum! */
664 icmp_statistics.IcmpInErrors++;
665 printk(KERN_INFO "ICMP: failed checksum from %s!\n", in_ntoa(saddr));
666 kfree_skb(skb, FREE_READ);
667 return(0);
668 }
669
670 /*
671 * 18 is the highest 'known' icmp type. Anything else is a mystery
672 *
673 * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently discarded.
674 */
675
676 if(icmph->type > 18)
677 {
678 icmp_statistics.IcmpInErrors++; /* Is this right - or do we ignore ? */
679 kfree_skb(skb,FREE_READ);
680 return(0);
681 }
682
683 /*
684 * Parse the ICMP message
685 */
686
687 if (daddr!=dev->pa_addr && ip_chk_addr(daddr) != IS_MYADDR)
688 {
689 /*
690 * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be silently ignored (we don't as it is used
691 * by some network mapping tools).
692 * RFC 1122: 3.2.2.8 An ICMP_TIMESTAMP MAY be silently discarded if to broadcast/multicast.
693 */
694 if (icmph->type != ICMP_ECHO)
695 {
696 icmp_statistics.IcmpInErrors++;
697 kfree_skb(skb, FREE_READ);
698 return(0);
699 }
700 /*
701 * Reply the multicast/broadcast using a legal
702 * interface - in this case the device we got
703 * it from.
704 */
705 daddr=dev->pa_addr;
706 }
707
708 len-=sizeof(struct icmphdr);
709 (*icmp_pointers[icmph->type].input)++;
710 (icmp_pointers[icmph->type].handler)(icmph,skb,skb->dev,saddr,daddr,len);
711 return 0;
712 }
713
714 /*
715 * This table is the definition of how we handle ICMP.
716 */
717
718 static struct icmp_control icmp_pointers[19] = {
719 /* ECHO REPLY (0) */
720 { &icmp_statistics.IcmpOutEchoReps, &icmp_statistics.IcmpInEchoReps, icmp_discard, 0 },
721 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1 },
722 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1 },
723 /* DEST UNREACH (3) */
724 { &icmp_statistics.IcmpOutDestUnreachs, &icmp_statistics.IcmpInDestUnreachs, icmp_unreach, 1 },
725 /* SOURCE QUENCH (4) */
726 { &icmp_statistics.IcmpOutSrcQuenchs, &icmp_statistics.IcmpInSrcQuenchs, icmp_unreach, 1 },
727 /* REDIRECT (5) */
728 { &icmp_statistics.IcmpOutRedirects, &icmp_statistics.IcmpInRedirects, icmp_redirect, 1 },
729 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1 },
730 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1 },
731 /* ECHO (8) */
732 { &icmp_statistics.IcmpOutEchos, &icmp_statistics.IcmpInEchos, icmp_echo, 0 },
733 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1 },
734 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1 },
735 /* TIME EXCEEDED (11) */
736 { &icmp_statistics.IcmpOutTimeExcds, &icmp_statistics.IcmpInTimeExcds, icmp_unreach, 1 },
737 /* PARAMETER PROBLEM (12) */
738 /* FIXME: RFC1122 3.2.2.5 - MUST pass PARAM_PROB messages to transport layer */
739 { &icmp_statistics.IcmpOutParmProbs, &icmp_statistics.IcmpInParmProbs, icmp_discard, 1 },
740 /* TIMESTAMP (13) */
741 { &icmp_statistics.IcmpOutTimestamps, &icmp_statistics.IcmpInTimestamps, icmp_timestamp, 0 },
742 /* TIMESTAMP REPLY (14) */
743 { &icmp_statistics.IcmpOutTimestampReps, &icmp_statistics.IcmpInTimestampReps, icmp_discard, 0 },
744 /* INFO (15) */
745 { &dummy, &dummy, icmp_discard, 0 },
746 /* INFO REPLY (16) */
747 { &dummy, &dummy, icmp_discard, 0 },
748 /* ADDR MASK (17) */
749 { &icmp_statistics.IcmpOutAddrMasks, &icmp_statistics.IcmpInAddrMasks, icmp_address, 0 },
750 /* ADDR MASK REPLY (18) */
751 { &icmp_statistics.IcmpOutAddrMaskReps, &icmp_statistics.IcmpInAddrMaskReps, icmp_discard, 0 }
752 };
753
754 void icmp_init(struct proto_ops *ops)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
755 {
756 struct sock *sk;
757 int err;
758 icmp_socket.type=SOCK_RAW;
759 icmp_socket.ops=ops;
760 if((err=ops->create(&icmp_socket, IPPROTO_ICMP))<0)
761 panic("Failed to create the ICMP control socket.\n");
762 sk=icmp_socket.data;
763 sk->allocation=GFP_ATOMIC;
764 sk->num = 256; /* Don't receive any data */
765 }
766