ip_icmp.c (1829d5da5355930d5cfa8ec8add8ff47dc0bebab) ip_icmp.c (e27b0c87759d9d7a6eebca60bc82f171fbf36afc)
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 166 unchanged lines hidden (view full) ---

175 unsigned icmplen, icmpelen, nlen;
176
177 KASSERT((u_int)type <= ICMP_MAXTYPE, ("%s: illegal ICMP type", __func__));
178#ifdef ICMPPRINTFS
179 if (icmpprintfs)
180 printf("icmp_error(%p, %x, %d)\n", oip, type, code);
181#endif
182 if (type != ICMP_REDIRECT)
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 166 unchanged lines hidden (view full) ---

175 unsigned icmplen, icmpelen, nlen;
176
177 KASSERT((u_int)type <= ICMP_MAXTYPE, ("%s: illegal ICMP type", __func__));
178#ifdef ICMPPRINTFS
179 if (icmpprintfs)
180 printf("icmp_error(%p, %x, %d)\n", oip, type, code);
181#endif
182 if (type != ICMP_REDIRECT)
183 V_icmpstat.icps_error++;
183 ICMPSTAT_INC(icps_error);
184 /*
185 * Don't send error:
186 * if the original packet was encrypted.
187 * if not the first fragment of message.
188 * in response to a multicast or broadcast packet.
189 * if the old packet protocol was an ICMP error message.
190 */
191 if (n->m_flags & M_DECRYPTED)
192 goto freeit;
193 if (oip->ip_off & ~(IP_MF|IP_DF))
194 goto freeit;
195 if (n->m_flags & (M_BCAST|M_MCAST))
196 goto freeit;
197 if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
198 n->m_len >= oiphlen + ICMP_MINLEN &&
199 !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiphlen))->icmp_type)) {
184 /*
185 * Don't send error:
186 * if the original packet was encrypted.
187 * if not the first fragment of message.
188 * in response to a multicast or broadcast packet.
189 * if the old packet protocol was an ICMP error message.
190 */
191 if (n->m_flags & M_DECRYPTED)
192 goto freeit;
193 if (oip->ip_off & ~(IP_MF|IP_DF))
194 goto freeit;
195 if (n->m_flags & (M_BCAST|M_MCAST))
196 goto freeit;
197 if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
198 n->m_len >= oiphlen + ICMP_MINLEN &&
199 !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiphlen))->icmp_type)) {
200 V_icmpstat.icps_oldicmp++;
200 ICMPSTAT_INC(icps_oldicmp);
201 goto freeit;
202 }
203 /* Drop if IP header plus 8 bytes is not contignous in first mbuf. */
204 if (oiphlen + 8 > n->m_len)
205 goto freeit;
206 /*
207 * Calculate length to quote from original packet and
208 * prevent the ICMP mbuf from overflowing.

--- 43 unchanged lines hidden (view full) ---

252 m_align(m, ICMP_MINLEN + icmplen);
253 m->m_len = ICMP_MINLEN + icmplen;
254
255 /* XXX MRT make the outgoing packet use the same FIB
256 * that was associated with the incoming packet
257 */
258 M_SETFIB(m, M_GETFIB(n));
259 icp = mtod(m, struct icmp *);
201 goto freeit;
202 }
203 /* Drop if IP header plus 8 bytes is not contignous in first mbuf. */
204 if (oiphlen + 8 > n->m_len)
205 goto freeit;
206 /*
207 * Calculate length to quote from original packet and
208 * prevent the ICMP mbuf from overflowing.

--- 43 unchanged lines hidden (view full) ---

252 m_align(m, ICMP_MINLEN + icmplen);
253 m->m_len = ICMP_MINLEN + icmplen;
254
255 /* XXX MRT make the outgoing packet use the same FIB
256 * that was associated with the incoming packet
257 */
258 M_SETFIB(m, M_GETFIB(n));
259 icp = mtod(m, struct icmp *);
260 V_icmpstat.icps_outhist[type]++;
260 ICMPSTAT_INC(icps_outhist[type]);
261 icp->icmp_type = type;
262 if (type == ICMP_REDIRECT)
263 icp->icmp_gwaddr.s_addr = dest;
264 else {
265 icp->icmp_void = 0;
266 /*
267 * The following assignments assume an overlay with the
268 * just zeroed icmp_void field.

--- 66 unchanged lines hidden (view full) ---

335 if (icmpprintfs) {
336 char buf[4 * sizeof "123"];
337 strcpy(buf, inet_ntoa(ip->ip_src));
338 printf("icmp_input from %s to %s, len %d\n",
339 buf, inet_ntoa(ip->ip_dst), icmplen);
340 }
341#endif
342 if (icmplen < ICMP_MINLEN) {
261 icp->icmp_type = type;
262 if (type == ICMP_REDIRECT)
263 icp->icmp_gwaddr.s_addr = dest;
264 else {
265 icp->icmp_void = 0;
266 /*
267 * The following assignments assume an overlay with the
268 * just zeroed icmp_void field.

--- 66 unchanged lines hidden (view full) ---

335 if (icmpprintfs) {
336 char buf[4 * sizeof "123"];
337 strcpy(buf, inet_ntoa(ip->ip_src));
338 printf("icmp_input from %s to %s, len %d\n",
339 buf, inet_ntoa(ip->ip_dst), icmplen);
340 }
341#endif
342 if (icmplen < ICMP_MINLEN) {
343 V_icmpstat.icps_tooshort++;
343 ICMPSTAT_INC(icps_tooshort);
344 goto freeit;
345 }
346 i = hlen + min(icmplen, ICMP_ADVLENMIN);
347 if (m->m_len < i && (m = m_pullup(m, i)) == 0) {
344 goto freeit;
345 }
346 i = hlen + min(icmplen, ICMP_ADVLENMIN);
347 if (m->m_len < i && (m = m_pullup(m, i)) == 0) {
348 V_icmpstat.icps_tooshort++;
348 ICMPSTAT_INC(icps_tooshort);
349 return;
350 }
351 ip = mtod(m, struct ip *);
352 m->m_len -= hlen;
353 m->m_data += hlen;
354 icp = mtod(m, struct icmp *);
355 if (in_cksum(m, icmplen)) {
349 return;
350 }
351 ip = mtod(m, struct ip *);
352 m->m_len -= hlen;
353 m->m_data += hlen;
354 icp = mtod(m, struct icmp *);
355 if (in_cksum(m, icmplen)) {
356 V_icmpstat.icps_checksum++;
356 ICMPSTAT_INC(icps_checksum);
357 goto freeit;
358 }
359 m->m_len += hlen;
360 m->m_data -= hlen;
361
362 if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
363 /*
364 * Deliver very specific ICMP type only.

--- 25 unchanged lines hidden (view full) ---

390 icmpsrc.sin_family = AF_INET;
391 bzero(&icmpdst, sizeof(icmpdst));
392 icmpdst.sin_len = sizeof(struct sockaddr_in);
393 icmpdst.sin_family = AF_INET;
394 bzero(&icmpgw, sizeof(icmpgw));
395 icmpgw.sin_len = sizeof(struct sockaddr_in);
396 icmpgw.sin_family = AF_INET;
397
357 goto freeit;
358 }
359 m->m_len += hlen;
360 m->m_data -= hlen;
361
362 if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
363 /*
364 * Deliver very specific ICMP type only.

--- 25 unchanged lines hidden (view full) ---

390 icmpsrc.sin_family = AF_INET;
391 bzero(&icmpdst, sizeof(icmpdst));
392 icmpdst.sin_len = sizeof(struct sockaddr_in);
393 icmpdst.sin_family = AF_INET;
394 bzero(&icmpgw, sizeof(icmpgw));
395 icmpgw.sin_len = sizeof(struct sockaddr_in);
396 icmpgw.sin_family = AF_INET;
397
398 V_icmpstat.icps_inhist[icp->icmp_type]++;
398 ICMPSTAT_INC(icps_inhist[icp->icmp_type]);
399 code = icp->icmp_code;
400 switch (icp->icmp_type) {
401
402 case ICMP_UNREACH:
403 switch (code) {
404 case ICMP_UNREACH_NET:
405 case ICMP_UNREACH_HOST:
406 case ICMP_UNREACH_SRCFAIL:

--- 48 unchanged lines hidden (view full) ---

455 goto badcode;
456 code = PRC_QUENCH;
457 deliver:
458 /*
459 * Problem with datagram; advise higher level routines.
460 */
461 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
462 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
399 code = icp->icmp_code;
400 switch (icp->icmp_type) {
401
402 case ICMP_UNREACH:
403 switch (code) {
404 case ICMP_UNREACH_NET:
405 case ICMP_UNREACH_HOST:
406 case ICMP_UNREACH_SRCFAIL:

--- 48 unchanged lines hidden (view full) ---

455 goto badcode;
456 code = PRC_QUENCH;
457 deliver:
458 /*
459 * Problem with datagram; advise higher level routines.
460 */
461 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
462 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
463 V_icmpstat.icps_badlen++;
463 ICMPSTAT_INC(icps_badlen);
464 goto freeit;
465 }
466 icp->icmp_ip.ip_len = ntohs(icp->icmp_ip.ip_len);
467 /* Discard ICMP's in response to multicast packets */
468 if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr)))
469 goto badcode;
470#ifdef ICMPPRINTFS
471 if (icmpprintfs)

