ping6.c (141611) | ping6.c (168866) |
---|---|
1/* $KAME: ping6.c,v 1.169 2003/07/25 06:01:47 itojun Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 64 unchanged lines hidden (view full) --- 73 The Regents of the University of California. All rights reserved.\n"; 74#endif /* not lint */ 75 76#ifndef lint 77#if 0 78static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; 79#endif 80static const char rcsid[] = | 1/* $KAME: ping6.c,v 1.169 2003/07/25 06:01:47 itojun Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 64 unchanged lines hidden (view full) --- 73 The Regents of the University of California. All rights reserved.\n"; 74#endif /* not lint */ 75 76#ifndef lint 77#if 0 78static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; 79#endif 80static const char rcsid[] = |
81 "$FreeBSD: head/sbin/ping6/ping6.c 141611 2005-02-10 09:19:34Z ru $"; | 81 "$FreeBSD: head/sbin/ping6/ping6.c 168866 2007-04-19 15:41:00Z mtm $"; |
82#endif /* not lint */ 83 84/* 85 * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 86 * measure round-trip-delays and packet loss across network paths. 87 * 88 * Author - 89 * Mike Muuss --- 55 unchanged lines hidden (view full) --- 145 u_int32_t tv32_usec; 146}; 147 148#define MAXPACKETLEN 131072 149#define IP6LEN 40 150#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */ 151#define ICMP6ECHOTMLEN sizeof(struct tv32) 152#define ICMP6_NIQLEN (ICMP6ECHOLEN + 8) | 82#endif /* not lint */ 83 84/* 85 * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 86 * measure round-trip-delays and packet loss across network paths. 87 * 88 * Author - 89 * Mike Muuss --- 55 unchanged lines hidden (view full) --- 145 u_int32_t tv32_usec; 146}; 147 148#define MAXPACKETLEN 131072 149#define IP6LEN 40 150#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */ 151#define ICMP6ECHOTMLEN sizeof(struct tv32) 152#define ICMP6_NIQLEN (ICMP6ECHOLEN + 8) |
153# define CONTROLLEN 10240 /* ancillary data buffer size RFC3542 20.1 */ |
|
153/* FQDN case, 64 bits of nonce + 32 bits ttl */ 154#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12) 155#define EXTRA 256 /* for AH and various other headers. weird. */ 156#define DEFDATALEN ICMP6ECHOTMLEN 157#define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN 158#define NROUTES 9 /* number of record route slots */ 159 160#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ --- 103 unchanged lines hidden (view full) --- 264void pr_suptypes(struct icmp6_nodeinfo *, size_t); 265void pr_nodeaddr(struct icmp6_nodeinfo *, int); 266int myechoreply(const struct icmp6_hdr *); 267int mynireply(const struct icmp6_nodeinfo *); 268char *dnsdecode(const u_char **, const u_char *, const u_char *, 269 char *, size_t); 270void pr_pack(u_char *, int, struct msghdr *); 271void pr_exthdrs(struct msghdr *); | 154/* FQDN case, 64 bits of nonce + 32 bits ttl */ 155#define ICMP6_NIRLEN (ICMP6ECHOLEN + 12) 156#define EXTRA 256 /* for AH and various other headers. weird. */ 157#define DEFDATALEN ICMP6ECHOTMLEN 158#define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN 159#define NROUTES 9 /* number of record route slots */ 160 161#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ --- 103 unchanged lines hidden (view full) --- 265void pr_suptypes(struct icmp6_nodeinfo *, size_t); 266void pr_nodeaddr(struct icmp6_nodeinfo *, int); 267int myechoreply(const struct icmp6_hdr *); 268int mynireply(const struct icmp6_nodeinfo *); 269char *dnsdecode(const u_char **, const u_char *, const u_char *, 270 char *, size_t); 271void pr_pack(u_char *, int, struct msghdr *); 272void pr_exthdrs(struct msghdr *); |
272void pr_ip6opt(void *); 273void pr_rthdr(void *); | 273void pr_ip6opt(void *, size_t); 274void pr_rthdr(void *, size_t); |
274int pr_bitrange(u_int32_t, int, int); 275void pr_retip(struct ip6_hdr *, u_char *); 276void summary(void); 277void tvsub(struct timeval *, struct timeval *); 278int setpolicy(int, char *); 279char *nigroup(char *); 280void usage(void); 281 --- 20 unchanged lines hidden (view full) --- 302 int fdmasks; 303#endif 304 int cc, i; 305 int ch, hold, packlen, preload, optval, ret_ga; 306 u_char *datap, *packet; 307 char *e, *target, *ifname = NULL, *gateway = NULL; 308 int ip6optlen = 0; 309 struct cmsghdr *scmsgp = NULL; | 275int pr_bitrange(u_int32_t, int, int); 276void pr_retip(struct ip6_hdr *, u_char *); 277void summary(void); 278void tvsub(struct timeval *, struct timeval *); 279int setpolicy(int, char *); 280char *nigroup(char *); 281void usage(void); 282 --- 20 unchanged lines hidden (view full) --- 303 int fdmasks; 304#endif 305 int cc, i; 306 int ch, hold, packlen, preload, optval, ret_ga; 307 u_char *datap, *packet; 308 char *e, *target, *ifname = NULL, *gateway = NULL; 309 int ip6optlen = 0; 310 struct cmsghdr *scmsgp = NULL; |
311 struct cmsghdr *cm; |
|
310#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 311 u_long lsockbufsize; 312 int sockbufsize = 0; 313#endif 314 int usepktinfo = 0; 315 struct in6_pktinfo *pktinfo = NULL; 316#ifdef USE_RFC2292BIS 317 struct ip6_rthdr *rthdr = NULL; --- 734 unchanged lines hidden (view full) --- 1052 err(1, "malloc"); 1053#endif 1054 1055 seenalrm = seenint = 0; 1056#ifdef SIGINFO 1057 seeninfo = 0; 1058#endif 1059 | 312#if defined(SO_SNDBUF) && defined(SO_RCVBUF) 313 u_long lsockbufsize; 314 int sockbufsize = 0; 315#endif 316 int usepktinfo = 0; 317 struct in6_pktinfo *pktinfo = NULL; 318#ifdef USE_RFC2292BIS 319 struct ip6_rthdr *rthdr = NULL; --- 734 unchanged lines hidden (view full) --- 1054 err(1, "malloc"); 1055#endif 1056 1057 seenalrm = seenint = 0; 1058#ifdef SIGINFO 1059 seeninfo = 0; 1060#endif 1061 |
1062 /* For control (ancillary) data received from recvmsg() */ 1063 cm = (struct cmsghdr *)malloc(CONTROLLEN); 1064 if (cm == NULL) 1065 err(1, "malloc"); 1066 |
|
1060 for (;;) { 1061 struct msghdr m; | 1067 for (;;) { 1068 struct msghdr m; |
1062 struct cmsghdr *cm; 1063 u_char buf[1024]; | |
1064 struct iovec iov[2]; 1065 1066 /* signal handling */ 1067 if (seenalrm) { 1068 retransmit(); 1069 seenalrm = 0; 1070 continue; 1071 } --- 50 unchanged lines hidden (view full) --- 1122 1123 m.msg_name = (caddr_t)&from; 1124 m.msg_namelen = sizeof(from); 1125 memset(&iov, 0, sizeof(iov)); 1126 iov[0].iov_base = (caddr_t)packet; 1127 iov[0].iov_len = packlen; 1128 m.msg_iov = iov; 1129 m.msg_iovlen = 1; | 1069 struct iovec iov[2]; 1070 1071 /* signal handling */ 1072 if (seenalrm) { 1073 retransmit(); 1074 seenalrm = 0; 1075 continue; 1076 } --- 50 unchanged lines hidden (view full) --- 1127 1128 m.msg_name = (caddr_t)&from; 1129 m.msg_namelen = sizeof(from); 1130 memset(&iov, 0, sizeof(iov)); 1131 iov[0].iov_base = (caddr_t)packet; 1132 iov[0].iov_len = packlen; 1133 m.msg_iov = iov; 1134 m.msg_iovlen = 1; |
1130 cm = (struct cmsghdr *)buf; 1131 m.msg_control = (caddr_t)buf; 1132 m.msg_controllen = sizeof(buf); | 1135 memset(cm, 0, CONTROLLEN); 1136 m.msg_control = (void *)cm; 1137 m.msg_controllen = CONTROLLEN; |
1133 1134 cc = recvmsg(s, &m, 0); 1135 if (cc < 0) { 1136 if (errno != EINTR) { 1137 warn("recvmsg"); 1138 sleep(1); 1139 } 1140 continue; --- 347 unchanged lines hidden (view full) --- 1488 from = (struct sockaddr *)mhdr->msg_name; 1489 fromlen = mhdr->msg_namelen; 1490 if (cc < sizeof(struct icmp6_hdr)) { 1491 if (options & F_VERBOSE) 1492 warnx("packet too short (%d bytes) from %s", cc, 1493 pr_addr(from, fromlen)); 1494 return; 1495 } | 1138 1139 cc = recvmsg(s, &m, 0); 1140 if (cc < 0) { 1141 if (errno != EINTR) { 1142 warn("recvmsg"); 1143 sleep(1); 1144 } 1145 continue; --- 347 unchanged lines hidden (view full) --- 1493 from = (struct sockaddr *)mhdr->msg_name; 1494 fromlen = mhdr->msg_namelen; 1495 if (cc < sizeof(struct icmp6_hdr)) { 1496 if (options & F_VERBOSE) 1497 warnx("packet too short (%d bytes) from %s", cc, 1498 pr_addr(from, fromlen)); 1499 return; 1500 } |
1501 if (((mhdr->msg_flags & MSG_CTRUNC) != 0) && 1502 (options & F_VERBOSE) != 0) 1503 warnx("some control data discarded, insufficient buffer size"); |
|
1496 icp = (struct icmp6_hdr *)buf; 1497 ni = (struct icmp6_nodeinfo *)buf; 1498 off = 0; 1499 1500 if ((hoplim = get_hoplim(mhdr)) == -1) { 1501 warnx("failed to get receiving hop limit"); 1502 return; 1503 } --- 226 unchanged lines hidden (view full) --- 1730 } 1731#undef safeputc 1732} 1733 1734void 1735pr_exthdrs(mhdr) 1736 struct msghdr *mhdr; 1737{ | 1504 icp = (struct icmp6_hdr *)buf; 1505 ni = (struct icmp6_nodeinfo *)buf; 1506 off = 0; 1507 1508 if ((hoplim = get_hoplim(mhdr)) == -1) { 1509 warnx("failed to get receiving hop limit"); 1510 return; 1511 } --- 226 unchanged lines hidden (view full) --- 1738 } 1739#undef safeputc 1740} 1741 1742void 1743pr_exthdrs(mhdr) 1744 struct msghdr *mhdr; 1745{ |
1746 ssize_t bufsize; 1747 void *bufp; |
|
1738 struct cmsghdr *cm; 1739 | 1748 struct cmsghdr *cm; 1749 |
1750 bufsize = 0; 1751 bufp = mhdr->msg_control; |
|
1740 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1741 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1742 if (cm->cmsg_level != IPPROTO_IPV6) 1743 continue; 1744 | 1752 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; 1753 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { 1754 if (cm->cmsg_level != IPPROTO_IPV6) 1755 continue; 1756 |
1757 bufsize = CONTROLLEN - ((caddr_t)CMSG_DATA(cm) - (caddr_t)bufp); 1758 if (bufsize <= 0) 1759 continue; |
|
1745 switch (cm->cmsg_type) { 1746 case IPV6_HOPOPTS: 1747 printf(" HbH Options: "); | 1760 switch (cm->cmsg_type) { 1761 case IPV6_HOPOPTS: 1762 printf(" HbH Options: "); |
1748 pr_ip6opt(CMSG_DATA(cm)); | 1763 pr_ip6opt(CMSG_DATA(cm), (size_t)bufsize); |
1749 break; 1750 case IPV6_DSTOPTS: 1751#ifdef IPV6_RTHDRDSTOPTS 1752 case IPV6_RTHDRDSTOPTS: 1753#endif 1754 printf(" Dst Options: "); | 1764 break; 1765 case IPV6_DSTOPTS: 1766#ifdef IPV6_RTHDRDSTOPTS 1767 case IPV6_RTHDRDSTOPTS: 1768#endif 1769 printf(" Dst Options: "); |
1755 pr_ip6opt(CMSG_DATA(cm)); | 1770 pr_ip6opt(CMSG_DATA(cm), (size_t)bufsize); |
1756 break; 1757 case IPV6_RTHDR: 1758 printf(" Routing: "); | 1771 break; 1772 case IPV6_RTHDR: 1773 printf(" Routing: "); |
1759 pr_rthdr(CMSG_DATA(cm)); | 1774 pr_rthdr(CMSG_DATA(cm), (size_t)bufsize); |
1760 break; 1761 } 1762 } 1763} 1764 1765#ifdef USE_RFC2292BIS 1766void | 1775 break; 1776 } 1777 } 1778} 1779 1780#ifdef USE_RFC2292BIS 1781void |
1767pr_ip6opt(void *extbuf) | 1782pr_ip6opt(void *extbuf, size_t bufsize) |
1768{ 1769 struct ip6_hbh *ext; 1770 int currentlen; 1771 u_int8_t type; | 1783{ 1784 struct ip6_hbh *ext; 1785 int currentlen; 1786 u_int8_t type; |
1772 socklen_t extlen, len; | 1787 socklen_t extlen, len, origextlen; |
1773 void *databuf; 1774 size_t offset; 1775 u_int16_t value2; 1776 u_int32_t value4; 1777 1778 ext = (struct ip6_hbh *)extbuf; 1779 extlen = (ext->ip6h_len + 1) * 8; 1780 printf("nxt %u, len %u (%lu bytes)\n", ext->ip6h_nxt, 1781 (unsigned int)ext->ip6h_len, (unsigned long)extlen); 1782 | 1788 void *databuf; 1789 size_t offset; 1790 u_int16_t value2; 1791 u_int32_t value4; 1792 1793 ext = (struct ip6_hbh *)extbuf; 1794 extlen = (ext->ip6h_len + 1) * 8; 1795 printf("nxt %u, len %u (%lu bytes)\n", ext->ip6h_nxt, 1796 (unsigned int)ext->ip6h_len, (unsigned long)extlen); 1797 |
1798 /* 1799 * Bounds checking on the ancillary data buffer: 1800 * subtract the size of a cmsg structure from the buffer size. 1801 */ 1802 if (bufsize < (extlen + CMSG_SPACE(0))) { 1803 origextlen = extlen; 1804 extlen = bufsize - CMSG_SPACE(0); 1805 warnx("options truncated, showing only %u (total=%u)", 1806 (unsigned int)(extlen / 8 - 1), 1807 (unsigned int)(ext->ip6h_len)); 1808 } 1809 |
|
1783 currentlen = 0; 1784 while (1) { 1785 currentlen = inet6_opt_next(extbuf, extlen, currentlen, 1786 &type, &len, &databuf); 1787 if (currentlen == -1) 1788 break; 1789 switch (type) { 1790 /* --- 20 unchanged lines hidden (view full) --- 1811 break; 1812 } 1813 } 1814 return; 1815} 1816#else /* !USE_RFC2292BIS */ 1817/* ARGSUSED */ 1818void | 1810 currentlen = 0; 1811 while (1) { 1812 currentlen = inet6_opt_next(extbuf, extlen, currentlen, 1813 &type, &len, &databuf); 1814 if (currentlen == -1) 1815 break; 1816 switch (type) { 1817 /* --- 20 unchanged lines hidden (view full) --- 1838 break; 1839 } 1840 } 1841 return; 1842} 1843#else /* !USE_RFC2292BIS */ 1844/* ARGSUSED */ 1845void |
1819pr_ip6opt(void *extbuf) | 1846pr_ip6opt(void *extbuf, size_t bufsize __unused) |
1820{ 1821 putchar('\n'); 1822 return; 1823} 1824#endif /* USE_RFC2292BIS */ 1825 1826#ifdef USE_RFC2292BIS 1827void | 1847{ 1848 putchar('\n'); 1849 return; 1850} 1851#endif /* USE_RFC2292BIS */ 1852 1853#ifdef USE_RFC2292BIS 1854void |
1828pr_rthdr(void *extbuf) | 1855pr_rthdr(void *extbuf, size_t bufsize) |
1829{ 1830 struct in6_addr *in6; 1831 char ntopbuf[INET6_ADDRSTRLEN]; 1832 struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf; | 1856{ 1857 struct in6_addr *in6; 1858 char ntopbuf[INET6_ADDRSTRLEN]; 1859 struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf; |
1833 int i, segments; | 1860 int i, segments, origsegs, rthsize, size0, size1; |
1834 1835 /* print fixed part of the header */ 1836 printf("nxt %u, len %u (%d bytes), type %u, ", rh->ip6r_nxt, 1837 rh->ip6r_len, (rh->ip6r_len + 1) << 3, rh->ip6r_type); | 1861 1862 /* print fixed part of the header */ 1863 printf("nxt %u, len %u (%d bytes), type %u, ", rh->ip6r_nxt, 1864 rh->ip6r_len, (rh->ip6r_len + 1) << 3, rh->ip6r_type); |
1838 if ((segments = inet6_rth_segments(extbuf)) >= 0) | 1865 if ((segments = inet6_rth_segments(extbuf)) >= 0) { |
1839 printf("%d segments, ", segments); | 1866 printf("%d segments, ", segments); |
1840 else | 1867 printf("%d left\n", rh->ip6r_segleft); 1868 } else { |
1841 printf("segments unknown, "); | 1869 printf("segments unknown, "); |
1842 printf("%d left\n", rh->ip6r_segleft); | 1870 printf("%d left\n", rh->ip6r_segleft); 1871 return; 1872 } |
1843 | 1873 |
1874 /* 1875 * Bounds checking on the ancillary data buffer. When calculating 1876 * the number of items to show keep in mind: 1877 * - The size of the cmsg structure 1878 * - The size of one segment (the size of a Type 0 routing header) 1879 * - When dividing add a fudge factor of one in case the 1880 * dividend is not evenly divisible by the divisor 1881 */ 1882 rthsize = (rh->ip6r_len + 1) * 8; 1883 if (bufsize < (rthsize + CMSG_SPACE(0))) { 1884 origsegs = segments; 1885 size0 = inet6_rth_space(IPV6_RTHDR_TYPE_0, 0); 1886 size1 = inet6_rth_space(IPV6_RTHDR_TYPE_0, 1); 1887 segments -= (rthsize - (bufsize - CMSG_SPACE(0))) / 1888 (size1 - size0) + 1; 1889 warnx("segments truncated, showing only %d (total=%d)", 1890 segments, origsegs); 1891 } 1892 |
|
1844 for (i = 0; i < segments; i++) { 1845 in6 = inet6_rth_getaddr(extbuf, i); 1846 if (in6 == NULL) 1847 printf(" [%d]<NULL>\n", i); 1848 else { 1849 if (!inet_ntop(AF_INET6, in6, ntopbuf, 1850 sizeof(ntopbuf))) 1851 strlcpy(ntopbuf, "?", sizeof(ntopbuf)); 1852 printf(" [%d]%s\n", i, ntopbuf); 1853 } 1854 } 1855 1856 return; 1857 1858} 1859 1860#else /* !USE_RFC2292BIS */ 1861/* ARGSUSED */ 1862void | 1893 for (i = 0; i < segments; i++) { 1894 in6 = inet6_rth_getaddr(extbuf, i); 1895 if (in6 == NULL) 1896 printf(" [%d]<NULL>\n", i); 1897 else { 1898 if (!inet_ntop(AF_INET6, in6, ntopbuf, 1899 sizeof(ntopbuf))) 1900 strlcpy(ntopbuf, "?", sizeof(ntopbuf)); 1901 printf(" [%d]%s\n", i, ntopbuf); 1902 } 1903 } 1904 1905 return; 1906 1907} 1908 1909#else /* !USE_RFC2292BIS */ 1910/* ARGSUSED */ 1911void |
1863pr_rthdr(void *extbuf) | 1912pr_rthdr(void *extbuf, size_t bufsize __unused) |
1864{ 1865 putchar('\n'); 1866 return; 1867} 1868#endif /* USE_RFC2292BIS */ 1869 1870int 1871pr_bitrange(v, soff, ii) --- 856 unchanged lines hidden --- | 1913{ 1914 putchar('\n'); 1915 return; 1916} 1917#endif /* USE_RFC2292BIS */ 1918 1919int 1920pr_bitrange(v, soff, ii) --- 856 unchanged lines hidden --- |