diff options
author | Sami Kerola <kerolasa@iki.fi> | 2019-07-22 18:16:14 +0100 |
---|---|---|
committer | Sami Kerola <kerolasa@iki.fi> | 2019-07-22 18:40:33 +0100 |
commit | 230689297b25a600b410e3ee810d6de6452a50aa (patch) | |
tree | 23606972ca797887573ecfa2de78366c213faa00 | |
parent | 918b876a5eb1e8bffe1a56c5697064c6dc80a141 (diff) | |
download | iputils-230689297b25a600b410e3ee810d6de6452a50aa.tar.gz |
ping: remove function prototypes
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
-rw-r--r-- | ping.c | 882 | ||||
-rw-r--r-- | ping6_common.c | 155 |
2 files changed, 513 insertions, 524 deletions
@@ -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; |