diff options
-rw-r--r-- | pingu.c | 42 | ||||
-rw-r--r-- | pingu.conf | 11 |
2 files changed, 34 insertions, 19 deletions
@@ -39,7 +39,8 @@ char *default_down_action = NULL; char *default_route_script = NULL; struct provider { - struct sockaddr_in address; + struct sockaddr_in dest_addr; + struct sockaddr_in src_addr; char *name; char *interface; char *gateway; @@ -128,7 +129,7 @@ int read_config(const char *file, struct provider_list *head) if (strcmp(key, "host") == 0) { p = xmalloc(sizeof(struct provider)); memset(p, 0, sizeof(struct provider)); - if (init_sockaddr(&p->address, value) < 0) + if (init_sockaddr(&p->dest_addr, value) < 0) return 1; p->gateway = xstrdup(value); p->status = 1; /* online by default */ @@ -175,6 +176,9 @@ int read_config(const char *file, struct provider_list *head) p->required_replies = atoi(value); } else if (strcmp(key, "timeout") == 0) { p->timeout = atof(value); + } else if (strcmp(key, "source-ip") == 0) { + if (init_sockaddr(&p->src_addr, value) < 0) + return 1; } else { log_error("Unknown keyword '%s' on line %i", key, lineno); @@ -184,8 +188,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, const char *iface) +int ping_status(struct provider *p, int *seq) { __u8 buf[1500]; struct iphdr *ip = (struct iphdr *) buf; @@ -194,15 +197,24 @@ int ping_status(struct sockaddr_in *to, int *seq, int retries, int retry; int replies = 0; 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) + int fd = icmp_open(p->timeout); + + /* bidn to interface if set */ + if (p->interface != NULL) + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, p->interface, + strlen(p->interface)+1) == -1) + goto close_fd; + + /* set source address */ + if (bind(fd, (struct sockaddr *)&p->src_addr, sizeof(p->src_addr)) < 0){ + log_error("bind source address %s: %s", + inet_ntoa(p->src_addr.sin_addr), strerror(errno)); goto close_fd; + } - for (retry = 0; retry < retries && replies < required_replies; retry++) { - icmp_send_ping(fd, (struct sockaddr *) to, sizeof(*to), - *seq, len); + for (retry = 0; retry < p->retry && replies < p->required_replies; retry++) { + icmp_send_ping(fd, (struct sockaddr *)&p->dest_addr, + sizeof(p->dest_addr), *seq, len); (*seq)++; (*seq) &= 0xffff; if ((len = icmp_read_reply(fd, (struct sockaddr *) &from, @@ -220,7 +232,7 @@ close_fd: printf("address=%s, replies=%i, required=%i\n", inet_ntoa(to->sin_addr), replies, required_replies); #endif - return (replies >= required_replies); + return (replies >= p->required_replies); } static void print_version(const char *program) @@ -264,7 +276,7 @@ char *get_provider_gateway(struct provider *p) { if (p->gateway != NULL) return p->gateway; - return inet_ntoa(p->address.sin_addr); + return inet_ntoa(p->dest_addr.sin_addr); } void exec_route_change(struct provider_list *head) @@ -316,9 +328,7 @@ void ping_loop(struct provider_list *head, int interval) change = 0; SLIST_FOREACH(p, head, provider_list) { int status; - status = ping_status(&p->address, &seq, p->retry, - p->required_replies, p->timeout, - p->interface); + status = ping_status(p, &seq); if (status != p->status) { change++; p->status = status; @@ -2,24 +2,29 @@ # comments are prefixed with # # global option -interval 1 +interval 10 retry 3 timeout 1.0 # route-script will be executed every time anything changes status. # All gateways that are "up" are sent as parameter. route-script /etc/pingu/route-script -host 10.65.67.11 +# host to ping +host 10.65.67.1 name ISP-1 +# bind to interface interface eth1 +# set the source ip +source-ip 10.65.67.12 timeout 0.3 retry 2 up-action echo "isp 1 went up" down-action echo "iso 1 went down" -#host 10.2.0.3 +#host 10.2.0.1 #name ISP-2 #interface eth0 +#source-ip 10.2.0.3 #up-action /etc/pingu/isp2 up #down-action /etc/pingu/isp2 down |