|
version 1.1.1.1, 2019/10/21 14:25:31
|
version 1.1.1.2, 2021/03/17 00:07:30
|
|
Line 11
|
Line 11
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
GNU General Public License for more details. |
| |
|
| You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License along |
| along with this program; if not, write to the Free Software | with this program; if not, write to the Free Software Foundation, Inc., |
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| */ |
*/ |
| |
|
| #include "config.h" |
#include "config.h" |
| |
|
| #include <errno.h> |
#include <errno.h> |
| |
#include <sys/types.h> |
| |
#include <ifaddrs.h> |
| #include <math.h> |
#include <math.h> |
| #include <stdlib.h> |
#include <stdlib.h> |
| #include <string.h> |
#include <string.h> |
|
Line 37
|
Line 39
|
| #include "display.h" |
#include "display.h" |
| #include "dns.h" |
#include "dns.h" |
| #include "utils.h" |
#include "utils.h" |
| |
#include "packet/sockaddr.h" |
| |
|
| #define MinSequence 33000 |
#define MinSequence 33000 |
| #define MaxSequence 65536 |
#define MaxSequence 65536 |
| |
|
| static int packetsize; /* packet size used by ping */ |
static int packetsize; /* packet size used by ping */ |
| |
|
| static void sockaddrtop( |
|
| struct sockaddr *saddr, |
|
| char *strptr, |
|
| size_t len); |
|
| |
|
| struct nethost { |
struct nethost { |
| ip_t addr; | ip_t addr; /* Latest host to respond */ |
| ip_t addrs[MAXPATH]; /* for multi paths byMin */ | ip_t addrs[MAX_PATH]; /* For Multi paths/Path Changes: List of all hosts that have responded */ |
| | int err; |
| int xmit; |
int xmit; |
| int returned; |
int returned; |
| int sent; |
int sent; |
|
Line 69 struct nethost {
|
Line 68 struct nethost {
|
| int saved[SAVED_PINGS]; |
int saved[SAVED_PINGS]; |
| int saved_seq_offset; |
int saved_seq_offset; |
| struct mplslen mpls; |
struct mplslen mpls; |
| struct mplslen mplss[MAXPATH]; | struct mplslen mplss[MAX_PATH]; |
| }; |
}; |
| |
|
| |
|
|
Line 85 static struct nethost host[MaxHost];
|
Line 84 static struct nethost host[MaxHost];
|
| static struct sequence sequence[MaxSequence]; |
static struct sequence sequence[MaxSequence]; |
| static struct packet_command_pipe_t packet_command_pipe; |
static struct packet_command_pipe_t packet_command_pipe; |
| |
|
| #ifdef ENABLE_IPV6 |
|
| static struct sockaddr_storage sourcesockaddr_struct; |
static struct sockaddr_storage sourcesockaddr_struct; |
| static struct sockaddr_storage remotesockaddr_struct; |
static struct sockaddr_storage remotesockaddr_struct; |
| static struct sockaddr_in6 *ssa6 = |
|
| (struct sockaddr_in6 *) &sourcesockaddr_struct; |
|
| static struct sockaddr_in6 *rsa6 = |
|
| (struct sockaddr_in6 *) &remotesockaddr_struct; |
|
| #else |
|
| static struct sockaddr_in sourcesockaddr_struct; |
|
| static struct sockaddr_in remotesockaddr_struct; |
|
| #endif |
|
| |
|
| static struct sockaddr *sourcesockaddr = |
static struct sockaddr *sourcesockaddr = |
| (struct sockaddr *) &sourcesockaddr_struct; |
(struct sockaddr *) &sourcesockaddr_struct; |
| static struct sockaddr *remotesockaddr = |
static struct sockaddr *remotesockaddr = |
| (struct sockaddr *) &remotesockaddr_struct; |
(struct sockaddr *) &remotesockaddr_struct; |
| static struct sockaddr_in *ssa4 = |
|
| (struct sockaddr_in *) &sourcesockaddr_struct; |
|
| static struct sockaddr_in *rsa4 = |
|
| (struct sockaddr_in *) &remotesockaddr_struct; |
|
| |
|
| static ip_t *sourceaddress; |
static ip_t *sourceaddress; |
| static ip_t *remoteaddress; |
static ip_t *remoteaddress; |
|
Line 121 static char localaddr[INET_ADDRSTRLEN];
|
Line 107 static char localaddr[INET_ADDRSTRLEN];
|
| static int batch_at = 0; |
static int batch_at = 0; |
| static int numhosts = 10; |
static int numhosts = 10; |
| |
|
| |
|
| |
#define host_addr_cmp(index, other, af) \ |
| |
addrcmp((void *) &(host[(index)].addr), (void *) (other), (af)) |
| |
|
| |
#define host_addrs_cmp(index, path, other, af) \ |
| |
addrcmp((void *) &(host[(index)].addrs[path]), (void *) (other), (af)) |
| |
|
| |
|
| /* return the number of microseconds to wait before sending the next |
/* return the number of microseconds to wait before sending the next |
| ping */ |
ping */ |
| int calc_deltatime( |
int calc_deltatime( |
|
Line 181 static void net_send_query(
|
Line 175 static void net_send_query(
|
| int time_to_live = index + 1; |
int time_to_live = index + 1; |
| |
|
| send_probe_command(ctl, &packet_command_pipe, remoteaddress, |
send_probe_command(ctl, &packet_command_pipe, remoteaddress, |
| sourceaddress, packetsize, seq, time_to_live); | sourceaddress, packet_size, seq, time_to_live); |
| } |
} |
| |
|
| |
|
| /* We got a return on something we sent out. Record the address and | /* |
| time. */ | Mark a sequence entry as completed and return the host index |
| | being probed. |
| | |
| | Returns -1 in the case of an invalid sequence number. |
| | */ |
| | static int mark_sequence_complete( |
| | int seq) |
| | { |
| | if ((seq < 0) || (seq >= MaxSequence)) { |
| | return -1; |
| | } |
| | |
| | if (!sequence[seq].transit) { |
| | return -1; |
| | } |
| | sequence[seq].transit = 0; |
| | |
| | return sequence[seq].index; |
| | } |
| | |
| | |
| | /* |
| | A probe has successfully completed. |
| | |
| | Record the round trip time and address of the responding host. |
| | */ |
| | |
| static void net_process_ping( |
static void net_process_ping( |
| struct mtr_ctl *ctl, |
struct mtr_ctl *ctl, |
| int seq, |
int seq, |
| |
int err, |
| struct mplslen *mpls, |
struct mplslen *mpls, |
| ip_t * addr, |
ip_t * addr, |
| int totusec) |
int totusec) |
|
Line 198 static void net_process_ping(
|
Line 219 static void net_process_ping(
|
| int oldavg; /* usedByMin */ |
int oldavg; /* usedByMin */ |
| int oldjavg; /* usedByMin */ |
int oldjavg; /* usedByMin */ |
| int i; /* usedByMin */ |
int i; /* usedByMin */ |
| |
int found = 0; |
| #ifdef ENABLE_IPV6 |
#ifdef ENABLE_IPV6 |
| char addrcopy[sizeof(struct in6_addr)]; |
char addrcopy[sizeof(struct in6_addr)]; |
| #else |
#else |
| char addrcopy[sizeof(struct in_addr)]; |
char addrcopy[sizeof(struct in_addr)]; |
| #endif |
#endif |
| |
struct nethost *nh = NULL; |
| |
|
| addrcpy((void *) &addrcopy, (char *) addr, ctl->af); | memcpy(&addrcopy, addr, sockaddr_addr_size(sourcesockaddr)); |
| |
|
| if ((seq < 0) || (seq >= MaxSequence)) { | index = mark_sequence_complete(seq); |
| | if (index < 0) { |
| return; |
return; |
| } |
} |
| |
nh = &host[index]; |
| |
nh->err = err; |
| |
|
| if (!sequence[seq].transit) { |
|
| return; |
|
| } |
|
| sequence[seq].transit = 0; |
|
| |
|
| index = sequence[seq].index; |
|
| |
|
| if (addrcmp((void *) &(host[index].addr), | if (addrcmp(&nh->addr, &addrcopy, ctl->af) != 0) { |
| (void *) &ctl->unspec_addr, ctl->af) == 0) { | for (i = 0; i < MAX_PATH;) { |
| /* should be out of if as addr can change */ | if (addrcmp(&nh->addrs[i], &nh->addr, ctl->af) == 0) { |
| addrcpy((void *) &(host[index].addr), addrcopy, ctl->af); | found = 1; /* This host is already in the list */ |
| host[index].mpls = *mpls; | |
| display_rawhost(ctl, index, (void *) &(host[index].addr)); | |
| |
| /* multi paths */ | |
| addrcpy((void *) &(host[index].addrs[0]), addrcopy, ctl->af); | |
| host[index].mplss[0] = *mpls; | |
| } else { | |
| for (i = 0; i < MAXPATH;) { | |
| if (addrcmp | |
| ((void *) &(host[index].addrs[i]), (void *) &addrcopy, | |
| ctl->af) == 0 | |
| || addrcmp((void *) &(host[index].addrs[i]), | |
| (void *) &ctl->unspec_addr, ctl->af) == 0) { | |
| break; |
break; |
| } |
} |
| |
if (addrcmp(&nh->addrs[i], &ctl->unspec_addr, ctl->af) == 0) { |
| |
break; /* Found first vacant position */ |
| |
} |
| i++; |
i++; |
| } |
} |
| |
|
| if (addrcmp((void *) &(host[index].addrs[i]), addrcopy, ctl->af) != | if (found == 0 && i < MAX_PATH) { |
| 0 && i < MAXPATH) { | memcpy(&nh->addrs[i], &nh->addr, sockaddr_addr_size(sourcesockaddr)); |
| addrcpy((void *) &(host[index].addrs[i]), addrcopy, ctl->af); | |
| host[index].mplss[i] = *mpls; | nh->mplss[i] = nh->mpls; |
| display_rawhost(ctl, index, (void *) &(host[index].addrs[i])); | display_rawhost(ctl, index, (void *)&(nh->addrs[i]), (void *)&(nh->addrs[i])); |
| } |
} |
| |
|
| |
/* Always save the latest host in nh->addr. This |
| |
* allows maxTTL to change whenever path changes. |
| |
*/ |
| |
memcpy(&nh->addr, addrcopy, sockaddr_addr_size(sourcesockaddr)); |
| |
nh->mpls = *mpls; |
| |
display_rawhost(ctl, index, (void *)&(nh->addr), (void *)&(nh->mpls)); |
| } |
} |
| |
|
| host[index].jitter = totusec - host[index].last; | nh->jitter = totusec - nh->last; |
| if (host[index].jitter < 0) { | if (nh->jitter < 0) { |
| host[index].jitter = -host[index].jitter; | nh->jitter = -nh->jitter; |
| } |
} |
| |
|
| host[index].last = totusec; | nh->last = totusec; |
| |
|
| if (host[index].returned < 1) { | if (nh->returned < 1) { |
| host[index].best = host[index].worst = host[index].gmean = totusec; | nh->best = nh->worst = nh->gmean = totusec; |
| host[index].avg = host[index].ssd = 0; | nh->avg = nh->ssd = 0; |
| |
|
| host[index].jitter = host[index].jworst = host[index].jinta = 0; | nh->jitter = nh->jworst = nh->jinta = 0; |
| } |
} |
| |
|
| if (totusec < host[index].best) { | if (totusec < nh->best) { |
| host[index].best = totusec; | nh->best = totusec; |
| } |
} |
| if (totusec > host[index].worst) { | if (totusec > nh->worst) { |
| host[index].worst = totusec; | nh->worst = totusec; |
| } |
} |
| |
|
| if (host[index].jitter > host[index].jworst) { | if (nh->jitter > nh->jworst) { |
| host[index].jworst = host[index].jitter; | nh->jworst = nh->jitter; |
| } |
} |
| |
|
| host[index].returned++; | nh->returned++; |
| oldavg = host[index].avg; | oldavg = nh->avg; |
| host[index].avg += (totusec - oldavg + .0) / host[index].returned; | nh->avg += (totusec - oldavg + .0) / nh->returned; |
| host[index].ssd += | nh->ssd += |
| (totusec - oldavg + .0) * (totusec - host[index].avg); | (totusec - oldavg + .0) * (totusec - nh->avg); |
| |
|
| oldjavg = host[index].javg; | oldjavg = nh->javg; |
| host[index].javg += | nh->javg += |
| (host[index].jitter - oldjavg) / host[index].returned; | (nh->jitter - oldjavg) / nh->returned; |
| /* below algorithm is from rfc1889, A.8 */ |
/* below algorithm is from rfc1889, A.8 */ |
| host[index].jinta += | nh->jinta += |
| host[index].jitter - ((host[index].jinta + 8) >> 4); | nh->jitter - ((nh->jinta + 8) >> 4); |
| |
|
| if (host[index].returned > 1) { | if (nh->returned > 1) { |
| host[index].gmean = | nh->gmean = |
| pow((double) host[index].gmean, | pow((double) nh->gmean, |
| (host[index].returned - 1.0) / host[index].returned) | (nh->returned - 1.0) / nh->returned) |
| * pow((double) totusec, 1.0 / host[index].returned); | * pow((double) totusec, 1.0 / nh->returned); |
| } |
} |
| |
|
| host[index].sent = 0; | nh->sent = 0; |
| host[index].up = 1; | nh->up = 1; |
| host[index].transit = 0; | nh->transit = 0; |
| |
|
| net_save_return(index, sequence[seq].saved_seq, totusec); |
net_save_return(index, sequence[seq].saved_seq, totusec); |
| display_rawping(ctl, index, totusec, seq); |
display_rawping(ctl, index, totusec, seq); |
|
Line 325 ip_t *net_addrs(
|
Line 343 ip_t *net_addrs(
|
| return (ip_t *) & (host[at].addrs[i]); |
return (ip_t *) & (host[at].addrs[i]); |
| } |
} |
| |
|
| |
/* |
| |
Get the error code corresponding to a host entry. |
| |
*/ |
| |
int net_err( |
| |
int at) |
| |
{ |
| |
return host[at].err; |
| |
} |
| |
|
| void *net_mpls( |
void *net_mpls( |
| int at) |
int at) |
| { |
{ |
|
Line 440 int net_max(
|
Line 467 int net_max(
|
| int max; |
int max; |
| |
|
| max = 0; |
max = 0; |
| for (at = 0; at < ctl->maxTTL - 1; at++) { | for (at = 0; at < ctl->maxTTL; at++) { |
| if (addrcmp((void *) &(host[at].addr), | if (host_addr_cmp(at , remoteaddress, ctl->af) == 0) { |
| (void *) remoteaddress, ctl->af) == 0) { | |
| return at + 1; |
return at + 1; |
| } else if (addrcmp((void *) &(host[at].addr), | } else if (host[at].err != 0) { |
| (void *) &ctl->unspec_addr, ctl->af) != 0) { | /* |
| | If a hop has returned an ICMP error |
| | (such as "no route to host") then we'll consider that the |
| | final hop. |
| | */ |
| | return at + 1; |
| | } else if (host_addr_cmp(at, &ctl->unspec_addr, ctl->af) != 0) { |
| max = at + 2; |
max = at + 2; |
| } |
} |
| } |
} |
| |
|
| |
if (max > ctl->maxTTL) |
| |
max = ctl->maxTTL; |
| return max; |
return max; |
| } |
} |
| |
|
|
Line 503 int net_send_batch(
|
Line 537 int net_send_batch(
|
| struct mtr_ctl *ctl) |
struct mtr_ctl *ctl) |
| { |
{ |
| int n_unknown = 0, i; |
int n_unknown = 0, i; |
| |
int restart = 0; |
| |
|
| /* randomized packet size and/or bit pattern if packetsize<0 and/or |
/* randomized packet size and/or bit pattern if packetsize<0 and/or |
| bitpattern<0. abs(packetsize) and/or abs(bitpattern) will be used |
bitpattern<0. abs(packetsize) and/or abs(bitpattern) will be used |
|
Line 514 int net_send_batch(
|
Line 549 int net_send_batch(
|
| have a range for "rand()" that runs to 32768, and the |
have a range for "rand()" that runs to 32768, and the |
| destination range is 10000, you end up with 4 out of 32768 |
destination range is 10000, you end up with 4 out of 32768 |
| 0-2768's and only 3 out of 32768 for results 2769 .. 9999. |
0-2768's and only 3 out of 32768 for results 2769 .. 9999. |
| As our detination range (in the example 10000) is much | As our destination range (in the example 10000) is much |
| smaller (reasonable packet sizes), and our rand() range much |
smaller (reasonable packet sizes), and our rand() range much |
| larger, this effect is insignificant. Oh! That other formula |
larger, this effect is insignificant. Oh! That other formula |
| didn't work. */ |
didn't work. */ |
|
Line 532 int net_send_batch(
|
Line 567 int net_send_batch(
|
| net_send_query(ctl, batch_at, abs(packetsize)); |
net_send_query(ctl, batch_at, abs(packetsize)); |
| |
|
| for (i = ctl->fstTTL - 1; i < batch_at; i++) { |
for (i = ctl->fstTTL - 1; i < batch_at; i++) { |
| if (addrcmp | if (host_addr_cmp(i, &ctl->unspec_addr, ctl->af) == 0) |
| ((void *) &(host[i].addr), (void *) &ctl->unspec_addr, | |
| ctl->af) == 0) | |
| n_unknown++; |
n_unknown++; |
| |
|
| /* The second condition in the next "if" statement was added in mtr-0.56, |
/* The second condition in the next "if" statement was added in mtr-0.56, |
|
Line 542 int net_send_batch(
|
Line 575 int net_send_batch(
|
| hosts. Removed in 0.65. |
hosts. Removed in 0.65. |
| If the line proves necessary, it should at least NOT trigger that line |
If the line proves necessary, it should at least NOT trigger that line |
| when host[i].addr == 0 */ |
when host[i].addr == 0 */ |
| if ((addrcmp((void *) &(host[i].addr), | if (host_addr_cmp(i, remoteaddress, ctl->af) == 0) { |
| (void *) remoteaddress, ctl->af) == 0)) | restart = 1; |
| n_unknown = MaxHost; /* Make sure we drop into "we should restart" */ | numhosts = i + 1; /* Saves batch_at - index number of probes in the next round!*/ |
| | break; |
| | } |
| } |
} |
| |
|
| if ( /* success in reaching target */ |
if ( /* success in reaching target */ |
| (addrcmp((void *) &(host[batch_at].addr), | (host_addr_cmp(batch_at, remoteaddress, ctl->af) == 0) || |
| (void *) remoteaddress, ctl->af) == 0) || | |
| /* fail in consecutive maxUnknown (firewall?) */ |
/* fail in consecutive maxUnknown (firewall?) */ |
| (n_unknown > ctl->maxUnknown) || |
(n_unknown > ctl->maxUnknown) || |
| /* or reach limit */ |
/* or reach limit */ |
| (batch_at >= ctl->maxTTL - 1)) { |
(batch_at >= ctl->maxTTL - 1)) { |
| |
restart = 1; |
| numhosts = batch_at + 1; |
numhosts = batch_at + 1; |
| |
} |
| |
|
| |
if(restart) { |
| batch_at = ctl->fstTTL - 1; |
batch_at = ctl->fstTTL - 1; |
| return 1; |
return 1; |
| } |
} |
|
Line 582 static void net_validate_interface_address(
|
Line 620 static void net_validate_interface_address(
|
| |
|
| |
|
| /* |
/* |
| |
Given the name of a network interface and a preferred address |
| |
family (IPv4 or IPv6), find the source IP address for sending |
| |
probes from that interface. |
| |
*/ |
| |
static void net_find_interface_address_from_name( |
| |
struct sockaddr_storage *addr, |
| |
int address_family, |
| |
const char *interface_name) |
| |
{ |
| |
struct ifaddrs *ifaddrs; |
| |
struct ifaddrs *interface; |
| |
int found_interface_name = 0; |
| |
|
| |
if (getifaddrs(&ifaddrs) != 0) { |
| |
error(EXIT_FAILURE, errno, "getifaddrs failure"); |
| |
} |
| |
|
| |
interface = ifaddrs; |
| |
while (interface != NULL) { |
| |
if (interface->ifa_addr != NULL && !strcmp(interface->ifa_name, interface_name)) { |
| |
found_interface_name = 1; |
| |
|
| |
if (interface->ifa_addr->sa_family == address_family) { |
| |
if (address_family == AF_INET) { |
| |
memcpy(addr, |
| |
interface->ifa_addr, sizeof(struct sockaddr_in)); |
| |
freeifaddrs(ifaddrs); |
| |
|
| |
return; |
| |
} else if (address_family == AF_INET6) { |
| |
memcpy(addr, |
| |
interface->ifa_addr, sizeof(struct sockaddr_in6)); |
| |
freeifaddrs(ifaddrs); |
| |
|
| |
return; |
| |
} |
| |
} |
| |
} |
| |
|
| |
interface = interface->ifa_next; |
| |
} |
| |
|
| |
if (!found_interface_name) { |
| |
error(EXIT_FAILURE, 0, "no such interface"); |
| |
} else if (address_family == AF_INET) { |
| |
error(EXIT_FAILURE, 0, "interface missing IPv4 address"); |
| |
} else if (address_family == AF_INET6) { |
| |
error(EXIT_FAILURE, 0, "interface missing IPv6 address"); |
| |
} else { |
| |
error(EXIT_FAILURE, 0, "interface missing address"); |
| |
} |
| |
} |
| |
|
| |
|
| |
/* |
| Find the local address we will use to sent to the remote |
Find the local address we will use to sent to the remote |
| host by connecting a UDP socket and checking the address |
host by connecting a UDP socket and checking the address |
| the socket is bound to. |
the socket is bound to. |
|
Line 592 static void net_find_local_address(
|
Line 685 static void net_find_local_address(
|
| int udp_socket; |
int udp_socket; |
| int addr_length; |
int addr_length; |
| struct sockaddr_storage remote_sockaddr; |
struct sockaddr_storage remote_sockaddr; |
| struct sockaddr_in *remote4; |
|
| struct sockaddr_in6 *remote6; |
|
| |
|
| udp_socket = |
udp_socket = |
| socket(remotesockaddr->sa_family, SOCK_DGRAM, IPPROTO_UDP); |
socket(remotesockaddr->sa_family, SOCK_DGRAM, IPPROTO_UDP); |
|
Line 605 static void net_find_local_address(
|
Line 696 static void net_find_local_address(
|
| We need to set the port to a non-zero value for the connect |
We need to set the port to a non-zero value for the connect |
| to succeed. |
to succeed. |
| */ |
*/ |
| if (remotesockaddr->sa_family == AF_INET6) { | addr_length = sockaddr_size(&remotesockaddr_struct); |
| #ifdef ENABLE_IPV6 | memcpy(&remote_sockaddr, &remotesockaddr_struct, addr_length); |
| addr_length = sizeof(struct sockaddr_in6); | *sockaddr_port_offset(&remote_sockaddr) = htons(1); |
| |
|
| memcpy(&remote_sockaddr, rsa6, addr_length); |
|
| remote6 = (struct sockaddr_in6 *) &remote_sockaddr; |
|
| remote6->sin6_port = htons(1); |
|
| #endif |
|
| } else { |
|
| addr_length = sizeof(struct sockaddr_in); |
|
| |
|
| memcpy(&remote_sockaddr, rsa4, addr_length); |
|
| remote4 = (struct sockaddr_in *) &remote_sockaddr; |
|
| remote4->sin_port = htons(1); |
|
| } |
|
| |
|
| if (connect |
if (connect |
| (udp_socket, (struct sockaddr *) &remote_sockaddr, addr_length)) { | (udp_socket, (struct sockaddr *) &remote_sockaddr, sockaddr_size(&remote_sockaddr))) { |
| | #ifdef __linux__ |
| | /* Linux doesn't require source address, so we can support |
| | * a case when mtr is run against unreachable host (that can become |
| | * reachable) */ |
| | if (errno == EHOSTUNREACH) { |
| | close(udp_socket); |
| | localaddr[0] = '\0'; |
| | return; |
| | } |
| | #endif |
| error(EXIT_FAILURE, errno, "udp socket connect failed"); |
error(EXIT_FAILURE, errno, "udp socket connect failed"); |
| } |
} |
| |
|
|
Line 631 static void net_find_local_address(
|
Line 720 static void net_find_local_address(
|
| error(EXIT_FAILURE, errno, "local address determination failed"); |
error(EXIT_FAILURE, errno, "local address determination failed"); |
| } |
} |
| |
|
| sockaddrtop(sourcesockaddr, localaddr, sizeof(localaddr)); | inet_ntop(sourcesockaddr->sa_family, sockaddr_addr_offset(sourcesockaddr), localaddr, sizeof(localaddr)); |
| |
|
| close(udp_socket); |
close(udp_socket); |
| } |
} |
|
Line 651 int net_open(
|
Line 740 int net_open(
|
| |
|
| net_reset(ctl); |
net_reset(ctl); |
| |
|
| remotesockaddr->sa_family = hostent->h_addrtype; | remotesockaddr->sa_family = sourcesockaddr->sa_family = hostent->h_addrtype; |
| | memcpy(sockaddr_addr_offset(remotesockaddr), hostent->h_addr, sockaddr_addr_size(remotesockaddr)); |
| |
|
| switch (hostent->h_addrtype) { | sourceaddress = sockaddr_addr_offset(sourcesockaddr); |
| case AF_INET: | remoteaddress = sockaddr_addr_offset(remotesockaddr); |
| addrcpy((void *) &(rsa4->sin_addr), hostent->h_addr, AF_INET); | |
| sourceaddress = (ip_t *) & (ssa4->sin_addr); | |
| remoteaddress = (ip_t *) & (rsa4->sin_addr); | |
| break; | |
| #ifdef ENABLE_IPV6 | |
| case AF_INET6: | |
| addrcpy((void *) &(rsa6->sin6_addr), hostent->h_addr, AF_INET6); | |
| sourceaddress = (ip_t *) & (ssa6->sin6_addr); | |
| remoteaddress = (ip_t *) & (rsa6->sin6_addr); | |
| break; | |
| #endif | |
| default: | |
| error(EXIT_FAILURE, 0, "net_open bad address type"); | |
| } | |
| |
|
| if (ctl->InterfaceAddress) { |
if (ctl->InterfaceAddress) { |
| net_validate_interface_address(ctl->af, ctl->InterfaceAddress); |
net_validate_interface_address(ctl->af, ctl->InterfaceAddress); |
| |
} else if (ctl->InterfaceName) { |
| |
net_find_interface_address_from_name( |
| |
&sourcesockaddr_struct, ctl->af, ctl->InterfaceName); |
| |
inet_ntop(sourcesockaddr->sa_family, sockaddr_addr_offset(sourcesockaddr), localaddr, sizeof(localaddr)); |
| } else { |
} else { |
| net_find_local_address(); |
net_find_local_address(); |
| } |
} |
|
Line 691 void net_reopen(
|
Line 771 void net_reopen(
|
| } |
} |
| |
|
| remotesockaddr->sa_family = addr->h_addrtype; |
remotesockaddr->sa_family = addr->h_addrtype; |
| addrcpy((void *) remoteaddress, addr->h_addr, addr->h_addrtype); | memcpy(remoteaddress, addr->h_addr, sockaddr_addr_size(remotesockaddr)); |
| memcpy(sockaddr_addr_offset(remotesockaddr), addr->h_addr, sockaddr_addr_size(remotesockaddr)); |
| switch (addr->h_addrtype) { | |
| case AF_INET: | |
| addrcpy((void *) &(rsa4->sin_addr), addr->h_addr, AF_INET); | |
| break; | |
| #ifdef ENABLE_IPV6 | |
| case AF_INET6: | |
| addrcpy((void *) &(rsa6->sin6_addr), addr->h_addr, AF_INET6); | |
| break; | |
| #endif | |
| default: | |
| error(EXIT_FAILURE, 0, "net_reopen bad address type"); | |
| } | |
| |
| net_reset(ctl); |
net_reset(ctl); |
| net_send_batch(ctl); |
net_send_batch(ctl); |
| } |
} |
|
Line 794 void net_save_return(
|
Line 861 void net_save_return(
|
| host[at].saved[idx] = ms; |
host[at].saved[idx] = ms; |
| } |
} |
| |
|
| /* Similar to inet_ntop but uses a sockaddr as it's argument. */ |
|
| static void sockaddrtop( |
|
| struct sockaddr *saddr, |
|
| char *strptr, |
|
| size_t len) |
|
| { |
|
| struct sockaddr_in *sa4; |
|
| #ifdef ENABLE_IPV6 |
|
| struct sockaddr_in6 *sa6; |
|
| #endif |
|
| |
|
| switch (saddr->sa_family) { |
|
| case AF_INET: |
|
| sa4 = (struct sockaddr_in *) saddr; |
|
| xstrncpy(strptr, inet_ntoa(sa4->sin_addr), len - 1); |
|
| strptr[len - 1] = '\0'; |
|
| return; |
|
| #ifdef ENABLE_IPV6 |
|
| case AF_INET6: |
|
| sa6 = (struct sockaddr_in6 *) saddr; |
|
| inet_ntop(sa6->sin6_family, &(sa6->sin6_addr), strptr, len); |
|
| return; |
|
| #endif |
|
| default: |
|
| error(0, 0, "sockaddrtop unknown address type"); |
|
| strptr[0] = '\0'; |
|
| return; |
|
| } |
|
| } |
|
| |
|
| |
|
| /* Address comparison. */ |
/* Address comparison. */ |
| int addrcmp( |
int addrcmp( |
| char *a, | void *a, |
| char *b, | void *b, |
| int family) |
int family) |
| { |
{ |
| int rc = -1; |
int rc = -1; |
|
Line 845 int addrcmp(
|
Line 881 int addrcmp(
|
| } |
} |
| |
|
| return rc; |
return rc; |
| } |
|
| |
|
| /* Address copy. */ |
|
| void addrcpy( |
|
| char *a, |
|
| char *b, |
|
| int family) |
|
| { |
|
| |
|
| switch (family) { |
|
| case AF_INET: |
|
| memcpy(a, b, sizeof(struct in_addr)); |
|
| break; |
|
| #ifdef ENABLE_IPV6 |
|
| case AF_INET6: |
|
| memcpy(a, b, sizeof(struct in6_addr)); |
|
| break; |
|
| #endif |
|
| } |
|
| } |
} |
| |
|
| /* for GTK frontend */ |
/* for GTK frontend */ |