aboutsummaryrefslogtreecommitdiffstats
path: root/pingu.c
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2010-03-11 09:08:05 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2010-03-11 09:08:05 +0000
commit7bd522b9e29b5c232ed18d86519eebb55e20e533 (patch)
treec48686f1729a8ca57b39d895276a94fc4312c61a /pingu.c
parent1fdd0045cbda214aa799c29d7a94cb365021f21f (diff)
downloadpingu-7bd522b9e29b5c232ed18d86519eebb55e20e533.tar.bz2
pingu-7bd522b9e29b5c232ed18d86519eebb55e20e533.tar.xz
pingu: bind to interface. fix gateway bug
Diffstat (limited to 'pingu.c')
-rw-r--r--pingu.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/pingu.c b/pingu.c
index f85fa58..2047901 100644
--- a/pingu.c
+++ b/pingu.c
@@ -130,6 +130,7 @@ int read_config(const char *file, struct provider_list *head)
memset(p, 0, sizeof(struct provider));
if (init_sockaddr(&p->address, value) < 0)
return 1;
+ p->gateway = xstrdup(value);
p->status = 1; /* online by default */
p->retry = default_retry;
p->timeout = default_timeout;
@@ -159,6 +160,8 @@ int read_config(const char *file, struct provider_list *head)
} else if (strcmp(key, "interface") == 0) {
p->interface = xstrdup(value);
} else if (strcmp(key, "gateway") == 0) {
+ if (p->gateway)
+ free(p->gateway);
p->gateway = xstrdup(value);
} else if (strcmp(key, "name") == 0) {
p->name = xstrdup(value);
@@ -182,7 +185,7 @@ int read_config(const char *file, struct provider_list *head)
/* returns true if it get at least required_replies/retries replies */
int ping_status(struct sockaddr_in *to, int *seq, int retries,
- int required_replies, float timeout)
+ int required_replies, float timeout, const char *iface)
{
__u8 buf[1500];
struct iphdr *ip = (struct iphdr *) buf;
@@ -193,6 +196,10 @@ int ping_status(struct sockaddr_in *to, int *seq, int retries,
int len = sizeof(struct iphdr) + sizeof(struct icmphdr);
int fd = icmp_open(timeout);
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, iface,
+ (iface == NULL) ? 0 : strlen(iface)+1) == -1)
+ goto close_fd;
+
for (retry = 0; retry < retries && replies < required_replies; retry++) {
icmp_send_ping(fd, (struct sockaddr *) to, sizeof(*to),
*seq, len);
@@ -207,6 +214,7 @@ int ping_status(struct sockaddr_in *to, int *seq, int retries,
replies++;
}
}
+close_fd:
icmp_close(fd);
#if 0
printf("address=%s, replies=%i, required=%i\n",
@@ -309,7 +317,8 @@ void ping_loop(struct provider_list *head, int interval)
SLIST_FOREACH(p, head, provider_list) {
int status;
status = ping_status(&p->address, &seq, p->retry,
- p->required_replies, p->timeout);
+ p->required_replies, p->timeout,
+ p->interface);
if (status != p->status) {
change++;
p->status = status;