--- 6 unchanged lines hidden (view full) ---

478 */
479 ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
480 if (ctlfunc)
481 (*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
482 (void *)&icp->icmp_ip);
483 break;
484
485 badcode:
464 goto freeit;
465 }
466 icp->icmp_ip.ip_len = ntohs(icp->icmp_ip.ip_len);
467 /* Discard ICMP's in response to multicast packets */
468 if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr)))
469 goto badcode;
470#ifdef ICMPPRINTFS
471 if (icmpprintfs)

--- 6 unchanged lines hidden (view full) ---

478 */
479 ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
480 if (ctlfunc)
481 (*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
482 (void *)&icp->icmp_ip);
483 break;
484
485 badcode:
486 V_icmpstat.icps_badcode++;
486 ICMPSTAT_INC(icps_badcode);
487 break;
488
489 case ICMP_ECHO:
490 if (!V_icmpbmcastecho
491 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
487 break;
488
489 case ICMP_ECHO:
490 if (!V_icmpbmcastecho
491 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
492 V_icmpstat.icps_bmcastecho++;
492 ICMPSTAT_INC(icps_bmcastecho);
493 break;
494 }
495 icp->icmp_type = ICMP_ECHOREPLY;
496 if (badport_bandlim(BANDLIM_ICMP_ECHO) < 0)
497 goto freeit;
498 else
499 goto reflect;
500
501 case ICMP_TSTAMP:
502 if (!V_icmpbmcastecho
503 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
493 break;
494 }
495 icp->icmp_type = ICMP_ECHOREPLY;
496 if (badport_bandlim(BANDLIM_ICMP_ECHO) < 0)
497 goto freeit;
498 else
499 goto reflect;
500
501 case ICMP_TSTAMP:
502 if (!V_icmpbmcastecho
503 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
504 V_icmpstat.icps_bmcasttstamp++;
504 ICMPSTAT_INC(icps_bmcasttstamp);
505 break;
506 }
507 if (icmplen < ICMP_TSLEN) {
505 break;
506 }
507 if (icmplen < ICMP_TSLEN) {
508 V_icmpstat.icps_badlen++;
508 ICMPSTAT_INC(icps_badlen);
509 break;
510 }
511 icp->icmp_type = ICMP_TSTAMPREPLY;
512 icp->icmp_rtime = iptime();
513 icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */
514 if (badport_bandlim(BANDLIM_ICMP_TSTAMP) < 0)
515 goto freeit;
516 else

--- 32 unchanged lines hidden (view full) ---

549 if (ip->ip_src.s_addr == 0) {
550 if (ia->ia_ifp->if_flags & IFF_BROADCAST)
551 ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr;
552 else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)
553 ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr;
554 }
555reflect:
556 ip->ip_len += hlen; /* since ip_input deducts this */
509 break;
510 }
511 icp->icmp_type = ICMP_TSTAMPREPLY;
512 icp->icmp_rtime = iptime();
513 icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */
514 if (badport_bandlim(BANDLIM_ICMP_TSTAMP) < 0)
515 goto freeit;
516 else

