Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/traceroute6/traceroute6.c
Show First 20 Lines • Show All 288 Lines • ▼ Show 20 Lines | |||||
#define MAXPACKET 65535 /* max ip packet size */ | #define MAXPACKET 65535 /* max ip packet size */ | ||||
#ifndef HAVE_GETIPNODEBYNAME | #ifndef HAVE_GETIPNODEBYNAME | ||||
#define getipnodebyname(x, y, z, u) gethostbyname2((x), (y)) | #define getipnodebyname(x, y, z, u) gethostbyname2((x), (y)) | ||||
#define freehostent(x) | #define freehostent(x) | ||||
#endif | #endif | ||||
u_char packet[512]; /* last inbound (icmp) packet */ | static u_char packet[512]; /* last inbound (icmp) packet */ | ||||
char *outpacket; /* last output packet */ | static char *outpacket; /* last output packet */ | ||||
int main(int, char *[]); | int main(int, char *[]); | ||||
int wait_for_reply(int, struct msghdr *); | int wait_for_reply(int, struct msghdr *); | ||||
#ifdef IPSEC | #ifdef IPSEC | ||||
#ifdef IPSEC_POLICY_IPSEC | #ifdef IPSEC_POLICY_IPSEC | ||||
int setpolicy(int so, char *policy); | int setpolicy(int so, char *policy); | ||||
#endif | #endif | ||||
#endif | #endif | ||||
markj: You also need to remove one of the #endifs. Please make sure to at least test the build before… | |||||
void send_probe(int, u_long); | void send_probe(int, u_long); | ||||
void *get_uphdr(struct ip6_hdr *, u_char *); | void *get_uphdr(struct ip6_hdr *, u_char *); | ||||
int get_hoplim(struct msghdr *); | int get_hoplim(struct msghdr *); | ||||
double deltaT(struct timeval *, struct timeval *); | double deltaT(struct timeval *, struct timeval *); | ||||
const char *pr_type(int); | const char *pr_type(int); | ||||
int packet_ok(struct msghdr *, int, int, u_char *, u_char *); | int packet_ok(struct msghdr *, int, int, u_char *, u_char *); | ||||
void print(struct msghdr *, int); | void print(struct msghdr *, int); | ||||
const char *inetname(struct sockaddr *); | const char *inetname(struct sockaddr *); | ||||
u_int32_t sctp_crc32c(void *, u_int32_t); | u_int32_t sctp_crc32c(void *, u_int32_t); | ||||
u_int16_t in_cksum(u_int16_t *addr, int); | u_int16_t in_cksum(u_int16_t *addr, int); | ||||
u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *, | u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *, | ||||
void *, u_int32_t); | void *, u_int32_t); | ||||
void usage(void); | void usage(void); | ||||
int rcvsock; /* receive (icmp) socket file descriptor */ | static int rcvsock; /* receive (icmp) socket file descriptor */ | ||||
int sndsock; /* send (raw/udp) socket file descriptor */ | static int sndsock; /* send (raw/udp) socket file descriptor */ | ||||
struct msghdr rcvmhdr; | static struct msghdr rcvmhdr; | ||||
struct iovec rcviov[2]; | static struct iovec rcviov[2]; | ||||
int rcvhlim; | static int rcvhlim; | ||||
struct in6_pktinfo *rcvpktinfo; | static struct in6_pktinfo *rcvpktinfo; | ||||
struct sockaddr_in6 Src, Dst, Rcv; | static struct sockaddr_in6 Src, Dst, Rcv; | ||||
u_long datalen = 20; /* How much data */ | static u_long datalen = 20; /* How much data */ | ||||
#define ICMP6ECHOLEN 8 | #define ICMP6ECHOLEN 8 | ||||
/* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */ | /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */ | ||||
char rtbuf[2064]; | static char rtbuf[2064]; | ||||
struct ip6_rthdr *rth; | static struct ip6_rthdr *rth; | ||||
struct cmsghdr *cmsg; | static struct cmsghdr *cmsg; | ||||
char *source = NULL; | static char *source = NULL; | ||||
char *hostname; | static char *hostname; | ||||
u_long nprobes = 3; | static u_long nprobes = 3; | ||||
u_long first_hop = 1; | static u_long first_hop = 1; | ||||
u_long max_hops = 30; | static u_long max_hops = 30; | ||||
u_int16_t srcport; | static u_int16_t srcport; | ||||
u_int16_t port = 32768+666; /* start udp dest port # for probe packets */ | static u_int16_t port = 32768+666; /* start udp dest port # for probe packets */ | ||||
u_int16_t ident; | static u_int16_t ident; | ||||
int options; /* socket options */ | static int options; /* socket options */ | ||||
int verbose; | static int verbose; | ||||
int waittime = 5; /* time to wait for response (in seconds) */ | static int waittime = 5; /* time to wait for response (in seconds) */ | ||||
int nflag; /* print addresses numerically */ | static int nflag; /* print addresses numerically */ | ||||
int useproto = IPPROTO_UDP; /* protocol to use to send packet */ | static int useproto = IPPROTO_UDP; /* protocol to use to send packet */ | ||||
int lflag; /* print both numerical address & hostname */ | static int lflag; /* print both numerical address & hostname */ | ||||
int as_path; /* print as numbers for each hop */ | static int as_path; /* print as numbers for each hop */ | ||||
char *as_server = NULL; | static char *as_server = NULL; | ||||
void *asn; | static void *asn; | ||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM }; | int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM }; | ||||
char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep; | char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep; | ||||
int ch, i, on = 1, seq, rcvcmsglen, error; | int ch, i, on = 1, seq, rcvcmsglen, error; | ||||
struct addrinfo hints, *res; | struct addrinfo hints, *res; | ||||
static u_char *rcvcmsgbuf; | static u_char *rcvcmsgbuf; | ||||
u_long probe, hops, lport; | u_long probe, hops, lport; | ||||
struct hostent *hp; | struct hostent *hp; | ||||
size_t size, minlen; | size_t size, minlen; | ||||
uid_t uid; | uid_t uid; | ||||
u_char type, code; | u_char type, code; | ||||
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) | |||||
Not Done Inline ActionsI think the comments are not necessary. They also break style(9) since the lines are longer than 80 columns. You don't need to include the array length in the definition, it should work to write char ipssp_inbypass[] = .... I don't quite understand what the "ipssp" string means. These strings should be defined under #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC). markj: I think the comments are not necessary. They also break style(9) since the lines are longer… | |||||
markjUnsubmitted Not Done Inline ActionsThe "#if" should not be indented; see the other places where #ifdef etc. are used. While here, could you convert other instances of #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC ... to #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) as you did here? markj: The "#if" should not be indented; see the other places where #ifdef etc. are used.
While here… | |||||
char ipsec_inpolicy[] = "in bypass"; | |||||
char ipsec_outpolicy[] = "out bypass"; | |||||
#endif | |||||
/* | /* | ||||
* Receive ICMP | * Receive ICMP | ||||
*/ | */ | ||||
if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { | if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { | ||||
perror("socket(ICMPv6)"); | perror("socket(ICMPv6)"); | ||||
exit(5); | exit(5); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
if (res->ai_next) { | if (res->ai_next) { | ||||
if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, | if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, | ||||
sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) | sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) | ||||
strlcpy(hbuf, "?", sizeof(hbuf)); | strlcpy(hbuf, "?", sizeof(hbuf)); | ||||
fprintf(stderr, "traceroute6: Warning: %s has multiple " | fprintf(stderr, "traceroute6: Warning: %s has multiple " | ||||
"addresses; using %s\n", hostname, hbuf); | "addresses; using %s\n", hostname, hbuf); | ||||
} | } | ||||
freeaddrinfo(res); | |||||
if (*++argv) { | if (*++argv) { | ||||
ep = NULL; | ep = NULL; | ||||
errno = 0; | errno = 0; | ||||
datalen = strtoul(*argv, &ep, 0); | datalen = strtoul(*argv, &ep, 0); | ||||
if (errno || *ep) { | if (errno || *ep) { | ||||
fprintf(stderr, | fprintf(stderr, | ||||
"traceroute6: invalid packet length.\n"); | "traceroute6: invalid packet length.\n"); | ||||
exit(1); | exit(1); | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | if (options & SO_DONTROUTE) | ||||
(void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE, | (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE, | ||||
(char *)&on, sizeof(on)); | (char *)&on, sizeof(on)); | ||||
#ifdef IPSEC | #ifdef IPSEC | ||||
#ifdef IPSEC_POLICY_IPSEC | #ifdef IPSEC_POLICY_IPSEC | ||||
/* | /* | ||||
* do not raise error even if setsockopt fails, kernel may have ipsec | * do not raise error even if setsockopt fails, kernel may have ipsec | ||||
* turned off. | * turned off. | ||||
*/ | */ | ||||
if (setpolicy(rcvsock, "in bypass") < 0) | if (setpolicy(rcvsock, ipsec_inpolicy) < 0) | ||||
errx(1, "%s", ipsec_strerror()); | errx(1, "%s", ipsec_strerror()); | ||||
if (setpolicy(rcvsock, "out bypass") < 0) | if (setpolicy(rcvsock, ipsec_outpolicy) < 0) | ||||
errx(1, "%s", ipsec_strerror()); | errx(1, "%s", ipsec_strerror()); | ||||
#else | #else | ||||
{ | { | ||||
int level = IPSEC_LEVEL_NONE; | int level = IPSEC_LEVEL_NONE; | ||||
(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, | (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, | ||||
sizeof(level)); | sizeof(level)); | ||||
(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, | (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, | ||||
Show All 39 Lines | if (rth) {/* XXX: there is no library to finalize the header... */ | ||||
} | } | ||||
} | } | ||||
#ifdef IPSEC | #ifdef IPSEC | ||||
#ifdef IPSEC_POLICY_IPSEC | #ifdef IPSEC_POLICY_IPSEC | ||||
/* | /* | ||||
* do not raise error even if setsockopt fails, kernel may have ipsec | * do not raise error even if setsockopt fails, kernel may have ipsec | ||||
* turned off. | * turned off. | ||||
*/ | */ | ||||
if (setpolicy(sndsock, "in bypass") < 0) | if (setpolicy(sndsock, ipsec_inpolicy) < 0) | ||||
errx(1, "%s", ipsec_strerror()); | errx(1, "%s", ipsec_strerror()); | ||||
if (setpolicy(sndsock, "out bypass") < 0) | if (setpolicy(sndsock, ipsec_outpolicy) < 0) | ||||
errx(1, "%s", ipsec_strerror()); | errx(1, "%s", ipsec_strerror()); | ||||
#else | #else | ||||
{ | { | ||||
int level = IPSEC_LEVEL_BYPASS; | int level = IPSEC_LEVEL_BYPASS; | ||||
(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, | (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, | ||||
sizeof(level)); | sizeof(level)); | ||||
(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, | (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, | ||||
Show All 13 Lines | |||||
#endif /*IPSEC_POLICY_IPSEC*/ | #endif /*IPSEC_POLICY_IPSEC*/ | ||||
#endif /*IPSEC*/ | #endif /*IPSEC*/ | ||||
/* | /* | ||||
* Source selection | * Source selection | ||||
*/ | */ | ||||
bzero(&Src, sizeof(Src)); | bzero(&Src, sizeof(Src)); | ||||
if (source) { | if (source) { | ||||
struct addrinfo hints, *res; | |||||
int error; | |||||
memset(&hints, 0, sizeof(hints)); | memset(&hints, 0, sizeof(hints)); | ||||
hints.ai_family = AF_INET6; | hints.ai_family = AF_INET6; | ||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/ | hints.ai_socktype = SOCK_DGRAM; /*dummy*/ | ||||
hints.ai_flags = AI_NUMERICHOST; | hints.ai_flags = AI_NUMERICHOST; | ||||
error = getaddrinfo(source, "0", &hints, &res); | error = getaddrinfo(source, "0", &hints, &res); | ||||
if (error) { | if (error) { | ||||
printf("traceroute6: %s: %s\n", source, | printf("traceroute6: %s: %s\n", source, | ||||
Not Done Inline ActionsLooking at this more closely, it's fine to just reuse the top-level variables. This makes me realize that the other use of getaddrinfo() above is missing a freeaddrinfo(res) call, so let's add that too. markj: Looking at this more closely, it's fine to just reuse the top-level variables.
This makes me… | |||||
gai_strerror(error)); | gai_strerror(error)); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
if (res->ai_addrlen > sizeof(Src)) { | if (res->ai_addrlen > sizeof(Src)) { | ||||
printf("traceroute6: %s: %s\n", source, | printf("traceroute6: %s: %s\n", source, | ||||
gai_strerror(error)); | gai_strerror(error)); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 800 Lines • ▼ Show 20 Lines | static u_int32_t crc_c[256] = { | ||||
0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, | 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, | ||||
0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, | 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, | ||||
0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, | 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, | ||||
0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, | 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, | ||||
0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 | 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 | ||||
}; | }; | ||||
u_int32_t | u_int32_t | ||||
sctp_crc32c(void *packet, u_int32_t len) | sctp_crc32c(void *pack, u_int32_t len) | ||||
{ | { | ||||
u_int32_t i, crc32c; | u_int32_t i, crc32c; | ||||
u_int8_t byte0, byte1, byte2, byte3; | u_int8_t byte0, byte1, byte2, byte3; | ||||
u_int8_t *buf = (u_int8_t *)packet; | u_int8_t *buf = (u_int8_t *)pack; | ||||
crc32c = ~0; | crc32c = ~0; | ||||
for (i = 0; i < len; i++) | for (i = 0; i < len; i++) | ||||
CRC32C(crc32c, buf[i]); | CRC32C(crc32c, buf[i]); | ||||
crc32c = ~crc32c; | crc32c = ~crc32c; | ||||
byte0 = crc32c & 0xff; | byte0 = crc32c & 0xff; | ||||
byte1 = (crc32c>>8) & 0xff; | byte1 = (crc32c>>8) & 0xff; | ||||
byte2 = (crc32c>>16) & 0xff; | byte2 = (crc32c>>16) & 0xff; | ||||
▲ Show 20 Lines • Show All 74 Lines • Show Last 20 Lines |
You also need to remove one of the #endifs. Please make sure to at least test the build before uploading to phabricator in the future.