Since FreeBSD10, only one struct addrinfo is used in ping6.
But in case of option -g, another one must be used to store gateway addrinfo.
In detail, when we call "ping6 host":
- the program calls getaddrinfo() for "host" and stores it into "res" which will be used later
- the program uses the struct "res" to send an ICMP request to "host"
But when we call "ping6 -g gateway host":
- the program calls getaddrinfo() for "host" and stores it into "res" which will be used later
- if -g is set a) the program calls getaddrinfo() for "gateway"; b) it stores addrinfo of "gateway" into "res", which overwrites addrinfo of "host"; c) uses addrinfo of "gateway" immediately in setsockopt(); d) then it makes freeaddrinfo(res);
- the program uses the struct "res" to send an ICMP request to "host", expecting that "res" contains addrinfo of "host"
... but "res" has been overwritten in step 2b (and freed in step 2d)
The given patch fixes this case, and the case of using hops too.
I have used the same variable names as in FreeBSD 9.3 .