--- 32 unchanged lines hidden (view full) ---

549 if (ip->ip_src.s_addr == 0) {
550 if (ia->ia_ifp->if_flags & IFF_BROADCAST)
551 ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr;
552 else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)
553 ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr;
554 }
555reflect:
556 ip->ip_len += hlen; /* since ip_input deducts this */
557 V_icmpstat.icps_reflect++;
558 V_icmpstat.icps_outhist[icp->icmp_type]++;
557 ICMPSTAT_INC(icps_reflect);
558 ICMPSTAT_INC(icps_outhist[icp->icmp_type]);
559 icmp_reflect(m);
560 return;
561
562 case ICMP_REDIRECT:
563 if (V_log_redirect) {
564 u_long src, dst, gw;
565
566 src = ntohl(ip->ip_src.s_addr);

--- 13 unchanged lines hidden (view full) ---

580 * are acting as router.
581 */
582 if (V_drop_redirect || V_ipforwarding)
583 break;
584 if (code > 3)
585 goto badcode;
586 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
587 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
559 icmp_reflect(m);
560 return;
561
562 case ICMP_REDIRECT:
563 if (V_log_redirect) {
564 u_long src, dst, gw;
565
566 src = ntohl(ip->ip_src.s_addr);

--- 13 unchanged lines hidden (view full) ---

580 * are acting as router.
581 */
582 if (V_drop_redirect || V_ipforwarding)
583 break;
584 if (code > 3)
585 goto badcode;
586 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
587 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
588 V_icmpstat.icps_badlen++;
588 ICMPSTAT_INC(icps_badlen);
589 break;
590 }
591 /*
592 * Short circuit routing redirects to force
593 * immediate change in the kernel's routing
594 * tables. The message is also handed to anyone
595 * listening on a raw socket (e.g. the routing
596 * daemon for use in updating its tables).

--- 58 unchanged lines hidden (view full) ---

655 struct in_addr t;
656 struct mbuf *opts = 0;
657 int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
658
659 if (IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
660 IN_EXPERIMENTAL(ntohl(ip->ip_src.s_addr)) ||
661 IN_ZERONET(ntohl(ip->ip_src.s_addr)) ) {
662 m_freem(m); /* Bad return address */
589 break;
590 }
591 /*
592 * Short circuit routing redirects to force
593 * immediate change in the kernel's routing
594 * tables. The message is also handed to anyone
595 * listening on a raw socket (e.g. the routing
596 * daemon for use in updating its tables).

--- 58 unchanged lines hidden (view full) ---

655 struct in_addr t;
656 struct mbuf *opts = 0;
657 int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
658
659 if (IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
660 IN_EXPERIMENTAL(ntohl(ip->ip_src.s_addr)) ||
661 IN_ZERONET(ntohl(ip->ip_src.s_addr)) ) {
662 m_freem(m); /* Bad return address */
663 V_icmpstat.icps_badaddr++;
663 ICMPSTAT_INC(icps_badaddr);
664 goto done; /* Ip_output() will check for broadcast */
665 }
666
667 t = ip->ip_dst;
668 ip->ip_dst = ip->ip_src;
669
670 /*
671 * Source selection for ICMP replies:

--- 52 unchanged lines hidden (view full) ---

724 * If the packet was transiting through us, use the address of
725 * the interface that is the closest to the packet source.
726 * When we don't have a route back to the packet source, stop here
727 * and drop the packet.
728 */
729 ia = ip_rtaddr(ip->ip_dst, M_GETFIB(m));
730 if (ia == NULL) {
731 m_freem(m);
664 goto done; /* Ip_output() will check for broadcast */
665 }
666
667 t = ip->ip_dst;
668 ip->ip_dst = ip->ip_src;
669
670 /*
671 * Source selection for ICMP replies:

--- 52 unchanged lines hidden (view full) ---

724 * If the packet was transiting through us, use the address of
725 * the interface that is the closest to the packet source.
726 * When we don't have a route back to the packet source, stop here
727 * and drop the packet.
728 */
729 ia = ip_rtaddr(ip->ip_dst, M_GETFIB(m));
730 if (ia == NULL) {
731 m_freem(m);
732 V_icmpstat.icps_noroute++;
732 ICMPSTAT_INC(icps_noroute);
733 goto done;
734 }
735match:
736#ifdef MAC
737 mac_netinet_icmp_replyinplace(m);
738#endif
739 t = IA_SIN(ia)->sin_addr;
740 ip->ip_src = t;

--- 217 unchanged lines hidden ---
733 goto done;
734 }
735match:
736#ifdef MAC
737 mac_netinet_icmp_replyinplace(m);
738#endif
739 t = IA_SIN(ia)->sin_addr;
740 ip->ip_src = t;

--- 217 unchanged lines hidden ---