summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Kerola <kerolasa@iki.fi>2019-07-22 18:16:14 +0100
committerSami Kerola <kerolasa@iki.fi>2019-07-22 18:40:33 +0100
commit230689297b25a600b410e3ee810d6de6452a50aa (patch)
tree23606972ca797887573ecfa2de78366c213faa00
parent918b876a5eb1e8bffe1a56c5697064c6dc80a141 (diff)
downloadiputils-230689297b25a600b410e3ee810d6de6452a50aa.tar.gz
ping: remove function prototypes
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
-rw-r--r--ping.c882
-rw-r--r--ping6_common.c155
2 files changed, 513 insertions, 524 deletions
diff --git a/ping.c b/ping.c
index c4692e2..4a1dcc0 100644
--- a/ping.c
+++ b/ping.c
@@ -87,13 +87,6 @@ static int settos = 0; /* Set TOS, Precedence or other QOS options */
static int broadcast_pings = 0;
static int multicast;
-static void pr_options(unsigned char *cp, int hlen);
-static void pr_iph(struct iphdr *ip);
-static unsigned short in_cksum(const unsigned short *addr, int len, unsigned short salt);
-static void pr_icmph(uint8_t type, uint8_t code, uint32_t info, struct icmphdr *icp);
-static int parsetos(char *str);
-static int parseflow(char *str);
-
static struct sockaddr_in source = { .sin_family = AF_INET };
char *device;
int pmtudisc = -1;
@@ -219,6 +212,51 @@ static double ping_strtod(const char *str, const char *err_msg)
return 0.0;
}
+static int parseflow(char *str)
+{
+ const char *cp;
+ unsigned long val;
+ char *ep;
+
+ /* handle both hex and decimal values */
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
+ cp = str + 2;
+ val = (int)strtoul(cp, &ep, 16);
+ } else
+ val = (int)strtoul(str, &ep, 10);
+
+ /* doesn't look like decimal or hex, eh? */
+ if (*ep != '\0')
+ error(2, 0, _("bad value for flowinfo: %s"), str);
+
+ if (val & ~IPV6_FLOWINFO_FLOWLABEL)
+ error(2, 0, _("flow value is greater than 20 bits: %s"), str);
+ return (val);
+}
+
+/* Set Type of Service (TOS) and other Quality of Service relating bits */
+static int parsetos(char *str)
+{
+ const char *cp;
+ int tos;
+ char *ep;
+
+ /* handle both hex and decimal values */
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
+ cp = str + 2;
+ tos = (int)strtol(cp, &ep, 16);
+ } else
+ tos = (int)strtol(str, &ep, 10);
+
+ /* doesn't look like decimal or hex, eh? */
+ if (*ep != '\0')
+ error(2, 0, _("bad TOS value: %s"), str);
+
+ if (tos > TOS_MAX)
+ error(2, 0, _("the decimal value of TOS bits must be in range 0-255: %d"), tos);
+ return (tos);
+}
+
int
main(int argc, char **argv)
{
@@ -846,6 +884,358 @@ int ping4_run(int argc, char **argv, struct addrinfo *ai, socket_st *sock)
main_loop(&ping4_func_set, sock, packet, packlen);
}
+static void pr_options(unsigned char *cp, int hlen)
+{
+ int i, j;
+ int olen, totlen;
+ unsigned char *optptr;
+ static int old_rrlen;
+ static char old_rr[MAX_IPOPTLEN];
+
+ totlen = hlen - sizeof(struct iphdr);
+ optptr = cp;
+
+ while (totlen > 0) {
+ if (*optptr == IPOPT_EOL)
+ break;
+ if (*optptr == IPOPT_NOP) {
+ totlen--;
+ optptr++;
+ printf(_("\nNOP"));
+ continue;
+ }
+ cp = optptr;
+ olen = optptr[1];
+ if (olen < 2 || olen > totlen)
+ break;
+
+ switch (*cp) {
+ case IPOPT_SSRR:
+ case IPOPT_LSRR:
+ printf(_("\n%cSRR: "), *cp == IPOPT_SSRR ? 'S' : 'L');
+ j = *++cp;
+ cp++;
+ if (j > IPOPT_MINOFF) {
+ for (;;) {
+ uint32_t address;
+ memcpy(&address, cp, 4);
+ cp += 4;
+ if (address == 0)
+ printf("\t0.0.0.0");
+ else {
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_addr = {
+ address
+ }
+ };
+
+ printf("\t%s", pr_addr(&sin, sizeof sin));
+ }
+ j -= 4;
+ putchar('\n');
+ if (j <= IPOPT_MINOFF)
+ break;
+ }
+ }
+ break;
+ case IPOPT_RR:
+ j = *++cp; /* get length */
+ i = *++cp; /* and pointer */
+ if (i > j)
+ i = j;
+ i -= IPOPT_MINOFF;
+ if (i <= 0)
+ break;
+ if (i == old_rrlen
+ && !memcmp(cp, old_rr, i)
+ && !(options & F_FLOOD)) {
+ printf(_("\t(same route)"));
+ break;
+ }
+ old_rrlen = i;
+ memcpy(old_rr, (char *)cp, i);
+ printf(_("\nRR: "));
+ cp++;
+ for (;;) {
+ uint32_t address;
+ memcpy(&address, cp, 4);
+ cp += 4;
+ if (address == 0)
+ printf("\t0.0.0.0");
+ else {
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_addr = {
+ address
+ }
+ };
+
+ printf("\t%s", pr_addr(&sin, sizeof sin));
+ }
+ i -= 4;
+ putchar('\n');
+ if (i <= 0)
+ break;
+ }
+ break;
+ case IPOPT_TS:
+ {
+ int stdtime = 0, nonstdtime = 0;
+ uint8_t flags;
+ j = *++cp; /* get length */
+ i = *++cp; /* and pointer */
+ if (i > j)
+ i = j;
+ i -= 5;
+ if (i <= 0)
+ break;
+ flags = *++cp;
+ printf(_("\nTS: "));
+ cp++;
+ for (;;) {
+ long l;
+
+ if ((flags & 0xF) != IPOPT_TS_TSONLY) {
+ uint32_t address;
+ memcpy(&address, cp, 4);
+ cp += 4;
+ if (address == 0)
+ printf("\t0.0.0.0");
+ else {
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_addr = {
+ address
+ }
+ };
+
+ printf("\t%s", pr_addr(&sin, sizeof sin));
+ }
+ i -= 4;
+ if (i <= 0)
+ break;
+ }
+ l = *cp++;
+ l = (l << 8) + *cp++;
+ l = (l << 8) + *cp++;
+ l = (l << 8) + *cp++;
+
+ if (l & 0x80000000) {
+ if (nonstdtime == 0)
+ printf(_("\t%ld absolute not-standard"), l & 0x7fffffff);
+ else
+ printf(_("\t%ld not-standard"), (l & 0x7fffffff) - nonstdtime);
+ nonstdtime = l & 0x7fffffff;
+ } else {
+ if (stdtime == 0)
+ printf(_("\t%ld absolute"), l);
+ else
+ printf("\t%ld", l - stdtime);
+ stdtime = l;
+ }
+ i -= 4;
+ putchar('\n');
+ if (i <= 0)
+ break;
+ }
+ if (flags >> 4)
+ printf(_("Unrecorded hops: %d\n"), flags >> 4);
+ break;
+ }
+ default:
+ printf(_("\nunknown option %x"), *cp);
+ break;
+ }
+ totlen -= olen;
+ optptr += olen;
+ }
+}
+
+/*
+ * pr_iph --
+ * Print an IP header with options.
+ */
+static void pr_iph(struct iphdr *ip)
+{
+ int hlen;
+ unsigned char *cp;
+
+ hlen = ip->ihl << 2;
+ cp = (unsigned char *)ip + 20; /* point to options */
+
+ printf(_("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst Data\n"));
+ printf(_(" %1x %1x %02x %04x %04x"),
+ ip->version, ip->ihl, ip->tos, ip->tot_len, ip->id);
+ printf(_(" %1x %04x"), ((ip->frag_off) & 0xe000) >> 13,
+ (ip->frag_off) & 0x1fff);
+ printf(_(" %02x %02x %04x"), ip->ttl, ip->protocol, ip->check);
+ printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->saddr));
+ printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->daddr));
+ printf("\n");
+ pr_options(cp, hlen);
+}
+
+/*
+ * pr_icmph --
+ * Print a descriptive string about an ICMP header.
+ */
+static void pr_icmph(uint8_t type, uint8_t code, uint32_t info, struct icmphdr *icp)
+{
+ switch (type) {
+ case ICMP_ECHOREPLY:
+ printf(_("Echo Reply\n"));
+ /* XXX ID + Seq + Data */
+ break;
+ case ICMP_DEST_UNREACH:
+ switch (code) {
+ case ICMP_NET_UNREACH:
+ printf(_("Destination Net Unreachable\n"));
+ break;
+ case ICMP_HOST_UNREACH:
+ printf(_("Destination Host Unreachable\n"));
+ break;
+ case ICMP_PROT_UNREACH:
+ printf(_("Destination Protocol Unreachable\n"));
+ break;
+ case ICMP_PORT_UNREACH:
+ printf(_("Destination Port Unreachable\n"));
+ break;
+ case ICMP_FRAG_NEEDED:
+ printf(_("Frag needed and DF set (mtu = %u)\n"), info);
+ break;
+ case ICMP_SR_FAILED:
+ printf(_("Source Route Failed\n"));
+ break;
+ case ICMP_NET_UNKNOWN:
+ printf(_("Destination Net Unknown\n"));
+ break;
+ case ICMP_HOST_UNKNOWN:
+ printf(_("Destination Host Unknown\n"));
+ break;
+ case ICMP_HOST_ISOLATED:
+ printf(_("Source Host Isolated\n"));
+ break;
+ case ICMP_NET_ANO:
+ printf(_("Destination Net Prohibited\n"));
+ break;
+ case ICMP_HOST_ANO:
+ printf(_("Destination Host Prohibited\n"));
+ break;
+ case ICMP_NET_UNR_TOS:
+ printf(_("Destination Net Unreachable for Type of Service\n"));
+ break;
+ case ICMP_HOST_UNR_TOS:
+ printf(_("Destination Host Unreachable for Type of Service\n"));
+ break;
+ case ICMP_PKT_FILTERED:
+ printf(_("Packet filtered\n"));
+ break;
+ case ICMP_PREC_VIOLATION:
+ printf(_("Precedence Violation\n"));
+ break;
+ case ICMP_PREC_CUTOFF:
+ printf(_("Precedence Cutoff\n"));
+ break;
+ default:
+ printf(_("Dest Unreachable, Bad Code: %d\n"), code);
+ break;
+ }
+ if (icp && (options & F_VERBOSE))
+ pr_iph((struct iphdr *)(icp + 1));
+ break;
+ case ICMP_SOURCE_QUENCH:
+ printf(_("Source Quench\n"));
+ if (icp && (options & F_VERBOSE))
+ pr_iph((struct iphdr *)(icp + 1));
+ break;
+ case ICMP_REDIRECT:
+ switch (code) {
+ case ICMP_REDIR_NET:
+ printf(_("Redirect Network"));
+ break;
+ case ICMP_REDIR_HOST:
+ printf(_("Redirect Host"));
+ break;
+ case ICMP_REDIR_NETTOS:
+ printf(_("Redirect Type of Service and Network"));
+ break;
+ case ICMP_REDIR_HOSTTOS:
+ printf(_("Redirect Type of Service and Host"));
+ break;
+ default:
+ printf(_("Redirect, Bad Code: %d"), code);
+ break;
+ }
+ {
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_addr = {
+ icp ? icp->un.gateway : info
+ }
+ };
+
+ printf(_("(New nexthop: %s)\n"), pr_addr(&sin, sizeof sin));
+ }
+ if (icp && (options & F_VERBOSE))
+ pr_iph((struct iphdr *)(icp + 1));
+ break;
+ case ICMP_ECHO:
+ printf(_("Echo Request\n"));
+ /* XXX ID + Seq + Data */
+ break;
+ case ICMP_TIME_EXCEEDED:
+ switch(code) {
+ case ICMP_EXC_TTL:
+ printf(_("Time to live exceeded\n"));
+ break;
+ case ICMP_EXC_FRAGTIME:
+ printf(_("Frag reassembly time exceeded\n"));
+ break;
+ default:
+ printf(_("Time exceeded, Bad Code: %d\n"), code);
+ break;
+ }
+ if (icp && (options & F_VERBOSE))
+ pr_iph((struct iphdr *)(icp + 1));
+ break;
+ case ICMP_PARAMETERPROB:
+ printf(_("Parameter problem: pointer = %u\n"),
+ icp ? (ntohl(icp->un.gateway) >> 24) : info);
+ if (icp && (options & F_VERBOSE))
+ pr_iph((struct iphdr *)(icp + 1));
+ break;
+ case ICMP_TIMESTAMP:
+ printf(_("Timestamp\n"));
+ /* XXX ID + Seq + 3 timestamps */
+ break;
+ case ICMP_TIMESTAMPREPLY:
+ printf(_("Timestamp Reply\n"));
+ /* XXX ID + Seq + 3 timestamps */
+ break;
+ case ICMP_INFO_REQUEST:
+ printf(_("Information Request\n"));
+ /* XXX ID + Seq */
+ break;
+ case ICMP_INFO_REPLY:
+ printf(_("Information Reply\n"));
+ /* XXX ID + Seq */
+ break;
+#ifdef ICMP_MASKREQ
+ case ICMP_MASKREQ:
+ printf(_("Address Mask Request\n"));
+ break;
+#endif
+#ifdef ICMP_MASKREPLY
+ case ICMP_MASKREPLY:
+ printf(_("Address Mask Reply\n"));
+ break;
+#endif
+ default:
+ printf(_("Bad ICMP type: %d\n"), type);
+ }
+}
+
int ping4_receive_error_msg(socket_st *sock)
{
ssize_t res;
@@ -938,6 +1328,46 @@ out:
return net_errors ? net_errors : -local_errors;
}
+#if BYTE_ORDER == LITTLE_ENDIAN
+# define ODDBYTE(v) (v)
+#elif BYTE_ORDER == BIG_ENDIAN
+# define ODDBYTE(v) ((unsigned short)(v) << 8)
+#else
+# define ODDBYTE(v) htons((unsigned short)(v) << 8)
+#endif
+
+static unsigned short
+in_cksum(const unsigned short *addr, int len, unsigned short csum)
+{
+ int nleft = len;
+ const unsigned short *w = addr;
+ unsigned short answer;
+ int sum = csum;
+
+ /*
+ * Our algorithm is simple, using a 32 bit accumulator (sum),
+ * we add sequential 16 bit words to it, and at the end, fold
+ * back all the carry bits from the top 16 bits into the lower
+ * 16 bits.
+ */
+ while (nleft > 1) {
+ sum += *w++;
+ nleft -= 2;
+ }
+
+ /* mop up an odd byte, if necessary */
+ if (nleft == 1)
+ sum += ODDBYTE(*(unsigned char *)w); /* le16toh() may be unavailable on old systems */
+
+ /*
+ * add back carry outs from top 16 bits to low 16 bits
+ */
+ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
+ sum += (sum >> 16); /* add carry */
+ answer = ~sum; /* truncate to 16 bits */
+ return (answer);
+}
+
/*
* pinger --
* Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
@@ -1148,399 +1578,6 @@ ping4_parse_reply(struct socket_st *sock, struct msghdr *msg, int cc, void *addr
return 0;
}
-#if BYTE_ORDER == LITTLE_ENDIAN
-# define ODDBYTE(v) (v)
-#elif BYTE_ORDER == BIG_ENDIAN
-# define ODDBYTE(v) ((unsigned short)(v) << 8)
-#else
-# define ODDBYTE(v) htons((unsigned short)(v) << 8)
-#endif
-
-unsigned short
-in_cksum(const unsigned short *addr, int len, unsigned short csum)
-{
- int nleft = len;
- const unsigned short *w = addr;
- unsigned short answer;
- int sum = csum;
-
- /*
- * Our algorithm is simple, using a 32 bit accumulator (sum),
- * we add sequential 16 bit words to it, and at the end, fold
- * back all the carry bits from the top 16 bits into the lower
- * 16 bits.
- */
- while (nleft > 1) {
- sum += *w++;
- nleft -= 2;
- }
-
- /* mop up an odd byte, if necessary */
- if (nleft == 1)
- sum += ODDBYTE(*(unsigned char *)w); /* le16toh() may be unavailable on old systems */
-
- /*
- * add back carry outs from top 16 bits to low 16 bits
- */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return (answer);
-}
-
-/*
- * pr_icmph --
- * Print a descriptive string about an ICMP header.
- */
-void pr_icmph(uint8_t type, uint8_t code, uint32_t info, struct icmphdr *icp)
-{
- switch (type) {
- case ICMP_ECHOREPLY:
- printf(_("Echo Reply\n"));
- /* XXX ID + Seq + Data */
- break;
- case ICMP_DEST_UNREACH:
- switch (code) {
- case ICMP_NET_UNREACH:
- printf(_("Destination Net Unreachable\n"));
- break;
- case ICMP_HOST_UNREACH:
- printf(_("Destination Host Unreachable\n"));
- break;
- case ICMP_PROT_UNREACH:
- printf(_("Destination Protocol Unreachable\n"));
- break;
- case ICMP_PORT_UNREACH:
- printf(_("Destination Port Unreachable\n"));
- break;
- case ICMP_FRAG_NEEDED:
- printf(_("Frag needed and DF set (mtu = %u)\n"), info);
- break;
- case ICMP_SR_FAILED:
- printf(_("Source Route Failed\n"));
- break;
- case ICMP_NET_UNKNOWN:
- printf(_("Destination Net Unknown\n"));
- break;
- case ICMP_HOST_UNKNOWN:
- printf(_("Destination Host Unknown\n"));
- break;
- case ICMP_HOST_ISOLATED:
- printf(_("Source Host Isolated\n"));
- break;
- case ICMP_NET_ANO:
- printf(_("Destination Net Prohibited\n"));
- break;
- case ICMP_HOST_ANO:
- printf(_("Destination Host Prohibited\n"));
- break;
- case ICMP_NET_UNR_TOS:
- printf(_("Destination Net Unreachable for Type of Service\n"));
- break;
- case ICMP_HOST_UNR_TOS:
- printf(_("Destination Host Unreachable for Type of Service\n"));
- break;
- case ICMP_PKT_FILTERED:
- printf(_("Packet filtered\n"));
- break;
- case ICMP_PREC_VIOLATION:
- printf(_("Precedence Violation\n"));
- break;
- case ICMP_PREC_CUTOFF:
- printf(_("Precedence Cutoff\n"));
- break;
- default:
- printf(_("Dest Unreachable, Bad Code: %d\n"), code);
- break;
- }
- if (icp && (options & F_VERBOSE))
- pr_iph((struct iphdr *)(icp + 1));
- break;
- case ICMP_SOURCE_QUENCH:
- printf(_("Source Quench\n"));
- if (icp && (options & F_VERBOSE))
- pr_iph((struct iphdr *)(icp + 1));
- break;
- case ICMP_REDIRECT:
- switch (code) {
- case ICMP_REDIR_NET:
- printf(_("Redirect Network"));
- break;
- case ICMP_REDIR_HOST:
- printf(_("Redirect Host"));
- break;
- case ICMP_REDIR_NETTOS:
- printf(_("Redirect Type of Service and Network"));
- break;
- case ICMP_REDIR_HOSTTOS:
- printf(_("Redirect Type of Service and Host"));
- break;
- default:
- printf(_("Redirect, Bad Code: %d"), code);
- break;
- }
- {
- struct sockaddr_in sin = {
- .sin_family = AF_INET,
- .sin_addr = {
- icp ? icp->un.gateway : info
- }
- };
-
- printf(_("(New nexthop: %s)\n"), pr_addr(&sin, sizeof sin));
- }
- if (icp && (options & F_VERBOSE))
- pr_iph((struct iphdr *)(icp + 1));
- break;
- case ICMP_ECHO:
- printf(_("Echo Request\n"));
- /* XXX ID + Seq + Data */
- break;
- case ICMP_TIME_EXCEEDED:
- switch(code) {
- case ICMP_EXC_TTL:
- printf(_("Time to live exceeded\n"));
- break;
- case ICMP_EXC_FRAGTIME:
- printf(_("Frag reassembly time exceeded\n"));
- break;
- default:
- printf(_("Time exceeded, Bad Code: %d\n"), code);
- break;
- }
- if (icp && (options & F_VERBOSE))
- pr_iph((struct iphdr *)(icp + 1));
- break;
- case ICMP_PARAMETERPROB:
- printf(_("Parameter problem: pointer = %u\n"),
- icp ? (ntohl(icp->un.gateway) >> 24) : info);
- if (icp && (options & F_VERBOSE))
- pr_iph((struct iphdr *)(icp + 1));
- break;
- case ICMP_TIMESTAMP:
- printf(_("Timestamp\n"));
- /* XXX ID + Seq + 3 timestamps */
- break;
- case ICMP_TIMESTAMPREPLY:
- printf(_("Timestamp Reply\n"));
- /* XXX ID + Seq + 3 timestamps */
- break;
- case ICMP_INFO_REQUEST:
- printf(_("Information Request\n"));
- /* XXX ID + Seq */
- break;
- case ICMP_INFO_REPLY:
- printf(_("Information Reply\n"));
- /* XXX ID + Seq */
- break;
-#ifdef ICMP_MASKREQ
- case ICMP_MASKREQ:
- printf(_("Address Mask Request\n"));
- break;
-#endif
-#ifdef ICMP_MASKREPLY
- case ICMP_MASKREPLY:
- printf(_("Address Mask Reply\n"));
- break;
-#endif
- default:
- printf(_("Bad ICMP type: %d\n"), type);
- }
-}
-
-void pr_options(unsigned char *cp, int hlen)
-{
- int i, j;
- int olen, totlen;
- unsigned char *optptr;
- static int old_rrlen;
- static char old_rr[MAX_IPOPTLEN];
-
- totlen = hlen - sizeof(struct iphdr);
- optptr = cp;
-
- while (totlen > 0) {
- if (*optptr == IPOPT_EOL)
- break;
- if (*optptr == IPOPT_NOP) {
- totlen--;
- optptr++;
- printf(_("\nNOP"));
- continue;
- }
- cp = optptr;
- olen = optptr[1];
- if (olen < 2 || olen > totlen)
- break;
-
- switch (*cp) {
- case IPOPT_SSRR:
- case IPOPT_LSRR:
- printf(_("\n%cSRR: "), *cp == IPOPT_SSRR ? 'S' : 'L');
- j = *++cp;
- cp++;
- if (j > IPOPT_MINOFF) {
- for (;;) {
- uint32_t address;
- memcpy(&address, cp, 4);
- cp += 4;
- if (address == 0)
- printf("\t0.0.0.0");
- else {
- struct sockaddr_in sin = {
- .sin_family = AF_INET,
- .sin_addr = {
- address
- }
- };
-
- printf("\t%s", pr_addr(&sin, sizeof sin));
- }
- j -= 4;
- putchar('\n');
- if (j <= IPOPT_MINOFF)
- break;
- }
- }
- break;
- case IPOPT_RR:
- j = *++cp; /* get length */
- i = *++cp; /* and pointer */
- if (i > j)
- i = j;
- i -= IPOPT_MINOFF;
- if (i <= 0)
- break;
- if (i == old_rrlen
- && !memcmp(cp, old_rr, i)
- && !(options & F_FLOOD)) {
- printf(_("\t(same route)"));
- break;
- }
- old_rrlen = i;
- memcpy(old_rr, (char *)cp, i);
- printf(_("\nRR: "));
- cp++;
- for (;;) {
- uint32_t address;
- memcpy(&address, cp, 4);
- cp += 4;
- if (address == 0)
- printf("\t0.0.0.0");
- else {
- struct sockaddr_in sin = {
- .sin_family = AF_INET,
- .sin_addr = {
- address
- }
- };
-
- printf("\t%s", pr_addr(&sin, sizeof sin));
- }
- i -= 4;
- putchar('\n');
- if (i <= 0)
- break;
- }
- break;
- case IPOPT_TS:
- {
- int stdtime = 0, nonstdtime = 0;
- uint8_t flags;
- j = *++cp; /* get length */
- i = *++cp; /* and pointer */
- if (i > j)
- i = j;
- i -= 5;
- if (i <= 0)
- break;
- flags = *++cp;
- printf(_("\nTS: "));
- cp++;
- for (;;) {
- long l;
-
- if ((flags & 0xF) != IPOPT_TS_TSONLY) {
- uint32_t address;
- memcpy(&address, cp, 4);
- cp += 4;
- if (address == 0)
- printf("\t0.0.0.0");
- else {
- struct sockaddr_in sin = {
- .sin_family = AF_INET,
- .sin_addr = {
- address
- }
- };
-
- printf("\t%s", pr_addr(&sin, sizeof sin));
- }
- i -= 4;
- if (i <= 0)
- break;
- }
- l = *cp++;
- l = (l << 8) + *cp++;
- l = (l << 8) + *cp++;
- l = (l << 8) + *cp++;
-
- if (l & 0x80000000) {
- if (nonstdtime == 0)
- printf(_("\t%ld absolute not-standard"), l & 0x7fffffff);
- else
- printf(_("\t%ld not-standard"), (l & 0x7fffffff) - nonstdtime);
- nonstdtime = l & 0x7fffffff;
- } else {
- if (stdtime == 0)
- printf(_("\t%ld absolute"), l);
- else
- printf("\t%ld", l - stdtime);
- stdtime = l;
- }
- i -= 4;
- putchar('\n');
- if (i <= 0)
- break;
- }
- if (flags >> 4)
- printf(_("Unrecorded hops: %d\n"), flags >> 4);
- break;
- }
- default:
- printf(_("\nunknown option %x"), *cp);
- break;
- }
- totlen -= olen;
- optptr += olen;
- }
-}
-
-
-/*
- * pr_iph --
- * Print an IP header with options.
- */
-void pr_iph(struct iphdr *ip)
-{
- int hlen;
- unsigned char *cp;
-
- hlen = ip->ihl << 2;
- cp = (unsigned char *)ip + 20; /* point to options */
-
- printf(_("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst Data\n"));
- printf(_(" %1x %1x %02x %04x %04x"),
- ip->version, ip->ihl, ip->tos, ip->tot_len, ip->id);
- printf(_(" %1x %04x"), ((ip->frag_off) & 0xe000) >> 13,
- (ip->frag_off) & 0x1fff);
- printf(_(" %02x %02x %04x"), ip->ttl, ip->protocol, ip->check);
- printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->saddr));
- printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->daddr));
- printf("\n");
- pr_options(cp, hlen);
-}
-
/*
* pr_addr --
*
@@ -1577,51 +1614,6 @@ pr_addr(void *sa, socklen_t salen)
}
-/* Set Type of Service (TOS) and other Quality of Service relating bits */
-int parsetos(char *str)
-{
- const char *cp;
- int tos;
- char *ep;
-
- /* handle both hex and decimal values */
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
- cp = str + 2;
- tos = (int)strtol(cp, &ep, 16);
- } else
- tos = (int)strtol(str, &ep, 10);
-
- /* doesn't look like decimal or hex, eh? */
- if (*ep != '\0')
- error(2, 0, _("bad TOS value: %s"), str);
-
- if (tos > TOS_MAX)
- error(2, 0, _("the decimal value of TOS bits must be in range 0-255: %d"), tos);
- return (tos);
-}
-
-int parseflow(char *str)
-{
- const char *cp;
- unsigned long val;
- char *ep;
-
- /* handle both hex and decimal values */
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
- cp = str + 2;
- val = (int)strtoul(cp, &ep, 16);
- } else
- val = (int)strtoul(str, &ep, 10);
-
- /* doesn't look like decimal or hex, eh? */
- if (*ep != '\0')
- error(2, 0, _("bad value for flowinfo: %s"), str);
-
- if (val & ~IPV6_FLOWINFO_FLOWLABEL)
- error(2, 0, _("flow value is greater than 20 bits: %s"), str);
- return (val);
-}
-
void ping4_install_filter(socket_st *sock)
{
static int once;
diff --git a/ping6_common.c b/ping6_common.c
index 4e083c1..adce865 100644
--- a/ping6_common.c
+++ b/ping6_common.c
@@ -83,8 +83,6 @@ static int multicast;
static unsigned char cmsgbuf[4096];
static size_t cmsglen = 0;
-static int pr_icmph(uint8_t type, uint8_t code, uint32_t info);
-
struct sockaddr_in6 source6 = { .sin6_family = AF_INET6 };
extern char *device;
@@ -848,6 +846,80 @@ int ping6_run(int argc, char **argv, struct addrinfo *ai, struct socket_st *sock
main_loop(&ping6_func_set, sock, packet, packlen);
}
+int print_icmp(uint8_t type, uint8_t code, uint32_t info)
+{
+ switch (type) {
+ case ICMP6_DST_UNREACH:
+ printf(_("Destination unreachable: "));
+ switch (code) {
+ case ICMP6_DST_UNREACH_NOROUTE:
+ printf(_("No route"));
+ break;
+ case ICMP6_DST_UNREACH_ADMIN:
+ printf(_("Administratively prohibited"));
+ break;
+ case ICMP6_DST_UNREACH_BEYONDSCOPE:
+ printf(_("Beyond scope of source address"));
+ break;
+ case ICMP6_DST_UNREACH_ADDR:
+ printf(_("Address unreachable"));
+ break;
+ case ICMP6_DST_UNREACH_NOPORT:
+ printf(_("Port unreachable"));
+ break;
+ default:
+ printf(_("Unknown code %d"), code);
+ break;
+ }
+ break;
+ case ICMP6_PACKET_TOO_BIG:
+ printf(_("Packet too big: mtu=%u"), info);
+ if (code)
+ printf(_(", code=%d"), code);
+ break;
+ case ICMP6_TIME_EXCEEDED:
+ printf(_("Time exceeded: "));
+ if (code == ICMP6_TIME_EXCEED_TRANSIT)
+ printf(_("Hop limit"));
+ else if (code == ICMP6_TIME_EXCEED_REASSEMBLY)
+ printf(_("Defragmentation failure"));
+ else
+ printf(_("code %d"), code);
+ break;
+ case ICMP6_PARAM_PROB:
+ printf(_("Parameter problem: "));
+ if (code == ICMP6_PARAMPROB_HEADER)
+ printf(_("Wrong header field "));
+ else if (code == ICMP6_PARAMPROB_NEXTHEADER)
+ printf(_("Unknown header "));
+ else if (code == ICMP6_PARAMPROB_OPTION)
+ printf(_("Unknown option "));
+ else
+ printf(_("code %d "), code);
+ printf(_("at %u"), info);
+ break;
+ case ICMP6_ECHO_REQUEST:
+ printf(_("Echo request"));
+ break;
+ case ICMP6_ECHO_REPLY:
+ printf(_("Echo reply"));
+ break;
+ case MLD_LISTENER_QUERY:
+ printf(_("MLD Query"));
+ break;
+ case MLD_LISTENER_REPORT:
+ printf(_("MLD Report"));
+ break;
+ case MLD_LISTENER_REDUCTION:
+ printf(_("MLD Reduction"));
+ break;
+ default:
+ printf(_("unknown icmp type: %u"), type);
+
+ }
+ return 0;
+}
+
int ping6_receive_error_msg(socket_st *sock)
{
ssize_t res;
@@ -918,7 +990,7 @@ int ping6_receive_error_msg(socket_st *sock)
} else {
print_timestamp();
printf(_("From %s icmp_seq=%u "), pr_addr(sin6, sizeof *sin6), ntohs(icmph.icmp6_seq));
- pr_icmph(e->ee_type, e->ee_code, e->ee_info);
+ print_icmp(e->ee_type, e->ee_code, e->ee_info);
putchar('\n');
fflush(stdout);
}
@@ -1264,7 +1336,7 @@ ping6_parse_reply(socket_st *sock, struct msghdr *msg, int cc, void *addr, struc
print_timestamp();
printf(_("From %s: "), pr_addr(from, sizeof *from));
}
- pr_icmph(icmph->icmp6_type, icmph->icmp6_code, ntohl(icmph->icmp6_mtu));
+ print_icmp(icmph->icmp6_type, icmph->icmp6_code, ntohl(icmph->icmp6_mtu));
}
if (options & F_AUDIBLE) {
@@ -1279,81 +1351,6 @@ ping6_parse_reply(socket_st *sock, struct msghdr *msg, int cc, void *addr, struc
return 0;
}
-
-int pr_icmph(uint8_t type, uint8_t code, uint32_t info)
-{
- switch (type) {
- case ICMP6_DST_UNREACH:
- printf(_("Destination unreachable: "));
- switch (code) {
- case ICMP6_DST_UNREACH_NOROUTE:
- printf(_("No route"));
- break;
- case ICMP6_DST_UNREACH_ADMIN:
- printf(_("Administratively prohibited"));
- break;
- case ICMP6_DST_UNREACH_BEYONDSCOPE:
- printf(_("Beyond scope of source address"));
- break;
- case ICMP6_DST_UNREACH_ADDR:
- printf(_("Address unreachable"));
- break;
- case ICMP6_DST_UNREACH_NOPORT:
- printf(_("Port unreachable"));
- break;
- default:
- printf(_("Unknown code %d"), code);
- break;
- }
- break;
- case ICMP6_PACKET_TOO_BIG:
- printf(_("Packet too big: mtu=%u"), info);
- if (code)
- printf(_(", code=%d"), code);
- break;
- case ICMP6_TIME_EXCEEDED:
- printf(_("Time exceeded: "));
- if (code == ICMP6_TIME_EXCEED_TRANSIT)
- printf(_("Hop limit"));
- else if (code == ICMP6_TIME_EXCEED_REASSEMBLY)
- printf(_("Defragmentation failure"));
- else
- printf(_("code %d"), code);
- break;
- case ICMP6_PARAM_PROB:
- printf(_("Parameter problem: "));
- if (code == ICMP6_PARAMPROB_HEADER)
- printf(_("Wrong header field "));
- else if (code == ICMP6_PARAMPROB_NEXTHEADER)
- printf(_("Unknown header "));
- else if (code == ICMP6_PARAMPROB_OPTION)
- printf(_("Unknown option "));
- else
- printf(_("code %d "), code);
- printf(_("at %u"), info);
- break;
- case ICMP6_ECHO_REQUEST:
- printf(_("Echo request"));
- break;
- case ICMP6_ECHO_REPLY:
- printf(_("Echo reply"));
- break;
- case MLD_LISTENER_QUERY:
- printf(_("MLD Query"));
- break;
- case MLD_LISTENER_REPORT:
- printf(_("MLD Report"));
- break;
- case MLD_LISTENER_REDUCTION:
- printf(_("MLD Reduction"));
- break;
- default:
- printf(_("unknown icmp type: %u"), type);
-
- }
- return 0;
-}
-
void ping6_install_filter(socket_st *sock)
{
static int once;